1. 程式人生 > 其它 >PostgreSQL控制檔案講解及案例

PostgreSQL控制檔案講解及案例

PostgreSQL控制檔案內容:

主要分為是三部分,初始化靜態資訊、WAL及檢查點的動態資訊、一些配置資訊。

我們可以用過pg_controldata命令直接讀取PostgreSQL控制檔案內容:

[postgres@postgresdb ~]$ /u01/postgres/pgsql/bin/pg_controldata -D /data/postgres/data
pg_control version number: 1100
Catalog version number: 201809051
Database system identifier: 6709564017377676696
Database cluster state: in production
pg_control last modified: Wed 17 Jul 2019 02:27:12 PM HKT
Latest checkpoint location: 5A/F522A8E0
Latest checkpoint's REDO location: 5A/F522A8A8
Latest checkpoint's REDO WAL file: 000000010000005A000000F5
Latest checkpoint's TimeLineID: 1
Latest checkpoint's PrevTimeLineID: 1
Latest checkpoint's full_page_writes: on
Latest checkpoint's NextXID: 0:57914
Latest checkpoint's NextOID: 73874
Latest checkpoint's NextMultiXactId: 1
Latest checkpoint's NextMultiOffset: 0
Latest checkpoint's oldestXID: 561
Latest checkpoint's oldestXID's DB: 1
Latest checkpoint's oldestActiveXID: 57914
Latest checkpoint's oldestMultiXid: 1
Latest checkpoint's oldestMulti's DB: 1
Latest checkpoint's oldestCommitTsXid:0
Latest checkpoint's newestCommitTsXid:0
Time of latest checkpoint: Wed 17 Jul 2019 02:27:07 PM HKT
Fake LSN counter for unlogged rels: 0/1
Minimum recovery ending location: 0/0
Min recovery ending loc's timeline: 0
Backup start location: 0/0
Backup end location: 0/0
End-of-backup record required: no
wal_level setting: replica
wal_log_hints setting: off
max_connections setting: 100
max_worker_processes setting: 8
max_prepared_xacts setting: 0
max_locks_per_xact setting: 64
track_commit_timestamp setting: off
Maximum data alignment: 8
Database block size: 8192
Blocks per segment of large relation: 1310720
WAL block size: 8192
Bytes per WAL segment: 16777216
Maximum length of identifiers: 64
Maximum columns in an index: 32
Maximum size of a TOAST chunk: 1996
Size of a large-object chunk: 2048
Date/time type storage: 64-bit integers
Float4 argument passing: by value
Float8 argument passing: by value
Data page checksum version: 0
Mock authentication nonce: ce6a83651b3b6ba8a8c8fcc8ee22ffb9c47d1aebaf3dae82462d23826c10f26f
[postgres@postgresdb ~]$
下面詳細介紹下各引數含義。

pg_control version number是控制檔案版本號。

Catalog version number 是系統表版本號,格式是yyyymmddN。記錄系統不相容性的改變。N是yyymmdd當天改變的次數。具體可以檢視原始碼檔案catversion.h。

Database system identifier 資料庫系統號 這個標識串是一個64bit的整數,其中包含了建立資料庫的時間戳和initdb時初始化的程序號,具體初始化方法可檢視原始碼檔案xlog.c。

建立時間可以通過to_timestamp轉換檢視到。

postgres=# SELECT to_timestamp(((6709564017377676696>>32) & (2^32 -1)::bigint));
to_timestamp 
------------------------
2019-07-04 06:15:08+08
Database cluster state 記錄例項的狀態。原始碼檔案中看到資料庫的幾種狀態,原始碼pg_control.h中可以看到:
starting up:表示資料庫正在啟動狀態。
shut down: 資料庫例項(非Standby)正常關閉後控制檔案中就是此狀態。
shut down in recovery:Standby例項正常關閉後控制檔案中就是此狀態。
shutting down:正常停庫時,先做checkpoint,開始做checkpoint時,會把狀態設定為此狀態,做完後把狀態設定為shut down。
in crash recovery:資料庫例項非異常停止後,重新啟動後,會先進行例項的恢復,在例項恢復時的狀態就是此狀態。
in archive recovery:Standby例項正常啟動後,就是此狀態。
in production:資料庫例項正常啟動後就是此狀態。Standby資料庫正常啟動後不是此狀態
Latest checkpoint location資料庫異常停止後再重新啟動時,需要做例項恢復,例項恢復的過程是從WAL日誌中,找到最後一次的checkpoint點,然後讀取這個點之後的WAL日誌,重新應用這些日誌,此過程稱為資料庫例項前滾,最後一次的checkpoint點的資訊記錄在Latest checkpont項中。
Latest checkpoint's REDO location 記錄資料庫日誌檔案上檢查點。
Latest checkpoint's REDO WAL file記錄WAL日誌名,目錄下pg_wal可以查到檔案。
Latest checkpoint's NextXID前面是新紀元值,冒號後面是下一個事務號,當前事務號最大值安全值可以在pg_xact目錄下通過檔名計算出來。 
Latest checkpoint's NextMultiXactId引數,可以通過pg_multixact/offsets檔名計算出來安全值。
Latest checkpoint's NextMultiOffset引數,當恢復控制檔案時可以通過pg_multixact/members資料夾下計算出此引數的安全值。 
Maximum length of identifiers是指一些資料庫物件名稱的最大長度,如表名、索引名的最大長度 Maximum columns in an index 表示一個索引最多多少列,目前為32個。 
Maximum size of a TOAST chunk是TOAST chunk的最大長度。TOAST是解決當列的內容太長,在一個數據塊中存不下時的一種行外儲存的方式。類似Oracle的行連結。
Data page checksum version是資料塊checksum的版本,預設為0,資料塊沒有使用checksum。執行initdb時加了-k引數,PG才會在資料塊上啟用checksum功能。
引數介紹到這裡,控制檔案各內容定義可以檢視原始檔pg_control.h。
PostgreSQL控制檔案重建
pg9.6前使用 pg_resetxlog,pg10之後使用pg_resetwal清理wal日誌或重置控制檔案中一些控制資訊。
命令詳細介紹可以檢視官方文件:
https://www.postgresql.org/docs/11/app-pgresetwal.html
[postgres@lsl-test1 ~]$ /u01/postgres/pgsql/bin/pg_resetwal -n -D /data/postgres/data
pg_resetwal: lock file "postmaster.pid" exists
Is a server running? If not, delete the lock file and try again.
[postgres@lsl-test1 ~]$ /u01/postgres/pgsql/bin/pg_resetwal --help
pg_resetwal resets the PostgreSQL write-ahead log.
Usage:
pg_resetwal [OPTION]... DATADIR
Options:
-c, --commit-timestamp-ids=XID,XID
set oldest and newest transactions bearing
commit timestamp (zero means no change)
[-D, --pgdata=]DATADIR data directory
-e, --epoch=XIDEPOCH set next transaction ID epoch
-f, --force force update to be done
-l, --next-wal-file=WALFILE set minimum starting location for new WAL
-m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID
-n, --dry-run no update, just show what would be done
-o, --next-oid=OID set next OID
-O, --multixact-offset=OFFSET set next multitransaction offset
-V, --version output version information, then exit
-x, --next-transaction-id=XID set next transaction ID
--wal-segsize=SIZE size of WAL segments, in megabytes
-?, --help show this help, then exit

下面看下命令各個引數具體含義:
-c引數有兩個引數值,一個最舊的事務號,一個最新的事務號。最舊的事務號的安全值,可以在pg_commit_ts目錄查詢最小的檔名;
最新事務ID的安全值,可以在pg_commit_ts目錄查詢最大的檔名。檔名都是16進位制。實際測試在11的版本pg_commit_ts目錄下未發現檔案。
[postgres@lsl-test1 data]$ cd /data/postgres/data/pg_commit_ts/
[postgres@lsl-test1 pg_commit_ts]$ ls -l

-e引數是設定事務號的新紀元(epoch),除了pg_resetwal設定的欄位之外,事務ID新紀元實際上並不儲存在資料庫的任何位置。您可能需要調整此值,

以確保Slony或者Skytools等複製系統能夠正確工作。如果是這樣的話,應該可以從下游複製資料庫的狀態獲得適當的值。

-l 引數通過指定下一個WAL段檔案的名稱,手動設定WAL啟動位置。該選項使用WAL檔名,而不是LSN。下一個段的名字應該大於當前存在pg_wal目錄下的任何WAL段檔名。

[postgres@lsl-test1 pg_commit_ts]$ cd ../pg_wal/
[postgres@lsl-test1 pg_wal]$ ls -l
total 933892
drwx------. 2 postgres postgres 4096 Jul 4 06:15 archive_status
-rw-------. 1 postgres postgres 16777216 Jul 17 10:49 000000010000005A000000FF
-rw-------. 1 postgres postgres 16777216 Jul 17 10:49 000000010000005B0000001D
-rw-------. 1 postgres postgres 16777216 Jul 17 10:49 000000010000005B00000026
-rw-------. 1 postgres postgres 16777216 Jul 17 10:49 000000010000005B00000028
-rw-------. 1 postgres postgres 16777216 Jul 17 10:50 000000010000005B00000025
-rw-------. 1 postgres postgres 16777216 Jul 17 10:51 000000010000005B00000003
-rw-------. 1 postgres postgres 16777216 Jul 17 10:52 000000010000005B00000004
-rw-------. 1 postgres postgres 16777216 Jul 17 10:52 000000010000005B0000002C
-rw-------. 1 postgres postgres 16777216 Jul 17 10:55 000000010000005B0000002D
-rw-------. 1 postgres postgres 16777216 Jul 17 14:27 000000010000005A000000F5