> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MySQL의 읽기 복제본

> MySQL 복제본으로 읽기를 확장하는 방법: 쿼리 라우팅, 복제 지연과 함께 살아가기, 그리고 모든 복제본 구성이 부딪히는 자신의 쓰기 읽기 문제입니다.

> [card] [VillageSQL is a drop-in replacement for MySQL with extensions.](https://villagesql.com/docs/en/8.4/stable/install-server.md)
>
> All examples on this page work on VillageSQL. Install Now →

읽기 복제본은 소스가 쓰는 모든 것을 재생하고 읽기 쿼리에 응답하는 두 번째 서버입니다. 복제본은 읽기를 거의 선형으로 확장하고 장애 조치를 위한 웜(warm) 사본을 제공하지만, 애플리케이션이 떠안아야 할 새로운 문제가 하나 생깁니다: 복제본은 항상 약간 뒤처져 있고, 어떤 설정 옵션도 그것을 없애주지 않습니다. 복제 자체를 구성하는 방법은 [복제 기초](https://villagesql.com/docs/ko/guides/replication-basics.md)에서 다룹니다; 이 가이드는 복제본을 잘 사용하는 방법에 관한 것입니다.

## 복제본의 용도

* **읽기 확장.** 대시보드, 검색, 내보내기, API 읽기가 소스에서 빠져나가, 소스의 용량이 쓰기를 위해 남습니다.
* **비싼 쿼리의 격리.** 분석가의 40초짜리 집계가 복제본에서 실행되어 아무도 막지 않습니다.
* **웜 스탠바이(warm standby).** 최신 상태의 복제본은 소스가 실패할 때 승격할 수 있습니다.

복제본의 용도가 아닌 것: 쓰기 확장 도구. 모든 복제본은 소스가 받는 모든 쓰기를 재생하므로, 복제본은 쓰기 용량을 전혀 더하지 않습니다.

## 읽기 라우팅

MySQL은 쿼리를 대신 라우팅해 주지 않습니다. 스택의 무언가가 쓰기를 소스로, 선택한 읽기를 복제본으로 보내야 합니다:

* **애플리케이션 수준 라우팅.** 대부분의 프레임워크가 직접 지원합니다(Django 데이터베이스 라우터, Rails `connects_to`/roles, Laravel 읽기/쓰기 연결). 단순하고 명시적이며, 애플리케이션이 쿼리마다 결정합니다.
* **프록시.** ProxySQL과 비슷한 도구들은 문장 유형이나 규칙에 따라 라우팅하므로, 애플리케이션은 연결 문자열 하나를 유지합니다. 장애 조치도 한곳에 모읍니다.

애플리케이션 수준 라우팅으로 시작하세요. 올바른 질문을 일찍 던지게 합니다: "이 쿼리를 복제본에서 실행할 수 있는가"가 아니라 "이 쿼리가 오래된 데이터를 견딜 수 있는가"입니다.

## 복제 지연: 진짜 어려운 부분

복제는 기본적으로 비동기입니다. 소스의 커밋은 복제본이 변경을 적용하기 전에 반환되므로, 잠시 뒤의 복제본 읽기는 이미 성공한 쓰기를 놓칠 수 있습니다. 복제본에서 지연을 측정하세요:

```sql theme={null}
SHOW REPLICA STATUS\G
```

`Seconds_Behind_Source` 필드가 표준 신호입니다. 보통은 0에 가깝고, 쓰기 폭주, 큰 트랜잭션, 스키마 변경 아래에서 치솟습니다. 이 값에 경보를 걸고, 읽기 경로별로 허용 범위를 알아 두세요.

전형적인 실패는 \*\*자신의 쓰기 읽기(read-your-own-writes)\*\*입니다: 사용자가 프로필을 저장하고(소스에 쓰기), 다음 페이지가 복제본에서 그것을 불러오는데, 복제본이 아직 그 쓰기를 적용하지 않은 경우입니다. 사용자는 자신의 변경이 사라지는 것을 봅니다. 표준 완화책을 가장 싼 것부터 나열하면:

* **쓰기 후 고정.** 세션이 쓰기를 한 뒤, 다음 몇 초 동안 그 세션의 읽기를 소스로 라우팅합니다. 많은 프레임워크와 프록시가 이 패턴을 직접 지원합니다.
* **허용 범위에 따라 라우팅.** 금액 잔액과 방금 편집한 페이지는 소스에서 읽고, 탐색 페이지, 검색, 분석은 복제본에서 읽습니다.
* **GTID를 통한 세션 일관성.** 쓰기 후 트랜잭션 식별자를 잡아두고, 복제본 읽기가 `WAIT_FOR_EXECUTED_GTID_SET()`으로 그것을 기다리게 합니다. 정확하지만, GTID를 요청에 실어 나르는 배관 작업이 필요합니다.

## 두 가지 실용적인 규칙

* **복제본은 남는 하드웨어가 아니라 소스 이상의 사양을 갖춘 하드웨어여야 합니다.** 소스보다 느린 복제본은, 바로 복제본을 추가하게 만든 그 부하 아래에서 뒤처집니다.
* **승격을 연습하세요.** 한 번도 승격해 본 적 없는 복제본은 한 번도 복원해 본 적 없는 백업입니다. 필요해지기 전에 장애 조치 경로를 연습하세요.

VillageSQL은 이 복제 메커니즘을 MySQL 8.4에서 변경 없이 물려받으므로, 위의 모든 내용이 VillageSQL에도 그대로 적용됩니다.

## 함께 보기

* [복제 기초](https://villagesql.com/docs/ko/guides/replication-basics.md) — 이 가이드가 기반으로 삼는 복제 구성하기
* [바이너리 로깅](https://villagesql.com/docs/ko/guides/binary-logging.md) — 복제본이 재생하는 로그 스트림
* [연결 풀링](https://villagesql.com/docs/ko/guides/connection-pooling.md) — 읽기와 쓰기가 나뉜 뒤 역할별 풀링


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.