Postgres并发控制之快照与MVCC
来源:互联网 发布:电脑程序编程培训 编辑:程序博客网 时间:2024/05/22 15:41
传统的基于锁的并发控制存在读事务(Reader)和写事务(Writer)相互阻塞的问题,为此Postgres引入了多版本并发控制机制,简称MVCC。一般说来,支持MVCC机制的数据库管理系统有着如下特点:
- 数据库管理系统能够得到元组的历史版本
- 数据库系统中存在判定元组版本对于处在特定上下文的事务是否有效的机制。简单地说,数据库通常会认为只有在事务执行开始之前就已提交的事务所生成的版本是有效的。为此,数据库系统需要记录元组的每个版本由哪个事务创建,以及这个事务是否在当前事务开始执行之前就已提交。
Postgres采用“快照”的方式来实现MVCC。数据库中每一个事务中的查询仅能看到:该事务启动之前已经提交的事务所作出的数据更改;当前事务中该查询之前的查询所作出的更改。Postgres中每一个版本的元组有两个ID,其中一个是CreationID即插入该元组的TransactionID,一个是ExpiredID,即删除或更新该元组的TransactionID。元组版本对一个Transaction可见,其ID要满足以下条件:
1.CreationID<当前TransactionID
2.ExpiredID>当前TransactionID或ExpiredID不存在
事务启动创建快照的过程简单说就是在事务启动的时刻,遍历当前所有活动的(还未提交)事务,记录在一个活动Transaction的ID数组中;选择所有活跃事务中最小的TransactionID,记录在xmin中,选择所有已提交事务中最大的TransactionID,加1后记录在xmax中。那么:
- 所有事务ID小于xmin的事务可以被认为已经完成,即事务已提交,其所做的修改对当前快照可见;
- 所有事务ID大于或等于xmax的事务可以被认为是正在执行,其所做的修改对当前快照不可见;
- 对于事务ID处在 [xmin, xmax)区间的事务, 需要结合活跃事务列表与事务提交日志CLOG,判断其所作的修改对当前快照是否可见;
struct HeapTupleHeaderData{union{HeapTupleFields t_heap;DatumTupleFields t_datum;}t_choice;ItemPointerData t_ctid;/* current TID of this or newer tuple *//* Fields below here must match MinimalTupleData! */uint16t_infomask2;/* number of attributes + various flags */uint16t_infomask;/* various flag bits, see below */uint8t_hoff;/* sizeof header incl. bitmap, padding *//* ^ - 23 bytes - ^ */bits8t_bits[1];/* bitmap of NULLs -- VARIABLE LENGTH *//* MORE DATA FOLLOWS AT END OF STRUCT */};
typedef struct HeapTupleFields{TransactionId t_xmin;/* inserting xact ID */TransactionId t_xmax;/* deleting or locking xact ID */union{CommandIdt_cid;/* inserting or deleting command ID, or both */TransactionId t_xvac;/* old-style VACUUM FULL xact ID */}t_field3;} HeapTupleFields;
typedef struct ItemPointerData{BlockIdData ip_blkid;OffsetNumber ip_posid;}
typedef struct HeapTupleData{uint32t_len;/* length of *t_data */ItemPointerData t_self;/* SelfItemPointer */Oidt_tableOid;/* table the tuple came from */HeapTupleHeader t_data;/* -> tuple header and data */} HeapTupleData;
元组头信息中的t_xmin和t_xmax分别表示创建此Tuple的XID 与删除此Tuple的XID,用于MVCC中的可见性判断。一般情况下,在同一个事务中创建并删除同一个元组的概率比较低,t_cid字段只需记录元组版本生效(或失效)命令ID即可。如果一个事务中确实创建并删除了同一个元组,则我们记录到两个命令组合的一个映射值即可。
BEGIN T1;INSERT INTO TEST_TABLE VALUES(A); // CommandId =0INSERT INTO TEST_TABLE VALUES(B); // CommandId =1DECLARE c1 CURSOR FOR SELECT * FROM TEST_TALBE;UPDATE TEST_TABLE SET ID=C WHERE ID=B; // CommandId =2END T1;<div style="text-align: center;"></div>
B被本事务创建同时也被本事务删除,所以B的xmin和xmax都是T1,为了标识B是被本事务的那条SQL创建和删除的,需要(cmin,cmax),其中cmin标识创建B的SQL语句,cmax标识删除B的SQL语句。但是在在内部数据结构中,cmin和cmax公用一个字段cmin_cmax,所以需要一个cmin_cmax到(cmin,cmax)的映射,同时为了区分cmin_cmax是一个映射还是cmin/cmax,必须要有一个标识,事实上它是由HeapTupleHeaderData的t_infomask标识的,即如果它是一个映射,则将t_infomask的相应位置为HEAP_COMBOCID。仍以上图2为例,值为1的CommandId被标识为映射(comboCid),它的映射值为(1,2),即表示第1条command创建了它,第2条command删除了它。
事务创建快照的入口函数是GetTransactionSnapshot,函数在查询执行exec_simple_query中被多处调用。例如当进行某些语法分析需要建立快照时:
- Postgres并发控制之快照与MVCC
- hbase的行锁与多版本并发控制(MVCC)
- postgres 并发控制
- MVCC 多版本并发控制
- 多版本并发控制MVCC
- Postgres 与Oracle对比(进程结构与并发控制)
- Postgres 数据库并发控制配置
- MySQL 架构 - MVCC多版本并发控制
- MySQL MVCC(多版本并发控制)
- MySQL InnoDB引擎 MVCC并发控制
- 【MySQL】MVCC(多版本并发控制)
- MVCC多版本并发控制浅析
- MySQL InnoDB引擎 MVCC并发控制
- innodb并发控制mvcc(多版本并发控制)
- MVCC(多版本并发控制,MultiVersion Concurrency Control)
- 多版本并发控制(MVCC)在分布式系统中的应用
- 多版本并发控制(MVCC)在分布式系统中的应用
- 多版本并发控制(MVCC)在分布式系统中的应用
- 动态规划求最大子段和
- mysql进阶(九)多表查询
- POJ 2777 Count Color(区间更新 + 状压)
- The summary of competition season
- zoj3886--Nico Number(素数筛+线段树)
- Postgres并发控制之快照与MVCC
- java设计模式之基本原则
- Mac开发者利器-Homebrew介绍及安装
- [UI]抽屉菜单DrawerLayout分析
- codevs1200 NOIP2012D2T1 同余方程
- poj 2503 map , 输入空一行怎么办
- PAT-Advanced Level- 1002 两个多项式相加
- numpy函数库中一些常用函数的记录
- NYOJ 95 众数问题(map练习)