前言
2022/8/13 12:51
暑假学习ing
推荐
【MySQL数据库教程天花板,mysql安装到mysql高级,强!硬!-哔哩哔哩】
第17章 其他数据库日志
我们在讲解数据库事务时,讲过两种日志:重做日志、回滚日志。
对于线上数据库应用系统,突然遭遇数据库宕机怎么办?在这种情况下,定位宕机的原因就非常关键。可以查看数据库的错误日志。因为日志中记录了数据库运行中的诊断信息,包括了错误、警告和注释等信息。比如:从日志中发现某个连接中的SQL操作发生了死循环,导致内存不足,被系统强行终止了。明确了原因,处理起来也就轻松了,系统很快就恢复了运行。
除了发现错误,日志在数据复制、数据恢复、操作审计,以及确保数据的永久性和一致性等方面,都有着不可替代的作用。
千万不要小看日志。很多看似奇怪的问题,答案往往就藏在日志里。很多情况下,只有通过查看日志才能发现问题的原因,真正解决问题。所以,一定要学会查看日志,养成检查日志的习惯,对提升你的数据库应用开发能力至关重要。
MySQL8.0官网日志地址:https://dev.mysql.com/doc/refman/8.0/en/server-logs.html
1.MySQL支持的日志
1.1日志类型
MySQL有不同类型的日志文件,用来存储不同类型的日志,分为二进制日志
、错误日志
、通用查询日志
和慢查询日志
,这也是常用的4种。MySQL 8又新增两种支持的日志:中继日志
和数据定义语句日志
。使用这些日志文件,可以查看MySQL内部发生的事情。
这6类日志分别为:
- 慢查询日志:记录所有执行时间超过long_query_time的所有查询,方便对查询进行优化。
通用查询日志:记录所有连接的起始时间和终止时间,以及连接发送给数据库服务器的所有指令,对复原操作的实际场景、发现问题,甚至是对数据库操作的审计都有很大的帮助。
错误日志:记录MySQL服务的启动、运行或停止MySQL服务时出现的问题,方便我们了解服务器的状态,从而从而对服务器进行维护。
二进制日志:记录所有更改数据的语句,可以用于主从服务器之间的数据同步,以及服务器遇到故障时数据的无损失恢复。
中继日志:用于主从服务器架构中,从服务器用来存放主服务器二进制日志内容的一个中间文件。从服务器通过读取中继日志的内容,来同步主服务器上的操作。
数据定义语句日志:记录数据定义语句执行的元数据操作。除二进制日志外,其他日志都是文本文件。默认情况下,所有日志创建于MySQL数据目录中。
除二进制日志外,其他日志都是文本文件
。默认情况下,所有日志创建于MySQL数据目录
中。
1.2日志的弊端
日志功能会降低MySQL数据库的性能。例如,在查询非常频繁的MySQL数据库系统中,如果开启了通用查询日志和慢查询日志,MySQL数据库会花费很多时间记录日志。
日志会占用大量的磁盘空间。对于用户量非常大、操作非常频繁的数据库,日志文件需要的存储空间设置比数据库文件需要的存储空间还要大。
2.慢查询日志(slow query log)
前面章节《第09章 性能分析工具的使用》已经详细讲述
第09章 性能分析工具的使用【2.索引及调优篇】【MySQL高级】
3.通用查询日志
通用查询日志用来记录用户的所有操作
,包括启动和关闭IMysQL服务、所有用户的连接开始时间和截止时间、发给MysQL数据库服务器的所有SQL指令等。当我们的数据发生异常时**,查看通用查询日志,还原操作时的具体场景**,可以帮助我们准确定位问题。
3.1问题场景
在电商系统中,购买商品并且使用微信支付完成以后,却发现支付中心的记录并没有新增,此时用户再次使用支付宝支付,就会出现重复支付的问题。但是当去数据库中查询数据的时候,会发现只有一条记录存在。那么此时给到的现象就是只有一条支付记录,但是用户却支付了两次。
对系统进行了仔细检查,没有发现数据问题,因为用户编号和订单编号以及第三方流水号都是对的。可是用户确实支付了两次,这个时候,我们想到了检查通用查询日志,看看当天到底发生了什么。
查看之后,发现: 1月1日下午2点,用户使用微信支付完以后,但是由于网络故障,支付中心没有及时收到微信支付的回调通知,导致当时没有写入数据。1月1日下午2点30,用户又使用支付宝支付,此时记录更新到支付中心。1月1日晚上9点,微信的回调通知过来了,但是支付中心已经存在了支付宝的记录,所以只能覆盖记录了。
由于网络的原因导致了重复支付。至于解决问题的方案就很多了,这里省略。
可以看到通用查询日志可以帮助我们了解操作发生的具体时间和操作的细节,对找出异常发生的原因极其关键。
3.2 查看当前状态
mysql> SHOW VARIABLES LIKE '%general%'; +------------------+------------------------------------+ | Variable_name | Value | +------------------+------------------------------------+ | general_log | OFF | | general_log_file | /var/lib/mysql/centos7-mysql-1.log | +------------------+------------------------------------+ 2 rows in set (0.01 sec)
说明1∶系统变量general_log的值是OFF,即通用查询日志处于关闭状态。在MySQL中,这个参数的默认值是关闭的。因为一旦开启记录通用查询日志,MySQL 会记录所有的连接起止和相关的SQL操作,这样会消耗系统资源并且占用磁盘空间。我们可以通过手动修改变量的值,在要的时候开启日志。
说明2:通用查询日志文件的名称是主机.log(centos7-mysql-1.log)。存储路径是/var/lib/mysql/,默认也是数据路径。这样我们就知道在哪里可以查看通用查询日志的内容了
3.3 启动日志
方式1:永久性方式
修改my.cnf或者my.ini配置文件来设置。在[mysqld]组下加入log选项,并重启MySQL服务。格式如下:
[mysqld] general_log=ON general_log_file=[path[filename]] #日志文件所在目录路径,filename为日志文件名
如果不指定目录和文件名,通用查询日志将默认存储在MySQL数据目录中的hostname.log文件中,hostname表示主机名。
方式2:临时性方式
使用SET语句停止MySQL通用查询日志功能:
SET GLOBAL general_log=on; # 开启通用查询日志 SET GLOBAL general_log_file='path/filename'; # 设置日志文件保存位置
对应的,关闭操作SQL命令如下:
SET GLOBAL general_log=off; # 关闭通用查询日志
查看设置后情况:
SHOW VARIABLES LIKE 'general_log%';
3.4 查看日志
通用查询日志是以文本文件 的形式存储在文件系统中的,可以使用文本编辑器 直接打开日志文件。每台MySQL服务器的通用查询日志内容是不同的。
在Windows操作系统中,使用文本文件查看器;
在Linux系统中,可以使用vi工具或者gedit工具查看;
在Mac OSX系统中,可以使用文本文件查看器或者vi等工具查看。
从SHOW VARIABLES LIKE ‘general_log%’; 结果中可以看到通用查询日志的位置。
[root@centos7-mysql-1 mysql]# vim centos7-mysql-1.log
/usr/sbin/mysqld, Version: 8.0.25 (MySQL Community Server - GPL). started with: Tcp port: 3306 Unix socket: /var/lib/mysql/mysql.sock Time Id Command Argument 2022-08-13T07:53:20.553426Z 8 Query SHOW VARIABLES LIKE '%general%' ~
/usr/sbin/mysqld, Version: 8.0.25 (MySQL Community Server - GPL). started with: Tcp port: 3306 Unix socket: /var/lib/mysql/mysql.sock Time Id Command Argument 2022-08-13T07:53:20.553426Z 8 Query SHOW VARIABLES LIKE '%general%' 2022-08-13T07:55:54.890076Z 8 Query SELECT DATABASE() 2022-08-13T07:55:54.890884Z 8 Init DB atguigudb3 2022-08-13T07:55:54.891761Z 8 Query show databases 2022-08-13T07:55:54.894469Z 8 Query show tables 2022-08-13T07:55:54.896959Z 8 Field List account 2022-08-13T07:55:54.901109Z 8 Field List class_comment 2022-08-13T07:55:54.905027Z 8 Field List class_comment1 2022-08-13T07:55:54.905935Z 8 Field List mylock 2022-08-13T07:55:54.907762Z 8 Field List student 2022-08-13T07:55:54.909025Z 8 Field List t1 2022-08-13T07:55:54.910411Z 8 Field List t2 2022-08-13T07:55:54.911197Z 8 Field List teacher 2022-08-13T07:55:54.911984Z 8 Field List test1 2022-08-13T07:55:54.912690Z 8 Field List test2 2022-08-13T07:55:54.913851Z 8 Field List test_load 2022-08-13T07:55:54.914996Z 8 Field List user1 2022-08-13T07:55:54.916575Z 8 Field List user3 2022-08-13T07:56:01.513469Z 8 Query show tables 2022-08-13T07:56:12.609141Z 8 Query select * from account
在通用查询日志里面,我们可以清楚地看到,什么时候开启了新的客户端登陆数据库,登录之后做了什么 SQL 操作,针对的是哪个数据表等信息。
3.5 停止日志
方式1:永久性方式
修改 my.cnf
或者 my.ini
文件,把[mysqld]组下的 general_log
值设置为 OFF
或者把general_log一项注释掉。修改保存后,再 重启MySQL服务
,即可生效。
举例1:
[mysqld] general_log=OFF
举例2:
[mysqld] #general_log=ON
方式2:临时性方式
使用SET语句停止MySQL通用查询日志功能:
SET GLOBAL general_log=off;
查询通用日志功能:
SHOW VARIABLES LIKE 'general_log%';
3.6 删除\刷新日志
如果数据的使用非常频繁,那么通用查询日志会占用服务器非常大的磁盘空间。数据管理员可以删除很长时间之前的查询日志,以保证MySQL服务器上的硬盘空间。
手动删除文件
SHOW VARIABLES LIKE 'general_log%';
可以看出,通用查询日志的目录默认为MySQL数据目录。在该目录下手动删除通用查询日志atguigu01.log。
使用如下命令重新生成查询日志文件,具体命令如下。刷新MySQL数据目录,发现创建了新的日志文件。前提一定要开启通用日志。
mysqladmin -uroot -p flush-logs
如果希望备份旧的通用查询日志,就必须先将旧的日志文件复制出来或者改名,然后执行上面的mysqladmin命令。正确流程如下
cd mysql-data-directory #输入自己的通用日志文件所在目录 mv mysql.general.log mysql.general.log.old #指名就的文件名 以及新的文件名 mysqladmin -uroot -p flush-logs
4. 错误日志(error log)
错误日志记录了MySQL服务器启动、停止运行的时间,以及系统启动、运行和停止过程中的诊断信息,包括错误
、警告
和提示
等。
通过错误日志可以查看系统的运行状态,便于即时发现故障、修复故障。如果MysQL服务出现异常
,错误日志是发现问题、解决故障的首选
。
4.1 启动日志
在MySQL数据库中,错误日志功能是 默认开启
的。而且,错误日志 无法被禁止
。
默认情况下,错误日志存储在MySQL数据库的数据文件夹下,名称默认为 mysqld.log
(Linux系统)或 hostname.err
(mac系统)。如果需要制定文件名,则需要在my.cnf或者my.ini中做如下配置:
[mysqld] log-error=[path/[filename]] #path为日志文件所在的目录路径,filename为日志文件名
修改配置项后,需要重启MySQL服务以生效。