为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【概述】 场景 + 问题概述
【应用框架及开发适配业务逻辑】
【背景】 做过哪些操作
【现象】 业务和数据库现象
【问题】 当前遇到的问题
【业务影响】
【TiDB 版本】
【附件】 相关日志及监控(https://metricstool.pingcap.com/)
若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。
为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【概述】 场景 + 问题概述
【应用框架及开发适配业务逻辑】
【背景】 做过哪些操作
【现象】 业务和数据库现象
【问题】 当前遇到的问题
【业务影响】
【TiDB 版本】
【附件】 相关日志及监控(https://metricstool.pingcap.com/)
若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。
TiDB使用的是percolator事务模型,第一个阶段被称为prewrite阶段,不是prepare阶段。在prewrite阶段如果失败的话,是要整体回滚的。prewrite阶段的主要工作如下,其中第三步会进行版本检查和锁冲突检查,无法通过检查都将导致事务被回滚
1、COMMIT语句向Percolator Worker发起Pre-write请求
2、在该事务包含的所有写操作中选取一个作为主(primary)操作(TiDB中将事务的第一行作为primary),其余的作为次(secondary)操作。主操作将作为整个事务的互斥点,标记事务的状态
3、先预写主操作,成功后再预写次操作。在预写过程中,对每一个写操作都要执行如下检查,通过检查后才能继续下一步
3.1、版本检查:检查写入的行对应的write列版本号是否晚于start_ts,如果是,说明有版本冲突(有其它事务已经提交),直接取消整个事务
3.2、锁冲突检查:检查写入的行对应的lock列是否有锁,如果有,说明其它事务正在写,直接取消整个事务
4、检查通过后,以start_ts作为版本号将数据写入data列(持久化),但不写write列,亦即此时写入的数据仍然不可见
5、对操作行加锁,即更新lock列的锁信息:主操作行的lock直接标为primary,次操作行的lock则标为主操作行的行键(key)和字段名
对,是prewrite阶段,如果prewrite阶段成功,进入第二阶段后,即commit阶段,分布式事务一定会成功吧?
是的,prewrite结束事务状态就已经确定了,所以才有了async commit这种优化