您的位置:首页 > 数据库 > SQL

autovacuum进程----数据架构师的PostgreSQL修炼

2017-12-16 15:39 776 查看


1. 检查autovacuum进程

[plain] view
plain copy

sherrywangs-MacBook-Pro:data postgres$ ps -fu postgres |grep autov  

  502  3199  3192   0 Sun08PM ??         0:00.27 postgres: autovacuum launcher process  

这是一个可选进程默认在postgresql.conf中,autovacuum = on。


2. 理解vacuum

当从表中删除某些记录时,PostgreSQL并不会立即从数据文件中删除这些记录,他们会被标记为删除。

当更新某些记录时,粗略看起来,像是执行了一次删除和一次插入操作;老版本的记录仍然留在系统中。

为什么这么做呢?

因为有一些正活跃的事务,希望看到它之前的数据。

这就是经典的MVCC(Multiversion Concurrent Control)技术,目的是提高并发度,读操作不会阻塞写操作,写操作也不会阻止读操作。

这样会引入一个新问题,一段时间之后,有些死记录变得无关紧要,因为已经没有事务再想要查看这些已经标记为删除的记录。

vacuum操作将对死记录的空间进行标识,进而可以在表内重用,该操作不需要锁定数据表。

vacuum full操作还会对死记录进行移除,该操作需要表上的一个排它锁。


3. vacuum实验


3.1 创建新的数据库vac和表myt,并查看所占磁盘空间

创建新数据库vac:

[plain] view
plain copy

postgres=# create database vac;  

CREATE DATABASE  

用oid2name那么查看vac的oid:

[plain] view
plain copy

postgres=# \! oid2name  

Password:  

All databases:  

    Oid  Database Name  Tablespace  

----------------------------------  

  12669       postgres  pg_default  

  12668      template0  pg_default  

      1      template1  pg_default  

  16393            vac  pg_default  

连接到数据库vac:

[plain] view
plain copy

postgres=# \c vac  

You are now connected to database "vac" as user "postgres".  

创建表myt:

[plain] view
plain copy

vac=# create table myt(id integer);  

CREATE TABLE  

表myt在磁盘上的文件名:

[plain] view
plain copy

vac=# select pg_relation_filepath('myt');  

 pg_relation_filepath  

----------------------  

 base/16393/16397  

(1 row)  

表myt所占磁盘空间为0:

[plain] view
plain copy

M121313CPG3QD:16393 postgres$ ls -l /PostgreSQL/9.6/data/base/16393/16397*  

-rw-------  1 postgres  daemon  0 Sep 13 18:28 /PostgreSQL/9.6/data/base/16393/16397  

可以用更便捷的方法查询表myt所占磁盘空间:

[plain] view
plain copy

vac=# select pg_total_relation_size('myt');  

 pg_total_relation_size  

------------------------  

                      0  

(1 row)  

向表myt插入100000行数据,查看myt所占用的磁盘空间:

[plain] view
plain copy

vac=# insert into myt select generate_series(1,100000);  

INSERT 0 100000  

vac=# select pg_total_relation_size('myt');  

 pg_total_relation_size  

------------------------  

                3653632  

(1 row)  

[plain] view
plain copy

M121313CPG3QD:16393 postgres$ ls -l /PostgreSQL/9.6/data/base/16393/16397*  

-rw-------  1 postgres  daemon  3629056 Sep 13 18:47 /PostgreSQL/9.6/data/base/16393/16397  

-rw-------  1 postgres  daemon    24576 Sep 13 18:46 /PostgreSQL/9.6/data/base/16393/16397_fsm  

删除表myt中的一部分数据,查看myt所占用的磁盘空间:

[plain] view
plain copy

vac=# delete from myt where id>5 and id<10000;  

DELETE 9994  

vac=# delete from myt where id>5 and id<100000;  

DELETE 90000  

  

vac=# select pg_total_relation_size('myt');  

 pg_total_relation_size  

------------------------  

                3653632  

(1 row)  

  

M121313CPG3QD:16393 postgres$ ls -l /PostgreSQL/9.6/data/base/16393/16397*  

-rw-------  1 postgres  daemon  3629056 Sep 13 18:51 /PostgreSQL/9.6/data/base/16393/16397  

-rw-------  1 postgres  daemon    24576 Sep 13 18:46 /PostgreSQL/9.6/data/base/16393/16397_fsm  

可以看到,删除了9994行数据后,表myt所占用的空间没有减小。

vacuum myt,查看myt所占用的磁盘空间:

[plain] view
plain copy

vac=# vacuum myt ;  

VACUUM  

vac=# select pg_total_relation_size('myt');  

 pg_total_relation_size  

------------------------  

                3661824  

(1 row)  

  

M121313CPG3QD:16393 postgres$ ls -l /PostgreSQL/9.6/data/base/16393/16397*  

-rw-------  1 postgres  daemon  3629056 Sep 13 18:51 /PostgreSQL/9.6/data/base/16393/16397  

-rw-------  1 postgres  daemon    24576 Sep 13 18:46 /PostgreSQL/9.6/data/base/16393/16397_fsm  

-rw-------  1 postgres  daemon     8192 Sep 13 18:52 /PostgreSQL/9.6/data/base/16393/16397_vm  

可以看到myt所占用磁盘空间没有显著减小。
另外发现新增加了一个16397_vm的文件,看来这个后缀_vm的文件和vacuum有关。

vacuum full myt,查看myt所占用的磁盘空间:

[plain] view
plain copy

vac=# vacuum full myt ;  

VACUUM  

vac=# select pg_total_relation_size('myt');  

 pg_total_relation_size  

------------------------  

                   8192  

(1 row)  

  

vac=# select pg_relation_filepath('myt');  

 pg_relation_filepath  

----------------------  

 base/16393/16400  

(1 row)  

  

  

M121313CPG3QD:16393 postgres$ ls -l /PostgreSQL/9.6/data/base/16393/16400*  

-rw-------  1 postgres  daemon  8192 Sep 13 18:56 /PostgreSQL/9.6/data/base/16393/16400  

可以发现,原来myt对应文件16397内容被移动到新文件16400,16397被清空,后续16397会被删除。


4.Autovacuum

vacuum进程可以自动清理数据文件,一般不推荐关闭autovacuum功能,因为vacuum会更新数据库统计信息,这些信息对查询计划有帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: