Last Updated on 8월 23, 2022 by Jade(정현호)
안녕하세요.
이번 포스팅은 AWS Aurora MySQL 에서 제공하는 fault injection queries(오류 삽입 쿼리)를 이용한 Aurora DB의 장애 시뮬레이션 테스트 관련 된 내용을 간단하게 확인 해보려고 합니다.
시뮬레이션 지원 종류
오류 삽입 쿼리를 사용하여 Amazon Aurora DB 클러스터의 내결함성을 테스트할 수 있습니다. 오류 삽입 쿼리는 Amazon Aurora 인스턴스에 SQL 명령으로 실행 되며 오류 삽입 쿼리를 통해 다음 이벤트 중 하나의 발생에 대한 시뮬레이션을 예약하는 데 사용됩니다.
-
라이터 또는 리더 DB 인스턴스의 충돌
-
Aurora 복제본의 실패
-
디스크 실패
-
디스크 정체
오류 삽입 쿼리가 실행이 되면 Aurora DB 인스턴스가 실제로 강제로 crash 되게 됩니다.
오류 삽입 쿼리를 제출할 때 실패 이벤트 시뮬레이션이 발생하는 시간 길이를 지정할 수도 있으며 Aurora의 클러스터 엔드포인트 중에서 Write 나 Reader 또는 인스턴스 별로 직접 접속하여 쿼리를 수행할 수 있습니다.
[주의] 문서나 포스팅 내용에서는 시뮬레이션이라는 표현에 의해서 실제로 되지는 않는 것으로 생각할 수도 있지만 아래의 명령어 수행시 실제로 instance crash 또는 I/O Failure 를 야기 하기 때문에 실제로 장애나 I/O 에서 문제가 일어난다 는 점을 알아두셔야 합니다.
• 포스팅에서 사용한 Aurora 버전: 8.0.mysql_aurora.3.02.0
Testing an instance crash
ALTER SYSTEM CRASH 명령어를 통해서 Aurora 인스터스를 장애(crash, 충돌) 를 강제로 일으킬수 있습니다.
구문
ALTER SYSTEM CRASH [ INSTANCE | DISPATCHER | NODE ];
이 오류 삽입 쿼리에는 다음 장애 유형 중 하나를 사용할 수 있습니다.
INSTANCE - Amazon Aurora인스턴스용 MySQL 호환 데이터베이스의 충돌이 시뮬레이션됩니다.
DISPATCHER - Aurora DB 클러스터용 라이터 인스턴스에서 디스패처 충돌이 시뮬레이션됩니다. 디스패처가 Amazon Aurora DB 클러스터용 클러스터 볼륨에 업데이트 쓰기 작업을 합니다.
NODE - MySQL 호환 데이터베이스 및 Amazon Aurora 인스턴스용 디스패처의 충돌이 모두 시뮬레이션됩니다. 이 오류 삽입 시뮬레이션의 경우 캐시도 삭제됩니다.
기본 충돌 유형은 INSTANCE 입니다.
각 옵션 마다 Aurora 내부적으로 발생되는 에러 유형은 조금은 다를 것이지만, 사용하는 측면에서 장애 결과는 동일 하게 각 인스턴스별로 모두 재시작이 발생되게 됩니다.
Writer 인스턴스에서 장애가 발생되면 Writer 인스턴스가 재시작 되며, Reader에서 실행하면 접속한 Reader 인스턴스가 재시작 되게 됩니다.
Aurora 버전에 따라서 Writer 인스턴스가 재시작 되면 Reader 도 재시작 될 수 있습니다.
Aurora PostgreSQL 및 버전 2.10 이전 Aurora MySQL
- Aurora PostgreSQL 호환 버전 과 Aurora MySQL 호환 버전 버전 1 및 버전 2.10 이전 버전의 경우 클러스터의 라이터 DB 인스턴스를 재부팅 하여 전체 Aurora DB 클러스터를 재부팅 합니다.
관련된 내용은 아래 포스팅을 추가로 참고하시면 됩니다.
데이터베이스의 사용 패턴이나 변경량 이나 환경에 따라서 다를 수 있겠으나 ALTER SYSTEM CRASH INSTANCE 실행시 가장 빠르게 인스턴스가 재시작 되었으며, DISPATCHER 나 NODE 이 INSTANCE 옵션에 비해 상대적으로 재시작에서 시간이 더 소요되는 것을 체감 하였습니다.
Testing an Aurora replica failure
ALTER SYSTEM SIMULATE READ REPLICA FAILURE 오류 삽입 쿼리를 사용하여 Aurora 복제본의 실패를 시뮬레이션할 수 있습니다.
Aurora 복제본 실패가 발생하면 지정된 시간 간격 동안 DB 클러스터의 특정 Aurora 복제본 또는 모든 Aurora 복제본에 대한 요청이 모두 차단됩니다. 시간 간격이 경과되면 해당 Aurora 복제본이 마스터 인스턴스와 자동으로 동기화됩니다.
구문
ALTER SYSTEM SIMULATE percentage_of_failure PERCENT READ REPLICA FAILURE [ TO ALL | TO "replica name" ] FOR INTERVAL quantity { YEAR | QUARTER | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND };
SQL 구문은 위와 같으며 사용 되는 파라미터는 아래와 같습니다.
percentage_of_failure - 실패 이벤트 도중 차단되는 요청 비율(%). 이 값은 0 ~ 100의 실수(Double)입니다. 0을 지정하면 요청이 차단되지 않습니다. 100을 지정하면 모든 요청이 차단됩니다.
결함 유형 - 시뮬레이션할 결함의 유형입니다. DB 클러스터의 모든 Aurora 복제본에 대한 실패를 시뮬레이션하려면 TO ALL 을 지정하면되며 단일 Aurora 복제본의 실패를 시뮬레이션하려면 TO 와 Aurora 복제본의 이름을 지정하면 됩니다.
기본 실패 유형은 TO ALL 입니다.
quantity - Aurora 복제본 결함 시뮬레이션 시간 길이를 의미 합니다. 이 간격 값 뒤에 시간 단위를 지정해야 하며 지정된 단위의 시간 동안 시뮬레이션이 발생합니다. 예를 들어 20 MINUTE 를 지정하면 20분 동안 시뮬레이션이 실행 됩니다.
명령어 사용 예시)
ALTER SYSTEM SIMULATE 100 PERCENT READ REPLICA FAILURE TO ALL FOR INTERVAL 5 MINUTE;
명령어를 수행하면 리더 인스턴스에서는 변경된 데이터가 반영이 되지 않게 됩니다.
(sysbench 로 데이터를 넣고 있는 과정에서 확인한 내용)
mysql> select count(*) from sbtest1; +----------+ | count(*) | +----------+ | 420289 | +----------+ mysql> select count(*) from sbtest1; +----------+ | count(*) | +----------+ | 471152 | <-- 데이터 변경이 반영이 안되고 있음 +----------+ mysql> select count(*) from sbtest1; +----------+ | count(*) | +----------+ | 471152 | <-- 데이터 변경이 반영이 안되고 있음 +----------+ mysql> select count(*) from sbtest1; +----------+ | count(*) | +----------+ | 471152 | <-- 데이터 변경이 반영이 안되고 있음 +----------+
데이터 변경 상황과 복제 중지 INTERVAL 시간에 따라서 리더 인스턴스는 재시작 될 수도 있습니다.
Writer 인스턴스와 Reader 인스턴스간의 Aurora Replica Gap 이 2분정도 지연이 된다면 Reader 가 재시작 될수 있습니다.
그래서 리더 인스턴스의 재 시작시 대부분 아래와 같이 이벤트가 기록이 되게 됩니다.
Read replica has fallen behind the master too much. Restarting Mysql.
* 테스트시 간혹 RDS의 Recent Event 에 남지 않을 경우도 있었음
REPLICA 복제 지연을 하게 되면 아래와 같이 Aurora Replica Lag 수치가 Spike 되는 것을 확인 할 수 있습니다.
해당 시뮬레이션의 경우 애플리케이션에서 DML 은 Writer 로 수행하고, SELECT 는 Reader 에서 수행하도록 사용하는 경우에서 복제 지연시 다시 Writer 인스턴스에서 읽을 수 있는지 등을 테스트 등을 해볼 수 있을 것도 같습니다.
Aurora MySQL 은 보통의 경우 설치형 MySQL 에 비해 Replica Lag 이 발생될 경우는 적으나, 상황에 따라서 수초~10초 사이의 Lag이 발생된 주변 케이스를 본적도 있습니다. 그렇기 때문에 이런 경우에 대비해서 조회처리에 대한 시뮬레이션을 해볼수도 있을것 같습니다.
Testing Disk
디스크 또는 스토리지 관련된 장애 시뮬레이션은 2가지가 있습니다.
• disk failure
• disk congestion
2가지의 의미나 내부적으로 발생되는 내역은 다르지만 사용자 측면에서 발생되는 에러 결과는 동일(유사) 하기에 같이 설명 드리도록 하겠습니다.
DISK FAILURE 구문
ALTER SYSTEM SIMULATE percentage_of_failure PERCENT DISK FAILURE [ IN DISK index | NODE index ] FOR INTERVAL quantity { YEAR | QUARTER | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND };
디스크 실패 시뮬레이션 중에는 Aurora DB 클러스터에서 임의로 디스크 세그먼트를 오류 상태로 표시하며, 시뮬레이션 기간 동안 이러한 세그먼트에 대한 요청이 차단됩니다.
이 쿼리에는 다음 파라미터가 사용 할 수 있습니다.
percentage_of_failure - 실패 이벤트 중에 오류 상태로 표시할 디스크의 비율(%). 이 값은 0 ~ 100의 실수(Double)입니다. 0을 지정하면 디스크의 어떤 부분도 오류 상태로 표시되지 않습니다. 100을 지정하면 전체 디스크가 오류 상태로 표시됩니다.
DISK index - 실패 이벤트를 시뮬레이션할 특정 논리 데이터 블록. 가용 논리 데이터 블록의 범위를 초과하는 경우, 지정할 수 있는 최대 인덱스 값을 알려주는 오류가 발생합니다.
NODE index - 실패 이벤트를 시뮬레이션할 특정 스토리지 노드. 가용 스토리지 노드의 범위를 초과하는 경우, 지정할 수 있는 최대 인덱스 값을 알려주는 오류가 발생합니다.
위의 DISK index 와 NODE index 에 대한 정보는 Aurora MySQL DB 클러스터를 위한 볼륨 상태 표시 섹션 에서 정보를 확인 할 수 있습니다.
mysql> SHOW VOLUME STATUS; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Disks | 96 | | Nodes | 74 | +---------------+-------+
테스트시 특정 인덱스값을 지정하였을 경우 장애가 유발이 안되는 경우가 있어서 DISK/NDOE 파라미터는 사용하지는 않았습니다.
quantity - 디스크 실패를 시뮬레이션하는 시간 길이이며, 이 간격 값 뒤에 시간 단위를 지정해야 합니다. 지정된 단위의 시간 동안 시뮬레이션이 발생합니다. 예를 들어 20 MINUTE를 지정하면 20분 동안 시뮬레이션이 실행됩니다.
구문 사용 예시)
ALTER SYSTEM SIMULATE 100 PERCENT DISK FAILURE FOR INTERVAL 5 MINUTE;
Disk Congestion 구문
ALTER SYSTEM SIMULATE percentage_of_failure PERCENT DISK CONGESTION BETWEEN minimum AND maximum MILLISECONDS [ IN DISK index | NODE index ] FOR INTERVAL quantity { YEAR | QUARTER | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND };
디스크 정체 시뮬레이션 중에는 Aurora DB 클러스터에서 임의로 디스크 세그먼트를 정체 상태로 표시하며, 시뮬레이션 기간 동안 지정된 최소 지연 시간과 최대 지연 시간 사이에서 이러한 세그먼트에 대한 요청이 지연됩니다.
쿼리에는 다음 파라미터를 사용할 수 있습니다.
percentage_of_failure - 실패 이벤트 중에 정체 상태로 표시할 디스크의 비율(%). 이 값은 0 ~ 100의 실수(Double)입니다. 0을 지정하면 디스크의 어떤 부분도 정체 상태로 표시되지 않습니다. 100을 지정하면 전체 디스크가 정체 상태로 표시됩니다.
DISK index 또는 NODE index - 실패 이벤트를 시뮬레이션할 특정 디스크 또는 노드. 디스크 또는 노드의 인덱스 범위를 초과할 경우 지정할 수 있는 최대 인덱스 값을 알려주는 오류가 발생합니다.
minimum 및 maximum - 최대 및 최소 정체 지연 시간(밀리초). 정체 상태로 표시된 디스크 세그먼트가 시뮬레이션 기간 중에 최소 밀리초 시간부터 최대 밀리초 시간까지의 시간 범위 내에서 임의 시간 동안 지연됩니다.
quantity - 디스크 정체를 시뮬레이션하는 시간 길이입니다. 이 간격 값 뒤에 시간 단위를 지정 하며, 지정된 단위의 시간 동안 시뮬레이션이 발생합니다. 예를 들어 20 MINUTE를 지정하면 20분 동안 시뮬레이션이 실행됩니다.
구문 사용 예시)
ALTER SYSTEM SIMULATE 100 PERCENT DISK CONGESTION BETWEEN 10000 AND 500000 MILLISECONDS FOR INTERVAL 5 MINUTE;
2개의 구문 모두 유사하게 에러를 받게 되며 장애 쿼리를 실행하는 인스턴스에 따라서 아래와 같이 동작 합니다.
(사용하는 버전이나 환경에 따라서 결과는 다를 수도 있습니다)
라이터 인스턴스 : 환경에 따라서 특정 분까지는 문제가 없음, 하지만 일정시간 이상으로 장애가 발생되면 Writer 와 Reader 모두 재시작이 되었음
리더 인스터스 : 리더에서는 쿼리 실행시 Pending 또는 Hang 현상이 되며, 장애 쿼리에서 설정한 시간이 길지 않다면 시간이 지나고 쿼리가 다시 수행 되며, 지정된 시간이 길어서 Replication 에 문제가 있다고 판단되면 리더 인스턴스가 재시작 되게 됩니다.
- Recent Event 내역
May 30, 2022, 10:51:10 PM UTC Read replica has fallen behind the master too much. Restarting Mysql. May 30, 2022, 10:51:17 PM UTC DB instance restarted
여기까지 해서 Aurora MySQL 에서 제공하는 장애 발생 쿼리 기능에 대해서 확인 해보았습니다.
서비스 오픈전이나 Aurora 사용에 관한 애플리케이션과의 구성시에 상황에 따라서 위와 같이 임의의 장애 상황을 유발하여 테스트 등을 진행해 보면 좋을 것도 같습니다.
Reference
Reference URL
• amazon.com/Managing.FaultInjectionQueries
관련된 다른 글
Principal DBA(MySQL, AWS Aurora, Oracle)
핀테크 서비스인 핀다에서 데이터베이스를 운영하고 있어요(at finda.co.kr)
Previous - 당근마켓, 위메프, Oracle Korea ACS / Fedora Kor UserGroup 운영중
Database 외에도 NoSQL , Linux , Python, Cloud, Http/PHP CGI 등에도 관심이 있습니다
purityboy83@gmail.com / admin@hoing.io