PostgreSQL 大表自动 freeze 优化思路

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: PostgreSQL 的版本冻结是一个比较蛋疼的事情,为什么要做版本冻结呢?因为PG的版本号是uint32的,是重复使用的,所以每隔大约20亿个事务后,必须要冻结,否则记录会变成未来的,对当前事务"不可见"。冻结的事务号是2 src/include/access/transam.h #def

有没有被突发的IO惊到过,有没有见到过大量的autovacuum for prevent wrap。
本文依依解开这些头痛的问题。

PostgreSQL 的版本冻结是一个比较蛋疼的事情,为什么要做版本冻结呢?
因为PG的版本号是uint32的,是重复使用的,所以每隔大约20亿个事务后,必须要冻结,否则记录会变成未来的,对当前事务"不可见"。
冻结的事务号是2

src/include/access/transam.h
#define InvalidTransactionId            ((TransactionId) 0)
#define BootstrapTransactionId          ((TransactionId) 1)
#define FrozenTransactionId                     ((TransactionId) 2)
#define FirstNormalTransactionId        ((TransactionId) 3)
#define MaxTransactionId                        ((TransactionId) 0xFFFFFFFF)



现在,还可以通过行的t_infomask来区分行是否为冻结行

src/include/access/htup_details.h
/*
 * information stored in t_infomask:
 */
#define HEAP_XMIN_COMMITTED             0x0100  /* t_xmin committed */
#define HEAP_XMIN_INVALID               0x0200  /* t_xmin invalid/aborted */
#define HEAP_XMIN_FROZEN                (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)



表的最老事务号则是记录在pg_class.relfrozenxid里面的。
执行vacuum freeze table,除了修改t_infomask,还需要修改该表对应的pg_class.relfrozenxid的值。


那么系统什么时候会触发对表进行冻结呢?
当表的年龄大于autovacuum_freeze_max_age时(默认是2亿),autovacuum进程会自动对表进行freeze。
freeze后,还可以清除掉比整个集群的最老事务号早的clog文件。
那么可能会出现这样的情形:
可能有很多大表的年龄会先后到达2亿,数据库的autovacuum会开始对这些表依次进行vacuum freeze,从而集中式的爆发大量的读IO(DATAFILE)和写IO(DATAFILE以及XLOG)。
如果又碰上业务高峰,会出现很不好的影响。


为什么集中爆发很常见?
因为默认情况下,所有表的autovacuum_freeze_max_age是一样的,并且大多数的业务,一个事务或者相邻的事务都会涉及多个表的操作,所以这些大表的最老的事务号可能都是相差不大的。
这样,就有非常大的概率导致很多表的年龄是相仿的,从而导致集中的爆发多表的autovacuum freeze。


PostgreSQL有什么机制能尽量的减少多个表的年龄相仿吗?
目前来看,有一个机制,也许能降低年龄相仿性,但是要求表有发生UPDATE,对于只有INSERT的表无效。
vacuum_freeze_min_age 这个参数,当发生vacuum或者autovacuum时,扫过的记录,只要年龄大于它,就会置为freeze。因此有一定的概率可以促使频繁更新的表年龄不一致。


那么还有什么手段能放在或者尽量避免大表的年龄相仿呢?
为每个表设置不同的autovacuum_freeze_max_age值,从认为的错开来进行vacuum freeze的时机。
例如有10个大表,把全局的autovacuum_freeze_max_age设置为5亿,然后针对这些表,从2亿开始每个表间隔1000万事务设置autovacuum_freeze_max_age。 如2亿,2.1亿,2.2亿,2.3亿,2.4亿....2.9亿。
除非这些表同时达到 2亿,2.1亿,2.2亿,2.3亿,2.4亿....2.9亿。 否则不会出现同时需要vacuum freeze的情况。


但是,如果有很多大表,这样做可能就不太合适了。
建议还是人为的在业务空闲时间,对大表进行vacuum freeze。

建议

  1. 分区,把大表分成小表。每个表的数据量取决于系统的IO能力,前面说了VACUUM FREEZE是扫全表的, 现代的硬件每个表建议不超过32GB。
  2. 对大表设置不同的vacuum年龄.
  3. table t set (autovacuum_freeze_max_age=xxxx);
  4. 用户自己调度 freeze,如在业务低谷的时间窗口,对年龄较大,数据量较大的表进行vacuum freeze。
  5. 年龄只能降到系统存在的最早的长事务即 min pg_stat_activity.(backend_xid, backend_xmin)。 因此也需要密切关注长事务。
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
6月前
|
SQL 关系型数据库 测试技术
沉浸式学习PostgreSQL|PolarDB 20: 学习成为数据库大师级别的优化技能
在上一个实验《沉浸式学习PostgreSQL|PolarDB 19: 体验最流行的开源企业ERP软件 odoo》 中, 学习了如何部署odoo和polardb|pg. 由于ODOO是非常复杂的ERP软件, 对于关系数据库的挑战也非常大, 所以通过odoo业务可以更快速提升同学的数据库优化能力, 发现业务对数据库的使用问题(如索引、事务对锁的运用逻辑问题), 数据库的代码缺陷, 参数或环境配置问题, 系统瓶颈等.
764 1
|
22天前
|
存储 JSON 关系型数据库
PostgreSQL Json应用场景介绍和Shared Detoast优化
PostgreSQL Json应用场景介绍和Shared Detoast优化
|
3月前
|
弹性计算 关系型数据库 数据库
开源PostgreSQL在倚天ECS上的最佳优化实践
本文基于倚天ECS硬件平台,以自顶向下的方式从上层应用、到基础软件,再到底层芯片硬件,通过应用与芯片的硬件特性的亲和性分析,实现PostgreSQL与倚天芯片软硬协同的深度优化,充分使能倚天硬件性能,帮助开源PostgreSQL应用实现性能提升。
|
7月前
|
SQL 弹性计算 测试技术
如何在PolarDB-X中优化慢SQL
《PolarDB-X动手实践》系列第六期,本场景带您体验如何使用PolarDB-X提供的解决慢SQL的相关工具。
733 0
|
8月前
|
存储 Java 测试技术
深度优化 | PolarDB-X 基于向量化SIMD指令的探索
本文将介绍PolarDB-X对于向量化SIMD指令的探索和实践,包括基本用法及实现原理,以及在具体算子实现中的思考和沉淀。
|
8月前
|
关系型数据库 测试技术 分布式数据库
PolarDB | PostgreSQL 高并发队列处理业务的数据库性能优化实践
在电商业务中可能涉及这样的场景, 由于有上下游关系的存在, 1、用户下单后, 上下游厂商会在自己系统中生成一笔订单记录并反馈给对方, 2、在收到反馈订单后, 本地会先缓存反馈的订单记录队列, 3、然后后台再从缓存取出订单并进行处理. 如果是高并发的处理, 因为大家都按一个顺序获取, 容易产生热点, 可能遇到取出队列遇到锁冲突瓶颈、IO扫描浪费、CPU计算浪费的瓶颈. 以及在清除已处理订单后, 索引版本未及时清理导致的回表版本判断带来的IO浪费和CPU运算浪费瓶颈等. 本文将给出“队列处理业务的数据库性能优化”优化方法和demo演示. 性能提升10到20倍.
596 4
|
9月前
|
存储 缓存 NoSQL
[译]解锁TOAST的秘密:如何优化PostgreSQL的大型列存储以最佳性能和可扩展性
[译]解锁TOAST的秘密:如何优化PostgreSQL的大型列存储以最佳性能和可扩展性
130 0
|
10月前
|
SQL 关系型数据库 MySQL
深度解析PolarDB DDL锁的优化和演进
DDL是数据库所有SQL操作中最繁重的一种,本文总结介绍了云原生数据库PolarDB中DDL全链路MDL锁治理的经验和进展,持续优化用户的使用体验,为用户打造最佳的云原生数据库。
|
11月前
|
SQL 关系型数据库 API
【PostgreSQL】PostgreSQL扩展:pg_stat_statements 优化SQL
【PostgreSQL】PostgreSQL扩展:pg_stat_statements 优化SQL
|
11月前
|
SQL 存储 缓存
开源分布式数据库PolarDB-X源码解读——PolarDB-X源码解读(十二):谈谈in常量查询的设计与优化
开源分布式数据库PolarDB-X源码解读——PolarDB-X源码解读(十二):谈谈in常量查询的设计与优化
185 0

相关产品

  • 云原生数据库 PolarDB