MySQL训练营-DDL性能问题

news/2025/3/11 2:52:08/文章来源:https://www.cnblogs.com/cnyuyang/p/18759456

DDL类型

copy/inplace/instant 复制、原地、即时

copy复制算法

原理

Copy 算法在执行 DDL 操作时,会创建一个新的临时表,该临时表具有修改后的表结构。然后将原表中的数据逐行复制到新的临时表中。复制完成后,删除原表,并将临时表重命名为原表的名称。

优点

兼容性好:几乎可以处理所有类型的 DDL 变更,不受存储引擎内部机制的限制。因为它是通过创建新表来实现结构变更,所以对各种复杂的变更场景都能很好地支持。

数据一致性高:在复制数据的过程中,可以保证数据的完整性和一致性。即使在复制过程中出现错误,也可以很方便地回滚操作,不会影响原表的数据。

缺点

性能开销大:需要额外的磁盘空间来存储临时表,并且数据复制过程会消耗大量的 I/O 和 CPU 资源。如果表的数据量非常大,复制操作可能会花费很长时间,导致数据库在操作期间性能严重下降。

锁表时间长:在复制过程中,通常需要对原表加锁,以防止数据的不一致。这会导致其他用户无法对原表进行读写操作,影响数据库的可用性。

适用场景

当需要进行复杂的表结构变更,而存储引擎不支持其他更高效的方式时,可以使用 Copy 算法。例如,在某些情况下需要修改表的字符集、添加或删除大字段等。

如要进行一个新增列操作,那么进行的流程为:

  1. 复制一个相同表结构的新表#sql-...,对新表进行DDL操作,将原表中的数据复制过去

  2. 删除原表

  3. #sql-...名字修改回T

use mysql;
drop table if exists users;
create table users(id int, age int);
insert into users(id,age) values(1,1),(2,2),(3,3);

修改DDL语句:ALTER TABLE users MODIFY COLUMN id INT PRIMARY KEY AUTO_INCREMENT;

课堂练习

  1. space id会不会变?

在 InnoDB 存储引擎里,数据和索引存储在表空间中,每个表空间都有一个与之对应的 SPACE ID。表空间可以是共享的(多个表共享一个表空间),也可以是独立的(每个表有自己单独的表空间),SPACE ID 能帮助 MySQL 准确地定位和管理这些表空间。

会变

修改前SPACE为22:

mysql> SELECT *  FROM INFORMATION_SCHEMA.innodb_tables WHERE NAME = 'mysql/users';
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
| TABLE_ID | NAME        | FLAG | N_COLS | SPACE | ROW_FORMAT | ZIP_PAGE_SIZE | SPACE_TYPE | INSTANT_COLS | TOTAL_ROW_VERSIONS |
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
|     1095 | mysql/users |   33 |      5 |    22 | Dynamic    |             0 | Single     |            0 |                  0 |
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
1 row in set (0.00 sec)

修改后SPACE为23:

mysql> SELECT *  FROM INFORMATION_SCHEMA.innodb_tables WHERE NAME = 'mysql/users';
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
| TABLE_ID | NAME        | FLAG | N_COLS | SPACE | ROW_FORMAT | ZIP_PAGE_SIZE | SPACE_TYPE | INSTANT_COLS | TOTAL_ROW_VERSIONS |
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
|     1089 | mysql/users |   33 |      6 |    23 | Dynamic    |             0 | Single     |            0 |                  0 |
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
1 row in set (0.00 sec)
  1. rows_examined是多少?

可以看到执行sql后的提示显示,影响了3行。

mysql> ALTER TABLE users MODIFY COLUMN id INT PRIMARY KEY AUTO_INCREMENT;
Query OK, 3 rows affected (0.07 sec)
Records: 3  Duplicates: 0  Warnings: 0
  1. 中间删除表后,select语句是否会报表不存在的错?

不会,应该是元数据锁?

inplace原地算法

静态添加索引c,加索引过程中不进行业务的DML。

该过程需要对

课堂练习

  1. space id会不会变?

不会

  1. rows_examined是多少?

N,需要读取数据

全程a.ibd需要加锁,只能读不能写

动态添加索引c,加索引过程中同步进行业务的DML。

alter_log应用到构建后的a.ibd需要加锁,只能读不能写。其他时间不加

与之相关存在系统参数:innodb_online_alter_log_max_size。若达到最大值,会发生回滚。

新索引紧凑吗?

不紧凑,因为应用alter_log顺序是不固定的。为了避免该场景,mysql会为每个page页面预留空间。

instant即时算法

相关资料:https://www.cnblogs.com/huaweiyun/p/18464467

直接修改元数据,如添加一列:alter table users add x int;

如果是小表的话,可能会看不到效果。

修改前:

mysql> SELECT *  FROM INFORMATION_SCHEMA.innodb_tables WHERE NAME = 'mysql/users';
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
| TABLE_ID | NAME        | FLAG | N_COLS | SPACE | ROW_FORMAT | ZIP_PAGE_SIZE | SPACE_TYPE | INSTANT_COLS | TOTAL_ROW_VERSIONS |
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
|     1099 | mysql/users |   33 |      5 |    33 | Dynamic    |             0 | Single     |            0 |                  0 |
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
1 row in set (0.01 sec)

修改后:

mysql> alter table users add x int;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> SELECT *  FROM INFORMATION_SCHEMA.innodb_tables WHERE NAME = 'mysql/users';
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
| TABLE_ID | NAME        | FLAG | N_COLS | SPACE | ROW_FORMAT | ZIP_PAGE_SIZE | SPACE_TYPE | INSTANT_COLS | TOTAL_ROW_VERSIONS |
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
|     1100 | mysql/users |   33 |      6 |    34 | Dynamic    |             0 | Single     |            0 |                  0 |
+----------+-------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
1 row in set (0.00 sec)

所以应该使用大表做测试,所以可以参考《MySQL训练营-准备阶段》的内容,导入tpch的数据进行测试。可以对其中的lineitem表进行加列测试:alter table lineitem add x int;

即使这样还是走不了instant算法,即使制定算法也不行,不知道是不是mysql的bug:

mysql> alter table lineitem add x int,ALGORITHM=INSTANT;
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY/INPLACE.

instant DDL语句有没有可能执行时间很长(比如超过1分)?

session1 session2 session3
begin;
select * from t limit 1;
alter table t add g int; //现象?
select * from t limit 1; //现象?

1、session2执行alter table t add g int;语句会被堵住,因为session1会获取MDL

2、select * from t limit 1;也会被堵住,它需要获取表 tMDL 读锁。然而,由于第二个会话正在等待获取 MDL 写锁,MySQL 为了保证操作的顺序和一致性,不会让第三个会话获取 MDL 读锁,因此第三个会话也会被阻塞,直到第二个会话获取到 MDL 写锁并完成操作,或者第一个会话释放 MDL 读锁。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Manus邀请码,Manus:科技圈新“炸点”,还是又一场狂欢?

2025年3月6日,AI圈被一款名为Manus的产品“炸醒”。这款由Monica团队开发的AI Agent,在短短4分钟的视频中展示出强大的功能,如旅行规划、股票分析、教育内容创建等,仿佛预示着一个新时代的到来。 嗨,大家好,我是小华同学,关注我们获得“最新、最全、最优质”开源项目和…

C# DataTable Merge() 合并DataTable

如果两个表具有不同的结构,则会在原有结构上保留新的架构:dt.Merge(dt2); 使用Add方法时,新表(dt2)的列数不能大于原表(dt)的列数,否则运行时会报错。(可以少于原表列数)dt.Rows.Add(dt2.Rows[0].ItemArray)

VS大型CPP项目调试,Debug模式,Release模式,附加到进程模式

windows下vs调试大型cpp项目,exe,dll,lib,debug模式调试,release模式调试,附加到进程调试,一文搞定visual studio 项目一览 以开源项目 cloudcompare 为例,一个大型项目 肯定会有很多模块,每个模块 根据需求 生成 dll 库 或者 lib 库主程序dll 库lib库debug 模式调试 …

ARC191 ~ 193 题解

ARC191 题解 A - Replace Digits简要题意给定一个长为 \(n\) 的字符串 \(a\)。\(m\) 次操作,第 \(k\) 次给定一个字符 \(b_k\),你需要选择一个 \(i \in [1, n]\) 并将 \(a_i\) 替换成 \(b_k\)。 求最后能得到的所有字符串中,字典序最大的是什么。 \(1 \leq n, m \leq 10^6\)…

物理机安装archLinux

从官网下载镜像并通过up启动成功联网后 一、基础配置 1.设置时间 查看时间 timedatectl status 如果时间不对 timedatectl set-ntp true 如果时区不对 timedatectl set-timezone Asia/Shanghai2.磁盘分区 对于 UEFI 需要至少创建三个分区(efi、swap、根)格式化分区 根分区mk…

Maven踩坑记录与反思

本次事件的发生是在我来到一个新的技术初创团队,由于团队中的前同事与我交接代码时候,关于Maven私服这块的账号密码为给我,导致一系列的爱恨情仇。事件的持续花费两天时间进行解决,现在总结一下遇到的问题与解决思路!回顾Mavenue的背景 关于Maven,维基百科给的解释主要有…

解决pyechart模块绘制地图无数据

在绘制地图发现没有数据错误原因: 传入数据中的省份名称不规范 例如: data = [("北京", 99),("上海", 199),("湖南", 299),("台湾", 399),("广东", 499) ]解决办法: 使用此函数,把传入地图的数据传入函数进行处理(返回规…

2025.3.8 考试记录

省流:炸完了!!! 7:35 开考,7:37开始看题。 先看一眼题,没有 DS ,那完了。 按照惯例先试着冲一下 T1 。 有点像二分图最大匹配的题,记不住怎么建图了,睡觉。 T2 是个树上最优解问题,似乎可以冲?先放在一边等着吧。 T3 是序列上的一个问题,序列上的找一个区间 min …

Ubuntu24.04安装Cherry Studio记录

1. 官网下载安装包 在Cherry Studio官网获取Appimage安装包 2. 修改运行权限 下载结束后终端输入chmod 777 AppImage文件路径修改Appimage文件权限为可执行文件。 3. 下载FUSE 直接运行./Cherry-Studio-1.0.6-x86_64.AppImage,发现类似报错:Need to install FUSE 打开FUSE的G…

两块滤膜

“部长通道”上,生态环境部部长掏出了两块滤膜 央视一套2025年03月08日 14:53 北京 ⇧点蓝色字关注“央视一套” 今天(8日),第十四届全国人民代表大会第三次会议第二场“部长通道”集中采访活动举行。生态环境部部长黄润秋、水利部部长李国英、农业农村部部长韩俊接受了媒体…

Windows编程----进程:环境变量

什么是系统环境变量 每台计算机针对当前用户和系统中所有用户分别提供了两个环境变量设置,通过计算机属性>环境变量的界面,我们可以查看当前这台计算机上的所有环境变量,这些环境变量都是key-value键值对。具体如下:上面看到的环境变量其实是存储在注册表中的, 系统环境…

软工作业二:个人项目

| 这个作业属于哪个课程 | 软件工程 | | 这个作业要求在哪里 | 作业要求 | | 这个作业的目标 | 设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。 | 一、使用说明📝 1.使用环境:c++;Visual studio 20…