您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“PostgreSQL中commit log有什么作用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“PostgreSQL中commit log有什么作用”吧!
Concurrency Control并發(fā)控制是一種機(jī)制,在并發(fā)進(jìn)行多個(gè)事務(wù)時(shí)維護(hù)一致性(Consistency)和隔離性(Isolation),一致性和隔離性是數(shù)據(jù)庫事務(wù)ACID(Atomicity, Consistency, Isolation, Durability) 屬性中的C和I。
多版本并發(fā)控制(MVCC)是廣泛使用的并發(fā)控制技術(shù),其主要優(yōu)勢(shì)是讀不會(huì)阻塞寫,而寫也不會(huì)阻塞讀。MVCC有很多種變體,PostgreSQL使用一種稱為快照隔離Snapshot Isolation (SI)的MVCC變體實(shí)現(xiàn)并發(fā)控制。
在MVCC中,每個(gè)DML操作創(chuàng)建一個(gè)數(shù)據(jù)(包括Index)的新版本,同時(shí)保留之前的舊版本。當(dāng)事務(wù)讀取數(shù)據(jù)時(shí),選擇其中一個(gè)“正確”的版本,以確保各個(gè)事務(wù)之間的隔離。
在
Multi Version Heap Tuple
這一章節(jié)中提到事務(wù)回滾后,新寫入的數(shù)據(jù)仍存儲(chǔ)在heap中,PostgreSQL如何識(shí)別產(chǎn)生這些數(shù)據(jù)的事務(wù)的狀態(tài)(提交/回滾/進(jìn)行中),從而確定哪些tuple可見不可見?PG通過clog(commit log)存儲(chǔ)每個(gè)事務(wù)的狀態(tài),在數(shù)據(jù)庫啟動(dòng)時(shí),clog文件會(huì)加載到共享內(nèi)存中,checkpoint時(shí)會(huì)把共享內(nèi)存中的事務(wù)狀態(tài)信息刷新到磁盤上.
事務(wù)ID
當(dāng)一個(gè)事務(wù)開啟時(shí),PostgreSQL事務(wù)管理器會(huì)為該事務(wù)分配一個(gè)唯一的事務(wù)ID(txid,無符號(hào)32bit整型).
通過txid_current()函數(shù)可獲取當(dāng)前事務(wù)號(hào).
testdb=# begin; BEGIN testdb=# select txid_current(); txid_current -------------- 2308 (1 row) testdb=#
在PG中,以下為系統(tǒng)保留使用的txid:
txid = 0,表示 Invalid txid,用于判斷txid的有效性
txid = 1,表示 Bootstrap txid,在intidb初始化數(shù)據(jù)庫時(shí)使用
txid = 2,表示 Frozen txid,在事務(wù)ID回卷時(shí),通過vacuum進(jìn)程處理時(shí)使用
事務(wù)狀態(tài)
PostgreSQL定義了四種事務(wù)狀態(tài),分別是IN_PROGRESS(進(jìn)行中), COMMITTED(已提交), ABORTED(已回滾), 和 SUB_COMMITTED(子事務(wù)已提交).
/* * Possible transaction statuses --- note that all-zeroes is the initial * state. * 可能的事務(wù)狀態(tài) --- 注意初始狀態(tài)全部為ASCII 0 * * A "subcommitted" transaction is a committed subtransaction whose parent * hasn't committed or aborted yet. * "subcommitted"事務(wù)是指已提交的子事務(wù),而該子事務(wù)所在的父事務(wù)尚未提交或者回滾. */ typedef int XidStatus; #define TRANSACTION_STATUS_IN_PROGRESS 0x00 #define TRANSACTION_STATUS_COMMITTED 0x01 #define TRANSACTION_STATUS_ABORTED 0x02 #define TRANSACTION_STATUS_SUB_COMMITTED 0x03
物理文件
clog文件存儲(chǔ)在$PGDATA/pg_xact目錄中
[xdb@localhost pg_xact]$ ll total 8 -rw-------. 1 xdb xdb 8192 Jan 8 15:55 0000 [xdb@localhost pg_xact]$
clog segment
如前所述,事務(wù)號(hào)是無符號(hào)的32bit整型,PG通過以下公式邏輯上把clog劃分為N個(gè)segment:
N = 0xFFFFFFFF/CLOG_XACTS_PER_PAGE/SLRU_PAGES_PER_SEGMENT
其中:
CLOG_XACTS_PER_PAGE定義為
/* We need two bits per xact, so four xacts fit in a byte */ #define CLOG_BITS_PER_XACT 2 -->每個(gè)事務(wù)狀態(tài)使用2bits表示 #define CLOG_XACTS_PER_BYTE 4 -->每個(gè)Byte可存儲(chǔ)4個(gè)事務(wù)狀態(tài) #define CLOG_XACTS_PER_PAGE (BLCKSZ * CLOG_XACTS_PER_BYTE) -->每個(gè)page可存儲(chǔ)8192*4個(gè)事務(wù)狀態(tài)
即CLOG_XACTS_PER_PAGE = 8192*4
SLRU_PAGES_PER_SEGMENT定義為
#define SLRU_PAGES_PER_SEGMENT 32
代入公式中:
N = 0xFFFFFFFF/CLOG_XACTS_PER_PAGE/SLRU_PAGES_PER_SEGMENT
= 0xFFFFFFFF/(8192*4)/32
= 4096
物理上,每個(gè)segment有32個(gè)Pages(SLRU_PAGES_PER_SEGMENT = 32),則每個(gè)segment file大小為8K*32=256K.
給定一個(gè)事務(wù)號(hào),如何獲取該事務(wù)對(duì)應(yīng)的狀態(tài)?
PG首先通過該事務(wù)號(hào)獲得該事務(wù)狀態(tài)存儲(chǔ)在clog中哪個(gè)page中(即pageno),然后再定位存儲(chǔ)事務(wù)狀態(tài)的Byte在該page中的偏移以及在該Byte中的偏移.
#define TransactionIdToPage(xid) ((xid) / (TransactionId) CLOG_XACTS_PER_PAGE) #define TransactionIdToPgIndex(xid) ((xid) % (TransactionId) CLOG_XACTS_PER_PAGE) #define TransactionIdToByte(xid) (TransactionIdToPgIndex(xid) / CLOG_XACTS_PER_BYTE) #define TransactionIdToBIndex(xid) ((xid) % (TransactionId) CLOG_XACTS_PER_BYTE)
如給定事務(wù)號(hào)2308,根據(jù)上述公式可得到:
Page = 2308 / (8192*4) = 0 —> 第0號(hào)page
PageIndex = 2308 % (8192*4) = 2308 —> Page內(nèi)偏移
ByteInPage = 2308 / 4 = 577 —> 該P(yáng)age內(nèi)的第577個(gè)Byte
ByteIndex = 2304 % 4 = 0 —> 該字節(jié)中的首2bits
下面通過實(shí)際案例驗(yàn)證
開啟事務(wù)
testdb=# begin; BEGIN testdb=# select txid_current(); txid_current -------------- 2308 (1 row)
查看clog
[xdb@localhost pg_xact]$ hexdump -C ./0000 -s 577 -n 1 00000241 00 |.| 00000242
0x00 —> TRANSACTION_STATUS_IN_PROGRESS
提交事務(wù)
執(zhí)行checkpoint,刷新到磁盤上
testdb=# commit; COMMIT testdb=# checkpoint; CHECKPOINT
查看clog
[xdb@localhost pg_xact]$ hexdump -C ./0000 -s 577 -n 1 00000241 01 |.| 00000242
值為0x01 —> TRANSACTION_STATUS_COMMITTED
重新開啟一個(gè)事務(wù)2309,回滾該事務(wù),clog中的值應(yīng)為0x09(二進(jìn)制值為:0000 1001)
testdb=# begin; BEGIN testdb=# select txid_current(); txid_current -------------- 2309 (1 row) testdb=# select 2308%4; ?column? ---------- 0 (1 row) testdb=# rollback; ROLLBACK testdb=# checkpoint; CHECKPOINT testdb=#
clog文件中的內(nèi)容0x09,與預(yù)期中的一致.
[xdb@localhost pg_xact]$ hexdump -C ./0000 -s 577 -n 1 00000241 09 |.| 00000242 [xdb@localhost pg_xact]$
到此,相信大家對(duì)“PostgreSQL中commit log有什么作用”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。