Mysql 数据库连接问题诊断分析笔记整理

99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,战胜焦虑,战胜那些心里空荡荡的时刻,而不是选择逃避。不要站在原地想象困难,行动永远是改变现状的最佳方式

写在前面


99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,战胜焦虑,战胜那些心里空荡荡的时刻,而不是选择逃避。不要站在原地想象困难,行动永远是改变现状的最佳方式

持续分享技术干货,感兴趣小伙伴可以关注下 ^_^


数据库连接问题诊断分析

数据连接认证流程

客户端执行命令或 SQL 前,需要先创建一个到数据库服务端的连接,并完成用户认证

MySQL 服务端使用插件的方式认证客户端的用户身份。不同的插件验证用户密码时,细节上会有所不同。MySQL 中,认证插件用户相关,不同用户可以使用不同的插件进行密码验证

创建用户时,如果不显式指定,会使用参数 default_authentication_plugin 指定的插件。从 MySQL 8.0 开始,使用 caching_sha2_password 作为默认的认证插件,而 5.7 使用的默认插件是 mysql_native_password

1
2
3
4
5
6
mysql> show variables like 'default_authentication_plugin';
+-------------------------------+-----------------------+
| Variable_name | Value |
+-------------------------------+-----------------------+
| default_authentication_plugin | caching_sha2_password |
+-------------------------------+-----------------------+

也可以在创建用户的时候指定认证插件

1
2
3
4
5
mysql> create user 'user_01'@'%' identified by 'somepass';
Query OK, 0 rows affected (0.27 sec)

mysql> create user 'user_02'@'%' identified with 'mysql_native_password' by 'somepass';
Query OK, 0 rows affected (0.56 sec)

或者通过 alter user 命令修改用户的认证插件

1
2
3
4
5
mysql> create user 'user_03'@'%' identified by 'somepass';
Query OK, 0 rows affected (0.26 sec)

mysql> alter user 'user_03'@'%' identified with 'sha256_password' by 'somepass';
Query OK, 0 rows affected (0.06 sec)

mysql.user表可以查看每个用户使用了哪个认证插件

1
2
3
4
5
6
7
8
9
mysql> select user,host,plugin,substring(authentication_string, 1, 18) as passwd 
from mysql.user where user like 'user%';
+---------+------+-----------------------+--------------------+
| user | host | plugin | passwd |
+---------+------+-----------------------+--------------------+
| user_01 | % | caching_sha2_password | $A$005$M,PHGCm7 |
| user_02 | % | mysql_native_password | *13883BDDBE566ECEC |
| user_03 | % | sha256_password | $5$N3kzW9A@+;+P'g |
+---------+------+-----------------------+--------------------+

caching_sha2_password 完整登录流程我们以 MySQL 8.0 默认的插件 caching_sha2_password 为例,分析连接建立的过程。

在这里插入图片描述

  1. 客户端首先要和服务端建立一个 TCP 连接。TCP 连接建立成功后,才能进行后续的步骤。
  2. 服务端发送握手协议包(ServerHandshake),握手协议包里面包含了服务器版本、使用的协议版本、服务端支持的特性(如是否支持加密连接)、服务端使用的认证插件(caching_sha2_password)、一串随机数据
  3. 客户端读取和解析服务端的协议包,发送握手协议回包回包里面有用户名、通过一定规则计算得到的密码哈希值、客户端支持的特性、客户端使用的认证插件、客户端版本等信息。不同版本的客户端可能会使用不同的默认认证插件。如 MySQL 5.7 版本的客户端默认使用 mysql_native_password 插件,MySQL 8.0 默认使用 caching_sha2_password 插件。客户端和服务端使用的默认插件可以不一样。
  4. 服务端在接收到客户端发送的握手协议回包之前,并不知道客户端使用的用户名,因此也不知道用户使用的认证插件。接收到客户端的回包后,服务端从里面解析出用户名,到用户列表中获取到用户信息,得到用户的认证插件。如果用户使用的认证插件和服务器的默认插件不一样,或者客户端和服务端使用的认证插件不一样,服务端就需要告诉客户端切换认证方式。
  5. 如果客户端和服务端的认证插件不一致,客户端需要根据服务端的要求,重新计算密码哈希后再发送到服务端。服务端接收到客户端新发送过来的认证包之后,就可以验证用户密码是否匹配了。对于 caching_sha2_password 插件,这里分为两种情况。
  • 用户首次登录时,服务端没有缓存用户的密码信息,此时需要进行完整的登录流程,就是上图中的 6、7、8、9 这几个步骤。
  • 用户登录成功后,会在服务端缓存哈希后的密码信息。下一次用户登录时,就可以根据缓存的密码哈希来验证,不需要进行完整的登录流程。缓存的密码哈希会在执行 ALTER USER、Flush Privileges 或重启数据库后失效。
  1. 使用 caching_sha2_password 时,如果服务端还没有缓存用户的密码哈希,会通知客户端发送明文的密码。
  2. 如果客户端和服务端建立了加密连接,则可以直接发送明文密码。但如果客户端和服务端之间的连接没有加密,直接发送明文密码是不安全的,此时客户端可以向服务端请求 RSA 公钥,用于加密明文的密码
  3. 服务端将 RSA 公钥发送给客户端。
  4. 客户端使用接收到的 RSA 公钥加密明文密码,发送到服务端。
  5. 服务端得到原始密码后,根据一定的规则计算哈希值,然后再跟存储在用户表中的 authentication_string 进行对比。用户认证成功后,服务端将密码哈希缓存起来。用户再次登录时,就可以基于缓存的密码哈希来验证用户登录信息。
  6. 如果服务端、客户端以及用户的认证插件都一样,并且用户信息已经缓存在服务端,那么上述 4~9 之间的步骤都会跳过,只需执行步骤 1、2、3、10

加密连接

MySQL 支持使用 TLS 协议建立加密连接。使用 MySQL 客户端连接数据库时,默认就会开启连接加密。

使用 MySQL 客户端登录服务器后,执行\s,查看 SSL 这一行的输出,如果显示 Cipher in use …,则说明当前连接启用了加密。

1
2
3
4
5
6
7
8
9
10
11
12
# mysql -uuser_01 -h172.16.121.234 -P3306 -psomepass

mysql> \s
--------------
mysql Ver 8.0.32 for Linux on x86_64 (MySQL Community Server - GPL)

Connection id: 121
Current database:
Current user: user_01@172-16-121-234
SSL: Cipher in use is ECDHE-RSA-AES128-GCM-SHA256
...
--------------

可以使用SHOW STATUS命令结合 Ssl_cipher 状态变量,如果 Ssl_cipher 的值不为空,那么当前的连接是加密的。如果值为空,则表示连接未使用SSL/TLS加密。这种方法不需要具有 PROCESS 权限,适用于 MySQL 5.7 及更高版本。

1
SHOW STATUS LIKE 'Ssl_cipher';

也可以在连接数据库时指定参数,不开启连接加密,此时“SSL”这一行显示“Not in use”

1
2
3
4
5
6
7
8
9
10
11
12
# mysql --ssl-mode=disabled -uuser_01 -h172.16.121.234 -P3306 -psomepass

mysql> \s
--------------
mysql Ver 8.0.32 for Linux on x86_64 (MySQL Community Server - GPL)

Connection id: 123
Current database:
Current user: user_01@172-16-121-234
SSL: Not in use
...
--------------

强制要求某些用户必须使用加密连接,这可以在创建用户时指定,或者通过 ALTER USER 命令修改。下面创建的几个用户都需要开启连接加密

1
2
3
mysql> create user 'user_05'@'%' identified by 'somepass' require ssl;
mysql> create user 'user_06'@'%' identified by 'somepass' require subject '/CN=MySQL_Server_8.0.32_Auto_Generated_Client_Certificate';
mysql> create user 'user_07'@'%' identified by 'somepass' require issuer '/helloworld';

必须开启加密连接,否则无法登录数据库

1
2
# mysql -uuser_05 -h127.0.0.1 -psomepass --ssl-mode=disabled
ERROR 1045 (28000): Access denied for user 'user_05'@'localhost' (using password: YES)

其中 user_06user_07 在登录时还必须提供客户端的证书,user_06 对证书 subject 有要求,user_07 对证书 issuer 有要求,如果提供的证书不满足要求,也无法登录数据库。

1
2
3
4
5
6
7
8
9
# mysql -uuser_06 -h127.0.0.1 -psomepass --ssl-key=server-key.pem --ssl-cert=server-cert.pem -e 'select 1';
ERROR 1045 (28000): Access denied for user 'user_06'@'localhost' (using password: YES)

# mysql -uuser_06 -h127.0.0.1 -psomepass --ssl-key=client-key.pem --ssl-cert=client-cert.pem -e 'select 1';
+---+
| 1 |
+---+
| 1 |
+---+

未开启加密连接或证书不对而无法登录数据库时,服务端返回的报错也是 ERROR 1045,跟密码不对时的报错信息是一样的。

在确认密码没有问题后,如果还是报 ERROR 1045,需要检查用户是否有加密连接和证书相关的要求。这一项我们可以到 mysql.user 表查看。

1
2
3
4
5
6
7
8
9
10
mysql> select user,host,ssl_type, cast(ssl_cipher as char) cipher, 
cast(x509_issuer as char) issuer, cast(x509_subject as char) subject
from mysql.user where user in ('user_05', 'user_06', 'user_07');
+---------+------+-----------+--------+-------------+-----------------------------------------------------------+
| user | host | ssl_type | cipher | issuer | subject |
+---------+------+-----------+--------+-------------+-----------------------------------------------------------+
| user_05 | % | ANY | | | |
| user_06 | % | SPECIFIED | | | /CN=MySQL_Server_8.0.32_Auto_Generated_Client_Certificate |
| user_07 | % | SPECIFIED | | /helloworld | |
+---------+------+-----------+--------+-------------+-----------------------------------------------------------+

从服务端的错误日志中,也可以看到一些相关的错误信息(需要将参数 log_error_verbosity 设置为 3)。

1
2
3
### alert.log
[Note] [MY-010290] [Server] X.509 issuer mismatch: should be '/helloworld' but is '/CN=MySQL_Server_8.0.32_Auto_Generated_CA_Certificate'
[Note] [MY-010926] [Server] Access denied for user 'user_07'@'localhost' (using password: YES)

数据库无法连接问题总结

检查数据库监听是否正常开启

可以在数据库服务器上通过 netstatss 命令查看数据库端口的监听是否正常开启。这里需要注意监听的 IP,如果监听的 IP127.0.0.1,则只能在本地连接到数据库。

1
2
3
4
5
# ss -nltp | grep 3306
LISTEN 0 128 [::]:3306 [::]:* users:(("mysqld",pid=13600,fd=33))

# netstat -nltp | grep 3306
tcp6 0 0 :::3306 :::* LISTEN 13600/mysqld

检查客户端到服务端之间的网络是否能连通(ERROR 2003 (HY000))

1
2
3
# telnet 172.16.121.234 3306
Trying 172.16.121.234...
telnet: connect to address 172.16.121.234: No route to host

如果端口不通,使用 MySQL 客户端访问数据库的时候,也会有相应的报错信息

1
2
3
4
5
# mysql  -h 172.16.121.234 -P 3306
ERROR 2003 (HY000): Can't connect to MySQL server on '172.16.121.234:3306' (113)

# mysql -h 172.16.121.234 -P3307 -uuser_01 -psomepass
ERROR 2003 (HY000): Can't connect to MySQL server on '172.16.121.234:3307' (111)
1
2
3
4
5
# perror 111
OS error code 111: Connection refused

# perror 113
OS error code 113: No route to host

这里的错误码跟操作系统有关,比如在 mac 下,错误码就变成了 61,需要在 mac 环境下使用 perror 工具查看。

1
2
3
4
5
$ mysql -uuser_01 -h172.16.121.234 -psomepass
ERROR 2003 (HY000): Can't connect to MySQL server on '172.16.121.234' (61)

$ perror 61
OS error code 61: Connection refused

是否是认证阶段出了问题(ERROR 2059,ERROR 2061,ERROR 1045)

ERROR 2059,Authentication plugin ‘caching_sha2_password’ cannot be loaded

客户端的版本太低了,不支持 caching_sha2_password 认证插件。解决方法是使用新版本的客户端

1
2
/opt/mysql5.6/bin/mysql -uuser_01 -h127.0.0.1 -psomepass
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/local/mysql/lib/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory

ERROR 2061,Authentication requires secure connection

1
2
# mysql --ssl-mode=disabled  -uuser_01 -h127.0.0.1 -psomepass
ERROR 2061 (HY000): Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.

使用 caching_sha2_password 认证插件时,用户首次登录时还没有被缓存,服务端需要获取用户的明文密码,如果客户端没有开启连接加密,发送明文密码有安全风险,就会报这个错误。开启连接加密可以解决这个问题,或者也可以在客户端指定 get-server-public-key 选项。

1
mysql --get-server-public-key --ssl-mode=disabled -uuser_01 -h127.0.0.1 -psomepass

使用 JDBC 时需要添加连接属性 allowPublicKeyRetrieval=true

MySQL 备库连接到主库时,也可能会遇到一样的问题,可以在建立复制时,指定 GET_MASTER_PUBLIC_KEYGET_SOURCE_PUBLIC_KEY 选项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
## 使用change master
change master to master_host='master-host-name',
master_user='repl',
master_password='somepass',
master_auto_position=1,
GET_MASTER_PUBLIC_KEY=1;

## 或者使用change replication source
change replication source to
source_host='master-host-name',
source_user='repl',
source_password='somepass',
source_auto_position=1,
GET_SOURCE_PUBLIC_KEY=1;

使用 MySQL 组复制(MGR)如果遇到这个问题,可以通过设置参数 group_replication_recovery_get_public_key 来解决。

1
set global group_replication_recovery_get_public_key=ON;

ERROR 1045 (28000): Access denied for user ‘username’@‘hostname’

ERROR 1045 可能是我们平时遇到最多的一个报错,通常这是由于客户端输入的密码不正确引起的。

但是我们在这一讲前面加密连接演示过,如果强制要求用户使用加密连接,或者对客户端的证书有要求,而客户端没有满足这些条件,那么连接时也会报这个错。可以到 mysql.user 表查看用户是否有 SSL 相关要求。同时也可以到数据库的错误日志中查看是否有相应的报错信息。

1
2
# mysql -uuser_07 -h172.16.121.234 -psomepassx --ssl-key=client-key.pem --ssl-cert=client-cert.pem -e 'select 1'
ERROR 1045 (28000): Access denied for user 'user_07'@'172-16-121-234' (using password: YES)

数据库连接数限制

MySQL 中有几个地方限制用户的连接数

参数 max_connections 限制了数据库允许创建的总连接数

参数 max_user_connections 限制了同一个用户允许创建的最大连接数。还可以指定某个具体的用户允许创建的最大连接数

1
2
3
mysql> create user 'user_09'@'%' identified by 'somepass' 
with MAX_USER_CONNECTIONS 2;
Query OK, 0 rows affected (0.04 sec)

如果连接数超过了限制,根据上面几种情况,分别会报下面这 3 个错误。

  • ERROR 1040 (08004): Too many connections
  • ERROR 1203 (42000): User user_01 already has more than ‘max_user_connections’ active connections
  • ERROR 1226 (42000): User ‘user_09’ has exceeded the ‘max_user_connections’ resource (current value: 2)

操作系统资源限制

ERROR 1135 (HY000): Can’t create a new thread (errno 11)

MySQL 创建连接时,需要消耗操作系统资源,如果操作系统资源超出了限制,也会导致客户端连接失败。下面这个例子中,MySQL 服务端无法创建新的线程

1
2
3
4
5
6
7
# mysql -uroot -h127.0.0.1 -pabc123
ERROR 1135 (HY000): Can't create a new thread (errno 11);
if you are not out of available memory, you can consult the manual
for a possible OS-dependent bug

# perror 11
OS error code 11: Resource temporarily unavailable

如果文件句柄数超出了限制,在数据库的错误日志中还可能会出现这样的报错信息。

1
[ERROR] [MY-010283] [Server] Error in accept: Too many open files

连接次数阈值限制

这也是一个比较致命的问题。客户端从某台机器连接数据库时,连续出错,出错的次数超过了参数 max_connect_errors 的设置后,服务端会禁止这台机器后续的连接。

ERROR 1129 (HY000): Host '172.16.121.237' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'

这里限制的是客户端的 IP,也就是从这个 IP 的发起所有连接都会被限制。从 performance_schema.host_cache 表里,我们可以看到客户端的连接错误次数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
mysql> select * from performance_schema.host_cache\G
*************************** 1. row ***************************
IP: 172.16.121.237
HOST: 172-16-121-237
HOST_VALIDATED: YES
SUM_CONNECT_ERRORS: 10
COUNT_HOST_BLOCKED_ERRORS: 5
COUNT_NAMEINFO_TRANSIENT_ERRORS: 0
COUNT_NAMEINFO_PERMANENT_ERRORS: 0
COUNT_FORMAT_ERRORS: 0
COUNT_ADDRINFO_TRANSIENT_ERRORS: 0
COUNT_ADDRINFO_PERMANENT_ERRORS: 0
COUNT_FCRDNS_ERRORS: 0
COUNT_HOST_ACL_ERRORS: 0
COUNT_NO_AUTH_PLUGIN_ERRORS: 0
COUNT_AUTH_PLUGIN_ERRORS: 0
COUNT_HANDSHAKE_ERRORS: 10
COUNT_PROXY_USER_ERRORS: 0
COUNT_PROXY_USER_ACL_ERRORS: 0
COUNT_AUTHENTICATION_ERRORS: 0
COUNT_SSL_ERRORS: 0
COUNT_MAX_USER_CONNECTIONS_ERRORS: 0
COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS: 0
COUNT_DEFAULT_DATABASE_ERRORS: 0
COUNT_INIT_CONNECT_ERRORS: 0
COUNT_LOCAL_ERRORS: 0
COUNT_UNKNOWN_ERRORS: 0
FIRST_SEEN: 2024-07-04 15:24:54
LAST_SEEN: 2024-07-04 15:37:46
FIRST_ERROR_SEEN: 2024-07-04 15:24:54
LAST_ERROR_SEEN: 2024-07-04 15:37:46

上面的报错信息中就提供了解决方法:执行 flush hosts 操作。

1
2
mysql> flush hosts;
Query OK, 0 rows affected, 1 warning (0.14 sec)

并不是所有的连接错误都会引起客户端被禁,比如密码错误并不会导致客户端被禁。host_cache 表的 COUNT_HANDSHAKE_ERRORS 达到 max_connect_errors,才会导致客户端被禁。

比如连续 telnet mysql 的端口会引起这个问题,或者使用了无效的 ssl 证书可能会导致这个问题。

1
2
# mysql  -uuser_06 -h 172.16.121.234 -psomepass --ssl-cert=client-cert.pem --ssl-key=client-key.pem --ssl-ca=ca.pem
ERROR 2026 (HY000): SSL connection error: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed

连接中断问题

使用 MySQL 自带的命令行客户端时,可能会遇到下面这几个报错。

比如使用 MySQL 自带的命令行客户端时,可能会遇到下面这几个报错。

  • ERROR 2013 (HY000): Lost connection to MySQL server during query
  • ERROR 4031 (HY000): The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior

使用 Java 编写的应用程序,在访问 MySQL 数据库时,比较常见的报错有 2

  • CommunicationsException: The last packet successfully received from the server was 15,032 milliseconds ago. The last packet sent successfully to the server was 15,035 milliseconds ago. is longer than the server configured value of ‘wait_timeout’.

  • Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.

客户端到服务器之间的连接断开了,实际的情况分析:

情况 1:连接被 Kill

如果有人使用 Kill 命令终止了某个会话,那么原先的那个客户端再执行 SQL 时,就会发现连接已经中断了。

1
2
3
4
5
6
7
8
9
mysql> show processlist;
+----+-----------------+----------------------+------+---------+------+
| Id | User | Host | db | Command | Time |
+----+-----------------+----------------------+------+---------+------+
| 30 | user_01 | 192.168.113.13:58850 | db01 | Sleep | 5 |
+----+-----------------+----------------------+------+---------+------+

mysql> kill 30;
Query OK, 0 rows affected (0.00 sec)

情况 2:数据库重启了

如果数据库重启发生了重启,那么原先所有的连接都会断开。

有一种比较特殊的情况,由于数据库底层数据文件损坏等原因,数据库在不停地重启。表现出来的现象是可以连接到数据库,但是执行 SQL 时,连接已经断开了。

1
2
3
4
5
6
mysql> show global status where variable_name in ('Uptime');
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Uptime | 64909 |
+---------------+-------+

我们可以通过查看数据库的 Uptime 状态变量来判断数据库最近是否有重启。Uptime 记录了数据库从启动后至今经过的秒数。

情况 3:连接空闲时间超时

MySQL 中参数 interactive_timeoutwait_timeout 用来控制连接的空闲超时,如果一个连接在指定的时间内没有发起任何请求,就会被服务器断开。

1
2
3
4
5
6
7
mysql> show global variables where variable_name in ('wait_timeout', 'interactive_timeout');
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
| wait_timeout | 28800 |
+---------------------+-------+

全局变量:

  • interactive_timeout 用来控制交互式连接的空闲超时时间,
  • wait_timeout 用来控制非交互式连接的空闲超时时间。

wait_timeout 还是一个会话级别的参数,每个会话可以分别设置不同的超时时间。默认情况下,服务器在创建一个连接时,根据客户端的连接类型来设置超时时间,对于交互式连接,

服务器基于 interactive_timeout 来设置连接的超时时间,对于非交互式连接,服务器根据全局变量 wait_timeout 来设置超时时间。连接还可以自己在会话级别修改超时时间。

要查看一个连接真实的超时时间,最简单的办法是通过这个连接查看会话变量 wait_timeout 的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> set wait_timeout=3600;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables where variable_name in ('wait_timeout');
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 3600 |
+---------------+-------+

mysql> select @@wait_timeout;
+----------------+
| @@wait_timeout |
+----------------+
| 3600 |
+----------------+
1 row in set (0.00 sec)

情况 4:代理(Proxy)超时

有的时候,数据库连接自身的空闲超时设置得比较大,但是在数据库之前配置了代理,而代理的空闲超时时间比较短。应用程序通过代理访问数据库时,就可能会遇到连接中断的问题。

下面是 nginx 的 4 层代理的一个例子。nginx 4 层代理默认的超时时间是 10 分钟,也就是如果 10 分钟内没有任何请求,就会把连接断开。

1
2
3
4
5
6
7
8
## /etc/nginx/nginx.conf
stream {
server {
listen 13306;
##proxy_timeout 10m; # 默认10分钟
proxy_pass 172.16.121.234:3306;
}
}

如果应用程序通过 nginx 来访问数据库,空闲时间超过 10 分钟后连接就会被断开。而且还有一个更严重的问题,通过代理无法执行耗时超过 10 分钟的 SQL

1
2
mysql> select sleep(610);
ERROR 2013 (HY000): Lost connection to MySQL server during query

那么连接断开的问题应该怎么解决呢?首先可以根据业务的实际情况,将空闲超时时间设置得长一些。如果使用了代理,需要注意代理的超时设置。

对于 Java 应用程序,一般会使用数据库连接池,要正确地设置连接池的参数。

有的连接池支持空闲连接回收,有的连接池支持连接探活(Keepalive),也就是每隔一定时间就执行一个 Keepalive 的 SQL,需要注意连接池的 Keepalive 执行间隔要比数据库的 wait_timeout 或代理的空闲超时时间设置得更短。

博文部分内容参考

© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知 :)



© 2018-至今 liruilonger@gmail.com, 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)

发布于

2024-12-10

更新于

2025-02-10

许可协议

评论
加载中,最新评论有1分钟缓存...
Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×