mysql复制原理
- master binlog
- slave
- IO thread,主动读,保存relay-log中
- sql thread,回放日志,解析执行sql
mysql复制类型
- 异步复制
- 半同步复制
- 半同步
- 无损半同步复制
mysql集群类型
- 从复制的角度
- 主从
- 双主
- mysql cluster
- 从功能上
- 主备
- 读写分离
- 分库分表
问题
- 高可用
- innodb cluster
- mysql只有主从,没有高可用
- innodb cluster
- 高可用套件,监控,自动选主
- MMM
- MHA
- 扩展性
- 读写分离
- 分库分表
- 分库:按表的业务关系拆分数据库
- 分表:
- 字段拆分
- 行拆分
- 主键生成策略
- UUID:单机无序
- SNOWFLAKE:单机无其他依赖,效率高,有序
- 64位:符号位+时间戳+机器号+序列号
- 服务器时间,如果不同或者调整可以就出问题,尤其是时钟回拨
- 改进的算法
- 固定长度改为变长,适应不同场景
- workId的获取,数据库,zk等
- 百度
- 美团:leaf
- 分片策略
- 范围
- hash:算法简单,数据均匀,缩扩容麻烦
- 改进: MD5均匀分布数据
- 一致性hash
- 缩扩容数据迁移小,只需要迁移部分数据
- hash环大小2^32
- ip%(2^32)=确定服务器位置
- 分布不均,数据倾斜
- 虚拟节点多插几个,比如每个ip搞10个节点
- hash(key)%(2^32)= 确定数据位置
- 数据位置在环上顺时针找到第一个服务器
- 分库分表中间件
- ShardingSphere
- Sharding jdbc 客户端代理,客户端直连数据库,性能高,用于应用
- Sharding proxy 服务端代理,客户端通过服务端代理访问,性能有损失,用于运维
- Sharding * 功能
- 数据分片
- 读写分离
- 弹性伸缩
- 分布式事务
- 控制台,权限和审计功能
- ShardingSphere
- 概念
- 表
- 逻辑表
- 真实表
- 绑定表:分片规则一致的主表和子表。
- 例如:t_order 表和 t_order_item 表,均按照 order_id 分片,则此两张表互为绑定表关系。
- 绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。
- 广播表:所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。
- 适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表。
- 分片键和分片算法
- hash
- 主键生成策略,
- 分布式事务
- XA两阶段事务,
- SEATA 柔性事务
- 表
TiDB
- TiDB Server:组成集群
- 连接:暴露 MySQL 协议的连接端口
- SQL解析:生成执行计划,不存数据
- PD (Placement Driver) Server:
- 信息:数据库定义和表结构,表与KV的映射
- 监控:Raft Group 的 Leader 会定期向 PD 汇报 Region状态
- 调度:
- 基本
- 副本不能多也不能少
- 副本需要分布在不同的物理机上
- 节点宕机或异常能够自动合理快速地进行容灾
- 进阶
- 维持整个集群的 Leader 分布均匀
- 维持每个节点的储存容量均匀
- 维持访问热点分布均匀
- 控制负载均衡的速度,避免影响在线服务
- 管理节点状态,包括手动上线/下线节点
- 手段:TiKV Region Raft Group
- 增加一个副本
- 删除一个副本
- 将 Leader 角色在一个 Raft Group 的不同副本之间 transfer(迁移)。
- 基本
- TiKV Server:
- 负责存储数据
- MVCC支持事务
- 分布式事务
- raft+Region支持分布式
- Leader 负责读/写,Follower 负责同步 Leader 发来的 Raft log
- RocksDB ,是KV存储引擎
- SQL执行过程
分布式事务
- 分布式与事务
- 横跨不同服务器,由多个本地事务组成
- 如无必要,不要引入分布式事务
- 分布式事务的典型场景
- 跨JVM进程:微服务,通过业务补偿解决
- 自动的补偿机制就是分布式事务。。。
- 跨数据库实例:
- 一个应用调用了多个库,不应该出现这样的情况,应该通过服务调用
- 数据库做了拆分,处于不同的数据库实例中
- 尽量避免这样的拆分,
- 通过绑定表这样的形式,比如订单库,都通过订单ID分片
- 但是客户级的处理就无法避免了
- 尽量避免这样的拆分,
- 跨JVM进程:微服务,通过业务补偿解决
- 解决方案
- 数据库维度和服务维度
- 两阶段提交
- XA 协议: 数据库视角的两阶段提交,性能原因不用,因为阻塞
- Saga:服务视角的两阶段提交,按逻辑依次调用服务,异常就补偿。因为提交了就不阻塞,但是不能保证隔离性
- 可靠消息最终一致性:依靠可靠消息驱动,变种的Sage
- TCC:应用层三阶段提交
- try:业务检查,资源预留
- confirm:业务处理
- cancel:业务回滚
- 业务侵入性,开发成本高,本身的业务需要做资源预留与隔离
- 实际使用: 金融场景中易于做资源预留的扣减模型。
- SEATA 柔性事务
- 支持TCC、SAGA 和 XA
- AT服务层的两阶段
- 优点
- 自动化
- 解析SQL,获取更新前和更新后镜像,插入到undo log表。
- 回滚使用undo log的更新前镜像
- 提交了数据库本地事务,不阻塞
- 自动化
- 缺点:整体效率不高,因为多查询两次,插入一次,一条数据库交互变成了4次
- AT结构
- TM (事务管理器):事务发起方,通过TC完成全局事务的开启,提交和回滚
- RM (资源管理器):事务参与者,上报TC,并配合TC完成本地事务提交和回滚
- TM 和 RM 以 jar 包的方式同业务应用一同部署
- TC (事务协调器):TC 是一个独立部署的服务
- 周期
- TM 要求 TC 开始一个全新的全局事务。
- TC 生成一个代表该全局事务的 XID,XID 贯穿于微服务的整个调用链。
- 作为该 XID 对应到的 TC 下的全局事务的一部分,RM 注册本地事务。
- TM 要求 TC 提交或回滚 XID 对应的全局事务。
- TC 驱动 XID 对应的全局事务下的所有分支事务完成提交或回滚。
- 优点
- 完整流程
- 一阶段:
- 解析SQL:update product set name = ‘GTS’ where name = ‘TXC’;
- 查询前镜像:根据解析得到的条件信息,生成查询语句,定位数据。
- select id, name, since from product where name = ‘TXC’;
- 执行业务SQL
- 查询后镜像:根据前镜像的结果,通过 主键 定位数据。
- select id, name, since from product where id = 1;
- 插入回滚日志:把前后镜像数据以及业务 SQL 相关的信息组成一条回滚日志记录,插入到 UNDO_LOG 表
中。 - 提交前,向 TC 注册分支:申请 product 表中,主键值等于 1 的记录的 全局锁 。
- 本地事务提交:业务数据的更新和前面步骤中生成的 UNDO LOG 一并提交。
- 将本地事务提交的结果上报给 TC
- 二阶段-回滚
- 收到 TC 的分支回滚请求,开启一个本地事务,执行如下操作。
- 通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。
- 数据校验:拿 UNDO LOG 中的后镜与当前数据进行比较,如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理,详细的说明在另外的文档中介绍。
- 根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句:
- update product set name = ‘TXC’ where id = 1;
- 提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC。
- 二阶段-提交
- 收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。
- 异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。
- 一阶段: