最近服务器出问题,老是挂掉,linux系统上的一个socket服务器,mysql的数据库。下面是gdb的结果
the resultlen is52.........2016 7 5 15 31 48..........
the command number is : 0
a9e961c2688b3eabread database the select * from comsocket where wifi_id='1afe34f76445'and com_id='a9e961c2688b3eab'
fetch data
insert 18446744073709551615 rows
update error
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffeffff700 (LWP 5005)]
0x00007ffff766f908 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) backtrace
#0 0x00007ffff766f908 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff78ce6a9 in ?? () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#2 0x00007ffff78cf228 in my_net_read () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#3 0x00007ffff78c87fa in cli_safe_read () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#4 0x00007ffff78c9928 in ?? () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#5 0x00007ffff78ca78c in mysql_real_query () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#6 0x000000000040706c in query_socket_outside (conn_ptr=0x60f4f0, socket_id=0x7fffefffee10 "\032\376\064\367dE",
com_id=0x7fffefffee00 "\251\351a\302h\213>\253\377\201@") at nat_server_mysql.c:322
#7 0x00000000004029ce in outside_send_to_socket (connection=0x60f4f0, addr_tel=0x62b575, sockfd=7, buf=0x62b589 "m\251\351a\302h\213>\253", send_len=37)
at wifi_socket_server.c:505
#8 0x0000000000402150 in parse_task (task_node=0x62b56d) at wifi_socket_server.c:276
#9 0x0000000000407f38 in thread_function (arg=0x62c270) at nat_server_thread.c:429
#10 0x00007ffff767de9a in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#11 0x00007ffff73aa3fd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#12 0x0000000000000000 in ?? ()
查看了一下,确定是mysql_real_query()引起的段错误。但是为什么会出现呢?
百度,谷歌搜索了一下,说法大体是初始化一类的,或者写的不规范。但是我本身的代码是没问题的,各种检查错误也都有。
后来将这段代码注释掉,发现依然有错误,不过是换成了其他地方的这个函数,看来是访问数据库的问题。
然后是将类似的函数都注释掉,发现没有问题了。
可以断定,是并发上出问题了,我的程序只有一个connection,所有线程共用,当业务量特别大的时候就会导致并发的问题,但是并发问题并不会导致段错误。
然后观察了很久,发现出错的地方大多是有重连的迹象,于是想到重连会到时候Connection变化,其他正在使用的线程中途会访问越界,导致段错误。
解决办法:
1.不重连。即线程做数据库操作的时候,如果失败就直接返回。但是有副作用,如果connection确实是出问题了,所有的线程都没法使用了。
2.消除掉并发量大的操作,尽量避免同时大批量访问数据库
3.引入线程池。这是根本的解决办法。