PostgreSQl 12主從流復制及歸檔配置
上一篇文章說道PostgreSQL 12 的源碼部署,這里我們說一下PostgreSQl 12的主從流復制和歸檔配置。
主從復制的兩種形式
1) 基于文件的日志傳送
創建一個高可用性(HA)集群配置可采用連續歸檔,集群中主服務器工作在連續歸檔模式下,備服務器工作在連續恢復模式下(1臺或多臺可隨時接管主服務器),備持續從主服務器讀取WAL文件。連續歸檔不需要對數據庫表做任何改動,可有效降低管理開銷,對主服務器的性能影響也相對較低。直接從一個數據庫服務器移動WAL記錄到另一臺服務器被稱為日志傳送,PostgreSQL通過一次一文件(WAL段)的WAL記錄傳輸實現了基于文件的日志傳送。日志傳送所需的帶寬取根據主服務器的事務率而變化;日志傳送是異步的,即WAL記錄是在事務提交后才被傳送,那么在一個窗口期內如果主服務器發生災難性的失效則會導致數據丟失,還沒有被傳送的事務將會被丟失;數據丟失窗口可以通過使用參數archive_timeout進行限制,可以低至數秒,但同時會增加文件傳送所需的帶寬。archive_timeout強制N秒以后進行一次歸檔,若設置太小,很快就會超過wal_keep_segments 的值,導致數據覆蓋丟失,因此不要盲目設置。
2)流復制
PostgreSQL在9.x之后引入了主從的流復制機制,所謂流復制,就是備服務器通過tcp流從主服務器中同步相應的數據,主服務器在WAL記錄產生時即將它們以流式傳送給備服務器,而不必等到WAL文件被填充。默認情況下流復制是異步的,這種情況下主服務器上提交一個事務與該變化在備服務器上變得可見之間客觀上存在短暫的延遲,但這種延遲相比基于文件的日志傳送方式依然要小得多,在備服務器的能力滿足負載的前提下延遲通常低于一秒;在流復制中,備服務器比使用基于文件的日志傳送具有更小的數據丟失窗口,不需要采用archive_timeout來縮減數據丟失窗口;PostgreSQL 12開始,在執行通過流復制來配置主備數據庫的時候,不再需要配置額外配置recovery.conf文件了。取而代之的是在備庫環境的$PGDATA路徑下配置一個standby.signal文件,注意該文件是一個普通的文本文件,內容為空。理解起來就是,該文件是一個標識文件。如果備庫通過執行pg_ctl promote提升為主庫的話,那么該文件將自動消失。
注意:全部操作都以postgres用戶進行。
配置主從流復制和歸檔
1)兩臺機器做免密登錄
我們備份和還原過程中所用的archive_command和restore_command命令都以postgres用戶運行,因此我們需要針對postgres用戶實現ssh無密碼登錄。
- # 用postgres用戶登錄到主pgsql服務器
- ssh-keygen -t rsa # 一路回車
- scp /home/postgres/.ssh/id_rsa.pub postgres@10.10.22.152:/home/postgres/.ssh/authorized_keys
- 或者拷貝id_rsa.pub文件到從pgsql上,然后到從上執行以下命令
- cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
- # 登錄從pgsql服務器查看權限
- chmod 700 /home/postgres/.ssh
- chmod 600 /home/postgres/.ssh/authorized_keys
- # 測試登錄
- ssh postgres@10.10.22.152
- # 從pgsql庫
- ssh-keygen -t rsa # 一路回車
- scp /home/postgres/.ssh/id_rsa.pub postgres@10.10.22.151:/home/postgres/.ssh/authorized_keys
- # 登錄從pgsql服務器查看權限
- chmod 700 /home/postgres/.ssh
- chmod 600 /home/postgres/.ssh/authorized_keys
- # 測試登錄
- ssh postgres@10.10.22.152
2)主庫配置
- # 創建用戶
- ceate user replica with replication login password 'replication';
- alter user replica with password 'replication';
- # 修改pg_hba.conf
- host replication replica 10.10.0.0/16 md5
- # 修改配置文件
- $ vim /data/postgresql-12/data/postgresql.conf
- # 監聽所有IP
- listen_addresses = "0.0.0.0"
- # 最大連接數,據說從機需要大于或等于該值
- max_connections = 200
- # 設置主pgsql為生成wal的主機,9.6開始沒有hot_standby(熱備模式)
- wal_level = replica
- # 開啟連續歸檔
- archive_mode = on
- #歸檔命令。-o "StrictHostKeyChecking no" 作用是取消第一次連接輸入yes或者no
- archive_command = 'scp -o "StrictHostKeyChecking no" %p pgslave.ptcloud.t.home:/data/postgresql-12/archive/%f'
- # archive_command = 'test ! -f /data/postgresql-12/archive/%f && scp %p pgslave.ayunw.cn:/data/postgresql-12/archive/%f'
- archive_cleanup_command = '/usr/local/postgresql-12/bin/pg_archivecleanup -d /data/postgresql-12/data/pg_wal %r >> /data/postgresql-12/log/archive_cleanup.log 2>&1'
- # 最多有16個流復制連接。
- max_wal_senders = 16
- # 設置流服務保留的最多wal(老版本叫xlog)文件個數
- wal_keep_segments = 256
- # 數據堆清理的最大進程
- autovacuum_max_workers = 2
- max_worker_processes = 16
- max_logical_replication_workers = 10
- # 日志設置
- log_destination = 'stderr'
- logging_collector = on
- log_directory = '/data/postgresql-12/log'
- log_filename = 'postgresql-%w.log'
- log_file_mode = 0600
- log_truncate_on_rotation = on
- log_rotation_age = 1d
- log_rotation_size = 1GB
- log_min_messages = error
- # 執行超過300ms的sql語句會記錄到pgsql的日志文件,類似于慢日志
- # 一般設置300ms就好,慢日志會打到pgsql日志文件,方便查問題
- log_min_duration_statement = 300
- log_checkpoints = on
- log_connections = on
- log_disconnections = on
- log_error_verbosity = verbose
- log_hostname = on
- log_line_prefix = '%m [%p] '
- log_lock_waits = on
- log_statement = 'ddl'
- # 主庫設置完成后,需要root用戶重啟PG服務才能使以上配置生效
- systemctl daemon-reload
- systemctl restart postgresql
- su - postgres
- psql
- # 主庫創建具有流復制權限的用戶replica
- CREATE user replica login replication encrypted password 'replication';
- postgres=# \du;
- List of roles
- Role name | Attributes | Member of
- -----------+------------------------------------------------------------+-----------
- postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
- replica | Replication | {}
- # 主庫增加主從復制的信任訪問(pg_hba.conf)
- $ vim /data/postgresql-12/data/pg_hba.conf
- # replication privilege.
- host replication replica 10.10.0.0/16 trust
- # 重啟服務
- systemctl daemon-reload
- systemctl restart postgresql
- systemctl status postgresql
3)從庫配置
- # 停止從庫,刪除從pgsql數據目錄中的數據
- # 備份數據目錄
- mkdir -p /opt/pgsqldata_backup
- mv /data/postgresql-12/data/* /opt/pgsqldata_backup
- pg_ctl -D /data/postgresql-12/data -l logfile stop
- rm -rf /data/postgresql-12/data/*
4)從庫做基礎備份
從主服務器上copy數據到從服務器,這一步叫做“基礎備份”
- su - postgres
- $ pg_basebackup -h 10.10.22.151 -p 5432 -U replica -W -R -Fp -Xs -Pv -D /data/postgresql-12/data/
- Password:
- pg_basebackup: initiating base backup, waiting for checkpoint to complete
- pg_basebackup: checkpoint completed
- pg_basebackup: write-ahead log start point: 0/8000028 on timeline 1
- pg_basebackup: starting background WAL receiver
- pg_basebackup: created temporary replication slot "pg_basebackup_13370"
- 31384/31384 kB (100%), 1/1 tablespace
- pg_basebackup: write-ahead log end point: 0/8000100
- pg_basebackup: waiting for background process to finish streaming ...
- pg_basebackup: syncing data to disk ...
- pg_basebackup: base backup completed
參數說明:
- -h 啟動的主庫數據庫地址
- -p 主庫數據庫端口
- -U 流復制用戶
- -W 使用密碼驗證,要用replica的密碼
- -Fp 備份輸出正常的數據庫目錄
- -Xs 使用流復制的方式進行復制
- -Pv 輸出復制過程的詳細信息
- -R 為備庫創建recovery.conf文件。但是pgsql 10以后的新版本的pgsql不需要這個文件了。
- -D 指定創建的備庫的數據庫目錄
5) 配置從庫的配置文件
注意:這時候,從庫數據目錄下的postgresql.conf文件是剛才從主的pgsql上同步過來的,并不是pgsql的配置文件,你需要將原先老的從庫上的配置文件拿過來用。
- $ cd /data/postgresql-12/data/
- $ mv postgres.conf postgres.conf_master.bak
- $ cp /opt/pgsqldata_backup/postgres.conf postgres.conf
- $ vim /data/postgresql-12/data/postgres.conf
- # 監聽所有IP
- listen_addresses = "0.0.0.0"
- # 最大連接數,從pgsql需要大于或等于主的值
- max_connections = 300
- restore_command = 'cp /data/postgresql-12/archive/%f %p'
- archive_cleanup_command = '/usr/local/postgresql-12/bin/pg_archivecleanup -d /data/postgresql-12/data/pg_wal %r && /usr/local/postgresql-12/bin/pg_archivecleanup -d /data/postgresql-12/archive %r >> /data/postgresql-12/log/archive_cleanup.log 2>&1'
- # 9.6開始沒有hot_standby(熱備模式)
- wal_level = replica
- # 最多有16個流復制連接。
- max_wal_senders = 16
- # 設置比主庫大,可以設置為2倍的數值
- wal_keep_segments = 512
- max_logical_replication_workers = 10
- autovacuum_max_workers = 2
- # 和主的值保持一致即可
- max_worker_processes = 16
- # 說明這臺機器不僅用于數據歸檔,還可以用于數據查詢
- hot_standby = on
- #流備份的最大延遲時間
- max_standby_streaming_delay = 30s
- # 向主機匯報本機狀態的間隔時間
- wal_receiver_status_interval = 10s
- # 出現錯誤復制,向主機反饋
- hot_standby_feedback = on
- # 日志設置
- log_destination = 'stderr'
- logging_collector = on
- log_directory = '/data/postgresql-12/log'
- log_filename = 'postgresql-%w.log'
- log_file_mode = 0600
- log_truncate_on_rotation = on
- log_rotation_age = 1d
- log_rotation_size = 1GB
- log_min_messages = error
- # 執行超過300ms的sql語句會被記錄到pgsql的日志文件中
- log_min_duration_statement = 300
- log_checkpoints = on
- log_connections = on
- log_disconnections = on
- log_error_verbosity = verbose
- log_hostname = on
- log_line_prefix = '%m [%p] '
- log_lock_waits = on
- log_statement = 'ddl'
6) 重啟從庫
要保證從庫的數據目錄是postgres屬主和屬組,且權限為0700
- su - postgres
- pg_ctl -D /data/postgresql-12/data restart
驗證pgsql主從
- # 登錄主庫
- su - postgres
- postgres=# psql
- postgres=# select client_addr,sync_state from pg_stat_replication;
- client_addr | sync_state
- --------------+------------
- 10.10.22.152 | async
- (1 row)
- select pid, usename, application_name, client_addr,
- backend_start, client_port, state, sync_state from pg_stat_replication;
- pid | usename | application_name | client_addr | backend_start | client_port | state | sync_state
- -------+---------+------------------+-------------+-------------------------------+-------------+-----------+------------
- 28356 | repl | walreceiver | 10.10.22.152 | 2021-12-30 17:00:59.357653+08 | 48660 | streaming | async
- (1 row)
以上說明10.10.22.152服務器是從節點,在接收異步流復制
到這里,主流復制和歸檔配置完成。
本文轉載自微信公眾號「運維開發故事」