天天看点

Postgresql的vacuum机制一些理解

我们知道,postgresql(以下简称pg)多版本控制mvcc和oracle有所不同,oracle通过回滚段实现,数据更新之前先将旧版本数据写入回滚段,然后再将待更新数据写入原data block,而pg mvcc则是当元组发生更改时,直接在原数据data page插入一条新的记录,同时将原元组逻辑上标识为删除,这些标识为删除的元组也叫死元组。这就导致当进行多次更新和删除操作,磁盘上会多出很多死元组,占用了很多磁盘空间并且导致系统性能下降。

vacuum的作用则是回收这些这些无效的空间。

vacuum命令

VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]

其中option可以是下列之一:

    FULL [ boolean ]
    FREEZE [ boolean ]
    VERBOSE [ boolean ]
    ANALYZE [ boolean ]
    DISABLE_PAGE_SKIPPING [ boolean ]
    SKIP_LOCKED [ boolean ]
    INDEX_CLEANUP [ boolean ]
    TRUNCATE [ boolean ]

而table_and_columns是:

    table_name [ ( column_name [, ...] ) ]
           

full vacuum和lazy vacuum

full vacuum:会加上排他锁,这意味着full vacuum期间,读写操作会被阻塞起来。并在执行过程中会生成fraged_pages和vacuum_pages两个链表,fraged_pages是可填充元组的文件块,而vacuum_pages是待清理的死元组文件块。当扫完关系表后,通过fraged_pages对有效元组跨块移动,通过vacuum_pages对死元组进行清理,并把清理后的磁盘空间归还给操作系统。

lazy vacuum: 不会加上排他锁,读写操作可并行,只是简单死元组块标识为未使用,这些文件块不会归还给操作系统。

analyze

更新优化器的统计信息。当一张表(特别是大表)短时间频繁更新,优化器的统计信息是不及时的,或者是不准确的。这样会导致优化器执行查询sql时选择错误的执行计划,导致sql查询性能差。可功过analyze更新指定表(甚至指定列)的统计信息。

参考文献

1、http://www.postgres.cn/docs/12/sql-vacuum.html

2、《postgresql数据库内核分析》