2017-09-23 41 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周 –