PostgreSQL 实例在启动的时候会创建一个 postmaster.pid
文件,通过查看该文件的状态可以知道实例启动的时间,另外 pg_stat_activity 记录了辅助进程的状态,因此我们可以通过 select pg_stat_file('postmaster.pid') AS start_time;
、 select MIN(backend_start) as start_time from pg_stat_activity;
或者 select pg_postmaster_start_time();
来获取实例启动的时间(或者 ),但如何知道实例的创建时间呢?
PostgreSQL 创建实例(initdb)的时候会写一个 global/pg_control
文件,这其中有一个字段 Database system identifier,在实例 bootstrap 的时候初始化该字段,且在实例之后的生命周期中不再变更。
void
BootStrapXLOG(void)
{
...
gettimeofday(&tv, NULL);
sysidentifier = ((uint64) tv.tv_sec) << 32;
sysidentifier |= ((uint64) tv.tv_usec) << 12;
sysidentifier |= getpid() & 0xFFF;
...
/* Now create pg_control */
InitControlFile(sysidentifier);
...
}
因此我们可以读取该字段,解析其高 32 位即可获取实例创建的时间:
➜ postgres_data pg_controldata . | head
pg_control version number: 1300
Catalog version number: 202308241
Database system identifier: 7271454612807718361
Database cluster state: in production
pg_control last modified: Mon Oct 2 12:56:26 2023
Latest checkpoint location: 0/2C0163A0
Latest checkpoint's REDO location: 0/2C016368
Latest checkpoint's REDO WAL file: 00000001000000000000002C
Latest checkpoint's TimeLineID: 1
Latest checkpoint's PrevTimeLineID: 1
postgres=# select to_hex(7271454612807718361);
to_hex
------------------
64e96571ccc795d9
(1 row)
postgres=# select '0x64e96571'::int;
int4
------------
1693017457
(1 row)
postgres=# select to_timestamp(1693017457) as cluster_init;
to_timestamp
------------------------
2023-08-26 10:37:37+08
(1 row)
或者用一条语句获取实例创建时间:
postgres=# select to_timestamp ( system_identifier >> 32 ) as cluster_init from pg_control_system();
cluster_init
------------------------
2023-08-26 10:37:37+08
(1 row)