由于 PostgreSQL 文档https://www.postgresql.org/docs/current/ddl-system-columns.html
xmin此行版本的插入事务的标识(事务 ID)(行版本是行的单独状态;行的每次更新都会为同一逻辑行创建新的行版本)。
我们正在使用它(不要问为什么,只是发生)同步数据并从 PostgreSQL 源数据库中提取(ETL 中的 E)更改,我们通过间隔扫描,特别是 xmin 间隔来实现它,例如我们已经同步了 xmin 间隔0 到 10002,当我们进行下一次同步时,在这种情况下,我们将从 10003 开始搜索 xmin。如果每个已提交且可见的事务都按顺序编号,则没有问题,所有数据更改都会按顺序编号,但如果事务在它们初始化的那一刻进行编号,则可能会发生下一种情况:
- 交易 10001 开始于 15:01
- 交易 10002 开始于 15:02
- 事务 10002 在 15:02 提交
- 事务 10001 在 15:03 提交
如果我们在 15:02 进行了同步,并且在目标 DB 中获得了 max xmin:10002,在这种情况下,在从 xmin 10003 开始的下一次同步中,我们将跳过 xmin 10001 并且将丢失更改。
那么 PostgreSQL 事务 id (xmin) 是否顺序出现在提交的版本中?
同一个文档中还有 xmax :
xmax删除事务的标识(事务 ID),或零表示未删除的行版本。在可见行版本中,此列可能不为零。这通常表明删除事务尚未提交,或者尝试的删除已回滚。
所以我们可以看到计划删除行的事务(如果它将被提交),所以也许 xmin 也显示了将更改行的事务?但由于 xmin 描述,这是不可能的:
...对于此行版本。(行版本是行的单个状态;行的每次更新都会为同一逻辑行创建一个新的行版本。)
因为,正如所写,它必须与我们读取的行版本匹配,这可能只有脏读(当我们看到未提交的数据时)才能匹配,但这在 PostgreSQL https://www.postgresql.org/docs/current中不会发生/transaction-iso.html
脏读:允许,但在 PG 中不允许