MySQL 8.0이 나온 지 벌써 몇 년이 지났는데, 그 사이에 릴리즈 모델 자체가 바뀌고, AI 시대에 맞춰 벡터 타입까지 등장했습니다 — 지금 MySQL은 어디까지 왔을까요?

개념 정의 — MySQL 9.x 한 줄 요약

MySQL 9.x는 Innovation 릴리즈 트랙 으로, 분기별로 새로운 기능을 빠르게 제공하는 버전입니다. 기존처럼 하나의 메이저 버전을 수년간 유지하는 방식이 아니라, LTS(장기 지원)와 Innovation(혁신) 두 트랙으로 나뉘어 관리됩니다.

핵심 키워드를 꼽자면 이렇습니다:

  • VECTOR 타입 — AI/ML 임베딩 벡터를 네이티브로 저장
  • JavaScript 스토어드 프로그램 — SQL 외에 JS로도 로직 작성 가능
  • ** 릴리즈 모델 전환** — LTS vs Innovation 이중 트랙 도입

릴리즈 모델 변화: LTS vs Innovation

MySQL 8.0까지는 하나의 메이저 버전이 나오면 몇 년간 패치를 받는 단일 트랙이었습니다. 8.0이 2018년에 나와서 2024년까지 계속 업데이트를 받았으니, 거의 6년간 하나의 버전이 유지된 셈입니다.

그런데 Oracle은 2023년부터 릴리즈 모델을 완전히 바꿨습니다.

두 가지 트랙

구분LTS (Long-Term Support)Innovation
** 현재 버전**MySQL 8.4MySQL 9.0, 9.1, 9.2
** 릴리즈 주기**2년마다 새 LTS분기별 (3개월)
** 지원 기간**5년 프리미어 + 3년 연장다음 릴리즈까지만
** 대상**프로덕션 환경새 기능 검증, 개발/테스트
** 업그레이드**LTS → 다음 LTSInnovation → 다음 Innovation 또는 LTS

어떤 걸 써야 할까?

공부하다 보니 이 부분이 가장 헷갈렸습니다. 결론부터 말하면:

  • ** 프로덕션 서버** → 8.4 LTS를 유지하는 게 안전합니다
  • ** 개발/스테이징 환경** → 9.x Innovation으로 새 기능을 미리 검증해 볼 수 있습니다
  • ** 다음 LTS 준비** → Innovation에서 검증된 기능이 다음 LTS(아마 10.x 또는 다음 LTS)에 포함됩니다

Innovation 릴리즈에서 LTS로 다운그레이드는 지원되지 않습니다. 한번 Innovation 트랙에 올라타면 계속 앞으로만 갈 수 있다는 점을 기억해야 합니다.

릴리즈 흐름

PLAINTEXT
MySQL 8.0 (기존)

    ├── MySQL 8.4 LTS ──────────────── 5년+ 장기 지원

    └── MySQL 9.0 (Innovation)

            ├── MySQL 9.1 (Innovation)
            │       │
            │       └── MySQL 9.2 (Innovation)
            │               │
            │               └── ... → 다음 LTS

            └── (각 Innovation은 다음 버전 나오면 지원 종료)

VECTOR 타입 (9.0)

MySQL 9.0에서 가장 눈에 띄는 변화입니다. AI 시대에 벡터 데이터를 저장하고 검색하는 수요가 폭발적으로 늘어나면서, MySQL도 드디어 네이티브 벡터 타입을 도입했습니다.

VECTOR(N)이 뭔가요?

VECTOR(N)은 N차원의 32비트 부동소수점 벡터를 저장하는 데이터 타입입니다. 쉽게 말해, 숫자 배열을 하나의 컬럼에 담을 수 있습니다.

SQL
-- 벡터 컬럼이 있는 테이블 생성
CREATE TABLE articles (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    content TEXT,
    -- 768차원 임베딩 벡터 (OpenAI text-embedding-3-small 등)
    embedding VECTOR(768)
);

데이터 삽입

벡터 데이터는 바이너리 형태로 저장되지만, 문자열 형태로도 삽입할 수 있습니다.

SQL
-- 문자열 표현으로 삽입
INSERT INTO articles (title, embedding)
VALUES ('MySQL 9.0 소개', STRING_TO_VECTOR('[0.1, 0.2, 0.3, ...]'));

-- TO_VECTOR 함수 사용
INSERT INTO articles (title, embedding)
VALUES ('벡터 검색 가이드', TO_VECTOR('[0.4, 0.5, 0.6, ...]'));

유사도 검색

벡터를 저장하는 이유는 결국 ** 유사도 검색 **을 하기 위해서입니다. MySQL 9.0은 DISTANCE() 함수를 제공합니다.

SQL
-- 코사인 유사도로 가장 비슷한 문서 5개 찾기
SELECT
    id,
    title,
    DISTANCE(embedding, TO_VECTOR('[0.1, 0.2, 0.3, ...]'), 'COSINE') AS similarity
FROM articles
ORDER BY similarity ASC
LIMIT 5;

지원되는 거리 함수:

  • COSINE — 코사인 거리 (방향 유사도, 가장 많이 사용)
  • DOT — 내적 (스케일에 민감)
  • EUCLIDEAN — 유클리디안 거리 (L2 거리)

현재 한계점

솔직히 말하면, 아직은 초기 단계입니다.

  • ** 인덱스 지원이 제한적** — 전용 벡터 인덱스(HNSW, IVFFlat 등)가 아직 없어서, 대량 데이터에서는 풀 스캔이 발생합니다
  • ** 차원 제한** — 최대 16,383차원까지 지원하지만, 대부분의 임베딩 모델은 768~1536차원이라 실무에서는 충분합니다
  • ** 전용 벡터 DB와의 성능 차이** — Pinecone, Milvus, pgvector 같은 전문 솔루션에 비하면 아직 기능이 부족합니다

그래도 "벡터 저장만을 위해 별도 DB를 운영할 필요가 없는" 소규모 프로젝트나, 기존 MySQL 인프라에 벡터 기능을 추가하고 싶을 때는 충분히 고려할 만합니다.

JavaScript 스토어드 프로그램 (9.0)

이건 처음 봤을 때 좀 놀랐습니다. MySQL 안에서 JavaScript로 함수를 작성할 수 있다니요.

기본 구조

GraalVM 기반으로 동작하며, LANGUAGE JAVASCRIPT 키워드로 JS 스토어드 함수를 정의합니다.

SQL
-- JavaScript로 스토어드 함수 만들기
CREATE FUNCTION format_price(price DOUBLE, currency VARCHAR(3))
RETURNS VARCHAR(50)
LANGUAGE JAVASCRIPT
AS $$
    // 통화에 따라 포맷 변경
    const formatter = new Intl.NumberFormat('ko-KR', {
        style: 'currency',
        currency: currency || 'KRW'
    });
    return formatter.format(price);
$$;

-- 사용
SELECT format_price(15000, 'KRW');
-- 결과: ₩15,000

프로시저도 가능

SQL
-- JavaScript 스토어드 프로시저
CREATE PROCEDURE validate_email(IN email VARCHAR(255), OUT is_valid BOOLEAN)
LANGUAGE JAVASCRIPT
AS $$
    // 정규식으로 이메일 검증
    const pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    is_valid = pattern.test(email);
$$;

CALL validate_email('user@example.com', @result);
SELECT @result; -- true

SQL 프로시저와 비교

구분SQL 프로시저JavaScript 프로시저
** 문법**SQL 절차적 확장표준 JavaScript (ES2023+)
** 문자열 처리**제한적정규식, 템플릿 리터럴 등 풍부
JSON 처리JSON_EXTRACT 등 함수 조합네이티브 객체 조작
** 외부 라이브러리**불가제한적으로 가능 (GraalVM 모듈)
** 성능**단순 로직은 빠름JIT 컴파일로 복잡 로직에서 유리
** 에디션**Community + EnterpriseEnterprise Edition 전용

주의할 점

  • Enterprise Edition에서만 사용 가능 할 수 있습니다. Community Edition에서의 지원 여부는 공식 문서를 반드시 확인하세요.
  • 데이터 처리 로직을 DB 안에 넣는 것 자체가 논란이 있으므로, 무분별한 사용은 피해야 합니다.
  • GraalVM 런타임이 필요하므로, 서버 설정 시 추가 구성이 필요합니다.

EXPLAIN ANALYZE FORMAT=JSON 개선

쿼리 튜닝할 때 EXPLAIN을 자주 쓰는데, 9.x에서는 EXPLAIN ANALYZE의 JSON 출력이 크게 개선되었습니다.

기존 EXPLAIN vs EXPLAIN ANALYZE

SQL
-- 기존 EXPLAIN: 예상 실행 계획만 보여줌
EXPLAIN SELECT * FROM orders WHERE user_id = 100;

-- EXPLAIN ANALYZE: 실제 실행 후 실측 데이터까지 보여줌
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 100;

기존 EXPLAIN은 옵티마이저가 예상한 비용과 행 수를 보여주는 반면, EXPLAIN ANALYZE는 쿼리를 ** 실제로 실행 **하고 각 단계의 실측 시간, 처리 행 수, 루프 횟수를 보여줍니다.

JSON 포맷 출력

SQL
EXPLAIN ANALYZE FORMAT=JSON
SELECT o.id, o.total, u.name
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE o.created_at > '2026-01-01';

결과는 이런 식으로 나옵니다:

JSON
{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "125.40"
    },
    "nested_loop": [
      {
        "table": {
          "table_name": "o",
          "access_type": "range",
          "key": "idx_created_at",
          "rows_examined_per_scan": 450,
          "rows_produced_per_join": 450,
          "actual_time_ms": {
            "first_row": 0.12,
            "last_row": 2.34
          },
          "actual_rows": 423
        }
      }
    ]
  }
}

이 JSON 출력이 좋은 이유:

  • ** 예상 vs 실측 비교가 쉽습니다** — rows_examined_per_scan(예상)과 actual_rows(실측)를 바로 비교할 수 있습니다
  • ** 프로그래밍 방식으로 파싱이 가능합니다** — 모니터링 도구에서 JSON을 파싱해서 자동으로 슬로우 쿼리를 분석할 수 있습니다
  • ** 시간 측정이 단계별로 나옵니다** — 어느 단계에서 병목이 생기는지 정확히 파악할 수 있습니다

실무에서 슬로우 쿼리를 잡을 때 TREE 포맷보다 JSON 포맷이 도구 연동에 훨씬 편합니다. Grafana나 자체 모니터링 시스템에 연결할 때 특히 유용합니다.

기타 주요 변경점

트리거 성능 개선 (9.1)

MySQL 9.1에서 트리거의 내부 처리 방식이 개선되어, 트리거가 많은 테이블에서의 DML 성능이 향상되었습니다.

SQL
-- 트리거가 걸린 테이블의 대량 INSERT 성능이 개선됨
-- 이전: 트리거 호출마다 오버헤드가 컸음
-- 이후: 내부적으로 배치 처리 최적화
INSERT INTO orders (user_id, total)
SELECT user_id, amount FROM temp_orders;

DDL 관련 개선

  • ALTER TABLE 진행률 표시 — Performance Schema를 통해 DDL 작업의 진행률을 확인할 수 있습니다
  • ** 온라인 DDL 범위 확대** — 더 많은 ALTER TABLE 작업이 락 없이 가능해졌습니다
SQL
-- DDL 진행률 확인
SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED
FROM performance_schema.events_stages_current
WHERE EVENT_NAME LIKE '%alter%';

보안 강화

  • FIDO/WebAuthn 인증 지원 — 패스워드 없는 인증(Passwordless Authentication)을 MySQL 레벨에서 지원합니다
  • OpenID Connect 인증 — 외부 IdP를 통한 인증이 가능해졌습니다
  • ** 감사 로그 개선** — 더 세밀한 감사 로그 필터링이 가능합니다
SQL
-- WebAuthn 인증 설정 예시
CREATE USER 'admin'@'localhost'
IDENTIFIED WITH authentication_webauthn;

Performance Schema 확장

  • 새로운 계측 포인트(instrument)가 추가되어 더 세밀한 성능 모니터링이 가능합니다
  • 메모리 사용량 추적이 개선되었습니다
  • 트랜잭션 레벨의 통계가 더 상세해졌습니다

8.4 LTS vs 9.x 선택 가이드

실무에서 "어떤 버전을 써야 하나요?"라는 질문을 자주 접하게 됩니다. 상황별로 정리해 보겠습니다.

프로덕션 환경 → 8.4 LTS

PLAINTEXT
✓ 안정성이 검증된 버전
✓ 5년 이상 보안 패치 제공
✓ 대부분의 ORM, 드라이버가 완벽 지원
✓ 클라우드 매니지드 서비스(RDS 등)에서 지원

개발/테스트 환경 → 9.x Innovation

PLAINTEXT
✓ VECTOR 타입으로 AI 기능 프로토타이핑
✓ JavaScript 스토어드 프로그램 실험
✓ 다음 LTS에 포함될 기능을 미리 경험
✗ 지원 기간이 짧아 프로덕션에는 부적합

업그레이드 경로 주의사항

이 부분이 가장 중요합니다:

  1. 8.4 LTS → 9.x Innovation: 가능하지만, 되돌릴 수 없습니다
  2. **9.x → 이전 버전 다운그레이드 **: 지원되지 않습니다
  3. 9.x → 다음 9.y 또는 다음 LTS: 정상 업그레이드 경로입니다
  4. 8.0 → 8.4 LTS: 권장되는 업그레이드 경로입니다
PLAINTEXT
[권장 경로]
8.0 ──→ 8.4 LTS ──→ (유지) ──→ 다음 LTS
                  └──→ 9.x (테스트용) ──→ 다음 LTS

[비권장]
8.0 ──→ 9.x (프로덕션) ──→ ??? (다운그레이드 불가)

프로덕션에서 Innovation 트랙을 쓰겠다면, 분기마다 업그레이드할 준비가 되어 있어야 합니다. 대부분의 팀에서는 LTS를 유지하면서 스테이징에서만 Innovation을 테스트하는 방식이 현실적입니다.

정리

MySQL 9.x의 핵심을 요약하면 이렇습니다:

변경점버전핵심 내용
** 릴리즈 모델**8.4+LTS(장기 지원)와 Innovation(분기 릴리즈) 이중 트랙
VECTOR 타입9.0N차원 벡터 저장 + 유사도 검색 함수
JS 스토어드 프로그램9.0GraalVM 기반 JavaScript 함수/프로시저
EXPLAIN ANALYZE JSON9.x실측 데이터의 JSON 출력 개선
** 보안 강화**9.xFIDO/WebAuthn, OpenID Connect
** 트리거 성능**9.1DML 트리거 처리 최적화

기억해 두면 좋은 포인트:

  • VECTOR 타입이 생겼다고 바로 pgvector나 전용 벡터 DB를 대체할 수준은 아닙니다. 하지만 MySQL만으로 간단한 벡터 검색이 가능해졌다는 것 자체가 의미 있는 변화입니다.
  • ** 릴리즈 모델 변화가 실무적으로 가장 큰 영향 **을 미칩니다. 앞으로 MySQL 버전 선택은 "최신 버전"이 아니라 "LTS냐 Innovation이냐"로 결정해야 합니다.
  • ** 프로덕션은 LTS, 실험은 Innovation** — 이 원칙만 기억하면 버전 선택에서 크게 헤매지 않습니다.
댓글 로딩 중...