❝开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, OceanBase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,可以解决你的问题。加群请联系 liuaustin3 ,(共2370人左右 1 + 2 + 3 + 4 +5 + 6 + 7)(1 2 3 4 5 群均已爆满,6群突破300人)
最近群里有人提出一个问题,为什么在进行vacuum操作的时候,wal日志会快速增长,怎么解决这个问题,我个人认为这是一个综合类的问题,是由于一连串的问题导致的最终的结果。如同我们最终走进ICU,脏器衰竭,那是vacuum 引起的?
但说到根本原因是DBA对PostgreSQL数据库工作原理不清晰,维护失职导致的,或者说是对PG数据库疏于维护,是根本原因,开发滥用PostgreSQL也有责任,把什么都往PG里面放,也会导致更多其他的问题。这点咱们下次说,这也是我对一些在POSTGRESQL中使用大量JSON存储有担心的地方,尤其做了主从强制一致的情况下,我对在PostgreSQL中处理大量JSON写抱有性能方面的担心。这点咱们可以开一个新的文章来说说,回到这个问题。
这个整体的问题的从根源上说,还的从源代码上开始讲(开头就是让人头疼的 源代码环节)
if (!PageIsAllVisible(page))
{
START_CRIT_SECTION();
/* mark buffer dirty before writing a WAL record */
MarkBufferDirty(buf);
/*
* It's possible that another backend has extended the heap,
* initialized the page, and then failed to WAL-log the page due
* to an ERROR. Since heap extension is not WAL-logged, recovery
* might try to replay our record setting the page all-visible and
* find that the page isn't initialized, which will cause a PANIC.
* To prevent that, check whether the page has been previously
* WAL-logged, and if not, do that now.
*/
if (RelationNeedsWAL(vacrel->rel) &&
PageGetLSN(page) == InvalidXLogRecPtr)
log_newpage_buffer(buf, true);
PageSetAllVisible(page);
visibilitymap_set(vacrel->rel, blkno, buf, InvalidXLogRecPtr,
vmbuffer, InvalidTransactionId,
VISIBILITYMAP_ALL_VISIBLE | VISIBILITYMAP_ALL_FROZEN);
END_CRIT_SECTION();
}
freespace = PageGetHeapFreeSpace(page);
UnlockReleaseBuffer(buf);
RecordPageWithFreeSpace(vacrel->rel, blkno, freespace);
return true;
}
上面的源代码,到底是做什么的
1 对于PostgreSQL中的表的页面是否可见 (当然有不可见的要不还需要vacuum吗)
2 在有不可见的情况下,需要进行标记,将这些不可见的tuple 标记为(需要进行等待刷新的页面)
3 将刷新的页面的操作写入到wal日志,且设置页面上的LSN为无效.
4 设置页面的可见性,对表文件中的 vm 文件进行刷新
5 任务完成.
从这里看到,在进行 vacuum 类操作的时候的确是要对WAL 日志进行操作。当然在一些其他的vacuum 代码中也有对wal进行操作的部分,这里就不在赘述了。
那么第一点,我们清晰了,确认了,做vacuum,autovacuum,就会导致要进行处理的页面信息,且要记录到wal日志中。
那么我们进入第二个部分,为什么进行vacuum, autovacuum 突然增加的wal 量要怪到DBA的头上。
1 PG数据库原理是否知晓
PostgreSQL 的原理与其他数据库不同这点事非常明显的,DBA 应非常明确此问题,也应该知道这样的情况下会导致的问题。(最近我们就有一个案例,一个客户的PostgreSQL 10在工作中不有效调节PostgreSQL autovacuum的参数,在业务高峰期突发进行集中式的Autovacuum 操作,使用了接近60%以上的CPU在长达30分钟进行Autovacuum 操作,引起CPU告警,Iops告警)
2 对容易出问题的表所在的系统业务表的工作情况是否有了解
对于系统的业务热表,是否有和开发方讨论,或自行进行研究,并进行数据的记录,如 inserted updated deleted等在一段时间的变化,比如我们1小时记录表行的变化,以及以上者三个量的变化。
3 是否合理调节过业务系统中的容易出问题表的 vacuum参数
针对一段时间的研究,将这些量进行分析后,对这些表的autovacuum参数进行修改,并持续关注。降低在业务高峰期出现系统集中在进行autovacuum 操作的情况。
不进行以上工作可能会产生的问题
1 某段时间I/O负载突发升高
这主要是autovacuum 在同一个时间处理大量的大表,会产生长时间高负载的I/O操作,导致磁盘系统I/O升高,影响数据库在同一时间对数据的从I/O系统提取或刷脏的操作响应的时间。
2 在进行autovacuum的操作中,CPU会被消耗资源,集中发生多数表触发autovacuum 将导致CPU被autovacuum操作霸占,影响正常业务使用CPU资源。
3 WAL 文件突发产生过多 Autovacuum 工作会产生大量write Ahead Logging日志,如果wal产生的速度过快,会影响数据库的性能,对于有从库,主从流复制,还会增加网络方面的压力。
4 锁的冲突 在autovacuum发生在业务高频表时,且在业务时间进行频繁查询时,则可能会发生用户查询,或事务运行与autovacuum表的锁冲突,导致查询性能下降和查询时间延迟的问题。
5 autovacuum 工作后,导致查询计划变化产生的SQL语句查询性能的变化。
解决方案:
可以参考之前与autovacuum有关的 6篇文章
PostgreSQL autovacuum 优化与调试 (1 触发 autovacuum 的条件)
PostgreSQL autovacuum 优化与调试 (2 autovacuum 进行了什么样的工作)
Postgresql autovacuum 3 怎么调整参数,拯救你惨淡的性能
postgresql autovacuum 4 怎么调整参数,让autovacuum 多干活,与成本的计算
PostgreSQL autovacuum 5 怎么监控(autovacuum 扫描表工作的百分比)
置顶文章:
微软 “爱” 上PostgreSQL, PG “嫁给” 微软!
撕逼!PostgreSQL 和 MongoDB 开撕,MySQL却躺枪
阿里云 安全扫描 ,说我PostgreSQL 自建主机极度不安全, 谁的问题?
PostgreSQL 13.0-13.15 功能更新和bug fixed列表
撕逼!PostgreSQL 和 MongoDB 开撕,MySQL却躺枪
PostgreSQL 哪些版本尽量避免使用,版本更新重点明晰(PG12)
PostgreSQL 15 16 小版本更新信息小结 版本更新是不是挤牙膏
PostgreSQL 14 小版本分析,有那个版本不建议使用
Windows 是MySQL和PostgreSQL高性能数据库的坟墓
往期热门文章:
PolarDB 最近遇到加字段加不上的问题 与 使用PolarDB 三年感受与恳谈
PostgreSQL 稳定性平台 PG中文社区大会--杭州来去匆匆
MySQL 的SQL引擎很差吗?由一个同学提出问题引出的实验
临时工访谈:从国产数据库 到 普罗大众的产品 !与在美国创业软件公司老板对话