pg_repack 处理表和索引的膨胀

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/ctypyb2002/article/details/85007105

os: ubuntu 16.04
db: postgresql 9.6.8
pg_repack: 1.4.4

postgresql 的 vacuum full 需要 access exclusive lock,获得这个锁后,针对该表的所有操作均无法执行,包括 select

pg_repack is a fork of the pg_reorg project, which has proven hugely successful. Unfortunately new feature development on pg_reorg has slowed or stopped since late 2011.

版本

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 16.04.5 LTS
Release:	16.04
Codename:	xenial

$ psql
psql (9.6.8)
Type "help" for help.

postgres=# select version();
                                                                   version                                                                    
----------------------------------------------------------------------------------------------------------------------------------------------
 PostgreSQL 9.6.8 on x86_64-pc-linux-gnu (Ubuntu 9.6.8-1.pgdg16.04+1), compiled by gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609, 64-bit
(1 row)

postgres=#

下载安装

https://github.com/reorg/pg_repack/releases
或者 https://pgxn.org/dist/pg_repack
都可以下载

$ wget https://github.com/reorg/pg_repack/archive/ver_1.4.4.zip

或者

$ wget http://api.pgxn.org/dist/pg_repack/1.4.4/pg_repack-1.4.4.zip

安装依赖包

# apt install cmake libssl-dev
$ unzip  pg_repack-ver_1.4.4.zip
$ ls -l 
drwxrwxr-x 8 postgres postgres   4096 Oct 18 19:30 pg_repack-ver_1.4.4
-rw-r--r-- 1 postgres postgres 124311 Dec 14  2018 pg_repack-ver_1.4.4.zip
$ cd pg_repack-ver_1.4.4
$ make

make[1]: Entering directory '/var/lib/postgresql/pg_repack-ver_1.4.4/bin'
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC -pie -fno-omit-frame-pointer pg_repack.o pgut/pgut.o pgut/pgut-fe.o  -L/usr/lib/x86_64-linux-gnu -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now  -L/usr/lib/x86_64-linux-gnu/mit-krb5 -Wl,--as-needed  -L/usr/lib/x86_64-linux-gnu -lpq -L/usr/lib/postgresql/9.6/lib -lpgcommon -lpgport -lssl -lcrypto -lz -lrt -lcrypt -ldl -lm -o pg_repack
make[1]: Leaving directory '/var/lib/postgresql/pg_repack-ver_1.4.4/bin'
make[1]: Entering directory '/var/lib/postgresql/pg_repack-ver_1.4.4/lib'
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC -pie -fno-omit-frame-pointer -fPIC -DREPACK_VERSION=1.4.4 -I. -I./ -I/usr/include/postgresql/9.6/server -I/usr/include/postgresql/internal -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2  -I/usr/include/mit-krb5  -c -o repack.o repack.c
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC -pie -fno-omit-frame-pointer -fPIC -DREPACK_VERSION=1.4.4 -I. -I./ -I/usr/include/postgresql/9.6/server -I/usr/include/postgresql/internal -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2  -I/usr/include/mit-krb5  -c -o pgut/pgut-spi.o pgut/pgut-spi.c
( echo '{ global:'; mawk '/^[^#]/ {printf "%s;\n",$1}' exports.txt; echo ' local: *; };' ) >exports.list
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC -pie -fno-omit-frame-pointer -fPIC -shared -Wl,--version-script=exports.list -o pg_repack.so repack.o pgut/pgut-spi.o -L/usr/lib/x86_64-linux-gnu  -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now  -L/usr/lib/x86_64-linux-gnu/mit-krb5 -Wl,--as-needed  
sed 's,REPACK_VERSION,1.4.4,g' pg_repack.sql.in > pg_repack--1.4.4.sql;
sed 's,REPACK_VERSION,1.4.4,g' pg_repack.control.in > pg_repack.control
make[1]: Leaving directory '/var/lib/postgresql/pg_repack-ver_1.4.4/lib'
make[1]: Entering directory '/var/lib/postgresql/pg_repack-ver_1.4.4/regress'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/var/lib/postgresql/pg_repack-ver_1.4.4/regress'

使用apt安装就需要在root下 make install(或者使用sudo),主要是权限的问题。
pg_repack 依赖 postgresql-server-dev-X.Y
make时出错,一般都是缺少依赖包导致,按照错误提示按照即可。

$ sudo make install

make[1]: Entering directory '/var/lib/postgresql/pg_repack-ver_1.4.4/bin'
/bin/mkdir -p '/usr/lib/postgresql/9.6/bin'
/usr/bin/install -c  pg_repack '/usr/lib/postgresql/9.6/bin'
make[1]: Leaving directory '/var/lib/postgresql/pg_repack-ver_1.4.4/bin'
make[1]: Entering directory '/var/lib/postgresql/pg_repack-ver_1.4.4/lib'
/bin/mkdir -p '/usr/lib/postgresql/9.6/lib'
/bin/mkdir -p '/usr/share/postgresql/9.6/extension'
/bin/mkdir -p '/usr/share/postgresql/9.6/extension'
/usr/bin/install -c -m 755  pg_repack.so '/usr/lib/postgresql/9.6/lib/pg_repack.so'
/usr/bin/install -c -m 644 .//pg_repack.control '/usr/share/postgresql/9.6/extension/'
/usr/bin/install -c -m 644  pg_repack--1.4.4.sql pg_repack.control '/usr/share/postgresql/9.6/extension/'
make[1]: Leaving directory '/var/lib/postgresql/pg_repack-ver_1.4.4/lib'
make[1]: Entering directory '/var/lib/postgresql/pg_repack-ver_1.4.4/regress'
make[1]: Nothing to be done for 'install'.
make[1]: Leaving directory '/var/lib/postgresql/pg_repack-ver_1.4.4/regress'

测试

pg_repack 是以 extension 的方式工作的。

peiybdb=# select * from pg_available_extensions where name like '%repack%' order by name;
   name    | default_version | installed_version |                           comment                            
-----------+-----------------+-------------------+--------------------------------------------------------------
 pg_repack | 1.4.4           |                   | Reorganize tables in PostgreSQL databases with minimal locks
(1 row)

peiybdb=# create extension pg_repack;
CREATE EXTENSION

peiybdb=# \dn
  List of schemas
  Name  |  Owner   
--------+----------
 public | postgres
 repack | postgres
(2 rows)
$ which pg_repack
/usr/lib/postgresql/9.6/bin/pg_repack

online vacuum full (include table indexes)

peiybdb=# \d+ tmp_t0
                       Table "public.tmp_t0"
 Column |  Type  | Modifiers | Storage | Stats target | Description 
--------+--------+-----------+---------+--------------+-------------
 c0     | bigint |           | plain   |              | 
 c1     | bigint |           | plain   |              | 
Indexes:
    "idx_tmp_t0_c1" btree (c1)

$ pg_repack --no-order --table tmp_t0 peiybdb
WARNING: relation "public.tmp_t0" must have a primary key or not-null unique keys

添加主键

peiybdb=# drop index idx_tmp_t0_c1;
peiybdb=# ALTER TABLE public.tmp_t0 ADD CONSTRAINT tmp_t0_pk PRIMARY KEY (c1) ;

peiybdb=# with tmp_0 as (
 select pc.oid as reloid,
        pn.nspname,
        pc.relname,
        pn.nspname||'.'||pc.relname as schema_relname,
        pc.relkind
   from pg_class pc,
        pg_namespace pn
  where 1=1
    and pc.relnamespace=pn.oid
)
select t0.reloid as tableoid,
       pt.schemaname||'.'||pt.tablename as schema_tablename,
       pg_relation_filepath(pt.schemaname||'.'||pt.tablename),
       pg_table_size(pt.schemaname||'.'||pt.tablename),
       pg_relation_size(pt.schemaname||'.'||pt.tablename),
       pg_total_relation_size(pt.schemaname||'.'||pt.tablename),
       t1.reloid as indexoid,
       pi.schemaname||'.'||pi.indexname,
       pg_relation_filepath(pi.schemaname||'.'||pi.indexname),
       pg_relation_size(pi.schemaname||'.'||pi.indexname),
       pg_indexes_size(pi.schemaname||'.'||pi.tablename)
 from pg_tables pt
      left outer join pg_indexes pi 
                   on pt.schemaname||'.'||pt.tablename = pi.schemaname||'.'||pi.tablename
      left outer join tmp_0 t0
                   on pt.schemaname||'.'||pt.tablename = t0.schema_relname
      left outer join tmp_0 t1
                   on pi.schemaname||'.'||pi.indexname = t1.schema_relname             
where 1=1
  and pt.schemaname='public'
  and pt.tablename='tmp_t0'
;

 tableoid | schema_tablename | pg_relation_filepath | pg_table_size | pg_relation_size | pg_total_relation_size | indexoid |     ?column?     | pg_relation_filepath | pg_relation_size | pg_indexes_size 
----------+------------------+----------------------+---------------+------------------+------------------------+----------+------------------+----------------------+------------------+-----------------
  1447603 | public.tmp_t0    | base/1406609/1447745 |      44318720 |         44285952 |               66805760 |  1447752 | public.tmp_t0_pk | base/1406609/1447752 |         22487040 |        22487040
(1 row)

再次执行

$ pg_repack --no-order --table tmp_t0 -d peiybdb


 tableoid | schema_tablename | pg_relation_filepath | pg_table_size | pg_relation_size | pg_total_relation_size | indexoid |     ?column?     | pg_relation_filepath | pg_relation_size | pg_indexes_size 
----------+------------------+----------------------+---------------+------------------+------------------------+----------+------------------+----------------------+------------------+-----------------
  1447603 | public.tmp_t0    | base/1406609/1447769 |      44318720 |         44285952 |               66805760 |  1447752 | public.tmp_t0_pk | base/1406609/1447772 |         22487040 |        22487040
(1 row)

可以看到,不管是 tmp_t0 (oid=1447603) 还是 tmp_t0_pk (oid=1447752),对应的 oid 都没有发生变化,但是在磁盘上的文件发生了变化。

online repack database

$ pg_repack --wait-timeout 3600 --jobs 10 --no-order -d peiybdb

online repack schema

$ pg_repack --wait-timeout 3600 --jobs 10 --no-order --schema=public -d peiybdb

online repack table and indexes

$ pg_repack --wait-timeout 3600 --no-order --table public.tmp_t0 -d peiybdb 

online repack only all index

$ pg_repack --only-indexes --table public.tmp_t0 -d peiybdb 

online repack only some index

$ pg_repack --index public.tmp_t0_pk -d peiybdb 

参考:
http://reorg.github.com/pg_repack
https://pgxn.org/dist/pg_repack
https://github.com/reorg/pg_repack

http://reorg.github.io/pg_repack/

猜你喜欢

转载自blog.csdn.net/ctypyb2002/article/details/85007105