一、事务定义
- 通过将一组相关操作组合为一个要么全部成功要么全部失败的单元。这组操作
是一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元) - 一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成
- 事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同
二、事务四大特征(ACID)
-
原子性(Atomicity):
对于事务中数据的DML操作要么全成功,要么全部失败回滚。 -
一致性(Consistent):
在事务开始和完成时,数据都必须保持一致状态。在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构都必须是正确的。 -
隔离性(Isolation)
一个事务所做的修改在最终提交以前,对其他事务是不可见的。 -
持久性(Durable)
事务一旦被提交,其结果就是永久性的。是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)
三、事务操作
- 开启事务:begin(或 start transaction 显式地开启一个事务)
- 提交事务: commit
- 事务回滚:rollback
四、事务的实现(事务日志)
-
undo log(回滚日志)
执行过程中发生异常,错误,手动回滚,执行undo log 回滚日志。
事务提交之后,mysql不会执行事务回滚日志 -
redo log(重做日志)
在事务 提交之后,数据没有来得及 写入 到 磁盘 的时候,mysql 重启 就会执行 redo log 重做日志。 -
show engine innodb status; 查看事务日志相关信息(选中某个库)
Log sequence number 16280405 日志文件LSN 日志文件序号(编号) Log flushed up to 16280405 刷新日志文件LSN 刷新到磁盘之前有个缓存区:Innodb_log_Buffer Last checkpoint at 16280405 刷新到磁盘的LSN编号
-
innodb_flush_log_at_trx_commit 用来配置flush log到磁盘的时机。具体就是从log buffer写到log file,并写入到磁盘上的时机。
0:(延迟写): log_buff --每隔1秒--> log_file —实时—> disk
log buffer(日志缓冲)将每秒一次地写入log file(日志文件)中,并且log file的flush(刷到磁盘)操作同时进行。在事务提交的时候,不会主动触发写入磁盘的操作(就是每隔1秒写,和提交事务没关系)。
优缺点: 速度会更快一点,但安全性比较差,即使MySQL挂了也可能会丢失数据。1:(实时写,实时刷): log_buff —>实时—> log_file —实时—> disk-->系统默认
每次事务提交时MySQL都会把log buffer(日志缓冲)的数据写入log file(日志文件),并且flush(刷到磁盘)中去
优缺点: 每一次事务提交或事务外的指令都需要把日志写入(flush)硬盘,最安全也是最耗时的。
2:(实时写,延迟刷): log_buff —实时—> log_file --每隔1秒--> disk
每次事务提交时MySQL都会把log buffer的数据写入log file,但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。
优缺点: 折中
注意事项:0:最快减少mysql写的等待 。该模式速度最快,但不太安全,mysqld进程的崩溃会导致上一秒钟所有事务数据的丢失。 1:当设置为1,该模式是最安全的,但也是最慢的一种方式。在mysqld 服务崩溃或者服务器主机crash的情况下,binary log 只有可能丢失最多一个语句或者一个事务。 2:折中,减少操作系统文件写入等待时间(只有在整个OS都挂了的情况下才有可能丢失数据)。当设置为2,该模式速度较快,也比0安全,只有在操作系统崩溃或者系统断电的情况下,上一秒钟所有事务数据才可能丢失。 3:查找资料时候看到其他文章说innodb_flush_log_at_trx_commit和sync_binlog 两个参数是控制MySQL 磁盘写入策略以及数据安全性的关键参数,当两个参数都设置为1的时候写入性能最差,推荐做法是innodb_flush_log_at_trx_commit=2,sync_binlog=500 或1000