PostgreSQL Vacuum清理垃圾?

PostgreSQL Vacuum清理垃圾?

Whoami:5年+金融、政府、医疗领域工作经验的DBA
Certificate:OCP、PCP
Skill:Oracle、Mysql、PostgreSQL
Platform:优快云、墨天伦、公众号(呆呆的私房菜)

业务范围:数据库安装部署、日常维护、主备切换、故障处理、性能优化、技术培训等。
需要的伙伴或者商业合作请移步 公众号【呆呆的私房菜】获取联系方式。

阅读本文可以了解PostgreSQL VACUUM概念、日常运维及相关建议。

01 VACUUM概述

通过上一篇文章 用pageinspect浅探下PostgreSQL的MVCC 我们可以了解到PostgreSQL为维护多版本并发控制功能,在数据库做update和delete操作的时候,会产生dead tuple。问题来了,如果任由这些dead tuple无限膨胀,浪费磁盘空间不说,还可能引发数据库性能问题,因此进行dead tuple的清理就显得格外重要了!没错,这个过程就叫做vacuum。

VACUUM 可以清理dead tuple、更新统计信息、重组数据和解决事务ID回卷问题。

02 VACUUM语法

  1. vacuum:不要求获得排他锁,只需要找到旧版本数据,标记状态为不可用,不会进行空间合并;
  2. vacuum full:需要lock table,这个操作除了进行vacuum,还会进行空间合并;
  3. vacuum analyze:更新统计信息,使优化器能够选择更好的方案执行sql;
  4. vacuum freeze:表记录冻结,可解决事务ID回卷问题。
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]

03 VACUUM形式

vacuum 标准形式:

  1. 回收dead tuple的磁盘空间,但是不会交给OS,而是为新tuple留着;
  2. 如果删除的记录位于表的末端,且没有tuple,其所占用的空间将会被物理释放并归还操作系统;
  3. 页内没有事务可见的tuple,即整个页都可以删除时,会做truncate操作,把尾部的这些页统一从文件中删除,文件大小和表所占空间也会减少;
  4. 标准形式vacuum可以和生产数据库DML操作并行运行,但在期间无法使用alter table等命令来更新表定义。
  5. vacuum会产生大量的I/O流量,这会导致其他活动会话性能变差。

vacuum full形式:

  1. 通过把dead tuple空间之外的内容写成一个完整的新版本表来主动紧缩表,这会最小化表的大小,但是需要花费较长时间;
  2. 实质上将当前删除记录后边的数据进行移动,使整体的记录连贯起来,降低“high water marked”。
  3. vacuum full重组了数据,会释放出来较大的磁盘空间,但存在如下弊端:
    a. 会给表加上排他锁,阻塞相关表的操作;
    b. 会创建一个表的副本,期间磁盘空间加倍,最大可能达到2倍。磁盘空间有限情况下,慎重执行vacuum full。

vacuum analyze形式:
可以调整指定字段的抽样率;

# value取值0-1000,其中值越低采样比例越低,分析准确性也就越低,但analyze命令执行速度就更快
alter table <table_name> alter column <columnname> set statistics <value>;

# 查看当前系统缺省采样值
show default_statistics_target;

vacuum freeze形式:
事务回卷指的是PostgreSQL的XID达到40亿后,XID会重置为0,而按MVCC机制规则,之前的事务可以看到新事务创建的元组,但新事务不能看到之前事务创建的元组,这违反了事务的可见性。

  1. PostgreSQL默认的存储引擎事务可见性依赖行头的事务号,因为事务号是32位的,会循环使用;
  2. 事务ID由32位数保存,而事务ID递增,当事务ID用完之后,会出现事务ID回卷问题,可以通过vacuum freeze来解决问题;
  3. 在一条记录产生之后,如果再次经历了20亿个事务,必须对其进行freeze,否则数据库会认为这条记录是未来事务产生的(可见性判断)可以调整指定字段的抽样率;
# PostgreSQL事务ID的特殊意义:
# 0 代表 invalid事务号
# 1 代表 bootstrap(辅助程序)事务号
# 2 代表 frozon事务号

# 注意:
# 1. frozon事务号比任何事务号都要老,可用的有效最小事务号为3;
# 2. vacuum时将所有已提交的事务ID均设置为2,之后所有的事务都比frozon事务新
# 3. 因此vacuum之前的所有已提交的数据对之后的事务可见,PostgreSQL通过这种方式实现了事务ID的循环利用

04 autovacuum

autovacuum 是PostgreSQL里非常重要的一个服务器进程,在一定条件下会触发执行。
autovacuum 参数控制autovacuum进程是否打开,默认为on,作用如下:

  1. 清理dead tuple,并对表进行分析;
  2. 更新可用空间映射(free space map),以便跟踪表块中的可用空间;
  3. 更新仅索引扫描的可见新图(visibility map);
  4. freeze表行,以便事务ID计数器可以安全的环绕。
autovacuum触发条件:
# 1.autovacuum_naptime:autovacuum唤醒间隔时间
# 2.表上(updte、delete >= autovacuum_vacuum_scale_factor * reltuples(表记录数) + autovacuum_vacuum_threshold
# 3.触发vacuum analyze:表上(insert、update、delete) >= autovacuum_analyze_scale_factor * reltuples (表记录数) + autovacuum_analyze_threshold
# 4.触发vacuum freeze:指定表上事务的最大年龄配置参数 autovacuum_freeze_max_age,默认为2亿

05 vacuum使用建议

  1. 开启全局auvacuum,设置参数autovacuum=on;
  2. 持续关注表中dead tuple的状况、表级计划性的执行vacuum;
# 查询需要vacuum的表,即表的dead tuple的量或者比例,默认情况下可能有少于20%的dead tuple
# 可通过以下sql命令查询表的空间使用情况:
select relname, n_live_tup, n_dead_tup 
from pg_stat_all_tables 
where n_dead_tup desc;
  1. 可使用安装目录bin下的vacuumdb或vacuumlo工具对数据进行手动清理;
  2. 适当调大参数maintenance_work_mem,可加快vacuum的执行速度;
  3. PostgreSQL 9.5引入了一个新的参数:jobs参数,可以并行运行vacuum;
  4. 对于有大量update的表,vacuum full是没有必要的,因为它的空间还是会则呢盖章;
  5. 定期监控数据量变化较大的表,确认其磁盘页面占有量接近临界值,可考虑vacuum full。
# 注意:
1. vacuum只会删除那些已经结束的事务所关联到的旧的已经不用的数据;
2. 如果一个事务还在执行,autovacuum就不会处理这个事务;
3. 如果应用中大量使用了table lock,会导致autovacuum无法执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值