Mysql MariaDB 10.4随机性能退化

Mysql MariaDB 10.4随机性能退化,mysql,mariadb,mariadb-10.4,Mysql,Mariadb,Mariadb 10.4,我有一个具有以下参数的服务器: 操作系统:Ubuntu 18.04.4 LTS x86_64 主机:X11DPi-N(T) 内核:4.15.0-112-generic CPU:Intel Xeon Silver 4214(48)@2.201GHz GPU:Asped Technology,Inc.Asped图形系列 内存:18552MiB/96336MiB SSD三星MZQLB960HAJR-00007 894.3G x 2 安装了5.5.5-10.4.12-MariaDB-1:10.4.1

我有一个具有以下参数的服务器:

  • 操作系统:Ubuntu 18.04.4 LTS x86_64
  • 主机:X11DPi-N(T)
  • 内核:4.15.0-112-generic
  • CPU:Intel Xeon Silver 4214(48)@2.201GHz
  • GPU:Asped Technology,Inc.Asped图形系列
  • 内存:18552MiB/96336MiB
  • SSD三星MZQLB960HAJR-00007 894.3G x 2
安装了
5.5.5-10.4.12-MariaDB-1:10.4.12+maria~bionic
。在此屏幕截图上显示了标准DB负载:

因此,我每秒有大约400-500次选择(主要是从具有500k记录的不太大的表中选择),每秒有100-190次更新,以及大约50-150次同步连接

我的问题是:有时,没有明显的原因,服务器有2000-3000个打开的连接/进程。根据
SHOW FULL PROCESSLIST
的说明,它们是标准的SQL请求,但处于“发送数据”状态,运行时间为400-500秒。当然,此时服务器冻结,无法正常工作。我说“没有明显的原因”,因为目前我没有看到该网站的用户数量增加或活动增加。此外,重新启动MariaDB服务或完全重新启动服务器有助于摆脱这种情况,但并不总是这样:有时即使在重新启动后,我几乎立即得到相同的2000-3000个冻结进程

有人遇到过类似的数据库行为吗?如有任何意见,我将不胜感激

UPD:

  • 我所有的SELECTs只调用一个表(~500k条记录,没有
    连接
    和/或子查询),而且大多数都有
    限制1
    ,所以数据量不太大

  • 错误日志显示了许多类似这样的记录:
    2020-08-26 22:12:35 787380[警告]中断了787380到db的连接:。。。(读取通信数据包时超时)

  • innodb\u lock\u wait\u timeout
    为50(默认值)

  • 慢速查询日志未显示异常情况

  • 我的
    优化器\u开关
    设置:
    索引\u合并=on,索引\u合并\u联合=on,索引\u合并\u排序\u联合=on,索引\u合并\u交叉=on,索引\u合并\u排序\u交叉=off,引擎\u条件\u下推=off,索引\u条件\u下推=on,派生\u键=on,firstmatch=on,loosescan=on,物化=on,在\u到\u存在=on,半连接=on,部分匹配rowid merge=on,部分匹配表格扫描=on,子查询缓存=on,mrr=off,基于成本的mrr=off,mrr\U排序关键字=off,外部连接关键字=on,半连接关键字=on,连接关键字=on,连接关键字=on,连接关键字=on,连接关键字=on,连接关键字=on,连接关键字=on,连接关键字=on,条件\u下推\u用于\u派生=on、拆分\u物化=on、条件\u下推\u用于\u子查询=on、rowid\u过滤器=on、条件\u下推\u来自\u having=on


  • 这听起来像是查询优化器随机进入大脑死亡的经典案例。这是一个由来已久的海森堡

    当您看到查询堆积起来时,对其中一个堆积起来的id运行
    SHOW EXPLAIN FOR thread\u id
    。查看查询计划是否不合理。如果是,请编辑查询应用程序端以包含索引提示,以防止查询优化器出错。如果您无法更改查询,则必须修改
    优化器_开关
    设置,直到您确定并删除使优化器疯狂的特定选项。

    中的任何内容

    如果数据库冻结,很可能是磁盘问题:可能是磁盘已满,如果无法写入任何内容,mariadb将冻结1分钟,如果临时表填满磁盘,则磁盘可能已满,或者使用复制算法对一个表进行更改;您是否在监视磁盘使用情况(不在映像中,您应该这样做)?可能是磁盘I/O都被一个查询使用:那么所有查询仍然会运行,但运行速度非常慢,所以是卡住了还是非常慢?可能是锁的问题

    由于查询运行了很长一段时间(400-500秒),所以它很可能不是锁:除非您更改了它,否则锁等待超时会更短()

    如果您知道没有运行
    ALTER TABLE
    ,并且没有磁盘问题(),那么它仍然可能是一个锁:
    SHOW ENGINE INNODB STATUS\G
    以进行检查

    您说过,执行
    显示完整的进程列表
    时,只有标准的SQL请求,所以很可能没有
    更改表

    如果您有一个写得不好的查询,一个临时表可能会填满您的磁盘,因此您需要
    解释
    执行
    显示完整进程列表时显示的查询
    要对此进行分析,并重写/优化/限制此类查询结果集的大小,请使用临时
    查找
    (您有时也可以在磁盘上进行排序:
    使用filesort
    )。将告诉您是否有使用磁盘的查询(如果在重新启动服务器时没有终止查询)

    如果您没有时间优化查询,并且如果查询很大,请选择
    减慢整个数据库的运行速度,以便向用户显示信息(报告),您可以使用脚本消除耗时过长的查询:这应该是最后的手段(如果脚本终止查询花费的时间太长,则可能会编写它们,以便以后能够分析它们)

    临时表填充磁盘或使用所有I/O是我看到数据库冻结并在重新启动后重新启动的唯一情况。对于数据库再次冻结的情况,可能用户正在重复(一次又一次)执行相同的查询

    编辑

    问题可能不是您的数据库,而是您的web应用程序:错误日志消息表明数据库正在终止某些连接

    查询发送数据和中断连接的组合对我来说是不常见的。通常,如果web应用程序未关闭连接,并且连接处于睡眠状态,则会发生中断连接。Y
    thread_handling=pool-of-threads
    thread_pool_size=48 
    #48 is a number of CPUs