对于某些常进行archiver或者 purge操作的表而言,如果我们不定期回收表空间,则表体积会越涨越大。
但是pg自带的 vacuum full 在回收的过程中会阻塞读写操作,不能在生产环境直接运行。
因此,在生产环境 我们常用的表空间收缩工具是pg_squeeze 和 pg_repack。
这里先贴 pg_repack 的用法:
项目地址: https://github.com/reorg/pg_repack
原理: 新建一个一模一样的影子表,然后拷贝原表的数据,最后rename替换原表。
注意: 待处理的表必须有主键
代码语言:javascript复制yum install centos-release-scl-rh
yum install llvm-toolset-7-clang
cd /home/postgres
tar xf pg_repack-ver_1.4.4.tar.gz
export PATH=/usr/local/pgsql-11.5/bin:$PATH -- 需要载入环境变量,不然编译过程中可能找不到pg_config这个文件
cd pg_repack-ver_1.4.4
make && make install
另外,会生成一个可执行的文件: /home/postgres/pg_repack-ver_1.4.4/bin/pg_repack
修改配置文件:
vim /usr/local/pgsql-11.5/data/postgresql.conf
代码语言:javascript复制shared_preload_libraries = 'pg_repack'
然后 ,重启pg进程
使用方法:
代码语言:javascript复制create database db1;
c db1
create extension pg_repack;
create table testdata (id integer,course int,grade numeric(4,2),testtime date);
alter table testdata add primary key (id);
insert into testdata
select generate_series(1,100) as id,
10 as course,
10.11 as grade,
'2017-07-06' as testtime;
然后,我们可以去看下PG datadir物理文件大小从1.1GB涨到了1.6GB了
然后,我们再使用命令 delete from testdata where id between 5000000 and 10000000; 对testdata表删除一半的数据 ,此时可以看到物理文件没有任何缩小。
然后,在外部使用pg_repack对 color表做空间回收:
代码语言:javascript复制cd /home/postgres/pg_repack-ver_1.4.4/bin
./pg_repack -h 127.0.0.1 --port 5434 -Upostgres -d db1 -t testdata -j 2 -D -k
返回的结果如下(根据实际表的大小,来决定这个结果等待的时长):
NOTICE: Setting up workers.conns
INFO: repacking table "public.testdata"
pg_repack参数说明:
代码语言:javascript复制 -a, --all repack all databases
-t, --table=TABLE repack specific table only
-I, --parent-table=TABLE repack specific parent table and its inheritors
-c, --schema=SCHEMA repack tables in specific schema only
-s, --tablespace=TBLSPC move repacked tables to a new tablespace
-S, --moveidx move repacked indexes to TBLSPC too
-o, --order-by=COLUMNS order by columns instead of cluster keys
-n, --no-order do vacuum full instead of cluster
-N, --dry-run print what would have been repacked
-j, --jobs=NUM Use this many parallel jobs for each table
-i, --index=INDEX move only the specified index
-x, --only-indexes move only indexes of the specified table
-T, --wait-timeout=SECS timeout to cancel other backends on conflict
-D, --no-kill-backend don't kill other backends when timed out
-Z, --no-analyze don't analyze at end
-k, --no-superuser-check skip superuser checks in client
-C, --exclude-extension don't repack tables which belong to specific extension
Connection options:
-d, --dbname=DBNAME database to connect
-h, --host=HOSTNAME database server host or socket directory
-p, --port=PORT database server port
-U, --username=USERNAME user name to connect as
-w, --no-password never prompt for password
-W, --password force password prompt
我们再去查看物理文件大小,发现PG整个的文件大小又缩回到1.4G了(回收掉的200MB差不多就是一半的testdata表的空间大小)
最后, 我们可以使用脚本定时检测对超过某些阈值的表定时执行 pg_repack 操作,以便回收磁盘空间。