PostgreSQL10基礎(7)MVCC

參考書籍: 《PostgreSQL10 High Performance》

MVCC即Multi Version Concurrency Control多版本併發控制,爲提升多用戶訪問同樣的數據而設計,性能優於鎖定。被廣泛用於諸多主流數據庫。

內部可見性計算

當一個事務創建時,數據庫會更新一個事務ID計算器,通常叫做XID。

  • 當插入一行或更新數據時,一個新行被創建(更新也會創建新行),該新行有一個字段insertion XID(通常稱作xmin),記錄了當前事務ID
  • 當刪除數據時,每個被刪除行有個delete XID(通常稱作xmax),當行未被刪除時值爲空
select txid_current(),xmin,xmax,id from test

txid_current()函數返回當前查詢的XID

如果一個查詢開始,行數據被找到的條件爲

(查詢XID >= xmin) && ((查詢XID <= xmax) || 查詢XID is null)

每個數據庫客戶會話都允許同時修改表,但他們只有在事務提交後纔對其他會話可見。

示例

會話1啓動事務並更新數據但不提交

# begin;
BEGIN

# select txid_current(),xmin,xmax,* from test;
 txid_current |   xmin   | xmax | id | name
--------------+----------+------+----+------
     81911792 | 81911784 |    0 |  1 | 1
     81911792 | 81911785 |    0 |  2 | 2
(2 rows)

# update test set name='new' where id=2; 
UPDATE 1

dd=# select txid_current(),xmin,xmax,* from test;
 txid_current |   xmin   | xmax | id | name
--------------+----------+------+----+------
     81911792 | 81911784 |    0 |  1 | 1
     81911792 | 81911792 |    0 |  2 | new
(2 rows)

會話2 查詢數據

因會話1未提交,會話2XID大於修改數據的XMAX值,因此看不到最新版本數據,只能看到老版本未修改的數據

# select txid_current(),xmin,xmax,* from test;
 txid_current |   xmin   |   xmax   | id | name
--------------+----------+----------+----+------
     81911793 | 81911784 |        0 |  1 | 1
     81911793 | 81911785 | 81911792 |  2 | 2
(2 rows)

會話1 提交

提交後xmax被清空

# commit;
COMMIT

如果會話沒有提交而是回滾,則直接刪除新版本數據即可。

會話2再次查詢(事務中)或新會話 查詢數據

因爲xmax被清空,因此可以查到提交的數據

# select txid_current(),xmin,xmax,* from test;
 txid_current |   xmin   | xmax | id | name
--------------+----------+------+----+------
     81911794 | 81911784 |    0 |  1 | 1
     81911794 | 81911792 |    0 |  2 | new
(2 rows)

dd=# commit;
COMMIT

更新數據行的實際過程

  • 讀入原行數據
  • 根據update修改數據字段
  • 將新數據行及其XID寫入到新的磁盤
  • 舊數據行在不再被使用後,可以被Vacuum刪除

刪除數據行的實際過程

  • 標記原行數據爲刪除,並更新XID
  • 舊數據行在不再被使用後,可以被Vacuum刪除

Heap only tuples(HOT)

上文提到更新和刪除的過程,HOT在特定條件下允許直接重用更新和刪除操作數據行後的磁盤空間。

例如更新行沒有更新任何索引字段,如果新數據行可以被當前數據行所在數據頁剩餘空間容納下時。將觸發一個數據塊上的mini vacuum。正常的Vacuum需要更新數據heap和Index,而mini vacuum只更新數據heap,因此稱爲heap only。

pg_stat_user_tables視圖記錄了表上所有更新次數n_tup_upd和HOT更新次數n_tup_hot_upd

MVCC優缺點

優點

最大程度避免了鎖定,讀數據不會與寫數據發生衝突,讀不會阻塞寫,寫也不會阻塞讀。

缺點

  • 佔用了磁盤空間,需要進行Vacuum清掃
    • 更新時使用了新的磁盤,老數據未被刪除
    • 刪除時老數據未被真正刪除磁盤
  • 要當心不可重複讀和髒讀問題

事務ID環繞

事務ID是32比特,大約20億個ID,超出則會變爲0。MVVC的可見機制將會出現問題。

爲了解決問題

  • 每個數據庫和每張表都有一個引用XID,可見於pg_class表relfrozenxid字段,該字段記錄本表或數據庫最小XID,小於該值得XID都見被置爲保留的凍結ID,Vacuum將處理這些XID
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章