(image via https://pixabay.com/en/military-stealth-bomber-refueling-602729/ )mysql
在上篇文章 从 SQL Server 到 MySQL (一):异构数据库迁移 - Log4D 中,咱们给你们介绍了从 SQL Server 到 MySQL 异构数据库迁移的基本问题和全量解决方案。 全量方案能够知足一部分场景的需求,可是这个方案仍然是有缺陷的: 迁移过程当中须要停机,停机的时长和数据量相关。 对于核心业务来讲,停机就意味着损失。 好比用户中心的服务,以它的数据量来使用全量方案,会致使迁移过程当中停机若干个小时。 而一旦用户中心中止服务,几乎全部依赖于这个中央服务的系统都会停摆。git
能不能作到无缝的在线迁移呢?系统不须要或者只须要极短暂的停机? 做为有追求的技术人,咱们必定要想办法解决上面的问题。github
针对 Oracle 到 MySQL,市面上已经有比较成熟的解决方案 - alibaba 的 yugong 项目。 在解决 SQL Server 到 MySQL 在线迁移以前,咱们先研究一下 yugong 是如何作到 Oracle 的在线迁移。web
下图是 yugong 针对 Oracle 到 MySQL 的增量迁移流程:sql
这其中有四个步骤:数据库
Oracle 物化视图(Materialized View)是 Oracle 提供的一个机制。 一个物化视图就是主库在某一个时间点上的复制,能够理解为是这个时间点上的 Snapshot。 当主库的数据持续更新时,物化视图的更新能够经过独立的批量更新完成,称之为 refreshes
。 一批 refreshes
之间的变化,就对应到数据库的内容变化状况。 物化视图常常用来将主库的数据复制到从库,也经常在数据仓库用来缓存复杂查询。缓存
物化视图有多种配置方式,这里比较关心刷新方式和刷新时间。 刷新方式有三种:服务器
刷新机制有两种模式: Refresh-on-commit 和 Refresh-On-Demand。微信
Oracle 基于物化视图,就能够完成增量数据的获取,从而知足阿里的数据在线迁移。 将这个技术问题泛化一下,想作到在线增量迁移须要有哪些特性? 咱们获得以下结论(针对源数据库):数据结构
回到咱们面临的问题上来,SQL Server 是否有这个机制知足这三个特性呢? 答案是确定的,SQL Server 官方提供了 CDC 功能。
什么是 CDC? CDC 全称 Change Data Capture,设计目的就是用来解决增量数据的。 它是 SQL Server 2008 新增的特性, 在这以前只能使用 SQl Server 2005 中的 after insert
/ after delete
/ after update
Trigger 功能来得到数据变化。
CDC 的工做原理以下:
当数据库表发生变化时候,Capture process 会从 transaction log 里面获取数据变化, 而后将这些数据记录到 Change Table 里面。 有了这些数据,用户能够经过特定的 CDC 查询函数将这些变化数据查出来。
CDC 的核心数据就是那些 Change Table 了,这里咱们给你们看一下 Change Table 长什么样,能够有个直观的认识。
经过如下的函数打开一张表(fruits)的 CDC 功能。
-- enable cdc for db
sys.sp_cdc_enable_db;
-- enable by table
EXEC sys.sp_cdc_enable_table @source_schema = N'dbo', @source_name = N'fruits', @role_name = NULL;
-- list cdc enabled table
SELECT name, is_cdc_enabled from sys.databases where is_cdc_enabled = 1;
复制代码
至此 CDC 功能已经开启,若是须要查看哪些表开启了 CDC 功能,可使用一下 SQL:
-- list cdc enabled table
SELECT name, is_cdc_enabled from sys.databases where is_cdc_enabled = 1;
复制代码
开启 CDC 会致使产生一张 Change Table 表 cdc.dbo_fruits_CT
,这张表的表结构如何呢?
.schema cdc.dbo_fruits_CT
name default nullable type length indexed
-------------- ------- -------- ------------ ------ -------
__$end_lsn null YES binary 10 NO
__$operation null NO int 4 NO
__$seqval null NO binary 10 NO
__$start_lsn null NO binary 10 YES
__$update_mask null YES varbinary 128 NO
id null YES int 4 NO
name null YES varchar(255) 255 NO
复制代码
这张表中以 __
开头的字段是 CDC 所记录的元数据,id
和 name
是 fruits 表的原始字段。 这意味着 CDC 的表结构和原始表结构是一一对应的。
接下来咱们作一些业务操做,让数据库的数据发生一些变化,而后查看 CDC 的 Change Table:
-- 1 step
DECLARE @begin_time datetime, @end_time datetime, @begin_lsn binary(10), @end_lsn binary(10);
-- 2 step
SET @begin_time = '2017-09-11 14:03:00.000';
SET @end_time = '2017-09-11 14:10:00.000';
-- 3 step
SELECT @begin_lsn = sys.fn_cdc_map_time_to_lsn('smallest greater than', @begin_time);
SELECT @end_lsn = sys.fn_cdc_map_time_to_lsn('largest less than or equal', @end_time);
-- 4 step
SELECT * FROM cdc.fn_cdc_get_all_changes_dbo_fruits(@begin_lsn, @end_lsn, 'all');
复制代码
这里的操做含义是:
查询出来的数据以下所示:
__$start_lsn __$end_lsn __$seqval __$operation __$update_mask id name
-------------------- ---------- -------------------- ------------ -------------- -- ------
0000dede0000019f001a null 0000dede0000019f0018 2 03 1 apple
0000dede000001ad0004 null 0000dede000001ad0003 2 03 2 apple2
0000dede000001ba0003 null 0000dede000001ba0002 3 02 2 apple2
0000dede000001ba0003 null 0000dede000001ba0002 4 02 2 apple3
0000dede000001c10003 null 0000dede000001c10002 2 03 3 apple4
0000dede000001cc0005 null 0000dede000001cc0002 1 03 3 apple4
复制代码
能够看到 Change Table 已经如实的记录了咱们操做内容,注意 __$operation
表明了数据库操做:
根据查出来的数据,咱们能够重现这段时间数据库的操做:
id
为 1 / 2 的两条数据id
为 2 的数据id
为 3 的数据id
为 3 的数据有了 CDC 这个利器,终于意味着咱们的方向是没有问题的,咱们终于稍稍吁了一口气。 但除了了解原理和使用方式,咱们还须要深刻了解 CDC 的工做机制,对其进行压测、调优, 了解其极限和边界,不然一旦线上出现不可控的状况,就会对业务带来巨大损失。
咱们先看看 CDC 的工做流程,就能够知道有哪些核心参数能够调整:
上图是 CDC Job 的工做流程:
maxscans
)maxtrans
pollinginterval
这三个参数平衡着 CDC 的服务器资源消耗、吞吐量和延迟, 根据具体场景,好比大字段,宽表,BLOB 表,能够调整从而达到知足业务须要。 他们的默认值以下:
maxscan
默认值 10maxtrans
默认值 500pollinginterval
默认值 5 秒掌握了可以调整的核心参数,咱们即将对 CDC 进行了多种形式的测试。 在压测以前,咱们还须要肯定关键的健康指标,这些指标有:
出于篇幅考虑,咱们没法将全部测试结果贴出来, 这里放一个在并发 30 下面插入一百万数据(随机数据)进行展现:
测试结论是,在默认的 CDC 参数下面:
CDC 的开启/关闭过程当中会致使若干个 Process Block, 大流量请求下面(15k TPS)过程会致使约 20 个左右 Process Block。 这个过程当中对服务器的 IO / CPU 无明显波动, 开启/关闭瞬间会带来 mssql.sql-statistics.sql-compilations 剧烈波动。 CDC 开启后,在大流量请求下面对 QPS / Page IO 无明显波动, 对服务器的 IO / CPU 也无明显波动, CDC 开启后能够在 16k TPS 下正常工做。
若是对性能不达标,官方有一些简单的优化指南:
OK,截目前位置,咱们已经具有了 CDC 这个工具,可是这仅仅提供了一种可能性, 咱们还须要一个工具将 CDC 的数据消费出来,并喂到 MySQL 里面去。
好在有 yugong。 Yugong 官方提供了 Oracle 到 MySQL 的封装,而且抽象了 Source / Target / SQL Tempalte 等接口, 咱们只要实现相关接口,就能够完成从 SQL Server 消费数据到 MySQL 了。
这里咱们不展开,我还会花专门的一篇文章讲如何在 yugong 上面进行开发。 能够提早剧透一下,咱们已经将支持 SQL Server 的 yugong 版本开源了。
数据库迁移这样的项目,咱们不只仅要保证单向从 SQL Server 到 MySQL 的写入, 同时要从 MySQL 写入 SQL Server。
这个流程一样考虑增量写入的要素:增量消费,延迟,幂等一致性。
MySQL 的 binlog 能够知足这三个要素,须要注意的是,MySQL binlog 有三种模式, Statement based,Row based 和 Mixed。只有 Row based 才能知足幂等一致性的要求。
确认理论上可行以后,咱们同样须要一个工具将 binlog 读取出来,而且将其转化为 SQL Server 能够消费的数据格式,而后写入 SQL Server。
咱们目光转到 alibaba 的另一个项目 Canal。 Canal 是阿里中间件团队提供的 binlog 增量订阅 & 消费组件。 之因此叫组件,是因为 Canal 提供了 Canal-Server 应用和 Canal Client Library, Canal 会模拟成一个 MySQL 实例,做为 Slave 链接到 Master 上面, 而后实时将 binlog 读取出来。 至于 binlog 读出以后想怎么使用,权看用户如何使用。
咱们基于 Canal 设计了一个简单的数据流,在 yugong 中增长了这么几个功能:
Canal Server 中的 binlog 只能作一次性消费, 内部实现是一个 Queue, 为了知足咱们能够重复消费数据的能力,咱们还额外设计了一个环节,将 Canal 的数据放到 Queue 中,在将来任意时间能够重复消费数据。 咱们选择了 Redis 做为这个 Queue,数据流以下。
数据库的迁移在去 Windows 中,是最不容得出错的环节。 应用是无状态的,出现问题能够经过回切较快地回滚。 但数据库的迁移就须要考虑周到,作好资源准备,发布流程, 故障预案处理。
考虑到多个事业部都须要经历这个一个过程,咱们项目组将每个步骤都固化下来, 造成了一个最佳实践。咱们的迁移步骤以下,供你们参考:
大阶段 | 阶段 | 事项 | 是否完成 | 负责人 | 耗时 | 开始时间 | 完成时间 | 备注 |
---|---|---|---|---|---|---|---|---|
白天 | 存量数据阶段 | 建立 MySQL 数据库,准备相关帐号资源 | DBA | |||||
开启 CDC | DBA | |||||||
从 Slave SQLServer dump 一份 snapshot 到 Backup SQL Server | DBA | |||||||
Backup SQL Server 消费数据, ETL 到 MySQL | DBA | |||||||
增量数据阶段 | 确认 ETL 数据已经消费完成,检查数据总条数 | DBA | ||||||
从 Slave SQLServer 开始消费 CDC 数据,持续写入 MySQL | DBA | |||||||
使用 yugong 检查一天内数据的一致性 | DBA | |||||||
检查不一致的数据,10 分钟以后人工进行检查,确认是 CDC 延迟带来的问题 | DBA | |||||||
检查数据总量条目 | DBA | |||||||
使用 yugong 对抽样表进行全量检查 | DBA | |||||||
凌晨 | 应用发布阶段 | 中止 SQL Server 的应用 | 技术经理 | |||||
检查没有链接进入 SQL Server | DBA | |||||||
使用 yugong 检查一天内数据的一致性 | DBA | |||||||
检查数据总量条目 | DBA | |||||||
启用基于 MySQL 的应用 | 运维 | |||||||
测试阶段 | 测试应用是否正常,回归全部功能 | QA | ||||||
(临时新增)测试 ReadOnly DB 的应用访问状况 | QA | |||||||
完成阶段 | 接入流量 | 运维 | ||||||
(可选)回滚阶段 | 发现问题,直接将应用切回 SQL Server | 运维 | ||||||
过后进行数据审计,进行新增数据补偿 | DBA | |||||||
(可选)回滚过程当中,使用 Canal 读取 binlog,并使用 Canal Client 重放到 SQL Server | DBA |
原文连接: https://blog.alswl.com/2018/05/sql-server-migration-2/
欢迎关注个人微信公众号:窥豹
3a1ff193cee606bd1e2ea554a16353ee