MySQL事务
目录
内容概述
1.MySQL慢查询
2.什么是事务
3.为什么需要事务
4.事务的4个特性
5.MySQL事务保存点
6.MySQL事务中的redo和undo
内容详细
1.MySQL慢查询
慢日志
1.将MySQL服务器中影响数据库性能的相关SQL语句记录到日志文件中
2.通过对这些特殊的SQL语句进行分析和改进,提高数据库的性能
默认情况下,MySQL数据库并不启动慢查询日志,需要我们手动来设置这个参数。
如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志或多或少会带来一定的性能影响。
慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表
配置慢日志
vim /etc/my.cnf
slow_query_log = on # 开启慢查询
log_queries_not_using_indexes=on # 慢查询中记录没有使用索引的query
slow_query_log_file=/tmp/slow.log # 慢查询日志存储的路径
long_query_time=0.5 # 慢查询时间,这里时间为0.5秒,超过0.5秒就会被记录
配置完配置文件后,退出已登录的MySQL用户,重启MySQL服务
# 查看是否开启
mysql> show variables like '%slow_query_log%';
+---------------------+---------------+
| Variable_name | Value |
+---------------------+---------------+
| slow_query_log | ON |
| slow_query_log_file | /tmp/slow.log |
+---------------------+---------------+
2 rows in set (0.00 sec)
测试慢日志
mysql> select sleep(2);
+----------+
| sleep(2) |
+----------+
| 0 |
+----------+
1 row in set (2.00 sec)
root@756ad135dd2e:/tmp# cat slow.log
# Time: 2021-09-28T16:15:29.967489Z
# User@Host: skip-grants user[root] @ localhost [] Id: 2
# Query_time: 2.000316 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
SET timestamp=1632845729;
select sleep(2);
2.什么是事务
事务
数据库事务指的是作为单个逻辑工作单元执行的一系列操作(SQL语句)这些操作要么全部成功,要么全部失败不执行
3.为什么需要事务
1.为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下也能保持一致性的方法。
2.当多个应用程序并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,防止彼此的操作互相干扰
4.事务的4个特性
事务的ACID特性
1.原子性
事务作为一个整体执行,所有对数据库的操作要么全部执行,要么全都不执行
2.一致性
数据库总是从一个一致状态变到另一个一致状态(事务修改前后的数据总体保证一致),例如转账
3.隔离性
多个事务并发执行时,一个事务的执行不影响其他事务的执行
4.持久性
一个事务一旦提交,它对数据库的修改应该永久保存在数据库中
# 强调:
一致性与原子性密切相关,原子性的破坏可能导致数据的不一致,但数据的一致性问题并不都和原子性有关。所以事务的原子性与一致性缺一不可。
5.MySQL事务保存点
savepoint和虚拟机中的快照类似,用于事务中,每设置一个savepoint就是一个保存点,当事务结束时会自动删除定义的所有保存点,在事务没有结束前可以回退到任意保存点。
1.设置保存点savepoint 保存点名字
2.回滚到某个保存点,该保存点之后的操作无效,rollback 某个保存点名
3.取消全部事务,删除所有保存点rollback
# rollback和commit都会结束事务,这之后无法再回退到某个保存点
6.MySQL事务中的redo和undo
InnoDB是一个支持事务的存储引擎,我们知道事务有4种特性:原子性、一致性、隔离性以及持久性,在事务中的操作,要么全部执行,要么全部不执行,保证数据的安全,这就是开启事务的目的。
Redo Log
Redo Log 记录的是尚未完成的操作,数据库崩溃则用其重写
Redo Log的工作流程:
Redo log可以简单分为以下两个部分:
1.保存在内存中重做日志的缓冲(redo log buffer),它是容易丢失的
2.保存在硬盘中的重做日志文件(redo log file),是持久的
第一步:InnoDB 会先把记录从硬盘读入内存
第二步:将旧数据写入undo日志文件以便日后回滚
第三步:更新内存的数据
第四步:生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值
第五步:当事务commit提交的时候,就将redo log buffer中的内容刷新到redo log file,对redo log file采用追加写的方式
第六步:定期将内存中修改的数据刷新到硬盘里(redo log file 只有在崩溃恢复数据时才用)如果数据库崩溃,则依据redo log buffer、redo log file进行重做,恢复数据,这才是redo log file的价值所在
Undo log
undo即撤销还原,用于记录更改前的一份copy,在操作出错时,可以用于回滚、撤销还原,只将数据库逻辑恢复到原来的样子
undo日志记录了什么?
一个并发场景,A更改数据,B查询数据
# A更改还没有提交,B查询的话,数据肯定为历史数据,这个历史数据就是来源于undo段
# A更改的事务为提交,需要回滚rollback,回滚rollback的数据也来自于undo段
结论:为了并发时读一致性成功,那么DML操作,肯定先写undo段
undo的存储位置
在InnoDB存储引擎中,undo存储在回滚段(Rollback Segment)中,每个回滚段记录了1024个undo log segment,而在每个undo log segment段中进行undo页的申请。
undo的类型
在InnoDB存储引擎中,undo log分为:
insert undo log
update undo log
insert undo log 是指在insert操作中产生的undo log,因为insert操作的记录,只对事务本身可见,对其他事务不可见,所以这个undo log 可以在事务提交后直接删除,而需要进行purge操作。
update undo log 记录的是对delete和update操作产生的undo log,该undo log可能需要提供MVCC机制,因此不能再事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除。
# purge线程两个主要作用是:q清理undo页和清除pag里面带有Delete_Bit标识的数据行
在InnoDB中,事务中的delete操并不是真正的删除掉数据行,而是一种delete mark操作,在记录上标识delete_bit,而不删除记录,是一种“假删除”,只是做了标记,真正的删除工作需要后台purge线程去完成。