MySQL日志是记录MySQL数据库的日常操作和错误信息的文件。MySQL中,日志可以分为二进制日志、错误日志、通用查询日志和慢查询日志。分析这些日志文件,可以了解MySQL数据库的运行情况、日常操作、错误信息和哪些地方需要进行优化。接下来讲解的内容包括:
日志是MySQL数据库的重要组成部分。日志文件中记录着MySQL数据库运行期间发生的变化。当数据库遭到意外的损害时,可以通过日志文件来查询出错原因,并且可以通过日志文件进行数据恢复。接下来将介绍MySQL日志的含义、作用和优缺点。
MySQL日志是用来记录MySQL数据库的客户端连接情况、SQL语句的执行情况和错误信息等。例如,一个名为root的用户登录到MySQL服务器。日志中就会记录这个用户的登录时间、执行的操作等。再例如,MySQL服务在某个时间出现异常,异常信息会被记录到日志文件中。
MySQL日志可以分为4种,分别是二进制日志、错误日志、通用查询日志和慢查询日志。下面分别简单地介绍这4种日志文件的作用。
除二进制日志外,其他日志都是文本文件。日志文件通常存储在MySQL数据库的数据目录下。默认情况下,只启动了错误日志的功能。其他3类日志都需要数据库管理员进行设置。
说明:如果MySQL数据库系统意外停止服务,可以通过错误日志查看出现错误的原因。并且,可以通过二进制日志文件来查看用户分执行了哪些操作、对数据库文件做了哪些修改。然后,可以根据二进制日志中的记录来修复数据库。
但是,启动日志功能会降低MySQL数据库的执行速度。例如,一个査询操作比较频 繁的MySQL中,记录通用查询日志和慢查询日志要花费很多的时间。并且,日志文件会 占用大童的硬盘空间。对于用户量非常大、操作非常频繁的数据库,日志文件需要的存储 空间甚至比数据库文件需要的存储空间还要大。
二进制日志也叫作变更日志(update log),主要用于记录数据库的变化情况。通过二进制日志可以查询MySQL数据库中进行了哪些改变。
默认情况下,二进制日志功能是关闭的。
通过 my.cnf 或者 my.ini 文件的 log-bin 选项可以开启二进制日志。
将log_bin选项加入到 my.cnf 或者 my.ini 文件的[mysqld]组中形式如下:
-- my.cnf (Linux操作系统下)或者 my.ini (Windows操作系统下)
[mysqld]
log-bin[=DIR \ [filename]]
其中,DIR参数指定二进制文件的存储路径;filename参数指定二进制文件的文件名, 其形式为 filename.number,number的形式为000001、000002等。每次重启MySQL服务后,都会生成一个新的二进制日志文件,这些日志文件的“number”会不断递增。除了生成上述文件外,还会生成一个名为 filename.index 的文件。这个文件中存储所有二进制日志文件的清单。
技巧:二进制日志与数据库的数据文件最好不要放在同一块硬盘上。即使数据文件所在的硬盘被破坏,也可以使用另一块硬盘上的二进制日志来恢复数据库文件。两块硬盘同时坏了的可能性要小得多。这样可以保证数据库中数据的安全。
如果没有DIR参数 和 filename 参数,二进制日志将默认存储在数据库的数据目录下。
示例:下面在 /etc/mysql/my.cnf 文件的[mysqld]组中添加下面的语句:
log-bin
重启MySQL服务器后,可以在MySQL数据库的数据目录下看到binlog.000001这个文件,同时还生成了 binlog.index 文件。
通过如下语句可以查看二进制日志是否开启:
show variables like 'log_bin';
使用二进制格式可以存储更多的信息,并且可以使写入二进制日志的效率更高。但是, 不能直接打开并查看二进制日志。如果需要查看二进制日志,必须使用mysqlbinlog命令。 mysqlbinlog 命令的语法形式如下:
mysqlbinlog filename-number
mysqlbinlog命令 将在当前文件夹下査找指定的二进制日志。因此需要在二进制日志 filename.number所在的目录下运行该命令,否则将会找不到指定的二进制日志文件。
示例:下面使用mysqlbinlog命令,来查看默认目录下的binlog文件。
root@zy:/var/lib/mysql# mysqlbinlog binlog.000001
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
······
······
# at 1777
#190521 21:35:40 server id 1 end_log_pos 1894 CRC32 0xe52cafcd Query thread_id=16 exec_time=0 error_code=0 Xid = 44
SET TIMESTAMP=1558445740/*!*/;
/*!80016 SET @@session.default_table_encryption=0*//*!*/;
create database Logtest
·····
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1971
#190521 21:35:53 server id 1 end_log_pos 2084 CRC32 0xfbef23b6 Query thread_id=16 exec_time=0 error_code=0 Xid = 45
SET TIMESTAMP=1558445753/*!*/;
drop database Logtest
·····
上面是mylog.000001中的部分内容。上述内容中记录了创建Logtest和删除Logtest的信息。
使用mysqlbinlog命令时,可以指定二进制文件的存储路径。这样可以确保mysqlbinlog命令可以找到二进制日志文件。
二进制日志会记录大量的信息。如果很长时间不清理二进制日志,将会浪费很多的磁盘空间。删除二进制日志的方法很多。接下来将详细介绍如何删除二进制日志。
删除所有二进制日志
使用RESET MASTER语句可以删除所有二进制日志。该语句的形式如下:
RESET MASTER
登录MySQL数据库后,可以执行该语句来删除所有二进制日志。删除所有二进制日志后,MySQL将会重新创建新的二进制日志。新二进制日志的编号从000001开始,如 binlog.000001。
根据编号来删除二进制日志
每个二进制日志文件后面有一个6位数的编号,如000001。使用PURGE MASTER LOGS TO语句,可以删除指定二进制日志的编号之前的日志。该语句的基本语法形式如下:
PURGE MASTER LOGS TO 'filename.number';
该语句将删除编号小于这个二进制日志的所有二进制日志。
示例:下面删除binlog.000004之前的二进制日志:
PURGE MASTER LOGS TO 'binlog.000004';
代码执行完后,编号为000001、000002和000003的二进制日志将被删除。
根据创建时间来删除二进制日志
使用PURGE MASTER LOGS TO语句,可以删除指定时间之前创建的二进制日志。 该语句的基本语法形式如下:
PURGE MASTER LOGS TO 'yyyy-mm-dd hh:MM;ss';
其中,“hh”表示24小时制下的小时。该语句将删除在指定时间之前创建的所有二进 制日志。
示例:下面删除2019-5-20 15:00:00之前创建的二进制日志:
PURGE MASTER LOGS TO '2019-5-20 15:00:00';
代码执行完后,2019-5-20 15:00:00 之前创建的所有二进制日志将被删除。
二进制日志记录了用户对数据库中数据的改变。如INSERT语句、UPDATE语句、 CREATE语句等都会记录到二进制日志中。一旦数据库遭到破坏,可以使用二进制日志来还原数据库。接下来将详细介绍使用二进制日志还原数据库的方法。
如果数据库遭到意外损坏,首先应该使用最近的备份文件来还原数据库。备份之后, 数据库可能进行了一些更新。这可以使用二进制日志来还原。因为二进制日志中存储了更新数据库的语句,如UPDATE语句、INSERT语句等。
二进制日志还原数据库的命令如下:
mysqlbinlog filename.number | mysql -u root -p
这个命令可以这样理解:使用 mysqlbinlog 命令来读取filename.number中的内容,然后,使用 mysql 命令将这些内容还原到数据库中。
注意:二进制日志虽然可以用来还原MySQL数据库,但是其占用的磁盘空间也是非常大的。因此,在备份MySQL数据库之后,应该删除备份之前的二进制日志。如果备份之后发生异常,造成数据库的数据丢失,可以通过备份之后的二进制日志进行还原。
使用mysqlbinlog命令进行还原操作时,必须是编号(number)小的先还原。例如binlog.000001 必须在 binlog.000002之前还原。
示例:下面使用二进制日志来还原数据库:
mysqlbinlog binlog.000001 | mysql -u root -p
mysqlbinlog binlog.000002 | mysql -u root -p
mysqlbinlog binlog.000003 | mysql -u root -p
mysqlbinlog binlog.000004 | mysql -u root -p
在配置文件中设置了 log-bin 选项以后,MySQL服务器将会一直开启二进制日志功能。 删除该选项后就可以停止二进制日志功能。如果需要再次启动这个功能,又需要重新添加 log-bin选项。
MySQL中提供了暂时停止二进制日志功能的语句。
如果用户不希望自己执行的某些SQL语句记录在二进制日志中,那么需要在执行这些 SQL语句之前暂停二进制日志功能。用户可以使用SET语句来暂停二进制日志功能。SET 语句的代码如下:
SET SQL_LOG_BIN=0;
执行该语句后,MySQL服务器会暂停二进制日志功能。但是,只有拥有SUPER权限的用户才可以执行该语句。
如果用户希望重新开启二进制日志功能,可以使用下面的 SET 语句。
SET SQL_LOG_BIN=1;
错误日志是MySQL数据库中最常用的一种日志。错误日志主要用来记录MySQL服务的开启、关闭和错误信息。
在MySQL数据库中,错误日志功能是默认开启的。而且,错误日志无法被禁止。默认情况下,错误日志存储在MySQL数据库的数据文件夹下。错误日志文件通常的名称为 hostname.err,ubuntu 下Mysql 8.0 版本错误日志为 errno.log 。其中,hostname表示MySQL服务器的主机名。错误日志的存储位置可以通过 log-error 选项来设置。将log-error选项加入到 my.ini 或者 my.cnf 文件的[mysql]组中。 形式如下:
my.cnf (Linux操作系统下)或者my.ini (Windows操作系统下)
[mysqld]
log-error[=DIR / [filename]
其中,DIR参数指定错误日志的路径。filename参数是错误日志的名称,没有该参数时默认为主机名。重启MySQL服务后,这个参数开始生效,可以在指定路径下看到 filename.err 的文件;如果没有指定 filename,那么错误日志将直接默认为hostname.err。
错误日志中记录着开启和关闭MySQL服务的时间,以及服务运行过程中出现哪些异常等信息。如果MySQL服务出现异常,可以到错误日志中查找原因。
错误日志是以文本文件的形式存储的,可以直接使用普通文本工具就可以查看。 Windows操作系统可以使用文本文件查看器查看。
在Linux操作系统下,可以使用vi工具 或者使用gedit工具来查看。
示例:下面是博主MySQL服务器的错误日志的部分内容:
2019-05-21T13:10:09.541711Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2019-05-21T13:10:09.564315Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Ve rsion: '8.0.16' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
2019-05-21T13:10:09.747313Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/v ar/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060
2019-05-21T13:10:30.380561Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.16) MySQL Community Server - GPL.
2019-05-21T13:10:30.841258Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.16) starting a s process 112670
数据库管理员可以删除很长时间之前的错误日志,以保证MySQL服务器上的硬盘空间。MySQL数据库中,可以使用 mysqladmin 命令来开启新的错误日志。语法如下:
mysqladmin -u root -p flush-logs
执行该命令后,数据库系统会自动创建一个新的错误日志。旧的错误日志仍然保留着, 只是已经更名为filename.err-old。
除了 mysqladmin命令外,也可以使用FLUSH LOGS语句来开启新的错误日志。使用该语句之前必须先登录到MySQL数据库中。创建好新的错误日志之后,数据库管理员可以将旧的错误日志备份到其他的硬盘上。如果数据库管理员认为filename.err-old己经没有存在的必要,可以直接删除。
说明:通常情况下,管理员不需要查看错误日志。但是,MySQL服务器发生异常时, 管理员可以从错误日志中找到发生异常的时间、原因。然后根据这些信息来解决异常。对于很久以前的错误日志,管理员查看这些错误日志的可能性不大,可以将这些错误日志删除。
通用查询日志是用来记录用户的所有操作,包括启动和关闭MySQL服务、更新语句 和 査询语句等。本节将为读者介绍通用查询日志的内容。
默认情况下,通用查询日志功能是关闭的。通过 my.cnf 或者 my.ini 文件的log选项可以开启通用查询日志。将log选项加入到my.cnf或者my.ini文件的[mysqld]组中。形式 如下:
-- my.cnf (Linux操作系统下〉或者my.ini (Windows搡作系统下)
[mysqld]
general-log[=DIR \ [filename]]
其中,DIR参数指定通用查询日志的存储路径;filename参数指定日志的文件名。如果不指定存储路径,通用査询日志将默认存储到MySQL数据库的数据文件夹下。如果不指定文件名,默认文件名为hostname.log。hostname是MySQL服务器的主机名。
用户的所有操作都会记录到通用查询日志中。如果希望了解某个用户最近的操作,可以査看通用查询日志。通用查询日志是以文本文件的形式存储的。Windows操作系统可以使用文本文件查看器查看。Linux操作系统下,可以使用vi工具或者使用gedit工具来査看。
通用查询日志会记录用户的所有操作。如果数据库的使用非常频繁,那么通用查询日志将会占用非常大的磁盘空间。数据库管理员可以删除很长时间之前的通用查询日志,以保证MySQL服务器上的硬盘空间。
MySQL数据库中,也可以使用mysqladmin命令来开启新的通用查询日志。新的通用 查询日志会直接覆盖旧的査询日志,不需要再手动删除了。mysqladmin命令的语法如下:
mysqladmin -u root -p flush-logs
如果希望备份旧的通用查询日志,那么就必须先将旧的日志文件拷贝出来或者改名。 然后,再执行上面的mysqladmin命令。
除了上述方法以外,可以手工删除通用查询日志。删除之后需要重新启动MySQL服务。重启之后就会生成新的通用查询日志。如果希望备份旧的日志文件,可以将旧的曰志文件改名,然后重启MySQL服务。
慢查询日志是用来记录执行时间超过指定时间的查询语句。通过慢查询日志,可以查 找出哪些查询语句的执行效率很低,以便进行优化。
默认情况下,慢査询日志功能是关闭的。通过my.cnf或者my.ini文件的log-slow-queries选项可以开启慢查询日志。通过long_query_time选项来设置时间值,时间以秒为单位。如果查询时间超过了这个时间值,这个查询语句将被记录到慢查询日志。将log-slow-queries选项和long query time选项加入到my.cnf或者my.ini文件的[mysqld]组中。形式如下:
# my.cnf (Linux操作系统下)或者my.ini (Windows操作系统下)
[mysqld]
slow-query-log = 1
slow_query_log_file="xxx.log"
long_query_time=n
使用命令 set global long_query_time=4修改后,需要重新连接或新开一个会话才能看到修改值。用show variables like 'long_query_time’查看是当前会话的变量值。
执行时间超过指定时间的査询语句会被记录到慢査询日志中。如果用户希望査询哪些查询语句的执行效率低,可以从慢查询日志中获得想要的信息。慢查询日志也是以文本文件的形式存储的。可以使用普通的文本文件査看工具来查看。
下面是示例MySQL服务器的慢查询日志的部分内容。
我们设置的时长为0.0001s,时间非常短,便于测试,由上述结果可以看出查询语句被记录到慢査询日志中。
慢查询日志的删除方法与通用查询日志的删除方法是一样的。可以使用mysqladmin 命令来删除。也可以使用手工方式来删除。mysqladmin命令的语法如下:
mysqladmin -u root -p flush-logs
新的慢查询日志会直接覆盖旧的查询日志,不需要再手动删除了。数据库管理员也可以手工删除慢查询日志,删除之后需要重新启动MySQL服务,重启之后就会生成新的慢查询日志。 如果希望备份旧的慢查洵日志文件,可以将旧的日志文件改名,然后重启MySQL服务。
注意:通用查询日志和慢查询日志都是使用这个命令,使用时一定要注意。一旦执行这个命令,通用查询日志和慢查询日志都只存在新的日志文件中。如果希望备份旧的慢查询日志,必须先将旧的日志文件复制出来或者改名。然后,再执行上面的 mysqladmin 命令。