外键是指引用其他表中具有唯一性约束或者主键约束的一列或几列数据,使两张表达成一定的契约关系,从而保证引用数据的一致性。在集群中使用外键,一定要保证集群各个节点数据一致,不然将会导致意想不到的产线事故。
事故回顾
20220728
09:38 生产环境主动将xxl-job的某两个定时任务先后暂停使用,我们在其界面手动点击停用按钮
09:40 运维人员发现mysql集群告警,查看日志发现从库数据同步异常
09:44 运维手动处理数据,集群恢复正常
事故剖析
1、查看xxl-job数据库,可以发现相关表存在外键约束
2、查看集群日志我们可以发现集群的从库在删除定时任务描述数据时候外键约束,导致删除失败。
3、查看xxl-job 源码发现在停用定时任务时候xxl-job-admin会先删除任务的触发器记录,并且删除本任务的任务描述。执行顺序为先删除触发器,再删除任务描述。
protected boolean removeJob(Connection conn, final JobKey jobKey)
throws JobPersistenceException {
try {
List<TriggerKey> jobTriggers = getDelegate().selectTriggerKeysForJob(conn, jobKey);
for (TriggerKey jobTrigger: jobTriggers) {
deleteTriggerAndChildren(conn, jobTrigger);
}
return deleteJobAndChildren(conn, jobKey);
} catch (SQLException e) {
throw new JobPersistenceException("Couldn't remove job: "
+ e.getMessage(), e);
}
}
为保证数据一致性,admin服务在触发器记录添加了任务描述外键。按照代码执行顺序,在删除任务描述时候触发器记录已经删除,故不会触发外键约束导致删除描述失败的情况。
4、本次事故主库并没有触发外键约束,定时任务删除成功,但是从库却触发了外键约束,可知道应该是从库数据同步异常导致本事故。
查看从库binlog
### DELETE FROM `xxl_job`.`XXL_JOB_QRTZ_TRIGGERS`
### WHERE
### @1='DefaultQuartzScheduler' /* VARSTRING(480) meta=480 nullable=0 is_null=0 */
### @2='17' /* VARSTRING(800) meta=800 nullable=0 is_null=0 */
### @3='DEFAULT' /* VARSTRING(800) meta=800 nullable=0 is_null=0 */
### @4='17' /* VARSTRING(800) meta=800 nullable=0 is_null=0 */
### @5='DEFAULT' /* VARSTRING(800) meta=800 nullable=0 is_null=0 */
### @6=NULL /* VARSTRING(1000) meta=1000 nullable=1 is_null=1 */### @7=1659034800000 /* LONGINT meta=0 nullable=1 is_null=0 */
### @8=1658948400000 /* LONGINT meta=0 nullable=1 is_null=0 */
### @9=5 /* INT meta=0 nullable=1 is_null=0 */
### @10='WAITING' /* VARSTRING(64) meta=64 nullable=0 is_null=0 */
### @11='CRON' /* VARSTRING(32) meta=32 nullable=0 is_null=0 */
### @12=1649944643000 /* LONGINT meta=0 nullable=0 is_null=0 */
### @13=0 /* LONGINT meta=0 nullable=1 is_null=0 */
### @14=NULL /* VARSTRING(800) meta=800 nullable=1 is_null=1 */
### @15=2 /* SHORTINT meta=0 nullable=1 is_null=0 */
### @16='' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
# at 619154171
#220728 9:37:09 server id 6 end_log_pos 619154198 Xid = 241555354
COMMIT/*!*/;
结论:从库数据不一致导致没有命中数据,由于触发器记录包含任务描述外键,删除后面任务描述触发外键引起。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/154703.html