首先,我要感谢大家参加我的12月19日,2019网络研讨会”MySQL的前三特征”。记录和幻灯片上可用网络研讨会页面。
这里有答案的提问参与者,我无法提供在网络研讨会。
问:什么时候undo日志和重做日志发挥作用?你能解释这些日志的背景操作吗?
答:这两个是完全不同的结构。
Undo日志
属于一个单一的活动事务。它包含的信息如何撤销聚集索引的最新变化,由该事务。
让我们用一个例子展示它们是如何工作的。
考虑一下这个表:
|
1
2
3
4
5
6
|
mysql
>
创建
表
t1
(
id
int
不
零
auto_increment
主
关键
,
f1
varchar
(
One hundred.
)
)
引擎=innodb
;
查询
好吧
,
0
行
影响
(
0.02
证券交易委员会
)
mysql
>
插入
成
t1
(
f1
)
值
(
“foo”
)
,
(
“巴尔”
)
,
(
“记者”
)
;
查询
好吧
,
3
行
影响
(
0.03
证券交易委员会
)
记录
:
3
重复的
:
0
警告
:
0
|
现在,让我们打开一个事务,从这个表中检索行:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
mysql
>
\
R
tr1
>
提示
集
来
“tr1 >”
tr1
>
开始
;
查询
好吧
,
0
行
影响
(
0.00
证券交易委员会
)
tr1
>
选择
*
从
t1
;
+ - - - + - - - +
|
id
|
f1
|
+ - - - + - - - +
|
1
|
喷火
|
|
2
|
巴尔
|
|
3
|
巴兹
|
+ - - - + - - - +
3
行
在
集
(
0.00
证券交易委员会
)
|
在另一个会话我们打开新的事务和修改行f1=“巴尔”来f1=“酒吧”:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
tr2
>
开始
;
查询
好吧
,
0
行
影响
(
0.00
证券交易委员会
)
tr2
>
更新
t1
集
f1=“酒吧”
在哪里
f1=“巴尔”
;
查询
好吧
,
1
行
影响
(
0.00
证券交易委员会
)
行
匹配
:
1
改变了
:
1
警告
:
0
tr2
>
提交
;
查询
好吧
,
0
行
影响
(
0.01
证券交易委员会
tr2
>
选择
*
从
t1
;
+ - - - + - - - +
|
id
|
f1
|
+ - - - + - - - +
|
1
|
喷火
|
|
2
|
酒吧
|
|
3
|
巴兹
|
+ - - - + - - - +
3
行
在
集
(
0.01
证券交易委员会
)
|
我们使用的是默认的事务隔离级别可重复的- - - - - -读。因此第一个事务应该得到相同的结果,因为它看到了变化和它前:
|
1
2
3
4
5
6
7
8
9
|
tr1
>
选择
*
从
t1
;
+ - - - + - - - +
|
id
|
f1
|
+ - - - + - - - +
|
1
|
喷火
|
|
2
|
巴尔
|
|
3
|
巴兹
|
+ - - - + - - - +
3
行
在
集
(
0.00
证券交易委员会
)
|
从撤销事务检索数据日志因为表已经更新提交。
取消默认日志存储在共享InnoDB表空间但可以放入单独的表空间更好的空间管理。这是推荐的选项。
你可以找到更多关于撤销登录的信息用户参考手册。
重做日志
重做日志是一个基于磁盘的数据结构用在崩溃恢复正确的数据写的不完整的交易。
在正常操作期间,InnoDB从未读它。只有在MySQL服务器不能正常停止InnoDB使用正确记录在重做日志数据。
为什么需要重做日志?
InnoDB存储中的数据行聚集索引。聚集索引的内部结构是b - tree。这个存储允许快速读访问,但慢写,因为它始终需要实现平衡树。此外,即使只是物价数据改变,需要时间找到合适的页面更新应该放置在磁盘上。
因此最初InnoDB存储内存的变化缓冲池。这允许成功返回到应用程序更快。在后台,InnoDB将数据从缓冲池到磁盘。因此在一段时间,新提交的数据可能只存在于内存中。然而,在崩溃的情况下,内存中的数据已经一去不复返了。
因此,与此同时,一个编码变更请求也写入重做日志。这样写是顺序的,没有时间要花在寻找合适的位置。因此这个操作要快得多更新表文件。不过,crash-safe,因为现在的数据存在于内存(活动数据集)和磁盘上的(在重做日志记录)。
重做日志的大小是有限的,两个选择:
- innodb_log_file_size
- 单独的日志文件的大小
- innodb_log_files_in_group
- 日志文件的数量
重做日志的总大小可以由公式计算:
|
1
|
innodb_log_file_size
*
innodb_log_files_in_group
|
会发生什么如果重做日志的总大小达到?
重做日志中的每个记录都有自己的数字:LSN。通常InnoDB始终将改变表文件和重写记录这些lsn已经刷新以循环的方式。
然而,如果合并后的重做日志的大小太小的数量写InnoDB接收在短的时间内,很可能在重做日志满之前InnoDB写数据到表文件。在这种情况下,InnoDB停止所有写活动和执行所谓的激进的冲洗。你可以阅读更多关于冲洗用户参考手册。
因此有必要重做日志的大小足够大,所以InnoDB可以跟上应用写道。看看如何计算好InnoDB日志文件大小。
问:InnoDB崩溃的情况(长信号量等)发生事故的原因是什么?
答:InnoDB使用信号量保护内部结构并发使用。这种信号通常是只有很短的时间内举行。因此如果信号量等超过600秒,InnoDB决定出了错,服务器崩溃。在这种情况下,您需要做什么错误消息显示:报告一个错误https://bugs.mysql.com和/或https://jira.雷竞技下载官网percona.com。
然而,有时信号后面长操作时等待完成。例如,分析表在一个非常大的表。在这种情况下,服务器可能会崩溃没有有效的原因。我们甚至看到情况诊断查询这样的失败引起的。据报道在ps - 6113和固定在raybetapp 。不过,这种限制存在于上游版本5.7.28和8.0.18 MySQL服务器





