MySQL Tutorial이 칼럼에서는 MySQL 및 MariaDB 온라인 DDL을 소개하고 안내합니다.
![참조 가이드: MySQL 및 MariaDB 온라인 DDL](https://img.php.cn/upload/article/000/000/052/7fcd6505ac9a795d872f742ae10dd1c4-0.jpg)
개요
초기 MySQL 버전에서는 DDL 작업(예: 인덱스 생성 등)을 수행하려면 일반적으로 데이터 테이블 잠금이 필요하며 작업 중에 DML 작업이 차단되어 정상적인 비즈니스에 영향을 미칩니다. MySQL 5.6 및 MariaDB 10.0은 DML의 정상적인 실행에 영향을 주지 않고 DDL 작업을 수행할 수 있는 온라인 DDL을 지원하기 시작합니다. 온라인에서 DDL 작업을 직접 실행하는 것은 기본적으로 사용자에게 보이지 않습니다(일부 작업은 성능에 영향을 미칩니다).
다양한 데이터베이스 버전에 따라 다양한 DDL 문 지원에 일정한 차이가 있습니다. 이 문서에서는 DDL 작업을 수행해야 하는 경우 온라인 DDL 지원을 참조할 수 있습니다. 이 기사의 상황 부분.
이 기사는 계속 수정되고 업데이트될 예정입니다. 더 흥미로운 콘텐츠를 보려면 GITHUB의 프로그래머 성장 계획 프로젝트를 참조하세요.
ALTER TABLE
문에서 온라인 DDL은 ALGORITHM
및 LOCK
문을 통해 지원됩니다. ALTER TABLE
语句中,支持通过 ALGORITHM
和 LOCK
语句来实现 Online DDL:
-
ALGORITHM
- 控制 DDL 操作如何执行,使用哪个算法
-
LOCK
- 控制在执行 DDL 时允许对表加锁的级别
ALTER TABLE tab ADD COLUMN c varchar(50), ALGORITHM=INPLACE, LOCK=NONE;复制代码
로그인 후 복사
ALGORITHM 支持的算法
ALGORITHM |
说明 |
DEFAULT |
默认算法,自动使用可用的最高效的算法 |
COPY |
最原始的方式,所有的存储引擎都支持,不使用 Online DDL,操作时会创建临时表,执行全表拷贝和重建,过程中会写入 Redo Log 和大量的 Undo Log,需要添加读锁,非常低效 |
INPLACE |
尽可能避免表拷贝和重建,更确切的名字应该是 ENGINE 算法,由存储引擎决定如何实现,有些操作是可以立即生效的(比如重命名列,改变列的默认值等),但有些操作依然需要全表或者部分表的拷贝和重建(比如添加删除列、添加主键、改变列为 NULL 等) |
NOCOPY |
该算法是 INPLACE 算法的子集,用于避免聚簇索引(主键索引)的重建造成全表重建,也就说用该算法会禁止任何引起聚簇索引重建的操作
|
INSTANT |
用于避免 INPLACE
-
ALGORITHM - DDL 작업이 수행되는 방식과 사용되는 알고리즘을 제어합니다.
-
LOCK - DDL을 실행할 때 허용되는 테이블 잠금 수준을 제어합니다.
ALTER TABLE tbl_name [WAIT n|NOWAIT] ...CREATE ... INDEX ON tbl_name (index_col_name, ...) [WAIT n|NOWAIT] ...DROP INDEX ... [WAIT n|NOWAIT]DROP TABLE tbl_name [WAIT n|NOWAIT] ...LOCK TABLE ... [WAIT n|NOWAIT]OPTIMIZE TABLE tbl_name [WAIT n|NOWAIT]RENAME TABLE tbl_name [WAIT n|NOWAIT] ...SELECT ... FOR UPDATE [WAIT n|NOWAIT]SELECT ... LOCK IN SHARE MODE [WAIT n|NOWAIT]TRUNCATE TABLE tbl_name [WAIT n|NOWAIT]复制代码 로그인 후 복사 로그인 후 복사
ALGORITHM 지원 알고리즘
ALGORITHM |
설명 th >
|
DEFAULT |
기본 알고리즘, 가장 효율적인 알고리즘을 자동으로 사용 |
COPY |
가장 독창적인 방식, 모든 저장 Online DDL을 사용하지 않는 경우 작업 중에 임시 테이블이 생성되고, 이 과정에서 전체 테이블 복사 및 재구성이 수행됩니다. 잠금을 추가해야 하는데 이는 매우 비효율적입니다. |
🎜 |
INPLACE🎜 |
테이블 복사 및 재구성을 최대한 피하세요. 보다 정확한 이름은 ENGINE 알고리즘이어야 합니다. 스토리지 엔진은 이를 구현하는 방법을 결정합니다. 일부 작업(예: 열 이름 바꾸기, 열 기본값 변경 등)은 여전히 전체 테이블 또는 테이블 일부를 복사하고 다시 작성해야 합니다. 열 추가 및 삭제, 기본 키 추가, 열을 NULL로 변경 등) 🎜🎜 |
NOCOPY🎜 |
이 알고리즘은 INPLACE 알고리즘의 하위 집합으로 사용됩니다. 전체 테이블을 재구성하는 클러스터형 인덱스(기본 키 인덱스)를 방지합니다. 즉, 이 알고리즘을 사용하면 클러스터형 인덱스 재구성이 금지됩니다. 🎜🎜🎜 |
INSTANT🎜 |
는 데이터 파일을 수정해야 할 때 INPLACE 알고리즘의 비정상적인 비효율성 문제를 피하기 위해 사용됩니다. 🎜관련된 모든 테이블 복사 및 재구축 작업은 금지됩니다🎜🎜🎜🎜🎜
NOCOPY 알고리즘 지원: NOCOPY 算法支持:MariaDB 10.3.2+,MySQL 不支持该算法。
INSTANT 算法支持:MariaDB 10.3.2+,MySQL 8.0.12+。
算法使用规则:
- 如果用户指定的算法为
COPY ,则 InnoDB 使用 COPY 算法。
- 如果用户指定的是
COPY 之外的其它算法,则 InnoDB 会按照算法效率,选择最高效的算法,最差的情况下采用用户指定的算法。比如用户指定了 ALOGRITHM = NOCOPY MariaDB 10.3.2 +, MySQL은 이 알고리즘을 지원하지 않습니다. ![ALGORITHM 优劣](https://img.php.cn/upload/article/000/000/052/1ad59f2d3ce895fe41b4e300dbd96e63-1.png)
INSTANT 알고리즘 지원: MariaDB 10.3.2+, MySQL 8.0.12+. 알고리즘 사용 규칙:
- 사용자가 지정한 알고리즘이
COPY 인 경우 InnoDB는 COPY 알고리즘을 사용합니다. - 사용자가
COPY 이외의 알고리즘을 지정하면 InnoDB는 알고리즘 효율성을 기준으로 가장 효율적인 알고리즘을 선택하며 최악의 경우에는 사용자가 지정한 알고리즘이 사용됩니다. 예를 들어, 사용자가 ALOGRITHM = NOCOPY 를 지정하면 InnoDB는 (NOCOPY, INSTANT)에서 지원되는 가장 효율적인 알고리즘을 선택합니다. ![참조 가이드: MySQL 및 MariaDB 온라인 DDL](https://img.php.cn/upload/article/000/000/052/1ad59f2d3ce895fe41b4e300dbd96e63-2.png)
MySQL 서비스는 크게 서버 레이어와 스토리지 엔진 레이어로 구성됩니다. 서버 레이어에는 MySQL의 핵심 기능 대부분과 모든 내장 기능, 스토어드 등의 크로스 스토리지 엔진 기능이 포함되어 있습니다. 프로시저 및 트리거, 보기 등 스토리지 엔진 계층은 데이터 저장 및 읽기를 담당하며 플러그인 아키텍처 모델을 채택합니다. ![INPLACE 算法执行过程](https://img.php.cn/upload/article/000/000/052/1ad59f2d3ce895fe41b4e300dbd96e63-3.png)
COPY 알고리즘은 서버 계층에서 작동하고 실행 프로세스는 서버 계층에서 이루어지므로 모든 스토리지 엔진은 이 알고리즘의 사용을 지원합니다. 실행 프로세스는 아래와 같습니다
INPLACE 알고리즘이 작동합니다. InnoDB 스토리지 엔진 고유의 DDL 알고리즘으로 실행 프로세스는 아래 그림과 같습니다 |
|
LOCK 전략
기본적으로 MySQL/MariaDB는 DDL 실행 중에 가능한 한 적은 잠금을 사용합니다. 필요한 경우 LOCK 절을 전달할 수 있습니다. DDL을 실행할 때 테이블에 허용되는 잠금 수준을 제어합니다. 지정된 작업에 필요한 제한 수준이 충족되지 않으면(EXCLUSIVE > SHARED > NONE) 문 실행이 실패하고 오류가 보고됩니다. |
|
Strategy | Description |
| DEFAULT | 현재 작업에서 지원하는 가장 작은 단위로 잠금 전략을 사용하세요.
| NONE | 어떤 테이블 잠금도 획득하지 말고 모든 D를 허용하세요. ML 작업
🎜 SHARED🎜🎜테이블에 공유 잠금(읽기 잠금)을 추가하면 읽기 전용 DML 작업만 허용됩니다.🎜🎜🎜🎜EXCLUSIVE🎜🎜테이블에 배타적 잠금(쓰기 잠금)을 추가하고 DML 작업은 허용되지 않습니다. 허용됨🎜🎜🎜🎜为了避免执行 DDL 时,由于锁表导致生产服务不可用,在执行表结构变更语句时,可以添加 LOCK=NONE 子句,如果语句需要获取共享锁或者排它锁,则会直接报错,这样就可以避免意外锁表,造成线上服务不可用了。
Online DDL 执行过程
Online DDL 操作主要分为三个阶段:
![Online DDL 执行过程](https://img.php.cn/upload/article/000/000/052/f7e4bce7573948c99b7e84fee997bb78-4.png)
-
阶段 1:初始化
在初始化阶段,服务器会根据存储引擎的能力,操作的语句和用户指定的 ALGORITHM 和 LOCK 选项来决定允许多大程度的并发。在这个阶段会创建一个 可升级的元数据共享锁(SU)来保护表定义。
-
阶段 2:执行
这个阶段会 准备 并 执行 DDL 语句,根据 阶段 1 评估的结果来决定是否将元数据锁升级为 排它锁 (X),如果需要升级为排它锁,则只在 DDL 的 准备阶段 短暂的添加排它锁。
-
阶段 3:提交表定义
在表定义的提交阶段,元数据锁会升级为排它锁来更新表的定义。独占排它锁的持续时间非常短。
元数据锁(참조 가이드: MySQL 및 MariaDB 온라인 DDL,Metadata Lock)主要用于 DDL 和 DML 操作之间的并发访问控制,保护表结构(表定义)的一致,保证读写的正确性。참조 가이드: MySQL 및 MariaDB 온라인 DDL 不需要显式的使用,在访问表时会自动加上。
![참조 가이드: MySQL 및 MariaDB 온라인 DDL](https://img.php.cn/upload/article/000/000/052/f7e4bce7573948c99b7e84fee997bb78-5.png)
由于上面三个阶段中对元数据锁的独占, Online DDL 过程必须等待已经持有元数据锁的并发事务提交或者回滚才能继续执行。
注意:当 Online DDL 操作正在等待元数据锁时,该元数据锁会处于挂起状态,后续的所有事务都会被阻塞。在 MariaDB 10.3 之后,可以通过添加 NO WAIT 或者 WAIT n 来控制等待所得超时时间,超时立即失败。
ALTER TABLE tbl_name [WAIT n|NOWAIT] ...CREATE ... INDEX ON tbl_name (index_col_name, ...) [WAIT n|NOWAIT] ...DROP INDEX ... [WAIT n|NOWAIT]DROP TABLE tbl_name [WAIT n|NOWAIT] ...LOCK TABLE ... [WAIT n|NOWAIT]OPTIMIZE TABLE tbl_name [WAIT n|NOWAIT]RENAME TABLE tbl_name [WAIT n|NOWAIT] ...SELECT ... FOR UPDATE [WAIT n|NOWAIT]SELECT ... LOCK IN SHARE MODE [WAIT n|NOWAIT]TRUNCATE TABLE tbl_name [WAIT n|NOWAIT]复制代码 로그인 후 복사 로그인 후 복사
评估 Online DDL 操作的性能
Online DDL 操作的性能取决于是否发生了表的重建。在对大表执行 DDL 操作之前,为了避免影响正常业务操作,最好是先评估一下 DDL 语句的性能再选择如何操作。
- 复制表结构,创建一个新的表
- 在新创建的表中插入少量数据
- 在新表上面执行 DDL 操作
- 检查执行操作后返回的
rows affected 是否是 0。如果该值非 0,则意味着需要拷贝表数据,此时对 DDL 的上线需要慎重考虑,周密计划
比如
由于在执行 Online DDL 过程中需要记录并发执行的 DML 操作发生的变更,然后在执行完 DDL 操作之后再应用这些变更,因此使用 Online DDL 操作花费的时间比不使用 Online 模式执行要更长一些。
Online DDL 支持情况
INSTANT 算法支持:MariaDB 10.3.2+,MySQL 8.0.12+。NOCOPY 只支持 MariaDB 10.3.2 以上版本,不支持 MySQL,这里就暂且忽略了。
重点关注是否 重建表 和 支持并发 DML:不需要重建表,支持并发 DML 最佳。
![Online DDL Select Path](https://img.php.cn/upload/article/000/000/052/769457287bc1609fe1742b1078d26bd0-6.png)
보조 인덱스
Operation |
INSTANT |
INPLACE |
테이블 재구성 |
동시 DML |
메타데이터만 수정 |
보조 인덱스 생성 또는 추가 | ❌ |
✅ |
❌ |
✅ |
❌ |
인덱스 삭제 |
❌ |
✅ |
❌ |
✅ |
✅ |
색인 이름 바꾸기(⚠️MySQL 5.7+, MariaDB 10.5.2+ ) |
❌ |
✅ | ❌ |
✅ |
✅ |
FULLTEXT 색인 추가 FULLTEXT 索引 |
❌ |
✅ ① |
❌ ① |
❌ |
❌ |
添加 SPATIAL 索引(⚠️MySQL 5.7+,MariaDB 10.2.2+) |
❌ |
✅ |
❌ |
❌ |
❌ |
修改索引类型 |
✅ |
✅ |
❌ |
✅ |
✅ |
说明:
- ① 第一次添加全文索引字段时需要重建表,之后就不需要了
主键
操作 |
INSTANT |
INPLACE |
重建表 |
并发 DML |
只修改元数据 |
添加主键 |
❌ |
✅ ② |
✅ ② |
✅ |
❌ |
删除主键 |
❌ |
❌ |
✅ |
❌ |
❌ |
删除一个主键同时添加一个新的 |
❌ |
✅ |
✅ |
✅ |
❌ |
说明:
- 重建聚簇索引总是需要拷贝表数据(InnoDB 是“索引组织表”),所以最好是在创建表的时候就定义好主键
- 如果创建表是没有指定主键,InnoDB 会选择第一个
NOT NULL 的 UNIQUE 索引作为主键,或者使用系统生成的 KEY
- ② 对聚簇索引来说,使用
INPLACE 模式比 COPY 模式要高效一些:不会产生 undo log 和 redo log,二级索引是有序的,所以可以按顺序加载,不需要使用变更缓冲区
普通列
操作 |
INSTANT |
INPLACE |
重建表 |
并发 DML |
只修改元数据 |
列添加 |
✅ ③ |
✅ |
❌ ③ |
✅ ③ |
❌ |
列删除 |
❌ ④ |
✅ |
✅ |
✅ |
❌ |
列重命名 |
❌ |
✅ |
❌ |
✅ ⑤ |
✅ |
改变列的顺序 |
❌ ⑫ |
✅ |
✅ |
✅ |
❌ |
设置默认值 |
✅ |
✅ |
❌ |
✅ |
✅ |
修改数据类型 |
❌ |
❌ |
✅ |
❌ |
❌ |
扩展 VARCHAR 长度(⚠️MySQL 5.7+, MariaDB 10.2.2+) |
❌ ⑬ |
✅ |
❌ ⑥ |
✅ |
✅ |
删除列的默认值 |
✅ |
✅ |
❌ |
✅ |
✅ |
改变自增值 |
❌ |
✅ |
❌ |
✅ |
❌ ⑦ |
设置列为 NULL |
❌ |
✅ |
✅ ⑧ |
✅ |
❌ |
设置列为 NOT NULL |
❌ |
✅ ⑨ |
✅ ⑨ |
✅ |
❌ |
修改 ENUM 和 SET
| ❌ | ✅ ① | ❌ ① | ❌ | ❌ |
SPATIAL 추가 code> 인덱스 (⚠️MySQL 5.7+, MariaDB 10.2.2+) 🎜❌🎜🎜✅🎜🎜❌🎜🎜❌🎜🎜❌🎜🎜🎜🎜인덱스 유형 수정🎜🎜✅🎜🎜 ✅ 🎜🎜❌ 🎜🎜✅🎜 🎜✅🎜🎜🎜🎜지침:
- ① 처음으로 전체 텍스트 인덱스 필드를 추가할 때 테이블을 다시 작성해야 하지만 그 이후에는 그렇지 않습니다.
기본 키🎜🎜🎜🎜🎜작업🎜🎜INSTANT🎜🎜INPLACE🎜🎜테이블 재구성🎜🎜동시 DML🎜🎜메타데이터만 수정🎜🎜🎜🎜🎜🎜추가 기본 키🎜 🎜 ❌🎜🎜✅ ②🎜🎜✅ ②🎜🎜✅🎜🎜❌🎜🎜🎜🎜기본 키 삭제🎜🎜❌🎜🎜❌🎜🎜✅🎜🎜❌🎜 🎜 ❌🎜🎜🎜🎜기본 키를 삭제하고 새 항목 추가🎜🎜 ❌🎜🎜✅🎜🎜✅🎜🎜✅🎜🎜❌🎜🎜🎜🎜
참고:
- 클러스터형 인덱스를 재구축하려면 항상 테이블 데이터를 복사해야 합니다(InnoDB는 "인덱스 구성 테이블")이므로 테이블을 생성할 때 기본 키를 정의하는 것이 가장 좋습니다.
- 기본 키를 지정하지 않고 테이블을 생성하면 InnoDB는 첫 번째
NOT NULL을 선택합니다. UNIQUE 인덱스를 기본 키로 사용하거나 시스템 생성 KEY를 사용하세요.
- ② 클러스터형 인덱스의 경우
INPLACE 를 사용하는 것이 더 저렴합니다. > 모드가 COPY 모드보다 더 효율적입니다. 실행 취소 로그 및 재실행 로그가 생성되지 않으므로 이를 수행할 수 있습니다. 순서대로 로드되며 변경 버퍼를 사용할 필요가 없습니다.
일반 열 🎜🎜🎜🎜🎜 작업 🎜🎜INSTANT🎜🎜INPLACE🎜 🎜테이블 재구성🎜🎜동시 DML🎜🎜메타데이터만 수정🎜🎜🎜🎜🎜🎜 열 추가 🎜🎜✅ ③🎜🎜✅🎜🎜❌ ③🎜🎜✅ ③🎜🎜❌🎜🎜 🎜🎜 칼럼 삭제됨 🎜🎜❌ ④🎜🎜 ✅🎜🎜✅🎜🎜 ✅🎜🎜❌🎜🎜🎜🎜열 이름 변경🎜 🎜❌🎜🎜✅🎜🎜❌🎜🎜✅ ⑤🎜🎜✅🎜🎜🎜🎜순서 변경 열🎜🎜❌ ⑫🎜🎜✅🎜🎜 ✅🎜🎜✅🎜🎜❌ 🎜🎜🎜🎜기본값 설정🎜🎜✅🎜 🎜✅🎜🎜❌🎜🎜✅🎜🎜✅🎜🎜🎜🎜데이터 유형 수정🎜🎜❌ 🎜🎜❌🎜🎜✅🎜🎜❌🎜🎜 ❌🎜🎜🎜 🎜확장된 VARCHAR 길이(⚠️MySQL 5.7+, MariaDB 10.2.2+)🎜🎜❌ ⑬🎜🎜✅🎜🎜❌ ⑥🎜🎜✅🎜🎜✅🎜🎜🎜 🎜제거 열의 기본값🎜🎜✅🎜🎜✅🎜🎜✅ ❌🎜🎜✅🎜🎜✅ 🎜🎜🎜🎜자동 증가 값 변경🎜🎜❌🎜🎜✅🎜🎜❌🎜🎜✅🎜 🎜❌ 7🎜🎜🎜 🎜NULL로 설정🎜🎜❌🎜🎜✅🎜 🎜✅ 8🎜🎜✅🎜🎜❌🎜🎜🎜 🎜열을 NOT NULL로 설정🎜🎜❌🎜🎜✅ ⑨🎜🎜✅ 9🎜 🎜✅🎜🎜❌🎜🎜🎜 🎜ENUM 및 SET 열의 정의 수정🎜🎜 ✅🎜🎜✅🎜🎜❌ ⑩🎜🎜✅🎜🎜✅🎜🎜🎜🎜
설명:
3 동시 DML: 자동 증가 열을 삽입할 때 동시 DML 작업을 지원하지 않습니다. 자동 증가 열을 추가하면 많은 양의 데이터가 재구성되므로 비용이 많이 듭니다
③ 테이블 재구축: MySQL 5.7 이하 버전에서는 ALGORITHM=INPLACE 인 경우 테이블을 재구축해야 하며, ALGORITHM인 경우에는 재구축할 필요가 없습니다. =INSTANT ALGORITHM=INPLACE 时,需要重建表,ALGORITHM=INSTANT 时不需要重建
-
③ INSTANT算法:添加列时,使用 INSTANT 算法有下面这些限制
- 添加列操作不能和其它不支持
INSTANT 算法的操作合并为一条 ALTER TABLE 语句
- 新增的列只能添加到表的最后,不能放到其它列的前面,在 MariaDB 10.4 之后,支持在任意位置添加
- 不能将列添加到
ROW_FORMAT=COMPRESSED 的表中
- 不能将列添加到包含
FULLTEXT 的表中
- 不能将列添加到临时表中,临时表只支持
ALGORITHM=COPY
- 不能将列添加到驻留在数据字典表空间中的表中
- 在添加列的时候不会计算行的大小限制,该限制在执行 DML 操作插入或者更新表时才会被检查
④ 删除列时,大量的数据需要被重新组织,代价高昂,在 MariaDB 10.4 之后,删除列支持 INSTANT 算法
⑤ 重命名列时,确保只改变列名,不改变数据类型,这样才能支持并发的 DML 操作
-
⑥ 扩展 VARCHAR 长度时,INPLACE 是有条件的,必须保证用于标识字符串长度的长度字节不变(这里说的都是字节,不是 VARCHAR 的字符长度,字节占用与采用的字符集有关,utf8 字符集下,一个字符占 3 个字节, utf8mb4 则 4 个字节)
- 当 VARCHAR 列长度在 0-255 个字节时,长度标识占用一个字节
- 当 VARCHAR 列长度大于 255 个字节时,长度标识占用两个字节
因此,INPLACE 只支持 0-255 个字节之间或者 256 个字节到更大的长度之间的变更。VARCHAR 列长度减小是不支持 INPLACE 的。
⑦ 自增列值变更是修改的内存中的值,不是数据文件
⑧ ⑨ 设置列为 [NOT] NULL 时,大量的数据被重新组织,代价高昂
⑩ 修改 ENUM 和 SET 类型的列定义时,是否需要表拷贝取决于已有元素的个数和插入成员的位置
⑫ 在 MariaDB 10.4 之后,列排序支持 INSTANT 算法
⑬ 在 MariaDB 10.4.3 之后,InnoDB 支持使用 INSTANT 算法增加列的长度,但是也有一些限制,具体参考 Changing the Data Type of a Column
生成列
操作 |
INSTANT |
INPLACE |
重建表 |
并发 DML |
只修改元数据 |
添加 STORED 列 |
❌ |
❌ |
✅ |
❌ |
❌ |
修改 STORED 列的排序 |
❌ |
❌ |
✅ |
❌ |
❌ |
删除 STORED 列 |
❌ |
✅ |
✅ |
✅ |
❌ |
添加 VIRTUAL 列 |
✅ |
✅ |
❌ |
✅ |
✅ |
修改 VIRTUAL 列的排序 |
✅ |
❌ |
✅ |
❌ |
❌ |
删除 VIRTUAL
|
| ③ INSTANT 알고리즘: 컬럼 추가 시 INSTANT 알고리즘을 사용하면 다음과 같은 제한 사항이 있습니다. |
컬럼 추가 작업은 지원하지 않는 다른 작업과 결합할 수 없습니다. INSTANT 알고리즘을 하나의 ALTER TABLE 문으로 통합 |
새 열은 테이블 끝에만 추가할 수 있으며 MariaDB 10.4 이후에는 다른 열 앞에 배치할 수 없습니다. 임의의 위치에 추가할 수 있습니다. |
ROW_FORMAT =COMPRESSED 에 열을 추가할 수 없습니다. |
FULLTEXT 가 포함된 테이블에는 열을 추가할 수 없습니다.
임시 테이블에는 열을 추가할 수 없습니다. , 임시 테이블은 ALGORITHM=COPY만 지원합니다.<h3 data-id="heading-10"></h3>데이터 사전 테이블스페이스에 있는 테이블에는 열을 추가할 수 없습니다.<table>
<thead>열을 추가할 때 행 크기 제한이 계산되지 않습니다. 이 제한은 DML 작업을 수행할 때 제거됩니다. 테이블을 삽입하거나 업데이트하려면 <tr class="firstRow">
<th></th>
<th>4 열을 삭제할 때 많은 양의 데이터를 재구성해야 하므로 비용이 많이 듭니다. MariaDB 10.4 이후에는 열 삭제가 INSTANT 알고리즘을 지원합니다 </th>
<th></th>
<th> ⑤ 컬럼 이름 변경 시 동시 DML 작업을 지원하기 위해 데이터 타입은 변경하지 않고 컬럼 이름만 변경해야 한다. </th>
<th></th>
<th>⑥ VARCHAR의 길이를 확장할 때 INPLACE는 조건부이며 길이 바이트는 사용되는 길이이다. 문자열의 길이를 식별하고 변경되지 않도록 보장해야 합니다(여기에 언급된 모든 단어는 섹션이며 VARCHAR의 문자 길이가 아닙니다. 바이트 점유는 사용된 문자 세트와 관련됩니다. <code>utf8 문자 세트에서 , 한 문자가 3바이트를 차지하며, utf8mb4 에서는 4자를 차지합니다. 섹션)
|
VARCHAR 컬럼 길이가 0~255바이트일 때 길이 식별자는 1바이트를 차지합니다
VARCHAR 컬럼의 경우 길이가 255바이트보다 크면 길이 식별자는 2바이트를 차지합니다 | 따라서 INPLACE는 0에서 255바이트 사이 또는 256바이트 이상 사이의 변경만 지원합니다. INPLACE에서는 VARCHAR 열 길이 감소가 지원되지 않습니다. |
| 7 자동 증가 컬럼 값의 변경은 데이터 파일이 아닌 메모리에 있는 수정된 값입니다 |
| 8 ⑨ 해당 컬럼이 [NOT] NULL
로 설정된 경우, 많은 양의 데이터가 재구성됨. 요소 및 삽입된 멤버의 위치 |
⑫ MariaDB 10.4 이후 열 정렬은 INSTANT 알고리즘을 지원합니다 |
| ⑬ MariaDB 10.4.3 이후 InnoDB는 열 길이를 늘리는 INSTANT 알고리즘 사용을 지원하지만 몇 가지 제한 사항이 있습니다. 자세한 내용은 열의 데이터 유형 변경 |
열 생성 |
|
Operation |
INSTANT
INPLACE🎜🎜테이블 다시 작성🎜을 참조하세요. 🎜동시 DML🎜🎜메타데이터만 수정🎜🎜🎜🎜🎜 🎜
STORED
열 추가🎜🎜❌🎜🎜❌🎜🎜✅🎜🎜❌🎜🎜❌🎜🎜🎜 🎜 정렬 수정 STORED 열🎜🎜❌🎜🎜❌ 🎜🎜 ✅🎜🎜❌🎜🎜❌🎜🎜🎜🎜
STORED
열 삭제 🎜🎜❌🎜🎜✅🎜🎜✅🎜 🎜✅🎜🎜❌ 🎜🎜🎜🎜
VIRT UAL
열 추가 🎜🎜✅🎜🎜✅🎜🎜❌🎜🎜✅🎜🎜✅🎜🎜🎜🎜
VIRTUAL
열 정렬 수정🎜🎜✅ 🎜🎜❌🎜🎜✅🎜🎜❌🎜 🎜❌🎜🎜🎜🎜
VIRTUAL
열 삭제 🎜🎜✅🎜🎜✅🎜🎜❌🎜🎜✅🎜🎜✅ 🎜🎜🎜🎜🎜외래 키🎜🎜 🎜🎜🎜Operation🎜🎜INSTANT🎜 🎜INPLACE🎜🎜테이블 재구성🎜🎜 동시 DML🎜🎜메타데이터만 수정🎜🎜🎜🎜🎜🎜외래 키 제약 조건 추가🎜🎜❌🎜🎜✅ ⑭🎜🎜❌🎜🎜✅🎜🎜✅🎜 🎜🎜🎜외래 키 제약 조건 삭제🎜 🎜❌🎜🎜✅🎜🎜 ❌🎜🎜✅🎜🎜✅🎜🎜🎜🎜
참고:
- ⑭ 외래 키를 추가할 때
INPLACE
알고리즘은 foreign_key_checks
옵션이 비활성화된 경우에만 지원됩니다foreign_key_checks
选项被禁用的时候才支持 INPLACE
算法
表
操作 |
INSTANT |
INPLACE |
重建表 |
并发 DML |
只修改元数据 |
修改 ROW_FORMAT
|
❌ |
✅ |
✅ |
✅ |
❌ |
修改 KEY_BLOCK_SIZE
|
❌ |
✅ |
✅ |
✅ |
❌ |
设置持久表统计信息 |
❌ |
✅ |
❌ |
✅ |
✅ |
指定字符集 |
❌ |
✅ |
✅ ⑮ |
❌ |
❌ |
转换字符集 |
❌ |
❌ |
✅ ⑯ |
❌ |
❌ |
优化表 |
❌ |
✅ ⑰ |
✅ |
✅ |
❌ |
使用 FORCE 选项重建表 |
❌ |
✅ ⑱ |
✅ |
✅ |
❌ |
执行空的重建 |
❌ |
✅ ⑲ |
✅ |
✅ |
❌ |
重命名表 |
✅ |
✅ |
❌ |
✅ |
✅ |
说明:
- ⑮⑯ 当字符集不同时,需要重建表
- ⑰⑱⑲ 如果表中包含
FULLTEXT
的字段,则不支持 INPLACE
表空间
操作 |
INSTANT |
INPLACE |
重建表 |
并发 DML |
只修改元数据 |
重命名常规表空间 |
❌ |
✅ |
❌ |
✅ |
✅ |
启用或者禁用常规表空间加密 |
❌ |
✅ |
❌ |
✅ |
❌ |
启用或者禁用 file-per-table 表空间加密 |
❌ |
❌ |
✅ |
❌ |
❌ |
限制
- 在临时表
TEMPORARY TABLE
上创建索引时会发生表拷贝
- 如果表上有
ON...CASCADE
或者 ON...SET NULL
约束,则 ALERT TABLE
不支持字句 LOCK=NONE
테이블
작업 |
INSTANT |
INPLACE |
테이블 재구성 |
동시 DML |
메타데이터만 수정 |
ROW_FORMAT |
❌ |
✅ |
✅ |
✅ |
❌ |
수정KEY_BLOCK_SIZE
|
❌ |
✅ |
✅ |
✅ | ❌
영구 테이블 통계 설정 |
❌ |
✅ |
❌ | ✅ |
✅ |
문자 집합 지정 |
❌ |
✅ | ✅ ⑮❌ |
❌ |
문자 집합 변환 |
❌ | ❌✅ ⑯ |
❌ |
❌ |
테이블 최적화 |
❌ |
✅ ⑰ |
✅ |
✅ |
❌ |
>FORCE 옵션 재구축 테이블 |
❌ |
✅ ⑱ |
✅ |
✅ |
❌ |
빈 재구축 수행 |
❌ |
✅ ⑲ |
✅ | ✅❌ |
테이블 이름 바꾸기 |
✅ |
✅ |
❌ |
✅ |
✅ |
- 참고:
⑮⑯ 문자 집합이 다른 경우 테이블은 다음과 같아야 합니다. 재구축됨 - ⑰⑱⑲ 테이블에
FULLTEXT
필드가 포함된 경우 INPLACE는 지원되지 않습니다 -
테이블 공간
작업 |
INSTANT |
INPLACE |
테이블 재구축 |
동시 DML | 메타데이터만 수정
일반 테이블스페이스 이름 바꾸기 |
❌ |
✅ | ❌✅ |
✅ |
일반 테이블스페이스 암호화 활성화 또는 비활성화 |
❌ |
✅ |
❌ |
✅ |
❌ |
파일 활성화 또는 비활성화 -테이블당 테이블 공간 암호화 |
❌ |
❌ |
✅ |
❌ | ❌ |
제한 사항
- 임시 테이블
TEMPORARY TABLE
테이블 복사
에 인덱스를 생성할 때 발생합니다. 테이블에 ON...CASCADE
또는 ON...SET NULL
제약 조건이 있는 경우 ALERT TABLE <code>LOCK=NONE
구문은 지원되지 않습니다. Onlne DDL 작업이 완료되기 전에 관련 테이블에 대한 메타데이터 잠금을 이미 보유하고 있는 트랜잭션이 커밋되거나 롤백될 때까지 기다려야 합니다. 이 프로세스에서는 관련 테이블의 새 트랜잭션이 차단되어 실행할 수 없습니다.
대형 테이블에서 테이블 재구성과 관련된 DDL을 실행할 때 다음과 같은 제한 사항이 있습니다.
온라인 DDL 작업을 일시 중지하거나 I/A를 제한하는 메커니즘이 없습니다. O 또는 온라인 DDL 작업의 CPU 사용량
작업이 실패할 경우 온라인 DDL 작업을 롤백하는 데 비용이 매우 많이 듭니다.오래 실행되는 온라인 DDL은 복제 지연을 일으킬 수 있습니다. 온라인 DDL 작업은 슬레이브에서 실행되기 전에 마스터에서 실행되어야 합니다. 이 과정에서 동시에 처리되는 DML은 DDL 작업이 실행되기 전에 슬레이브에서 완료될 때까지 기다려야 합니다. 마지막에 작성이 글은 계속 수정되고 업데이트될 예정이니 팔로우하시면 더욱 흥미로운 내용을 보실 수 있습니다.
🎜🎜더 많은 관련 무료 학습 권장사항: 🎜🎜🎜mysql 튜토리얼🎜🎜🎜(동영상)🎜🎜🎜
위 내용은 참조 가이드: MySQL 및 MariaDB 온라인 DDL의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!