PG课堂笔记-第12课MVCC机制

mvcc机制

写新数据时,旧数据不删除,而是把新数据插入,将旧数据标记为无效,PostgreSQL就是使用的这种实现方法,新老数据存放在一起,在被清理之前,会一直占据着空间,所以会导致膨胀。
两种方法各有利弊,相对于第一种来说,PostgreSQL的MVCC实现方式优缺点如下:

优点

优点
1.无论事务进行了多少操作,事务回滚可以立即完成,Oracle中使用了回滚段,如Oracle数据库宕机时如果有很多事务正在运行,这时数据库再启动后,需要把之前的事务做回滚,当没有回滚完成时,数据行上仍然有锁的,这时业务仍然不能正常操作,如果恰好碰到要回滚一些很大的事务,情况会更坏。
2.数据可以进行很多更新,不必像Oracle和MySQL的Innodb引擎那样需要经常保证回滚段不会被用完,也不会像oracle数据库那样经常遇到“ORA-1555”错误的困扰

缺点

1.旧版本的数据需要清理。好在在v8.3中,PostgreSQL引入了自动化的autovacuum,采用多进程架构,支持多表同时操作2.旧版本的数据可能会导致查询需要扫描的数据块增多,从而导致查询变慢
3.空间持续上涨,存储没有被有效利用

事务标识

postgres=# begin;
BEGIN
postgres=*# select txid_current();
 txid_current 
--------------
          756
(1 row)
​

特殊事务标识:

0:InvalidTransactionId,表示无效的事务ID
1:BootstrapTransactionId,表示系统表初始化时的事务ID,比任何普通的事务ID都旧。
2:FrozenTransactionId,冻结的事务ID,比任何普通的事务ID都旧。
大于2的事务ID都是普通的事务ID。

代码逻辑

/*
*TransactionIdPrecedes---isid1logically<id2?
*/
bool
TransactionIdPrecedes(TransactionIdid1,TransactionIdid2){

对比逻辑

*IfeitherIDisapermanentXIDthenwecanjustdounsigned
*comparison.Ifbotharenormal,doamodulo-2^32comparison.*/
​
int32 diff;
​
if(!TransactionIdIsNormal(id1)||!TransactionIdIsNormal(id2))
return(id1<id2);diff=(int32)(id1-id2);
return(diff<0);
​
txid可以相互比较大小。例如对于txid=100的事务,大于100的txid属于“未来”,且对于txid=100的事务而言都是不可见(invisible)的;小于100的txid属于“过去”,且对该事务可见,如图5.1(a)所示。
​
因为txid在逻辑上是无限的,而实际系统中的txid空间不足(4字节取值空间约42亿),因此PostgreSQL将txid空间视为一个环。对于某个特定的txid,其前约21亿个txid属于过去,而其后约21亿个txid属于未来。如图5.1(b)所示。
​
所谓的txid回卷问题将在5.10.1节中介绍。

image-20231228100150024

元组结构

image-20231228101133365

虽然HeapTupleHeaderData结构包含七个字段,但后续部分中只需要了解四个字段即可。
​
t_xmin保存插入此元组的事务的txid。
t_xmax保存删除或更新此元组的事务的txid。如果尚未删除或更新此元组,则t_xmax设置为0,即无效。
t_cid保存命令标识(command id, cid),cid意思是在当前事务中,执行当前命令之前执行了多少SQL命令,从零开始计数。例如,假设我们在单个事务中执行了三条INSERT命令BEGIN;INSERT;INSERT;INSERT;COMMIT;。如果第一条命令插入此元组,则该元组的t_cid会被设置为0。如果第二条命令插入此元组,则其t_cid会被设置为1,依此类推。
t_ctid保存着指向自身或新元组的元组标识符(tid)。如第1.3节中所述,tid用于标识表中的元组。在更新该元组时,其t_ctid会指向新版本的元组;否则t_ctid会指向自己。

元组的增删改查

image-20231228101516841

插入操作

插入操作的过程和结果分析:
t_xmin被设置为99,表示插入该元组的txid
t_xmax被设置为0,因为该元组还未被更新或删除过
t_cid被设置为0,因为这是该事务的第一条命令
t_ctid指向自身,被设置为(0,1),表示该元组位于0号page的第1个位置上

删除操作

删除操作的过程和结果分析
t_xmin不变,也是99,
t_xmax变成为111,因为是删除操作
t_cid被设置为0,因为这是该事务的第一条命令
t_ctid指向自身,被设置为(0,1),表示该元组位于0号page的第1个位置上
当txid=111的事务提交时,tuple_1就不再需要了,称为dead tuple.但是这个dead tuple依然还是在这个page上,随着数据库的运行,这种死元组越来越多,他们会在vacuum时最终被清理掉。

更新操作

更新操作过程和结果分析
看第一条tuple
t_xmin不变,也是99,
t_xmaix变成为100,这个是删除操作,
t_cid t_cid被设置为0,因为这是该事务的第一条命令
t_ctid指向自身,被设置为(0,2),表示该元组位于0号page的第2个位置上
接着插入一条新数据
t_xmin,也是100,
t_xmaix变成为0,因为没有删除操作
t_cid被设置为0,因为这是该事务的第一条命令
t_ctid指向自身,被设置为(0,2),表示该元组位于0号page的第2个位置上
再来看第二天tuple
Tuple_2
t_xmin 不变,表示插入该元组的txid
t_xmax 被设置为100,即删除该元组的txid
t_cid 被设置为1,因为这是该事务的第二条命令
t_ctid 指向新版本元组,被设置为(0,3),表示新元组位于0号page的第3个位置上
Tuple_3
t_xmin 被设置为100,表示插入该元组的txid
t_xmax 被设置为0,因为该元组还未被更新或删除过
t_cid 被设置为1,因为这是该事务的第二条命令

xmin,xmax 与 t_xmin,t_xmax 的区别:

​
1、xmin,xmax 最早事务和最晚事务 , select txid_current_snapshot();
使用场景:MVCC事务可见性场景用到。
2、t_xmin,t_xmax  插入改元组的txid,和删除更新改元组的txid,那请问txid是什么呢?txid也就是当前事务 ID ,通过 select txid_current();  获取
使用场景:DML 语句中用到。
​
补充一点:只读事务使用的是虚拟ID,用 select txid_current_if_assigned(); 

参考博客:https://www.cnblogs.com/flying-tiger/p/9567213.html

作者公众号

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MySQLMVCC(Multi-Version Concurrency Control)机制是一种并发控制机制,用于处理并发事务的读写冲突。它通过为每个事务创建一个独立的版本,并使用这些版本来提供对数据的一致性读取,从而实现并发控制。 MVCC机制在MySQL中的实现主要依赖于以下两个重要的组件: 1. Undo日志:MySQL使用undo日志记录数据修改操作的旧值。当一个事务开始时,MySQL会将当前数据行的快照复制到undo日志中。如果其他事务需要读取该数据行,它将读取这个快照而不受正在进行的事务的影响。 2. Read View:Read View是一个事务的快照视图,用于确定哪些数据行是对当前事务可见的。每个事务在开始时都会创建一个Read View。Read View包含一个活动事务列表和一个已提交事务列表。活动事务列表包含当前正在运行的活动事务,已提交事务列表包含已经提交的事务。当一个事务需要读取数据时,它会根据Read View确定哪些数据行是可见的。 基于这两个组件,MVCC机制提供了以下几个特点: 1. 高并发性:MVCC机制允许多个事务并发地读取和修改数据,因为它们之间不会产生读写冲突。 2. 一致性读取:MVCC机制确保事务只能读取已经提交的数据,避免了脏读和不可重复读的问题。 3. 无锁读取:MVCC机制的读取操作不会阻塞写入操作。读取操作只需要根据Read View判断数据是否可见。 需要注意的是,MVCC机制只适用于InnoDB存储引擎,而不适用于其他存储引擎,如MyISAM。另外,MVCC机制在一些特殊情况下可能会导致存储空间的增加,因为每个事务都会创建一个版本。因此,在设计数据库时需要考虑这些因素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_26009505

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值