Whoami:5年+金融、政府、医疗领域工作经验的DBACertificate:PGCM、OCP、YCPSkill:Oracle、Mysql、PostgreSQL、国产数据库Platform:CSDN、墨天轮、公众号(呆呆的私房菜)
1. 建表和插入数据
CREATE TABLE `large_data_table` (`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',`user_id` VARCHAR(36) NOT NULL DEFAULT '' COMMENT '用户ID(UUID格式)',`name` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户名',`age` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '年龄',`province_id` INT(10) UNSIGNED NOT NULL COMMENT '省份ID',`city_id` INT(10) UNSIGNED NOT NULL COMMENT '城市ID',`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`),KEY `idx_user_id` (`user_id`),KEY `idx_create_time` (`create_time`),KEY `idx_province_city` (`province_id`, `city_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4AUTO_INCREMENT=1COMMENT='亿级数据表';-- 插入1亿条数据DELIMITER $$CREATE PROCEDURE generate_100m_data()BEGINDECLARE i INT DEFAULT 1;WHILE i <= 100000000 DOINSERT INTO large_data_table (user_id, name, age, province_id, city_id)VALUES (UUID(),CONCAT('用户', i),FLOOR(18 + (RAND() * 62)), -- 年龄范围18-80岁FLOOR(1 + (RAND() * 33)), -- 省份ID范围1-34FLOOR(100 + (RAND() * 3400)) -- 城市ID范围101-3420);SET i = i + 1;-- 每1万条提交一次事务IF i % 10000 = 0 THENCOMMIT;START TRANSACTION;END IF;END WHILE;END$$DELIMITER ;-- 调用存储过程CALL generate_100m_data();
2. 模拟cpu高消耗sql
select * from large_data_table order by rand() limit 100;
3. 客户开始反馈业务卡顿、CPU消耗100%了。。。
1. top查看进程情况
top

通过top工具发现mysql进程CPU使用率已经超过100%,继续分析。
2. 查看内存使用情况
free -h

通过 free 工具发现内存使用情况还好,继续分析。
3. 检查MYSQL线程情况
top -H -p `pidof mysqld`

通过 top 工具可以明显发现 2775 线程CPU使用率异常。
4. 查看线程详细情况
select a.user, a.host, a.db, b.thread_os_id, b.thread_id, a.id processlist_id, a.command, a.time, a.state, a.infofrom information_schema.processlist a, performance_schema.threads bwhere a.id = b.processlist_idand b.thread_os_id = 2775;

select *from performance_schema.events_statements_currentwhere thread_id in (select thread_id from performance_schema.threads where thread_os_id = 2775)\G;

kill 2775;
5. 如果是事后才发现MYSQL有CPU高的情况,那怎么办?只能试试用慢日志分析一下咯。
-- 慢日志相关参数show variables like 'long_query_time';show variables like 'slow_query_log';-- 查看慢日志,找到具体故障时间点的sqlless /mysql/mysql8/slowlog/mysql-slow.log

1. 常规的手段是先 kill 会话,然后分析SQL执行计划并进行优化或SQL重构。
kill 2775;explain select * from large_data_table order by rand() limit 100000;

2. 关注索引的使用情况,一般where、join、max()、min()、order by、group by等字句用到的字段要创建相应的索引;同时要关注二级索引的正确使用; 3. 数据库参数优化:优化 key_buffer_size、table_cache、innodb_buffer_pool_size、innodb_log_file_size 等参数的大小;
本文内容就到这啦,相信本篇的内容能为您排查MYSQL思路带来一些参考和帮助。我们下篇再见!

文章转载自呆呆的私房菜,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




