05-innoDB核心特性

1.事务的核心特性(ACID)

A:atomicity:原子性 在一个事务工作单元中,所有标准事务语句(DML),要么全成功,要么全回滚(服务器突然宕机就会又这两种现象)

C (consistency):一致性 事务发生前,中,后都应该保证数据是始终一致状态。MySQL的各项功能的设计,都是最终要保证一致性。

I (isolation) :隔离性 MySQL 可以支持多事务并发工作的系统。某个事务工作的时候,不能受到其他事务的影响。

D (durability) :持久性   当事务提交(Commit命令执行成功后),此次事务操作的所有数据“落盘”,都要永久保存下去。不会因为数据实例发生故障,导致数据失效。

2.事务生命周期管理

(1) 标准事务控制语句
begin / start transaction; 开启事务
commit; 提交事务
rollback; 回滚事务

(2) 标准的事务语句: 
insert 
update 
delete 
select

例子: 
begin;
DML1
DML2
DML3
rollback ;

(3) 自动提交功能
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)
在autocommit=1的时候,没有加begin(没有显示的开启事务)。
在你执行dml语句时,会自动在这个DML之前加一个begin,

begin;   --> 自动
delete .....
commit;  --> 自动

begin;   --> 自动
update .....
commit;  --> 自动

应用场景: 
autocommit=1 ,一般适合于非交易类业务场景。
如果是交易类的业务:
方案1: 
    autocommit=0;  commit,手工提交才生效。
方案2: 
    autocommit=1; 
    每次想要发生事务型操作。
    begin 和 commit都手工操作。

设置方法: 
    (1)临时生效:
     mysql> set global autocommit=0;
     重新开启会话生效。
    (2)永久生效
     vim /etc/my.cnf 
     autocommit=0
     重启数据库生效。

(4)隐式事务控制
隐式提交: 
    1. 设置了autocommit=1
    2. DDL,DCL等非DML语句时,会触发隐式提交
    session 1: 
    begin;
    DML1 
    DML2 
    commit;
    drop database world;

    begin;
    DML1 
    DML2 
    begin;
    
    导致提交的非事务语句:
    DDL语句: (ALTER、CREATE 和 DROP)
    DCL语句: (GRANT、REVOKE 和 SET PASSWORD)
    锁定语句:(LOCK TABLES 和 UNLOCK TABLES)
    导致隐式提交的语句示例:
    TRUNCATE TABLE
    LOAD DATA INFILE
    SELECT FOR UPDATE
隐式回滚: 
    会话关闭
    数据库宕机
    事务语句执行失败

3.InnoDB 事务的ACID如何保证

(1)重做日志

redo log: 重做日志 ib_logfile0~N 48M , 轮询使用记录的是数据页的变化。

redo log buffer: redo内存区域
(2)数据页存储位置
ibd : 存储数据行和索引
buffer pool: 缓冲区池,数据页和索引页的缓冲
(3)LSN : 日志序列号
磁盘数据页,redo文件,buffer pool,redo buffer
MySQL 每次数据库启动,都会比较磁盘数据页和redo log的LSN,必须要求两者LSN一致数据库才能正常启动
(4)WAL : write ahead log 日志优先与数据页,写的方式实现持久化
(5)脏页: 内存脏页,内存中发生了修改,没回写入到磁盘之前,我们把内存页称之为脏页.
(6)CKPT:Checkpoint,检查点,就是将脏页刷写到磁盘的动作
(7)TXID: 事务号,InnoDB会为每一个事务生成一个事务号,伴随着整个事务生命周期.
(8)UNDO: ibdata1 , 存储了事务工作过程中的回滚信息。

4.InnoDB 事务的工作流程

redo log
1》 Redo是什么?
redo,顾名思义“重做日志”,是事务日志的一种。
2》 作用是什么?
在事务ACID过程中,实现的是“D”持久化的作用。对于AC也有相应的作用
3》 redo日志位置
redo的日志文件:iblogfile0 iblogfile1
4》 redo buffer
redo的buffer:数据页的变化信息+数据页当时的LSN号
LSN:日志序列号 磁盘数据页、内存数据页、redo buffer、redolog
5》 redo的刷新策略
commit;
刷新当前事务的redo buffer到磁盘
还会顺便将一部分redo buffer中没有提交的事务日志也刷新到磁盘

补充: redo存储的是在事务工作过程中,数据页变化。
commit时会立即写入磁盘(默认),日志落盘成功commit。
正常MySQL工作过程中,主要的工作是提供快速D的功能。
MySQL出现Crash异常宕机时,主要提供的是前滚功能(CSR)。

 

 

 

 

6.双一标准之一:
innodb_flush_log_at_trx_commit = 0 / 1 / 2
1: 在每次事务提交时,会立即刷新redo buffer到磁盘,commit才能成功。
0:每秒刷新redo buffer到os cache,再fsync()到磁盘,异常宕机时,会有可能导致丢失1s内的事务
2:每次事务提交,都立即刷新redo buffer 到 os cache,再每秒 fsync() 磁盘,异常宕机时,会有可能导致丢失1s内的事务。
目前默认是1.
另外,
1. redo buffer 还和操作系统缓存机制有关,所以刷写策略可能和innodb_flush_method参数有一定关系。
2. redo也有group commit; 可以理解为,在每次刷新已提交的redo时,顺便可以将一些未提交的事务redo也一次性
刷写到磁盘。此时为了区分不同状态的redo,会加一些比较特殊的标记(是否提交标记)。

1.2.3 UNDO Logs
1》 undo是什么?
undo,顾名思义“回滚日志”
2》 作用是什么?
在事务ACID过程中,实现的是 “A” 原子性的作用
另外CI也依赖于Undo
在rolback时,将数据恢复到修改之前的状态
在CSR实现的是,先redo前滚,在Undo回滚。

3》 什么是一致性快照?
每个事务开启时(begin),都会通过undo生成一个一致性的快照。
undo提供快照技术,保存事务修改之前的数据状态.
保证了MVCC,隔离性,mysqldump的热备功能。

undo在生成过程中,也会记录redo信息。

1.2.4 隔离级别和锁机制
作用: 主要是提供I的特性,另外对于C的特性也有保证。
(1)transaction_isolation 事务隔离性介绍
RU : 读未提交
RC : 读已提交
RR : 可重复读 :默认级别
SR : 可串行化
读什么意思?
这里的读不是SQL层的数据行的select,而指的是存储引擎的读,是page的读取。
(2)隔离级别说明
《1》RU (READ-UNCOMMITTED) : 读未提交
出现的问题:脏页读,不可重复读,幻读
《2》RC (READ-COMMITTED) : 读已提交
出现的问题:不可重复读,幻读
《3》RR (REPEATABLE-READ) : 可重复读
出现的问题:有可能出现幻读,但是可以通过其他手段防止幻读出现
《4》SR ( SERIALIZABLE ) : 可串行化
串行化事务。以上问题都能规避,但是不利于事务的并发。

(3)参数修改
mysql> select @@transaction_isolation;
临时调整:
mysql> set global transaction_isolation='read-uncommitted';
重启会话生效
永久修改:
vim /etc/my.cnf
transaction_isolation='read-uncommitted'
重启生效

(4)例子演示:
调整成transaction_isolation='read-uncommitted'
《1》脏读:
在Session2事务中读取到了,session1未提交数据的脏数据。这个现象就是脏读
对于脏读,在生产业务中是一般不允许出现的。
《2》不可重复读现象
session2中的事务中,执行相同查询命令时,读到了session1正在发生变化的数据。
对于事务的隔离性和数据最终一致性要求比较高的业务,不允许出现的。
如果业务能够容忍,也是可以出现的。
《3》幻读
在一个事务窗口中,更新操作,出现了别的插入数据的幻行。

调整成transaction_isolation='read-committed'
《1》不可重复读现象
session2中的事务中,执行相同查询命令时,读到了session1正在发生变化的数据。
对于事务的隔离性和数据最终一致性要求比较高的业务,不允许出现的。
如果业务能够容忍,也是可以出现的。
《2》幻读
在一个事务窗口中,更新操作,出现了别的插入数据的幻行。

调整成transaction_isolation='REPEATABLE-READ'
1. 防止不可重复读现象:
利用的就是 UnDO的一致性快照读。MVCC重要功能。
2. 通过RR,已经可以解决99以上的幻读的,为了更加严禁。
加入了GAP锁,next-lock。

 

posted @ 2020-02-24 20:49  Panky_Wise  阅读(77)  评论(0)    收藏  举报