当表的年龄大于vacuum_freeze_table_age时,会执行急切冻结,表的年龄通过oldestxmin-pg_class.relfrozenxid计算得到,pg_class.relfrozenxid字段是在某个表被冻结后更新的,代表着某个表最近的冻结事务id。而pg_database.datfrozenxid代表着当前库所有表的最小冻结标识,所以只有当该库具有最小冻结标识的表被冻结时,pg_database.datfrozenxid字段才会被更新。急切冻结的触发条件是pg_database.datfrozenxid<oldestxmin-vacuum_freeze_table_age,这其实和上面的说法不冲突,因为某个数据库所有表中的最老的relfrozenxid就是数据库的datfrozenxid,所以冻结可以用一句话来理解:当数据库中存在某个表的年龄大于vacuum_freeze_table_age参数设定值,就会执行急切冻结过程,当表中元组年龄超过vacuum_freeze_min_age,就可以被冻结,这里其实是必须和可以的区别。
假设oldestxmin为150002000,那么freezelimit_txid = 150002000 - 50000000 = 100002000,所有小于freezelimit_txid的元组都会被冻结,并且扫描每一个数据页面,即使某个页面已经被冻结过,
在postgresql9.6之后,对freeze进行了优化,在vm文件中添加了一个标志位all_frozen。在9.6之前,假如某一个页面之前已经被冻结过,但执行急切模式的freeze依旧会扫描该页面,在9.6之后,通过判断vm文件中的all_frozen标志位,即可判断是否需要冻结该页面,如下,第一个页面的all_fro