ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

【PostgreSQL】PostgreSQL的vacuum调优和客户化调度vacuum任务

2022-07-01 21:34:29  阅读:196  来源: 互联网

标签:PostgreSQL autovacuum cost limit pg 设置 vacuum 调优


 

PostgreSQL内嵌的autovacuum一直在改进,但是在很多客户环境下,仍然有很多不满足的地方。

常见的问题和限制

1.在系统高峰时期,表成了autovacuum的候选对象

autovacuum的设置是基于一些扩展因子和阈值的。在高峰期,如果表上有大量的事务,就很容易超过这些设置。实际上是在错误的时间做了vacuum操作。

2.表饥饿

很容易看到有些表频繁变成autovacuum的候选对象,重复地占用了工作进程。而对于那些在候选表列表靠后的表,会很长时间得不到vacuum。当前的autovacuum还不够智能,并不能知道哪些表需要给与高优先级做vacuum。

3.无法动态控制autovacuum工作进程

这可能是最糟糕的事情。即使dba基于需求和时间窗口,想调整autovacuum_vacuum_cost_limit:

alter system set autovacuum_vacuum_cost_limit=2000;
select pg_reload_conf();

这对正在工作的autovacuum工作进程不会起作用,下一次启动才有效。

4.dba试图调优参数通常是适得其反

看到过期的表或饥饿的表,绝望的dba会设置激进的设置和分配更多的工作进程。很多时候,这会使系统超出其限制,因为当系统已经有大量活动会话时,一切都在错误的时间以高攻击性出现。 工作进程的个数*maintenance_work_mem,太多的内存消耗,系统性能受到很大影响。我见过的最糟糕的情况是autovacuum worker占用了高达50% 的服务器资源。

5.在活动时间窗期间的autovacuum违背了它自己的目的

如果在高峰窗口期间完成,autovacuum worker将引用旧的xid/快照。它不会清理在同一时间段内生成的死元组,这与autovacuum的目的背道而驰。

6.饥饿的表触发wraparoud会阻塞autovacuum

很容易遇到,在autovacuum持续时间较长的情况下饥饿的表会达到 autovacuum_freeze_max_age并触发wraparound从而阻塞autovacuum。

由于效率低下,我们不断看到DBA倾向于完全禁用autovacuum并引发更多问题甚至中断。至少,我对PostgreSQL新手的要求是,请永远不要尝试关闭autovacuum。这不是解决autovacuum 相关问题的方法。

调优autovacuum

全局设置

参数autovacuum_vacuum_cost_limit和autovacuum_vacuum_cost_delay是控制autovacuum工作进程的两个主要参数。autovacuum_max_workers控制同时在不同表上工作的进程数量。默认情况下,autovacuum_vacuum_cost_limit将被禁用 (-1),这意味着其他参数Vacuum_cost_limit的值将生效。所以建议的第一件事是为autovacuum_vacuum_cost_limit设置一个值,这将有助于我们单独控制autovacuum工作进程。

我在许多安装中看到的一个常见错误是autovacuum_max_workers设置为非常高的值,例如 15!。假设这会使autovacuum运行得更快。请记住autovacuum_vacuum_cost_limit在所有工作进程之间分配。所以工作进程的数量越高,每个工作进程的运行速度就越慢。如上所述,较慢的工作进程意味着无效的清理工作。而且,它们每一个最多可以占用maintenance_work_mem大小的内存,一般情况下,autovacuum_max_workers的默认值,即3就足够了。请仅在绝对必要时考虑增加它。

postgres=# show autovacuum_vacuum_cost_limit;
autovacuum_vacuum_cost_limit
------------------------------
-1
(1 row)

postgres=# show autovacuum_vacuum_cost_delay;
autovacuum_vacuum_cost_delay
------------------------------
2ms
(1 row)

postgres=# show vacuum_cost_limit;
vacuum_cost_limit
-------------------
200
(1 row)

postgres=# show autovacuum_max_workers;
autovacuum_max_workers
------------------------
3
(1 row)

postgres=# show maintenance_work_mem;
maintenance_work_mem
----------------------
64MB
(1 row)

postgres=#

表级别的设置

实例级别的一揽子调整设置可能对一些表不起作用。这些异常需要特殊处理,并且在表级别调整设置可能变得不可避免。我将从那些过于频繁地成为 utovacuum候选者的表开始。

PostgreSQL使用log_autovacuum_min_duration记录日志,该设置提供了那些经常成为候选表的详细信息,以及那些花费大量时间和精力的autovacuum运行。就个人而言,我更喜欢以此为起点。也可以通过比较两个不同时间戳中的pg_stat_all_tables的autovacuum_count来获得autovacuum运行的摘要。我们需要考虑的是HOT(Heap Only Tuple)更新和填充因子。可以使用同一视图 (pg_stat_all_tables) 的 n_tup_hot_upd分析热更新信息,调整它可以大大降低autovacuum要求。

根据所有这些信息分析,可以调整特定的表级别设置。例如:

alter table t1 set (autovacuum_vacuum_scale_factor=0.0, autovacuum_vacuum_threshold=130000, autovacuum_analyze_scale_factor=0.0, autovacuum_analyze_threshold=630000, autovacuum_enabled=true, fillfactor=82);

  

额外调度vacuum任务

我们的目标不是禁用autovacuum,而是用我们对系统的了解来补充autovacuum。这根本不需要复杂。我们可以拥有的最简单的方法是在其自身或其 TOAST 具有最大年龄的表上运行“VACUUM FREEZE”。

我们可以在最长时间或toast表上执行

例如,我们可以实现具有以下内容的 vaccumjob.sql 文件

WITH cur_vaccs AS (SELECT split_part(split_part(substring(query from '.*\..*'),'.',2),' ',1) as tab FROM pg_stat_activity WHERE query like 'autovacuum%')
select 'VACUUM FREEZE "'|| n.nspname ||'"."'|| c.relname ||'";'
from pg_class c
inner join pg_namespace n on c.relnamespace = n.oid
left join pg_class t on c.reltoastrelid = t.oid and t.relkind = 't'
where c.relkind in ('r','m')
AND NOT EXISTS (SELECT * FROM cur_vaccs WHERE tab = c.relname)
order by GREATEST(age(c.relfrozenxid),age(t.relfrozenxid)) DESC
limit 100;
\gexec

找出当前需要autovacuum的100个aged表,并执行“vacuum freeze”。其中“\gexec”会执行上面的查询结果。

也可以做的定时任务:

0 0 * * * /full/path/to/psql -X -f /path/to/vacuumjob.sql > /tmp/vacuumjob.out 2>&1

 

手动设置定时任务具有以下好处:

1.在高峰期这些表变成autovacuum的候选表的机会降低了。

2.在低峰期间执行可以提高资源的使用。

3.候选表的选择是根据表的age,而不是扩展因子和阈值,表饥饿的机会降低了。也避免了有些表频繁地变成候选表。

4.在客户/用户环境中,几乎不会再报告wraparound阻塞autovacuum。

 

标签:PostgreSQL,autovacuum,cost,limit,pg,设置,vacuum,调优
来源: https://www.cnblogs.com/abclife/p/16428288.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有