Mysql

MySQL 總是將簡單的臨時/記憶體表寫入磁碟(tmp_table_size 和 max_heap_table_size 都設置為 8GB)

  • January 30, 2015

我正在努力解決這個問題,只是無法弄清楚為什麼會這樣。

CREATE TABLE sitecache._test ENGINE=MEMORY SELECT * FROM website.gallery_likes WHERE 1=0;

每次執行此查詢時,Created tmp disk tables伺服器變數立即增加5。同樣的事情CREATE TEMPORARY TABLE ...也發生在創建具有結構定義的表而不是從另一個表中複製結構時。

website.gallery_likes的結構:

CREATE TABLE gallery_likes (
 photoid mediumint(8) unsigned NOT NULL,
 userid int(10) unsigned NOT NULL,
 timestamp int(10) unsigned NOT NULL,
 KEY photoid (photoid,userid)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

如您所見,沒有 TEXT 和 BLOB 欄位,這是一個相當簡單的表。如果我隨後將大量數據轉儲到該臨時/記憶體表中,則需要幾分鐘才能完成,我可以看到 mysqld 如何將大量數據寫入 C:\Windows\Temp 目錄中的臨時文件。

tmp_table_sizemax_heap_table_size都設置為 8GB(並通過 SHOW VARIABLES 確認)。

Windows Server 2012 R2 x64 上的 MySQL 5.6.17 x64,具有 64GB RAM。

配置:

[client]
no-beep
port=3306

[mysql]
default-character-set=latin1

[mysqld_safe]
open-files-limit=16384

[mysqld]
log-bin="D:/MySQL Blackhole/master_replication.log"
sync_binlog=0
binlog-do-db=...
binlog-ignore-db=...
...edited...
binlog-format=STATEMENT
expire_logs_days=1
server-id=1
ft_min_word_len=3
innodb_ft_min_token_size=3
port=3306
datadir="D:/MySQL/data/"
character-set-server=latin1
default-storage-engine=MYISAM
sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
log-output=NONE
general-log=0
general_log_file="MYSQL_SERVER.log"
slow-query-log=0
slow_query_log_file="MYSQL_SERVER-slow.log"
long_query_time=10
log-error="MYSQL_SERVER.err"
max_connections=1024
query_cache_size=0
table_open_cache=4096
tmp_table_size=8G
max_heap_table_size=8G
thread_cache_size=64
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=256M
key_buffer_size=8192M
read_buffer_size=2M
read_rnd_buffer_size=128M
sort_buffer_size=8M
innodb_flush_log_at_trx_commit=0
innodb_flush_log_at_timeout=1
innodb_log_buffer_size=32M
innodb_buffer_pool_size=32G
innodb_log_file_size=8G
innodb_thread_concurrency=0
innodb_autoextend_increment=64
innodb_buffer_pool_instances=8
innodb_concurrency_tickets=5000
innodb_old_blocks_time=0
innodb_open_files=4096
innodb_stats_on_metadata=0
innodb_file_per_table=1
innodb_checksum_algorithm=strict_crc32
innodb_adaptive_hash_index=ON
back_log=80
flush_time=0
join_buffer_size=8M
max_allowed_packet=16M
max_connect_errors=10
open_files_limit=16384
query_cache_type=0
table_definition_cache=2500
binlog_row_event_max_size=8K
sync_master_info=10000
sync_relay_log=10000
sync_relay_log_info=10000

query_cache_size=0並且default-storage-engine=MYISAM是故意的)

這發生在生產系統上。我的開發機器(Windows 8.1 x64)上有 MySQL 5.6.16 x64,執行完全相同的數據庫和幾乎相同的配置(較小的 innodb 緩衝池,tmp_table_size 為 512M,無複製),這不會發生在這裡。環境必須有所不同。

我現在已經多次閱讀文件,但我只是看不出任何關於為什麼會發生這種情況的聯繫。該表相當簡單,沒有超過 512 字節長的列。

完全披露:我已經在 StackOverflow 上發布了它,但沒有人回應。

好的,萬一有人偶然發現類似的問題,Google將他們指向這裡:

我不完全弄清楚為什麼,但有點弄清楚是什麼原因造成的,phpMyAdmin是罪魁禍首。

直接在 mysql 命令行中發出相同的命令不會導致將臨時表寫入磁碟。

現在,我的開發機器上也有 phpMyAdmin,這不是問題。但是我在 Apache 中將 PHP 作為一個模組執行,而在生產伺服器上它是 IIS,PHP 作為 FastCGI 執行。所以一定是某些配置或限制導致了這種情況,不確定。

引用自:https://dba.stackexchange.com/questions/90647