简介

mysql有5种日志

  1. 错误日志(error log): 记录mysql服务的启停时正确和错误的信息, 还记录启动,停止,运行过程中的错误信息
  2. 全局sql日志(general log): 记录建立的客户端连接和执行的语句
  3. 二进制日志(bin log): 记录所有更改数据的语句, 可用于数据复制
  4. 慢查询日志(slow log): 记录所有执行时间超过long_query_time的所有查询或不使用索引的查询
  5. 中继日志(relay log): 主从复制时候的日志

除了这5种日志,在需要的时候还会创建DDL日志

日志刷新操作

以下操作会刷新日志文件,刷新日志文件时会关闭旧的日志文件并重新打开日志文件.对于有些日志类型,如二进制日志, 刷新日志会滚动日志文件,而不仅仅是关闭并重新打开

  1. mysql> FLUSH LOGS;
  2. shell> mysqladmin flush-logs
  3. shell> mysqladmin refresh

错误日志

记录了mysql启动和运行过程中的错误信息
--log-error=[file_name] 可以这样指定记录的错误日志文件, 如果没有指定,那就是 datadir目录下的 `hostname.err,hostname表示当前的主机名<br />也可以在配置文件中, 使用log-error` 指定错误日志的路径

  1. mysql> show variables like 'log_error';
  2. +---------------+----------------------------------------+
  3. | Variable_name | Value |
  4. +---------------+----------------------------------------+
  5. | log_error | /var/lib/mysql/node1.longshuai.com.err |
  6. +---------------+----------------------------------------+

在MySQL 5.5.7之前,刷新日志操作(如flush logs)会备份旧的错误日志(以_old结尾),并创建一个新的错误日志文件并打开,
在MySQL 5.5.7之后,执行刷新日志的操作时,错误日志会关闭并重新打开,如果错误日志不存在,则会先创建。

全局sql日志

永远不要在生产环境使用,默认是关闭的
log_output={TABLE|FILE|NONE} ``# 定义一般查询日志和慢查询日志的输出格式,不指定时默认为file

配置文件开启

  1. # 开启
  2. general_log=1
  3. # 记录日志文件的路径
  4. general_log_file=/path/logfile
  5. # 输出格式
  6. log_output=FILE

编码方式启用

  1. set global general_log=1;
  2. set global log_output='TABLE';

你编写的sql会记录在mysql库里面的general_log表里,可以用下面命令查看

  1. select * from mysql.general_log;

测试下
首先开启一般查询日志

  1. mysql> set @@global.general_log=1;

执行几个语句
查看日志

  1. Time Id Command Argument
  2. 180421 20:04:41 13 Query select user,host from mysql.user
  3. 180421 20:06:06 13 Query show variables like "%error%"
  4. 180421 20:07:28 13 Query insert into ttt values(233)
  5. 180421 20:11:47 13 Query create table tt(id int)
  6. 180421 20:12:29 13 Query set @a:=3

慢查询日志

默认情况,mysql没有开启慢查询日志,需要手动来开启
和慢查询有关的变量:

  1. long_query_time=10 # 指定慢查询超时时长(默认10秒),超出此时长的属于慢查询
  2. log_output={TABLE|FILE|NONE} # 定义一般查询日志和慢查询日志的输出格式,默认为file
  3. log_slow_queries={yes|no} # 是否启用慢查询日志,默认不启用
  4. slow_query_log={1|ON|0|OFF} # 也是是否启用慢查询日志,此变量和log_slow_queries修改一个另一个同时变化
  5. slow_query_log_file=/mydata/data/hostname-slow.log #默认路径为库文件目录下主机名加上-slow.log
  6. log_queries_not_using_indexes=OFF # 查询没有使用索引的时候是否也记入慢查询日志

查询是否开启

  1. show variables like '%slow_query_log%';

开启下
修改my.cnf文件,增加或修改参数slow_query_logslow_query_log_file后,然后重启MySQL服务器,如下所示

  1. slow_query_log =1
  2. long_query_time=10 # 指定慢查询超时时长(默认10秒),超出此时长的属于慢查询
  3. log_queries_not_using_indexes=OFF # 查询没有使用索引的时候是否也记入慢查询日志
  4. slow_query_log_file=/tmp/mysql_slow.log

测试下
现在启用慢查询日志

  1. mysql> set @@global.slow_query_log=on;

因为配置了超时时长为6秒,所以进行一个10秒的查询

  1. mysql> select sleep(6);

查下日志,后面的微秒也记录了

  1. /usr/local/opt/mysql/bin/mysqld, Version: 8.0.19 (Homebrew). started with:
  2. Tcp port: 3306 Unix socket: /tmp/mysql.sock
  3. Time Id Command Argument
  4. # Time: 2020-06-02T16:00:02.233390Z
  5. # User@Host: root[root] @ localhost [] Id: 8
  6. # Query_time: 6.064708 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1
  7. use app;
  8. SET timestamp=1591113596;
  9. select sleep(6);

分析慢查询日志工具

  1. # mysqldumpslow --help
  2. -d debug
  3. -v verbose:显示详细信息
  4. -t NUM just show the top n queries:仅显示前n条查询
  5. -a don't abstract all numbers to N and strings to 'S':归类时不要使用N替换数字,S替换字符串
  6. -g PATTERN grep: only consider stmts that include this string:通过grep来筛选select语句。

image.png
该工具归类的时候,默认会将同文本但变量值不同的查询语句视为同一类,并使用N代替其中的数值变量,使用S代替其中的字符串变量。可以使用-a来禁用这种替换。如:

  1. [root@xuexi data]# mysqldumpslow xuexi-slow.log
  2. Reading mysql slow query log from xuexi-slow.log
  3. Count: 1 Time=10.00s (10s) Lock=0.00s (0s) Rows=1.0 (1), root[root]@localhost
  4. select sleep(N)
  5. [root@xuexi data]# mysqldumpslow -a xuexi-slow.log
  6. Reading mysql slow query log from xuexi-slow.log
  7. Count: 1 Time=10.00s (10s) Lock=0.00s (0s) Rows=1.0 (1), root[root]@localhost
  8. select sleep(10)

显然,这里归类后的结果只是精确到0.01秒的,如果想要显示及其精确的秒数,则使用-d选项启用调试功能。

  1. [root@xuexi data]# mysqldumpslow -d xuexi-slow.log
  2. Reading mysql slow query log from xuexi-slow.log
  3. [[/usr/local/mysql/bin/mysqld, Version: 5.6.35-log (MySQL Community Server (GPL)). started with:
  4. Tcp port: 3306 Unix socket: /mydata/data/mysql.sock
  5. Time Id Command Argument
  6. # Time: 170329 9:55:58
  7. # User@Host: root[root] @ localhost [] Id: 1
  8. # Query_time: 10.000847 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
  9. use test;
  10. SET timestamp=1490752558;
  11. select sleep(10);
  12. ]]
  13. <<>>
  14. <<# Time: 170329 9:55:58
  15. # User@Host: root[root] @ localhost [] Id: 1
  16. # Query_time: 10.000847 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
  17. use test;
  18. SET timestamp=1490752558;
  19. select sleep(10);
  20. >> at /usr/local/mysql/bin/mysqldumpslow line 97, <> chunk 1.
  21. [[# Time: 170329 9:55:58
  22. # User@Host: root[root] @ localhost [] Id: 1
  23. # Query_time: 10.000847 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
  24. use test;
  25. SET timestamp=1490752558;
  26. select sleep(10);
  27. ]]
  28. {{ select sleep(N)}}
  29. Count: 1 Time=10.00s (10s) Lock=0.00s (0s) Rows=1.0 (1), root[root]@localhost
  30. select sleep(N)

慢查询包含的内容

image.png

pt-query-digest 工具

这个工具对慢查询日志的分析比mysqldumpslow好

image.png

如何通过慢查询日志发现有问题的sql?
image.png

mysqlsla分析

mysqlsla是 hackmysql.com推出的一款日志分析工具(该网站还维护了 mysqlreport, mysqlidxchk 等比较实用的mysql工具)
整体来说, 功能非常强大. 数据报表,非常有利于分析慢查询的原因, 包括执行频率, 数据量, 查询消耗等.

安装方法如下:

  1. tar zxf http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz
  2. cd mysqlsla-2.03
  3. perl Makefile.PL
  4. make
  5. make install

使用起来很简单:
/path/to/mysqlsla slow.log

image.png
格式说明如下:
总查询次数 (queries total), 去重后的sql数量 (unique)
输出报表的内容排序(sorted by)
最重大的慢sql统计信息, 包括平均执行时间, 等待锁时间, 结果行的总数, 扫描的行总数.

Count, sql的执行次数及占总的slow log数量的百分比.
Time, 执行时间, 包括总时间, 平均时间, 最小, 最大时间, 时间占到总慢sql时间的百分比.
95% of Time, 去除最快和最慢的sql, 覆盖率占95%的sql的执行时间.
Lock Time, 等待锁的时间.
95% of Lock , 95%的慢sql等待锁时间.
Rows sent, 结果行统计数量, 包括平均, 最小, 最大数量.
Rows examined, 扫描的行数量.
Database, 属于哪个数据库
Users, 哪个用户,IP, 占到所有用户执行的sql百分比

Query abstract, 抽象后的sql语句
Query sample, sql语句

binlog

二进制日志文件

二进制日志包含了引起或可能引起数据库改变(如delete语句但没有匹配行)的事件信息,但绝不会包括select和show这样的查询语句。语句以”事件”的形式保存,所以包含了时间、事件开始和结束位置等信息。

二进制日志是以事件形式记录的,不是事务日志(但可能是基于事务来记录二进制日志),不代表它只记录innodb日志,myisam表也一样有二进制日志。

对于事务表的操作,二进制日志只在事务提交的时候一次性写入(基于事务的innodb二进制日志),提交前的每个二进制日志记录都先cache,提交时写入。对于非事务表的操作,每次执行完语句就直接写入。

MariaDB/MySQL默认没有启动二进制日志,要启用二进制日志使用 --log-bin=[on|off|file_name]选项指定,如果没有给定file_name,则默认为datadir下的主机名加”-bin”,并在后面跟上一串数字表示日志序列号,如果给定的日志文件中包含了后缀(logname.suffix)将忽略后缀部分。

my.cnf

  1. log_bin=ON
  2. server-id=123454

用的如果是5.7及以上版本的话,必须还要指定一个参数 server-id
随机指定一个不能和其他集群中机器重名的字符串,如果只有一台机器,那就可以随便指定了

  1. mysql> show variables like '%log_bin%';
  2. +---------------------------------+-----------------------------------+
  3. | Variable_name | Value |
  4. +---------------------------------+-----------------------------------+
  5. | log_bin | ON |
  6. | log_bin_basename | /usr/local/var/mysql/binlog |
  7. | log_bin_index | /usr/local/var/mysql/binlog.index |
  8. | log_bin_trust_function_creators | OFF |
  9. | log_bin_use_v1_row_events | OFF |
  10. | sql_log_bin | ON |
  11. +---------------------------------+-----------------------------------+
  12. 6 rows in set (0.00 sec)

log_bin_basename 是binlog日志的基本文件名,后面会追加标识来表示每一个文件
log_bin_index 是binlog文件的索引文件,这个文件管理了所有的binlog文件的目录

二进制日志文件的最大值通过变量 max_binlog_size 设置(默认值为1G)。但由于二进制日志可能是基于事务来记录的(如innodb表类型),而事务是不应该跨文件记录的,如果正好二进制日志文件达到了最大值但事务还没有提交则不会滚动日志,而是继续增大日志,所以 max_binlog_size 指定的值和实际的二进制日志大小不一定相等。

:::info 因为二进制日志文件增长迅速,但官方说明因此而损耗的性能小于1%,且二进制目的是为了恢复定点数据库和主从复制,所以出于安全和功能考虑,极不建议将二进制日志和datadir放在同一磁盘上 :::

查看二进制日志

mysqlbinlog工具

  1. mysqlbinlog [option] log-file1 log-file2...

常用选项

  1. -d,--database=name:只查看指定数据库的日志操作
  2. -o,--offset=#:忽略掉日志中的前n个操作命令
  3. -r,--result-file=name:将输出的日志信息输出到指定的文件中,使用重定向也一样可以。
  4. -s,--short-form:显示简单格式的日志,只记录一些普通的语句,会省略掉一些额外的信息如位置信息和时间信息以及基于行的日志。可以用来调试,生产环境千万不可使用
  5. --set-charset=char_name:在输出日志信息到文件中时,在文件第一行加上set names char_name
  6. --start-datetime,--stop-datetime:指定输出开始时间和结束时间内的所有日志信息
  7. --start-position=#,--stop-position=#:指定输出开始位置和结束位置内的所有日志信息
  8. -v,-vv:显示更详细信息,基于row的日志默认不会显示出来,此时使用-v或-vv可以查看

在进行测试之前,先对日志进行一次刷新,以方便解释二进制日志的信息

  1. shell> mysqladmin -uroot -p refresh

假设现在的日志文件是mysql-bin.000001,里面暂时只有一些初始信息,没有记录任何操作过的记录。
现在在数据库中执行下面的操作:

  1. use test;
  2. create table student(studentid int not null primary key,name varchar(30) not null,gender enum('female','mail'));
  3. alter table student change gender gender enum('female','male');
  4. insert into student values(1,'malongshuai','male'),(2,'gaoxiaofang','female');

再查看二进制日志信息

  1. # --no-defaults的意思是这个工具无法识别binlog中的配置中的default-character-set=utf8这个指令
  2. # my.cnf中将default-character-set=utf8 修改为 character-set-server=utf8需要重启
  3. mysqlbinlog --no-defaults mysql-bin.000001

Mysql Binlog日志分析

通过MysqlBinlog指令查看具体的mysql日志,如下:

  1. SET TIMESTAMP=1350355892/*!*/;
  2. BEGIN
  3. /*!*/;
  4. # at 1643330
  5. #121016 10:51:32 server id 1 end_log_pos 1643885 Query thread_id=272571 exec_time=0 error_code=0
  6. SET TIMESTAMP=1350355892/*!*/;
  7. Insert into T_test….)
  8. /*!*/;
  9. # at 1643885
  10. #121016 10:51:32 server id 1 end_log_pos 1643912 Xid = 0
  11. COMMIT/*!*/;
  1. 1.开始事物的时间:
  2. SET TIMESTAMP=1350355892/*!*/;
  3. BEGIN
  4. 2.sqlevent起点
  5. #at 1643330 :为事件的起点,是以1643330字节开始。
  6. 3.sqlevent 发生的时间点
  7. #121016 10:51:32:是事件发生的时间,
  8. 4.serverId
  9. server id 1 :为master serverId
  10. 5.sqlevent终点及花费时间,错误码
  11. end_log_pos 1643885:为事件的终点,是以1643885 字节结束。
  12. execTime 0: 花费的时间
  13. error_code=0:错误码
  14. Xid:事件指示提交的XA事务

整理下类似
image.png

其中timestamp记录的是从1970-01-01到现在的总秒数时间戳,可以使用 date -d ‘@1490736093’ 转换

使用-r命令将日志文件导入到指定文件中,使用重定向也可以实现同样的结果。并使用-s查看简化的日志文件。

  1. [root@xuexi data]# mysqlbinlog mysql-bin.000001 -r /tmp/binlog.000001
  2. [root@xuexi data]# mysqlbinlog mysql-bin.000001 -s>/tmp/binlog.sample

使用-s后,少了基于行的日志信息,也少了记录的位置和时间信息。
使用-o可以忽略前N个条目,例如上面的操作涉及了6个操作。忽略掉前3个

  1. [root@xuexi data]# mysqlbinlog mysql-bin.000001 -o 3

使用-d可以只显示指定数据库相关的操作。例如先切换到其他数据库进行一番操作,然后再使用-d查看日志

  1. [root@xuexi data]# mysqlbinlog mysql-bin.000001 -d mysql

可以看到,除了指定的mysql数据库的信息输出了,还非常简化的输出了其他数据库的信息。
mysqlbinlog最有用的两个选项就是指定时间和位置来输出日志。
指定时间时,将输出指定时间范围内的日志。指定的时间可以不和日志中记录的日志相同。

  1. # mysqlbinlog mysql-bin.000001 --start-datetime='2017-03-28 00:00:01' --stop-datetime='2017-03-29 05:21:23'

同理指定位置也一样,但是指定位置时有个要求是如果指定起始位置,则必须指定日志文件中明确的起始位置。例如,日志文件中有位置120、305、441,可以指定起始和结束位置为120、500,但是不可以指定起止位置为150、500,因为日志文件中不存在150这个位置。

  1. # mysqlbinlog mysql-bin.000001 --start-position=150 --stop-position=441

show binary logs查看当前使用了哪些二进制日志文件

可以通过查看二进制的index文件来查看当前正在使用哪些二进制日志

  1. [root@xuexi data]# cat mysql-bin.index
  2. ./mysql-bin.000003
  3. ./mysql-bin.000004
  4. ./mysql-bin.000005
  5. ./mysql-bin.000006

也可以在mysql环境中使用 show {binary | master} logs 来查看。binary和master是同义词

  1. mysql> show binary logs;
  2. +------------------+-----------+
  3. | Log_name | File_size |
  4. +------------------+-----------+
  5. | mysql-bin.000003 | 167 |
  6. | mysql-bin.000004 | 785 |
  7. | mysql-bin.000005 | 1153 |
  8. | mysql-bin.000006 | 602 |
  9. +------------------+-----------

show binlog events查看日志中进行了哪些操作

  1. mysql> show binlog events in 'mysql-bin.000005';

image.png
可以指定起始位置。同样,起始位置必须指定正确,不能指定不存在的位置

  1. mysql> show binlog events in 'mysql-bin.000005' from 961;
  2. +------------------+------+------------+-----------+-------------+--------------------------------+
  3. | Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
  4. +------------------+------+------------+-----------+-------------+--------------------------------+
  5. | mysql-bin.000005 | 961 | Table_map | 1 | 1019 | table_id: 98 (test.student) |
  6. | mysql-bin.000005 | 1019 | Write_rows | 1 | 1075 | table_id: 98 flags: STMT_END_F |
  7. | mysql-bin.000005 | 1075 | Xid | 1 | 1106 | COMMIT /* xid=129 */ |
  8. | mysql-bin.000005 | 1106 | Rotate | 1 | 1153 | mysql-bin.000006;pos=4 |
  9. +------------------+------+------------+-----------+-------------+--------------------------------+

show master status 显示主服务器中的二进制日志信息

显示主服务器中的二进制日志信息。如果是主从结构,它只会显示主从结构中主服务器的二进制日志信息。

  1. mysql> show master status;
  2. +------------------+----------+--------------+------------------+-------------------+
  3. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
  4. +------------------+----------+--------------+------------------+-------------------+
  5. | mysql-bin.000006 | 602 | | | |
  6. +------------------+----------+--------------+------------------+-------------------+

可以查看到当前正在使用的日志及下一事件记录的开始位置,还能查看到哪些数据库需要记录二进制日志,哪些数据库不记录二进制日志。

删除二进制日志

删除二进制日志有几种方法。不管哪种方法,都会将删除后的信息同步到二进制index文件中

  1. reset master将会删除所有日志,并让日志文件重新从000001开始
    1. mysql> reset master;
    2.**PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }**
    purge master logs to "binlog_name.00000X" 将会清空00000X之前的所有日志文件。例如删除000006之前的日志文件

master和binary是同义词
purge master logs before 'yyyy-mm-dd hh:mi:ss' 将会删除指定日期之前的所有日志。但是若指定的时间处在正在使用中的日志文件中,将无法进行purge

  1. mysql> purge master logs before '2017-03-29 07:36:40';
  2. mysql> show warnings;
  3. +---------+------+---------------------------------------------------------------------------+
  4. | Level | Code | Message |
  5. +---------+------+---------------------------------------------------------------------------+
  6. | Warning | 1868 | file ./mysql-bin.000003 was not purged because it is the active log file. |
  7. +---------+------+---------------------------------------------------------------------------+
  1. 使用--expire_logs_days=N选项指定过了多少天日志自动过期清空

二进制日志的记录格式

MySQL支持statement、row、mixed三种形式的记录方式。row形式是基于行来记录,也就是将相关行的每一列的值都在日志中保存下来,这样的结果会导致日志文件变得非常大,但是保证了动态值的确定性。还有一种mixed形式,表示如何记录日志由MySQL自己来决定。

日志的记录格式由变量 binlog_format 来指定。其值有:row,statement,mixed

下面将记录格式改为row。

  1. mysql> alter table student add birthday datetime default now();
  2. mysql> flush logs;
  3. mysql> set binlog_format='row';
  4. mysql> insert into student values(7,'xiaowoniu','female',now());

查看产生的日志, 发现是一堆看不懂的东西,使用-vv可将这些显示出来。可以看出,结果中记录的非常详细,这也是为什么基于row记录日志会导致日志文件极速变大

  1. [root@xuexi data]# mysqlbinlog mysql-bin.000005 -vv
  2. ...前面省略...
  3. BINLOG '
  4. gPraWBMBAAAAOgAAAAIBAAAAAF4AAAAAAAEABHRlc3QAB3N0dWRlbnQABAMP/hIFHgD3AQAMCf3N
  5. uA==
  6. gPraWB4BAAAAOAAAADoBAAAAAF4AAAAAAAEAAgAE//AHAAAACXhpYW93b25pdQGZnDqBmCz35ow=
  7. '/*!*/;
  8. ### INSERT INTO `test`.`student`
  9. ### SET
  10. ### @1=7 /* INT meta=0 nullable=0 is_null=0 */
  11. ### @2='xiaowoniu' /* VARSTRING(30) meta=30 nullable=0 is_null=0 */
  12. ### @3=1 /* ENUM(1 byte) meta=63233 nullable=1 is_null=0 */
  13. ### @4='2017-03-29 08:06:24' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
  14. # at 314
  15. ...后面省略...

还有一种mixed模式。这种模式下默认会采用statement的方式记录,只有以下几种情况会采用row的形式来记录日志。

  1. 表的存储引擎为NDB,这时对表的DML操作都会以row的格式记录。
  2. 使用了uuid()、user()、current_user()、found_rows()、row_count()等不确定函数。但测试发现对now()函数仍会以statement格式记录,而sysdate()函数会以row格式记录。
  3. 使用了insert delay语句。
  4. 使用了临时表。

二进制日志相关的变量

注意:在配置binlog相关变量的时候,相关变量名总是搞混,因为有的是binlog,有的是log_bin,当他们分开的时候,log在前,当它们一起的时候,bin在前。在配置文件中也同样如此。

  • log_bin = {on | off | base_name} #指定是否启用记录二进制日志或者指定一个日志路径(路径不能加.否则.后的被忽略)
  • sql_log_bin ={ on | off } #指定是否启用记录二进制日志,只有在log_bin开启的时候才有效
  • expire_logs_days = #指定自动删除二进制日志的时间,即日志过期时间
  • binlog_do_db = #明确指定要记录日志的数据库
  • binlog_ignore_db = #指定不记录二进制日志的数据库
  • log_bin_index = #指定mysql-bin.index文件的路径
  • binlog_format = { mixed | row | statement } #指定二进制日志基于什么模式记录
  • binlog_rows_query_log_events = { 1|0 } # MySQL5.6.2添加了该变量,当binlog format为row时,默认不会记录row对应的SQL语句,设置为1或其他true布尔值时会记录,但需要使用mysqlbinlog -v查看,这些语句是被注释的,恢复时不会被执行。
  • max_binlog_size = #指定二进制日志文件最大值,超出指定值将自动滚动。但由于事务不会跨文件,所以并不一定总是精确。
  • binlog_cache_size = 32768 #基于事务类型的日志会先记录在缓冲区,当达到该缓冲大小时这些日志会写入磁盘
  • max_binlog_cache_size = #指定二进制日志缓存最大大小,硬限制。默认4G,够大了,建议不要改
  • binlog_cache_use:使用缓存写二进制日志的次数(这是一个实时变化的统计值)
  • binlog_cache_disk_use:使用临时文件写二进制日志的次数,当日志超过了binlog_cache_size的时候会使用临时文件写日志,如果该变量值不为0,则考虑增大binlog_cache_size的值
  • binlog_stmt_cache_size = 32768 #一般等同于且决定binlog_cache_size大小,所以修改缓存大小时只需修改这个而不用修改binlog_cache_size
  • binlog_stmt_cache_use:使用缓存写二进制日志的次数
  • binlog_stmt_cache_disk_use: 使用临时文件写二进制日志的次数,当日志超过了binlog_cache_size的时候会使用临时文件写日志,如果该变量值不为0,则考虑增大binlog_cache_size的值
  • sync_binlog = { 0 | n } #这个参数直接影响mysql的性能和完整性
    • sync_binlog=0:不同步,日志何时刷到磁盘由FileSystem决定,这个性能最好。
    • sync_binlog=n:每写n次二进制日志事件(不是事务),MySQL将执行一次磁盘同步指令fdatasync()将缓存日志刷新到磁盘日志文件中。Mysql中默认的设置是sync_binlog=0,即不同步,这时性能最好,但风险最大。一旦系统奔溃,缓存中的日志都会丢失。 :::info 在innodb的主从复制结构中,如果启用了二进制日志(几乎都会启用),要保证事务的一致性和持久性的时候,必须将sync_binlog的值设置为1,因为每次事务提交都会写入二进制日志,设置为1就保证了每次事务提交时二进制日志都会写入到磁盘中,从而立即被从服务器复制过去 :::

二进制日志定点还原数据库

只需指定二进制日志的起始位置(可指定终止位置)并将其保存到sql文件中,由mysql命令来载入恢复即可。当然直接通过管道送给mysql命令也可。
至于是基于位置来恢复还是基于时间点来恢复,这两种行为都可以。选择时间点来恢复比较直观些,并且跨日志文件恢复时更方便。

  1. mysqlbinlog --stop-datetime="2014-7-2 15:27:48" /tmp/mysql-bin.000008 | mysql -u user -p password

恢复多个二进制日志文件时:

  1. mysqlbinlog mysql-bin.[*] | mysql -uroot -p password

或者将它们导入到一个文件中后恢复。

  1. mysqlbinlog mysql-bin.000001 > /tmp/a.sql
  2. mysqlbinlog mysql-bin.000002 >>/tmp/a.sql
  3. mysql -u root -p password -e "source /tmp/a.sql"