拆库中的数据同步漫谈

拆库中的数据同步漫谈

唯有不便的就是变化,这是我信仰的一句自己的creation。当自己熟悉的领域被更替,自己会显得内心焦虑和无助,可这改变不了什么,改变自己,改变自己脑子里的东西,以适应变化,或许是无奈,也只有这样才能生存。

话归正路,拆库,每个项目由小变大,都要有这个过程,什么横向切分,什么纵向切分,这样的文章多的是。今天想说的是,数据库拆分后的数据同步问题,这是横在拆库面前的一座山。

说道拆库和数据同步,又可以分为,同种数据库的拆库,和异种数据库的数据同步。这里如果仅仅依靠数据库自己的数据同步方式,那就比较惨了,无论是SQL SERVER REPLICAITON, 还是 MYSQL 的 canal (现在叫OTTER),还是ORACLE 使用的流复制, 或者PG 的 postgres_fdw,等等这都有一个问题,就是单单依靠数据库的复制方式,要不比较死,要不不靠谱。

为什么这么说,依靠数据流的复制,你要考虑,是不是有字段可以不复制,目的地表是不是只读的模式,是否可以更改,更改后还能继续复制吗,以及如果DDL 的操作,复制是不是要中断等等,问题。

所以在拆库时,系统架构师是很少给出通过数据库,或表级别的简单的复制,如果给出这个方法,也是基于,比如这个表就是一个基础表,不经常变换,只能数据分发,不能直接对其修改等等多种限制。

好像说道这里拆库和DBA 越走越远了,是吗? 如何保证程序能捕获到每个表里面每次 DML 的操作,并且如果变换就进行数据的通知,这方法不应该是DBA 提出,或者至少和开发商议的吗。我们可以任务,这样的方法就是程序对你数据库数据捕获的接口,所以工作还的往下做,千万别说,I am  done.

首先,要解决的就是第一个问题,如何判断一行的数据的 DML 变化,在任何时刻。有人说TRIGGER, OK 是的,这可以,建立一个字段,你在UPDATE 这个行时,在这一行附加字段上进行一些改变,可这是一个好方法吗,个人觉得 NO,这绝对不是一个好方法,尤其在当下,TRIGGER 在各种强大的程序员使用的程序的基础上,已经属于鸡肋和对程序稳定性的一种挑战。

以下的方法,要做到几点,1 节省开发人员的时间和经历,让其更关注于应用而不是底层的设计和架构,如果你有几百人的开发团队,并且有底层设计的开发人员,第一点当我没说。 2 稳定并且容易去实现

1 SQL SERVER 如何实现

在SQL SERVER里面已经有特殊的设计来支持此操作,以下均为假设

1 我们在系统里面有一个表test ,里面有两个字段,请见下图

拆库中的数据同步漫谈

2 假设KEY1 是主键(聚簇索引必须),我们开始给表里面添加一条数据

INSERT INTO test VALUES (1, 'test'); 

3 我们利用SQL SERVER 本身的特性来查看着一行的 checksum

拆库中的数据同步漫谈

4 好了,我们继续,我修改一个值

拆库中的数据同步漫谈

4 我们可以清晰的看到,在将字段改为大写后,再次检查checksum,值已经变化了。

由此我们可以判断,这一行的值变化了。

说完,到这里大家可能还是迷糊,到底在程序里面怎么应用,才能做到,拆库的时候,通过程序来将表的数据进行同步。  我们来捋一捋

1   假设,表里面已经有数据,这是难点,(插入数据在进行数据分发这个不难)这里就不说了),如何判断数据一行里面有任何值得变化,并且传送到另外一个库的,另一个表。

2  程序接收到对一行值得变动请求,修改(此时要获取表的主键,以及对当前行进行一个 binary_checksum)然后可以记录到自己的程序的缓存中,并且将这些记录到数据库里面(这里建议异构数据库记录,不要在自己的数据库记录,压力太大,我们可以使用 MONGODB 来记录,或者文本(不推荐,原因和简单,这里不说了,当然也可以用更时髦的时序数据库来记录(SORRY 还没看这个最近崛起的数据库新类型)),

作为一个保障。

3 程序接收到了数据修改的回执,ack

4 马上在进行一个 binary_checksum, 对这一行(你已经有了主键,那这还不是手拿把攥)

5  获得了这一行的值的确是变动了,马上将这个值,复制到另一个数据库的表里面,通过程序的手段。

这里有几个问题

1 我们是否需要对整个行进行一个判断,NO NO NO ,没有必要,浪费计算(CPU),我们只需要对改变值得字段进行 CHECKSUM 即可,当然如果更新的字段多过整行的百分之60,那还是去 * 吧,当时一定不要把类型

varchar(8000), 4000,这样的字段也去checksum ,  那的确是不怎么美好的一件事。

2 这个准确吗,准确,但是有禁忌, 游标,IMAGE, TEST,XML 类型的数据 NO NO NO ,不可以这样做,其实和上面的不美好有异曲同工之妙。

3 这个算法是什么,是MD5 的算法

——————————————————————————————

这是方法其一,还有一种程序员(使用SQL SERVER)程序员经常使用的一种数据类型,也可以做这件事,当然过程可能和上面不打一样,这里BAIDU 里面都是,就不说了。

——————————————————————————————

以此类推,ORACLE 数据库 我们可以使用 ora_hash 或者其他hash方法,

Postgresql 使用 lead  lag (具体方法和上面的不一样),来解决,

MYSQL 使用 MD5()或者   SHA1 等等来解决。

一通百通。

——————————————————————————————

但以上的方法的缺点也显而易见,就是你可千万别是一个每天访问量超高的网站,那是不大合适的。那还是要用物理的数据复制的方法来搞吧

以上方法细节上还需要完善,仅仅是一个通用的方案。

——————————————————————————————

拆库中的数据同步漫谈

最近看了一下 MYSQL8.0 的新功能,有一项让我感到,呵呵其中有一项叫做,option to disallow tables without primary keys 

OMG  OMG  OMG ,好了重要的事情的说三遍,这是什么鬼,ORACLE 终于要培养一个,能和自己竞争的数据库,另外 MYSQL 8.0 将有近百项的关键性的更新,也就是如此更新后,我们看到的是 一个 O_MYSQL,O记得MYSQL,在某些情形下以前可以说,ORACLE 到 MYSQL 的程序迁移是对 程序员的 极大考验和 程序员等级的考级, 而现在,MYSQL 8.0 将彻底降低对程序员 DBA 在MYSQL 使用上的考验,应该是一次地震基本的更新和观念的改变。 或许不会那么快,但已经来了。

拆库中的数据同步漫谈

上次没有说清楚的国产数据库,DM目前最新的版本要上8 类似 ORACLE 12C 的产品等级,在2017 年,某省国家电网就开始使用国产数据库了

拆库中的数据同步漫谈

拆库中的数据同步漫谈

从上看,ORACLE 在国有项目的占比未来不会越来越高,

1 费用,费用,费用,电信,电网,逐年降低成本,尤其在当前国家反腐倡廉的高压下,国有项目使用ORACLE 数据库,给返点回扣的事情会越来越少,国产的数据库在国有项目中如果能稳定运行,那铺开的速度会更快,节省成本,领导的在任的“丰功伟绩”。 当然还有美国的TRUMP 时不时的来一把坑害ORACLE。 

拆库中的数据同步漫谈

2 民企,私企,成本的原因,如果使用数据量不够大的情况下,大量已经使用MYSQL  来替换ORACLE ,关键还是成本,

3 PG 数据库开源数据库的使用率在提高,摆脱大数据量,复杂的SQL 离不开ORACLE 的现状

4  其他数据库类型的围追堵截  (尤其分布式数据库的崛起,ORACLE 不是分布式数据库)

借用“金拱门”的广告,选择更多,欢乐更多,无论程序员,还是架构师,千万别再一棵树上吊死。(当然在拆库数据同步的方式上,其实也是条条大路通长安,今天仅仅说了其中一个方案点)

拆库中的数据同步漫谈