MySQL 数据丢失排查案例


Posted in MySQL onMay 08, 2021

前言

最近,有一位朋友突然微信联系我,说MySQL出现了数据丢失的情况;毫无疑问,对于一个DBA而言,这无疑是最令人紧张的一件事情,没有之一;听到这个消息后,我也就立刻投入到问题排查中。

现场排查

一开始听到这个消息,我心里面当然也是非常紧张,不过很快就让自己冷静下来,开始进行排查:

(1)实例状态是不是正常的?    --经确认,实例状态正常

(2)业务库是哪个?是否还存在?是否被删除?    --经确认,业务库存在

(3)业务是访问哪个表报错?该表是否存在?是否被删除?    --经确认,业务表存在

(4)应用用户的权限是否正常?    --经确认,应用用户拥有业务库的所有权限

(5)业务访问是报什么错?    --经确认,业务侧是访问某些页面报错

(6)排查到这里,一方面是怀疑应用程序是否有异常,另一方面是怀疑是否出现部分记录丢失;开发侧和运维侧同时在排查,这边给运维侧排查的思路是 业务表是否有主键?业务侧访问报错和业务表的对应关系是怎样的?能否找出相对应的记录?

(7)进一步分析发现,该业务表有主键,开发侧也提供了查询的记录,经排查该记录存在,并未被误删除;开发侧排查应用程序,日志也未很清晰打印出报错信息

(8)在这种情况下,只能先咨询一下当晚是否有做什么变更/发布?    --经确认,当晚有做一些表的DDL变更

继续排查发现,当晚DDL变更有涉及到该业务表的操作,变更内容为修改字段长度,类似alter table xxx modify column xxx char(x);问题到这里也就开始有思路了,接下去开始排查sql_mode配置、查询相应的完整行记录给开发确认,最终确认是DDL变更导致字段被截断,最后只能通过备份进行恢复,问题最终得到解决。

案例复现

看完刚刚的排查过程,相信很多童鞋都会有疑问,为什么修改字段长度对导致数据被截断?MySQL难道不会不会做数据校验吗?让我们接着往下看。

(1)场景1

mysql> select * from sbtest2 limit 1;
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k       | c                                                                                                                       | pad                                                         |
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
|  1 | 3718516 | 08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977 | 63188288836-92351140030-06390587585-66802097351-49282961843 |
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> alter table sbtest2 modify column pad char(1);
ERROR 1265 (01000): Data truncated for column 'pad' at row 1

mysql> select * from sbtest2 limit 1;
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k       | c                                                                                                                       | pad                                                         |
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
|  1 | 3718516 | 08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977 | 63188288836-92351140030-06390587585-66802097351-49282961843 |
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.00 sec)

(2)场景2

mysql> select * from sbtest2 limit 1;
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k       | c                                                                                                                       | pad                                                         |
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
|  1 | 3718516 | 08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977 | 63188288836-92351140030-06390587585-66802097351-49282961843 |
+----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> alter table sbtest2 modify column pad char(1);Query OK, 100 rows affected, 100 warnings (0.06 sec)
Records: 100  Duplicates: 0  Warnings: 100

mysql> select * from sbtest2 limit 1;
+----+---------+-------------------------------------------------------------------------------------------------------------------------+------+
| id | k       | c                                                                                                                       | pad  |
+----+---------+-------------------------------------------------------------------------------------------------------------------------+------+
|  1 | 3718516 | 08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977 | 6    |
+----+---------+-------------------------------------------------------------------------------------------------------------------------+------+
1 row in set (0.00 sec)

场景1是比较符合我们预期的,直接报错“数据被截断”;场景2是执行成功,导致“数据部分丢失”;那么,MySQL是没有进行数据校验吗?其实MySQL都有对数据进行校验的,只是在场景2中,因为sql_mode配置有问题,没有设置STRICT_TRANS_TABLES,导致MySQL没有阻止该操作执行,从而导致“数据丢失”惨案。

总结

至此,“数据丢失”惨案也就可以告一段落,根本原因是sql_mode没有设置STRICT_TRANS_TABLES;这个案例也是在提醒我们,sql_mode是一个非常关键的配置,千万不可随便设置和修改;关于sql_mode的更多内容,下篇文章会继续给大家分享。

以上就是MySQL 数据丢失排查案例的详细内容,更多关于MySQL 数据丢失排查的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
Mysql - 常用函数 每天积极向上
Apr 05 MySQL
详解MySQL集群搭建
May 26 MySQL
Mysql中 unique列插入重复值该怎么解决呢
May 26 MySQL
MySQL 发生同步延迟时Seconds_Behind_Master还为0的原因
Jun 21 MySQL
mysql联合索引的使用规则
Jun 23 MySQL
MySQL系列之四 SQL语法
Jul 02 MySQL
MySQL 那些常见的错误设计规范,你都知道吗
Jul 16 MySQL
MySQL 开窗函数
Feb 15 MySQL
MySQL 分区表中分区键为什么必须是主键的一部分
Mar 17 MySQL
Mysql使用全文索引(FullText index)的实例代码
Apr 03 MySQL
WINDOWS下安装mysql 8.x 的方法图文教程
Apr 19 MySQL
MySQL数据库Innodb 引擎实现mvcc锁
May 06 MySQL
MySQL update set 和 and的区别
May 08 #MySQL
MySQL查询学习之基础查询操作
May 08 #MySQL
MySQL sql_mode修改不生效的原因及解决
May 07 #MySQL
一篇文章弄懂MySQL查询语句的执行过程
详解MySQL主从复制及读写分离
MySQL 表空间碎片的概念及相关问题解决
MySQL kill不掉线程的原因
May 07 #MySQL
You might like
php实现memcache缓存示例讲解
2013/12/04 PHP
yii实现model添加默认值的方法(2种方法)
2016/01/06 PHP
php自定义函数实现JS的escape的方法示例
2016/07/07 PHP
js中的布尔运算符使用介绍
2013/11/20 Javascript
JavaScript错误处理
2015/02/03 Javascript
js+HTML5基于过滤器从摄像头中捕获视频的方法
2015/06/16 Javascript
JS实现把鼠标放到链接上出现滚动文字的方法
2016/04/06 Javascript
用JS实现图片轮播效果代码(一)
2016/06/26 Javascript
RequireJS简易绘图程序开发
2016/10/28 Javascript
仿iframe效果Aajx文件上传实例
2016/11/18 Javascript
详解微信小程序开发—你期待的分享功能来了,微信小程序序新增5大功能
2016/12/23 Javascript
H5图片压缩与上传实例
2017/04/21 Javascript
JS鼠标滚动分页效果示例
2017/07/05 Javascript
canvas+gif.js打造自己的数字雨头像的示例代码
2017/10/26 Javascript
vue中$set的使用(结合在实际应用中遇到的坑)
2018/07/10 Javascript
什么时候不能在 Node.js 中使用 Lock Files
2019/06/24 Javascript
Python2.x版本中基本的中文编码问题解决
2015/10/12 Python
python 迭代器和iter()函数详解及实例
2017/03/21 Python
Python标准库inspect的具体使用方法
2017/12/06 Python
pip安装时ReadTimeoutError的解决方法
2018/06/12 Python
Python计算开方、立方、圆周率,精确到小数点后任意位的方法
2018/07/17 Python
python 画三维图像 曲面图和散点图的示例
2018/12/29 Python
Python 实现遥感影像波段组合的示例代码
2019/08/04 Python
关于windows下Tensorflow和pytorch安装教程
2020/02/04 Python
canvas 绘图时位置偏离的问题解决
2020/09/16 HTML / CSS
英国最大的海报商店:GB Posters
2018/03/20 全球购物
本科毕业生的求职信范文
2013/11/20 职场文书
2013的个人自我评价
2013/12/26 职场文书
可口可乐广告词
2014/03/20 职场文书
大三学习计划书范文
2014/05/02 职场文书
爱心捐款倡议书范文
2014/05/12 职场文书
高中生逃课检讨书
2014/10/10 职场文书
优秀员工自荐书
2015/03/06 职场文书
机关工会工作总结2015
2015/05/26 职场文书
Python OpenCV超详细讲解基本功能
2022/04/02 Python
vmware虚拟机打不开vmx文件怎么办 ?vmware虚拟机vmx文件打开方法
2022/04/08 数码科技