論PostgreSQL中的各種“xid”
在分析PostgreSQL 9.6.9(下文稱PG)的多版本(MVCC)問題時,經常打交道的就是Snapshot了,而Snapshot的構造過程中,我們會看到多種“xid”,而這些“xid”究竟如何賦值?作用又是什麼?說實話,我並沒有完全搞明白。今天,把這些“xid”做一些歸納總結,以便於以後分析定位問題。
/*
* These are updated by GetSnapshotData. We initialize them this way
* for the convenience of TransactionIdIsInProgress: even in bootstrap
* mode, we don't want it to say that BootstrapTransactionId is in progress.
*
* RecentGlobalXmin and RecentGlobalDataXmin are initialized to
* InvalidTransactionId, to ensure that no one tries to use a stale
* value. Readers should ensure that it has been set to something else
* before using it.
*/
TransactionId TransactionXmin = FirstNormalTransactionId;
TransactionId RecentXmin = FirstNormalTransactionId;
TransactionId RecentGlobalXmin = InvalidTransactionId;
TransactionId RecentGlobalDataXmin = InvalidTransactionId;
1. 各種xid的生成
爲了說明這些“xid”是如何產生的,我們必須從GetSnapshotData着手。
通過上圖,可看出:
- (考慮事務號輪轉問題)
- (初值賦定)
通過上圖,可看出:
- globalxmin是allPgXact中所有PGXACT中最小的xmin
- xmin是allPgXact中所有PGXACT中最小的xid
- globalxmin是allPgXact中所有xid和xmin中最小的。
通過上圖,可看出:
- allPgXact中的每個PGXACT的xmin是如此賦值的。
- TransactionXmin是allPgXact中所有PGXACT中最小的xid。
通過上圖,可看出:
- RecentGlobaXmin是所有allPgXact中最小的 .
通過上圖,可看出:
- 的,按照註釋來說應該是用於非系統表的vacuum操作的。
通過上圖,可看出:
總結一下:
- 是最近一次已完成事務+1。
- 是allPgXact中最小的xid。
- 是allPgXact中所有xid和xmin中最小的。
- 。
- 。
如上所述,即有:
2. RecentGlobalDataXmin
the global xmin for non-catalog tables >= RecentGlobalXmin
3. RecentGlobalXmin
the global xmin (oldest TransactionXmin across all running transactions, except those running LAZY VACUUM). This is the same computation done by GetOldestXmin(true, true).
4. TransactionXmin
the oldest xmin of any snapshot in use in the current transaction (this is the same as MyPgXact->xmin).
5. RecentXmin
the xmin computed for the most recent snapshot. XIDs older than this are known not running any more.
還是不太明白,這些“xid”的具體作用,一頭霧水… …
未完待續… …