目录
1.MySQL支持的日志
2.慢查询日志(slow query log)
2.1 慢查询日志相关参数
2.2 开启慢查询日志
2.3 数据记录
3.通用查询日志(general query log)
3.1 查看当前开启状态
3.2 启动方式
3.3 数据记录
3.4 删除/刷新日志
4.错误日志(error log)
4.1 启动日志
4.2 查看日志
4.3 删除/刷新日志
5.二进制日志(bin log)
5.1 查看默认情况
5.2 日志参数设置
5.3 查看日志
5.4 使用日志恢复数据
5.5 删除二进制日志
5.6 其他场景
5.7 写入机制
5.8 bin log与redo log对比
5.9 两阶段提交
6.中继日志(relay log)
6.1 介绍
6.2 查看中继日志
之前写数据库事务的时候,写过两种日志:重做日志(redo log)、回滚日志(undo log)。对于线上数据库系统,如果发生突然宕机,那么定位到宕机的原因就很关键。我们可以查看数据库的错误日志,因为日志中记录了数据库运行中的诊断信息,包括了错误、警告和注释等信息。
MySQL有不同类型的日志文件,用来存储不同类型的日志,分为二进制日志、错误日志、通用查询日志和慢查询日志,这是常用的4种日志。MySQL8.0又新增了两种支持的日志:中继日志和数据定义语句日志。
慢查询日志:记录所有执行时间超过long_query_time的所有查询,方便我们对查询进行优化。
通用查询日志:记录所有连接起始时间和终止时间,以及连接发送给数据库服务器的所有指令。
错误日志:记录MySQL服务启动、运行或停止服务时出现的问题,方便我们了解服务器状态。
二进制日志:记录所有更改数据的语句,可以用于主从服务器之间的数据同步,以及服务器遇到故障时数据的无损恢复。
中继日志:用于主从服务器架构中,从服务器用来存放主服务器二进制日志内容的一个中间文件。从服务器通过读取中继日志的内容,来同步主服务器上的操作。
除二进制文件外,其他日志都是文本文件。默认情况下,所有日志创建于MySQL数据目录中。
MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10S以上的语句。默认情况下,Mysql数据库并不启动慢查询日志,需要我们手动来设置这个参数,当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。
slow_query_log:是否开启慢查询日志,1表示开启,0表示关闭。
slow-query-log-file:慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件host_name-slow.log
long_query_time:慢查询阈值,当查询时间多于设定的阈值时,记录日志。
log_queries_not_using_indexes:未使用索引的查询也被记录到慢查询日志中(可选项)。
log_output:日志存储方式。log_output = 'FILE'表示将日志存入文件,默认值是'FILE'。log_output = 'TABLE'表示将日志存入数据库,这样日志信息就会被写入到mysql.slow_log表中。MySQL数据库支持同时两种日志存储方式,配置的时候以逗号隔开即可,如:log_output = 'FILE,TABLE'。日志记录到系统的专用日志表中,要比记录到文件耗费更多的系统资源,因此对于需要启用慢查询日志,又需要能够获得更高的系统性能,那么建议优先记录到文件。
show variables like '%slow_query_log%';
永久开启
修改my.cnf文件,新增下列参数配置
[mysqld]
slow_query_log=1
slow_query_log_file=/var/lib/mysql/atguigu-slow.log
long_query_time=3
log_output=FILE
临时开启(重启服务器后失效)
set global slow_query_log = 1;
开启后在mysql数据目录下会生成一个xxx-slow.log的文件。
新开一个session执行 select sleep(4);操作,然后打开慢查询日志文件查看。
通用查询日志用来记录用户的所有操作,包括启动和关闭MySQL、所有用户连接开始时间和截止时间、发给MySQL数据库服务器的所有SQL指令等。当我们的数据发生异常时,查看通用查询日志,可以帮助我们还原当时具体场景,定位问题。
show variables like '%general%';
方式1:永久性启动
修改my.cnf配置文件来设置。在【mysqld】组下加入log选项,并重启MySQL服务。
[mysqld]
general_log=ON
general_log_file=[path[filename]]
如果不指定目录和文件名,通用查询日志将默认存储在MySQL数据目录中的hostname.log中,hostname表示主机名。
方式2:临时性启动(重启服务器后失效)
SET GLOBAL general_log = ON
可以看到在 general_log_file路径下生成了一个名为iz2ze6890p10n5yp0jerfrz.log的日志文件。
新开一个session执行增删改查操作,然后打开通用查询日志文件查看。
可以看到增删改查操作都被记录到了通用查询日志里。
MySQL通用查询日志是以文本文件的形式存储在文件系统中的,可以直接删除。
rm -f iz2ze6890p10n5yp0jerfrz.log.log
在运行状态下删除错误日志后,MySQL并不会自动创建日志文件。重建日志指令:
mysqladmin -uroot -proot flush-logs
错误日志记录了MySQL服务器启动、停止运行的时间,以及系统启动、运行和停止过程中的诊断信息,包括错误、警告和提示等。通过错误日志可以查看系统的运行状态,便于及时发现故障、修复故障。
在MySQ中,错误日志功能是默认开启且无法被禁止的。默认情况下,错误日志在MySQL数据文件夹下,名称默认为mysqld.log。在配置文件中可以对文件生成路径进行配置:
show variables like 'log_err%';
MySQL错误日志是以文本文件的形式存储在文件系统中的,可以直接删除。
rm -f mysqld.log
在运行状态下删除错误日志后,MySQL并不会自动创建日志文件。重建日志指令:
mysqladmin -uroot -proot flush-logs
如果报错则执行:
install -omysql -gmysql -m0644 /dev/null /var/log/mysqld.log
binlog即binary log,二进制日志文件,也叫做变更日志(update log)。它记录了数据库所有执行的DDL和DML等数据库更新事件的语句,但是不包含没有修改任何数据的语句(如select、show等)。
它以事件形式记录并保存在二进制文件中。通过这些信息,我们可以再现数据更新操作的全过程。
show variables like '%log_bin%';
log_bin:是否开启bin log。
log_bin_basename:bin log存放路径。
log_bin_index:bin log索引文件存放路径。
log_bin_trust_function_creators:是否信任bin log中的函数。
log_bin_use_v1_row_events:bin log版本信息,从5.6默认使用v2,所以该参数为OFF
sql_log_bin:变更型sql文件是否记录到bin log中。
启动方式:修改my.cnf配置文件来设置,并重启MySQL服务。
方式一:mysqlbinlog
mysqlbinlog - v "/usr/local/mysql/data/mysql-bin.000001"
-v:按照事件的方式展示
方式二:show binlog events
show binlog events [in 'log_name'] [from pos][limit [offset] row_count]
in 'log_name':指定要查询的binlog文件名(不指定默认第一个文件)
from pos:指定从哪个pos起始点开始查
limit [offset]:偏移量(不指定就是0)
row_count:查询总条数(不指定就是所有行)
如果MySQL服务器启用了二进制日志,在数据库出现意外丢失数据时,可以使用MySQLbinlog工具从指定的时间点开始,直到现在或另一个指定时间点的日志中恢复数据。
mysqlbinlog恢复数据的语法如下:
mysqlbinlog [option] filename|mysql -uuser -ppass
filename:日志文件名
option:可选项,比较重要的两对option参数是--start-date、--stop-date和--start-position、--stop-position
--start-date和--stop-date:可以指定恢复数据库的起始时间和结束时间点
--start-position、--stop-position:可以指定恢复数据哭的开始位置和结束位置
注:使用mysqlbinlog命令进行恢复操作时,必须是编号小的文件先恢复,例如mysql-bin.000001必须在mysql-bin.000002之前恢复。
MySQL的二进制文件可以配置自动删除,同时MySQL也提供了安全手动删除二进制文件的方法。PURGE MASTER LOGS只删除指定部分的二进制日志文件,RESET MASTER删除所有的二进制日志文件。具体如下:
PURGE MASTER LOGS:删除指定日志文件
语法如下:
PURGE {MASTER|BINARY} LOGS TO '指定日志文件名'
PURGE {MASTER|BINARY} LOGS BEFORE'指定日期'
删除指定文件名之前的日志文件或删除指定日期之前的日志文件
RESET MASTER:删除所有二进制日志文件
RESET MASTER指令会清空所有的binlog日志。MySQL会重新创建二进制文件,新的日志文件扩展名将重新从000001开始编号。
数据恢复
如果MySQL服务器意外停止,可以通过二进制日志文件来查看用户执行了哪些操作,对数据库服务器文件做了哪些修改,然后根据二进制日志文件中的记录来恢复数据库数据。
数据复制
master主机把它的二进制日志传递给slaves来达到主从数据一致。
在事务执行过程中,MySQL先把日志写到binlog cache中,事务提交的时候,再把binlog cache写到binlog文件中。因为一个事务的binlog不能被拆开,无论这个事务多大,也要保证一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache。
我们可以通过binlog_cache_size参数控制单个线程binlog cache大小,如果存储内容超过了这个参数的容量,就要把binlog cache中的数据刷到磁盘上。binlog日志刷盘流程如下:
上图的write,是指把日志写入到文件系统的page cache,并没有把数据持久化到磁盘,所以速度比较快
上图的fsync,才是将数据持久化到磁盘的操作
write和fsync的时机,可以由参数sync_binlog控制,默认是0。为0的时候,表示每次提交事务都只write,由系统自行判断什么时候执行fsync。虽然性能得到提升,但是机器宕机,page cache里面的binglog会丢失。
为了安全起见,可以设置为1,表示每次提交事务都会执行fsync,就如同binlog日志刷盘流程一样。最后还有一种折中方式,可以设置为N(N>1),表示每次提交事务都write,但累积N个事务后才fsync。在出现IO瓶颈的场景里,将sync_binlog设置成一个比较大的值,可以提升性能。同样的,如果机器宕机,会丢失最近N个事务的binlog日志。
redo log是物理日志,记录内容是"在某个数据页上做了什么修改",属于InnoDB存储引擎层产生的。
binlog是逻辑日志,记录内容是语句的原始逻辑,类似于"给 ID = 2这一行的C字段加1"。属于MySQL的 Server层。
redo log和bin log都属于数据库持久化的保证,但侧重点不同。redo log侧重让InnoDB拥有崩溃恢复的能力。bin log保证了MySQL集群数据的一致性。
在执行更新语句过程中,会记录redo log和bin log两部分日志,以基本的事务为单位,redo log在事务执行过程中可以不断的写入,而bin log只有在提交事务时才写入,所以redo log与bin log的写入时机不一样。
如果redo log与bin log两份日志之间的逻辑不一致,比如redo log记录正常但bin log记录失败,那么就会造成主从数据库间的数据不一致。
为了保证两份日志的逻辑一致性MySQL采用了两阶段提交。下面是一个 update 语句的执行流程图,图中浅色框表示是在 InnoDB 内部执行的,深色框表示是在执行器中执行的。
图片借鉴于:MySql事务之两阶段提交与redo log、binlog - 简书
"两阶段提交"的逻辑也很简单,就是将redo log的写入拆成了两个步骤:prepare 和 commit。在commit阶段会判断bin log是否写入成功再去提交。简单来说,redo log和bin log都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。
中继日志只在主从服务器架构的从服务器上存在。从服务器为了与主服务器保持数据一致,要从主服务器读取二进制日志的内容,并把读取到的信息写入本地的日志文件中,这个存储在从服务器本地的日志文件叫做中继日志。
搭建好从服务器后,中继日志默认保存在从服务器数据目录下。中继日志还有一个索引文件:从服务器名-relay-bin.index,用来定位当前正在使用的中继日志。
中继日志与二进制日志格式相同,可以用mysqlbinlog工具进行查看。