카테고리 : MySQL/기술노트

MySQL 고가용성 설계 개요: 단일 장애점, RTO/RPO, failover domain

MySQL 고가용성을 장애 영역, 데이터 보존 경계, 쓰기 권한 전환으로 나누고 단일 장애점과 RTO/RPO를 검증하는 설계 기준을 정리한다.

저자: MySQL 기술 노트 작성: 2026.10.28 약 11분 6,422자
다운로드

서버 두 대가 있다는 사실만으로 고가용성이 완성되지는 않는다. 두 서버가 같은 전원·스토리지·네트워크에 의존하면 함께 멈출 수 있고, 복제본이 살아 있어도 연결 경로가 끊기면 서비스는 사용할 수 없다. 반대로 복구 시간을 줄이려고 확인 없이 복제본을 승격하면 누락된 트랜잭션과 이중 쓰기라는 더 큰 장애를 만들 수 있다.

고가용성 설계의 출발점은 제품 선택이 아니라 세 가지 계약이다. 어떤 장애까지 견디는가, 어느 데이터 경계까지 보존하는가, 언제부터 업무가 다시 성공해야 하는가. 이 글은 Community MySQL 8.0/8.4를 중심으로 그 계약을 구성하고, Aurora MySQL에서는 책임 경계가 어떻게 달라지는지 설명한다.

아래 SQL은 폐기용 MySQL 8.0 인스턴스에서 실행한 진단과 설계 판정 예제다. 가정한 GTID 집합·시간·승인 플래그를 사용하며, 실제 다중 서버 장애 전환이나 Aurora 장애를 재현한 결과가 아니다. 설계식의 실행 성공과 운영 환경의 고가용성 입증을 구분해야 한다.

1. 가용성의 단위는 프로세스가 아니라 업무 경로다

DB 프로세스가 살아 있는지와 주문 처리가 가능한지는 다른 질문이다. 업무 요청은 일반적으로 애플리케이션의 연결 풀, 이름 해석 또는 프록시, 인증, MySQL 실행, 로그와 데이터 저장을 거친다. 어느 한 요소가 유일한 경로라면 그 요소가 단일 장애점(SPOF)이 될 수 있다.

  • 데이터 경로: writer, 복제 채널, 저장 장치, 네트워크, 연결 풀, 프록시.
  • 판단·제어 경로: 장애 감지기, 승격 제어기, 합의 구성원, 잠금 또는 lease 저장소, 운영자 승인 경로.
  • 복구 경로: 백업 저장소, 암호화 키, 이미지·패키지 저장소, 복원 권한, DNS와 비밀정보 배포 경로.

제어 경로가 잠시 고장 나도 이미 연결된 DB는 계속 서비스할 수 있다. 그러나 그 상태에서 writer까지 고장 나면 자동 전환이 불가능하다. 따라서 정상 시 가용성과 전환 시 가용성을 따로 점검한다. 백업도 같은 계정과 같은 장애 영역에만 있으면 DB와 함께 접근 불능이 될 수 있다.

flowchart TD
    A[업무 요청과 연결 풀] --> B[이름 해석 또는 프록시]
    B --> W[현재 writer]
    W --> D[커밋 로그와 데이터]
    W --> R[후보 replica]
    M[독립적인 장애 관측] --> C[승격 제어와 승인]
    C --> F[기존 writer 쓰기 차단]
    F --> G[후보 데이터 경계 확인]
    G --> P[새 writer 승격]
    P --> B
    P --> V[재접속과 업무 검증]

이 그림은 역할 분리를 보여 준다. 모든 구성 요소를 별도 서버로 설치하라는 뜻은 아니다. 다만 복제 데이터가 도착했다는 신호를 쓰기 권한 이전의 승인으로 사용해서는 안 된다. 데이터 보존과 writer 독점은 서로 다른 검증 항목이다.

2. 장애 영역과 failover domain을 먼저 그린다

장애 영역(failure domain)은 같은 원인으로 함께 실패할 수 있는 범위다. 프로세스, 가상 머신 호스트, 물리 장비, 랙, 가용 영역, 리전, 계정·권한 체계로 넓어질 수 있다. 같은 랙의 서로 다른 서버는 프로세스 장애에는 독립적이지만 랙 전원 장애에는 독립적이지 않다.

이 글에서 failover domain은 장애를 감지하고 후보를 선택해 쓰기 권한과 접속 경로를 넘기는 운영 범위를 뜻한다. MySQL의 단일 설정 변수명이 아니다. 같은 리전 내 자동 승격과 리전 간 재해복구는 서로 다른 전환 범위로 설계할 수 있다. 각 범위마다 승인 주체, 허용 손실, 네트워크 차단 방식, 복귀 절차를 명시한다.

2.1 노드 수보다 장애 후 남는 배치가 중요하다

세 구성원의 과반수 합의에서 한 구성원을 잃어도 두 구성원이 통신하면 과반수를 유지할 수 있다. 그러나 세 구성원 중 둘을 같은 가용 영역에 놓으면 그 영역을 잃을 때 과반수도 잃는다. MySQL Group Replication의 단순한 구성원 장애 모델에서는 2f + 1개의 구성원으로 f개 장애를 견디는 구조지만, 실제 영역 장애는 여러 구성원을 한꺼번에 제거할 수 있다.

따라서 배치도를 그릴 때는 서버 아이콘만 세지 않는다. 각 장애 시나리오에서 남는 투표 구성원, 후보의 데이터, 접속 가능 경로, 인증과 키 접근을 함께 확인한다. 중재자 한 대를 임의로 추가했다고 Group Replication의 정식 구성원이 된다고 해석해서도 안 된다.

2.2 상관 장애는 복제로 해결되지 않는다

잘못된 배포, 대량 삭제, 계정 탈취, 잘못된 DDL은 여러 노드로 전파될 수 있다. 복제본이 최신일수록 실수도 빠르게 복제된다. 이 경우 HA보다 시점 복구, 불변 백업, 지연 복제, 권한 분리가 필요하다. 고가용성과 재해복구, 논리적 오류 복구는 대체 관계가 아니라 상호 보완 관계다.

3. RTO와 RPO를 장애 시나리오별로 정의한다

RTO는 정의한 장애 시작점부터 업무 기능이 허용 수준으로 복구될 때까지의 목표 시간이다. 모니터링 경보 발생부터 측정하면 경보 이전의 미탐지 시간을 누락할 수 있다. 종료점 역시 DB 승격 완료가 아니라 재접속, 인증, 첫 성공 트랜잭션, 필요한 처리량 회복 중 무엇인지 정해야 한다.

직렬 절차의 계획 예산은 다음과 같이 나눌 수 있다.

탐지 + 판단·격리 + 후보 데이터 적용 + 승격 + 접속 전환·업무 검증

실제 병렬 작업이 있으면 합계 대신 임계 경로를 사용한다. 각 단계의 p95를 더한 값을 전체 RTO의 p95라고 부르지 않는다. 여러 훈련에서 동일한 시작·종료 기준으로 측정해야 분포를 비교할 수 있다.

RPO는 장애 시 잃어도 되는 데이터의 시간적 범위에 관한 목표다. 거래 시스템에서는 마지막 고객 응답 완료 커밋, 복제본에 영속화된 경계, 후보가 적용한 경계를 구분하고 누락된 업무 키까지 확인하는 것이 중요하다. 복제 지연 수치 한 개나 GTID 개수 차이만으로 초 단위 RPO를 계산할 수 없다.

예를 들어 비동기 복제에서 source가 성공 응답한 커밋이 replica로 전송되기 전에 source를 잃으면 데이터가 누락될 수 있다. 반면 이벤트가 relay log에 안전하게 도착했지만 아직 적용되지 않았다면, 누락이 아니라 승격 전 적용에 필요한 시간이 문제일 수 있다. 이 구분을 하지 않으면 RPO를 맞추기 위한 대기 시간을 RTO 계획에서 빠뜨린다.

3.1 계획 예산의 실행 가능한 점검

다음 수치는 설명용 가정이다. 실제 전환 시간이나 제품 보장값이 아니다. 목표보다 짧은 계획과 초과한 계획뿐 아니라 관측되지 않은 단계도 분리한다. NULL을 0초로 바꾸면 미확인 상태가 정상으로 통과하므로 금지한다.

WITH budgets AS (
    SELECT 'planned' AS scenario, 10 AS detect_s, 15 AS fence_s,
           20 AS apply_s, 5 AS promote_s, 30 AS reconnect_s, 90 AS target_s
    UNION ALL
    SELECT 'slow_apply', 10, 15, 70, 5, 30, 90
    UNION ALL
    SELECT 'unknown_fence', 10, NULL, 20, 5, 30, 90
), totals AS (
    SELECT scenario, target_s,
           detect_s + fence_s + apply_s + promote_s + reconnect_s AS budget_s
    FROM budgets
)
SELECT scenario, budget_s, target_s,
       CASE WHEN budget_s IS NULL THEN 'UNVERIFIED'
            WHEN budget_s <= target_s THEN 'WITHIN_BUDGET'
            ELSE 'OVER_BUDGET' END AS assessment
FROM totals
ORDER BY scenario;

실행 결과(MySQL 8.0.x):

mysql> WITH budgets AS (
    ->     SELECT 'planned' AS scenario, 10 AS detect_s, 15 AS fence_s,
    ->            20 AS apply_s, 5 AS promote_s, 30 AS reconnect_s, 90 AS target_s
    ->     UNION ALL
    ->     SELECT 'slow_apply', 10, 15, 70, 5, 30, 90
    ->     UNION ALL
    ->     SELECT 'unknown_fence', 10, NULL, 20, 5, 30, 90
    -> ), totals AS (
    ->     SELECT scenario, target_s,
    ->            detect_s + fence_s + apply_s + promote_s + reconnect_s AS budget_s
    ->     FROM budgets
    -> )
    -> SELECT scenario, budget_s, target_s,
    ->        CASE WHEN budget_s IS NULL THEN 'UNVERIFIED'
    ->             WHEN budget_s <= target_s THEN 'WITHIN_BUDGET'
    ->             ELSE 'OVER_BUDGET' END AS assessment
    -> FROM totals
    -> ORDER BY scenario;

+---------------+----------+----------+---------------+
| scenario      | budget_s | target_s | assessment    |
+---------------+----------+----------+---------------+
| planned       |       80 |       90 | WITHIN_BUDGET |
| slow_apply    |      130 |       90 | OVER_BUDGET   |
| unknown_fence |     NULL |       90 | UNVERIFIED    |
+---------------+----------+----------+---------------+
3 rows in set (0.00 sec)

WITHIN_BUDGET는 입력한 숫자가 예산 안이라는 뜻일 뿐이다. 장애 탐지 오판, API 제한, DNS 캐시, 복제 적용 경합, 연결 폭주를 견뎠다는 증거가 아니다. 실제 운영 승인에는 장애 주입과 업무 수준 검증이 추가되어야 한다.

4. 커밋 보장과 승격 보장은 같은 것이 아니다

MySQL의 기본 비동기 복제에서는 source의 커밋과 replica의 수신·적용이 분리된다. source의 innodb_flush_log_at_trx_commit과 sync_binlog는 로컬 내구성을 해석하는 출발점이지만, 값만으로 다른 노드까지 커밋이 보존되었다고 할 수 없다. 저장 장치의 영속화 동작, binlog 활성화 여부, 복제 상태도 조건에 포함된다.

반동기 복제는 설정한 수의 replica가 이벤트를 수신하고 로그에 기록했음을 확인하도록 source를 대기시킨다. 이는 replica에서 업무 행 적용까지 끝났다는 보장이 아니다. 대기 시간 초과 뒤 비동기 방식으로 돌아가는 동작도 고려해야 한다. 따라서 “반동기 설정이 켜져 있다”와 “해당 커밋이 반동기 확인을 받았다”를 구분하고, 실제 상태와 timeout 이력을 감시한다. 확인을 준 replica가 아닌 다른 후보를 승격해도 같은 데이터 보존을 얻는다고 가정해서는 안 된다.

Group Replication은 그룹 통신·인증·멤버십과 과반수에 기반한 다른 경로를 사용한다. 여기서도 일관성 모드, 트랜잭션 적용 대기, 실패 감지 시간, 클라이언트 접속 경로를 별도로 설계한다. 그룹 합의가 있다는 사실이 애플리케이션 연결의 무중단을 뜻하지는 않는다.

4.1 로컬 상태를 읽되 범위를 넘겨 해석하지 않는다

다음 진단은 접속한 서버의 역할 관련 설정을 읽는다. 테스트 인스턴스는 binlog와 GTID를 사용하지 않으므로 log_bin=0, gtid_mode=OFF가 표시될 수 있다. 그것은 검증 환경의 상태이지 운영 권장 설정이 아니다. 이 쿼리만으로 복제 정상성이나 승격 가능 여부를 판정하지 않는다.

SELECT VERSION() AS mysql_version,
       @@GLOBAL.log_bin AS log_bin,
       @@GLOBAL.gtid_mode AS gtid_mode,
       @@GLOBAL.read_only AS read_only,
       @@GLOBAL.super_read_only AS super_read_only,
       @@GLOBAL.innodb_flush_log_at_trx_commit AS redo_flush,
       @@GLOBAL.sync_binlog AS sync_binlog;

실행 결과(MySQL 8.0.x):

mysql> SELECT VERSION() AS mysql_version,
    ->        @@GLOBAL.log_bin AS log_bin,
    ->        @@GLOBAL.gtid_mode AS gtid_mode,
    ->        @@GLOBAL.read_only AS read_only,
    ->        @@GLOBAL.super_read_only AS super_read_only,
    ->        @@GLOBAL.innodb_flush_log_at_trx_commit AS redo_flush,
    ->        @@GLOBAL.sync_binlog AS sync_binlog;

+---------------+---------+-----------+-----------+-----------------+------------+-------------+
| mysql_version | log_bin | gtid_mode | read_only | super_read_only | redo_flush | sync_binlog |
+---------------+---------+-----------+-----------+-----------------+------------+-------------+
| 8.0.46        |       0 | OFF       |         0 |               0 |          1 |           1 |
+---------------+---------+-----------+-----------+-----------------+------------+-------------+
1 row in set (0.00 sec)

read_only에는 권한에 따른 예외가 있고, super_read_only는 일반 클라이언트 쓰기를 더 강하게 제한한다. 그러나 네트워크가 분리된 예전 writer에 설정을 전달할 수 없다면 그 값을 바꾸려는 시도 자체가 fencing의 증거가 되지 않는다. 읽기 전용 설정도 적절한 권한을 가진 주체가 해제할 수 있으므로 권한 통제와 함께 사용한다.

5. 안전한 전환은 탐지·차단·데이터 확인·승격의 순서다

5.1 응답 없음은 사망 증명이 아니다

감시 지점에서 writer로 접근할 수 없는 이유는 프로세스 종료, 네트워크 단절, 과부하, 인증 실패 등 여러 가지다. 다른 애플리케이션에서는 여전히 writer에 연결할 수 있을 수 있다. 한 지점의 ping 실패만으로 새 writer를 만들면 서로 다른 데이터 계보가 발생하는 split-brain을 만들 수 있다.

Fencing은 이전 writer가 업무 쓰기를 계속할 수 없도록 보장하는 조치다. 전원·인스턴스 제어, 네트워크 차단, 저장소 접근 통제, 모든 writer가 준수하는 외부 lease 같은 방법을 환경에 맞게 선택한다. 어느 방법이든 우회 접속, 기존 연결, 제어 API 실패, lease 만료와 시간 가정을 검토해야 한다. 프록시의 새 연결만 변경하고 기존 writer의 직접 접속을 열어 두면 충분하지 않다.

차단 여부를 증명하지 못한 상태는 “전환을 빨리 해야 한다”가 아니라 자동 승격 중지 조건이다. 데이터 손실 허용 승인과 이중 writer 방지 승인은 서로 대체되지 않는다.

5.2 후보의 데이터 경계는 명시적 집합으로 확인한다

다음은 GTID 집합 포함 관계를 계산하는 축소 예제다. UUID는 설명용 식별자이고 입력 플래그는 외부 검증 결과를 가정한다. required_set은 장애 전에 보존했다고 주장하는 커밋 경계다. 실제 장애로 이 경계를 확보하지 못하면 RPO 0을 증명할 수 없으며 미확인으로 처리해야 한다.

WITH candidates AS (
    SELECT 'ready' AS candidate, 1 AS fence_ok, 1 AS evidence_ok,
           'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-100' AS required_set,
           'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-100' AS applied_set
    UNION ALL
    SELECT 'missing', 1, 1,
           'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-100',
           'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-98'
    UNION ALL
    SELECT 'unfenced', 0, 1,
           'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-100',
           'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-100'
    UNION ALL
    SELECT 'unknown', 1, 0, NULL,
           'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-100'
    UNION ALL
    SELECT 'divergent', 1, 1,
           'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-100',
           'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-101'
)
SELECT candidate,
       GTID_SUBTRACT(required_set, applied_set) AS missing_gtids,
       CASE WHEN fence_ok <> 1 OR fence_ok IS NULL THEN 'BLOCK_FENCING'
            WHEN evidence_ok <> 1 OR evidence_ok IS NULL
                 OR required_set IS NULL OR applied_set IS NULL
                 THEN 'BLOCK_EVIDENCE'
            WHEN GTID_SUBSET(required_set, applied_set) = 0 THEN 'BLOCK_MISSING'
            WHEN GTID_SUBSET(applied_set, required_set) = 0 THEN 'REVIEW_EXTRA'
            ELSE 'READY_FOR_REVIEW' END AS decision
FROM candidates
ORDER BY candidate;

실행 결과(MySQL 8.0.x):

아래는 입력 CTE와 조회문 표시만 줄인 결과다. 결과 열과 행은 모두 유지했다.

mysql> WITH candidates AS (...) SELECT ... ORDER BY candidate;
+-----------+---------------------------------------------+------------------+
| candidate | missing_gtids                               | decision         |
+-----------+---------------------------------------------+------------------+
| divergent |                                             | REVIEW_EXTRA     |
| missing   | aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:99-100 | BLOCK_MISSING    |
| ready     |                                             | READY_FOR_REVIEW |
| unfenced  |                                             | BLOCK_FENCING    |
| unknown   | NULL                                        | BLOCK_EVIDENCE   |
+-----------+---------------------------------------------+------------------+
5 rows in set (0.00 sec)

missing은 마지막 두 GTID가 부족하고, unfenced는 집합이 같아도 차단한다. unknown은 경계 미확인으로 차단한다. divergent는 기준 밖 이력이 있어 검토 대상으로 둔다. 기준을 채집한 뒤 정상적으로 생성된 커밋일 수도 있으므로 추가 GTID를 무조건 데이터 오염으로 단정하지 않는다. 다만 후보만의 쓰기인지, 다른 source의 이력인지, 기준이 오래되었는지 확인 없이 넘기지 않는다.

READY_FOR_REVIEW도 자동 승격 명령이 아니다. GTID 집합은 실행 이력을 나타내지만, 필터링이나 빈 GTID 주입이 있으면 같은 집합이라도 업무 행이 다를 수 있다. 실무에서는 채널의 수신·적용 오류, relay log의 미적용 이벤트, 데이터 정합성, 후보 부하, 접속 경로를 더 확인한다. 문자열 함수는 GTID 모드가 꺼진 테스트 서버에서도 계산되므로 이 결과를 실제 복제 검증으로 확대할 수 없다.

6. 전환 완료의 마지막 구간은 애플리케이션이다

승격이 끝난 뒤에도 기존 연결은 자동으로 새 writer에 이동하지 않는다. 연결 풀의 검증·폐기·재생성, DNS 캐시 수명, 프록시의 대상 갱신, 재시도 정책이 복구 시간을 결정한다. 모든 클라이언트가 동시에 재접속하면 인증과 연결 처리 자체가 병목이 되므로 제한된 재시도와 지수형 대기, 무작위 지연을 적용한다.

더 중요한 문제는 커밋 결과 불명확성이다. 서버가 커밋한 뒤 성공 응답이 유실되면 클라이언트는 실패를 보지만 데이터는 이미 반영되어 있을 수 있다. 무조건 재실행하면 중복 결제·중복 주문을 만들 수 있다. 요청 식별자의 고유성, 멱등 처리, 결과 조회 후 재시도 계약이 HA 설계에 포함되어야 한다.

첫 업무 쓰기 전에 후보를 포기하는 것과 새 writer에서 업무 쓰기가 시작된 뒤 예전 writer로 돌아가는 것은 다르다. 후자는 새로운 데이터 계보를 반영해야 하는 별도의 복귀 작업이다. 예전 서버가 살아났다고 주소만 돌리지 말고 격리 유지, 데이터 재동기화 또는 재구축, 검증 후 replica 편입 순서로 처리한다.

7. Aurora MySQL에서는 저장소와 컴퓨트의 장애 대응을 분리한다

Aurora는 클러스터 데이터를 여러 가용 영역의 분산 저장소에 보관한다. 이 저장소 중복은 reader 인스턴스 유무와 별개의 성질이다. 저장소 사본이 있다는 사실과 즉시 승격할 컴퓨트 후보가 있다는 사실은 다르다. Writer만 있는 구성과 다른 가용 영역에 승격 가능한 reader를 둔 구성은 복구 경로가 다르다.

AWS 문서는 reader를 두 개 이상의 가용 영역에 배치하도록 권고하며, 장애 시 reader의 승격 순서를 promotion tier 등으로 제어할 수 있다고 설명한다. 후보의 인스턴스 용량과 설정도 업무 부하를 감당해야 한다. 다른 리전의 장애 복구는 같은 클러스터 안의 writer 교체와 구분하여 Aurora Global Database 등 별도 범위로 설계한다.

클러스터 endpoint를 사용하더라도 이미 열린 연결이 보존되는 것은 아니다. 장애 동안 읽기·쓰기가 실패할 수 있고 애플리케이션의 재접속과 트랜잭션 재시도가 필요하다. 공식 문서의 통상적인 복구 시간 설명을 업무 시스템의 RTO 보장값으로 사용하지 않는다. DNS·연결 풀·업무 검증 시간을 포함해 직접 측정한다.

Aurora의 저장소 복제에 Community MySQL의 binlog 반동기 복제 모델을 그대로 대입하지 않는다. 관리형 서비스가 감지·승격의 상당 부분을 수행해도 후보 배치, endpoint 사용, 멱등성, 접근 권한, 백업 보존, 리전 장애 대책은 사용자의 설계 책임으로 남는다. 이 글에서는 Aurora API를 호출하거나 실제 failover 시간을 측정하지 않았다.

8. 장애 시나리오별 승인 기준과 리허설

운영 문서는 “자동 전환 지원” 한 줄보다 장애별 수용 기준이 구체적이어야 한다.

  • Writer 프로세스 종료: 후보의 수신·적용 상태, 이전 프로세스 재기동 시 격리, 접속 전환 후 업무 성공을 확인한다.
  • 가용 영역 상실: 후보뿐 아니라 과반수, 프록시, 제어 API 접근, 인증 경로가 남는지 확인한다.
  • 네트워크 분할: 양쪽에서 동시에 쓰기를 받아들이지 않는지 검증한다. 접근 불가와 종료를 구분하는 핵심 시험이다.
  • 복제 적용 지연·오류: 느린 후보를 승격하지 않거나 적용 완료까지 대기하는 정책을 확인한다. 기다림은 RTO에 포함한다.
  • 제어기 장애: 현재 writer 유지와 신규 전환 불가 상태를 구분하고 수동 승인 경로를 점검한다.
  • 논리적 데이터 훼손: 단순 failover 대신 백업·PITR로 복구할 경계를 정하고 사고 변경의 재적용을 막는다.

리허설은 장애 주입 시각, 탐지 시각, fencing 증거, 마지막 확인 커밋, 후보 적용 경계, 승격 완료, 첫 업무 성공을 기록한다. 복구 후 몇 행을 조회하는 것만으로 충분하지 않다. 실패한 요청의 중복 실행 여부와 이전 writer의 쓰기 거부도 관측해야 한다. 검증 범위를 넘는 장애는 별도 미검증 항목으로 남긴다.

설계 검토 체크리스트

9. 정리

고가용성은 복제본을 추가하는 작업이 아니라 장애 영역을 분리하고, 데이터 보존 경계를 확인하며, 쓰기 권한을 안전하게 이전하는 운영 계약이다. 빠른 승격이 안전한 승격을 의미하지 않고, 데이터 사본이 많다고 업무 복구가 자동으로 빨라지지도 않는다.

설계는 장애별 RTO/RPO와 차단 조건에서 시작하고, 검증은 실제 업무의 성공과 중복·누락 부재에서 끝나야 한다. 이후 개별 HA 구성과 failover 절차를 다룰 때도 이 기준을 유지하면 제품 기능 목록이 아니라 검증 가능한 운영 체계로 비교할 수 있다.

참고 자료