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