MySQL高级篇——事务 mysql事务、bin log、redo log

一、简介

1. 什么是事务

事务是由一个或多个sql语句组成一个最小的不可再分的工作单元。里面的内容要么都执行成功,要么都不成功。

2. 事务的ACID特性

  • 原子性(atomicity)
    事务是一个不可分割的工作单元,要么全部提交,要么全部失败回滚。
  • 一致性(consistency)
    一致性指事务执行前后,数据从一个合法性状态变换到另一个合法性状态。例如要满足存在的约束,满足数据的一致性等、
  • 隔离性(isolation)
    指一个事务的执行不能被其他事务干扰。
  • 持久性(durability)
    一个事务一旦提交成功,它对数据库中数据的改变将是永久性的,接下来的其他操作或故障不应对其有任何影响。

3. 存储引擎支持情况

show engines 命令可以查看mysql存储引擎支持事务的情况。

在mysql中,只有innodb是支持事务的。


二、开启事务

1. 显式事务

START TRANSACTION或BEGIN能显式的开启一个事务。

BEGIN;
# 或者
START TRANSACTION;

START TRANSACTION相较于BEGIN可以在后边跟随几个修饰符。

  • READ ONLY : 表示当前事务是一个只读事务
  • READ WRITE : 当前事务是一个读写事务
  • WITH CONSISTENT SNAPSHOT 启动一致性读(在开启事务的时候就生成Readview)

事务的相关操作如下:

COMMIT;
ROLLBACK;
ROLLBACK TO [SAVEPOINT];
SAVEPOINT 保存点名称;
RELEASE SAVEPOINT 保存点名称; #删除保存点

2. 隐式事务

如果不显式使用START TRANSACTION或BEGIN开启一个事务,那么每一条语句是一个独立的事务,这种特性叫做事务的自动提交。
如果想关闭自动提交,有两种方法:

  • 显式使用START TRANSACTION或BEGIN
  • 把系统变量autocommit的值设置为off

注意事项——隐式提交

  • 数据定义语言。当使用create、alter、drop等语句去修改数据库对象时,就会隐式提交前边语句所属的事务。
  • 当我们在一个事务还未提交或回滚时又使用START TRANSACTION或BEGIN开启一个事务时,会提交上一个事务。

三、事务的隔离级别

1. 介绍

SQL在并发事务执行过程中可能存在以下问题:

脏写、脏读、不可重复读、幻读

mysql提供四种隔离级别,用来解决并发问题:

  • READ UNCOMMITTED : 读未提交,在该隔离级别下,所有事务都可以看到其他事务未提交的数据。不能避免脏读、不可重复读、幻读。
  • READ COMMITTED : 读已提交,一个事务只能看到已经提交的事务。可以避免脏读,不能避免不可重复读、幻读。
  • REPEATABLE READ : 可重复读,事务A在读到记录后,其他事务对该记录修改后,A事务读到的还是原来的内容。可以避免脏读、不可重复读,不能避免幻读。这是mysql默认的隔离级别。
  • SERIALIZABLE : 可串行化,所有事务串行执行。

2. 设置

show variables like 'tx_isolation'; # 查看隔离级别,mysql5.7.20之前
show variables like 'transaction_isolation' # 查看隔离级别,mysql5.7.20之后
select @@transaction_isolation
SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔离级别'

四、undo日志

undo log是事务原子性的保证,在事务更新数据时需要先写入undo log。

1 作用

  • 回滚数据

用户对undo日志可能有误解:undo用于将数据库物理地恢复到执行语句或事务之前的样子。但事实并非如此。undo是逻辑日志,因此只是将数据库逻辑地恢复到原来的样子。所有修改都被逻辑地取消了,但是数据结构和页本身在回滚之后可能大不相同。
这是因为在多用户并发系统中,可能会有数十、数百甚至数千个并发事务。数据库的主要任务就是协调对数据记录的并发访问。比如,一个事务在修改当前一个页中某几条记录,同时还有别的事务在对同一个页中另几条记录进行修改。因此,不能将一个页回滚到事务开始的样子,因为这样会影响其他事务正在进行的工作。

MVCC

undo的另一个作用是MVCC,即在InnoDB存储引擎中MNCc的实现是通过undo来完成。当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过undo读取之前的行版本信息,以此实现非锁定读取。

2 结构

InnoDB对undo log的管理采用段的方式,也就是回滚段(rollback segment),每个回滚段记录类1024个undo log segment

innodb_undo_directory : 设置文件所在路径。
innodb_undo_tablespaces : 设置文件数量.

undo log类型分为:

  • insert undo log

因为insert操作的记录,只对事务本身可见,对其他事务不可见。故该undo log可以在事务提交后直接删除,不需要进行purge操作

  • update undo log

该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除

3 工作流程


五、redo日志

redo log称为重做日志,提供再写入操作,恢复提交事务修改页操作,用来保证事务的持久性。
redo log记录的是物理级别上页的修改操作。

1. WAL

InnoDB的事务存储引擎,其通过Force Log at Commit机制实现事务的持久性,即当事务提交时,先将redo log buffer写入到redo log file进行持久化,待事务的commit操作完成后才算完成。这种做法也被称为Write-Ahead Log(预先日志持久化),在持久化一个数据页之前,先将内存中相应的日志持久化。

2. 刷盘策略

通过调整innodb_flush_log_at_trx_commit,支持不同的刷盘策略:

  • 0 : 表示每次事务提交时不进行刷盘操作,由系统后台线程每隔1s进行一次同步。
  • 1 : 默认为1,表示每次事务提交时都将进行同步,刷盘操作
  • 2 : 表示每次事务提交时都只写到oage cache,不进行同步,由os自己决定什么时候同步到磁盘。
作者:笔深原文地址:https://blog.csdn.net/qq_51114283/article/details/126725565

%s 个评论

要回复文章请先登录注册