第17章 其它数据库日志

118 阅读7分钟

第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%';

image.png

2.2 启动日志

方式1:永久性方式

image.png

方式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:永久性方式 image.png 方式2:临时性方式 image.png

image.png image.png

3.错误日志(error log)

image.png

3.1 启动日志

image.png

3.2 查看日志
mysql> SHOW VARIABLES LIKE 'log_err%';

image.png

3.3 删除\刷新日志

image.png image.png

image.png

4. 二进制日志(bin log)

image.png image.png

4.1 查看默认情况

image.png

4.2 日志参数设置

方式1:永久性方式 image.png

重启 systemctl restart mysqld 查看 /var/lib/mysql 设置带文件夹的bin-log日志存放目录 image.png

image.png 方式2:临时性方式

image.png

# 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 查看日志
  • 方式一 {-- image.png

    image.png --} image.png (-- image.png--}

    # 可查看参数帮助 
    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';
    

image.png

4.4 使用日志恢复数据

image.png

  • 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:

方式一 : image.png 方式二 : image.png

4.5 删除二进制日志

image.png

PURGE {MASTER | BINARY} LOGS TO ‘指定日志文件名’ 
-- [开始 , 指定文件)
PURGE {MASTER | BINARY} LOGS BEFORE ‘指定日期’

image.png


image.png


image.png

5. 再谈二进制日志(binlog)

5.1 写入机制

binlog的写入时机也非常简单,事务执行过程中,先把日志写到binlog cache事务提交候,再把binlog cache写到binlog文件中。因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cacheimage.png image.png image.png write和fsync的时机,可以由参数sync_binlog控制,默认是 0。为0的时候,表示每次提交事务都只write由系统自行判断什么时候执行fsync。虽然性能得到提升,但是机器宕机,page cache里面的binglog 会丢失。如下图: image.png 为了安全起见,可以设置为1,表示每次提交事务都会执行fsync,就如同redo log 刷盘流程一样。

最后还有一种折中方式,可以设置为N(N>1),表示每次提交事务都write,但累积N个事务后才fsync。

image.png 在出现IO瓶颈的场景里,将sync_binlog设置成一个比较大的值,可以提升性能。同样的,如果机器宕机,会丢失最近N个事务的binlog日志。

5.2 binlog与redolog对比
  • redo log 它是物理日志,记录内容是“在某个数据页上做了什么修改”,属于 InnoDB 存储引擎层产生的
  • 而 binlog 是逻辑日志,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”,属于MySQL Server 层
  • 虽然它们都属于持久化的保证,但是侧重点不同。
    • redo log 让InnoDB存储引擎拥有了崩溃恢复能力
    • binlog保证MySQL集群架构的数据一致性
5.3 两阶段提交

在执行更新语句过程,会记录redo log与binlog两块日志,以基本的事务为单位,redo log在事务执行过程中可以不断写入,而binlog只有在提交事务时才写入,所以redo log与binlog的写入时机不一样。 image.png {-- image.png image.png image.png --}

  • 为了解决两份日志之间的逻辑一致问题,InnoDB存储引擎使用两阶段提交方案。原理很简单, 将 redo log 的写入拆分成了两个步骤 prepare 和 commit, 这就是两阶段提交 image.png
    • 情况一 image.png
    • 情况二 另一个场景,redo log设置commit阶段发生异常,那会不会回滚事务呢? image.png 并不会回滚事务,它会执行上图框住的逻辑,虽然redo log是处于prepare阶段,但是能通过事务id找到对应的binlog日志,所以MySQL认为是完整的,就会提交事务恢复数据。

6. 中继日志(relay log)

6.1 介绍

中继日志只在主从服务器架构的从服务器上存在。从服务器为了与主服务器保持一致,要从主服务器读取二进制日志的内容,并且把读取到的信息写入本地的日志文件中,这个从服务器本地的日志文件就叫中继日志。然后,从服务器读取中继日志,并根据中继日志的内容对从服务器的数据进行更新,完成主从服务器的数据同步

image.png image.png

6.2 查看中继日志

image.png

6.3 恢复的典型错误
  • 如果从服务器宕机,
    • 有的时候为了系统恢复,要重装操作系统,这样就可能会导致你的服务器名称与之前不同
      • 而中继日志里是包含从服务器名的。在这种情况下,就可能导致你恢复从服务器的时候,无法从宕机前的中继日志里读取数据,以为是日志文件损坏了,其实是名称不对了。

解决的方法也很简单,把从服务器的名称改回之前的名称。