资讯专栏INFORMATION COLUMN

聊聊PostgreSQL事务id那点事

IT那活儿 / 2537人阅读
聊聊PostgreSQL事务id那点事

点击上方“IT那活儿”,关注后了解更多精彩内容!!!


 01 

提到事务ID,就不得不提PostgreSQL的MVCC机制。

PostgreSQL没有类似于Oracle的undo来保证MVCC,其数据一致性通过使用一种多版本模型来维护。

这就意味着每个 SQL 语句看到的都只是一小段时间之前的数据快照,而不管底层数据的当前状态。

这样可以保护语句不会看到可能由其他在相同数据行上执行更新的并发事务造成的不一致数据,为每一个数据库会话提供事务隔离。

主要有如下特点:

A) 基于事务ID

B) ⾏级多版本,且都存储于页面内部

C) ⽆回滚段,⾏内存储

D) ⼀次update操作,产⽣记录的两个版本


 02 

MVCC元组结构如下:

Xmin: 插入该行版本或者回滚的事务ID。对一个逻辑行的每一次更新都将创建一个新的行版本。

Xmax: 删除事务或更新事务的事务ID,对于未删除的行版本为0。对于一个可见的行版本,该列值也可能为非零。这通常表示删除事务或更新事务还没有提交,或者一个删除或更新尝试被回滚。

Cmin: 插入事务中的命令标识符(从0开始)。

Cmax: 删除事务中的命令标识符,或者为0。

Ctid: 行版本在其表中的物理位置。注意尽管ctid可以被用来非常快速地定位行版本,但是一个行的ctid会在被更新或者被VACUUM FULL移动时改变。因此,ctid不能作为一个长期行标识符。应使用主键来标识逻辑行。


 03 

下面介绍下DML对应的MVCC信息:

Insert场景:

从上图我们可以看到insert时,xmin记录了新插入行的事务id,xmax为0。

接下来我们update来看看:

先在session A执行update。

session A没有提交或者回滚的情况下,在session B查看事务ID如下:

此时我们发现在可见的行版本中,xmin记录了回滚时的事务ID,xmax记录了更新事务ID。

当我们在session A commit之后,xmin的值就会变成该行更新时的事务ID值。

最后来看看delete:

先在session A执行delete。

session A没有提交或者回滚的情况下,在session B查看事务ID如下:

我们可以发现xmax记录的是delete时的事务id。在session A commit之后, id = 10这行已不可见。



 04 


从上述DML的事务ID来看,PostgreSQL事务可见性需要依赖行头的事务号,如果一个行版本的xmin(插入事务ID)小于或等于当前事务ID,那这个就相当于“过去的”事务,这是对其他session是可见的。


如果行版本的xmin(插入事务ID)大于当前事务id,那它是属于“未来的”,并且对当前事务是不可见。但是因为事务 ID 是32位的,且循环使用。一个长时间(超过 40 亿个事务)运行的集簇,XID 计数器回卷到 0,并且本来属于过去的事务突然间就变成了属于未来,这意味着之前的行均变成不可见。


这就是事务ID回卷问题,数据丢失。

为了避免发生这种情况,有必要至少每 20 亿个事务就清理每个数据库中的每个表。

事务ID复用图:

清理原理如下:

PostgreSQL保留了一个特殊的XID(FrozenTransactionId),这个XID并不遵循普通XID的比较规则 并且总是被认为比任何普通 XID要老。

这也意味着这个插入XID为FrozenTransactionId的行版本对于所有当前和未来事务来说当然都是可见的。

这个行为就被称之为冻结(freeze),由VACUUM去把行标记为冻结。

因此,一旦一个行版本被冻结,这样它们对所有普通事务来说都是“在过去”,而不管回卷问题。并且这样的行版本将一直有效直到被删除,不管它有多旧。


 05 

这里介绍下涉及冻结的三个重要参数:

参数一:vacuum_freeze_table_age

VACUUM通常会跳过不含有任何死亡行版本的页面,但是不会跳过那些含有带旧 XID 值的行版本的页面。要保证所有旧的行版本都已经被冻结,需要对整个表做一次扫描。

vacuum_freeze_table_age就是控制VACUUM什么时候这样做,如果该表经过vacuum_freeze_table_age减去vacuum_freeze_min_age个事务还没有被完全扫描过,则会强制一次全表清扫。 

官档建议vacuum_freeze_table_age设置成0.95 * autovacuum_freeze_max_age,因为0.95的乘数为在防回卷自动清理发生之前运行一次手动VACUUM留出了一些空间。

将它设置得太接近可能导致防回卷自动清理,即使该表最近因为回收空间的目的被清理过,而较低的值将导致更频繁的全表扫描。

参数二:autovacuum_freeze_max_age

任何包含比autovacuum_freeze_max_age配置参数所指定的年龄更老的 XID 的未冻结行的表上调用自动清理,即便自动清理被禁用,也会被强制开启。

参数三:vacuum_freeze_min_age

说的通俗点就是事务信息保留的时间,其控制在其行版本被冻结前一个 XID 值应该有多老。如果被冻结的行将很快会被再次修改,增加这个设置可以避免不必要的工作。

当然这个不能设置过小,因为它可能导致VACUUM做无用的工作:如果该行在被替换成FrozenXID之后很快就被修改(导致该行获得一个新的 XID),那么冻结一个行版本就是浪费时间。

因此该设置应该足够大,这样直到行不再可能被修改之前,它们都不会被冻结。

注:

VACUUM freeze操作涉及全表扫,对IO有一定影响,所以要尽量避免在高峰期自动触发。应该主动监控数据库年龄并在低峰期做VACUUM freeze。


 06 

vacuum freeze日常操作步骤:

1) 查询数据库年龄:

SELECT datname, age(datfrozenxid) FROM pg_database;

2) 查询指定表的年龄:

select relname, age(relfrozenxid) as xid_age, pg_size_pretty(pg_table_size(oid)) as table_size from 
pg_class where relname = test1;

3) 这查询按照最老的XID排序,查看大于1G而且是排名前20的表:

select relname, age(relfrozenxid) as xid_age, pg_size_pretty(pg_table_size(oid)) as table_size

from pg_class where relkind = r and pg_table_size(oid) > 1073741824

order by xid_age desc limit 20;

--vacuum前事务年龄为 61436

    relname | xid_age | table_size

----------------+---------+------------

 test_tab | 31260 | 4327 MB

4) 建议使用vacuum freeze来对指定的表进行xid 冻结清理:

vacuum full freeze xxx.xxxx;

--vacuum后事务年龄变为0

    relname | xid_age | table_size

----------------+---------+------------

 test_tab | 0 | 4327 MB




本 文 原 创 来 源:IT那活儿微信公众号(上海新炬王翦团队)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/129667.html

相关文章

  • 【第1期】聊聊css居中点事

    摘要:前言居中是网页布局中再常见不过的一种方式了,今天我们就来聊聊居中的那点事。我是水平居中的同样是针对块级元素才有效果。来看代码我是水平居中的必须配合来使用来可以实现居中的效果。方法二我是垂直居中的注意此方法要考虑的兼容性问题。 前言:居中是网页布局中再常见不过的一种方式了,今天我们就来聊聊css居中的那点事。 我们主要从这几个方面来了解下居中: 水平居中 垂直居中 水平垂直居中 水平...

    刘永祥 评论0 收藏0
  • 聊聊加密点事——PHP加密最佳实践

    摘要:所谓对称加密,就是加密和解密使用同一秘钥,这也是这种加密算法最显著的缺点之一。非对称加密算法由于对称加密在通信加密领域的缺陷,年和提出了非对称加密的概念。非对称加密,其主要缺点之一就是慢,适合加密少量数据。 1. 加密的目的 加密不同于密码,加密是一个动作或者过程,其目的就是将一段明文信息(人类或机器可以直接读懂的信息)变为一段看上去没有任何意义的字符,必须通过事先约定的解密规则才能将...

    lcodecorex 评论0 收藏0
  • 聊聊加密点事——PHP加密最佳实践

    摘要:所谓对称加密,就是加密和解密使用同一秘钥,这也是这种加密算法最显著的缺点之一。非对称加密算法由于对称加密在通信加密领域的缺陷,年和提出了非对称加密的概念。非对称加密,其主要缺点之一就是慢,适合加密少量数据。 1. 加密的目的 加密不同于密码,加密是一个动作或者过程,其目的就是将一段明文信息(人类或机器可以直接读懂的信息)变为一段看上去没有任何意义的字符,必须通过事先约定的解密规则才能将...

    Mr_zhang 评论0 收藏0
  • 文件下载点事

    摘要:不过这种方式有问题,目前查到的大部分过程都是会在服务器新建出一个文件,等下载完毕在做删除,还没有找到可以跨过这一步的方式。 showImg(https://segmentfault.com/img/remote/1460000018850368); Content-Disposition / Content-Type Content-Disposition http 头部的 Conte...

    PascalXie 评论0 收藏0
  • 我在全球最大的同性社交平台点事

    摘要:从最大的同性社交平台获取数据好了,言归正传,回到题目。乌云密布的爬虫百度网盘这件事,是我不想看到的,这类安全问题的一个共同特点用户自身确实存在问题。 本文作者:夏之冰雪,i春秋签约作家 《我在百度网盘上看到上万条车主个人信息,企业、政府高官信息、各种数据库和无穷无尽的盗版》,一时间,这篇文章就火了,火爆程度另百度猝不及防。 其实呢,这事真不能全怪百度,毕竟用户分享出去了。之所以引起这么...

    AlphaWatch 评论0 收藏0
  • 移动端开发:架构点事

    摘要:移动精英开发社群的第期,也是围绕架构这个话题进行讨论。本次我们希望结合实际开发中遇到的问题,来聊聊移动端的架构设计。这样的模式改进一些,可能会更适合移动端架构。潘卫杰之前我们公司移动端的大项目就是插座式开发的,批量出各个行业的。 此前,58 同城的技术委员会执行主席沈剑在 OneAPM 的技术公开课上分享过一个主题,「好的架构不是设计出来的,而是演技出来的」。因为对很多创业公司而言,随...

    KnewOne 评论0 收藏0

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<