生产问题(十六)数据丢失-mysql binlog排查

一、引言

    最近作者遇到一个线上问题,是mysql 的数据丢失了,这里记录一下排查过程和binlog的分析。

二、问题

    问题出现的表象是应用系统大量报错,各种空指针之类的,这种一看就不可能是代码发布的问题,原因一定在框架、网络或者数据层。

    我们首先根据日志找到了报错数据,然后在查sqlserver的时候发现是有的,但是mysql里面没有数据。

    这里要提一下作者这里的数据架构背景,目前是双引擎的,sqlserver和mysql同时双写,有一个公共组件进行写入和更新,所以我们第一想法是组件有问题。

三、排查

1、公共组件

    我们首先联系了公共组件的人,询问有无相关发布,但是很明显没有,并且公共组件还找了日志截图

    可以明显看到插入语句和更新语句都是有返回影响行数的,所以公共组件应该是没什么问题

图片

    这样的话,怀疑的方向就到了数据层,是不是mysql的库坏了,虽然很少见,但是开发团队多的确什么情况都有,隔壁的数据库经常出问题

2、数据库

    在觉得数据库有问题之后,我们就找dba导出binlog查看,这里要知道一下mysql的写入顺序。作者之前写过文章,binlog是最后写入的,在undo、redo之后,所以看数据问题binlog就可以

https://blog.csdn.net/m0_69270256/article/details/128311652?spm=1001.2014.3001.5501

图片

    先看一个单子的binlog写入,由于需要隐藏信息,这里的表和字段都呗替换成虚拟的

    begin代表事务开启,

  • end_log_pos 26:这表示事件在二进制日志文件中的结束位置是26。这个数字是一个字节偏移量,指示了下一个事件在日志文件中的起始位置。

  • CRC32 0xe1:这是一个循环冗余校验(CRC32)值,用于检测日志内容在存储或传输过程中是否发生了变化。0xe1是这个特定事件内容的CRC32校验和。

  • Query:这表明记录的事件类型是一个查询。在二进制日志中,可以记录多种类型的事件,例如Query(查询)、Xid(事务ID)、Table_map(表映射)等。

  • thread_id=666:这是执行查询的线程ID。在MySQL中,每个客户端连接都由一个线程处理,这个ID可以用来追踪是哪个线程执行了这个查询。

  • exec_time=0:这表示查询的执行时间是0秒。这个值通常用于性能分析,了解查询执行的耗时。

  • error_code=0:这表示查询执行时没有发生错误。0通常表示操作成功,非零值表示发生了错误。

    重点在于Write_rows和commit,这代表数据肯定是插入了

  • Write_rows:这表明事件的类型是写入行操作。这意味着该事件包含了被插入到表中的行的信息。

  • table id 94:这标识了行被插入的表。表ID是二进制日志文件中唯一的数字标识符,用于将事件与特定的表关联起来。要知道这个ID指的是哪个表,您需要查看二进制日志中前面的Table_map事件,该事件将表ID映射到实际的表名。

  • flags: STMT_END_F:这是与事件相关联的一组标志。特别是STMT_END_F标志表明这个Write_rows事件标志着一个语句的结束。在二进制日志的上下文中,这意味着该事件是代表单个SQL语句的一系列事件中的最后一个。

BEGIN
/*!*/;
# at 572
#523 13:15:39 server id id1  end_log_pos pos1 CRC32 0x60a16a59   Rows_query
# /*Client[MSG_ID:msgid1]*/REPLACE INTO `product` (`id`,`product`) VALUES (1,'product1')
# at pos1
#523 13:15:39 server id id1  end_log_pos 22 CRC32 0xc3   Table_map: `msdb`.`product` mapped to number 94
# at 22
#523 13:15:39 server id id1  end_log_pos 23 CRC32 0xfb   Write_rows: table id 94 flags: STMT_END_F
### INSERT INTO `msdb`.`product`
### SET
###   @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */
###   @2='uid1' /* VARSTRING(80) meta=80 nullable=0 is_null=0 */
###   @3='' /* VARSTRING(80) meta=80 nullable=0 is_null=0 */
# at 23
#523 13:15:39 server id id1  end_log_pos 24 CRC32 0xb1   Xid = 222
COMMIT/*!*/;
# at 24
# at 25
#523 13:15:39 server id id1  end_log_pos 26 CRC32 0xe1   Query  thread_id=666  exec_time=0  error_code=0=134/*!*/;

    如果是被回滚了,他应该是这样的,ROLLBACK标志会非常明显,所以一定不是回滚然后没有插入

BEGIN/*!*/;
# at 572
#523 13:15:39 server id id1  end_log_pos pos1 CRC32 0x60a16a59   Rows_query
# /*Client[MSG_ID:msgid1]*/REPLACE INTO `product` (`id`,`product`) VALUES (1,'product1')
# at pos1
#523 13:15:39 server id id1  end_log_pos 22 CRC32 0xc3   Table_map: `msdb`.`product` mapped to number 94
# at 22
#523 13:15:39 server id id1  end_log_pos 23 CRC32 0xfb   Write_rows: table id 94 flags: STMT_END_F
### INSERT INTO `msdb`.`product`
### SET
###   @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */
###   @2='product1' /* VARSTRING(80) meta=80 nullable=0 is_null=0 */
# at 23
#523 13:15:39 server id id1  end_log_pos 24 CRC32 0xb1   Xid = 222
ROLLBACK/*!*/;
# at 24

    而且后续还能看到更新这条数据的binlog,同样说明了数据是进入数据库的

BEGIN/*!*/;
# at 572
#523 13:15:39 server id id1  end_log_pos pos1 CRC32 0x60a16a59   Rows_query
# /*Client[MSG_ID:msgid1]*/UPDATE `product` SET `product`='product2' WHERE `id`=1
# at pos1
#523 13:15:39 server id id1  end_log_pos 22 CRC32 0xc3   Table_map: `msdb`.`product` mapped to number 94
# at 22
#523 13:15:39 server id id1  end_log_pos 23 CRC32 0xfb   Update_rows: table id 94 flags: STMT_END_F
### UPDATE `msdb`.`product`
### WHERE
###   @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */
###   @2='product1' /* VARSTRING(80) meta=80 nullable=0 is_null=0 */
### SET
###   @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */
###   @2='product2' /* VARSTRING(80) meta=80 nullable=0 is_null=0 */
# at 23
#523 13:15:39 server id id1  end_log_pos 24 CRC32 0xb1   Xid = 224
COMMIT/*!*/;
# at 24

   

     既然数据有了,那有没有可能是被删除了,但是我们是没有物理删除的,也没有人提工单去手工删除,

    再看看binlog找不到删除的语句,如果有应该会像下面的语句一样

    但是binlog也不是准确的,这里说的不准确不是说mysql服务器的binlog不准确,而是dba提供的下载工具。这种下载工具一般是计算好文件偏移量,然后进行多线程读取,但是文件在不断写入又被读取,事关数据库也不会锁文件,这中间有offset偏移是很正常的,所以下载的文件流很容易丢失和读取偏移。

BEGIN/*!*/;
# at 572
#523 13:15:39 server id id1  end_log_pos pos1 CRC32 0x60a16a59   Rows_query
# /*Client[MSG_ID:msgid1]*/DELETE FROM `product` WHERE `id`=1 AND `product`='product1'
# at pos1
#523 13:15:39 server id id1  end_log_pos 22 CRC32 0xc3   Table_map: `msdb`.`product` mapped to number 94
# at 22
#523 13:15:39 server id id1  end_log_pos 23 CRC32 0xfb   Delete_rows: table id 94 flags: STMT_END_F
### DELETE FROM `msdb`.`product`
### WHERE
###   @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */
###   @2='product1' /* VARSTRING(80) meta=80 nullable=0 is_null=0 */
# at 23
#523 13:15:39 server id id1  end_log_pos 24 CRC32 0xb1   Xid = 223
COMMIT/*!*/;
# at 24

    到这里就有点坑了,不能纠结到底是不是binlog下载丢失,也有可能是就没有删除日志。好在后面又找到了一个两天前的老单子,在mysql对应bi 的数据库里面有数据,因为bi库都是T-1的,所以可以证明数据的确是被删除了

    后面换方向排查db审批工单的确发现是被删除了,属于误操作删除

三、拓展

    有的读者可能不太了解binlog,作者这里讲讲它的原理和使用

1、原理

  1. 日志格式:MySQL支持三种binlog格式:statement-based replication (SBR),row-based replication (RBR),和mixed-mode replication。SBR记录SQL语句,RBR记录行的变化,mixed模式根据操作自动选择SBR或RBR。

  2. 日志内容:binlog记录了所有修改数据库状态的SQL语句,如INSERT、UPDATE、DELETE,以及DDL语句如CREATE TABLE、ALTER TABLE等。

  3. 日志作用:

    • 复制:在主从复制中,从服务器会读取主服务器的binlog来复制数据。

    • 数据恢复:可以使用binlog来恢复因操作错误或其他原因丢失的数据。

    • 审计:binlog可以用来审计数据库的变更历史。

  4. 日志索引:MySQL会维护一个binlog索引文件,记录所有binlog文件的列表。

2、操作

  1. 启用binlog:在my.cnf(或my.ini)配置文件中设置log_bin参数来启用binlog。

  2. 查看binlog:可以使用SHOW BINARY LOGS命令查看当前的binlog文件列表。

  3. 读取binlog:使用mysqlbinlog工具可以读取和解析binlog文件。

  4. 刷新binlog:使用FLUSH LOGS命令可以关闭当前的binlog文件并开启一个新的binlog文件。

  5. 清理binlog:可以设置expire_logs_days参数来自动删除旧的binlog文件,或者使用PURGE BINARY LOGS命令手动删除。

3、使用经验

  1. 选择合适的日志格式:根据应用场景选择SBR、RBR或mixed模式。RBR更精确但可能产生更大的日志文件,SBR更易读但在某些情况下可能导致数据不一致。

  2. 监控binlog空间:binlog可能会占用大量磁盘空间,需要定期监控和清理。

  3. binlog备份:定期备份binlog文件,以便在需要时进行数据恢复。

  4. 安全考虑:binlog中可能包含敏感信息,需要确保binlog文件的安全。

  5. 性能影响:虽然binlog对性能有一定影响,但通常这种影响是可以接受的。如果性能是关键考虑因素,可以考虑使用SSD来存储binlog文件。

  6. 使用mysqlbinlog工具:熟悉mysqlbinlog工具的使用,它可以帮助你解析、过滤和应用binlog事件。

  7. 测试恢复流程:定期测试使用binlog的数据恢复流程,确保在紧急情况下能够快速有效地恢复数据。

四、总结

    业务场景,读者们和作者可能不一样,但是这个排查思路和binlog分析都是可以学习的经验。

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/845412.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十八节:认识一些经典递归过程

一 暴力递归就是尝试 1,把问题转化为规模缩小了的同类问题的子问题 2,有明确的不需要继续进行递归的条件(base case) 3,有当得到了子问题的结果之后的决策过程 4,不记录每一个子问题的解 二 打印n层汉诺塔从最左边移动到最右边的全…

分形之科赫雪花

前言 分形是一种具有自相似性的几何图形或数学对象。它的特点是无论在任何放大或缩小的尺度下,都能够看到与整体相似的图形。分形的形状可以非常复杂,常常具有分支、重复的图案,以及细节层次丰富的结构。 分形在自然界中广泛存在,如云朵、树枝、山脉、海岸线等,它们都展…

Java常用API(三)

一、Arrays类 1.定义 Arrays是一个用于操作数组的工具类。 2.常用方法 1.toString方法 public class Demo {public static void main(String[] args) {//toString 将数组变成字符串int[] arr {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};System.out.println(Arrays.toString(arr));…

故障——pod状态为pending该如何解决

一、报错问题 当您的虚拟机出现如下报错,您首先快照一下虚拟机如果仍然报错 二、解决方法 2.1 任务管理器 首先进入任务管理器(CtrlAltDel)内,查看所有vmware是否都处在运行的状态,可能会跳出一个比较突兀的进程&#…

【Spring Cloud】微服务链路跟踪Sleuth

目录 为什么要使用微服务链路跟踪微服务的现状多服务协同工作复杂的调用链条容易出错 微服务链路跟踪需要实现的需求实现监控决策避免技术债务快速定位故障 微服务链路跟踪的技术要求低消耗应用透明延展性可控采样率可视化 Spring Cloud Sleuth简介Spring Cloud Sleuth的4个特点…

自动控制:控制系统的稳定性

自动控制:控制系统的稳定性 在自动控制领域,控制系统的稳定性是一个至关重要的问题。稳定性决定了系统在受到扰动后是否能够恢复到平衡状态。本文将介绍控制系统稳定性的基本概念、如何利用特征值分析稳定性,并通过具体示例和Python代码展示…

【洛谷B3643】图的存储 解题报告

洛谷B3643 - 图的存储 题目描述 给定一个 n n n 个顶点 m m m 条边的无向图。请以邻接矩阵和邻接表的形式输出这一张图。 输入格式 第一行输入两个正整数 n n n 和 m m m,表示图的顶点数和边数。 第二行开始,往后 m m m 行,每行输入…

Docker中布置Jenkins实现Android项目的自动化构建

因项目需要,要在服务器上使用Jenkins完成Android项目的自动化构建,但服务器上登录的账户没有管理员权限,无法用sudo命令,因此需要把相应环境布置在docker中。 环境搭建 docker容器相关命令 创建容器 docker create -it contai…

【Python】解决Python报错:AttributeError: ‘function‘ object has no attribute ‘xxx‘

🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…

未来已来, AI将作为超级工具?

人工智能时代已来 1.AI将作为超级工具:AI是推动全产业数字化转型的高效工具,机遇比互联网时代大10倍,但只有1/3的机会留给初创企业。 2.硅谷AI市场分类中,特别看好开源平台,其将为初创企业和大企业提供更多选择。 3.…

C# 字节数组(byte[])拼接的性能对比测试

将C#中的三种字节数组拼接方式的性能做了一个对比测试,DEMO程序代码如下: using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks;namespace Byte数组拼接测…

使用 DuckDuckGo API 实现多种搜索功能

在日常生活中,我经常使用搜索引擎来查找信息,如谷歌和百度。然而,当我想通过 API 来实现这一功能时,会发现这些搜索引擎并没有提供足够的免费 API 服务。如果有这样的免费 API, 就能定时获取“关注实体”的相关内容,并…

Gbase 国产数据库

参考:参考: 5分钟学会Linux环境GBase 8t安装和部署 - 光洋山 - twt企业IT交流平台 (talkwithtrend.com)https://www.talkwithtrend.com/Article/197237 视频 GBase 8s快速入门-功能简介与演示-大数据教程-腾讯课堂 (qq.com)https://ke.qq.com/course/…

ADB日常使用命令

【ADB全称 Android Debug Bridge】 是Android SDK中的一个命令行工具adb命令可以直接操作管理Android模拟器或真实的Android设备(手机) 建立PC和模拟器连接 # 建立连接 adb connect 127.0.1: 模拟器端口号〈逍遥模拟器21503〉 # 验证是否连接成功 adb d…

整数乘除法练习题

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<time.h> #include<Windows.h>void show1(); .//开始界面 int getchoice(); //选择界面 int dowork(int n); //随机做乘除法 int num(); //用户确定做题的数量 v…

OrangePi AIpro 变身 Android 打包机

主板基本信息介绍 OrangePi AIpro&#xff0c;是香橙派联合华为精心打造&#xff0c;建设人工智能新生态而设计的一款开发板&#xff0c;这次为大家分享下我上手的这款 OrangePi AIpro 8GB&#xff08;算力达8TOPS&#xff09; 的一些小小的经验。 基本参数如下&#xff1a; …

首创十八道工艺,口味王引领槟榔产业高质量发展

说到槟榔&#xff0c;相信大伙都不会陌生&#xff0c;槟榔的历史可以追溯到汉代&#xff0c;不少文献有过记载&#xff0c;如汉代的沈约著的《咏竹槟榔盘》中提到“荐羞虽百品&#xff0c;所贵浮天实”&#xff1b;唐朝“诗仙”李白更是写道“何时黄金盘&#xff0c;一斛荐槟榔…

分享 ASP.NET Core Web Api 中间件获取 Request Body 两个方法

不废话&#xff0c;直接上正文。_ 方法一 思路&#xff1a;利用 BodyReader 直接读取 HttpContext 的 Request Body&#xff0c;再反序列化 var reqStream context.Request.BodyReader.AsStream(); var jsonObj JsonSerializer.Deserialize<CheckAndParsingMiddlewareM…

buuctf的RSA(五)

[RoarCTF2019]RSA 一看到题目&#xff0c;我就有些蒙了&#xff0c;A是代表了什么&#xff0c; 先来分解n 接下来可以暴力破解e了&#xff0c;因为e没有给出来&#xff0c;应该不会太大&#xff0c;猜测是四位数字 import gmpy2 import libnum from Crypto.Util.number import…

网卡配置基础知识

1、网络设置方式 首先科普下Virtual Box虚拟机的几种主流的网络设置方式&#xff0c;官方文档&#xff1a; 2解释 Host-only&#xff1a;仅主机模式 虚拟机和宿主机、虚拟机之间能互通&#xff0c;但是不能访问外网&#xff0c;虚拟机和宿主机同网段的其他主机不能互通这种…