当数据库中存在某个表的年龄大于vacuum_freeze_table_age,就会执行急切冻结过程

当表的年龄大于vacuum_freeze_table_age时,会执行急切冻结,表的年龄通过oldestxmin-pg_class.relfrozenxid计算得到,pg_class.relfrozenxid字段是在某个表被冻结后更新的,代表着某个表最近的冻结事务id。而pg_database.datfrozenxid代表着当前库所有表的最小冻结标识,所以只有当该库具有最小冻结标识的表被冻结时,pg_database.datfrozenxid字段才会被更新。急切冻结的触发条件是pg_database.datfrozenxid 假设oldestxmin为150002000,那么freezelimit_txid = 150002000 - 50000000 = 100002000,所有小于freezelimit_txid的元组都会被冻结,并且扫描每一个数据页面,即使某个页面已经被冻结过,

在postgresql9.6之后,对freeze进行了优化,在vm文件中添加了一个标志位all_frozen。在9.6之前,假如某一个页面之前已经被冻结过,但执行急切模式的freeze依旧会扫描该页面,在9.6之后,通过判断vm文件中的all_frozen标志位,即可判断是否需要冻结该页面,如下,第一个页面的all_frozen的标志位为1,那么就可以跳过该页面,继续冻结第二个页面,冻结完之后再将vm文件的all_frozen标志位置1

查询库中所有表的年龄:

 select relname ,age(relfrozenxid) from pg_class where relkind in ('r','m') order by age desc;

postgres=#  select relname ,age(relfrozenxid) from pg_class where relkind in ('r','m') order by age desc;
                 table_name                 |  age
--------------------------------------------+--------
 zhparser.t                                 | 378686
 t4                                         | 378685
 test_pre_migrate_612069                    | 378684
 pg_statistic                               | 378682
 pg_type                                    | 378681
 test_pre_migrate_611918                    | 378680
 shun_a                                     | 378678
 shun_b                                     | 378676
 pg_foreign_table                           | 378674
 t1                                         | 378673
 pg_authid                                  | 378671
 pg_statistic_ext_data                      | 378668
 test_pre_migrate_612047                    | 378667
 test_pre_migrate_612092                    | 378666
 t1_idx                                     | 378665
 tab1                                       | 378664
 test_pre_migrate_611531                    | 378663

查询所有数据库的年龄:

select datname, age(datfrozenxid) from pg_database;

postgres=# select datname, age(datfrozenxid) from pg_database;
  datname  |   age
-----------+---------
 postgres  |  378686
 template1 | 1344913
 ctsdb     | 1344915
 testdb    | 1344913
 template0 | 1344841
 db3       | 1344913
 peiybdb   | 1344913
 ctsdb3    | 1344913

冻结某个表

postgres=# vacuum FREEZE zhparser.t;

相应的数据库的年龄也会变小,如下所示postgres 数据库的age由原来的378686变为378685(这个似乎是瞬间完成的)

postgres=# select datname, age(datfrozenxid) from pg_database;
  datname  |   age
-----------+---------
 postgres  |  378685
 template1 | 1344913
 ctsdb     | 1344915
 testdb    | 1344913
 template0 | 1344841
 db3       | 1344913
 peiybdb   | 1344913
 ctsdb3    | 1344913

再vacuum freeze一下,age又变了

postgres=# vacuum FREEZE t4;
VACUUM
postgres=# select datname, age(datfrozenxid) from pg_database;
  datname  |   age
-----------+---------
 postgres  |  378684
 template1 | 1344913
 ctsdb     | 1344915
 testdb    | 1344913
 template0 | 1344841
 db3       | 1344913
 peiybdb   | 1344913
 ctsdb3    | 1344913

你可能感兴趣的:(postgresql)