第17章 其它数据库日志
1. MySQL支持的日志
1.1 日志类型
MySQL有不同类型的日志文件,用来存储不同类型的日志,分为二进制日志、错误日志、通用查询日志和慢查询日志,这也是常用的4种。MySQL 8又新增两种支持的日志:中继日志和数据定义语句日志。使用这些日志文件,可以查看MySQL内部发生的事情。
-
慢查询日志: 记录所有执行时间超过long_query_time的所有查询,方便我们对查询进行优化。(第九章_性能分析工具中有讲)
-
通用查询日志: 记录所有连接的起始时间和终止时间,以及连接发送给数据库服务器的所有指令,对我们复原操作的实际场景、发现问题,甚至是对数据库操作的审计都有很大的帮助。
-
错误日志: 记录MySQL服务的启动、运行或停止MySQL服务时出现的问题,方便我们了解服务器的状态,从而对服务器进行维护。
-
二进制日志: 记录所有更改数据的语句,可以用于主从服务器之间的数据同步,以及服务器遇到故障时数据的无损失恢复。
-
中继日志: 用于主从服务器架构中,从服务器用来存放主服务器二进制日志内容的一个中间文件。从服务器通过读取中继日志的内容,来同步主服务器上的操作。
-
数据定义语句日志: 记录数据定义语句执行的元数据操作。
除二进制日志外,其他日志都是文本文件。默认情况下,所有日志创建于MySQL数据目录中。
1.2 日志的弊端
-
日志功能会
降低MySQL数据库的性能。 -
日志会
占用大量的磁盘空间。
2. 通用查询日志(general query log)
通用查询日志用来记录用户的所有操作,包括启动和关闭MySQL服务、所有用户的连接开始时间和截止时间、发给 MySQL 数据库服务器的所有 SQL 指令等。当我们的数据发生异常时,查看通用查询日志,还原操作时的具体场景,可以帮助我们准确定位问题。
2.1 查看当前状态
mysql> SHOW VARIABLES LIKE '%general%';
2.2 启动日志
方式1:永久性方式
方式2:临时性方式
SET GLOBAL general_log=on;
# 开启通用查询日志
SET GLOBAL general_log_file=’path/filename’;
# 设置日志文件保存位置
SET GLOBAL general_log=off;
# 关闭通用查询日志
SHOW VARIABLES LIKE 'general_log%';
# 查看设置后情况
2.3 停止日志
方式1:永久性方式
方式2:临时性方式
3.错误日志(error log)
3.1 启动日志
3.2 查看日志
mysql> SHOW VARIABLES LIKE 'log_err%';
3.3 删除\刷新日志
4. 二进制日志(bin log)
4.1 查看默认情况
4.2 日志参数设置
方式1:永久性方式
重启
systemctl restart mysqld查看/var/lib/mysql设置带文件夹的bin-log日志存放目录
方式2:临时性方式
# global 级别
mysql> set global sql_log_bin=0;
ERROR 1228 (HY000): Variable 'sql_log_bin' is a SESSION variable and can`t be used with SET GLOBAL
# session级别
mysql> SET sql_log_bin=0;
Query OK, 0 rows affected (0.01 秒)
4.3 查看日志
-
方式一 {--
--}
(--
--}
# 可查看参数帮助 mysqlbinlog --no-defaults --help # 查看最后100行 mysqlbinlog --no-defaults --base64-output=decode-rows -vv atguigu-bin.000002 |tail -100 # 根据position查找 mysqlbinlog --no-defaults --base64-output=decode-rows -vv atguigu-bin.000002 |grep -A20 '4939002' -
方式二
上面这种办法读取出binlog日志的全文内容比较多,不容易分辨查看到pos点信息,下面介绍一种更为方便的查询命令:
mysql> show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];IN 'log_name':指定要查询的binlog文件名(不指定就是第一个binlog文件)FROM pos:指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算)LIMIT [offset]:偏移量(不指定就是0)row_count:查询总条数(不指定就是所有行)
-- eg: mysql> show binlog events in 'atguigu-bin.000002';
4.4 使用日志恢复数据
filename:是日志文件名。option:可选项,比较重要的两对option参数是--start-date、--stop-date 和 --start-position、-- stop-position。--start-date 和 --stop-date:可以指定恢复数据库的起始时间点和结束时间点。--start-position和--stop-position:可以指定恢复数据的开始位置和结束位置。
注意:
- 使用mysqlbinlog命令进行恢复操作时,必须是编号小的先恢复,例如atguigu-bin.000001必须在atguigu-bin.000002之前恢复。
- 利用 4.3 查看日志
- 方式一进行查看, 可以选定指定 时间戳
- 方式二进行查看, 可以选定指定 pos 点
eg:
方式一 :
方式二 :
4.5 删除二进制日志
PURGE {MASTER | BINARY} LOGS TO ‘指定日志文件名’
-- [开始 , 指定文件)
PURGE {MASTER | BINARY} LOGS BEFORE ‘指定日期’
5. 再谈二进制日志(binlog)
5.1 写入机制
binlog的写入时机也非常简单,事务执行过程中,先把日志写到binlog cache,事务提交的时候,再把binlog cache写到binlog文件中。因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache。
write和fsync的时机,可以由参数
sync_binlog控制,默认是 0。为0的时候,表示每次提交事务都只write,由系统自行判断什么时候执行fsync。虽然性能得到提升,但是机器宕机,page cache里面的binglog 会丢失。如下图:
为了安全起见,可以设置为
1,表示每次提交事务都会执行fsync,就如同redo log 刷盘流程一样。
最后还有一种折中方式,可以设置为N(N>1),表示每次提交事务都write,但累积N个事务后才fsync。
在出现IO瓶颈的场景里,将sync_binlog设置成一个比较大的值,可以提升性能。同样的,如果机器宕机,会丢失最近N个事务的binlog日志。
5.2 binlog与redolog对比
- redo log 它是
物理日志,记录内容是“在某个数据页上做了什么修改”,属于 InnoDB 存储引擎层产生的。 - 而 binlog 是
逻辑日志,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”,属于MySQL Server 层。 - 虽然它们都属于持久化的保证,但是侧重点不同。
- redo log 让InnoDB存储引擎拥有了
崩溃恢复能力。 - binlog保证了
MySQL集群架构的数据一致性
- redo log 让InnoDB存储引擎拥有了
5.3 两阶段提交
在执行更新语句过程,会记录redo log与binlog两块日志,以基本的事务为单位,redo log在事务执行过程中可以不断写入,而binlog只有在提交事务时才写入,所以redo log与binlog的写入时机不一样。
{--
--}
- 为了解决两份日志之间的逻辑一致问题,InnoDB存储引擎使用两阶段提交方案。原理很简单, 将 redo log 的写入拆分成了两个步骤 prepare 和 commit, 这就是两阶段提交
- 情况一
- 情况二
另一个场景,redo log设置commit阶段发生异常,那会不会回滚事务呢?
并不会回滚事务,它会执行上图框住的逻辑,虽然redo log是处于prepare阶段,但是能通过事务id找到对应的binlog日志,所以MySQL认为是完整的,就会提交事务恢复数据。
- 情况一
6. 中继日志(relay log)
6.1 介绍
中继日志只在主从服务器架构的从服务器上存在。从服务器为了与主服务器保持一致,要从主服务器读取二进制日志的内容,并且把读取到的信息写入本地的日志文件中,这个从服务器本地的日志文件就叫中继日志。然后,从服务器读取中继日志,并根据中继日志的内容对从服务器的数据进行更新,完成主从服务器的数据同步。
6.2 查看中继日志
6.3 恢复的典型错误
- 如果从服务器宕机,
- 有的时候为了系统恢复,要重装操作系统,这样就可能会导致你的
服务器名称与之前不同。- 而中继日志里是
包含从服务器名的。在这种情况下,就可能导致你恢复从服务器的时候,无法从宕机前的中继日志里读取数据,以为是日志文件损坏了,其实是名称不对了。
- 而中继日志里是
- 有的时候为了系统恢复,要重装操作系统,这样就可能会导致你的
解决的方法也很简单,把从服务器的名称改回之前的名称。