现在,我阅读了关于“Transaction ID Wraparound”的文档,但有一些我真的不明白,该文档是以下网址 http://www.postgresql.org/docs/9.0/static/routine-vacuuming .html#VACUUM-FOR-WRAPAROUND
23.1.4. 防止事务 ID 环绕失败
PostgreSQL 的 MVCC 事务语义依赖于能够比较事务 ID (XID) 编号:插入 XID 大于当前事务 XID 的行版本是“将来”的,不应对当前事务可见。但是由于事务 ID 的大小有限(32 位),一个长时间运行(超过 40 亿个事务)的集群将遭受事务 ID 环绕:XID 计数器环绕为零,并且突然之间的事务在过去似乎在未来——这意味着它们的输出变得不可见。简而言之,灾难性的数据丢失。(实际上,数据仍然存在,但是如果您无法获得它,那就太冷了。)为了避免这种情况,必须至少每 20 亿个事务一次对每个数据库中的每个表进行一次真空吸尘。
我不理解语句“将遭受交易 ID 环绕:XID 计数器环绕为零,突然之间过去的交易似乎在未来 - 这意味着它们的输出变得不可见”
有人可以解释一下吗?为什么在数据库遭受事务 ID 环绕之后,过去的事务会出现在未来?简而言之,我想知道在autovacuum事务ID回绕后PostgreSQL是否会出现“数据丢失”的情况?
对于我个人的观点,我们可以通过使用 txid_current() 函数来获取当前事务 ID,输出是 64 位的,不会被循环。所以我认为知道为 xmin 的元组的插入事务 ID 会比得到的 xid 更大通过 txid_current() 函数。除了您将在关闭 PostgreSQL 服务器后使用 pg_resetxlog reset reset transaction ID。我对吗 ?谢谢
Jac*_*las 10
为什么在数据库遭受事务 ID 环绕之后,过去的事务会出现在未来?
他们没有。引用的文本只是解释了为什么 postgres 需要使用模 2 31算术(这意味着只要旧事务足够早地“冻结”,事务就可以回绕):
正常的 XID 使用模 2^31 算法进行比较。这意味着对于每个正常的 XID,有 20 亿个“较旧”的 XID 和 20 亿个“较新”的 XID
再具体一点:
旧行版本必须在达到 20 亿交易旧标记之前的某个时间重新分配 XID FrozenXID
或者将 XID 包裹起来会导致事情破裂。为了防止这种情况,postgres 将开始发出警告,并最终关闭并在必要时拒绝启动新的事务:
如果由于某种原因 autovacuum 无法从表中清除旧的 XID,当数据库最旧的 XID 从环绕点达到一千万个事务时,系统将开始发出这样的警告消息:
Run Code Online (Sandbox Code Playgroud)WARNING: database "mydb" must be vacuumed within 177009986 transactions HINT: To avoid a database shutdown, execute a database-wide VACUUM in "mydb".
(按照提示的建议,手动 VACUUM 应该解决问题;但请注意,VACUUM 必须由超级用户执行,否则它将无法处理系统目录,从而无法推进数据库的 datfrozenxid。)如果出现这些警告被忽略,一旦剩余交易少于 100 万,系统将关闭并拒绝开始任何新交易直到回绕
换句话说,“过去的交易似乎是未来的”和“数据丢失”完全是理论上的,在实践中不会由交易 ID 环绕引起。
归档时间: |
|
查看次数: |
8572 次 |
最近记录: |