事务在提交时会通过XLogSetAsyncXactLSN函数设置本事务相关WAL的终点,只有当WALWriter将XLogSetAsyncXactLSN函数设置的LSN之前的WAL全部刷入磁盘,才能保证这个事务真正提交。当对一个元组做可见性判断时,会为这个元组设置Hint Bits。例如,如果可见性检查发现产生这个元组的事务已经提交,那么就会在元组上设置HEAP_XMIN_COMMITTED标记。当下次访问这个元组时,就不用去clog中查看事务是否提交,而是直接通过HEAP_XMIN_COMMITTED标记来判断。

但异步提交并不是真正的提交,在事务日志被刷入磁盘之前,这种标记位不应该被设置,而应该在clog中查看事务的提交状态。这要求我们在设置Hint Bits时,判断这个事务的日志是否已经落盘,也就是说要记录这个事务的最终LSN。

PG目前为每32个事务记录一个LSN,这个LSN是这32个事务中最新的LSN,这样就形成了一个针对最新LSN的LSN GROUP。在事务做异步提交时,需要同时将事务的最终LSN作为参数传递进来,并且记录到事务对应的LSN GROUP中。

在设置元组的Hint Bits时,需要检查最终LSN,如果还没有落盘,则不设置元组的Hint Bits。

PostgreSQL数据库WAL——XLogSetAsyncXactLSN异步提交_元组