死元组未被 VACUUM FULL 命令收集
Dead Tuples are not being collected by VACCUM FULL Command
抱歉,这很长 post 和问题 & postgres 新手
想知道 postgres VACCUM 和 VACCUM FULL 是如何工作的,这对于 700 GB Table 无需停机归档。
VACCUM 完整案例:
在这种情况下,在执行 vacuum full 命令后,内存似乎被释放到 OS,但 n_dead_tuples 保持相同大小。
这个n_dead_tup会在下一次插入/更新/删除中重复使用吗?
步骤:
CREATE TABLE Foo (
id SERIAL PRIMARY KEY,
x INTEGER NOT NULL
);
// CREATE TABLE
INSERT INTO Foo (x) VALUES (generate_series(1,1000000));
// INSERT 0 1000000
SELECT pg_size_pretty(pg_relation_size('foo'));
// 35 MB
SELECT n_dead_tup FROM pg_stat_user_tables where relname = 'foo';
// 0
UPDATE Foo SET x = x + 1;
// UPDATE 1000000
SELECT pg_size_pretty(pg_relation_size('foo'));
// 69 MB
SELECT n_dead_tup FROM pg_stat_user_tables where relname = 'foo';
// 1000000
VACUUM FULL VERBOSE foo;
// INFO: vacuuming "public.foo"
// INFO: "foo": found 1000000 removable, 1000000 nonremovable row versions in 8850 pages
// DETAIL: 0 dead row versions cannot be removed yet.
// CPU 0.07s/0.67u sec elapsed 0.76 sec.
// VACUUM
SELECT pg_size_pretty(pg_relation_size('foo'));
// 35 MB
SELECT n_dead_tup FROM pg_stat_user_tables where relname = 'foo';
// 1000000
VACCUM 案例
步骤:
与上述步骤相同,除了 VACCUM FULL,需要 运行 下面的命令,在这种情况下看起来死元组被删除但大小没有释放到 OS.
VACUUM VERBOSE foo;
// INFO: vacuuming "public.foo"
// INFO: scanned index "foo_pkey" to remove 1000000 row versions
// DETAIL: CPU 0.01s/0.27u sec elapsed 0.34 sec.
// INFO: "foo": removed 1000000 row versions in 4425 pages
// DETAIL: CPU 0.00s/0.02u sec elapsed 0.02 sec.
// INFO: index "foo_pkey" now contains 1000000 row versions in 8237 pages
// DETAIL: 1000000 index row versions were removed.
// 0 index pages have been deleted, 0 are currently reusable.
// CPU 0.00s/0.00u sec elapsed 0.00 sec.
// INFO: "foo": found 1000000 removable, 1000000 nonremovable row versions in 8850 out of 8850 pages
// DETAIL: 0 dead row versions cannot be removed yet.
// There were 0 unused item pointers.
// Skipped 0 pages due to buffer pins.
// 0 pages are entirely empty.
// CPU 0.03s/0.52u sec elapsed 0.61 sec.
// VACUUM
SELECT pg_size_pretty(pg_relation_size('foo'));
// 69 MB
SELECT n_dead_tup FROM pg_stat_user_tables where relname = 'foo';
// 0
AUTO VACUUM 等同于 VACUUM ?
提前致谢。
一个简单的 VACUUM
通常不会像 explained in the documentation:
那样释放磁盘 space
[...] However, extra space is not returned to the operating system (in most cases); it's just kept available for re-use within the same table. [...]
对于 VACUUM FULL
它是不同的,因为它基本上将整个 table 数据重写为 explained in the documentation:
[...] This method also requires extra disk space, since it writes a new copy of the table and doesn't release the old copy until the operation is complete. [...]
通过重写,数据在物理上紧密地写入,没有旧行版本引起的漏洞。所需的不断增长的磁盘 space 是 PostgreSQL 实施的 MVCC 的缺点之一,需要仔细观察和调整大型和更新繁重的 tables。
自动吸尘器将永远不会执行VACUUM FULL
,因为它会阻塞它正在工作的table/relation上的任何其他activity对任何连接的应用程序产生不可预测的table后果。
如果您 运行 遇到这里的问题,您应该至少开始考虑以维护 VACUUM FULL
的影响保持较低的方式对 table 进行分区(因为分区体积小)甚至更好,使您能够只删除一个分区而不需要重写。但这实际上取决于您存储和更新的数据的语义。
抱歉,这很长 post 和问题 & postgres 新手
想知道 postgres VACCUM 和 VACCUM FULL 是如何工作的,这对于 700 GB Table 无需停机归档。
VACCUM 完整案例:
在这种情况下,在执行 vacuum full 命令后,内存似乎被释放到 OS,但 n_dead_tuples 保持相同大小。
这个n_dead_tup会在下一次插入/更新/删除中重复使用吗?
步骤:
CREATE TABLE Foo (
id SERIAL PRIMARY KEY,
x INTEGER NOT NULL
);
// CREATE TABLE
INSERT INTO Foo (x) VALUES (generate_series(1,1000000));
// INSERT 0 1000000
SELECT pg_size_pretty(pg_relation_size('foo'));
// 35 MB
SELECT n_dead_tup FROM pg_stat_user_tables where relname = 'foo';
// 0
UPDATE Foo SET x = x + 1;
// UPDATE 1000000
SELECT pg_size_pretty(pg_relation_size('foo'));
// 69 MB
SELECT n_dead_tup FROM pg_stat_user_tables where relname = 'foo';
// 1000000
VACUUM FULL VERBOSE foo;
// INFO: vacuuming "public.foo"
// INFO: "foo": found 1000000 removable, 1000000 nonremovable row versions in 8850 pages
// DETAIL: 0 dead row versions cannot be removed yet.
// CPU 0.07s/0.67u sec elapsed 0.76 sec.
// VACUUM
SELECT pg_size_pretty(pg_relation_size('foo'));
// 35 MB
SELECT n_dead_tup FROM pg_stat_user_tables where relname = 'foo';
// 1000000
VACCUM 案例
步骤:
与上述步骤相同,除了 VACCUM FULL,需要 运行 下面的命令,在这种情况下看起来死元组被删除但大小没有释放到 OS.
VACUUM VERBOSE foo;
// INFO: vacuuming "public.foo"
// INFO: scanned index "foo_pkey" to remove 1000000 row versions
// DETAIL: CPU 0.01s/0.27u sec elapsed 0.34 sec.
// INFO: "foo": removed 1000000 row versions in 4425 pages
// DETAIL: CPU 0.00s/0.02u sec elapsed 0.02 sec.
// INFO: index "foo_pkey" now contains 1000000 row versions in 8237 pages
// DETAIL: 1000000 index row versions were removed.
// 0 index pages have been deleted, 0 are currently reusable.
// CPU 0.00s/0.00u sec elapsed 0.00 sec.
// INFO: "foo": found 1000000 removable, 1000000 nonremovable row versions in 8850 out of 8850 pages
// DETAIL: 0 dead row versions cannot be removed yet.
// There were 0 unused item pointers.
// Skipped 0 pages due to buffer pins.
// 0 pages are entirely empty.
// CPU 0.03s/0.52u sec elapsed 0.61 sec.
// VACUUM
SELECT pg_size_pretty(pg_relation_size('foo'));
// 69 MB
SELECT n_dead_tup FROM pg_stat_user_tables where relname = 'foo';
// 0
AUTO VACUUM 等同于 VACUUM ?
提前致谢。
一个简单的 VACUUM
通常不会像 explained in the documentation:
[...] However, extra space is not returned to the operating system (in most cases); it's just kept available for re-use within the same table. [...]
对于 VACUUM FULL
它是不同的,因为它基本上将整个 table 数据重写为 explained in the documentation:
[...] This method also requires extra disk space, since it writes a new copy of the table and doesn't release the old copy until the operation is complete. [...]
通过重写,数据在物理上紧密地写入,没有旧行版本引起的漏洞。所需的不断增长的磁盘 space 是 PostgreSQL 实施的 MVCC 的缺点之一,需要仔细观察和调整大型和更新繁重的 tables。
自动吸尘器将永远不会执行VACUUM FULL
,因为它会阻塞它正在工作的table/relation上的任何其他activity对任何连接的应用程序产生不可预测的table后果。
如果您 运行 遇到这里的问题,您应该至少开始考虑以维护 VACUUM FULL
的影响保持较低的方式对 table 进行分区(因为分区体积小)甚至更好,使您能够只删除一个分区而不需要重写。但这实际上取决于您存储和更新的数据的语义。