前言:
mysql作为数据库,有着存储数据、读写数据的基本功能,当然作为数据库,必须具备有安全性、可靠性等相关基础功能。
以我个人的理解,mysql多被用在分布式集群、高并发情景等数据量较大的地方,此时能够支撑mysql完成一系列事务的原因之一就是"日志"。
mysql中有着庞大的日志体系,有二进制日志、重做日志、回滚日志等。这些日志起到了不同的作用。接下来就来深入探究一下这些日志的作用以及相关的作用原理。
MySQL数据目录:
MySQL 服务器的管理信息、业务数据、日志⽂件、磁盘缓冲⽂件默认存储在数据目录下:
管理信息:1.用户名和密码 2.用户的授权 3.系统变量的默认值 4.用户创建的库和表等
业务数据:1.用户创建的库和表以及表中的数据
MySQL工作时主要操作的目录,最重要的目录!!
一般在以下文件中,可以通过ll指令查看:
/var/lib/mysql
数据⽬录下的每个⼦⽬录都是⼀个数据库⽬录,对应服务器管理的⼀个数据库,包括MySQL 安装成功后创建的标准数据库:
a. mysql⽬录对应于mysql系统库,包含mysql服务器运⾏时所需的信息,该数据库包含数据字典表和系统表;b. performance_schema⽬录对应于Performance Schema,提供了在运⾏时⽤于检查服务器内部执⾏的信息;c. sys⽬录对应于sys系统库,提供⼀组对象来帮助解释性能模式相关信息;d. 其他⼦⽬录对应于⽤⼾或应⽤程序创建的数据库,也就是说我们每创建⼀个数据库,就会在数据⽬录⽣成⼀个同名的⽬录来保存对应的数据。
日志介绍:
mysql server涉及以下几种日志:
⽇志类型 ⽇志信息错误⽇志 (Error log) mysqld在启动、运⾏或停⽌时遇到的问题⼀般查询⽇志 (General query log) 已建⽴的客⼾端连接和从客⼾端接收到的语句慢查询⽇志 (Slow query log) 执⾏时间超过 long_query_time 指定秒数的查询⼆进制⽇志 (Binary log) 更改数据的语句(也⽤于主从复制)中继⽇志 (Relay log) 从源服务器接收到的数据更改DDL⽇志(metadata log) DDL 语句执⾏的操作回滚⽇志/撤销⽇志(undo log) ⽤于事务的回滚操作重做⽇志(redo log) ⽤于服务器崩溃恢复
上述日志是作为mysql的核心之一!!
Linux下默认开启错误日志和⼆进制⽇志
在服务器运⾏期间可以控制⼀般查询和慢查询⽇志的禁⽤与开启,也可以更改⽇志⽂件名
⼀般查询⽇志和慢查询⽇志记录可以写⼊⽇志表、⽇志⽂件或两者同时写⼊
默认情况下,所有启⽤的⽇志将写⼊数据⽬录,可以通过刷新⽇志强制服务器关闭并重新打开⽇志⽂件
通过 FLUSH LOGS 语句刷新⽇志来强制服务器关闭并重新打开⽇志⽂件 ,也可以使⽤mysqladmin 的 flush-logs 或 refresh 参数,或mysqldump 的 --flush-logs 或 --master-data 选项
一般查询日志和慢查询日志的输出形式:
如果启⽤⼀般查询⽇志和慢查询⽇志,⽇志的输出⽅式可以指定为⽇志⽂件或 mysql 系统库中的 general_log 和 slow_log 表,也可以两者同时指定。
启动时的日志控制:
通过设置 general_log 系统变量的值来控制⼀般查询⽇志的 开启 1 与 禁⽤ 0 ,如果要为⽇志指定⾃定义的路径或⽂件名可以使⽤ general_log_file 系统变量通过设置 slow_query_log 系统变量的值来控制慢查询⽇志的 开启 1 与 禁⽤ 0 ,如果要为⽇志指定⾃定义的路径或⽂件名可以使⽤ slow_query_log_file 系统变量
[mysqld]# ⽇志写⼊表和⽂件log_output=TABLE,FILE# 开启⼀般查询⽇志general_log=1
[mysqld]log_output=TABLE # ⽇志写⼊表general_log=1 # 开启⼀般查询⽇志slow_query_log=1 # 开启慢查询⽇志
[mysqld]log_output=FILE # ⽇志⽂件slow_query_log=1 # 开启慢查询⽇志
[mysqld]# ⽇志⽂件log_output=FILE# 开启⼀般查询⽇志general_log=1# 指定⾃定义的⽂件名general_log_file=/var/lib/mysql/general.log# 开启慢查询⽇志slow_query_log=1# 指定⾃定义的⽂件名slow_query_log_file=/var/lib/mysql/slow_query.log
运行时日志控制:
语法: SET [GLOBAL|SESSION] variable_name =value
1 SET GLOBAL log_output=[FILE, TABLE, NONE]
1.general_log[={0|1}] 和 slow_query_log[={0|1}] 可以表⽰启⽤和禁⽤⼀般查询日志和慢查询⽇志2.general_log_file 和 slow_query_log_file 表⽰通⽤查询⽇志和慢查询⽇志⽂件名称只对当前会话禁⽤或启⽤⼀般查询⽇志记录,将 SESSION 作⽤域的 sql_log_off 变量设置为 ON 或 OFF
使用日志表优点:
SHOW CREATE TABLE mysql.general_log; # ⼀般查询⽇志SHOW CREATE TABLE mysql.slow_log; # 慢查询⽇志
一般查询日志:
表结构如下:
mysql> SHOW CREATE TABLE mysql.general_log;CREATE TABLE `general_log` (# 发⽣时间`event_time` timestamp ( 6 ) NOT NULL DEFAULT CURRENT_TIMESTAMP ( 6 ) ON UPDATECURRENT_TIMESTAMP ( 6 ),`user_host` mediumtext NOT NULL ,`thread_id` bigint unsigned NOT NULL ,`server_id` int unsigned NOT NULL ,`command_type` varchar ( 64 ) NOT NULL ,`argument` mediumblob NOT NULL) ENGINE=CSV DEFAULT CHARSET=utf8mb3 COMMENT= 'General log'
慢查询日志:
慢查询日志由执⾏时间超过系统变量 long_query_time 指定的秒数的 SQL 语句组成,并且检查的行数⼤于系统变量 min_examined_row_limit 指定值。被记录的慢查询需要进⾏优化,可以使⽤ mysqldumpslow客⼾端程序对慢⽇志进⾏分析汇总。获取初始锁的时间不计⼊执⾏时间,mysqld在执行完SQL语句并释放所有锁后才将符合条件的语句写⼊慢速查询日志,因此⽇志顺序可能与执行顺序不同
慢查询日志参数:
1.long_query_time 的默认值是10,最⼩值是0;2.默认情况下,不记录管理语句,也不记录不使⽤索引的查询3.默认为关闭(不开启),要启⽤慢查询⽇志可以使⽤:请使⽤ --slow_query_log[={0|1}] .4.默认⽇志⽂件名为 host_name -slow.log ,可以使⽤slow_query_log_file= file_name 修改;5.使⽤ --log-short-format 选项,以简要格式记录慢查询⽇志6.要记录管理语句,启⽤ log_slow_admin_statements 系统变量。管理语句包括 ALTERTABLE 、 ANALYZE TABLE 、 CHECK TABLE 、 CREATE INDEX 、 DROP INDEX 、OPTIMIZE TABLE 和 REPAIR TABLE 。7.要记录不使⽤索引的查询,启⽤ log_queries_not_using_indexes 系统变量。当记录不使⽤索引的查询时,⽇志会快速增⻓,通过设置系统变量 log_throttle_queries_not_using_indexes 限制每分钟写⼊慢查询⽇志同类查询的数量,默认值是0,表示无限制。
慢查询日志内容:
1.Query_time: : SQL语句的执行时间,单位秒2.Lock_time: 获取锁的时间,单位秒3.Rows_sent: 发送到客⼾端的⾏数4.Rows_examined: 服务器检查的⾏数5.启用--log-slow-extra[={OFF|ON}]系统变量会将以下额外字段写⼊到FILE中,TABLE形式不受影响6.Thread_id: 线程标识符7.Errno: 错误码,没有发⽣错误则为 08.Killed: 如果语句被终⽌,⽤错误码表示原因,如果语句正常终止则为 0。9.Bytes_received: 接收到SQL语句的Bytes值。10.Bytes_sent: 返回给客⼾端的Byte值。11.Read_first: 索引中第⼀个条⽬被读取的次数,如果这个值很⾼,表明服务器正在执⾏⼤量完整索引扫描12.Read_last: 读取索引中最后⼀个键的请求数,使⽤ ORDER BY 时关注13.Read_key: 基于索引读取⼀⾏数据的请求数。如果这个值很⾼,表明表为当前查询建⽴了正确的索引14.Read_next: 按索引排序读取下一行的请求数,查询具有范围约束的索引列,或者进⾏索引扫描,此值将递增。15.Read_prev: 按索引排序读取前一行的请求数。主要⽤于优化ORDER BYRDESC。16.Read_rnd: 基于固定位置读取一行的请求数。这个值很⾼表⽰,正在执⾏⼤量需要对结果进⾏排序的查询,可能有很多查询进⾏了全表扫描整,或者没有正确使⽤索引的连接。17.Read_rnd_next: 读取数据⽂件中下一行的请求数。如果进⾏⼤量的表扫描,这个值会很⾼。通常,表示表没有建⽴正确地索引,或者查询没有利⽤索引。18.Sort_merge_passes: 排序算法完成的归并次数,如果这个值很⼤,考虑增加 sort_buffer_size 系统变量的值。19.Sort_range_count: 使⽤范围进⾏排序的次数。20.Sort_rows: 排序的⾏数。21.Sort_scan_count: 通过扫描表完成的排序数。22.Created_tmp_disk_tables: 服务器在执⾏语句时创建内部磁盘临时表的数量。23.Created_tmp_tables: 服务器在执⾏语句时创建的内部临时表的数量。24.Start: 执⾏SQL语句开始时间25.End: 执⾏SQL语句结束时间
mysql> SHOW CREATE TABLE mysql.slow_log;CREATE TABLE `slow_log` (`start_time` timestamp ( 6 ) NOT NULL DEFAULT CURRENT_TIMESTAMP ( 6 ) ON UPDATECURRENT_TIMESTAMP ( 6 ),`user_host` mediumtext NOT NULL ,`query_time` time ( 6 ) NOT NULL ,`lock_time` time ( 6 ) NOT NULL ,`rows_sent` int NOT NULL ,`rows_examined` int NOT NULL ,`db` varchar ( 512 ) NOT NULL ,`last_insert_id` int NOT NULL ,`insert_id` int NOT NULL ,`server_id` int unsigned NOT NULL ,`sql_text` mediumblob NOT NULL ,`thread_id` bigint unsigned NOT NULLENGINE=CSV DEFAULT CHARSET=utf8mb3 COMMENT= 'Slow log'
错误日志:
1.如果错误⽇志输出⽬标是控制台,则服务器将 log_error 系统变量设置为 stderr . 否则,将以⽂件形式输⼊错误⽇志,并以 log_error 的值为⽂件名。2.如果显⽰写出 - -log-error 但没有指定具体⽂件,则默认路径是数据⽬录中host_name .err 的⽂件;3.可以通过指定绝对路径,来更改默认的⽇志位置。
[mysqld]log-error=/var/log/mysql/error_log.err # ⾃定义错误⽇志的路径
错误日志中事件的字段
time :件时间戳,精度为微秒;msg :事件消息字符串;prio :事件优先级,包括 System event - 系统(0)、 Error event - 错误(1)、 Warningevent - 警告(2)或 Note/information event - 通知/提⽰事件(3),值越⼩优先级越⾼;err_code :事件错误代码;err_symbol :以字符串形式表⽰的事件错误符,例如 'ER_DUP_KEY' ;SQL_state :事件 SQLSTATE 值,与 err_symbol 对应,例如 'ER_DUP_KEY' 对应的SQLSTATE为23000subsystem :事件发⽣的⼦系统。可能的值: InnoDB (InnoDB存储引擎)、 Repl (复制⼦系统)、 Server (其他)。
二进制日志:
主从节点数据复制 :从节点服务器读取主节点服务器上的⼆进制⽇志⽂件,并根据⼆进制⽇志中记录的事件在从节点上执⾏相同的操作,保证主从节点服务器上数据⼀致,实现数据复制功能。在主从复制专题中我们重点讲解复制过程;数据恢复: 从某个时间点恢复备份数据后,将重新执行备份时间点之后记录在⼆进制日志中的事件。这些事件使数据库从备份点更新到当前最新状态
⼆进制日志的语句中如果涉及用户的密码,则由服务器进行加密,不会以纯⽂本形式出现。
查看二进制日志相关的系统变量:
查看⼆进制⽇志相关的系统变量mysql> show variables like '%bin%';+ ------------------------------------------------+--------------------------------+| Variable_name | Value|+ ------------------------------------------------+--------------------------------+| binlog_cache_size | 32768|| binlog_checksum | CRC32|| binlog_direct_non_transactional_updates | OFF|| binlog_encryption | OFF|| binlog_error_action | ABORT_SERVER|| binlog_expire_logs_auto_purge | ON|| binlog_expire_logs_seconds | 2592000|| binlog_format | ROW|| binlog_group_commit_sync_delay | 0| binlog_group_commit_sync_no_delay_count | 0|| binlog_gtid_simple_recovery | ON|| binlog_max_flush_queue_time | 0|| binlog_order_commits | ON|| binlog_rotate_encryption_master_key_at_startup | OFF|| binlog_row_event_max_size | 8192|| binlog_row_image | FULL|| binlog_row_metadata | MINIMAL|| binlog_row_value_options ||| binlog_rows_query_log_events | OFF|| binlog_stmt_cache_size | 32768|| binlog_transaction_compression | OFF|| binlog_transaction_compression_level_zstd | 3|| binlog_transaction_dependency_history_size | 25000|| binlog_transaction_dependency_tracking | COMMIT_ORDER|| innodb_api_enable_binlog | OFF|| log_bin | ON|| log_bin_basename | D:\log\MySQL\ 8.0 \bin_log|| log_bin_index |D:\log\MySQL\ 8.0 \bin_log.index || log_bin_trust_function_creators | OFF|| log_bin_use_v1_row_events | OFF|| log_statements_unsafe_for_binlog | ON|| max_binlog_cache_size | 18446744073709547520|| max_binlog_size | 1073741824|| max_binlog_stmt_cache_size | 18446744073709547520|| sql_log_bin | ON|| sync_binlog | 1|+ ------------------------------------------------+--------------------------------+38 rows in set , 1 warning ( 0.00 sec)
查看⼆进制日志相关的状态变量:
mysql> show status like '%bin%';+ ----------------------------+-------+| Variable_name | Value |+ ----------------------------+-------+| Binlog_cache_disk_use | 0 || Binlog_cache_use | 0 || Binlog_stmt_cache_disk_use | 0 || Binlog_stmt_cache_use | 0 || Com_binlog | 0 || Com_show_binlog_events | 0 || Com_show_binlogs | 0 |+ ----------------------------+-------+7 rows in set ( 0.00 sec)
特别说明:
1.默认情况下启⽤⼆进制⽇志, log_bin 系统变量为 ON ;2.禁⽤⼆进制⽇志,可以指定 --skip-log-bin 或 --disable-log-bin 选项。如果同时指定了 --log-bin 则后指定的选项优先;3.选项 --log-bin[= base_name ] ⽤于指定⼆进制⽇志⽂件的基本名称,如果不指定 --logbin 选项,默认基本名称为 binlog ,建议为⼆进制⽇志指定⼀个基本名;4.⼆进制⽇志⽂件名是由基本名+数字扩展名组成的,服务器每次创建⼀个新的⽇志⽂件时,数字扩展名都会增加,从⽽保证有序的⽂件系列,发⽣以下事件时,服务器都会在创建⼀个新的⽇志⽂件:5.服务器已启动或重新启动6.服务器刷新⽇志7.当前日志⽂件的⼤⼩达到 max_binlog_size (单个⽇志⽂件的最⼤字节数,最⼩值 4096 字节,最⼤值和默认值 1GB).
8.mysqld还会创建⼀个包含⼆进制⽇志⽂件名的⽇志索引⽂件,默认情况下,这与⼆进制⽇志⽂件具有相同的基本名称,扩展名为 .index . 可以使⽤选项 --log-bin-index[= file_name ]修改索引⽂件名;9.⼆进制日志⽂件和索引⽂件的默认位置是数据⽬录。可以使⽤ --log-bin[= file_name ] 选项指定⾃定义路径, file_name 格式 = 绝对路径+基本名。 --log-bin 对应的系统变量是log_bin_basename ;
使⽤客⼾端⼯具mysqlbinlog查看mysqlbinlog binlog.000001 > binlog.000001
通过SQL语句查看mysql> show binlog events in 'binlog.000001' from N limit S;
Redo Log 和 Undo Log
Redo Log :重做⽇志,⽤于恢复数据;Undo Log :撤消⽇志⽤于回滚操作;