🔥 파라미터 그룹과 옵션 그룹: DB 설정의 추상

1772자
21분

처음 RDS 인스턴스 하나에서 max_connections를 손보려 했을 때 콘솔에서 한참을 헤맸다. Configuration 탭에서 max_connections 값이 보이긴 했지만 그 화면에서 직접 고치는 입력 칸이 없었다. 어디선가 본 안내를 따라 Parameter groups 메뉴로 들어가자 default-mysql-8-0이라는 그룹 한 개가 있었는데, 들어가서 값을 고치려고 하니 입력 칸이 회색으로 잠겨 있었다. 다시 인스턴스 화면으로 돌아와 Modify를 눌러 보니 Parameter group을 골라 바꾸는 드롭다운이 있었다. 그제야 인스턴스가 한 그룹을 직접 갖는 게 아니라 그룹을 가리키고 있고, default 그룹은 잠겨 있어 새 그룹을 만들어 갈아 끼워야 한다는 점을 또렷이 알았다.

백업과 PITR: 시점 복구의 범위에서 PITR이 default parameter group과 default option group을 받아 복원한다는 사실을 짚었다. 그 default가 정확히 무엇이고, custom은 어떻게 만들고, 한 번 바꾼 값이 언제 살아나는지를 모르면 복구한 인스턴스에 application이 못 붙는 사고가 난다. 두 그룹은 RDS의 자동이 끝나는 지점에서 사용자가 인스턴스의 동작을 직접 조정하는 통로다.

cover — parameter group과 option group이 인스턴스 한 대 위에 두 단으로 붙는 추상

Parameter Group이란: 엔진 설정의 외부화

Parameter group은 DB 엔진의 동작을 결정하는 설정값들의 묶음이다. MySQL의 max_connections·innodb_buffer_pool_size·slow_query_log, PostgreSQL의 shared_buffers·work_mem·log_min_duration_statement 같은 값들이 모두 이 그룹 안에 들어간다. 인스턴스 자체가 이 값을 갖는 게 아니라, 인스턴스가 한 parameter group을 가리키는 구조다. 같은 그룹을 여러 인스턴스가 동시에 가리킬 수 있고, 그룹 한 곳을 고치면 그곳을 가리키는 모든 인스턴스에 RDS가 변경을 그대로 반영한다.

이 외부화가 만들어 내는 운영적인 효과가 두 가지다. 하나는 같은 환경(dev/staging/prod)의 인스턴스 여러 대에 동일한 튜닝을 한 번에 적용할 수 있다는 것이다. dev에서 검증한 max_connections = 500을 production 인스턴스 다섯 대에 따로따로 콘솔로 클릭하지 않고, 같은 그룹을 가리키게 하면 한 곳을 고치는 순간 다섯 대가 따라온다. 다른 하나는 인스턴스를 새로 만들 때 이미 검증된 그룹을 골라 시작할 수 있다는 것이다. PITR로 복원한 인스턴스에 default parameter group이 회귀해서 application이 멈춘 사고가 일어나는 까닭은, 운영 중에 쓰던 custom 그룹의 존재가 잊혀 있었거나 복원 명령에 그 그룹이 명시되지 않았기 때문이다.

엔진과 major version마다 별도의 그룹이 존재한다. MySQL 8.0용 그룹은 PostgreSQL 16용 인스턴스에 붙지 않는다. MySQL 5.7용 그룹과 MySQL 8.0용 그룹도 호환되지 않는다. 이 묶음 단위가 곧 DB parameter group family라는 이름으로 불리고, 그룹 생성 시 family를 선택해 시작한다.

Parameter group의 적용 범위 — 한 그룹을 여러 인스턴스가 가리키고, 그룹 한 곳의 변경이 인스턴스 전체에 반영된다

동적과 정적: 같은 그룹 안의 두 갈래

Parameter group 안의 모든 파라미터는 두 갈래로 나뉜다. 동적(dynamic) 파라미터는 그룹 값이 바뀌는 순간 RDS가 인스턴스에 즉시 반영한다. 정적(static) 파라미터는 인스턴스를 재부팅해야 새 값이 살아난다. AWS 공식 문서가 그렇게 명시한다.

Changes to dynamic parameters are applied to the DB instance immediately without a reboot. Changes to static parameters are applied only after the DB instance is rebooted.

이 갈림이 운영적으로 직접적인 결과를 만든다. MySQL의 slow_query_log는 동적 파라미터라서 production 운영 중에 켜고 끄는 게 가능하다. 같은 MySQL의 innodb_buffer_pool_size는 정적 파라미터라서 그룹 값을 바꿔도 인스턴스가 재부팅되기 전까지는 옛 값으로 동작한다. Single-AZ 인스턴스의 reboot 소요 시간은 엔진·진행 중인 트랜잭션·crash recovery 상태에 따라 달라져 정해진 한 숫자가 없고, Multi-AZ 인스턴스의 failover는 AWS 공식 문서 기준 보통 60~120초 안에 standby로 넘어간다.

ApplyMethod라는 인자가 이 두 갈래 위에 더 얹는다. 그룹 값을 고치는 modify-db-parameter-group 호출에는 두 가지 ApplyMethod가 있다. immediate는 변경을 즉시 적용하고, pending-reboot는 다음 재부팅 시점까지 보류한다. 조합 규칙은 단순하지만 한 번씩 사용자가 발을 헛디딘다.

  • 동적 + immediate → 즉시 적용, 재부팅 없음
  • 동적 + pending-reboot → 변경 보류, 다음 재부팅에 적용
  • 정적 + immediate → API가 거부함(정적은 immediate를 못 받음)
  • 정적 + pending-reboot → 변경 보류, 다음 재부팅에 적용

콘솔은 동적 파라미터에 자동으로 immediate를 잡고, 정적 파라미터에 자동으로 pending-reboot를 잡는다. CLI나 API에서는 ApplyMethod를 직접 명시할 수 있고, 그래서 동적 파라미터에도 pending-reboot를 골라 다음 정기 재부팅까지 변경을 보류하는 운영이 가능하다. 한 가지 예외가 SQL Server다. 같은 문서가 짧게 적는다.

Using pending-reboot with dynamic parameters in the AWS CLI or RDS API on RDS for SQL Server DB instances generates an error.

SQL Server 인스턴스에서는 동적 파라미터에 pending-reboot를 시도하면 API가 에러를 돌려준다. apply-immediately만 받는다.

운영 절차서를 만들 때 두 가지를 함께 적어 두면 사고가 줄어든다. 첫째, 파라미터별로 동적·정적이 어느 쪽인지를 표로 묶어 두는 것. 둘째, 정적 파라미터를 바꾸는 작업은 무조건 변경 윈도(maintenance window)와 묶어 두는 것. 정적 파라미터 변경과 재부팅 사이에 시간차가 있으면 두 사건의 인과가 한눈에 보이지 않아, 한참 뒤 다른 이유로 인스턴스를 재부팅했더니 의도치 않은 값이 함께 살아나는 사고가 난다.

동적과 정적 파라미터의 apply 시점 — 동적은 즉시 또는 다음 재부팅, 정적은 무조건 다음 재부팅

Default와 Custom: 잠긴 기본형과 떠 와야 할 사본

엔진 family를 만들면 AWS가 자동으로 default.mysql8.0 같은 default parameter group을 한 개 부여한다. 이 default 그룹은 immutable이다. 그 안의 어떤 값도 사용자가 직접 수정할 수 없다. 콘솔에서 들어가 보면 입력 칸 자체가 잠겨 있다. AWS가 default를 잠그는 이유는 단순하다. 같은 family를 쓰는 신규 인스턴스의 baseline이 사용자 손에 의해 의도치 않게 바뀌는 사고를 막기 위함이다.

운영 중에 어떤 파라미터든 한 줄을 고치고 싶다면 절차가 정해져 있다. default를 사본으로 떠서 custom 그룹을 새로 만들고, 그 사본을 인스턴스에 붙인 뒤, 사본 안에서 값을 고친다. 명령 한 줄로 표현하면 다음과 같다.

bash
aws rds copy-db-parameter-group \
    --source-db-parameter-group-identifier default.mysql8.0 \
    --target-db-parameter-group-identifier my-mysql8-tuned \
    --target-db-parameter-group-description "production tuning"
 
aws rds modify-db-instance \
    --db-instance-identifier mydb-prod \
    --db-parameter-group-name my-mysql8-tuned \
    --apply-immediately
bash
aws rds copy-db-parameter-group \
    --source-db-parameter-group-identifier default.mysql8.0 \
    --target-db-parameter-group-identifier my-mysql8-tuned \
    --target-db-parameter-group-description "production tuning"
 
aws rds modify-db-instance \
    --db-instance-identifier mydb-prod \
    --db-parameter-group-name my-mysql8-tuned \
    --apply-immediately

이 두 명령 사이에 한 가지 다른 부분이 있다. modify-db-instance로 그룹을 갈아 끼우는 행위 자체는 즉시 인스턴스에 연결되지만, 새 그룹 안에 설정된 값이 인스턴스 동작에 반영되려면 한 번의 재부팅이 필요하다. 그룹 안의 값을 따로 수정하는 호출(modify-db-parameter-group)과 인스턴스가 가리키는 그룹을 바꾸는 호출(modify-db-instance)이 서로 다른 동작이라는 점을 구분해야 한다. 전자는 동적·정적 규칙을 따라 즉시 또는 재부팅 후에 RDS가 값을 적용하고, 후자는 연결 자체는 즉시지만 새 그룹 값의 활성화를 위해 재부팅이 한 번 더 필요하다.

기본 quota도 운영적으로 짚어 두면 좋다. 한 region·한 계정당 사용자가 만들 수 있는 custom DB parameter group의 기본 한도는 region에 따라 다르다. AWS 공식 quota 문서 기준 ap-south-1은 20개에서 시작하고 그 외 다수 region은 50개에서 시작한다(서울 region 기준 단가는 quota 문서에서 그때그때 확인). default 그룹은 이 카운트에 포함되지 않는다. 한도를 넘어가는 환경(여러 product의 prod/staging/dev 인스턴스를 한 계정 안에서 운영하는 큰 조직)은 Service Quotas 콘솔에서 증액 신청을 통해 한도를 키운다.

Default와 Custom — default는 잠긴 baseline, custom은 default를 사본으로 떠서 수정 가능한 사본

Aurora의 두 단: Cluster Parameter Group과 DB Parameter Group

엔진 선택: MySQL·PostgreSQL·Aurora에서 Aurora는 storage가 cluster 단위로 공유되는 독자적인 아키텍처라는 사실을 짚었다. 그 구조 때문에 Aurora는 parameter group을 두 단으로 나눈다. 클러스터 전체에 적용되는 DB Cluster Parameter Group과 인스턴스 한 대에 적용되는 DB Parameter Group이다.

Cluster parameter group은 cluster 안의 모든 writer·reader 인스턴스가 공유해야 하는 값을 담는다. 대표적인 예가 innodb_file_per_table 같은 storage 레이아웃에 영향을 주는 파라미터다. cluster의 storage가 6 segment로 분산되는 모델 때문에, 한 인스턴스만 다른 storage layout을 쓸 수 없다. AWS 공식 문서가 짧게 명시한다.

The Aurora shared storage model requires that every DB instance in an Aurora cluster use the same setting for parameters such as innodb_file_per_table.

DB parameter group은 인스턴스마다 다르게 줄 수 있는 값을 담는다. 인스턴스의 메모리 크기에 비례하는 max_connections 같은 값이 여기에 든다. r6g.large reader와 r6g.4xlarge writer가 같은 cluster 안에 함께 있을 때, 두 인스턴스에 같은 max_connections 값을 강제하면 작은 reader가 자기 메모리에 안 맞는 connection 수를 받아 OOM 직전까지 간다.

두 그룹의 우선순위는 정해져 있다. 같은 파라미터가 양쪽에 모두 정의돼 있다면 인스턴스 단의 DB parameter group이 cluster parameter group을 덮어쓴다. 한 인스턴스의 max_connections를 손봐 두면 그 값은 cluster parameter group의 max_connections보다 우선한다. 그러다 인스턴스 단 설정을 지우고 cluster 단으로 돌아가고 싶다면 reset-db-parameter-group을 호출해 인스턴스 단 그룹을 reset해야 한다. 그냥 cluster 그룹의 값을 다시 바꾸는 것으로는 인스턴스 단 override가 사라지지 않는다.

Aurora의 2-tier parameter group — cluster 그룹의 storage·복제 파라미터, instance 그룹의 메모리 파라미터, instance가 cluster를 override하는 우선순위

Option Group: 엔진별 추가 기능의 묶음

Parameter group이 엔진에 이미 있는 설정값을 조정하는 통로라면, option group은 엔진에 없는 기능을 추가로 켜는 통로다. AWS RDS 문서는 option을 다음과 같이 설명한다. 기본 데이터베이스 설치에는 포함되지 않은 엔진별 plugin이나 추가 기능이라는 의미다. 대표적인 예가 다음 셋이다.

  • SQLSERVER_BACKUP_RESTORE: .bak 파일로 SQL Server native backup을 S3에 떠 넣고 그곳에서 다시 복원하는 기능. RDS의 자동 백업과 별개로 운영 가능하다.
  • Oracle TDE: Transparent Data Encryption. 디스크 단의 암호화를 엔진 자체로 켜는 기능. AWS 공식 분류 기준 permanent and persistent 옵션이라 한 번 켜면 그 옵션이 포함된 option group을 후속 snapshot·복원·DR 환경 모두에서 함께 유지해야 한다.
  • Oracle OEM: Oracle Enterprise Manager Database Control. RAM을 약 300 MB 점유한다. db.t3.micro 같은 작은 인스턴스에서 이 옵션을 켜면 다른 워커 메모리가 모자라 OOM 또는 swap 상황으로 들어선다.

Option group도 parameter group과 마찬가지로 default가 한 개 부여되고, 그 안에 사용자 옵션을 추가하려면 custom group을 새로 만들어 인스턴스에 붙여야 한다. 한 가지 추가 제약이 있다. AWS는 option group을 engine + major version 단위로 관리한다. SQL Server 2019용 option group은 SQL Server 2022 인스턴스에 붙지 않고, 엔진 메이저 버전 업그레이드 시 인스턴스에는 target 메이저 버전과 호환되는 option group을 명시해 두어야 한다(이미 호환되는 사본이 있다면 재사용도 가능).

persistent 옵션과 permanent 옵션이라는 두 가지 추가 카테고리도 운영에 영향을 준다. Oracle TDE는 두 분류를 모두 받는 옵션의 대표적인 예로, 한 번 켠 인스턴스의 snapshot에서 다른 VPC로 복원할 때도 같은 옵션이 포함된 option group을 새로 만들어 함께 명시해야 한다. 더 강한 제약은 permanent 옵션이 만든다. 한 번 option group에 추가된 permanent 옵션은 그 group에서 제거되지 않고, 그 group을 가리키는 인스턴스 역시 그 옵션이 포함된 group으로만 갈아탈 수 있다. 새로 켜기 전에 시뮬레이션 환경에서 한 번 검증하는 게 운영적인 안전선이다.

Option group의 엔진별 지원 — SQL Server·Oracle·MySQL·MariaDB·Db2는 option group, Aurora MySQL/PostgreSQL은 cluster parameter group으로 동등 기능

Option Group이 답이 아닌 경우

운영 환경을 골라 본 다음 option group이 답인지 아닌지부터 확인해 두면 시간을 아낀다. 답이 아닌 경우가 명확하다.

Aurora MySQL과 Aurora PostgreSQL은 option group을 받지 않는다. AWS 공식 문서가 그렇게 명시한다. Aurora의 추가 기능은 두 갈래로 나뉜다. PostgreSQL의 aws_s3 같은 외부 통합 extension은 데이터베이스 안에서 CREATE EXTENSION aws_s3 한 줄로 깔리고, 인스턴스 메모리·로깅 같은 엔진 동작 파라미터는 cluster parameter group이나 인스턴스 단의 DB parameter group에서 조정한다. Aurora 환경에서 option group을 만들려고 시도하면 콘솔이 엔진 선택 단계에서 Aurora variant를 보여 주지 않는다. 이 사실을 모르고 SQL Server 운영 절차서를 그대로 Aurora MySQL에 적용하려다 막히는 게 흔한 시작 사고다.

Aurora가 아닌 엔진이라도 사용자가 켜려는 기능을 parameter 한 줄로 충분히 적을 수 있다면 option group을 만들 필요는 없다. MySQL의 general_log나 PostgreSQL의 log_statement는 parameter group의 한 줄로 활성화한다. option group은 plugin·외부 통합·라이선스 단의 기능이 필요할 때만 의미가 있다.

작은 인스턴스에서 무거운 옵션을 켜는 경우도 답이 아니다. db.t3.micro에서 OEM을 켜는 시도, db.t3.small에서 SQL Server SSRS 옵션을 켜는 시도는 인스턴스의 메모리가 옵션의 baseline에 못 미쳐 운영 단계에서 사고가 난다. 옵션을 켜기 전에 그 옵션의 RAM 요구치를 인스턴스 클래스의 메모리와 비교해 두는 한 단의 점검이 필요하다.

다음으로

Parameter group과 option group이라는 두 추상은 인스턴스의 동작을 운영자가 조정하는 통로다. 두 그룹의 default·custom·dynamic·static·persistent 갈래를 따라가 보면, RDS의 자동 7갈래 중 configuration management만 운영자에게 남아 있다는 점이 또렷하다. 다음으로는 RDS의 청구가 어떻게 만들어지는지(instance hour·storage·IOPS·backup·DTO의 다섯 갈래가 한 달 청구서에 어떤 비율로 나타나는지)를 짚는다. 여기서 짚었던 parameter group을 안 만지면 default가 워크로드와 안 맞는 채로 운영되는 숨은 비용과, RDS 청구의 다섯 갈래가 만나는 지점이 다음 단계의 출발점이다.

YouTube 영상

채널 보기
스칼라 곱셈과 내적의 기하학적 의미 | 선형대수학
AI 추천 시스템의 원리, 벡터 사이의 각도와 코사인 유사도 | 선형대수학
트라이(Trie)를 이용한 자동 완성 알고리즘 | Trie 자료구조 이야기
트라이(Trie)에서 단어를 삭제하는 방법 | Trie 자료구조 이야기
인공지능은 세상을 어떻게 숫자로 읽는가? - 이미지, 소리 그리고 텍스트가 행렬이 되는 원리 | 선형대수학
직교성과 벡터 투영 | 선형대수학
AI는 데이터를 어떻게 분류할까? 벡터의 거리와 KNN 알고리즘 | 선형대수학
AI는 왜 수백 차원의 벡터를 사용할까? 고차원 공간과 행렬 | 선형대수학