DB 개선 계획 작성
This commit is contained in:
@@ -0,0 +1,644 @@
|
||||
# Synology 읽기 복제본 구축 가이드
|
||||
|
||||
> 실시간 MariaDB Replication으로 Synology NAS를 운영 DB의 최신 사본으로 유지
|
||||
> - 작성일: 2026-09-15
|
||||
> - 대상 환경: AWS EC2 (운영 MariaDB 10.11.13) ↔ Synology NAS (MariaDB 10)
|
||||
> - 이 문서는 **계획 문서**입니다. 실제 구현은 아직 하지 않았습니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 개념: MariaDB Replication
|
||||
|
||||
### 마스터-슬레이브 구조
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ AWS EC2 (마스터) │
|
||||
│ MariaDB 10.11.13 │
|
||||
│ - 모든 쓰기 실행 │
|
||||
│ - Binlog 기록 │
|
||||
│ :3306 │
|
||||
└──────────────┬──────────────┘
|
||||
│ 바이너리 로그 복제
|
||||
│ (지속적, 초단위)
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ Synology NAS (슬레이브) │
|
||||
│ MariaDB 10 │
|
||||
│ - 로그 수신 & 적용 │
|
||||
│ - 읽기만 가능 │
|
||||
│ mariadb.jisangs.com:3306 │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
**동작 원리:**
|
||||
1. 마스터에서 모든 변경(INSERT/UPDATE/DELETE)을 **바이너리 로그**에 기록
|
||||
2. 슬레이브가 지속적으로 마스터의 로그를 읽음
|
||||
3. 슬레이브가 같은 명령을 로컬에서 재실행 (replay)
|
||||
4. 결과적으로 마스터와 슬레이브의 데이터가 항상 동일 (보통 < 1초 지연)
|
||||
|
||||
**현재 시스템과의 비교:**
|
||||
|
||||
| 항목 | 현재 (매일 덤프) | 변경 후 (실시간 복제) |
|
||||
|---|---|---|
|
||||
| 네트워크 | NAS가 마스터 SELECT | 마스터가 NAS에 쓰기 푸시 |
|
||||
| 용량 | SQL 파일 (매일 수백 MB) | 바이너리 로그 (변경분만) |
|
||||
| 복원 속도 | 수십 분 | 초 단위 |
|
||||
| 운영 DB 부하 | 매일 높음 (SELECT * 시간) | 거의 없음 |
|
||||
| 백업 용도 | 덤프 파일 자체 | 복제본 + 덤프 (필요시) |
|
||||
| 분석 쿼리 영향 | 운영 DB 느려짐 | 복제본이므로 무관 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 단계별 구현
|
||||
|
||||
### 단계 1: 운영 DB 설정 (AWS EC2)
|
||||
|
||||
#### 2-1. Binlog 활성화
|
||||
|
||||
`mariadb-dump`와 `mariadb-restore`를 쓰는 현재 시스템과 달리, 복제를 위해서는 바이너리 로그가 계속 켜져 있어야 합니다.
|
||||
|
||||
**Docker 컨테이너에서 확인:**
|
||||
```bash
|
||||
# EC2 인스턴스에서
|
||||
docker exec <container_name> mariadb -e "SHOW VARIABLES LIKE 'log_bin%';"
|
||||
# 결과 예: log_bin = ON
|
||||
```
|
||||
|
||||
**만약 OFF라면:**
|
||||
```bash
|
||||
# Docker 실행 시 또는 my.cnf에 추가
|
||||
[mysqld]
|
||||
log_bin = mysql-bin
|
||||
binlog_format = ROW
|
||||
binlog_expire_logs_days = 14 # 14일 후 자동 삭제
|
||||
server_id = 1 # 마스터는 1, 슬레이브는 2+
|
||||
```
|
||||
|
||||
**Docker 컨테이너 재시작 필요** (또는 운영 설정 파일 재로드)
|
||||
|
||||
**온라인 확인 및 임시 활성화** (재시작 없음):
|
||||
```sql
|
||||
-- 연결: mysql -h chocomae.jinaju.com -u root -p
|
||||
SET GLOBAL binlog_format = 'ROW';
|
||||
SET GLOBAL log_bin = ON;
|
||||
|
||||
-- 확인
|
||||
SHOW VARIABLES LIKE 'binlog%';
|
||||
SHOW MASTER STATUS; -- File='mysql-bin.000001', Position=XXX 나와야 함
|
||||
```
|
||||
|
||||
> **중요**: 컨테이너를 재시작하면 `SET GLOBAL`은 초기화됩니다. 영구 적용은 Docker 설정 파일에서 해야 합니다.
|
||||
|
||||
#### 2-2. 복제 계정 생성
|
||||
|
||||
Synology(슬레이브)에서 마스터의 로그를 읽기 위한 전용 계정:
|
||||
|
||||
```sql
|
||||
-- 운영 DB에서 (EC2, root 권한)
|
||||
CREATE USER 'replication'@'mariadb.jisangs.com' IDENTIFIED BY '복제_비밀번호_여기_입력';
|
||||
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replication'@'mariadb.jisangs.com';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
-- 확인
|
||||
SHOW GRANTS FOR 'replication'@'mariadb.jisangs.com';
|
||||
```
|
||||
|
||||
> **보안**: 비밀번호는 강력하게. Synology의 접속 파일(`.chocomae_replication.cnf` 같은)에 저장하되, 권한을 `600` (읽기 전용)으로 제한합니다.
|
||||
|
||||
#### 2-3. 현재 로그 위치 기록
|
||||
|
||||
초기 데이터 복사(2-5단계)를 시작하기 전에 **현재의 마스터 로그 상태**를 기록해야 합니다. 그 이후의 변경분부터 복제하므로:
|
||||
|
||||
```sql
|
||||
SHOW MASTER STATUS;
|
||||
```
|
||||
|
||||
**출력 예:**
|
||||
```
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
mysql-bin.000001 154
|
||||
```
|
||||
|
||||
이 값(`mysql-bin.000001`, `154`)을 메모해 두세요. 슬레이브 설정(2-7단계)에서 사용합니다.
|
||||
|
||||
---
|
||||
|
||||
### 단계 2: Synology 초기화
|
||||
|
||||
#### 2-4. 현재 스테이징 DB 확인
|
||||
|
||||
Synology의 MariaDB 상태 확인:
|
||||
|
||||
```bash
|
||||
# Synology SSH에서
|
||||
mariadb -u root -p -e "SELECT @@version, @@datadir;"
|
||||
```
|
||||
|
||||
현재 `mariadb.jisangs.com:3306`에 기존 `chocomae` DB가 있습니다 (스테이징/테스트용).
|
||||
|
||||
#### 2-5. 초기 데이터 복사 (Binlog 이전까지)
|
||||
|
||||
**방법 A: 현재 backup-db.sh 스크립트 활용 (추천)**
|
||||
|
||||
이미 작성된 [backup-db.sh](../db/260907-daily-db-backup/backup-db.sh)는 `mariadb-dump --single-transaction`을 사용합니다. 이것이 바로 복제용 초기 데이터 복사의 좋은 도구입니다.
|
||||
|
||||
1. 운영 DB에서 현재 상태의 덤프를 받습니다 (위에서 메모한 로그 위치 이후의 변경분만 복제되므로 OK).
|
||||
2. Synology에서 그 덤프를 복원합니다.
|
||||
|
||||
**구체적 커맨드:**
|
||||
```bash
|
||||
# Synology SSH에서
|
||||
# 1) 기존 테스트 DB를 백업 (선택, 필요하면)
|
||||
mariadb-dump -u root -p chocomae > /volume1/backup/chocomae_before_replication.sql
|
||||
|
||||
# 2) 운영 DB에서 현재 상태의 덤프를 받기 (스테이징의 backup-db.sh 스크립트 참고)
|
||||
# 또는 EC2에서 Synology로 직접 파이프
|
||||
mariadb-dump -h chocomae.jinaju.com -u backup -p \
|
||||
--single-transaction \
|
||||
--default-character-set=utf8mb4 \
|
||||
chocomae | mariadb -u root -p chocomae
|
||||
|
||||
# (또는) 파일로 저장했다면
|
||||
mariadb -u root -p chocomae < /volume1/backup/chocomae_latest.sql
|
||||
```
|
||||
|
||||
이제 Synology의 `chocomae` DB가 운영 DB와 동일한 상태입니다 (위에서 기록한 로그 위치 시점의).
|
||||
|
||||
#### 2-6. Synology MariaDB 설정
|
||||
|
||||
슬레이브를 위한 추가 설정. Synology의 MariaDB 설정 파일 (보통 `/etc/my.cnf` 또는 `/var/packages/MariaDB10/target/etc/my.cnf`):
|
||||
|
||||
```ini
|
||||
[mysqld]
|
||||
server_id = 2 # 슬레이브는 2 이상 (마스터와 다른 ID)
|
||||
skip_slave_start = OFF # 시작 시 자동으로 복제 시작 (선택)
|
||||
# 보통은 ON으로 두고 수동 START SLAVE 권장
|
||||
relay_log = mysql-relay-bin
|
||||
relay_log_index = mysql-relay-bin.index
|
||||
log_slave_updates = ON # 슬레이브도 로그 기록 (선택, 슬레이브의 슬레이브 필요시)
|
||||
read_only = ON # 슬레이브에서의 쓰기 금지 (권장)
|
||||
```
|
||||
|
||||
Synology의 MariaDB 재시작 또는 SSH에서 `SET GLOBAL`로 설정:
|
||||
```sql
|
||||
SET GLOBAL server_id = 2;
|
||||
SET GLOBAL read_only = ON; # 슬레이브를 읽기 전용으로 (권장)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 단계 3: 복제 시작 (Synology)
|
||||
|
||||
#### 2-7. CHANGE MASTER TO
|
||||
|
||||
2-3단계에서 메모한 운영 DB의 로그 위치를 사용:
|
||||
|
||||
```sql
|
||||
-- Synology의 MariaDB에서 (root 또는 관리자)
|
||||
-- 먼저 기존 복제 설정 확인
|
||||
SHOW SLAVE STATUS;
|
||||
-- 아무 것도 없으면 OK, 뭔가 있으면 아래 항목 먼저 실행:
|
||||
-- STOP SLAVE;
|
||||
-- RESET SLAVE;
|
||||
|
||||
-- 복제 설정
|
||||
CHANGE MASTER TO
|
||||
MASTER_HOST = 'chocomae.jinaju.com',
|
||||
MASTER_PORT = 3306,
|
||||
MASTER_USER = 'replication',
|
||||
MASTER_PASSWORD = '복제_비밀번호',
|
||||
MASTER_LOG_FILE = 'mysql-bin.000001', -- 2-3단계의 File 값
|
||||
MASTER_LOG_POS = 154; -- 2-3단계의 Position 값
|
||||
```
|
||||
|
||||
> **타임존 고려**: MariaDB는 일반적으로 UTC 기반이므로 `MASTER_CONNECT_RETRY` 같은 추가 설정은 대개 불필요합니다. 네트워크 재연결 시간은 기본값(60초)이 적절합니다.
|
||||
|
||||
#### 2-8. 복제 시작
|
||||
|
||||
```sql
|
||||
START SLAVE;
|
||||
|
||||
-- 몇 초 기다린 뒤 상태 확인
|
||||
SHOW SLAVE STATUS\G
|
||||
|
||||
-- 확인할 항목:
|
||||
-- Slave_IO_Running: Yes
|
||||
-- Slave_SQL_Running: Yes
|
||||
-- Seconds_Behind_Master: 0 (또는 작은 숫자)
|
||||
-- Last_Error: (비어 있음)
|
||||
```
|
||||
|
||||
**복제가 정상 동작하면:**
|
||||
- `Slave_IO_Running: Yes` — 마스터의 바이너리 로그를 계속 읽는 중
|
||||
- `Slave_SQL_Running: Yes` — 읽은 로그를 Synology에서 재실행 중
|
||||
- `Seconds_Behind_Master: 0` — 지연 없음 (또는 1~2초 이내)
|
||||
|
||||
**문제가 있으면:**
|
||||
- `Slave_IO_Running: Connecting` — 네트워크 문제. 방화벽, 호스트명, 포트 확인
|
||||
- `Slave_SQL_Running: No` — 로컬 SQL 오류. `Last_Error` 확인
|
||||
- `Last_Error`에 오류 내용: 보통 "테이블 없음", "컬럼 이름 다름" 등. [4장](#4-문제-해결)에서 다룹니다.
|
||||
|
||||
---
|
||||
|
||||
## 3. 권한 관리 및 모니터링
|
||||
|
||||
### 3-1. 사용자 계정 분리
|
||||
|
||||
**Synology에서 생성할 계정들:**
|
||||
|
||||
```sql
|
||||
-- 1) 분석용 계정 (읽기 전용)
|
||||
CREATE USER 'analytics'@'localhost' IDENTIFIED BY 'analytics_password';
|
||||
GRANT SELECT ON chocomae.* TO 'analytics'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
-- 2) 스테이징/개발용 (기존)
|
||||
-- 이미 있음: backup@... 등
|
||||
|
||||
-- 3) 모니터링용 (선택)
|
||||
CREATE USER 'monitor'@'localhost' IDENTIFIED BY 'monitor_password';
|
||||
GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'monitor'@'localhost';
|
||||
```
|
||||
|
||||
> **운영 DB (마스터)의 권한은 유지**:
|
||||
> - `backup@chocomae.jinaju.com` — 백업용 (이미 있음)
|
||||
> - `replication@mariadb.jisangs.com` — 복제용 (2-2단계에서 생성)
|
||||
|
||||
### 3-2. 모니터링 쿼리
|
||||
|
||||
**Synology SSH에서 주기적 확인:**
|
||||
|
||||
```bash
|
||||
# 매 시간 또는 매 15분마다 실행 (cron 추천)
|
||||
mariadb -u monitor -p chocomae -e "SHOW SLAVE STATUS\G" > /volume1/logs/replication.log
|
||||
|
||||
# 또는 한 줄로
|
||||
mariadb -u monitor -p -e "SHOW SLAVE STATUS\G" | grep -E 'Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master|Last_Error'
|
||||
```
|
||||
|
||||
**확인할 항목:**
|
||||
| 항목 | 정상 | 주의 | 위험 |
|
||||
|---|---|---|---|
|
||||
| `Slave_IO_Running` | Yes | Connecting | No |
|
||||
| `Slave_SQL_Running` | Yes | (거의 없음) | No |
|
||||
| `Seconds_Behind_Master` | 0~1 | 1~10 | 10+ |
|
||||
| `Last_Error` | (비어 있음) | (있음) | (있음) |
|
||||
|
||||
---
|
||||
|
||||
## 4. 기존 백업(backup-db.sh)과의 통합
|
||||
|
||||
### 4-1. 현재 백업 스크립트의 역할 변경
|
||||
|
||||
**현재 [backup-db.sh](../db/260907-daily-db-backup/backup-db.sh):**
|
||||
- 실행 위치: Synology
|
||||
- 대상: 운영 DB(`chocomae.jinaju.com`)
|
||||
- 방식: `mariadb-dump`로 전체 SQL 파일 생성
|
||||
- 보관: 28일
|
||||
|
||||
**복제 후 권장 변경:**
|
||||
|
||||
**옵션 A: 그대로 유지 (가장 안전)**
|
||||
- 기존 스크립트 유지 (매일 운영 DB에서 전체 덤프)
|
||||
- 추가로: Synology의 복제본도 매주 백업 (별도 스크립트)
|
||||
- 장점: 두 백업이 서로 다른 경로 제공
|
||||
- 단점: 운영 DB 부하 계속 (매일)
|
||||
|
||||
**옵션 B: Synology 백업 중심으로 전환 (권장)**
|
||||
- 기존 스크립트: 실행 대상을 `chocomae.jinaju.com` → `localhost`로 변경
|
||||
```bash
|
||||
DB_HOST="localhost" # Synology 로컬
|
||||
```
|
||||
- 실행 시간: 기존과 동일 (매일 새벽)
|
||||
- 장점: 운영 DB 부하 제거 (복제본에서만 덤프)
|
||||
- 단점: 복제 지연 중에 스냅샷이 약간 뒤떨어질 수 있음
|
||||
|
||||
**옵션 C: 하이브리드 (균형)**
|
||||
- 주중 (월~금): 복제본에서 백업 (스크립트 변경)
|
||||
- 주말 (토): 운영 DB에서 백업 (원본 보장)
|
||||
- 월: 복제본 검증 후 운영 DB 백업
|
||||
|
||||
### 4-2. 백업 스크립트 변경 (옵션 B 선택 시)
|
||||
|
||||
```bash
|
||||
# backup-db.sh 수정 항목
|
||||
# 라인 46: DB_HOST="chocomae.jinaju.com" → DB_HOST="localhost"
|
||||
# 라인 48: DB_PORT="3306" → DB_PORT="3306" (그대로)
|
||||
# 라인 50: DB_USER="backup" → DB_USER="root" (Synology 로컬이므로)
|
||||
# 또는 별도 계정 생성
|
||||
|
||||
# 그 외는 모두 동일
|
||||
```
|
||||
|
||||
**변경 후 테스트:**
|
||||
```bash
|
||||
# Synology에서
|
||||
/path/to/backup-db.sh
|
||||
|
||||
# 로그 확인
|
||||
tail -f /path/to/backup_dir/backup.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 장애 시나리오 및 대응
|
||||
|
||||
### 5-1. 복제 지연 (Seconds_Behind_Master > 10)
|
||||
|
||||
**원인:** 운영 DB의 쓰기 폭주, 네트워크 지연, Synology의 처리 능력 한계
|
||||
|
||||
**대응:**
|
||||
1. 운영 DB에서 슬로우 쿼리 로그 확인 (`long_query_time = 1`)
|
||||
2. Synology의 CPU/메모리 사용량 확인 (`docker stats` 또는 `top`)
|
||||
3. 복제 쿼리 재개 전까지 기다림 (보통 자동 복구)
|
||||
4. 계속되면 네트워크 대역폭 확인
|
||||
|
||||
**일시적 해결:** 아무 것도 안 하고 기다리기 (복제는 자동으로 따라잡음)
|
||||
|
||||
### 5-2. 복제 중단 (Slave_SQL_Running: No)
|
||||
|
||||
**원인:** 로컬 SQL 오류, 테이블/컬럼 불일치, 제약 조건 위반
|
||||
|
||||
**대응:**
|
||||
1. `Last_Error` 확인 (실제 오류 메시지)
|
||||
2. 오류의 SQL을 수동으로 Synology에서 실행해보기
|
||||
3. 원인 제거 (보통 운영 DB의 스키마가 바뀐 경우)
|
||||
4. `STOP SLAVE; START SLAVE;` (재시작)
|
||||
5. 계속 실패하면 [5-4](#5-4-복제-재초기화)
|
||||
|
||||
### 5-3. 연결 끊김 (Slave_IO_Running: No/Connecting)
|
||||
|
||||
**원인:** 네트워크 이슈, 방화벽, 호스트명 오류, 복제 계정 삭제
|
||||
|
||||
**대응:**
|
||||
1. Synology에서 운영 DB로 연결 테스트:
|
||||
```bash
|
||||
mariadb -h chocomae.jinaju.com -u replication -p -e "SELECT 1;"
|
||||
```
|
||||
2. 연결되면: `STOP SLAVE; START SLAVE;` (재시작)
|
||||
3. 연결 안 되면:
|
||||
- 호스트명 재확인 (`ping chocomae.jinaju.com`)
|
||||
- 방화벽 (AWS 보안 그룹) 확인
|
||||
- 복제 계정 확인 (운영 DB에서 `SELECT USER FROM mysql.user WHERE User='replication';`)
|
||||
|
||||
### 5-4. 복제 재초기화 (완전 초기화 필요한 경우)
|
||||
|
||||
복제가 완전히 깨졌거나 마스터와 슬레이브가 불일치한 경우:
|
||||
|
||||
```sql
|
||||
-- Synology에서
|
||||
STOP SLAVE;
|
||||
RESET SLAVE ALL;
|
||||
|
||||
-- 다시 초기화 (2-5단계 ~ 2-8단계 반복)
|
||||
-- 1. 운영 DB에서 덤프 받기
|
||||
-- 2. Synology에 복원
|
||||
-- 3. CHANGE MASTER TO ... START SLAVE;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 성능 영향 및 고려사항
|
||||
|
||||
### 6-1. 운영 DB (마스터) 오버헤드
|
||||
|
||||
| 요소 | 영향도 | 설명 |
|
||||
|---|---|---|
|
||||
| Binlog 기록 | ~1~2% | 모든 쓰기를 로그에 기록하는 비용 |
|
||||
| Binlog 파일 크기 | ~2GB/월 (예상) | 현재 record 저장이 월 ~17만 행 × 파일 크기 |
|
||||
| 복제 스레드 | ~1~2% | 슬레이브가 로그를 읽는 데 필요한 스레드 |
|
||||
| **총 오버헤드** | **<5%** | 거의 무시할 수 있는 수준 |
|
||||
|
||||
#### 6-1-1. 현재 시스템과의 실제 비교
|
||||
|
||||
**현재 (일일 덤프 백업):**
|
||||
```
|
||||
매일 밤 Synology에서 운영 DB로 전체 SELECT 쿼리 실행
|
||||
- 타입: 운영 DB에 대한 대량 SELECT
|
||||
- 빈도: 1회/일
|
||||
- 부하: 시간 단위로 높음 (덤프 시간 동안)
|
||||
- 영향: 이 시간에 실시간 사용자가 영향받을 수 있음
|
||||
|
||||
부하 패턴:
|
||||
▓▓▓▓▓▓▓▓▓▓ (매일 새벽, 고부하)
|
||||
▁▁▁▁▁▁▁▁▁▁ (나머지 시간, 낮음)
|
||||
```
|
||||
|
||||
**복제 후 (실시간 바이너리 로그 동기화):**
|
||||
```
|
||||
운영 DB는 변경분만 로그에 기록 (항상 실행 중)
|
||||
- 타입: 로그 기록 (매우 가볍고 배치 처리)
|
||||
- 빈도: 상시
|
||||
- 부하: 초당 6~10 건 정도 (매우 미미)
|
||||
- 영향: 무시할 수 있는 수준
|
||||
|
||||
부하 패턴:
|
||||
▁▁▁▁▁▁▁▁▁▁ (상시, 거의 무감지)
|
||||
```
|
||||
|
||||
**결과: 실제로는 부하가 감소합니다** — 매일 덤프 시 높던 SELECT 부하가 제거됩니다.
|
||||
|
||||
#### 6-1-2. 위험 시나리오 및 대응
|
||||
|
||||
**시나리오 1: 기록 저장 폭증**
|
||||
|
||||
원인: 이벤트, 버그, 또는 대량 데이터 로드
|
||||
- 현재: 평균 초당 ~6건 (월 17만 건 / 2.6M초)
|
||||
- 위험: 초당 천 건 이상 저장되는 경우
|
||||
|
||||
**대응:**
|
||||
```bash
|
||||
# Synology에서 모니터링
|
||||
mariadb -u monitor -p -e "SHOW SLAVE STATUS\G" | grep Seconds_Behind_Master
|
||||
|
||||
# 만약 Seconds_Behind_Master > 10이면:
|
||||
# - 운영 DB의 슬로우 쿼리 로그 확인
|
||||
# - Synology의 CPU/메모리 사용률 확인
|
||||
# - 보통 자동으로 따라잡음 (기다리면 OK)
|
||||
```
|
||||
|
||||
**시나리오 2: Synology 디스크 느림**
|
||||
|
||||
원인: NAS가 RAID 5/6, 다른 작업 경합
|
||||
- 현상: 복제 지연 증가 (`Seconds_Behind_Master > 30`)
|
||||
- 지속성: 자동 복구 (바이너리 로그는 계속 축적)
|
||||
|
||||
**대응:**
|
||||
```bash
|
||||
# 모니터링만 (수동 개입 필요 없음)
|
||||
# 지연은 자동으로 따라잡음
|
||||
# 필요시 Synology의 다른 작업 중단
|
||||
```
|
||||
|
||||
**시나리오 3: 네트워크 단절**
|
||||
|
||||
원인: EC2 ↔ Synology 연결 끊김
|
||||
- 현상: `Slave_IO_Running: No` 또는 `Connecting`
|
||||
- 기간: 자동 재연결 시도 (기본 60초 주기)
|
||||
|
||||
**대응:**
|
||||
```bash
|
||||
# 1. 연결 테스트
|
||||
mariadb -h chocomae.jinaju.com -u replication -p -e "SELECT 1;" 2>&1
|
||||
|
||||
# 2. 연결 불가면 확인
|
||||
ping chocomae.jinaju.com # DNS/네트워크
|
||||
aws ec2 describe-security-groups # AWS 보안 그룹 확인
|
||||
|
||||
# 3. 수동 재연결
|
||||
mariadb -u root -p -e "STOP SLAVE; START SLAVE;"
|
||||
```
|
||||
|
||||
#### 6-1-3. 권장 모니터링 절차
|
||||
|
||||
**정기 확인 (cron, 매시간):**
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Synology에서 /volume1/scripts/check_replication.sh
|
||||
|
||||
RESULT=$(mariadb -u monitor -p"비밀번호" -e "SHOW SLAVE STATUS\G" 2>/dev/null)
|
||||
|
||||
IO_RUNNING=$(echo "$RESULT" | grep "Slave_IO_Running:" | awk '{print $NF}')
|
||||
SQL_RUNNING=$(echo "$RESULT" | grep "Slave_SQL_Running:" | awk '{print $NF}')
|
||||
SECONDS_BEHIND=$(echo "$RESULT" | grep "Seconds_Behind_Master:" | awk '{print $NF}')
|
||||
LAST_ERROR=$(echo "$RESULT" | grep "Last_Error:" | awk '{print $NF}')
|
||||
|
||||
echo "[$(date)] IO=$IO_RUNNING SQL=$SQL_RUNNING Behind=${SECONDS_BEHIND}s Error=$LAST_ERROR" >> /volume1/logs/replication.log
|
||||
|
||||
# 이상 발생 시 경고 (선택)
|
||||
if [ "$IO_RUNNING" != "Yes" ] || [ "$SQL_RUNNING" != "Yes" ]; then
|
||||
echo "WARNING: Replication issue detected at $(date)" | mail -s "Synology Replication Alert" admin@example.com
|
||||
fi
|
||||
```
|
||||
|
||||
**cron 설정:**
|
||||
```bash
|
||||
# Synology SSH에서
|
||||
crontab -e
|
||||
|
||||
# 추가
|
||||
0 * * * * /volume1/scripts/check_replication.sh
|
||||
# (매 시간 0분에 실행)
|
||||
```
|
||||
|
||||
**정상 상태 (매시간 확인):**
|
||||
```
|
||||
IO=Yes SQL=Yes Behind=0s Error=None
|
||||
IO=Yes SQL=Yes Behind=1s Error=None
|
||||
```
|
||||
|
||||
**이상 상태 (조사 필요):**
|
||||
```
|
||||
IO=Connecting SQL=Yes Behind=X Error=None # 네트워크 재연결 시도 중
|
||||
IO=No SQL=No Behind=NULL Error=... # 심각한 오류, 복제 중단
|
||||
IO=Yes SQL=No Behind=X Error=... # SQL 오류, 로그 재생 실패
|
||||
```
|
||||
|
||||
### 6-2. Synology의 수신 능력
|
||||
|
||||
복제본이 지속적으로 마스터의 로그를 읽어 재실행하므로, Synology의 네트워크 대역폭과 디스크 I/O가 관련됩니다.
|
||||
|
||||
- **네트워크**: 로컬 LAN이라면 문제 없음
|
||||
- **디스크 I/O**: 복제 적용 속도에 영향. NAS의 RAID 설정에 따라 다름
|
||||
|
||||
### 6-3. 백업 용량 및 보관
|
||||
|
||||
**바이너리 로그 크기 (예상):**
|
||||
- 월 17만 개 기록 = 약 2GB/월
|
||||
- 14일 보관(`binlog_expire_logs_days = 14`) = ~1GB
|
||||
|
||||
**현재 SQL 덤프:**
|
||||
- 월 1회 ~수백 MB
|
||||
|
||||
→ **바이너리 로그가 SQL 덤프보다 훨씬 효율적**
|
||||
|
||||
---
|
||||
|
||||
## 7. 검증 및 테스트
|
||||
|
||||
### 7-1. 초기 동기화 확인
|
||||
|
||||
복제 시작 후 1시간 기다린 뒤:
|
||||
|
||||
```sql
|
||||
-- Synology에서
|
||||
SHOW SLAVE STATUS\G
|
||||
-- Seconds_Behind_Master = 0 확인
|
||||
```
|
||||
|
||||
### 7-2. 데이터 무결성 확인
|
||||
|
||||
기록 저장/삭제를 몇 번 한 뒤 양쪽 DB에서 결과 비교:
|
||||
|
||||
```sql
|
||||
-- 운영 DB
|
||||
SELECT COUNT(*) FROM best_record;
|
||||
SELECT MAX(BestRecordID) FROM best_record;
|
||||
|
||||
-- Synology (5초 뒤)
|
||||
SELECT COUNT(*) FROM best_record;
|
||||
SELECT MAX(BestRecordID) FROM best_record;
|
||||
-- 같아야 함
|
||||
```
|
||||
|
||||
### 7-3. 분석 쿼리 확인
|
||||
|
||||
Synology에서 무거운 쿼리를 한두 번 실행해보고, 운영 DB에 영향이 없는지 확인:
|
||||
|
||||
```sql
|
||||
-- Synology에서 (읽기 전용)
|
||||
SELECT MaestroID, COUNT(*) FROM best_record GROUP BY MaestroID ORDER BY COUNT(*) DESC LIMIT 10;
|
||||
|
||||
-- 동시에 운영 DB의 응답 시간 확인
|
||||
-- (필요하면 운영 DB에서 `SHOW PROCESSLIST;`)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 체크리스트
|
||||
|
||||
### 구현 전
|
||||
- [ ] 운영 DB의 Binlog 활성화 여부 확인 (`SHOW VARIABLES LIKE 'log_bin'`)
|
||||
- [ ] Docker 설정 파일 (my.cnf) 위치 파악
|
||||
- [ ] Synology SSH 접속 가능 확인
|
||||
- [ ] 현재 backup-db.sh 스크립트 백업
|
||||
- [ ] Synology의 기존 DB 상태 기록
|
||||
|
||||
### 구현 중
|
||||
- [ ] 운영 DB에서 복제 계정 생성
|
||||
- [ ] 마스터 로그 위치 기록 (SHOW MASTER STATUS)
|
||||
- [ ] Synology에 초기 데이터 복사
|
||||
- [ ] Synology MariaDB 설정 파일 수정 (server_id, read_only)
|
||||
- [ ] CHANGE MASTER TO 실행
|
||||
- [ ] START SLAVE 실행
|
||||
- [ ] SHOW SLAVE STATUS로 상태 확인
|
||||
|
||||
### 구현 후
|
||||
- [ ] 1시간 기다린 뒤 Seconds_Behind_Master = 0 확인
|
||||
- [ ] 기록 저장/삭제 후 양쪽 데이터 일치성 확인
|
||||
- [ ] 분석 쿼리를 Synology에서 실행해보기
|
||||
- [ ] backup-db.sh 스크립트 변경 (옵션 선택 시)
|
||||
- [ ] 모니터링 스크립트 (cron) 설정
|
||||
- [ ] 정기 백업 확인 (덤프가 Synology에서 정상 생성되는지)
|
||||
|
||||
---
|
||||
|
||||
## 9. 다음 단계
|
||||
|
||||
이 문서의 구현이 완료되면:
|
||||
|
||||
1. **안1~안5의 DB 성능 개선**과 **병행 가능**
|
||||
- Replication은 운영 체계 (백업·장애대비)
|
||||
- 안1~5는 쿼리 성능 개선
|
||||
- 서로 독립적 → 순서 자유
|
||||
|
||||
2. **분석·통계를 Synology에서 안전하게 수행**
|
||||
- 운영 DB 영향 0
|
||||
- 복제본에서만 덤프 (운영 DB 부하 제거)
|
||||
|
||||
3. **장애 시 빠른 복구**
|
||||
- 복제본이 항상 최신 상태 유지
|
||||
- 필요 시 슬레이브를 마스터로 昇格 (선택사항)
|
||||
|
||||
Reference in New Issue
Block a user