MySQL 学习心得和知识总结(五)|MySQL的一般查询日志(general log)

news2025/1/18 14:36:31

注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下:

1、参考书籍:《PostgreSQL数据库内核分析》
2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》
3、PostgreSQL数据库仓库链接,点击前往
4、日本著名PostgreSQL数据库专家 铃木启修 网站主页,点击前往
5、参考书籍:《PostgreSQL中文手册》
6、参考书籍:《PostgreSQL指南:内幕探索》,点击前往
7、参考书籍:《事务处理 概念与技术》
8、Linux安装odbc连接mysql,点击前往


1、本文内容全部来源于开源社区 GitHub和以上博主的贡献,本文也免费开源(可能会存在问题,评论区等待大佬们的指正)
2、本文目的:开源共享 抛砖引玉 一起学习
3、本文不提供任何资源 不存在任何交易 与任何组织和机构无关
4、大家可以根据需要自行 复制粘贴以及作为其他个人用途,但是不允许转载 不允许商用 (写作不易,还请见谅 💖)


MySQL的一般查询日志 general log

  • 文章快速说明索引
  • 一般查询日志简单介绍
    • 日志简介参数配置
    • 文件生成内容分析
    • odbc连接内容生成
  • 一般查询日志性能影响
    • 系统信息
    • 禁用一般查询日志
    • 启用一般查询日志
    • 输出是文件
    • 输出为表(CSV 表)
    • 输出为表(MYISAM 表)
    • 输出为表(MYISAM 表,结构发生一些变化)
    • 结论



文章快速说明索引

学习目标:

做数据库内核开发久了就会有一种 少年得志,年少轻狂 的错觉,然鹅细细一品觉得自己其实不算特别优秀 远远没有达到自己想要的。也许光鲜的表面掩盖了空洞的内在,每每想到于此,皆有夜半临渊如履薄冰之感。为了睡上几个踏实觉,即日起 暂缓其他基于PostgreSQL数据库的兼容功能开发,近段时间 将着重于学习分享Postgres的基础知识和实践内幕。


学习内容:(详见目录)

1、MySQL的一般查询日志(general log)


学习时间:

2024-04-03 18:06:50 星期三


学习产出:

1、MySQL数据库基础知识回顾 1个
2、CSDN 技术博客 1篇
3、PostgreSQL数据库内核深入学习


注:下面我们所有的学习环境是Centos8+PostgreSQL16.1+Oracle19C+MySQL8.0

postgres=# select version();
                                                  version                                                   
------------------------------------------------------------------------------------------------------------
 PostgreSQL 17devel on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-21), 64-bit
(1 row)

postgres=#

#-----------------------------------------------------------------------------#

SQL> select * from v$version;          

BANNER        Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production	
BANNER_FULL	  Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production Version 19.17.0.0.0	
BANNER_LEGACY Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production	
CON_ID 0


#-----------------------------------------------------------------------------#

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.27    |
+-----------+
1 row in set (0.06 sec)

mysql>

一般查询日志简单介绍

日志简介参数配置

查询日志分为一般查询日志和慢查询日志。

通过查询是否超出如下变量指定时间的值来判定的,例如:

# 指定慢查询超时时长,超出此时长的属于慢查询,会记录到慢查询日志中

[root@127.0.0.1] mysql>show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.01 sec)

[root@127.0.0.1] mysql>
# 定义一般查询日志和慢查询日志的输出格式,不指定时默认为file

# log_output={TABLE|FILE|NONE}
# TABLE:表示记录日志到表中
# FILE:表示记录日志到文件中
# NONE:表示不记录日志

[root@127.0.0.1] mysql>show variables like 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output    | FILE  |
+---------------+-------+
1 row in set (0.01 sec)

[root@127.0.0.1] mysql>

在超时时间内完成的查询是一般查询,可以将其记录到一般查询日志中;而超出时间的查询是慢查询,可以将其记录到慢查询日志中。我们今天学习的重点在于一般查询日志,慢查询日志后面有机会详聊!


一般查询日志general log,记录了服务器接收到的每一个查询或是命令,无论这些查询或是命令是否正确甚至是否包含语法错误,general log 都会将其记录下来。

开启general log,MySQL服务器就会不断地记录日志,会产生一定的系统开销。因此所有都默认关闭一般查询日志。

开启general log,如下:

# 它是全局变量

[root@127.0.0.1] mysql>show variables like 'general_log';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| general_log   | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

[root@127.0.0.1] mysql>set global general_log=on;
Query OK, 0 rows affected (0.00 sec)

[root@127.0.0.1] mysql>show global variables like 'general_log';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| general_log   | ON    |
+---------------+-------+
1 row in set (0.01 sec)

[root@127.0.0.1] mysql>
# 设置日志文件路径,默认是库文件路径下 主机名加上.log

[root@127.0.0.1] mysql>show global variables like 'general_log_file';
+------------------+--------------------------------------------+
| Variable_name    | Value                                      |
+------------------+--------------------------------------------+
| general_log_file | /home/mysql/mysql-8.0.27/data/dbserver.log |
+------------------+--------------------------------------------+
1 row in set (0.00 sec)

[root@127.0.0.1] mysql>set global general_log_file='/home/mysql/general.log';
Query OK, 0 rows affected (0.00 sec)

[root@127.0.0.1] mysql>show variables like 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output    | FILE  |
+---------------+-------+
1 row in set (0.00 sec)

[root@127.0.0.1] mysql>

文件生成内容分析

general logGeneral Query Log,记录了MySQL服务器的操作。当客户端连接、断开连接、接收到客户端的SQL语句等,都会向general log中写入日志。开启general_log会损失一定的性能(性能上的损失 下面详细解释),但是在开发、测试环境下开启日志,可以帮忙我们加快排查出现的问题。如下:

# 我这里开启两个连接 间隔执行SQL 如下:

[mysql@dbserver ~]$ cat general.log 
/home/mysql/mysql-8.0.27/bin/mysqld, Version: 8.0.27 (MySQL Community Server - GPL). started with:
Tcp port: 3306  Unix socket: /tmp/mysql.sock
Time                 Id Command    Argument
2024-04-02T06:58:16.355675Z	   10 Query	show variables like 'log_output'
2024-04-02T07:00:20.967875Z	   10 Quit	
2024-04-02T07:00:41.942253Z	   11 Connect	root@localhost on  using SSL/TLS
2024-04-02T07:00:41.944182Z	   11 Query	select @@version_comment limit 1
2024-04-02T07:00:41.945409Z	   11 Query	select USER()
2024-04-02T07:01:11.162705Z	   11 Query	SELECT DATABASE()
2024-04-02T07:01:11.163151Z	   11 Init DB	mysql
2024-04-02T07:01:25.838190Z	   12 Connect	root@localhost on  using SSL/TLS
2024-04-02T07:01:25.838263Z	   12 Connect	Access denied for user 'root'@'localhost' (using password: YES)
2024-04-02T07:01:51.785487Z	   13 Connect	root@localhost on  using SSL/TLS
2024-04-02T07:01:51.785881Z	   13 Query	select @@version_comment limit 1
2024-04-02T07:01:51.786956Z	   13 Query	select USER()
2024-04-02T07:01:57.526667Z	   13 Query	SELECT DATABASE()
2024-04-02T07:01:57.526913Z	   13 Init DB	mysql
2024-04-02T07:02:29.853995Z	   11 Query	show tables
2024-04-02T07:02:52.531882Z	   11 Query	drop table t0401
2024-04-02T07:04:43.538680Z	   11 Query	create table t0402(id int, curtime TIMESTAMP(6))
2024-04-02T07:06:27.948203Z	   11 Query	insert into t0402 values(1, CURRENT_TIMESTAMP(6))
2024-04-02T07:06:37.420331Z	   13 Query	select * from t0402
2024-04-02T07:07:04.077164Z	   13 Query	drop table t0402
2024-04-02T07:08:04.054919Z	   13 Query	create table t0402(id int, curtime_int bigint(15))
2024-04-02T07:09:14.694347Z	   13 Query	insert into t0402 values(1, REPLACE(unix_timestamp(current_timestamp(6)),'.',''))
2024-04-02T07:09:24.407249Z	   11 Query	select * from t0402
2024-04-02T07:10:18.758216Z	   11 Quit	
2024-04-02T07:10:23.518195Z	   13 Quit	
[mysql@dbserver ~]$

[mysql@dbserver ~]$ mysql -h 127.0.0.1 -u root -p -A
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 8.0.27 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

[root@127.0.0.1] (none)>use mysql;
Database changed
[root@127.0.0.1] mysql>select * from t0402;
+------+------------------+
| id   | curtime_int      |
+------+------------------+
|    1 | 1712041754694258 |
+------+------------------+
1 row in set (0.00 sec)

[root@127.0.0.1] mysql>prepare p1 as select * from t0402 where id < $1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as select * from t0402 where id < $1' at line 1
[root@127.0.0.1] mysql>
[root@127.0.0.1] mysql>prepare p1 from select * from t0402 where id < $1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from t0402 where id < $1' at line 1
[root@127.0.0.1] mysql>
[root@127.0.0.1] mysql>prepare p1 from 'select * from t0402 where id < $1';
ERROR 1054 (42S22): Unknown column '$1' in 'where clause'
[root@127.0.0.1] mysql>
[root@127.0.0.1] mysql>prepare p1 from 'select * from t0402 where id < ?';
Query OK, 0 rows affected (0.00 sec)
Statement prepared

[root@127.0.0.1] mysql>SET @a = 3;
Query OK, 0 rows affected (0.00 sec)

[root@127.0.0.1] mysql>EXECUTE p1 USING @a;
+------+------------------+
| id   | curtime_int      |
+------+------------------+
|    1 | 1712041754694258 |
+------+------------------+
1 row in set (0.00 sec)

[root@127.0.0.1] mysql>prepare p2 from 'select * from t0402 where id = ?';
Query OK, 0 rows affected (0.00 sec)
Statement prepared

[root@127.0.0.1] mysql>SET @a = 1;
Query OK, 0 rows affected (0.00 sec)

[root@127.0.0.1] mysql>EXECUTE p2 USING @a;
+------+------------------+
| id   | curtime_int      |
+------+------------------+
|    1 | 1712041754694258 |
+------+------------------+
1 row in set (0.00 sec)

[root@127.0.0.1] mysql>
...
2024-04-02T07:40:34.865834Z	   15 Connect	root@localhost on  using SSL/TLS
2024-04-02T07:40:34.866145Z	   15 Query	select @@version_comment limit 1
2024-04-02T07:40:34.866744Z	   15 Query	select USER()
2024-04-02T07:40:47.075169Z	   15 Query	SELECT DATABASE()
2024-04-02T07:40:47.075481Z	   15 Init DB	mysql
2024-04-02T07:40:58.135514Z	   15 Query	select * from t0402
2024-04-02T07:42:26.177204Z	   15 Query	PREPARE p1 FROM ...
2024-04-02T07:42:40.265662Z	   15 Query	PREPARE p1 FROM ...
2024-04-02T07:42:40.265822Z	   15 Prepare	select * from t0402 where id < ?
2024-04-02T07:43:18.121465Z	   15 Query	SET @a = 3
2024-04-02T07:43:41.852319Z	   15 Query	EXECUTE p1 USING @a
2024-04-02T07:43:41.852422Z	   15 Execute	select * from t0402 where id < 3
2024-04-02T07:45:07.481268Z	   15 Query	PREPARE p2 FROM ...
2024-04-02T07:45:07.481445Z	   15 Prepare	select * from t0402 where id = ?
2024-04-02T07:45:19.637677Z	   15 Query	SET @a = 1
2024-04-02T07:45:26.939353Z	   15 Query	EXECUTE p2 USING @a
2024-04-02T07:45:26.939432Z	   15 Execute	select * from t0402 where id = 1
[mysql@dbserver ~]$

在这里插入图片描述

如上图所示:

  • 有语法错误的没有记入
  • 有错 但非 语法错误,则仍然记入
  • simple query记入一行 Query
  • 一个prepare/execute 记入两行:Query Prepare/Execute

如上各列说明,如下:

  • Time 日志记录的时间
  • Id 进程ID,可以通过show processlist命令查看
  • Command 执行的命令
  • Argument 命令参数

这里的命令类型,如下:

// sql\sql_parse.cc

const std::string Command_names::m_names[] = {
    "Sleep",
    "Quit",
    "Init DB", // 使用命令use选择库时的记录
    "Query",
    "Field List",
    "Create DB",
    "Drop DB",
    "Refresh",
    "Shutdown",
    "Statistics",
    "Processlist",
    "Connect",
    "Kill",
    "Debug",
    "Ping",
    "Time",
    "Delayed insert",
    "Change user",
    "Binlog Dump",
    "Table Dump",
    "Connect Out",
    "Register Replica",
    "Prepare",
    "Execute",
    "Long Data",
    "Close stmt",
    "Reset stmt",
    "Set option",
    "Fetch",
    "Daemon",
    "Binlog Dump GTID",
    "Reset Connection",
    "clone",
    "Group Replication Data Stream subscription",
    "Error"  // Last command number
};
// include\my_command.h

/**
  @enum  enum_server_command

  @brief A list of all MySQL protocol commands.

  These are the top level commands the server can receive
  while it listens for a new command in ::dispatch_command

  @par Warning
  Add new commands to the end of this list, otherwise old
  servers won't be able to handle them as 'unsupported'.
*/
enum enum_server_command {
  /**
    Currently refused by the server. See ::dispatch_command.
    Also used internally to mark the start of a session.
  */
  COM_SLEEP,
  COM_QUIT,       /**< See @ref page_protocol_com_quit */
  COM_INIT_DB,    /**< See @ref page_protocol_com_init_db */
  COM_QUERY,      /**< See @ref page_protocol_com_query */
  COM_FIELD_LIST, /**< Deprecated. See @ref page_protocol_com_field_list */
  COM_CREATE_DB, /**< Currently refused by the server. See ::dispatch_command */
  COM_DROP_DB,   /**< Currently refused by the server. See ::dispatch_command */
  COM_REFRESH,   /**< Deprecated. See @ref page_protocol_com_refresh */
  COM_DEPRECATED_1, /**< Deprecated, used to be COM_SHUTDOWN */
  COM_STATISTICS,   /**< See @ref page_protocol_com_statistics */
  COM_PROCESS_INFO, /**< Deprecated. See @ref page_protocol_com_process_info */
  COM_CONNECT,      /**< Currently refused by the server. */
  COM_PROCESS_KILL, /**< Deprecated. See @ref page_protocol_com_process_kill */
  COM_DEBUG,        /**< See @ref page_protocol_com_debug */
  COM_PING,         /**< See @ref page_protocol_com_ping */
  COM_TIME,         /**< Currently refused by the server. */
  COM_DELAYED_INSERT, /**< Functionality removed. */
  COM_CHANGE_USER,    /**< See @ref page_protocol_com_change_user */
  COM_BINLOG_DUMP,    /**< See @ref page_protocol_com_binlog_dump */
  COM_TABLE_DUMP,
  COM_CONNECT_OUT,
  COM_REGISTER_SLAVE,
  COM_STMT_PREPARE, /**< See @ref page_protocol_com_stmt_prepare */
  COM_STMT_EXECUTE, /**< See @ref page_protocol_com_stmt_execute */
  /** See  @ref page_protocol_com_stmt_send_long_data */
  COM_STMT_SEND_LONG_DATA,
  COM_STMT_CLOSE, /**< See @ref page_protocol_com_stmt_close */
  COM_STMT_RESET, /**< See @ref page_protocol_com_stmt_reset */
  COM_SET_OPTION, /**< See @ref page_protocol_com_set_option */
  COM_STMT_FETCH, /**< See @ref page_protocol_com_stmt_fetch */
  /**
    Currently refused by the server. See ::dispatch_command.
    Also used internally to mark the session as a "daemon",
    i.e. non-client THD. Currently the scheduler and the GTID
    code does use this state.
    These threads won't be killed by `KILL`

    @sa Event_scheduler::start, ::init_thd, ::kill_one_thread,
    ::Find_thd_with_id
  */
  COM_DAEMON,
  COM_BINLOG_DUMP_GTID,
  COM_RESET_CONNECTION, /**< See @ref page_protocol_com_reset_connection */
  COM_CLONE,
  COM_SUBSCRIBE_GROUP_REPLICATION_STREAM,
  /* don't forget to update const char *command_name[] in sql_parse.cc */

  /* Must be last */
  COM_END /**< Not a real command. Refused. */
};

如上文件中的时间值,转换为微秒的时间戳 如下:

[root@127.0.0.1] (none)>select REPLACE(unix_timestamp('2024-04-02T07:10:18.758216Z'),'.','');
+---------------------------------------------------------------+
| REPLACE(unix_timestamp('2024-04-02T07:10:18.758216Z'),'.','') |
+---------------------------------------------------------------+
| 1712013018758216                                              |
+---------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

[root@127.0.0.1] (none)>show variables like "%time_zone%";
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)

[root@127.0.0.1] (none)>select now();
+---------------------+
| now()               |
+---------------------+
| 2024-04-02 15:29:36 |
+---------------------+
1 row in set (0.00 sec)

[root@127.0.0.1] (none)>
[root@127.0.0.1] (none)>select REPLACE(unix_timestamp('2024-04-02 07:10:18.758216'),'.','');
+--------------------------------------------------------------+
| REPLACE(unix_timestamp('2024-04-02 07:10:18.758216'),'.','') |
+--------------------------------------------------------------+
| 1712013018758216                                             |
+--------------------------------------------------------------+
1 row in set (0.00 sec)

[root@127.0.0.1] (none)>

这里的prepare操作,转换如下:

2024-04-02T07:45:07.481268Z	   15 Query	PREPARE p2 FROM ...
2024-04-02T07:45:07.481445Z	   15 Prepare	select * from t0402 where id = ?
2024-04-02T07:45:19.637677Z	   15 Query	SET @a = 1
2024-04-02T07:45:26.939353Z	   15 Query	EXECUTE p2 USING @a
2024-04-02T07:45:26.939432Z	   15 Execute	select * from t0402 where id = 1

// sql\sql_rewrite.cc

/**
  Rewrite the query for the PREPARE statement.

  @param[in,out] rlb     Buffer to return the rewritten query in.

  @retval        true    the query was rewritten
  @retval        false   otherwise
*/
bool Rewriter_prepare::rewrite(String &rlb) const {
  LEX *lex = m_thd->lex;

  if (lex->prepared_stmt_code_is_varref) return false;

  rlb.append(STRING_WITH_LEN("PREPARE "));
  rlb.append(lex->prepared_stmt_name.str, lex->prepared_stmt_name.length);
  rlb.append(STRING_WITH_LEN(" FROM ..."));
  return true;
}

odbc连接内容生成

SQL> select version();
+----------+
| version()|
+----------+
| 8.0.27   |
+----------+
SQLRowCount returns 1
1 rows fetched
SQL> 
[mysql@dbserver ~]$ sudo yum install unixODBC unixODBC-devel libtool-ltdl libtool-ltdl-devel
已加载插件:ulninfo
软件包 unixODBC-2.3.1-14.0.1.el7.x86_64 已安装并且是最新版本
软件包 unixODBC-devel-2.3.1-14.0.1.el7.x86_64 已安装并且是最新版本
软件包 libtool-ltdl-2.4.2-22.el7_3.x86_64 已安装并且是最新版本
软件包 libtool-ltdl-devel-2.4.2-22.el7_3.x86_64 已安装并且是最新版本
无须任何处理
[mysql@dbserver ~]$ 

## https://downloads.mysql.com/archives/c-odbc/
[mysql@dbserver odbc_mysql8]$ wget https://cdn.mysql.com/archives/mysql-connector-odbc-8.0/mysql-connector-odbc-8.0.20-1.el7.x86_64.rpm
--2024-04-03 16:09:12--  https://cdn.mysql.com/archives/mysql-connector-odbc-8.0/mysql-connector-odbc-8.0.20-1.el7.x86_64.rpm
正在解析主机 cdn.mysql.com (cdn.mysql.com)... 2402:4f00:4002:19d::1d68, 2402:4f00:4002:190::1d68, 23.7.220.59
正在连接 cdn.mysql.com (cdn.mysql.com)|2402:4f00:4002:19d::1d68|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:4302344 (4.1M) [application/x-redhat-package-manager]
正在保存至: “mysql-connector-odbc-8.0.20-1.el7.x86_64.rpm”

100%[=========================================================================================================================================================================>] 4,302,344   3.47MB/s 用时 1.2s   

2024-04-03 16:09:16 (3.47 MB/s) - 已保存 “mysql-connector-odbc-8.0.20-1.el7.x86_64.rpm” [4302344/4302344])

[mysql@dbserver odbc_mysql8]$ ls
mysql-connector-odbc-8.0.20-1.el7.x86_64.rpm
[mysql@dbserver odbc_mysql8]$ 
[mysql@dbserver odbc_mysql8]$ sudo rpm -ivh mysql-connector-odbc-8.0.20-1.el7.x86_64.rpm 
警告:mysql-connector-odbc-8.0.20-1.el7.x86_64.rpm: 头V3 DSA/SHA1 Signature, 密钥 ID 5072e1f5: NOKEY
准备中...                          ################################# [100%]
正在升级/安装...
   1:mysql-connector-odbc-8.0.20-1.el7################################# [100%]
Success: Usage count is 1
Success: Usage count is 1
[mysql@dbserver odbc_mysql8]$

测试unixODBC安装是否成功,如下:

[mysql@dbserver ~]$ odbcinst -j
unixODBC 2.3.1
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /home/mysql/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
[mysql@dbserver ~]$ odbcinst -q -d
[PostgreSQL]
[MySQL]
[MySQL ODBC 8.0 Unicode Driver]
[MySQL ODBC 8.0 ANSI Driver]
[mysql@dbserver ~]$

配置 odbc.ini,如下:

[mysql@dbserver ~]$ odbcinst -j
unixODBC 2.3.1
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /home/mysql/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
[mysql@dbserver ~]$ odbcinst -q -d
[PostgreSQL]
[MySQL]
[MySQL ODBC 8.0 Unicode Driver]
[MySQL ODBC 8.0 ANSI Driver]
[mysql@dbserver ~]$ 
[mysql@dbserver ~]$ sudo vim /etc/odbc.ini
[mysql@dbserver ~]$ 
[mysql@dbserver ~]$ cat /etc/odbc.ini
[mysql]
Description     = Data source sampleMySQL for accessing MySQL database sampleMySQL
Driver          = MySQL ODBC 8.0 Unicode Driver
Server          = 127.0.0.1
Host            = 127.0.0.1
Database        = mysql
Port            = 3306
User            = root
Password        =123456
[mysql@dbserver ~]$ 
[mysql@dbserver ~]$ isql -v mysql
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL>

我这里使用odbc进行操作,日志内容 如下:

[mysql@dbserver ~]$ cat general.log | grep '12 '
2024-04-03T08:26:37.163240Z	   12 Connect	root@localhost on mysql using SSL/TLS
2024-04-03T08:26:37.163849Z	   12 Query	SET NAMES utf8
2024-04-03T08:26:37.164332Z	   12 Query	SET character_set_results = NULL
2024-04-03T08:26:37.164538Z	   12 Query	SET SQL_AUTO_IS_NULL = 0
2024-04-03T08:27:18.292965Z	   12 Query	set @@sql_select_limit=DEFAULT
2024-04-03T08:27:18.293298Z	   12 Query	desc t0402
2024-04-03T08:27:35.010027Z	   12 Query	select * from t0402
2024-04-03T08:28:04.549888Z	   12 Query	PREPARE odbcp1 FROM ...
2024-04-03T08:28:04.550654Z	   12 Prepare	select * from t0402 where id < ?
2024-04-03T08:28:32.707333Z	   12 Query	SET @a = 3
2024-04-03T08:28:58.102807Z	   12 Query	EXECUTE odbcp1 USING @a
2024-04-03T08:28:58.102929Z	   12 Execute	select * from t0402 where id < 3
2024-04-03T08:29:12.346332Z	   12 Quit	
[mysql@dbserver ~]$

可以看出使用odbc的日志记录(格式/内容)上,和上面直接使用client一致!


一般查询日志性能影响

  • IMPACT OF GENERAL QUERY LOG ON MYSQL PERFORMANCE,点击前往

有时,需要启用通用查询日志(默认情况下禁用)。如果启用了通用查询日志,则当客户端连接或断开连接时,以及从客户端接收到的每个 SQL 语句时,服务器都会写入此日志信息。问题是:

  • 启用通用查询日志会影响MySQL性能吗?
  • 另外,可以将该日志的输出记录到mysql数据库(mysql.general_log)中的文件或表中,每种记录对性能有何影响?

让我们针对这些场景做一些简单的基准测试来衡量对 mysql 性能的实际影响。


系统信息

硬件配置:

  • CPU: Intel® Core™ i7-3520M Processor (4M Cache, up to 3.60 GHz).
    • 2 cores, 4 threads, HT enabled.
  • Memory: 8GB RAM (1600).
  • Storage: HDD 1TB/ 5400RPM.

软件配置:

  • OS: Ubuntu 12.04
  • MySQL Server: 5.6.17
  • Sysbench: 0.4.12

测试信息:

  • Sysbench命令:
sysbench --num-threads=1 --max-requests=1000 --db-driver=mysql --test=oltp --mysql-table-engine=InnoDB --mysql-user=root run 
  • sysbench 测试使用的表结构
mysql> show create table sbtest.sbtest\G

CREATE TABLE `sbtest` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `k` int(10) unsigned NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=8574 DEFAULT CHARSET=latin1

注意:

该测试针对 1、2、4、8、16 和 32 个线程进行,每个测试用例的每个线程数的每个吞吐量/响应时间值是由十 (10) 次执行的平均值生成的。


禁用一般查询日志

要确保禁用常规查询日志:

mysql> show global variables like'general_log';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| general_log   | OFF   |
+---------------+-------+

测试结果,如下:

在这里插入图片描述

启用一般查询日志

通用查询日志是一个动态变量,这意味着它可以在线启用或禁用,而无需重新启动 MySQL(自 MySQL 5.1 起):

mysql> SET GLOBAL general_log=ON;

我们可以选择将此日志输出到日志文件(默认情况下)或 MySQL 表 (mysql.general_log) 中。如果我们将日志输出存储在表而不是文件中,我们可能会得到什么好处?

  • 我们可以使用普通的 SQL 语句访问日志内容来获取有关特定条件的信息(例如使用 WHERE 条件),这在处理文件时有点困难
  • 如果有人可以连接到 MySQL 服务器,则可以远程访问日志内容
  • 日志条目的标准格式
  • 如果日志表使用 CSV 引擎,则可以轻松将 CSV 文件导入到电子表格中
  • 只需 TRUNCATE 日志表即可轻松使日志过期
  • 通过使用 RENAME TABLE 语句可以进行日志轮转
  • 日志条目不会复制到从属服务器,因为它们不会写入二进制日志
  • 即使使用了 --all-databases 备份选项,mysqldump 也不在备份中包含日志表内容(general_log 或 Slow_log)

那么,让我们检查一下每个日志输出对性能的影响。

输出是文件

要检查通用查询日志的输出目的地,应使用以下命令:

mysql> show global variables like'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output    | FILE  |
+---------------+-------+

测试结果,如下:

在这里插入图片描述

输出为表(CSV 表)

要将通用查询日志的输出目的地从文件更改为表(默认为 CSV),应使用以下命令:

mysql> SET GLOBAL log_output='TABLE';
mysql> show global variables like'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output    | TABLE |
+---------------+-------+

测试结果,如下:

在这里插入图片描述

输出为表(MYISAM 表)

也许由于 CSV 存储引擎的性质,我们在之前的案例中遇到了性能问题。是否可以更改general_log表的表引擎?

答案是肯定的,但不幸的是,我们被限制只能使用 MyISAM 存储引擎,不允许使用 CSV 或 MyISAM 以外的引擎。检查此链接以获取更多信息。

要更改日志表,您必须首先禁用日志记录:

mysql> alter table mysql.general_log engine=MYISAM;
ERROR 1580 (HY000): You cannot 'ALTER' a log table if logging is enabled
mysql> SET GLOBAL general_log=OFF;

mysql> alter table mysql.general_log engine=MYISAM;

mysql> SET GLOBAL general_log=ON;

测试结果,如下:

在这里插入图片描述

输出为表(MYISAM 表,结构发生一些变化)

一般来说,为了使任何 SQL 查询运行得更快,我们可能需要优化表结构、添加索引、重写查询等。

通用查询日志表结构如下:

mysql> show create table mysql.general_log\G

CREATE TABLE `general_log` (
  `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `user_host` mediumtext NOT NULL,
  `thread_id` bigint(21) unsigned NOT NULL,
  `server_id` int(10) unsigned NOT NULL,
  `command_type` varchar(64) NOT NULL,
  `argument` mediumtext NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='General log'

我们来看看如何优化general_log表结构(欢迎其他建议):

  • 我们可以在该表上创建分区来提高我们的搜索吗?虽然这是一个普通的 MyISAM 表,但日志表不允许分区(顺便说一句,CSV 表也不允许分区)
  • 我们可以将user_host列的数据类型从mediumtext更改为例如 varchar(100)?(我的机器上该列数据的最大长度不超过50个字符)虽然它在语法方面已被接受,但此后表中不会存储任何日志,并且错误日志文件中将打印以下错误:
2014-03-06 18:44:21 6987 [ERROR] Failed to write to mysql.general_log:
2014-03-06 18:44:23 6987 [ERROR] Incorrect definition of table mysql.general_log: expected column 'user_host' at position 1 to have type mediumtext, found type varchar(100).
  • 在我们将用于大多数搜索的列(event_timeargument)上创建索引怎么样?

    • event_time 列上添加索引
mysql> SET GLOBAL general_log=OFF;

mysql> alter table mysql.general_log add index ev_tm_idx(`event_time`);

mysql> show create table mysql.general_log\G

CREATE TABLE `general_log` (
  `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `user_host` mediumtext NOT NULL,
  `thread_id` bigint(21) unsigned NOT NULL,
  `server_id` int(10) unsigned NOT NULL,
  `command_type` varchar(64) NOT NULL,
  `argument` mediumtext NOT NULL,
  KEY `ev_tm_idx` (`event_time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='General log'

mysql> SET GLOBAL general_log=ON;

测试结果,如下:

在这里插入图片描述

    • argument列上添加全文索引
mysql> SET GLOBAL general_log=OFF;

mysql> alter table mysql.general_log add fulltext index (`argument`);

mysql> show create table mysql.general_log\G

CREATE TABLE `general_log` (
  `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `user_host` mediumtext NOT NULL,
  `thread_id` bigint(21) unsigned NOT NULL,
  `server_id` int(10) unsigned NOT NULL,
  `command_type` varchar(64) NOT NULL,
  `argument` mediumtext NOT NULL,
  KEY `ev_tm_idx` (`event_time`),
  FULLTEXT KEY `argument` (`argument`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='General log'

mysql> SET GLOBAL general_log=ON;

测试结果,如下:

在这里插入图片描述
为了更清楚地说明,以下是将所有结果组合在一张图表中,然后进行响应时间比较:

在这里插入图片描述
在这里插入图片描述
每秒事务数的原始结果可能有用:

Threads12481632
General Query Log disabled383.996814.7591421.2881674.7331414.9851071.189
General Query Log enabled (File)281.642521.391230.7431406.1271095.896923.986
General Query Log enabled (CSV Table)231.659447.173787.578507.846426.324439.992
General Query Log enabled (MyISAM Table)249.47536.379933.304532.912476.454454.015
General Query Log enabled (MyISAM Table + index)238.508430.05875.209465.464465.464395.063
General Query Log enabled (MyISAM Table + Fulltext index)157.436236.156210.968212.273218.617220.701

结论

  • 在上述所有测试用例中,最好的MySQL性能可以通过禁用常规查询日志来实现,例如,如果我们比较上述4并发线程情况的结果(大多数情况下的最高值),我们会发现:

    • 使用启用的通用查询日志 (general_log = ON) 且日志目标为文件 (log_output = FILE) 可使吞吐量降低 13.4%,并使响应时间增加 17.5%
    • 使用启用的通用查询日志并且日志目标是 CSV 表,吞吐量降低了 44.6%,响应时间增加了 90%
    • 使用启用的通用查询日志并且日志目标是 MyISAM 表,吞吐量降低了 34.3%,响应时间增加了 59%
    • 使用启用的通用查询日志并且日志目标是 MyISAM,并在event_time列上添加索引,吞吐量降低了 38.4%,响应时间增加了 73%
    • 使用启用的通用查询日志并且日志目标是 MyISAM,在event_time列上添加索引并在argument列上添加 FULLTEXT 索引,吞吐量降低了 85%,响应时间增加了 542%
  • 虽然使用表作为日志输出目的地有很多好处(如上所述),但与日志文件相比,它对 MySQL 性能的负面影响更大

  • 增加并发运行的线程数(在 log_output=TABLE 的情况下)将增加general_log 表争用,该争用由MyISAM 或CSV ENGINES 的表锁定级别控制

  • 与任何其他 MySQL 表一样 - 日志表中插入的行数越多,负面性能影响越大

  • 虽然 mysqldump 不包括备份中的日志表内容,但使用 Xtrabackup 或任何其他基于物理备份的工具进行完整物理备份时,情况并非如此

  • 最后,最好只在真正需要时才启用通用查询日志,不建议在生产系统中启用它。它可以(动态)启用一段时间,然后在我们获得要搜索的内容后再次禁用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1566995.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机视觉——图像金字塔理解与代码示例

图像金字塔 有时为了在图像中检测一个物体&#xff08;例如人脸、汽车或其他类似的物体&#xff09;&#xff0c;需要调整图像的大小或对图像进行子采样&#xff0c;并进行进一步的分析。在这种情况下&#xff0c;会保持一组具有不同分辨率的同一图像。称这种集合为图像金字塔…

耐腐蚀耐高温实验室塑料烧杯进口高纯PFA材质反应器特氟龙烧杯

PFA烧杯在实验过程中可作为储酸容器或涉及强酸强碱类实验的反应容器&#xff0c;用于盛放样品、试剂&#xff0c;可搭配电热板加热、蒸煮、赶酸用。 外壁均有凸起刻度&#xff0c;直筒设计&#xff0c;带翻边&#xff0c;便于夹持和移动&#xff0c;边沿有嘴&#xff0c;便于倾…

【前端面试3+1】10 npm run dev 发生了什么、vue的自定义指令如何实现、js的数据类型有哪些及其不同、【最长公共前缀】

一、npm run dev发生了什么 运行npm run dev时&#xff0c;通常是在一个基于Node.js的项目中&#xff0c;用来启动开发服务器或者执行一些开发环境相关的任务。下面是一般情况下npm run dev会执行的步骤&#xff1a; 1. 查找package.json中的scripts字段&#xff1a; npm会在项…

Unity自定义icon

Unity自定义icon 1. 新建文件夹 OfficeFabricIconSet2. 新建Iconset3. 新建子文件夹Textures并添加icon图片4. 向iconset添加Quad Icons5. 最终效果 教程来源处&#xff1a; https://365xr.blog/build-your-own-button-icon-set-for-microsoft-hololens-2-apps-with-mrtk-using…

园区管理(源码+文档)

园区管理系统&#xff08;小程序、ios、安卓都可部署&#xff09; 文件包含内容程序简要说明含有功能项目截图客户端登录页我的退出登录发布详细注意事项公告列表入园记录主页我的资料电梯报修意见反馈客服入园申请注册招商列表 后台管理签到管理公告管理招商管理入园管理反馈报…

玩机进阶教程-----高通9008线刷XML脚本修改备份 檫除的操作步骤解析

在高通9008官方固件中我们可以看到刷写需要的脚本rawprogram0.xml和辅助脚本patch0.xml&#xff0c;脚本的作用在于将固件内各个分区对应写入手机内。根据分区地址段。然后判断脚本中那些分区不写入。以下步骤将分析emmc字库为例来讲解如何将默认刷入脚本修改为备份 檫除脚本。…

从汇编看函数调用

文章目录 函数调用流程栈相关寄存器及的作用简介寄存器功能指令功能 函数的括号{}正括号反括号 栈函数调用函数内部处理 参数传递传值&#xff0c;变量不可改传指针&#xff0c;变量可改C 传引用 函数调用流程 目标&#xff1a;函数调用前后栈保持不变 保存main函数的寄存器…

爬虫实战三、PyCharm搭建Scrapy开发调试环境

#一、环境准备 Python开发环境以及Scrapy框架安装&#xff0c;参考&#xff1a;爬虫实战一、Scrapy开发环境&#xff08;Win10Anaconda&#xff09;搭建 PyCharm安装和破解&#xff0c;参考&#xff1a;爬虫实战二、2019年PyCharm安装&#xff08;激活到2100年&#xff09; …

【机器学习】“强化机器学习模型:Bagging与Boosting详解“

1. 引言 在当今数据驱动的世界里&#xff0c;机器学习技术已成为解决复杂问题和提升决策制定效率的关键工具。随着数据的增长和计算能力的提升&#xff0c;传统的单一模型方法已逐渐无法满足高精度和泛化能力的双重要求。集成学习&#xff0c;作为一种结合多个学习算法以获得比…

WPS二次开发专题:如何获取应用签名SHA256值

作者持续关注WPS二次开发专题系列&#xff0c;持续为大家带来更多有价值的WPS开发技术细节&#xff0c;如果能够帮助到您&#xff0c;请帮忙来个一键三连&#xff0c;更多问题请联系我&#xff08;QQ:250325397&#xff09; 在申请WPS SDK授权版时候需要开发者提供应用包名和签…

如何处理Jenkins打包npm install没有拉取到最新依赖的问题

问题背景&#xff1a; 我们项目中有私有依赖包 frame&#xff0c;是私有服务器上通过 npm 去管理。frame包 publish 之后&#xff0c;通过Jenkins打包时&#xff0c;npm install 一直没有拉取最新的代码。 思考&#xff1a;通过在本地直接替换 node_modules 里的 frame 包&…

推理端框架简介 高通SNPE 神经网络处理引擎 阿里巴巴 MNN 腾讯 FeatherCNN 端侧推理引擎 卷积计算优化 卷积计算优化

高性能计算(High performance computing, 缩写HPC) 指通常使用很多处理器(作为单个机器的一部分) 或者某一集群中组织的几台计算机(作为单个计 算资源操作)的计算系统和环境。 有许多类型的HPC 系统,其范围从标准计算机的大型集群,到高度专用的硬件。 大多数基于集群的H…

复现带积分柱状图+多个分类注释

Original research: Tumor microenvironment evaluation promotes precise checkpoint immunotherapy of advanced gastric cancer - PMC (nih.gov) 补充文件位置&#xff1a;https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8356190/bin/jitc-2021-002467supp001.xlsx 原图 该…

【JavaSE】类和对象详解(下)

前言 面向对象程序的三大特性&#xff1a;封装、继承、多态~ 书接上回 类和对象&#xff08;上&#xff09;~ 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 前言 封装 private public 快速生成可访问封装的方法 包…

29-控制流(下):iam-apiserver服务核心功能实现讲解

我们再来看下 iam-apiserver 中的核心功能实现。 这些关键代码设计分为 3 类&#xff0c;分别是应用框架相关的特性、编程规范相关的特性和其他特性。 应用框架相关的特性 应用框架相关的特性包括三个&#xff0c;分别是优雅关停、健康检查和插件化加载中间件。 优雅关停 …

尚硅谷2024最新Git企业实战教程 | Git与GitLab的企业实战

这篇博客是尚硅谷2024最新Git企业实战教程&#xff0c;全方位学习git与gitlab的完整笔记。 这不仅仅是一套Git的入门教程&#xff0c;更是全方位的极狐GitLab企业任务流开发实战&#xff01;作为一应俱全的一站式DevOps平台&#xff0c;极狐GitLab的高阶功能全面覆盖&#xff0…

Python实现BOA蝴蝶优化算法优化卷积神经网络分类模型(CNN分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蝴蝶优化算法(butterfly optimization algorithm, BOA)是Arora 等人于2019年提出的一种元启发式智能算…

云存储中常用的相同子策略的高效、安全的基于属性的访问控制的论文阅读

参考文献为2022年发表的Efficient and Secure Attribute-Based Access Control With Identical Sub-Policies Frequently Used in Cloud Storage 动机 ABE是实现在云存储中一种很好的访问控制手段&#xff0c;但是其本身的计算开销导致在实际场景中应用收到限制。本论文研究了…

Wireshark TS | HTTP 传输文件慢问题

问题背景 之前有几篇文章写过关于应用传输慢的问题&#xff0c;延用之前的老套话&#xff0c;应用传输慢是一种比较常见的问题&#xff0c;慢在哪&#xff0c;为什么慢&#xff0c;有时候光从网络数据包分析方面很难回答的一清二楚&#xff0c;毕竟应用的定义范围实在太广&…

蓝桥杯嵌入式学习笔记(9):RTC程序设计

目录 前言 1. RTC介绍 2. 使用CubeMx进行源工程配置 3. 代码编程 3.1 准备工作 3.2 进行bsp_rtc.h编写 3.3 进行bsp_rtc.c编写 3.4 main.c编写 3.4.1 头文件引用 3.4.2 变量声明 3.4.3 子函数声明 3.4.4 函数实现 3.4.5 main函数编写 4. 代码实验 5. 总结 前言 因本人备赛蓝…