1. 程式人生 > >【PostgreSQL-9.6.3】程序及體系結構

【PostgreSQL-9.6.3】程序及體系結構

本文主要講述了PG的幾個主要程序,以及PG的核心架構。程序和體系結構詳見下圖:


從上面的體系結構圖可以看出來,PG使用經典的C/S架構,程序架構。在伺服器端有主程序、服務程序、子程序、共享記憶體以及檔案儲存幾大部分,下面著重講述伺服器端的程序部分:

1. Postmaster主程序和服務程序

當PG資料庫啟動時,首先會啟動Postmaster主程序。這個程序是PG資料庫的總控制程序,負責啟動和關閉資料庫例項。實際上Postmaster程序是一個指向postgres命令的連結,如下:

[[email protected] ~]$ 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