找回密码
 立即注册
首页 业界区 安全 PostgreSQL patroni 高可用 2:patroni安装和配置 ...

PostgreSQL patroni 高可用 2:patroni安装和配置

蟠鲤 2025-9-26 18:22:03
PostgreSQL patroni高可用
PostgreSQL patroni 高可用 1:ectd 安装和配置
PostgreSQL patroni 高可用 2:patroni安装和配置
PostgreSQL patroni 高可用 3:patroni 运维
 

PostgreSQL patroni 高可用 2:patroni 安装 PostgreSQL ptroni的高可用架构图如下所示,本文完成如下架构图中红色标记内的patroni安装和配置。
1.png

图片来源于:https://docs.percona.com/postgresql/12/solutions/high-availability.html#architecture-layout
1,服务器环境

Ubuntu08:192.168.152.115Ubuntu09:192.168.152.116Ubuntu10:192.168.152.117 2,patroni依赖包安装

patroni是一个python开发的中间件,需要依赖python3环境以及python库
Patroni[etcd] 表示Patroni 使用 etcd 作为分布式配置存储 (DCS)。
  1. apt update
  2. apt install -y libpq-dev python3-dev gcc
  3. pip3 install -U pip setuptools wheel importlib_metadata
  4. pip3 install -U psycopg2
  5. pip3 install -U psycopg2-binary
  6. pip3 install -U patroni[etcd]
  7. 安装目录
  8. root@ubuntu08:/usr/local# whereis patroni
  9. patroni: /usr/local/bin/patroni
复制代码
 
3,创建patroni目录
  1. mkdir /usr/local/pgsql16/patroni
  2. 该目录一定要授权给postgres用户,因为patroni是用postgres用户运行的,否则会导致后续无权限写入
  3. chown -R postgres:postgres /usr/local/pgsql16/patroni
  4. chmod 700 -R /usr/local/pgsql16/patroni
复制代码
 
4,编译patroni配置文件patroni.yml

1,本地初已安装的PostgreSQL服务需手动停止,并且移除数据文件目录,2,patroni启动会自动初始化数据库,以及创建postgres用户,其中以patroni.yml参数文件中指定的参数为准。3,etcd3节点,一定要指定etcd3,默认是etcd2,默认情况会报错4,scope: pg_cluster_wy_prod,PostgreSQL实例的cluster_name参数,集群中所有节点的cluster_name都会设置为该名字     namespace: /service/ ,etcd的前缀名字,类似一个命名空间的名字5,patroni.yml是靠空格缩进的,而不是tab键,整个参数文件中,任何一行,如果多一个或者少一个空格,都会导致无法启动,这一点非常逆天,该死的yml配置,希望早日放弃这种逆天的配置格式。
  笔者在这里卡了很久,而且实际测试中看,patroni.yml并不支持中文备注,如下配置文件中的中文注释仅供参考,搭建环境是需移除 
参考如下配置文件,patroni启动的时候,会以如下文件为模板,将相关配置项写入ectd数据库中,同时会初始化一个数据库。 需要注意的是:
在etcd的搭建过程中,etcd的配置文件中,是定义了集群内所有成员的,也即如下
ETCD_INITIAL_CLUSTER="etcd01=http://192.168.152.115:2380,etcd02=http://192.168.152.116:2380,etcd03=http://192.168.152.117:2380",但是在patroni的配置文件,中并没有指定PostgreSQL的主从信息,为什么patroni启动后,从节点会自动从主节点复制数据?
Patroni 节点启动时流程如下:1,Patroni节点启动后,向DCS(这里是 etcd)注册自己的信息(名字、角色、状态)。2,Patroni 查询 DCS,看当前集群有没有 leader(primary)。  如果已有 leader → 本节点会自动配置成 replica,并从 leader 获取数据。  如果没有 leader → 通过选举,本节点可能成为新的 leader。  Ubuntu08上的patroni配置文件,位置:/usr/local/pgsql16/patroni
  1. scope: pg_cluster_wy_prod
  2. namespace: /service/
  3. name: ubuntu08
  4. restapi:
  5.   listen: 192.168.152.115:8008
  6.   connect_address: 192.168.152.115:8008
  7. # 这里一定要是etcd3
  8. etcd3:
  9.   host: 192.168.152.115:2379
  10. log:
  11.   level: INFO
  12.   traceback_level: ERROR
  13.   dir: /usr/local/pgsql16/patroni/
  14.   file_num: 10
  15.   file_size: 104857600
  16. bootstrap:
  17.   dcs:
  18.     ttl: 30
  19.     loop_wait: 10
  20.     retry_timeout: 10
  21.     maximum_lag_on_failover: 1048576
  22.     max_timelines_history: 0
  23.     master_start_timeout: 300
  24.     master_stop_timeout: 0
  25.     synchronous_mode: false
  26.     postgresql:
  27.       use_pg_rewind: true
  28.       pg_hba:
  29.       - host replication repl_user 0.0.0.0/0 md5
  30.       - host all all 0.0.0.0/0 md5
  31.       use_slots: true
  32.       parameters:
  33.         wal_level: hot_standby
  34.         hot_standby: "on"
  35.         max_connections: 100
  36.         max_worker_processes: 8
  37.         wal_keep_segments: 8
  38.         max_wal_senders: 10
  39.         max_replication_slots: 10
  40.         max_prepared_transactions: 0
  41.         max_locks_per_transaction: 64
  42.         wal_log_hints: "on"
  43.         track_commit_timestamp: "off"
  44.         archive_mode: "on"
  45.         archive_timeout: 1800s
  46.         archive_command: test ! -f /usr/local/pgsql16/pg_wal_arch/%f && cp %p /usr/local/pgsql16/pg_wal_arch/%f
  47.         
  48.         log_destination: stderr
  49.         logging_collector: "on"
  50.         log_directory: "log"
  51.         log_filename: "postgresql-%Y-%m-%d_%H%M%S.log"
  52.         log_file_mode: "0600"
  53.         log_rotation_age: "1d"
  54.         log_min_duration_statement: 1
  55.         log_autovacuum_min_duration: 0
  56.         log_checkpoints: "on"
  57.         log_connections: "on"
  58.         log_disconnections: "on"
  59.         log_hostname: "on"
  60.         log_line_prefix: "%m [%p] user:%u,db:%d,app:%a,host:%h "
  61.         log_lock_waits: "on"
  62.         log_recovery_conflict_waits: "on"
  63.         log_statement: "ddl"
  64.         log_replication_commands: "on"
  65.         log_temp_files: 1
  66.         log_timezone: "Asia/Shanghai"
  67.         
  68.   # some desired options for 'initdb'
  69.   initdb:  # Note: It needs to be a list (some options need values, others are switches)
  70.   - encoding: UTF8
  71.   - data-checksums
  72. postgresql:
  73.   listen: 192.168.152.115:9000
  74.   connect_address: 192.168.152.115:9000
  75.   data_dir: /usr/local/pgsql16/pg9000/data
  76.   bin_dir: /usr/local/pgsql16/server/bin
  77.   #config_dir:
  78.   pgpass: /home/postgres/.pgpass
  79.   # 用户名和密码可以自定义
  80.   authentication:
  81.     replication:
  82.       username: repl_user
  83.       password: repl_user_123456
  84.     superuser:
  85.       username: postgres
  86.       password: postgres_pwd
  87.     rewind:  # Has no effect on postgres 10 and lower
  88.       username: rewind_user
  89.       password: rewind_pwd
  90.   parameters:
  91.     unix_socket_directories: '..'  # parent directory of data_dir
  92. tags:
  93.     # failover_priority: 1
  94.     # sync_priority: 1
  95.     noloadbalance: false
  96.     clonefrom: false
  97.     nostream: false
复制代码
   Ubuntu09上的patroni配置文件,位置:/usr/local/pgsql16/patroni
Ubuntu09上的patroni配置文件
  1. scope: pg_cluster_wy_prod
  2. namespace: /service/
  3. name: ubuntu09
  4. restapi:
  5.   listen: 192.168.152.116:8008
  6.   connect_address: 192.168.152.116:8008
  7. etcd3:
  8.   host: 192.168.152.116:2379
  9. log:
  10.   level: INFO
  11.   traceback_level: ERROR
  12.   dir: /usr/local/pgsql16/patroni/
  13.   file_num: 10
  14.   file_size: 104857600
  15. bootstrap:
  16.   dcs:
  17.     ttl: 30
  18.     loop_wait: 10
  19.     retry_timeout: 10
  20.     maximum_lag_on_failover: 1048576
  21.     max_timelines_history: 0
  22.     master_start_timeout: 300
  23.     master_stop_timeout: 0
  24.     synchronous_mode: false
  25.     postgresql:
  26.       use_pg_rewind: true
  27.       pg_hba:
  28.       - host replication repl_user 0.0.0.0/0 md5
  29.       - host all all 0.0.0.0/0 md5
  30.       use_slots: true
  31.       parameters:
  32.         wal_level: hot_standby
  33.         hot_standby: "on"
  34.         max_connections: 100
  35.         max_worker_processes: 8
  36.         wal_keep_segments: 8
  37.         max_wal_senders: 10
  38.         max_replication_slots: 10
  39.         max_prepared_transactions: 0
  40.         max_locks_per_transaction: 64
  41.         wal_log_hints: "on"
  42.         track_commit_timestamp: "off"
  43.         archive_mode: "on"
  44.         archive_timeout: 1800s
  45.         archive_command: test ! -f /usr/local/pgsql16/pg_wal_arch/%f && cp %p /usr/local/pgsql16/pg_wal_arch/%f
  46.         log_destination: stderr
  47.         logging_collector: "on"
  48.         log_directory: "log"
  49.         log_filename: "postgresql-%Y-%m-%d_%H%M%S.log"
  50.         log_file_mode: "0600"
  51.         log_rotation_age: "1d"
  52.         log_min_duration_statement: 1
  53.         log_autovacuum_min_duration: 0
  54.         log_checkpoints: "on"
  55.         log_connections: "on"
  56.         log_disconnections: "on"
  57.         log_hostname: "on"
  58.         log_line_prefix: "%m [%p] user:%u,db:%d,app:%a,host:%h "
  59.         log_lock_waits: "on"
  60.         log_recovery_conflict_waits: "on"
  61.         log_statement: "ddl"
  62.         log_replication_commands: "on"
  63.         log_temp_files: 1
  64.         log_timezone: "Asia/Shanghai"
  65.         
  66.   # some desired options for 'initdb'
  67.   initdb:  # Note: It needs to be a list (some options need values, others are switches)
  68.   - encoding: UTF8
  69.   - data-checksums
  70. postgresql:
  71.   listen: 192.168.152.116:9000
  72.   connect_address: 192.168.152.116:9000
  73.   data_dir: /usr/local/pgsql16/pg9000/data
  74.   bin_dir: /usr/local/pgsql16/server/bin
  75.   #config_dir:
  76.   pgpass: /home/postgres/.pgpass
  77.   authentication:
  78.     replication:
  79.       username: repl_user
  80.       password: repl_user_123456
  81.     superuser:
  82.       username: postgres
  83.       password: postgres_pwd
  84.     rewind:  # Has no effect on postgres 10 and lower
  85.       username: rewind_user
  86.       password: rewind_user_pwd
  87.   parameters:
  88.     unix_socket_directories: '..'  # parent directory of data_dir
  89. tags:
  90.     # failover_priority: 1
  91.     # sync_priority: 1
  92.     noloadbalance: false
  93.     clonefrom: false
  94.     nostream: false
复制代码
 
Ubuntu10上的patroni配置文件,位置:/usr/local/pgsql16/patroni
Ubuntu10上的patroni配置文件
  1. scope: pg_cluster_wy_prod
  2. namespace: /service/
  3. name: ubuntu10
  4. restapi:
  5.   listen: 192.168.152.117:8008
  6.   connect_address: 192.168.152.117:8008
  7. etcd3:
  8.   host: 192.168.152.117:2379
  9. log:
  10.   level: INFO
  11.   traceback_level: ERROR
  12.   dir: /usr/local/pgsql16/patroni/
  13.   file_num: 10
  14.   file_size: 104857600
  15. bootstrap:
  16.   dcs:
  17.     ttl: 30
  18.     loop_wait: 10
  19.     retry_timeout: 10
  20.     maximum_lag_on_failover: 1048576
  21.     max_timelines_history: 0
  22.     master_start_timeout: 300
  23.     master_stop_timeout: 0
  24.     synchronous_mode: false
  25.     postgresql:
  26.       use_pg_rewind: true
  27.       pg_hba:
  28.       - host replication repl_user 0.0.0.0/0 md5
  29.       - host all all 0.0.0.0/0 md5
  30.       use_slots: true
  31.       parameters:
  32.         wal_level: hot_standby
  33.         hot_standby: "on"
  34.         max_connections: 100
  35.         max_worker_processes: 8
  36.         wal_keep_segments: 8
  37.         max_wal_senders: 10
  38.         max_replication_slots: 10
  39.         max_prepared_transactions: 0
  40.         max_locks_per_transaction: 64
  41.         wal_log_hints: "on"
  42.         track_commit_timestamp: "off"
  43.         archive_mode: "on"
  44.         archive_timeout: 1800s
  45.         archive_command: test ! -f /usr/local/pgsql16/pg_wal_arch/%f && cp %p /usr/local/pgsql16/pg_wal_arch/%f
  46.         log_destination: stderr
  47.         logging_collector: "on"
  48.         log_directory: "log"
  49.         log_filename: "postgresql-%Y-%m-%d_%H%M%S.log"
  50.         log_file_mode: "0600"
  51.         log_rotation_age: "1d"
  52.         log_min_duration_statement: 1
  53.         log_autovacuum_min_duration: 0
  54.         log_checkpoints: "on"
  55.         log_connections: "on"
  56.         log_disconnections: "on"
  57.         log_hostname: "on"
  58.         log_line_prefix: "%m [%p] user:%u,db:%d,app:%a,host:%h "
  59.         log_lock_waits: "on"
  60.         log_recovery_conflict_waits: "on"
  61.         log_statement: "ddl"
  62.         log_replication_commands: "on"
  63.         log_temp_files: 1
  64.         log_timezone: "Asia/Shanghai"
  65.         
  66.   # some desired options for 'initdb'
  67.   initdb:  # Note: It needs to be a list (some options need values, others are switches)
  68.   - encoding: UTF8
  69.   - data-checksums
  70. postgresql:
  71.   listen: 192.168.152.117:9000
  72.   connect_address: 192.168.152.117:9000
  73.   data_dir: /usr/local/pgsql16/pg9000/data
  74.   bin_dir: /usr/local/pgsql16/server/bin
  75.   #config_dir:
  76.   pgpass: /home/postgres/.pgpass
  77.   authentication:
  78.     replication:
  79.       username: repl_user
  80.       password: repl_user_123456
  81.     superuser:
  82.       username: postgres
  83.       password: postgres_pwd
  84.     rewind:  # Has no effect on postgres 10 and lower
  85.       username: rewind_user
  86.       password: rewind_user_pwd
  87.   parameters:
  88.     unix_socket_directories: '..'  # parent directory of data_dir
  89. tags:
  90.     # failover_priority: 1
  91.     # sync_priority: 1
  92.     noloadbalance: false
  93.     clonefrom: false
  94.     nostream: false
复制代码
 
4.1 相关参数

scope: pg_cluster_wy_prod

1,该参数会注册到etcd的key中2,在patroni的配置中,可以在这里体现出来  scope: 参数为pg_cluster_wy_prod  namespace:参数为 /service/
  1. root@ubuntu08:/usr/local# etcdctl get /service --prefix --keys-only
  2. {"level":"warn","ts":"2025-09-22T16:47:36.675953+0800","caller":"flags/flag.go:94","msg":"unrecognized environment variable","environment-variable":"ETCDCTL_API=3"}
  3. /service/pg_cluster_wy_prod/config
  4. /service/pg_cluster_wy_prod/history
  5. /service/pg_cluster_wy_prod/initialize
  6. /service/pg_cluster_wy_prod/leader
  7. /service/pg_cluster_wy_prod/members/ubuntu08
  8. /service/pg_cluster_wy_prod/members/ubuntu09
  9. /service/pg_cluster_wy_prod/members/ubuntu10
  10. /service/pg_cluster_wy_prod/status
复制代码
 
5,编辑patroni systemctl服务文件

patroni的systemctl 启动文件,各个节点都一样
  1. [Unit]
  2. Description=patroni
  3. After=network.target remote-fs.target nss-lookup.target etcd.service #一定要等到etcd启动之后再启动patroni
  4. Requires=etcd.service
  5. [Service]
  6. Type=forking
  7. User=postgres
  8. Group=postgres
  9. Environment="PGHOME=/usr/local/pgsql16/server"
  10. Environment="PGDATA=/usr/local/pgsql16/pg9000/data"
  11. Environment="PGPORT=9000"
  12. Environment="LD_LIBRARY_PATH=/usr/local/pgsql16/server/lib"
  13. Environment="PATH=/usr/local/pgsql16/server/bin:/usr/local/bin"
  14. ExecStart=/bin/bash -c "patroni /usr/local/pgsql16/patroni/patroni.yml >> /usr/local/pgsql16/patroni/patroni.log 2>&1 &"
  15. ExecReload=/bin/kill -s HUP $MAINPID
  16. ExecStop=/usr/bin/killall patroni
  17. KillMode=process
  18. TimeoutSec=30
  19. Restart=no
  20. [Install]
  21. WantedBy=multi-user.target
复制代码
 
6,启动partoni

设置自动启动,并启动服务,检查集群状态,patronictl -c /usr/local/pgsql16/patroni/patroni.yml list
  1. systemctl daemon-reload
  2. systemctl start patroni
  3. systemctl enable patroni
  4. root@ubuntu08:/usr/local# patronictl -c /usr/local/pgsql16/patroni/patroni.yml list
  5. + Cluster: pg_cluster_wy_prod (7552796412810163150) +-----------+
  6. | Member   | Host           | Role   | State   | TL | Lag in MB |
  7. +----------+----------------+--------+---------+----+-----------+
  8. | ubuntu08 | 127.0.0.1:9000 | Leader | running |  1 |           |
  9. +----------+----------------+--------+---------+----+-----------+
  10. root@ubuntu08:/usr/local#
  11. root@ubuntu08:/usr/local# systemctl status patroni
  12. ● patroni.service - patroni
  13.      Loaded: loaded (/etc/systemd/system/patroni.service; enabled; vendor preset: enabled)
  14.      Active: active (running) since Mon 2025-09-22 14:27:29 CST; 42min ago
  15.    Main PID: 623548 (patroni)
  16.       Tasks: 13 (limit: 4550)
  17.      Memory: 95.6M
  18.      CGroup: /system.slice/patroni.service
  19.              ├─623548 /usr/bin/python3 /usr/local/bin/patroni /usr/local/pgsql16/patroni/patroni.yml
  20.              ├─623575 /usr/local/pgsql16/server/bin/postgres -D /usr/local/pgsql16/pg9000/data --config-file=/usr/local/pgsql16/pg9000/data/postgresql.conf --listen_addresses=127.0.0.1 --port=9000 --cluster>
  21.              ├─623577 postgres: pg_cluster_wy_prod: checkpointer
  22.              ├─623578 postgres: pg_cluster_wy_prod: background writer
  23.              ├─623580 postgres: pg_cluster_wy_prod: walwriter
  24.              ├─623581 postgres: pg_cluster_wy_prod: autovacuum launcher
  25.              ├─623583 postgres: pg_cluster_wy_prod: logical replication launcher
  26.              └─623588 postgres: pg_cluster_wy_prod: postgres postgres 127.0.0.1(48710) idle
  27. Sep 22 14:27:29 ubuntu08 systemd[1]: Starting patroni...
  28. Sep 22 14:27:29 ubuntu08 systemd[1]: Started patroni.
  29. --查看patroni集群状态
  30. root@ubuntu08:/usr/local# patronictl -c /usr/local/pgsql16/patroni/patroni.yml list
  31. + Cluster: pg_cluster_wy_prod (7552796412810163150) +-----------+
  32. | Member   | Host           | Role   | State   | TL | Lag in MB |
  33. +----------+----------------+--------+---------+----+-----------+
  34. | ubuntu08 | 127.0.0.1:9000 | Leader | running |  1 |           |
  35. +----------+----------------+--------+---------+----+-----------+
  36. root@ubuntu08:/usr/local#
  37. root@ubuntu08:/usr/local#
复制代码
patroni环境变量配置,这样不需要patronictl 每次都加上-c /usr/local/pgsql16/patroni/patroni.yml 来指定配置文件
  1. 为了方便日常操作,添加以下内容到/etc/profile中
  2. vi /etc/profile
  3. export PATRONICTL_CONFIG_FILE=/home/postgres/patroni/patroni.yml
  4. source /etc/profile
复制代码
 
7,patroni环境下修改PostgreSQL配置文件

这部分非常非常非常重要,很容易误解,笔者在这里花了一个多小时的时间,来测试各种场景。
方法1 patronictl edit-config

patronictl -c /usr/local/pgsql16/patroni/patroni.yml edit-config,该命令会以nano编辑器的方式打开patroni.yml配置文件,修改后:1,edit-config的方式修改配置,不是修改patroni.yml这个物理配置文件自身,而是操作etcd数据库的方式,将数据写入ectd数据库,在任何一个节点都可以修改,并且会同步至其他节点2,如果参数有误或者格式不对,保存的时候(Ctrl + O → Enter → Ctrl + X)会直接报错3,如果正常保存,不会重写patroni.yml这个物理文件自身,也就是说即便修改成功,这个文件也不会变4,修改后该参数不会自动更新或保存在postgresql.auto.conf配置文件中5,如果正常保存,会自动重写pg数据库实例目录下的patroni.dynamic.json文件6,如果正常保存,会保存在ectd数据库中,如下修改"shared_buffers",   "old_value"始终是默认值,而不是字面意思上修改前的值  我擦我试了好几次才发现这个规律    "shared_buffers": {            "old_value": "128MB",            "new_value": "1GB"        }7,修改后的参数会下发到所有的PostgreSQL实例,其他PostgreSQL实例下,同样会自动重写patroni.dynamic.json文件8,patroni的日志中,会自动记录修改参数的日志:Changed shared_buffers from '128MB' to '512MB' (restart might be required) 关于修改参数的patronictl edit-config, 语法上是patronictl 指定一个配置文件修改,修改后实际上修改的etcd的中的记录,然后etcd中的new_value记录的会分发到etcd的所有节点,但是其old_value并不是修改前的值,而是默认值,我一直以为搞错了,试了三次才发现是这个规律 <img>。 方法2 ALTER SYSTEM SET 命令

通过ALTER SYSTEM SET parameter='***'的方式修改这种方式修改后,1,可以再任意节点执行修改2,执行成功后,会将参数保存在postgresql.auto.conf配置文件中,3,这种方式的修改,只会对当前节点生效,*不会*同步至其他节点“方法2”修改的参数会优先于“方式1”修改的加载,也就是说postgresql.auto.conf优先级会高于patroni.dynamic.json
  1. --在从节点上执行
  2. SHOW listen_addresses;
  3. listen_addresses|
  4. ----------------+
  5. 192.168.152.115 |
  6. --查看当前work_mem
  7. show work_mem;
  8. work_mem|
  9. --------+
  10. 4MB     |
  11. --修改work_mem
  12. ALTER SYSTEM SET work_mem TO '8MB';
  13. SELECT pg_reload_conf();
复制代码
 通过patronictl edit-config来修改PostgreSQL的参数,遇到以下一个问题,原本修改记录是记录在etcd中的(再次说了edit-config的方式修改配置,不是修改patroni.yml这个物理配置文件自身,而是操作etcd数据库),但是work_mem参数的修改就不会记录在ectd中,还是有缓存? work_mem参数的新增或者修改不会记录类似修改前后的值?
2.png
 
3.png
 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

前天 18:28

举报

前排留名,哈哈哈
您需要登录后才可以回帖 登录 | 立即注册