postgreSQL 如何标记冻结的行?
How posgreSQL marks frozen rows?
我正在研究VACUUM
命令。特别是它如何解决环绕问题。
基本上每笔交易都有一个交易ID。每行都关联了具有 updated/inserted 它的最后一个事务的事务 ID。与特定行关联的事务 ID 可以在系统列 xmin
中看到。具有相同事务的行 updated/inserted 将具有相同的事务 ID (XID)。
这些 ID 控制该行对其他并发事务的可见性。 ID为50的事务,可以看到transactionID < 50的所有行。
交易ID可以有40亿以上的值(32位)。问题是,当我们达到这个值时,事务 ID 需要重新启动,这意味着对于这个事务,所有行突然都不可见(它具有最低的事务 ID),即使这些行是过去添加的。这称为环绕问题。
我知道 vacuum 解决了将旧行标记为冻结的问题。如何查看已冻结的行? xmin
会有具体值吗?
此信息存储在 tuple header (HeapTupleHeaderData
) 的 t_infomask
中。请参阅 src/include/access/htup_details.h
中的以下定义:
/*
* information stored in t_infomask:
*/
[...]
#define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */
#define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */
#define HEAP_XMIN_FROZEN (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)
您无法通过 SQL 直接访问该信息,但如果您使用 pageinspect 扩展,则可以使用 heap_page_items
和 heap_tuple_infomask_flags
函数来读取该信息来自原始的 8kB 页面。
我正在研究VACUUM
命令。特别是它如何解决环绕问题。
基本上每笔交易都有一个交易ID。每行都关联了具有 updated/inserted 它的最后一个事务的事务 ID。与特定行关联的事务 ID 可以在系统列 xmin
中看到。具有相同事务的行 updated/inserted 将具有相同的事务 ID (XID)。
这些 ID 控制该行对其他并发事务的可见性。 ID为50的事务,可以看到transactionID < 50的所有行。
交易ID可以有40亿以上的值(32位)。问题是,当我们达到这个值时,事务 ID 需要重新启动,这意味着对于这个事务,所有行突然都不可见(它具有最低的事务 ID),即使这些行是过去添加的。这称为环绕问题。
我知道 vacuum 解决了将旧行标记为冻结的问题。如何查看已冻结的行? xmin
会有具体值吗?
此信息存储在 tuple header (HeapTupleHeaderData
) 的 t_infomask
中。请参阅 src/include/access/htup_details.h
中的以下定义:
/*
* information stored in t_infomask:
*/
[...]
#define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */
#define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */
#define HEAP_XMIN_FROZEN (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)
您无法通过 SQL 直接访问该信息,但如果您使用 pageinspect 扩展,则可以使用 heap_page_items
和 heap_tuple_infomask_flags
函数来读取该信息来自原始的 8kB 页面。