我们正在运行一个用户当前发现缓慢的网站(Moodle)。我认为我已将问题归结为MySQL在磁盘上创建临时表。我created_tmp_disk_tables
在Mysql Workbench服务器管理中观察该变量,并且该数目以大约50个表/秒的速度增加。使用几天后,created_tmp_disk_tables
> 100k。此外,似乎没有释放内存。使用率一直在增加,直到系统变得几乎无法使用为止,我们必须重新启动MySQL。我几乎每天都需要重新启动它,首先要使用大约30-35%的可用内存,然后以80%的时间结束一天。
我在数据库中没有斑点,也无法控制查询,因此我无法尝试对其进行优化。我还使用了Percona Confirguration向导来生成配置文件,但是my.ini也不能解决我的问题。
问题
我应该怎么做才能阻止MySQL在磁盘上创建临时表?是否需要更改设置?我应该为此增加更多的内存吗?
如何阻止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_size
和max-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