MySQL的日志系统
时间:2019-06-26
本文章向大家介绍MySQL的日志系统,主要包括MySQL的日志系统使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、日志类型
-
逻辑日志:存储了逻辑SQL修改语句
-
物理日志:存储了数据被修改的值
二、binlog
1.定义
binlog 是 MySQL 的逻辑日志,也叫二进制日志、归档日志,由 MySQL Server 来记录。
用于记录用户对数据库操作的SQL语句(除了查询语句)信息,以二进制的形式保存在磁盘中。
2.记录方式
binlog 通过追加的方式写入的,可通过配置参数 max_binlog_size 设置每个 binlog 文件的大小,当文件大小大于给定值后,日志会发生滚动,之后的日志记录到新的文件上。
3.格式
binlog 日志有三种格式,分别为 STATMENT、ROW 和 MIXED。
STATMENT
|
ROW
|
|
说明
|
基于SQL语句的复制(statement-based replication, SBR),每一条会修改数据的sql语句会记录到binlog中。
是bin log的默认格式。
|
基于行的复制(row-based replication, RBR):不记录每一条SQL语句的上下文信息,仅保存哪条记录被修改。
|
优点
|
不需要记录每一条SQL语句与每行的数据变化,减少了bin log的日志量,节约了磁盘IO,提高性能。
|
会非常清楚的记录下每一行数据修改的细节,不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。
|
缺点
|
在某些情况下会导致master-slave中的数据不一致,如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题。
|
会产生大量的日志,尤其是alter table的时候会让日志暴涨。
|
MIXED模式是基于 STATMENT 和 ROW 两种模式的混合复制(mixed-based replication, MBR),一般的复制使用STATEMENT模式保存 binlog,对于 STATEMENT 模式无法复制的操作使用ROW模式保存 binlog,MySQL 会根据执行的 SQL 语句选择日志保存方式。
三、redo log
1.定义:
redo log 是 MySQL 的物理日志,也叫重做日志,记录存储引擎 InnoDB 的事务日志。
MySQL 每执行一条 SQL 更新语句,不是每次数据更改都立刻写到磁盘,而是先将记录写到 redo log 里面,并更新内存(这时内存与磁盘的数据不一致,将这种有差异的数据称为脏页),一段时间后,再一次性将多个操作记录写到到磁盘上,这样可以减少磁盘 io 成本,提高操作速度。先写日志,再写磁盘,这就是 MySQL 里经常说到的 WAL 技术,即 Write-Ahead Logging,又叫预写日志。MySQL 通过 WAL 技术保证事务的持久性。
2.记录方式
InnoDB 的 redo log 大小是固定的,采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。如下图:
write pos表示日志当前记录的位置,当ib_logfile_4写满后,会从ib_logfile_1从头开始记录;
check point表示将日志记录的修改写进磁盘,完成数据落盘,数据落盘后check point会将日志上的相关记录擦除掉,
即write pos->check point之间的部分是redo log空着的部分,用于记录新的记录,check point->write pos之间是redo log待落盘的数据修改记录。当write pos追上check point时,得先停下记录,先推动check point向前移动,空出位置记录新的日志。
有了 redo log,当数据库发生宕机重启后,可通过 redo log 将未落盘的数据(check point之后的数据)恢复,保证已经提交的事务记录不会丢失,这种能力称为crash-safe。
四、两阶段提交
有了 redo log,为什么还需要 binlog 呢?先来看看 binlog 和redo log 的区别:
redo log
|
binlog
|
|
文件大小
|
redo log 的大小是固定的。
|
binlog 可通过配置参数max_binlog_size 设置每个 binlog 文件的大小。
|
实现方式
|
redo log 是 InnoDB 引擎层实现的,并不是所有引擎都有。
|
binlog是 Server 层实现的,所有引擎都可以使用 binlog 日志。
|
记录方式
|
redo log 采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。日志上的记录修改落盘后,日志会被覆盖掉,无法用于数据回滚/数据恢复等操作。
|
binlog 通过追加的方式记录,当文件大小大于给定值后,日志会发生滚动,之后的日志记录到新的文件上,不会覆盖以前的记录。
|
由 binlog 和 redo log 的区别可知:binlog 日志只用于归档,只依靠 binlog 是没有 crash-safe 能力的。但只有 redo log 也不行,因为 redo log 是InnoDB 特有的,且日志上的记录落盘后会被覆盖掉。因此需要 binlog 和 redo log 二者同时记录,才能保证当数据库发生宕机重启时,数据不会丢失。
当执行一条 SQL 更新语句时,过程如下:
可以看到,在“两阶段提交”阶段,将 redo log 的写入分成了两步:prepare 和 commit。在 redo log 状态为 prepare 时记录 binlog 可以保证两个日志的记录一致。
五、如果数据库误操作, 如何执行数据恢复?
DB宕机后重启,InnoDB 会首先去查看数据页中的LSN的数值。这个值代表数据页被刷新回磁盘的 LSN 的大小。然后再去查看 redo log 的 LSN 的大小。
如果数据页中的 LSN 值大说明数据页领先于 redo log 刷新回磁盘,不需要进行恢复。反之需要从redo log中恢复数据。
注:LSN 是 日志序列号, 为 log sequence number 的缩写,主要用于发生 crash 时对数据进行 recovery。LSN是一个一直递增的整型数字,表示事务写入到日志的字节总量。
LSN 不仅只存在于重做日志中,在每个数据页头部也会有对应的 LSN 号,该 LSN 记录当前页最后一次修改的 LSN 号,用于在 recovery 时对比重做日志 LSN 号决定是否对该页进行恢复数据。
前面说的check point也是由 LSN 号记录的,LSN 号串联起一个事务开始到恢复的过程。
如果将 innodb_flush_log_at_trx_commit 和 sync_binlog 参数设置成 1,前者表示每次事务的 redo log 都直接持久化到磁盘,后者表示每次事务的 binlog 都直接持久化到磁盘,可以双重保证 MySQL 异常重启之后的数据不会丢失。
原文:https://www.cnblogs.com/sunshineliulu/p/10905483.html
原文地址:https://www.cnblogs.com/ivy-zheng/p/11094528.html
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- typescript实战总结之实现一个互联网黑白墙
- 文件上传漏洞演示(一句话木马文件 + 蚁剑)
- [Bazel]构建Golang项目
- 2020--IDEA破解失败后无法打开(mac/win)【已解决】
- CPU:别再拿我当搬砖工!
- 7类 登录/注册 安全漏洞
- 安全弹出你的移动设备,保护数据安全!
- burpsuite系列
- idea_Maven_setting文件依赖源国内镜像
- Wapiti安装及使用
- 利用burpsuite+sqlmap POST自动化注入详解
- GSoC: GitHub Checks API 项目第一阶段总结
- GoldenEye靶机渗透
- RBash - 受限的Bash绕过
- 【Rust日报】2020-08-10:在 Rust 中存储连续数据