PostgreSQL VACUUM 之深入浅出 (四)
VACUUM 参数优化
上面已经介绍过了以下设置表级 AUTOVACUUM 相关参数和 autovacuum_max_workers:
ALTER TABLE pgbench_accounts SET (autovacuum_vacuum_scale_factor = 0.1, autovacuum_vacuum_threshold = 2000);
ALTER TABLE pgbench_accounts SET (autovacuum_analyze_scale_factor = 0.05, autovacuum_analyze_threshold = 2000);
下面就以下常用 VACUUM 参数详细介绍如何进行调优。
maintenance_work_mem 参数
#maintenance_work_mem = 64MB # min 1MB
#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem
vacuum_cost_delay 参数
#vacuum_cost_delay = 0
#autovacuum_vacuum_cost_delay = 20ms
vacuum_cost_limit 参数
#vacuum_cost_limit = 200
#autovacuum_vacuum_cost_limit = -1
参数优化测试用例
使用 pgbench 生成 5000 万测试数据。
pgbench -i -s 500 alvindb
设置表级 AUTOVACUUM 相关参数:
ALTER TABLE pgbench_accounts SET (autovacuum_vacuum_scale_factor = 0.1, autovacuum_vacuum_threshold = 2000);
ALTER TABLE pgbench_accounts SET (autovacuum_analyze_scale_factor = 0.05, autovacuum_analyze_threshold = 2000);
删除 2000 万数据:
DELETE FROM pgbench_accounts WHERE aid>=1500001 AND aid <=3500000;
DELETE FROM pgbench_accounts WHERE aid>=15000001 AND aid <=17000000;
DELETE FROM pgbench_accounts WHERE aid>=25000001 AND aid <=28000000;
DELETE FROM pgbench_accounts WHERE aid>=35000001 AND aid <=38000000;
DELETE FROM pgbench_accounts WHERE aid>=40000001;
另外,将 autovacuum_naptime 设置为 3min 以给删除数据留够时间。
alvindb=> SHOW autovacuum_naptime;
autovacuum_naptime
--------------------
3min
(1 row)
AUTOVACUUM 测试
首先采用默认参数:
SHOW maintenance_work_mem;
maintenance_work_mem
----------------------
64MB
(1 row)
SHOW autovacuum_work_mem;
autovacuum_work_mem
---------------------
-1
(1 row)
SHOW autovacuum_vacuum_cost_delay;
autovacuum_vacuum_cost_delay
------------------------------
20ms
(1 row)
SHOW autovacuum_vacuum_cost_limit;
autovacuum_vacuum_cost_limit
------------------------------
-1
(1 row)
SHOW vacuum_cost_limit;
vacuum_cost_limit
-------------------
200
(1 row)
执行测试用例的同时,通过如下 SQL 查询
SELECT * FROM pg_stat_activity WHERE backend_type ~ 'autovacuum worker' AND pid <> pg_backend_pid();\watch 1
可以看到, AUTOVACUUM 已触发,并且 autovacuum worker 已启动,先是 query 为空,而后 query 为 VACUUM ANALYZE public.pgbench_accounts。
2021年11月07日 星期日 23时17分09秒 (every 1s)
-[ RECORD 1 ]----+------------------------------
datid | 37509
datname | alvindb
pid | 16660
usesysid |
usename |
application_name |
client_addr |
client_hostname |
client_port |
backend_start | 2021-11-07 23:17:09.427627+08
xact_start | 2021-11-07 23:17:09.426378+08
query_start |
state_change |
wait_event_type |
wait_event |
state |
backend_xid |
backend_xmin | 13180269
query |
backend_type | autovacuum worker
2021年11月07日 星期日 23时17分10秒 (every 1s)
-[ RECORD 1 ]----+---------------------------------------------------
datid | 37509
datname | alvindb
pid | 16660
usesysid |
usename |
application_name |
client_addr |
client_hostname |
client_port |
backend_start | 2021-11-07 23:17:09.427627+08
xact_start | 2021-11-07 23:17:09.459083+08
query_start | 2021-11-07 23:17:09.459083+08
state_change | 2021-11-07 23:17:09.459084+08
wait_event_type |
wait_event |
state | active
backend_xid |
backend_xmin | 13180269
query | autovacuum: VACUUM ANALYZE public.pgbench_accounts
backend_type | autovacuum worker
完成后,根据 last_autoanalyze 和 last_autovacuum 得知是先做了 VACUUM,然后做 ANALYZE:
schemaname | public
relname | pgbench_accounts
autovacuum_vacuum_scale_factor | 0.1
autovacuum_vacuum_threshold | 2000
autovacuum_analyze_scale_factor | 0.05
autovacuum_analyze_threshold | 2000
n_live_tup | 30000000
reltuples | 30000000
autovacuum_analyze_trigger | 1502001
n_mod_since_analyze | 0
rows_to_mod_before_analyze | 1502001
last_autoanalyze | 2021-11-07 23:22:41.640812+08
autovacuum_vacuum_trigger | 3002001
n_dead_tup | 142848
rows_to_delete_before_vacuum | 2859153
last_autovacuum | 2021-11-07 23:22:14.06792+08
查看 PostgreSQL 日志,得知 VACUUM 用时 304.60 s,ANALYZE 用时 27.56 s。
[ 2021-11-07 23:22:14.067 CST 16660 6187edf5.4114 1 3/238595 13180270]LOG: automatic vacuum of table "alvindb.public.pgbench_accounts": in
dex scans: 2
pages: 35699 removed, 165914 remain, 576 skipped due to pins, 0 skipped frozen
tuples: 6190880 removed, 30142834 remain, 0 are dead but not yet removable, oldest xmin: 13180269
buffer usage: 419596 hits, 40795 misses, 100492 dirtied
avg read rate: 4.185 MB/s, avg write rate: 10.310 MB/s
system usage: CPU: user: 14.02 s, system: 1.41 s, elapsed: 304.60 s
[ 2021-11-07 23:22:41.640 CST 16660 6187edf5.4114 2 3/238596 13180271]LOG: automatic analyze of table "alvindb.public.pgbench_accounts" system usage: CPU: user: 3.25 s, system: 7.58 s, elapsed: 27.56 s
通过调整参数,逐步并反复测试,结果如下:
| maintenance_work_mem | autovacuum_vacuum_cost_delay | vacuum_cost_limit | AUTOVACUUM 用时 |
|---|---|---|---|
| 64MB | 20ms | 200 | 304.60 s + 27.56 s |
| 64MB | 2ms | 200 | 39.45 s +8.73 s |
| 64MB | 2ms | 2000 | 18.79 s + 5.50 s |
| 64MB | 2ms | 200 | 42.04 s + 8.00 s |
| 64MB | 20ms | 200 | 329.72 s + 22.82 s |
| 64MB | 0ms | 2000 | 17.72 s + 3.45 s |
| 512MB | 0ms | 2000 | 12.75 s + 3.35 s |
| 64MB | 0ms | 2000 | 15.13 s + 5.45 s |
根据如上测试,可以验证,适当增大 autovacuum_work_mem 和 autovacuum_vacuum_cost_limit、减少 autovacuum_vacuum_cost_delay 可提高 AUTOVACUUM 性能。
手动 VACUUM ANALYZE 测试
下面测试手动 VACUUM ANALYZE。测试方法基本与 AUTOVACUUM 一样。
这里主要简单测试下 maintenance_work_mem,其他不再重复测试。
关闭 autovacuum 并将 vacuum_cost_delay 设置为 0,并手动执行如下 SQL:
VACUUM ANALYZE pgbench_accounts;
用时统计如下:
| maintenance_work_mem | vacuum_cost_delay | vacuum_cost_limit | AUTOVACUUM 用时 |
|---|---|---|---|
| 64MB | 0ms | 2000 | 23.137 s |
| 128MB | 0ms | 2000 | 18.284 s |
| 64MB | 0ms | 2000 | 24.144 s |
根据如上测试,可以验证,适当增大 maintenance_work_mem 和 vacuum_cost_limit、减少 vacuum_cost_delay 可提高 AUTOVACUUM 性能。
与 AUTOVACUUM 不同的是,手动 VACUUM 可以通过如下方式设置参数。这样,在实际工作中,就可以灵活调整参数而不需要改配置文件了。
SET vacuum_cost_delay = 10;
VACUUM ANALYZE pgbench_accounts;
公众号
关注 DBA Daily 公众号,第一时间收到文章的更新。
通过一线 DBA 的日常工作,学习实用数据库技术干货!

公众号优质文章推荐
[PG Upgrade Series] Extract Epoch Trap
[PG Upgrade Series] Toast Dump Error
GitLab supports only PostgreSQL now
PostgreSQL VACUUM 之深入浅出 (四)的更多相关文章
- PostgreSQL VACUUM 之深入浅出 (一)
前言 VACUUM 是 PostgreSQL MVCC (Multiversion concurrency control) 实现的核心机制之一,是 PostgreSQL 正常运行的重要保证.本文将通 ...
- PostgreSQL VACUUM 之深入浅出 (二)
AUTOVACUUM AUTOVACUUM 简介 PostgreSQL 提供了 AUTOVACUUM 的机制. autovacuum 不仅会自动进行 VACUUM,也会自动进行 ANALYZE,以分析 ...
- PostgreSQL VACUUM 之深入浅出 (三)
VACUUM 相关参数 对 VACUUM 有了一定的了解之后,下面系统介绍下 VACUUM 相关参数. VACUUM 相关参数主要分为三大类. 第一类 与资源相关参数 #--------------- ...
- postgresql vacuum操作
postgresql vacuum操作 PostgreSQL数据库管理工作中,定期vacuum是一个重要的工作.vacuum的效果: 1.1释放,再利用 更新/删除的行所占据的磁盘空间. 1.2更新P ...
- Postgresql VACUUM COPY等
1.VACUUM VACUUM回收dead tuples占用的存储空间. 在一般的PostgreSQL操作中,被update操作删除或废弃的元组不会从物理表中删除; 它们一直存在,直到执行VACUUM ...
- PostgreSQL 务实应用(四/5)JSON
JSON 可谓风靡互联网,在数据交换使用上,其优势特别明显,其结构简洁.可读易读.形式灵活.很多 API 接口的数据都采用 JSON 来表示. PostgreSQL 对 JSON 提供了良好的支持.具 ...
- VC++动态链接库(DLL)编程深入浅出(四)
这是<VC++动态链接库(DLL)编程深入浅出>的第四部分,阅读本文前,请先阅读前三部分:(一).(二).(三). MFC扩展DLL的内涵为MFC的扩展,用户使用MFC扩展DLL就像使用M ...
- PostgreSQL Replication之第四章 设置异步复制(7)
4.7 冲突管理 在PostgreSQL中,流复制数据仅在一个方向流动.XLOG由master提供给几个slave,这些slave消耗事务日志并为您提供一个较好的数据备份.您可能想知道这怎么会导致冲突 ...
- 跟我一起读postgresql源码(十四)——Executor(查询执行模块之——Join节点(下))
3.HashJoin 节点 postgres=# explain select a.*,b.* from test_dm a join test_dm2 b on a.xxx = b.xxx; QUE ...
随机推荐
- java下拉框转换公共方法
1. 下拉框实例类 import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang3.Boolean ...
- ARTS Week 22
Algorithm 本周的 LeetCode 题目为 297. 二叉树的序列化与反序列化 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也 ...
- 带你十天轻松搞定 Go 微服务系列(三)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务(本文) 产品服务 订单服务 支付服务 RPC 服务 Auth ...
- MySQL语句SQL应用
目录 一:sql语句 1.什么是SQL语句? 二:基本SQL语句之库操作 三:基本SQL语句之表操作 1.查看当前所在库名称 2.切换数据库 四:基本SQL语句之记录操作 五:创建表的完整语法 一:s ...
- yum搭建私有仓库远程版
目录 一:yum安装 1.简介 1.安装 2.卸载 3.更新 4.yum安装的生命周期 二:yum搭建私有仓库(本地版) 1.下载必须的软件包(准备配置) 2.创建软件仓库 3.下载对应的软件 4.初 ...
- 多选菜单shell脚本
有 很多方法 可以读取Bash脚本中的用户输入. 但是,允许用户键入输入会带来一些问题. 主要问题是输入验证,您必须在其中考虑所有可能的输入. 解决此问题的一种简单方法是为Bash脚本创建一个多选菜单 ...
- Halcon视觉入门芯片识别
Halcon视觉入门芯片识别 需求 有如下图的一个摆盘,摆盘的方格中摆放芯片,一个格子中只放一个,我们需要知道每个方格中是否有芯片去指导我们将芯片放到空的方格中. 分析 通过图片分析得出 我们感兴趣的 ...
- WebService、Http请求、Socket请求
WebService 定义 一种web程序访问方式,常见协议:SOAP(简单对象访问协议),其实就是Http+XML.利用对象进行数据交互. 请求方法 import lombok.extern.slf ...
- String存放位置
简介 字符串在不同的JDK版本中,存放的位置不同,创建方式不同,存放的位置也不同. 存放位置 JDK1.7以下,无论何种方法创建String对象,位置都位于方法区. JDK1.8及1.8以上,new ...
- Swift 类的构造函数
构造函数的介绍 构造函数类似于OC中的初始化方法:init方法 默认情况下载创建一个类时,必然会调用一个构造函数 即便是没有编写任何构造函数,编译器也会提供一个默认的构造函数. 如果是继承自NSObj ...