Description:
On hevy loaded host when query lasts too long sometimes result of mysql_query() called from signal handler returns result of previous query. For example: program executes query "a" that lasts 2-3 secs. In time, when it executes happend SIGALRM, in it's handler executes another query "b". But it returns result of query "a".
Call stack looks like this:
#2 0x80xe9xx in get_something_base (id=2261, value=0xbfffdc44) at all_functions.c:245
#3 0x80xd5xx in My_Signal (sig=14) at all_process.c:3152
#4 0x400x84xx in __restore () at ../sysdeps/unix/sysv/linux/i386/sigaction.c:127
#5 0x400x13xx in my_real_read () from /usr/lib/mysql/libmysqlclient.so.12
#6 0x400x15xx in my_net_read () from /usr/lib/mysql/libmysqlclient.so.12
#7 0x400xdaxx in net_safe_read () from /usr/lib/mysql/libmysqlclient.so.12
#8 0x400x03xx in mysql_read_query_result () from /usr/lib/mysql/libmysqlclient.so.12
#9 0x400x13xx in mysql_real_query () from /usr/lib/mysql/libmysqlclient.so.12
#10 0x400x13xx in mysql_query () from /usr/lib/mysql/libmysqlclient.so.12
so get_something_base() returns not it actually requests. It is very strange, that no out_of_sync error happend, and net->reading_or_writing == 0, and server status "ready".
(gdb) print mysql
$1 = {net = {vio = 0x80xxa90, buff = 0x80xxae8 "Ч", buff_end = 0x80xxae8 "", write_pos = 0x80xxae8 "Ч",
read_pos = 0x80xxae8 "Ч", fd = 3, max_packet = 8192, max_packet_size = 1073741824, last_errno = 0, pkt_nr = 6,
compress_pkt_nr = 6, write_timeout = 31536000, read_timeout = 31536000, retry_count = 1, fcntl = 0,
last_error = '\000' <repeats 199 times>, error = 0 '\000', return_errno = 0 '\000', compress = 0 '\000',
remain_in_buf = 0, length = 0, buf_length = 0, where_b = 0, return_status = 0x0, reading_or_writing = 0 '\000',
save_char = 0 '\000', no_send_ok = 0 '\000', query_cache_query = 0x0}, connector_fd = 0x0,
host = 0x80xxb60 "192.168.1.2", user = 0x80xxbf8 "user", passwd = 0x80xxba0 "pass", unix_socket = 0x0,
server_version = 0x8077b78 "4.0.20-log", host_info = 0x80xxb40 "192.168.1.2 via TCP/IP", info = 0x0,
db = 0x80xxbb8 "mybase", charset = 0x400xxa0c, fields = 0x0, field_alloc = {free = 0x80xx0a8, used = 0x0,
pre_alloc = 0x0, min_malloc = 32, block_size = 8164, block_num = 5, first_block_usage = 0, error_handler = 0},
affected_rows = 1, insert_id = 0, extra_info = 0, thread_id = 7129395, packet_length = 0, port = 3306,
client_flag = 8205, server_capabilities = 8236, protocol_version = 10, field_count = 1, server_status = 2,
server_language = 7, options = {connect_timeout = 0, client_flag = 0, port = 0, host = 0x0, init_command = 0x0,
user = 0x0, password = 0x0, unix_socket = 0x0, db = 0x0, my_cnf_file = 0x0, my_cnf_group = 0x0, charset_dir = 0x0,
charset_name = 0x0, ssl_key = 0x0, ssl_cert = 0x0, ssl_ca = 0x0, ssl_capath = 0x0, ssl_cipher = 0x0,
max_allowed_packet = 0, use_ssl = 0 '\000', compress = 0 '\000', named_pipe = 0 '\000', rpl_probe = 0 '\000',
rpl_parse = 0 '\000', no_master_reads = 0 '\000'}, status = MYSQL_STATUS_READY, free_me = 0 '\000',
reconnect = 1 '\001', scramble_buff = "fK%t;h|U", rpl_pivot = 1 '\001', master = 0x80xx1e0, next_slave = 0x80xx1e0,
last_used_slave = 0x0, last_used_con = 0x80xx1e0}
How to repeat:
execute long query, set SIGALRM handler, call ararm(1); mysql_query("long query"); and than call mysql_query() from SIGALRM handler. Check result. On my host, whitch is on hevy load it repeats 10-15 times in a day.