本文地址:https://www.cnblogs.com/ajiangg/p/9850902.html 约半年前上线了去哪儿的开源审核工具Inception(最近发现已经闭源了.....)以及基于Inception的SQL审核平台Yearning。 一直都用得很爽...直到昨天踩坑。

昨天晚上某个表A新加了一个字段,今早收到业务告警。最后从日志中发现类似如下报错(B表的外键指向了不存在的表_A_old): Cannot add or update a child row: a foreign key constraint fails (db.B, CONSTRAINT B_ibfk_2 FOREIGN KEY (A_id) REFERENCES _A_old (id)) 至于为啥会有外键...这属于历史遗留问题。

第一反应,昨天加字段的时候Inception调用pt-osc出问题了,导致外键没有链接到新表上去。 既然pt-osc会有问题,那就老老实实直接删除外键,重加吧 alter table B drop foreign key B_ibfk_2,add constraint new_key FOREIGN KEY (A_id) REFERENCES A(id) 悲剧的是B表实在是太大,线上跑了一个小时也无果,于是Kill回滚。

回过头来研究为毛B表会指向利用pt-osc进行字段增加时的旧表_A_old呢? 先看看pt-osc关于外键的参数--alter-foreign-keys-method: (1)auto 自动决定采用哪个方法,如果可以就采用rebuild_constraints,如果不可以就采用drop_swap (2)rebuild_constraints 该方法采用alter table来drop并re-add链接新表的外键。除非相关的子表太大使得alter过程花费时间过长,一般都采用该方法。这里的花费时间是通过比较子表中的行数和该工具将原始表数据拷贝到新表中的拷贝速率来评估的,如果评估后发现子表中数据能够在少于--chunk-time的时间内alter完成,就会采用该方法。另外,因为在MySQL中alter table比外部拷贝数据的速率快很多,所以拷贝速率是按照--chunk-size-limit来决定的 因为MySQL的限制,外键在改表前后的名字会不一样,改表后新表中的外键名前会加一个下划线,同样,会自动的更改外键相应的索引名字 (3)drop_swap 该方法禁止外键检查(FOREIGN_KEY_CHECKS=0),然后在rename新表之前就将原始表drop掉,这个方法更快而且不会被阻塞,但是风险比较大,风险有二: 在drop掉原始表和rename新表之间有一个时间差,在这段时间里这个表是不存在的,这会导致查询报错 如果rename新表时发生了错误,那问题就大了,因为原始表已经被drop掉了,只能呵呵了 (4)none 这个方法类似没有"swap"的drop_swap,原始表中的所有外键都会被指定到一个不存在的表上 因为原始表(database.tablename)会被rename为database.tablename_old然后drop掉。这种处理外键的方法可以让DBA在需要时取消该工具的这种内置功能

以下是我关于这些参数的测试结果(参数auto略过了): 1.有子表的表A使用最安全的--alter-foreign-keys-method=rebuild_constraints来进行线上更新时, 在copy完父表之后,子表进行更改的方式是alter table B drop foreign key old_key,add constraint new_key FOREIGN KEY (A_id) REFERENCES A(id)。如果子表B比较大,或者A表有好几个子表,那么我还有使用pt-osc的必要么?(对线上的影响可能远远大于直接alter table A带来的影响)

2.有子表的表A使用--alter-foreign-keys-method=none来进行线上更新时, 在copy完父表之后,数据库是直接执行set FOREIGN_KEY_CHECKS=0,然后drop旧表_A_old,然后rename新表_A_new为A。然后就收工了。 所以子表B的外键指向的仍然是pt-osc运行过程中的那张原始父表_A_old 很显然,Inception针对pt-osc的默认配置就是使用--alter-foreign-keys-method=none。

3.有子表的表A使用--alter-foreign-keys-method=drop_swap来进行线上更新时, 在copy完父表之后,数据库是直接执行set FOREIGN_KEY_CHECKS=0,然后drop旧表_A_old,然后rename新表_A_new为_A_old,最后再rename为A。 这样弄完之后父子表的关系仍然存在。(在rename_A_new为_A_old之后,drop旧表_A_old产生的错误指向就被带回来了) --------------------------------------------------------------------------------------解决方法----------------------------------------------------------------------------------------------- 既然rename表之后,子表的外键关系能跟着变,那么最后线上问题的修正方法也就有了: 现在子表B的外键指向是一个不存在的表_A_old,那么我把现在的A表rename成_A_old,外键关系联系上了之后再重新rename回A表,不就好了么: alter table A rename _A_old; alter table _A_old rename A; 经测试没问题,秒恢复正常,然后线上执行OK。

最后回过头来检查Inception关于pt-osc对外键的配置发现: inception_osc_alter_foreign_keys_method的默认配置是none(即它调用pt-osc的默认参数为--alter-foreign-keys-method=none),所以出现了外键指向不存在的表。 在这里我将配置改成了drop_swap

--------------------------------------------------------------------------------------华丽丽的分割线----------------------------------------------------------------------------------------------- 最后的反省: 数据库有变更的时候,变更完成后需要对相关的业务进行检查。这次虽然我们业务告警系统也在变更之后立即告警了,但却当成“狼来了”给略过了,此处需向老板好好反省...... 关于外键,一直都是抵制的。对于新表,新需求一直都禁止使用外键。但旧的系统,很难推动去改掉它。 以前对于外键的一些细节,总是想着反正不会用到,所以遇到这样的细节直接就跳过了。 现在看来,虽然可能一般不会碰到,但这些细节还是需要好好的去理解掌握。 本文地址:https://www.cnblogs.com/ajiangg/p/9850902.html

JAVA incept_关于Inception默认配置的一个坑相关推荐

  1. SAP Spartacus里使用injection token提供默认配置的一个例子

    以AsmStoreModule为例: import { CommonModule } from '@angular/common'; import { HttpClientModule } from ...

  2. 数据连接池默认配置带来的坑testOnBorrow=false,cloes_wait 终于解决了

    首先说一下自己程序中遇到的问题,前一段新写了一个项目,主要为方便公司业务切库做准备,为其他项目提供接口(spring boot 项目<spring boot + mongo data jpa+m ...

  3. 微信公众平台测试号接口配置的一个坑——ngrok的

    先说坑,我觉得真坑 要想做公众号开发,但是个人账号是没有公众平台的全部接口权限的,所以需要申请测试账号.URL填写需要一个域名,所以选择用内网穿透,我这里使用的就是ngrok,直接去官网下就可以了.我 ...

  4. java checkstyle 导入_Checkstyle的配置详解

    Checkstyle是一款检查java程序代码样式的工具,可以有效的帮助我们检视代码以便更好的遵循代码编写标准,特别适用于小组开发时彼此间的样式规范和统一.Checkstyle提供了高可配置性,以便适 ...

  5. JAVA项目代码手写吗_一个老程序员是如何手写Spring MVC的

    见人爱的Spring已然不仅仅只是一个框架了.如今,Spring已然成为了一个生态.但深入了解Spring的却寥寥无几.这里,我带大家一起来看看,我是如何手写Spring的.我将结合对Spring十多 ...

  6. 【Java基础】Java中的char是否可以存储一个中文字符之理解字符字节以及编码集

    Java中的一个char采用的是Unicode编码集,占用两个字节,而一个中文字符也是两个字节,因此Java中的char是可以表示一个中文字符的. 但是在C/C++中由于采用的字符编码集是ASCII, ...

  7. SpringBoot 2.0 编程方式配置,不使用默认配置方式

    SpringBoot的一般配置是直接使用application.properties或者application.yml,因为SpringBoot会读取.perperties和yml文件来覆盖默认配置: ...

  8. hadoop配置文件默认配置

    原文地址:http://www.linuxqq.net/archives/964.html 获取默认配置 配置hadoop,主要是配置core-site.xml,hdfs-site.xml,mapre ...

  9. Feign-2覆写Feign的默认配置

    现在我们来复写Feign的默认配置7.2 Overriding Feign Defaultshttps://cloud.spring.io/spring-cloud-netflix/multi/mul ...

最新文章

  1. hdu4560 不错的建图,二分最大流
  2. 查询时要处理好各种异常情况
  3. intValue()的用法
  4. OpenCV直方图均衡化
  5. HDLBits答案(21)_Verilog有限状态机(8)
  6. Fiddle:使用断点:bpu,bpafter
  7. macos降级_iOS12.3 beta2更新了什么 iOS12.3测试版2新特性与升降级方法
  8. 明晚来墨天轮直播间,听杨长老聊聊Oracle数据库并行的是是非非
  9. delphi 调用Msftedit.dll,重写Richedit,支持RTF画表格
  10. 关于nginx keep-alive 参数的验证和心得
  11. c语言字符合法,C语言字符数据的合法形式
  12. python app逆向_python之app逆向破解data参数中的PassWord DES加密无填充
  13. 【FastDFS-V5.11】Linux下FastDFS+Nginx实现分布式图片服务器搭建详细教程(单机模式)
  14. 阿里天猫小镇的实质就是为了圈地!
  15. UE4 虚幻 常用的流程控制蓝图节点介绍
  16. html自动播放音乐
  17. C语言双人贪吃蛇游戏瘦身版本
  18. 软件测试常用工具有哪些
  19. 手机测试相关基础知识
  20. 4K显示器和防蓝光眼镜膜

热门文章

  1. 249部经典电影,大家编程之余可以看一下
  2. 2021-2027全球与中国电动汽车线束和连接器市场现状及未来发展趋势
  3. [读书笔记]Core Java: Volume I - Fundamentals Chapter 8
  4. 注册功能课件详解:前后端
  5. 基于单片机烟雾及温度报警器-火灾监测-毕设课设资料
  6. 深入分析ClassLoader
  7. 微信小程序全栈开发实践 第二章 微信小程序组件介绍及使用 -- 2.3 rich-text 组件,以及如何单击预览它的节点图片并保存
  8. 科技云报道:AI+Science、元宇宙、仿生机器人……云栖大会带你看到未来的样子
  9. Maven — maven filtering OTS parsing error incorrect file size in WOFF head 产生原因及两种解决方案
  10. 【Pandas处理CSV】Error tokenizing data. C error: Expected 1 fields in line XX, saw XX