本文主要講述了PG的幾個主要進程,以及PG的核心架構。進程和體繫結構詳見下圖: 從上面的體繫結構圖可以看出來,PG使用經典的C/S架構,進程架構。在伺服器端有主進程、服務進程、子進程、共用記憶體以及文件存儲幾大部分,下麵著重講述伺服器端的進程部分: 1. Postmaster主進程和服務進程 當PG數 ...
本文主要講述了PG的幾個主要進程,以及PG的核心架構。進程和體繫結構詳見下圖:
從上面的體繫結構圖可以看出來,PG使用經典的C/S架構,進程架構。在伺服器端有主進程、服務進程、子進程、共用記憶體以及文件存儲幾大部分,下麵著重講述伺服器端的進程部分:
1. Postmaster主進程和服務進程
當PG資料庫啟動時,首先會啟動Postmaster主進程。這個進程是PG資料庫的總控制進程,負責啟動和關閉資料庫實例。實際上Postmaster進程是一個指向postgres命令的鏈接,如下:
[postgres@drz ~]$ ll /opt/postgresql/bin/postmaster
lrwxrwxrwx. 1 postgres dba 8 Aug 7 23:33 /opt/postgresql/bin/postmaster -> postgres
當用戶和PG資料庫建立連接時,要先與Postmaster進程建立連接,此時客戶端進程會發送身份驗證消息給Postmaster主進程,Postmaster主進程根據消息進行身份驗證,驗證通過後,Postmaster主進程會fork出一個會話服務進程為這個用戶連接服務。可以通過pg_stat_activity表來查看服務進程的pid,如下:
test=# select pid,usename,client_addr,client_port from pg_stat_activity;
pid | usename | client_addr | client_port
-------+----------+-------------+-------------
26402 | postgres | | -1
(1 row)
2. BgWriter(後臺寫)進程
BgWriter進程是把共用記憶體中的臟頁寫到磁碟上的進程。它的作用有兩個:一是定期把臟數據從記憶體緩衝區刷出到磁碟中,減少查詢時的阻塞;二是PG在定期作檢查點時需要把所有臟頁寫出到磁碟,通過BgWriter預先寫出一些臟頁,可以減少設置檢查點(CheckPoint,資料庫恢復技術的一種)時要進行的IO操作,使系統的IO負載趨向平穩。BgWriter是PostgreSQL 8.0以後新加的特性,它的機制可以通過postgresql.conf文件中以"bgwriter_"開頭配置參數來控制:
# - Background Writer -
#bgwriter_delay = 200ms # 10-10000ms between rounds
#bgwriter_lru_maxpages = 100 # 0-1000 max buffers written/round
#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round
#bgwriter_flush_after = 512kB # measured in pages, 0 disables
bgwriter_delay:
backgroud writer進程連續兩次flush數據之間的時間的間隔。預設值是200,單位是毫秒。
bgwriter_lru_maxpages:
backgroud writer進程每次寫的最多數據量,預設值是100,單位buffers。如果臟數據量小於該數值時,寫操作全部由backgroud writer進程完成;反之,大於該值時,大於的部分將有server process進程完成。設置該值為0時表示禁用backgroud writer寫進程,完全有server process來完成;配置為-1時表示所有臟數據都由backgroud writer來完成。(這裡不包括checkpoint操作)
bgwriter_lru_multiplier:
這個參數表示每次往磁碟寫數據塊的數量,當然該值必須小於bgwriter_lru_maxpages。設置太小時需要寫入的臟數據量大於每次寫入的數據量,這樣剩餘需要寫入磁碟的工作需要server process進程來完成,將會降低性能;值配置太大說明寫入的臟數據量多於當時所需buffer的數量,方便了後面再次申請buffer工作,同時可能出現IO的浪費。該參數的預設值是2.0。
bgwriter的最大數據量計算方式:
1000/bgwriter_delay*bgwriter_lru_maxpages*8K=最大數據量
bgwriter_flush_after:
數據頁大小達到bgwriter_flush_after時觸發BgWriter,預設是512KB。
3. PgArch(歸檔)進程
類似於Oracle資料庫的ARCH歸檔進程,不同的是ARCH是吧redo log進行歸檔,PgArch是把WAL日誌進行歸檔。再深入點,WAL日誌會被迴圈使用,也就是說,過去的WAL日誌會被新產生的日誌覆蓋,PgArch進程就是為了在覆蓋前把WAL日誌備份出來。歸檔日誌的作用是為了資料庫能夠使用全量備份和備份後產生的歸檔日誌,從而讓資料庫回到過去的任一時間點。PG從8.X版本開始提供的PITR(Point-In-Time-Recovery)技術,就是運用的歸檔日誌。
PgArch進程通過postgresql.conf文件中的如下參數進行配置:
# - Archiving -
#archive_mode = off # enables archiving; off, on, or always
# (change requires restart)
#archive_command = '' # command to use to archive a logfile segment
# placeholders: %p = path of file to archive
# %f = file name only
# e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
#archive_timeout = 0 # force a logfile segment switch after this
# number of seconds; 0 disables
archive_mode:
表示是否進行歸檔操作,可選擇為off(關閉)、on(啟動)和always(總是開啟),預設值為off(關閉)。
archive_command:
由管理員設置的用於歸檔WAL日誌的命令。在用於歸檔的命令中,預定義變數“%p”用來指代需要歸檔的WAL全路徑文件名,“%f”表示不帶路徑的文件名(這裡的路徑都是相對於當前工作目錄的路徑)。每個WAL段文件歸檔時將調用archive_command所指定的命令。當歸檔命令返回0時,PostgreSQL就會認為文件被成功歸檔,然後就會刪除或迴圈使用該WAL段文件。否則,如果返回一個非零值,PostgreSQL會認為文件沒有被成功歸檔,便會周期性地重試直到成功。
archive_timeout:
表示歸檔周期,在超過該參數設定的時間時強制切換WAL段,預設值為0(表示禁用該功能)。
4. PgStat(統計數據收集)進程
PgStat進程是PostgreSQL資料庫的統計信息收集器,用來收集資料庫運行期間的統計信息,如表的增刪改次數,數據塊的個數,索引的變化等等。收集統計信息主要是為了讓優化器做出正確的判斷,選擇最佳的執行計劃。postgresql.conf文件中與PgStat進程相關的參數,如下:
#------------------------------------------------------------------------------
# RUNTIME STATISTICS
#------------------------------------------------------------------------------
# - Query/Index Statistics Collector -
#track_activities = on
#track_counts = on
#track_io_timing = off
#track_functions = none # none, pl, all
#track_activity_query_size = 1024 # (change requires restart)
#stats_temp_directory = 'pg_stat_tmp'
track_activities:表示是否對會話中當前執行的命令開啟統計信息收集功能,該參數只對超級用戶和會話所有者可見,預設值為on(開啟)。
track_counts:表示是否對資料庫活動開啟統計信息收集功能,由於在AutoVacuum自動清理進程中選擇清理的資料庫時,需要資料庫的統計信息,因此該參數預設值為on。
track_io_timing:定時調用數據塊I/O,預設是off,因為設置為開啟狀態會反覆的調用資料庫時間,這給資料庫增加了很多開銷。只有超級用戶可以設置
track_functions:表示是否開啟函數的調用次數和調用耗時統計。
track_activity_query_size:設置用於跟蹤每一個活動會話的當前執行命令的位元組數,預設值為1024,只能在資料庫啟動後設置。
stats_temp_directory:統計信息的臨時存儲路徑。路徑可以是相對路徑或者絕對路徑,參數預設為pg_stat_tmp,設置此參數可以減少資料庫的物理I/O,提高性能。此參數只能在postgresql.conf文件或者伺服器命令行中修改。
5. AutoVacuum(自動清理)進程
在PG資料庫中,對數據進行UPDATE或者DELETE操作後,資料庫不會立即刪除舊版本的數據,而是標記為刪除狀態。這是因為PG資料庫具有多版本的機制,如果這些舊版本的數據正在被另外的事務打開,那麼暫時保留他們是很有必要的。當事務提交後,舊版本的數據已經沒有價值了,資料庫需要清理垃圾數據騰出空間,而清理工作就是AutoVacuum進程進行的。postgresql.conf文件中與AutoVacuum進程相關的參數有:
#------------------------------------------------------------------------------
# AUTOVACUUM PARAMETERS
#------------------------------------------------------------------------------
#autovacuum = on # Enable autovacuum subprocess? 'on'
# requires track_counts to also be on.
#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and
# their durations, > 0 logs only
# actions running at least this number
# of milliseconds.
#autovacuum_max_workers = 3 # max number of autovacuum subprocesses
# (change requires restart)
#autovacuum_naptime = 1min # time between autovacuum runs
#autovacuum_vacuum_threshold = 50 # min number of row updates before
# vacuum
#autovacuum_analyze_threshold = 50 # min number of row updates before
# analyze
#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum
#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze
#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum
# (change requires restart)
#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age
# before forced vacuum
# (change requires restart)
#autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for
# autovacuum, in milliseconds;
# -1 means use vacuum_cost_delay
#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for
# autovacuum, -1 means use
# vacuum_cost_limit
autovacuum:是否啟動系統自動清理功能,預設值為on。
log_autovacuum_min_duration:這個參數用來記錄 autovacuum 的執行時間,當 autovaccum 的執行時間超過 log_autovacuum_min_duration參數設置時,則autovacuum信息記錄到日誌里,預設為 "-1", 表示不記錄。
autovacuum_max_workers:設置系統自動清理工作進程的最大數量。
autovacuum_naptime:設置兩次系統自動清理操作之間的間隔時間。
autovacuum_vacuum_threshold和autovacuum_analyze_threshold:設置當表上被更新的元組數的閾值超過這些閾值時分別需要執行vacuum和analyze。
autovacuum_vacuum_scale_factor和autovacuum_analyze_scale_factor:設置表大小的縮放繫數。
autovacuum_freeze_max_age:設置需要強制對資料庫進行清理的XID上限值。
autovacuum_vacuum_cost_delay:當autovacuum進程即將執行時,對 vacuum 執行 cost 進行評估,如果超過 autovacuum_vacuum_cost_limit設置值時,則延遲,這個延遲的時間即為 autovacuum_vacuum_cost_delay。如果值為 -1, 表示使用 vacuum_cost_delay 值,預設值為 20 ms。
autovacuum_vacuum_cost_limit:這個值為 autovacuum 進程的評估閥值, 預設為 -1, 表示使用 "vacuum_cost_limit " 值,如果在執行 autovacuum 進程期間評估的cost 超過 autovacuum_vacuum_cost_limit, 則 autovacuum 進程則會休眠。
6. WalWriter(預寫式日誌寫)進程
預寫式日誌WAL(Write Ahead Log,也稱為Xlog)的中心思想是對數據文件的修改必須是只能發生在這些修改已經記錄到日誌之後,也就是先寫日誌後寫數據(日誌先行)。使用這種機制可以避免數據頻繁的寫入磁碟,可以減少磁碟I/O。資料庫在宕機重啟後可以運用這些WAL日誌來恢複數據庫。postgresql.conf文件中與WalWriter進程相關的參數如下:
#------------------------------------------------------------------------------
# WRITE AHEAD LOG
#------------------------------------------------------------------------------
# - Settings -
#wal_level = minimal # minimal, replica, or logical
# (change requires restart)
#fsync = on # flush data to disk for crash safety
# (turning this off can cause
# unrecoverable data corruption)
#synchronous_commit = on # synchronization level;
# off, local, remote_write, remote_apply, or on
#wal_sync_method = fsync # the default is the first option
# supported by the operating system:
# open_datasync
# fdatasync (default on Linux)
# fsync
# fsync_writethrough
# open_sync
#full_page_writes = on # recover from partial page writes
#wal_compression = off # enable compression of full-page writes
#wal_log_hints = off # also do full page writes of non-critical updates
# (change requires restart)
#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers
# (change requires restart)
#wal_writer_delay = 200ms # 1-10000 milliseconds
#wal_writer_flush_after = 1MB # measured in pages, 0 disables
#commit_delay = 0 # range 0-100000, in microseconds
#commit_siblings = 5 # range 1-1000
wal_level:控制wal存儲的級別。wal_level決定有多少信息被寫入到WAL中。 預設值是最小的(minimal),其中只寫入從崩潰或立即關機中恢復的所需信息。replica 增加 wal 歸檔信息 同時包括 只讀伺服器需要的信息。(9.6 中新增,將之前版本的 archive 和 hot_standby 合併)
logical 主要用於logical decoding 場景
fsync:該參數直接控制日誌是否先寫入磁碟。預設值是ON(先寫入),表示更新數據寫入磁碟時系統必須等待WAL的寫入完成。可以配置該參數為OFF,表示更新數據寫入磁碟完全不用等待WAL的寫入完成。
synchronous_commit:參數配置是否等待WAL完成後才返回給用戶事務的狀態信息。預設值是ON,表明必須等待WAL完成後才返回事務狀態信息;配置成OFF能夠更快地反饋回事務狀態。
wal_sync_method:WAL寫入磁碟的控制方式,預設值是fsync,可選用值包括open_datasync、fdatasync、fsync_writethrough、fsync、open_sync。open_datasync和open_sync分別表示在打開WAL文件時使用O_DSYNC和O_SYNC標誌;fdatasync和fsync分別表示在每次提交時調用fdatasync和fsync函數進行數據寫入,兩個函數都是把操作系統的磁碟緩存寫回磁碟,但前者只寫入文件的數據部分,而後者還會同步更新文件的屬性;fsync_writethrough表示在每次提交並寫回磁碟會保證操作系統磁碟緩存和記憶體中的內容一致。
full_page_writes:表明是否將整個page寫入WAL。
wal_buffers:用於存放WAL數據的記憶體空間大小,系統預設值是64K,該參數還受wal_writer_delay、commit_delay兩個參數的影響。
wal_writer_delay:WalWriter進程的寫間隔時間,預設值是200毫秒,如果時間過長可能造成WAL緩衝區的記憶體不足;時間過短將會引起WAL的不斷寫入,增加磁碟I/O負擔。
wal_writer_flush_after:
commit_delay:表示一個已經提交的數據在WAL緩衝區中存放的時間,預設值是0毫秒,表示不用延遲;設置為非0值時事務執行commit後不會立即寫入WAL中,而仍存放在WAL緩衝區中,等待WalWriter進程周期性地寫入磁碟。
commit_siblings:表示當一個事務發出提交請求時,如果資料庫中正在執行的事務數量大於commit_siblings值,則該事務將等待一段時間(commit_delay的值);否則該事務則直接寫入WAL。系統預設值是5,該參數還決定了commit_delay的有效性。
wal_writer_flush_after:當臟數據超過閾值時,會被刷出到磁碟。
7. CheckPoint(檢查點)進程
檢查點是系統設置的事務序列點,設置檢查點保證檢查點前的日誌信息刷到磁碟中。postgresql.conf文件中與之相關的參數有:
# - Checkpoints -
#checkpoint_timeout = 5min # range 30s-1d
#max_wal_size = 1GB
#min_wal_size = 80MB
#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0
#checkpoint_flush_after = 256kB # measured in pages, 0 disables
#checkpoint_warning = 30s # 0 disables
The End!
2017-08-31