pg中索引页的复用不像堆表那样被vacuum回收后就可以直接使用,因为索引页面中数据都是按照顺序排放的,所以只有是PAGE的边界内的值才允许插入。
所以我们会经常遇到索引膨胀的情况,这种时候我们一般都会去重建索引。但是我们在vacuum的时候仍然还是会去回收index page(但即使回收了空间仍然不可重用,所以意义不大)。
因此在pg12中vacuum命令新增了一个index_cleanup选项,用来指定vacuum时不去回收index page,因为我们已经打算重建索引了。
语法:
Command: VACUUM
Description: garbage-collect and optionally analyze a database
Syntax:
VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
where option can be one of:
FULL [ boolean ]
FREEZE [ boolean ]
VERBOSE [ boolean ]
ANALYZE [ boolean ]
DISABLE_PAGE_SKIPPING [ boolean ]
SKIP_LOCKED [ boolean ]
INDEX_CLEANUP [ boolean ]
TRUNCATE [ boolean ]
and table_and_columns is:
table_name [ ( column_name [, ...] ) ]
例子:
–建表
bill=# create table test (id int primary key, info text , crt_time timestamp);
CREATE TABLE
bill=# insert into test select generate_series(1,1000000), md5(random()::text), clock_timestamp();
INSERT 0 1000000
bill=# update test set info='test' where id in (select (random()*1000)::int from generate_series(1,100));
UPDATE 96
–正常vacuum
可以看到对index page进行了处理
bill=# vacuum verbose test;
INFO: vacuuming "bill.test"
INFO: scanned index "test_pkey" to remove 96 row versions
DETAIL: CPU: user: 0.04 s, system: 0.00 s, elapsed: 0.04 s
INFO: "test": removed 96 row versions in 10 pages
DETAIL: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
INFO: index "test_pkey" now contains 1000000 row versions in 2745 pages
DETAIL: 96 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO: "test": found 96 removable, 1000000 nonremovable row versions in 9347 out of 9347 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 139938
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.13 s, system: 0.00 s, elapsed: 0.13 s.
INFO: vacuuming "pg_toast.pg_toast_130849"
INFO: index "pg_toast_130849_index" now contains 0 row versions in 1 pages
DETAIL: 0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO: "pg_toast_130849": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 139938
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
–INDEX_CLEANUP false禁止vacuum索引
跳过了对index pgae的回收
bill=# update test set info='test' where id in (select (random()*1000)::int from generate_series(1,100));
UPDATE 98
bill=# vacuum (verbose, INDEX_CLEANUP false) test;
INFO: vacuuming "bill.test"
INFO: "test": found 98 removable, 1155 nonremovable row versions in 12 out of 9347 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 139939
There were 17 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO: vacuuming "pg_toast.pg_toast_130849"
INFO: "pg_toast_130849": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 139939
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
最后我们可以在线重建索引:
bill=# reindex table concurrently test;
REINDEX