如何处理表或索引的膨胀
首先说明:
vacuum命令一般不会减小table的大小,vacuum的作用是释放dead tuple占用的空间,释放出来的空间可以被本表上的其他事务重用。
1、缓解膨胀:
可以从数据库参数层面进行优化:
配置较为积极的数据库参数,目的是让autovacuum操作尽快尽早进行,以便dead tuple占用的空间被尽早释放,进而可被本表上的其他事物重用。
autovacuum_naptime=15ms |
2、解决膨胀的方法之一:vacuum full
postgresql 的 vacuum full 需要 access exclusive lock,获得这个锁后,针对该表的所有操作均无法执行,包括 select。因此,本方法的适用场景是业务停机状态下。
vacuum full需要额外的磁盘空间,因为vacuum full的过程是建立新表的过程。
vacuum full的过程,会改变table的pg_relation_filepath,会改变index的pg_relation_filepath
vacuum full的过程,不会改变table的oid,不会改变index的oid
注意:使用vacuum full会造成锁表,禁止在业务运行高峰期时使用
3、解决膨胀的方法之二:使用pg_repack extension。
截止目前,pg_repack的最新版本是1.4.5,支持的PostgreSQL版本是9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 10, 11, 12
pg_repack可以单独编译安装,编译安装的前提:
要求服务器操作系统上有gcc、zlib、zlib-devel、readline-devel 操作系统包
pg_repack安装之后,在bin目录下形成pg_repack命令。
pg_repack的运行不会使用独占锁,pg_repack运行时对target table持有ACCESS SHARE LOCK
pg_repack的使用前提:
1.超级用户运行
2.表必须有primary key,或者至少一个unique key,且组成unique key的列是非空列。
3.需要足够的空余磁盘空间,假设表和索引是1GB,那么至少需要2GB的空余磁盘空间。
警告:不带任何参数的pg_repack会直接repack,不要pg-repack不带参数直接敲回车!!!
pg_repack的使用限制:
1.不能对temp table使用
2.不能对GiST index使用
3.在pg_repack运行过程中,不能执行DDL语句(除了vacuum、analyze)
4.pg_repack是服务器端的程序,因此必须在服务器端安装pg_repack
pg_repack的过程,会改变table的pg_relation_filepath,会改变index的pg_relation_filepath
pg_repack的过程,不会改变table的oid,不会改变index的oid
pg_repack执行的细粒度
1.针对某个schema
2.针对某个table及其索引
3.针对某个index
4.针对某个表上的所有索引