gpt4 book ai didi

multithreading - MySQL 多线程应用程序和重新连接到 MySQL 到工作线程时出现段错误

转载 作者:行者123 更新时间:2023-11-29 13:56:43 26 4
gpt4 key购买 nike

我有 MySQL 的多线程应用程序客户端,并且我使用 MySQL C 客户端 (libmysqlclient_r)。我有数据库连接池,我在创建线程 worker (pthread_create)之前打开连接。

每个工作人员在开始工作之前仅从连接池中获取单个连接,并在完成工作后将其放入池中。每个工作人员都使用其独特的连接。

但是,数据库服务器非常过载,MySQL 客户端出现错误:MySQL“在查询期间丢失与 MySQL 服务器的连接”或“MySQL 服务器已消失”。我的应用程序在工作线程中重新连接:

my_bool res = mysql_ping(c->mysql);
if (res) {
mysql_close(c->mysql);
mysql_thread_end();

c->mysql = mysql_init(NULL);
mysql_thread_init();

struct conn_desc *cd = &c->db->cds[c->num];
syslog(LOG_ERR, "reconnect :[%s:%d]\t%s\tnew MySQL=%X tid=%X\n", cd->host, cd->port, c->db->default_db_name, c->mysql, pthread_self());

res = mysql_real_connect(c->mysql, cd->host, cd->login, cd->passwd, c->db->default_db_name, cd->port, NULL, 0);
if (res == NULL) {
syslog(LOG_ERR, "[restart ] reconnect Error\n");
exit(1);
}
}

有时,我的 mysql_ping() 或 mysql_real_connect() 出现段错误。为什么?我在工作线程之间使用单独的 mysql 连接。怎么了?做正确的事怎么样?

 0  0x0000000000000000 in ?? ()
1 0x00007ffff7a7fc29 in my_net_local_init () from /usr/lib64/mysql/libmysqlclient_r.so.16
2 0x00007ffff7ab0144 in my_net_init () from /usr/lib64/mysql/libmysqlclient_r.so.16
3 0x00007ffff7aab245 in **mysql_real_connect ()** from /usr/lib64/mysql/libmysqlclient_r.so.16
4 0x000000000040e72c in mysql_query_run (c=0xc36760,
q=0x7fffca1fb670 "SELECT `id`, `name` FROM `msg_dir` WHERE `owncrc` = 2831014197") at mysql.c:163
5 0x000000000040fdf2 in mysql_load_user (uid=2831014197, online=0) at mysql.c:706
6 0x0000000000406047 in get_mess_count (uid=2831014197, mid=0, online=0) at commands.c:158
7 0x000000000040618c in cmd_get_all_mess_count (key=0x7fffa80bb074 "gamc|2831014197|0|0 ", data=0x0, data_len=0, ret=0x7fffca1fbbc0, ret_len=0x7fffca1fbbdc) at commands.c:194
8 0x0000000000405f52 in execute_command (key=0x7fffa80bb074 "gamc|2831014197|0|0 ", data=0x0, data_len=0,
ret=0x7fffca1fbbc0, ret_len=0x7fffca1fbbdc) at commands.c:132
9 0x000000000040c4be in memcache_get (loop=0x7fffa40008c0, mctx=0x7fffa80bb040) at mc.c:479
10 0x000000000040d353 in memcached_client (loop=0x7fffa40008c0, io=0x7fffa80bb040, revents=1) at mc.c:785
11 0x00007ffff61e5071 in ev_invoke_pending () from /usr/lib64/libev.so.4
12 0x00007ffff61ea23a in ev_run () from /usr/lib64/libev.so.4
13 0x000000000040b5ec in ev_loop (loop=0x7fffa40008c0, flags=0) at /usr/include/libev/ev.h:810
14 0x000000000040e24c in worker_listen (arg=0x10) at mc.c:1126
15 0x00007ffff762c851 in start_thread () from /lib64/libpthread.so.0
16 0x00007ffff5d2f6dd in clone () from /lib64/libc.so.6

接下来的BT:

0  0x00000000009f3f70 in ?? ()
1 0x00007ffff7aaf32a in net_real_write () from /usr/lib64/mysql/libmysqlclient_r.so.16
2 0x00007ffff7aaf63b in net_flush () from /usr/lib64/mysql/libmysqlclient_r.so.16
3 0x00007ffff7aaf901 in net_write_command () from /usr/lib64/mysql/libmysqlclient_r.so.16
4 0x00007ffff7aac6a9 in cli_advanced_command () from /usr/lib64/mysql/libmysqlclient_r.so.16
5 0x00007ffff7a7b1fd in **mysql_ping** () from /usr/lib64/mysql/libmysqlclient_r.so.16
6 0x000000000040e8f1 in mysql_query_run (c=0x9ed930,
q=0x7fff6fffe670 "SELECT `invisible` FROM meetre.autho2 WHERE `crc` = 1032552218") at mysql.c:164
7 0x00000000004107a0 in mysql_load_user (uid=1032552218, online=1) at mysql.c:858
8 0x0000000000406278 in get_mess_count (uid=1032552218, mid=0, online=1) at commands.c:165
9 0x00000000004063bd in cmd_get_all_mess_count (key=0x7fff90383f84 "gamc|1032552218|0|1 ", data=0x0, data_len=0,
ret=0x7fff6fffebc0, ret_len=0x7fff6fffebdc) at commands.c:201
10 0x0000000000406182 in execute_command (key=0x7fff90383f84 "gamc|1032552218|0|1 ", data=0x0, data_len=0,
ret=0x7fff6fffebc0, ret_len=0x7fff6fffebdc) at commands.c:135
11 0x000000000040c718 in memcache_get (loop=0x7fff5c0008c0, mctx=0x7fff90383f50) at mc.c:459
12 0x000000000040d5cb in memcached_client (loop=0x7fff5c0008c0, io=0x7fff90383f50, revents=1) at mc.c:765
13 0x00007ffff61e5071 in ev_invoke_pending () from /usr/lib64/libev.so.4
14 0x00007ffff61ea23a in ev_run () from /usr/lib64/libev.so.4
15 0x000000000040b81c in ev_loop (loop=0x7fff5c0008c0, flags=0) at /usr/include/libev/ev.h:810
16 0x000000000040e4f4 in worker_listen (arg=0x1e) at mc.c:1106
17 0x00007ffff762c851 in start_thread () from /lib64/libpthread.so.0
18 0x00007ffff5d2f6dd in clone () from /lib64/libc.so.6

代码2:

pthread_mutex_lock(&conn_mutex);
my_bool res = mysql_ping(c->mysql);
pthread_mutex_unlock(&conn_mutex);

if (res != OK) {
mysql_close(c->mysql);
mysql_library_end();

pthread_mutex_lock(&conn_mutex);
mysql_library_init(0, NULL, NULL);
pthread_mutex_unlock(&conn_mutex);

c->mysql = mysql_init(NULL);

struct conn_desc *cd = &c->db->cds[c->num];
syslog(LOG_ERR, "reconnect :[%s:%d]\t%s\tnew MySQL=%X tid=%X %s\n", cd->host, cd->port, c->db->default_db_name, c->mysql, pthread_self(), mysql_error(c->mysql));
res = mysql_real_connect(c->mysql, cd->host, cd->login, cd->passwd, c->db->default_db_name, cd->port, NULL, 0);

if (res == NULL) {
syslog(LOG_ERR, "[restart ] reconnect Error\n");
exit(1);
}
}

最佳答案

(通过 Google 搜索找到了这个。我知道问题的原作者可能早已不在了,但为了后代做出回应,以防其他人在这里绊倒。)

您的重新连接尝试过于复杂,您可能会被它绊倒而导致这些崩溃。

在尝试重新连接期间,您:

  1. 释放您的互斥锁。
  2. 关闭连接。
  3. 允许其他线程尝试使用现已关闭的连接,这将出现段错误。毕竟,您解锁了互斥锁。
  4. 在没有任何锁定的情况下调用 mysql_library_end(),这会在整个进程范围内破坏 libmysqlclient。任何尝试运行 mysql_ping 或除 mysql_connect 之外的大多数 mysql_ 函数,无论在何处或使用哪些参数,现在都将出现段错误,并且您仍然没有锁定来阻止其他线程执行此操作。<
  5. 您重新获取锁并调用 mysql_library_init,然后由于某种原因再次释放它。
  6. 最后调用 mysql_real_connect,告诉它对共享的 c->mysql 变量进行操作,而不进行任何锁定。这可以由多个线程同时运行,因此也可能出现段错误。

正如您所看到的,您的代码有几个点是值得崩溃的。修复方法如下:

  1. 在整个操作过程中保持 conn_mutex,从 mysql_ping 之前到重新连接尝试完成之后。任何其他计划都会导致您的线程争夺谁可以尝试重新连接。
  2. 根本不要调用 mysql_library_end 或 mysql_library_init ——这些调用无缘无故地影响进程范围的状态,并且与重新建立各个连接无关。仅在程序中建立第一个连接之前、关闭最后一个连接之后以及仅在一个线程上调用这些连接。
  3. 确保您的代码在所有新线程上调用 mysql_thread_init,并在主线程以外的任何线程退出之前调用 mysql_thread_end。 (这些调用也独立于任何特定的连接,并且将它们排除在外可能会导致一些非常微妙的问题,因为事情通常仍然大部分工作。例如,如果 LOAD DATA INFILE 段错误对您来说,这可能是您的问题问题。)
  4. 确保您将代码与线程安全的 libmysqlclient_r 链接,而不是常规的 libmysqlclient,否则以上方法都无法拯救您。

希望对遇到类似问题的其他人有所帮助。

关于multithreading - MySQL 多线程应用程序和重新连接到 MySQL 到工作线程时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15740587/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com