들어가며
MariaDB는 오픈 소스 관계형 데이터베이스 관리 시스템(RDBMS)이다. 세상에서 가장 인기 있는 오픈 소스 데이터베이스인 MySQL를 포크 하여 2009년도(2009. 10. 29)에 출시되었다. 라이선스는 GPL v2(GNU General Public License version 2)를 따른다. 2010년 이후 MariaDB의 인기는 MySQL과의 호환성, 커뮤니티 중심 개발, 향상된 기능, 오픈 소스 원칙 및 활동적인 커뮤니티에 의한 활기찬 생태계 등 다양한 원인이 있을 수 있다. DB-ENGINES 사이트의 Ranking 정보에 따르면 23년도 6월 기준, 전체 420 데이터베이스 시스템 중 13위로 지속적인 인기를 유지하고 있으며, 엔터프라이즈 데이터베이스 시장에서 새로운 경쟁자로 자리매김하고 있다.
이런 MariaDB의 인기와는 다르게 상대적으로 상용 데이터베이스에 비해 모니터링 및 성능 최적화에 대한 관심도가 낮아 미연에 예방할 수 있는 시스템 장애를 놓치는 경우가 많다. 본 리포트에서는 MariaDB의 중요 스토리지 엔진(storage engine)(1)의 InnoDB Redo Log에 대해 모니터링 및 성능 최적화 방법에 대해 다뤄 보도록 하겠다.
(1) 데이터베이스 엔진(database engine)이라고도 얘기하며, DBMS의 데이터베이스에 대해 데이터를 삽입, 추출, 업데이트 및 삭제(CRUD 참조)하는 데 사용하는 기본 소프트웨어 컴포넌트이다.
InnoDB Redo Log 역할은?
InnoDB 스토리지 엔진에서 InnoDB 리두 로그의 역할은 MariaDB 서버가 Crash로 인해 실제 디스크 데이터 파일에 데이터 변경 사항이 제대로 반영하지 못 한 경우, MariaDB Crash 시점의 트랜잭션 상태(Commit 또는 Rollback) 기준으로 Crash Recovery(충돌 복구)를 위해 사용되며, 데이터베이스 트랜잭션 속성 ACID(Atomicity, Consistency, Isolation, Durability) 중에서 내구성(“D”)를 보장한다.
InnoDB Redo Log의 무엇을 알아야 할까?
1. InnoDB Redo Log Capacity
MariaDB 서버 10.4 버전까지는 리두 로그 용량은 N 개의 리두 로그 파일의 결합 크기였다. MariaDB 서버 10.5부터는 1개의 리두 로그 파일만 갖기 때문에 리두 로그 파일 크기가 리두 로그 전체 용량과 동일하다. 이는 MariaDB 서버 10.5부터는 Redo Log 크기를 나눠서 관리해야 되는 대부분의 문제가 개선되었기 때문이다. MariaDB 서버 버전 10.9부터는 리두 로그 파일 크기를 온라인 상태에서 동적으로 변경 가능하도록 변경되어 이전 버전보다 더 유연하게 관리할 수 있게 되었다.
2. Checkpoint
InnoDB 체크포인트는 MariaDB 서버 메모리 영역인 InnoDB 버퍼 풀에 수정된 데이터(더티 페이지(2))를 디스크의 데이터 파일과 동기화하여 데이터 일관성(Consistency)과 내구성(Durability)을 보장하는 메커니즘이다. 이 때, WAL(Write-Ahead Logging) 메커니즘을 사용하는 InnoDB 스토리지 엔진은 더티 페이지를 InnoDB 리두 로그 파일에 먼저 기록하고, 해당 데이터(데이터 파일)가 변경되기 전에 MariaDB 서버 Crash나 시스템 장애가 발생한 경우 데이터를 안정적으로 복구할 수 있는 가능성을 보장한다.
InnoDB에서 체크포인트 작업은 InnoDB 마스터 백그라운드 스레드가 담당한다.
체크포인트 트리거 시점은 InnoDB 관련 시스템 변수, InnoDB 매트릭스 및 MariaDB 버전에 따라 차이가 있을 수 있다.
InnoDB에서 체크포인트가 트리거 되면 InnoDB 마스터 백그라운드 스레드는 InnoDB 버퍼 풀에서 LSN(3) (Log Sequence Number)이 가장 오래된(숫자가 가장 작은) 더티 페이지를 찾아 LSN 정보를 InnoDB 리두 로그에 기록한다. 이때, InnoDB 버퍼 풀에서 가장 오래된 더티 페이지보다 낮은 LSN의 페이지는 모두 데이터(데이터 파일)로 Flush 되었음을 의미하며, 이 LSN은 체크포인트 작업이 완료된 후 레퍼런스 포인트로 사용된다. 또한 Crash Recovery 작업에서 데이터를 복구할 때 중요한 기준점 역할을 한다. 이후 InnoDB 마스터 백그라운드 스레드는 더티 페이지를 디스크로 Flush 하는 작업을 수행한다. 이 작업은 비동기적(asynchronous)으로 상당한 오버헤드가 발생하거나 MariaDB 데이터베이스 성능에 영향을 줄 수 있는 과도한 I/O 지연이 발생하지 않도록 한다.
(2) InnoDB Buffer Pool(메모리)에 수정된 데이터가 있는 페이지로서 디스크(데이터 파일)에 아직 기록되지 않은 상태를 말한다.
(3) LSN(Log Sequence Number)는 InnoDB Redo Log 내의 Record에 할당된 고유 식별자이다. MariaDB에서는 트랜잭션 구분, WAL(Write Ahead Logging) 메커니즘, Crash Recovery 및 Replication 등의 용도로 사용된다.
3. Checkpoint Age
체크포인트 Age는 현재 LSN(SHOW ENGINE INNODB STATUS의 LOG 세션의 “Log sequence number”)과 InnoDB 스토리지 엔진에서 마지막으로 완료된 체크포인트의 LSN(SHOW ENGINE INNODB STATUS의 LOG 세션의 “Last checkpoint at”) 사이의 InnoDB 리두 로그에 기록된 데이터(Record)의 크기이다. 체크포인트 Age는 InnoDB 리두 로그를 모니터링하고 최적화에 필요한 매우 중요한 지표 중 하나이다. 현재 체크포인트 Age의 크기를 확인하는 방법은 다음과 같다.
MariaDB 서버 10.5부터는 체크포인트 Age 크기를 확인하기 위해 관련 InnoDB Status 변수 “Innodb_checkpoint_age”가 다시 도입되었다.
4. InnoDB Redo Log Occupancy
InnoDB 리두 로그 점유율은 InnoDB 리두 로그에서 디스크 데이터 파일로 아직 Flush 되지 않은 더티 페이지가 차지하는 InnoDB 리두 로그 용량(체크포인트 Age)의 백분율이다.
InnoDB Redo Log Occupancy (%) = Checkpoint Age / InnoDB Redo Log Size * 100
5. InnoDB Redo log 관련 주요 변수
InnoDB System/Status 변수 관련 더 자세한 설명은 MariaDB Knowledge Base(https://mariadb.com/kb/en/) 사이트 정보를 참조하기 바란다.
InnoDB Redo Log 성능 최적화는 어떻게 해야 할까?
InnoDB 리두 로그 성능 최적화는 어디서부터 접근해야 될지 막막할 수 있다. 단순한 조정 작업을 통해 최적화된 성능을 낼 수 있는 것이 아니라, 복잡하고 다각적으로 검토하고 조정 작업을 통해서 최적의 성능을 낼 수 있다.
동일 조건의 테스트 환경에서 InnoDB 리두 로그 관련 InnoDB 시스템 변수 설정 값을 변경하면서, 트랜잭션 처리 시간이 어떻게 변화되는지 확인해 보겠다.
테스트 환경
- OS : CentOS 7.9
- CPU : 8 core / 16 processor
- Memory : 32 GB
- MariaDB Version : 10.6.14 Community Version
동일 테스트 조건
- 50만 rows 테이블 32개 동시 생성 수행
- InnoDB 버퍼 풀 크기 : 2048 MB
- 테스트 관련 InnoDB 시스템 변수 설정 외 모든 변수 설정은 동일함.
1. InnoDB 리두 로그 크기 조정 – innodb_log_file_size
InnoDB 리두 로그 크기는 최대 InnoDB 버퍼 풀 크기를 초과하지 않는 선에서 테스트 수행한다. MariaDB 10.6에서는 InnoDB 리두 로그 파일 개수는 하나이다.
테스트 결과 InnoDB 버퍼 풀과 동일한 경우(테스트1) 트랜잭션 처리 시간이 빨랐다. InnoDB 버퍼 풀 크기만큼 InnoDB 리두 로그 크기를 설정한 경우, Crash Recovery 수행 시간이 오래 걸릴 수 있다. 극단적인 경우, 사용을 고려해 볼 수 있다. 반대로 InnoDB 리두 로그 크기가 너무 작은 경우(테스트2) Crash Recovery 수행에 필요한 InnoDB 리두 로그 자체가 깨질 수 있다. InnoDB 리두 로그가 깨지면, MariaDB 서버 에러 로그 파일에 “[ERROR] InnoDB: Crash recovery is broken due to insufficient innodb_log_file_size; last checkpoint LSN=15578801970, current LSN=15608999132. Shutdown is in progress.” 라는 메시지가 출력된다. 6번의 테스트 수행 결과 중 필자는 “테스트2”의 리두 로그 크기를 적절한 설정 값으로 판단하고 이어서 테스트를 진행해 보겠다.
2. InnoDB I/O 용량 조정 – innodb_io_capacity, innodb_io_capacity_max
기존 설정
- innodb_io_capacity : 1,000
- innodb_io_capacity_max : 2,000
- innodb_flush_sync : ON
InnoDB I/O 용량은 페이지(16KB) 단위를 사용한다. 테스트2에서는 InnoDB I/O 용량이 1,000이고 최대 용량이 2,000이다. I/O 용량을 최대 용량을 배로 늘리며 테스트를 진행하였을 때, 테스트 결과 InnoDB I/O 용량을 4,000으로 하고 최대 용량을 8,000으로 한 경우(테스트8) 가장 트랜잭션 처리 시간이 빨랐다. InnoDB I/O 용량을 8,000으로 설정한 경우(테스트9)는 체크포인트에서 발생하는 I/O 버스트에 대해 Innodb_flush_sync 시스템 변수가 ON(기본값)인 경우에는 Innodb_io_capacity 설정이 무시되고, Innodb_io _max_capacity 설정값(16,000) 만큼을 디스크 데이터 파일로 Flush 하게 된다. 과부하 I/O로 인해 트랜잭션 처리 시간이 더 소요된 것이다. InnoDB I/O 용량이 클수록 데이터가 버퍼에서 너무 빨리 제거되어 캐싱의 효율성이 떨어지기 때문에 이 부분 또한 고려되어야 한다.
이런 부분까지 고려되었을 때, 트랜잭션 처리 성능은 향상되고, InnoDB 버퍼 풀의 캐싱 효율성이 적정하다고 판단되는 “테스트7”의 I/O Capacity 설정 값을 선택한다.
3. InnoDB 버퍼 풀 더티 페이지 비율 조정 – InnoDB_max_dirty_pages_pct, InnoDB_max_dirty_pages_pct_lwm
InnoDB 버퍼 풀에서 체크포인트 트리거가 발생하는 조건은 다양하다. InnoDB 매트릭스 정보를 가지고 있는 information_schema.innodb_metrics 테이블에는 체크포인트 Age에 따른 비동기/동기(MariaDB 10.5이하 버전만 해당) Flush 시작 시점에 대해 값을 제공한다. 비동기식 Flush 시작 점은 InnoDB 리두 로그 크기 기준 대략 70%이다. MariaDB 10.5 이하 버전에는 동기식 Flush 시작 점도 가지고 있는데, InnoDB 리두 로그 크기 기준 대략 75%이다. MariaDB 10.5 이상에서는 최대 체크포인트 Age 크기를 상태 변수 “Innodb_checkpoint_max_age” 값으로 확인할 수 있다. 최대 체크포인트 Age 크기는 InnoDB 리두 로그 크기 기준 대략 80% 정도이다. 이러한 값들은 체크포인트 Age 크기를 관리하기 위한 체크포인트 트리거 조건으로 사용되며, 더 격렬한 체크포인트가 수행될 수 있도록 하여, 체크포인트 Age를 감소시키는 역할을 한다.
설정된 값들은 InnoDB 리두 로그 크기에 의해 자동으로 설정된다. MariaDB 서버 10.9 이상에서는 InnoDB 리두 로그 크기를 운영 중에 동적으로 변경이 가능하지만, 그 이하 버전에서는 그 크기를 조정하기 위해서는 MariaDB 서버 중단 후 수행해야만 한다. 이런 불편함을 해소하기 위해 MariaDB 서버는 운영 중 체크포인트 트리거 지점을 조정할 수 있는 동적으로 변경 가능한 새로운 체크포인트 트리거 지점인 “innodb_max_ dirty_pages_pct”, “innodb_max_dirty_pages_pct_lwm” 시스템 변수를 제공한다.
innodb_max_dirty_pages_pct 시스템 변수는 InnoDB 버퍼 풀에서 더티 페이지가 차지하는 최대 비율(%)이다. MariaDB 10.5.6 이하는 75%, MariaDB 10.5.7 이상은 90%가 기본 값이다. 기본 값을 사용하는 경우, 일반적으로 InnoDB 리두 로그 파일 크기보다 크게 설정되어 있어 체크포인트 트리거에 영향을 미치지 않는다.
innodb_max_dirty_pages_pct_lwm는 InnoDB 버퍼 풀의 더티 페이지 비율을 낮추기 위해 Flush를 활성화하는 더티 페이지의 Low water mark(LWM) 비율을 설정한다. 기본 값은 0%으로 innodb_max_dirty_pages_pct 변수 설정 값을 따른다. 이번 테스트에서는 innodb_max_dirty_pages_pct 값이 10%인 경우와 innodb_max_dirty_pages_ pct_lwm 값이 10%인 경우를 테스트7 결과와 비교해 보겠다.
테스트 결과 InnoDB 로그 파일 크기 기준으로 체크포인트 트리거 지점보다 더 낮은 시점에 체크포인트 트리거 시점이 제공되어 체크포인트 수가 증가하였고, I/O 작업을 동반하는 더티 페이지를 디스크 데이터 파일로 Flush 하는 작업도 더 빈번하게 수행되었다. 체크포인트 Age 크기를 작게 유지하여 Crash Recovery 작업 성능에 좋을 수 있으나, 적절하지 못한 사용은 MariaDB 전체적인 성능에 영향을 미칠 수 있으니 설정하여 사용하는 경우 충분히 고려되어야 한다.
4. Best-case vs Worst-case 성능 비교
InnoDB 리두 로그 성능 최적화를 위해 11번의 테스트를 진행하였다. 이 테스트 결과 중 Crash Recovery가 깨진 경우를 제외하고 Best-case vs Worst-case 성능을 비교해 보겠다.
테스트7(Best-case)은 테스트5(Worst-case)보다 트랜잭션 처리 시간이 47% 단축되었고, 체크포인트 수행 수는 78%(277회) 감소되어 InnoDB 버퍼 풀의 더티 페이지 Flush 작업으로 발생하는 디스크 I/O 부분도 개선되었다. Worst-case의 경우 비동기 시작 시점을 상회하여 InnoDB 최대 체크포인트 Age 크기까지 체크포인트 Age가 지속적으로 유지되어, Flush 작업이 매우 빈번하게 발생하였다. 반면에 Best-case의 경우 InnoDB 충분한 리두 로그 크기 확보로 체크포인트 Age가 안정적으로 관리되고 Flush 작업 또한 안정적인 패턴을 나타낸다. 체크포인트 실행 회수나 InnoDB 버퍼 풀에서의 더티 페이지 Flush 처리되는 페이지 양으로 볼 때, Worst-case가 Best-case보다 MariaDB 서버에 상당한 오버헤드가 발생할 수 있으며, 과도한 I/O 작업으로 인해 성능에 영향을 미쳤음을 테스트 결과로 확인할 수 있었다.
마치며
MariaDB 서버 InnoDB 스토리지 엔진의 InnoDB 리두 로그 모니터링 및 최적화에 대해 알아보았다. MariaDB 서버 InnoDB 스토리지 관련 성능 문제로 고민하고 있거나, 더 좋은 성능을 고민하고 있는 MariaDB 담당자에게 이 리포트가 도움이 되기를 바란다.
# References
- https://db-engines.com/en/ranking
- https://mariadb.com/kb/en/innodb-system-variables/
- https://mariadb.com/kb/en/innodb-status-variables/
- https://mariadb.com/kb/en/innodb-redo-log/
- https://mariadb.com/kb/en/information-schema-innodb_metrics-table/
이규환 프로
소프트웨어사업부 OSS사업팀
에스코어 OSS기술그룹에서 오픈소스DB와 관련된 전문가로 기술지원 업무를 하고 있습니다.
Register for Download Contents
- 이메일 주소를 제출해 주시면 콘텐츠를 다운로드 받을 수 있으며, 자동으로 뉴스레터 신청 서비스에 가입됩니다.
- 뉴스레터 서비스 가입 거부 시 콘텐츠 다운로드 서비스가 제한될 수 있습니다.
- 파일 다운로드가 되지 않을 경우 s-core_mktg@samsung.com으로 문의해주십시오.