1. 事务
a. 概述
事务的特性
原子性(
atumicity
)
一致性(
consistency
)
隔离性(
isolation
)
持久性(
durability
)
b. 分类
扁平事务
带有保存点的扁平事务
链事务
嵌套事务
分布式事务
2. 事务的实现
a. Redo
重做日志用来实现事务的持久性,即事务
D
。由两部分组成:
i.
内存的重做日志缓冲(
redo log buffer
)(易失性)
ii.
重做日志文件(
redo log file
)(持久性)
为了确保每次日志都写入重做日志文件,在每次将重做日志写入重做日志文件后,
InnoDB
存储引擎都需要调用一次
fsync
操作。由于重做日志文件打开并没有使用
o_direct
选项,因此重做日志缓冲先写入文件系统缓存。为了确保重做日志写入磁盘,必须进行一次
fsync
操作。由于
fsync
的效率取决于磁盘的性能,因此磁盘的性能决定了事务提交的性能,也就是数据库的性能。
使用参数
innodb_flush_log_at_trx_commit
用来控制重做日志刷新到磁盘的策略:
-
1
默认值,表示事务提交时必须调用一次
fsync
操作
-
0
事务提交时不进行写入重做日志操作,这个操作仅在
master thread
中完成,而在
master thread
中每
1
秒会进行一次重做日志文件的
fsync
操作
-
2
表示事务提交时将重做日志写入重做日志文件,但仅写入文件系统的缓存中,不进行
fsync
操作。
二进制日志与重做日志的区别:
1.
重做日志是在
InnoDB
存储引擎层产生,而二进制日志是
MySQL
数据库的上层产生的,并且二进制日志不仅仅针对于
InnoDB
存储引擎,
MySQL
数据中的任何存储引擎对于数据库的更改都会产生二进制日志。
2.
两种日志记录的内容形式不同。二进制日志是一种逻辑日志,其记录的是对应的
SQL
语句。重做日志是物理格式日志,其记录的是对于每个页的修改。
3. 两种日志写入磁盘的时间点不同。二进制日志只在事务提交完成后进行一次写入。重做日志在事务进行中不断地被写入。
b. Undo
在对数据库进行修改时,InnoDB存储引擎不但会产生redo,还会产生一定量的undo。
redo存放在重做日志文件中,与redo不同,undo存放在数据库内部的一个特殊段中,这个段称为undo段。undo段位于共享表空间内。
Undo 参数:
- Innodb_undo_directory 设置rollback segment文件成的路径。
- Innodb_undo_logs 设置rollbacksegment的个数,默认值128.
- Innodb_undo_tablespace 设置构成rollbacksegment文件的数量
可以通过innodb_trx_rollback_segment与innodb_trx_undo来查看undo信息
c. Purge
purge用于最终完成delete和update操作。InnoDB存储引擎支持MVCC,所以记录不能在事务提交时立即进行处理。
d. Group commit
BLGC(binary LogGroup Commit)实现步骤
- flush阶段,将每个事务的二进制日志写入内存中
- Sync阶段,将内存中的二进制日志刷新到磁盘,若队列中有多个事务,那么仅一次fsync操作就完成了二进制日志的写入,这就是BLGC
- commit阶段,leader根据顺序调用存储引擎层事务的提交,InnoDB存储引擎本就支持groupcommit,因此修改了原先由于锁prepare_commit_mutex导致group commit 失效的问题
参数binlog_max_flush_queue_time用来控制flush阶段中等等待的时间,默认值为0,且推荐设置依然为0。
3. 对于事务操作的统计
TPS =
(
com_commit+com_rollback
)
/time
可以使用
handler_commit
和
handler_rollback
用于事务的统计,建议使用
com_commit
与
com_rollback
4. 事务隔离级别
- READ UNCOMMITTED
- READCOMMITTED
除了唯一性的约束检查及外键约束的检查需要
gap lock,InnoDB
存储引擎不会使用
gap lock
的锁算法。
- REPEATABLEREAD
- SERIALIZABLE
5. 分布式事务
XA
事务由一个或多个资源管理器(
ResourceManagers
)、一个事务管理器(
Transaction Manager
)以及一个应用程序(
Application Program
)组成。
- 资源管理器:提供访问事务资源的方法。通常一个库就是一个资源管理器
- 事务管理器:协调参与全局事务中的各个事务。需要和参与全局事务的所有资源管理进行通信
- 应用程序:定义事务的边界,指定全局事务中的操作