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


Posted in MySQL onNovember 01, 2021

分表的目的

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

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

举个栗子

比如咱们最常见的用户表(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 infobright的安装步骤
Apr 07 MySQL
MySQL 视图(View)原理解析
May 19 MySQL
MySQL库表名大小写的选择
Jun 05 MySQL
mysq启动失败问题及场景分析
Jul 15 MySQL
SQL实现LeetCode(180.连续的数字)
Aug 04 MySQL
mysql如何能有效防止删库跑路
Oct 05 MySQL
深入解析MySQL索引数据结构
Oct 16 MySQL
一文弄懂MySQL索引创建原则
Feb 28 MySQL
面试中老生常谈的MySQL问答集锦夯实基础
Mar 13 MySQL
MySQL如何快速创建800w条测试数据表
Mar 17 MySQL
了解MySQL查询语句执行过程(5大组件)
Aug 14 MySQL
MySQL中的 inner join 和 left join的区别解析(小结果集驱动大结果集)
May 08 MySQL
MySQL8.0升级的踩坑历险记
Nov 01 #MySQL
详细聊聊关于Mysql联合查询的那些事儿
Oct 24 #MySQL
mysql事务对效率的影响分析总结
Oct 24 #MySQL
mysql事务隔离级别详情
mysql主从复制的实现步骤
记一次Mysql不走日期字段索引的原因小结
Oct 24 #MySQL
Mysql关于数据库是否应该使用外键约束详解说明
Oct 24 #MySQL
You might like
一个自定义位数的php多用户计数器代码
2007/03/11 PHP
PHP通用检测函数集合
2011/02/08 PHP
PHP中iconv函数转码时截断字符问题的解决方法
2015/01/21 PHP
PHP实现获取毫秒时间戳的方法【使用microtime()函数】
2019/03/01 PHP
php+js实现的无刷新下载文件功能示例
2019/08/23 PHP
javascript 继承实现方法
2009/08/26 Javascript
JavaScript解析URL参数示例代码
2013/08/12 Javascript
js和html5实现手机端刮刮卡抽奖效果完美兼容android/IOS
2013/11/18 Javascript
Javascript基础教程之JavaScript语法
2015/01/18 Javascript
jquery读取xml文件实现省市县三级联动的方法
2015/05/29 Javascript
jquery插件bootstrapValidator表单验证详解
2016/12/15 Javascript
angular2模块和共享模块详解
2018/04/08 Javascript
JS动态插入脚本和插入引用外部链接脚本的方法
2018/05/21 Javascript
VUE DEMO之模拟登录个人中心页面之间数据传值实例
2019/10/31 Javascript
vue中音频wavesurfer.js的使用方法
2020/02/20 Vue.js
[03:07]【DOTA2亚洲邀请赛】我们,梦开始的地方
2017/03/07 DOTA
python网络编程之TCP通信实例和socketserver框架使用例子
2014/04/25 Python
Python中使用socket发送HTTP请求数据接收不完整问题解决方法
2015/02/04 Python
Python实现对excel文件列表值进行统计的方法
2015/07/25 Python
使用python爬虫获取黄金价格的核心代码
2018/06/13 Python
Python获取网段内ping通IP的方法
2019/01/31 Python
python flask解析json数据不完整的解决方法
2019/05/26 Python
Django之编辑时根据条件跳转回原页面的方法
2019/08/21 Python
纯CSS打造(无图像无js)的非常流行的讲话(语音)气泡效果
2012/12/28 HTML / CSS
html5教程实现Photoshop渐变色效果
2013/12/04 HTML / CSS
24个canvas基础知识小结
2014/12/17 HTML / CSS
HTML5中图片之间的缝隙完美解决方法
2017/07/07 HTML / CSS
健康监测猫砂:Pretty Litter
2017/05/25 全球购物
意大利消费电子产品购物网站:SLG Store
2019/12/26 全球购物
路德维希•贝克(LUDWIG BECK)中文官网:德国大型美妆百货
2020/09/19 全球购物
法人代表委托书
2014/04/04 职场文书
学习型家庭事迹材料
2014/12/20 职场文书
2015年第十五个全民国防教育日宣传活动方案
2015/05/06 职场文书
2016年校园社会综合治理宣传月活动总结
2016/03/16 职场文书
JavaScript数组reduce()方法的语法与实例解析
2021/07/07 Javascript
CSS中使用grid布局实现一套模板多种布局
2022/07/15 HTML / CSS