Rumah pangkalan data tutorial mysql mysql连接hang住问题分析_MySQL

mysql连接hang住问题分析_MySQL

Jun 01, 2016 pm 01:34 PM
mysql multithreading pangkalan data

bitsCN.com

mysql连接hang住问题分析

 

【问题现象】:

 

1.       Linuxc多线程连接mysql数据库,每次都是短连接,操作完后就释放连接,有时候会出现mysql_real_connect挂住的现象

 

2.       挂住超时mysql_real_connect返回后报错如下:Lostconnection to MySQL server at 'reading initial communication packet', systemerror: 104,返错后线程号没变,会继续往下运行

 

【初步原因分析】:

 

1.       mysql_real_connect连接数据库, 没有显式调用超时时间,重连什么的,使用的默认值:

 

2.       昨天拿c   mysqlclient的源码进行了分析测试,发现以下几个配置项的默认值(如果调mysql_real_connect之前没有设置任何属性,mysql client端的机器上/etc/my.cnf也没有配置)如下:

 

connect_timeout = 0

 

read_timeout = 0

 

write_timeout = 0

 

reconnect = 0  //1表示自动重连

 

所以这些参数是需要显式设置的。

 

{net = {vio = 0x7b8f150, options = {connect_timeout = 0, read_timeout = 0, write_timeout = 0,}

 

3.       Mysqlclient中报错的代码如下(与服务端连接建立后,读解析包的时候失败了):

 

  /*

 

    Part 1: Connection established, read and parse first packet

 

  */

 

if ((pkt_length=cli_safe_read(mysql)) == packet_error)

 

  {

 

    if (mysql->net.last_errno == CR_SERVER_LOST)

 

      set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,

 

                               ER(CR_SERVER_LOST_EXTENDED),

 

                               "reading initial communication packet",

 

                               errno);

 

         fprintf(myfp,"%s after cli_safe_read packet_error /n",cur_time());

 

    goto error;

 

  }

 

线程阻塞时抓到的堆栈如下:

 

#0  0x0000003ebe0c5f3b in read () from /lib64/libc.so.6

 

#1  0x00007f240dd91430 in vio_read () from /usr/lib/libmysql.so.16.0.0

 

#2  0x00007f240dcf9b05 in my_real_read () from /usr/lib/libmysql.so.16.0.0

 

#3  0x00007f240dcf9e38 in my_net_read () from /usr/lib/libmysql.so.16.0.0

 

#4  0x00007f240dcec396 in cli_safe_read () from /usr/lib/libmysql.so.16.0.0

 

#5  0x00007f240dceea17 in mysql_real_connect () from /usr/lib/libmysql.so.16.0.0

 

4.       似乎根本原因是为什么阻塞在了read函数上,并且没有超时返回

 

size_t vio_read(Vio * vio, uchar* buf, size_t size)

 

{

 

  size_t r;

 

  DBUG_ENTER("vio_read");

 

  DBUG_PRINT("enter", ("sd: %d  buf: 0x%lx  size: %u", vio->sd, (long) buf,

 

                       (uint) size));

 

 

 

  /* Ensure nobody uses vio_read_buff and vio_read simultaneously */

 

  DBUG_ASSERT(vio->read_end == vio->read_pos);

 

#ifdef __WIN__

 

  r = recv(vio->sd, buf, size,0);

 

#else

 

  errno=0;                                               /* For linux */

 

 r = read(vio->sd, buf, size);

 

#endif /* __WIN__ */

 

#ifndef DBUG_OFF

 

  if (r == (size_t) -1)

 

  {

 

    DBUG_PRINT("vio_error", ("Got error %d during read",errno));

 

  }

 

#endif /* DBUG_OFF */

 

  DBUG_PRINT("exit", ("%ld", (long) r));

 

  DBUG_RETURN(r);

 

}

 

5. 跟了下mysqlclient中与服务端连接读写socket的代码,发现配置的mysql_options中配置的MYSQL_OPT_READ_TIMEOUT和MYSQL_OPT_WRITE_TIMEOUT正是socket连接中的读写超时时间:

 

setsockopt(vio->sd, SOL_SOCKET, which ? SO_SNDTIMEO : SO_RCVTIMEO,

 

                IF_WIN(const char*, const void*)&wait_timeout,

 

                sizeof(wait_timeout))

 

这个超时时间默认是很大的值(31536000s),如果read阻塞了线程就会挂住,直到tcp的超时时间断开连接(默认2小时)

 

6.  mysql官网上有类似的说明:

 

http://dev.mysql.com/worklog/task/?id=1907

 

http://bugs.mysql.com/bug.php?id=4143

 

7.  数据库读/写超时可以通过调用mysql_options()设置,具体参数为MYSQL_OPT_READ_TIMEOUT和MYSQL_OPT_WRITE_TIMEOUT。

 

MYSQL_OPT_READ_TIMEOUT (argument type: unsigned int *) 

The timeout in seconds for attempts to read from the server. Each attempt usesthis timeout value and there are retries if necessary, so the total effectivetimeout value is three times the option value. You can set the value so that alost connection can be detected earlier than the TCP/IP Close_Wait_Timeoutvalue of 10 minutes. Before MySQL 5.1.41, this option applies only to TCP/IPconnections and, prior to MySQL 5.1.12, only for Windows. 

 

MYSQL_OPT_WRITE_TIMEOUT (argument type: unsigned int *) 

The timeout in seconds for attempts to write to the server. Each attempt usesthis timeout value and there are net_retry_count retries if necessary, so thetotal effective timeout value is net_retry_count times the option value. BeforeMySQL 5.1.41, this option applies only to TCP/IP connections and, prior toMySQL 5.1.12, only for Windows. 

 

然而,值得注意的是此两个参数并不是对所有版本都支持:

 

Before MySQL 5.1.41, this option applies only to TCP/IPconnections and, prior to MySQL 5.1.12, only for Windows.

 

对于linux系统来说,你必须使用官方发布的5.1.12版本之后的客户端库,否则你需要自己编译线程安全的客户端库。

 

bitsCN.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk mengoptimumkan prestasi pertanyaan MySQL dalam PHP? Bagaimana untuk mengoptimumkan prestasi pertanyaan MySQL dalam PHP? Jun 03, 2024 pm 08:11 PM

Prestasi pertanyaan MySQL boleh dioptimumkan dengan membina indeks yang mengurangkan masa carian daripada kerumitan linear kepada kerumitan logaritma. Gunakan PreparedStatements untuk menghalang suntikan SQL dan meningkatkan prestasi pertanyaan. Hadkan hasil pertanyaan dan kurangkan jumlah data yang diproses oleh pelayan. Optimumkan pertanyaan penyertaan, termasuk menggunakan jenis gabungan yang sesuai, membuat indeks dan mempertimbangkan untuk menggunakan subkueri. Menganalisis pertanyaan untuk mengenal pasti kesesakan; gunakan caching untuk mengurangkan beban pangkalan data;

Bagaimana untuk membetulkan ralat mysql_native_password tidak dimuatkan pada MySQL 8.4 Bagaimana untuk membetulkan ralat mysql_native_password tidak dimuatkan pada MySQL 8.4 Dec 09, 2024 am 11:42 AM

Salah satu perubahan utama yang diperkenalkan dalam MySQL 8.4 (keluaran LTS terkini pada 2024) ialah pemalam "Kata Laluan Asli MySQL" tidak lagi didayakan secara lalai. Selanjutnya, MySQL 9.0 mengalih keluar pemalam ini sepenuhnya. Perubahan ini mempengaruhi PHP dan apl lain

Bagaimana untuk membuat jadual MySQL menggunakan PHP? Bagaimana untuk membuat jadual MySQL menggunakan PHP? Jun 04, 2024 pm 01:57 PM

Mencipta jadual MySQL menggunakan PHP memerlukan langkah berikut: Sambung ke pangkalan data. Buat pangkalan data jika ia tidak wujud. Pilih pangkalan data. Buat jadual. Laksanakan pertanyaan. Tutup sambungan.

Cabaran dan tindakan balas pengurusan memori C++ dalam persekitaran berbilang benang? Cabaran dan tindakan balas pengurusan memori C++ dalam persekitaran berbilang benang? Jun 05, 2024 pm 01:08 PM

Dalam persekitaran berbilang benang, pengurusan memori C++ menghadapi cabaran berikut: perlumbaan data, kebuntuan dan kebocoran memori. Tindakan balas termasuk: 1. Menggunakan mekanisme penyegerakan, seperti mutex dan pembolehubah atom 2. Menggunakan struktur data tanpa kunci 3. Menggunakan penunjuk pintar 4. (Pilihan) Melaksanakan pengumpulan sampah;

Tutorial terperinci tentang mewujudkan sambungan pangkalan data menggunakan MySQLi dalam PHP Tutorial terperinci tentang mewujudkan sambungan pangkalan data menggunakan MySQLi dalam PHP Jun 04, 2024 pm 01:42 PM

Cara menggunakan MySQLi untuk mewujudkan sambungan pangkalan data dalam PHP: Sertakan sambungan MySQLi (require_once) Cipta fungsi sambungan (functionconnect_to_db) Fungsi sambungan panggilan ($conn=connect_to_db()) Laksanakan pertanyaan ($result=$conn->query()) Tutup sambungan ( $conn->close())

iOS 18 menambah fungsi album 'Dipulihkan' baharu untuk mendapatkan semula foto yang hilang atau rosak iOS 18 menambah fungsi album 'Dipulihkan' baharu untuk mendapatkan semula foto yang hilang atau rosak Jul 18, 2024 am 05:48 AM

Keluaran terbaharu Apple bagi sistem iOS18, iPadOS18 dan macOS Sequoia telah menambah ciri penting pada aplikasi Photos, yang direka untuk membantu pengguna memulihkan foto dan video yang hilang atau rosak dengan mudah disebabkan pelbagai sebab. Ciri baharu ini memperkenalkan album yang dipanggil "Dipulihkan" dalam bahagian Alat pada apl Foto yang akan muncul secara automatik apabila pengguna mempunyai gambar atau video pada peranti mereka yang bukan sebahagian daripada pustaka foto mereka. Kemunculan album "Dipulihkan" menyediakan penyelesaian untuk foto dan video yang hilang akibat kerosakan pangkalan data, aplikasi kamera tidak disimpan ke pustaka foto dengan betul, atau aplikasi pihak ketiga yang menguruskan pustaka foto. Pengguna hanya memerlukan beberapa langkah mudah

Bagaimana untuk mengendalikan ralat sambungan pangkalan data dalam PHP Bagaimana untuk mengendalikan ralat sambungan pangkalan data dalam PHP Jun 05, 2024 pm 02:16 PM

Untuk mengendalikan ralat sambungan pangkalan data dalam PHP, anda boleh menggunakan langkah berikut: Gunakan mysqli_connect_errno() untuk mendapatkan kod ralat. Gunakan mysqli_connect_error() untuk mendapatkan mesej ralat. Dengan menangkap dan mengelog mesej ralat ini, isu sambungan pangkalan data boleh dikenal pasti dan diselesaikan dengan mudah, memastikan kelancaran aplikasi anda.

Bagaimanakah Go WebSocket berintegrasi dengan pangkalan data? Bagaimanakah Go WebSocket berintegrasi dengan pangkalan data? Jun 05, 2024 pm 03:18 PM

Cara mengintegrasikan GoWebSocket dengan pangkalan data: Sediakan sambungan pangkalan data: Gunakan pakej pangkalan data/sql untuk menyambung ke pangkalan data. Simpan mesej WebSocket ke pangkalan data: Gunakan pernyataan INSERT untuk memasukkan mesej ke dalam pangkalan data. Dapatkan semula mesej WebSocket daripada pangkalan data: Gunakan pernyataan SELECT untuk mendapatkan semula mesej daripada pangkalan data.

See all articles