PostgreSQL之Vacuum processing

Outline of concurrent vacuum

做了什么

真空处理对数据库中的指定表或所有表执行以下任务:

1.移除死元组(空间整理,包含表数据,索引数据)

oracle如何进行空间整理?手动进行尺寸thrink

  • 删除死元组并对每个页面的活元组进行碎片整理。
  • 删除指向死元组的索引元组

2.冷冻老的txid

  • 必要时冻结老元组的txid
  • 更新冻结的与系统目录(pg_database和pg_class)相关的txid
  • 如有可能,移除clog中不必要的部分

3.其他

  • 更新已处理的fsm和vm.
  • 更新几个统计数据(pg_stat_all_tables等),给优化器提供可参考的信息

处理流程(扫描->空间整理,更新统计信息和fsm,vm->clog删除)

  1. 从指定的表中获取每个表
  2. 获取表的shareupdateExclusiveLock锁,此锁允许读取其他事务.不能做dml操作???
  3. 扫描所有页面以获取所有死元组,必要时冻结旧元组.
  4. 如果存在,则移除执行相应死元组的索引元组.
  5. 对表的每一页执行步骤6)和7)
  6. 移除死元组并重新分配页面中的活元组 
  7. 更新目标表的相应的fsm和vm 
  8. 如果最后一页没有元组,则截断最后一页;中间有空的块不会删除
  9. 更新与目标表的真空处理相关的统计数据和系统目录
  10. 更新与真空处理相关的统计数据和系统目录
  11. 如果可能的话,删除不必要的文件和clog页面.

First Block

执行冻结处理并删除指向死元组的索引元组

  1. 扫描目标表,创建死元组列表
  2. 通过死元组列表删除表和索引元组,即清理阶段
  3. 如此循环直到清完为止

Second Block

PostgreSQL之Vacuum processing_第1张图片

Third Block

  1. 第三个块更新与每个目标表的真空处理相关的统计信息和系统目录 
  2. 此外,如果最后一页没有元组,则从表文件中将其截断
  3. 如果可能的话,他会删除不必要的clog部分

Visibility map

可见性地图的作用是给vacuum操作的时候提供辅助手段,以此来提高vacuum的效率。

PostgreSQL之Vacuum processing_第2张图片

功能增强

  • 9.6版本之后vacuum得到了增强,以提高冻结处理效率
  • 新的vm显示页面可见性和关于在每个页面中元组是否冻结的信息

Freeze processing 空间整理是密集型IO

冻结处理有两种模式:

  • Lazy mode (惰性模式) ,日常做卫生
    • 什么时候触发冻结?什么时候开始做vacuum? autovacuum,1分钟一次。不是每次都要出发冻结,由参数vacuum_freeze_min_age来控制.默认值5kw.xid用过5kw,等到一次vacuum,会触发惰性冻结。
    • 冻结极限txid定义如下:
      • freezelimit_txid=(oldestxmin-vacuum_freeze_min_age) 
      • oldestxmin当前事务中最早的没有完成的事务id。
      • 低于freezelimit_txid的事务所修改的行都要冻结
    • 冻结最大的目的是为了行可见性判断。
    • vm减少了块扫描次数
    • 原理:
      • 在t_infomask上标识xmin_frozen.惰性冻结只处理含有无效数据的块。

PostgreSQL之Vacuum processing_第3张图片

  • Eager mode (急切模式) 年终大扫除
    • 条件:pg_database.datfrozenxid<(OldestXmin−vacuum_freeze_table_age) 
    • 冻结极限id: freezelimit_txid=(oldestxmin-vacuum_freeze_min_age) 
    • datfrozenxid 数据字典列,表示数据库最近一次被冻结(急性冻结)的时候事务id号
    • vacuum_freeze_table_age 1亿5kw;每用1.5亿就会发生急性冻结。
    • 表级和库级冻结xid的关系
    • PostgreSQL之Vacuum processing_第4张图片
    • 早期的急切冻结所有数据块都要扫描。(密集型IO) 
      • 一次急性冻结数据库的 datfrozenxid 都会被全部更新,冻结是所有数据库一起做。
      • pg_class 的 relfrozenxid 记录了表急性冻结id。
    • 后期版本
      • 如果数据块中所有数据被惰性冻结了,且未发生修改(增删改),用1表示,就告诉pg没有需要冻结的行,下次急性冻结的时候会跳过。
      • 利用vm辅助告诉pg什么时候需要扫描数据块。
    • 冻结的目的是 
      • 为了简化多版本数据行可见性规则的判断。 
      • 快速的回收事务id,事务id空间是有限的,冻结过的事务id才是可用的。(事务id是边用边管理) 
    • 冻结后不再去判断事务状态,直接根据t_infomask 的XMIN_FROZEN 判断事务状态是提交,可见性。 
    • 凡是状态是XMIN_FROZEN 的都是被提交的,未提交的数据经过整理后都已经被删掉了。

     PostgreSQL之Vacuum processing_第5张图片

Removing unnecessary clog files

什么时候删除不需要的clog?

什么时候删除clog?判断行可见性是否用得着clog,用不着就可以删除。

PostgreSQL之Vacuum processing_第6张图片

Autovacuum daemon

9.3版本之前需要手动去做,后面的版本有专门的autovacuum。

  • 默认每分钟执行一次,由autovacuum_naptime参数定义
  • 默认调用三个worker进程进行工作,由autovacuum_max_workers参数定义。

Full vacuum

普通vacuum可以把空间释放,但是表的尺寸不会被释放。

full模式,重建数据文件。

Full vacuum autovacuum是不会帮我们做的,只有手动去做才可以。autovacuum只会帮我们整理空间。

PostgreSQL之Vacuum processing_第7张图片

When should I do vacuum full?

  • Create extension pg_freespacemap;
  • SELECT count(*) as "number of pages",pg_size_pretty(cast(avg(avail) as bigint)) as "Av. freespace size",round(100 * avg(avail)/8192 ,2) as "Av. freespace ratio" from pg_freespace('accounts');
  • 删除完数据autovacuum后会空间整理,表的空间利用率会下降。
  • Select pg_relation_path('ywst.t_ywgy_dzjz_ws');
  • ll -l
  • du -sk
  • autovacuum前后空间不会变化
  • Vacuum full前后filenode会变,空间使用率提升。
  • 对于大表需要定时查看是否需要full vacuum
  • Full vacuum 的好处,全表扫描的代价是不一样的。
  • SELECT count(*) as "number of pages",pg_size_pretty(cast(avg(avail) as bigint)) as "Av. freespace size",round(100 * avg(avail)/8192 ,2) as "Av. freespace ratio" FROM pg_freespace('');

编译安装插件:

Cd $PGDATA/contrib/pg_freespacemap/

Make

Make install

vacuum处理表的目的

  • 恢复或者重用由update和delete删除元组后占用的磁盘空间
  • 更新由postgresql查询计划器使用的数据统计信息
  • 更新可见性映射,可以加快index-only scan的速度
  • 保护由于事务ID循环处理或者多个事务ID循环处理导致的老旧数据的丢失

vacuum和 vacuum full 对比。

VACUUM

VACUUM FULL

1.如果删除的记录位于表的末端,其所占用的空间将会被物理释放并归还操作系统。

1.不论被删除的数据是否处于数据表的末端,这些数据所占用的空间都将被物理的释放并归还于操作系统。之后再有新数据插入时,将分配新的磁盘页面以供使用。

2.如果不是末端数据,该命令会将指定表或索引中被删除数据所占用空间重新置为可用状态,那么在今后有新数据插入时,将优先使用该空间,直到所有被重用的空间用完时,再考虑使用新增的磁盘页面。

2.full vacuum新建一个数据文件,将每行剩下的行放到新的数据文件,可用减少表对尺寸;

3.vacuum可以与dml并行运行,但不能与ddl并行运行

3.vacuum full不能与dml、ddl并行运行获取排它锁

表级别的共享更新排它锁。

可并发进行数据库对象清理。

访问排它锁。

经常执行更新和删除操作,没有插入操作时。

只能一次执行一个。

Vacuum更新表统计信息

Vacuum通过analyze可更新表对象统计信息。Postgresql查询计划器通过表对象统计信息生成查询计划。可以通过vacuum的可选选项analyze在对dead tuple标记或者清理时同时更新表的统计信息,以便于查询计划器生成更好的执行计划。

对于autovacuum启动状态下,postgresql将会自动执行analyze命令。

可见性映射-VM

Vm是可见性映射文件表,每个表都有可见性映射文件,以跟踪页面中包含一致对象所有活跃事务可见的元组,同时也跟踪页面仅包含冻结的元组。该文件命名以表对象oid为前缀,——vm为后缀存在。

可见性映射是一个位图,每个heap page都有两个位,表示全部页面可见和全部页面冻结。

如果可见位被设置,意味着页面上所有元组对于所有事物都是可见的,因此,该页面不需要清理。

如果冻结位被设置,意味着页面上所有元组都被完全冻结,因此,即使需要对整个表进行vacuum,也无需对该页面进行vacuum处理,仅当页面全部已经可见时,才需要对全冻结位设置。

你可能感兴趣的:(PostgreSQL笔记,dba)