postgresql , 10.0 , 2pc , txid_status , unknown事务
在一些极端情况下,例如当客户端发出事务提交sql后,客户端收到数据库返回的提交状态前,如果客户端崩溃或数据库异常,导致客户端不知道事务的最终状态到底是提交成功还是失败的。
那么怎么解决这个问题呢?
1. 一种方法是走2pc协议,先使用预提交,然后在发出commit 之前的预提交。(因为只要预提交成功,就可以认为后面的commit是一定可以成功的),从而来避免unknown的事务问题。
但是2pc引入了性能的问题,因为需要和数据库交互多次。
2. 10.0引入一个新的功能,查看以往的事务提交状态。在发生崩溃问题后,应用程序再起来之后,可以通过事务号,查到事务的提交状态。杜绝unknown的事务。
为了查询事务状态,应用程序必须要保留事务号,目前postgresql通过txid_current()可以查询当前的事务号,结合insert ,update,... returning txid_current(),可以在一次交互中得到这个事务号。从避免因为这个功能引入的增加一次交互。
未来postgresql可能会在驱动层面解决这个问题,减少业务程序的开发工作量(使用txid_current()获得事务号)。
例子
patch如下
这个patch的讨论,详见邮件组,本文末尾url。
postgresql社区的作风非常严谨,一个patch可能在邮件组中讨论几个月甚至几年,根据大家的意见反复的修正,patch合并到master已经非常成熟,所以postgresql的稳定性也是远近闻名的。
<a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=857ee8e391ff6654ef9dcc5dd8b658d7709d0a3c">https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=857ee8e391ff6654ef9dcc5dd8b658d7709d0a3c</a>
<a href="https://blog.2ndquadrant.com/traceable-commit-postgresql-10/">https://blog.2ndquadrant.com/traceable-commit-postgresql-10/</a>