有人可以建议检查 pgsql 复制状态的步骤以及如何确定复制是否未正确进行吗?
我们在 pgsql9.0 和 pgsql9.4 中使用流复制
我通常使用以下 SQL 查询来检查 Postgres v11 上的状态。
主上:
select * from pg_stat_replication;
在副本上(在我的例子中是流复制):
select * from pg_stat_wal_receiver;
在您的主服务器上,pg_stat_replication 提供有关正在进行的复制的数据:
select client_addr, state, sent_location, write_location,
flush_location, replay_location from pg_stat_replication;
在 postgresql v10 上:
select client_addr, state, sent_lsn, write_lsn,
flush_lsn, replay_lsn from pg_stat_replication;
在 PostgreSQL 中显示复制状态
postgres=# select usename,application_name,client_addr,backend_start,state,sync_state from pg_stat_replication ;
usename | application_name | client_addr | backend_start | state | sync_state
------------+------------------+----------------+-------------------------------+-----------+------------
replicator | walreceiver | 192.168.10.132 | 2018-07-06 06:12:20.786918+03 | streaming | async
(1 row)
postgres=# select pg_is_in_recovery();
pg_is_in_recovery
-------------------
t
(1 row)
postgres=# select pg_last_xlog_receive_location();
pg_last_xlog_receive_location
-------------------------------
0/540C1DB8
postgres=# select pg_last_xlog_replay_location();
pg_last_xlog_replay_location
------------------------------
0/540C1DB8
(1 row)
postgres=# SELECT CASE WHEN pg_last_xlog_receive_location() = pg_last_xlog_replay_location()
THEN 0
ELSE EXTRACT (EPOCH FROM now() - pg_last_xact_replay_timestamp())
END AS log_delay;
log_delay
-----------
0
(1 row)
执行完整数据库复制时有多个阶段:
pg_basebackup
将数据库从主服务器克隆到备用服务器(备用服务器未运行)A) 完整备份
自 PostgreSQL 13 起,您可以使用
pg_stat_progress_basebackup
表,您可以在其中获取每个复制阶段(从主复制阶段)的进度:
psql -c "select TO_CHAR(backup_streamed::decimal/backup_total*100,'fm00D00%'),phase from pg_stat_progress_basebackup;" -t
31.79% | streaming database files
复制过程有多个阶段,每个阶段都会报告进度:
initializing
starting file transfer
streaming database files
finishing file transfer
transferring WAL
在早期的 PostgreSQL 版本中,您只能使用普通磁盘:
$ primary=$(du -s /var/lib/postgresql/14/main/base | awk '{print $1}')
$ replica=4648394012 # same command as above only from replica
$ echo ${replica}/${primary}*100 | bc -l
34.90793993287965597200
pg_stat_replication
给你例如replay_lag
这对整体进步没有太大帮助。您只能估计您实际可能需要保留多少 WAL。
psql -c "select state, client_hostname, write_lag, replay_lag, flush_lag from pg_stat_replication;"
state | client_hostname | write_lag | replay_lag | flush_lag
-----------+-----------------+-----------------+-----------------+-----------------
backup | | | |
streaming | | 00:00:00.000516 | 12:23:15.991732 | 00:00:00.310261
(2 rows)
B) 恢复
备用服务器已完成第一阶段,假设服务器能够启动(关键参数的正确配置)。现在
postgres
进程必须在备用数据库上重放累积的 WAL 或从存档中复制它们(例如使用 archive_command
)才能达到一致的恢复状态。您可以使用 pg_controldata
获取 LSN:
$ /usr/lib/postgresql/14/bin/pg_controldata /var/lib/postgresql/14/main | grep "Minimum recovery"
Minimum recovery ending location: 4034A/1BFFFB58
注意:现阶段,主数据库的
pg_stat_replication
表中没有记录。
您会在日志中注意到类似以下内容:
FATAL: the database system is not yet accepting connections
DETAIL: Consistent recovery state has not been yet reached.
LOG: restored log file "000000020004022E00000029" from archive
HEX 数字指向一个可以转储的 WAL 文件(通常单行就足够了)
/usr/lib/postgresql/14/bin/pg_waldump 14/main/pg_wal/00000002000402340000003D -n 1
rmgr: Heap len (rec/tot): 48/ 48, tx: 1350166609, lsn: 40234/F4001C08, prev 40234/F3FFFDB0, desc: HEAP_CONFIRM off 52, blkref #0: rel 1663/16421/2324630632 blk 85514
我们正在寻找 LSN 部分,例如
lsn: 40234/F4001C08
。现在,当我们回到主服务器时,我们可以获得文件大小单位的滞后:
psql -c "SELECT pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), '40234/F4001C08'));" -t
1813 GB
1813 GB
是当前 WAL 与正在重放的 WAL 之间的差异。
另一种选择是使用
pg_controldata
$ /usr/lib/postgresql/14/bin/pg_controldata /var/lib/postgresql/14/main | grep location
Latest checkpoint's REDO location: 40335/C001D040
您可以在其中获取以下LSN指针:
Backup start location
Latest checkpoint's REDO location
- 当前恢复位置Minimum recovery ending location
C) WAL 流式传输
主备服务器的状态几乎相同,两台服务器都在接受连接。除了这两个服务器之间可能存在一些延迟,这可能是由写入 WAL 的频率、网络传输速度等引起的。
待机状态:
psql -c "SELECT extract(epoch from now() - pg_last_xact_replay_timestamp());"
小学:
psql -c "select state, client_hostname, write_lag, replay_lag, flush_lag from pg_stat_replication;"
这会给你两个服务器之间的时间差。