代码之家  ›  专栏  ›  技术社区  ›  alostale

死行是否被真空以外的东西清除了?

  •  0
  • alostale  · 技术社区  · 7 年前

    在PostgreSQL 9.3.19日志中,我看到了给定表的autovacuum的以下两个连续条目:

    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 logged : log_autovacuum_min_duration=0 .

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

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

    1 回复  |  直到 7 年前
        1
  •  1
  •   Laurenz Albe    7 年前

    一种解释可能是 HOT updates .

    如果表块中有空间,并且没有索引更新的列,PostgreSQL将把新行版本放在与原始行版本相同的块中,并在新行版本指向新行版本的地方创建一个“热链”。这允许PostgreSQL跳过更新指向该表行的所有索引。

    除了在 UPDATE ,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 大于零,我们有一个案例。