学一学Mysql中的事务
学一学mysql的事务
事务是什么
事务是一组数据库操作的集合,比如我们建了张员工表,然后我们会插入、查询员工信息,我们保证这一组操作要全部成功要么就全部失败。
CREATE TABLE test( id int(5)) engine=innodb;
begin; # 开始事务
insert into test value(5);
insert into test value(6);
commit; # 提交事务
四大特性
- 原子性:构成事务的所有操作必须是一个逻辑单元,要么全部成功,要么全部失败;
- 一致性:数据库在事务执行前后都是稳定或者一致的,就是说在事务前和事务后,数据库完整性不会被破坏。人话就是事务执行前后数据库都是正确的;
- 隔离性:事务之间是隔离的。主要由锁机制和MVCC机制来实现,MVCC就是多版本并发控制;
- 持久性:事务执行成功后必须全部写入磁盘,事务提交后,对数据的修改是永久性的,即使系统故障也不会丢失。
redo log 、Undo log、Buffer Pool
在学习四大特性原理之前,我们需要学习一些其他的东西
重做日志 redo log
存储数据之前要存储数据的日志,也就说“先写日志,再写磁盘”。InnoDB有一种WAL机制,也就是Write-Ahead Logging,预写日志策略。
在回放日志的时候把已经COMMIT的事务重做一遍,对于没有commit的事务按照abort处理,不进行任何操作。
使用redo log时事务执行顺序
- 记录START T
- 记录事务需要修改记录的新值(要求持久化)
- 记录COMMIT T(要求持久化)
- 将事务相关的修改写入数据库
redo log 包括两部分:一是内存中的日志缓冲(redo log buffer),该部分日志是易失性的;二是磁盘上的重做日志文件(redo log file),该部分日志是持久的。
redo log是物理日志,记录的是数据库中物理页的情况 。
回滚日志 Undo log
Undo log把所有没提交的事务回滚到开始前的状态。
undo日志的完整性和可靠性需要redo日志来保证,所以崩溃恢复先做redo恢复数据,然后做undo回滚。
使用undo log时事务执行顺序
- 记录START T
- 记录需要修改的记录的旧值(要求持久化)
- 根据事务的需要更新数据库(要求持久化)
- 记录COMMIT T
缓存Buffer Pool
InnoDB提供给缓存Buffer Pool来读写数据。
我们直到数据库的数据都是存在磁盘当中的,而磁盘的IO速度很慢。所以我们减少磁盘的IO。而Buffer Pool就是这个问题的答案。
Buffer Pool 是位于内存的,包含了磁盘中部分数据页的映射。读取数据时,InnoDB会首先尝试Buffer Pool的页面读取,读不到就去磁盘读取再放入Buffer Pool;写入时,会先写入Buffer Pool中的页面,这样的页面被称之为dirty,并放到专门的flush list上,这些修改的数据页会在后续某个时刻被刷新到磁盘,这个过程就是刷脏。
这样频繁的磁盘IO转换为内存的读写。
特性的原理
原子性
Undo Log 是原子性的原理。
原子性的关键是,事务回滚的时候可以撤销之前执行的sql语句。Undo log是逻辑日志,会记录sql执行相关的信息。回滚时做出相反的工作。
持久性
InnoDB通过Buffer Pool提高读写性能。但随之而来也有一个严重的问题:如果MySql宕机,此时Buffer Pool中的数据还没有“刷脏”到磁盘,这一段时间数据就无效了。这显然不符合我们的持久性,我们需要设计一些东西来解决这个问题。
redo log 就是引入解决这个问题的。数据被修改的时候时,InnoDB也会在redo log进行刷盘,记录下来。如果MySql宕机,重启时可以读取redo log的数据,对数据库修复。
隔离性
一致性
一致性的成立在前三种特性。