【Mysql】quick review 分布式事务 存储 redo undo all-in-one

1 存储引擎

存储引擎主要有: 1. MyIsam , 2. InnoDB, 3. Memory, 4. Archive, 5. Federated

1.1 InnoDB(B+树):InnoDB 底层存储结构为B+树, B树的每个节点对应innodb的一个page,page大小是固定的, 一般设为 16k。其中非叶子节点只有键值,叶子节点包含完成数据。

  • 适用场景:
  • 经常更新的表,适合处理多重并发的更新请求。
  • 支持事务。
  • 可以从灾难中恢复(通过 bin-log 日志等)
  • 外键约束。只有他支持外键
  • 支持自动增加列属性 auto_increment。

1.2 MyIASM

  • MyIASM 是 MySQL 默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键, 因此当 INSERT(插入)或 UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。
  • MyISAM 执行读取操作的速度很快,而且不占用大量的内存和存储资源。在设计之初就预想数据组织 成有固定长度的记录,按顺序存储的。---ISAM 是一种静态索引结构。缺点是它不支持事务处理。

1.3 Memory

  • Memory(也叫 HEAP)堆内存:使用存在内存中的内容来创建表。每个 MEMORY 表只实际对应 一个磁盘文件。MEMORY 类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用 HASH 索引。但是一旦服务关闭,表中的数据就会丢失掉。 Memory 同时支持散列索引和 B 树索 引,B树索引可以使用部分查询和通配查询,也可以使用<,>和>=等操作符方便数据挖掘,散列索 引相等的比较快但是对于范围的比较慢很多。

 

2 索引(帮助 MySQL 高效获取数据的数据结构)

常见的查询算法,顺序查找,二分查找,二 叉排序树查找,哈希散列法,分块查找,平衡多路搜索树 B 树(B-tree)

  • 1. 唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。
  • 2. 为经常需要排序、分组和联合操作的字段建立索引:
  • 3.为常作为查询条件的字段建立索引。
  • 4.限制索引的数目: 越多的索引,会使更新表变得很浪费时间。 尽量使用数据量少的索引
  • 5.如果索引的值很长,那么查询的速度会受到影响。 尽量使用前缀来索引
  • 6.删除不再使用或者很少使用的索引
  • 7 . 最左前缀匹配原则,非常重要的原则。
  • 8. 尽量选择区分度高的列作为索引,区分度的公式是表示字段不重复的比例
  • 9 . 索引列不能参与计算,保持列“干净”:带函数的查询不参与索引。
  • 10. 尽量的扩展索引,不要新建索引。

 

3 数据库三范式

第一范式(1st NF -列都是不可再分)

第二范式(2nd NF-每个表只描述一件事情)

第三范式(3rd NF- 不存在对非主键列的传递依赖)顾客姓名依赖于非主键顾客编号

 

4 数据库事务

ACID

 

5 数据库并发策略

乐观锁和悲观锁以及时间戳

  • 时间戳原理:(每次读出来的时候,把该字 段也读出来,当写回去的时候,把该字段加 1,提交之前 ,跟数据库的该字段比较一次,如果比数 据库的值大的话,就允许保存,否则不允许保存)

6 数据库锁

行级锁,表级锁,页级锁

 

7 分库分表

垂直切分和水平切分两种

 

8 两阶段提交协议

  • 准备阶段:事务协调者(事务管理器)给每个参与者(资源管理器)发送 Prepare 消息,在本地执行事务,写本地的 redo 和 undo 日志,但不提交(先锁定资源)。
  • 提交阶段:如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息(根据undo日志回滚);否则, 发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)

经验:

磁盘的顺序写性能比内存的写性能差不了多少;

在数据库的世界里,数据从来都不重要,日志才是最重要的,有了日志就有了一切;

日志的重要性:先持久化日志的策略叫做Write Ahead Log,即预写日志;

 

how?

  • undo日志用于记录事务开始前的状态,用于事务失败时的回滚操作;redo日志记录事务执行后的状态,用来恢复未写入data file的已成功事务更新的数据。
  • 例如某一事务的事务序号为T1,其对数据X进行修改,设X的原值是5,修改后的值为15,那么
  • Undo日志为<T1, X, 5>;
  • Redo日志为<T1, X, 15>;

 

事务执行的各个阶段:

  • (1)写undo日志到log buffer;<T1, X, 5>;
  • (2)执行事务,并写redo日志到log buffer;<T1, X, 15>;
  • (3)如果innodb_flush_log_at_trx_commit=1,则将redo日志写到log file,并刷新落盘。
  • (4)提交事务。 // 如果innodb_flush_log_at_trx_commit=1并且数据commit后宕机,重启后一定可以根据redo 日志文件恢复数据;

why?

几种异常情况:

  • innodb_flush_log_at_trx_commit=2(innodb_flush_log_at_trx_commit和sync_binlog参数详解)时,将redo日志写入logfile后,为提升事务执行的性能,存储引擎并没有调用文件系统的sync操作,将日志落盘。如果此时宕机了,那么未落盘redo日志事务的数据是无法保证一致性的。
  • undo日志同样存在未落盘的情况,可能出现无法回滚的情况。

 

what?

  • 数据库数据存放的文件称为data file;日志文件称为log file;数据库数据是有缓存的,如果没有缓存,每次都写或者读物理disk,那性能就太低下了。数据库数据的缓存称为data buffer,日志(redo)缓存称为log buffer。

 

checkpoint:

  • checkpoint是为了定期将db buffer的内容刷新到data file。当遇到内存不足、db buffer已满等情况时,需要将db buffer中的内容/部分内容(特别是脏数据)转储到data file中。在转储时,会记录checkpoint发生的”时刻“。在故障回复时候,只需要redo/undo最近的一次checkpoint之后的操作。

 

8.2 两阶段提交协议缺点

 

  • 1 同步堵塞,所有的节点,获取资源最后释放;
  • 2 单点故障,协调者堵塞,所有参与者都堵塞,协调者重要性;
  • 3 数据不一致(脑裂问题),第二个阶段commit过程中,部分节点收到了请求,其余节点没有收到请求,就会出现脑裂问题;// 解决方案 ,补偿
  • 4 二阶段无法解决的问题(数据状态不确定)协调者再发出 commit 消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道 事务是否被已经提交。// 解决方案,类似zk 先执行同步,一半以上ack后,在通知参与者执行commit请求;

 

9 三阶段提交协议

改进点:

  • 1 引入超时机制。同时在协调者和参与者中都引入超时机制。
  • 2 在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。也就是说,除了引入超时机制之外,3PC 把 2PC 的准备阶段再次一分为二,这样三阶段 提交就有 CanCommit、PreCommit、DoCommit 三个阶段。

 

  • CanCommit 阶段:协调者向参与者发送 commit 请求,参与者如果可以提交就返回 Yes 响应,否则返回 No 响应。
  • PreCommit 阶段:协调者根据参与者的反应情况来决定是否可以继续进行,有以下两种可能。假如协调者从所有的 参与者获得的反馈都是 Yes 响应,那么就会执行事务的预执行(undo 和 redo 、redo log 数据落盘)。假如有任何一个参与者向协调者发送了No 响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。
  • doCommit 阶段:该阶段进行真正的事务提交,主要包含 1.协调者发送提交请求 2.参与者提交事务 3.参与者响应反馈( 事务提交完之后,向协调者发送 Ack 响应。)4.协调者确定完成事务。// 该阶段也有可能脑裂,数据不一致,数据状态不确定,但是概率比二阶段提交协议小很多;

 

10 柔性事务

  • CAP 理论以及 BASE 理论;
  • CAP:(一致性、可用性、分 区容忍性)
  • BASE:基本可用(Basically Available)、柔性状态(Soft State)、最终一致性 (Eventual Consistency)

柔性事务:两阶段型、补偿型(TCC,SAGA)、异步确保型、最大努力通知型

 

两阶段型2PC:就是分布式事务两阶段提交,对应技术上的 XA、JTA/JTS。这是分布式环境下事务处理的典型模式。

补偿型:TCC 型事务(Try/Confirm/Cancel)可以归为补偿型。TCC(Try-Confirm-Cancel) 实际上是服务化的两阶段提交协议,业务开发者需要实现这三个服务接口,第一阶段服务由业务代码编排来调用 Try 接口进行资源预留,所有参与者的 Try 接口都成功了,事务管理器会提交事务,并调用每个参与者的 Confirm 接口真正提交业务操作,否则调用每个参与者的 Cancel 接口回滚事务。

 

 

补偿型:SAGA事务

 

  • Saga 是一种补偿协议,在 Saga 模式下,分布式事务内有多个参与者,每一个参与者都是一个冲正补偿服务,需要用户根据业务场景实现其正向操作和逆向回滚操作。
  • 分布式事务执行过程中,依次执行各参与者的正向操作,如果所有正向操作均执行成功,那么分布式事务提交。如果任何一个正向操作执行失败,那么分布式事务会退回去执行前面各参与者的逆向回滚操作,回滚已提交的参与者,使分布式事务回到初始状态。
  • Saga 理论出自 Hector & Kenneth 1987发表的论文 Sagas。
  • Saga 正向服务与补偿服务也需要业务开发者实现

 

异步确保型: 通过将一系列同步的事务操作变为基于消息执行的异步操作, 避免了分布式事务中的同步阻塞操作的影响。

 

QMQ:(去哪儿网开源)

 

  1. begin tx 开启本地事务
  2. do work 执行业务操作
  3. insert message 向同实例消息库插入消息
  4. end tx 事务提交
  5. send message 网络向 server 发送消息
  6. reponse server 回应消息
  7. delete message 如果 server 回复成功则删除消息
  8. scan messages 补偿任务扫描未发送消息
  9. send message 补偿任务补偿消息
  10. delete messages 补偿任务删除补偿成功的消息

 

最大努力通知型(多次尝试): 这是分布式事务中要求最低的一种, 也可以通过消息中间件实现, 与前面异步确保型操作不 同的一点是, 在消息由 MQ Server 投递到消费者之后, 允许在达到最大重试次数之后正常结束事务。

 

 

 

 

 

 

 

 

 

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页