1. 程式人生 > 其它 >[USACO20FEB]Help Yourself P 題解

[USACO20FEB]Help Yourself P 題解

文章目錄
一、PostgreSQL程序分類
二、程序介紹
2.1 主程序postmaster
2.2 Logger系統日誌程序
2.3 BgWriter後臺寫程序
2.4 WalWriter預寫日誌程序
2.5 PgArch歸檔程序
2.6 AutoVacuum自動清理程序
2.7 PgStat統計資料收集程序
2.8 CheckPoint(檢查點)程序
一、PostgreSQL程序分類
在這裡插入圖片描述

主程序Postmaster
輔助子程序Logger(系統日誌)程序
輔助子程序BgWriter(後臺寫)程序
輔助子程序WalWriter(預寫日誌)程序
輔助子程序PgArch(歸檔)程序

輔助子程序AutoVacuum(系統自動清理)程序
輔助子程序PgStat(統計資訊收集)程序
輔助子程序CheckPoint(檢查點)程序
二、程序介紹
2.1 主程序postmaster
  主程序postmaster是資料庫例項的總控程序,負責啟停資料庫,同時會fork出一些輔助子程序,這些輔助子程序各自負責一部分功能;postgres為postmaster 的軟連結,pg_ctl就是封裝了postgres命令。

-rwxr-xr-x 1 postgres postgres 36M Sep 3 22:58 postgres
lrwxrwxrwx 1 postgres postgres 8 Sep 3 22:58 postmaster -> postgres

1
2
  使用者連線時,會先與postmaster程序建立連線,進行身份校驗,之後fork出服務子程序。pg_stat_activity表中PID就為這些連線程序的PID。

postgres=# select * from pg_stat_activity;
±[ RECORD 1 ]-----±--------------------------------+
| datid | |
| datname | |
| pid | 27436 |
| usesysid | 10 |
| usename | postgres |
| application_name | |
| client_addr | |

| client_hostname | |
| client_port | |
| backend_start | 2020-12-20 11:38:11.58027+08 |
| xact_start | |
| query_start | |
| state_change | |
| wait_event_type | Activity |
| wait_event | LogicalLauncherMain |
| state | |
| backend_xid | |
| backend_xmin | |
| query | |
| backend_type | logical replication launcher |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2.2 Logger系統日誌程序
  Logger系統日誌程序通過postmaster程序、服務程序和其餘輔助程序收集所有的stderr輸出,並記錄到日誌檔案中。相關引數如下:

logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%a.log'
log_truncate_on_rotation = on
log_rotation_age = 1d
log_rotation_size = 0

#log_destination:配置日誌輸出目標,根據不同的執行平臺會設定不同的值,Linux下預設為stderr。
#logging_collector:是否開啟日誌收集器,當設定為on時啟動日誌功能;否則,系統將不產生系統日誌輔助程序。
#log_directory:配置日誌輸出資料夾。
#log_filename:配置日誌檔名稱命名規則。
#log_rotation_size:配置日誌檔案大小,當前日誌檔案達到這個大小時會被關閉,然後建立一個新的檔案來作為當前日誌檔案。
1
2
3
4
5
6
7
8
9
10
11
12
2.3 BgWriter後臺寫程序
  BgWriter程序負責把共享記憶體中的髒頁寫到磁碟上。為了提高效能,我們可能並不需要每次進行持久化,如果重新整理頻率過快會導致頻繁的IO,如果重新整理頻率過慢會導致新查詢缺少記憶體空間;因此PostgreSQL通過以下SQL進行管理:

bgwriter_delay = 200ms # 10-10000ms between rounds
bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables
bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round
bgwriter_flush_after = 1024kB # 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_delaybgwriter_lru_maxpages8K=最大資料量
#bgwriter_flush_after:資料頁大小達到bgwriter_flush_after時觸發BgWriter,預設是512KB。
1
2
3
4
5
6
7
8
9
10
11
2.4 WalWriter預寫日誌程序
  預寫日誌可以保證資料的完整性;在修改資料之前,資料庫會將修改操作記錄到磁碟中。這樣就不必擔心資料未持久化到磁碟導致資料丟失。如果資料庫宕機,重啟後資料庫會讀取WAL日誌最後一部分重新執行,將資料庫恢復為宕機時的狀態。WAL日誌儲存在pg_xlog下,xlog檔案的預設大小為16MB,在xlog目錄下會儲存多個日誌,來保證未持久化的資料可以恢復,不需要的日誌會自動被覆蓋。相關引數如下:

#wal_level = minimal # minimal, replica, orlogical
# (changerequires restart)
#fsync = on # flush data to disk for crash safety
# (turningthis off can cause
# unrecoverable datacorruption)
#synchronous_commit =on # synchronization level;
# off, local,remote_write, remote_apply
,or on
#wal_sync_method =fsync # the default is thefirst option
# supported by theoperating 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-pagewrites
#wal_log_hints =off # also do full pagewrites of non-critical updates
#wal_buffers = -1 # min 32kB, -1 sets basedon shared_buffers
#wal_writer_delay = 200ms # 1-10000 milliseconds
#wal_writer_flush_after= 1MB # 0 disables
#commit_delay = 0 # range 0-100000, inmicroseconds
#commit_siblings =5 # range 1-1000

- 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= 0 # 0 disables #default is 256kB on linux, 0 otherwise
#checkpoint_warning =30s # 0 disables
wal_level:控制wal儲存的級別。wal_level決定有多少資訊被寫入到WAL中。預設值是最小的(minimal),其中只寫入從崩潰或立即關機中恢復的所需資訊。replica 增加 wal 歸檔資訊同時包括只讀伺服器需要的資訊。(9.6 中新增,將之前版本的 archive 和 hot_standby合併)
fsync:該引數直接控制日誌是否先寫入磁碟。預設值是ON(先寫入)。開啟該值時表明,更新資料寫入磁碟時系統必須等待WAL的寫入完成。可以配置該引數為OFF,更新資料寫入磁碟完全不用等待WAL的寫入完成,沒有了等待的時間,顯然接下來的工作能夠更早的去做,節省了時間,提高了效能。其直接隱患是無法保證在系統崩潰時最近的事務能夠得到恢復,也就無法保證相關資料的真實與正確性。
synchronous_commit:該引數表明是否等待WAL完成後才返回給使用者事務的狀態資訊。預設值是ON,表明必須等待WAL完成後才返回事務狀態資訊。配置OFF值能夠更快的反饋回事務狀態。因引數只是控制事務的狀態反饋,因此對於資料的一致性不存在風險。但事務的狀態資訊影響著資料庫的整個狀態。該引數可以靈活的配置,對於業務沒有嚴謹要求的事務可以配置為OFF,能夠為系統的效能帶來不小的提升。
wal_sync_method:WAL 寫入磁碟的控制方式,預設值是fsync。可選用值:open_datasync,fdatasync,fsync_writethrough,fsync,open_sync。一般採用預設值即可,對於裸裝置或檔案系統的可選配置,在實際的使用中所帶來的方便相對fsync很有限。
full_page_writes:引數表明是否將整個page寫入WAL。postgresql中資料處理過程中的資料只儲存在記憶體和WAL中,在記憶體中的整個page中包含更新提交和沒有提交的,如果不將整個page寫入WAL中,在介質恢復的時候WAL中記錄的資料不足以實現完整的恢復(說白了就是無法實現介質恢復時事務的回滾)。
wal_buffers:用於存放WAL資料的記憶體空間,最小32K。
wal_writer_delay: WAL writer程序的間歇時間。預設值是200ms。準確的配置應該根據自身系統的執行狀況。如果時間過長可能造成WAL buffer的記憶體不足;反之過小將會引起WAL的不斷的寫入,對磁碟的IO也是很大考驗。
wal_writer_flush_after wal write的位元組數超過配置的閾值(wal_writer_flush_after)時,觸發fsync,預設值為1MB,如果設定為0,關閉該特性(9.6版本新增的引數)
commit_delay:表示一個已經提交的資料在WAL buffer中存放的時間,單位ms,預設值是0,不用延遲。非0值表示可能存在多個事務的WAL同時寫入磁碟。如果設定為非0,表明了某個事務執行 commit後不會立即寫入WAL中,而仍存放在WAL buffer中,這樣對於後面的事務申請WAL buffer時非常不利,尤其是提交事務較多的高峰期,可能引起WAL buffer記憶體不足。如果記憶體足夠大,可以儘量延長該引數值,能夠使資料集中寫入這樣降低了系統的IO,提高了效能。同樣如果此時崩潰資料面臨著丟失的危險。
commit_siblings該引數還決定了commit_delay的有效性。系統預設值是5。表示當一個事務發出提交請求,此時資料庫中正在執行的事務數量大於5,則該事務將等待一段時間(commit_delay的值),反之,該事務則直接寫入WAL。
min_wal_size :最小的wal 空間
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2.5 PgArch歸檔程序
  WAL日誌被迴圈使用,老的日誌會被覆蓋;PgArch程序會在日誌被覆蓋前備份出來。結合全備資料加上之後的WAL日誌即可把資料庫前滾到全量後的任意時間點。相關引數:

archive_mode = on # enables archiving; off, on, or always
#archive_command = ‘’ # command to use to archive a logfile segment
# placeholders: %p = path of file to archive
# e.g. ‘test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f’
#archive_timeout = 0 # force a logfile segment switch after this

#archive_mode:表示是否進行歸檔操作,可選擇為off(關閉)、on(啟動)和always(總是開啟),預設值為off(關閉)。
#archive_command:由管理員設定的用於歸檔WAL日誌的命令。在用於歸檔的命令中,預定義變數“%p”用來指代需要歸檔的WAL全路徑檔名,“%f”表示不帶路徑的檔名(這裡的路徑都是相對於當前工作目錄的路徑)。每個WAL段檔案歸檔時將呼叫archive_command所指定的命令。當歸檔命令返回0時,PostgreSQL就會認為檔案被成功歸檔,然後就會刪除或迴圈使用該WAL段檔案。否則,如果返回一個非零值,PostgreSQL會認為檔案沒有被成功歸檔,便會週期性地重試直到成功。
#archive_timeout:表示歸檔週期,在超過該引數設定的時間時強制切換WAL段,預設值為0(表示禁用該功能)。
1
2
3
4
5
6
7
8
9
2.6 AutoVacuum自動清理程序
  在PostgreSQL中,對資料進行UPDATE或者DELETE操作後,資料庫不會立即刪除舊版本的資料,而是標記為刪除狀態。當事務提交後,舊版本的資料已經沒有價值了,資料庫需要清理垃圾資料騰出空間,而清理工作就是AutoVacuum程序進行的。相關引數如下:

#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem
#autovacuum = on # Enable autovacuum subprocess? ‘on’
#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and
#autovacuum_max_workers = 3 # max number of autovacuum subprocesses
#autovacuum_naptime = 1min # time between autovacuum runs
#autovacuum_vacuum_threshold = 50 # min number of row updates before
#autovacuum_analyze_threshold = 50 # min number of row updates before
#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
#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age
#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for
# autovacuum, in milliseconds;
#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for
# autovacuum, -1 means use

#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, 表示使用autovacuum_vacuum_cost_delay 值,預設值為 20 ms。
#autovacuum_vacuum_cost_limit:這個值為 autovacuum 程序的評估閥值, 預設為 -1, 表示使用 "vacuum_cost_limit " 值,如果在執行autovacuum 程序期間評估的cost 超過 autovacuum_vacuum_cost_limit, 則 autovacuum 程序則會休眠。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2.7 PgStat統計資料收集程序
  PgStat程序是PostgreSQL資料庫的統計資訊收集器,用來收集資料庫執行期間的統計資訊,如表的增刪改次數,資料塊的個數,索引的變化等等。收集統計資訊主要是為了讓優化器做出正確的判斷,選擇最佳的執行計劃。如下

#track_commit_timestamp = off # collect timestamp of transaction commit
#track_activities = on
#track_counts = on
#track_io_timing = off
#track_functions = none # none, pl, all
#track_activity_query_size = 1024 # (change requires restart)
# requires track_counts to also be on.

#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檔案或者伺服器命令列中修改。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2.8 CheckPoint(檢查點)程序
  檢查點是系統設定的事務序列點,設定檢查點保證檢查點前的日誌資訊刷到磁碟中。相關引數如下:

#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

#checkpoint_timeout :生成檢查點的最大的間隔時間。
#checkpoint_completion_target 引數表示checkpoint的完成目標,系統預設值是0.5,也就是說每個checkpoint需要在checkpoints間隔時間的50%內完成。
PostgreSQL 9.5 廢棄了checkpoint_segments 引數, 並引入max_wal_size 和 min_wal_size 引數,