(转)Mysql数据库之Binlog日志使用总结

 使用mysqlbinlog提取二进制日志html

原文:http://blog.csdn.net/leshami/article/details/41962243python

 MySQL binlog日志记录了MySQL数据库从启用日志以来全部对当前数据库的变动。binlog日志属于二进制文件,咱们能够从binlog提取出来生成可阅读的SQL语句来重建当前数据库以及根据须要实现时点恢复或不彻底恢复。本文主要描述了若是提取binlog日志,并给出相关示例。mysql

    有关binlog的介绍与描述请参考:MySQL 二进制日志(Binary Log)sql

 

一、提取mysqlbinlog的几种方式
a、使用show binlog events方式能够获取当前以及指定binlog的日志,不适宜提取大量日志。
b、使用mysqlbinlog命令行提取(适宜批量提取日志)。数据库

 

二、演示show binlog events方式vim

[sql]  view plain  copy
 
 print?
  1. mysql> show variables like 'version';  
  2. +---------------+------------+  
  3. | Variable_name | Value      |  
  4. +---------------+------------+  
  5. | version       | 5.6.12-log |  
  6. +---------------+------------+  
  7.   
  8. mysql> show binary logs;  
  9. +-----------------+-----------+  
  10. | Log_name        | File_size |  
  11. +-----------------+-----------+  
  12. | APP01bin.000001 |       120 |  
  13. +-----------------+-----------+  
  14.   
  15. a、只查看第一个binlog文件的内容(show binlog events)   
  16. mysql> use replication;  
  17. Database changed  
  18. mysql> select * from tb;  
  19. +------+-------+  
  20. | id   | val   |  
  21. +------+-------+  
  22. |    1 | robin |  
  23. +------+-------+  
  24.   
  25. mysql> insert into tb values(2,'jack');  
  26. Query OK, 1 row affected (0.02 sec)  
  27.   
  28. mysql> flush logs;  
  29. Query OK, 0 rows affected (0.00 sec)  
  30.   
  31. mysql> insert into tb values(3,'fred');  
  32. Query OK, 1 row affected (0.00 sec)  
  33.   
  34. mysql> show binary logs;  
  35. +-----------------+-----------+  
  36. | Log_name        | File_size |  
  37. +-----------------+-----------+  
  38. | APP01bin.000001 |       409 |  
  39. | APP01bin.000002 |       363 |  
  40. +-----------------+-----------+  
  41.   
  42. mysql> show binlog events;  
  43. +-----------------+-----+-------------+-----------+-------------+----------------------------------------------------+  
  44. | Log_name        | Pos | Event_type  | Server_id | End_log_pos | Info                                               |  
  45. +-----------------+-----+-------------+-----------+-------------+----------------------------------------------------+  
  46. | APP01bin.000001 |   4 | Format_desc |        11 |         120 | Server ver: 5.6.12-log, Binlog ver: 4              |  
  47. | APP01bin.000001 | 120 | Query       |        11 |         213 | BEGIN                                              |  
  48. | APP01bin.000001 | 213 | Query       |        11 |         332 | use `replication`; insert into tb values(2,'jack') |  
  49. | APP01bin.000001 | 332 | Xid         |        11 |         363 | COMMIT /* xid=382 */                               |  
  50. | APP01bin.000001 | 363 | Rotate      |        11 |         409 | APP01bin.000002;pos=4                              |  
  51. +-----------------+-----+-------------+-----------+-------------+----------------------------------------------------+  
  52. -- 在上面的结果中第3行能够看到咱们执行的SQL语句,第4行为自动提交  
  53. -- Author : Leshami  
  54. -- Blog   : http://blog.csdn.net/leshami  
  55.   
  56. b、查看指定binlog文件的内容(show binlog events in 'binname.xxxxx')  
  57. mysql> show binlog events in 'APP01bin.000002';  
  58. +-----------------+-----+-------------+-----------+-------------+----------------------------------------------------+  
  59. | Log_name        | Pos | Event_type  | Server_id | End_log_pos | Info                                               |  
  60. +-----------------+-----+-------------+-----------+-------------+----------------------------------------------------+  
  61. | APP01bin.000002 |   4 | Format_desc |        11 |         120 | Server ver: 5.6.12-log, Binlog ver: 4              |  
  62. | APP01bin.000002 | 120 | Query       |        11 |         213 | BEGIN                                              |  
  63. | APP01bin.000002 | 213 | Query       |        11 |         332 | use `replication`; insert into tb values(3,'fred') |  
  64. | APP01bin.000002 | 332 | Xid         |        11 |         363 | COMMIT /* xid=394 */                               |  
  65. +-----------------+-----+-------------+-----------+-------------+----------------------------------------------------+  
  66.   
  67. c、查看当前正在写入的binlog文件(show master status\G)   
  68. mysql> show master status\G  
  69. *************************** 1. row ***************************  
  70.              File: APP01bin.000002  
  71.          Position: 363  
  72.      Binlog_Do_DB:   
  73.  Binlog_Ignore_DB:   
  74. Executed_Gtid_Set:   
  75. 1 row in set (0.00 sec)  
  76.   
  77. d、获取指定位置binlog的内容(show binlog events from)   
  78. mysql> show binlog events from 213;  
  79. +-----------------+-----+------------+-----------+-------------+----------------------------------------------------+  
  80. | Log_name        | Pos | Event_type | Server_id | End_log_pos | Info                                               |  
  81. +-----------------+-----+------------+-----------+-------------+----------------------------------------------------+  
  82. | APP01bin.000001 | 213 | Query      |        11 |         332 | use `replication`; insert into tb values(2,'jack') |  
  83. | APP01bin.000001 | 332 | Xid        |        11 |         363 | COMMIT /* xid=382 */                               |  
  84. | APP01bin.000001 | 363 | Rotate     |        11 |         409 | APP01bin.000002;pos=4                              |  
  85. +-----------------+-----+------------+-----------+-------------+----------------------------------------------------+  

三、演示mysqlbinlog方式提取binlogapi

[python]  view plain  copy
 
 print?
  1. a、提取指定的binlog日志  
  2. # mysqlbinlog /opt/data/APP01bin.000001  
  3. # mysqlbinlog /opt/data/APP01bin.000001|grep insert  
  4. /*!40019 SET @@session.max_insert_delayed_threads=0*/;  
  5. insert into tb values(2,'jack')  
  6.   
  7. b、提取指定position位置的binlog日志  
  8. # mysqlbinlog --start-position="120" --stop-position="332" /opt/data/APP01bin.000001  
  9.   
  10. c、提取指定position位置的binlog日志并输出到压缩文件  
  11. # mysqlbinlog --start-position="120" --stop-position="332" /opt/data/APP01bin.000001 |gzip >extra_01.sql.gz  
  12.   
  13. d、提取指定position位置的binlog日志导入数据库  
  14. # mysqlbinlog --start-position="120" --stop-position="332" /opt/data/APP01bin.000001 | mysql -uroot -p  
  15.   
  16. e、提取指定开始时间的binlog并输出到日志文件  
  17. # mysqlbinlog --start-datetime="2014-12-15 20:15:23" /opt/data/APP01bin.000002 --result-file=extra02.sql  
  18.   
  19. f、提取指定位置的多个binlog日志文件  
  20. # mysqlbinlog --start-position="120" --stop-position="332" /opt/data/APP01bin.000001 /opt/data/APP01bin.000002|more  
  21.   
  22. g、提取指定数据库binlog并转换字符集到UTF8  
  23. # mysqlbinlog --database=test --set-charset=utf8 /opt/data/APP01bin.000001 /opt/data/APP01bin.000002 >test.sql  
  24.   
  25. h、远程提取日志,指定结束时间   
  26. # mysqlbinlog -urobin -p -h192.168.1.116 -P3306 --stop-datetime="2014-12-15 20:30:23" --read-from-remote-server mysql-bin.000033 |more  
  27.   
  28. i、远程提取使用row格式的binlog日志并输出到本地文件  
  29. # mysqlbinlog -urobin -p -P3606 -h192.168.1.177 --read-from-remote-server -vv inst3606bin.000005 >row.sql  

四、获取mysqlbinlog的帮助信息(仅列出经常使用选项)
-?, --help
   显示帮助消息并退出。缓存

-d, --database=name
   只列出该数据库的条目(只适用本地日志)。安全

-f, --force-read
   使用该选项,若是mysqlbinlog读它不能识别的二进制日志事件,它会打印警告,忽略该事件并继续。没有该选项,若是mysqlbinlog读到此类事件则中止。性能优化

-h, --host=name
   获取给定主机上的MySQL服务器的二进制日志。

-l, --local-load=name
   为指定目录中的LOAD DATA INFILE预处理本地临时文件。

-o, --offset=# 
   跳过前N个条目。

-p, --password[=name]
   当链接服务器时使用的密码。若是使用短选项形式(-p),选项和密码之间不能有空格。 
   若是在命令行中–password或-p选项后面没有密码值,则提示输入一个密码。

-P, --port=# 
   用于链接远程服务器的TCP/IP端口号。

--protocol=name
   使用的链接协议。

-R, --read-from-remote-server|--read-from-remote-master=name
   从MySQL服务器读二进制日志。若是未给出该选项,任何链接参数选项将被忽略,即链接到本地。
   这些选项是–host、–password、–port、–protocol、–socket和–user。

-r, --result-file=name 
   将输出指向给定的文件。

-s, --short-form
   只显示日志中包含的语句,不显示其它信息,该方式能够缩小生成sql文件的尺寸。

-S, --socket=name
   用于链接的套接字文件。

--start-datetime=name
   从二进制日志中读取等于或晚于datetime参量的事件,datetime值相对于运行mysqlbinlog的机器上的本地时区。
   该值格式应符合DATETIME或TIMESTAMP数据类型。例如:2004-12-25 11:25:56 ,建议使用引号标识。

--stop-datetime=name
   从二进制日志中读取小于或等于datetime的全部日志事件。关于datetime值的描述参见--start-datetime选项。

-j, --start-position=# 
   从二进制日志中第1个位置等于N参量时的事件开始读。

--stop-position=#
   从二进制日志中第1个位置等于和大于N参量时的事件起中止读。

--server-id=#   
   仅仅提取指定server_id的binlog日志

--set-charset=name 
   添加SET NAMES character_set到输出      
                
-t, --to-last-log 
   在MySQL服务器中请求的二进制日志的结尾处不中止,而是继续打印直到最后一个二进制日志的结尾。
   若是将输出发送给同一台MySQL服务器,会致使无限循环。该选项要求–read-from-remote-server。

-D, --disable-log-bin
   禁用二进制日志。若是使用–to-last-logs选项将输出发送给同一台MySQL服务器,能够避免无限循环。
   该选项在崩溃恢复时也颇有用,能够避免复制已经记录的语句。注释:该选项要求有SUPER权限。

-u, --user=name
   链接远程服务器时使用的MySQL用户名。

-v, --verbose
   用于输出基于row模式的binlog日志,-vv为列数据类型添加注释

-V, --version
   显示版本信息并退出。

 

五、小结
a、能够经过show binlog events以及mysqlbinlog方式来提取binlog日志。
b、show binlog events 参数有限不适宜批量提取,mysqlbinlog可用于批量提取来创建恢复数据库的SQL。
c、mysqlbinlog能够基于时间点,position等方式实现不彻底恢复或时点恢复。
d、mysqlbinlog能够从支持本地或远程方式提取binlog日志。
e、mysqlbinlog能够基于server_id,以及基于数据库级别提取日志,不支持表级别。

 

Mysql数据库之Binlog日志使用总结

原文:http://www.cnblogs.com/kevingrace/p/6065088.html

binlog二进制日志对于mysql数据库的重要性有多大,在此就很少说了。下面根据本人的平常操做经历,并结合网上参考资料,对binlog日志使用作一梳理:

1、binlog日志介绍
1)什么是binlog
binlog日志用于记录全部更新了数据或者已经潜在更新了数据(例如,没有匹配任何行的一个DELETE)的全部语句。语句以“事件”的形式保存,它描述数据更改。

2)binlog做用
由于有了数据更新的binlog,因此能够用于实时备份,与master/slave主从复制结合。

3)和binlog有关参数
log_bin
设置此参数表示启用binlog功能,并指定路径名称
log_bin_index
设置此参数是指定二进制索引文件的路径与名称
binlog_do_db
此参数表示只记录指定数据库的二进制日志
binlog_ignore_db
此参数表示不记录指定的数据库的二进制日志
max_binlog_cache_size
此参数表示binlog使用的内存最大的尺寸
binlog_cache_size
此参数表示binlog使用的内存大小,能够经过状态变量binlog_cache_use和binlog_cache_disk_use来帮助测试。
binlog_cache_use:使用二进制日志缓存的事务数量
binlog_cache_disk_use:使用二进制日志缓存但超过binlog_cache_size值并使用临时文件来保存事务中的语句的事务数量

max_binlog_size
Binlog最大值,最大和默认值是1GB,该设置并不能严格控制Binlog的大小,尤为是Binlog比较靠近最大值而又遇到一个比较大事务时,为了保证事务的完整性,不可能作切换日志的动做,只能将该事务的全部SQL都记录进当前日志,直到事务结束
sync_binlog
这个参数直接影响mysql的性能和完整性
sync_binlog=0
当事务提交后,Mysql仅仅是将binlog_cache中的数据写入Binlog文件,但不执行fsync之类的磁盘 同步指令通知文件系统将缓存刷新到磁盘,而让Filesystem自行决定何时来作同步,这个是性能最好的。
sync_binlog=n,在进行n次事务提交之后,Mysql将执行一次fsync之类的磁盘同步指令,同志文件系统将Binlog文件缓存刷新到磁盘。
Mysql中默认的设置是sync_binlog=0,即不做任何强制性的磁盘刷新指令,这时性能是最好的,但风险也是最大的。一旦系统绷Crash,在文件系统缓存中的全部Binlog信息都会丢失

4)binlog的删除
binlog的删除能够手工删除或自动删除:
a)自动删除binlog
经过binlog参数(expire_logs_days )来实现mysql自动删除binlog
mysql> show binary logs;
mysql> show variables like 'expire_logs_days';      //该参数表示binlog日志自动删除/过时的天数,默认值为0,表示不自动删除
mysql> set global expire_logs_days=3;        //表示日志保留3天,3天后就自动过时。
b)手工删除binlog
mysql> reset master;        //删除master的binlog,即手动删除全部的binlog日志
mysql> reset slave;          //删除slave的中继日志
mysql> purge master logs before '2012-03-30 17:20:00';         //删除指定日期之前的日志索引中binlog日志文件
mysql> purge master logs to 'binlog.000002';       //删除指定日志文件的日志索引中binlog日志文件

mysql> set sql_log_bin=1/0;       //若是用户有super权限,能够启用或禁用当前会话的binlog记录
mysql> show master logs;          //查看master的binlog日志列表
mysql> show binary logs;           //查看master的binlog日志文件大小
mysql> show master status;     //用于提供master二进制日志文件的状态信息
mysql> show slave hosts;        //显示当前注册的slave的列表。不以--report-host=slave_name选项为开头的slave不会显示在本列表中

mysql> flush logs;     //产生一个新的binlog日志文件

 

mysql binlog日志自动清理及手动删除案例说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
当开启MySQL数据库主从时,会产生大量如mysql-bin.00000*  log 的文件,这会大量耗费您的硬盘空间。
mysql-bin.000001
mysql-bin.000002
mysql-bin.000003
mysql-bin.000004
mysql-bin.000005
 
删除这些binlog日志有三种解决方法:
1.关闭mysql主从,关闭binlog;
实例操做以下:
[root@huqniupc ~]# vim /etc/my.cnf     //注释掉log-bin和binlog_format
# Replication Master Server (default)
# binary logging is required for replication
# log-bin=mysql-bin
# binary logging format - mixed recommended
# binlog_format=mixed
而后重启数据库
 
2.开启mysql主从,设置expire_logs_days;
实例操做以下:
[root@huqniupc ~]# vim /etc/my.cnf   //修改expire_logs_days,x是自动删除的天数,通常将x设置为短点,如10
expire_logs_days = x   //二进制日志自动删除的天数。默认值为0,表示“没有自动删除”
此方法须要重启mysql
 
固然也能够不重启mysql,开启mysql主从,直接在mysql里设置expire_logs_days
> show binary logs;
> show variables like  '%log%' ;
> set global expire_logs_days = 10;
 
 
3.手动清除binlog文件,(好比Mysql> PURGE MASTER LOGS TO ‘MySQL-bin.010′;)
实例操做以下:
[root@huqniupc ~]# /usr/local/mysql/bin/mysql -u root -p
> PURGE MASTER LOGS BEFORE DATE_SUB(CURRENT_DATE, INTERVAL 10 DAY);    //删除10天前的MySQL binlog日志,附录2有关于PURGE MASTER LOGS手动删除用法及示例
> show master logs;
  
也能够重置master,删除全部binlog文件:
# /usr/local/mysql/bin/mysql -u root -p
> reset master;   //附录3有清除binlog时,对从mysql的影响说明
  
-----------------------------------------------------------------------------------------------------------------------------------------------
PURGE MASTER LOGS手动删除用法及示例,MASTER和BINARY是同义词
> PURGE {MASTER | BINARY} LOGS TO  'log_name'
> PURGE {MASTER | BINARY} LOGS BEFORE  'date'
删除指定的日志或日期以前的日志索引中的全部二进制日志。这些日志也会从记录在日志索引文件中的清单中被删除MySQL BIN-LOG 日志,这样被给定的日志成为第一个。
 
实例:
> PURGE MASTER LOGS TO  'MySQL-bin.010' ;   //清除MySQL-bin.010日志
> PURGE MASTER LOGS BEFORE  '2008-06-22 13:00:00' ;    //清除2008-06-22 13:00:00前binlog日志
> PURGE MASTER LOGS BEFORE DATE_SUB( NOW( ), INTERVAL 3 DAY);   //清除3天前binlog日志BEFORE,变量的date自变量能够为'YYYY-MM-DD hh:mm:ss'格式。
-----------------------------------------------------------------------------------------------------------------------------------------------

5)清除binlog时,对从mysql的影响
若是有一个活跃的slave从属服务器,该服务器当前正在读取您正在试图删除的日志之一,则本语句不会起做用,而是会失败,并伴随一个错误;不过若是slave从属服务器是关闭的(或master-slave主从关系关闭),而且碰巧清理了其想要读取的日志之一,则slave从属服务器启动后不能复制;当从属服务器正在复制时,本语句能够安全运行,不须要中止它们。

6)binglog的查看
经过mysqlbinlog命令能够查看binlog的内容
[root@localhost ~]# mysqlbinlog /home/mysql/binlog/binlog.000003 | more
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#120330 16:51:46 server id 1 end_log_pos 98 Start: binlog v 4, server v 5.0.45-log created 120330 1
6:51:46
# Warning: this binlog was not closed properly. Most probably mysqld crashed writing it.
# at 196
#120330 17:54:15 server id 1 end_log_pos 294 Query thread_id=3 exec_time=2 error_code=0
SET TIMESTAMP=1333101255/*!*/;
insert into tt7 select * from tt7/*!*/;
# at 294
#120330 17:54:46 server id 1 end_log_pos 388 Query thread_id=3 exec_time=28 error_code=0
SET TIMESTAMP=1333101286/*!*/;
alter table tt7 engine=innodb/*!*/;

解析binlog格式:
位置
位于文件中的位置,“at 196”说明“事件”的起点,是以第196字节开始;“end_log_pos 294”说明以第294字节结束

时间戳
事件发生的时间戳:“120330 17:54:46”

事件执行时间
事件执行花费的时间:"exec_time=28"

错误码
错误码为:“error_code=0”

服务器的标识
服务器的标识id:“server id 1”

注意下面几点:
1.mysql的日志切不可想象是能够恢复到任什么时候间的状态,这个恢复是有前提的!
至少得有一个从日志记录开始后的数据库备份,经过日志恢复数据库实际上只是一个对之前操做的回放过程而已,不用想得太复杂。
既然是回放操做,那么就得注意了,若是是执行了两次恢复那就至关因而回放了两次,后果可想而知。
因此:
1)恢复前务必先备份数据.
2)因为二进制文件多,而且须要恢复的数据跨度大,能够考虑将日志文件合并在恢复.

2. 开启binlog日志功能
要想经过日志恢复数据库,必须首先在my.cnf文件里定义,log-bin=mysql-bin,这样产生的binlog日志名就是以mysql-bin命名的

3.何时会生成新的binlog文件
1)在备份的时候加入--flush-logs
2)从新启动mysql服务的时候
特别提示,mysql每次启动都会从新生成一个相似mysql-bin.00000n的文件,若是你的mysql天天都要从新启动一次的话,这时候你就要特别注意不要选错日志文件了。

 

2、binlog日志格式介绍 

(1)Mysql binlog日志有三种格式,分别是Statement、MiXED、ROW

1)Statement:每一条会修改数据的sql都会记录在binlog中
优势:不须要记录每一行的变化,减小了binlog日志量,节约了IO,提升性能。(相比row能节约多少性能与日志量,这个取决于应用的SQL状况,正常同一条记录修改或者插入row格式所产生的日志量还小于Statement产生的日志量,可是考虑到若是带条件的update操做,以及整表删除,alter表等操做,ROW格式会产生大量日志,所以在考虑是否使用ROW格式日志时应该跟据应用的实际状况,其所产生的日志量会增长多少,以及带来的IO性能问题。)
缺点:因为记录的只是执行语句,为了这些语句能在slave上正确运行,所以还必须记录每条语句在执行的时候的一些相关信息,以保证全部语句能在slave获得和在master端执行时候相同 的结果。另外mysql 的复制,像一些特定函数功能,slave可与master上要保持一致会有不少相关问题(如sleep()函数, last_insert_id(),以及user-defined functions(udf)会出现问题).

使用如下函数的语句也没法被复制:
* LOAD_FILE()
* UUID()
* USER()
* FOUND_ROWS()
* SYSDATE() (除非启动时启用了 --sysdate-is-now 选项)

同时在INSERT ...SELECT 会产生比 RBR 更多的行级锁

2)Row:不记录sql语句上下文相关信息,仅保存哪条记录被修改
优势: binlog中能够不记录执行的sql语句的上下文相关的信息,仅须要记录那一条记录被修改为什么了。因此rowlevel的日志内容会很是清楚的记录下每一行数据修改的细节。并且不会出现某些特定状况下的存储过程,或function,以及trigger的调用和触发没法被正确复制的问题
缺点:全部的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,好比一条update语句,修改多条记录,则binlog中每一条修改都会有记录,这样形成binlog日志量会很大,特别是当执行alter table之类的语句的时候,因为表结构修改,每条记录都发生改变,那么该表每一条记录都会记录到日志中。

3)Mixedlevel: 是以上两种level的混合使用,通常的语句修改使用statment格式保存binlog,如一些函数,statement没法完成主从复制的操做,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种.新版本的MySQL中队row level模式也被作了优化,并非全部的修改都会以row level来记录,像遇到表结构变动的时候就会以statement模式来记录。至于update或者delete等修改数据的语句,仍是会记录全部行的变动。

Mixed日志说明:
在slave日志同步过程当中,对于使用now这样的时间函数,MIXED日志格式,会在日志中产生对应的unix_timestamp()*1000的时间字符串,slave在完成同步时,取用的是sqlEvent发生的时间来保证数据的准确性。另外对于一些功能性函数slave能完成相应的数据同步,而对于上面指定的一些相似于UDF函数,致使Slave没法知晓的状况,则会采用ROW格式存储这些Binlog,以保证产生的Binlog能够供Slave完成数据同步。

(2)binlog基本配制与格式设定
1)基本配制
binlog日志格式能够经过mysql的my.cnf文件的属性binlog_format指定。如如下:
binlog_format = MIXED              //binlog日志格式
log_bin =目录/mysql-bin.log       //binlog日志名
expire_logs_days = 7                 //binlog过时清理时间
max_binlog_size 100m              //binlog每一个日志文件大小

binlog-do-db=须要备份的数据库名,若是备份多个数据库,重复设置这个选项便可
binlog-ignore-db=不须要备份的数据库苦命,若是备份多个数据库,重复设置这个选项便可

2)Binlog日志格式选择
Mysql默认是使用Statement日志格式,推荐使用MIXED.
因为一些特殊使用,能够考虑使用ROWED,如本身经过binlog日志来同步数据的修改,这样会节省不少相关操做。对于binlog数据处理会变得很是轻松,相对mixed,解析也会很轻松(固然前提是增长的日志量所带来的IO开销在容忍的范围内便可)。

3)mysqlbinlog格式选择
mysql对于日志格式的选定原则:若是是采用 INSERT,UPDATE,DELETE 等直接操做表的状况,则日志格式根据 binlog_format 的设定而记录,若是是采用 GRANT,REVOKE,SET PASSWORD 等管理语句来作的话,那么不管如何 都采用 SBR 模式记录

(3)Mysql Binlog日志分析

经过MysqlBinlog指令查看具体的mysql日志,以下:

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SET TIMESTAMP=1350355892/*!*/;

BEGIN

/*!*/;

# at 1643330

#121016 10:51:32 server id 1 end_log_pos 1643885 Query thread_id=272571 exec_time=0 error_code=0

SET TIMESTAMP=1350355892/*!*/;

Insert into T_test….)

/*!*/;

# at 1643885

#121016 10:51:32 server id 1 end_log_pos 1643912 Xid = 0

COMMIT/*!*/;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

1.开始事物的时间:

SET TIMESTAMP=1350355892/*!*/;

BEGIN

2.sqlevent起点

#at 1643330 :为事件的起点,是以1643330字节开始。

3.sqlevent 发生的时间点

#121016 10:51:32:是事件发生的时间,

4.serverId

server id 1 :为master 的serverId

5.sqlevent终点及花费时间,错误码

end_log_pos 1643885:为事件的终点,是以1643885 字节结束。

execTime 0: 花费的时间

error_code=0:错误码

Xid:事件指示提交的XA事务

 

3、mysql日志(重点binlog日志)的优化说明
MySQL系统的伸缩性很强,既能够在充足的硬件资源环境下高效运行,也能够在极少资源环境下很好的运行,
但无论怎样,尽量充足的硬件资源对MySQL的性能提高老是有帮助的。

下面着重分析一下MySQL的日志(主要是Binlog)对系统性能的影响,并根据日志的相关特性得出相应的优化思路。

1)日志产生的性能影响
因为日志的记录带来的直接性能损耗就是数据库系统中最为昂贵的IO资源。

MySQL的日志主要包括错误日志(ErrorLog),更新日志(UpdateLog),二进制日志(Binlog),查询日志(QueryLog),慢查询日志(SlowQueryLog)等。
特别注意:更新日志是老版本的MySQL才有的,目前已经被二进制日志替代。

在默认状况下,系统仅仅打开错误日志,关闭了其余全部日志,以达到尽量减小IO损耗提升系统性能的目的。
可是在通常稍微重要一点的实际应用场景中,都至少须要打开二进制日志,由于这是MySQL不少存储引擎进行增量备份的基础,也是MySQL实现复制的基本条件。
有时候为了进一步的mysql性能优化,定位执行较慢的SQL语句,不少系统也会打开慢查询日志来记录执行时间超过特定数值(由咱们自行设置)的SQL语句。

通常状况下,在生产系统中不多有系统会打开查询日志。由于查询日志打开以后会将MySQL中执行的每一条Query都记录到日志中,会该系统带来比较大的IO负担,而带来的实际效益却并非很是大。通常只有在开发测试环境中,为了定位某些功能具体使用了哪些SQL语句的时候,才会在短期段内打开该日志来作相应的分析。
因此,在MySQL系统中,会对性能产生影响的MySQL日志(不包括各存储引擎本身的日志)主要就是Binlog了。

2)Binlog 相关参数及优化策略
咱们首先看看Binlog的相关参数,经过执行以下命令能够得到关于Binlog的相关参数。
固然,其中也显示出了“innodb_locks_unsafe_for_binlog”这个Innodb存储引擎特有的与Binlog相关的参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
mysql> show variables  like  '%binlog%' ;
+ -----------------------------------------+----------------------+
| Variable_name                           | Value                |
+ -----------------------------------------+----------------------+
| binlog_cache_size                       | 16777216             |
| binlog_checksum                         | CRC32                |
| binlog_direct_non_transactional_updates |  OFF                   |
| binlog_error_action                     | IGNORE_ERROR         |
| binlog_format                           | MIXED                |
| binlog_gtid_simple_recovery             |  OFF                   |
| binlog_max_flush_queue_time             | 0                    |
| binlog_order_commits                    |  ON                    |
| binlog_row_image                        |  FULL                  |
| binlog_rows_query_log_events            |  OFF                   |
| binlog_stmt_cache_size                  | 32768                |
| binlogging_impossible_mode              | IGNORE_ERROR         |
| innodb_api_enable_binlog                |  OFF                   |
| innodb_locks_unsafe_for_binlog          |  OFF                   |
| max_binlog_cache_size                   | 18446744073709547520 |
| max_binlog_size                         | 1073741824           |
| max_binlog_stmt_cache_size              | 18446744073709547520 |
| simplified_binlog_gtid_recovery         |  OFF                   |
| sync_binlog                             | 1                    |
+ -----------------------------------------+----------------------+
19  rows  in  set  (0.00 sec)

“binlog_cache_size":在事务过程当中容纳二进制日志SQL语句的缓存大小。二进制日志缓存是服务器支持事务存储引擎而且服务器启用了二进制日志(—log-bin选项)的前提下为每一个客户端分配的内存,注意,是每一个Client均可以分配设置大小的binlogcache空间。若是读者朋友的系统中常常会出现多语句事务的华,能够尝试增长该值的大小,以得到更有的性能。固然,咱们能够经过MySQL的如下两个状态变量来判断当前的binlog_cache_size的情况:Binlog_cache_use和Binlog_cache_disk_use。

“max_binlog_cache_size”:和"binlog_cache_size"相对应,可是所表明的是binlog可以使用的最大cache内存大小。当咱们执行多语句事务的时候,max_binlog_cache_size若是不够大的话,系统可能会报出“Multi-statementtransactionrequiredmorethan'max_binlog_cache_size'bytesofstorage”的错误。

“max_binlog_size”:Binlog日志最大值,通常来讲设置为512M或者1G,但不能超过1G。该大小并不能很是严格控制Binlog大小,尤为是当到达Binlog比较靠近尾部而又遇到一个较大事务的时候,系统为了保证事务的完整性,不可能作切换日志的动做,只能将该事务的全部SQL都记录进入当前日志,直到该事务结束。这一点和Oracle的Redo日志有点不同,由于Oracle的Redo日志所记录的是数据文件的物理位置的变化,并且里面同时记录了Redo和Undo相关的信息,因此同一个事务是否在一个日志中对Oracle来讲并不关键。而MySQL在Binlog中所记录的是数据库逻辑变化信息,MySQL称之为Event,实际上就是带来数据库变化的DML之类的Query语句。

“sync_binlog”:这个参数是对于MySQL系统来讲是相当重要的,他不只影响到Binlog对MySQL所带来的性能损耗,并且还影响到MySQL中数据的完整性。对于“sync_binlog”参数的各类设置的说明以下:

sync_binlog=0,当事务提交以后,MySQL不作fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定何时来作同步,或者cache满了以后才同步到磁盘。

sync_binlog=n,当每进行n次事务提交以后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。

在MySQL中系统默认的设置是sync_binlog=0,也就是不作任何强制性的磁盘刷新指令,这时候的性能是最好的,可是风险也是最大的。由于一旦系统Crash,在binlog_cache中的全部binlog信息都会被丢失。而当设置为“1”的时候,是最安全可是性能损耗最大的设置。由于当设置为1的时候,即便系统Crash,也最多丢失binlog_cache中未完成的一个事务,对实际数据没有任何实质性影响。从以往经验和相关测试来看,对于高并发事务的系统来讲,“sync_binlog”设置为0和设置为1的系统写入性能差距可能高达5倍甚至更多。


另:
MySQL的复制(Replication),实际上就是经过将Master端的Binlog经过利用IO线程经过网络复制到Slave端,而后再经过SQL线程解析Binlog中的日志再应用到数据库中来实现的。因此,Binlog量的大小对IO线程以及Msater和Slave端之间的网络都会产生直接的影响。

MySQL中Binlog的产生量是没办法改变的,只要咱们的Query改变了数据库中的数据,那么就必须将该Query所对应的Event记录到Binlog中。那咱们是否是就没有办法优化复制了呢?固然不是,在MySQL复制环境中,其实是是有8个参数可让咱们控制须要复制或者须要忽略而不进行复制的DB或者Table的,分别为:

Binlog_Do_DB:设定哪些数据库(Schema)须要记录Binlog;

Binlog_Ignore_DB:设定哪些数据库(Schema)不要记录Binlog;

Replicate_Do_DB:设定须要复制的数据库(Schema),多个DB用逗号(“,”)分隔;

Replicate_Ignore_DB:设定能够忽略的数据库(Schema);

Replicate_Do_Table:设定须要复制的Table;

Replicate_Ignore_Table:设定能够忽略的Table;

Replicate_Wild_Do_Table:功能同Replicate_Do_Table,但能够带通配符来进行设置;

Replicate_Wild_Ignore_Table:功能同Replicate_Ignore_Table,可带通配符设置;


经过上面这八个参数,咱们就能够很是方便按照实际需求,控制从Master端到Slave端的Binlog量尽量的少,从而减少Master端到Slave端的网络流量,减小IO线程的IO量,还能减小SQL线程的解析与应用SQL的数量,最终达到改善Slave上的数据延时问题。

实际上,上面这八个参数中的前面两个是设置在Master端的,然后面六个参数则是设置在Slave端的。虽然前面两个参数和后面六个参数在功能上并无很是直接的关系,可是对于优化MySQL的Replication来讲均可以启到类似的功能。固然也有必定的区别,其主要区别以下:

若是在Master端设置前面两个参数,不只仅会让Master端的Binlog记录所带来的IO量减小,还会让Master端的IO线程就能够减小Binlog的读取量,传递给Slave端的IO线程的Binlog量天然就会较少。这样作的好处是能够减小网络IO,减小Slave端IO线程的IO量,减小Slave端的SQL线程的工做量,从而最大幅度的优化复制性能。固然,在Master端设置也存在必定的弊端,由于MySQL的判断是否须要复制某个Event不是根据产生该Event的Query所更改的数据


所在的DB,而是根据执行Query时刻所在的默认Schema,也就是咱们登陆时候指定的DB或者运行“USEDATABASE”中所指定的DB。只有当前默认DB和配置中所设定的DB彻底吻合的时候IO线程才会将该Event读取给Slave的IO线程。因此若是在系统中出如今默认DB和设定须要复制的DB不同的状况下改变了须要复制的DB中某个Table的数据的时候,该Event是不会被复制到Slave中去的,这样就会形成Slave端的数据和Master的数据不一致的状况出现。一样,若是在默认Schema下更改了不须要复制的Schema中的数据,则会被复制到Slave端,当Slave端并无该Schema的时候,则会形成复制出错而中止。

而若是是在Slave端设置后面的六个参数,在性能优化方面可能比在Master端要稍微逊色一点,由于无论是须要仍是不须要复制的Event都被会被IO线程读取到Slave端,这样不只仅增长了网络IO量,也给Slave端的IO线程增长了RelayLog的写入量。可是仍然能够减小Slave的SQL线程在Slave端的日志应用量。虽然性能方面稍有逊色,可是在Slave端设置复制过滤机制,能够保证不会出现由于默认Schema的问题而形成Slave和Master数据不一致或者复制出错的问题。

3)慢查询日志Query Log 相关参数及使用建议
再来看看SlowQueryLog的相关参数配置。有些时候,咱们为了定位系统中效率比较地下的Query语句,则须要打开慢查询日志,也就是SlowQueryLog。咱们能够以下查看系统慢查询日志的相关设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> show variables  like  'log_slow%' ;
+ ------------------+-------+
| Variable_name | Value |
+ ------------------+-------+
| log_slow_queries |  ON  |
+ ------------------+-------+
1 row  in  set  (0.00 sec)
 
mysql> show variables  like  'long_query%' ;
+ -----------------+-------+
| Variable_name | Value |
+ -----------------+-------+
| long_query_time | 1 |
+ -----------------+-------+
1 row  in  set  (0.01 sec)

“log_slow_queries”参数显示了系统是否已经打开SlowQueryLog功能,而“long_query_time”参数则告诉咱们当前系统设置的SlowQuery记录执行时间超过多长的Query。在MySQLAB发行的MySQL版本中SlowQueryLog能够设置的最短慢查询时间为1秒,这在有些时候可能没办法彻底知足咱们的要求,若是但愿可以进一步缩短慢查询的时间限制,可使用Percona提供的microslow-patch(件成为mslPatch)来突破该限制。mslpatch不只仅能将慢查询时间减少到毫秒级别,同时还能经过一些特定的规则来过滤记录的SQL,如仅记录涉及到某个表的SlowQuery等等附加功能。

打开SlowQueryLog功能对系统性能的总体影响没有Binlog那么大,毕竟SlowQueryLog的数据量比较小,带来的IO损耗也就较小,可是,系统须要计算每一条Query的执行时间,因此消耗老是会有一些的,主要是CPU方面的消耗。若是你们的系统在CPU资源足够丰富的时候,能够没必要在意这一点点损耗,毕竟他可能会给咱们带来更大性能优化的收获。但若是咱们的CPU资源也比较紧张的时候,也彻底能够在大部分时候关闭该功能,而只须要间断性的打开SlowQueryLog功能来定位可能存在的慢查询。

MySQL的其余日志因为使用不多(QueryLog)或者性能影响不多,在此就不作过多分析了。

 

***************当你发现本身的才华撑不起野心时,就请安静下来学习吧***************
相关文章
相关标签/搜索