mysql 大表如何ddl

news2024/12/23 5:22:59

大家好,我是蓝胖子,mysql对大表(千万级数据)的ddl语句,在生产上执行时一定要千万小心,一不小心就有可能造成业务阻塞,数据库io和cpu飙高的情况。今天我们就来看看如何针对大表执行ddl语句。

通过这篇文章,你能了解到下面的知识点,

Pasted image 20230831165346.png

传统ddl 和online ddl的区别

mysql的ddl 经过了几个版本的演进,Online DDL这个特性是在MySQL5.6.7开始支持,在此之前mysql执行ddl语句时,会生成新表,然后将原表数据复制到新表,整个过程是会阻塞DML语句的。

online ddl 定义其实就是在执行ddl语句时,不会阻塞dml语句,那么我们就称这样的ddl为online ddl

ddl 的算法参数选项又分为 copy, Inplace, INSTANT ,其中copy就是之前传统ddl执行的过程,会阻塞dml语句。Inplace, INSTANT 算法执行期间 都是可以执行DML语句的,所以我们称使用这两种算法的ddl语句为online ddl。

📢📢 但需要注意的是,并不是所有的ddl操作都支持这两种算法,具体什么ddl操作类型支持什么算法需要去查阅官方文档。

INSTANT 算法是mysql8.0 以后新加的,它能在秒级别对千万级别的大表进行加字段操作,至于其他ddl 语句类型是不是也支持INSTANT 算法,需要去看下官网了,由于我们线上还是使用的mysql5.7 ,所以我还是会给予mysql5.7去进行分析。

在mysql5.7中,例如我们执行下面的ddl 加字段的语句,

ALTER TABLE tbl_name ADD COLUMN column_name column_definition

mysql会去判断当前执行的ddl语句类型能不能用online ddl inplace 方式,如果能用,那么它就会采用。

使用Inplace算法的ddl语句,执行过程分为3个阶段,

阶段1: Initialization初始化

在初始化阶段,服务器将考虑存储引擎功能、语句中指定的操作以及用户指定的ALGORITHM和LOCK选项,确定操作期间允许多少并发性。在此阶段,使用一个可升级MDL读锁来保护当前表定义。

阶段2:Execution执行

如果评估阶段发现ddl语句不能使用inplace算法,则会将mdl读锁升级为排它锁,阻塞DML语句执行。并且,这个阶段,会真正的执行ddl语句。

阶段3:Commit Table Definition 提交表定义

在提交表定义阶段,MDL读锁升级为MDL排他锁,以排除旧表定义并提交新表定义。一旦授予,独占MDL锁的持续时间就会很短。

可以看到如果使用inplcae 算法,只有在任务提交阶段(时间很短), ddl才会阻塞dml语句,因为任务提交阶段会持有MDL 排他锁,而DML 语句执行时需要获取MDL读锁,所以在此期间,DML语句会被阻塞。

具体哪些ddl操作类型支持Inplace 算法,可以查看官方文档链接,比如下面的mysql5.7的文档

https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html

如下图所示,可以发现mysql5.7对加字段的ddl 支持inplace 算法,不过执行期间需要rebuild table即建立新表,并且运行并发的dml语句执行。但是改变字段数据类型ddl,则只能按copy算法进行执行。

inplace 算法不是不会产生数据的复制,只是复制期间,不会阻塞dml语句的执行。

Pasted image 20230831173151.png

mysql ddl 的陷阱

online ddl机制是否一定不会阻塞业务?

接着我们来看下ddl时使用inplcae 算法(online ddl)是不是一定不会阻塞业务,其实答案是显而易见的,业务也有可能阻塞,因为online ddl 在提交表定义阶段是会获取MDL排他锁的,如果有其他事务获取了MDL读锁,那么online ddl 语句也会阻塞住,从而导致发生在ddl语句执行时间点后面的那些需要获取MDL锁的sql阻塞掉。具体的操作例子可以查看mysql官方给出的一个例子,

https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-performance.html

Pasted image 20230901163914.png

ddl 过程中从库的延迟性

ddl的第二个陷阱是要注意从库的延迟性,比如mysql5.7加新列,虽然默认可以使用inplace算法来让dml语句不阻塞,但是建立新列还是需要表的rebuild操作,如果是大表,整个过程还是很慢的,如果从库只开启了一个线程去执行主从复制,就会导致主从库间出现极大的延迟。

解决办法是开启并行复制,可以用下面的语句在从库上执行,查看从库是否开启了并行复制

SHOW VARIABLES LIKE 'slave_parallel_workers';

online ddl Duplicate entry…错误

虽然使用inplace算法的ddl (online ddl) 可以不阻塞业务操作,但是在大表上执行时,由于ddl过程比较长,还是有可能会出现Duplicate entry 错误。下面我来介绍下它出现的场景,比如一张几千万的表,里面有一个唯一键,在add column ddl期间,对表进行插入,并且插入的值刚好就触发了唯一键约束。那么最后ddl再快完成的时候就会出现这个错误。

这是由于add column ddl期间,会发生表的rebuild,相当于新建一个临时表然后对旧表进行拷贝,但是ddl期间还是允许业务修改,插入数据,所以online ddl将执行期间新的修改记录到一个叫做row_log的对象里,在ddl最后阶段,将mdl锁升级为排它锁,然后将row_log对象中的数据和新表的数据进行合并,这样就达到了ddl期间兼容dml操作的目的。

但是应用row log的过程是不允许报错,如果期间发生了报错就会导致ddl回滚,因为在ddl期间,记录了相同唯一键的数据,所以在应用row log的时候,产生了报错。

官方也给出了online ddl 报错的场景,连接如下

https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-failure-conditions.html

其实我认为本质原因是mysql5.7 执行add column 的ddl时间还是太长了,在这么长时间里可能就会发生业务对相同唯一键的插入操作,如果能缩短ddl执行时间应该就能很大程度避免这种问题。

mysql8.0 在add column 时可以采用instance 算法,能达到秒级别的加新字段的操作,理论上可以避免这个错误。

如果不是mysql8.0 ,又想对千万级的大表添加字段,又要避免Duplicate entry 错误,那么可以使用pt-online-schema-change这个工具。

pt-online-schema-change 工具进行字段添加

下面我就来简单的介绍下pt-online-schema-change,它对表结构的修改原理是创建一张新表(拥有最新的表定义),然后在旧表上创建delete,update,insert的触发器,来对增量数据进行更新,对旧表数据采取insert ignore 新表 select 老表 LOCK S 的方式进行分块拷贝,最后拷贝完成后,在一个事务里对旧表进行删除,新表进行重命名,这样就完成了对表结构的变更。

同时在变更期间,你能够通过下面的参数控制从库延迟

  • –max-lag
    • 默认1s
    • 检查从库延迟的时间,如果超过,则停止copy data,休息–check-interval秒后,再重新开始copy数据
    • 查看通过延迟时间,是通过从库show slave status,查看Seconds_Behind_Master
    • 如果指定–check-slave-lag,该工具只检查该服务器的延迟,而不是所有服务器。
  • –check-interval
    • 从库延迟超过指定的–max-lag,中断copy data休息的时间
    • 默认为1s

下面是pt-online-schema-change 语句执行的完整示例,它同时会列出拷贝过程完成的百分比。

pt-online-schema-change --alter "add pkg_source tinyint(2) default 0 not null;" h=主机ip,P=端口,p=密码,u=用户名,D=数据库名,t=表明  --recursion-method=none  --execute --statistics

如果你的ddl需要拷贝表,那么用pt-online-schema-change 工具再合适不过了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/974635.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

射频功率放大器的指标有哪些内容

射频功率放大器是射频系统中至关重要的组件,用于放大射频信号的功率。本文将详细介绍射频功率放大器的指标,包括功率增益、带宽、线性度、效率、稳定性等关键指标。 一、功率增益 功率增益是射频功率放大器最基本的指标之一,表示放大器将输入…

FaceChain应用生态爆发?无限可能的人物应用等你加入探索!

1 核心功能进展 在过去的不到一个月,FaceChain开源项目从无到有,成功突破了相关技术瓶颈,GitHub(GitHub - modelscope/facechain: FaceChain is a deep-learning toolchain for generating your Digital-Twin.)获得了…

松下GF9使用心得

文章目录 规格参数关键特征USB接口充电功能旋转显示屏WiFi直连4K拍摄和后对焦模式 快速指南机身按键及功能拍摄模式屏显信息拍摄时回放时 菜单列表拍摄菜单动态影像菜单自定义菜单设置菜单回放菜单 核心功能拍摄模式智能自动模式程序 AE 模式、光圈优先 AE 模式、快门优先 AE 模…

恒运资本:股市涨跌如何预测?如何避免股价的泡沫?

股市的涨跌受到多种要素影响,其直接关系到投资者的收益。那么股市涨跌怎么猜测?怎么防止股价的泡沫?恒运资本也为我们准备了相关内容,以供参阅。 股市涨跌怎么猜测? 股市涨跌具有不确定性,没有方法能够确保…

vue基于Echarts、百度地图MapVGL实现可视化大屏数据展示

一、布局 常见的大屏数据展示布局&#xff0c;一般会将地图作为整个屏幕的背景&#xff0c;在地图上以九宫格布局展示各类数据图表。实现这一效果可以使地图的z-index1,在地图上的图表等z-index>1,下面会详细描述这种设计该如何实现&#xff1a; <div style"width…

如何通过构建遥感光谱反射信号与地表参数之间的关系模型来准确估算植被参数?植被参数光学遥感反演方法(Python)及遥感与生态模型数据同化算法

目录 专题一 植被参数遥感反演理论 专题二 植被叶片及冠层反射率模拟与处理 专题三 植被遥感模型参数敏感性分析 专题四 基于查找表(LUT)方法反演植被参数 专题五 基于优化算法反演植被参数 专题六 基于机器学习反演植被参数 专题七 遥感数据同化理论 专题八 同化遥感反…

浅谈一下酒吧和酒馆的不同

相信有很多朋友还不怎么清楚酒吧和酒馆的区别是什么&#xff0c;这里为大家简单介绍一下两者的不同&#xff0c;个人见解&#xff0c;如有错漏&#xff0c;欢迎指出。一、首先是他们的经营范围不同酒馆经营通常包含酒水和餐饮&#xff0c;适合朋友聚会或者是和商业伙伴聊天。而…

/etc/ssh/sshd_config 配置文件中的 PasswordAuthentication PermitRootLogin 参数作用

1、PasswordAuthentication PasswordAuthentications是一种身份验证方式&#xff0c;通常用于远程服务器的登录。当用户连接到远程服务器并进行身份验证时&#xff0c;服务器会根据 用户名进行验证&#xff0c;如果验证成功允许用户访问服务器。在SSH中&#xff0c;PasswordAut…

Docker容器日志和宿主机的时间问题

容器与主机的时间 我们在部署完docker之后往往会发现&#xff0c;容器的时间和主机的时间其实是对不上的&#xff0c;因为宿主机设置了时区&#xff0c;而Docker容器并没有设置&#xff0c;导致Docker容器的时间和宿主机时间不同步&#xff0c;导致两者相差8小时。我们可以进入…

常用命令之mysql命令之show命令

一、mysql show命令简介 mysql数据库中show命令是一个非常实用的命令&#xff0c;SHOW命令用于显示MySQL数据库中的信息。它可以用于显示数据库、表、列、索引和用户等各种对象的信息。我们常用的有show databases&#xff0c;show tables&#xff0c;show full processlist等&…

KreadoAI:国产免费用的AI数字人视频工具

hi&#xff0c;同学们&#xff0c;我是赤辰&#xff0c;本期是赤辰第4篇AI工具类教程&#xff0c;文章底部准备了粉丝福利&#xff0c;看完可以领取&#xff01; 今天来给大家分享一个可以免费生成虚拟数字人视频的网站。操作简单&#xff0c;一学就会&#xff0c;你也可以很方…

typescript 支持与本地调试

typescript 支持与本地调试 typescript 支持与本地调试 前言支持 typescript函数的本地调试 启用 node-terminal 调试invoke localserverless-offline Next Chapter完整示例及文章仓库地址 前言 在上一章节&#xff0c;我们创建了一个 hello world 函数&#xff0c;并把它顺…

用「渣男」心态去面试,爽翻!

转载自博学谷公众号&#xff01; 面试是一场“销售”自己的考试&#xff0c;很多程序员掌握的技术、知识都非常过关&#xff0c;但在面试中却不能完全展现出来&#xff0c;屡屡发挥失常。 同样是天选打工人 别人的offer&#xff0c;像猴子摘苞谷&#xff0c;应接不暇 而你的of…

双亲委派机制的作用

文章目录 类加载过程一、java有哪些类加载器&#xff1f;二、双亲委派机制自定义String类 总结 类加载过程 先简单说一下java的类加载器 类加载器&#xff0c;顾名思义就是一个可以将Java字节码加载为java.lang.Class实例的工具。这个过程包括&#xff0c;读取字节数组、验证…

喜讯!Cancer Res(IF:11.2)发表胃癌PICH的转录调控机制

2023年8月30日&#xff0c;兰州大学第二医院焦作义教授团队在肿瘤学Top期刊Cancer Research&#xff08;IF:11.2&#xff09;发表“PICH activates Cyclin A1 transcription to drive S-phase progression and chemoresistance in gastric cancer”的研究论文。该研究鉴定了SNF…

框架分析(9)-Hibernate

框架分析&#xff08;9&#xff09;-Hibernate 专栏介绍Hibernate特性对象关系映射&#xff08;ORM&#xff09;数据库连接和事务管理查询语言&#xff08;HQL&#xff09;缓存机制透明的持久化操作对象的延迟加载事务管理 优缺点优点简化数据库操作跨数据库平台高度可定制性缓…

设置 Hue Server 与 Hue Web 界面之间的会话超时时间

设置 Hue Server 与 Hue Web 界面之间的会话超时时间 在 CDH 的 Hue 中&#xff0c;Auto Logout Timeout 参数表示用户在不活动一段时间后将自动注销&#xff08;登出&#xff09;的超时时间。当用户在 Hue 中处于不活动状态超过该设定时间时&#xff0c;系统将自动注销用户&am…

深度学习入门教学——代价敏感学习

1、背景 常用于分类器性能评估的指标为&#xff1a;准确率或错误率&#xff0c;也就是代价不敏感学习。【注】代价&#xff1a;一个类别被错误分类到其他类别的惩罚&#xff08;也称为权重&#xff09;。代价不敏感学习的前提是&#xff1a; 不同类的误分类代价相同。用于学习…

【力扣周赛】第 112 场双周赛

文章目录 竞赛链接Q1&#xff1a;7021. 判断通过操作能否让字符串相等 IQ2&#xff1a;7005. 判断通过操作能否让字符串相等 II&#xff08;贪心&#xff09;Q3&#xff1a;2841. 几乎唯一子数组的最大和竞赛时代码——滑动窗口 Q4&#xff1a;8050. 统计一个字符串的 k 子序列…

小白学go基础05-变量声明形式

和Python、Ruby等动态脚本语言不同&#xff0c;Go语言沿袭了静态编译型语言的传统&#xff1a;使用变量之前需要先进行变量的声明。 变量声明形式使用决策流程图 这里大致列一下Go语言常见的变量声明形式&#xff1a; var a int32 var s string "hello" var i 13 …