一、脏页率说明
每当更新或删除PostgreSQL表中的行时,都会留下死元组。VACUUM摆脱了它们,以便空间可以重复使用。如果一个表没有被清理,它就会变得臃肿,这会浪费磁盘空间并减慢表的顺序扫描(以及索引扫描)。
VACUUM还负责冻结表行,以避免在事务ID计数器环绕时出现问题 资料参考pg中文论坛
实际操作新表insert也会产生脏页,特别是gds导入失败后空表也会占用大量空间;空表查询缓慢
pg/dws中有参数控制autovacuum = on,但是该参数功能有致命缺陷:在插DML过程会偶发达到指定脏叶阈值触发autovacuum,导致DML失败,且该功能一般在会话高峰期触发,消耗大量磁盘IO,严重影响数据库性能。所以建议实际使用把autovacuum 参数功能,自己编写代码避开业务高峰控制vacuum的时间窗口及并发度。
一般数据库事务管理中所指的锁是指表级锁,GaussDB(DWS)中支持的锁模式有8种,按排他级别分别为1-8。
每种锁模式都有与之相冲突的锁模式,由锁冲突表定义相关的信息,锁冲突表如下:
vacuum 与 vacuum full 区别
vacuum 模式名.表名;过程上的是share update exclusive,和 1 2 3种锁对应的会话类型均不冲突,也就是不会影响增删改查 。vacuum full 模式名.表名;过程上的是share update exclusive , vacuum full时会与该表其他所有类型会话冲突,执行期间,基于该表的操作全部挂起。为什么还要考虑vacuum full?
vacuum 实际不会释放物理空间,可以用select pg_size_pretty(pg_total_relation_size(‘tab’)) as size验证;功能仅限于将如果删除的记录位于表的末端,其所占用的空间将会被物理释放并归还操作系统。而如果不是末端数据,会将表中或索引中dead tuple(死亡元组)所占用的空间置为可用状态,从而复用这些空间。
vacuum full 会释放物理空间,不论被清理的数据处于何处,这些数据锁占用的空间将被物理释放并归还于操作系统。当再有数据插入后,分配新的磁盘页面使用。
:不论被清理的数据处于何处,这些数据锁占用的空间将被物理释放并归还于操作系统。当再有数据插入后,分配新的磁盘页面使用。
二、注意事项及应对方式
2.1、风险
•数据库将进行大量读写操作,可能影响正常使用,建议选择空闲时间执行。
•数据库的存储空间越大,即数据可能越多,清理的时间越长。
VACUUM FULL回收所有过期的行空间,但是它需要对每个正在处理的表进行独占锁定,大量消耗IO,建议控制并发不超过2,并且可能需要很长时间才能完成大型分布式数据库表。节点数较少的大表vacuum full时间较长,可能会两个小时也未能做完vacuum full,期间整表上锁,因此这里建议大表按照分区来做vacuum full lockwait_timeout
分区脏页查询方式
2.2、应对方式
设置statement_timeout
设置锁等待时间与lockwait_timeout和max_query_retry_times
vacuum full需要避免在业务高峰期进行,且需要做判断机制,有业务跳过,可以通过select count(*) from pg_lock relation=‘模式名.表名’::regclass::oid进行识别,有会话就会上锁,vacuum full 语句执行了也会等锁。vacuum full过程有该表业务会话需要停止,可以后台同时启动监控数据库会话进程,定时查询pgxc_stat_activity上有无业务会话,如果有,可以通过pg_terminate_backend(pid)函数去对应的节点上杀掉持锁语句,dws 管理账号可以使用 pgxc_cancel_query(queryid)或者pgxc_terminate_backend(pid)
如果该表是实时业务需要约定时间停止,否则基本无解,vacuum full 过程会先持有4级锁进行,中途会有升级8级锁过程,实时业务很容易让vacuum full 拿8级锁失败报错
三、脏页率查询
3.1、模式脏页率
pgxc_get_stat_dirty_tables(int dirty_percent, int n_tuples)
pgxc_get_stat_dirty_tables(int dirty_percent, int n_tuples, text schema)
描述:获取各表的插入、更新、删除以及脏页率信息。该函数针对视图
PGXC_GET_STAT_ALL_TABLES进行了性能优化, 可以快速筛选出每个DN上满足脏页
率大于dirty_percent,dead元组数大于n_tuples的表,将筛选结果返回到CN进行汇总
并输出。
3.2、单表脏页率(准确),可写程序定时收集到表中
select pg_stat_get_live_tuples(‘schema.table’::regclass::oid) as n_live_tup
,pg_stat_get_dead_tuples(‘schema.table’::regclass::oid) as n_dead_tup
,case n_dead_tup when 0 then 0 else round(n_dead_tup/(n_live_tup+n_dead_tup)*100,2) end as dirty_ratio;
3.3系统自带查询函数,特别慢不建议使用
pgxc_get_stat_all_tables