暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

CPU又100%了

呆呆的私房菜 2025-03-18
8
    Whoami5年+金融、政府、医疗领域工作经验的DBA
    Certificate:PGCM、OCP、YCP
    Skill:Oracle、Mysql、PostgreSQL、国产数据库
    Platform:CSDN、墨天轮、公众号(呆呆的私房菜)
    复制

    阅读本文可以了解可以了解Mysql CPU占用率高的时候如何进行定位和优化,帮助DBA们在处理故障时提供排查和优化思路。

    01

    模拟测试数据
    • 1. 建表和插入数据
      CREATE TABLE `large_data_table` (
        `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
        `user_id` VARCHAR(36NOT NULL DEFAULT '' COMMENT '用户ID(UUID格式)',
        `name` VARCHAR(50NOT 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=utf8mb4 
        AUTO_INCREMENT=1 
        COMMENT='亿级数据表';




      -- 插入1亿条数据
      DELIMITER $$
      CREATE PROCEDURE generate_100m_data()
      BEGIN
        DECLARE i INT DEFAULT 1;
        WHILE i <= 100000000 DO
          INSERT 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-34
            FLOOR(100 + (RAND() * 3400)) -- 城市ID范围101-3420
          );
          SET i = i + 1;
          -- 每1万条提交一次事务
          IF i % 10000 = 0 THEN
            COMMIT;
            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%了。。。

        02

        问题排查
        • 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.info 
                from information_schema.processlist a, performance_schema.threads b 
                where a.id = b.processlist_id 
                and b.thread_os_id = 2775;
                复制
                  select * 
                  from performance_schema.events_statements_current 
                  where thread_id in (select thread_id from performance_schema.threads where thread_os_id = 2775)\G;
                  复制
                  ok,抓到慢日志,定位是哪个应用的SQL,确认是否可以kill
                    kill 2775;
                    复制
                    • 5. 如果是事后才发现MYSQL有CPU高的情况,那怎么办?只能试试用慢日志分析一下咯。
                      -- 慢日志相关参数
                      show variables like 'long_query_time';
                      show variables like 'slow_query_log';


                      -- 查看慢日志,找到具体故障时间点的sql
                      less /mysql/mysql8/slowlog/mysql-slow.log
                      复制

                      03

                      问题处理
                      • 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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                        评论