MySQL 8.0 DDL Lock 정리

결론

ALGORITHM=INSTANTALGORITHM=INPLACE, LOCK=NONE은 둘 다 온라인 DDL 계열로 볼 수 있지만, 동작 방식과 운영 영향이 다르다.

  • ALGORITHM=INSTANT는 가능한 경우 테이블 데이터를 재작성하지 않고 메타데이터만 변경한다.
  • ALGORITHM=INPLACE는 테이블 복사는 피하지만, 작업 종류에 따라 내부적으로 테이블/인덱스 데이터를 읽거나 재구성할 수 있다.
  • LOCK=NONE은 DDL 수행 중 일반 DML을 허용하겠다는 옵션이지, Metadata Lock 자체가 없다는 의미는 아니다.
  • 어떤 방식이든 DDL이기 때문에 MDL, 즉 Metadata Lock은 잡는다.

따라서 운영에서는 INSTANT라고 해서 완전히 무락이라고 보면 안 된다. 다만 INPLACE보다 훨씬 가볍고 빠르게 끝날 수 있다.

비교

설정 의미 데이터 재작성 DML 허용 MDL 운영 영향
ALGORITHM=INSTANT, LOCK=NONE 메타데이터만 변경 가능한 경우 즉시 반영 거의 없음 가능 있음 가장 가볍다
ALGORITHM=INPLACE, LOCK=NONE 테이블 복사 없이 제자리 변경 작업에 따라 있음 가능 있음 작업 시간이 길 수 있다
ALGORITHM=COPY 새 테이블을 만들고 데이터를 복사 있음 제한 큼 있음 가장 무겁다

ALGORITHM=INSTANT

INSTANT는 MySQL 8.0 InnoDB에서 지원하는 가장 가벼운 DDL 방식이다. 가능한 작업에서는 기존 row를 수정하거나 테이블을 다시 만들지 않고, 데이터 딕셔너리의 메타데이터 변경만으로 DDL을 처리한다.

예시:

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INSTANT,
  LOCK = NONE;

특징:

  • 테이블 데이터를 물리적으로 재작성하지 않는다.
  • 기존 row 전체를 스캔하거나 업데이트하지 않는다.
  • 매우 빠르게 끝나는 편이다.
  • 그래도 DDL이므로 MDL은 필요하다.
  • 오래 열린 트랜잭션이 있으면 ALTER TABLE이 MDL 획득을 기다릴 수 있다.
  • ALTER TABLE이 MDL 대기열에 들어간 상태에서는 뒤따라 들어오는 쿼리들도 같이 막히는 현상이 발생할 수 있다.

“메타데이터만 변경한다”는 의미

여기서 말하는 메타데이터는 “실제 row 데이터”가 아니라, MySQL/InnoDB가 테이블을 해석하기 위해 들고 있는 테이블 정의 정보다.

예를 들면 다음과 같은 정보들이 메타데이터에 가깝다.

  • 테이블 이름
  • 컬럼 목록
  • 컬럼 순서
  • 컬럼 타입
  • NULL 허용 여부
  • 기본값
  • 컬럼 comment
  • 인덱스 정의
  • row를 읽을 때 각 컬럼을 어떻게 해석할지에 대한 정보

반대로 실제 데이터는 디스크의 테이블스페이스 안에 저장된 row record다.

Copy
┌──────────────────────────────┐
│ metadata                     │
│ - member 테이블에는 id가 있다  │
│ - name 컬럼이 있다             │
│ - created_at 컬럼이 있다       │
│ - 각 컬럼의 타입은 무엇이다     │
└──────────────┬───────────────┘
               │ 이 정의를 기준으로 row를 해석
               ▼
┌──────────────────────────────┐
│ physical row records          │
│ row1 bytes                    │
│ row2 bytes                    │
│ row3 bytes                    │
└──────────────────────────────┘

ALGORITHM=INSTANT로 컬럼을 추가할 때는 기존 row record를 전부 찾아가서 새 컬럼 값을 써 넣지 않는다. 대신 “이 테이블에는 이제 mtime이라는 컬럼이 하나 더 있다”는 정의만 바꾼다.

예를 들어 기존 테이블이 다음과 같다고 하자.

Copy
CREATE TABLE member (
  id bigint NOT NULL,
  name varchar(50),
  created_at datetime(6)
);

디스크에 저장된 기존 row는 개념적으로 다음과 같다.

Copy
row1 = [id=1][name='kim'][created_at='2026-05-21 10:00:00']
row2 = [id=2][name='lee'][created_at='2026-05-21 10:01:00']

여기서 다음 DDL을 실행한다.

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INSTANT,
  LOCK = NONE;

그러면 기존 row가 즉시 이렇게 다시 쓰이는 것이 아니다.

Copy
row1 = [id=1][name='kim'][created_at='...'][mtime=NULL]
row2 = [id=2][name='lee'][created_at='...'][mtime=NULL]

실제로는 기존 row record는 그대로 두고, 테이블 정의만 다음처럼 바뀐 것으로 보면 된다.

Copy
metadata before
- column 1: id
- column 2: name
- column 3: created_at

metadata after
- column 1: id
- column 2: name
- column 3: created_at
- column 4: mtime, nullable, default NULL

이후 MySQL이 기존 row를 읽을 때는 “이 row는 예전 형식으로 저장된 row라서 mtime 물리 값이 없다. 그러면 새 컬럼은 기본값 또는 NULL로 해석한다”는 식으로 처리한다.

즉, 조회 결과에는 mtime 컬럼이 보인다.

Copy
SELECT id, name, created_at, mtime
FROM member;

결과는 개념적으로 다음처럼 나온다.

Copy
id | name | created_at              | mtime
---|------|-------------------------|------
1  | kim  | 2026-05-21 10:00:00.000 | NULL
2  | lee  | 2026-05-21 10:01:00.000 | NULL

하지만 이 NULL은 ALTER 시점에 모든 row에 물리적으로 써 넣은 값이라기보다, 새 메타데이터를 기준으로 기존 row를 읽을 때 보정해서 해석한 값에 가깝다.

새로 insert되거나 update되는 row는 새 테이블 정의를 기준으로 저장된다.

Copy
INSERT INTO member (id, name, created_at, mtime)
VALUES (3, 'park', NOW(6), NOW(6));

이 row는 처음부터 mtime 컬럼을 포함한 새 구조로 저장된다.

Copy
old rows
row1 = 예전 row format, mtime 물리 값 없음 -> 읽을 때 NULL로 해석
row2 = 예전 row format, mtime 물리 값 없음 -> 읽을 때 NULL로 해석

new rows
row3 = 새 row format, mtime 물리 값 있음

그래서 “메타데이터만 변경한다”는 말은 다음과 같이 이해하면 된다.

  • 기존 row를 전부 스캔하지 않는다.
  • 기존 row를 전부 다시 쓰지 않는다.
  • 테이블 파일을 새로 만들고 복사하지 않는다.
  • 테이블 정의 정보만 바꾼다.
  • 기존 row에 없는 새 컬럼 값은 읽는 시점에 기본값 또는 NULL로 해석한다.

이 방식 때문에 INSTANT ADD COLUMN은 데이터가 수천만 건이어도 가능한 조건에서는 빠르게 끝날 수 있다. 다만 DDL 자체는 테이블 정의를 바꾸는 작업이므로 MDL은 필요하다.

ALGORITHM=INPLACE, LOCK=NONE

INPLACE는 테이블 전체를 새로 복사하는 COPY 방식은 피하지만, 작업 종류에 따라 내부적으로 데이터나 인덱스 구조를 만질 수 있다.

예시:

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INPLACE,
  LOCK = NONE;

특징:

  • COPY보다는 가볍다.
  • 하지만 INSTANT처럼 항상 메타데이터만 변경하는 것은 아니다.
  • 작업 종류에 따라 시간이 오래 걸릴 수 있다.
  • LOCK=NONE이면 DDL 중 DML을 허용하려고 시도한다.
  • 그래도 시작/종료 시점에는 MDL이 필요하다.
  • 긴 트랜잭션이나 장시간 쿼리가 있으면 대기하거나 영향을 줄 수 있다.

LOCK=NONE의 의미

LOCK=NONE은 “락을 전혀 잡지 않는다”가 아니다.

정확히는 DDL 작업 중 가능한 한 SELECT, INSERT, UPDATE, DELETE 같은 동시 DML을 허용하겠다는 의미다.

하지만 DDL 실행을 위해 테이블 정의를 바꾸려면 MDL이 필요하다. 그래서 다음 상황에서는 운영 장애처럼 보일 수 있다.

Copy
-- session 1
BEGIN;
SELECT * FROM member WHERE idx = 1;
-- COMMIT 하지 않고 유지

-- session 2
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL,
  ALGORITHM = INSTANT,
  LOCK = NONE;
-- session 1 때문에 MDL 대기

-- session 3
SELECT * FROM member WHERE idx = 2;
-- session 2의 ALTER가 MDL 대기열에 있어서 같이 대기할 수 있음

즉, LOCK=NONE은 DML을 막지 않는 온라인 DDL을 요청하는 옵션이지, MDL 대기 리스크까지 없애주는 옵션은 아니다.

이번 케이스

이번 DDL은 nullable 컬럼을 추가하는 형태다.

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INSTANT,
  LOCK = NONE;

MySQL 8.0 InnoDB에서 조건이 맞으면 ADD COLUMNINSTANT로 처리될 수 있다. 이 경우 ALGORITHM=INPLACE, LOCK=NONE보다 ALGORITHM=INSTANT, LOCK=NONE이 더 적절하다.

추천:

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INSTANT,
  LOCK = NONE;

MySQL 버전별 지원 차이

결론부터 말하면 ALGORITHM=INSTANT는 MySQL 5.7에서는 사용할 수 없다. MySQL 8.0 계열에서 추가된 기능이며, 더 정확히는 InnoDB의 instant ADD COLUMN은 MySQL 8.0.12부터 지원된 것으로 보는 것이 안전하다.

즉, 버전별로 보면 다음과 같이 정리할 수 있다.

MySQL 버전 ALGORITHM=INSTANT ALGORITHM=INPLACE, LOCK=NONE 설명
MySQL 5.7 지원 안 함 지원 가능 온라인 DDL은 가능하지만 INSTANT 방식은 없음
MySQL 8.0.11 이하 일반적으로 INSTANT ADD COLUMN 기대 불가 지원 가능 8.0 초기 버전이라도 instant add column 지원 여부를 조심해야 함
MySQL 8.0.12 이상 지원 가능 지원 가능 nullable 컬럼을 뒤에 추가하는 케이스는 보통 INSTANT 가능
MySQL 8.0.29 이상 지원 범위 확대 지원 가능 instant add/drop column 범위가 더 넓어짐. 단, 제약 조건은 여전히 확인 필요

MySQL 5.7에서 ALGORITHM=INSTANT를 쓰면?

MySQL 5.7에서는 INSTANT 알고리즘 자체를 지원하지 않기 때문에 아래 구문은 사용할 수 없다.

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INSTANT,
  LOCK = NONE;

5.7에서는 대개 다음과 같은 형태를 사용하게 된다.

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INPLACE,
  LOCK = NONE;

하지만 여기서 중요한 점은, 5.7의 INPLACE는 8.0의 INSTANT와 다르다는 것이다.

5.7에서 ADD COLUMNINPLACE로 수행하더라도 기존 row를 메타데이터만으로 즉시 해석하는 방식이 아니다. 작업 종류에 따라 테이블을 rebuild할 수 있고, 데이터 양에 따라 시간이 오래 걸릴 수 있다. LOCK=NONE 덕분에 DML을 허용하려고 시도하지만, 작업 자체가 가벼워지는 것은 아니다.

두 설정의 버전별 의미

1. MySQL 8.0에서 추천되는 설정

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INSTANT,
  LOCK = NONE;

의미:

  • 가능한 경우 메타데이터만 변경한다.
  • 기존 row를 전부 다시 쓰지 않는다.
  • 테이블을 새로 복사하지 않는다.
  • 매우 빠르게 끝날 수 있다.
  • 그래도 MDL은 필요하다.
  • MySQL 8.0.12 이상인지 확인하는 것이 좋다.

2. MySQL 5.7에서 현실적으로 가능한 설정

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INPLACE,
  LOCK = NONE;

의미:

  • COPY 방식은 피하려고 한다.
  • DDL 중 DML을 허용하려고 한다.
  • 하지만 INSTANT처럼 메타데이터만 바꾸는 것은 아니다.
  • 테이블 rebuild가 발생할 수 있다.
  • 데이터 양이 많으면 오래 걸릴 수 있다.
  • 시작/종료 시점의 MDL은 필요하다.

운영 판단 기준

MySQL 8.0.12 이상이고, nullable 컬럼을 맨 뒤에 추가하는 단순 케이스라면 ALGORITHM=INSTANT, LOCK=NONE을 우선 고려한다.

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INSTANT,
  LOCK = NONE;

MySQL 5.7이라면 INSTANT는 선택지가 아니므로 ALGORITHM=INPLACE, LOCK=NONE을 사용하되, 운영 영향은 더 크게 봐야 한다.

Copy
ALTER TABLE member
  ADD COLUMN mtime datetime(6) NULL COMMENT '수정일자',
  ALGORITHM = INPLACE,
  LOCK = NONE;

정리하면 다음과 같다.

Copy
MySQL 5.7
  └─ INSTANT 불가
  └─ INPLACE + LOCK=NONE 가능
  └─ 테이블 rebuild 가능성 있음
  └─ 데이터 크기에 따라 오래 걸릴 수 있음

MySQL 8.0.12+
  └─ INSTANT 가능
  └─ 조건이 맞으면 metadata only
  └─ 기존 row 물리 재작성 없음
  └─ 가장 가볍지만 MDL은 필요

운영 실행 전 확인할 것

실행 전에 긴 트랜잭션이 있는지 확인한다.

Copy
SELECT *
FROM information_schema.innodb_trx
ORDER BY trx_started;

MDL 대기가 있는지 확인한다.

Copy
SELECT *
FROM performance_schema.metadata_locks
WHERE object_schema = 'myservice'
  AND object_name = 'member';

실행 중 세션 상태를 확인한다.

Copy
SHOW PROCESSLIST;

운영 기준 정리

  • ADD COLUMNINSTANT 가능한 경우에는 ALGORITHM=INSTANT, LOCK=NONE을 우선 사용한다.
  • INSTANT가 실패하면 실제로 INPLACE가 필요한 변경인지 검토한다.
  • INPLACELOCK=NONE을 붙여도 작업 시간이 길 수 있으므로 트래픽 낮은 시간대에 수행하는 것이 안전하다.
  • DDL 실행 전에는 long transaction과 metadata lock 대기를 확인한다.
  • INSTANT도 MDL은 잡기 때문에 완전한 무중단이라고 표현하지 않는다.

동작 방식 이미지 설명

아래 그림들은 실제 내부 구현을 완전히 표현한 것은 아니고, 운영 관점에서 이해하기 쉽게 단순화한 모델이다.

이미지 1. INSTANT는 메타데이터만 바꾸는 방식

Copy
Before

┌──────────────────────────────┐
│ member table metadata         │
│ - id                          │
│ - name                        │
│ - created_at                  │
└──────────────┬───────────────┘
               │ points to
┌──────────────▼───────────────┐
│ physical rows                 │
│ row1: id, name, created_at    │
│ row2: id, name, created_at    │
│ row3: id, name, created_at    │
└──────────────────────────────┘

ALTER TABLE ... ADD COLUMN mtime ... ALGORITHM=INSTANT

After

┌──────────────────────────────┐
│ member table metadata         │
│ - id                          │
│ - name                        │
│ - created_at                  │
│ - mtime                       │  ← metadata만 추가
└──────────────┬───────────────┘
               │ points to
┌──────────────▼───────────────┐
│ physical rows                 │
│ row1: 기존 물리 row 그대로     │
│ row2: 기존 물리 row 그대로     │
│ row3: 기존 물리 row 그대로     │
└──────────────────────────────┘

INSTANT는 기존 row를 하나씩 찾아가서 mtime = NULL을 써 넣는 방식이 아니다. 테이블 정의에 새 컬럼 정보를 추가하고, 기존 row를 읽을 때 새 컬럼은 기본값 또는 NULL로 해석되도록 처리한다. 그래서 가능한 조건에서는 매우 빠르게 끝난다.

이미지 2. INPLACE는 테이블 복사는 피하지만 내부 작업이 있을 수 있음

Copy
ALTER TABLE ... ALGORITHM=INPLACE, LOCK=NONE

┌──────────────────────────────┐
│ original table                │
└──────────────┬───────────────┘
               │
               │ 테이블 전체 COPY는 피함
               │
               ▼
┌──────────────────────────────┐
│ InnoDB internal operation     │
│ - 인덱스 재구성 가능           │
│ - row format 변경 가능         │
│ - background 작업 가능         │
│ - 작업 시간이 길어질 수 있음    │
└──────────────┬───────────────┘
               │
               ▼
┌──────────────────────────────┐
│ changed table definition      │
└──────────────────────────────┘

INPLACECOPY처럼 새 테이블을 만들어 전체 데이터를 복사하는 방식은 아니지만, 작업 종류에 따라 내부적으로 데이터를 읽거나 인덱스를 재구성할 수 있다. 그래서 INSTANT보다 무거울 수 있다.

이미지 3. COPY는 새 테이블을 만들고 데이터를 복사하는 방식

Copy
ALTER TABLE ... ALGORITHM=COPY

┌──────────────────────────────┐
│ old member table              │
└──────────────┬───────────────┘
               │ copy rows
               ▼
┌──────────────────────────────┐
│ new temporary table           │
│ - changed schema              │
│ - copied rows                 │
└──────────────┬───────────────┘
               │ swap
               ▼
┌──────────────────────────────┐
│ new member table              │
└──────────────────────────────┘

COPY는 가장 이해하기 쉬운 대신 가장 무겁다. 데이터 양이 많을수록 오래 걸리고, 운영 중 영향도 커질 수 있다.

이미지 4. LOCK=NONE이어도 MDL 대기는 발생할 수 있음

Copy
시간 흐름 →

Session 1
BEGIN;
SELECT member ...
┌──────────────────────────────┐
│ member에 대한 MDL 보유         │
│ COMMIT 전까지 유지 가능        │
└──────────────────────────────┘

Session 2
ALTER TABLE member ... ALGORITHM=INSTANT, LOCK=NONE
                  │
                  ▼
┌──────────────────────────────┐
│ exclusive MDL 필요             │
│ Session 1 때문에 대기           │
└──────────────────────────────┘

Session 3
SELECT member ...
                  │
                  ▼
┌──────────────────────────────┐
│ ALTER 뒤에 줄 서서 대기 가능    │
└──────────────────────────────┘

핵심은 LOCK=NONE이 “락을 잡지 않는다”가 아니라는 점이다. DML을 허용하는 온라인 DDL을 요청하는 옵션이지만, DDL 자체는 테이블 정의를 바꾸기 때문에 MDL이 필요하다. 그래서 오래 열린 트랜잭션이 있으면 INSTANT DDL도 대기할 수 있고, 그 뒤에 들어온 쿼리들이 같이 막힐 수 있다.

이미지 5. 운영 관점에서의 체감 차이

Copy
가벼움 ───────────────────────────────────────────── 무거움

INSTANT
  └─ metadata 변경 중심
  └─ 기존 row 물리 변경 없음
  └─ 짧은 MDL 필요

INPLACE + LOCK=NONE
  └─ table copy는 피함
  └─ 작업 종류에 따라 내부 재구성 가능
  └─ DML 허용 시도
  └─ 시작/종료 시 MDL 필요

COPY
  └─ 새 테이블 생성
  └─ 데이터 복사
  └─ 테이블 교체
  └─ 운영 영향 가장 큼

동작 방식 PNG 이미지 설명

기존 이미지 n 텍스트 다이어그램을 PNG 이미지로도 볼 수 있도록 보강한다. 아래 이미지는 실제 InnoDB 내부 구조를 1:1로 표현한 것이 아니라, 운영 관점에서 이해하기 쉽게 단순화한 설명용 그림이다.

PNG 1. INSTANT는 메타데이터 중심 변경

INSTANT ADD COLUMN metadata only

INSTANT ADD COLUMN은 기존 row 전체에 mtime = NULL을 물리적으로 써 넣는 방식이 아니다. 테이블 정의에 mtime 컬럼을 추가하고, 기존 row를 읽을 때 새 컬럼 값을 NULL 또는 default로 해석한다.

PNG 2. INPLACE는 COPY는 피하지만 내부 작업이 있을 수 있음

INPLACE DDL internal operation

INPLACECOPY처럼 새 테이블을 만들어 전체 데이터를 복사하지는 않지만, 작업 종류에 따라 인덱스나 데이터 구조를 재구성할 수 있다. 그래서 LOCK=NONE을 붙여도 작업 시간이 길어질 수 있다.

PNG 3. COPY는 새 테이블을 만들고 데이터를 복사

COPY DDL creates temporary table and copies rows

COPY는 가장 무거운 방식이다. 새 테이블을 만들고 기존 데이터를 복사한 뒤 테이블을 교체한다. 데이터가 많을수록 오래 걸리고 운영 영향이 커진다.

PNG 4. LOCK=NONE이어도 MDL 대기는 발생할 수 있음

Metadata lock waiting queue

LOCK=NONE은 락이 없다는 뜻이 아니다. DML을 허용하는 온라인 DDL을 요청하는 옵션일 뿐이고, DDL이 테이블 정의를 바꾸려면 MDL은 필요하다. 오래 열린 트랜잭션이 있으면 INSTANT도 대기할 수 있다.

PNG 5. 운영 관점에서의 무게감

DDL algorithm weight

운영 영향은 보통 INSTANT < INPLACE < COPY 순으로 커진다. 단, 어떤 방식이든 DDL인 이상 MDL은 발생할 수 있으므로 long transaction 확인은 필요하다.

한 줄 요약

ALGORITHM=INSTANT는 메타데이터 변경 중심이라 가장 가볍고, ALGORITHM=INPLACE, LOCK=NONE은 DML 허용은 가능하지만 작업 자체가 더 무거울 수 있다. 둘 다 MDL은 잡으므로 운영에서는 long transaction 여부를 반드시 확인해야 한다.