签到成功

知道了

CNDBA社区CNDBA社区

openGauss VACUUM 说明

2023-04-18 00:02 1504 0 原创 openGauss
作者: dave

1 VACUUM 说明

1.1 背景说明

在之前的博客我们了解到openGauss中有两种数据引擎:Astore和Ustore。http://www.cndba.cn/cndba/dave/article/116557

Astore采用追加更新模式,即同一个page页中既存在前映像也存在当前值,只是前映像会被标记为删除。

Astore是opengauss的默认存储引擎,Astore存储引擎由于同一个块中包含太多的前映像,如果频繁的更新操作会导致大量的磁盘“垃圾”,因为在执行查询操作的时候即使标记了删除也会扫描,所以大大的降低性能。

openGauss Astore(Append Update)和 Ustore(In-place Update)数据引擎 说明
https://www.cndba.cn/dave/article/116545

为了保证openGauss的性能,需要定期执行VACUUM或者VACUUM full进行清理。VACUUM可以回收表或B-Tree索引中已经删除的行所占据的存储空间,特别是在经常更新的表上。

1.2 vacuum 注意事项

  1. 如果没有参数,VACUUM处理当前数据库里用户拥有相应权限的每个表。如果参数指定了一个表,VACUUM只处理指定的那个表。
  2. 要对一个表进行VACUUM操作,通常用户必须是表的所有者或者被授予了指定表VACUUM权限的用户,默认系统管理员有该权限。数据库的所有者允许对数据库中除了共享目录以外的所有表进行VACUUM操作(该限制意味着只有系统管理员才能真正对一个数据库进行VACUUM操作)。VACUUM命令会跳过那些用户没有权限的表进行垃圾回收操作。
  3. VACUUM不能在事务块内执行。
  4. 建议生产数据库经常清理(至少每晚一次),以保证不断地删除失效的行。尤其是在增删了大量记录之后,对受影响的表执行VACUUM ANALYZE命令是一个很好的习惯。这样将更新系统目录为最近的更改,并且允许查询优化器在规划用户查询时有更好地选择。
  5. 不建议日常使用FULL选项,但是可以在特殊情况下使用。例如在用户删除了一个表的大部分行之后,希望从物理上缩小该表以减少磁盘空间占用。VACUUM FULL通常要比单纯的VACUUM收缩更多的表尺寸。FULL选项并不清理索引,所以推荐周期性的运行REINDEX命令。实际上,首先删除所有索引,再运行VACUUM FULL命令,最后重建索引通常是更快的选择。如果执行此命令后所占用物理空间无变化(未减少),请确认是否有其他活跃事务(删除数据事务开始之前开始的事务,并在VACUUM FULL执行前未结束)存在,如果有等其他活跃事务退出进行重试。
  6. VACUUM会导致I/O流量的大幅增加,这可能会影响其他活动会话的性能。因此,有时候会建议使用基于开销的VACUUM延迟特性。
  7. 如果指定了VERBOSE选项,VACUUM将打印处理过程中的信息,以表明当前正在处理的表。各种有关当前表的统计信息也会打印出来。但是对于列存表执行VACUUM操作,指定了VERBOSE选项,无信息输出。
  8. 当含有带括号的选项列表时,选项可以以任何顺序写入。如果没有括号,则选项必须按语法显示的顺序给出。
  9. VACUUM和VACUUM FULL时,会根据参数vacuum_defer_cleanup_age延迟清理行存表记录,即不会立即清理刚刚删除的元组。
  10. VACUUM ANALYZE先执行一个VACUUM操作,然后给每个选定的表执行一个ANALYZE。对于日常维护脚本而言,这是一个很方便的组合。
  11. 简单的VACUUM(不带FULL选项)只是简单地回收空间并且令其可以再次使用。这种形式的命令可以和对表的普通读写并发操作,因为没有请求排他锁。VACUUM FULL执行更广泛的处理,包括跨块移动行,以便把表压缩到最少的磁盘块数目里。这种形式要慢许多并且在处理的时候需要在表上施加一个排他锁。
  12. VACUUM列存表内部执行的操作包括三个:迁移delta表中的数据到主表、VACUUM主表的delta表、VACUUM主表的desc表。该操作不会回收delta表的存储空间,如果要回收delta表的冗余存储空间,需要对该列存表执行VACUUM DELTAMERGE。
  13. 同时执行多个VACUUM FULL可能出现死锁。
  14. 如果没有打开xc_maintenance_mode参数,那么VACUUM FULL操作将跳过所有系统表。
  15. 执行DELETE后立即执行VACUUM FULL命令,可能不会回收空间,这取决于是否有DELETE事务之前开启的事务仍处于活跃状态。此时需要等待所有事务结束,或者重启数据库,再重新执行VACUUM FULL命令进行清理。

2 自动清理

在openGauss中,系统自动清理线程(autovacuum)自动执行VACUUM和ANALYZE命令,回收被标识为删除状态的记录空间,并更新表的统计数据。http://www.cndba.cn/cndba/dave/article/116557http://www.cndba.cn/cndba/dave/article/116557

自动清理的相关配置参数如下:

http://www.cndba.cn/cndba/dave/article/116557

openGauss=# select name,setting,context,source from pg_settings where name like '%autovacuum%';
              name               |  setting   |  context   |       source       
---------------------------------+------------+------------+--------------------
 autovacuum                      | on         | sighup     | configuration file
 autovacuum_analyze_scale_factor | 0.1        | sighup     | default
 autovacuum_analyze_threshold    | 50         | sighup     | default
 autovacuum_freeze_max_age       | 4000000000 | postmaster | default
 autovacuum_io_limits            | -1         | sighup     | default
 autovacuum_max_workers          | 3          | postmaster | default
 autovacuum_mode                 | mix        | sighup     | default
 autovacuum_naptime              | 600        | sighup     | default
 autovacuum_vacuum_cost_delay    | 20         | sighup     | default
 autovacuum_vacuum_cost_limit    | -1         | sighup     | default
 autovacuum_vacuum_scale_factor  | 0.2        | sighup     | default
 autovacuum_vacuum_threshold     | 50         | sighup     | default
 log_autovacuum_min_duration     | -1         | sighup     | default
(13 rows)

关于这些参数的说明,直接参考官方手册:

https://docs.opengauss.org/zh/docs/5.0.0/docs/DatabaseReference/%E8%87%AA%E5%8A%A8%E6%B8%85%E7%90%86.htmlhttp://www.cndba.cn/cndba/dave/article/116557

3 操作示例

3.1 语法说明

回收空间并更新统计信息,对关键字顺序无要求:

VACUUM [ ( { FULL | FREEZE | VERBOSE | {ANALYZE | ANALYSE }} [,...] ) ]
    [ table_name [ (column_name [, ...] ) ] [ PARTITION ( partition_name ) | SUBPARTITION ( subpartition_name ) ] ] ;

仅回收空间,不更新统计信息:http://www.cndba.cn/cndba/dave/article/116557

VACUUM [ FULL [COMPACT] ] [ FREEZE ] [ VERBOSE ] [ table_name 
[ PARTITION ( partition_name )  | SUBPARTITION ( subpartition_name ) ] ] ;

回收空间并更新统计信息,且对关键字顺序有要求:http://www.cndba.cn/cndba/dave/article/116557

http://www.cndba.cn/cndba/dave/article/116557

VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] { ANALYZE | ANALYSE } [ VERBOSE ] 
    [ table_name [ (column_name [, ...] ) ] ] [ PARTITION ( partition_name ) ];

这里要注意 FULL 选项:

  1. 选择“FULL”清理,这样可以恢复更多的空间,但是需要耗时更多,并且在表上施加了排他锁,会影响业务的使用。
  2. 使用FULL参数会导致统计信息丢失,如果需要收集统计信息,需要在VACUUM FULL语句中加上analyze关键字。

3.2 操作示例

[dave@www.cndba.cn ~]$ gsql -h localhost -p 15500 -d postgres -U omm -W omm@123456 -r 
gsql ((openGauss 5.0.0 build a07d57c3) compiled at 2023-03-29 03:07:56 commit 0 last mr  )
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.

openGauss=# vacuum analyze cndba;
VACUUM

openGauss=# vacuum verbose cndba;
INFO:  vacuuming "public.cndba"(dn_6001_6002_6003 pid=3297)
INFO:  "cndba": found 0 removable, 2 nonremovable row versions in 1 out of 1 pages(dn_6001_6002_6003 pid=3297)
DETAIL:  0 dead row versions cannot be removed yet. There were 0 unused item pointers. 0 pages are entirely empty. CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM

openGauss=# vacuum (verbose,analyze) cndba;
INFO:  vacuuming "public.cndba"(dn_6001_6002_6003 pid=3297)
INFO:  "cndba": found 0 removable, 2 nonremovable row versions in 1 out of 1 pages(dn_6001_6002_6003 pid=3297)
DETAIL:  0 dead row versions cannot be removed yet. There were 0 unused item pointers. 0 pages are entirely empty. CPU 0.00s/0.00u sec elapsed 0.00 sec.
INFO:  analyzing "public.cndba"(dn_6001_6002_6003 pid=3297)
INFO:  ANALYZE INFO : "cndba": scanned 1 of 1 pages, containing 2 live rows and 0 dead rows; 2 rows in sample, 2 estimated total rows(dn_6001_6002_6003 pid=3297)
VACUUM

openGauss=# vacuum (full,analyze) cndba;
VACUUM

openGauss=# vacuum (verbose,full,analyze) cndba;
INFO:  vacuuming "public.cndba"(dn_6001_6002_6003 pid=3297)
INFO:  "cndba": found 0 removable, 2 nonremovable row versions in 1 pages(dn_6001_6002_6003 pid=3297)
DETAIL:  0 dead row versions cannot be removed yet.
CPU 0.00s/0.00u sec elapsed 0.01 sec.
INFO:  analyzing "public.cndba"(dn_6001_6002_6003 pid=3297)
INFO:  ANALYZE INFO : "cndba": scanned 1 of 1 pages, containing 2 live rows and 0 dead rows; 2 rows in sample, 2 estimated total rows(dn_6001_6002_6003 pid=3297)
VACUUM

openGauss=# vacuum (verbose,full,analyze) customer_par partition(p1);
INFO:  vacuuming "public.customer_par"(dn_6001_6002_6003 pid=3297)
INFO:  "customer_par": found 0 removable, 0 nonremovable row versions in 0 pages(dn_6001_6002_6003 pid=3297)
DETAIL:  0 dead row versions cannot be removed yet.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM
openGauss=#

查看表占用空间大小:

http://www.cndba.cn/cndba/dave/article/116557

openGauss=# SELECT nspname || '.' || relname AS "relation",
 pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
 FROM pg_class C
 LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
 WHERE nspname NOT IN ('pg_catalog', 'information_schema')
 AND C.relkind <> 'i'
 AND nspname !~ '^pg_toast' and relname='cndba';

   relation   | total_size 
--------------+------------
 public.cndba | 8192 bytes
(1 row)

4 VACUUM FULL表大小无变化

当对表使用VACUUM FULL也可能出现清理完成后表大小和清理前一样大的情况。

假定该表的名称为table_name,对于该现象可能有以下两种原因:http://www.cndba.cn/cndba/dave/article/116557

  1. table_name表本身没有delete过数据,使用VACUUM FULL table_name后无需清理delete的数据。
  2. 在执行VACUUM FULL table_name时有并发的事务存在,可能会导致VACUUM FULL跳过清理最近删除的数据,导致清理不完全。

对于第二种可能原因,有如下两种处理方法:

  1. 如果在VACUUM FULL时有并发的事务存在,此时需要等待所有事务结束,再次执行VACUUM FULL命令对该表进行清理。
  2. 再使用以下命令查看活跃事务列表: select txid_current_snapshot(); 如果发现活跃事务列表中有XID比当前的事务XID小时,停止数据库再启动数据库,再次使用VACUUM FULL。

版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2261
    原创
  • 3
    翻译
  • 578
    转载
  • 191
    评论
  • 访问:8014373次
  • 积分:4346
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ