赞
踩
锁机制
实现。重做日志
,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。回滚日志
,回滚行记录到某个特定版本,用来保证事务的原子性、一致性。恢复操作
,但 undo 并不是 redo 的逆过程redo log
:是存储引擎层(innodb)生成的日志,记录的是 物理级别
上的页修改操作,比如页号xxx,偏移量yyy,写了zzz数据,主要为了保证数据的可靠性。undo log
:是存储引擎(innodb)生成的日志,记录的是 逻辑操作
的日志。比如对某一行数据进行了insert语句操作,那么undo log就记录一条与之相反的delete操作。主要用于 事务的回滚
(undo log 记录的是每个修改操作的 逆日志)和 一致性非锁定读(回滚行记录到某种特定版本,即多版本并发控制)。数据从磁盘读取到内存
的缓冲池上进行修改。脏页
。不是每次生成脏页就将脏页刷新回磁盘
,这样会产生海量的IO操作,严重影响InnoDB的处理性能。数据的丢失
。redo log
就应运而生了。innoDB 引擎的事务采用了
WAL技术
( write-ahead logging ),这种技术的思想就是先写日志,再写磁盘,只有日志写入成功,才算事务提交成功,这里的日志就是 redo log。当发生宕机且数据未刷到磁盘的时候,可以通过 redo log 来恢复,保证ACID 中的 D(持久性),这就是 redo 的作用。
redo log 的写入并不是直接写入磁盘的,InnoDB 引擎会在写 redo log 的时候先写 redo log buffer,之后以
一定的频率
刷入到真正的 redo log file 中。
innodb_flush_log_at_trx_commit
参数值 | 说明 |
---|---|
0 | 表示每次事务提交时不进行刷盘操作。(系统默认的 master thread 每隔 1s 进行一次重做日志的同步) |
1 | 表示每次事务提交时都将进行同步,刷盘操作( 默认值 ) |
2 | 表示每次事务提交时都只把 redo log buffer 内容写入 page cache,不进行同步。由 os 自己决定什么时候同步到磁盘文件。 |
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size
:redo log buffer 大小,默认 16M ,最大值是 4096M,最小值为 1M。mysql> show variables like '%innodb_log_buffer_size%';
+------------------------+----------+
| Variable_name | Value |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+
1 row in set (0.00 sec)
mysql>
innodb_log_group_home_dir
./
,表示在数据库的数据目录下。ib_logfile0
和 ib_logfile1
的文件,log buffer中的日志默认情况下就是刷新到这两个磁盘文件中。mysql> show variables like '%innodb_log_group_home_dir%';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| innodb_log_group_home_dir | ./ |
+---------------------------+-------+
1 row in set (0.01 sec)
mysql>
innodb_log_files_in_group
:指明redo log file的个数,命名方式如:ib_logfile0,iblogfile1… iblogfilen。默认2个,最大100个。mysql> show variables like '%innodb_log_files_in_group%';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| innodb_log_files_in_group | 2 |
+---------------------------+-------+
1 row in set (0.01 sec)
mysql>
innodb_log_file_size
48M
,最大值为512G。mysql> show variables like '%innodb_log_file_size%';
+----------------------+----------+
| Variable_name | Value |
+----------------------+----------+
| innodb_log_file_size | 50331648 |
+----------------------+----------+
1 row in set (0.00 sec)
mysql>
undo log 是事务原子性的保证,在事务中
更新数据的前置操作
其实是要先写入一个 undo log。
undo日志的作用:1. 回滚数据;2. MVCC
原子性
,也就是事务中的操作要么全部完成,要么什么也不做。原子性
要求。场景 | 操作 |
---|---|
插入 | 至少要把这条记录的主键值记下来,之后回滚的时候需要把这个主键值对应的 记录删掉 。 |
删除 | 至少要把这条记录的内容都记下来,这样之后回滚再把这些内容组成一条新记录 插入到表 中就好了。 |
更新 | 至少要把修改过这条记录前的旧值都记录下来,这样之后回滚时再把这条记录更新为旧值 就好了。 |
查询 | 并不会修改任何用户记录,并 不需要 记录对应的undo log日志。 |
回滚段(rollback segment)
。未提交的回滚数据(uncommitted undo information)
:该数据所关联的事务并未提交,用于实现读一致性,所以该数据不能被其它事务的数据覆盖;已经提交但未过期的回滚数据(committed undo information)
:该数据关联的数据已经提交,但是仍受到 undo retention 参数的保持时间的影响;事务已经提交并过期的数据(expired undo information)
:事务已经提交,而且数据保存时间已经超过 undo retention 参数指定的时间,属于已经过期的数据。当回滚段满了之后,会优先覆盖此部分数据。事务提交后并不能马上删除 undo log 及 undo log 所在的页。这是因为可能还有其它事务需要通过 undo log 来得到行记录之前的版本;故事务提交时将 undo log 放入一个链表中,是否可以最终删除 undo log 及 undo log 所在的页由 purge 线程来判断(后续会讲到)。
列 | 说明 |
---|---|
DB_ROW_ID | 如果没有为表显示的定义主键,并且表中也没有定义唯一索引,那么 InnoDB 会自动为表添加一个 row_id 的隐藏列作为主键。 |
DB_TRX_ID | 每个事务都会分配一个事务 ID,当对某条记录发生变更时,就会将这个事务的事务 ID 写入 trx_id 中。 |
DB_ROLL_PTR | 回滚指针,本质上就是指向 undo log 的指针。 |
BEGIN;
INSERT INTO user (name) VALUES ("tom");
# 不更新主键时会把老的记录写入新的 undo log,让回滚指针指向新的 undo log
# 它的 undo no 会 +1,并且新的 undo log 会指向老的 undo log
UPDATE user SET name = "Sun" WHERE id = 1;
# 对于更新主键的操作,会先把原来的数据 deletemark 标识打开,这是并没有真正的删除数据,真正的删除会交给清理线程去判断
# 然后在后面插入一条新的数据,新的数据也会产生 undo log
UPDATE user SET id = 2 WHERE id = 1;
清理undo页
和 清理page里面带有Delete_Bit标识的数据行
。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。