数据库===》日志管理

一、mysql日志分类

不管是哪个数据库产品,一定会有日志文件。在MariaDB/MySQL中,主要有5种日志文件:
1.错误日志(error log):记录mysql服务的启停时正确和错误的信息,还记录启动、停止、运行过程中的错误信息。
2.查询日志(general log):记录建立的客户端连接和执行的语句。
3.二进制日志(bin log):记录所有更改数据的语句,可用于数据复制。
4.慢查询日志(slow log):记录所有执行时间超过long_query_time的所有查询或不使用索引的查询。
5.中继日志(relay log):主从复制时使用的日志。

二、错误日志

1.错误日志会记录如下信息

  • mysql执行过程中的错误信息
  • mysql执行过程中的告警信息
  • event scheduler运行时所产生信息
  • mysq启动和停止过程中产生的信息
  • 主从复制结构中,重从服务器IO复杂线程的启动信息

2.错误日志相关参数

#编辑配置文件
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
log-error=/var/log/mysqld.log

 #查看方式
[root@localhost ~]# mysql -u root -p123456
mysql> show variables where variable_name="log_error" or variable_name="log_warnings";  #查看方式
+---------------+---------------------+
| Variable_name | Value               |
+---------------+---------------------+
| log_error     | /var/log/mysqld.log |
| log_warnings  | 1                   |
+---------------+---------------------+
2 rows in set (0.00 sec)


注释:
log_error:错误日志的存放路径
log_warnings:表示是否记录告警信息到错误日志,0表示不记录告警信息,1表示记录告警信息,大于1表示各类告警信息,例如有关网络故障的信息和重新连接信息写入错误日志。

三、查询日志

1.查询日志记录内容

查询自然在mysql中被称之为general log,查询日志记录了数据库执行的命令,不管这些语法是否正确,都会被记录。由于数据库操作命令非常多而且比较频繁,所以开启了查询日志以后,数据库可能需要不停的写入查询,这样会增大服务器的IO压力,增加很多的系统开销,所以默认情况下,mysql的查询日志是没有开启的,但是开启查询日志也有助于我们分析那些语句执行密集,执行密集的select语句对应的数据是否能够被缓存,查询日志也可以帮助我们分析问题,所以,我们可以更具实际情况决定是否开启查询日志,如果需要可以手动开启。

2.查询日志相关参数

#查看方式
mysql> show variables where variable_name like "%general_log%" or variable_name = "log_output";
+------------------+-----------------------------+
| Variable_name    | Value                       |
+------------------+-----------------------------+
| general_log      | OFF                         |
| general_log_file | /backup/data1/localhost.log |
| log_output       | FILE                        |
+------------------+-----------------------------+
3 rows in set (0.00 sec)


注释:
general_log:表示查询日志是否开启,ON表示开启,OFF表示未开启,默认未OFF
log_output:表示当查询日志开启以后,以哪种方式存放。FILE表示存放于文件中,TABLE表示存放于表mysql.general_log中(慢查询存放于表mysql.slow_log),FILE,TABLE表示同时存放于文件和表中,NONE表示不记录日志。log_output不仅控制查询日志,还控制慢查询日志。
general_log_file:表示查询日志存放于文件的路径。

四、慢查询日志

1.慢查询日志记录内容

某些sql语句执行完毕所花费的时间特别长,我们将这种响应比较慢的语句记录在慢查询日志中,只要超过指定时间的sql语句,都称为“慢查询”,被记录在慢查询日志中。

慢查询日志默认情况下是关闭的,默认设置下,超过10s的语句才会被记录到慢查询日志中。

2.慢查询日志相关参数

mysql> show  variables where variable_name like 'slow_query%' or variable_name='long_query_time' or variable_name='log_queries_not_using_indexes';
+-------------------------------+----------------------------------+
| Variable_name                 | Value                            |
+-------------------------------+----------------------------------+
| log_queries_not_using_indexes | OFF                              |
| long_query_time               | 10.000000                        |
| slow_query_log                | OFF                              |
| slow_query_log_file           | /backup/data1/localhost-slow.log |
+-------------------------------+----------------------------------+
4 rows in set (0.00 sec)

注释:
slow_query_log:表示查询日志是否开启,ON表示开启,OFF表示未开启,默认OFF
slow_query_log_file:表示查询日志存放于文件的路径
long_query_time:表示多长时间的查询被认为"慢查询",默认10s
log_queries_not_using_indexes:表示如果运行的sql语句没有使用到索引,也被记录到慢查询日志,OFF表示不记录,ON表示记录,默认OFF

五、二进制日志

1.二进制日志记录内容

二进制日志是一个二进制文件,记录了对MySQL数据库执行更改的所有操作,并且记录了语句发生时间、执行时长、操作数据等其他额外信息,但是他不记录SELECT、SHOW等那些不改变数据库的SQL语句。二进制日志主要用于数据库恢复和主从复制,以及审计操作。

2.二进制日志相关参数

mysql> show variables where
    -> variable_name="log_bin" or
    -> variable_name="log_bin_basename" or
    -> variable_name="max_binlog_size" or
    -> variable_name="log_bin_index" or
    -> variable_name="binlog_format" or
    -> variable_name="sql_log_bin" or
    -> variable_name="sync_binlog";
+------------------+-------------------------------+
| Variable_name    | Value                         |
+------------------+-------------------------------+
| binlog_format    | STATEMENT                     |
| log_bin          | ON                            |
| log_bin_basename | /backup/data1/mysql-bin       |
| log_bin_index    | /backup/data1/mysql-bin.index |
| max_binlog_size  | 1073741824                    |
| sql_log_bin      | ON                            |
| sync_binlog      | 0                             |
+------------------+-------------------------------+
7 rows in set (0.00 sec)


注释:
log_bin:表示二进制日志是否开启,ON表示开启,OFF表示未开启,默认OFF
log_bin_basename:二进制日志文件前缀名,二进制日志就记录在该文件中
max_binlog_size:二进制日志文件的最大大小,超过此大小,二进制文件会自动滚动
log_bin_index:二进制日志文件索引文件名,用于记录所有的二进制文件
binlog_format:决定了二进制日志的记录方式,STATEMENT以语句的形式记录,ROW以数据修改的形式记录,MIXED以语句和数据修改混合形式记录
sql_log_bin:决定是否对二进制日志进行日志记录,ON表示执行记录,OFF表示不执行记录,默认OFF,这个是会话级别变量可以通SET sql_log_bin = {0|1}来改变该变量值
sync_binlog:决定二进制日志写入磁盘时机,如果sync_binlog为0,操作系统来决定什么时候写入磁盘,如果sync_binlog为N(N=1,2,3..),则每N次事务提交后,都立即将内存中的二进制日志写入磁盘,如何选择取决于安全性与性能的权衡。

3.二进制日志的三种格式

STATEMENT:记录对数据库做出修改的语句,比如,update A set test='test',如果使用statement模式,那么这条update语句将被记录到二进制日志中,使用statement模式时,优点是binlog日志量少,IO压力小,性能高,缺点是为了尽可能一致的还原操作,除了记录语句本身外,可能还需要记录一些相关信息,而且,在使用一些特定函数时,并不能保证恢复操作与记录完全一致。

ROW:记录对数据库做出的修改的语句所影响到的数据行以及这些行的修改,比如,update A set test='test',如果使用row模式,那么这条update所影响到的行所对应的修改,将会记录在binlog中,使用row模式时,优点是能完还原和复制被日志记录时的操作,缺点是日志量较大,IO压力比较大,性能消耗比较大。

MIXED:混合上述两种模式,一般使用statement方式进行记录,如果遇到一些特殊函数使用row方式进行记录,这种记录方式称为mixed。

六、事务日志

1.redo log和undo log

undo log 和 redo log 其实都不是 MySQL 数据库层面的日志,而是 InnoDB 存储引擎的日志。二者的作用联系紧密,事务的隔离性由锁来实现,原子性、一致性、持久性通过数据库的 redo log 或 redo log 来完成。redo log 又称为重做日志,用来保证事务的持久性,undo log 用来保证事务的原子性和 MVCC。

2.redo log(重做日志)

#功能
和大多数关系型数据库一样,InnoDB 记录了对数据文件的物理更改,并保证总是日志先行,也就是所谓的 WAL,即在持久化数据文件前,保证之前的 redo 日志已经写到磁盘。由于 redo log 是顺序整块写入,所以性能要更好。

重做日志两部分组成:一是内存中的重做日志缓冲(redo log buffer),是易失的;二是重做日志文件(redo log file),是持久的。redo log 记录事务操作的变化,记录的是数据修改之后的值,不管事务是否提交都会记录下来。


#执行步骤
update t1 set num=2 where num=1; 
1)首先将t1表中num=1的行所在数据页加载到内存中buffer page
2)MySQL实例在内存中将num=1的数据页改成num=2
3)num=1变成num=2的变化过程会记录到,redo内存区域,也就是redo buffer page中

#提交事务执行步骤
commit; 
1)当敲下commit命令的瞬间,MySQL会将redo buffer page写入磁盘区域redo log
2)当写入成功之后,commit返回ok

当对应事务的脏页写入到磁盘之后,redo log 的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。


另外 redo log 占用的空间是固定的,会循环写入。文件大小由innodb_log_file_size参数控制。

3.undo log(回滚日志)

#undo log 有两个作用:提供回滚和多版本并发控制下的读(MVCC),也即非锁定读

在数据修改的时候,不仅记录了redo,还记录了相对应的 undo,如果因为某些原因导致事务失败或回滚了,可以借助该 undo 进行回滚。

undo log 和 redo log 记录物理日志不一样,它是逻辑日志。可以认为当 delete 一条记录时,undo log 中会记录一条对应的 insert 记录,反之亦然,当 update 一条记录时,它记录一条对应相反的 update 记录。

有时候应用到行版本控制的时候,也是通过 undo log 来实现的:当读取的某一行被其他事务锁定时,它可以从 undo log 中分析出该行记录以前的数据是什么,从而提供该行版本信息,让用户实现非锁定一致性读取。

undo log 是采用段(segment)的方式来记录的,每个 undo 操作在记录的时候占用一个 undo log segment。

另外,undo log 也会产生 redo log,因为 undo log 也要实现持久性保护。

当事务提交的时候,InnoDB 不会立即删除 undo log,因为后续还可能会用到 undo log,如隔离级别为 repeatable read 时,事务读取的都是开启事务时的最新提交行版本,只要该事务不结束,该行版本就不能删除,即 undo log 不能删除。

当事务提交之后,undo log 并不能立马被删除,而是放入待清理的链表,由 purge 线程判断是否有其他事务在使用 undo 段中表的上一个事务之前的版本信息,决定是否可以清理 undo log 的日志空间。

在 MySQL 5.7 之前,undo log 存储在共享表空间中,因此有可能大大增加表空间的占用,5.7 之后可以通过配置选择存储在独立的表空间中。

4.innodb更新操作执行步骤

1.开启事务
2.查询待更新的记录到内存,并加 X 锁
3.记录 undo log 到内存 buffer
4.记录 redo log 到内存 buffer
5.更改内存中的数据记录
6.提交事务,触发 redo log 刷盘
7.记录 bin log
8.事务结束
上一篇:CodeQL分析python代码6-分析python代码的数据流


下一篇:超详细的Canal入门,看这篇就够了!