MySQL在磁盘上创建临时表。如何停止?


27

我们正在运行一个用户当前发现缓慢的网站(Moodle)。我认为我已将问题归结为MySQL在磁盘上创建临时表。我created_tmp_disk_tables在Mysql Workbench服务器管理中观察该变量,并且该数目以大约50个表/秒的速度增加。使用几天后,created_tmp_disk_tables> 100k。此外,似乎没有释放内存。使用率一直在增加,直到系统变得几乎无法使用为止,我们必须重新启动MySQL。我几乎每天都需要重新启动它,首先要使用大约30-35%的可用内存,然后以80%的时间结束一天。

我在数据库中没有斑点,也无法控制查询,因此我无法尝试对其进行优化。我还使用了Percona Confirguration向导来生成配置文件,但是my.ini也不能解决我的问题。

问题

  1. 我应该怎么做才能阻止MySQL在磁盘上创建临时表?是否需要更改设置?我应该为此增加更多的内存吗?

  2. 如何阻止MySQL耗尽内存?

编辑

我启用了slow_queries日志,发现查询SELECT GET_LOCK()记录得很慢。快速搜索显示,我已允许PHP配置(mysqli.allow_persistent = ON)中的持久连接。我关闭了 这降低了MySQL占用内存的速度,尽管它仍在创建临时表。

我还检查了key_buffer size是否足够大。我看着变量key_writes。应该为零。如果不是,请增加key_buffer_size.I为零key_reads和零,key_writes因此我假设key_buffer_size足够大。

我将tmp_table_sizemax-heap-table-size增加到1024M,因为created_tmp_disk_tables的增加可能表示表无法容纳在内存中。这没有解决。

参考:http : //www.mysqlperformanceblog.com/2007/08/16/how-much-overhead-is-caused-by-on-disk-temporary-tables/

编辑2

如果sort_merge_passes在SHOW GLOBAL STATUS输出中看到每秒很多,则可以考虑增加该sort_buffer_size值。我sort_merge_passes一个小时有2个,所以我认为sort_buffer_size足够大了。

参考:Mysql手册 sort_buffer_size

编辑3

我已经按照@RolandoMySQLDBA的建议修改了排序和联接缓冲区。结果显示在下表中,但我认为created_tmp_tables_on_disk仍然很高。我更改了值并检查created_tmp_tables_on_disk了一天(8h)后并计算平均值后,重新启动了mysql服务器。还有其他建议吗?在我看来,有些东西不能放入某种容器中,但是我无法弄清楚它到底是什么。

+---------------------+-------------+-------------+--------------------+
| Tmp_table_size,     | Sort_buffer | Join_buffer | No of created      |
| max_heap_table_size |             |             | tmp_tables on disk |
+---------------------+-------------+-------------+--------------------+
| 125M                | 256K        | 256K        |  100k/h            |
+---------------------+-------------+-------------+--------------------+
| 125M                | 512K        | 512K        |  100k/h            |
+---------------------+-------------+-------------+--------------------+
| 125M                | 1M          | 1M          |  100k/h            |
+---------------------+-------------+-------------+--------------------+
| 125M                | 4M          | 4M          |  100k/h            |
+---------------------+-------------+-------------+--------------------+   



这是我的配置:

+-----------------------+-----------------------+
|DATABASE SERVER        |WEB SERVER             |
+-----------------------+-----------------------+
|Windows Server 2008 R2 |Windows Server 2008 R2 |
+-----------------------+-----------------------+
|MySQL 5.1.48           |IIS 7.5                |
+-----------------------+-----------------------+
|4 Core CPU             |4 Core CPU             |
+-----------------------+-----------------------+
|4GB RAM                |8GB RAM                |
+-----------------------+-----------------------+

附加信息

+--------------------+---------+
|PARAM               |VALUE    |
+--------------------+---------+
|Num of tables in Db |361      |
+--------------------+---------+
|Size of database    |2.5G     |
+--------------------+---------+
|Database engine     |InnoDB   |
+--------------------+---------+
|Read/write ratio    |3.5      |
|(Innodb_data_read/  |         |
|innodb_data_written)|         |
+--------------------+---------+
|Avg table size      |15k rows |
+--------------------+---------+
|Max table size      |744k rows|
+--------------------+---------+

这个设置是给我的,所以我对此的控制有限。Web服务器使用的CPU和RAM很少,因此排除了该机器的瓶颈。大多数MySQL设置都来自配置自动生成工具。

在过去的几天里,我已经使用PerfMon监视了系统。由此,我得出结论,不是操作系统正在交换磁盘。

My.ini

[client]
port=3306
[mysql]
default-character-set=utf8

[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.1/"
datadir="D:/DBs/Data/"
default-character-set=utf8
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=125
query_cache_size=350M
table_cache=1520
tmp_table_size=125M
table-definition-cache= 1024
max-heap-table-size= 32M
thread_cache_size=38

MyISAM Specific options
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=125M
key_buffer_size=55M
read_buffer_size=1024K
read_rnd_buffer_size=256K
sort_buffer_size=1024K
join_buffer_size=1024K


INNODB Specific options
innodb_data_home_dir="D:/DBs/"
innodb_additional_mem_pool_size=32M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=16M
innodb_buffer_pool_size=2G
innodb_log_file_size=407M
innodb_thread_concurrency=8

评论不作进一步讨论;此对话已转移至聊天
保罗·怀特说GoFundMonica

Answers:


16

看着my.ini,我有两个建议

建议#1

我会提高您的以下设置 my.ini

sort_buffer_size=4M
join_buffer_size=4M

这将使一些联接和排序保留在内存中。当然,一旦a JOIN或a 的ORDER BY需求超过4M,它将作为MyISAM表分页到磁盘。

如果您不能以身份登录root@localhost,则使用

C:\> net stop mysql
C:\> net start mysql

如果您可以root @ localhost身份登录,则不必重新启动mysql即可使用这些设置。

只需在MySQL客户端中运行此命令即可:

SET @FourMegs = 1024 * 1024 * 4;
SET GLOBAL sort_buffer_size = @FourMegs;
SET GLOBAL join_buffer_size = @FourMegs;

建议#2

由于数据的驱动器D:,你可能有磁盘I /驱动器上Ø C:

请运行以下查询:

mysql> show variables like 'tmpdir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tmpdir        | C:\Windows\TEMP |
+---------------+-----------------+
1 row in set (0.00 sec)

由于我在默认情况下在桌面上运行mysql,因此我的临时表已写入Drive C:。如果驱动器d是一个更好的磁盘驱动器相比C:,或许你可以映射临时表到驱动器D:通过设置TMPDIRmy.ini,如下所示:

tmpdir="D:/DBs/"

由于tmpdir不是动态变量,因此您将必须重新启动mysql 。

试试看 !!!

更新2013-11-29 10:09 EST

建议#3

考虑到MySQL在Windows中运行并且您无法触摸核心软件包中的查询这一事实,我有两个想法必须同时完成。

理念1:将数据库移至Linux计算机

你应该能够

  • 设置Linux机器
  • 在Linux机器上安装MySQL
  • 在Windows中为MySQL启用二进制日志记录
  • mysqldump数据库到文本SQL文件
  • 将SQL文件加载到Linux中运行的MySQL
  • 设置从MySQL / Windows复制到MySQL / Linux

理念2:重新配置Moodle以指向Linux机器

Moodle首先是为LAMP设计的。只需将配置文件更改为指向Linux计算机而不是localhost。

这是旧的Moodle 2.3文档的有关设置MySQL的链接:http : //docs.moodle.org/23/en/Installing_Moodle#Create_an_empty_database

我相信最新的文档也可以使用。

将数据库移至Linux的意义是什么?

这如何帮助临时表情况???

然后,我建议将RAM磁盘设置为临时表的目标文件夹

临时表的创建仍然会发生,但是它将被写入RAM而不是磁盘。减少磁盘I / O。

更新2013-11-29 11:24 EST

建议#4

我建议使用快速的RAID-0磁盘(32+ GB)重新访问建议2,并将其配置为驱动器T:(T表示温度)。安装了这样的磁盘后,将其添加到my.ini

[mysqld]
tmpdir="T:\"

使用以下命令需要重启MySQL

net stop mysql
net start mysql

顺便说一句,我之所以说RAID-0是为了让您在RAID-1,RAID-10上获得良好的写入性能。一个tmp表磁盘不是我要多余的东西。

如果不优化@RaymondNijland一直在评论的查询,就无法以任何方式减少临时表的创建次数。SUGGESTION #3SUGGESTION #4提供加速临时表创建和临时表I / O的唯一选择。


13

为了完整起见,我在这里回答我自己的问题

我将选择@RolandoMySQLDBA作为首选答案,因为即使实际上并不能解决我的问题,它也给了我最多的提示。

以下是我的调查结果

结论

Windows上的MySQL只会创建大量临时表,并且通过修改配置文件的内容来调整MySQL并没有帮助。

细节

该表详细说明了在执行任何查询之前我分别在my.ini中修改的参数。在每次测试之间都重新启动了MySQL。

我将原始问题中找到的my.ini用作模板,然后根据下表逐一更改了参数的值。

我使用JMeter生成了100个并发Web请求(代表了我们的用法),重复了10次十次。Test因此,每个请求总共包含1000个请求。这导致随后的数据库调用。这表明,无论我们更改了什么配置参数,MySQL都会创建许多临时表。

+----+------------+-------+---------------+------------+
|Test|Parameter   |Value  |NumOfTempTables|Db Max Conn |
+----+------------+-------+---------------+------------+
| 1  |key_buffer_ | 25M   | 30682         | 29         |
|    |size        |       |               |            | 
+----+------------+-------+---------------+------------+
| 2  |key_buffer_ | 55M   | 30793         | 29         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 3  |key_buffer_ | 100M  | 30666         | 28         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 4  |key_buffer_ | 125M  | 30593         | 24         |
|    |size        |       |               |            | 
+----+------------+-------+---------------+------------+
| 5  |query_cache_| 100M  | 30627         | 32         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 6  |query_cache_| 250M  | 30761         | 26         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 7  |query_cache_| 500M  | 30864         | 83*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 8  |query_cache_| 1G    | 30706         | 75*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 9  |tmp_table_  | 125M  | 30724         | 31         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 10 |tmp_table_  | 250M  | 30689         | 90*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 11 |tmp_table_  | 500M  | 30792         | 28         |
|    |size        |       |               |            |  
+----+------------+-------+---------------+------------+
| 12 |Sort_buffer&| 256K  | 30754         | 28         |
|    |Join_buffer |       |               |            |
+----+------------+-------+---------------+------------+
| 13 |Sort_buffer&| 512K  | 30788         | 30         |
|    |Join_buffer |       |               |            | 
+----+------------+-------+---------------+------------+
| 14 |Sort_buffer&| 1M    | 30788         | 28         |
|    |Join_buffer |       |               |            | 
+----+------------+-------+---------------+------------+
| 15 |Sort_buffer&| 4M    | 30642         | 35         |
|    |Join_buffer |       |               |            |
+----+------------+-------+---------------+------------+
| 16 |innodb-     | 1G    | 30695         | 33         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            |
+----+------------+-------+---------------+------------+
| 17 |innodb-     | 2G    | 30791         | 28         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            | 
+----+------------+-------+---------------+------------+
| 18 |innodb-     | 3G    | 30719         | 34         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            |  
+----+------------+-------+---------------+------------+

*三轮平均

下图描述了不同配置所需的数据库服务器内存和CPU数量。黑线表示最小值和最大值,蓝条表示起始值和结束值。最大内存4096M如问题所示。

内存使用情况 CPU使用率


您正在使用哪个存储引擎?MyiSAM?如果您不使用MyISAM表,则依赖key_buffer_size毫无意义。如果您使用的是innodb存储引擎,则innodb_buffer_pool_size的大小是多少。您在使用query_cache吗?
卡西2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.