PostgreSQLMVCC源码的示例分析-创新互联

这篇文章主要为大家展示了“PostgreSQL MVCC源码的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“PostgreSQL MVCC源码的示例分析”这篇文章吧。

专注于为中小企业提供成都做网站、成都网站设计服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业石台免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了成百上千企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。

      MVCC对每一个DBA来讲,都不陌生,即多版本控制(Multi-Version-Control)。正因为数据有了多个版本,才实现了读和写在一定程度上的分离,提高数据库每秒处理查询的能力(QPS)。

用户发起的普通查询请求(不包含select … for update语句),并不堵塞DML事务。在Read Commit事务隔离级别时,查询请求只读取查询请求之前已经提交的事务的数据更改,对当前版本的数据并不影响;

而DML语句,会操作当前版本。因此做到了读写分离的目的,提高数据库并发能力。

      不同的数据库,实现MVCC的方法不同。Oracle和MySQL Innodb 存储引擎类似的使用undo来实现。

      对于PostgreSQL数据库来讲,他没有undo,那么,PG又是怎么来实现他自己的MVCC呢?又有那些优缺点呢?

     PG用copy tuple和tuple的xmin,xmax,cmin,cmax等标记来实现多版本。

     xmin:在创建记录(tuple)时,记录此时,后面每次update也会更新。

     xmax: 在删除tuple或者lock时,记录此时;如果记录没有被删除,那么此时为0。

     cmin和cmax:主要为标识在同一个事务中多个语句命令的序列值。用于同一个事务中实现版本可见性判断。

1.下面我们先来看一下xmin和xmax的变化:

PostgreSQL MVCC源码的示例分析

从上图可以看出,4条记录的xmin是一样的,都是“390689”,这说明是在同一个事务中创建的。另外xmax都为“0”,说明都没有被删除。cmin和cmax都是1,说明是同一个命令创建的。

接下来,我们update一下id为1的记录,看发生什么情况:

update之后,并没有提交,重新开起另外一个窗口,查询:

PostgreSQL MVCC源码的示例分析

我们看到,ID为1的记录,只有xmin没有变化,其它三个值都发生了变化,其中xmax变成了”390691”。

然后我把事务提交掉,再在新窗口中查询:

PostgreSQL MVCC源码的示例分析

我们看到,提交后,ID 为1的记录,xmin变为“390691”,xmin增加了1;而xmax变成了0。

从上面的案例中,我们从表面上可以看出,xmin增加了。但是事实上,PostgreSQL在底层所做的事情,远比这个要多。底层已经生成了一个新版本的tuple,新版本tuple的xmin等于老版本的xmax。

详细的internal,我后面再展开讲。

2.我们再来看一下cmin和cmax的变化:

我起一个事务,包含两条update,一条update ID值为2的记录,一条insert ID值为3的记录:

PostgreSQL MVCC源码的示例分析

事务“390694”中,cmin和cmax的值,依次递增。从目前来看cmin和cmax实际上是同一个field。

源码定义如下,用union实现了CommandId,是一个combo command id。

PostgreSQL MVCC源码的示例分析

因此,从上面的例子来看,PostgreSQL的mvcc实现是比较简单的。只需要通过对比tuple header中xmin,xmax,cmin,cmax与当前的xid,就可以得到在scan tuple时,此tuple对于当前查询的可视性。

可见性判断逻辑:

PostgreSQL MVCC源码的示例分析

但是也带来了另外一个问题:就是在没有undo的情况下,会导致空间的增长。因此PostgreSQL引入了vacumm后台进程,来定期清理这些 DEAD tuple。

以上是“PostgreSQL MVCC源码的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联-成都网站建设公司行业资讯频道!


分享文章:PostgreSQLMVCC源码的示例分析-创新互联
当前路径:http://scyanting.com/article/shcdi.html