1. 程式人生 > 其它 >pg事務一

pg事務一

事務回捲淺析
文章目錄
事務回捲淺析
事務ID(txid)
事務可比較
事務空間
事務回捲
防止事務回捲

在這裡,我們描述事務ID回捲問題。
事務ID(txid)
每當事務開始時,由事務管理器分配一個唯一識別符號 事務id(txid)。PostgreSQL的txid是一個32位無符號整數,約為42億。如果在事務開始後呼叫內部函式 txid_current(),則返回當前的txid,如下所示。

testdb=# BEGIN;
BEGIN
test=> SELECT txid_current();
txid_current
--------------
592
(1 row)
1
2
3
4
5
6
7
PostgreSQL保留以下三個特殊的 txid:

0 表示 Invalid txid,無效txid。
1 表示 Bootstrap txid, 它僅用於資料庫叢集的初始化。
2 表示 Frozen txid, 用來描述凍結狀態。
所以資料庫系統的第一個正常的事務ID是從3開始的,然後不停遞增,達到4位元組整數的最大值後,再從3開始。事務ID為0、1、2的始終保留。

事務可比較
PostgreSQL的 MVCC 依賴於能夠進行時間比較的事務 ID(XID):mvcc是基於 Timestamp Ordering(T/O)的多版本併發,PostgreSQL採用了事物 ID(XID),事物ID是嚴格按照時間順序產生的,因此滿足 T/O 的基本要求。

如果一個行版本的插入 XID 大於當前事務的 XID,它就是“屬於未來的”並且不應該對當前事務可見。

例如,從txid 100的角度看,大於100的txid表示“將來的”,並且它們在txid 100中不可見; 小於100的txid表示"過去的"並且可見

— — — — — — — —
… 97 98 99 100 101 102 …
事務空間
事務 ID 的尺寸是有限的(32位),只能存放約 42 億個事務。為了能夠迴圈使用事務空間,提供了一種機制,普通 XID 使用模-2^32演算法來比較。這意味著對於每一個普通 XID都有 21 億個 XID “更老” 並且有 21 億個“更新”,另一種解釋的方法是普通 XID 空間是沒有端點的環。 因此,一旦一個行版本建立時被分配了一個特定的普通 XID,該行版本將成為接下來 21 億個事務的“過去”(與我們談論的具體哪個普通 XID 無關)。如果在 21 億個事務之後該行版本仍然存在,它將突然變得好像在未來。

事務回捲
事務回捲問題(transaction wraparound problem) 是指本來屬於過去的事務突然間就變成了屬於未來 — 這意味著它們的輸出變成不可見。簡而言之,就是災難性的資料丟失(實際上資料仍然在那裡,但是如果你不能得到它也無濟於事)。為了避免發生這種情況,必要至少每 21 億個事務就清理每個資料庫中的每個表。

假定 txid 100 插入元組 Tuple_1,即 Tuple_1 的 普通t_xmin 為 100。伺服器運行了很長時間,Tuple_1 沒有被修改。當前 txid 為21億+100,並執行 SELECT 命令。此時,Tuple_1 可見,因為 txid 100 是過去(可見的)。然後,執行相同的SELECT 命令; 此時,目前的 txid 為21億+101。然而,Tuple_1 不再可見,因為 txid 100 在未來(如下圖)。

防止事務回捲
週期性的清理能夠解決該問題,pg資料庫提供了VACUUM清理機制。VACUUM會把行標記為 凍結 FREEZE,這表示它們是被一個在足夠遠的過去提交的事務所插入, 這樣從 MVCC 的角度來看,效果就是該插入事務對所有當前和未來事務來說當然都是可見的。PostgreSQL保留了一個特殊的 XID (FrozenTransactionId),這個 XID 並不遵循普通 XID 的比較規則 並且總是被認為比任何普通 XID 要老。要阻止事務回捲的發生,被凍結行版本會被看成其插入 XID 為FrozenTransactionId, 這樣它們對所有普通事務來說都是“在過去”,而不管回捲問題。並且這樣 的行版本將一直有效直到被刪除,不管它有多舊。
————————————————

原文連結:https://blog.csdn.net/pg_hgdb/article/details/117448120

螃蟹在剝我的殼,筆記本在寫我,漫天的我落在楓葉上雪花上,而你在想我。 --章懷柔