mysql - 事务相关概念

mysql - 事务相关概念

 

 

 事务概述:

我们可以把事务理解成一组sql语句的集合,事务可以只包含一条sql语句,也可以包含多条复杂的sql语句,事务中的所有sql语句被当做一个操作单元,换句话说,事务中的sql语句要么都执行成功,要么全部执行失败,事务内的sql语句被当做一个整体,被当做一个原子进行操作。

innodb支持事务 & ACID特性:

mysql中,innodb存储引擎是支持事务的,而且innodb存储引擎的事务完全符合ACID的特性,ACID是如下四大特性的首字母缩写。

A:atomicity    原子性

C:consistency   一致性

I:isolation    隔离性

D:durability   持久性

 

原子性:整个事务中的所有操作要么全部执行成功,要么全部执行失败后混滚到最初状态。

一致性:数据库总是从一个一致性状态转为另一个一致性状态。

隔离性:一个事务在提交之前所做出的的操作是否能为其他事务可见,由于不同的场景需求不同,所以针对隔离性来说,有不同的隔离级别。

持久性:事务一旦提交,事务所做出的修改将会永久保存,此时即使数据库崩溃,修改的数据也不会丢失。

事务日志:

redo log(重做日志):

概述:

  1. mysql会将事务中的sql语句涉及到的所有数据操作先记录到redo log中
  2. 然后再将操作从redo log中同步到对应数据文件中(此处假设事物操作的数据量并非巨大),换句话说,在事务执行提交成功以前,在修改对应的数据文件中的记录之前,一定要保证对应的所有修改操作已经记录到了redo log中,
  3. 假设事务中的sql语句涉及到60条记录的修改,那么在修改这60条记录之前,要将这60条修改操作记录到redo log中,当这60条操作都记录到redolog中以后,再从redo log中一条一条同步到数据文件的对应记录中。
  4. 所以,即使数据文件中的数据被修改到一半时被打断(比如停电),那么也能依靠redo log中的日志将剩余的部分操作再次同步到对应的数据文件中。

使用redo log,能够实现ACID中的A,也就是原子性,即事务中的所有sql被当做一个执行单元。

redo log其实由两部分组成redo log buffer(重做日志缓冲)redo log file(重做日志文件)

redo log buffer存在于内存之中,是易失的,redo log file是持久的,存在于磁盘上。

mysql - 事务相关概念

 

 

缓存到磁盘

重做日志先被写入到redo log buffer中,虽然内存的速度极快,但是无法满足持久性的需求,因为内存中的数据是易失的,所以为了满足持久性,需要将redo log buffer中的日志写入到redo log file中,相当于从内存中同步到磁盘上,所以磁盘的性能会影响事务的性能,由于redo log file是磁盘上一段连续的空间,所以写速度还是比较快的,比离散的写操作要快很多,当操作记录被记录到redo log file中以后,再从redo log file中将操作同步到数据文件中。

缓存刷新策略

虽然,我们应该实时将redo log buffer中的数据写入到redo log file中以保证数据的安全性,但是这样会极大的降低性能,我们可以通过设置innodb_flush_log_at_trx_commit参数来修改从redo log buffer写入redo log file的策略,但是如果这样做,则会丧失持久性,有可能会丢失部分数据,具体使用怎样的刷写策略,还需要根据实际情况自己权衡。

 

redo log是物理日志,之所以说它是物理日志,是因为redo log 中记录的是数据库对页的操作,而不是逻辑上的增删改查,重做日志具有幂等性。

undo log概述:

刚才我们大致的描述了什么是redo log ,现在来聊聊什么是undo log,我们可以把undo log理解成数据被修改前的备份。如果说事务进行了一半,有一条sql没有执行成功,那么数据库可以根据undo log进行撤销,将所有修改过的数据从逻辑上恢复到修改之前的样子,注意,是逻辑上还原成原来的样子,比如,之前insert了1000条数据 ,那么就delete它们,如果delete了2000条,就insert它们,如果update了500条数据,就再次根据undo log去update它们,所以,undo log是逻辑日志,与redo log记录的页操作物理日志不同。

 

log group概述:

log group为重做日志组,一个重做日志组(log group)中有多个重做日志文件(redo log file),当日志组中的第一个logfile被写满,则会开始将redo log写入日志组中的下一个重做日志文件中,以此类推,当日志组中的所有redo log file都被写满,则将redo log再写入第一个redo log file 中,覆盖原来的redo log,以便新的redo log 被写入。

如果重做日志所在的设备崩溃了,那么redo log将有可能丢失,这样就无法保证redo log在任何时候都是可用的,所以,log group还支持日志组镜像,为了保险起见,我们应该将log group放在有冗余能力的设备上,比如raid1

 

其他:

  1. redo log存储于重做日志文件中,undo log则不同,undo存放在数据库内部的特哥特殊段中,这个段被称为undo段(undo segment),undo段位于共享表空间中;
  2. mysql中,innodb存储引擎是支持事务的,myisam存储引擎是不支持事务的;
  3. 不管是redo log或者undo log,都是innodb的产物,或者说是innodb存储引擎层面的产物
  4. binlog不止针对于innodb,mysql数据库中的任何存储引擎对于数据库的更改都会产生二进制日志(binlog)
  5. innodb的redo log记录的是物理格式的日志,记录了对页的操作,而binlog记录的是逻辑日志记录的是对应的SQL
  6. redolog与binlog写入磁盘的时机也不同,innodb的redo log在事务进行时会不断的写入redo log filebinlog只在事务提交完成后进行一次磁盘写入

 转载自:mysql/mariadb知识点总结(19):事务相关概念 (事务总结之一) | 朱双印博客

mysql - 事务相关概念

上一篇:MySQL出现:ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)问题解决


下一篇:【MyBatis】SqlSession相关的生命周期及作用域