目录
mysqlbinlog工具的作用是解析mysql的二进制binlog日志内容,把二进制日志解析成可以在MySQL数据库里执行的SQL语句。
[root@db02 ~]# ls -l /data/3306/mysql-bin.00000*
-rw-rw---- 1 mysql mysql 1520 May 30 17:00 /data/3306/mysql-bin.000001
-rw-rw---- 1 mysql mysql 126 May 30 17:00 /data/3306/mysql-bin.000002
-rw-rw---- 1 mysql mysql 126 May 31 09:34 /data/3306/mysql-bin.000003
-rw-rw---- 1 mysql mysql 126 May 31 09:38 /data/3306/mysql-bin.000004
-rw-rw---- 1 mysql mysql 564055 Jun 3 17:49 /data/3306/mysql-bin.000005
-rw-rw---- 1 mysql mysql 5316 Jun 5 19:06 /data/3306/mysql-bin.000006
-rw-rw---- 1 mysql mysql 3536 Jun 5 21:51 /data/3306/mysql-bin.000007
[root@db02 ~]# grep "log-bin" /data/3306/my.cnf
log-bin = /data/3306/mysql-bin
必须要打开log-bin功能才能生成上述文件
mysql的binlog日志作用是用来记录mysql内部增删改等对mysql数据库有更新的内容的记录(对数据库的改动),对数据库查询的语句如show
,select
开头的语句,不会被binlog日志记录。
binlog的主要作用是,用于数据库的主从复制以及数据库的增量恢复
。
默认情况下,bin-log日志是二进制格式的,不能使用cat、vi等文本工具来查看
[root@db02 ~]# file /data/3306/mysql-bin.000001
/data/3306/mysql-bin.000001: MySQL replication log
# 解析
# 创建一个RSQ数据库
mysql> create database RSQ;
Query OK, 1 row affected (0.00 sec)
mysqlbinlog /data/3306/mysql-bin.000007
......
# at 3536
#180606 3:43:38 server id 1 end_log_pos 3617 Query thread_id=104 exec_time=0 error_code=0
SET TIMESTAMP=1528227818/*!*/;
SET @@session.foreign_key_checks=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=33/*!*/;
create database RSQ
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
mysqlbinlog工具分库导出binlog,如果使用-d参数,那更新数据时,必须有use databases,才能分出指定库的binlog
按照位置截取:精确
mysqlbinlog mysqlbin.000020 --start-position=365 --stop-position=456 -r pos.sql
# 指定开始位置,不指定结束位置,那么会自动到结尾
mysqlbinlog mysqlbin.000020 --start-position=365 -r pos.sql
# 制定结束位置,不指定开始位置,那么会自动匹配前边所有
mysqlbinlog mysqlbin.000020 --stop-position=456 -r pos.sql
按照时间截取:模糊、不准确
mysqlbinlog mysqlbin.000020 --start-datetime='2018-06-05 17:14:15' --stop-datetime=2018-06-05 17:15:15'' -r time.sql
# 指定开始时间,不指定结束时间,那么会自动匹配到最新
mysqlbinlog mysqlbin.000020 --start-datetime='2018-06-05 17:14:15' -r time.sql
# 指定结束时间,不指定开始时间,那么会自动匹配到最老的时间
mysqlbinlog mysqlbin.000020 --stop-datetime=2018-06-05 17:15:15'' -r time.sql
1、把binlog解析为sql语句(包含位置和时间点)
2、-d参数根据指定库拆分binlog(拆分单表binlog可通过SQL关键字过滤)
3、通过位置参数截取部分binlog:–start-position=365 –stop-position=456,精确定位取部分内容。
4、通过时间参数截取部分binlog:–start-datetime=’2018-06-05 17:14:15’ –stop-datetime=2018-06-05 17:15:15”,模糊取部分内容,会丢数据。
5、-r 文件名,相当于重定向 “>文件名”
6、解析ROW级别的binlog日志方法
mysqlbinlog –base64-output=decode-rows -v mysql-bin.00016
mysqlbinlog –base64-output=decode-rows –verbose mysql-bin.00004
MySQL的错误日志(error log)记录MySQL服务进程mysqld在启动/关闭或运行过程中遇到的错误信息;
开启此日志功能需要在配置文件添加或者mysql中添加
# 配置文件中添加
[mysqld_safe]
log-error=/data/3306/mysql_oldboy3306.err
# mysq中添加
mysqld_safe --default-file=/data/3306/my.cnf --log-error=/data/3306/mysql_oldboy.err &
1、先把日志文件备份并清空启动一下mysql服务,然后再查看日志文件报有什么错误
2、然后把mysql的3306目录下面所有文件都加上属主并且递归-R
3、然后查看一下有没有这个mysql ID
4、重新启动mysql服务
5、此时再查看一下服务有没有启动起来
慢查询日志(show query log
)记录执行时间超出指定值(long_query_time
)的SQL语句;
慢查询日志(show query log)调整:
vim /data/3306/my.cnf
long_query_time = 1
log-slow-queries = /data/3306/slow.log
log_queries_not_using_indexes
慢查询的设置,对于数据库SQL的优化很重要
egrep "query" /data/3306/my.cnf|tail -3
二进制日志(binary log):记录数据被修改的相关信息;
二进制日志(binary log)调整:
mysql> show variables like '%log_bin%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| log_bin | ON | # 记录binlog开关
| log_bin_trust_function_creators | OFF |
| sql_log_bin | ON | # 临时不记录binlog开关(增量恢复)
+---------------------------------+-------+
日志中会记录成每一行数据被修改的形式,然后在slave端再对相同的数据进行修改。
优点:在rowlevel模式下,bin-log中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条记录被修改了,修改成什么样了。所以row level的日志内容会非常清楚的记录下每一行数据修改的细节,非常容易理解。而且不会出现某些特定情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题。
**缺点:**row level下,所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,比如有这样一条update语句:update product set owner_member_id = 'b' where owner_member_id='a'
,执行之后,日志中记录的不是这条update语句所对应事件(MySQL以事件的形式来记录bin-log日志),而是这条语句所更新的每一条记录的变化情况,这样就记录成很多条记录被更新的很多个事件。自然,bin-log日志量就会很大
。尤其是当执行alter table之类的语句的时候,产生的日志量是惊人的。
每一条被修改数据的sql都会记录到master的bin-log中。slave在复制的时候sql进程会解析成和原来的master端执行的相同的sql来再次执行。
优点: statement level下的优点首先就是解决了row level下的缺点,不需要记录每一行数据的变化,减少bin-log日志量
,节约IO
,提高性能。因为他只需要记录在Master上所执行的语句细节,以及执行语句时候的上下文的信息。
缺点:由于他是记录的执行语句,所以,为了让这些语句在salve端也能正确执行,那么他还必须记录每条语句在执行的时候的一些相关信息,也就是上下文信息,以保证所有语句在slave端被执行的时候能够得到和在master端执行时候相同的结果。
实际上就是前两种模式的
结合
。在Mixed模式下,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。新版本中的Statement level还是和以前一样,仅仅记录执行的语句
。而新版本的MySQL中对row level模式也做了优化,并不是所有的修改都会以row level来记录,像遇到的表结构变更的时候就会以statement模式来记录,如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。
log-bin=mysql-bin
#binlog_format = "STATEMENT"
#binlog_format = "ROW"
binlog_format = "MIXED"
# 查看默认binlog模式:
mysql> show variables like "%binlog_format%";
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
1 row in set (0.00 sec)
# 临时生效
mysql> set global binlog_format= 'ROW';
Query OK, 0 rows affected (0.00 sec)
mysql> show global variables like "%binlog_format%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec)
# 在配置文件修改binlog模式为MIXED,永久生效
vim /data/3306/my.cnf
[mysqld]
binlog_format = "MIXED"
/data/3306/mysql stop
/data/3306/mysql start
mysql -uroot -p123456 -S /data/3306/mysql.sock
mysql> show variables like "%binlog_format%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+
1 row in set (0.00 sec)