暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgresQL MVCC 机理与 还得学习

AustinDatabases 2019-09-04
554

昨天写了些 MYSQL MVCC ,今天就的搞搞 PostgresQL 的MVCC ,最近从某些网站上获得的信息,PostgresQL的 相关人员的需求量在国内开始增加,但和需求相比,会的人少,所以你懂得。


昨天已经说过了,个人浅薄的认为MVCC 主要解决的问题 

1   读不影响写

2   写不影响读

PostgreSQL 在这方面是做的不错的,基于ORACLE 与 MYSQL 是采用 UNDO log 来进行的,而PostgreSQL 则是在表的存储结构中将数据的版本信息进行存储。

这里可以先给一个前提,ORACLE ,MYSQL 都是有 UNDO 表空间的,而 POSTGRESQL 则没有,并且POSTGRESQL 回滚也是立即的,那 postgresql 到底是怎么完成没有UNDO 表空间的情况下,进行数据 UNDO 和MVCC的。


下面我们做一个实验来看看


1  我们在 POSTGRESQL 中建立一个test 数据库,并且在数据库中建立一个一个test 表。


2  我们查看当前的事务号是多少

Select TXID_CURRENT();

646

3  我们在一个事务中开始下面的操作

Begin

然后插入记录,查看当前的事务号,并查看当前 test 表中,隐藏的四个字段值,其中仅仅是 xmin 变化了,变为插入数据之前的事务号  647

后我们开始在插入一些记录,因为是在一个事务中的,所以再次插入记录事务号是不变的,但在事务号中标记事务次序的 cmin  cmax 有了变化。

我们对刚才的第一条记录进行UPATE 的操作,可以很清晰的看到第一行的在数据表中的位置有了变化(postgresql  UPDATE   不是在原记录上更新而是插入一条新的记录,删除老的记录的方式),同时 cmin  cmax 也变化了,说明update 是在insert 的操作之后

上面的实验,证明了事务中对事务中产生的行是有唯一的事务号标记的,并且,在事务中对行的变化,是有相关顺序标记来进行记录的。


到这里还是没有说到 MVCC  是怎通过上述的方式来进行多版本的控制。


我们继续做实验,我们对刚才的 test 表的 ID =1 的记录进行 update

我们可以发现ID=1 的事务号已经变化了


那多版本的控制是怎么体现的


我们做如下实验,两个事务


事务1 


更新第一行数据        数据行的  xmin  进行变化


事务2  查看同样表的数据,发现被事务1 修改的行的 xmax 为事务一中的xmin的值

 

以上就证明了文字中开头的两点


1  读对写不阻塞

2  写对读不阻塞


但写对写就产生了锁等待,PG 默认来说是无限的等待,如果你不想这样,可以对 lock_timeout 进行设置

则在碰上在两个事务中,对同一个行进行操作,最后会将后面的事务对这行的操作直接cancel 掉。



PG 的这样设计的优点对比 ORACLE  MYSQL 就是不会出现 UNDO 空间不够用的情况,同时回滚的速度也是很快,但这样的设计也会产生PG 独有的表膨胀需要vacuum 来进行废弃行的清理,并且事务比较大的情况,则发生表膨胀的情况会更严重,所以从礼拜 1  到 礼拜 3  SQL SERVER , MYSQL , PG 这三种数据库我们都可以看到一个问题,就是事务的大小,对系统的性能的影响。所以不是光 MYSQL 需要小事务, SQL SERVER  ,PG  也是需要控制你的事务大小的。


从多种数据库的学习中,可以发现异同点,越学,越会发现不同设计理念的优点和不足,所以“药”不能停。



最后修改时间:2019-11-22 17:37:39
文章转载自AustinDatabases,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论