代码改变世界

mysql之binlog和各类日志介绍

2018-12-12 15:08  烟雨楼人  阅读(1271)  评论(0编辑  收藏  举报

1.错误日志

错误日志作用记录MySQL的启动、停止信息以及在MySQL运行过程中的错误信息。

参数log_error(默认开启)  修改后重启生效

log_error=[path/[file_name]],如果不指定文件名,则默认hostname.err.

查看错误日志路径:

mysql> show variables like '%log_error%';

删除错误日志后:

<5.5.7版本时,flush logs会将filename.err命名为filename.err_old

>5.5.7版本则只是会重建错误日志,也就是除非错误日志被删除了,会重建一个否则不会对线上错误日志有影响。

注意:删除错误日志后,不会自动重建。需要flush logs或者重启数据库。

 

mysqladmin -u root -p flush-logs  或者 mysql>flush logs;重新后生成错误日志(同名).

2.MySQL general日志(默认关闭)

作用:会记录所有的mysql内执行的sql语句(注意是所有语句,包括查询语句).一般不开启,因为要记录所有的语句,所以IO压力比较大当统计某些sql的执行频率,写脚本过滤一些sql.是用到.
查看general日志路径:
mysql> show variables like '%general_log%';

general_log(默认关闭){0-关闭,1-开启可以在线打开和关闭;

set global general_log='ON;

general_log_file=file_name,

不指定文件名只指定路径则为hostname.log (例如主机名为master,则为master.log)

3.MySQL慢查询日志(默认关闭)

作用:记录慢sql,执行比较慢的sql.

路径mysql> show variables like '%slow_query_log%';

MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在 MySQL中响应时间超过阀值的语句。(默认关闭)

注意:慢查询日志不会计算语句在开始执行之前等待锁的时间 (initial slow query)mysqld只会从语句等待的锁释放掉,并开始执行开始计算时间(执行开始后的锁定时间会记录)。所以慢查询日志中的语句顺序和语句的发出顺序或者general log的顺序不同。

相关参数:

slow_query_log =1/0   ---开启关闭慢查询

long_query_time = 1 2 3  ---慢查询阀值.(单位是s)

log_queries_not_using_indexes:记录没有用索引的查询

参数:log_throttle_queries_not_using_indexes:#设定每分钟记录到日志的未使用索引的语句数目,超过这个数目后只记录语句数量和花费的总时间

参数:min_examined_row_limit:要检查的行数大于等于N时 才记录为慢查询,前提是必须满足long_query_time log-queries-not-using-indexes约束。

参数:log_slow_admin_statements:管理语句是否记录

参数:log_slow_slave_statements:从库的语句执行是否记录.

慢日志信息例子:

# Time: 2018-10-18T21:56:45.731545+08:00

# User@Host: root[root] @ localhost []  Id:     5

# Query_time: 3.059106  Lock_time: 0.000208 Rows_sent: 1048576  Rows_examined: 1048576

SET timestamp=1539871005;

select * from lbg;

分析:

Time:---sql执行完时间。 

 root[root] @ localhost     ---用户、发出sql的ip

 Query_time:       ----sql执行时间        

 Lock_time:            ---查询等待锁的时间

 Rows_sent            -----结果集大小

Rows_examined         ---扫描行数

SET timestamp        ----发出sql的时间

慢日志分析工具:  MySQLdumpSlow工具

-s, 是表示按照何种方式排序,ctlr分别是按照记录次数、时间、查询时间、返回 的记录数来排序,

acatalar,表示相应的倒叙;

-t, top n的意思,即为返回前面多少条的数据;

-g, 后边可以写一个正则匹配模式,大小写不敏感的;

比如:

统计用时最长的10sql

mysqldumpslow  -s t -t 10 mysql-slow.log

执行频率最高的10sql

mysqldumpslow  -s c -t 10 mysql-slow.log 

例子:

[root@lbg logs]# mysqldumpslow  -s t -t 10 mysql-slow.log 

Reading mysql slow query log from mysql-slow.log

Count: 1  Time=18.34s (18s)  Lock=0.00s (0s)  Rows=1048576.0 (1048576), []@[]

  throttle:         N 'S' warning(s) suppressed.

Count: 1  Time=3.06s (3s)  Lock=0.00s (0s)  Rows=1048576.0 (1048576), root[root]@localhost

  select * from lbg

Count: 4  Time=0.01s (0s)  Lock=0.00s (0s)  Rows=0.0 (0), root[root]@localhost

  insert into lbg select * from lbg

Died at /usr/local/mysql/bin/mysqldumpslow line 161, <> chunk 6.

4.binlog

 1.binlog作用及文件路径

作用: binlog其实是(binary log)是MySQL二进制日志,以二进制的形式记录了对于数据库的变更操作,记录所有的mysql的变化情况(不包括select show 等查询语句),其左右有:

1.用来查看mysql变更

2.mysql的备份恢复

3.mysql的主从复制

查看bin_log路径:

mysql> show variables like '%log_bin_basename%';

[root@lbg mysql3306]# ll mysql-bin*

-rw-r----- 1 mysql mysql 154 Oct 18 22:07 mysql-bin.000001

-rw-r----- 1 mysql mysql  43 Oct 18 22:07 mysql-bin.index

说明: mysql-bin.000001,数字慢慢增大,刚生成的binlog大小为154.

其中mysql-bin.index 里记录的就是bin-log文件的位置。

[root@lbg mysql3306]# cat mysql-bin.index 

/home/mysql3306/mysql3306/mysql-bin.000001

     2.bin-log生成方式

1.mysql在启动时候,会生成新的binlog.

2.flush logs     ----重新生成错误日志,也会重新生成bin-log

3.当达到单个binlog 文件的阀值的时候

mysql> show variables like '%max_binlog%';

 Variable_name                               Value                

 max_binlog_cache_size           8589934592           

 max_binlog_size                      1073741824           

 max_binlog_stmt_cache_size  18446744073709547520 

注意:当超过1GB文件的时候,会自动切到新的binlog,执行某些大事务,为了事务的完整性,binlog要等事务执行完成后切换,所以binlog可能大于1GB.

 

     3.bin-log相关参数

binlog_cache_size 内存分配,线程级别的内存分配,要给每一个线程单独的分配binlog cache

binlogcache大小=binlog_cache_size*线程数(这也是buffer-pool为最大为内存75%的原因之一,要留一部分内存给binlog和操作系统用)

max_binlog_cache_size,全局参数,所有的binlogcache size总和不超过该值,超过该值,报下面错: Multi-statement transaction required more than 'max_binlog_cache_size' bytes ofstorage

max_binlog_size:设置 binlog文件的最大值,默认和最大是1GB,并不能严格限定二进制文件的大小

binlog_do_db: 此参数表示只记录指定数据库的二进制日志

binlog_ignore_db: 此参数表示不记录指定的数据库的二进制日志

binlog_checksum  {CRC32|NONE}

binlog时,会将内容生成校验位,之后存储在binlog中。默认情况下,服务器记录事件的长度以及事件本身,并使用它来验证事件是否正确写入。也可以通过设置binlog_checksum系统变量来使服务器为事件写入校验和。

log_bin与log_bin_basename:决定了msyql binlog的名字,生成的binlog名字为mysql-bin.000001

binlog_format: 规定binlog的格式,binlog有三种格式statementrow以及mixed默认使用statement,建议使用row格式

expire_logs_days :过期时间(单位是天)

sync_binlog: 值为01n,    在提交n次事务后,进行binlog的落盘,0为不进行强行的刷新操作,而是由文件系统控制刷新日志文件.  如果是在线交易和帐有关的数据建议设置成1, 如果是其它数据可以保持为0即可。(1配置参数之一.)

0  1s落盘一次

1  每次commit落盘一次

n  n个事务落盘一次

sql_log_bin  --关闭当前sessionbinlog (导入大量数据时,不希望记录binlog.导完再开启参数)

    4.清理binlog

 在开启mysql的主从后,会产生大量的binlog日志文件,可能占用大量的磁盘空间,

 1.手工删除binlog

mysql> reset master; //删除masterbinlog ---会删除所有的binlog文件,重置为1,非常危险.

###reset master后,会造成slave无法找到master的严重后果

mysql> reset slave; //删除slave的中继日志

mysql> purge master logs before '2012-03-30 17:20:00'; //删除指定日期以前的日志索引中binlog日志文件

mysql> purge master logs to 'binlog.000002'; //删除指定日志文件的日志索引中binlog日志文件

或者直接用操作系统命令直接删除:直接rm(mysql-bin日志,删除索引信息mysql-bin.index里对应信息.)注意:不能删除正在使用的binlog(1.编号最大的binlog  2.从库还没有同步完成的binlog,)  这种方法尽量不用.

 2.自动删除binlog(通过参数expire_logs_days )

通过binlog参数(expire_logs_days ,设置binlog的过期参数)来实现mysql自动删除binlog

show binary logs;

show variables like 'expire_logs_days';

set global expire_logs_days=7;

    5.binlog格式

binlog格式由参数binlog_format定义.分三种: statement , row,mixed  格式.

statement格式:

特点:记录每一条数据的SQL语句,将执行的每一条SQL记录在binlog.

优点:减少日志量,节省IO,提高性能。

缺点:某些SQL中的函数无法使用,比如SYSDATE(),在同步过程中会出现无法同步的问题。

row格式:

特点:修改之前和修改之后的行的信息.

binlog中仅仅记录哪一条记录被修改,不记录sql语句,会详细记录每一row的更改细节,不会出现无法复制的问题。

优点:安全,一般线上使用row格式。

缺点:因为要记录每一条修改记录的日志, 数据比较大,可能对数据网络压力 IO压力造成影响大量占用磁盘IO和大量使用硬盘空间。

mixed格式:

特点:结合了上面两种方式,一般的语句使用SQL语句来记录,遇到特殊的语句使用row格式来记录,保证数据的一致性和复制的准确性。

注意:上面三种都是针对DML语句, DDL不管在哪个格式,都只记录语句. drop table test1;

查看binlog格式:    mysql> show variables like '%binlog_format%'; 

修改binlog格式: mysql> set global binlog_format='row';

显示存在的binlog: mysql> show binary logs;

查看binlog文件内容: mysql> show binlog events;

一般我们我们如何在binlog里面定位一个事务?

文件名:mysql-bin.000001. 加上position点可以定位一个事务.

position:就是写入binlog的字节数.(154开启,前面是无意义信息.开始文件就是154)

xid :是储存引擎内部分布式事务编号。

  6.查看binlog文件

在数据库里查看:mysql> show binlog events;(这是经过被解析后的结果,其实文件底层是二进制)
查看binlog文件:
[root@lbg1 mysql3306]# mysqlbinlog mysql-bin.000003 -vv >/tmp/lbg.bin

--vv的作用:第一个v,显示sql,第二个v,显示sql的字段类型和其他信息.

[root@lbg1 mysql3306]# cat /tmp/lbg.bin

@1指表的第1个字段。@2表示第2个字段。底下蓝色的###段落是其上面对应乱码翻译后的解释。

 

注意:mysqlbinlog命令文件是不是安装目录下的bin文件里(which mysqlbinlog),因为可能系统安装过mysql,那么可能读取的是/usr/bin/mysqlbinlog,低版本解析有问题。

mysqlbinlog使用方法:

截取pos点范围或者时间范围的binlog:start-datetime   stop-datetime 或者start-positionstop-position  。

使用mysqlbinlog查看binlog:

/usr/local/mysql/bin/mysqlbinlog  /home/mysql3306/mysql3306/mysql-bin.000001  > /tmp/mysql_binlog.sql

根据时间查看binlog:

/usr/local/mysql/bin/mysqlbinlog --start-date="2017-04-20 9:00:00" --stop-date="2017-07-20 18:00:00"

/home/mysql3306/mysql3306/mysql-bin.000001 > /tmp/mysql_binlog.sql

startstop的范围是 [start, stop)

根据pos点查看binlog:

/usr/local/mysql/bin/mysqlbinlog bin.000017 --start-position=1959 --stop-position=2057 -vv > /tmp/a.sql

解析row格式的mysqlbinlogSQL格式:

mysqlbinlog  mysql-bin.000001 --base64-output=DECODE-ROWS  -vv > /tmp/all.bin

--base64-output=DECODE-ROWS 是为了适应mysql,  server设置binlog_format=row。

注意:若用于恢复数据,则一定不能带--base64-output=DECODE-ROWS选项,否则会恢复有问题。

 7.导入多个binlog的注意事项

binlog恢复:

注意,如果有多个 binlog文件想要恢复, 不要一个一个恢复

shell> mysqlbinlog binlog.000001 | mysql -u root -p

shell> mysqlbinlog binlog.000002 | mysql -u root -p

上面这种恢复方式是错误的,如果 binlog.000001 中创建了一个临时表(CREATE TEMPORARY TABLE),而 binlog.000002 中要使用这个临时表,但是 第一个线程(binlog.000001) 在释放的时候会删除临时表,此时第二个线程(binlog.000002) 就无法使用这个临时表了.

正确的做法如下:

shell> mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p ##

或者

shell> mysqlbinlog binlog.000001 > /tmp/statements.sql

shell> mysqlbinlog binlog.000002 >> /tmp/statements.sql

或者

shell> mysqlbinlog binlog.00000[1-2] > /tmp/statements.sql 

shell> mysql -u root -p -e "source /tmp/statements.sql"

 8.binlog和redo的区别

Binlog:二进制日志是一种逻辑日志,可能只记录了对应的SQL语句。

Innodb存储引擎的的redo日志记录的是数据页被修改的的物理格式日志,

两种日志的写入时间也不一样,binlog只在事务提交的时候写入,redo需要在事务过程中不断的写入。

 9.MyFlash的使用

 该工具注意事项

1.binlog格式必须为row,binlog_row_image=full

2.仅支持5.65.7

3.只能回滚DML(增、删、改)

使用美团工具如下:

[root@lbg1 MyFlash-master]# unzip MyFlash.zip

[root@lbg1 MyFlash-master]# ls

binary  binlog_output_base.flashback  build.sh  doc  README.md  source  testbinlog

安装依赖并编译:

yum -y install glib2*

gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback

完成上面操作后:

[root@lbg1 MyFlash-master]# cd binary/

[root@lbg1 binary]# ls

flashback  mysqlbinlog20160408        ---实际此文件在编译前就有。

其中要使用的就是flashback工具。

使用命令:

1.回滚整个文件:

./flashback --binlogFileNames=haha.000041

mysqlbinlog binlog_output_base.flashback | mysql -h -u -p

2.回滚该文件中的所有deldte语句

./flashback --sqlTypes='DELETE' --binlogFileNames=haha.000041

mysqlbinlog binlog_output_base.flashback | mysql -h -u -p

说明:使用flashback后会生成当前路径下生成新的二进制binlog文件。想查看的话可msyqlbinlog 文件名 > /tmp/lbg.bin,再查看/tmp/lbg.bin即可,想恢复数据直接source /tmp/lbg.bin即可。

3.根据position点恢复数据

[root@lbg1 soft]#  /soft/MyFlash-master/binary/flashback   --start-position=801 --stop-position=1591   --sqlTypes='DELETE' --binlogFileNames=/home/mysql3306/mysql3306/mysql-bin.000001

注意:查找start-position时需是begin字段前的position点,stop-position的值是commit后的position点。

4.回滚大文件:

回滚

./flashback --binlogFileNames=haha.000042

切割⼤文件

./flashback --maxSplitSize=1 --binlogFileNames=binlog_output_base.flashback

应⽤

mysqlbinlog binlog_output_base.flashback.000001 | mysql -h -u -p

...

mysqlbinlog binlog_output_base.flashback. | mysql -h -u -p

10.binlog实时远程备份命令

[root@lbg2 lbg]# mysqlbinlog --read-from-remote-server --raw --host=192.168.88.8 --port=3306 --user=root --password=root --stop-never mysql-bin.000001

----生成的binlog在本地。

不足:这个方式有个问题,对于常规的主从复制来说,如果主从直接的连接断开了,则从会自动再次连接,而对于mysqlbinlog,如果断开了,并不会自动连接。可通过脚本来弥补上述不足。实际上定义了一个死循环,如果备份失败,则10s后重新连接。