postgresql - Postgres auto-vacuum 不会回收死元组空间导致磁盘已满问题
问题描述
我有一个用例,每分钟同时在另一端插入 100 000 行,少数线程会获取这些行并将它们从我的表中删除。所以肯定会在我的表中创建很多死元组。
我的自动真空配置是
autovacuum_max_workers = 3
autovacuum_naptime = 1min
utovacuum_vacuum_scale_factor = 0.2
autovacuum_analyze_scale_factor = 0.1
autovacuum_vacuum_cost_delay = 20ms
autovacuum_vacuum_cost_limit = -1
从“pg_stat_user_tables”我可以发现自动真空正在我的表上运行,但在几个小时内我的磁盘将满(500 GB),我无法插入任何新行。
在第二次尝试时,我更改了以下配置
autovacuum_naptime = 60min
autovacuum_vacuum_cost_delay = 0
这次我的模拟和自动真空运行良好,最大磁盘大小为 180 GB。
这里我的疑问是,如果我将“autovacuum_vacuum_cost_delay”更改为零毫秒,自动真空如何释放死元组空间并 PG 重用它?如果我将值设置为 20 毫秒,为什么它不能按预期工作?
解决方案
这里我的疑问是,如果我将“autovacuum_vacuum_cost_delay”更改为零毫秒,自动真空如何释放死元组空间并 PG 重用它?
真空释放的空间记录在可用空间映射中,从那里分发以供将来的 INSERT 重复使用。
另一个要补充的细节是,在 9.6 中,只有在整个表本身被完全清空后才会清空可用空间映射,因此直到那时才能找到释放的空间。如果 VACUUM 由于太慢或被中断而永远无法完成,那么它释放的空间将不会被重新用于 INSERT。这在 v11 中得到了改进。
如果我将值设置为 20 毫秒,为什么它不能按预期工作?
因为真空跟不上那个值。PostgreSQL 的默认值通常只适用于较小的服务器,而您的服务器似乎并不适用。在这种情况下更改默认值是适当且可取的。请注意,在 v12 中,默认值从 20 降低到 2(其类型也相应地从 int 更改为 float,因此您现在可以更精确地指定值)
推荐阅读
- php - 当文件不存在时抑制 PHP filemtime() 错误
- swift - 无法使用带有 unicode 字符的电子邮件正则表达式找到匹配项
- azure - APIM 的条件 ARM 模板部署:只创建,不更新
- c - 使用 long long integer 存储 32 位指针会导致 printf 出错
- c++ - WinSock UDP IP_DONTFRAGMENT
- angular - 打字稿复杂构造函数
- ios - 导航栏上自定义titleView和后退按钮之间的间距
- python - 当我 pip 安装它时,pyproj 无法编译。这与 gcc 无关
- django - 使当前用户只能访问用户配置文件
- java - 使用从 Java 导入的自定义模块运行 Python 脚本