当前分析针对版本:MariaDB 10.5

线上出现报错:can't create more than max_prepared_stmt_count statements。造成这个错误的直接原因就是同时开启了 prepare 句柄太多导致的,所以比较直接的方式是调大参数,首先查看设置的值:

show global variables like 'max_prepared_stmt_count';

如果这个值比较小,我们需要手动调大:

set global max_prepared_stmt_count=1048576;

或者也可以修改配置文件,不过需要重启。

配置好之后我们注意观察下面几个参数的变化:

show global status like 'com_stmt%';

主要涉及下面的 3 个参数:

  1. Com_stmt_close 表示 prepare 语句关闭的次数
  2. Com_stmt_execute 表示 prepare 语句执行的次数
  3. Com_stmt_prepare 表示语句 prepare 的次数

注意这些参数,正常来说 3 者应该差不多,如果打开的和关闭的差距越来越大,那说明可能存在很多 statement 没有关闭,如果一直增长直到出现上面的报错,那说明肯定有程序存在 bug,忘记的关闭 statement 最终导致超出了限制。

如果程序比较少,应该很容易排查,但是如果操作当前 MySQL 实例的程序比较多,就需要从数据库角度来分析了。

第一种方法可以开启日志追踪打印所有 SQL 执行的情况:

set global general_log = 'ON';

这样所有的 SQL 执行情况都会打印出来,我们需要从日志中找到没有 close 的 prepare 从而定位问题,但是如果 SQL 特别多同时日志中有没有客户端来源,看日志会非常麻烦,不容易分析问题。

然后第二种方法就是开启性能追踪,首先需要确认性能追踪模式是否开启:

SHOW VARIABLES LIKE 'performance_schema';

如果没有开启,这个参数是无法直接动态开启的,因为这个是只读的变量,必须通过配置文件修改:

[mysqld]
performance_schema=ON

保存配置后,确定在不影响生产环境的前提下重启数据库:

systemctl restart mariadb

重启后我们需要开启下面这些性能追踪相关的表:

use performance_schema;
show tables like '%statement%';

我们主要用到下面这几个表:

  1. events_statements_current 当前正在执行查询的表
  2. events_statements_history 最近的10个完成的查询,通过 performance_schema_events_statements_history_size 可以调整大小,限制在 1024 之内
  3. events_statements_history_long 最近的1万个完成的查询,具体通过参数 performance_schema_events_statements_history_long_size 配置大小,限制在 1048576 之内

表结构参考:https://mariadb.com/kb/en/performance-schema-events_statements_current-table/

我们需要确认 setup_instruments 和 setup_consumers 中是否开启采集:

select * from setup_instruments where name like "statement/%";
-- 如果 enabled 是 NO 则可以开启
update setup_instruments set enabled="YES" where name like "statement/%";

确认 setup_consumers 中是否开启:

select * from setup_consumers;
-- 开启参数
update setup_consumers set enabled='YES' where name in ('events_statements_current', 'events_statements_history', 'events_statements_history_long');

表结构参考:https://mariadb.com/kb/en/performance-schema-setup_consumers-table/

开启后如果有查询我们在对应的事件表中应该可以查询到结果,也可以编写一个程序执行 prepare 单不要关闭,此时我们就可以通过 events_statements_current 表查询到具体的 SQL。

那么最后我们应该怎么找到是哪个客户端发起的查询呢?我们注意到上面的查询事件表中都有 THREAD_ID 字段,如果想看到具体正在进行的查询可以查询 processlist 表,那么这时候 threads 表就可以将 THREAD_ID 和 PROCESSLIST_ID 给关联起来,也就是说我们此时应该通过 threads 表通过 THREAD_ID 查询得到 PROCESSLIST_ID。

threads 表结构参考:https://mariadb.com/kb/en/performance-schema-threads-table/

然后我们查询具体的任务来源:

show processlist;
select * from information_schema.processlist where ID=<PROCESSLIST_ID>;

这样就可以找到具体查询来源的客户端了,processlist 表结构参考:https://mariadb.com/kb/en/information-schema-processlist-table/

我们可以通过 join 实现组合查询,快速找到出现问题的 SQL 来源,然后就可以基于机器和端口号进一步找到客户端进程的具体位置,从而方面定位问题。

Reference:

  1. https://stackoverflow.com/questions/26660763/mysql-performance-schema-not-working-properly
  2. https://www.cnblogs.com/Courage129/p/14188422.html

MySQL 分析查询与来源机器的更多相关文章

  1. mysql慢查询日志分析工具 mysqlsla(转)

    mysql数据库的慢查询日志是非常重要的一项调优辅助日志,但是mysql默认记录的日志格式阅读时不够友好,这是由mysql日志记录规则所决定的,捕获一条就记录一条,虽说记录的信息足够详尽,但如果将浏览 ...

  2. Linux下MySQL慢查询分析mysqlsla安装使用

    说明: 操作系统:CentOS 5.X 64位 MySQL版本:mysql-5.5.35 MySQL配置文件:/etc/my.cnf MySQL 数据库存放目录:/data/mysql 实现目的:开启 ...

  3. Mysql慢查询和慢查询日志分析

     Mysql慢查询和慢查询日志分析   众所周知,大访问量的情况下,可添加节点或改变架构可有效的缓解数据库压力,不过一切的原点,都是从单台mysql开始的.下面总结一些使用过或者研究过的经验,从配置以 ...

  4. MySQL 慢查询日志分析及可视化结果

    MySQL 慢查询日志分析及可视化结果 MySQL 慢查询日志分析 pt-query-digest分析慢查询日志 pt-query-digest --report slow.log 报告最近半个小时的 ...

  5. mysqlsla 分析mysql慢查询日志

    发现有一个工具mysqlsla,分析查询日志比 mysqldumpslow分析的会更清晰明了! 安装mysqlsla: 下载mysqlsla-2.03.tar.gz [root@yoon export ...

  6. mysql慢查询分析工具 mysqlsla 安装

    概述 mysqlsla 是一款很不错的mysql慢查询日志分析工具,而且简单易用.mysqlsla 是用perl编写的脚本,运行需要perl-DBI和per-DBD-Mysql两模块的支持.mysql ...

  7. 企业级中带你ELK如何实时收集分析Mysql慢查询日志

    什么是Mysql慢查询日志? 当SQL语句执行时间超过设定的阈值时,便于记录到指定的日志文件中或者表中,所有记录称之为慢查询日志 为什么要收集Mysql慢查询日志? 数据库在运行期间,可能会存在这很多 ...

  8. mysql死锁-查询锁表进程-分析锁表原因【转】

    查询锁表进程: 1.查询是否锁表 show OPEN TABLES where In_use > 0;   2.查询进程     show processlist   查询到相对应的进程===然 ...

  9. MySQL慢查询日志总结 日志分析工具mysqldumpslow

    MySQL慢查询日志总结 - 潇湘隐者 - 博客园 https://www.cnblogs.com/kerrycode/p/5593204.html 2016-06-17 10:32 by 潇湘隐者, ...

  10. Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解

    Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解   Mysql慢查询开启 Mysql的查询讯日志是Mysql提供的一种日志记录,它用来记录在Mysql中响应 ...

随机推荐

  1. 接入移动手机号一键登录类的封装,app应用,php服务端类的封装与调用

    需求:实现手机号一键登录,由于官方只有java的demo和jar包,没有php的sdk及demo <?php/* * 手机号一键登录加解密 */class Autophone{ const A_ ...

  2. FastWiki v0.1.0发布!新增超多功能

    FastWiki 发布 v0.1.0 https://github.com/239573049/fast-wiki/releases/tag/v0.1.0 更新日志 兼容OpenAI接口格式 删除Bl ...

  3. python tcp socket 源码分享

    服务端的源码: import socketserver class Handler_TCPServer(socketserver.BaseRequestHandler): ""&q ...

  4. Android MaterialButtonToggleGroup使用

    原文地址: Android MaterialButtonToggleGroup使用 - Stars-One的杂货小窝 觉得单选框不好看,发现了一个Material里的单选按钮组,感觉UI还不错,记下使 ...

  5. 反转链表——java

    给定一个链表,请你将链表反转过来. 举例:原链表:1→2→3→4→5→null 反转链表:5→4→3→2→1→null 代码: package algorithm_niuke; public clas ...

  6. linux系统必备软件

    linux系统必备软件 需要配置好epel源 必须安装的工具 tree vim wget bash-completion bash-completion-extras lrzsz net-tools ...

  7. linux下永久添加静态路由-不同

    linux下永久添加静态路由-不同 添加路由的命令: 1,route add route add -net 192.56.76.0 netmask 255.255.255.0 dev eth0#添加一 ...

  8. java实战字符串1:给定两个字符串 s 和 t,判断他们的编辑距离是否为 1。

    题目描述给定两个字符串 s 和 t,判断他们的间距是否为 1.(满足以下三个条件) 往 s 中插入一个字符得到 t从 s 中删除一个字符得到 t在 s 中替换一个字符得到 t 例1 输入: ab ac ...

  9. Java数据类型转换,字符串(String)转日期(Date)

    Java类型转换,字符串(String)转日期(Date) import java.text.ParseException; import java.text.SimpleDateFormat; im ...

  10. 敏捷MVP面面观

    在过去的十年中,软件开发经历了许多阶段.从使流程敏捷高效到使用DevOps简化IT服务,已经有了许多突破,MVP是对软件开发过程产生了根本性影响的进步之一.本文将深入探讨MVP在软件开发中怎样起作用. ...