mysql事务(一)——redo log与undo log

数据事务

即支持ACID四大特性。

A:atomicity          原子性——事务中所有操作要么全部执行成功,要么全部执行失败,回滚到初始状态

C:consistency     一致性——数据库总是从一个一致性状态变化到另一个一致性状态

I:isolation            隔离性——一个事务所做的操作在事务提交前是否被另外一个事务可见,mysql可配置,用以适用不同场景

D:durability         持久性——事务一旦提交,所做操作永久保存(不是仅仅在内存中修改)

mysql通过redo log和undo log保障事务

redo log

事务中所有操作会先写到redo log中,然后再同步到数据库文件中。所以数据库文件进行事务操作修改时,redo log肯定已经记录了所有事务操作,此时即使数据库挂掉,事务操作也都已经持久化到redo log中了,数据库恢复后可以继续执行剩下操作。

redo log有两部分组成,redo log buffer与redo log file。如果每个事务的redo log都实时写到file中,再写到数据文件中,那么性能会比较差,所以可以先把一定时间间隔中的事务操作记录到buffer中,然后统一刷新到file中(此时数据库文件的刷新不一定晚于重做日志文件的刷新)。

redo log使用buffer缓存,丢失了数据持久性,数据库宕机时,没有持久化到redo log file中的事务操作也会丢失。此时数据库数据需要回滚到这些丢失事务之前的状态,undo log正好记录了事务之前的状态。

redo log是物理日志,记录里的是对数据库页的操作,不是sql语句,具有幂等性。

log group包含多个redo log,redo log循环覆盖log group中的文件。

undo log

undo log记录了事务提交之前的数据状态。所以当事务操作同步到数据文件仅仅执行了一半就失败了,恢复后无法找到剩余事务操作,那就只好回滚到事务执行前了。这是就可以使用undo log了。

不同于redo log存放在单独文件中,undo log存放在数据库内部特殊的段中(undo segment),这个段位于共享表空间中。可以知道,undo log必然发生在事务执行之前,所以事务操作执行开始了,undo log必然已经存在了。

redo log与binlog的区别

mysql只有innodb支持事务,redo log和undo log都是innodb的产物。binlog也可以用作数据恢复,不过它是整个mysql的日志,对于所有存储引擎都生效。

binlog存储的是逻辑sql,这一点与redo log中的物理格式不同。

binlog在事务结束后才写进文件,redo log在事务执行中写进文件。

redo log参数设置

执行show global variables like '%innodb%log%';查看参数

1、innodb_log_file_size:redo log大小,单位字节

2、innodb_log_files_in_group:redo log group大小,日志组中存在多少个redo log文件

3、innodb_log_group_home_dir:redo log路径,上图表示同数据文件路径

4、innodb_log_buffer_size:重做日志缓存大小

5、innodb_flush_log_at_trx_commit:事务从redo log buffer刷新到redo log file策略

默认值为1,表示redo log事务提交时,立即将操作从buffer刷入file中(commit ->redo log buffer->os buffer->redo log file)。

0表示每innodb_flush_log_at_trx_commit秒钟将redo log buffer刷入redo log file一次。数据库宕机,最多丢失innodb_flush_log_at_trx_commit秒操作。

2表示每次事务提交,都会将redo log buffer写入os buffer,每innodb_flush_log_at_trx_commit秒钟将os buffer同步到redo log file中。这种情况下,数据库宕机,服务器没有宕机,数据库恢复后,已经写入os buffer的事务操作还可以写到redo log file中。

6、innodb_flush_log_at_timeout:配合innodb_flush_log_at_trx_commit使用,表示redo log多久从buffer刷入file中。

 

相关推荐:

如何解决 MySQL 轮询中无法获取新数据的问题

python使用mysql-connector-python轮询mysql时,首次查询能返回结果,后续却始终为空——根本原因在于游标未显式获取数据且连接复用导致事务隔离或结果集缓存问题,需正确管理游标生命周期与连接状态。 python使用mysql-connector-python轮询mysql时,...

Django悲观锁怎么用_select_for_update()在事务中锁定行记录

必须在数据库事务中使用select_for_update()来避免“读-改-写”竞态,否则锁无效;需确保查询走索引以防升级为表锁,并合理配置nowait、skip_locked、of等参数。 什么时候必须用select_for_update()而不是普通查询 当多个并发请求可能同时读取同一行、再基于...

NumPy对数怎么算_np.log()自然对数与np.log10/log2换底对数

np.log()默认是自然对数(底数为e),非常用对数;需用np.log10()或np.log2()分别处理以10或2为底的场景,且输入必须为正数,否则返回nan或-inf。 np.log()默认是自然对数,不是以10为底 很多人一看到np.log()就默认它等于计算器上的“log”(即log₁₀)...

Django事务怎么用_transaction.atomic装饰器保证数据一致性

必须用@transaction.atomic当一组数据库操作需原子性执行,任一失败则全部回滚;它确保数据一致性,避免脏数据,适用于视图或管理命令,不可用于模型方法或异步视图。 什么时候必须用@transaction.atomic 当你有一组数据库操作,其中任意一步失败都该让前面所有改动回滚,而不是留...

如何使用 Python 的 MySQL Connector 创建存储过程

本文详解在python中通过mysql-connector-python创建mysql存储过程的正确方法,重点解决“commandsoutofsync”错误,说明为何不能使用delimiter语句、如何规避多结果集冲突,并提供可直接运行的安全示例。 本文详解在python中通过mysql-conne...