PostgreSQL XID與virtual XID區別
PG中事務號有兩個概念,一個就是通常意義上的事務號transaction id。如tuple中的xmin,xmax等。另外一個意義是虛擬事務ID,即virtual transaction ID。那麼這兩個有
什麼區別呢?
1.Transaction Id
它是用來標識事務的順序的,類似於Oracle的LSN(Logical Sequence Number)。但是PG中的這個事務號是可以wrap的,也就是重複使用的。
PG定義此事務ID為32位長度。相當於4 billion。因為是重複使用的,所以首尾相接,構成一個環。那也就是說,對於任何一個事務ID,有2 billion的事務ID比自己old,
有2 billion的事務比自己new。另外有三個事務ID有特殊意義:”0”代表invalid 事務號,”1”代表bootstrap事務號,“2”代表frozen 事務,“3”代表最小的使用者事務ID。
另外,1“和”2“也都是valid。frozen transaction id比任何事務都要old。PG用來解決事務號wrap問題,在事務號迴圈使用情況下,可能會出現新的事務號比老的事務號要小。
因此將老的事務號設定為”2”,表示是frozen transaction。frozen transaction id的動作由vacuum發起。具體介紹請我的另外一篇文章”PostgreSQL vacuum原理—vacuum揭秘“。
transaction id的產生受lwlock ”XidGenLock“保護,存放在ShmemVariableCache共享記憶體段中。
transaction id 原始碼定義如下:
事務號型別定義:
2.Virtual Transaction Id
也就是通常所講的虛擬事務ID。virtual transaction id 由兩部分組成,backend process ID 號和local transaction id組成。
backend process ID 號不是作業系統的程式ID,而是PG中用來標識程式序列號的ID。而local transansaction id也是用32位長度來表示。跟上面講的transaction id的區別看名字就知道:是local和非local的差別。
也就是說這個local transaction id是每個backend 程式獨有的。而上面第一部分講的transaction id是全域性的,即整個PG cluster 級別的。
圖中第一個紅色圈中部分就是全域性的transaction id。而第二圈中的內容就是virtual transaction id。 backend id號和local transaction id用”/“符號分隔。
前面部分為backend id號,後面部分為local transaction id。第三個紅色圈中部分為系統程式號。這裡明顯看到,virtual transaction id中的backend id號跟第三個紅色圈中的pid是不同的。
pid是作業系統的程式號。virtual transaction id只有valid 和invalid之分。”0“表示為invalid,其它都是valid。另外,virtual transaction id 在資料庫重起後,就會重新使用;但是在同一個backend id下會按順序增長。
virtual transaction id的持有,都是ExclusiveLock,因為在一個程式私有空間內,不存在爭用情況。這點上,跟transaction id是一樣的,transaction id是全域性獨享的,因此也是ExclusiveLock。
從上面圖中的mode列,我們可以清晰的看到。
定義如下:
3.總結
為什麼PG會搞這麼兩個transaction id呢,用途和意義是什麼呢?
我們知道,像類似於SELECT語句,並不會改變資料庫;而DML語句會對資料庫狀態產生影響。因此這也就是為什麼區別對待的原因。
transaction id屬於permanent id,即永久ID。它的意義是指對資料庫的更改序列,使得資料庫從一種狀態變成另外一種狀態,而且狀態的改變是持久的,可恢復,是一致性的。
這也符合的資料庫理論ACID的要求。
而查詢,實際上並不需要這種永久事務ID,只需要處理好MVCC,鎖的獲取和釋放即可,因此virtual transaction id也就足夠了。不需要去獲取XidGenLock而產生transaction id,
從而提高資料庫效能。另外,資料庫也不會因為查詢而導致transaction id快速wrap around。MVCC的處理是不需要transaction id值的。當查詢時,獲取當前每個活動程式的xmin和xmax值,
以此區間去對比每個tuple header中的xmin和xmax即可得到可見性snapshot。MVCC詳細實現見”PostgreSQL MVCC 原始碼實現“。
另外獲取的時機也有很大差別。PG的事務實現有三層,分別為top layer, middle layer 和bottom layer。virtual transaction id在top layer中獲取。不管是查詢,還是DML操作,每個
命令都有virtual transaction id。而transaction id是在bottom layer中獲取的,只有真正涉及到資料修改時,才去獲取。修改tuple後,會將transaction id的值存放到tuple header 中,
這也是我們通常講的xmin或者xmax。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30088583/viewspace-1633348/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 事務標識(xid)解析
- 解析MYSQL BINLOG 二進位制格式(7)--Xid_log_event/XID_EVENTMySql
- ITL中xid 和 uba的驗證!
- Challenges preventing us moving to 64 bit transaction id (XID)?
- PostgreSQL 原始碼解讀(129)- MVCC#13(vacuum過程-vacuum_set_xid_limits函式)SQL原始碼MVCC#MIT函式
- Postgresql與MySQL的區別MySql
- 【轉】C#中virtual和abstract的區別C#
- postgresql關於postgresql.auto.conf和postgresql.conf的區別SQL
- 論Postgres的“已提交的而且xmin’比當前事務的XID小的記錄對當前事務才是可見的”
- &與&&, |與||區別
- ??與?:的區別
- <section>與<article> 區別
- showModal()與show() 區別
- localStorage與sessionStorage 區別Session
- mouseenter與mouseover區別
- GET與POST區別
- put與putIfAbsent區別
- JavaScript 與TypeScript區別JavaScriptTypeScript
- animation與transition 區別
- classList與className區別
- NIO與IO區別
- match()與exec()區別
- JavaScript與ECMAScript 區別JavaScript
- currentTarget與target區別
- 區別mouseover與mouseenter?
- offset與style區別
- onmouseover與onmouseenter區別
- 運算子與= 區別
- MySQL的@與@@區別MySql
- prop()與attr()區別
- #include與#include區別
- mybatis #與$的區別MyBatis
- Null 與 “” 的區別Null
- exp與expdp區別
- WebViewClient與WebChromeClient 區別WebViewclientChrome
- expimp與expdpimpdp區別
- in與exist , not in與not exist 的區別
- 資料型別與函式索引-PostgreSQL篇資料型別函式索引SQL