打开general_log对性能的影响

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 打开general_log对性能的影响

原文: https://fromdual.com/general_query_log_vs_mysql_performance

Sometimes, it is required to enable the general query log (which is disabled by default). If the general query log is enabled the server writes to this log information when clients connect or disconnect, and each SQL statement received from the client.

有时,需要启用general_log(默认情况下禁用)。 如果启用了general_log,服务器将在客户端连接或断开连接以及从客户端接收到的每条SQL语句时写入此日志信息。

The question is, does enabling the general query log affects the MySQL performance ?

Also, it is possible to record the output of this log into either file or table in the mysql database (mysql.general_log), what is the performance impact of each one?

问题是,启用general_log会影响MySQL性能吗?  同样,可以将这个日志的输出记录到mysql数据库(mysql.general_log)的文件或表中,每个日志的性能影响是什么?

Let's do some simple benchmark for those scenarios to measure the actual impact on the mysql performance.

让我们对这些场景进行一些简单的基准测试,以衡量对mysql性能的实际影响。

SYSTEM INFORMATION系统信息:

HW CONFIGURATIONS:

  • 2 cores, 4 threads, HT enabled.
  • Memory: 8GB RAM (1600).
  • Storage: HDD 1TB/ 5400RPM.

SOFTWARE CONFIGURATIONS 软件配置:

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

TEST INFORMATION测试信息:

  • Sysbench command: sysbench --num-threads=1 --max-requests=1000 --db-driver=mysql --test=oltp --mysql-table-engine=InnoDB --mysql-user=root run .
  • Table structure which was used by sysbench tests:
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


注:

The test had been made against 1,2,4,8,16 and 32 threads, each throughput/response time value for each thread's number for each test case is generated by the average of ten (10) times execution.

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

GENERAL LOG DISABLED禁用general_log:

To make sure that the general query log is disabled:

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

测试结果:

image.png

GENERAL LOG ENABLED启用general_log:

The general query log is a dynamic variable which means that it could be enabled or disabled ONLINE without restarting MySQL (since MySQL 5.1):

general_log是一个动态变量,这意味着它可以在不重启MySQL的情况下启用或禁用ONLINE(从MySQL 5.1开始):

mysql>SET GLOBAL general_log=ON;

We can choose the output for this log to be either in a log file (by default) or in a MySQL table (mysql.general_log).

我们可以选择将该日志的输出放在日志文件中(默认情况下),或者放在MySQL表中(MySQL.general_log)。

What are the benefits that we might get if we have the log output to be stored in a table not in a file?

如果我们将日志输出存储在表中而不是文件中,我们可能会得到什么好处?

  • We can use the normal SQL statements to access the log contents to get information about specific criteria (e.g. using WHERE condition) and this is a little harder when dealing with files.


  • 我们可以使用普通的SQL语句来访问日志内容,以获得关于特定条件的信息(例如使用WHERE条件),这在处理文件时有点困难。


  • The log contents could be accessed remotely if someone can connect to the MySQL server.


  • 如果有人可以连接到MySQL服务器,那么可以远程访问日志内容。


  • Standard format for the log entries.


  • 日志条目的标准格式。


  • If the CSV engine is used for the log table, it will be easy to import the CSV file into spreadsheets.


  • 如果CSV引擎用于日志表,那么很容易将CSV文件导入电子表格。


  • It is easy to expire the logs by simply TRUNCATE the log table.


  • 通过简单地截断日志表,很容易使日志过期。


  • Log rotation is possible by using RENAME TABLE statement.


  • 通过使用RENAME TABLE语句可以实现日志轮换。


  • Log entries are not replicated to the slave because they are not written to the binary logs.


  • 日志条目不会复制到从服务器,因为它们没有写入二进制日志。


  • The mysqldump does not include the log tables contents (general_log or slow_log) in the backup even if --all-databases backup option is used.


  • 即使使用了——all-databases备份选项,mysqldump也不包括备份中的日志表内容(general_log或slow_log)。

So, let's check the performance impact then of each log output.

因此,让我们检查每个日志输出的性能影响。

OUTPUT IS FILE输出到文件:

要检查常规日志的输出目标,应该使用以下命令:

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

测试结果:

image.png

OUTPUT IS TABLE (CSV TABLE)输出到CSV表格:


To change the output destination of the general log from file to table (CSV by default), the following command should be used:

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

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

测试结果:

image.png

OUTPUT IS TABLE (MYISAM TABLE)输出到MYISAM表:

Maybe due to the nature of the CSV storage ENGINE we faced performance issues in the previous case. Is it possible to change the table engine of the general_log table?

可能由于CSV存储引擎的特性,我们在前面的例子中遇到了性能问题。 是否有可能改变通用al_log表的表引擎?

The answer is yes, but unfortunately, we are restricted to use only MyISAM storage engine and no engines other than CSV or MyISAM are allowed. Check this link for more information.

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

To alter the log table, you must first disable the logging:

要改变日志表,你必须首先禁用日志:

mysql>altertable 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>altertable mysql.general_log engine=MYISAM;mysql>SET GLOBAL general_log=ON;

测试结果:

image.png

OUTPUT IS TABLE (MYISAM TABLE WITH SOME STRUCTURES CHANGES)输出到改变表结构的MYISAM表:


In general, to make any SQL query work faster, we might need to optimize the table structure, add indexes, re-write the query, .. etc.

通常,为了使任何SQL查询工作得更快,我们可能需要优化表结构,添加索引,重写查询,.. 等。

The following is the general log table structure:

表结构如下:

mysql> show createtable mysql.general_log\G
CREATETABLE `general_log` (  `event_time` timestampNOTNULL DEFAULT CURRENT_TIMESTAMP ONUPDATE CURRENT_TIMESTAMP,  `user_host` mediumtextNOTNULL,  `thread_id` bigint(21)unsignedNOTNULL,  `server_id` int(10)unsignedNOTNULL,  `command_type` varchar(64)NOTNULL,  `argument` mediumtextNOTNULL) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='General log'

Let's check what can we do to optimize the general_log table structure (other suggestions are welcomed):

让我们检查一下我们可以做什么来优化generalal_log表结构(欢迎其他建议):

  • Can we create partitions on that table which might boost our search?
    Although this is a normal MyISAM table but partitioning IS NOT allowed for the log tables (by the way, partitioning is not permitted also for CSV tables).


  • 我们是否可以在该表上创建分区,从而提高搜索效率?  虽然这是一个普通的MyISAM表,但是不允许对日志表进行分区(顺便说一下,对CSV表也不允许分区)。


  • Can we change the datatype of the `user_host` column from mediumtext to e.g. varchar(100)? (The max length of this column's data on my machine didn't exceed 50 characters)
    While it is - syntax wise - accepted but no logs will be stored in the table after that and the following error will be printed in the error log file:


  • 我们可以将' user_host '列的数据类型从mediumtext改为例如varchar(100)吗? (该列数据在我的机器上的最大长度不超过50个字符)  虽然它是-语法明智-接受,但没有日志将存储在表之后,以下错误将打印在错误日志文件:
2014-03-0618:44:216987[ERROR] Failed to write to mysql.general_log:2014-03-0618:44:236987[ERROR] Incorrect definition of table mysql.general_log: expected column 'user_host' at position 1 to have type mediumtext, found type varchar(100).
  • What about creating indexes on the columns we will use for most of our searches (`event_time` and `argument`)? lets try that!
  • Add index on `event_time` column:
  • 如何在我们大多数搜索(' event_time '和' argument ')中使用的列上创建索引? 让试试!
mysql>SET GLOBAL general_log=OFF;mysql>altertable mysql.general_log add index ev_tm_idx(`event_time`);mysql> show createtable mysql.general_log\G
CREATETABLE `general_log` (  `event_time` timestampNOTNULL DEFAULT CURRENT_TIMESTAMP ONUPDATE CURRENT_TIMESTAMP,  `user_host` mediumtextNOTNULL,  `thread_id` bigint(21)unsignedNOTNULL,  `server_id` int(10)unsignedNOTNULL,  `command_type` varchar(64)NOTNULL,  `argument` mediumtextNOTNULL,  KEY `ev_tm_idx` (`event_time`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='General log'mysql>SET GLOBAL general_log=ON;

测试结果是:

image.png

  • Add FULLTEXT index on `argument` column:
mysql>SET GLOBAL general_log=OFF;mysql>altertable mysql.general_log add fulltext index (`argument`);mysql> show createtable mysql.general_log\G
CREATETABLE `general_log` (  `event_time` timestampNOTNULL DEFAULT CURRENT_TIMESTAMP ONUPDATE CURRENT_TIMESTAMP,  `user_host` mediumtextNOTNULL,  `thread_id` bigint(21)unsignedNOTNULL,  `server_id` int(10)unsignedNOTNULL,  `command_type` varchar(64)NOTNULL,  `argument` mediumtextNOTNULL,  KEY `ev_tm_idx` (`event_time`),  FULLTEXT KEY `argument` (`argument`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='General log'mysql>SET GLOBAL general_log=ON;

测试结果:

image.png

To make it more clear, the following is the combination of all results in one graph followed by response time comparison:

为了更清楚地说明这一点,下面是一张图中所有结果的组合,然后是响应时间比较:

image.png

image.png

The raw results in Transactions / Sec might be useful:

THREADS 1 2 4 8 16 32
General log disabled 383.996 814.759 1421.288 1674.733 1414.985 1071.189
General log enabled (File) 281.642 521.39 1230.743 1406.127 1095.896 923.986
General log enabled (CSV Table) 231.659 447.173 787.578 507.846 426.324 439.992
General log enabled (MyISAM Table) 249.47 536.379 933.304 532.912 476.454 454.015
General log enabled (MyISAM Table + index) 238.508 430.05 875.209 465.464 465.464 395.063
General log enabled (MyISAM Table + Fulltext index) 157.436 236.156 210.968 212.273 218.617 220.701


CONCLUSION结论:


  • The best MySQL performance - among all above test cases - could be achieved by disabling the general query log, e.g. if we compared the above results for the case 4 concurrent threads (the highest value for most scenarios) we would find that:
  • MySQL最好的性能-在所有以上的测试用例中-可以通过禁用一般的查询日志来实现,例如,如果我们比较上述4个并发线程的结果(大多数情况下的最高值),我们会发现:
  • Using the general log enabled (general_log = ON) and the log destination is file (log_output = FILE) decreased the throughput by 13.4% and increased the response time by 17.5%.

使用启用的general_log(general_log = ON)和日志目标是文件(log_output = file)的情况下,吞吐量降低了13.4%,响应时间增加了17.5%。

  • Using the general log enabled and the log destination is CSV table decreased the throughput by 44.6% and increased the response time by 90%.

使用启用general_log和日志目标为CSV表的情况下,吞吐量降低了44.6%,响应时间增加了90%。

  • Using the general log enabled and the log destination is MyISAM table decreased the throughput by 34.3% and increased the response time by 59%.

使用启用了general_log且日志目的是MyISAM表的情况下,吞吐量降低了34.3%,响应时间增加了59%。

  • Using the general log enabled and the log destination is MyISAM having an index added on column `event_time` decreased the throughput by 38.4% and increased the response time by 73%.

如果启用了general_log,并且日志目标是MyISAM,并在' event_time '列上添加了索引,则吞吐量降低了38.4%,响应时间增加了73%。

  • Using the general log enabled and the log destination is MyISAM having an index added on column `event_time` and FULLTEXT index added on column `argument` decreased the throughput by 85% and increased the response time by 542%.

使用general_log启用和日志目标是MyISAM在列' event_time '上添加索引,在列' argument '上添加FULLTEXT索引,吞吐量降低了85%,响应时间增加了542%。

  • Although using table as a log output destination has many benefits - as described above - but it has more negative impact on the MySQL performance as compared to log file.

尽管使用表作为日志输出目标有很多好处(如上所述),但与日志文件相比,它对MySQL性能有更多的负面影响。

  • Increasing the number of concurrently running threads - in the case of log_output=TABLE - will increase the general_log table contention which is controlled by the table locking level for MyISAM or CSV ENGINES.

增加并发运行线程的数量——在log_output=TABLE的情况下——将增加由MyISAM或CSV引擎的表锁定级别控制的general_log表争用。

  • Like any other MySQL table - as many rows inserted in the log table as more negative performance impact.

与其他MySQL表一样,插入日志表的行越多,对性能的影响就越大。

  • Although mysqldump does not include the log tables contents in the backup but this is not the case when having full physical backup using Xtrabackup or any other physical backup based tools.

虽然mysqldump在备份中不包括日志表的内容,但当使用xtrabbackup或任何其他基于物理备份的工具进行完全物理备份时,情况就不同了。

  • Finally, it is preferred to only enable the general query log when it is really needed and it is not recommended to enable it in a production system. It could be enabled (dynamically) for a while then should be disabled again once we have got what we are searching for.

最后,最好只在真正需要时启用 general log,不建议在生产系统中启用它。 它可以启用(动态)一段时间,然后应该再次禁用,一旦我们得到了我们正在搜索的东西。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
6月前
|
Linux 应用服务中间件 PHP
性能工具之linux常见日志统计分析命令
通过本文的介绍,我相信同学们一定会发现 linux三剑客强大之处。在命令行中,它还能够接受,和执行外部的 AWK 程序文件,可以对文本信息进行非常复杂的处理,可以说“只有想不到的,没有它做不到的。
194 1
最牛逼 Java 日志框架—Log4j2,性能无敌,横扫对手
Logback 算是JAVA 里一个老牌的日志框架,从06年开始第一个版本,迭代至今也十几年了。不过logback最近一个稳定版本还停留在 2017 年,好几年都没有更新;logback的兄弟 slf4j 最近一个稳定版也是2017年,有点凉凉的意思。
|
6月前
|
存储 缓存 Java
浅析JAVA日志中的几则性能实践与原理解释
本篇文章通过几个技术点说明日志记录过程中的性能实践,计算机领域的性能往往都遵循着冰山法则,即你能看得见的、程序员能感知的只是其中的一小部分,还有大量的细节隐藏在冰山之下。
|
1月前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
244 3
|
2月前
|
缓存 监控 算法
分析慢日志文件来优化 PHP 脚本的性能
分析慢日志文件来优化 PHP 脚本的性能
|
4月前
|
SQL JSON 数据处理
5% 消耗,6 倍性能:揭秘新一代 iLogtail SPL 日志处理引擎与 Logstash 的 PK
在本文中,我们将深入探讨为何选择 iLogtail,以及它在 SPL 数据处理方面相较于 Logstash 有何独特优势。通过对比这两款工具的架构、性能以及功能,我们希望能够揭示 iLogtail 如何在日益复杂的日志处理需求中脱颖而出,帮助您做出明智的技术选择。
40425 20
|
6月前
|
消息中间件 存储 运维
更优性能与性价比,从自建 ELK 迁移到 SLS 开始
本文介绍了 SLS 基本能力,并和开源自建 ELK 做了对比,可以看到 SLS 相比开源 ELK 有较大优势。
55813 153
|
4月前
|
运维 中间件 数据库
浅析JAVA日志中的性能实践与原理解释问题之元信息打印会导致性能急剧下降问题如何解决
浅析JAVA日志中的性能实践与原理解释问题之元信息打印会导致性能急剧下降问题如何解决
|
4月前
|
开发框架 缓存 Java
浅析JAVA日志中的性能实践与原理解释问题之"Garbage Free"技术的实现方式问题如何解决
浅析JAVA日志中的性能实践与原理解释问题之"Garbage Free"技术的实现方式问题如何解决
|
4月前
|
缓存 自然语言处理 Java
浅析JAVA日志中的性能实践与原理解释问题之减少看得见的业务开销问题如何解决
浅析JAVA日志中的性能实践与原理解释问题之减少看得见的业务开销问题如何解决
下一篇
无影云桌面