获取当前时间线

PostgreSQL 9.6 及更高版本

PostgreSQL 9.6 开始,可以通过函数 pg_control_checkpoint() 获取当前时间线。

postgres=# SELECT timeline_id FROM pg_control_checkpoint();
 timeline_id
-------------
           1
(1 row)

(注意:在standby节点上,如果刚刚发生了一次时间线切换,pg_control_checkpoint() 返回的值可能是前一个时间线,直到下一次 检查点 (Checkpoint) 才会更新。)

或者,在standby节点上,视图 pg_stat_wal_receiver 也提供了当前时间线。

postgres=# SELECT pid, status, received_lsn, received_tli FROM pg_stat_wal_receiver;
  pid  |  status   | received_lsn | received_tli
-------+-----------+--------------+--------------
 11969 | streaming | 0/30015B0    |            1
(1 row)

PostgreSQL 9.5 及更早版本

在 9.6 版本之前,没有简单的方法可以明确地将当前时间线作为一个独立的值检索出来,必须使用以下变通方法之一。

在数据库层面,可以通过执行以下语句间接检索:

SELECT pg_xlogfile_name(pg_current_xlog_insert_location()); 

这将返回当前的 WAL (Write-Ahead Logging) 文件名,其前 8 位数字包含了时间线(此操作只能在主节点上执行)。

上述方法的变种,将时间线提取为整数:

SELECT SUBSTR(pg_xlogfile_name(pg_current_xlog_insert_location()), 1, 8)::INT AS timeline;

使用 pg_controldata

pg_controldata 命令会返回当前时间线信息。

$ pg_controldata /path/to/postgres/data/ | grep -i timeline
Latest checkpoint's TimeLineID:       1
Latest checkpoint's PrevTimeLineID:   1
Min recovery ending loc's timeline:   0

使用复制连接

通过发起一个到服务器的复制连接并执行 IDENTIFY_SYSTEM 命令,也可以获得当前时间线。

$ psql "dbname=postgres host=localhost user=repl_user replication=1"
psql (9.5.3)
Type "help" for help.

postgres=# IDENTIFY_SYSTEM;
      systemid       | timeline |  xlogpos  | dbname
---------------------+----------+-----------+--------
 6301592708518993068 |        1 | 0/5002168 | 
(1 row)