站点图标 起风网

日志信息记录表|全方位认识 mysql 系统库

日志信息记录表|全方位认识 mysql 系统库缩略图

日志信息记录表|全方位认识 mysql 系统库

2020-12-04 00:00
来源:老叶茶馆

原标题:日志信息记录表|全方位认识 mysql 系统库

在上一期《复制信息记录表|全方位认识 mysql 系统库》中,我们详细介绍了mysql系统库中的复制信息记录表,本期我们将为大家带来系列第八篇《日志记录等混杂表|全方位认识 mysql 系统库》,下面请跟随我们一起开始 mysql 系统库的系统学习之旅吧!

日志信息记录表

01

1.1. 日志信息概述

MySQL的日志系统包含:general query log、slow query log、error log(记录MySQL Server启动时、运行中、停止时的错误信息)、binary log(记录MySQL Server运行过程中的数据变更的逻辑日志)、relay log(记录从库IO线程从主库获取的主库数据变更日志)、DDL log(记录DDL语句执行时的元数据变更信息。5.7中只支持写入到文件,8.0中支持写入到innodb_ddl_log表中,注意,ddl log与online ddl的alter log不同,不要搞混了),其中,在MySQL 5.7中,只有general query log、slow query log支持写入到表中(也支持写入到文件中),其他日志类型在MySQL 5.7版本中只支持写入到文件中,所以,下文中对于日志系统表主要介绍 general query log、slow query log表。

默认情况下,除Windows上的错误日志之外,其他平台的所有日志默认情况下不启用 (DDL日志只在需要时创建,并且无用户可配置选项)。

默认情况下,所有日志均写在datadir目录下,但可以使用每种日志对应的路径参数自行更改路径。

默认情况下,所有的日志都写入到磁盘文件,但general query log和slow query log可以通过log_output=TABLE设置保存到表mysql.general_log和mysql.slow_log表中(DDL log在8.0中可以配置,可打印到错误日志中,也可以保存在表innodb_ddl_log中)。

默认情况下,binary log根据max_binlog_size参数设置的大小自动滚动、relay log根据max_relay_log_size或者max_binlog_size自动滚动(如果max_relay_log_size没设置就按照max_binlog_size大小滚动),其他的日志类型不会滚动,总是使用同一个文件,所以其他日志类型增长过大之后,需要自行做切割。

日志表实现具有以下特征:

通常,日志表的主要目的是为程序提供一个访问接口,以便查看Server内的SQL运行情况,所以,日志记录存放在表中比存放在磁盘文件中会更加方便,因为存储在表中可以远程访问这些日志记录,而不需要登录操作系统去访问磁盘文件。

日志表可以使用CREATE TABLE,ALTER TABLE和DROP TABLE语句,但前提是需要先使用对应的开关关闭掉表,不能在使用期间操作(例如:set global general_log=0,然后操作general_log表)。

general_log和slow_log表默认是CSV引擎,使用逗号分割的格式来存放日志记录,CSV数据文件可以很方便地导入其他程序进行处理,例如:excel电子表格。

日志表可以修改引擎为MyISAM,但修改之前必须先停止表的使用。合法的引擎为CSV和MyISAM,其他引擎不支持。

要禁用日志记录表以便进行相应的DDL语句操作,可以使用以下步骤(以慢查询表为例进行说明,slow_log和general_log表操作方式类似)。

SET@old_log_state = @@ global.general_log;

SETGLOBALgeneral_log = ‘OFF’;

ALTERTABLEmysql.general_log ENGINE= MyISAM;

SETGLOBALgeneral_log = @old_log_state;

可以使用TRUNCATE TABLE来清空日志记录。

可以使用RENAME TABLE来实现日志表的归档,新旧表做一个原子的名称互换操作,如下:

usemysql;

DROPTABLEIFEXISTSgeneral_log2;

CREATETABLEgeneral_log2 LIKEgeneral_log;

RENAMETABLEgeneral_log TOgeneral_log_backup,general_log2 TOgeneral_log;

注意事项

PS:MySQL的查询日志、错误日志等是使用明文记录的,所以,这些日志中有可能会记录用户的明文密码信息,可以使用rewrite插件来使用原始格式记录,详见链接:

1.2. 日志表详解
1.2.1. general_log

该表提供查询普通SQL语句的执行记录信息,用于查找客户端到底在服务端上执行了什么SQL(当然,还可以使用企业版的audit log审计插件记录,本文不做赘述,有兴趣的童鞋自行研究)。

该表中的信息在SQL开始执行时就会进行记录,而不是等待SQL执行结束才记录。

root@localhost : (none) 07:25:50> set global log_output= ‘TABLE’;

Query OK, 0rows affected ( 0. 00sec)

root@localhost : (none) 07:26:20> set global general_log= 1;

Query OK, 0rows affected ( 0. 01sec)

root@localhost : (none) 07:26:32> select * from mysql.general_log;

+—————————-+—————————+———–+———–+————–+———————————+

| event_time |user_host | thread_id |server_id | command_type |argument |

+—————————-+—————————+———–+———–+————–+———————————+

| 2018061919:26:32.891371| root[root] @ localhost [] |3| 3306102 |Query | show databases |

| 2018-06-19 19:26:42.012064 |root[root] @ localhost [] | 3 |3306102| Query |select * from mysql.general_log |

+—————————-+—————————+———–+———–+————–+———————————+

2 rows inset (0.00 sec)

root@localhost : (none) 07:26:42> select connection_id;

+—————–+

| connection_id |

+—————–+

| 3|

+—————–+

1 row inset (0.00 sec)

mysqld按照接收请求的顺序将语句写入查询日志中(这可能与它们的执行顺序不同)。

在主从复制架构中。

查询日志可以使用系统变量sql_log_off变量动态关闭当前会话或者所有会话的查询日志记录功能(与sql_log_bin系统变量的作用类似)。

查询日志开关general_log变量和查询磁盘日志文件路径general_log_file变量都可以动态修改(如果已经有查询日志处于打开状态,则使用general_log_file变量修改查询日志路径时关闭旧的查询日志,打开新的查询日志),当启用查询日志时,查询日志将保持到系统变量log_output指定的目的地。

如果启用了查询日志,则Server重新启动的时候会重新打开查询日志文件,如果查询日志存在,则直接重新打开,如果查询日志不存在,则重新创建,如果需要再Server运行时动态归档查询日志,则可以按照如下命令操作(linux或者unix平台)。

shell>mv host_name.log host_name-old.log

shell>mysqladmin flush-logs

shell>mv host_name-old.log backup-directory

#在Windows上,请直接使用重命名,而不是mv命令

也可以在Server运行时通过语句先关闭查询日志功能,然后使用外部命令来归档,然后再重新启用查询日志,这样就不需要使用flush-logs命令来刷新日志文件了,此方法适用于任何平台,命令如下:

SETGLOBALgeneral_log = ‘OFF’;

# 在禁用日志的情况下,从外部重命名日志文件;例如,从命令行。然后再次启用日志:SETGLOBALgeneral_log =‘ON’;# 此方法适用于任何平台,不需要重新启动服务器。

默认情况下,在Server中执行的语句如果带了用户密码,会被Server重写该语句之后再写入到查询日志中,如果需要记录明文密码,则需要使用–low-raw选项启动Server(使用该选项会绕过密码重写功能),通常不建议记录密码明文信息到查询日志中,因为不安全,但如果有必要,自行判断(例如:需要查询原始的语句信息来排查问题时)。

一些语法错误的SQL默认情况下也不会被记录到查询日志中,使用–low-raw选项启动Server会记录所有的原始SQL语句。

查询日志表中的时间戳信息来源于系统变量log_timestamps(包括慢查询日志文件和错误日志文件中的时间戳都来自此系统变量的值),该时间戳值在查询时可以使用CONVERT_TZ函数或通过设置会话将从这些表中的时间戳信息从本地系统时区转换为任何所需时区(修改会话级别的time_zone变量值)。

1.2.2. slow_log

该表提供查询执行时间超过long_query_time设置值的SQL,或者未使用索引的(需要开启参数log_queries_not_using_indexes=ON)或者管理语句(需要开启参数log_slow_admin_statements=ON)。

root@localhost : test 08 :46:04> set global long_query_time= 0;

Query OK, 0rows affected ( 0. 01sec)

root@localhost : test 08 :55:14> set global slow_query_log= 1;

Query OK, 0rows affected ( 0. 01sec)

# 断开会话重新连接

root@localhost : (none) 08 :56:12> use test

Database changed

root@localhost : test 08 :56:13> show tables;

+—————-+

| Tables_in_test |

+—————-+

| customer |

| product |

| shares |

| test |

| transreq |

+—————-+

5rows inset ( 0. 01sec)

root@localhost : test 08 :56:16> select * from test;

+—+—+——+——+——+——+

| a |b | c |d | e |f |

+—+—+——+——+——+——+

| 1| 1 |1| 1 |1| 1 |

| 2 |2| 2 |2| 2 |2|

| 3| 3 |3| 3 |3| 3 |

| 4 |4| 4 |4| 4 |4|

| 5| 5 |4| 4 |5| 5 |

+—+—+——+——+——+——+

5rows inset ( 0. 01sec)

root@localhost : test 08 :56:18> select * from mysql.slow_log;

+—————————-+—————————+—————–+—————–+———–+—————+——+—————-+———–+———–+———————————-+———–+

| start_time |user_host | query_time |lock_time | rows_sent |rows_examined | db |last_insert_id | insert_id |server_id | sql_text |thread_id |

+—————————-+—————————+—————–+—————–+———–+—————+——+—————-+———–+———–+———————————-+———–+

| 2018061920:56:12.254716| root[root] @ localhost [] |00:00:00. 000286 | 00:00:00.000000 |1| 0 || 0 |0| 3306102 |select @@version_comment limit 1| 4 |

| 2018-06-19 20:56:12.258551 |root[root] @ localhost [] | 00:00:00.000153 |00:00:00. 000000| 1 |0| |0| 0 |3306102| select USER |4|

| 2018061920:56:13.975382| root[root] @ localhost [] |00:00:00. 000247| 00:00:00.000000 |1| 0 || 0 |0| 3306102 |SELECT DATABASE | 4 |

| 2018-06-19 20:56:13.975627 |root[root] @ localhost [] | 00:00:00.000095 |00:00:00. 000000| 1 |0| test |0| 0 |3306102| Init DB |4|

| 2018061920:56:16.277207| root[root] @ localhost [] |00:00:00. 00049 0| 00:00:00.000264 |5| 5 |test | 0 |0| 3306102 |show tables | 4 |

| 2018-06-19 20:56:18.936831 |root[root] @ localhost [] | 00:00:00.000694 |00:00:00. 000400| 5 |5| test |0| 0 |3306102| select * from test |4|

+—————————-+—————————+—————–+—————–+———–+—————+——+—————-+———–+———–+———————————-+———–+

6 rows inset (0.00 sec)

慢查询日志包含了执行时间超过long_query_time系统变量设置的秒数的SQL语句,并且包含了需要检查行数超过min_examined_row_limit系统变量设置的值的SQL语句(默认情况下该变量为0,表示不限制检查行数)。long_query_time的最小值和默认值分别为0和10(单位秒)。该值可以指定为微秒(使用小数),但微秒单位只对记录到文件有效。对于记录到表中的慢查询语句,不支持微秒,微秒部分被忽略。

默认情况下,慢查询日志不会记录管理语句,也不会记录未使用索引的语句,但可以使用log_slow_admin_statements和log_queries_not_using_indexes系统变量更改默认行为,使MySQL Server把管理语句和未使用索引的语句也一并计入慢查询日志。

慢查询日志中语句获取初始锁的时间不计入执行时间,包含时间范围为:获取锁之后,并在语句执行完成之后,将锁释放之前。然后将慢查询语句写入慢查询日志中。所以,在慢查询日志中记录的顺序可能与MySQL Server接收到的语句顺序(执行顺序)并不相同,因为可能有的先执行的语句最后才释放完所有的锁,有的后执行的语句先释放完所有的锁。

默认情况下,慢查询日志不启用。要启用可以使用–slow_query_log =1进行设置,要指定慢查询日志文件名称,可以使用–slow_query_log_file = file_name进行设置,要指定慢查询日志输出目标,可以使用–log-output=FILE|TABLE|NONE 进行设置。

如果使用了log_slow_admin_statements=1 设置,则MySQL Server会在慢查询日志中记录如下管理语句:

如果使用了log_queries_not_using_indexes=1 设置,则MySQL Server会把任何不使用索引的查询语句记录到慢查询日志中。

MySQL Server按照以下顺序来判断语句是否需要计入慢查询:

慢查询日志记录的时间戳由log_timestamps系统变量控制。

默认情况下,复制架构中的从库不会将重放binlog产生的慢查询写入自己的慢速查询日志中,如果需要记录从库重放binlog的慢查询语句计入慢查询日志,需要启用变量log_slow_slave_statements=1。

写入慢查询日志的语句中的密码被服务器重写,不会以纯文本形式出现。如果需要记录原始语句,需要使用–log-raw选项。

混杂表

02

由于本系列不介绍企业版认证插件的audit_log_filter, audit_log_user表、防火墙插件的firewall_users, firewall_whitelis表,所以只剩下一个servers混杂表的篇幅不足够另起一期,所有我们强塞到本期里,主要是federated引擎使用的信息,如无兴趣可直接跳过本期后续内容。

2.1. servers

该表提供查询连接组合信息(远程实例的IP、端口、帐号、密码、数据库名称等信息,详见后续示例),这些连接组合信息通常用于federated引擎(当然也可以作为在数据库中保存连接组合的一种方式,维护也较为方便),该表中的信息需要使用create server方式创建。

在介绍别字段含义之前,先看看dederated引擎的两种创建方式。

# 使用create server方式创建的连接组合

Syntax:

CREATESERVERserver_name

FOREIGN DATAWRAPPER wrapper_name

OPTIONS ( option[, option] …)

option:

{ HOST character-literal

| DATABASEcharacter-literal

| USERcharacter-literal

| PASSWORDcharacter-literal

| SOCKET character-literal

| OWNER character-literal

| PORT numeric-literal }

# 直接使用CONNECTION选项指定完整的连接组合

CONNECTION=scheme://user_name[: password]@host_name[:port_num]/db_name/tbl_name

root@localhost Tue Jun 501:12:05201801:12:05[(none)]>CREATE SERVER fedlink_ip

-> FOREIGN DATA WRAPPER mysql

-> OPTIONS (USER ‘test’,PASSWORD ‘test’, HOST ‘127.0.0.1’, PORT 3306, DATABASE ‘test_table’,Owner ‘test_table1’);

Query OK, 1row affected ( 0. 00sec)

root@localhost Tue Jun 501:12:10201801:12:10[(none)]>CREATE SERVER fedlink_socket

-> FOREIGN DATA WRAPPER mysql

-> OPTIONS (USER ‘test’,PASSWORD ‘test’, SOCKET ‘/data/mysql/mysql3306/data/mysql.sock’, PORT 3306, DATABASE ‘test_table’,Owner ‘test_table2’);

Query OK, 1row affected ( 0. 00sec)

root@localhost Tue Jun 501:12:10201801:12:10[(none)]>CREATE SERVER fedlink_socket_ip

-> FOREIGN DATA WRAPPER mysql

-> OPTIONS (USER ‘test’,PASSWORD ‘test’, HOST ‘127.0.0.1’,SOCKET ‘/data/mysql/mysql3306/data/mysql.sock’, PORT 3306, DATABASE ‘test_table’,Owner ‘test_table3’);

Query OK, 1row affected ( 0. 00sec)

root@localhost Tue Jun 501:12:10201801:12:10[(none)]>select * from mysql.servers;

+——————-+———–+————+———-+———-+——+—————————————+———+————-+

| Server_name |Host | Db |Username | Password |Port | Socket |Wrapper | Owner |

+——————-+———–+————+———-+———-+——+—————————————+———+————-+

| fedlink_socket_ip |127.0. 0. 1| test_table |test | test |3306| /data/mysql/mysql3306/data/mysql.sock |mysql | test_table3 |

| fedlink_socket || test_table |test | test |3306| /data/mysql/mysql3306/data/mysql.sock |mysql | test_table2 |

| fedlink_ip |127.0. 0. 1| test_table |test | test |3306| |mysql | test_table1 |

+——————-+———–+————+———-+———-+——+—————————————+———+————-+

3rows inset ( 0. 00sec)

# 如果要删除连接组合记录,可以使用如下语句

root@localhost Tue Jun 501:10:41201801:10:41[(none)]>drop SERVER fedlink;

Query OK, 1row affected ( 0. 00sec)

root@localhost Tue Jun 501:11:30201801:11:30[(none)]>drop SERVER fedlink_socket ;

Query OK, 1row affected ( 0. 00sec)

root@localhost Tue Jun 501:11:55201801:11:55[(none)]>drop SERVER fedlink_socket_ip;

Query OK, 1row affected ( 0. 00sec)

federated引擎的两种使用方式读写远程实例数据示例。

# 创建远程实例用户

root@localhost Tue Jun 500:23:45201800:23:45[(none)]>grant all on *.* to test@ ‘%’identified by ‘test’;

Query OK, 0rows affected ( 0. 00sec)

# 创建用于存放远程实例表的库

root@localhost Tue Jun 500:24:06201800:24:06[(none)]>create database test_table;

Query OK, 1row affected ( 0. 00sec)

root@localhost Tue Jun 500:30:50201800:30:50[(none)]>use test_table

Database changed

# 创建远程实例表test_table1和test_table2

root@localhost Tue Jun 500:31:03201800:31:03[test_table]>CREATE TABLE test_table1 (

-> id INT( 20) NOT NULL AUTO_INCREMENT,

-> name VARCHAR( 32) NOT NULL DEFAULT ,

-> other INT( 20) NOT NULL DEFAULT ‘0’,

-> PRIMARY KEY (id),

-> INDEX name (name),

-> INDEX other_key (other)

-> );

Query OK, 0rows affected ( 0. 06sec)

root@localhost Tue Jun 500:31:09 201800:31:09 [test_table]>CREATE TABLE test_table2 (

-> id INT( 20) NOT NULL AUTO_INCREMENT,

-> name VARCHAR( 32) NOT NULL DEFAULT ,

-> other INT( 20) NOT NULL DEFAULT ‘0’,

-> PRIMARY KEY (id),

-> INDEX name (name),

-> INDEX other_key (other)

-> );

Query OK, 0rows affected ( 0. 00sec)

# 创建存放federated引擎表的库

root@localhost Tue Jun 500:31:16201800:31:16[test_table]>create database federated;

Query OK, 1row affected ( 0. 00sec)

root@localhost Tue Jun 500:31:22201800:31:22[test_table]>use federated

Database changed

# 使用create server方式创建一个连接字符串组合,该记录会保存到mysql.servers表中

root@localhost Tue Jun 500:31:25201800:31:25[federated]>CREATE SERVER fedlink

-> FOREIGN DATA WRAPPER mysql

-> OPTIONS (USER ‘test’,PASSWORD ‘test’, HOST ‘127.0.0.1’, PORT 3306, DATABASE ‘test_table’);

Query OK, 1row affected ( 0. 03sec)

# 查看mysql.servers表中的记录

root@localhost Tue Jun 500:31:37201800:31:37[federated]>select * from mysql.servers;

+————-+———–+————+———-+———-+——+——–+———+——-+

| Server_name |Host | Db |Username | Password |Port | Socket |Wrapper | Owner |

+————-+———–+————+———-+———-+——+——–+———+——-+

| fedlink |127.0. 0. 1| test_table |test | test |3306| |mysql | |

+————-+———–+————+———-+———-+——+——–+———+——-+

1row inset ( 0. 00sec)

# 使用create server连接字符串组合方式,创建federated引擎表

root@localhost Tue Jun 500:32:12201800:32:12[federated]>CREATE TABLE federated1 (

-> id INT( 20) NOT NULL AUTO_INCREMENT,

-> name VARCHAR( 32) NOT NULL DEFAULT ,

-> other INT( 20) NOT NULL DEFAULT ‘0’,

-> PRIMARY KEY (id),

-> INDEX name (name),

-> INDEX other_key (other)

-> )

-> ENGINE=FEDERATED

-> CONNECTION= ‘fedlink/test_table1’;

Query OK, 0rows affected ( 0. 04sec)

root@localhost Tue Jun 500:32:17201800:32:17[federated]>show create table federated1;

| Table |Create Table |

| federated1 | CREATE TABLE `federated1` (

`id` int(20) NOT NULL AUTO_INCREMENT,

`name` varchar(32) NOT NULL DEFAULT ”,

`other` int(20) NOT NULL DEFAULT ‘0’,

PRIMARY KEY (`id`),

KEY `name` (`name`),

KEY `other_key` (`other`)

) ENGINE=FEDERATED DEFAULT CHARSET=utf8 CONNECTION=’fedlink/test_table1′ |

1row inset ( 0. 00sec)

# 往federated引擎表federated1中插入数据,然后可以在federated引擎表和远程实例表中都查询到相同的数据

root@localhost Tue Jun 500:32:58201800:32:58[federated]>insert into federated1(name) values( ‘federated1’);

Query OK, 1row affected ( 0. 00sec)

root@localhost Tue Jun 500:33:42201800:33:42[federated]>select * from federated1;

+—-+————+——-+

| id |name | other |

+—-+————+——-+

| 1 |federated1 | 0 |

+—-+————+——-+

1row inset ( 0. 00sec)

root@localhost Tue Jun 500:33:49201800:33:49[federated]>select * from test_table.test_table1;

+—-+————+——-+

| id |name | other |

+—-+————+——-+

| 1 |federated1 | 0 |

+—-+————+——-+

1row inset ( 0. 00sec)

# 使用CONNECTION方式完整的连接字符串创建federated引擎表

root@localhost Tue Jun 500:32:32201800:32:32[federated]>CREATE TABLE federated2 (

-> id INT( 20) NOT NULL AUTO_INCREMENT,

-> name VARCHAR( 32) NOT NULL DEFAULT ,

-> other INT( 20) NOT NULL DEFAULT ‘0’,

-> PRIMARY KEY (id),

-> INDEX name (name),

-> INDEX other_key (other)

-> )

-> ENGINE=FEDERATED

-> CONNECTION= ‘mysql://test:test@127.0.0.1:3306/test_table/test_table2’;

Query OK, 0rows affected ( 0. 00sec)

# 往federated引擎表federated2中插入数据,然后可以在federated引擎表和远程实例表中都查询到相同的数据

root@localhost Tue Jun 500:34:08 201800:34:08 [federated]>insert into federated2(name) values( ‘federated2’);

Query OK, 1row affected ( 0. 00sec)

root@localhost Tue Jun 500:34:16201800:34:16[federated]>select * from test_table.test_table2;

+—-+————+——-+

| id |name | other |

+—-+————+——-+

| 1 |federated2 | 0 |

+—-+————+——-+

1row inset ( 0. 00sec)

root@localhost Tue Jun 500:34:22201800:34:22[federated]>select * from federated2;

+—-+————+——-+

| id |name | other |

+—-+————+——-+

| 1 |federated2 | 0 |

+—-+————+——-+

1row inset ( 0. 00sec)

root@localhost Tue Jun 500:34:28201800:34:28[federated]>select * from mysql.servers;

+————-+———–+————+———-+———-+——+——–+———+——-+

| Server_name |Host | Db |Username | Password |Port | Socket |Wrapper | Owner |

+————-+———–+————+———-+———-+——+——–+———+——-+

| fedlink |127.0. 0. 1| test_table |test | test |3306| |mysql | |

+————-+———–+————+———-+———-+——+——–+———+——-+

1row inset ( 0. 00sec)

# 使用socket方式类似,如果使用socket时,create server连接组合创建方式参照”表记录内容示例”

表字段含义。

PS:

https://dev.mysql.com/doc/refman/5.7/en/federated-create-server.html

https://dev.mysql.com/doc/refman/5.7/en/server-logs.html

“翻过这座山,你就可以看到一片海!”。坚持阅读我们的”全方位认识 mysql 系统库”系列文章分享,你就可以系统地学完它。谢谢你的阅读,我们下期不见不散!

返回搜狐,查看更多

责任编辑:

声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
阅读 ()

退出移动版