开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, OceanBase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,可以解决你的问题。加群请联系 liuaustin3 ,(共2750人左右 1 + 2 + 3 + 4 +5 + 6 + 7 + 8 +9)(1 2 3 4 5 6 7群均已爆满,,开8群200+ 9群)
上期MySQL的分析和自动脚本的基础是基于MySQL的show engine innodb status;
今天我们进一步进行分析,现在大部分同学应该开始使用了MySQL8,截止2025年MySQL已经发布了MySQL 9.2,虽然MySQL在走下坡路的事情已经是人尽皆知了。但是现在MySQL的保有量和存量还是有的,另外一些蹩脚的开发者还就只会个MySQL,虽然这样的开发者也会被淘汰,但还是那句话MySQL的存量还是有的。
这里说句题外话,前两天在丁奇的直播间听了半个小时,我个人觉得丁奇丁老师,在数据库方面还是很实话实说的,丁老师的直播间有人在问,现在学MySQL还是PostgreSQL,丁老师不带有个人利益或个人倾向性的说了一下,我记得大致意思是
1 MySQL还是要学的,如果你去的是互联网企业或类似的企业
2 MySQL和PG这两个数据库不是二选一,是都要会,一个要精通,另一个至少要熟悉和会。
3 类MySQL的数据库性能已经超过开源MySQL (此篇发布较晚,实际上是2月份某天听的直播)
我觉得这样的人才能称为数据库专家,没有误导大家,点赞!
话归正传,今天说说Performance_schema中的系统表来分析MySQL的内存使用情况。上一篇是非常粗狂的对MySQL的使用内存的方式进行分析和通过自动脚本来进行打印,来获取命中率和刷新率等信息。
这里performance_schema 来分析MySQL的内存可以通过更多的维度来进行分析,并且细化到底内存用到哪里了。这里画了一个分析图。

语句1:通过语句来分析全局的MySQL在使用内存的情况
SELECT
EVENT_NAME,
COUNT_ALLOC,
SUM_NUMBER_OF_BYTES_ALLOC AS TOTAL_ALLOCATED_BYTES,
SUM_NUMBER_OF_BYTES_FREE AS TOTAL_FREED_BYTES,
SUM_NUMBER_OF_BYTES_ALLOC - SUM_NUMBER_OF_BYTES_FREE AS CURRENT_MEMORY_USAGE
FROM performance_schema.memory_summary_global_by_event_name
ORDER BY CURRENT_MEMORY_USAGE DESC
LIMIT 10;复制
+-----------------------------------------------------------------------------+-------------+-----------------------+-------------------+----------------------+
| EVENT_NAME | COUNT_ALLOC | TOTAL_ALLOCATED_BYTES | TOTAL_FREED_BYTES | CURRENT_MEMORY_USAGE |
+-----------------------------------------------------------------------------+-------------+-----------------------+-------------------+----------------------+
| memory/innodb/buf_buf_pool | 8 | 1096286208 | 0 | 1096286208 |
| memory/performance_schema/events_statements_summary_by_digest | 1 | 41600000 | 0 | 41600000 |
| memory/mysys/KEY_CACHE | 3 | 33555920 | 0 | 33555920 |
| memory/innodb/hash0hash | 32 | 30212544 | 0 | 30212544 |
| memory/innodb/ut0link_buf | 2 | 25165888 | 0 | 25165888 |
| memory/innodb/buf0dblwr | 1151 | 48074720 | 27608288 | 20466432 |
| memory/innodb/ut0new | 6 | 16859962 | 0 | 16859962 |
| memory/performance_schema/events_statements_history_long | 1 | 14560000 | 0 | 14560000 |
| memory/performance_schema/events_errors_summary_by_thread_by_error | 257 | 12390400 | 0 | 12390400 |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name | 1 | 10268672 | 0 | 10268672 |
+-----------------------------------------------------------------------------+-------------+-----------------------+-------------------+----------------------+复制
上面的信息中,我们可以得到的分配内存是多少,总的释放内存是多少,这些信息是从开启数据库后的累计数据。同时还有当前的内存使用值是多少。
其中最主要的有着几部分 memory/innodb/buf_buf_pool: 这个部分是我们非常熟悉的innodb_buffer_pool 的部分这里显示分配了 1.2G
memory/performance_schema/events_statements_summary_by_digest: 这个部分是给出语句收集部分组件的消耗的内存,在40MB
memory/innodb/buf0dblwr:这里还有MySQL向磁盘刷新数据时锁消耗的内存。
语句2: 分析用户或线程使用内存的情况 按照用户来分析
SELECT
USER,
EVENT_NAME,
SUM_NUMBER_OF_BYTES_ALLOC - SUM_NUMBER_OF_BYTES_FREE AS CURRENT_MEMORY_USAGE
FROM performance_schema.memory_summary_by_user_by_event_name
ORDER BY CURRENT_MEMORY_USAGE DESC
LIMIT 10;复制
按线程来分析或用户我们可以得到如下的信息,这里可以注意到一点,我们平时在分析系统的内存的时候,在一个MySQL中分别有不同的项目来使用数据库的INNODB BUFFER POOL 此时如果问到底那个应用的系统使用的内存更多,可能很难回答。 这里我们使用这条语句可以清晰的看到不同的用户使用innodb buffer pool 内存的情况,这样对于我们后续在内存添加和拆库上有很多可以给出有力的数据。
同时我们还可以注意到下面的信息中有两个重要的部分 innodb的部分和SQL层的部分。SQL层的部分memory/sql/dd::objects,memory/sql/dd::String_type
+------+--------------------------------------+----------------------+
| USER | EVENT_NAME | CURRENT_MEMORY_USAGE |
+------+--------------------------------------+----------------------+
| NULL | memory/innodb/memory | 436048 |
| NULL | memory/sql/dd::objects | 353536 |
| NULL | memory/sql/dd::String_type | 227922 |
| NULL | memory/mysqld_openssl/openssl_malloc | 150302 |
| root | memory/innodb/memory | 116640 |
| NULL | memory/sql/THD::main_mem_root | 116272 |
| NULL | memory/sql/NET::buff | 65564 |
| NULL | memory/innodb/ha_innodb | 64957 |
| NULL | memory/mysys/TREE | 38936 |
| root | memory/sql/THD::main_mem_root | 28696 |
+------+--------------------------------------+----------------------+
10 rows inset (0.01 sec)复制
SELECT
THREAD_ID,
EVENT_NAME,
SUM_NUMBER_OF_BYTES_ALLOC - SUM_NUMBER_OF_BYTES_FREE AS CURRENT_MEMORY_USAGE
FROM performance_schema.memory_summary_by_thread_by_event_name
ORDER BY CURRENT_MEMORY_USAGE DESC
LIMIT 10;复制
语句 3: 分析INNODB的内存分配
如果要整体的内存分配进行统计和计算,可以使用下面的语句。
SELECT
EVENT_NAME,
COUNT_ALLOC,
SUM_NUMBER_OF_BYTES_ALLOC - SUM_NUMBER_OF_BYTES_FREE AS CURRENT_MEMORY_USAGE
FROM performance_schema.memory_summary_global_by_event_name
WHERE EVENT_NAME LIKE 'memory/innodb/%'
ORDER BY CURRENT_MEMORY_USAGE DESC;复制
+-----------+--------------------------------------+----------------------+
| THREAD_ID | EVENT_NAME | CURRENT_MEMORY_USAGE |
+-----------+--------------------------------------+----------------------+
| 1 | memory/innodb/memory | 308912 |
| 1 | memory/sql/dd::String_type | 225564 |
| 1 | memory/sql/dd::objects | 193312 |
| 37 | memory/sql/dd::objects | 160224 |
| 1 | memory/mysqld_openssl/openssl_malloc | 150302 |
| 37 | memory/innodb/memory | 120984 |
| 53 | memory/innodb/memory | 116640 |
| 37 | memory/sql/THD::main_mem_root | 108072 |
| 1 | memory/sql/NET::buff | 65564 |
| 1 | memory/innodb/ha_innodb | 41309 |
+-----------+--------------------------------------+----------------------+复制
语句 4: 分析系统内存占用情况
下面的语句可以给出总体的MySQL的使用中的内存情况,总体分配了多少内存,当前释放了多少内存,当前正在使用的内存是多少,分别是已经分配了1.47G内存,释放了80MB的内存,当前正在使用的内存是1.4G等,通过这个部分可以动态监控内存的使用情况。
SELECT
SUM(SUM_NUMBER_OF_BYTES_ALLOC) AS TOTAL_ALLOCATED_BYTES,
SUM(SUM_NUMBER_OF_BYTES_FREE) AS TOTAL_FREED_BYTES,
SUM(SUM_NUMBER_OF_BYTES_ALLOC) - SUM(SUM_NUMBER_OF_BYTES_FREE) AS CURRENT_MEMORY_USAGE
FROM performance_schema.memory_summary_global_by_event_name;
+-----------------------+-------------------+----------------------+
| TOTAL_ALLOCATED_BYTES | TOTAL_FREED_BYTES | CURRENT_MEMORY_USAGE |
+-----------------------+-------------------+----------------------+
| 1556430074 | 84261392 | 1472168682 |
+-----------------------+-------------------+----------------------+
1 row in set (0.00 sec)复制
SELECT CONCAT('KILL QUERY ', t.THREAD_ID, ';') AS kill_command
FROM performance_schema.threads AS t
JOIN performance_schema.events_statements_current AS s
ON t.THREAD_ID = s.THREAD_ID
WHERE t.NAME LIKE 'thread/sql/%'
AND t.PROCESSLIST_TIME > 300;复制
以上的语句为自动打印超过5分钟的还在执行的语句,答应KILL 语句
SELECT EVENT_NAME, SUM(CURRENT_NUMBER_OF_BYTES_USED) AS memory_used
FROM performance_schema.memory_summary_global_by_event_name
WHERE EVENT_NAME = 'memory/innodb/lock_sys'
GROUP BY EVENT_NAME;复制
以上的语句分析当前的锁分配是否有异常,是否存在大量的SQL锁之间的竞争,潜在说明SQL之间存在死锁,BLOCKED,或长时间运行的SQL等。
下面通过一个语句将系统中thread中运行的语句时间进行打印。 通过ctrl+c停止这个脚本。这里展示的是历史的信息,如果要展示当前的语句执行的信息还需要配合 show processlist来进行观察。
const mysql = require('mysql2');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'root',
database: 'mysql',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
console.log('Press Ctrl+C to stop the script.');
rl.on('SIGINT', () => {
console.log('Stopping script...');
pool.end((err) => {
if (err) {
console.error('Error closing connection pool:', err);
} else {
console.log('Connection pool closed.');
process.exit(0);
}
});
});
pool.getConnection((err, connection) => {
if (err) {
console.error('Error getting connection from pool:', err);
return;
}
connection.query('SELECT * FROM performance_schema.threads WHERE THREAD_ID != connection_id()', (err, rows) => {
if (err) {
console.error('Error querying threads:', err);
connection.release();
return;
}
rows.forEach(row => {
if (row.USER !== 'system') {
connection.query(`
SELECT
s.PROCESSLIST_USER,
e.DIGEST_TEXT,
e.TIMER_WAIT 1000000 AS duration_ms
FROM
performance_schema.events_statements_history_long e
JOIN
performance_schema.threads s ON e.THREAD_ID = s.THREAD_ID
WHERE
e.THREAD_ID = ${row.THREAD_ID}
ORDER BY e.TIMER_WAIT DESC
LIMIT 1;
`, (err, slowQuery) => {
if (err) {
console.error(`Error querying slow queries for thread ${row.THREAD_ID}:`, err);
} elseif (slowQuery.length > 0) {
console.log(`Thread ID: ${row.THREAD_ID}, User: ${slowQuery[0].USER}, SQL: ${slowQuery[0].DIGEST_TEXT}, Duration: ${slowQuery[0].duration_ms} ms`);
}
});
}
});
connection.release();
});
});复制

置顶
天上的“PostgreSQL” 说 地上的 PostgreSQL 都是“小垃圾”
云原生数据库砸了 K8S云自建数据库的饭碗--- CXL内存技术
云原生 DB 技术将取代K8S为基础云数据库服务-- 2025年云数据库专栏(一)
临时工:数据库人生路,如何救赎自己 -- 答某个迷茫DBA的职业咨询
开源软件是心怀鬼胎的大骗局 -- 开源软件是人类最好的正能量 --- 一个人的辩论会
PolarDB 相关文章
云原生数据库砸了 K8S云自建数据库的饭碗--- CXL内存技术
“PostgreSQL” 高性能主从强一致读写分离,我行,你没戏!
POLARDB 添加字段 “卡” 住---这锅Polar不背
PolarDB 版本差异分析--外人不知道的秘密(谁是绵羊,谁是怪兽)
PolarDB 答题拿-- 飞刀总的书、同款卫衣、T恤,来自杭州的Package(活动结束了)
PolarDB for MySQL 三大核心之一POLARFS 今天扒开它--- 嘛是火星人
PolarDB-MySQL 并行技巧与内幕--(怎么薅羊毛)
PolarDB 并行黑科技--从百套MySQL撤下说起 (感谢8018个粉丝的支持)
PolarDB 杀疯了,Everywhere Everytime Everydatabase on Serverless
POLARDB 从一个使用者的角度来说说,POALRDB 怎么打败 MYSQL RDS
PolarDB 最近遇到加字段加不上的问题 与 使用PolarDB 三年感受与恳谈
PolarDB 从节点Down机后,引起的主从节点强一致的争论
PolarDB serverless 真敢搞,你出圈了你知道吗!!!!
PolarDB VS PostgreSQL "云上"性能与成本评测 -- PolarDB 比PostgreSQL 好?
临时工访谈:PolarDB Serverless 发现“大”问题了 之 灭妖记 续集
临时工访谈:庙小妖风大-PolarDB 组团镇妖 之 他们是第一
POLARDB -- Ausitndatabases 历年的文章集合
PolarDB for PostgreSQL 有意思吗?有意思呀
PostgreSQL 相关文章
天上的“PostgreSQL” 说 地上的 PostgreSQL 都是“小垃圾”
“PostgreSQL” 高性能主从强一致读写分离,我行,你没戏!
全世界都在“搞” PostgreSQL ,从Oracle 得到一个“馊主意”开始
PostgreSQL 加索引系统OOM 怨我了--- 不怨你怨谁
PostgreSQL “我怎么就连个数据库都不会建?” --- 你还真不会!
PostgreSQL 稳定性平台 PG中文社区大会--杭州来去匆匆
PostgreSQL 分组查询可以不进行全表扫描吗?速度提高上千倍?
POSTGRESQL --Austindatabaes 历年文章整理
PostgreSQL 查询语句开发写不好是必然,不是PG的锅
跟我学OceanBase4.0 --阅读白皮书 (OB分布式优化哪里了提高了速度)
跟我学OceanBase4.0 --阅读白皮书 (4.0优化的核心点是什么)
跟我学OceanBase4.0 --阅读白皮书 (0.5-4.0的架构与之前架构特点)
跟我学OceanBase4.0 --阅读白皮书 (旧的概念害死人呀,更新知识和理念)
MongoDB 相关文章
MongoDB 大俗大雅,上来问分片真三俗 -- 4 分什么分
MongoDB 大俗大雅,高端知识讲“庸俗” --3 奇葩数据更新方法
MongoDB 大俗大雅,高端的知识讲“通俗” -- 2 嵌套和引用
MongoDB 大俗大雅,高端的知识讲“低俗” -- 1 什么叫多模
MongoDB 合作考试报销活动 贴附属,MongoDB基础知识速通
MongoDB 使用网上妙招,直接DOWN机---清理表碎片导致的灾祸 (送书活动结束)
数据库 《三体》“二向箔” 思维限制 !8个公众号联合抽奖送书 建立数据库设计新思维
MongoDB 是外星人,水瓶座,怎么和不按套路出牌的他沟通?
POLARDB 添加字段 “卡” 住---这锅Polar不背
PolarDB 版本差异分析--外人不知道的秘密(谁是绵羊,谁是怪兽)
PolarDB 答题拿-- 飞刀总的书、同款卫衣、T恤,来自杭州的Package(活动结束了)
PolarDB for MySQL 三大核心之一POLARFS 今天扒开它--- 嘛是火星人
PolarDB-MySQL 并行技巧与内幕--(怎么薅羊毛)
PolarDB 并行黑科技--从百套MySQL撤下说起 (感谢8018个粉丝的支持)
PolarDB 杀疯了,Everywhere Everytime Everydatabase on Serverless
POLARDB 从一个使用者的角度来说说,POALRDB 怎么打败 MYSQL RDS
PolarDB 最近遇到加字段加不上的问题 与 使用PolarDB 三年感受与恳谈
PolarDB 从节点Down机后,引起的主从节点强一致的争论
PolarDB serverless 真敢搞,你出圈了你知道吗!!!!
PolarDB VS PostgreSQL "云上"性能与成本评测 -- PolarDB 比PostgreSQL 好?
临时工访谈:PolarDB Serverless 发现“大”问题了 之 灭妖记 续集
临时工访谈:庙小妖风大-PolarDB 组团镇妖 之 他们是第一
POLARDB -- Ausitndatabases 历年的文章集合
PolarDB for PostgreSQL 有意思吗?有意思呀
没有谁是垮掉的一代--记 第四届 OceanBase 数据库大赛
阿里云系列
阿里云数据库产品权限设计缺陷 ,六个场景诠释问题,你可以做的更好?
阿里云数据库--市场营销聊胜于无--3年的使用感受与反馈系列
阿里云数据库产品 对内对外一样的卷 --3年阿里云数据库的使用感受与反馈系列
阿里云数据库使用感受--客户服务问题深入剖析与什么是廉价客户 --3年的使用感受与反馈系列
阿里云数据库使用感受--操作界面有点眼花缭乱 --3年的使用感受与反馈系列
