MySQL

77-MySQL-日志

2023-01-13  本文已影响0人  紫荆秋雪_文

MySQL8.0 官网日志地址

一、MySQL支持的日志

MySQL有不同类型的日志文件,用来存储不同类型的日志,分为 二进制日志错误日志通用查询日志慢查询日志 ,这也是常用的4种。MySQL 8又新增两种支持的日志: 中继日志数据定义语句日志 。使用这些日志文件,可以查看MySQL内部发生的事情

1.1、日志的弊端

二、慢查询日志(slow query log)

三、通用查询日志(general query log)

通用查询日志用来 记录用户的所有操作,包括启动和关闭MysQL服务、所有用户的连接开始时间截止时间、发给 MySQL 数据库服务器的所有 SQL 指令等。当我们的数据发生异常时,查看通用查询日志,还原操作时的具体场景,可以帮助我们准确定位问题。

3.1问题场景

在电商系统中,购买商品并且使用微信支付完成以后,却发现支付中心的记录并没有新增,此时用户再次使用支付宝支付,就会出现 重复支付 的问题。但是当去数据库中查询数据的时候,会发现只有一条记录存在。那么此时给到的现象就是只有一条支付记录,但是用户却支付了两次。
我们对系统进行了仔细检查,没有发现数据问题,因为用户编号订单编号以及第三方流水号都是对的。可是用户确实支付了两次,这个时候,我们想到了检查通用查询日志,看看当天到底发生了什么。
查看之后,发现:1月1日下午2点,用户使用微信支付完以后,但是由于网络故障,支付中心没有及时收到微信支付的回调通知,导致当时没有写入数据。1月1日下午2点30,用户又使用支付宝支付,此时记录更新到支付中心。1月1日晚上9点,微信的回调通知过来了,但是支付中心已经存在了支付宝的记录,所以只能覆盖记录了。

3.2查看当前状态

SHOW VARIABLES LIKE '%general%';
查看当前通用查询日志状态.png

3.3 启动日志

3.3.1 永久性启动日志

修改my.cnf或者my.ini配置文件来设置。在[mysqld]组下加入log选项,并重启MySQL服务。如果不指定目录和文件名,通用查询日志将默认存储在MySQL数据目录中的hostname.log文件中,hostname表示主机名

[mysqld]
general_log=ON
#  日志文件所在目录路径,filename为日志文件名
general_log_file=[path[filename]] 
3.3.2 临时性启动日志
SET GLOBAL general_log=on;
SET GLOBAL general_log_file=’path/filename’;
SET GLOBAL general_log=off;
SHOW VARIABLES LIKE 'general_log%';

3.4 查看日志

通用查询日志是以 文本文件 的形式存储在文件系统中的,可以使用 文本编辑器 直接打开日志文件。每台MySQL服务器的通用查询日志内容是不同的

SHOW VARIABLES LIKE 'general_log%';
cat raven-mysql-0.log 
usr/sbin/mysqld, Version: 8.0.31 (MySQL Community Server - GPL). started with:
Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument
2022-12-14T15:17:44.115654Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:44.118549Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:44.119479Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ select database()
2022-12-14T15:17:44.123749Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:44.126374Z        16 Query     SELECT @@session.transaction_isolation
2022-12-14T15:17:47.151800Z        16 Query     SELECT @@session.transaction_isolation
2022-12-14T15:17:47.154022Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ set session transaction read write
2022-12-14T15:17:47.156549Z        16 Query     SELECT @@session.transaction_read_only
2022-12-14T15:17:47.158780Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:47.160113Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ SET net_write_timeout=600
2022-12-14T15:17:47.160770Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ SHOW VARIABLES LIKE 'general_log%'
2022-12-14T15:17:47.180542Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:47.186542Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:47.188044Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ select database()
2022-12-14T15:17:47.191568Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:47.193943Z        16 Query     SELECT @@session.transaction_isolation
2022-12-14T15:17:51.753388Z        16 Query     SELECT @@session.transaction_isolation
2022-12-14T15:17:51.754277Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ set session transaction read write
2022-12-14T15:17:51.757078Z        16 Query     SELECT @@session.transaction_read_only
2022-12-14T15:17:51.759036Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:51.760204Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ select database()
2022-12-14T15:17:51.764532Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:51.766647Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:51.768083Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ SET net_write_timeout=600
2022-12-14T15:17:51.768694Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ SET SQL_SELECT_LIMIT=501
2022-12-14T15:17:51.769289Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ SELECT *
FROM student
2022-12-14T15:17:51.784761Z        16 Query     SHOW WARNINGS
2022-12-14T15:17:51.789334Z        16 Query     SELECT @@session.transaction_isolation
2022-12-14T15:18:56.781345Z        16 Query     SELECT @@session.transaction_isolation
2022-12-14T15:18:56.782926Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ set session transaction read write
2022-12-14T15:18:56.785348Z        16 Query     SELECT @@session.transaction_read_only
2022-12-14T15:18:56.786850Z        16 Query     SHOW WARNINGS
2022-12-14T15:18:56.788342Z        16 Query     SELECT @@session.transaction_read_only
2022-12-14T15:18:56.788922Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ SET net_write_timeout=600
2022-12-14T15:18:56.789465Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ SET SQL_SELECT_LIMIT=DEFAULT
2022-12-14T15:18:56.790033Z        16 Query     /* ApplicationName=DataGrip 2022.3.2 */ INSERT INTO student
VALUES (22, 'Raven-22', '五班'),
       (23, 'Raven-23', '五班'),
       (24, 'Raven-24', '五班')

3.5、停止日志

3.5.1、永久性停止日志

修改 my.cnf 或者 my.ini文件,把[mysqld]组下的 general_log 值设置为 OFF 或者把general_log一项注释掉。修改保存后,再 重启MySQL服务 ,即可生效

[mysqld]
general_log=OFF

[mysqld]
#general_log=ON
3.5.2、临时性停止日志
SET GLOBAL general_log=off;
SHOW VARIABLES LIKE 'general_log%';

3.6 删除/刷新日志

如果数据的使用非常频繁,那么通用查询日志会占用服务器非常大的磁盘空间。数据管理员可以删除很长时间之前的查询日志,以保证MySQL服务器上的硬盘空间。

3.6.1 手动删除文件
#  /var/lib/mysql/raven-mysql-0.log
SHOW VARIABLES LIKE 'general_log%';

刷新MySQL数据目录,发现创建了新的日志文
件。前提一定要开启通用日志

mysqladmin -uroot -p flush-logs

如果希望备份旧的通用查询日志,就必须先将旧的日志文件复制出来或者改名,然后执行上面的mysqladmin命令。正确流程如下

#  输入自己的通用日志文件所在目录
cd mysql-data-directory 
#  指名就的文件名 以及 新的文件名
mv mysql.general.1og mysql.general.1og.old 

mysqladmin -uroot -p flush-logs

四、错误日志(error log)

错误日志记录了 MySQL 服务器启动停止运行的时间,以及系统启动运行和停止过程中的诊断信息,包括错误警告提示等。
通过错误日志可以查看系统的运行状态,便于即时发现故障修复故障。如果MySQL服务 出现异常,错误日志是发现问题、解决故障的 首选

4.1启动日志

在MySQL数据库中,错误日志功能是 默认开启 的。而且,错误日志 无法被禁止

4.1.1启动日志文件路径配置

默认情况下,错误日志存储在MySQL数据库的数据文件夹下,名称默认为 mysqld.log (Linux系统)或hostname.err (mac系统)。如果需要制定文件名,则需要在my.cnf或者my.ini中做如下配置,修改配置项后,需要重启MySQL服务才能生效

[mysqld]
#  path为日志文件所在的目录路径,filename为日志文件名
log-error=[path/[filename]] 

4.2查看日志

SHOW VARIABLES LIKE 'log_err%';
image.png

4.3 删除/刷新日志

对于很久以前的错误日志,数据库管理员查看这些错误日志的可能性不大,可以将这些错误日志删除,以保证MySQL服务器上的 硬盘空间 。MySQL的错误日志是以文本文件的形式存储在文件系统中的,可以直接删除

在运行状态下删除错误日志文件后,MySQL并不会自动创建日志文件

rm -f /var/lib/mysgl/mysqld.1og
mv /var/log/mysqld.log /var/log/mysqld.log.old
mysqladmin -u root -p flush-logs
mysqladmin: refresh failed; 
error: 'Could not open file '/var/log/mysqld.log' 
for error logging.'
install -omysql -gmysql -m0644 /dev/null /var/log/mysqld.log

4.4 MySQL8.0新特性

MySQL8.0里对错误日志的改进。MySQL8.0的错误日志可以理解为一个全新的日志,在这个版本里,接受了来自社区的广泛批评意见,在这些意见和建议的基础上生成了新的日志

4.4.1 来自社区的意见
4.4.2 针对这些意见,MySQL做了如下改变
4.4.3 小结

通常情况下,管理员不需要查看错误日志。但是,MySQL服务器发生异常时,管理员可以从错误日志中找到发生异常的时间、原因,然后根据这些信息来解决异常

五、二进制日志(bin log)

binlog可以说是MySQL中比较 重要 的日志了,在日常开发及运维过程中,经常会遇到。
binlog即binary log,二进制日志文件,也叫作变更日志 (update log)。它记录了数据库所有执行的DDLDML等数据库更新事件的语句,但是不包含没有修改任何数据的语句 (如数据查询语句select、show等)。
它以 事件形式 记录并保存在 二进制文件 中。通过这些信息,我们可以再现数据更新操作的全过程。

5.1、binlog主要应用场景

5.1.1、数据恢复

如果MySQL数据库意外停止,可以通过二进制日志文件来查看用户执行了哪些操作,对数据库服务器文件做了哪些修改,然后根据二进制日志文件中的记录来恢复数据库服务器。

5.1.2、数据复制

由于日志的延续性时效性,master把它的二进制日志传递给slaves来达到master-slave数据一致的目的。可以说MySQL数据库的数据备份、主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性

image.png

5.2、查看默认情况

查看记录二进制日志是否开启:在MySQL8中默认情况下,二进制文件是开启的

SHOW VARIABLES LIKE '%log_bin%';
image.png

5.3、日志参数设置

5.3.1、永久性方式

修改MySQL的 my.cnfmy.ini文件可以设置二进制日志的相关参数,重新启动MySQL服务生效

[mysqld]
#  启用二进制日志
log-bin=atguigu-bin
binlog_expire_logs_seconds=600
max_binlog_size=100M
5.3.2、设置带文件夹的bin-log日志存放目录

如果想改变日志文件的目录和名称,可以对my.cnf或my.ini中的log_bin参数修改如下

[mysqld]
log-bin="/var/lib/mysql/binlog/atguigu-bin"
5.3.3、新建的文件夹需要使用mysql用户,使用下面的命令即可
chown -R -v mysql:mysql binlog
5.3.4、小结

数据库文件最好不要与日志文件放在同一个磁盘上!这样,当数据库文件所在的磁盘发生故障时,可以使用日志文件恢复数据

5.3.5、临时性方式

如果不希望通过修改配置文件并重启的方式设置二进制日志的话,还可以使用如下指令,需要注意的是在mysql8中只有 会话级别 的设置,没有了global级别的设置。

# GLOBAL 级别
SET GLOBAL sql_log_bin = 0;

[HY000][1228] Variable 'sql_log_bin' is a SESSION variable and can't be used with SET GLOBAL
# session级别
SET sql_log_bin=0;

5.4 查看日志

当MySQL创建二进制日志文件时,先创建一个以filename为名称、以.index为后缀的文件,再创建一个以filename为名称、以.000001为后缀的文件。
MySQL服务 重新启动一次 ,以.000001为后缀的文件就会增加一个,并且后缀名按1递增。即日志文件的个数与MySQL服务启动的次数相同;如果日志长度超过了 max_binlog_size 的上限(默认是1GB),就会创建一个新的日志文件。

SHOW BINARY LOGS;
image.png
UPDATE student
SET name= '张三back'
WHERE id = 1;
mysqlbinlog /var/lib/mysql/binlog.000054;
mysqlbinlog -v --base64-output=DECODE-ROWS "/var/lib/mysql/binlog.000054"
mysqlbinlog --no-defaults --help
mysqlbinlog --no-defaults --base64-output=decode-rows -vv atguigu-bin.000002 |tail -100
mysqlbinlog --no-defaults --base64-output=decode-rows -vv atguigu-bin.000002 |grep -A
20 '4939002'
show binlog events [IN 'log_name' ] [FROM pos] [LIMIT [offset,] row_count];
 show binlog events in 'binlog.000054';
#a、查询第一个最早的binlog日志
show binlog events\G;

#b、指定查询mysql-bin.000054这个文件
show binlog events in 'binlog.000054'\G;

#c、指定查询mysql-bin.000054这个文件,从pos点:391开始查起:
show binlog events in "binlog.000054' from 391\G;

#d、指定查询mysql-bin.000054这个文件,从pos点:391开始查起,查询5条(即5条语句)
show binlog events in 'binlog.000054' from 391 limit 5\G;

#e、指定查询 mysql-bin.000054这个文件,从pos点:391开始查起,偏移2行(即中间跳过2个)查询5条(即5条语句)
show binlog events in 'atguigu-bin.000054' from 391 limit 2,5\G;
show variables like 'binlog_format';

5.5 使用日志恢复数据

如果MysQL服务器启用了二进制日志,在数据库出现意外丢失数据时,可以使用MySQLbinlog工具从指定的时间点开始(例如,最后一次备份)直到现在或另一个指定的时间点的日志中恢复数据

5.5.1 使用日志恢复数据
上一篇 下一篇

猜你喜欢

热点阅读