刷写策略
innodb_flush_log_at_trx_commit=1
innodb_flush_method
sync_binlog=1 ---> 双一之一,在事务提交时,立即刷新binlog到磁盘
0 通用日志
0.1 作用:
记录MySQL发生过的所有命令. 一般可以用作审计.
0.2 配置
vim /etc/my.cnf
general_log=ON
general_log_file=/data/mysql/data/db01.log
1. 错误日志 (log_error)
1.1 作用
记录启动\关闭\日常运行过程中,状态信息,警告,错误
1.2 配置
默认就是开启的: /数据路径下/hostname.err
手工设定:
Master [(none)]>select @@log_error;
vim /etc/my.cnf
log_error=/var/log/mysql.log
log_timestamps=system **
重启生效
show variables like 'log_error';
说明
log_timestamps 这个参数主要是控制 error log、slow_log、genera log,等等记录日志的显示时间参数,但不会影响 general log 和 slow log 写到表 (mysql.general_log, mysql.slow_log) 中的显示时间。
https://www.cnblogs.com/glon/p/6737391.html
1.3 日志内容查看
主要关注[ERROR],看上下文
2. 二进制日志 (binlog:binary logs)
2.1 作用:
用来记录 MySQL工作过程中,所有变更类的语句.
(1)备份恢复必须依赖二进制日志
(2)主从环境必须依赖二进制日志
2.2 binlog配置 (5.7必须加server_id)
注意:MySQL默认是没有开启二进制日志的。
基础参数查看:
开关:
[(none)]>select @@log_bin;
日志路径及名字
[(none)]>select @@log_bin_basename;
服务ID号:
[(none)]>select @@server_id;
二进制日志格式:
[(none)]>select @@binlog_format;
双一标准之二:
[(none)]>select @@sync_binlog; **进行提交事务,立马将内存中的binlog刷写到磁盘中,是最安全但是性能损耗最大的设置
vim /etc/my.cnf
server_id=6 ----->5.6中,单机可以不需要此参数
log_bin=/data/binlog/mysql-bin
binlog_format=row
重启数据库生效
2.2.1参数说明
server_id=3306
主要是在主从复制过程中必须要加的,但是在5.7版本中,要用以下参数(log_bin),开启binlog日志,即使是单机也是必加的
log_bin=/data/binlog/mysql-bin
(1)开启二进制日志功能
(2)设置二进制日志目录及名称前缀
binlog_format=row
binlog的记录格式??
2.3 binlog记录了什么
2.3.0 引入
binlog是SQL层的功能。记录的是变更SQL语句,不记录查询语句。
2.3.1 记录SQL语句种类
DDL :原封不动的记录当前DDL(statement语句方式)。
DCL :原封不动的记录当前DCL(statement语句方式)。
DML :只记录已经提交的事务DML
2.3.2 DML 语句三种记录格式
binlog_format(binlog的记录格式)参数影响
(1)statement(5.6默认)SBR(statement based replication) :语句模式原封不动的记录当前DML。
(2)ROW(5.7 默认值) RBR(ROW based replication) :记录数据行的变化(用户看不懂,需要工具分析)
(3)mixed(混合)MBR(mixed based replication)模式 :以上两种模式的混合
2.3.3 SBR 与RBR两种格式的区别 (面试题)
SBR与RBR模式的对比
STATEMENT:可读性较高,日志量少,但是不够严谨
ROW :可读性很低,日志量大,足够严谨
update t1 set xxx=xxx where id>1000 ? -->一共500w行,row模式怎么记录的日志
为什么row模式严谨? 一些函数操作
例:
id name intime
insert into t1 values(1,'zs',now())
我们建议使用:row记录模式
2.4 binlog的记录内容格式 ---event (事件)
2.4.1 事件简介
二进制日志的最小记录单元
对于DDL,DCL,一个语句就是一个event
对于DML语句来讲:只记录已提交的事务。
例如以下列子,就被分为了4个event
begin; 120 - 340
DML1 340 - 460
DML2 460 - 550
commit; 550 - 760
2.4.2 事件的组成
三部分构成:
(1) 事件的开始标识
(2) 事件内容
(3) 事件的结束标识
Position:
开始标识: at 194
结束标识: end_log_pos 254
194? 254?
某个事件在binlog中的相对位置号
位置号的作用是什么?
为了方便我们截取事件
2.5 二进制日志的管理
2.5.1 查看日志的开启情况
log_bin参数设置的路径,可以找到二进制日志
Master [(none)]>show variables like '%log_bin%';
+---------------------------------+------------------------------+
| Variable_name | Value |
+---------------------------------+------------------------------+
| log_bin | ON |
| log_bin_basename | /data/binlog/mysql-bin |
| log_bin_index | /data/binlog/mysql-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| sql_log_bin | ON |
+---------------------------------+------------------------------+
6 rows in set (0.01 sec)
2.5.2 查看一共多少个binlog
Master [(none)]>show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 154 |
+------------------+-----------+
1 row in set (0.01 sec)
Master [(none)]>flush logs;
Query OK, 0 rows affected (0.03 sec)
Master [(none)]>flush logs;
Query OK, 0 rows affected (0.01 sec)
Master [(none)]>show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 201 |
| mysql-bin.000002 | 201 |
| mysql-bin.000003 | 154 |
+------------------+-----------+
3 rows in set (0.00 sec)
Master [(none)]>
2.5.3查看mysql正在使用的日志文件
Master [(none)]>show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
Master [(none)]>
**file:当前MySQL正在使用的文件名**
**Position:最后一个事件的结束位置号**
2.5.4 二进制日志内容查看
Master [binlog]>show binlog events in 'mysql-bin.000003';
+------------------+-----+----------------+-----------+-------------+----------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+----------------------------------------+
| mysql-bin.000003 | 4 | Format_desc | 6 | 123 | Server ver: 5.7.20-log, Binlog ver: 4 |
| mysql-bin.000003 | 123 | Previous_gtids | 6 | 154 | |
| mysql-bin.000003 | 154 | Anonymous_Gtid | 6 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 219 | Query | 6 | 319 | create database binlog |
| mysql-bin.000003 | 319 | Anonymous_Gtid | 6 | 384 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000003 | 384 | Query | 6 | 486 | use `binlog`; create table t1 (id int) |
+------------------+-----+----------------+-----------+-------------+----------------------------------------+
Log_name:binlog文件名
Pos:开始的position *****
Event_type:事件类型
Format_desc:格式描述,每一个日志文件的第一个事件,多用户没有意义,MySQL识别binlog必要信息
Server_id:mysql服务号标识
End_log_pos:事件的结束位置号 *****
Info:事件内容*****
补充:
SHOW BINLOG EVENTS
[IN 'log_name']
[FROM pos]
[LIMIT [offset,] row_count]
[root@db01 binlog]# mysql -e "show binlog events in 'mysql-bin.000004'" |grep drop
2.5.5 binlog文件内容详细查看
[root@db01 /data/binlog]# mysqlbinlog /data/binlog/mysql-bin.000002
[root@db01 /data/binlog]# mysqlbinlog --base64-output=decode-rows -vvv /data/binlog/mysql-bin.000002 |grep -v SET **提高可读性**
[root@db01 /data/binlog]# mysqlbinlog -d xxx /data/binlog/mysql-bin.000002 |grep -v SET
**-d 参数过滤出某个库的binlog 如果没有启用gtid 使用参数 --skip-gtids**
2.5.6 基于position号进行截取
思路:
1. 分析日志: 得到截取日志起点和终点.
mysql> show binlog events in 'mysql-bin.000002';
起点: 找到建库的位置 : 219
终点: 删除之前位置点 : 787
2. 进行截取
mysqlbinlog --start-position=219 --stop-position=787 /data/binlog/mysql-bin.000002 >/tmp/binlog.sql
3. 恢复日志
mysql> set sql_log_bin=0; ----> 临时关闭binlog日志记录
mysql> source /tmp/binlog.sql;
mysql> set sql_log_bin=1;
重点案例
1. 需要的日志在多个日志文件怎么截取?
方法1:
1-100000 219 219 100000
1-2020 2020 154 2020
方法2 :
--start-datetime=xxxx --stop-datetime=xxxxx file1 file >aa.sql
2. 以上案例,如果xxx库在2年前创建的,怎么恢复?
最近的一次全备+备份之后一直到误删除之前的所有日志
full+binlog
2.6 binlog日志的GTID新特性
2.6.1 GTID介绍
从MySQL 5.6 版,加入的新特性.唯一编号,用来标识每一个二进制日志"事务".
事务1: begin; dml1;dml2;commit; 会产生一个GTID编号.
事务2: DDL或者DCL,一个event就是一个事务.会产生一个GTID编号.
5.6 版本新加的特性,5.7中做了加强
5.6 中不开启,没有这个功能.
5.7 中的GTID,即使不开也会有自动生成
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
2.6.2 GTID(Global Transaction ID)编号格式
GTID = source_id :transaction_id
79f1839c-0439-11ea-83bb-000c29d354c0:29
[root@db01 /data/mysql/data]# cat auto.cnf
[auto]
server-uuid=79f1839c-0439-11ea-83bb-000c29d354c0
2.6.3 GTID开启
vim /etc/my.cnf
gtid-mode=ON
enforce-gtid-consistency=ON
log_slave_updates=ON
systemctl restart mysqld
logs-slave-updates 参数主要在多主多从的集群架构中开启,否则会导致各从实例无法完整同步集群的全量数据的问题。
[https://segmentfault.com/a/1190000018504399?utm_source=tag-newest](https://segmentfault.com/a/1190000018504399?utm_source=tag-newest)
2.6.4 gtid模式日志管理
(1)查看事件
db01 [damao]>show master status ;
+------------------+----------+--------------+------------------+----------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000001 | 421 | | | bb339c37-0bf8-11ea-b374-000c2942a0b7:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)
db01 [damao]>show binlog events in 'mysql-bin.000001';
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000001 | 4 | Format_desc | 7 | 123 | Server ver: 5.7.26-log, Binlog ver: 4 |
| mysql-bin.000001 | 123 | Previous_gtids | 7 | 154 | |
| mysql-bin.000001 | 154 | Gtid | 7 | 219 | SET @@SESSION.GTID_NEXT= 'bb339c37-0bf8-11ea-b374-000c2942a0b7:1' |
| mysql-bin.000001 | 219 | Query | 7 | 292 | BEGIN |
| mysql-bin.000001 | 292 | Table_map | 7 | 341 | table_id: 108 (damao.da) |
| mysql-bin.000001 | 341 | Write_rows | 7 | 390 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000001 | 390 | Xid | 7 | 421 | COMMIT /* xid=18 */ |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
7 rows in set (0.00 sec)
db01 [damao]>create table mao(id int);
Query OK, 0 rows affected (0.02 sec)
db01 [damao]>show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000001 | 586 | | | bb339c37-0bf8-11ea-b374-000c2942a0b7:1-2 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
(2)截取日志
具备GTID后,截取查看某些事务日志:
--include-gtids :包括GTID的范围
--exclude-gtids :排除include中的某些GTID
mysqlbinlog --skip-gtids --include-gtids='dff98809-55c3-11e9-a58b-000c2928f5dd:1-6' --exclude-gtids='dff98809-55c3-11e9-a58b-000c2928f5dd:4' /data/binlog/mysql-bin.000004
注意: 开了gtid模式 ,一定要添加--skip-gtids ,因为mysql会自动检查gtid幂等性
2.6.5 GTID的幂等性
开启GTID后,MySQL恢复Binlog时,重复GTID的事务不会再执行了
就想恢复?怎么办?
--skip-gtids
mysqlbinlog --include-gtids='3ca79ab5-3e4d-11e9-a709-000c293b577e:4' /data/binlog/mysql-bin.000004 /data/binlog/mysql-bin.000004
set sql_log_bin=0;
source /tmp/binlog.sql
set sql_log_bin=1;
2.7 二进制日志的其他操作
2.7.1 二进制日志滚动
(1) 重启MySQL 会自动滚动一个新的二进制日志
(2) flush logs;
(3) max_binlog_size=1073741824 二进制日志文件达到1G自动滚动
每天备份日志:
flush logs;
cp
(4)mysqldump -F :备份的时候加入-F 参数自动滚动
(5)mysqladmin -uroot -p123 flush-logs :mysqladmin命令滚动
2.7.2 二进制日志的删除
(1)配置自动删除
mysql> select @@expire_logs_days;
show variables like '%expire%';
自动清理时间,是要按照全备周期+1
set global expire_logs_days=8;
永久生效:
my.cnf
expire_logs_days=15; **全备周期为一周**
至少预留一轮全备周期+1的过期时间
企业建议,至少保留两个全备周期+1的binlog
(2)手工删除 注意:不要手工 rm binlog文件
Examples:
PURGE BINARY LOGS TO 'mysql-bin.010'; **删除010之前的binlog日志**
PURGE BINARY LOGS BEFORE '2008-04-02 22:46:26'; **删除指定时间之前的binlog文件**
(3)全部删除 危险
mysql> reset master;
reset master; 主从关系中,主库执行此操作,主从环境必崩
3. 慢日志
3.1 作用
记录MySQL运行过程中执行较慢的语句. 辅助管理员优化语句
数据库较慢的场景:
1. 应急性
show processlist;
-----> select
-----> explain
2. 持续性
slowlog ---> SQL
----> select
----> explain
3.2 配置(默认没有开启)
slow_query_log=1 开关
slow_query_log_file=/data/mysql/slow.log 文件位置及名字
long_query_time=0.1 设定慢查询时间:
log_queries_not_using_indexes 没走索引的语句也记录:
vim /etc/my.cnf
slow_query_log=1
slow_query_log_file=/data/mysql/slow.log
long_query_time=0.1
log_queries_not_using_indexes
systemctl restart mysqld
3.3 mysqldumpslow 分析慢日志
mysqldumpslow -s c -t 10 /data/mysql/slow.log
-s:排序
c:计数
-t:统计前几名 top n
# 第三方工具(自己扩展)
https://www.percona.com/downloads/percona-toolkit/LATEST/
yum install perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL perl-Digest-MD5
toolkit工具包中的命令:
./pt-query-diagest /data/mysql/slow.log
Anemometer基于pt-query-digest将MySQL慢查询可视化