国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

PostgreSQL 的 MVCC 機(jī)制解析

開發(fā) 開發(fā)工具 數(shù)據(jù)庫運(yùn)維 PostgreSQL
PostgreSQL是通過MVCC(Multi-Version Concurrency Control)來保證事務(wù)的原子性和隔離性,具體MVCC機(jī)制是怎樣實(shí)現(xiàn)的,下面舉些示例來做個(gè)簡單解析以加深理解。

[[200391]]

導(dǎo)語

PostgreSQL是通過MVCC(Multi-Version Concurrency Control)來保證事務(wù)的原子性和隔離性,具體MVCC機(jī)制是怎樣實(shí)現(xiàn)的,下面舉些示例來做個(gè)簡單解析以加深理解。

前提

表中隱藏的系統(tǒng)字段

PostgreSQL的每個(gè)表中都有些系統(tǒng)隱藏字段,包括:

  • oid: 對(duì)象標(biāo)識(shí)符,生成的值是全局唯一的,表、索引、視圖都帶有oid,如果需要在用戶創(chuàng)建的表中使用oid字段,需要顯示指定“with oids”選項(xiàng)。
  • ctid: 每條記錄(稱為一個(gè)tuple)在表中的物理位置標(biāo)識(shí)。
  • xmin: 創(chuàng)建一條記錄(tuple)時(shí),記錄此值為當(dāng)前事務(wù)ID。
  • xmax: 創(chuàng)建tuple時(shí),默認(rèn)為0,刪除tuple時(shí),記錄此值為當(dāng)前事務(wù)ID。
  • cmin/cmax: 標(biāo)識(shí)在同一個(gè)事務(wù)中多個(gè)語句命令的序列值,從0開始,用于同一個(gè)事務(wù)中實(shí)現(xiàn)版本可見性判斷

MVCC機(jī)制

MVCC機(jī)制通過這些隱藏的標(biāo)記字段來協(xié)同實(shí)現(xiàn),下面舉幾個(gè)示例來解釋MVCC是如何實(shí)現(xiàn)的

  1. //seesion1: 
  2.  
  3. 創(chuàng)建表,顯示指定oid字段: 
  4. testdb=# create table t1(id intwith oids; 
  5. CREATE TABLE 
  6.  
  7. 插入幾條記錄 
  8. testdb=# insert into t1 values(1); 
  9. INSERT 17569 1 
  10. testdb=# insert into t1 values(2); 
  11. INSERT 17570 1 
  12. testdb=# insert into t1 values(3); 
  13. INSERT 17571 1 

查詢當(dāng)前表中的tuple信息,xmin為創(chuàng)建tuple時(shí)的事務(wù)ID,xmax默認(rèn)為0

  1. testdb=# select ctid, xmin, xmax, cmin, cmax, oid, id from t1; 
  2.  ctid  |   xmin   | xmax | cmin | cmax |  oid  | id 
  3. -------+----------+------+------+------+-------+---- 
  4.  (0,1) | 80853357 |    0 |    0 |    0 | 17569 |  1 
  5.  (0,2) | 80853358 |    0 |    0 |    0 | 17570 |  2 
  6.  (0,3) | 80853359 |    0 |    0 |    0 | 17571 |  3 
  7. (3 rows

接下來,我們更新某個(gè)tuple的字段,將tuple中id值為1更新為4,看看會(huì)發(fā)生什么

  1. testdb=# begin
  2. BEGIN 
  3. testdb=# select txid_current(); 
  4.  txid_current 
  5. -------------- 
  6.      80853360 
  7. (1 row) 
  8.  
  9. testdb=# update t1 set id = 4 where id = 1; 
  10. UPDATE 1 

查看tuple詳細(xì)信息

  1. testdb=# select ctid, xmin, xmax, cmin, cmax, oid, id from t1; 
  2.  ctid  |   xmin   | xmax | cmin | cmax |  oid  | id 
  3. -------+----------+------+------+------+-------+---- 
  4.  (0,2) | 80853358 |    0 |    0 |    0 | 17570 |  2 
  5.  (0,3) | 80853359 |    0 |    0 |    0 | 17571 |  3 
  6.  (0,4) | 80853360 |    0 |    0 |    0 | 17569 |  4 
  7. (3 rows

可以看到id為1的tuple(oid=17569)已經(jīng)被修改了,id值被更新為4,另外ctid、xmin字段也被更新了,ctid值代表了該tuple的物理位置,xmin值是創(chuàng)建tuple時(shí)都已經(jīng)寫入,這兩個(gè)字段都不應(yīng)該被更改才對(duì),另起一個(gè)seesion來看下(當(dāng)前事務(wù)還未提交)

  1. //seesion2: 
  2.  
  3. testdb=# select ctid, xmin, xmax, cmin, cmax, oid, id from t1; 
  4.  ctid  |   xmin   |   xmax   | cmin | cmax |  oid  | id 
  5. -------+----------+----------+------+------+-------+---- 
  6.  (0,1) | 80853357 | 80853360 |    0 |    0 | 17569 |  1 
  7.  (0,2) | 80853358 |        0 |    0 |    0 | 17570 |  2 
  8.  (0,3) | 80853359 |        0 |    0 |    0 | 17571 |  3 
  9. (3 rows

可以看到id為1的tuple(oid=17569)還存在,只是xmax值被標(biāo)記為當(dāng)前事務(wù)Id。 原來更新某個(gè)tuple時(shí),會(huì)新增一個(gè)tuple,填入更新后的字段值,將原來的tuple標(biāo)記為刪除(設(shè)置xmax為當(dāng)前事務(wù)Id)。同理,可以看下刪除一個(gè)tuple的結(jié)果

  1. //seesion1: 
  2. testdb=# delete from t1 where id = 2; 
  3. DELETE 1 
  4.  
  5. //seesion2: 
  6. testdb=# select ctid, xmin, xmax, cmin, cmax, oid, id from t1; 
  7.  ctid  |   xmin   |   xmax   | cmin | cmax |  oid  | id 
  8. -------+----------+----------+------+------+-------+---- 
  9.  (0,1) | 80853357 | 80853360 |    0 |    0 | 17569 |  1 
  10.  (0,2) | 80853358 | 80853360 |    1 |    1 | 17570 |  2 
  11.  (0,3) | 80853359 |        0 |    0 |    0 | 17571 |  3 
  12. (3 rows

刪除某個(gè)tuple時(shí)也是將xmax標(biāo)記為當(dāng)前事務(wù)Id,并不做實(shí)際的物理記錄清除操作。另外cmin和cmax值遞增為1,表明了同一事務(wù)中操作的順序性。在該事務(wù)(seesion1)未提交前,其他事務(wù)(seesion2)可以看到之前的版本信息,不同的事務(wù)擁有各自的數(shù)據(jù)空間,其操作不會(huì)對(duì)對(duì)方產(chǎn)生干擾,保證了事務(wù)的隔離性。

提交事務(wù),查看最終結(jié)果如下:

  1. //seesion1: 
  2. testdb=# commit
  3. COMMIT 
  4. testdb=# select ctid, xmin, xmax, cmin, cmax, oid, id from t1; 
  5.  ctid  |   xmin   | xmax | cmin | cmax |  oid  | id 
  6. -------+----------+------+------+------+-------+---- 
  7.  (0,3) | 80853359 |    0 |    0 |    0 | 17571 |  3 
  8.  (0,4) | 80853360 |    0 |    0 |    0 | 17569 |  4 
  9. (2 rows

但是,如果我們不提交事務(wù)而是回滾,結(jié)果又是如何?

  1. testdb=# begin ; 
  2. BEGIN 
  3. testdb=# update t1 set id = 5 where id = 4; 
  4. UPDATE 1 
  5. testdb=# rollback
  6. ROLLBACK 
  7. testdb=# select ctid, xmin, xmax, cmin, cmax, oid, id from t1; 
  8.  ctid  |   xmin   |   xmax   | cmin | cmax |  oid  | id 
  9. -------+----------+----------+------+------+-------+---- 
  10.  (0,3) | 80853359 |        0 |    0 |    0 | 17571 |  3 
  11.  (0,4) | 80853360 | 80853361 |    0 |    0 | 17569 |  4 
  12. (2 rows
  13. xmax標(biāo)記并未清除,繼續(xù)新增一條記錄: 
  14.  
  15. testdb=# insert into t1 values(5); 
  16. INSERT 17572 1 
  17. testdb=# select ctid, xmin, xmax, cmin, cmax, oid, id from t1; 
  18.  ctid  |   xmin   |   xmax   | cmin | cmax |  oid  | id 
  19. -------+----------+----------+------+------+-------+---- 
  20.  (0,3) | 80853359 |        0 |    0 |    0 | 17571 |  3 
  21.  (0,4) | 80853360 | 80853361 |    0 |    0 | 17569 |  4 
  22.  (0,6) | 80853362 |        0 |    0 |    0 | 17572 |  5 
  23. (3 rows

發(fā)現(xiàn)沒有清理掉新增的tuple,消除原有tuple上的xmax標(biāo)記,這是為何?處于效率的原因,如果事務(wù)回滾時(shí)也進(jìn)行清除標(biāo)記,可能會(huì)導(dǎo)致磁盤IO,降低性能。那如何判斷該tuple的是否有效呢?答案是PostgreSQL會(huì)把事務(wù)狀態(tài)記錄到clog(commit log)位圖文件中,每讀到一行時(shí),會(huì)到該文件中查詢事務(wù)狀態(tài),事務(wù)的狀態(tài)通過以下四種來表示:

  • #define TRANSACTION_STATUS_IN_PROGRESS=0x00 正在進(jìn)行中
  • #define TRANSACTION_STATUS_COMMITTED=0x01 已提交
  • #define TRANSACTION_STATUS_COMMITTED=0x02 已回滾
  • #define TRANSACTION_STATUS_SUB_COMMITTED=0x03 子事務(wù)已提交

MVCC保證原子性和隔離性

原子性

事務(wù)的原子性(Atomicity)要求在同一事務(wù)中的所有操作要么都做,要么都不做。根據(jù)PostgreSQL的MVCC規(guī)則,插入數(shù)據(jù)時(shí),會(huì)將當(dāng)前事務(wù)ID寫入到xmin中,刪除數(shù)據(jù)時(shí),會(huì)將事務(wù)ID寫入xmax中,更新數(shù)據(jù)相當(dāng)于先刪除原來的tuple再新增一個(gè)tuple,增刪改操作都保留了事務(wù)ID,根據(jù)事務(wù)ID提交或撤銷該事務(wù)中的所有操作,從而保證了事務(wù)的原子性。

隔離性

事務(wù)的隔離性(Isolation)要求各個(gè)并行事務(wù)之間不能相互干擾,事務(wù)之間是隔離的。PostgreSQL可讀取的數(shù)據(jù)是xmin小于當(dāng)前的事務(wù)ID且已經(jīng)提交。對(duì)某個(gè)tuple進(jìn)行更新或刪除時(shí),其他事務(wù)讀取的就是這個(gè)tuple之前的版本。

MVCC的優(yōu)勢

讀寫不會(huì)相互阻塞,寫操作并沒有堵塞其他事務(wù)的讀,在寫事務(wù)未提交前,讀取的都是之前的版本,提高了并發(fā)的訪問效率。

事務(wù)可以快速回滾,操作后的tuple都帶有當(dāng)前事務(wù)ID,直接標(biāo)記clog文件中對(duì)應(yīng)事務(wù)的狀態(tài)就可達(dá)到回滾的目的。

MVCC帶來的問題

事務(wù)ID回卷問題

PostgreSQL也需要事務(wù)ID來確定事務(wù)的先后順序,PostgreSQL中,事務(wù)被稱為XID,獲取當(dāng)前XID:

  1. testdb=# select txid_current(); 
  2.  txid_current 
  3. -------------- 
  4.      80853335 
  5. (1 row) 

事務(wù)ID由32bit數(shù)字表示,當(dāng)事務(wù)ID用完時(shí),就會(huì)出現(xiàn)新的事務(wù)ID會(huì)比老ID小,導(dǎo)致事務(wù)ID回卷問題(Transaction

ID Wraparound)。 PostgreSQL的事務(wù)ID規(guī)則:

  • 0: InvalidXID,無效事務(wù)ID
  • 1: BootstrapXID,表示系統(tǒng)表初使化時(shí)的事務(wù)
  • 2: FrozenXID,凍結(jié)的事務(wù)ID,比任務(wù)普通的事務(wù)ID都舊。

– 大于2的事務(wù)ID都是普通的事務(wù)ID。

當(dāng)***和最舊事務(wù)之差達(dá)到2^31時(shí),就把舊事務(wù)換成FrozenXID,然后通過公式((int32)(id1 - id2)) < 0比較大小即可

垃圾數(shù)據(jù)問題

根據(jù)MVCC機(jī)制,更新和刪除的記錄都不會(huì)被實(shí)際刪除,操作頻繁的表會(huì)積累大量的過期數(shù)據(jù),占用磁盤空間,當(dāng)掃描查詢數(shù)據(jù)時(shí),需要更多的IO,降低查詢效率。PostgreSQL的解決方法是提供vacuum命令操作來清理過期的數(shù)據(jù)。

原文鏈接:https://www.qcloud.com/community/article/528634,作者:黃輝

【本文是51CTO專欄作者“騰訊云技術(shù)社區(qū)”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過51CTO聯(lián)系原作者獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2025-05-27 01:00:00

2017-08-17 17:09:28

PostgreSQL 數(shù)據(jù)塊機(jī)制

2025-12-02 07:02:33

2025-10-21 08:06:20

2023-10-31 10:51:56

MySQLMVCC并發(fā)性

2023-12-06 08:23:16

MVCCmysql

2024-08-12 14:37:38

2018-08-20 16:00:23

MySQL并發(fā)控制MVCC

2011-11-23 09:39:33

JavaClassLOader機(jī)制

2024-12-23 13:00:00

MySQLMVCC數(shù)據(jù)庫

2024-12-18 21:37:24

2010-01-25 18:24:11

C++

2011-03-16 09:26:41

ReadWriteLoJava

2010-04-26 10:44:27

Oracle SCN

2023-10-16 10:29:51

mysqlMVCC

2011-07-01 15:04:49

Qt 內(nèi)省

2021-07-07 21:07:16

PostgreSQL架構(gòu)容災(zāi)庫

2010-10-08 10:42:30

2023-11-08 14:21:51

Python拷貝

2011-04-07 17:54:22

Policing
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

色网站国产精品| 午夜久久久影院| 成人精品一区二区三区电影免费 | 亚洲国产精品影视| 狠狠综合久久av一区二区老牛| 欧美猛交免费看| 亚洲天堂一区二区| 制服丝袜亚洲色图| а√天堂中文在线资源bt在线| 亚洲一区日韩精品中文字幕| www亚洲成人| 国产日本欧洲亚洲| 激情五月开心婷婷| 波多野洁衣一区| 日韩国产小视频| 黄页视频在线91| 一区不卡视频| 九九九久久久精品| 艳母动漫在线免费观看| 石原莉奈一区二区三区在线观看| 国产精品加勒比| 欧美一区二区三区久久精品茉莉花| 日韩免费av一区二区| 亚洲制服欧美另类| 日本一本a高清免费不卡| 欧美日韩国产一区二区在线观看| 在线播放日韩欧美| 日韩在线你懂得| 久久视频在线观看免费| 国产精品国产亚洲精品| 精品中文字幕在线| 日韩高清在线免费观看| 奇米4444一区二区三区| 青草国产精品| 91国产在线播放| 亚洲无吗在线| 欧美日韩综合久久| 精品一区二区三区不卡| 999一区二区三区| 97se亚洲国产综合自在线不卡 | 精品国产美女| 成人午夜激情网| 红桃视频国产一区| 亚洲视频一区二区免费在线观看| 欧美少妇在线观看| gogo大胆日本视频一区| 男女视频在线看| 激情成人中文字幕| 国产日产一区二区三区| 亚洲精品999| 成人久久网站| 热门国产精品亚洲第一区在线| 亚洲国产精品成人| 欧美一区二区在线视频观看| 国产一区二区不卡| 美女黄色片视频| 亚洲最快最全在线视频| 国产黄色片在线观看| 日韩视频免费观看高清完整版在线观看| 国产91足控脚交在线观看| 亚洲视频自拍偷拍| 日韩a级大片| 国产私拍一区| 成人精品小蝌蚪| 九色视频一区| 日韩欧美www| 无码国模国产在线观看| 5566av亚洲| 国产成人精品免费| 360天大佬第二季在线观看| 在线电影欧美成精品| 激情小说亚洲| 亚洲自拍偷拍区| 国产成人免费av在线| 阳光姐妹淘韩国版| 日韩精品极品在线观看| 国产精品一在线观看| 日本一区二区精品| 亚洲欧洲av一区二区三区久久| 九七久久人人| 9.1国产丝袜在线观看| 视频一区在线播放| 日本一级黄视频| 欧美性猛交xxxx富婆| 成人影院在线免费观看| www.成人av| 日本一区二区免费在线观看视频| 欧美日本高清| 日本精品中文字幕| 国产成人日日夜夜| 国产玉足榨精视频在线观看| 日韩在线免费观看视频| 99国产精品视频免费观看一公开| 91视频免费版污| 精品福利一区二区三区免费视频| 视频国产一区| 九一国产精品视频| 日韩欧美一区二区视频| 欧美伦理在线视频| 亚洲色欲综合一区二区三区| 日韩一二三区视频| 日韩伦理一区| 中文字幕一区二区三区四区在线视频| 欧美本精品男人aⅴ天堂| 四季av在线一区二区三区| 久久久精品在线视频| 亚洲国产婷婷香蕉久久久久久| 999国产精品永久免费视频app| 国产免费视频传媒| 亚洲图片欧美日产| 肉色丝袜一区二区| 成人免费在线观看| 国产精品视频免费在线| 欧美国产激情二区三区| 日本在线中文字幕一区二区三区| 欧美综合激情| 欧美三级中文字| 亚洲成人最新网站| 91在线电影| 青草青草久热精品视频在线观看| 久久久综合网站| 欧美a一级片| 日本福利视频一区| 欧美精品一区二区高清在线观看| 国产精品观看| 韩国免费在线视频| 国产欧美日韩最新| 亚洲精品一二三| 久久a爱视频| 亚洲成熟丰满熟妇高潮xxxxx| 日本在线精品视频| 久久一区二区三区av| 美女精品视频| 成人三级毛片| 欧美一级成年大片在线观看 | fc2成人免费人成在线观看播放| 黄网站视频在线观看| 成人国产精品日本在线| 亚洲视频图片小说| 综合成人在线| 中文字幕在线观看第三页| 伊人一区二区三区久久精品| 久久66热偷产精品| 日韩电影毛片| 中文字幕日韩一区二区三区| 欧美videos大乳护士334| 国产日韩亚洲欧美精品| 伊人久久大香线蕉综合四虎小说| 东方欧美亚洲色图在线| free性欧美hd另类精品| 久久99精品久久久久久久久久| 亚洲mv在线观看| 国产高清一区二区| 蜜桃视频在线观看网站| 亚洲一区中文字幕在线观看| 狠狠色噜噜狠狠狠狠97| 国内精品美女在线观看| 黄av在线播放| 一区二区三区偷拍| 视频一区视频二区国产精品| 91在线你懂得| 97精品久久| 中午字幕在线观看| 高清日韩一区| 精品国产伦一区二区三区观看体验| 理论电影国产精品| 久久久久亚洲精品中文字幕| 福利在线免费| 精品国产福利| 亚洲美女视频网站| 久久人人爽爽爽人久久久| 天堂在线精品| 黄色片视频在线观看| 亚洲狠狠婷婷综合久久久| 一区二区三区视频观看| 国产精品色噜噜| 91视频久久| 超碰97国产精品人人cao| 黄色免费观看视频网站| 5566日本婷婷色中文字幕97| 天天操天天干天天综合网| 国产毛片久久| 深夜成人在线| 成人软件网18免费视频| 97视频中文字幕| 亚洲精品国产拍免费91在线| 久久欧美一区二区| 一区二区三区国产精华| 成人女同在线观看| 男人天堂成人在线| www.久久久| 少妇高潮久久久久久潘金莲| 日韩美女久久久| 亚洲女优在线| 日韩免费成人| 蜜桃av在线免费观看| 三级4级全黄60分钟| 国产亚洲欧美一区二区| 精品中文字幕在线| 欧美一个色资源|