使用pg_repack 回收表體積

  • 2019 年 10 月 5 日
  • 筆記

對於某些常進行archiver或者 purge操作的表而言,如果我們不定期回收表空間,則表體積會越漲越大。

但是pg自帶的 vacuum full 在回收的過程中會阻塞讀寫操作,不能在生產環境直接運行。

因此,在生產環境 我們常用的表空間收縮工具是pg_squeeze 和 pg_repack。

這裡先貼 pg_repack 的用法:

項目地址:  https://github.com/reorg/pg_repack

原理: 新建一個一模一樣的影子表,然後拷貝原表的數據,最後rename替換原表。

注意: 待處理的表必須有主鍵

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

shared_preload_libraries = 'pg_repack'

然後 ,重啟pg進程

使用方法:

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表做空間回收:

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參數說明:

  -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 操作,以便回收磁盤空間。