MySQL:硬盘在24 * 7工作中罢工了,我该怎么办?

作者:媒体转发 时间:2019-06-03 21:08

字号

MySQL:硬盘在24 * 7工作中罢工了,我该怎么办?

虽然他们不承认, 但我还是这个系统的核心, 因为我保存着这个系统最最重要的东西:数据。

为了能让Tomcat他们访问, 我提供了几十个数据库连接——不能提供更多了,因为每个连接都要耗费我不少资源。

这些天Tomcat他们实在不像话,数据库读写的请求像大海的波涛一样汹涌澎湃,不断向我袭来。

996是别想了, 24*7才是残酷人生。

我没办法, 只好拼命地压榨硬盘,看着他的磁头在光滑的盘片上滑来滑去,寻找磁道,定位扇区,读取数据。这小伙子挺不错的, 任劳任怨,但是就是太慢,居然比内存慢几千倍。

很快,连硬盘也招架不住了,他对我说:“MySQL大哥,再这样下去我就要坏掉了。”

果然,没过几天,硬盘病倒了,系统崩溃了。

读写分离

第二天我一觉醒来,就发现系统重启了,但是有点不对劲,这Tomcat发来的SQL怎么这么少啊!还都是些Insert, Update, Delete !

硬盘对我说:“你还不知道吧,昨天晚上我们的主人张大胖做了个数据库的读写分离!”

“读写分离?”

“是啊, 张大胖统计了一下, 我们读和写的比例大概是20:1, 非常适合读写分离,简单来说,就是建立多个数据库,你是主库,主要负责写,还有两个从库,主要负责读。这样我们就没有多少压力了。”

MySQL:硬盘在24 * 7工作中罢工了,我该怎么办?

“我这里存了这么多数据, 怎么复制给另外两个小弟呢?” 我问道。

“这你不用担心,张大胖昨天已经给你做了一个快照,他把快照已经复制到了那两个小弟那里。接下来你只需要把今天早上产生的新的数据发过去就行了。”

基于SQL语句的复制

正在这个时候,那个叫旺财的小弟给我打招呼了: “大哥,你把你那里的执行过的Insert, Update, Delete这样的SQL语句都记录下来,然后发给我和小强,我们俩要这些SQL在我们自己的数据库上'重放'一下!”

MySQL:硬盘在24 * 7工作中罢工了,我该怎么办?

我看了一下自己的配置,果然如此,我只需要把SQL语句发过去就OK了。

有了两个小弟的承接读操作,我的工作大大减轻,又可以和硬盘喝茶聊天了。

可是没多久,Tomcat气冲冲地来质问我:“你们怎么搞的,数据出现不一致了,Order表, rand_num那一列!”

这是怎么回事? 我可是把所有的SQL语句都发给旺财和小强执行了啊,怎么会不一致?

我们三个不敢怠慢, 赶紧翻看最近执行的SQL, 尤其是更新Order表, rand_num列相关的。

终于发现了罪魁祸首,就是这个函数: RAND() , 它会返回一个随机数, 经过处理后,更新到rand_num这一列。

在不同的数据库执行,这个函数返回的值也就不同,这就会导致我们的数据不一致了。

我感到非常羞愧,因为数据的一致性是我们数据库家族最引以为豪的特性。 在单机的时候,我们自己就可以通过事务来保证了。 但是一旦有多个数据库,形成了分布式的环境,想让大家都保持一致,怎么会这么麻烦?

我们只好请张大胖手工把数据改成一致的, 然后再想新的办法。

基于行的复制

小强说道:“大哥,我提议一个新方法,以后你别记录SQL了,你只记录SQL的所影响的行和相关的值,然后把这些日志发给我们,例如:

对于Insert, 记录下所有列的新值。

对于Delete,记录下到底是哪一行被删除(用主键来标识)

对于Update,记录下哪一行被更新(用主键来标识),以及被更新的列和新值

有了这些日志,我们就可以清楚地知道你那边到底发生了什么变化,我们把这些日志应用到我们的数据库上就可以了!”

鉴于上一次的教训,这次我们仔细分析各种例外情况,确保没有问题才正式采用。

我,旺财和小强通力合作,新的复制方式工作得很好。直到有一天我们遇到了一个Update语句:

update xxx set flag = 0; 

这个语句一下子更新了几十万条数据。 在之前使用基于SQL的复制时,记录下这一条语句就行了。 用现在的方式,得记录几十万条数据,这太要命了!

怎么办? 退回到原来的“基于SQL的复制”,肯定不行!

要不默认用SQL复制? 如果SQL执行结果“不确定”,例如有RAND()函数调用,那我们就使用语句复制。

这是一种混合的模式,虽然麻烦,但也只能如此了。

数据延迟

责任编辑:CQITer新闻报料:400-888-8888   本站原创,未经授权不得转载
关键词 >>MySQL 硬盘 数据库
继续阅读
热新闻
推荐
关于我们联系我们免责声明隐私政策 友情链接