后端工程师的高阶面经
邓明
前 Shopee 高级工程师,Beego PMC
6888 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
后端工程师的高阶面经
15
15
1.0x
00:00/00:00
登录|注册

15|数据迁移:如何在不停机的情况下保证迁移数据的一致性?

你好,我是大明。今天我们来聊聊数据迁移的问题。
我之前就注意到很多人的简历里面都会提到数据迁移方面的内容。比如:
重构老系统:使用新的表结构来存储数据;
单库拆分分库分表、分库分表扩容;
大表修改表结构定义。
但是在面试的时候,他们就是说不清楚数据迁移究竟应该怎么做,又或者说自己是停机迁移数据的。
这就是小看了数据迁移这个面试点。数据迁移其实是一个很能够综合体现你设计复杂方案解决棘手问题的点,它能进一步凸显你在数据库方面的积累,所以千万不能忽视。今天我就给你展示一个非常全面的不停机数据迁移的方案。

数据备份工具

这里我先来介绍一下 MySQL 上常用的两款数据备份工具:mysqldump 和 XtraBackup。
mysqldump:一个用于备份和恢复 MySQL 数据库的命令行工具。它允许用户导出 MySQL 数据库的结构、数据以及表之间的关系,以便在数据库发生问题时进行恢复。它是一个逻辑备份工具,导出的内容是一条条 SQL。
XtraBackup:它使用了 InnoDB 存储引擎的数据备份技术,支持增量备份和恢复,并且支持多主机备份和恢复。它是一个物理备份工具,相当于直接复制 InnoDB 的底层存储文件。
如果你使用的不是 MySQL,可以自己收集一下你使用的数据库的工具。要注意分析这些工具的优缺点,尤其是导入导出速度以及可行的优化手段。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了在不停机的情况下如何保证数据迁移的一致性,并介绍了MySQL上常用的数据备份工具、innodb_autoinc_lock_mode参数对主键生成策略的影响、面试准备建议以及全面的不停机数据迁移方案。文章还重点讨论了初始化目标表数据和第一次校验与修复的具体操作。此外,还提到了利用binlog进行触发校验和修复的方案,以及切换双写顺序和保持增量校验和修复的重要性。整体而言,本文内容涵盖了数据迁移的技术细节和面试准备建议,对读者快速了解数据迁移的一致性保证具有指导意义。文章内容丰富,涵盖了技术细节和实用建议,适合需要深入了解数据迁移技术的读者阅读。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《后端工程师的高阶面经》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(22)

  • 最新
  • 精选
  • Johar
    1.由于目标表没有数据需要全量同步源表数据,会占用源库的资源,可能影响性能,此外,在进行检验恢复数据时,需要切换目标表为主库,才能写目标表。 2.可以,但是不好确认目标库数据是否已经入库,同时插入可能存在冲突,考虑这种情况,可以使用消息总线的延时队列,另外在双写目标库时使用insert into ignore进行写入。

    作者回复: 赞! 而且第二个问题还要考虑数据覆盖的问题,所以不怎么适合。

    2023-07-20归属地:重庆
    3
  • peter
    请教老师几个问题: Q1:导出源表时,截止点怎么定?数据一直在写入,在哪一行停止导出? Q2:假设表中有一百万行数据,导出到目的表后,需要校验数据的正确性吗? 怎么校验?逐行对比,而且每一行都对比每一列吗? Q3:标记位是业务代码中设置的吗?还是MySQL中设置的? Q4:Insert语句怎么拿到主键?Insert执行后返回0或1,表示插入是否成功,也没有返回主键啊。 Q5:切换双写部分的第一个图,没有目标表,可能是个笔误。

    作者回复: 1. 你不需要关心截止点。你只需要在导入数据之后,找到每张表对应的最后更新时间,就可以认为是那个截止点。 2. 严格做法就是逐行比对。有些公司会抽样比对,但是抽样比对我个人认为效果很差。比如说你一千万行数据,出错几率是万分之一,你抽样是百分之一,你发现错误的几率,也就是百分之一。就是执行时间会很长,我们之前逐行比对,有执行过好几天。 3. 业务代码管理,MySQL 没有感知。 4. 你可以拿到 last insert id。这是 mysql 协议规定的。但是你用的 ORM 框架可能屏蔽了,所以你需要找找。 5. 感谢提醒,我们修复一下。

    2023-07-19归属地:北京
    2
  • sheep
    回答课后问题: 1. 初始化时目标表数据为空,作为源表的一个从库的话,同步过程中会占用源库的资源,影响性能。另外从库一般只提供读功能,此时要实现双写的话,就得把从库readonly=true关闭,另外此时支持从库支持写入后,从库同步应用主库过来的数据往往会有意想不到的问题(比如:主键冲突) 2. 可以,但得考虑的消费SQL时候,可能找不到对应数据了

    作者回复: 赞! 1. 要考虑的问题就是很多,主键冲突是一方面,还有就是主键过来一个 UPDATE,而我连初始数据都没有,就更加麻烦了。 2. 嗯,要考虑覆盖数据,以及乱序的问题。

    2023-10-24归属地:广东
    1
  • sheep
    1. “数据一致性问题”这里,"写入源表成功了,但是写入目标表失败了,该怎么办?那么最基础的回答就是不管"。这里一两条的话,确实可以通过后面修复机制去完善。但是这里一直失败的话,也不管么 2. "数据一致性问题"这里,"UPDATE xxx WHERE a = 123"什么情况下目标表会写入失败呢?另外为啥通过消息队列的处理方式没办法定位到源表的哪一行?不就是a = 123这一行么

    作者回复: 1. 一直失败就确实得管,这种时候多半是代码有问题,比如说我们之前目标表的列类型变了,导致源表的数据读到程序里面,再存储的时候,就发现数据库类型-Go类型-数据库类型这个转换崩了,只能是打补丁。 2. 因为当你收到消息的时候,原本 a= 123 的可能又被修改为 a = 124 了,所以你找不到。

    2023-10-17归属地:广东
    1
  • nadream
    什么时候停止第一次校验与修复?是在开启双写前吗?那停止第一次校验与修复步骤与开启双写步骤会不会存在时间差,导致这段时间内的数据丢失。

    作者回复: 好问题。第一次校验与修复,你随便跑一下就可以,后面还要持续运行增量校验,也可以设置增量校验的起始时间从你第一次校验跑完之后的时间点之后开始进行。 后续要是觉得不保险你就可以运行全量校验或者增量校验。

    2024-02-20归属地:浙江
  • nadream
    双写的时候,一个源表可能对应多个目标表,该怎么处理呢?

    作者回复: 只能追求最终一致性。也就是说,源表对应多个目标表,如果目标表在不同的数据库上(你没有办法用本地事务),那么就做好监控、告警以及数据校验和修复。实际上,它只是放大了不一致的风险。写单表还是写多表,监控、告警和数据校验与修复都少不了。

    2024-01-20归属地:浙江
  • nadream
    GORM ConnPool 替换这块有详细代码吗?看的不是很明白

    作者回复: 我给训练营上课写的一个,你可以参考。https://gitee.com/geektime-geekbang_admin/geektime-basic-go/blob/master/webook/pkg/gormx/connpool/doublewrite.go

    2024-01-20归属地:浙江
  • Geek_6c2524
    老师,想请教下,切换写入流程的时间节点是什么时候?比如,双写开始多久之后从——读写源表+写目标表,切换到读写目标表+写源表;多久之后,系统从双写切换到最终的单写到新目标表里?

    作者回复: 一般来说,在运行增量校验和修复一段时间之后,发现系统运行很平稳,就可以切换了。实际上这个过程也没想的那么高危,毕竟你可以再切换回来。实在不放心,就挑个半夜凌晨切换。

    2024-01-03归属地:上海
  • Geek_3d0fe8
    一下子切换到新系统太粗暴了,我们之前的做法是每个用户都打上状态的标记,决定读写走哪个系统

    作者回复: 其实你这就是用户粒度上的控制而已。也就是,每一个用户都可以单独控制,本质上没区别的。 我个人认为,没太大必要。在经过双写以目标表为准的阶段之后,直接切也没问题。 用户维度的控制,对于数据校验来说,很难搞,你得明确知道用源表数据,还是用目标表数据来校验和修复。

    2023-12-11归属地:广东
  • jCodePorter
    老师有没有Java版本实现双写的案例参考

    作者回复: 以前的工作代码写过,但是开源的没有。 有很多做法: 1. 利用 spring 的 AOP,拦截数据库操作,而后引入双写步骤 2. 利用连接池的扩展机制,把单写变成双写。比如说一般连接池都有类似于 Conn 的抽象,Conn 就会发起真的查询,那么你就可以扩展一个实现。

    2023-10-27归属地:河南
收起评论
显示
设置
留言
22
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部