线上服务宕机,码农试用期被毕业,原因竟是给MySQL加个字段
1. 问题:怎么给线上表加字段?
工作中最常遇到的问题,怎么给线上频繁使用的大表添加字段?
比如:给下面的用户表(user)添加年龄(age)字段。
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(100) DEFAULT NULL COMMENT '姓名',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';
有同学会说,这还不简单,直接加不加完了,用下面的命令:
ALTER TABLE `user` ADD `age` int NOT NULL DEFAULT '0' COMMENT '年龄';
添加完,再查看一下表结构:
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(100) DEFAULT NULL COMMENT '姓名',
`age` int NOT NULL DEFAULT '0' COMMENT '年龄',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';
这不是添加成功了吗?有什么呀!
是的,线下数据库怎么整都行,但是如果在线上数据库这样操作,整个服务都有宕机的风险!自己也离毕业不远了。
不是危言耸听,我们找个case测试一下:
- Session1启动了一个事务,没有提交。
- Session2执行添加列的操作,被阻塞。
- 更严重的是,Session3执行简单查询的语句也被阻塞了。
2. 线上服务宕机的原因
为什么会出现这种情况呢?
原因是在执行查询语句的时候,MySQL自动加了MDL锁(metadata lock,即元数据锁)。
不行的话,我们可以再执行一下show processlist命令,查看有哪些正在执行的进程:
可以清楚的看到Session2和Session3的语句正在等待MDL锁,Waiting for table metadata lock。
MDL锁的作用是什么?
为了保证并发操作下数据的一致性。
如果一个事务正在执行中,另一个在这时修改了表结构,不但可能导致当前事务出现不可重复读的问题,还有可能连事务都无法提交。
什么时候会加MDL锁?
MDL锁是MySQL自动隐式加锁,无需我们手动操作。
在我们执行DDL语句的时候,MySQL自动添加MDL读锁。
在我们执行DML语句的时候,MySQL自动添加MDL写锁。
读锁与读锁之间不互斥,读锁与写锁、写锁与写锁之间互斥。
注意:MDL锁是表锁,会对整张表加锁。
普及额外的小知识点,什么是DML和DDL:
DML(Data Manipulation Language)数据操纵语言:
适用范围:对表数据进行操作,比如 insert、delete、select、update等。
DDL(Data Definition Language)数据定义语言:
适用范围:对表结构进行操作,比如create、drop、alter、rename、truncate等。
3. 如何优雅的给线上表加字段
既然修改表结构的时候,MySQL会自动添加表锁,并且是写锁,会阻塞后续的所有读写请求,造成非常严重的后果。
还有没有办法能优雅的给线上表添加字段呢?
当然有,从MySQL5.6版本开始增加了Online DDL,作用就是在执行DDL的时候,允许并发执行DML。简单翻译就是修改表结构的时候,也能同时支持并发执行增删查改操作。
从MySQL8.0版本开始又优化了Online DDL,支持快速添加列,可以实现给大表秒级加字段。
具体用法就是在DDL语句后面增加两个参数ALGORITHM和LOCK。
比如下面这样:
ALTER TABLE `user` ADD `age` int NOT NULL DEFAULT '0' COMMENT '年龄',
ALGORITHM=Inplace,
LOCK=NONE;
这两个参数分别是干嘛用的?有哪些选项呢?
ALGORITHM可以指定使用哪种算法执行DDL,可选项有:
Copy:
拷贝方式,MySQL5.6 之前 DDL 的执行方式,过程就是先创建新表,修改新表结构,把旧表数据复制到新表,删除旧表,重命名新表。执行过程非常耗时,产生大量的磁盘IO和占用CPU,还有使Buffer poll失效,而且需要锁住旧表,性能较差,现在基本很少使用。
Inplace:
原地修改,MySQL5.6开始引入的,优点是不会在Server层发生表数据拷贝,过程中允许并发执行DML操作。过程就是先添加MDL写锁,执行初始化操作,然后降级为MDL读锁,执行DDL操作(比较耗时,允许并发执行DML操作),升级为MDL写锁,完成DDL操作。
Instant:
快速修改,MySQL8.0开始引入的,可以实现快速给大表添加字段。
性能依次是,Instant > Inplace > Copy。
LOCK可以指定执行过程中,是否加锁,可选项有:
NONE
不加锁,允许DML操作。
SHARED
加读锁,允许读操作,禁止DML操作。
DEFAULT
默认锁模式,在满足DDL操作前提下,默认锁模式会允许尽可能多的读操作和DML操作。
EXCLUSIVE
加写锁,禁止读操作和DML操作。
Online DDL并不是支持所有DDL操作,看一下到底支持哪些操作?
操作 | Instant | Inplace | Rebuilds Table | 允许并发DML | 仅修改元数据 |
---|---|---|---|---|---|
添加列 | Yes | Yes | No | Yes | No |
删除列 | No | Yes | Yes | Yes | No |
重命名列 | No | Yes | No | Yes | Yes |
更改列顺序 | No | Yes | Yes | Yes | No |
设置列默认值 | Yes | Yes | No | Yes | Yes |
更改列数据类型 | No | No | Yes | No | No |
设置VARCHAR列大小 | No | Yes | No | Yes | Yes |
删除列默认值 | Yes | Yes | No | Yes | Yes |
更改自动增量值 | No | Yes | No | Yes | No |
设置列为null | No | Yes | Yes | Yes | No |
设置列not null | No | Yes | Yes | Yes | No |
像最常见的添加列就可以使用Instant,而像删除列、重命名列、更改列数据类型就只能使用Inplace了。
线上服务宕机,码农试用期被毕业,原因竟是给MySQL加个字段的更多相关文章
- 最近两周我们接触到的两种线上抓娃娃机的技术实现方案(一种RTSP/一种RTMP)
线上抓娃娃机需求 最近线上抓娃娃机的项目火爆了,陆陆续续几十款线上抓娃娃机上架,还有一大波正在开发上线中,各大视频云提供商都在蹭热度发布自己的线上抓娃娃机方案,综合了一下,目前线上抓娃娃机的视频需求无 ...
- 记-ItextPDF+freemaker 生成PDF文件---导致服务宕机
摘要:已经上线的项目,出现服务挂掉的情况. 介绍:该服务是专门做打印的,业务需求是生成PDF文件进行页面预览,主要是使用ItextPDF+freemaker技术生成一系列PDF文件,其中生成流程有:解 ...
- 线上服务的FGC问题排查,看这篇就够了!
线上服务的GC问题,是Java程序非常典型的一类问题,非常考验工程师排查问题的能力.同时,几乎是面试必考题,但是能真正答好此题的人并不多,要么原理没吃透,要么缺乏实战经验. 过去半年时间里,我们的广告 ...
- 记一次线上服务CPU 100%的处理过程
告警 正在开会,突然钉钉告警声响个不停,同时市场人员反馈客户在投诉系统登不进了,报504错误.查看钉钉上的告警信息,几台业务服务器节点全部报CPU超过告警阈值,达100%. 赶紧从会上下来,SSH登录 ...
- 糟了,线上服务出现OOM了
前言 前一段时间,公司同事的一个线上服务OOM的问题,我觉得挺有意思的,在这里跟大家一起分享一下. 我当时其实也参与了一部分问题的定位. 1 案发现场 他们有个mq消费者服务,在某一天下午,出现OOM ...
- Linux(2)---记录一次线上服务 CPU 100%的排查过程
Linux(2)---记录一次线上服务 CPU 100%的排查过程 当时产生CPU飙升接近100%的原因是因为项目中的websocket时时断开又重连导致CPU飙升接近100% .如何排查的呢 是通过 ...
- 由Redis的hGetAll函数所引发的一次服务宕机事件
昨晚通宵生产压测,终于算是将生产服务宕机的原因定位到了,心累.这篇博客,算作一个复盘和记录吧... 先来看看Redis的缓存淘汰算法思维导图: 说明:当实际占用的内存超过Redis配置的maxmemo ...
- 线上服务CPU100%问题快速定位实战
功能问题,通过日志,单步调试相对比较好定位. 性能问题,例如线上服务器CPU100%,如何找到相关服务,如何定位问题代码,更考验技术人的功底. 58到家架构部,运维部,58速运技术部联合进行了一次线上 ...
- 线上服务内存OOM问题定位[转自58沈剑]
相信大家都有感触,线上服务内存OOM的问题,是最难定位的问题,不过归根结底,最常见的原因: 本身资源不够 申请的太多 资源耗尽 58到家架构部,运维部,58速运技术部联合进行了一次线上服务内存OOM问 ...
随机推荐
- Unity3D学习笔记10——纹理数组
目录 1. 概述 2. 详论 2.1. 实现 2.2. 注意 3. 参考 1. 概述 个人认为,纹理数组是一个非常有用的图形特性.纹理本质上是一个二维的图形数据:通过纹理数组,给图形数据再加上了一个维 ...
- sql语句实现每日资格设置
CREATE TABLE 'iDayAuth'( 'openid' VARCHAR(16) NOT NULL , 'iStamp' INT(10) NOT NULL, 'iDayAuth' SMALL ...
- javascript引用奇趣
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 奇技淫巧玄妙无穷| M1 mac os(苹果/AppleSilicon)系统的基本操作和设置
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_191 最近有个朋友跟我说,说他新入职了一家公司,公司还不错,给他配了一台Mac,但是呢他以前一直在Windows环境下开发,对Ma ...
- DP选讲
$DP$选讲直接上题吧放个题单[各省省选DP](https://www.luogu.com.cn/training/151079)$P5322[BJOI2019]$排兵布阵一眼题,考虑$dp[i][j ...
- 一键到位「GitHub 热点速览 v.22.32」
作者:HelloGitHub-小鱼干 上上周在 B 站观看了智能键盘--瀚文的制作过程,本周 GitHub 热榜上出现了它的软硬件开源项目 HelloWord-Keyboard,如果你的动手能力强不妨 ...
- 前端须知的 Cookie 知识
文章已收录到我的 GitHub 中,欢迎 star cookie 是什么和使用场景 cookie 是服务器端保存在浏览器的一小段文本信息,浏览器每次向服务器端发出请求,都会附带上这段信息(不是所有都带 ...
- React报错之Expected `onClick` listener to be a function
正文从这开始~ 总览 当我们为元素的onClick属性传递一个值,但是该值却不是函数时,会产生"Expected onClick listener to be a function" ...
- Jira使用浅谈篇一
本篇参考: https://www.jianshu.com/u/9dd427d9ad94 Salesforce 生命周期管理(二)Agile & Scrum 浅谈 我们都知道 salesfor ...
- [SDOI2017]序列计数 (矩阵加速,小容斥)
题面 Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数. Alice还希望,这n个数中,至少有一个数是质数. Alice想知道,有多少个序列满足她的要求 ...