1.错误日志
1.1 作用
首先需要明确的是, 错误日志中记录的未必都是错误日志,在Mysql的错误日志中,存储以下日志信息
- 服务器启动和关闭过程中的信息
- 服务器运行过程中的错误信息
- 事件调度器运行一个事件时产生的信息
- 在从服务器上启动从服务器进程时产生的信息
1.2 默认位置
错误日志默认位置:/mysql/data/$hostname.err错误日志默认文件名称:$hostname.err
1.3 错误日志配置:
#开启方式:默认就是开启的: /mysql/data/$hostname.err#编辑配置文件[root@db01 ~]# vim /etc/my.cnf[mysqld]log_error=/usr/local/mysql/data/$hostname.errlog_warnings = 1|0 #是否记录warnings信息到错误日志中#查看方式:mysql> show variables like 'log_error';
2.一般查询日志
2.1 作用
记录mysql所有执行成功的SQL语句信息,可以做审计用,但是我们很少开启。
2.2 默认位置
/usr/local/mysql/data/$hostnamel.log
2.3 一般查询日志配置
#MySQL安装完之后默认不开启一般查询日志配置#编辑配置文件[root@db01 ~]# vim /etc/my.cnf[mysqld]general_log=ongeneral_log_file=/application/mysql/data/$hostnamel.log#查看方式mysql> show variables like '%gen%';
3.二进制日志
3.1 作用
MySQL的二进制日志(binary log)是一个二进制文件,主要用于记录修改数据或有可能引起数据变更的MySQL语句。
binlog作用主要有:
数据恢复:如果我拥有数据库搭建开始所有的二进制日志,那么我可以通过mysqlbinlog工具把数据恢复到任意时刻
数据的备份恢复
数据的复制:MySQL Replication在Master端开启binlog,Master把它的二进制日志传递给slaves并回放来达到master-slave数据一致的目的
3.2 二进制日志的模式
row:行模式,日志中会记录每一行数据被修改的过程
statement:语句模式,每一条会修改数据的sql都会记录到日志中(默认模式)。
mixed:以上两者的混合模式。
企业推荐使用row模式
row行模式:
日志中会记录每一行数据被修改的形式,然后在slave端再对相同的数据进行修改
优点:在row level模式下,bin-log中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条被修改所以row level的日志内容会非常清楚的记录下每一行数据修改的细节。不会出现某些特定的情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题
缺点:row level,所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,不太以被读懂,会产生大量的日志内容。
statement语句模式:
每一条会修改数据的sql都会记录到master的bin-log中。slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行
优点:statement level下的优点首先就是解决了row level下的缺点,不需要记录每一行数据的变化,减少bin-log日志量,节约IO,提高性能,因为它只需要在Master上锁执行的语句的细节,以及执行语句的上下文的信息。
缺点:由于只记录语句,所以,在statement level下 已经发现了有不少情况会造成MySQL的复制出现问题,主要是修改数据的时候使用了某些定的函数或者功能的时候会出现。
mixed自动模式:
在Mixed模式下,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志格式,也就是在Statement和Row之间选择一种。如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。
3.3 二进制日志开启方式
[root@db01 ~]# vim /etc/my.cnf[mysqld]log_bin=ONlog_bin_basename=/var/local/mysql/data/mysql-binlog_bin_index=/var/local/mysql/data/mysql-bin.index#binlog_format=row #指定二进制日志模式#server_id=1 #在mysql5.7中开启binlog必须要加上server-id。第一个参数是打开binlog日志第二个参数是binlog日志的基本文件名,后面会追加标识来表示每一个文件第三个参数指定的是binlog文件的索引文件,这个文件管理了所有的binlog文件的目录
当然也有一种简单的配置,一个参数就可以搞定
log-bin=/var/local/mysql/data/mysql-bin
这一个参数的作用和上面三个的作用是相同的,mysql会根据这个配置自动设置log_bin为on状态,自动设置log_bin_index文件为你指定的文件名后跟.index
3.4 二进制日志查看
#物理查看[root@db01 data]# ll /app/mysql/data/-rw-rw---- 1 mysql mysql 285 Mar 6 2017 mysql-bin.000001mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000001#命令行查看查看所有的二进制文件mysql> show binary logs;查看当前正在使用的二进制文件mysql> show master status;#查看binlog事件mysql> show binlog events in 'mysql-bin.000001';
事件介绍
1)在binlog中最小的记录单元为event
2)一个事务会被拆分成多个事件(event)
事件(event)特性
1)每个event都有一个开始位置(start position)和结束位置(stop position)。
2)所谓的位置就是event对整个二进制的文件的相对位置。
3)对于一个二进制日志中,前120个position是文件格式信息预留空间。
4)MySQL第一个记录的事件,都是从120开始的。
3.5 二进制日志的刷新和删除
刷新binlog日志
1)flush logs;
2)重启数据库时会刷新
3)二进制日志上限(max_binlog_size)1G
删除二进制日志
1)原则
在存储能力范围内,能多保留则多保留
基于上一次全备前的可以选择删除
删除方式
1.根据存在时间删除日志
自动清理#临时生效set global expire_logs_days=7;#永久生效[root@db01 data]# vim /etc/my.cnf[mysqld]expire_logs_days = 7
手动清理:
2.使用purge命令删除
PURGE BINARY LOGS BEFORE now() - INTERVAL 3 day;
3.根据文件名删除
PURGE BINARY LOGS TO 'mysql-bin.000001';
注意:不要手工 rm binlog文件1. my.cnf binlog关闭掉,启动数据库2.把数据库关闭,开启binlog,启动数据库删除所有binlog,并从000001开始重新记录日志
4.全部删除
mysql> reset master; #主从关系中,主库执行此操作,主从环境必崩
3.6 row模式下二进制日志分析及数据恢复
#查看binlog信息mysql> show master status;#创建一个binlog库mysql> create database binlog;#使用binlog库mysql> use binlog#创建binglog_table表mysql> create table binlog_table(id int);#查看binlog信息mysql> show master status;#插入数据1mysql> insert into binlog_table values(1);#查看binlog信息mysql> show master status;#提交mysql> commit;#查看binlog信息mysql> show master status;#插入数据2mysql> insert into binlog_table values(2);#插入数据3mysql> insert into binlog_table values(3);#查看binlog信息mysql> show master status;#提交mysql> commit;#删除数据1mysql> delete from binlog_table where id=1;#查看binlog信息mysql> show master status;#提交mysql> commit;#更改数据2为22mysql> update binlog_table set id=22 where id=2;#查看binlogmysql> show master status;#提交mysql> commit;#查看binlog信息mysql> show master status;#查看数据mysql> select * from binlog_table;#删表mysql> drop table binlog_table;#删库mysql> drop database binlog;
恢复数据到delect之前
#查看binlog事件
mysql> show binlog events in 'mysql-bin.000013';
#使用mysqlbinlog来查看
[root@db01 data]# mysqlbinlog /application/mysql/data/mysql-bin.000013
[root@db01 data]# mysqlbinlog /application/mysql/data/mysql-bin.000013|grep -v SET
[root@db01 data]# mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000013
### UPDATE `binlog`.`binlog_table`
### WHERE
### @1=2 /* INT meta=0 nullable=1 is_null=0 */
### SET
### @1=22 /* INT meta=0 nullable=1 is_null=0 */
#分析
update binlog.binlog_table
set
@1=22 --------->@1表示binlog_table中的第一列,集合表结构就是id=22
where
@1=2 --------->@1表示binlog_table中的第一列,集合表结构就是id=2
#结果
update binlog.binlog_table set id=22 where id=2;
#截取二进制日志
查看二进制日志后,发现删除语句开始位置是858
[root@db01 data]# mysqlbinlog --start-position=120 --stop-position=858 /application/mysql/data/mysql-bin.000013 > binlog.sql
#临时关闭binlog
mysql> set sql_log_bin=0;
#执行sql文件
mysql> source /tmp/binlog.sql
#查看删除的库
mysql> show databases;
#进binlog库
mysql> use binlog
#查看删除的表
mysql> show tables;
#查看表中内容
mysql> select * from binlog_table;
思考,存在问题:
数据库或表被误删除的是很久之前创建的(一年前) 如果基于binlog全量恢复,成本很高 1)可以用备份恢复+短时间内二进制日志,恢复到故障之前 2)非官方方法,binlog2sql,binlog取反,类似于Oracle的flushback 3)延时从库 如果同一时间内和故障库无关的数据库都有操作,在截取binlog时都会被截取到 想一个办法过滤出来? 1)grep? 其他过滤方案? 1)-d 参数接库名
模拟数据
#为了让大家更清晰看到新的操作
#刷新一个新的binlog
mysql> flush logs;
#创建db1、db2两个库
mysql> create database db1;
mysql> create database db2;
#库db1操作
mysql> use db1
#创建t1表
mysql> create table t1(id int);
#插入5条数据
mysql> insert into t1 values(1),(2),(3),(4),(5);
#提交
mysql> commit;
#库db2操作
mysql> use db2
#创建t2表
mysql> create table t2(id int);
#插入3条数据
mysql> insert into t2 values(1),(2),(3);
#提交
mysql> commit;
#查看binlog事件
mysql> show binlog events in 'mysql-bin.000014';
#查看db1的操作
[root@db01 data]# mysqlbinlog -d db1 --base64-output=decode-rows -vvv /application/mysql/data/mysql-bin.000014
4.慢查询日志
慢查询日志在调优过程中使用的比较多,其中主要记录的是执行较慢的操作,具体时间可通过参数进行设置。
4.1 作用
1)是将mysql服务器中影响数据库性能的相关SQL语句记录到日志文件
2)通过对这些特殊的SQL语句分析,改进以达到提高数据库性能的目的
4.2 默认位置
mysql/data/$hostname-slow.log
4.3 慢查询日志开启方式
(默认没有开启)
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
#指定是否开启慢查询日志,可选值为0和1,默认为0。
slow_query_log = 1
#指定慢日志文件存放位置(默认在data)
slow_query_log_file=/app/mysql/data/slow.log
#设定慢查询的阀值(默认10s),时间长度,单位毫秒,超过此时间的操作将会被记录至日志。
long_query_time=0.5
#不使用索引的慢查询日志是否记录到索引
log_queries_not_using_indexes
#查询检查返回少于该参数指定行的SQL不被记录到慢查询日志(鸡肋)
min_examined_row_limit=100
4.4 分析慢查询日志
使用mysqldumpslow命令来分析慢查询日志
输出记录次数最多的10条SQL语句
$PATH/mysqldumpslow -s c -t 10 /database/mysql/slow-log
参数说明:
-s:
是表示按照何种方式排序,c、t、l、r分别是按照记录次数、时间、查询时间、返回的记录数来排序,ac、at、al、ar,表示相应的倒叙;
-t:
是top n的意思,即为返回前面多少条的数据;
-g:
后边可以写一个正则匹配模式,大小写不敏感的;
例:
#得到返回记录集最多的10个查询
$PATH/mysqldumpslow -s r -t 10 /database/mysql/slow-log#得到按照时间排序的前10条里面含有左连接的查询语句$PATH/mysqldumpslow -s t -t 10 -g “left join”/database/mysql/slow-log
4.5 模拟慢查询日志语句
#进入world库
mysql> use world
#查看表
mysql> show tables
#将city表中所有内容加到t1表中
mysql> create table t1 select * from city;
#查看t1的表结构
mysql> desc t1;
#将t1表所有内容插入到t1表中(多插入几次)
mysql> insert into t1 select * from t1;
mysql> insert into t1 select * from t1;
mysql> insert into t1 select * from t1;
mysql> insert into t1 select * from t1;
#提交
mysql> commit;
#删除t1表中id>2000的数据
mysql> delete from t1 where id>2000;
#查看慢日志
[root@db01 ~]# cat /application/mysql/data/mysql-db01
