首页 > 其他分享 >当 autovacuum 不工作时

当 autovacuum 不工作时

时间:2024-01-15 22:25:23浏览次数:27  
标签:事务 副本 autovacuum 清理 查询 工作 运行

快速回顾一下,autovacuum后台进程清理死行,例如旧的已删除行版本。您也可以通过运行手动执行清理VACUUM,但autovacuum会根据表中死行的数量在适当的时候自动执行清理,不要太频繁但足够频繁以控制“垃圾”的数量。

一般来说,autovacuum不能运行得太频繁,只有在表中累积了一定数量的死行后才会执行清理。但它可能会由于各种原因而延迟,导致表和索引变得比预期的要大,这正是这篇文章的主题。那么常见的罪魁祸首是什么以及如何识别它们呢?

节流

autovacuum worker 被限制为每个时间间隔只能执行一定数量的工作。默认限制相当低,大约 4MB/s 的写入,8MB/s 的读取。这适用于像 Raspberry Pi 这样的微型机器或 10 年前的小型服务器,但现在的机器更强大(在 CPU 和 I/O 方面)并且处理更多的数据。

假设您有几张大表和几张小表。如果所有三个autovacuum工作人员都开始清理大表,则无论小表累积了多少死行,都不会清理任何小表。假设您有足够的监控,识别这并不是特别困难。寻找所有autovacuum工作人员都忙碌而尽管累积了许多死行但表未被清理的时间段。

所有必要的信息都在 pg_stat_activity ( autovacuum worker进程数) and pg_stat_all_tables (last_autovacuum and n_dead_tup)。

增加autovacuum工人数量不是解决方案,因为总工作量保持不变。您可以指定每个表的限制,从总限制中排除该工作人员,但这仍然不能保证在需要时会有可用的工作人员。

正确的解决方案是调整节流,使用与硬件配置和工作负载模式相关的合理限制。如果你能减少数据库中产生的死行数量,那将是一个理想的解决方案。

从这一点来看,我们假设节流不是问题,即工作autovacuum人员不会长时间饱和,并且在所有表上触发清理而不会出现不合理的延迟。

长事务

所以,如果定期清理表,肯定不会积累很多死行,对吧?很不幸的是,不行。这些行在被删除后实际上并不是立即“可移动”的,但只有在没有可能看到它们的事务时才可以。确切的行为取决于其他事务正在(正在)做什么和序列化级别,但一般来说:

读已提交

  • 运行查询块清理
  • 空闲事务仅在执行写入时才阻止清理
  • 空闲事务(没有任何写入)不会阻止清理(但无论如何保留它们不是一个好习惯)

可序列化

  • 运行查询块清理
  • 空闲事务块清理(即使它们只进行了读取)

在实践中它当然更细微,但解释所有不同的位需要首先解释 XID 和快照是如何工作的,这不是本文的目标。您真正应该从中得出的结论是,长事务不是一个好主意,尤其是如果这些事务可能已完成写入。

当然,您可能需要长时间保留事务是有充分正当理由的(例如,如果您需要确保所有更改的 ACID)。但要确保它不会在不必要的情况下发生,例如由于应用程序设计不佳。

一个有点出乎意料的结果是高 CPU 和 I/O 使用率,由于autovacuum一遍又一遍地运行,没有清除任何死行(或只是其中的一些)。因此,这些表仍然有资格在下一轮进行清理,弊大于利。

如何检测这个?首先,您需要监控长时间运行的事务,尤其是空闲事务。您需要做的就是从pg_stat_activity. 视图定义随着 PostgreSQL 版本发生了一些变化,因此您可能需要稍微调整一下:

SELECT xact_start, state FROM pg_stat_activity;

-- count 'idle' transactions longer than 15 minutes (since BEGIN)
SELECT COUNT(*) FROM pg_stat_activity
 WHERE state = 'idle in transaction'
  AND (now() - xact_start) > interval '15 minutes'

-- count transactions 'idle' for more than 5 minutes
SELECT COUNT(*) FROM pg_stat_activity
 WHERE state = 'idle in transaction'
  AND (now() - state_change) > interval '5 minutes'

您也可以简单地使用一些现有的监控插件,例如check_postgres.pl。那些已经包括这种类型的健全性检查。您必须决定什么是合理的事务/查询持续时间,这是特定于应用程序的。

从 PostgreSQL 9.6 开始,您还可以使用idle_in_transaction_session_timeout自动终止空闲时间过长的事务。同样,对于长查询,有statement_timeout

另一个有用的东西是VACUUM VERBOSE它实际上会告诉你有多少死行还不能被删除:

db=# VACUUM verbose z;
INFO:  vacuuming "public.z"
INFO:  "z": found 0 removable, 66797 nonremovable row versions in 443 out of 443 pages
DETAIL:  12308 dead row versions cannot be removed yet.
...

它不会告诉您哪个后端阻止了清理,但它是正在发生的事情的一个非常清楚的标志。

注意:您无法轻松地从中获取此信息,autovacuum因为它仅在默认情况下记录DEBUG2(并且您肯定不希望在生产中使用该日志级别运行)。

热备长查询

让我们假设表被及时清理,但没有删除死元组,导致表和索引膨胀。您正在监控pg_stat_activity并且没有长时间运行的事务。可能是什么问题?

如果您有一个流式副本,那么问题很可能就在那里。如果副本使用hot_standby_feedback=on,则副本上的查询几乎就像主服务器上的事务一样,包括阻塞清理。当然,hot_standby_feedback=on在对副本运行长查询(例如分析和 BI 工作负载)时恰好使用它,以防止由于复制冲突而取消。

遗憾的是,您必须做出选择,要么保留hot_standby_feedback=on并接受清理延迟,要么处理取消的查询。您也可以使用它max_standby_streaming_delay来限制影响,尽管这并不能完全阻止取消(因此您仍然需要重试查询)。

实际上,现在还有第三种选择,逻辑复制。您可以使用 PostgreSQL 10 中提供的新逻辑复制来复制更改,而不是对 BI 副本使用物理流复制。逻辑复制放松了主副本之间的耦合,并使集群大部分独立(独立清理等等)。

这解决了与物理流复制相关的两个问题,延迟清理主数据库或取消 BI 副本的查询。不过,对于服务于 DR 目的的副本,流式复制仍然是正确的选择,但是那些副本没有(或不应该)运行长时间查询。

注意:虽然我提到逻辑复制将在 PostgreSQL 10 中可用,但基础设施的很大一部分在以前的版本中可用(特别是 PostgreSQL 9.6)。因此,您甚至可以在旧版本上执行此操作(我们为我们的一些客户这样做),但 PostgreSQL 10 将使它更加方便和舒适。

糟糕的autoanalyze

您可能会错过的一个细节是,autovacuum工人实际上执行两项不同的任务。首先是清理(就像运行一样VACUUM),而且还收集统计信息(就像运行一样ANALYZE)。并且这两个部分都使用autovacuum_cost_limit

但是在处理事务上有很大的不同。每当VACUUM部分到达时autovacuum_cost_limit,工作人员释放快照并休眠一段时间。但是ANALYZE必须在单个快照/事务中运行,这会阻止清理。

这是搬起石头砸自己脚的优雅方式,特别是如果你也这样做的话:

  • 增加default_statistics_target以从更大的样本中构建更准确的统计数据
  • 降低autovacuum_analyze_scale_factor以更频繁地收集统计信息

意想不到的后果当然是ANALYZE会更频繁地发生,需要更长的时间并且(与VACUUM部分不同)会阻止清理。解决方案通常相当简单,不要降低autovacuum_analyze_scale_factor太多。每次运行ANALYZE10% 的表更改在大多数情况下应该绰绰有余。

n_dead_tup

我想提及的最后一件事是关于pg_stat_all_tables.n_dead_tup值的变化。您可能认为该值是一个简单的计数器,每当创建新的死元组时递增,并在清除时递减。但它实际上只是对死元组数量的估计,由ANALYZE. 对于小表(小于 240MB),差别不大,因为ANALYZE读取整个表,所以非常准确。然而,对于大型表,它可能会发生很大变化,具体取决于对表的哪个子集进行采样。降低autovacuum_vacuum_scale_factor使其更加随机。

n_dead_tup所以在监控系统中查看时要小心。值的突然下降或增加可能仅仅是由于ANALYZE重新计算不同的估计,而不是由于实际清理和/或表中出现新的死元组。

总结

总结为几个简单的要点:

  • autovacuum只有在没有可能需要死元组的事务的情况下才能完成它的工作。
  • 长时间运行的查询会阻止清理。考虑使用statement_timeout以限制查询。
  • 长时间运行的事务可能会阻止清理,确切的行为取决于隔离级别或事务中发生的事情,监视它们并在可能的情况下终止它们。
  • 对副本的长时间运行查询hot_standby_feedback=on也可能会阻止清理。
  • autoanalyze也受到限制,但与VACUUM不同,它保留单个快照(因此会阻止清理)。
  • n_dead_tup只是ANALYZE维护的估计值,因此预计会有一些波动(尤其是在大表上)。

标签:事务,副本,autovacuum,清理,查询,工作,运行
From: https://www.cnblogs.com/jl1771/p/17966529

相关文章

  • 高效工作法:占位图片生成工具助力项目快速迭代
    在现代设计和开发项目中,图片资源的重要性不言而喻。然而,项目中经常会遇到寻找合适图片、调整图片尺寸和格式等问题,这些问题不仅耗时耗力,还可能影响到项目的进度和质量。此时,占位图片生成工具应运而生,它为我们的项目带来了诸多好处,解决了诸多难题。占位图片|一个覆盖广泛主......
  • N-gram模型如何工作?
    我们知道语言模型(LanguageModel,LM)实际上是对一种token序列的概率分布。例如对一个句子\(S=w_1,...,w_t\),我们要估计这一个句子的概率,计算过程如下:\[P(S)=P(w_1,...,w_t)\\=P(w_1,...,w_{t-1})*P(w_t|w_1,...,w_{t-1})\\=P(w_1,...,w_{t-2})*P(w_{t-1}......
  • 转载一篇 vb.net await 工作顺序
    VB.net-异步编程之asyncawait结构的学习芯艺在.net中有一种非常先进的异步编程机制,那就是async和await组成的异步方法调用,用好这两个关键字可使异步程序就象同步代码一样简洁易懂。async用于指定一个方法为异步方法,实际上就是告诉编译器该方法内有await等待,需要将此方法中......
  • 【计网笔记】互联网标准化工作
    互联网标准化工作互联网标准化组织:互联网协会1992年由于互联网不再归美国政府管辖,因此成立了一个国际性组织叫作互联网协会(InternetSociety,简称为ISOC)[W-ISOC],以便对互联网进行全面管理以及在世界范围内促进其发展和使用。ISOC下面有一个技术组织叫作互联网体系结构委员会I......
  • fastlio工程化工作
    fastliofastlio2pointlio都是港大开源的很好的工作其中fastlio2是对fastlio的升级 没有使用特征提取使用gicp方式做点到面的约束pointlio没有使用迭代卡尔曼滤波方式进行优化也没有做针对scan的运动补偿而是针对scan中的每一个点的时间都做了观测。针对激光建图来说fas......
  • 使用Local Persistent Volume 部署有状态工作负载
    本文分享自华为云社区《使用LocalPersistentVolume部署有状态工作负载》,作者:张俭。使用LocalPersistentVolume部署有状态工作负载本教程以部署DemoStatefulSet为例,指导您利用 LocalPersistentVolume (即本地持久卷)技术使用标准PVC对象访问本地磁盘。安装kubernete......
  • 使用 Python 将数据写入 Excel 工作表
    在数据处理和报告生成等工作中,Excel表格是一种常见且广泛使用的工具。然而,手动将大量数据输入到Excel表格中既费时又容易出错。为了提高效率并减少错误,使用Python编程语言来自动化数据写入Excel表格是一个明智的选择。Python作为一种简单易学且功能强大的编程语言,其丰富的......
  • Compileflow工作流引擎使用讲解
    目录1Compileflow1.1简介1.2特点1.3Compileflow插件下载1.4main方法调用1.4.1pom.xml1.4.2新建bpm文件1.4.3各个节点绑定方法1.4.4测试方法1.5bpm各个标签说明1.5.1BPM根节点1.5.2全局变量1.5.3开始节点:start1.5.4结束节点:end1.5.5自动节点:autoTask--流程节......
  • 投屏的工作原理是什么,使用了什么协议
    投屏(ScreenMirroring)是一种将一个设备的屏幕内容显示到另一个设备上的技术。其工作原理通常涉及以下步骤:检测设备:首先,需要在投屏源设备(如手机、电脑)和目标设备(如电视、投影仪)之间建立连接。这可以通过无线或有线连接方式进行。建立连接:投屏设备之间通过特定的协议建立连接,以便传......
  • Windows Server 2016 & 2019 工作站速配脚本
    之前有一篇关于把WindowsServer打造成工作站系统的随笔,其中的步骤完全基于手工操作,一部分对系统不熟悉的朋友恐怕会找不到设置的入口。与其弄一堆截图写所谓的教程,还不如写一个程序来自动化处理。init.ps1Write-Host"`n正在启用声音服务"Set-Service-Name"Audiosrv"-Stat......