【发布时间】:2020-05-28 01:55:29
【问题描述】:
由于 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 中不允许
【问题讨论】:
标签: postgresql transactions mvcc