MySQL日志简介

img

错误日志

默认是否开启:开启

默认路径及文件名:

  • 源码和二进制安装:datadir/$hostname.err
  • yum安装:/var/log/mysql.log

是否可以修改:可以

作用:查看MySQL启动时的报错 找[Error]

如何修改:

mysql> show variables like 'log_error';
+---------------+------------+
| Variable_name | Value      |
+---------------+------------+
| log_error     | ./db01.err |
+---------------+------------+

[root@db02 ~]# vim /etc/my.cnf
[mysqld]
log_error=/tmp/db01.err

## 日志文件必须提前创建出来,并且针对mysql用户有写入权限
touch /tmp/db01.err
chown -R mysql.mysql /tmp/db01.err

一般查询日志

默认是否开启:

默认路径及文件名:datadir/$hostname.log

是否可以修改:可以

作用:记录mysql所有执行成功的SQL语句信息,可以做审计用,但是我们很少开启。

如何修改:

# 查看变量可以看到
mysql> show variables like '%general%';
+------------------+--------------------------+
| Variable_name    | Value                    |
+------------------+--------------------------+
| general_log      | OFF                      |
| general_log_file | /app/mysql/data/db01.log |
+------------------+--------------------------+

### 常规日志开启(在企业中是不会开启该日志,数据量太大了)
vim /etc/my.cnf
[mysqld]
general_log=1
general_log_file=/tmp/db01.log

二进制日志(binlog)

默认是否开启:

mysql> show variables like '%log_bin%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin                         | OFF   |
+---------------------------------+-------+

## 常规日志日志名:
mysql-bin.000001
mysql-bin.000002
mysql-bin.000003
mysql-bin.000004

默认路径及文件名:$datadir 数据目录下

是否可以修改:可以

作用:

  • 1,记录已结束的DML事务语句,并拆分为多个事件(event)来进行记录
  • 2,记录所有对库表造成变化的SQL语句 DML DDL DCL

如何修改:

## 以下修改方式为 MySQL5.6
# 方式一:它默认就是在/data下
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
binlog_format=row

# 方式二:可以加绝对路径
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
log-bin=/app/mysql/data/mysql-bin
binlog_format=row

# 方式三:可以自定义名字
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
log-bin=/tmp/hg-bin
binlog_format=row

## MySQL5.7修改方式
MySQL5.7想要开binlog必须配置 server_id
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
server_id=1
log-bin=mysql-bin
binlog_format=row

# mysql-bin.index :MySQL二进制日志binlog的索引文件,有几个binlog会记录几个binlog

二进制日志的工作模式

  • statment:语句模式(MySQL5.6默认的工作模式)
# 查看默认的工作模式
mysql> show variables like  'binlog_format';
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+

# statment :将所有的语句,记录在binlog中
    优点:通俗易懂,占用磁盘空间小
    缺点:不记录数据修改过程 不严谨
  • row:行级模式(MySQL5.7的默认工作模式)
# 查看默认的工作模式
mysql> show variables like  'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+

# row :将所有的语句及变化过程,记录在binlog中
    优点:记录数据修改过程 严谨
    缺点:不易懂、占用磁盘空间大(但企业中严谨比磁盘空间重要)
  • mixed:混合模式
# 语句模式和行级模式的混合模式 (狗都不用)
# 该模式会自己判断,什么时候只记录语句,什么时候记录语句和变化过程

工作模式如何修改

# 修改配置文件 重启数据库 即可
[root@db02 data]# vim /etc/my.cnf
[mysqld]
log-bin=/app/mysql/data/mysql-bin
binlog_format=row

[root@db02 data]# /etc/init.d/mysqld restart

查看binlog

## 查看语句模式
mysqlbinlog binlog名字
[root@db01 ~]# mysqlbinlog mysql-bin.000001

## 查看行级模式(行级模式有加密)-vvv --base64-output=decode-row 配合使用 解除加密 查看操作
[root@db01 ~]# mysqlbinlog -vvv --base64-output=decode-row mysql-bin.000001

## 库内查看当前有几个binlog日志及大小
mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       177 |
| mysql-bin.000002 |       468 |
| mysql-bin.000003 |       217 |
| mysql-bin.000004 |       796 |
| mysql-bin.000005 |       194 |
+------------------+-----------+

## 库内查看指定binlog日志的事件
mysql> show binlog events in 'mysql-bin.000001';
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000001 |   4 | Format_desc    |         1 |         123 | Server ver: 5.7.42-log, Binlog ver: 4 |
| mysql-bin.000001 | 123 | Previous_gtids |         1 |         154 |                                       |
| mysql-bin.000001 | 154 | Stop           |         1 |         177 |                                       |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+

# 查看当前的binlog
mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000005 |      194 |              |                  | f8e49854-358c-11ee-9756-000c294b61a6:1 |
+------------------+----------+--------------+------------------+----------------------------------------+

事件介绍

  • 在binlog中最小的记录单元为事件(event)
  • 一个事务会被拆分成多个事件(event)
## MySQL5.6 事件(event)特性
1)每个event都有一个开始位置(start position)和结束位置(stop position)。
2)所谓的位置就是event对整个二进制的文件的相对位置。
3)对于一个二进制日志中,前120个position是文件格式信息预留空间。
4)MySQL第一个记录的事件,都是从120开始的。
5)MySQL5.6空的binlog 143

## MySQL5.7 事件(event)特性
1)每个event都有一个开始位置(start position)和结束位置(stop position)。
2)所谓的位置就是event对整个二进制的文件的相对位置。
3)对于一个二进制日志中,前154个position是文件格式信息预留空间。
4)MySQL第一个记录的事件,都是从154开始的。
5)MySQL5.7空的binlog 177

二进制日志数据故障恢复

# 查看binlog信息
mysql>  show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000005 |      194 |              |                  | f8e49854-358c-11ee-9756-000c294b61a6:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

# 创建一个binlog库
mysql> create database binlog;
Query OK, 1 row affected (0.00 sec)

# 使用binlog库
mysql> use binlog;
Database changed

# 创建test_binlog表
mysql>  create table test_binlog(id int);
Query OK, 0 rows affected (0.00 sec)

# 插入数据1
mysql> insert into test_binlog values(1);
Query OK, 1 row affected (0.05 sec)

# 提交
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

# 查看binlog信息
mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000005 |      800 |              |                  | f8e49854-358c-11ee-9756-000c294b61a6:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

# 插入数据2
mysql> insert into test_binlog values(2);
Query OK, 1 row affected (0.00 sec)

# 插入数据3
mysql> insert into test_binlog values(3);
Query OK, 1 row affected (0.00 sec)

# 提交
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

# 查看binlog信息
mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000005 |     1332 |              |                  | f8e49854-358c-11ee-9756-000c294b61a6:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

# 查看test_binlog表内的内容
mysql> select * from test_binlog;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

# 更改数据1为10
mysql> update test_binlog set id=10 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

# 提交
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

# 查看test_binlog表内的信息
mysql> select * from test_binlog;
+------+
| id   |
+------+
|   10 |
|    2 |
|    3 |
+------+
3 rows in set (0.01 sec)

# 查看binlog信息
mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000005 |     1604 |              |                  | f8e49854-358c-11ee-9756-000c294b61a6:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

# 删除数据3
mysql> delete from test_binlog where id=3;
Query OK, 1 row affected (0.00 sec)

# 提交
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

# 查看test_binlog表内的信息
mysql> select * from test_binlog;
+------+
| id   |
+------+
|   10 |
|    2 |
+------+
2 rows in set (0.00 sec)

# 查看binlog信息
mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000005 |     1870 |              |                  | f8e49854-358c-11ee-9756-000c294b61a6:1 |
+------------------+----------+--------------+------------------+----------------------------------------+

# 查看库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

模拟数据故障

# 删除test_binlog表
mysql>  drop table test_binlog;
Query OK, 0 rows affected (0.01 sec)

# 删除binlog库
mysql> drop database binlog;
Query OK, 0 rows affected (0.00 sec)

# 查看binlog信息
mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000005 |     2217 |              |                  | f8e49854-358c-11ee-9756-000c294b61a6:1 |
+------------------+----------+--------------+------------------+----------------------------------------+

恢复数据

# 1.查看当前使用的是哪个binlog?
mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000005 |     2217 |              |                  | f8e49854-358c-11ee-9756-000c294b61a6:1 |
+------------------+----------+--------------+------------------+----------------------------------------+

# 一般binlog写入的都为最后一个
mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       177 |
| mysql-bin.000002 |       468 |
| mysql-bin.000003 |       217 |
| mysql-bin.000004 |       796 |
| mysql-bin.000005 |      2217 |
+------------------+-----------+

# 2.使用mysqlbinlog命令查看binlog内容
[root@db01 ~]# cd /app/mysql/data/
[root@db01 data]# [root@db01 data]# mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000005|head -25
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#230808 17:56:19 server id 1  end_log_pos 123 CRC32 0x496c7ac5  Start: binlog v 4, server v 5.7.42-log created 230808 17:56:19 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
# at 123
#230808 17:56:19 server id 1  end_log_pos 194 CRC32 0xa56df546  Previous-GTIDs
# f8e49854-358c-11ee-9756-000c294b61a6:1
# at 194
#230808 18:09:31 server id 1  end_log_pos 259 CRC32 0xec1f8e6f  Anonymous_GTID  last_committed=0        sequence_number=1       rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 259
#230808 18:09:31 server id 1  end_log_pos 359 CRC32 0x5d8ae956  Query   thread_id=5     exec_time=0     error_code=0
SET TIMESTAMP=1691489371/*!*/;
SET @@session.pseudo_thread_id=5/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1436549152/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create database binlog

[root@db01 data]# [root@db01 data]# mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000005|tail -25
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
# at 1839
#230808 18:11:51 server id 1  end_log_pos 1870 CRC32 0xe38497d7         Xid = 36
COMMIT/*!*/;
# at 1870
#230808 18:15:11 server id 1  end_log_pos 1935 CRC32 0x74250576         Anonymous_GTID  last_committed=7        sequence_number=8       rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1935
#230808 18:15:11 server id 1  end_log_pos 2063 CRC32 0x83e927bf         Query   thread_id=5     exec_time=0     error_code=0
SET TIMESTAMP=1691489711/*!*/;
DROP TABLE `test_binlog` /* generated by server */
/*!*/;
# at 2063
#230808 18:15:20 server id 1  end_log_pos 2128 CRC32 0x4bc30e26         Anonymous_GTID  last_committed=8        sequence_number=9       rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 2128
#230808 18:15:20 server id 1  end_log_pos 2217 CRC32 0x9fb16e51         Query   thread_id=5     exec_time=0     error_code=0
SET TIMESTAMP=1691489720/*!*/;
drop database binlog
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

# 3.先找到起始位置点
4

# 4.找到结束位置点
删表前1935    ##恢复到这有库表数据10,2
删库前2128    ##恢复到这只有库
# 1.要恢复到数据的状态 查看对应的binlog,找到起始位置点和结束位置点

# 5.截取binlog
[root@db01 data]# mysqlbinlog --start-position=4 --stop-position=1935 mysql-bin.000005 >/tmp/test_binlogbiao.sql

# 6.先临时关闭binlog的记录
mysql> set sql_log_bin=0;

# 7.恢复数据
mysql> source /tmp/test_binlogbiao.sql

# 8.开启binlog记录
mysql> set sql_log_bin=1;

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| binlog             |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

mysql> select * from test_binlog;
+------+
| id   |
+------+
|   10 |
|    2 |
+------+

以上恢复方法还存在的问题

  • 问题一:如果误删除的库是10年前创建的
# 解决方案:
全量备份,配合binlog的增量部分
  • 问题二:用户使用数据是穿插使用的,binlog也不是一个库一个库记录的
# 解决方案:
只损坏了wyk2这个库 其他库是好的 所以我们只需要过滤出,被删除的数据库相关binlog中的sql语句
使用-d指定数据库截取binlog
[root@db04 data]# mysqlbinlog -d wyk2 -vvv --base64-output=decode-row mysql-bin.000004

企业存在的问题

1)企业中的binlog很大,位置点不好找 grep

2)企业中所有数据不会只在一个binlog中 配合全备(mysqldump)

3)想要恢复的库,中途有其他库表操作,如何只截取指定库的

刷新binlog

## 以下情况会刷新binlog 也就是增加 binlog日志的数量
# 1.重启数据库会自动刷新binlog

# 2.当binlog大小达到1G的时候,会自动刷新出下一个binlog

# 3.库内手动执行 flush logs;

# 4.使用mysqladmin flush-log
[root@db01 data]# mysqladmin -uroot -p123 flush-log

# 5.使用mysqldump做备份时,可以刷新binlog    -A:全备  -F;刷新binlog 
[root@db01 data]# mysqldump -A -F > /tmp/full.sql

删除binlog

### 删除binlog的原则:
在存储能力范围内,能保留多少binlog就保留多少binlog

## 1.根据存在时间删除日志
# 库内执行(临时生效)删除7天之前的所有binlog日志
set global expire_logs_days = 7;

# 永久生效需要添加到配置文件内 然后重启数据库(不建议使用)
[root@db01 data]# vim /etc/my.cnf
[mysqld]
expire_logs_days = 7

## 2.库内执行 purge命令 删除指定时间段binlog,before now() 在什么之前 删除3天内的所有binlog日志
purge binary logs before now() - interval 3 day;

## 3.指定binlog名字删除,这种方法会删除你指定的binlog名字前面的所有binlog日志(推荐)
mysql> purge binary logs to 'mysql-bin.000005'; # 保留000005 删除000005前面的所有

## 4.reset master重置binlog,删除所有binlog,只剩一个001日志
mysql> reset master;
mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       154 |
+------------------+-----------+

MySQL慢查询日志

mysql> show variables like '%slow%';
+---------------------------+-------------------------------+
| Variable_name             | Value                         |
+---------------------------+-------------------------------+
| log_slow_admin_statements | OFF                           |
| log_slow_slave_statements | OFF                           |
| slow_launch_time          | 2                             |
| slow_query_log            | OFF                           |
| slow_query_log_file       | /app/mysql/data/db01-slow.log |
+---------------------------+-------------------------------+

## 常规日志日志名:
$HOSTNAME-slow.log

## 常规日志存储位置:
$datadir 数据目录下

## 常规日志默认是否开启:
关闭

## 如何修改配置:
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
#指定是否开启慢查询日志
slow_query_log = 1
#指定慢日志文件存放位置(默认在data)
slow_query_log_file=/application/mysql/data/slow.log
#设定慢查询的阀值(默认10s)
long_query_time=0.05
#不使用索引的慢查询日志是否记录到索引
log_queries_not_using_indexes
#查询检查返回少于该参数指定行的SQL不被记录到慢查询日志(鸡肋)
min_examined_row_limit=100

慢查询命令

[root@db01 data]# mysqldumpslow db01-slow.log

[root@db01 data]# mysqldumpslow -s c db01-slow.log
-s:指定如何排序
    c:count按照SQL语句的执行记录次数
    ac:按照SQL语句的执行记录次数 倒序排序

    t:time按照SQL语句的执行时间排序
    at:按照SQL语句的执行时间排序 倒序排序

    r:row按照SQL语句的执行返回记录数排序(查出来的数据)
    ar:按照SQL语句的执行返回记录数 倒序排序

    l:lock按照SQL语句的查询时间排序(查询的速度)
    al:按照SQL语句的查询时间 倒序排序

-t:top N (指定显示前N的内容)
-g:指定正则表达式