1 概述
本文将介绍如下Mysql的六种日志的相关概念
查询日志:general_log
慢查询日志:log_slow_queries
错误日志:log_error, log_warnings
二进制日志:binlog
中继日志:relay_log
事务日志:innodb_log
2 查询日志
默认没有开启,考虑到数据库服务器本身占用存储IO,所以一般不会使用查询日志的功能,防止给mysql造成性能降低
记录查询语句,日志存储位置:
文件:file
表:table (mysql.general_log),在mysql库里
general_log={ON|OFF}:一般日志,日志功能的开关
general_log_file=HOSTNAME.log :日志输出的位置,有两个地方,如general_log_file指定的文件,还有下面的TABLE,
log_output={FILE|TABLE|NONE},启动general_log的时候,还要指定log_output为file或者table,如果定义为file,则general_log这张表就没用了,如果要两者都记录,就定义为file,table,如果不记录日志,就设定为none,即使是设定为on,也指定了log的路径,也不会记录日志,默认为file.
默认情况下,日志文件是当前主机名.log(注意,需要本机反向解析ip可以得到主机名才能为当前主机名,否则默认为localhost.log),没有session级别的参数,只有全局级别,查看如下
MariaDB [mysql]> show global variables like 'general%';
在global级别修改,但是该参数不支持session级别,所以参数也可以立即生效,设置如下
MariaDB [mysql]> set @@global.general_log=on;
开启后,在数据库中执行相关操作后,日志文件在当前主机名.log下,如这里是CentOS7A.log,如果是日志文件是相对路径,则默认该日志在数据目录下,即/var/lib/mysql/下面,这里的文件是/var/lib/mysql/CentOS7A.log,该文件有数据库操作的详细记录 ,查看如下
cat /var/lib/mysql/CentOS7A.log
改成TABLE类型,所有的日志都会被记录在mysql.general_log这张表里,文件/var/lib/mysql/CentOS7A.log将不再记录
MariaDB [mysql]> set @@global.log_output='table';
3 慢查询日志
慢查询:运行时间超出指定时长的查询,一般是指long_query_time指定的时长;
long_query_time:长时间的执行时间,默认单位是秒,默认是10s
查看变量可以有以下两种方法进行查看
MariaDB [mysql]> show global variables like 'long%';
MariaDB [mysql]> select @@global.long_query_time;
不是被其他语句阻塞或者是语句本身查询时间很长,查询很慢,需要启用慢查询来记录,这个一般要启用,用来分析系统的相关问题,如网页打开慢的问题
存储位置:
文件:FILE
表:TABLE,mysql.slog_log
log_slow_queries={ON|OFF}:启用慢查询,slow_query_log和是启用慢查询,不同mysql版本里启用的参数可能不一样,可能同时存在两个参数,如果要确保可以记录,建议这两个参数都启用
slow_query_log={ON|OFF}
slow_query_log_file=
log_output={FILE|TABLE|NONE}
log_slow_filter=admin,filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk:这里定义的条件的查询超过10s才记录到慢查询日志。这些一般是语句本身慢导致的
log_slow_rate_limit
log_slow_verbosity
慢查询的启用,注意,该log不会记录所有的操作,只记录log_slow_filter字段定义的条件,记录的日志在/var/lib/mysql/CentOS7A-slow.log
MariaDB [mysql]> set @@global.slow_query_log=ON;
启用 slow_query_log bool型值不需要加引号,如ON或off
以上的定义是临时有效的,全局的参数重启mysql后失效,会话级别的关闭session就会失效,要长期有效,需要配置到配置文件里
4 错误日志
记录如下四类信息:包括三种非错误的日志,如下
(1) mysqld启动和关闭过程中输出的信息;
(2) mysqld运行中产生的错误信息;
(3) event scheduler运行时产生的信息;#相当于是mysql内部的周期计划,和系统crontab一样的效果的计划
(4) 主从复制架构中,从服务器复制线程启动时产生的日志;
log_error=
/var/log/mariadb/mariadb.log|OFF #指定文件路径,即表示ON,如果不启用log_error,就直接用OFF来设定
log_warnings={ON|OFF}:#ON表示是否将warning级别的日志记录到log_error里面
通过rpm安装的mysql,默认会启用error日志,解压的方式安装可能没有启用,一般是要启用错误日志功能。
MariaDB [mysql]> select @@global.log_error;
5 二进制日志
服务器级别,跟引擎没关系,只能改配置参数才能生效,但是支持在会话级别指定关闭或者生效,一般不关闭该功能,只有要使用重放的时候,即做恢复的时候,才关闭该功能。需要在配置文件中修改才会生效。但是可以在会话级控制是否要记录对应的会话的二进制文件log
mysql运行过程中的修改类操作(引起数据改变,或者可能会引起数据改变的操作),未保存前,会记录到这里的二进制文件,服务器级别,跟引擎无关,二进制文件,不能使用cat等文本工具来查看,可能会导致文件被破坏,因为被保存未二进制格式,每一次的记录被保存未event,event根据位置来记录(根据偏移量决定 ,如第一个事件0--16,但是,最后的16是第一个事件的结束,没有被第一个事件暂用,是第二个事件的开始,如第二个事件为 16--36,这里36是第三个事件开始),这里用二进制编码来记录,作用是可以精确到用字节来记录来记录每一个事件的起始和结束位置
作为记录事件,要记录事件发生的时间和操作
二进制日志文件,作用是用来重放,当系统崩溃的时候,可以用来恢复系统用,建议将该日志放在独立的位置,用绝对日志,同时确保mysql用户有读写权限。需要修改配置文件才生效
二进制日志记录有三种格式
binlog_format={STATEMENT|ROW|MIXED}
STATEMENT:语句,即记录操作命令
ROW:行;
MIXED:混编;
用于记录引起数据改变或存在引起数据改变的潜在可能性的语句(STATEMENT)或改变后的结果(ROW),也可能是二者混合;
记录行得到更精确的结果,但是量比较大,记录“语句”相对轻量,如果定义问MIXED,则系统会自行决定用语句或者行的格式来记录。 默认实时statement
注意,如执行某个语句时,插入的字段是由函数执行生成,如now()函数,时间每次执行都会不一样,下次重新执行,结果是不一样的。所以记录的是执行结果,使得重新执行时,结果一样。这种记录方式成为记录row
查看当前的格式如下:
MariaDB [mysql]> show global variables like 'binlog_format';
服务器变量:
log_bin=/PATH/TO/BIN_LOG_FILE
只读变量;建议不使用数据目录,即/var/lib/mysql,因为二进制日志是将来用来恢复数据的方法,很重要,如果二进制日志和数据目录放在同一磁盘,将来一旦磁盘故障,所有的内容都丢失就不能恢复了,因此建议另外设定路径
例子:创建两个目录,将数据和log分开,分别挂载在不同的磁盘上,并更改数组和属主,修改配置文件,指定路径
[root@CentOS7A mysql]#mkdir -pv /mydata/{data,log}
[root@CentOS7A mysql]#chown -R mysql.mysql /mydata/*
[root@CentOS7A mysql]#vim /etc/my.cnf.d/server.cnf
log_bin = /mydata/log/master-log#定义日志文件不能加后缀
保存退出后重启mysql服务
[root@CentOS7A mysql]#systemctl restart mariadb
在路径 /mydata/log下会生成一个二进制的文件master-log.000001,该二进制文件会进行滚动,重启服务或者用flush logs命令都会进行滚动,文件后缀名会自动变更。该路径下还有一个文件master-log.index,该索引不是数据索引,而是日志文件索引,文本格式,如当master-log.000001这种文件很多时,mysql识别的文件是记录在master-log.index这个里面的。
master-log.000001是二进制文件,不能用cat等文本查看工具直接查看,查看二进制文件master-log.000001的方法如下
到mysql里
查看有多少个二进制文件,如下,该命令和直接查看master-log.index内容一样
MariaDB [sunny]> show binary logs;
+-------------------+-----------+
| Log_name | File_size |
+-------------------+-----------+
| master-log.000001 | 245 |
+-------------------+-----------+
1 row in set (0.00 sec)
手动滚动日志,可以用如下命令
MariaDB [sunny]> flush logs;
查看二进制日志文件列表:
SHOW MASTER|BINARY LOGS;
MariaDB [sunny]> show master logs;
MariaDB [sunny]> show binary logs;
查看当前正在使用的二进制日志文件:
SHOW MASTER STATUS;
查看当前正在使用的二进制文件,Position指当前写到哪个字节的位置,一般不是从0开始,因为该日志有自我描述信息,即文件头,记录当然日志文件是哪个版本,兼容哪些版本等等,默认是从245的位置开始
MariaDB [sunny]> show master status;
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-log.000003 | 245 | | |
+-------------------+----------+--------------+------------------+
查看二进制 日志文件中的事件:
SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
查看二进制文件记录的内容, Pos是开始位置,End_log_pos是结束位置, Event_type事件类型,Info 事件描述信息,信息中, xid=16是mysql记录的标识符
,Server_id是记录服务器的唯一信息,如果不做协同工作,默认id是1,同一集群中id号不能相同,需要手动修改该参数,
MariaDB [sunny]> show binlog events in 'master-log.000003';
+-------------------+-----+-------------+-----------+-------------+-------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+-------------------+-----+-------------+-----------+-------------+-------------------------------------------------+
| master-log.000003 | 4 | Format_desc | 1 | 245 | Server ver: 5.5.56-MariaDB, Binlog ver: 4 |
| master-log.000003 | 245 | Query | 1 | 314 | BEGIN |
| master-log.000003 | 314 | Query | 1 | 412 | use `sunny`; delete from students where id=1001 |
| master-log.000003 | 412 | Xid | 1 | 439 | COMMIT /* xid=15 */ |
+-------------------+-----+-------------+-----------+-------------+-------------------------------------------------+
4 rows in set (0.00 sec)
从指定的位置开始查看log,该位置值必须是起始位置,不能是中间的任意数
MariaDB [sunny]> show binlog events in 'master-log.000003' from 314;
从指定的位置开始查看log,偏移2行
MariaDB [sunny]> show binlog events in 'master-log.000003' from 245 limit 2;
session.sql_log_bin={ON|OFF}
控制某会话中的“写”操作语句是否会被记录于日志文件中;
关闭语句如下,之后该session的记录将不会被记录到二进制文件中,建议不要关闭,只在重放的时候才关闭该功能
MariaDB [sunny]> set @@session.sql_log_bin=off;
max_binlog_size=1073741824 #写入配置文件,定义二进制文件的最大值,单位是字节byte,1073741824为1G,但是文件实际大小可能不精准,超过这个值就滚动,文件可能不会精准到这个值后滚动,大小会相差一点点。
sync_binlog={1|0} #把日志从内存同步到硬盘,一般是缓存在内存区,一段时间后在同步到硬盘,这个好处是效率高,但是有可能会导致异常情况数据还在内存中而丢失。这里有个极端的情况是,如果丢失的数据是commint,这样数据就恢复不了,这里如果设置为1,就是当前操作是commit,就马上记录到磁盘里,数据重放更安全,但是性能会降低,需要根据实际情况而决定要不要开启功能
mysqlbinlog:#这个命令行工具的主要作用就是用来查看日志的内容,一般开始的245字节是文件的文件头,信息都是在这文件头之后,一般信息都有特定格式记录,第一个# at开头之前的为头部信息,每一个事件的操作记录以# at开头 ,以 end_log_poss结束。一般增删改查操作都是要先查询,所以都是Query。小于1s的执行时间exec_time都记录为0.error_code如果没有错误都是0。每一个连接就是一个线程thread_id。
相关选项:
--start-datetime=
--stop-datetime=
注意这里时间格式是:YYYY-MM-DD hh:mm:ss
例子:
[root@CentOS7A log]#mysqlbinlog /mydata/log/master-log.000003 --start-datetime="2018-01-14 11:27:41"
-j, --start-position=#表示从哪个位置开始
--stop-position=#到哪个位置结束
例子:从哪个位置开始查看
[root@CentOS7A log]#mysqlbinlog /mydata/log/master-log.000001 -j 314
--user, --host, --password
该命令是客户端命令,可以被远程执行,注意文件不能加引号
,但是,测试时,提示文件不存在
[root@CentOS7E ~]#mysqlbinlog -uroot -pPass123456 -h 192.168.1.71 /mydata/log/master-log.000001
例子:不加选项
[root@CentOS7A log]#mysqlbinlog /mydata/log/master-log.000001
附上二进制日志事件格式:
# at 553
#160831 9:56:08 server id 1 end_log_pos 624 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1472608568/*!*/;
BEGIN
/*!*/;
事件的起始位置:# at 553
事件发生的日期时间:#160831 9:56:08
事件发生的服务器id:server id 1
事件的结束位置:end_log_pos 624
事件的类型:Query
事件发生时所在服务器执行此事件的线程的ID: thread_id=2
语句的时间戳与将其写入二进制日志文件中的时间差:exec_time=0
错误代码:error_code=0
设定事件发生时的时间戳:SET TIMESTAMP=1472608568/*!*/;
事件内容:BEGIN
6 中继日志
从服务器上记录下来从主服务器的二进制日志文件同步过来的事件;是mysql主从复制时,二进制是主服务器上记录的日志,从服务器上通过中继日志,从服务器在本地进行重放,得到一样的二进制文件。使得主从复制一样。
二进制日志还有另一个作用是能做时间点还原,不一定要用于主从复制,这个恢复手段很有效,因为即使是备份操作,当备份没有备份的时间开始到系统崩溃的时间段,可以用这个二进制日志基于时间来恢复没有备份的时间段的数据的恢复。
7 事务日志
事务型存储引擎innodb用于保证事务特性的日志文件:
redo log
undo log