mysql存储引擎核心特性详解

innodb 存储引擎核心特性详解

innodb引擎核心功能都是围绕事务进行工作的

事务特性:

事务是伴随着交易类业务出现的概念
MySQL事务遵循着 ACID 四大特点

  1. A : 原子性 同一个事务中所有的语句必须是 同时成功或同时失败

  2. C : 一致性 一个事务过程中的数据,在事务开始前,中,后都将保证一致性.

  3. I : 隔离性 事务发生过程中操作的数据和其他事务进行隔离

  4. D : 持久性 事务完成后 从内存落入到磁盘中

事务生命周期控制

标准事务控制语句:

begin;      # 开启事务  后面写DML语句
DML DML语言  # 增删改查
commit;     # 提交事务(修改后的数据写入磁盘中)
rollback;   # 回滚    (放弃修改数据)

特殊语句:
auto_commit # 自动提交事务 默认开启 自动结束上一个事务

有了它可理解为 一条命令就是开启了一个事务

隐式结束
原因:

  1. begin;开启事务后 没输入结束时 再输入一个begin 开启事务 就会自动结束上一个事务
  2. 使用了DDL语句也会直接结束这个事务
  3. 使用了DCL语句
  4. 锁定语句 (LOCK TABLES 和UNLOCK TABLES) 都会直接结束事务
    隐式回滚
    会话断开时自动触发 (exit kill 连接窗口关闭)
    死锁 关机 宕机都会自动回滚

事务的ACID保证

了解名词:

  1. redo 重做日志用来存储数据页的变化(修改的内容) 等信息

  2. redo_buffer 日志缓冲区

  3. undo 回滚日志

  4. datafile city.ibd 所有数据的文件

  5. data buffer pool 数据缓冲区 数据页(数据行和索引)

  6. LSN : log seq no 日志序列号 数据和redo

  7. 脏页 未写入磁盘的内存中数据

  8. CKPT 刷新内存脏页到磁盘中

  9. TXID 每个事务开始时 会分配一个唯一事务编号

  10. WAL write ahead log 日志优先写

redo

用来记录数据页的变化 主要用来保证ACID中D的特性

文件路径为:
数据路径下的 ib_logfile0~n 轮询方式进行写入数据

redo 相关的内存 redobuffer
查看参数
show variables like ‘%log%’;
参数
innodb_log_file_size=128M # 控制每个文件大小
innodb_log_fies_in_group=3~5 个 # 控制个数
innodb_log_buffer_size # 设置redo内存空间大小 一般为 文件大小个数2~3
innodb_flush_log_at_trx_commit=1 # 控制redo什么时候往磁盘上写

redo 功能文字描述

MySQL : 在启动时,必须保证redo日志文件和数据文件LSN必须一致, 如果不一致就会触发CSR,最终保证一致
情况一:
我们做了一个事务,
begin;update;commit.

  1. begin后 ,会立即分配一个TXID=tx_01(标记).

  2. update时,会将需要修改的数据页(dp_01(数据页),LSN=101),加载到data buffer

  3. IO线程,会进行dp_01数据页修改更新,并更新LSN=102(日志版本号)

  4. 日志写线程,会将dp_01数据页的变化+LSN+TXID存储到redo buffer

  5. 执行commit时,日志写线程会将redo buffer信息写入redo log日志文件中,基于WAL原则,在日志完全写入磁盘后,commit命令才执行成功,(会将此日志打上commit标记)

  6. 假如此时宕机,内存脏页没有来得及写入磁盘,内存数据全部丢失

  7. MySQL再次重启时,必须要redo log和磁盘数据页的LSN是一致的.但是,此时dp_01,TXID=tx_01磁盘是LSN=101,dp_01,TXID=tx_01,redo log中是LSN=102

自动故障恢复(ACSR)

MySQL此时无法正常启动,MySQL触发CSR.在内存追平LSN号,触发ckpt(刷新脏页到磁盘),将内存数据页更新到磁盘,从而保证磁盘数据页和redo log LSN一值.这时MySQL正常启动

以上的工作过程,我们把它称之为基于 REDO 的"前滚操作"

补充:
MySQL redo具备预写入功能,刷写redo buffer到磁盘时, 满足已经提交的时候(innodb_flush_log_at_trx_commit=1 ),
会立即触发写入磁盘,一些未提交的的redo buffer日志,也会被连带着被刷写磁盘.
此时,redo log就会存在多种状态的事务日志.
怎么区分?
通过标签不同来区分此日志对应的事务是否提交.

undo 日志

作用和redo差不多 只不过记录用户的反操作
ACID 只要作用是A的原子性 CI也有一定的作用

快照功能

undo可以实现针对不同时间点版本快照.对MVCC提供功能保证.

锁功能

保证了ACID中I (隔离性) 的特性
innodb支持行锁 保证事务更新某行数据时 不会收到其他事务的影响

锁分类

主要分为
x锁 : 写入数据
s锁 : 读取数据
IX / IS锁 在获取s/x锁之前 先检查有没有IS / IX锁 如果没有 证明此表正在被使用 那么就不用继续向下检查行锁了
GAP锁 , Next-lock锁 : 为了解决RR(隔离级别) ,防止幻读

隔离级别

锁和隔离级别组成了 ACID的隔离性
隔离级别 影响的时读数据的时候(将数据从磁盘拿到内存中的过程) (增删改查过程)
查看锁级别
select @@tx_isolation;
种类:

  1. RU : 读未提交,可脏读,一般不允许出现.
  2. RC : 读已提交,可能出现幻读,可以防止脏读.有可能出现"不可重复读"和"幻读".
  3. RR(默认) : 可重复读,功能是防止"不可重复读"现象 ,利用的是undo的快照技术+GAP(间隙锁)+NextLock(下键锁)一同防止"幻读".
  4. SR : 可串行化,可以防止死锁,但是并发事务性能较差

各种隔离级别功能演示

在配置文件中添加

vim /etc/my.cnf 
autocommit=0            # 关闭自动事务
transaction_isolation=read-uncommitted  # 指定隔离级别

你可能感兴趣的:(mysql存储引擎核心特性详解)