首頁>技術>

wal日誌即write ahead log預寫式日誌,簡稱wal日誌。wal日誌可以說是PostgreSQL中十分重要的部分,相當於oracle中的redo日誌。

當資料庫中資料發生變更時:

change發生時:先要將變更後內容計入wal buffer中,再將變更後的資料寫入data buffer;

commit發生時:wal buffer中資料重新整理到磁碟;

checkpoint發生時:將所有data buffer重新整理的磁碟。

可以想象,如果沒有wal日誌,那麼資料庫中將會發生什麼?

首先,當我們在資料庫中更新資料時,如果沒有wal日誌,那麼每次更新都會將資料刷到磁碟上,並且這個動作是隨機i/o,效能可想而知。並且沒有wal日誌,關係型資料庫中事務的ACID如何保證呢?

因此wal日誌重要性可想而知。其中心思想就是:先寫入日誌檔案,再寫入資料。

說到checkpoint,我們再來看看哪些情況會觸發資料庫的checkpoing:

1.手動執行CHECKPOINT命令;

2.執行需要檢查點的命令(例如pg_start_backup 或pg_ctl stop|restart等等);

3.達到檢查點配置時間(checkpoint_timeout);

4.max_wal_size已滿。

其中1和2兩點都和資料庫的配置無關,我們暫時先不看,這裡先介紹下checkpoint_timeout和max_wal_size兩個引數。

checkpoint_timeout:

自動 WAL 檢查點之間的最長時間,以秒計。合理的範圍在 30 秒到 1 天之間。預設是 5 分鐘(5min)。增加這個引數的值會增加崩潰恢復所需的時間。

bill@bill=>show checkpoint_timeout ;

checkpoint_timeout

--------------------

30min

(1 row)

1

2

3

4

5

1

2

3

4

5

max_wal_size:

在自動 WAL檢查點之間允許WAL 增長到的最大尺寸。這是一個軟限制,在特殊的情況 下 WAL 尺寸可能會超過max_wal_size, 例如在重度負荷下、archive_command失敗或者高的 wal_keep_segments設定。預設為 1 GB。增加這個引數可能導致崩潰恢復所需的時間。

bill@bill=>show max_wal_size ;

max_wal_size

--------------

2GB

(1 row)

1

2

3

4

5

1

2

3

4

5

和max_wal_size相對應的還有個min_wal_size,這裡簡單介紹下:

可能對oracle熟悉的人會覺得wal日誌和redo還是有些不同,沒錯,oracle中redo是固定幾個redo日誌檔案,然後輪著切換去寫入,因此我們常常會在io高的資料庫中看到redo切換相關的等待事件。

而在pg中wal日誌是動態切換,從pg9.6開始採用這種模式。和oracle不同的是,pg中這種動態wal切換步驟是這樣的:單個wal日誌寫滿(預設大小16MB,編譯資料庫時指定)繼續寫下一個wal日誌,直到磁碟剩餘空間不足min_wal_size時才會將舊的 WAL檔案回收以便繼續使用。

但是這種模式有一個弊端就是如果在checkpoint之前產生了大量的wal日誌就會導致發生checkpoint時對效能的影響巨大,因此pg中還有一個引數checkpoint_completion_target來進行調整。

checkpoint_completion_target:

指定檢查點完成的目標,作為檢查點之間總時間的一部分。預設是 0.5。

什麼意思呢,假如我的checkpoint_timeout設定是30分鐘,而wal生成了10G,那麼設定成0.5就允許我在15分鐘內完成checkpoint,調大這個值就可以降低checkpoint對效能的影響,但是萬一資料庫出現故障,那麼這個值設定越大資料就越危險。

總結:

大多數檢查點應該是基於時間的,即由checkpoint_timeout觸發。

效能(不頻繁檢查點)與恢復所需時間(頻繁檢查點)之間需要抉擇:

值在15-30分鐘之間是比例合適的,但到1小時不是什麼壞事。

在決定checkpoint_timeout後,透過估計WAL的數量選擇max_wal_size。

設定checkpoint_completion_target以便核心將資料重新整理到磁碟的時間足夠(但不是太多)。

24
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 怎麼用Python函式寫一個萬曆表?我來教你