1. 程式人生 > >Postgres多版本控制

Postgres多版本控制

hot tubple mvcc pg多版本控制

高並發控制肯定是數據必須達到的一個標準, 在並發操作中,對於同一個數據,同時讀和寫的兩個回話有可能產生不一致,所以出現了在高並發情況下如何保持性能又保持一致出現了MVCC,多版本並發

實現MVCC的方法有兩種:

1)寫數據時,將舊數據移到一個單獨的地方,比如回滾段中,從回滾段把舊數據讀回來

2)寫數據時,舊數據不刪除,而是插入新數據,舊數據寫文件。

MySQL,Oracle基本上是通過第一種方式操作,而PostGres則通過第二種操作,

針對第一種來說第二種的劣勢:舊版本的數據塊需要清理,舊版本的數據因為在文件中,訪問可能會造成I/O及掃描更多的數據塊,

優勢:數據可以進行很多更新,不必擔心沒有回滾段或者回滾段裝不下數據,

事物回滾可以立即完成,無論事物進行了多少操作,


針對多版本並發介紹幾個要的術語

表中的隱含字段

oid tableoid ctid xmin xmax cmin cmax 後四個字段實現控制數據行是否對用戶可見


事物ID回卷問題

Postgres的事物ID 0 代表無效 1 初始化 2 代表凍結 3才是正式開始的事物ID值,

pg的id值一直從3一直增加 達到4字節整數的最大值,然後再回頭從3開始,pg比較新舊事物到底是前還是後,通過事物id值來看,如果現在達到最大值,那麽比價9》3 他就認為9是最新的事物ID,其實這是有問題的,為了解決這個問題,pg規定兩個事物id差的最大值不得超過2的31次冪,這樣就不會產生回卷問題,比如(int32(id1-id2))<0 這個結果id1=9 id2=3 肯定成功,但是id1=3 id2= 9肯定就是負數不成功,


pg物理存儲術語

Relation 表示表或者索引

Tuple表示行即MYSQL中的ROW 記錄了版本控制的幾個值,

Page 表示磁盤中的數據塊

Buffer表示內存中的數據塊

數據塊默認8k最大32k,


數據塊的空閑空間的管理

如果一個數據更新刪除插入,肯定會纏上舊版本的數據,那麽在數據塊就會產生空閑的空間,那麽這些空閑的空間如何回收利用,比如插入一個數據是如何選擇空間的空間塊的,

首先記錄每個數據塊空閑空間的大小,實現快速的查找合適的空閑空間塊,每個表都會有oid,如果某個oid出現了空閑的空間塊,那麽就會產生表oid_fsm文件,這個文件就是記錄了空閑塊的信息


可見性映射表文件

Tuple更新之後,數據塊不會馬上清理掉,而是需要等待vacuum命令是清理,而_vm的文件就是記錄了哪些需要清理,方便進程清理的時候只需要掃描這個表即可,另外一個就是該表記錄的是行對全部事物是否可見,還是行對部分事物可見,

這裏根據上面的可見性映射表文件引出一個Index-only-scans技術,就是因為此文件記錄的是事物的可見性,所以根據此表判斷從索引取回的數據是否對當前事物可見,就不需要再去訪問表中的行了,個人理解這個就是不去掃描表了,直接掃描了這個_vm表,有待考究


另一個新技術HOT技術

更新後的新行與舊行在同一個數據塊內,舊行會有一個指針,指向新行,這就不必更新索引了,這裏涉及一個填充因子,好像是控制這個是不是要指向新的一個指針,

本文出自 “運維邦” 博客,謝絕轉載!

Postgres多版本控制