vacuum与max_fsm_pages关系的分析

本文深入探讨了Greenplum数据库中Vacuum命令的工作原理及其与max_fsm_pages参数之间的关系。通过实验演示了不同场景下Vacuum的操作过程及如何避免max_fsm_pages限制导致的问题。
部署运行你感兴趣的模型镜像

vacuum是postgreSQL和greenplum数据库维护时常用的命令,定期vacuum数据库中的表是防止表过度‘膨胀’的有效方法。

本文就vacuum与max_fsm_pages的关系进行分析,来说明为什么有时vacuum时会出现relation "XXX" contains more than "max_fsm_pages" pages with useful free space这种错误。


1,vacuum的作用是回收已删除元组占据的存储空间。因为MVCC机制,delete和update的元组是没有从表中物理删掉的,在完成vacuum之前一直存在并占据空间。vacuum时使用是读取锁,它会简单地删掉数据页上这些失效的元组,但数据页还是不变,这时就需要fsm(Free Space Map)来记录哪些数据页上有因为vacuum而存在的空闲的空间,可以再插入数据。

vacuum full会使用排它锁,但它并不是只简单地删掉失效的无组,还会移动数据块来尽可能地使用最少的数据页,所以使用vacuum full命令时可以忽略fsm的影响。

greenplum中除了heap表还有appendonly表


greenplum 中对分布键重新设置的功能:

ALTER TABLE [ONLY] name SET 
     DISTRIBUTED BY (column, [ ... ] ) 
   | DISTRIBUTED RANDOMLY 
   | WITH (REORGANIZE=true|false) 

有一个隐含的作用就是vacuum full 该表。


2,实验用表是官方文档中的faa_otp_load,并在此基础上新建一表faa来进行分析。

2.1
--查看表的大小,其实表的大小可以直接根据下面vacuum显示的信息计算出。
--(5575+5278)*32*1024=355631104,5575和5278是该表在两个实例上分别的数据页,greenplum中每张数据页的大小是32K。
tutorial=# select pg_relation_size('faa');               
 pg_relation_size 
------------------
        355631104
(1 row)


--查看vacuum时的详细信息。
tutorial=# vacuum verbose faa;
INFO:  vacuuming "faa.faa"  (seg0 sdw1:40000 pid=2785)
INFO:  vacuuming "faa.faa"  (seg1 sdw2:40000 pid=2770)
INFO:  "faa": found 0 removable, 526707 nonremovable row versions in 5575 pages  (seg0 sdw1:40000 pid=2785)
--这句的意思是现在在主机sdw1上的seg0实例上的5575张数据页上有0个元组可移除,526707不能移除。
DETAIL:  0 dead row versions cannot be removed yet.
--0个失效元组不能被移除。
There were 0 unused item pointers.
--0个没有被使用的指针。
59 pages contain useful free space.
--59个页面有可用的空间。
0 pages are entirely empty.
--0张数据页完全是空的。
CPU 0.28s/0.00u sec elapsed 1.66 sec.
INFO:  vacuuming "pg_toast.pg_toast_860902"  (seg0 sdw1:40000 pid=2785)
INFO:  index "pg_toast_860902_index" now contains 0 row versions in 1 pages  (seg0 sdw1:40000 pid=2785)
--本表中没有出现大字段,为了简洁,关于大字段toast表和索引的记录在后面的文中不再列出。
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
INFO:  "pg_toast_860902": found 0 removable, 0 nonremovable row versions in 0 pages  (seg0 sdw1:40000 pid=2785)
DETAIL:  0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
0 pages contain useful free space.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
INFO:  "faa": found 0 removable, 497845 nonremovable row versions in 5278 pages  (seg1 sdw2:40000 pid=2770)
DETAIL:  0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
64 pages contain useful free space.
0 pages are entirely empty.
CPU 0.15s/0.06u sec elapsed 1.72 sec.
INFO:  vacuuming "pg_toast.pg_toast_860902"  (seg1 sdw2:40000 pid=2770)
INFO:  index "pg_toast_860902_index" now contains 0 row versions in 1 pages  (seg1 sdw2:40000 pid=2770)
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.00s/0.00u sec elapsed 0.09 sec.
INFO:  "pg_toast_860902": found 0 removable, 0 nonremovable row versions in 0 pages  (seg1 sdw2:40000 pid=2770)
DETAIL:  0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
0 pages contain useful free space.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.09 sec.
VACUUM


--查看当前 max_fsm_pages和max_fsm_relations的值,并设置max_fsm_pages为5000以低于之前看到的在每个实例上的数据页。
--max_fsm_pages必须大于 16 * max_fsm_relations,且max_fsm_pages最小必须为100,否则数据库无法启动,这里设为200

--设置完成后重启数据库以使其生效。
[gpadmin@mdw ~]$ gpconfig -s max_fsm_pages
Values on all segments are consistent
GUC          : max_fsm_pages
Master  value: 200000
Segment value: 200000
[gpadmin@mdw ~]$ gpconfig -s max_fsm_relations
Values on all segments are consistent
GUC          : max_fsm_relations
Master  value: 1000
Segment value: 1000
[gpadmin@mdw ~]$ gpconfig -c max_fsm_relations -v 200
20150701:20:09:46:003601 gpconfig:mdw:gpadmin-[INFO]:-completed successfully
[gpadmin@mdw ~]$ gpconfig -c max_fsm_pages -v 5000        
20150701:20:10:04:003681 gpconfig:mdw:gpadmin-[INFO]:-completed successfully
--这里重启数据库。
[gpadmin@mdw ~]$ gpconfig -s max_fsm_pages
Values on all segments are consistent
GUC          : max_fsm_pages
Master  value: 5000
Segment value: 5000
[gpadmin@mdw ~]$ gpconfig -s max_fsm_relations
Values on all segments are consistent
GUC          : max_fsm_relations
Master  value: 200
Segment value: 200


2.2 
--首先看一下将1张表,全删掉时将其vacuum的情况。
tutorial=# delete from faa;       
DELETE 1024552
tutorial=# select pg_relation_size('faa');               
 pg_relation_size 
------------------
        355631104
(1 row)


----------------------
tutorial=# vacuum verbose faa;
INFO:  vacuuming "faa.faa"  (seg0 sdw1:40000 pid=3842)
INFO:  vacuuming "faa.faa"  (seg1 sdw2:40000 pid=4253)
INFO:  "faa": removed 497845 row versions in 5278 pages  (seg1 sdw2:40000 pid=4253)
--移除了 5278 张数据页中的 497845个元组。
INFO:  "faa": found 497845 removable, 0 nonremovable row versions in 5278 pages  (seg1 sdw2:40000 pid=4253)
DETAIL:  0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
5278 pages contain useful free space.
0 pages are entirely empty.
CPU 0.11s/0.06u sec elapsed 3.83 sec.
WARNING:  relation "faa.faa" contains more than "max_fsm_pages" pages with useful free space  (seg1 sdw2:40000 pid=4253)
--报错提示max_fsm_pages的值过低。
HINT:  Consider compacting this relation or increasing the configuration parameter "max_fsm_pages".
INFO:  "faa": truncated 5278 to 0 pages  (seg1 sdw2:40000 pid=4253)
--这里直接truncated 了5278张数据页。
DETAIL:  CPU 0.07s/0.00u sec elapsed 0.26 sec.
INFO:  "faa": removed 526707 row versions in 5576 pages  (seg0 sdw1:40000 pid=3842)
INFO:  "faa": found 526707 removable, 0 nonremovable row versions in 5576 pages  (seg0 sdw1:40000 pid=3842)
DETAIL:  0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
5576 pages contain useful free space.
0 pages are entirely empty.
CPU 0.23s/0.07u sec elapsed 7.19 sec.
WARNING:  relation "faa.faa" contains more than "max_fsm_pages" pages with useful free space  (seg0 sdw1:40000 pid=3842)
HINT:  Consider compacting this relation or increasing the configuration parameter "max_fsm_pages".
INFO:  "faa": truncated 5576 to 0 pages  (seg0 sdw1:40000 pid=3842)
DETAIL:  CPU 0.08s/0.00u sec elapsed 0.37 sec.
VACUUM
tutorial=# select pg_relation_size('faa');
 pg_relation_size 
------------------
                0
(1 row)
-- 由上可以看出当表中没有数据时,vacuum不仅移除了失效的所有元组还直接truncated整张表。
--由此可以看出当需要清空整张表时,直接用truncate以直接释放物理空间。



2.2
--当表中有有效的数据时,vacuum时的情况。
--这里先将表中数据删除掉,再加入数据。
tutorial=# insert into faa select * from faa_otp_load ;
INSERT 0 1024552
tutorial=# delete from faa;
DELETE 1024552
tutorial=# insert into faa select * from faa_otp_load;
INSERT 0 1024552
tutorial=# select pg_relation_size('faa');
 pg_relation_size 
------------------
        711262208
(1 row)


tutorial=# vacuum verbose faa;
INFO:  vacuuming "faa.faa"  (seg0 sdw1:40000 pid=4570)
INFO:  vacuuming "faa.faa"  (seg1 sdw2:40000 pid=4726)
INFO:  "faa": removed 497845 row versions in 5278 pages  (seg1 sdw2:40000 pid=4726)
INFO:  "faa": found 497845 removable, 497845 nonremovable row versions in 10555 pages  (seg1 sdw2:40000 pid=4726)
DETAIL:  0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
5331 pages contain useful free space.
0 pages are entirely empty.
CPU 1.50s/0.45u sec elapsed 99.03 sec.
WARNING:  relation "faa.faa" contains more than "max_fsm_pages" pages with useful free space  (seg1 sdw2:40000 pid=4726)
HINT:  Consider compacting this relation or increasing the configuration parameter "max_fsm_pages".
INFO:  "faa": removed 526707 row versions in 5576 pages  (seg0 sdw1:40000 pid=4570)
INFO:  "faa": found 526707 removable, 526707 nonremovable row versions in 11151 pages  (seg0 sdw1:40000 pid=4570)
DETAIL:  0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
5627 pages contain useful free space.
0 pages are entirely empty.
CPU 1.55s/0.50u sec elapsed 114.73 sec.
WARNING:  relation "faa.faa" contains more than "max_fsm_pages" pages with useful free space  (seg0 sdw1:40000 pid=4570)
HINT:  Consider compacting this relation or increasing the configuration parameter "max_fsm_pages".
VACUUM
--由上可以看出当max_fsm_pages不足时,表中的无效元组还是删除掉了的。




2.3
--此时fsm的作用可通过下面的分析得出。
--现在每个实例上的fsm记录了5000张数据页的情况,则现在向表中插入数据,会先插入fsm上有记录的空闲空间,然后堆在表的后面。
--插入数据后,如果继续对表分析,则fsm会记录之前漏过的有空闲空间的数据页,因其数量已减少,此时可能不会再报错了。



tutorial=# insert into faa select * from faa_otp_load;
INSERT 0 1024552
tutorial=# select pg_relation_size('faa');
 pg_relation_size 
------------------
        902168576
--与之前的相法一致,所用空间并不是355631104*3=1066893312,原表中总数据页为10853,这次插入只额外增加了5027张数据页。


tutorial=# vacuum verbose faa;
INFO:  vacuuming "faa.faa"  (seg0 sdw1:40000 pid=6090)
INFO:  vacuuming "faa.faa"  (seg1 sdw2:40000 pid=6252)
INFO:  "faa": found 0 removable, 995690 nonremovable row versions in 13319 pages  (seg1 sdw2:40000 pid=6252)
DETAIL:  0 dead row versions cannot be removed yet.
There were 263643 unused item pointers.
2854 pages contain useful free space.
0 pages are entirely empty.
CPU 0.59s/0.07u sec elapsed 38.39 sec.
INFO:  "faa": found 0 removable, 1053414 nonremovable row versions in 14213 pages  (seg0 sdw1:40000 pid=6090)
DETAIL:  0 dead row versions cannot be removed yet.
There were 292112 unused item pointers.
3148 pages contain useful free space.
0 pages are entirely empty.
CPU 0.47s/0.10u sec elapsed 41.51 sec.
VACUUM
--果然,继续vacuum并不会报错,因为表中需要记录有空间的数据页的张数已少于5000.


3. max_fsm_pages在postgreSQL中的默认值是20000,postgreSQL中每张数据页的大小是8K,20000*8K约为156M,
这意味着postgreSQL中某张表的delete或update信息超过156M时,vacuum时就会提示fsm不足。
 max_fsm_pages在greenplum中的默认值是200000,greenplum中每张数据页的大小是32K,200000*32K约为6.1G,而且这还是每个实例上的数值。
如果某个greenplum集群有40个实例,但在vacuum时还提示fsm不足,则说明表中的delete或update的失效信息已经超过了244G。
如果提示relation "XXX" contains more than "max_fsm_pages" pages with useful free space,也不用太担心,找个业务不太繁忙的时间vacuum full该表就行了。


您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think> 我们正在讨论如何调整PostgreSQL的自动清理(autovacuum)频率,特别是通过参数autovacuum_vacuum_scale_factor等。 根据引用[1][2][3][4],调整自动清理频率的关键参数包括: - autovacuum_vacuum_scale_factor:触发VACUUM的死元组占表总行数的比例因子 - autovacuum_vacuum_threshold:触发VACUUM的死元组绝对数量阈值 - autovacuum_analyze_scale_factor 和 autovacuum_analyze_threshold:用于触发ANALYZE操作 触发自动VACUUM的条件是: $死元组数量 > autovacuum\_vacuum\_threshold + autovacuum\_vacuum\_scale\_factor \times 表的总行数$ 类似地,触发自动ANALYZE的条件是: $自上次ANALYZE以来插入、更新或删除的元组数量 > autovacuum\_analyze\_threshold + autovacuum\_analyze\_scale\_factor \times 表的总行数$ 默认情况下,自动清理参数为: autovacuum_vacuum_threshold = 50 autovacuum_vacuum_scale_factor = 0.2 autovacuum_analyze_threshold = 50 autovacuum_analyze_scale_factor = 0.1 这意味着,对于一张100万行的表,需要积累的死元组数量达到:$50 + 0.2 \times 1000000 = 200050$ 才会触发自动清理。 对于更新频繁的大表,这个默认设置可能导致死元组积累过多(因为20%的比例对于大表来说太大),因此我们需要调整这些参数。 调整方法: 1. 系统级调整(影响所有表): 修改postgresql.conf文件或使用ALTER SYSTEM命令,例如: ALTER SYSTEM SET autovacuum_vacuum_scale_factor = 0.03; ALTER SYSTEM SET autovacuum_vacuum_threshold = 500; ALTER SYSTEM SET autovacuum_analyze_scale_factor = 0.02; ALTER SYSTEM SET autovacuum_analyze_threshold = 500; 然后重新加载配置(无需重启): SELECT pg_reload_conf(); 2. 表级调整(针对特定表): 如果某张表特别活跃,可以单独设置: ALTER TABLE table_name SET (autovacuum_vacuum_scale_factor = 0.01); ALTER TABLE table_name SET (autovacuum_vacuum_threshold = 1000); ALTER TABLE table_name SET (autovacuum_analyze_scale_factor = 0.01); ALTER TABLE table_name SET (autovacuum_analyze_threshold = 1000); 3. 参数调整建议: - 对于频繁更新的大表:降低scale_factor(例如0.01~0.05),提高threshold(例如500~5000),使得清理更频繁但又不至于过于频繁而影响性能。 - 对于小表:可以适当提高scale_factor,因为小表即使比例高,实际死元组数量也不多。 4. 监控调整效果: 通过查询pg_stat_user_tables视图,观察n_dead_tup的变化,确保死元组数量在触发清理前不会过高。 5. 其他相关参数: - autovacuum_vacuum_cost_delay:控制autovacuum的速度,默认20ms。如果希望autovacuum更快完成,可以减小该值(如0)。 - autovacuum_vacuum_cost_limit:定义autovacuum在一次工作中消耗的总成本,默认值为200。可以适当提高(如1000)以加速清理。 注意:调整参数需要根据具体负载测试,避免autovacuum过于频繁影响正常业务。 示例:调整一个频繁更新的表`orders`,使其在死元组达到1000或总行数的1%时触发自动清理。 ```sql -- 表级调整 ALTER TABLE orders SET (autovacuum_vacuum_scale_factor = 0.01); ALTER TABLE orders SET (autovacuum_vacuum_threshold = 1000); -- 验证设置 SELECT reloptions FROM pg_class WHERE relname = 'orders'; ``` 通过以上调整,可以更精细地控制自动清理的频率,避免表膨胀。 注意:对于更新极其频繁的表,可能需要结合监控和手动清理,特别是在业务高峰期autovacuum可能跟不上时。 引用: [1]:调整系统级autovacuum参数示例[^1] [2]:autovacuumPostgreSQL自动清理死元组的后台进程[^2] [3]:自动清理根据死行数阈值触发,繁忙时会更频繁[^3] [4]:触发条件由阈值和比例因子共同决定[^4] [5]:调整autovacuum_naptime示例(但注意naptime是两次autovacuum进程启动之间的休眠时间,默认1分钟)[^5] 相关问题: 1. 如何监控autovacuum的运行状态? 2. 调整autovacuum参数后如何验证效果? 3. 除了调整参数,还有哪些优化autovacuum的方法? </think> ### 如何调整 PostgreSQL 自动清理频率 通过调整 `autovacuum_vacuum_scale_factor` 等参数可优化自动清理行为,核心公式为: $$ \text{触发清理阈值} = \text{autovacuum\_vacuum\_threshold} + (\text{表总行数} \times \text{autovacuum\_vacuum\_scale\_factor}) $$ 当死元组数量超过该阈值时触发自动清理[^4]。 #### 调整步骤 1. **系统级参数调整**(影响所有表) ```sql -- 降低比例因子使清理更频繁 ALTER SYSTEM SET autovacuum_vacuum_scale_factor = 0.03; -- 默认0.2[^1] -- 降低绝对阈值 ALTER SYSTEM SET autovacuum_vacuum_threshold = 300; -- 默认50[^1] -- 调整分析操作参数 ALTER SYSTEM SET autovacuum_analyze_scale_factor = 0.03;-- 默认0.1 ALTER SYSTEM SET autovacuum_analyze_threshold = 300; -- 默认50[^1] -- 重载配置生效 SELECT pg_reload_conf(); ``` 2. **表级参数调整**(针对特定表) ```sql -- 对高频更新表单独设置 ALTER TABLE 订单表 SET (autovacuum_vacuum_scale_factor=0.01); ALTER TABLE 日志表 SET (autovacuum_vacuum_threshold=500)[^1]; ``` 3. **频率控制参数** ```sql -- 缩短自动清理进程唤醒间隔(默认1min) ALTER SYSTEM SET autovacuum_naptime = '30s'; -- 最小可设10s[^5] ``` #### 参数调整策略 | 场景 | 推荐参数值 | 作用说明 | |---------------------|------------------------------------|------------------------------| | **高频写入大表** | scale_factor=0.01, threshold=1000 | 更频繁清理防止膨胀 | | **低频更新表** | scale_factor=0.05, threshold=100 | 避免过度清理浪费资源 | | **分析操作优化** | analyze_scale_factor=0.02 | 加速统计信息更新[^4] | | **紧急修复膨胀** | 临时设naptime='10s' + 手动VACUUM | 快速回收空间[^5] | #### 验证调整效果 ```sql -- 检查参数生效情况 SELECT name, setting FROM pg_settings WHERE name LIKE 'autovacuum%'; -- 监控清理触发频率 SELECT relname, n_dead_tup, last_autovacuum, age(now(), last_autovacuum) AS 距上次清理 FROM pg_stat_user_tables WHERE n_dead_tup > 0; ``` #### 注意事项 1. **渐进式调整**:先在小规模环境测试,避免频繁清理影响IO性能 2. **监控负载**:调整后观察`pg_stat_activity`中autovacuum进程的资源占用 3. **表大小差异**:对小表优先使用`threshold`,对大表优先调整`scale_factor`[^4] 4. **长期维护**:结合`pg_stat_user_tables`持续监控死元组比例(参考前文方法) > **关键原则**:对于频繁更新的交易系统,应缩小比例因子和阈值使清理更频繁[^1]。通过合理优化,可使autovacuum在繁忙时段更及时回收空间[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值