适用版本
OceanBase 数据库 V2.x 和 V3.x 版本。
问题现象
先 Truncate 分区,再使用 INSERT INTO ... SELECT 的方式为新分区插入数据,发生 SQL 报错 transaction needs rollback。
obclient> alter table A truncate partition PX;
obclient> insert into A select from B;
问题原因
Truncate 实际是 Drop + Create。Root Service 会在 Create 分区时选择一个 Leader,在 Truncate 完成后,Root Service 的负载均衡又会重新调整 Leader,而这时 INSERT 语句正好在执行中,分布式事务执行中发生了 Leader 切换导致事务回滚。
OceanBase 数据库 V3.2 版本对于分布式事务中的 Leader 切换做了优化,尽量避免 Leader 切换导致的事务回滚。优化内容为:
在进行有主改选时,如果旧的 Leader 上正在执行的事务日志能在规定的时间内(
trx_force_kill_threshold, default=100ms)把同步到新 Leader 上,则新 Leader 上任后可以继续推进事务的执行。如果不能在规定的时间内完成事务日志的同步,则需要回滚正在执行的事务。
因为 INSERT 语句涉及事务日志量较大,不能在规定的时间内完成日志的同步,所以发生了这个报错。
解决方法
Truncate 后等待 Leader 重分布完成后再执行事务。
不推荐修改
trx_force_kill_threshold的值来规避该问题。
相关文档
关于系统配置项 trx_force_kill_threshold 的详细介绍,请参考 trx_force_kill_threshold。