MySQL日志管理

一、MySQL日志

   错误日志:      --log-error                文件名   host_name.err

   常规日志:      --general-log            文件名 host_name.log

   慢查询日志:  --slow_query_log      文件名  host_name-slow.log                 程序:mysqldumpslow

                             --long_query_log      

    二进制日志   --log-bin                      文件名:  host_name-bin.0000001       程序:mysqlbinlog

    审计日志       --audit_log                  文件名:audit.log

1.1错误日志

         作用:就是排查MySQL运行过程中出现的故障;

         错误日志默认开启;

         存放路径:datadir

[root@#localhost data]# ls
auto.cnf  care4           ibdata1      ibtmp1                      #localhost.pid      school
care2     employtest      ib_logfile0  #localhost.localdomain.err  mysql               sys
care3     ib_buffer_pool  ib_logfile1  localhost.localdomain.err   performance_schema  worknode

       日志名称:localhost.localdomain.err 

        定制存放路径:在my.cnf中   mysqld下配置    log_error=/data/error.log     目录必须有mysql权限

1.2二进制日志(binlog)

         作用:主从要依赖二进制日志;

                     数据恢复要依赖二进制日志;

         配置(默认没有开启):

                    server_id=1~65535

                    log_bin=/data/mysql/data/mysql-bin            /data/mysql/data/是存放目录,要有mysql:mysql权限  mysql-bin是文件名

         在my.cnf中配置

[mysqld]
server_id=3306
log_bin=/data/mysql/data/mysql-bin

1.2.1二进制日志记录的内容

          记录数据库所有的变更类的日志,DCL,DML,DDL;

          DDL,DCL 以语句的方式原样记录;

          DML  记录已经提交的事务;

          DML记录日志的格式包括:statement,row,mixed,通过binlog-format=row参数控制,这个参数只能控制DML语句的格式。

                                         statement   :SBR    语句模式记录日志

                                         ROW          :RBR    行模式,记录行的变化

                                        MIXED        :MBR    混合模式

‘                                                    SBR和RBR的对比:

                                                                SBR可读性比较强,对应范围操作,日志量比较小,但是有可能不准确,可能会出现记录不准确的情况,比如日志记录了now(),等恢复数据时候会出错;

                                                                RBR可读性弱,记录之日量大,不会出现记录错误;

1.2.2二进制记录的单元            

                最小单元是事件;

                DDL每一个语句就是一个事件;

                DML;一个完整的事务

1.2.3二进制日志的管理                                       

           查看二进制日志的存放位置

mysql> show variables like '%log_bin%';
+---------------------------------+----------------------------------+
| Variable_name                   | Value                            |
+---------------------------------+----------------------------------+
| log_bin                         | ON                               |
| log_bin_basename                | /data/mysql/data/mysql-bin       |
| log_bin_index                   | /data/mysql/data/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.03 sec)

查看二进制日志

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       307 |
+------------------+-----------+
1 row in set (0.01 sec)

刷新日志:

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

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       354 |
| mysql-bin.000002 |       154 |
+------------------+-----------+
2 rows in set (0.00 sec)

查看正在使用的二进制日志

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

查看二进制日志中执行的DDL语句

mysql> show binlog events in 'mysql-bin.000002';
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000002 |   4 | Format_desc    |         6 |         123 | Server ver: 5.7.16-log, Binlog ver: 4 |
| mysql-bin.000002 | 123 | Previous_gtids |         6 |         154 |                                       |
| mysql-bin.000002 | 154 | Anonymous_Gtid |         6 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000002 | 219 | Query          |         6 |         319 | create database binlog                |
| mysql-bin.000002 | 319 | Anonymous_Gtid |         6 |         384 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000002 | 384 | Query          |         6 |         484 | use `binlog`; create table t(id int)  |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
6 rows in set (0.00 sec)

查看二进制日志文件内容:从一个at到下一个at就是一个event

[root@#localhost data]# mysqlbinlog mysql-bin.000002
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#220720 16:33:49 server id 6  end_log_pos 123 CRC32 0x9da4e6f9     Start: binlog v 4, server v 5.7.16-log created 220720 16:33:49
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
7b3XYg8GAAAAdwAAAHsAAAABAAQANS43LjE2LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
AfnmpJ0=
'/*!*/;

查看详细内容:

[root@#localhost data]# mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000002

截取二进制日志

[root@#localhost data]# mysqlbinlog --start-position=219  --stop-position=319 mysql-bin.000002

1.2.4二进制日志恢复数据

创建实验数据:

mysql> create database he;
Query OK, 1 row affected (0.01 sec)

mysql> use he;
Database changed
mysql> create table t1(id int);
Query OK, 0 rows affected (0.04 sec)

mysql> insert into t1 values(1);
Query OK, 1 row affected (0.03 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> drop database he;
Query OK, 1 row affected (0.12 sec)

查看使用的是哪个日志,查看恢复日志的开始位置

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |     1195 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


mysql> show binlog events in 'mysql-bin.000002';

+------------------+------+----------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos  | Event_type     | Server_id | End_log_pos | Info                                  |
+------------------+------+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000002 |    4 | Format_desc    |         6 |         123 | Server ver: 5.7.16-log, Binlog ver: 4 |
| mysql-bin.000002 |  123 | Previous_gtids |         6 |         154 |                                       |
| mysql-bin.000002 |  154 | Anonymous_Gtid |         6 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000002 |  219 | Query          |         6 |         319 | create database binlog                |
| mysql-bin.000002 |  319 | Anonymous_Gtid |         6 |         384 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000002 |  384 | Query          |         6 |         484 | use `binlog`; create table t(id int)  |
| mysql-bin.000002 |  484 | Anonymous_Gtid |         6 |         549 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000002 |  549 | Query          |         6 |         637 | create database he                    |
| mysql-bin.000002 |  637 | Anonymous_Gtid |         6 |         702 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000002 |  702 | Query          |         6 |         795 | use `he`; create table t1(id int)     |
| mysql-bin.000002 |  795 | Anonymous_Gtid |         6 |         860 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000002 |  860 | Query          |         6 |         930 | BEGIN                                 |
| mysql-bin.000002 |  930 | Table_map      |         6 |         973 | table_id: 108 (he.t1)                 |
| mysql-bin.000002 |  973 | Write_rows     |         6 |        1013 | table_id: 108 flags: STMT_END_F       |
| mysql-bin.000002 | 1013 | Xid            |         6 |        1044 | COMMIT /* xid=24 */                   |
| mysql-bin.000002 | 1044 | Anonymous_Gtid |         6 |        1109 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000002 | 1109 | Query          |         6 |        1195 | drop database he                      |
+------------------+------+----------------+-----------+-------------+---------------------------------------+
17 rows in set (0.00 sec)

导出有效的日志:

[root@#localhost data]# mysqlbinlog --start-position=549 --stop-position=1109 mysql-bin.000002>/tmp/he.sql

开始恢复数据

mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)
mysql> source /tmp/he.sql
Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

将二进制日志开启
mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)

1.2.5 二进制日志的gtid模式

      对于binlog中的每一个事务,都会生成一个GTID号码;DDL,DCL一个事件就是一个事务,就会生成一个GTID号,DML语句从begin到commit是一个事务,生成一个GTID号,

GTID的组成:server_uudi:TID         TID是一个自增长的数字,从1开始

[root@#localhost data]# cat auto.cnf 
[auto]
server-uuid=a99a829e-fd98-11ec-9933-000c29d9caa0

GTID的配置和开启

[root@#localhost data]# vi /etc/my.conf
gtid-mode=on
enforce-gtid-consistency=true

查看;

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)
mysql> create database gttid;
Query OK, 1 row affected (0.01 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000003 |      316 |              |                  | a99a829e-fd98-11ec-9933-000c29d9caa0:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

新增一个事务就会生成一个新的GTID

mysql> use gttid
Database changed
mysql> create table t1(id int);
Query OK, 0 rows affected (0.05 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000003 |      480 |              |                  | a99a829e-fd98-11ec-9933-000c29d9caa0:1-2 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

基于GTID的数据恢复:

drop  database gttid;
mysql> 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.16-log, Binlog ver: 4                             |
| mysql-bin.000003 | 123 | Previous_gtids |         6 |         154 |                                                                   |
| mysql-bin.000003 | 154 | Gtid           |         6 |         219 | SET @@SESSION.GTID_NEXT= 'a99a829e-fd98-11ec-9933-000c29d9caa0:1' |
| mysql-bin.000003 | 219 | Query          |         6 |         316 | create database gttid                                             |
| mysql-bin.000003 | 316 | Gtid           |         6 |         381 | SET @@SESSION.GTID_NEXT= 'a99a829e-fd98-11ec-9933-000c29d9caa0:2' |
| mysql-bin.000003 | 381 | Query          |         6 |         480 | use `gttid`; create table t1(id int)                              |
| mysql-bin.000003 | 480 | Gtid           |         6 |         545 | SET @@SESSION.GTID_NEXT= 'a99a829e-fd98-11ec-9933-000c29d9caa0:3' |
| mysql-bin.000003 | 545 | Query          |         6 |         640 | drop database gttid                                               |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
8 rows in set (0.00 sec)

导出日志:  --skip-gtids 跳过之前的已经产生的gtid号,不检查原来的生成的gitd号,恢复时候生成新的gtid号,不然恢复报错

[root@#localhost data]# mysqlbinlog --skip-gtids --include-gtids='a99a829e-fd98-11ec-9933-000c29d9caa0:1-2' mysql-bin.000003>/tmp/gttid.sql

恢复数据:

mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.01 sec)
mysql> source /tmp/gttid2.sql
mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)

1.3慢日志slow-log

      记录运行较慢的语句;

 1.3.1配置开启慢日志记录

           #开关

                  slow_query_log=1

           #存放位置

                   slow_query_log_file=/data/mysql/data/slow.log

           #时间设定

                   long_query_time=0.2

         #没有走索引也记录

                  log_queries_not_using_indexes

vi  /etc/my.cnf
slow_query_log=1
slow_query_log_file=/data/mysql/data/slow.log
long_query_time=0.2
log_queries_not_using_indexes

1.3.2慢日志分析

[root@#localhost data]# mysqldumpslow -s c -t 10  /data/mysql/data/slow.log

 二、重做日志  Redo  log

任何事务的操作都会记录redo日志,InnoDB引擎独有,用于恢复数据库到宕机的位置。

Redo  log 记录的是新数据的备份。

在事务提交前,只要将Redo  Log持久化即可,不需要将数据持久化。

当系统崩溃时候,虽然数据没有持久化,但是RedoLog已经持久化。

系统可以根据RedoLog的内容,将说有的数据恢复到最新的状态。

数据库崩溃以后:

先要做前滚,redo  log+旧的数据块 

在做回滚(undo、rollback)

保护做了修改有没有刷到磁盘的脏页。

2.1   前滚

rolling   forward(前滚)

数据库启动时候,然后通过 online  redologs  中的重做日志,重现实例崩溃前对数据库的修改操作。在恢复过程中对已经提交的事务,但尚未写入数据文件的那部分数据全部写入数据文件。

2.2  回滚

rolling    back

rolling  forward之后,虽然已经提交的修改操作更改的数据都已经被写入数据文件,但是在实例崩溃时候,部分未提交的事务操作数据也被写入到数据文件,这些事务必须被撤销。

2.3 redo  log重做日志的由来

InnoDB有buffer  pool(简称bp) 是数据库页面的缓存,对InnoDB的任何修改都会首先在bp的page上进行,然后这样的页面将被标记为dirty并被放到专门的flush  list上,后续将由master thread 或专门的刷脏线程阶段性的将这些页面写入磁盘(disk  or   ssd)。

这样的好处是避免每次写操作都是操作磁盘导致大量的随机IO,阶段性的刷脏也也可以将多次对页面的修改merge成一次的IO操作,同时一步写入也降低了访问的时延。

然而,如果在dirty page还未刷入磁盘时候,server非正常关闭,这些修改操作将会丢失,如果写入操作正在进行,甚至会由于损坏数据文件导致数据库不可用。

为了避免上述问题,Innodb将所有的对页面的修改操作写入一个专门的文件,并在数据库启动时候从此文件进行恢复操作,这个文件就是redo  log  file。

这样的技术推迟了bp页面的刷新,从而提升了数据库的吞吐,有效的降低了访问时候的时延。带来的问题是额外的写redo  log操作的开销,以及数据库启动时候恢复曹组所需的时间。

2.4  如何写redo  log 重做日志

redo  log  info >  redo  log  buffer  >  redo  log  files

redo  log  buffer:

   1、日志会先写到  redo   log    buffer  ,根据指定条件刷新到redo  log  file 

   2、由log  block 组成

   3、每个log  block  512字节,所以不需要double  write,因为每次刷新都是原子的

重做日志都是以512字节进行存储的

即:重做日志缓冲,重做日志文件都是以块block的方式进行保存,统称为重做日志块redo  log  block 大小:512字节。

2.5 日志块的组成

  日志块头 log  blockheader  12 字节

   日志本身 492字节

   日志块尾 log  block tailer  8字节

2.6 log buffer 往log  file里面写redo  log的触发机制

        01、每1S 写一次;

        02、大于log  buffer  空间的1/2的时候,默认是8M;

        03、commit的时候;

        04、log  buffer到了1M的时候

       05、WAL日志先写机制,当后台脏也往磁盘写的时候,先要把日志写过来。WAL:磁盘上的数据是比较旧的,而日志文件是比较新的。日志比最小的数据还要新。

 redo文件在系统的位置

[root@localhost ~]# cd /mysql/data/
-rw-r-----  1 mysql mysql  536870912 10月  9 21:31 ib_logfile0
-rw-r-----  1 mysql mysql  536870912 10月  4 17:17 ib_logfile1

        06、MySQL里边的redo日志只能做崩溃恢复,只针对innodb表起作用。

       07、redo里边记录的是日志写入,里面有个很重要的概念叫做lsn

2.7  checkpoint

      1、缩短数据库的恢复时间;

      2、缓冲池不够用时候,将脏页刷到磁盘;

      3、重做日志不可用时候,刷新脏页。

 当数据库发生宕机时候,数据库不需要重做所有的日志,因为Checkpoint之前的页都已经刷新回磁盘,数据库只需要对Checkpoint后的重做日志进行恢复,这样就大大缩短了恢复的时间。

2.8 checkpoint种类

    sharp checkpoint  当MySQL正常关闭的时候,需要将所有的脏页都刷新;

    fuzzy  checkpoint 为了考虑数据库的性能,MySQL按照一定算法刷新部分脏页。

三、日志序列号 LSN

3.1 日志介绍

show  engine  innodb status\G

Log sequence number 2642018  ---redo log buffer 的lsn,存放在redo  log  buffer中
Log flushed up to   2642018  ---redo  log  file的lsn,存放redo  log   file  中的lsn
Pages flushed up to 2642018  ---数据刷盘data  page 的lsn
Last checkpoint at  2642009  ---checkpooint,存放在redo log  file里面的第一个文件的头部

3.12 日志的整个生命周期

创建日志:事务创建一条日志,写入redo  log  buffer 中;

日志刷盘:日志从缓存中写到磁盘的日志文件中;

数据刷盘:日志对应的脏页数据写而入磁盘中的数据文件;

写checkpoint:日志被当着checkpoint写入日志文件中;

3.3  重做日志的配置

mysql> show variables like '%innodb_log%';
+-----------------------------+-----------+
| Variable_name               | Value     |
+-----------------------------+-----------+
| innodb_log_buffer_size      | 16777216  |
| innodb_log_checksums        | ON        |
| innodb_log_compressed_pages | ON        |
| innodb_log_file_size        | 536870912 |
| innodb_log_files_in_group   | 2         |
| innodb_log_group_home_dir   | ./        |
| innodb_log_write_ahead_size | 8192      |
+-----------------------------+-----------+
7 rows in set (0.01 sec)

可以配置在my.cnf

innodb_log_file_size=512M
innodb_log_file_in_group=2
innodb_log_buffer_size=16M

 四、undo  log日志

undo用于回滚,undo也回产生redo,undo除了回滚,还用于并发控制;

4.1查看参数

mysql> show variables like '%undo%';
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| innodb_max_undo_log_size | 1073741824 |
| innodb_undo_directory    | ./         |
| innodb_undo_log_truncate | OFF        |   -----------当undo表空间慢的时候是否自动清理
| innodb_undo_logs         | 128        |   ----------8.0版本后参数被改为innodb_rollback_sgements
| innodb_undo_tablespaces  | 0          |
+--------------------------+------------+
5 rows in set (0.01 sec)

 

posted @ 2022-07-20 23:31  中仕  阅读(16)  评论(0)    收藏  举报