PostgreSQL 到底有沒有PAGE 鎖 與 Advisory Locks

事情的起因是,之前寫了一篇比較MYSQL 和 PG 的MVCC的文字,其中提到PG 沒有 PAGE LOCK,有同學指正,提出PG是有 PAGE LOCK 的。

到底PG 有沒有 PAGE LOCK 個人覺得的搞搞清楚,並且有錯必改,也感謝給我指正的 “燦” 同學。

1 首先最直觀的方式就是官方文檔

https://www.postgresql.org/docs/12/explicit-locking.html

但問題可能有同學提出在PG 9.3 以及以前的版本中並未看到,單獨列出的 page level locks 這個單獨的項目,但實際仔細的查找之前的版本的 page level locks 是在 Row-level locks 這個項目中,並且從早期的9.x寫到現在的PG12 都是一句話帶過

和有些數據庫對PAGE LOCKS 的詳細描述和功能性的描述(對比SQL SERVER),PG 對PAGE LOCKS 描述有點簡單。

 既然想從文檔中探究祕密的想法無法達成,只能看看源代碼裏面能不能有點收穫 lock.h 文件中有相關鎖的定義和處理的方式,打開文件

相關的使用locktage_page 鎖的例子,可以在src/backend/access/gin/ginfast.c:               

LockPage(index,GIN_METAPAGE_BLKNO, ExclusiveLock)

中找到相關使用locktage_page 的程序段

應該還有其他的PAGE 鎖,但限於時間和經歷的限制,沒有繼續再找,如果還有其他的還請高手不吝賜教,感謝。

實際上在上一篇中給出一句PG 沒有PAGE 鎖,這個的確是不正確的,這裏也說說我理解的PAGE 鎖的含義是什麼,爲什麼說了那樣一句話。

先用一個圖來看一下SQL SERVER 的PAGE LOCK 和 ROW LOCK  , TABLE LOCK 的關係

SQL SERVER 與其他數據庫不一樣的地方,在於資源的動態鎖定,也就是他可能一開始使用了ROW 鎖, 但由於後期整體操作的複雜度提高,直接將ROW 鎖升級爲頁鎖, 而其他的數據庫目前我是沒有聽到有確認的一種叫法 Lock escalation.

另外SQL SERVER 在行鎖和頁鎖中,是可以將其進行 enabled 和 disabled的,這點相對於其他數據庫的方面還是靈活的。

所以可能如果從之前理解的一些頁鎖的概念和使用的方式來說, PG的頁鎖是不可隨意控制,從應用程序developer角度也無需深刻理解的。

反觀SQL SERVER 如果程序員在處理一些應用的過程中,建議還是考慮一下鎖升級的問題,因爲鎖升級必然導致更多的鎖衝突。

回過頭來在看PG 的Advisory Locks ,下面通過兩個例子來說明advisory locks 的作用。因爲其他的數據庫沒有這樣的設定(如果有還請指正,至少沒MYSQL , SQL SERVER 是沒有的)

1  SESSION 下面我們找兩個SESSION   SESSION 1  SESSION 2 

SESSION 1

SESSION 2 

從上面的例子中可以領會到Advisory Locks 具體的功能,首先在MVCC 無法解決應用關於數據處理的次序性和數據的唯一性的情況下通過Advisory Locks在應用程序中使用,通過SESSION 級別 或者 transcation 級別通過Advisory Locks來達到某種特殊的需求。

如上面的例子中,SESSION 1  插入數據, 但SESSION 2 需要刪除 ID =1 的數據,但問題是怎麼判斷 SESSION1中的數據表中已經存在了 數據,如果是其他的數據庫可能需要其他手段,例如在表中設置狀態位的邏輯方式來不斷進行判斷,但實際上這就產生了鎖,任何對數據庫中的表的操作都會產生鎖,這就造成了數據庫的資源的爭奪,在頻繁的獲取狀態的情況或修改狀態的情況下,就會產生BLOCK 甚至可能會有死鎖。PG 在這方面對於應用是友好的通過Advisory Locks  不會物理的對數據庫產生任何的資源消耗,而是在應用程序中,設置Advisory Locks 來在不同的SESSION 或者 TRANSACTION 中判斷相互的狀態,而採取相對的操作。

下面是一個事務的例子,併發的時候transaction 2,無法獲知到底transaction1到底是不是將ID =4 插入到 TEST 表中,所以通過pg_try_advisory_xact_lock 來阻止 transactoin 2 程序出錯,這也是一種使用advisory_lock的方式。

transaction 1

transaction 2

之所以之前沒有看到有人提到這個所,估計是運維DBA 不關心,因爲這與軟件的設計有關,至少要懂得業務的邏輯與程序的設計, 而程序員目前能完全掌握PG的人,估計比DBA 還少,大多都是淺嘗, 所以學習PG 必須深挖"三不管", 讓其爲程序設計提供更多的服務方式和使用方式.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章