2017-09-23 40 views
-2

最近,生產MySQL服務器從5.5升級到5.7.19後偶爾崩潰。以下是錯誤日誌中的堆棧跟蹤以及與有問題的查詢相關的表。我已經打開了一般日誌,每次MySQL崩潰。在最後幾個日誌條目中有一個非常大的insert on duplicate key查詢。與重複密鑰查詢更新mysql崩潰

0xf4bd75 my_print_stacktrace + 53 
0x7d0144 handle_fatal_signal + 1188 
0x34d8a0f710 _end + -693094128 
0x800b23 Field_blob::copy_blob_value(st_mem_root*) + 51 
0xe9af6e mysql_prepare_blob_values(THD*, List<Item>&, st_mem_root*) + 686 
0xe9b575 write_record(THD*, TABLE*, COPY_INFO*, COPY_INFO*) + 565 
0xe9c952 Sql_cmd_insert::mysql_insert(THD*, TABLE_LIST*) + 2146 
0xe9d16e Sql_cmd_insert::execute(THD*) + 222 
0xd10279 mysql_execute_command(THD*, bool) + 4025 
0xd1481d mysql_parse(THD*, Parser_state*) + 1005 
0xd160ac dispatch_command(THD*, COM_DATA const*, enum_server_command) + 6188 
0xd16a74 do_command(THD*) + 404 
0xdea70c handle_connection + 668 
0xf69d64 pfs_spawn_thread + 372 
0x34d8a079d1 _end + -693126191 
0x311e4e8b6d _end + 475909485 


CREATE TABLE `t` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `col2` varchar(128) DEFAULT NULL, 
    `col3` int(11) DEFAULT NULL , 
    `col4` int(11) DEFAULT NULL , 
    `col5` int(11) DEFAULT NULL , 
    `col6` int(11) DEFAULT NULL , 
    `col7` varchar(128) DEFAULT NULL , 
    `col8` varchar(1024) DEFAULT NULL , 
    `report` longtext , 
    `create_date` datetime DEFAULT NULL , 
    `start_date` datetime DEFAULT NULL , 
    `finish_date` datetime DEFAULT NULL , 
    `state` varchar(128) DEFAULT NULL , 
    `col9` text , 
    `col10` int(11) DEFAULT NULL , 
    `col11` int(11) DEFAULT NULL , 
    `col12` text , 
    `count_post` int(11) DEFAULT NULL , 
    `count_reply` int(11) DEFAULT NULL , 
    `count_link` int(11) DEFAULT NULL , 
    `remark` text , 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `col2` (`col2`), 
    KEY `col4` (`col4`), 
    KEY `col5` (`col5`), 
    KEY `col6` (`col6`), 
    KEY `col7` (`col7`), 
    KEY `create_date` (`create_date`), 
    KEY `finish_date` (`finish_date`) 
) ENGINE=InnoDB AUTO_INCREMENT=405597973 DEFAULT CHARSET=utf8' 

這是5.7.19的bug嗎?我發現了一個相關問題Crash on UPDATE ON DUPLICATE KEY但我無法重複。我該如何避免這種情況,或者我該如何解決這個問題?

威爾遜豪克指出,有關threads_%

mysql> SHOW GLOBAL STATUS LIKE 'threads_%'; 
+-------------------+-------+ 
| Variable_name  | Value | 
+-------------------+-------+ 
| Threads_cached | 1  | 
| Threads_connected | 2530 | 
| Threads_created | 5920 | 
| Threads_running | 2  | 
+-------------------+-------+ 

mysql> SHOW GLOBAL VARIABLES LIKE 'thread_%'; 
+-------------------+---------------------------+ 
| Variable_name  | Value      | 
+-------------------+---------------------------+ 
| thread_cache_size | 8       | 
| thread_handling | one-thread-per-connection | 
| thread_stack  | 262144     | 
+-------------------+---------------------------+ 
+0

看來THREAD創建/產卵是涉及到這個問題。 您能否與我們分享 的結果SHOW GLOBAL STATUS LIKE'threads_%'; 和SHOW GLOBAL VARIABLES LIKE'thread_%' –

+0

@WilsonHauck我在問題的最後附加了與'thread'相關的東西。 – zczhuohuo

+0

你的系統現在是否穩定?如果是這樣,請接受最佳答案,以擺脫「未答覆」列表。 –

回答

0

MySQL的19年7月5日更新日誌下面的東西說,這下錯誤修正:對執行INSERT語句可能會發生

不正確的行爲在存儲程序或預編譯語句上下文中,如果ON DUPLICATE KEY UPDATE子句的VALUES部分引用INSERT列列表中的BLOB值。 (Bug#24538207,Bug#25361251,Bug#25530880,Bug#25684790)

很明顯,他們沒有在5.7.19中完全修復它。 :-(

但它提出了一種解決方法,我

如果你有這樣的說法:

INSERT INTO t (id, report) VALUES (1234, 'report report report') 
ON DUPLICATE KEY UPDATE report='report report report'; 

可以重寫,以避免在UPDATE子句中使用blob值:

INSERT INTO t (id, report) VALUES (1234, 'report report report') 
ON DUPLICATE KEY UPDATE report=VALUES(report); 

此語法意味着將報告列設置爲您嘗試在第一行插入的值,它只是簡寫,所以您不必重複字面值每列兩次。

該錯誤描述似乎表示,如果在存儲過程或準備好的語句中執行此操作,則會導致崩潰。我喜歡使用VALUES()技巧,因爲它很方便,但我不能說我已經在5.7.19的存儲過程中用blob嘗試了它。

鑑於該錯誤的措辭「如果ON DUPLICATE KEY UPDATE子句的VALUES部分引用了BLOB值...」,我認爲它可能會解決問題,如果您明確地重複整個blob值而不是使用簡寫的VALUES()

否則不要在存儲過程中這樣做,如果這是問題所在。

+0

不幸的是,我的所有更新字段都由'VALUES'包裝,正如您在我原來的聲明中所建議的那樣。 :-( – zczhuohuo

+0

修改了INSERT語句之後,它是否解決了崩潰問題? –

+0

no。它仍然不時崩潰 – zczhuohuo

0

threads_connected〜2500 +表示客戶端使用完系統後沒有處理註銷/註銷斷開連接。

爲了避免線程創建/終止流失,我會的my.ini/CNF thread_cache_size = 100 #8爲8.0 建議,以支持在這種情況下產生的5000個多名線程CAP改變。

對於更詳細的分析,請發表

RAM on your server 
SHOW GLOBAL STATUS; 
SHOW GLOBAL VARIABLES; 
SHOW ENGINE INNODB STATUS; 

和你一般的日誌一分鐘。

+0

請讓我們知道當前的狀態,我提供了更詳細的分析報告,本週提供,然後休假2周 –