innodb 存储引擎核心特性详解
innodb引擎核心功能都是围绕事务进行工作的
事务特性:
事务是伴随着交易类业务出现的概念
MySQL事务遵循着 ACID 四大特点
A : 原子性 同一个事务中所有的语句必须是 同时成功或同时失败
C : 一致性 一个事务过程中的数据,在事务开始前,中,后都将保证一致性.
I : 隔离性 事务发生过程中操作的数据和其他事务进行隔离
D : 持久性 事务完成后 从内存落入到磁盘中
事务生命周期控制
标准事务控制语句:
begin; # 开启事务 后面写DML语句
DML DML语言 # 增删改查
commit; # 提交事务(修改后的数据写入磁盘中)
rollback; # 回滚 (放弃修改数据)
特殊语句:
auto_commit
# 自动提交事务 默认开启 自动结束上一个事务
有了它可理解为 一条命令就是开启了一个事务
隐式结束
原因:
- begin;开启事务后 没输入结束时 再输入一个begin 开启事务 就会自动结束上一个事务
- 使用了DDL语句也会直接结束这个事务
- 使用了DCL语句
- 锁定语句 (LOCK TABLES 和UNLOCK TABLES) 都会直接结束事务
隐式回滚
会话断开时自动触发 (exit kill 连接窗口关闭)
死锁 关机 宕机都会自动回滚
事务的ACID保证
了解名词:
redo 重做日志用来存储数据页的变化(修改的内容) 等信息
redo_buffer 日志缓冲区
undo 回滚日志
datafile city.ibd 所有数据的文件
data buffer pool 数据缓冲区 数据页(数据行和索引)
LSN : log seq no 日志序列号 数据和redo
脏页 未写入磁盘的内存中数据
CKPT 刷新内存脏页到磁盘中
TXID 每个事务开始时 会分配一个唯一事务编号
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.
在
begin
后 ,会立即分配一个TXID=tx_01
(标记).update
时,会将需要修改的数据页(dp_01
(数据页),LSN=101
),加载到data buffer
中IO线程,会进行dp_01数据页修改更新,并更新
LSN=102
(日志版本号)日志写线程,会将
dp_01
数据页的变化+LSN+TXID
存储到redo buffer
执行
commit
时,日志写线程会将redo buffer
信息写入redo log
日志文件中,基于WAL原则,在日志完全写入磁盘后,commit
命令才执行成功,(会将此日志打上commit
标记)假如此时宕机,内存脏页没有来得及写入磁盘,内存数据全部丢失
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;
种类:
- RU : 读未提交,可脏读,一般不允许出现.
- RC : 读已提交,可能出现幻读,可以防止脏读.有可能出现"不可重复读"和"幻读".
- RR(默认) : 可重复读,功能是防止"不可重复读"现象 ,利用的是undo的快照技术+GAP(间隙锁)+NextLock(下键锁)一同防止"幻读".
- SR : 可串行化,可以防止死锁,但是并发事务性能较差
各种隔离级别功能演示
在配置文件中添加
vim /etc/my.cnf
autocommit=0 # 关闭自动事务
transaction_isolation=read-uncommitted # 指定隔离级别