原文鏈接:https://cloud.tencent.com/developer/article/1469101
墨墨導讀:本文主要從日志文件、參數文件、控制文件、數據文件、redo日志(WAL)、后台進程這六個方面來討論PostgreSQL的結構。
7月16日晚20:30-21:30,雲和恩墨大講堂邀請到了雲和恩墨東區技術顧問成暘老師為我們分享Oracle中統計信息的相關知識。成老師將帶我們由點到面,系統地了解統計信息。線上直播報名鏈接:https://cs.enmotech.com/event/53(或者點擊“閱讀原文”立即報名)
一、引言
PostgreSQL是最像Oracle的開源數據庫,我們可以拿MySQL和Oracle來比較學習它的體系結構,比較容易理解。本文會討論pg的如下結構:
- 日志文件
- 參數文件
- 控制文件
- 數據文件
- redo日志(WAL)
- 后台進程
PostgreSQL的主要結構如下:

二、日志文件
2.1 日志文件種類
1)$PGDATA/log 運行日志(pg10之前為$PGDATA/pg_log) 2)$PGDATA/pg_wal 重做日志(pg10之前為$PGDATA/pg_xlog) 3)$PGDATA/pg_xact 事務提交日志(pg10之前為$PGDATA/pg_clog) 4)服務器日志,可以在啟動的時候指定,比如pg_ctl start -l ./alert.log
2.2 運行日志
2.2.1 運行日志參數
運行日志主要相關的參數如下,默認沒有開啟的話沒有log目錄,開啟后會自動生成。
參數 |
可選值/說明 |
---|---|
log_destination = 'csvlog' |
# stderr, csvlog, syslog, and eventlog ,csvlog requires logging_collector to be on一般選擇這個,可以將csv日志導入數據庫中查看 |
logging_collector=on |
# Enable capturing of stderr and csvlog into log files選scv格式的日志必須設置這個參數on,修改需要重啟 |
log_directory = 'log' |
日志輸出目錄 |
log_filename='postgresql-%Y-%m-%d_%H%M%S.log |
日志文件名字格式 |
log_file_mode=0600 |
# creation mode for log files 日志文件權限 |
log_truncate_on_rotation = on |
設置重用日志 |
log_rotation_age = 1d |
多長時間重用日志 |
log_rotation_size = 10MB |
日志達到多大重用 |
log_min_messages=warning |
#debug5,debug4,debug3,debug2,debug1,info,notice,warning,error,log,fatal,panic |
log_min_duration_statement = 60 |
慢sql記錄(超過多長時間的sql) |
log_checkpoints = on |
記錄checkpoint操作 |
log_connections = on |
記錄會話連接操作 |
log_disconnections = on |
記錄會話斷開操作 |
log_duration = on |
記錄sql執行時間 |
log_lock_waits=on |
# log lock waits >= deadlock_timeout 記錄時間長的阻塞 |
log_statement='ddl' |
# none, ddl, mod, all 記錄ddl |
2.2.2 csv日志入庫
CREATE TABLE pg_log
( log_time timestamp(3) with time zone, user_name text, database_name text, process_id integer, connection_from text, session_id text, session_line_num bigint, command_tag text, session_start_time timestamp with time zone, virtual_transaction_id text, transaction_id bigint, error_severity text, sql_state_code text, message text, detail text, hint text, internal_query text, internal_query_pos integer, context text, query text, query_pos integer, location text, application_name text, PRIMARY KEY (session_id, session_line_num) ); < pg@cs-db /oracle/soft/data/log 16:12 --> pwd /oracle/soft/data/log < pg@cs-db /oracle/soft/data/log 16:12 --> < pg@cs-db /oracle/soft/data/log 16:12 --> ls -rtl total 8 -rw------- 1 pg pg 168 Nov 10 16:08 postgresql-16.log -rw------- 1 pg pg 502 Nov 10 16:08 postgresql-16.csv < pg@cs-db /oracle/soft/data/log 16:12 --> pwd /oracle/soft/data/log < pg@cs-db /oracle/soft/data/log 16:12 --> psql psql (11beta3) Type "help" for help. li=# copy pg_log from '/oracle/soft/data/log/postgresql-16.csv' with csv; COPY 3 li=#
這樣就可以用sql來查看了。
2.3 pg_wal 見六
2.4 事務日志pg_xact
pg_xact是事務提交日志,記錄了事務的元數據。默認開啟。內容一般不能直接讀。
2.5 服務器日志
如果用pg_ctl啟動的時候沒有指定-l參數來指定服務器日志,錯誤可能會輸出到cmd前台。服務器日志記錄了數據庫的重要信息,一個服務器日志的內容如下:
[postgres@whf307 log]$ more alert.log 2019-05-16 14:11:36.718 CST [14660] LOG: listening on IPv4 address "0.0.0.0", port 5432 2019-05-16 14:11:36.718 CST [14660] LOG: listening on IPv6 address "::", port 5432 2019-05-16 14:11:36.720 CST [14660] LOG: listening on Unix socket "/data/.s.PGSQL.5432" 2019-05-16 14:11:36.729 CST [14660] LOG: redirecting log output to logging collector process 2019-05-16 14:11:36.729 CST [14660] HINT: Future log output will appear in directory "log".
lsof或許可以過濾出在寫的日志文件
lsof -c postgres| grep REG | grep -v /usr | grep -v /dev | grep -v /SYS
三、參數文件
3.1 postgresql.conf
pg的主要參數文件,有很詳細的說明和注釋,和Oracle的pfile,MySQL的my.cnf類似。默認在$PGDATA下。很多參數修改后都需要重啟。9.6之后支持了alter system來修改,修改后的會報存在$PGDATA/postgresql.auto.conf下,可以reload或者 restart來使之生效。
主要的參數如下:
參數 |
可選值/說明 |
---|---|
listen_addresses='*' |
監聽客戶端的地址,默認是本地的,需要修改為*或者0.0.0.0 |
port = 5432 |
pg端口,默認是5432 |
max_connections = 2000 |
最大連接數,默認100 |
unix_socket_directories |
socket文件的位置,默認在/tmp下面 |
shared_buffers |
數據緩存區,類型Oracle的buffer cache。建議值 1/4主機內存 |
maintenance_work_mem |
維護工作內存,用於vacuum,create index,reindex等。建議值(1/4 主機內存)/autovacuum_max_workers |
max_worker_processes |
總worker數 |
max_parallel_workers_per_gather |
單條QUERY中,每個node最多允許開啟的並行計算WORKER數 |
wal_level |
wal級別,11 默認是replica了 |
wal_buffers |
類似Oracle的log buffer |
checkpoint_timeout |
checkpoint時間間隔 |
max_wal_size |
控制wal的數量 |
min_wal_size |
控制wal的數量 |
archive_command |
開歸檔,比如 'test ! -f /disk1/digoal/arch/%f && cp %p /disk1/digoal/arch/%f' |
autovacuum |
開啟自動vacuum |
3.2 pg_hba.conf
這個是黑白名單的設置。文件里有詳細的參數說明,默認參數如下:
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust # IPv6 local connections: host all all ::1/128 trust # Allow replication connections from localhost, by a user with the # replication privilege. local replication all trust host replication all 127.0.0.1/32 trust host replication all ::1/128 trust # local DATABASE USER METHOD [OPTIONS] # host DATABASE USER ADDRESS METHOD [OPTIONS] # hostssl DATABASE USER ADDRESS METHOD [OPTIONS] # hostnossl DATABASE USER ADDRESS METHOD [OPTIONS]
type 列有local,host,hostssl,hostnossl四種。local是本地認證 database 可以是all,或者指定的數據庫 user列可以是all,或者具體的用戶 address 可以是ip或者網段 method比較重要,有"trust", "reject", "md5", "password", "scram-sha-256", # "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert"這么多可選。trust是免密登錄;reject是黑名單拒絕;md5是加密的密碼;password是沒有加密的密碼;ident是Linux下PostgreSQL默認的local認證方式,凡是能正確登錄服務器的操作系統用戶(注:不是數據庫用戶)就能使用本用戶映射的數據庫用戶不需密碼登錄數據庫
3.3 pg_ident.conf
pg_ident.con是用戶映射配置文件。結合pg_hba.connf中,method為ident可以用特定的操作系統用戶和指定的數據庫用戶登錄數據庫。如下: pg_ident.conf如下:
# MAPNAME SYSTEM-USERNAME PG-USERNAME mapll test sa
pg_hba.conf如下:
# TYPE DATABASE USER CIDR-ADDRESS METHOD
local all all ident map=mapll
四、控制文件
4.1 控制文件位置
$PGDATA/global/pg_control
控制文件在數據庫目錄的global目錄下。控制文件記錄了數據庫的重要信息。
4.2 查看控制文件
pg_controldata可以查看控制文件的內容
[postgres@whf307 global]$ pg_controldata $PGDATA pg_control version number: 1100 Catalog version number: 201809051 Database system identifier: 6684270596680436587 #dbid Database cluster state: in production # primary pg_control last modified: Thu 16 May 2019 02:26:37 PM CST Latest checkpoint location: 0/48812A0 Latest checkpoint's REDO location: 0/4881268 #redo 位置 Latest checkpoint's REDO WAL file: 000000010000000000000001 #wal文件號 Latest checkpoint's TimeLineID: 1 Latest checkpoint's PrevTimeLineID: 1 Latest checkpoint's full_page_writes: on Latest checkpoint's NextXID: 0:572 #下一個事務id Latest checkpoint's NextOID: 16388 #下一個OID 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: 572 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: Thu 16 May 2019 02:26:36 PM CST 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級別 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: 131072 WAL block size: 8192 #wal 數據塊大小 Bytes per WAL segment: 67108864 #單個wal大小 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: 1 Mock authentication nonce: f01b78f5a88882f2f1811bbbc637cc4766d57d39831139a6b3e881d76272d892 [postgres@whf307 global]$
controlfile記錄了數據庫運行的一些信息,比如數據庫id,是否open,wal的位置,checkpoint的位置,等等。controlfile是很重要的文件,數據庫部署和調整。
五、數據文件
5.1 page
pg中,每個索引和表都是一個單獨的文件,pg中叫做page。默認是每個大於1G的page會被分割pg_class.relfilenode.1這樣的文件。page的大小在initdb的時候指定(--with-segsize)。
5.2 page物理位置
page的物理位置在$PGDATA/BASE/DATABASE_OID/PG_CLASS.RELFILENODE
mydb=# select relfilenode from pg_class where relname='t1'; relfilenode ------------- 16385 (1 row) mydb=# select pg_relation_filepath('t1'); pg_relation_filepath ---------------------- base/16384/16385 (1 row) mydb=# show data_directory; data_directory ---------------- /data (1 row) mydb=# \q [postgres@whf307 global]$ ls -rtl /data/base/16384/16385 -rw------- 1 postgres postgres 8192 May 16 14:26 /data/base/16384/16385 [postgres@whf307 global]$
需要注意的是,pg_class.relfilenode類似dba_objects.data_object_id,truncate表之后relfilenode會變。對應的物理文件名字也會變。
六、WAL日志
6.1 wal位置
wal在$PGDATA/pg_wal下。10之前為pg_xlog
[postgres@whf307 data]$ cd pg_wal [postgres@whf307 pg_wal]$ [postgres@whf307 pg_wal]$ ls -rtl total 65536 drwx------ 2 postgres postgres 6 Apr 27 02:23 archive_status -rw------- 1 postgres postgres 67108864 May 16 15:56 000000010000000000000001 [postgres@whf307 pg_wal]$
6.2 wal命名格式
文件名稱為16進制的24個字符組成,每8個字符一組,每組的意義如下:
00000001 00000000 00000001 -------- -------- -------- 時間線 邏輯id 物理id
6.3 查看wal時間
postgres=# select pg_walfile_name(pg_current_wal_lsn()); pg_walfile_name -------------------------- 000000010000000000000001 (1 row) postgres=# postgres=# select * from pg_ls_waldir() order by modification asc; name | size | modification --------------------------+----------+------------------------ 000000010000000000000001 | 67108864 | 2019-05-16 15:56:32+08 (1 row) postgres=#
6.4 切換wal
postgres=# select pg_switch_wal(); pg_switch_wal --------------- 0/48814E8 (1 row) postgres=# select * from pg_ls_waldir() order by modification asc; name | size | modification --------------------------+----------+------------------------ 000000010000000000000001 | 67108864 | 2019-05-16 16:12:29+08 000000010000000000000002 | 67108864 | 2019-05-16 16:12:30+08 (2 rows)
6.5 pg_waldump查看wal

pg_waldump可以查看wal的具體內容
七、后台進程
postgres 15309 1 0 15:51 pts/0 00:00:00 /pg/pg11/bin/postgres postgres 15310 15309 0 15:51 ? 00:00:00 postgres: logger postgres 15312 15309 0 15:51 ? 00:00:00 postgres: checkpointer postgres 15313 15309 0 15:51 ? 00:00:00 postgres: background writer postgres 15314 15309 0 15:51 ? 00:00:00 postgres: walwriter postgres 15315 15309 0 15:51 ? 00:00:00 postgres: autovacuum launcher postgres 15316 15309 0 15:51 ? 00:00:00 postgres: stats collector postgres 15317 15309 0 15:51 ? 00:00:00 postgres: logical replication launcher
- postgres 主進程
- logger 日志進程
- checkpointer checkpoint進程
- background writer 數據文件寫進程
- walwriter wal寫進程
- autovacuum launcher autovacuum進程
- stats collector 統計信息收集進程