VACUUM FULL执行慢
VACUUM FULL执行慢的常见场景及处理方法如下:
场景一:存在锁等待导致VACUUM FULL执行慢
- 8.1.x及以上集群版本的处理方法:
- 通过查询pgxc_lock_conflicts视图查看锁冲突情况。
1
SELECT * FROM pgxc_lock_conflicts;
- 在查询结果中查看granted字段为“f”,表示VACUUM FULL语句正在等待其他锁。granted字段为“t”,表示INSERT语句是持有锁。nodename,表示锁产生的位置,即CN或DN位置,例如cn_5001,继续执行2。
- 如果查询结果为0 rows,则表示不存在锁冲突。则需排查其它场景。
- 根据语句内容判断是终止持锁语句后继续执行VACUUM FULL还是在业务低峰期选择合适的时间执行VACUUM FULL。
如果要终止持锁语句,则执行以下语句。pid从上述步骤1获取,cn_5001为所查询到的nodename。
1
execute direct on (cn_5001) 'SELECT PG_TERMINATE_BACKEND(pid)';
- 语句终止后,再重新执行VACUUM FULL。
1
VACUUM FULL table_name;
- 8.0.x及以前版本的处理方法:
- 在数据库中执行语句,获取VACUUM FULL操作对应的query_id。
1
SELECT * FROM pgxc_stat_activity WHERE query LIKE '%vacuum%'AND waiting = 't';
- 根据1获取的query_id,执行以下语句查看是否存在锁等待。
1
SELECT * FROM pgxc_thread_wait_status WHERE query_id = {query_id};
- 查询结果中“wait_status”存在“acquire lock”表示存在锁等待。同时查看“node_name”显示在对应的CN或DN上存在锁等待,记录相应的CN或DN名称,例如cn_5001或dn_600x_600y,继续执行3。
- 查询结果中“wait_status”不存在“acquire lock”,排除锁等待情况,继续排查其它场景。
- 执行以下语句,到等锁的对应CN或DN上从pg_locks中查看VACUUM FULL操作在等待哪个锁。以cn_5001为例,如果在DN上等锁,则改为相应的DN名称。pid为2获取的tid。
回显中记录relation的值。
1
execute direct on (cn_5001) 'SELECT * FROM pg_locks WHERE pid = {tid} AND granted = ''f''';
- 根据获取的relation,从pg_locks中查看当前持有锁的pid。relation从3获取。
1
execute direct on (cn_5001) 'SELECT * FROM pg_locks WHERE relation = {relation} AND granted = ''t''';
- 根据pid,执行以下语句查到对应的SQL语句。pid从4获取。
1
execute direct on (cn_5001) 'SELECT query FROM pg_stat_activity WHERE pid ={pid}';
- 根据语句内容判断是终止持锁语句后继续执行VACUUM FULL还是在业务低峰期选择合适的时间执行VACUUM FULL。
如果要终止持锁语句,则执行以下语句。pid从上述4获取,cn_5001为所查询到的nodename。
1
execute direct on (cn_5001) 'SELECT PG_TERMINATE_BACKEND(pid)';
- 语句终止后,再执行VACUUM FULL。
1
VACUUM FULL table_name;
场景二:存在IO/网络问题导致事务无法提交
处理方法:执行一个简单的CRETAE TABLE语句,如果CRETAE TABLE语句执行也很慢,说明可能存在IO/网络问题,可以进一步排查IO和网络情况。
场景三:系统表过大导致VACUUM FULL执行慢
在排除IO/网络问题后,对空表执行VACUUM FULL,即使是空表执行VACUUM FULL也比较慢,则说明是系统表较大导致。因为VACUUM FULL任意一张表时,都会扫描pg_class、pg_partition、pg_proc三张系统表,当这三个系统表过大时,也会导致VACUUM FULL执行较慢。
处理方法:GaussDB(DWS)支持对系统表执行VACUUM FULL,但是会产生八级锁,涉及相关系统表的业务会被阻塞,注意要在业务空闲时间窗或停止业务期间且没有DDL操作时清理系统表。
有关清理系统表的操作,请参考哪些系统表不能做VACUUM FULL。
场景四:列存表使用了局部聚簇(PCK)时,VACUUM FULL执行慢
对列存表执行VACUUM FULL时,如果存在PCK,就会将PARTIAL_CLUSTER_ROWS中多条记录全都加载到内存中再进行排序,如果表较大或psort_work_mem设置较小,会导致PCK排序时产生下盘(数据库选择将临时结果暂存到磁盘),进行外部排序;一旦进行外部排序,时间消耗就会增加很多。
- 执行以下语句查看表定义。回显中存在“PARTIAL CLUSTER KEY”信息,表示存在PCK。
1
SELECT * FROM pg_get_tabledef('table name');
- 登录DWS管理控制台,左侧选择“集群管理”。
- 单击对应的集群名称,进入集群详情页。
- 左侧选择“参数修改”,在搜索栏中输入psort_work_mem进行搜索,将CN参数值和DN参数值同时调大,单击“保存”。
- 再重新执行VACUUM FULL操作。