成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Postgresql 探索MVCC

張利勇 / 1836人閱讀

摘要:分析對(duì)于的自身事務(wù)的一定是不可見(jiàn)對(duì)于自身事務(wù)的并且已經(jīng)提交的事務(wù)可見(jiàn)除外對(duì)于第一條規(guī)則很好判斷在自身事務(wù)之后的動(dòng)作一定是看不見(jiàn)的。第二條規(guī)則困難一些需要判斷一個(gè)事務(wù)是否提交可能還需判斷是否是。

Postgresql MVCC Postgresql的隱藏列

tableoid
是表對(duì)象的一個(gè)唯一標(biāo)識(shí)符,可以和pg_class中的oid聯(lián)合起來(lái)查看

xmin
是插入的事務(wù)標(biāo)識(shí)符,是用來(lái)標(biāo)識(shí)不同事務(wù)下的一個(gè)版本控制

xmax
是刪除更新的事務(wù)標(biāo)識(shí)符,如果該值不為0,則說(shuō)明該行數(shù)據(jù)當(dāng)前還未提交或回滾

cmin
插入事務(wù)的命令標(biāo)識(shí)符,從0開始

cmax
刪除事務(wù)的命令標(biāo)識(shí)符,或者為0

ctid
是每行數(shù)據(jù)在表中的一個(gè)物理位置標(biāo)識(shí)符

下面舉例說(shuō)明:

t1=# create table test (id integer, value text);
CREATE TABLE
t1=# insert into test values (1, "a"), (2, "aa"), (3, "aaa");
INSERT 0 3
t1=# select cmin,cmax,xmin,xmax,ctid, * from test;
 cmin | cmax |   xmin   | xmax | ctid  | id | value 
------+------+----------+------+-------+----+-------
    0 |    0 | 75066031 |    0 | (0,1) |  1 | a
    0 |    0 | 75066031 |    0 | (0,2) |  2 | aa
    0 |    0 | 75066031 |    0 | (0,3) |  3 | aaa
(3 rows)

 xmin: 75066031 是插入數(shù)據(jù)的事務(wù)id
 xmax: 0 表示已經(jīng)提交了
 ctid: (0, 1), (0, 2), (0, 3)是tuple 所在table中的位置
 
 t1=# begin;
 BEGIN
 t1=# select tableoid from test;
    tableoid 
 ----------
    96972
    96972
    96972
 (3 rows)

t1=# insert into test values (4, "b");
INSERT 0 1
t1=# insert into test values (5, "bb");
INSERT 0 1
t1=# insert into test values (6, "bbb");
INSERT 0 1
t1=# select cmin,cmax,xmin,xmax,ctid, * from test;
cmin | cmax |   xmin   | xmax | ctid  | id | value 
------+------+----------+------+-------+----+-------
0 |    0 | 75066031 |    0 | (0,1) |  1 | a
0 |    0 | 75066031 |    0 | (0,2) |  2 | aa
0 |    0 | 75066031 |    0 | (0,3) |  3 | aaa
0 |    0 | 75066040 |    0 | (0,4) |  4 | b
1 |    1 | 75066040 |    0 | (0,5) |  5 | bb
2 |    2 | 75066040 |    0 | (0,6) |  6 | bbb
(6 rows)

t1=# commit;
COMMIT

tableoid: 是表的oid
探索postgresql MVCC 原理
首先打開兩個(gè)psql
t1=# begin;
BEGIN
t1=# select cmin,cmax,xmin,xmax,ctid, * from test;
cmin | cmax |   xmin   | xmax | ctid  | id | value 
------+------+----------+------+-------+----+-------
0 |    0 | 75066031 |    0 | (0,1) |  1 | a
0 |    0 | 75066031 |    0 | (0,2) |  2 | aa
0 |    0 | 75066031 |    0 | (0,3) |  3 | aaa
0 |    0 | 75066040 |    0 | (0,4) |  4 | b
1 |    1 | 75066040 |    0 | (0,5) |  5 | bb
2 |    2 | 75066040 |    0 | (0,6) |  6 | bbb
(6 rows)

t1=# update test set value = "c" where id = 4;
UPDATE 1
t1=# select cmin,cmax,xmin,xmax,ctid, * from test;
cmin | cmax |   xmin   | xmax | ctid  | id | value 
------+------+----------+------+-------+----+-------
0 |    0 | 75066031 |    0 | (0,1) |  1 | a
0 |    0 | 75066031 |    0 | (0,2) |  2 | aa
0 |    0 | 75066031 |    0 | (0,3) |  3 | aaa
1 |    1 | 75066040 |    0 | (0,5) |  5 | bb
2 |    2 | 75066040 |    0 | (0,6) |  6 | bbb
0 |    0 | 75066045 |    0 | (0,7) |  4 | c
(6 rows)
t1=# select txid_current();
txid_current 
--------------
    75066045
(1 row)

從上面的數(shù)據(jù)可以看出當(dāng)數(shù)據(jù)庫(kù)做一個(gè)更新操作時(shí),并不是將老的數(shù)據(jù)刪除,再將新的數(shù)據(jù)覆蓋上去,相反它會(huì)把老的數(shù)據(jù)做一個(gè)標(biāo)記隔離出去,然后再新增新的數(shù)據(jù)作為一個(gè)新的版本

現(xiàn)在看另一個(gè)psql
t1=# begin;
BEGIN
t1=# select cmin,cmax,xmin,xmax,ctid, * from test;
 cmin | cmax |   xmin   |   xmax   | ctid  | id | value 
------+------+----------+----------+-------+----+-------
0 |    0 | 75066031 |        0 | (0,1) |  1 | a
0 |    0 | 75066031 |        0 | (0,2) |  2 | aa
0 |    0 | 75066031 |        0 | (0,3) |  3 | aaa
0 |    0 | 75066040 | 75066045 | (0,4) |  4 | b
1 |    1 | 75066040 |        0 | (0,5) |  5 | bb
2 |    2 | 75066040 |        0 | (0,6) |  6 | bbb
(6 rows)


從上面的數(shù)據(jù)逆推當(dāng)Update時(shí)postgres 至少做三個(gè)動(dòng)作
1. copy olddata to newplace
2. update data
3. add new transaction id to old data xmax

postgresq Delete 會(huì)更簡(jiǎn)單一些只需要在tuple 上做一個(gè)標(biāo)記.

既然postgres不會(huì)直接在olddata上修改,又是如何對(duì)這些tuple做隔離的呢? 簡(jiǎn)而言之postgres 如何判斷這些tuple 是否對(duì)一個(gè)事務(wù)可見(jiàn)。
分析:
1. 對(duì)于tuple 的 xmin > 自身事務(wù)id 的row 一定是不可見(jiàn)
2. 對(duì)于tuple xmin < 自身事務(wù)id 的row并且已經(jīng)提交的事務(wù)可見(jiàn)(deleted tuple 除外)

對(duì)于第一條規(guī)則很好判斷(在自身事務(wù)之后的動(dòng)作一定是看不見(jiàn)的)。 第二條規(guī)則困難一些需要判斷一個(gè)事務(wù)是否提交,(可能還需判斷tuple是否是deleted。因?yàn)閜ostgresql vacuum 是異步刪除deleted tuple)
對(duì)于這個(gè)問(wèn)題postgres在tuple的header 里加入一個(gè)屬性 t_infomask 用于標(biāo)記transaction的狀態(tài).
Extension Pageinspect
select * from pg_available_extensions;
create extension pageinspect;
t1=# begin;
BEGIN
t1=# select cmin,cmax,xmin,xmax,ctid, * from test;
 cmin | cmax |   xmin   | xmax | ctid  | id | value 
------+------+----------+------+-------+----+-------
    0 |    0 | 75066031 |    0 | (0,1) |  1 | a
    0 |    0 | 75066031 |    0 | (0,2) |  2 | aa
    0 |    0 | 75066031 |    0 | (0,3) |  3 | aaa
    1 |    1 | 75066040 |    0 | (0,4) |  5 | bb
    2 |    2 | 75066040 |    0 | (0,5) |  6 | bbb
    0 |    0 | 75066110 |    0 | (0,6) |  4 | b
(6 rows)

t1=# SELECT * FROM heap_page_items(get_raw_page("test", 0));
 lp | lp_off | lp_flags | lp_len |  t_xmin  | t_xmax | t_field3 | t_ctid | t_infomask2 | t_infomask | t_hoff | t_bits | t_oid 
----+--------+----------+--------+----------+--------+----------+--------+-------------+------------+--------+--------+-------
  1 |   8160 |        1 |     30 | 75066031 |      0 |        0 | (0,1)  |           2 |       2818 |     24 |        |      
  2 |   8128 |        1 |     31 | 75066031 |      0 |        0 | (0,2)  |           2 |       2818 |     24 |        |      
  3 |   8096 |        1 |     32 | 75066031 |      0 |        0 | (0,3)  |           2 |       2818 |     24 |        |      
  4 |   8064 |        1 |     31 | 75066040 |      0 |        1 | (0,4)  |           2 |       2818 |     24 |        |      
  5 |   8032 |        1 |     32 | 75066040 |      0 |        2 | (0,5)  |           2 |       2818 |     24 |        |      
  6 |   8000 |        1 |     30 | 75066110 |      0 |        0 | (0,6)  |           2 |      11010 |     24 |        |      
(6 rows)

t1=# update test set value = "c" where id = 4;
UPDATE 1
t1=# SELECT * FROM heap_page_items(get_raw_page("test", 0));
 lp | lp_off | lp_flags | lp_len |  t_xmin  |  t_xmax  | t_field3 | t_ctid | t_infomask2 | t_infomask | t_hoff | t_bits | t_oid 
----+--------+----------+--------+----------+----------+----------+--------+-------------+------------+--------+--------+-------
  1 |   8160 |        1 |     30 | 75066031 |        0 |        0 | (0,1)  |           2 |       2818 |     24 |        |      
  2 |   8128 |        1 |     31 | 75066031 |        0 |        0 | (0,2)  |           2 |       2818 |     24 |        |      
  3 |   8096 |        1 |     32 | 75066031 |        0 |        0 | (0,3)  |           2 |       2818 |     24 |        |      
  4 |   8064 |        1 |     31 | 75066040 |        0 |        1 | (0,4)  |           2 |       2818 |     24 |        |      
  5 |   8032 |        1 |     32 | 75066040 |        0 |        2 | (0,5)  |           2 |       2818 |     24 |        |      
  6 |   8000 |        1 |     30 | 75066110 | 75066121 |        0 | (0,7)  |       16386 |       8962 |     24 |        |      
  7 |   7968 |        1 |     30 | 75066121 |        0 |        0 | (0,7)  |       32770 |      10242 |     24 |        |      
(7 rows)

t1=# select cmin,cmax,xmin,xmax,ctid, * from test;
 cmin | cmax |   xmin   | xmax | ctid  | id | value 
------+------+----------+------+-------+----+-------
    0 |    0 | 75066031 |    0 | (0,1) |  1 | a
    0 |    0 | 75066031 |    0 | (0,2) |  2 | aa
    0 |    0 | 75066031 |    0 | (0,3) |  3 | aaa
    1 |    1 | 75066040 |    0 | (0,4) |  5 | bb
    2 |    2 | 75066040 |    0 | (0,5) |  6 | bbb
    0 |    0 | 75066121 |    0 | (0,7) |  4 | c
(6 rows)

t1=# select txid_current();
 txid_current 
--------------
 75066121
(1 row)

Vacuum internals 文章實(shí)在太好了
Postgres Hint Bits

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/38954.html

相關(guān)文章

  • 關(guān)系型數(shù)據(jù)庫(kù)中的事務(wù)管理詳解:并發(fā)控制與事務(wù)日志

    摘要:關(guān)系型數(shù)據(jù)庫(kù)中的事務(wù)管理詳解并發(fā)控制與事務(wù)日志數(shù)據(jù)庫(kù)系統(tǒng)的萌芽出現(xiàn)于年代。并發(fā)控制并發(fā)控制旨在針對(duì)數(shù)據(jù)庫(kù)中對(duì)事務(wù)并行的場(chǎng)景,保證中的一致性與隔離性。絕大部分?jǐn)?shù)據(jù)庫(kù)會(huì)采用鎖或者數(shù)據(jù)版本控制的方式來(lái)處理并發(fā)控制問(wèn)題。 本文節(jié)選自:關(guān)系型數(shù)據(jù)庫(kù)理論 https://url.wx-coder.cn/DJNQn ,涉及引用/整理的文章列舉在了 Database-List。 showImg(htt...

    Pink 評(píng)論0 收藏0
  • 關(guān)系型數(shù)據(jù)庫(kù)中的事務(wù)管理詳解:并發(fā)控制與事務(wù)日志

    摘要:關(guān)系型數(shù)據(jù)庫(kù)中的事務(wù)管理詳解并發(fā)控制與事務(wù)日志數(shù)據(jù)庫(kù)系統(tǒng)的萌芽出現(xiàn)于年代。并發(fā)控制并發(fā)控制旨在針對(duì)數(shù)據(jù)庫(kù)中對(duì)事務(wù)并行的場(chǎng)景,保證中的一致性與隔離性。絕大部分?jǐn)?shù)據(jù)庫(kù)會(huì)采用鎖或者數(shù)據(jù)版本控制的方式來(lái)處理并發(fā)控制問(wèn)題。 本文節(jié)選自:關(guān)系型數(shù)據(jù)庫(kù)理論 https://url.wx-coder.cn/DJNQn ,涉及引用/整理的文章列舉在了 Database-List。 showImg(htt...

    haobowd 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<