除真空以外,是否可以通过其他方法清除死行?

时间:2018-07-03 14:01:24

标签: postgresql postgresql-9.3 vacuum

在PostgreSQL 9.3.19日志中,我看到给定表的自动清空的以下两个连续条目:

2018-06-29 17:24:06 CDT 13177 14/870454 0 LOG:  automatic vacuum of table "openbravo.public.ad_session_status": index scans: 0
    pages: 0 removed, 235 remain
    tuples: 0 removed, 14669 remain
    buffer usage: 1090 hits, 673 misses, 4 dirtied
    avg read rate: 6.745 MB/s, avg write rate: 0.040 MB/s

-

2018-06-29 17:24:55 CDT 13529 40/699086 0 LOG:  automatic vacuum of table "openbravo.public.ad_session_status": index scans: 0
    pages: 0 removed, 235 remain
    tuples: 0 removed, 13039 remain
    buffer usage: 1143 hits, 663 misses, 0 dirtied
    avg read rate: 3.086 MB/s, avg write rate: 0.000 MB/s

All autovacuums are loggedlog_autovacuum_min_duration=0

之间没有其他手动吸尘器。

如果这两个真空中的任何一个都没有清除死的元组,那么在第二个元组之后,剩余的元组数会减少吗? PostgreSQL还有其他删除死行的方法吗?

1 个答案:

答案 0 :(得分:1)

一个解释可能是HOT updates

如果表块中有空间,并且没有索引更新列,则PostgreSQL将把新行版本与原始行放置在同一块中,并创建一个“热链”,其中旧行版本指向新行。这使PostgreSQL可以跳过更新指向该表行的所有索引。

除了减少UPDATE期间的I / O之外,HOT还允许“即时”删除旧行版本:只要访问的页面几乎已满并且可以获得必要的锁,PostgreSQL就会通过重组该区块来执行“微真空”。

这可能导致观察到的元组减少。

要支持或反驳这一理论,请运行以下查询:

SELECT n_tup_upd, n_tup_hot_upd
FROM pg_stat_user_tables
WHERE schemaname = 'public' AND relname = 'ad_session_status';

如果n_tup_hot_upd大于零,则说明情况成立。