PostgreSQL 事務模型介紹
PostgreSQL有自己的事務實現模型。總體上分為三層:top layer, middle layer和bottom layer。
1. Top Layer
Top Layer主要由使用者控制,對使用者可見。這一層的事務,主要由使用者來決定事務的發起與結束。事務生命週期由使用者控制,是high-level的。
也就是通常所說的事務塊,transaction block。當使用者發起:BEGIN, COMMIT, ROLLBACK, SAVEPOINT, ROLLBACK TO or RELEASE等命令時,
PG的traffic cop會將這些call重新轉寄到Top Layer routine中,相對應的方法如下:
BeginTransactionBlock
EndTransactionBlock
UserAbortTransactionBlock
DefineSavepoint
RollbackToSavepoint
ReleaseSavepoint
2.Middle Layer
這一層基本上是語句層級的。對使用者不可見,也就是說使用者無法控制具體生命週期。這一層的處理是跟語句相對應的。由postgres.c處理,相對應的方法如下:
StartTransactionCommand
CommitTransactionCommand
AbortCurrentTransaction
3.Bottom Layer
這是最低層的事務原子性的實現,是row-level層級的。是真正意義上的事務實現,以及嵌套交易處理等。
相對應的方法如下:
StartTransaction
CommitTransaction
AbortTransaction
CleanupTransaction
StartSubTransaction
CommitSubTransaction
AbortSubTransaction
CleanupSubTransaction
從上面三層模型,可以看出PG交易管理粒度由粗到細。調用由中層向底層調用。另外如果有使用者層級的事務控制,如出現“BEGIN”等,則被postgres.c轉寄到top layer中。
假設下面一個案例:
1) BEGIN
2) SELECT * FROM foo
3) INSERT INTO foo VALUES (...)
4) COMMIT
那麼相應的調用方法調用循序如下:
/ StartTransactionCommand;
/ StartTransaction;
1) < ProcessUtility; << BEGIN
\ BeginTransactionBlock;
\ CommitTransactionCommand;
/ StartTransactionCommand;
2) / ProcessQuery; << SELECT ...
\ CommitTransactionCommand;
\ CommandCounterIncrement;
/ StartTransactionCommand;
3) / ProcessQuery; << INSERT ...
\ CommitTransactionCommand;
\ CommandCounterIncrement;
/ StartTransactionCommand;
/ ProcessUtility; << COMMIT
4) < EndTransactionBlock;
\ CommitTransactionCommand;
\ CommitTransaction;
在第一步中,使用者定義的事務邊界開始,也是此事務的生命週期起點。
首先,”BEGIN”也是作為一個命令語句的,因此本身這一步也是需要middle layer中的方法調用將其包圍起來。
接著起動low-level事務,即由middle layer調用bottom layer的方法。StartTransaction時,會產生vxid(virtual transaction id,即backend id與local transaction id)。
判斷當前事務是否是read-only或者目前是否處於recovery狀態。交易隔離等級,事務是否非同步commit等資訊都在這裡初始化。將transState狀態設定為:TRANS_INPROCESS。
因為有“BEGIN”命令語句,所以是top layer的。因此又被轉到BeginTransactionBlock邏輯中。開始transaction block 處理,並將事務狀態設定為:TBLOCK_START。
起transaction block和起transaction的區別在於對事務狀態的設定不一樣。
start trasaction block是將事務狀態設定為:TBLOCK_START,而一般的start transaction是將其設定為:TRANS_INPROCESS。
事務塊與事務是有區別的,在狀態上。事務塊有以下幾種狀態,是可以嵌套的:
而一般事務,只有以下幾種狀態,沒有嵌套:
另外,在源碼定義上,用了不同的結構體來儲存。TransState,儲存low-level事務狀態。
而TBlockState儲存high-level事務狀態。從這裡也明顯可以看出,PG在事務層級上做了區分的。
在第二步中,發起select查詢。上面講過,middle layer是跟命令語句對應的。因此針對select 查詢,也是用middle layer中的方法調用將其包圍。
另外增加CID,用於同一事務中的MVCC可見度判斷。
在第三步中,發起insert操作。這一步大邏輯上基本上等同於第二步。只是在處理insert時,需要將當前的xid更新到tupler header中去。
通常涉及到insert,update,delete等操作都是跟heap緊密相關,涉及到heap的物理上tuple新增和刪除。在這一層中,PG需要為每一個DML
操作assign一個事務ID,並將此事務ID更新到tuple header中的xmin或者xmax中。從而實現MVCC。另外這一層也會增加commandID,主要用來實現同一事務中的可見度判斷。
在第四步中,使用者發起commit,提交事務。事務生命週期結束。這一步邏輯等同於第一步。這裡不僅需要結束top layer 的transaction block。也需要結束low-level中的事務,實現
事務原子性。另外還需要釋放資源,釋放buffer pin,釋放鎖等。
從上面的講解中,我們可以比較清晰的看到,PG在事務實現的大致邏輯。完整實現ACID功能。
Atomity:原子性由low-level層級實現,從StartTransaction開始,結束於CommitTransaction。
Consistency:一致性由語句層級實現,即middle layer對應。另外在tuple header 中更新的xmin,xmax,cmin,cmax為事務可見度提供判斷基礎。
Isolation:在StartTransaction時,初始化交易隔離等級。為MVCC建立snapshot時,提供基礎。
Duarability:通過CommitTransaction實現,提交交易記錄等。為資料恢複和持久化提供基礎。實現WAL(Write Ahead Log)功能。
------------------------------------華麗麗的分割線------------------------------------
CentOS 6.3環境下yum安裝PostgreSQL 9.3
PostgreSQL緩衝詳述
Windows平台編譯 PostgreSQL
Ubuntu下LAPP(Linux+Apache+PostgreSQL+PHP)環境的配置與安裝
Ubuntu上的phppgAdmin安裝及配置
CentOS平台下安裝PostgreSQL9.3
PostgreSQL配置Streaming Replication叢集
如何在CentOS 7/6.5/6.4 下安裝PostgreSQL 9.3 與 phpPgAdmin
------------------------------------華麗麗的分割線------------------------------------
PostgreSQL 的詳細介紹:請點這裡
PostgreSQL 的:請點這裡
本文永久更新連結地址: