当前位置: 首页 > 科技观察

基于MySQLReplication的业务需求分析与改进

时间:2023-03-22 14:17:24 科技观察

今天和同事聊了一个问题。主要背景是有两个数据库需要向数据仓库系统传输数据。数据库的存储量虽然很大,但是需要传输的数据量不会太大,比如源库有100张表占用800G,但是只需要10张表进行数据传输,占用30G,所以在搭建数据源集市的时候,我们选择了多源复制模式,并把两个数据库组合起来进行对外交付,本质上是基于主从复制模式,但是更加灵活。最近,有一个新的需求打破了这种平静。现在需要添加几张新的数据表,并传输到数据仓库系统中。尴尬的是,由于历史原因,这些表都没有子表。单表数据量上亿。如果采用逻辑导出导入的方式,需要5个小时左右,最重要的是,它也带来了一系列的问题:1)这种数据导出导入的模式,导致数据后的数据难以完成导入完成。因为数据是从主数据库复制过来的,所以这个中间节点始终是一个动态的数据处理过程。从理论上讲,没有办法跟上数据。2)数据复制是基于GTID。什么时候做选择也是一个难题,比如另外10张表正在实时复制,新加入的表会生成新的GTID。在应用数据之前,会出现一系列的GTID,无法自动修复。图片再全面一点的话,其实是有这样一个结构的。默认是有数据的灾备节点,中间节点直接从主库复制数据。解决目前的问题,导出导入5小时显然不合理,比较理想的方式是基于物理数据的处理方式。一种是转移表空间,直接将ibd文件复制到中间节点,然后修复数据差异。此时,有两种修复差异的模式。一种是基于表中的增量时间,不够通用。第二种是更严谨的模式,就是修改数据的复制链接,基于从库的级联复制。这里的关键是在启用transfertablespace之前先停止slavereplication,让整个系统处于静止状态,这样可以保证数据的完整性。如果过程是复制ibd文件,大约30G的文件,30分钟左右就可以完成。复制完成后,可以继续保持基于从库的复制,也可以根据需要重新调整主库的GTID绑定。变化的最终状态与原来基本相同。第二种处理方式简单直接,就是要找到数据问题的根源。比如源库有100张表,占用800G,需要迁移10张表,占用30G。是否可以直接基于数据库级别和实例级别进行数据处理?Replication,等数据复制状态正常后,我们再清理那90张表。在处理过程中,我们会对一些可能的复制异常代码进行统一的过滤处理。这样我们的数据总是实时更新的,无论是状态数据的实时更新,还是日志类数据的实时更新,都可以灵活适配。同时,我们此时也可以针对多源复制做一些取舍。这种场景下,我觉得用起来意义不大。综上所述,数据复制是一个很好的数据交换,可以灵活适配和处理很多偏向于业务需求的数据逻辑。在这个过程中,基于系统层,物理处理方式远比逻辑处理效率高很多。