
- 作用: 记录mysql数据库的一般状态信息及报错信息,是我们对于数据库常规报错处理的常用日志。
- 默认位置: DATA_DIR/hostname.err
- 开启方式:(MySQL安装完后默认开启)
-
- #查询
- mysql> select @@log_error;
- +-------------+
- | @@log_error |
- +-------------+
- | ./mysql.log |
- +-------------+
- mysql> show variables like 'log_error';
- +---------------+-------------+
- | Variable_name | Value |
- +---------------+-------------+
- | log_error | ./mysql.log |
- +---------------+-------------+
- #修改
- vim /etc/my.cnf
- [mysqld]
- log_error=/data/mysql/data/mysql.log
- 作用: 记录mysql所有执行成功的SQL语句信息,可以做审计用,但是我们很少开启。
- 默认位置: DATA_DIR/hostname.log
- 开启方式:(MySQL安装完之后默认不开启)
-
- #查看
- mysql> show variables like '%general%';
- +------------------+---------------------------+
- | Variable_name | Value |
- +------------------+---------------------------+
- | general_log | OFF |
- | general_log_file | /data/mysql/data/db02.log |
- +------------------+---------------------------+
- #修改
- vim /etc/my.cnf
- [mysqld]
- general_log=1
- general_log_file=/data/mysql/data/db02.log
- 作用:
- 记录已提交的DML事务语句,并拆分为多个事件(event)来进行记录
- 记录所有DDL、DCL等语句 ,实现数据恢复、主从复制
- 总之,二进制日志会记录所有对数据库发生修改的操作
- 二进制日志模式:
- STATEMENT:SBR,语句模式,记录操作语句本身,MySQL5.6的默认模式
- 优点:简单明了,容易被看懂,就是sql语句,记录时不需要太多的磁盘空间。
- 缺点:记录不够严谨。
- ROW:RBR,行模式,即数据行的变化过程,MySQL5.7的默认模式
- 优点:记录更加严谨。
- 缺点:有可能会需要更多的磁盘空间,不太容易被读懂。
- MIXED:MBR,以上两者的混合模式
- 企业推荐使用row模式
- log_bin:binlog开关、设定存放位置文件的路径及文件名前缀
- server_id(5.6不需要添加此参数,5.7以上必须加)
- 生产要求:日志和数据分开存放
- # 创建binlog目录,并修改归属
- # mkdir -p /data/mysql/binlog
- # chown -R mysql.mysql /data/mysql/binlog
-
- # 修改MySQL配置文件
- # vim /etc/my.cnf
- [mysqld]
- server_id=6
- log_bin=/data/mysql/binlog/mysql-bin
-
- # 重启mysqld
- # systemctl restart mysqld
-
- # 系统下查看binlog
- # ls /data/mysql/binlog/mysql-bin.*
- total 8
- -rw-r----- 1 mysql mysql 154 Apr 7 22:52 mysql-bin.000001
- -rw-r----- 1 mysql mysql 36 Apr 7 22:52 mysql-bin.index
-
- # MySQL中查看
- # 查看binlog的参数
- mysql> show variables like '%log_bin%';
- +---------------------------------+------------------------------------+
- | Variable_name | Value |
- +---------------------------------+------------------------------------+
- | log_bin | ON |
- | log_bin_basename | /data/mysql/binlog/mysql-bin |
- | log_bin_index | /data/mysql/binlog/mysql-bin.index |
- | log_bin_trust_function_creators | OFF |
- | log_bin_use_v1_row_events | OFF |
- | sql_log_bin | ON |
- +---------------------------------+------------------------------------+
-
- # 查看binlog模式
- mysql> show variables like 'binlog_format';
-
- # 查看所有的binlog文件
- mysql> show binary logs;
-
- # 查看查看当前日志工作
- mysql> show master logs;
-
- # 查看正在工作的binlog
- mysql> show master status;
-
- # 查看指定binlog文件的事件
- mysql> show binlog events in 'mysql-bin.000001';
- +------------------+-----+----------------+-----------+-------------+------------
- ---------------------------+
- | Log_name | Pos | Event_type | Server_id | End_log_pos | Info
- |
- +------------------+-----+----------------+-----------+-------------+------------
- ---------------------------+
- | mysql-bin.000001 | 4 | Format_desc | 6 | 123 | Server
- ver: 5.7.32-log, Binlog ver: 4
- | mysql-bin.000001 | 123 | Previous_gtids | 6 | 154 |
- | mysql-bin.000001 | 154 | Anonymous_Gtid | 6 | 219 | SET
- @@SESSION.GTID_NEXT= 'ANONYMOUS'
- | mysql-bin.000001 | 219 | Query | 6 | 322 | create
- database binlong
- | mysql-bin.000001 | 322 | Anonymous_Gtid | 6 | 387 | SET
- @@SESSION.GTID_NEXT= 'ANONYMOUS'
- | mysql-bin.000001 | 387 | Query | 6 | 478 | drop
- database binlong
- | mysql-bin.000001 | 478 | Anonymous_Gtid | 6 | 543 | SET
- @@SESSION.GTID_NEXT= 'ANONYMOUS'
- | mysql-bin.000001 | 543 | Query | 6 | 643 | create
- database binlog
-
- bin_log头部标记:
- 5.6 前120个Position号
- 5.7 前123个Position号
- 注释:以上输出中每一行为一个事件
- Log_name:日志名
- Pos:事件开始的Position *****
- Event_type:事件类型
- Server_id:发生在哪台机器的事件 //主从时区分机器
- End_log_pos:事件结束的位置号 *****
- Info:事件内容
- 二进制日志的最小记录单元
- 对于DDL,DCL,一个语句就是一个event
- 对于DML语句来讲:只记录已提交的事务。
- event的组成
- 事件的开始标识(start position)
- at
- 事件内容
- 事件的结束标识(stop position)
- end_log_pos
-
- 例如以下例子,就被分为了4个event
- position号码(字节偏移量)
- begin; 120 - 340
- DML1 340 - 460
- DML2 460 - 550
- commit; 550 - 760
- 作用:方便对日志进行截取,指定部分日志进行数据恢复
- 案例练习1:
- 环境
- create database test;
- use test
- create table t1(id int);
- insert into t1 values(1);
- insert into t1 values(2),(3),(4);
- 模拟误操作,删除2
- delete from t1 where id=2;
- 要求:将上述误操作恢复
- 1.观察事务日志,找到误操作之前的节点
- 需要解码,通过误操作前的commit来寻找end_log_position
- mysqlbinlog --base64-output=decode-rows -v /data/mysql/binlog/mysql-bin.000001
- # at 1220
- #240228 14:49:02 server id 6 end_log_pos 1251 CRC32 0xa44eb22a Xid = 32
- COMMIT/*!*/;
- # at 1251
- #240228 14:50:01 server id 6 end_log_pos 1316 CRC32 0x7bc48a6e Anonymous_GTID last_committed=4 sequence_number=5 rbr_only=yes
- /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
- SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
- # at 1316
- #240228 14:49:44 server id 6 end_log_pos 1388 CRC32 0x71c50f4b Query thread_id=2 exec_time=0 error_code=0
- SET TIMESTAMP=1709102984/*!*/;
- BEGIN
- /*!*/;
- # at 1388
- #240228 14:49:44 server id 6 end_log_pos 1433 CRC32 0x2b1a91b1 Table_map: `test`.`t1` mapped to number 108
- # at 1433
- #240228 14:49:44 server id 6 end_log_pos 1473 CRC32 0x587544fc Delete_rows: table id 108 flags: STMT_END_F
- ### DELETE FROM `test`.`t1`
- ...
-
- 2.导出该节点之前binlog信息
- mysqlbinlog --start-position=219 --stop-position=1251 /data/mysql/binlog/mysql-bin.000003 > /tmp/binlog.sql
-
- 3.导入到数据库中
- 在mysql的交互环境中导入上述步骤的sql文件的内容
- #1.临时关闭binlog
- set sql_log_bin=0;
-
- #2.source导入
- drop table test.t1;
- source /tmp/binlog.sql
-
- #3.查询数据是否恢复
- select * from test.t1;
-
- #4.开启binlog
- set sql_log_bin=1;
- 也可以关闭会话,重新登录
-
- 案例练习2
- 环境
- create table t2(id int);
- insert into t2 values(5),(6),(7);
- # 误操作1
- update t1 set id=33 where id=3;
- insert into t2 values(8),(9);
- # 误操作2
- delete from t1 where id=1;
- create table t3(id int);
- insert into t3 values(111),(222);
-
- 1.观察事务日志,找到误操作之前的节点
- 需要解码,通过误操作前的commit来寻找end_log_position
- mysqlbinlog --base64-output=decode-rows -v /data/mysql/binlog/mysql-bin.000001
- # at 1220
- #240228 14:49:02 server id 6 end_log_pos 1251 CRC32 0xa44eb22a Xid = 32
- COMMIT/*!*/;
- # at 1251
- #240228 14:50:01 server id 6 end_log_pos 1316 CRC32 0x7bc48a6e Anonymous_GTID last_committed=4 sequence_number=5 rbr_only=yes
- /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
- SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
- # at 1316
- #240228 14:49:44 server id 6 end_log_pos 1388 CRC32 0x71c50f4b Query thread_id=2 exec_time=0 error_code=0
- SET TIMESTAMP=1709102984/*!*/;
- BEGIN
- /*!*/;
- # at 1388
- #240228 14:49:44 server id 6 end_log_pos 1433 CRC32 0x2b1a91b1 Table_map: `test`.`t1` mapped to number 108
- # at 1433
- #240228 14:49:44 server id 6 end_log_pos 1473 CRC32 0x587544fc Delete_rows: table id 108 flags: STMT_END_F
- ### DELETE FROM `test`.`t1`
- ...
-
- 根据上述细节分析,我们的有效数据有三段
- test库,t1表起始:672
- test库,t1表结束:1509
-
- t2表起始:1762
- t2表结束:2187
-
- t3表起始:2957
- t3表结束:3312
-
- 2.导出该节点之前binlog信息
- 在shell中使用mysqlbinlog工具导出上述结果
- mysqlbinlog --start-position=672 --stop-position=1509 /data/mysql/binlog/mysql-bin.000001 > /tmp/binlog1.sql
- mysqlbinlog --start-position=1762 --stop-position=2187 /data/mysql/binlog/mysql-bin.000001 > /tmp/binlog2.sql
- mysqlbinlog --start-position=2957 --stop-position=3312 /data/mysql/binlog/mysql-bin.000001 > /tmp/binlog3.sql
-
- 3.导入到数据库中
- 在mysql的交互环境中导入上述步骤的sql文件的内容
- #1.临时关闭binlog
- set sql_log_bin=0;
-
- #2.source导入
- drop database test;
- source /tmp/binlog1.sql
- source /tmp/binlog2.sql
- source /tmp/binlog3.sql
-
- #3.查询数据是否恢复
- select * from test.t1;
- select * from test.t2;
- select * from test.t3;
-
- #4.开启binlog
- set sql_log_bin=1;
-
- 也可以关闭会话,重新登录
- 1.刷新binlog
-
- mysql> flush logs;
-
- mysqladmin -uroot -p flush-logs;
-
- 重启数据库时
- 设置binlog上限(max_binlog_size 默认是1G大小)。
-
- 2.删除binlog
- 1.手动删除
- 1)使用PURGE手动删除,不会重置binlog编号
- mysql> PURGE BINARY LOGS BEFORE now() - INTERVAL 3 day; //删除从现在开始三天之前的二
- 进制日志
- mysql> PURGE BINARY LOGS TO 'mysql-bin.000003'; //删除到哪里为止
- 2)使用reset master;删除所有binlog,并重新计数(从000001开始)
- mysql> reset master;
- 2.自动删除
- 设置超时时间
- 临时生效的
- SET GLOBAL expire_logs_days= 7;
- 永久生效:
- vim /etc/my.cnf
- expire_logs_days=7
- 自动删除设置依据:至少是一个全备周期+1,企业建议至少2个全备周期+1
记录慢SQL语句的日志,定位低效SQL语句的工具日志默认没开启
- vim /data/3307/my.cnf
- slow_query_log=1 #指定是否开启慢查询日志
- slow_query_log_file=/data/mysql/slow.log #指定慢日志文件存放位置,可以为空,系统会给一个
- 缺省的文件host_name-slow.log
- long_query_time=0.05 #设定慢查询的阀值,超出次设定值的SQL即被记录到慢查询日志,缺省值为10s
- log_queries_not_using_indexes=1 #不使用索引的慢查询日志是否记录到日志中
- min_examined_row_limit=100 #查询检查返回少于该参数指定行的SQL不被记录到慢查询日志,鸡肋
- 进入数据库:查看参数是否生效
- mysql> show variables like 'long_query_time';
- use world
- create table t1 select * from city;
- insert into t1 select * from t1;
- insert into t1 select * from t1;
- commit;
- insert into t1 select * from t1;
- insert into t1 select * from t1;
- commit;
- insert into t1 select * from t1;
- insert into t1 select * from t1;
- commit;
- select count(*) from t1;
- select * from t1 group by id;
- 1.mysqldumpslow命令
- mysqldumpslow -s c -t 10 /data/mysql/slow.log
- 这会输出记录次数最多的10条SQL语句,其中:
- -s
- 是表示按照何种方式排序,c、t、l、r
- 分别是按照记录次数、时间、查询时间、返回的记录数来排序
- ac、at、al、ar,表示相应的倒叙
- -t
- 是top n的意思,即为返回前面多少条的数据;
- -g,
- 后边可以写一个正则匹配模式,大小写不敏感的;
- 例子:
- /path/mysqldumpslow-s r -t 10 /database/mysql/slow-log
- 得到返回记录集最多的10个查询。
- /path/mysqldumpslow-s t -t 10 -g “left join”/database/mysql/slow-log
- 得到按照时间排序的前10条里面含有左连接的查询语句。
-
- 2.pt-query-digest
- pt-query-digest基本使用:
- 下载二进制包地址
- https://www.percona.com/downloads/percona-toolkit/LATEST/
- 安装软件包支持:(不同的版,依赖包不一样)
- yum install -y *Dumper* *MD5*
- /xxx/bin/pt-query-digest /data/mysql/slow.log
- 扩展:Anemometer基于pt-query-digest将MySQL慢查询可视化
- httpss://github.com/box/Anemometer 可视化代码下载