# MariaDB -> MySQL 이관

## Azure MariaDB 종료 대응 : 180GB 데이터를 Azure MySQL 로 이전한 경험

Azure MariaDB 서비스 종료에 따라, 기존 PaaS MariaDB 인스턴스를 Azure MySQL 로 이전해야 하는 작업이 필요했다.

처음에는 가장 익숙한 방식인 `mysqldump` 를 생각했지만, 전체 DB 크기가 약 180GB 였고, 예상 dump 시간이 16시간 수준으로 나왔다. 이 정도면 운영 영향이 너무 커서 현실적인 선택지가 아니었다.

그래서 최종적으로는 `mysqlsh` 를 이용해 초기 데이터를 적재하고, 이후 MariaDB 와 MySQL 간 replication 을 구성해 변경분을 따라잡는 방식으로 전환 전략을 잡았다.

핵심은 단순 dump/restore 가 아니라, **대용량 데이터를 빠르게 옮기고 최종 cutover 시점의 차이를 최소화하는 것** 이었다.&#x20;

***

### 왜 mysqldump 대신 mysqlsh 를 선택했는가

이번 작업에서 가장 먼저 한 판단은 도구 선택이었다.

`mysqldump` 는 익숙하고 단순하지만, 180GB 규모에서는 시간이 너무 오래 걸렸다. 반면 `mysqlsh` 는 대용량 이관에서 유리한 기능을 제공했다.

* `thread` : 병렬 처리로 dump/load 속도 향상
* `chunking` : 큰 테이블을 작은 단위로 나눠 처리
* `consistent` : 백업 시작 시점 기준 일관성 보장
* `users` :  계정과 권한 정보까지 함께 이관 가능
* `showProgress` : 진행률 실시간 확인 가능

즉 , `mysqlsh` 는 단순 백업 도구라기보다 **대용량 마이그레이션용 도구** 에 더 가까웠다.

***

### 전체 작업 흐름&#x20;

이번 작업은 아래 순서로 진행했다.

1. Azure MySQL 서버 생성 및 준비
2. 디스크 용량이 큰 서버에 `mysqlsh` 설치
3. 서버에서 MariaDB 를 `util.dumpInstance()` 로 데이터 export
4. export 한 데이터를 MySQL 에 `util.loadDump()` 로 import&#x20;
5. binlog 정보를 기반으로 MariaDB -> MySQL replication 구성
6. 데이터 개수 및 상태 검증
7. 최종 cutover 준비

여기서 중요한 건 dump/load 만으로 끝내지 않고, replication 을 붙여 초기 **적재 이후 발생하는 변경분까지 따라가게 만든 점** 이었다.&#x20;

***

### mysqlsh 사용 시 중요하게 봤던 옵션

#### threads

백업/복구 작업을 여러 스레드로 나누어 병렬 처리할 수 있다.

CPU 와 I/O 여유가 있는 환경에서는 이 값이 전체 속도에 큰 영향을 준다.

#### consistent

백업 도중 데이터가 변경되더라도, 백업 시작 시점 기준으로 일관성을 유지한다.

운영 데이터 이관에서는 사실상 필수에 가까운 옵션이었다.

#### chunking

대형 테이블을 한 번에 처리하지 않고 여러 덩어리로 나누기 때문에, 실패 복구와 병렬 처리 효율면에서 유리했다.

#### users

사용자 계정과 권한 정보도 함께 옮길 수 있어서 후처리 부담을 줄일 수 있었다.

***

### replication 을 구성한 이유

초기 dump/load 만으로도 데이터를 옮길 수는 있지만, 운영 중인 DB 는 그 사이에서도 계속 변경된다.

그래서 dump 시점 이후의 변경분을 따라잡기 위해 replication 을 추가로 구성했다.

작업 흐름은 다음과 같았다.

* dump 결과 폴더에서 binlog file / position 확인
* `mysql.az_replication_change_master(...)` 호출
* `mysql.az_replication_start` 로 replication 시작
* `show slave status\G` 로 상태 확인.

이 과정을 통해 초기 적재와 실제 전환 시점 사이의 차이를 줄일 수 있었다.

***

### 성능 튜닝 : import 속도를 어떻게 줄였는가

이 작업에서 개인적으로 가장 의미 있었던 부분은 import 성능을 차수별로 비교한 것이다.

기본 설정으로도 import 는 가능했지만, 세팅을 바꾸면서 시간을 더 줄일 수 있었다.

예를 들어 아래 변수들을 조정했다.

* `innodb_buffer_pool_size`
* `innodb_flush_log_at_trx_commit`
* `local_infile`
* `sql_log_bin`
* `sync_binlog`

초기에는 기본 import 로 진행했고, 이후 buffer pool, binlog 관련 옵션 등을 조정하면서 import 시간을 단축했다.

특히 `sync_binlog=0`, `sql_log_bin=OFF` 같은 설정은 이관 작업 속도에 직접적인 영향을 줬다.&#x20;

물론 이런 설정은 운영 환경에서 항상 그대로 쓰는 게 아니라, **이관 작업 목적에 맞게 신중하게 적용해야 한다.**

| 차수 | 환경     | 주요 설정             | 소요 시간             |
| -- | ------ | ----------------- | ----------------- |
| 1차 | 집 노트북  | default import    | 13분               |
| 2차 | 집 노트북  | buffer\_pool 16GB | 11분               |
| 3차 | 집 노트북  | 추가 튜닝 적용          | 10분               |
| 4차 | 집 노트북  | sync\_binlog=0 포함 | 8분                |
| 5차 | 회사 노트북 | 4차와 동일            | lock wait timeout |

* `sql_log_bin=OFF` : import 중 불필요한 binary log 부담 완화
* `innodb_flush_log_at_trx_commit=2` : 쓰기 성능 개선
* `sync_binlog=0` : 디스크 flush 부담 감소
* `innodb_buffer_pool_size=16GB` : 메모리 캐시 확보

***

### 실제로 느낀 점

이번 작업을 하면서 가장 크게 느낀건, 대용량 DB 이관에서는 단순히 "데이터를 옮긴다" 보다 **도구 선택, 네트워크 위치, 디스크 I/O, replication 전략** 이 훨씬 중요하다는 점이었다.

특히 추천하고 싶은 조건은 다음과 같다.

* 성능이 좋은 서버를 사용할 것
* 가능하다면 DB 와 같은 네트워크/VPC 안에서 작업할 것
* import 전 읽기/쓰기 성능을 확인할 것

실제로 노트북별 디스크 속도 차이도 import 결과에 영향을 줬고, 이런 부분이 체감상 꽤 컸다.

***

### 마무리

이번 작업은 단순한 dump/restore 가 아니라, **Azure MariaDB 종료에 대응해 180GB 규모의 데이터를 Azure MySQL 로 안정적으로 이전하기 위한 마이그레이션 작업** 이었다.

결과적으로 이번 경험을 통해 배운건 세 가지였다.

* 대용량 DB 에서는 `mysqldump` 가 항상 정답이 아니다.
* `mysqlsh` 는 병렬 처리와 일관성 보장 측면에서 강력한 선택지다.
* 초기 적재 후 replication 을 붙이면 cutover 부담을 크게 줄일 수 있다.

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wjddustkd45.gitbook.io/organizeme/company-org/mariadb-greater-than-mysql.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
