postgresql系列_MVCC機制以及鎖機制理解

數據庫操作遇到的問題

  1. 臟讀:一個事務讀取了另一個未提交事務寫入的數據;
  2. 不可重復讀:一個事務重新讀取前面讀取過的數據,發現該數據已經被另一個已經提交的事務修改;
  3. 幻讀:一個事務重新執行一個查詢,返回符合查詢條件的行的集合,發現滿足查詢條件的行的集合因為其它最近提交的事務而發生了改變。

事務特性

  1. 原子性(Atomicity):事務作為一個整體被執行,包含在其中的對數據庫的操作要么全部被執行,要么都不執行;
  2. 一致性(Consistency):事務應確保數據庫的狀態從一個一致狀態轉變為另一個一致狀態。一致狀態的含義是數據庫中的數據應滿足完整性約束;
  3. 隔離性(Isolation):多個事務并發執行時,一個事務的執行不應影響其他事務的執行;
  4. 持久性(Durability):一個事務一旦提交,他對數據庫的修改應該永久保存在數據庫中。

數據庫事務隔離級別

  1. 讀未提交(READ UNCOMMITTED)
  2. 讀已提交(READ COMMITTED)
  3. 可重復讀(REPEATABLE READS)
  4. 可序列化(SERIALIZABLE)

數據庫事務隔離級別&&解決問題

數據庫事務隔離級別.png

參考:http://www.postgres.cn/docs/9.5/transaction-iso.html

樂觀鎖與悲觀鎖

參考:http://www.hollischuang.com/archives/934

MVCC(multiversion concurrency control,多版本并發控制)

  1. MVCC(多版本并發控制)與使用鎖的優缺點:
    在MVCC里,對檢索(讀)數據的鎖請求與寫數據的鎖請求不沖突,所以讀不會阻塞寫,而寫也從不阻塞讀。甚至當通過創新的序列化快照隔離(SSI)級別提供事務隔離的嚴格等級時,PostgreSQL維持這樣的保證。
    在PostgreSQL里也有表和行級別的鎖定機制,用于給那些無法輕松接受MVCC行為的應用。 不過,恰當地使用MVCC總會提供比鎖更好的性能。另外,由應用定義的咨詢鎖提供了一個獲得不依賴于單獨事務的鎖的機制。
    問題:PG什么時候選擇MVCC什么時候選擇使用鎖?
    在PostgreSQL里也有表和行級別的鎖功能,用于那些通常不需要完整事務隔離并且想要顯式管理特定沖突點的應用。不過,恰當地使用MVCC通常會提供比鎖更好的性能。

  2. MVCC的兩種實現方法

  3. 寫新數據時,把舊數據移到一個單獨的地方,如回滾段中,其他人讀數據時,從回滾段中把舊的數據讀出來;
    2.寫數據時,舊數據不刪除,而是把新數據插入。PostgreSQL數據庫使用第二種方法,而Oracle數據庫和MySQL中的innodb引擎使用的是第一種方法;

  4. 與oracle數據庫和MySQL中的innodb引擎相比較,PostgreSQL的MVCC實現方式的優缺點如下:

    • 優點:
      1. 事務回滾可以立即完成,無論事務進行了多少操作;
      2. 數據可以進行很多更新,不必像Oracle和MySQL的Innodb引擎那樣需要經常保證回滾段不會被用完,也不會像oracle數據庫那樣經常遇到“ORA-1555”錯誤的困擾;
    • 缺點:
      1. 舊版本數據需要清理。PostgreSQL清理舊版本的命令成為Vacuum;
      2. 舊版本的數據會導致查詢更慢一些,因為舊版本的數據存在于數據文件中,查詢時需要掃描更多的數據塊。

PG中delete和update語句機制

在PostgreSQL中,使用delete和update語句刪除或更新的數據行并沒有被實際刪除,而只是在舊版本數據行的物理地址上將該行的狀態置為已刪除或已過期。因此當數據表中的數據變化極為頻繁時,那么在一段時間之后該表所占用的空間將會變得很大,然而數據量卻可能變化不大。要解決該問題,需要定期對數據變化頻繁的數據表執行VACUUM操作

  • 無VACUUM:只是將刪除的數據狀態置為已刪除,該空間不能記錄被重新使用.
  • VACUUM:刪除的記錄位于末端,占用的空間會被物理釋放歸還操作系統,如果不是位于末端,會將刪除數據鎖占用的空間置為可用狀態.
  • VACUUM FULL:不論被刪除的數據是否處于數據表末端,這些數據鎖占用的空間都將被物理釋放并歸還操作系統.
    下面的blog詳細分析了vacuum和vacuum full的區別,以及如何恢復索引和delete后的磁盤空間:
    http://www.cnblogs.com/stephen-liu74/archive/2011/12/27/2304155.html

PG的MVCC實現機制(以insert形式展開說明)

在Postgres中,每一個事務都會得到一個被稱作為 XID 的事務ID。這里說的事務不僅僅是被 BEGIN - COMMIT 包裹的一組語句,還包括單條的insert、update或者delete語句。當一個事務開始時,Postgrel遞增XID,然后把它賦給這個事務。Postgres還在系統里的每一行記錄上都存儲了事務相關的信息,這被用來判斷某一行記錄對于當前事務是否可見。
insert的MVCC說明:

  1. 當插入一行記錄時,PG會把當前事務的XID存儲在這行數據中的xmin;
  2. 當插入的數據未COMMIT之前,這行數據對其他數據是不可見的;
  3. 當插入的數據COMMIT后,這行數據對其他數據是可見的;
  4. 資料說只有xmin<XID條件,才能查看這條新記錄,但測試發現可能存在可重復讀;
  • 事務1:
    事務ID:x
    查詢數據1;
    阻塞;
    查詢數據2;
  • 事務2:
    事務ID:x+1
    插入數據

上面2個示例,如果事務2在事務1阻塞的時候提交,在事務1中的查詢數據2是能查看到這條新數據的,因為PG默認的事務隔離級別是讀已提交.如果更改事務隔離級別為SERIALIZABLE后,則不會發生可重復讀的情況(即查詢1和查詢2兩次的結果一致).
自己測試查看語句:

--獲取行xmin,xmax值
select xmin, xmax,* from tablename;
--獲取當前事務的XID
select txid_current();
--改變事務隔離級別
BEGIN TRANSACTION ISOLATION LEVEl [READ COMMITTED/REPEATABLE READ/SERIALIZABLE];  --一次啟動事務并指定事務隔離級別

對于delete和update來說,機制也是類似的,當對于他們來說PG使用xmax來判斷數據的可見性.
自己測試思路可以參考:
http://www.zlovezl.cn/articles/postgresql-concurrency-with-mvcc/
原理也可參考:
說明:https://my.oschina.net/Kenyon/blog/108850
示例:https://my.oschina.net/Kenyon/blog/63668

PG中的事務隔離

PG的表鎖

PG文檔表鎖機制:http://www.postgres.cn/docs/9.5/explicit-locking.html#LOCKING-TABLES
通過實例較好的說明了PG的鎖機制:http://www.oschina.net/translate/postgresql-locking-revealed

PG的行鎖

PG文檔行級鎖:http://www.postgres.cn/docs/9.5/explicit-locking.html#LOCKING-ROWS
pg行鎖解讀:http://blog.itpub.net/30088583/viewspace-1699315/

PG事務常用操作

  • 開啟事務
BEGIN;
START TRANSACTION [ transaction_mode [, ...] ]
-這里的 transaction_mode是下列之一:
-    ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
-    READ WRITE | READ ONLY
-    [ NOT ] DEFERRABLE
  • 設置事務模式
SET TRANSACTION transaction_mode [, ...]
SET TRANSACTION SNAPSHOT snapshot_idSET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...] 
-這里的 transaction_mode是下列之一:
-    ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
-    READ WRITE | READ ONLY
-    [ NOT ] DEFERRABLE
--事務隔離級別,定義多個事務時間的隔離級別
BEGIN TRANSACTION ISOLATION LEVEl [READ COMMITTED/REPEATABLE READ/SERIALIZABLE];  --一次啟動事務并指定事務隔離級別
BEGIN;
TRANSACTION ISOLATION LEVEl [READ COMMITTED/REPEATABLE READ/SERIALIZABLE];  --先啟動事務,再設置事務隔離級別
  • 結束事務
commit
rollback
  • 預備事務
--預備事務,使得事務分階段可以提交
PREPARE TRANSACTION 'foobar';
......
COMMIT PREPARE TRANSACTION 'foobar';
ROLLBACK PREPARE TRANSACTION 'foobar';
  • 保存點
--保存點savepoint,可以支持事務的部分回滾
insert into lyy values(1,'nn');
savepoint svp1;
insert into lyy values(2,'ff');
rollback to savepoint svp1;
--此時提交的話,第二個insert未被插入,但是第一個插入成功。
  • 查看當前事務的事務id
select  txid_current();

詳情參考:https://my.oschina.net/liuyuanyuangogo/blog/415395

其他參考

pg鎖機制理解:http://francs3.blog.163.com/blog/static/40576727201082134343604/
mysql鎖機制理解: http://hedengcheng.com/?p=771
pg中mvcc實現機制:http://www.zlovezl.cn/articles/postgresql-concurrency-with-mvcc/
http://blog.itpub.net/30088583/viewspace-1585695/
較好的闡釋了pg中mvcc的原理:https://my.oschina.net/Kenyon/blog/108850
pg事務級別查看與變更:http://blog.csdn.net/scugxl/article/details/51126433
mysql與pg對比:https://www.sdk.cn/news/4587
pg維護vacuum解析:http://www.cnblogs.com/stephen-liu74/archive/2011/12/27/2304155.html
Ubuntu安裝PG與使用:http://wenzhixin.net.cn/2014/01/12/hello_postgresql

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,362評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,013評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,346評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,421評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,146評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,534評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,585評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,767評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,318評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,074評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,258評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,828評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,486評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,916評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,156評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,993評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,234評論 2 375

推薦閱讀更多精彩內容