当前位置:首页 >  站长 >  建站经验 >  正文

千万级大表加索引不敢动?Online DDL和pt-online-schema-change实测

 2026-08-31 09:07  来源: 互联网   我来投稿 撤稿纠错

  一键部署OpenClaw

大表加索引是站长的经典恐惧:ALTER TABLE一执行,表被锁住,网站瞬间打不开,KILL掉还要回滚几小时。以前确实是这样,MySQL 5.6之后Online DDL成熟了,加索引这类操作可以在线做,执行期间允许并发读写。但“可以在线”不等于“随便什么时候都行”,坑还是有的。

Online DDL的原理:操作分三阶段,准备阶段拿元数据锁(很快),执行阶段在InnoDB内部建临时索引文件同时记录增量变更,最后提交阶段短暂拿锁把增量应用进去。绝大部分时间不阻塞业务,坑就在最后那个提交锁——如果有长事务一直占着表,DDL会在收尾时一直等,而它一等,后面所有查询全排队,现象就是“加索引把站锁死了”。

-- 1. 动手前先查有没有长事务
SELECT * FROM information_schema.INNODB_TRX
ORDER BY trx_started LIMIT 5;
-- trx_started超过几秒的,先处理掉再DDL

-- 2. 加索引(InnoDB在线操作)
ALTER TABLE articles ADD INDEX idx_status_time (status, created_at), ALGORITHM=INPLACE, LOCK=NONE;
-- ALGORITHM=INPLACE LOCK=NONE:明确要求不锁表
-- 如果MySQL说做不到会直接报错,而不是悄悄降级锁表

ALGORITHM和LOCK这两个显式参数我建议必写。不写的话,MySQL遇到不支持在线的操作会自动降级成锁表执行,命令照样跑,表照样锁,你以为没事其实站已经挂了。显式写上,不支持就直接报错终止,把选择权留给自己。

注意不是所有操作都能在线:加索引、加列、删列都是INPLACE;改列类型是COPY(锁表);5.6加全文索引也是COPY。执行前拿ALTER TABLE ... , ALGORITHM=INPLACE, LOCK=NONE试一下,报不报错一试便知。

pt-online-schema-change是另一条路:它建一张影子表,用触发器同步增量,最后原子改名切换。优点是各版本通用、可以限速(--max-load控制负载)、失败可以安全重试;缺点是要占双倍磁盘、有触发器开销。表特别大或者MySQL版本老,用它更稳。

pt-online-schema-change \
--alter "ADD INDEX idx_status_time (status, created_at)" \
D=mydb,t=articles,u=root,p=密码 \
--max-load Threads_running=50 \ # 超过50并发就暂停复制
--chunk-time 1.0 \ # 控制批处理节奏
--execute

不管哪种方式,都请在低峰期执行,并且执行时盯两样东西:SHOW PROCESSLIST看DDL进度,业务监控看错误率。事后EXPLAIN验证索引真的被用上了,别加完索引优化器不认,白忙一场。

数据来源:MySQL官方手册

申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!

相关标签
php教程
mysql

相关文章

  • 读多写少的站,主从复制加读写分离,一台变三台

    资讯类、内容站的流量特点很一致:读请求是写请求的几十上百倍。一台MySQL扛不住时,主从复制把读压力分给从库,主库专心写,是最省钱的扩容路径——不用换机器、不用改表结构,加从库就行。前提是主从复制先搭好(这个之前写过:主库开binlog、建同步账号,从库CHANGEMASTERTO)。复制跑通后,剩

    标签:
    php教程
    mysql
  • 容器删了数据就没了?Docker卷的备份恢复,别等出事才想起来

    用Docker跑MySQL的站长,最该问自己的一个问题:数据库文件现在能被备份脚本摸到吗?数据在卷(volume)里,如果卷是匿名卷、或者备份脚本只tar了网站目录,那数据库其实处于裸奔状态,容器一坏就只能恢复到上次手动导出的时点。先搞清楚自己的数据在哪。Docker存数据两种方式:bindmoun

    标签:
    php教程
    mysql
  • docker pull龟速还磁盘报警?镜像加速和空间清理一次讲清

    Docker用久了两大顽疾:拉镜像慢得像挂了,以及/var/lib/docker目录悄悄吃掉几十G直到磁盘写满、整站报错。这两件事都有标准解法,十分钟配完。先说拉取慢。DockerHub在国内直连基本不可用,需要配镜像加速器。各家云厂商都提供免费加速地址,阿里云的控制台里有一串专属地址,填到daem

    标签:
    php教程
  • 容器启动顺序乱成一锅粥?Compose依赖、健康检查和一键启停

    站稍微复杂一点,容器就不止三个:Web、PHP、MySQL、Redis,再加个定时任务的容器。用dockerrun一个个敲,重启顺序错一次就一堆报错——PHP比MySQL先起来,连接失败直接崩。Compose的价值就是把这套依赖关系写进配置,一键按正确顺序拉起。关键是depends_on加健康检查。

    标签:
    php教程
  • 环境配一次崩一次?Docker一条命令拉起LNMP,搬家不再从零开始

    传统装LNMP的痛,装过的都懂:PHP版本、扩展依赖、MySQL配置,换台服务器全部重来一遍,中途各种版本冲突。Docker把整套环境固化成配置文件,机器挂了,新机器上dockercomposeup一条命令,几分钟恢复原样。核心概念就三个:镜像(环境模板)、容器(跑起来的实例)、卷(挂出来的数据目录

    标签:
    php教程
    docker

热门排行

信息推荐