---
title: "Aurora storage architecture 개요: 공유 분산 스토리지와 redo 중심 복제"
description: "Aurora MySQL의 공유 분산 스토리지, redo 기반 쓰기 경로, 스토리지 quorum과 reader 지연을 구분하고 장애 대응과 관측 기준을 정리한다."
tags: [ MySQL, Aurora, 아키텍처, 복제, 고가용성 ]
image: "mysql-report-bg.png"
published: "2026-11-08"
updated: "2026-11-08"
author: "MySQL 기술 노트"
source_url: ""
---

Aurora MySQL을 이해할 때 가장 먼저 바꿔야 하는 관점은 “MySQL 서버마다 전체 데이터 파일이 있고 binlog로 서로 복사한다”는 모델이다. 같은 리전의 한 Aurora DB 클러스터에서는 writer와 reader가 하나의 논리적인 클러스터 볼륨을 사용한다. 데이터의 내구성을 담당하는 분산 스토리지와 SQL을 실행하는 DB 인스턴스가 분리되어 있다.

그러나 공유 스토리지라고 해서 모든 reader가 같은 순간에 같은 결과를 반환하는 것은 아니다. 스토리지에 변경이 내구적으로 기록되는 시점, reader가 변경을 읽을 준비를 마치는 시점, 애플리케이션 트랜잭션이 그 변경을 볼 수 있는 시점은 서로 다르다. 이 구분을 놓치면 쓰기 성공을 읽기 일관성으로 오해하거나 reader 증설을 데이터 사본 증설로 잘못 계산하게 된다.

이 글은 일반적인 단일 리전 Aurora MySQL DB 클러스터를 대상으로 한다. Global Database의 리전 간 복제, 외부 MySQL과의 binlog 복제, 별도 샤딩 제품은 같은 구조로 취급하지 않는다. 구조 설명은 AWS 공개 문서에 근거하며, 뒤의 SQL은 폐기용 Community MySQL에서 실행한 관측 예제와 가정 계산이다. 실제 Aurora 스토리지 장애나 failover를 실험한 결과는 아니다.

## 1. 계산 계층과 저장 계층을 나누어 보기

### 1.1 DB 인스턴스가 담당하는 일

Writer는 연결과 세션을 관리하고, SQL을 해석하고 최적화하며, 트랜잭션·잠금·MVCC 처리를 수행한다. Reader도 독립적인 계산 자원으로 SELECT를 실행한다. 인스턴스마다 CPU, 메모리, 버퍼 캐시와 연결 상태가 있으므로 같은 클러스터 볼륨을 사용해도 쿼리 지연이나 캐시 적중률은 다를 수 있다.

데이터 페이지가 메모리에 있다고 해서 메모리만으로 영속성이 보장되는 것은 아니다. 반대로 데이터가 스토리지에 존재한다고 해서 새 reader의 메모리 캐시가 이미 준비되어 있다는 뜻도 아니다. 인스턴스 교체 직후에는 영속 데이터의 존재와 별개로 캐시 준비, 연결 재수립, 실행 계획과 작업 부하의 영향을 살펴야 한다.

### 1.2 클러스터 볼륨이 담당하는 일

클러스터 볼륨은 여러 스토리지 노드에 분산된 데이터를 하나의 논리 볼륨으로 노출한다. AWS 문서는 데이터를 리전 내 세 가용 영역에 걸쳐 복제하고, 해당 볼륨에 연결된 여섯 스토리지 노드로 쓰기를 전달하는 구조를 설명한다. 내부적으로는 볼륨을 여러 보호 단위로 나누어 관리한다. “클러스터 전체가 고정된 여섯 디스크로만 구성된다”는 의미가 아니다.

이 스토리지 복제 수는 DB 인스턴스 수와 독립적이다. Reader가 없는 클러스터도 스토리지 계층의 다중 사본 보호를 사용한다. Reader를 추가하는 목적은 읽기 처리 용량과 승격 가능한 계산 자원을 확보하는 것이지, 데이터의 내구성 사본을 하나씩 늘리는 것이 아니다.

정렬과 일부 임시 작업 등에는 인스턴스 로컬 저장 공간도 사용된다. 따라서 공유 볼륨의 여유 공간만 보고 모든 디스크 관련 장애를 배제할 수 없다. 영속 볼륨, 로컬 임시 공간, 메모리 부족을 분리해서 진단해야 한다.

```mermaid
flowchart TB
    A[애플리케이션 쓰기] --> W[Writer: SQL·트랜잭션·버퍼 캐시]
    B[애플리케이션 읽기] --> R[Reader: 별도 SQL 실행·버퍼 캐시]
    W -->|redo 중심 로그 전달| S[공유 분산 클러스터 볼륨]
    W -.->|비동기 변경 전달·상태 동기화| R
    R -->|필요한 페이지 읽기| S
    S --- Z1[가용 영역 A의 스토리지 사본]
    S --- Z2[가용 영역 B의 스토리지 사본]
    S --- Z3[가용 영역 C의 스토리지 사본]
```

그림의 점선은 reader의 변경 가시성이 writer의 커밋과 완전히 같은 시점이 아님을 나타낸다. 구현 내부의 모든 메시지나 복구 단계를 표현한 프로토콜 명세는 아니다.

## 2. redo 중심 쓰기 경로가 바꾸는 것

### 2.1 Community InnoDB와의 출발점 비교

일반적인 InnoDB에서는 변경한 페이지를 버퍼 풀에 유지하고 redo를 기록하며, dirty page를 나중에 데이터 파일에 반영한다. 장애 복구는 데이터 파일과 로그의 관계를 이용한다. Binlog는 서버 계층에서 복제와 시점 복구 등에 쓰이는 별도 로그이며, InnoDB redo와 같은 것이 아니다.

Aurora는 이 중 저장 계층의 역할을 다시 나눈다. 계산 노드가 모든 변경 페이지의 사본을 여러 DB 서버에 보내는 대신, redo 중심의 로그 레코드를 분산 스토리지에 전달한다. 스토리지 노드는 로그를 내구적으로 저장하고, 필요한 페이지 상태를 구성하며, 사본 간 복구를 처리한다. 이것이 AWS가 설명하는 스토리지 계층으로의 작업 이동이다.

이 구조를 “Aurora에는 페이지가 없다”거나 “redo만 무한히 쌓는다”고 해석하면 안 된다. 쿼리는 여전히 페이지와 인덱스를 읽고, 계산 계층은 메모리에 페이지를 캐시하며, 저장 계층은 읽기에 필요한 데이터 상태를 제공한다. 달라진 것은 로그 전송·페이지 구성·복구의 책임 분배다.

### 2.2 쓰기 성공까지의 경계

공개된 스토리지 설계를 기준으로 쓰기 경로는 다음과 같이 이해할 수 있다.

1. Writer가 SQL을 실행하고 트랜잭션 변경에 필요한 로그를 만든다.
2. 로그를 관련 스토리지 사본들에 병렬로 전달한다.
3. 스토리지 노드는 로그를 내구적으로 기록한 뒤 응답한다.
4. 필요한 쓰기 quorum을 확보하고 트랜잭션 커밋 조건을 충족하면 클라이언트에 성공을 알린다.
5. 스토리지의 페이지 구성과 사본 보완 등 후속 작업은 별도의 경로로 진행될 수 있다.

AWS의 스토리지 엔진 설명은 여섯 사본 중 네 사본의 응답을 쓰기 성공 기준으로 제시한다. 모든 사본의 후속 작업이 끝날 때까지 기다리는 모델과는 다르다. 다만 이 숫자만으로 SQL 응답 시간을 계산할 수는 없다. 로그 생성량, 네트워크, group commit, 잠금 대기, CPU와 클라이언트 왕복 시간이 함께 작용한다.

또한 이 설명은 SQL 하나마다 네 번의 과금 I/O가 발생한다는 뜻이 아니다. 트랜잭션, 로그 레코드, 저장 계층 I/O, 과금 집계는 서로 다른 단위다. Reader 수나 여섯 사본이라는 숫자를 SQL 실행 횟수에 곱해 비용을 계산하지 않는다.

### 2.3 redo와 binlog를 분리해야 하는 이유

같은 클러스터의 Aurora Replica는 일반적인 외부 MySQL replica처럼 독립된 전체 데이터 파일에 binlog 이벤트를 SQL 또는 row 변경으로 재실행하여 사본을 만드는 구조가 아니다. 공유 볼륨과 Aurora 고유의 복제 경로를 사용한다.

반면 외부 MySQL로 복제하거나 CDC 도구를 연결할 때는 binlog 설정·보존·소비 지연이 별도의 운영 항목이 된다. Binlog를 켰다고 내부 스토리지 사본이 늘어나지 않으며, 껐다고 공유 볼륨의 보호가 사라지는 것도 아니다. Aurora Global Database 역시 리전 간 별도 클러스터의 복제이므로 같은 리전의 공유 볼륨과 구분해야 한다.

## 3. quorum: 쓰기 가용성과 데이터 내구성은 다른 질문이다

### 3.1 여섯 사본 중 네 응답의 의미

쓰기 quorum이 네 사본이라면, 단순한 고정 구성 모델에서는 응답 가능한 사본이 네 개일 때까지 기준을 충족한다. 세 개만 응답하면 그 기준을 충족하지 못한다. 여기에서 곧바로 “세 사본이 안 보이면 데이터가 유실되었다”고 결론 내릴 수는 없다. 쓰기를 계속 받아들일 수 있는지와 이미 커밋한 데이터를 복구할 수 있는지는 별개다.

AWS 설계 설명에는 복구 시 세 사본을 같은 LSN까지 맞추어 읽기 quorum을 확보하는 과정도 나온다. 이것을 “일반 SELECT는 항상 스토리지 세 곳에 요청한다”는 의미로 확대하면 안 된다. 정상 읽기는 캐시나 필요한 LSN을 충족하는 스토리지 노드에서 제공될 수 있으며, 장애 복구의 quorum 확인과 일반 페이지 읽기는 같은 경로가 아니다.

### 3.2 가정 모델을 SQL로 계산하기

다음은 실시간 Aurora 상태 조회가 아니라, 여섯 사본과 쓰기 기준 네 개를 입력한 설명용 계산이다. `unavailable_copies`는 단지 응답 불가로 가정한 사본 수다. 실제 시스템의 자동 복구, 사본별 로그 진행 상태, 네트워크 분할, 가용 영역 배치를 모델링하지 않는다.

```sql
WITH scenarios AS (
    SELECT 0 AS unavailable_copies
    UNION ALL SELECT 1
    UNION ALL SELECT 2
    UNION ALL SELECT 3
)
SELECT unavailable_copies,
       6 - unavailable_copies AS responding_copies,
       4 AS required_write_acks,
       CASE WHEN 6 - unavailable_copies >= 4
            THEN 'threshold_met'
            ELSE 'threshold_not_met'
       END AS assumed_write_gate
FROM scenarios
ORDER BY unavailable_copies;
```

실행 결과(MySQL 8.0.x):

```text
mysql> WITH scenarios AS (
    ->     SELECT 0 AS unavailable_copies
    ->     UNION ALL SELECT 1
    ->     UNION ALL SELECT 2
    ->     UNION ALL SELECT 3
    -> )
    -> SELECT unavailable_copies,
    ->        6 - unavailable_copies AS responding_copies,
    ->        4 AS required_write_acks,
    ->        CASE WHEN 6 - unavailable_copies >= 4
    ->             THEN 'threshold_met'
    ->             ELSE 'threshold_not_met'
    ->        END AS assumed_write_gate
    -> FROM scenarios
    -> ORDER BY unavailable_copies;

+--------------------+-------------------+---------------------+--------------------+
| unavailable_copies | responding_copies | required_write_acks | assumed_write_gate |
+--------------------+-------------------+---------------------+--------------------+
|                  0 |                 6 |                   4 | threshold_met      |
|                  1 |                 5 |                   4 | threshold_met      |
|                  2 |                 4 |                   4 | threshold_met      |
|                  3 |                 3 |                   4 | threshold_not_met  |
+--------------------+-------------------+---------------------+--------------------+
4 rows in set (0.00 sec)
```

기준 통과는 실제 쓰기 승인이나 SLA 판정이 아니다. 예를 들어 “두 사본이 응답하지 않는다”는 관측만으로 남은 사본들이 모두 필요한 로그를 보유하고 정상 응답할 것이라고 보장할 수 없다. 이 SQL의 목적은 가용성 기준과 데이터 손실 판단을 분리하는 데 있다.

운영자는 스토리지 내부 멤버를 직접 강제로 재구성하는 방식으로 대응하지 않는다. AWS 이벤트와 서비스 상태를 확인하고, DB 인스턴스 장애인지 저장 계층 문제인지 구별한 뒤, 애플리케이션 쓰기 차단·재시도·업무 복구 정책을 적용해야 한다.

## 4. 공유 스토리지인데 왜 reader 지연이 생기는가

Reader는 별도의 실행 주체다. Writer에서 커밋된 변경을 reader가 자신의 캐시와 실행 상태에 반영하고 새로운 읽기에 제공하기까지 지연이 생길 수 있다. AWS 문서는 Aurora Replica가 비동기 복제를 사용하며, 변경량이 많으면 지연이 증가할 수 있다고 설명한다. 저장 계층의 내구성 확보와 reader의 변경 가시성을 같은 완료 조건으로 묶지 않는 것이 중요하다.

여기에 트랜잭션 스냅샷 문제가 추가된다. Reader가 최신 변경을 반영했더라도, 이미 열린 일관 읽기의 Read View는 과거 상태를 계속 볼 수 있다. 따라서 쓰기 후 읽기에서 오래된 결과가 보이면 최소한 다음 경계를 나누어야 한다.

- **접속 대상:** 요청이 writer로 갔는가, 어느 reader로 갔는가.
- **reader 진행 상태:** 그 인스턴스가 해당 변경을 읽을 수 있는 상태인가.
- **트랜잭션 수명:** 새 읽기인가, 이전에 만든 Read View를 재사용하는 읽기인가.
- **응용 계층:** 연결 풀, 재시도, 결과 캐시가 이전 상태를 돌려주는가.

엄격한 쓰기 후 읽기가 필요한 작업은 writer에서 적절한 새 읽기를 수행하는 등 명시적인 일관성 정책을 세운다. Reader endpoint의 존재만으로 일관성이 보장되지는 않는다. Write forwarding 관련 일관성 설정도 해당 기능의 활성화 조건과 지원 버전을 확인한 뒤 사용해야 한다.

## 5. 무엇을 관측하고 무엇을 추론하지 말아야 하는가

### 5.1 계산 계층의 SQL 관측

다음 SQL은 서버 식별 정보, 로그 관련 설정과 버퍼 풀 누적 카운터를 확인한다. 공개 결과는 Community MySQL 테스트 인스턴스에서 얻은 값이다. Aurora 내부 스토리지 quorum이나 사본 건강 상태를 조회하는 SQL이 아니며, Aurora에서는 지원 변수와 의미를 해당 엔진 버전의 문서로 다시 확인해야 한다.

```sql
SELECT VERSION() AS mysql_version,
       @@version_comment AS distribution;

SELECT @@global.log_bin AS binary_logging_enabled,
       @@global.innodb_flush_log_at_trx_commit AS flush_policy;

SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM performance_schema.global_status
WHERE VARIABLE_NAME IN (
    'Innodb_buffer_pool_read_requests',
    'Innodb_buffer_pool_reads'
)
ORDER BY VARIABLE_NAME;
```

실행 결과(MySQL 8.0.x):

```text
mysql> SELECT VERSION() AS mysql_version,
    ->        @@version_comment AS distribution;

+---------------+------------------------------+
| mysql_version | distribution                 |
+---------------+------------------------------+
| 8.0.46        | MySQL Community Server - GPL |
+---------------+------------------------------+
1 row in set (0.00 sec)

mysql> SELECT @@global.log_bin AS binary_logging_enabled,
    ->        @@global.innodb_flush_log_at_trx_commit AS flush_policy;

+------------------------+--------------+
| binary_logging_enabled | flush_policy |
+------------------------+--------------+
|                      0 |            1 |
+------------------------+--------------+
1 row in set (0.00 sec)

mysql> SELECT VARIABLE_NAME, VARIABLE_VALUE
    -> FROM performance_schema.global_status
    -> WHERE VARIABLE_NAME IN (
    ->     'Innodb_buffer_pool_read_requests',
    ->     'Innodb_buffer_pool_reads'
    -> )
    -> ORDER BY VARIABLE_NAME;

+----------------------------------+----------------+
| VARIABLE_NAME                    | VARIABLE_VALUE |
+----------------------------------+----------------+
| Innodb_buffer_pool_read_requests | 15375          |
| Innodb_buffer_pool_reads         | 1021           |
+----------------------------------+----------------+
2 rows in set (0.01 sec)
```

두 버퍼 풀 카운터는 한 시점의 누적값이다. 같은 인스턴스에서 일정 간격으로 수집한 증가량을 비교해야 그 구간의 읽기 특성을 해석할 수 있다. 재시작이나 카운터 초기화를 먼저 확인하고, 요청 증가량이 없는 구간에는 비율 계산을 보류한다. 특히 `Innodb_buffer_pool_reads`를 Aurora의 청구 읽기 I/O와 일대일로 대응시키지 않는다.

이 예제의 `log_bin` 값은 테스트 인스턴스의 실행 설정일 뿐이다. Aurora의 binlog 사용 여부는 외부 복제·CDC 요구에 따라 별도로 확인한다. `innodb_flush_log_at_trx_commit` 역시 Community InnoDB의 로컬 파일 쓰기 해석을 Aurora 분산 저장 계층에 그대로 대입하는 근거로 사용하지 않는다.

### 5.2 Aurora에서 함께 볼 지표

- **`CommitLatency`:** 엔진과 저장 계층이 커밋 작업을 완료하는 평균 소요 시간이며 단위는 밀리초다. 전체 SQL 응답 시간이나 애플리케이션의 꼬리 지연을 대신하지 않는다. 커밋 처리량, CPU, 대기 유형과 함께 본다.
- **`AuroraReplicaLag`:** 같은 리전의 writer 변경이 replica로 전달되는 지연을 관측한다. 단위는 밀리초다. 이 글의 범위 밖인 Global Database 보조 클러스터에서는 지표의 기준점이 다르므로 리전 간 지연과 혼동하지 않는다.
- **`VolumeReadIOPs`, `VolumeWriteIOPs`:** 클러스터 볼륨 수준으로 집계되며 AWS 문서의 단위는 5분당 횟수다. 이름의 IOPs만 보고 초당 값으로 읽지 않는다. 초당 평균으로 환산하려면 해당 집계 구간의 길이를 반영해야 한다.
- **`BufferCacheHitRatio`:** 캐시에서 충족되는 요청의 비율이다. Reader별 차이와 캐시 준비 상태를 보되, 높은 비율만으로 모든 읽기가 빠르다고 결론 내리지 않는다.
- **`VolumeBytesUsed`, `FreeLocalStorage`:** 공유 볼륨 사용량과 인스턴스의 로컬 공간 상태를 구분하는 관측점이다. 지원 인스턴스·엔진과 지표 정의를 확인하여 사용한다.

볼륨 I/O 지표를 인스턴스별로 중복 합산하거나 스토리지 사본 수만큼 다시 곱하지 않는다. 실제 I/O 요금은 Aurora Standard와 Aurora I/O-Optimized 같은 저장 구성에 따라 다르므로, 지표 증가를 곧바로 같은 금액의 비용 증가로 치환해서도 안 된다.

## 6. 구조에서 도출되는 장애 대응 원칙

### 6.1 Writer 장애와 스토리지 장애를 구분한다

Writer가 멈췄다고 클러스터 볼륨 전체가 사라지는 것은 아니다. 적절한 reader를 승격하면 이미 존재하는 공유 영속 데이터에 접근할 수 있다. 다만 장애 감지, 승격, endpoint 변경, DNS와 연결 풀의 회복은 별도 과정이다. “데이터를 처음부터 복사하지 않는다”는 설명을 무중단 또는 트랜잭션 자동 복구 보장으로 바꾸면 안 된다.

스토리지 사본이 여러 가용 영역에 있어도 writer와 모든 reader를 한 가용 영역에 몰아 두면 계산 계층의 장애 대응 선택지가 줄어든다. 저장 계층의 가용 영역 분산과 DB 인스턴스의 배치는 각각 검토한다.

### 6.2 성공 응답을 못 받았다고 미커밋으로 단정하지 않는다

연결이 끊긴 순간, 서버는 커밋했지만 클라이언트가 성공 응답을 받지 못했을 수 있다. 이는 분산 스토리지가 제거해 주는 문제가 아니다. 업무 요청 식별자, 고유 제약, 처리 결과 조회를 이용해 재시도의 중복 적용을 막는다. 단순히 같은 INSERT를 반복하거나 “통신 오류면 모두 재실행”하는 정책은 별도로 검증해야 한다.

### 6.3 사본 수는 백업을 대신하지 않는다

정상 권한으로 실행된 잘못된 DELETE나 UPDATE도 정상 변경으로 저장되고 reader에 보인다. 여섯 사본은 여섯 개의 독립적인 과거 복구 지점이 아니다. 자동 백업 보존, 시점 복구, 스냅샷, 실제 복원 검증은 여전히 필요하다.

또한 단일 리전 내 세 가용 영역의 보호는 리전 간 재해복구 계획과 다르다. 리전 장애를 다루려면 별도 리전의 복구 자산과 전환 절차, 데이터 손실 허용 범위를 설계해야 한다.

## 7. 운영 점검표

- [ ] 같은 리전 Aurora Replica, 외부 binlog replica, Global Database를 구성도에서 구분했다.
- [ ] Reader 수와 스토리지 내구성 사본 수를 독립적인 항목으로 다룬다.
- [ ] Writer·reader의 가용 영역 배치와 승격 가능한 계산 용량을 확인했다.
- [ ] 스토리지 쓰기 완료, reader 반영, 트랜잭션 Read View를 별도 시점으로 이해한다.
- [ ] 쓰기 후 읽기 요구가 있는 API의 접속 대상과 새 트랜잭션 경계를 명시했다.
- [ ] 커밋 지연, replica 지연, 버퍼 캐시, 볼륨 I/O를 올바른 단위와 차원으로 수집한다.
- [ ] 공유 볼륨과 로컬 임시 공간의 사용량 경보를 분리했다.
- [ ] 연결 단절 시 커밋 결과가 불명확한 요청에 대해 멱등성과 결과 확인 경로를 준비했다.
- [ ] 스토리지 사본의 장애 보호와 논리 오류의 백업·PITR 복구를 구분했다.
- [ ] 로컬 MySQL 검증 결과를 Aurora 장애 주입이나 서비스 가용성 보장으로 해석하지 않는다.

## 8. 정리

Aurora storage architecture의 핵심은 계산과 저장의 분리, 공유 분산 클러스터 볼륨, redo 중심의 쓰기 전달이다. 이 설계는 DB 인스턴스마다 전체 데이터 사본을 재구축하는 방식과 다른 복제·복구 경로를 제공한다. 그러나 reader의 변경 가시성, 캐시 상태, 트랜잭션 수명, 클라이언트 재연결까지 하나의 원자적인 완료 단계로 묶어 주지는 않는다.

후속 주제에서는 이 구조를 바탕으로 Aurora의 로그 처리, I/O 비용, 캐시와 reader 지연을 각각 살펴볼 수 있다. 출발점은 동일하다. 어떤 계층이 데이터를 보존하고, 어떤 계층이 요청을 실행하며, 지금 보고 있는 지표가 어느 완료 시점을 나타내는지부터 구분한다.

## 참고 자료와 검증 범위

- [AWS: Aurora storage and reliability](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.Overview.StorageReliability.html)
- [AWS: High availability for Amazon Aurora](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Concepts.AuroraHighAvailability.html)
- [AWS: Replication with Amazon Aurora](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.Replication.html)
- [AWS: Introducing the Aurora Storage Engine](https://aws.amazon.com/blogs/database/introducing-the-aurora-storage-engine/)
- [AWS: Amazon CloudWatch metrics for Amazon Aurora](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraMonitoring.Metrics.html)

스토리지 엔진 소개 글은 quorum과 로그 전달 구조의 설계 근거로 사용했다. 과거 소개 글에 적힌 저장 용량 상한이나 성능 배수를 현재 모든 버전의 제한·성능으로 인용하지 않았다. 공개 실행 결과의 검증 범위는 Community MySQL의 진단 SQL 실행과 가정 quorum 계산이다. 실제 Aurora 인스턴스, 사본 장애, 네트워크 분할, reader 지연 및 과금은 이 글에서 실측하지 않았다.
