惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Stack Overflow Blog
Stack Overflow Blog
T
Tor Project blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Palo Alto Networks Blog
T
The Exploit Database - CXSecurity.com
P
Privacy International News Feed
C
Cybersecurity and Infrastructure Security Agency CISA
MyScale Blog
MyScale Blog
D
DataBreaches.Net
I
Intezer
GbyAI
GbyAI
Jina AI
Jina AI
The GitHub Blog
The GitHub Blog
S
Security @ Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
NISL@THU
NISL@THU
Project Zero
Project Zero
博客园_首页
Martin Fowler
Martin Fowler
A
About on SuperTechFans
J
Java Code Geeks
AI
AI
WordPress大学
WordPress大学
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
L
LINUX DO - 热门话题
云风的 BLOG
云风的 BLOG
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cisco Blogs
L
LangChain Blog
Google Online Security Blog
Google Online Security Blog
AWS News Blog
AWS News Blog
Help Net Security
Help Net Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
D
Docker
N
Netflix TechBlog - Medium
Know Your Adversary
Know Your Adversary
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Secure Thoughts
H
Heimdal Security Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
O
OpenAI News
S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 【当耐特】
雷峰网
雷峰网
V
Visual Studio Blog
T
Threat Research - Cisco Blogs

暗无天日

读:AI Agent 安全日志——从可见性与隐私的两难说起 - 暗无天日 AI写作的语言指纹——如何让文字不那么像机器 - 暗无天日 读:50 条 Claude Code 技巧——一个工程经理的六个月使用心得 读:AI 辅助开发为什么让 E2E 测试更有价值 - 暗无天日 读:在Emacs中使用Claude Code(Spacemacs适配版) - 暗无天日 Claude Code 背后的工程哲学——读 Agent Harness Engineering 读:Agent Harness Engineering——AI 智能体不只是模型,还有套件 - 暗无天日 browser-harness:让 AI 直接接管你的浏览器 - 暗无天日 读:Security-First CI/CD —— DevSecOps 自动化实践指南 TIL: 数字小键盘的小数点陷阱与行内算术求值 - 暗无天日 读:Immutability 不是万能药,它是一种权衡 - 暗无天日 Conducty:给 Claude Code 加上项目记忆和并行执行能力 - 暗无天日 读 — GitHub Trending 里的 Claude Code 技能包 读 — Prompt Caching 省钱指南 TIL: Emacs 中那些跟鼠标配合的冷门快捷键 - 暗无天日 读:Anvil——把 Emacs 变成 AI 的工具服务器 读:Emacs 代码折叠终极指南 - 暗无天日 读:Clojure 搭车客指南 - 暗无天日 git推送失败后恢复仓库损坏的完整记录 - 暗无天日 多智能体系统的两个有效模式——以及对 Claude Code 用户的启示 - 暗无天日 用 Org Babel 写 Literate 博文:扩展执行 + 定制导出 proced:Emacs 内置的进程查看器 - 暗无天日 从 proced 定制中学到的 Elisp 模式 读:让 Emacs proced 在 macOS 上显示 CPU 和内存 异步编程的函数着色税 - 暗无天日 链式调用的代价:JavaScript 和 Clojure 的共同教训 - 暗无天日 hyperfine:命令行基准测试工具 - 暗无天日 管道中的变量去哪了?——子 shell 作用域陷阱 - 暗无天日 开源包装器的信任陷阱:四个危险信号 - 暗无天日 程序员愿意为 AI 写文档,却不愿为同事写 - 暗无天日 mktemp: Shell 脚本中临时文件的安全陷阱与最佳实践 - 暗无天日 WSL9x —— 在 Windows 9x 里跑 Linux 内核 6.19 用 ox.el 做你想做的事 —— org-export 高级编程指南 读:Hot-wiring the Lisp Machine —— 用纯 Elisp 构建零依赖的 Org 静态站点生成器 Elisp 性能优化的六个实战教训 - 暗无天日 fcitx5 下 Emacs 无法切换输入法的排查 - 暗无天日 ERT 测试交互命令的三种方式 - 暗无天日 SEM Assistant: 当 Elisp 守护进程遇上 LLM 用 dmsg 给 Elisp 加上结构化调试日志 用 org-habit 追踪非每日习惯 - 暗无天日 Clojure X-Men:当编程语言特性变成超能力 - 暗无天日 TIL: 用 diff-hl 在 fringe 中显示 git 变更 读:llm-test —— 用 LLM agent 驱动 Emacs 测试 TIL: AI 时代的橡皮鸭调试 - 暗无天日 fcitx 启动后键盘输入卡顿的排查 - 暗无天日 TIL: 早期网页的图片热区导航 - 暗无天日 读 Seeing the Whole System 用 Emacs 自动生成每周链接推荐 - 暗无天日 读:ASCII control characters in my terminal 读 What to learn - 暗无天日 Lisp 的括号之痛——一个愚人节玩笑揭开的老伤疤 - 暗无天日 一本书该"线性读"还是"并行读" - 暗无天日 读 How to Monetize a Blog:一篇伪装成变现指南的讽刺文 Python Mock 第三方依赖的四种策略 - 暗无天日 Emacs Lisp 热重载实用指南 - 暗无天日 Prot 的 Emacs 配置哲学 - 暗无天日 TIL: 从直播对谈中学到的三个 Emacs 技巧 - 暗无天日 TIL: 自动使用项目虚拟环境的 Python - 暗无天日 TIL: 让 Help buffer 自动获得焦点 一条命令让本地开发用上 HTTPS —— slim 工具介绍 用 fsck 检查和修复 Linux 文件系统 排查Linux进程"卡死"实战:从strace到gdb全流程 - 暗无天日 PostgreSQL 索引:从基础到你可能不知道的高级用法 - 暗无天日 用 .pdbrc 自定义 Python 调试器 ANSI 转义码的标准化现状 - 暗无天日 终端程序的潜规则 - 暗无天日 PARA Org-mode 测试配置 - 暗无天日 AI越强越辣鸡?控制论说这是必然的 - 暗无天日 AI 越强越需要你盯着——反馈循环实操指南 - 暗无天日 你的AI代理正在偷你的密钥——四种你没想到的泄露通道 - 暗无天日 LLM 在 DevOps 中的三种角色 - 暗无天日 写作风格的反建议 - 暗无天日 反驳本质复杂性——Dan Luu 论为什么《没有银弹》错了 - 暗无天日 文件充满了危险——Dan Luu 谈文件系统的可靠性陷阱 - 暗无天日 AI 时代的 PARA 方法:用 Org-mode 和 AI 打造个人知识管理系统 Linux 数据去重学习笔记 - 暗无天日 创建跨平台 ZIP 文件的隐藏陷阱:Extra Field - 暗无天日 X11 Forwarding 排障指南 - 暗无天日 IP欺骗端口扫描:当别人冒充你去扫描别人 - 暗无天日 Linux 输入栈全景解析:从硬件按键到屏幕响应 - 暗无天日 Unix 系统中那些被埋没的配置开关——以 FontConfig 为例 - 暗无天日 在Linux上限制儿童使用电脑 - 暗无天日 GIF不仅仅是一种图片格式——用GIF流做些奇怪的事 - 暗无天日 Leiningen 学习笔记:Clojure 项目构建与管理从入门到实战配置 - 暗无天日 Google SRE Book 读书笔记 - 暗无天日 yes 管道 head 发生了什么 - 暗无天日 为什么 nohup 在 crontab 中不起作用 Bash中的Indirection与Nameref - 暗无天日 Linux PAM 简介 - 暗无天日 从Linux ISO文件启动计算机 - 暗无天日 用 Bash 打造一个Screen Locker 用GitHub Actions自动构建EGO博客 - 暗无天日 blocking I/O 的作用 - 暗无天日 mobileog 手机端同步提示Error:2 No such file 的解决方法 回收 WSL2 VHDX 文件占用空间 使用 org-mode columnview 生成任务列表 - 暗无天日 Emacs 作为 MPD 客户端 - 暗无天日 移动文件路径却不破坏org file link的方法 - 暗无天日 如何合理的导出help link 成HTML - 暗无天日 笑话理解之Biology - 暗无天日
TIL: MySQL 慢了从哪查起——六个工具的排查顺序 - 暗无天日
lujun9972,Claude Code · 2026-05-31 · via 暗无天日

目录

  • 是什么
  • 为什么值得关注
  • 怎么用
    • 第一步:记基线
    • 第二步:看实时
    • 第三步:看 InnoDB 内部状态
    • 第四步:定位慢查询
    • 第五步:检查配置
    • 第六步:验证效果

TecMint 上有篇 文章 介绍了六个 MySQL 性能监控的命令行工具。工具清单不难搜到,但这几个工具恰好覆盖了从"接到投诉"到"验证修复"的完整排查链路,理成工作流比单独学每个工具有用。

是什么

数据库慢了怎么查?我的习惯是先看基线数字,判断是不是真的在变慢;再看实时状态,确认现在正在发生什么;如果线程正常但查询就是慢,用 InnoDB 诊断工具看看是不是引擎层的问题;接着翻慢查询日志,揪出拖后腿的 SQL;然后检查配置参数有没有不合理的;改完东西之后跑一轮压测,确认改动生效。

步骤 工具 关键指标
基线检查 mysqladmin Slow queries 累计数、Threads 数
实时监控 mytop qps now(实时每秒查询数)、正在跑的 SQL
InnoDB 诊断 innotop Buffer Pool 命中率、锁等待
慢查询定位 pt-query-digest Response time 占比最高的查询
配置检查 MySQLTuner [!!] 标记的参数问题
压测验证 mysqlslap 改前改后的平均耗时对比

这些步骤之间有依赖关系。比如你不知道基线的 Slow queries 是多少,就没法判断慢查询是不是在加速增长。 mytop 看到线程数正常但查询就是慢,就轮到 innotop 看是不是 InnoDB 层的问题(缓冲池不够或者锁竞争)。不开慢查询日志的话, pt-query-digest 也没数据可吃。调完参数不压测,等于盲改。

为什么值得关注

排查 MySQL 性能问题时特别容易犯的毛病就是跳步,一上来就改 innodb_buffer_pool_size ,或者到处加索引,但你还没搞清楚到底是查询慢还是连接数爆了。按依赖顺序排查,每步只盯一两个关键指标,能少走弯路。

另外有个坑,这几个工具的安装方式差别挺大。 mysqladminmysqlslap 是 MySQL 自带的, mytop 原版 2009 年就停更了得找社区 fork, innotop 大部分发行版有包但名字不一样, pt-query-digest 要加 Percona 仓库, MySQLTuner 倒是省事,单个 Perl 脚本下载就能跑。记住哪个工具怎么装、该看什么,比死记参数管用。

怎么用

第一步:记基线

mysqladmin 是 MySQL 自带的管理工具,不用额外安装:

mysqladmin -u root -p status
Uptime: 475424  Threads: 9  Questions: 2491823  Slow queries: 14  Opens: 412  ...

记住 Slow queries 的值。这个数字只增不减(服务器重启才归零),过一小时再查一次,从 14 涨到 140 就说明这一小时出了问题。 Threads 数如果逼近 max_connections 上限,新连接会被直接拒绝。

持续观察加 -i 2 每 2 秒刷新:

mysqladmin -u root -p -i 2 status

第二步:看实时

mytop 提供类似 Linux top 的实时视图,能看到每秒查询数和正在跑的 SQL:

mytop -u root -p YourPassword -h localhost

mytop-p 后面必须跟密码,不像 mysql 那样单独写 -p 会弹出交互提示。嫌命令行暴露密码的话,可以在 ~/.mytop 里写配置:

user=root
pass=YourPassword
host=localhost
db=mysql

写完后记得 chmod 600 ~/.mytop ,否则别的用户能读到密码。

MySQL on localhost (8.0.36)                up 5+12:03:44 [12:45:01]
 Queries: 2.5M   qps:   87   Slow:    14   Se/In/Up/De(%):  62/18/14/06
             qps now:   92   Slow qps: 0.3  Threads:    9 (   8/  1)

      Id    User       Host/IP         DB      Time    Cmd Query or State
      112    app_user   192.168.1.45    mydb       0    Query SELECT * FROM orders WHERE...

qps now 是实时的每秒查询数。这个数字飙升但应用响应变慢,就是负载问题。下半部分能看到哪个用户在跑什么 SQL。

注意,原版 mytop 2009 年停更, apt install mytop 在 MySQL 8 上装不上。要用社区 fork( fevangelou/mytop ),安装步骤:

sudo apt install libdbi-perl libdbd-mysql-perl libterm-readkey-perl
cd ~ && git clone https://github.com/fevangelou/mytop.git
cd mytop && chmod +x mytop
sudo cp mytop /usr/local/sbin/

sudo dnf install perl-DBI perl-DBD-MySQL perl-TermReadKey
cd ~ && git clone https://github.com/fevangelou/mytop.git
cd mytop && chmod +x mytop
sudo cp mytop /usr/local/sbin/

第三步:看 InnoDB 内部状态

mytop 看的是线程和查询列表,但如果线程数正常、查询也跑着就是慢,问题大概率在 InnoDB 引擎层。 innotop 能看到 InnoDB 的缓冲池状态、锁等待和事务详情。

大部分发行版有包,直接装:

sudo apt install innotop      sudo dnf install innotop      sudo pacman -S innotop        

如果仓库里没有,从 GitHub 装也行: git clone https://github.com/innotop/innotop.git 。装好后连接:

[RO] InnoDB Txns, InnoDB 8.0.36, 9 threads, 92.0 QPS

CXN     Timeouts  Deadlocks  Txns  RollSegments  History
local          0          0     3           128       42

ID  User        Host    DB      Time  Undo  Query
42  app_user    local   mydb       3    18  UPDATE inventory SET qty=qty-1 WHERE...

重点盯两个东西。第一个是 Deadlocks 列,只要不是 0 就说明有事务在互相等锁,需要排查哪两个 SQL 在争同一行。第二个是按 B 键切换到 Buffer Pool 视图,看缓冲池命中率。命中率低于 99% 说明内存不够用,数据在走磁盘而不是走内存,这时候调大 innodb_buffer_pool_size 比优化 SQL 更管用。

第四步:定位慢查询

先确保慢查询日志开着(超过 1 秒的查询记下来)。

mysql -u root -p -e "SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1;"

注意 SET GLOBAL 只对当前运行实例生效,MySQL 重启后失效。要持久化的话写进 my.cnf

[mysqld]
slow_query_log = ON
long_query_time = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log

然后从 Percona Toolkit 安装 pt-query-digest

curl -O https://repo.percona.com/apt/percona-release_latest.generic_all.deb
sudo apt install ./percona-release_latest.generic_all.deb
sudo percona-release enable pt release
sudo apt update && sudo apt install percona-toolkit

sudo yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
sudo percona-release enable pt release
sudo yum install percona-toolkit

装好后分析慢查询日志:

pt-query-digest /var/log/mysql/mysql-slow.log
# Overall: 184 total, 8 unique, 0.02 QPS, 0.14x concurrency
# Attribute          total     min     max     avg     95%  stddev  median
# Exec time           512s      1s    143s     3s      9s      14s     1s

# Profile
# Rank  Query ID           Response time  Calls  R/Call  Item
#    1  0x813031B8BBC3B329  341s 66.6%    42  8.12s   SELECT orders items
#    2  0xA0CA1BBEDCD1B80D  108s 21.1%    89  1.21s   SELECT users sessions

Response time 的百分比直接告诉你优先级。Rank 1 占了 66% 的慢查询时间,跑了 42 次平均每次 8 秒。加个索引或者改写 JOIN,就能砍掉一大半的慢查询负担。不用把 8 个慢查询都修一遍,修占比最高的那一两条就够了。

同属 Percona Toolkit 的 pt-mysql-summary 适合在排查前先跑一遍,了解全局状态:

pt-mysql-summary -- -u root -p

它会一次性输出 MySQL 版本、运行端口、数据目录、当前进程列表( Command 列按 Query/Sleep 分类统计)、缓冲池使用率、复制状态等。其中 Processlist 部分能看到 Sleep 连接占用了多少时间。如果 SleepSUM(Time) 很高,说明大量空闲连接没关,是连接池配置的问题而不是查询的问题。第一次登录一台不熟悉的服务器时跑一遍,能快速判断方向。

第五步:检查配置

MySQLTuner 是单个 Perl 脚本,下载就能跑:

wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl
perl mysqltuner.pl --user root --ask-pass

--ask-pass 交互输入密码,避免密码留在 shell 历史里。

[!!] InnoDB buffer pool / data size: 128M / 2G
[!!] InnoDB buffer pool instances: 1 (recommended 2)

General recommendations:
    Increase innodb_buffer_pool_size to 1.5G or more
    Add innodb_buffer_pool_instances = 2 to my.cnf

[!!] 标记的是需要关注的问题。上面这个输出说的是,缓冲池(InnoDB 用来缓存数据和索引的内存区域)只有 128MB,但实际数据有 2GB,大量读操作在走磁盘而不是走内存。把 innodb_buffer_pool_size 设到可用内存的 70% 左右,新服务器上这一步改下来效果通常最明显。

第六步:验证效果

改完配置后用 mysqlslap (MySQL 自带)跑基准测试,先记下改前的数字,改完再跑一次对比:

mysqlslap -u root -p --concurrency=50 --iterations=1 \
  --auto-generate-sql --number-of-queries=200
Benchmark
        Average number of seconds to run all queries: 3.847 seconds
        Number of clients running queries: 50
        Average number of queries per client: 4

记下 Average number of seconds 。加索引后再跑,从 3.8 秒降到 1.2 秒就说明有效。也可以指定真实 SQL 来测特定查询:

mysqlslap -u root -p --concurrency=25 --iterations=3 \
  --query="SELECT * FROM mydb.orders WHERE status='pending'" \
  --create-schema=mydb