首页
产品
CLup:PostgreSQL高可用集群平台CData高性能数据库云一体机CBackup数据库备份恢复云平台CPDA高性能双子星数据库机
解决方案
数据库专业技术服务全栈式PostgreSQL解决方案Oracle分布式存储化数据库云
文章
客户及伙伴
中启开源
关于我们
公司简介 联系我们
中启开源

1. 控制文件的作用

PostgreSQL的控制文件与Oracle类似,都是记录数据库的一些重要信息。如数据库唯一ID、检查点、状态。

2. 查看控制文件内容的方法

使用pg_controldata命令就可以显示出控制文件中的内容:

  1. [postgres@pg01 ~]$ pg_controldata
  2. pg_control version number: 942
  3. Catalog version number: 201409291
  4. Database system identifier: 6197591927813975882
  5. Database cluster state: in production
  6. pg_control last modified: Wed 23 Sep 2015 04:14:47 PM CST
  7. Latest checkpoint location: 0/1748510
  8. Prior checkpoint location: 0/1739E70
  9. Latest checkpoint's REDO location: 0/17484D8
  10. Latest checkpoint's REDO WAL file: 000000010000000000000001
  11. Latest checkpoint's TimeLineID: 1
  12. Latest checkpoint's PrevTimeLineID: 1
  13. Latest checkpoint's full_page_writes: on
  14. Latest checkpoint's NextXID: 0/1830
  15. Latest checkpoint's NextOID: 24582
  16. Latest checkpoint's NextMultiXactId: 1
  17. Latest checkpoint's NextMultiOffset: 0
  18. Latest checkpoint's oldestXID: 1800
  19. Latest checkpoint's oldestXID's DB: 1
  20. Latest checkpoint's oldestActiveXID: 1830
  21. Latest checkpoint's oldestMultiXid: 1
  22. Latest checkpoint's oldestMulti's DB: 1
  23. Time of latest checkpoint: Wed 23 Sep 2015 04:14:46 PM CST
  24. Fake LSN counter for unlogged rels: 0/1
  25. Minimum recovery ending location: 0/0
  26. Min recovery ending loc's timeline: 0
  27. Backup start location: 0/0
  28. Backup end location: 0/0
  29. End-of-backup record required: no
  30. Current wal_level setting: hot_standby
  31. Current wal_log_hints setting: off
  32. Current max_connections setting: 100
  33. Current max_worker_processes setting: 8
  34. Current max_prepared_xacts setting: 0
  35. Current max_locks_per_xact setting: 64
  36. Maximum data alignment: 8
  37. Database block size: 8192
  38. Blocks per segment of large relation: 131072
  39. WAL block size: 8192
  40. Bytes per WAL segment: 16777216
  41. Maximum length of identifiers: 64
  42. Maximum columns in an index: 32
  43. Maximum size of a TOAST chunk: 1996
  44. Size of a large-object chunk: 2048
  45. Date/time type storage: 64-bit integers
  46. Float4 argument passing: by value
  47. Float8 argument passing: by value
  48. Data page checksum version: 0

3. 内容解析

我们下面对上面输出的这些内容进行详细的解析。

我们先讲一些与版本、平台迁移升级有关的一些信息。如果这些信息不同,即使在同一种Linux平台上,数据库也是不能迁移或升级的。在数据库启动过程中,读取控制文件后发现不能兼容则报“database files are incompatible with server”
的错误。

控制文件中还记录了数据库的唯一标识串(Database system identifier):

  1. Database system identifier: 6197591927813975882

这个标识串是一个64bit的整数,其中包含了创建数据库时的时间戳及initdb时初使化的进程号,所以通常是不会重复的。计算方法可以见xlog.c中:

  1. gettimeofday(&tv, NULL);
  2. sysidentifier = ((uint64) tv.tv_sec) << 32;
  3. sysidentifier |= ((uint64) tv.tv_usec) << 12;
  4. sysidentifier |= getpid() & 0xFFF;

如上面的显示的数据库标识串为“6197591927813975882”,通过下面的SQL,我们就可以知道此数据库是什么时候建的:

  1. postgres=# SELECT to_timestamp(((6197591927813975882>>32) & (2^32 -1)::bigint));
  2. to_timestamp
  3. ------------------------
  4. 2015-09-23 14:21:57+08
  5. (1 row)

在控制文件中还记录了实例的状态,在命令pg_controldata中的“Database cluster state”项显示的就是控制文件中实例的状态,有以下几种状态:

在源码实现中,实例的状态是用一个枚举类型来表示的,具体见pg_control.h中

  1. typedef enum DBState
  2. {
  3. DB_STARTUP = 0,
  4. DB_SHUTDOWNED,
  5. DB_SHUTDOWNED_IN_RECOVERY,
  6. DB_SHUTDOWNING,
  7. DB_IN_CRASH_RECOVERY,
  8. DB_IN_ARCHIVE_RECOVERY,
  9. DB_IN_PRODUCTION
  10. } DBState;

下面我们来看一些与PostgreSQL的异常重启后的实例恢复、物理备份的信息:

  1. Latest checkpoint location: 0/1748510
  2. Prior checkpoint location: 0/1739E70
  3. Latest checkpoint's REDO location: 0/17484D8
  4. Latest checkpoint's REDO WAL file: 000000010000000000000001
  5. Latest checkpoint's TimeLineID: 1
  6. Latest checkpoint's PrevTimeLineID: 1
  7. Latest checkpoint's full_page_writes: on
  8. Latest checkpoint's NextXID: 0/1830
  9. Latest checkpoint's NextOID: 24582
  10. Latest checkpoint's NextMultiXactId: 1
  11. Latest checkpoint's NextMultiOffset: 0
  12. Latest checkpoint's oldestXID: 1800
  13. Latest checkpoint's oldestXID's DB: 1
  14. Latest checkpoint's oldestActiveXID: 1830
  15. Latest checkpoint's oldestMultiXid: 1
  16. Latest checkpoint's oldestMulti's DB: 1
  17. Minimum recovery ending location: 0/0

当数据库异常停止后再重新启动时,需要做实例恢复,实例恢复的过程是从WAL日志中,找到最后一次的checkpoint点,然后读取这个点之后的WAL日志,然后重新应用这些日志,这个过程称为数据库实例的前滚恢复。最后一次的checkpoint点的信息就记录在上面“Latest checkpoint”项中。

上面中还需要关注的一个内容是“Minimum recovery ending location”。这个值与Standby库应用WAL日志有关,需要注意的是主库与备库的控制文件中的checkpoint的信息是不同的。在备库中,每replay一些WAL日志后,就会做一次checkpoint点,然后把这个checkpoint点的信息记录到控制文件中。当在备库replay一些日志后,如果有一些脏数据刷新到磁盘中后,会把产生脏数据的最新日志的位置记录到“Minimum recovery ending location”。为什么要记录呢?因为这是为了能保证恢复到一个一致点。想象一下,备库异常停机后,再启动后,如果备库马上提供只读服务(或激活成主库),但磁盘上的数据不是一个一致的数据,这时如果读备库就会读到错误的数据,所以要replay日志一直到超过“Minimum recovery ending location”位置后,才能对外提供只读服务(或激活成主库)。

最后我们来讲一下与热备份相关的三项:

“Backup start location”与“Backup end location”记录了一个WAL日志的位置。有人可能会误认为当在主库上执行完“SELECT pg_start_backup(‘tangxxxx’);”后,控制文件中“Backup start location”就会变成当前的WAL值,实际不是这样的。

在主库上做“SELECT pg_start_backup(‘osdba201509230923’);”后,只是在主库的数据目录下生成了一个backup_label文件,此文件的内容如下:

  1. START WAL LOCATION: 0/4000028 (file 000000010000000000000004)
  2. CHECKPOINT LOCATION: 0/4000060
  3. BACKUP METHOD: pg_start_backup
  4. BACKUP FROM: master
  5. START TIME: 2015-09-22 19:44:23 CST
  6. LABEL: osdba201509230923

这时我们拷贝主库,拷贝出来的数据文件中就包括了backup_label文件。备库启动时,如果发现了有backup_label这个文件,就会从这个文件中记录的点开始恢复,同时备库会把此位置记录到控制文件的“Backup start location”中。

而“Backup end location:”与“End-of-backup record required”记录了备库恢复过程中的一些中间状态。