mysql扩展什么意思_Mysql扩展

概述

业务初期数据库设计大多采用单库单表的结构,随着业务发展QPS和数据量增长到一定瓶颈,单库单表的架构就支撑不住了,这时就要进行数据库层面的扩展。数据库的扩展可以分为如下场景:

读性能扩展

写性能扩展

分库分表

表结构扩展(大表DDL)

本篇文章只系统的介绍基于DB的方案。和其他中间件配合的方案,之后有可能也会系统写一篇。

读性能扩展

最基本的表设计指导思想:

业务需求决定表的字段

查询需求决定表的索引

90b323cf3f14?utm_campaign=haruki

数据库扩展-读性能扩展.jpg

业内常用的读扩展方案是主从架构。业务上,我们通常至少有两套系统:运营后台和C端应用。两者的查询维度一般不一样,这意味着要有两套不同的索引结构。而我们又不希望运营后台的请求影响到C端,所以数据要隔离。

所以,我们要搞两组slave。slave1用于处理C端读请求,假设C端的请求多以uid为查询条件,创建uid索引。slave2用于处理运营后台读请求,假设运营后台请求多以日期为查询条件,创建date索引。

这种方案既提高了读性能,也实现了请求互不影响,而且实现简单。缺点是不同组的slave存在着不同的索引,对于DBA来说存在一定的维护成本。又引入了主从延时的问题,参考我的另一篇文章Mysql主从延时。

写性能扩展

90b323cf3f14?utm_campaign=haruki

数据库扩展-写性能扩展.jpg

增加从库扩展读性能,很容易想到增加主库扩展写性能。数据库层面的负载均衡通常用LVS做,成本低,性能好。关于负载均衡,参考我的另一篇文章聊聊负载均衡。

双主同时对外提供服务,需要冗余全部数据。冗余数据,就会有数据不一致的问题。比如:master1生成一条id为3的数据,这条数据同步到master2之前,master2此时收到一个insert请求,也会生成一条id为3的数据。这时,就出现了双主id冲突的问题。这个问题的解决思路是保证双主生成的id不重复,方案有两种

数据库层解决方案。master1,master2设置不同的初始值,相同的步长。如图master1生成1,3,5,7。master2生成2,4,6,8。这种方案缺点是:两台机器配置不一样,会提高运维的复杂性。

应用层解决方案。主键有应用生成,采用全局id生成器来保证id不重复。

分库分表

表结构扩展(大表DDL)

DDL操作一定要在业务低峰期做!切记!切记!切记!

Online DDL原理

MySQL 的 DDL(Data Definition Language) 包括增减字段、增减索引等操作。在 MySQL 5.6 之前,MySQL 的 DDL 操作会按照原来的表复制一份,并做相应的修改,例如,对表 A 进行 DDL 的具体过程如下:

按照表 A 的定义新建一个表 B

对表 A 加 exclusive metadata lock

在表 B 上执行 DDL 指定的操作

将 A 中的数据拷贝到 B

释放 A 的 exclusive metadata lock

删除表 A

将表 B 重命名为 A

如果表 A 数据量比较大,拷贝到表 B 的过程会消耗大量时间,并占用额外的存储空间。此外,由于 DDL 操作占用了表 A 的exclusive metadata lock,所以表 A 上的 DDL 和 DML 都将阻塞无法提供服务。

MySQL 5.6之后支持了Online DDL。大致过程如下:

按照表 A 的定义新建一个表 B

对表 A 加 exclusive metadata lock

生成rows_log,用于记录期间发生的DML

将exclusive metadata lock 降级为shared

在表 B 上执行 DDL 指定的操作

将 A 中的数据拷贝到 B

将rows_log应用到表B

将表A的shared metadata lock 升级为exclusive

如果前两步之间又有新的数据产生,再次应用row_log的数据到表B

释放表A的exclusive metadata lock

删除表 A

将表 B 重命名为 A

可以看出Online DDL和DDL原理的区别主要在rows_log和metadata lock的降级,这保证了这个过程中最耗时的部分-复制表数据是允许DML操作的。这也是Online的由来。

Online DDL用法

ALTER TABLE tbl_name ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE;

ALGORITHM=INPLACE 表示执行DDL的过程中server和engine间不发生表copy,过程中允许并发执行DML(INPLACE表的copy是在engine内部执行的,不需要像COPY一样占用大量的磁盘I/O和CPU,减少了数据库负载)。

LOCK=NONE 表示对 DML 操作不加锁,DDL 过程中允许所有的 DML 操作。此外还有 EXCLUSIVE(持有排它锁,阻塞所有的请求,适用于需要尽快完成DDL或者服务库空闲的场景)、SHARED(允许SELECT,但是阻塞INSERT UPDATE DELETE,适用于数据仓库等可以允许数据写入延迟的场景)和 DEFAULT(根据DDL的类型,在保证最大并发的原则下来选择LOCK的取值)

不过并不是所有的 DDL 操作都能用 INPLACE 的方式执行,具体的支持情况可以在 Mysql5.7官方文档中查看。

90b323cf3f14?utm_campaign=haruki

mysql online ddl.png

业界也有开源的成熟的大表DDL工具:gh-ost

注意:Mysql写锁优先于读锁。Online DDL可能存在如下问题。

sessionA

select * from A where id =1;

sessionB

select * from A where id =1;

sessionC online ddl

sessionD

select * from A where id =1;

假如sessionA和sessionB还未提交时,开始online ddl,也就是sessionC。由于sessionA和sessionB持有 shared metadata lock。sessionC申请 exclusive metadata lock会被阻塞。之后sessionD开始,由于Mysql写锁优先于读锁,所以sessionD获取shared metadata lock的请求也会阻塞,直到sessionA, sessionB执行完,sessionC获得exclusive metadata lock,之后释放exclusive metadata lock。

这个问题准确来说不是Online DDL的问题,读写锁的实现机制很多都有这个问题。写下来是为了提醒读者注意。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值