mysql分表之后如何平滑上线详解

 更新时间:2021年10月29日 08:59:29   作者:程序员小饭  
项目开发中,我们的数据库数据越来越大,随之而来的是单个表中数据太多,以至于查询书读变慢,当出现这种情况时,我们可以考虑分表,这篇文章主要给大家介绍了关于mysql分表之后如何平滑上线的相关资料,需要的朋友可以参考下

分表的目的

项目开发中,我们的数据库数据越来越大,随之而来的是单个表中数据太多。以至于查询数据变慢,而且由于表的锁机制导致应用操作也受到严重影响,出现了数据库性能瓶颈。

当出现这种情况时,我们可以考虑分表,即将单个数据库表进行拆分,拆分成多个数据表,然后用户访问的时候,根据一定的算法,让用户访问不同的表,这样数据分散到多个数据表中,减少了单个数据表的访问压力。提升了数据库访问性能。

举个栗子

比如咱们最常见的用户表(user表)

id user_id 其他字段
主键id 用户id 其他字段

咱们一般都会用user_id去查询对应的用户信息,但是随着业务的增长,这张表会越来越大,甚至上亿,严重影响了查询性能。 所以咱们就会对这张表进行分表处理,分到多张表减小查询压力

分表策略

以分10张表为例(具体分多少张表 根据实际情况来估算) 首先咱们建10张表 user1、user2、user3。。。。。user10

一般情况下,我们都会用作为索引的字段(user_id)进行取模处理。想分多少张表,就按照多少取模,比如这个case就是10

$table_name = $user_id % 10;

按照上面的取模公式

  • user_id为1295的会落在user5里面
  • user_id为8634的会落在user4里面
  • 。。。。。。。

「每次CURD根据上面查找表的策略进行就行了」,这个问题不大,我们暂且先不多说。

已经上线的运行中的表怎么办?

其实上面的方法大家应该都知道怎么用,但是有个问题,已经上线了的表怎么办?那张表的数据在线上是一直被查找或者改变的。如何能够进行平滑的分表,并且让用户无感知呢?

方法1

直接上线,提前写个脚本,脚本内容是把旧表(user)的数据同步到user1表到user10表,一上线了赶紧执行

这种方法明显是行不通的,主要是存在以下问题

  • 如果执行过程中脚本有问题怎么办?代码全部回滚?
  • 脚本把把旧表(user)的数据同步到user1表到user10表,这个脚本得执行多久? 如果是1个小时,那么这段时间线上和这张表相关的业务都是不正常的

这显然是行不通的,对线上影响很大。

方法2

先写个同步数据的脚本,脚本内容是把旧表(user)的数据同步到user1表到user10表,脚本同步完了再上线。

这个方法看起来友好了一些,不过也存在一些问题。

  • 脚本同步完,立即上线,这两件事之间是有一些时间差的,这个时间差中线上表可能有一些改动,这些改动怎么办?

「以上两种方法看起来貌似都行不通,所以看来得来点不一样的了。咱们直接看结论。」

步骤1 上线双写

首先咱们把双写上线了,什么意思呢?比如user_id=123,对于增加,删除,修改操作来说,咱们既操作user表,也操作user_id=123对应的user3表。

function modify($user_id){  //包含增加,删除,修改操作
  modify_user();  //modify user表
  $table_name = $user_id % 10;
  modify_user($table_name) //modify对应的分表
}

因为查询的部分还是在user表中查询的,所以上面的操作对线上用户是无任何影响的。

步骤2 全量同步

写一个全量同步user表到user1-user10的表,最好找个低峰期执行脚本,以防万一影响user表的查询

这一步执行之后,因为咱们之前上线了双写(见步骤1),所以user表和user1-user10表之间的数据已经是完全一致的了。

步骤3 查询新表数据

将查询的部分改到user1-user10

因为前面两个步骤咱们已经保证了user表和各个分表之间的数据完全一致性,所以直接把查询的部分改掉是没有任何问题的

如果按照以上步骤执行,那么对线上的数据是没有任何影响的,而且我们线上就是这么操作了,经过了多次实践确保不会出问题,放心使用即可。

总结

到此这篇关于mysql分表之后如何平滑上线的文章就介绍到这了,更多相关mysql分表平滑上线内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Mysql连接数设置和获取的方法

    Mysql连接数设置和获取的方法

    这篇文章主要介绍了Mysql连接数设置和获取的方法,帮助大家更好的理解和使用MySQL,感兴趣的朋友可以了解下
    2021-01-01
  • 详解MySQL单列索引和联合索引

    详解MySQL单列索引和联合索引

    联合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏进行排序,然后按名字对有相同姓氏的人进行排序,这篇文章主要介绍了MySQL单列索引和联合索引,需要的朋友可以参考下
    2022-09-09
  • MySQL中关于datetime、date、time、str之间的转化与比较

    MySQL中关于datetime、date、time、str之间的转化与比较

    这篇文章主要介绍了MySQL中关于datetime、date、time、str之间的转化与比较,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • MySQL OOM(内存溢出)的解决思路

    MySQL OOM(内存溢出)的解决思路

    这篇文章主要介绍了MySQL OOM(内存溢出)的解决思路,文中讲解非常细致,帮助大家在学习工作中解决内存溢出的问题,感兴趣的朋友可以了解下
    2020-08-08
  • mysql初始化命令mysqld --initialize参数说明小结

    mysql初始化命令mysqld --initialize参数说明小结

    本文主要介绍了mysql初始化命令mysqld --initialize参数说明小结,文中通过图表代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • 不卸载原有mysql直接安装mysql8.0

    不卸载原有mysql直接安装mysql8.0

    本文主要介绍了不卸载原有mysql直接安装mysql8.0,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • mysql如何对String类型的数字值排序

    mysql如何对String类型的数字值排序

    这篇文章主要介绍了mysql如何对String类型的数字值排序问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 分享15个Mysql索引失效的场景

    分享15个Mysql索引失效的场景

    这篇文章主要介绍了分享15个Mysql索引失效的场景,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • C3P0连接池+MySQL的配置及wait_timeout问题的解决方法

    C3P0连接池+MySQL的配置及wait_timeout问题的解决方法

    这篇文章主要介绍了C3P0连接池+MySQL的配置及wait_timeout问题的解决方法,本文介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • Mysql大数据量查询优化思路详析

    Mysql大数据量查询优化思路详析

    这篇文章主要介绍了Mysql大数据量查询优化思路,Mysql大表查询优化,理论上千万级别以下的数据量Mysql单表查询性能处理都是可以的。下文我们就来看看具体得思路解析
    2022-01-01

最新评论