您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“PostgreSQL MVCC源碼的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“PostgreSQL MVCC源碼的示例分析”這篇文章吧。
MVCC對每一個DBA來講,都不陌生,即多版本控制(Multi-Version-Control)。正因為數據有了多個版本,才實現了讀和寫在一定程度上的分離,提高數據庫每秒處理查詢的能力(QPS)。
用戶發起的普通查詢請求(不包含select … for update語句),并不堵塞DML事務。在Read Commit事務隔離級別時,查詢請求只讀取查詢請求之前已經提交的事務的數據更改,對當前版本的數據并不影響;
而DML語句,會操作當前版本。因此做到了讀寫分離的目的,提高數據庫并發能力。
不同的數據庫,實現MVCC的方法不同。Oracle和MySQL Innodb 存儲引擎類似的使用undo來實現。
對于PostgreSQL數據庫來講,他沒有undo,那么,PG又是怎么來實現他自己的MVCC呢?又有那些優缺點呢?
PG用copy tuple和tuple的xmin,xmax,cmin,cmax等標記來實現多版本。
xmin:在創建記錄(tuple)時,記錄此時,后面每次update也會更新。
xmax: 在刪除tuple或者lock時,記錄此時;如果記錄沒有被刪除,那么此時為0。
cmin和cmax:主要為標識在同一個事務中多個語句命令的序列值。用于同一個事務中實現版本可見性判斷。
1.下面我們先來看一下xmin和xmax的變化:
從上圖可以看出,4條記錄的xmin是一樣的,都是“390689”,這說明是在同一個事務中創建的。另外xmax都為“0”,說明都沒有被刪除。cmin和cmax都是1,說明是同一個命令創建的。
接下來,我們update一下id為1的記錄,看發生什么情況:
update之后,并沒有提交,重新開起另外一個窗口,查詢:
我們看到,ID為1的記錄,只有xmin沒有變化,其它三個值都發生了變化,其中xmax變成了”390691”。
然后我把事務提交掉,再在新窗口中查詢:
我們看到,提交后,ID 為1的記錄,xmin變為“390691”,xmin增加了1;而xmax變成了0。
從上面的案例中,我們從表面上可以看出,xmin增加了。但是事實上,PostgreSQL在底層所做的事情,遠比這個要多。底層已經生成了一個新版本的tuple,新版本tuple的xmin等于老版本的xmax。
詳細的internal,我后面再展開講。
2.我們再來看一下cmin和cmax的變化:
我起一個事務,包含兩條update,一條update ID值為2的記錄,一條insert ID值為3的記錄:
事務“390694”中,cmin和cmax的值,依次遞增。從目前來看cmin和cmax實際上是同一個field。
源碼定義如下,用union實現了CommandId,是一個combo command id。
因此,從上面的例子來看,PostgreSQL的mvcc實現是比較簡單的。只需要通過對比tuple header中xmin,xmax,cmin,cmax與當前的xid,就可以得到在scan tuple時,此tuple對于當前查詢的可視性。
可見性判斷邏輯:
但是也帶來了另外一個問題:就是在沒有undo的情況下,會導致空間的增長。因此PostgreSQL引入了vacumm后臺進程,來定期清理這些 DEAD tuple。
以上是“PostgreSQL MVCC源碼的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。