游客发表
使用数据库时,连接偶尔会出现数据库连接数飙升的数被场景,最严重的打满的种情况是连接打满,root 用户无法获取到连接,紧急解决登陆数据库失败。连接这时候无法登录数据库kill 掉相关的数被数据连接,影响数据库的稳定性。下面将对这类的打满的种故障的处理进行详述。
2. 使用sysbench 模拟并发连接

3. 尝试登录数据库报错
复制$ /greatsql/svr/greatsql/bin/mysql -h127.0.0.1 -uroot -p ERROR 1040 (HY000): Too many connections1.2.从GreatSQL 8.0起,GreatSQL 支持在配置文件配置admin_port和admin_address,连接这两个参数都是静态参数,不支持动态修改。数被admin_address没有默认值,打满的种如果没有显式开启,紧急解决GreatSQL 不会维护任何的连接管理接口。admin_port即为管理接口连接TCP/IP的数被端口号,默认值为33062。打满的种
注意如果admin_address未设置,admin_port也将无效。
查看配置文件是否配置了admin_address和admin_port 复制$cat /greatsql/conf/greatsql.cnf | grep admin admin_address=127.0.0.1 admin_port=38061.2.3. 使用admin_port 和admin_address尝试登录数据库,登录成功。 复制$ /greatsql/svr/greatsql/bin/mysql -h127.0.0.1 -uroot -p -P3806 greatsql > SELECT count(*),服务器托管User FROM information_schema.processlist GROUP BY 2 ; +----------+-----------------+ | count(*) | User | +----------+-----------------+ | 1 | root | | 500 | test_user | +----------+-----------------+ 1 row in set (0.00 sec)1.2.3.4.5.6.7.8.9. 使用kill 将特定条件的连接杀掉,如果处于业务高峰期,也可以先使用SET GLOBAL max_connections=[value]临时调大连接数,要注意此时资源的负载情况。 下面表示的是查找出语句正在运行中且执行时间超过100s,用户叫test_user 的id 并拼装成kill 语句。请结合实际场景进行条件调整。 复制greatsql> SELECT concat("kill ",id,";") FROM information_schema.processlist WHERE info IS NOT NULL AND command != sleep AND time>100 AND USER =test_user;1.2.3.4.5. 方案2:GDB 在线关闭 TCP SOCKET上述演示是最为顺利的情况,但是不妨假设,如果未设置admin_address 和admin_port ,难道只有剩下数据库重启这种方式了吗?
其实不然,GreatSQL 默认使用 TCP/IP 进行网络连接,那是否可以把实例上由远程机器请求的部分 TCP socket 连接 kill 掉,但保持数据库进程的运行,以腾出部分连接数供 root 用户登录呢?
通过查阅资料, gdb attach 刚好能满足我们的设想:gdb attach 是 GDB(GNU 调试器)中的一个命令,用于附加(Attach)到一个正在运行的进程,而关闭一个 SOCKET,只要调用 close 函数就可以了。简单来说就是云服务器使用gdb attach 到进程上下文,然后 call close($fd)。
不过需要注意的是,gdb attach 会暂停目标进程的所有线程。对于生产环境中需要持续运行的进程(如服务、数据库、实时系统等),这种暂停可能导致服务中断或超时。且gdb 需要较大的性能开销,进程的运行速度会显著下降,需要经过谨慎评估后再使用此方式。
继续复现一个连接数打满,但是未启用admin_address和 admin_port 的场景,此时尝试用管理员登录报错ERROR 1040 (HY000): Too many connections 。
通过 netstat 反查数据库的进程号为18979 复制$ netstat -nltp | grep 3306 tcp6 0 0 :::3306 :::* LISTEN 18979/mysqld1.2.2. 使用 lsof 找到进程号18979的文件描述,并找到对应的 socket
复制$ lsof -np 18979 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 18979 greatsql cwd DIR 8,2 4096 4971025 /greatsql/dbdata/data3306/data mysqld 18979 greatsql rtd DIR 8,2 4096 2 / mysqld 18979 greatsql txt REG 8,2 1241425104 4971271 /greatsql/svr/GreatSQL-8.0.32-27-Linux-glibc2.17-x86_64/bin/mysqld mysqld 18979 greatsql mem REG 8,2 37216 688174 /usr/lib64/libnss_sss.so.2 ... mysqld 18979 greatsql 371u IPv6 31132193 0t0 TCP 172.17.134.208:mysql->172.17.139.57:40694 (ESTABLISHED) mysqld 18979 greatsql 372u IPv6 31132194 0t0 TCP 172.17.134.208:mysql->172.17.139.57:40698 (ESTABLISHED) mysqld 18979 greatsql 373u IPv6 31132195 0t0 TCP 172.17.134.208:mysql->172.17.139.57:40700 (ESTABLISHED) mysqld 18979 greatsql 374u IPv6 31132196 0t0 TCP 172.17.134.208:mysql->172.17.139.57:40702 (ESTABLISHED) mysqld 18979 greatsql 375u IPv6 31132197 0t0 TCP 172.17.134.208:mysql->172.17.139.57:40704 (ESTABLISHED) mysqld 18979 greatsql 376u IPv6 31132198 0t0 TCP 172.17.134.208:mysql->172.17.139.57:40706 (ESTABLISHED) mysqld 18979 greatsql 377u IPv6 31132201 0t0 TCP 172.17.134.208:mysql->172.17.139.57:40708 (ESTABLISHED) ...1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.其中NODE NAME 有(ESTABLISHED)表示两台主机TCP连接已经成功建立。找到对应的 FD,并记录下来
3. 使用 gdb 连接到进程,并关闭 socket 连接
复制$ gdb -p 18979 GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-114.el7 Copyright (C) 2013 Free Software Foundation, Inc .... Loaded symbols for /greatsql/svr/greatsql/lib/mysql/libjemalloc.so Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done. $ (gdb) call close(371u) $1 = 0 $ (gdb) call close(372u) $1 = 0 ....1.2.3.4.5.6.7.8.9.10.11.4. 查看数据库进程,并再次尝试登录数据库,登录成功。高防服务器
复制$ ps -ef | grep mysql greatsql 18979 1 99 13:30 ? 00:48:41 /greatsql/svr/greatsql/bin/mysqld --defaults-file=/greatsql/conf/greatsql.cnf1.2. 方案3:预防性设置 max_user_connections以上的情况为出现问题的时候的紧急处理,但作为DBA,保障线上稳定性为第一前提,连接数打满已经是一个较为糟糕的情况了。且前文描述的是数据库大版本为 8.0 后才开始支持admin_address ,admin_port 作为突发情况的紧急处理。但如果GreatSQL 5.7 或者更低的情况, 如何去保障生产的稳定性呢?
GreatSQL 还有一个参数max_user_connections ,我们来比较max_user_connections 和max_connections 的区别
max_connections:代表允许连接数据库的所有用户的连接数总和max_user_connections:代表允许单个用户的连接数最大值,即并发值出故障的时候,往往是同一个用户频繁的申请连接,那如果我们把单个用户的最大连接数调整到比最大连接数再小一点的值,确保管理员账号有足够的连接数进行突发故障的处理。 也可以有效减少连接打满的情况。且可以动态调整,可以使用SET GLOBAL max_user_connections=[value]生效。除此之外,该参数可针对特定用户设置 :如ALTER USER test_user@% WITH MAX_USER_CONNECTIONS 100;
随机阅读
热门排行
友情链接