《MySQL自学笔记》之日志

mysql的日志分类 : 1.错误日志 2.通用日志 3.慢查询日志 4.二进制日志(biglog)
按照存储引擎(innodb)还可以有 1.重做日志 2.回滚日志

1.错误日志

错误日志记录了当mysqld启动和停止时,以及服务器在运行过程中发生任何严重错误是相关信息,当数据库出现任何故障导致无法启动或使用时候可以首先看错误日志

错误日志的配置

查看错误日志的配置路径

mysql>  show variables like 'log_error';
+---------------+------------------------------+
| Variable_name | Value                        |
+---------------+------------------------------+
| log_error     | /var/mysql_log/mysql-err.log |
+---------------+------------------------------+
1 row in set (0.00 sec)

配置错误日志

打开my.cnf,在[mysqld]分类下加入如下配置
log_error=/var/mysql_log/mysql-err.log

2.通用查询日志

MySQL的查询日志记录了所有MySQL数据库请求的信息。无论这些请求是否得到了正确的执行。默认文件名为hostname.log。默认情况下MySQL查询日志是关闭的。生产环境,如果开启MySQL查询日志,对性能还是有蛮大的影响的(生产上不建议打开)。另外很多时候,MySQL慢查询日志基本可以定位那些出现性能问题的SQL,所以MySQL查询日志应用的场景其实不多,有点鸡肋的感觉,它跟SQL Server中的profiler有点类似,但是这个不能跟踪某个会话、用户、客户端。它只能对整个数据库进行跟踪。

查看通用日志配置

mysql> show variables like 'general_%';
+------------------+---------------------------------+
| Variable_name    | Value                           |
+------------------+---------------------------------+
| general_log      | ON                              |
| general_log_file | /var/mysql_log/mysql-common.log |
+------------------+---------------------------------+

查看查询日志

[root@server-1 mysql_log]# tail -f mysql-common.log 
Time                 Id Command    Argument
181228  6:02:17     1 Connect   root@localhost on demo_ds_0
            1 Query show databases
            1 Query show tables
            1 Field List    t_order 
            1 Field List    t_order_item 
            1 Query select * from t_order
181228  6:02:31     1 Query show variables like 'general_log'
181228  6:02:38     1 Query show variables like 'general_'
181228  6:02:42     1 Query show variables like 'general_%'
181228  6:03:35     1 Query select * from t_order  #6点的时候执行了查询

3.慢查询日志

MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10S以上的语句。默认情况下,Mysql数据库并不启动慢查询日志,需要我们手动来设置这个参数,当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。

查看是否开启了慢查询日志

mysql> show variables like 'slow_query_%';
+---------------------+-----------------------------------------+
| Variable_name       | Value                                   |
+---------------------+-----------------------------------------+
| slow_query_log      | ON                                     |
| slow_query_log_file | /usr/local/mysql/data/server-1-slow.log |
+---------------------+-----------------------------------------+
2 rows in set (0.00 sec)

慢查询日志的配置

slow_query_log    :是否开启慢查询日志,on表示开启,off表示关闭。
slow_query_log_file:新版(5.6及以上版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件host_name-slow.log
long_query_time :慢查询阈值,当查询时间多于设定的阈值时,记录日志。
log_queries_not_using_indexes:未使用索引的查询也被记录到慢查询日志中(可选项)。
log_output:日志存储方式。log_output='FILE'表示将日志存入文件,默认值是'FILE'。log_output='TABLE'表示将日志存入数据库,这样日志信息就会被写入到mysql.slow_log表中。MySQL数据
库支持同时两种日志存储方式,配置的时候以逗号隔开即可,如:log_output='FILE,TABLE'。日志记录到系统的专用日志表中,要比记录到文件耗费更多的系统资源,因此对于需要启用慢查询日志,又需
要能够获得更高的系统性能,那么建议优先记录到文件

什么样的语句才会被记录到慢查询日志

通过设置long_query_time的值来控制,默认是10秒,可以在my.cnf文件下[mysqld]分类设置成long_query_time=1表示大于1秒的语句会被记录到慢查询日志里
如果要记录未使用索引的查询被记录到慢日志中可以配置log_queries_not_using_indexes=on

4.二进制日志(binlog)

二进制日志(BINLOG)记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但是不包括数据查询语句。语句以“事件”的形式保存,它阐述了数据的更改过程。此日志对于灾难时的数据恢复起着极其重要的作用
一般来说开启二进制日志大概会有1%的性能损耗(参见MySQL官方中文手册 5.1.24版)。二进制有两个最重要的使用场景:

  • Master端开启binlog,Master把它的二进制日志传递给slaves来达到master-slave数据一致的目的(数据库的同步)
  • 数据恢复,当生产上出现数据需要恢复时,可以通过biglog日志+mysqlbinlog工具来完成数据的修复

biglog的设置

vi编辑打开mysql配置文件
# vi /usr/local/mysql/etc/my.cnf
在[mysqld] 区块设置/添加 log-bin=mysql-bin 确认是打开状态(值 mysql-bin 是日志的基本名或前缀名)
log-bin=mysql-bin

查看biglog是否开启

mysql> show variables like 'log_bin%';
+---------------------------------+-------------------------------------------+
| Variable_name                   | Value                                     |
+---------------------------------+-------------------------------------------+
| log_bin                         | ON                                        |
| log_bin_basename                | /usr/local/mysql/data/mysql-bin-128       |
| log_bin_index                   | /usr/local/mysql/data/mysql-bin-128.index |
| log_bin_trust_function_creators | OFF                                       |
| log_bin_use_v1_row_events       | OFF                                       |
+---------------------------------+-------------------------------------------+
5 rows in set (0.00 sec)

常用biglog日志命令

binlog日志使用二进制存储的,所以不能直接通过cat,vi命令打开,需要用mysqlbinlog工具查看

  1. 查看所有的biglog日志列表
mysql> show master logs;
+----------------------+-----------+
| Log_name             | File_size |
+----------------------+-----------+
| mysql-bin-128.000001 |      1035 |
| mysql-bin-128.000002 |     12984 |
| mysql-bin-128.000003 |       143 |
| mysql-bin-128.000004 |       143 |
| mysql-bin-128.000005 |       662 |
| mysql-bin-128.000006 |       143 |
| mysql-bin-128.000007 |       120 |
| mysql-bin-128.000008 |       120 |
| mysql-bin-128.000009 |       120 |
| mysql-bin-128.000010 |       143 |
| mysql-bin-128.000011 |       143 |
| mysql-bin-128.000012 |       143 |
| mysql-bin-128.000013 |       143 |
| mysql-bin-128.000014 |       143 |
| mysql-bin-128.000015 |       143 |
| mysql-bin-128.000016 |       143 |
| mysql-bin-128.000017 |       120 |
+----------------------+-----------+
17 rows in set (0.00 sec)
  1. 查看master状态,即最后(最新)一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| mysql-bin-128.000017 |      120 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

3.刷新log日志,执行后会重新生成一个新编号的biglog日志文件

mysql> flush logs;
Query OK, 0 rows affected (0.29 sec)

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       143 |
| mysql-bin.000002 |       143 |
| mysql-bin.000003 |       143 |
| mysql-bin.000004 |       143 |
| mysql-bin.000005 |       167 |
| mysql-bin.000006 |       167 |
| mysql-bin.000007(新生成的biglog日志) |       120 |
+------------------+-----------+
7 rows in set (0.00 sec)

注:每当mysqld服务重启时会自动执行flush logs,在mysqldump备份数据时加-F也会刷新binlog日志

使用mysqlbinlog工具查看binlog日志

注: binlog是二进制文件,普通文件查看器cat more vi等都无法打开,必须使用自带的 mysqlbinlog 命令查看
binlog日志与数据库文件在同目录中(我的环境配置安装是选择在/usr/local/mysql/data中)
在MySQL5.5以下版本使用mysqlbinlog命令时如果报错,就加上 “--no-defaults”选项
1.查询第一个binlog日志(show binlog语法是使用在mysql客户端的)
show binlog events;

*************************** 517. row ***************************
   Log_name: mysqlmaster-bin.000751
        Pos: 75139
 Event_type: Xid
  Server_id: 135
End_log_pos: 75170
       Info: COMMIT /* xid=68318 */
*************************** 518. row ***************************
   Log_name: mysqlmaster-bin.000751
        Pos: 75170
 Event_type: Query
  Server_id: 135
End_log_pos: 75257
       Info: BEGIN

2.指定查询某个binlog日志
show binlog events in 'mysql.bin.000892'\G;
3.指定查询某个binlog日志并设置从哪个pos点开始查询

mysql> show binlog events in 'mysqlmaster-bin.000751' from 26969 limit 2 \G; 
#表示从pos=26969开始,获取2行
*************************** 1. row ***************************
   Log_name: mysqlmaster-bin.000751
        Pos: 26969
 Event_type: Intvar
  Server_id: 135
End_log_pos: 27001
       Info: INSERT_ID=23398
*************************** 2. row ***************************
   Log_name: mysqlmaster-bin.000751
        Pos: 27001
 Event_type: Query
  Server_id: 135
End_log_pos: 27433
       Info: use `test`; insert into roder(id,name,kk) values ('126828','126828','gpc')
2 rows in set (0.00 sec)

4.采用mysqlbinlog命令(在linux命令行使用,下面有具体的语法)

[root@Slave2 mysql]# mysqlbinlog mysqlmaster-bin.000751 > /home/xuzy/mysqlmaster-bin-000751.log

binlog日志删除

1.删除所有的binlog日志

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       143 |
| mysql-bin.000002 |       120 |
+------------------+-----------+
2 rows in set (0.00 sec)

mysql> reset master; #删除所有binlog日志
Query OK, 0 rows affected (0.29 sec)

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       120 |
+------------------+-----------+
1 row in set (0.00 sec)

2.删除指定binglog日志之前的日志

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       167 |
| mysql-bin.000002 |       120 |
+------------------+-----------+
2 rows in set (0.00 sec)

mysql> purge master logs to 'mysql-bin.000002'; #删除编号000002之前编号的日志
Query OK, 0 rows affected (0.17 sec)

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000002 |       120 |
+------------------+-----------+
1 row in set (0.00 sec)

3.删除指定时间之前产生的日志
purge master logs before '2018-12-12 04:10:00'
4.配置文件配置自动删除
expire_logs_days=4 #表示4天后自动删除之前的日志

使用binlog命令恢复数据库

语法命令:
mysqlbinlog mysql-bin.0000xx | mysql -u用户名 -p密码 数据库
常用选项:
--start-position=953 起始pos点
--stop-position=1437 结束pos点
--start-datetime="2013-11-29 13:18:54" 起始时间点
--stop-datetime="2013-11-29 13:21:53" 结束时间点
--database=zyyshop 指定只恢复zyyshop数据库(一台主机上往往有多个数据库,只限本地log日志)
1.根据binlog进行全部恢复(一般不这样做,做恢复的时候如果不指定恢复的pos,可能将原来错误的语句也加执行进入。例如drop table 语句也会被加入到binlog日志中,如果直接执行全部恢复而不指定pos,就可能将drop table语句也包含进去)
mysqlbinlog mysql-bin.000324 | /usr/local/mysql/mysql

采用binlog恢复数据库

2.指定pos结束点恢复

mysqlbinlog --start-position=900 --stop-position=14232 --database=数据库名称 /usr/local/mysql/data/mysql-bin.000023 | /usr/local/mysql/bin/mysql -uroot -p123456 -v 数据库名称
#也可以指定时间点恢复,将--start-position,--stop-position换成
#--start-datetime="2013-11-29 13:18:54"  起始时间点
#--stop-datetime="2013-11-29 13:21:53"   结束时间点

数据恢复场景模拟:

  1. 早上6点时定时器对数据库进行了备份
#学习下备份的几个常用的命令
#对 demo_ds_0数据库备份到demo_ds_0.sql文件
mysqldump -uroot -p123456 demo_ds_0 > demo_ds_0.sql
#备份所有数据库
mysqldump -uroot -p123456 --all-database > all.sql
#备份demo_ds_0 demo_ds_1
mysqldump -uroot -p123456 --database demo_ds_0 demo_ds_1 > demo_ds_.sql
#备份demo_ds_0 中的 t_order表
mysqldump -uroot -p123456  demo_ds_0 t_order > demo_ds_1_t_order.sql
#--single-transaction参数:此选项将使得 InnoDB 存储引擎得到一个快照(Snapshot),使得备份的数据能够保证一致性
mysqldump -uroot -p123456 --single-transaction  demo_ds_1 > demo_ds_1.sql
#-A:备份所有库
#-d:只备份表结构
#-t:只备份数据
#-l : MyISAM 存储引擎在备份的时候需要加上-l 参数,表示将所有表加上读锁,在备份期间,所有表将只能读而不能进行数据更新
#-F : 生成一个新的binlog日志(这个最好再定时备份的时候加上,每天生成一个新的binlog,方便恢复)
mysqldump -uroot -p123456 -l test person > test_person.sql
#全量恢复
mysql -uroot -p123456 demo_ds_0 < demo_ds_0.sql
  1. 数据库正常运行中.....各种增删改查
  2. 早上10点时开发人员不小心执行了drop语句将表给删除了,蛋疼
  3. 此时需要做数据恢复......
  4. 首先先使用命令查看早上6点到早上10点的binlog日志
    show master status #查看下当前数据库是使用的哪个二进制日志
mysql> show master status;
+------------------------+-----------+--------------+------------------+-------------------+
| File                   | Position  | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------------+-----------+--------------+------------------+-------------------+
| mysqlmaster-bin.000752 | 332156714 |              |                  |                   |
+------------------------+-----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

查看早上6点到10点这段时间的二进制日志,并找到那条drop语句的前一个pos点(可以先根据--start-datetime=xxx定位到对应日志,然后找到drop table对应的pos,假设drop table语句的pos=15000,则我们需要的是恢复从早上6点的pos点到pos=14999的数据)

  1. 先将mysqlmaster-bin.000752备份,并重新flush logs,让其重新产生日志
cp mysqlmaster-bin.000752 mysqlmaster-bin.000752_bak
mysql> flush logs;
  1. 将早上6点的备份进行数据恢复(执行后,早上6点之前的数据都恢复过来,但是6点到10点这段的操作都将失去,这段时间的我们采用二进制日志恢复)
/usr/local/mysql/bin/mysql -uroot -p123456 -v < 备份的脚本.sql #进行数据库恢复
  1. 将早上6点到10点这段的数据采用binlog恢复
#从binlog文件中获取需要恢复的数据库事务操作
#--database 指定要查询的数据库
mysqlbinlog --start-position=1321--stop-position=14999 --database=数据库名称 /usr/local/mysql/data/mysqlmaster-bin.000752 > resql.sql
#导入sql来恢复
mysql -u root -p123456  –one-database 数据库名称 < resql.sql
  1. 至此数据库完全恢复,总结下恢复过程需要分成两段
  • 早上6点之前的数据采用原来备份的dump进行恢复,首先保证今天之前的数据正确
  • 6点到10点之间的数据通过查看binlog日志,找到错误语句之前的pos进行恢复

5.慢日志分析工具(mysqldumpslow)

mysqldumpslow是mysqlserver自带的用来分析慢日志的工具,主要作用是分析慢查询日志文件,将日志中的内容进行摘要后输出显示

[root@linx1 root]# mysqldumpslow --help
Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]

Parse and summarize the MySQL slow query log. Options are

  --verbose    verbose
  --debug      debug
  --help       write this text to standard output

  -v           verbose
  -d           debug
  -s ORDER     what to sort by (al, at, ar, c, l, r, t), 'at' is default
                al: average lock time
                ar: average rows sent
                at: average query time
                 c: count
                 l: lock time
                 r: rows sent
                 t: query time  
  -r           reverse the sort order (largest last instead of first)
  -t NUM       just show the top n queries
  -a           don't abstract all numbers to N and strings to 'S'
  -n NUM       abstract numbers with at least n digits within names
  -g PATTERN   grep: only consider stmts that include this string
  -h HOSTNAME  hostname of db server for *-slow.log filename (can be wildcard),
               default is '*', i.e. match all
  -i NAME      name of server instance (if using mysql.server startup script)
  -l           don't subtract lock time from total time

常用参数

-s : 表示根据什么排序(-s t 根据时间排序)
al 平均锁定时间
ar 平均返回记录时间
at 平均查询时间(默认)
c 计数
l 锁定时间
r 返回记录
t 查询时间
-t,是top n的意思,即为返回前面多少条的数据
-g,后边可以写一个正则匹配模式,大小写不敏感的
例如 mysqldumpslow -s t -t 10 slow.log 中的 -s t 表示根据查询进行进行排序, -t 10 表示返回前10条。整体的意思就是查询的结果是10条执行时间最慢的sql语句

返回结果解析

[root@linux test]# mysqldumpslow -s t -t 10 mysql-slow.log 

Reading mysql slow query log from mysql-slow.log
Count: 4  Time=19.72s (78s)  Lock=0.00s (0s)  Rows=79.2 (317), root[root]@2hosts
  SELECT * FROM `t_s_attachment`

Count: 1  Time=21.39s (21s)  Lock=0.00s (0s)  Rows=82.0 (82), root[root]@[211.97.129.74]
  SELECT * FROM `t_s_attachment`;
  C:\Program Files\MySQL\MySQL Server N.N\bin\mysqld.exe, Version: N.N.N-log (MySQL Community Server (GPL)). started with:
  TCP Port: N, Named Pipe: (null)
  C:\Program Files\MySQL\MySQL Server N.N\bin\mysqld.exe, Version: N.N.N-log (MySQL Community Server (GPL)). started with:
  TCP Port: N, Named Pipe: (null)
  # Time: N N:N:N
  # User@Host: root[root] @  [N.N.N.N]  Id: N
  # Query_time: N.N  Lock_time: N.N Rows_sent: N  Rows_examined: N
  use fqdyzyz;
  SET timestamp=N;
  SELECT * FROM `t_s_attachment`

Count: 1  Time=0.00s (0s)  Lock=0.00s (0s)  Rows=0.0 (0), 0users@0hosts
  C:\Program Files\MySQL\MySQL Server N.N\bin\mysqld.exe, Version: N.N.N-log (MySQL Community Server (GPL)). started with:
  TCP Port: N, Named Pipe: (null)
  C:\Program Files\MySQL\MySQL Server N.N\bin\mysqld.exe, Version: N.N.N-log (MySQL Community Server (GPL)). started with:
  TCP Port: N, Named Pipe: (null)
  # Time: N N:N:N
  # User@Host: root[root] @  [N.N.N.N]  Id:  N
  # Query_time: N.N  Lock_time: N.N Rows_sent: N  Rows_examined: N
  use jeewx;
  SET timestamp=N;
  SELECT * FROM `t_s_attachment`
  • Count : 表示这类型的查询语句执行了几次
  • Time : 这类型的查询语句执行的最大时间 Time=19.72s(78s) 19.72表示这类最大查询时间,78表示这类执行总花费时间
  • Lock : 锁表的时间
  • Rows : 返回的记录条数 Rows=79.2(317) 表示一共返回的总记录,我这里执行了4次,每次返回79条
    示例
mysqldumpslow -s r -t 10 /database/mysql/slow-log.txt
得到返回记录集最多的10个查询。

mysqldumpslow -s t -t 10 -g “left join” /database/mysql/slow-log.txt
得到按照时间排序的前10条里面含有左连接的查询语句。

mysqldumpslow -a -s t -t 2 /opt/slow_query_log.txt
-a 参数,说明不合并类似的SQL语句,显示具体的SQL语句中的数字和字符串。

参考

MySQL慢查询日志总结
MySQL的binlog日志
Mysqldumpslow的用法汇总
MySQL中的 redo 日志文件

你可能感兴趣的:(《MySQL自学笔记》之日志)