콘텐츠로 이동

15. Altibase 튜닝#

이 장에서는 서버의 성능 향상을 위해서 Altibase가 제공하는 다음 두 가지 기능에 대해서 설명한다.

  • 로그 파일 그룹 (Log File Group)
  • 그룹 커밋 (Group Commit)

로그 파일 그룹#

이 절에서는 Altibase에서 제공하는 로그 파일 그룹 기능에 대해서 기술한다.

로그 파일 그룹의 개념#

Altibase는 기본적으로 로그 파일들을 LOG_DIR프로퍼티에 설정된 하나의 디렉터리에서 관리한다. 그리고 그 로그 파일들 중 오직 하나의 로그 파일에 데이터베이스 서버 운영 중에 발생하는 로그가 기록된다. 트랜잭션의 영속성(Durability)보장을 위해서 로깅은 필수적이다.

이와 같이 하나의 로그 경로, 즉 여러 개의 로그 파일을 지니는 로깅 시스템의 최소 단위를 로그 파일 그룹(Log File Group, LFG)이라고 칭한다. 앞으로는 설명의 편의를 위하여 로그 파일그룹을 간략하게 LFG라고 통칭한다.

LFG의 구성요소#

LFG는 다음과 같은 구성 요소를 지닌다.

로그 파일 경로 (LOG_DIR 프로퍼티)#

LOG_DIR 프로퍼티는 로그 파일이 저장되는 디렉터리 경로를 지정한다. 이 디렉터리는 하나 혹은 그 이상의 로그 파일들이 존재한다. Altibase는 그 중 오직 하나의 로그 파일에만 로그를 기록할 수 있다.

아카이브 로그 파일 경로 (ARCHIVE_DIR 프로퍼티)#

데이터베이스가 아카이브로그 모드로 운영중이라면, LOG_DIR 프로퍼티에 지정된 디렉터리에 위치하는 기록이 완료된 로그 파일들은 ARCHIVE_DIR 프로퍼티에 지정된 디렉터리로 복사된다. 이러한 아카이브 로그 파일은 데이터베이스 복구와 백업을 위해 사용된다.

이 프로퍼티의 수는 LOG_DIR프로퍼티의 수와 정확히 일치해야 한다. 아울러, LOG_DIR 프로퍼티가 여러 개인 경우 ARCHIVE_DIR 프로퍼티들은 LOG_DIR 프로퍼티 값과 순서대로 1:1로 매핑되도록 기술해야 한다.

LFG를 위해서 다음과 같은 세가지 종류의 쓰레드가 존재한다.

로그 파일 준비 쓰레드 (Log File Prepare Thread)#

기록 중인 로그 파일이 꽉 차게 되면, Altibase는 새로운 로그 파일에 로그를 기록하기 시작한다. 이 때, 새로운 로그 파일로의 교체가 필요한 시점에 Altibase가 새로운 로그 파일을 생성한다면, 로그를 기록하려는 트랜잭션은 로그 파일이 생성되는 동안 아무 작업도 수행하지 못한 채로 기다려야 한다는 문제점이 발생한다.

이 쓰레드는 로그 기록을 계속하기 위한 새 로그 파일이 필요한 시점 전에 로그 파일을 미리 만들어 둔다.

참고로, 체크포인트 중에 더 이상 사용되지 않는 로그 파일들을 별도로 분류하여 체크포인트가 완료되는 시점에 이를 삭제한다.

로그 플러시 쓰레드 (Log Flush Thread)#

최근에 기록된 로그를 주기적으로 디스크로 기록하는 쓰레드이다. 트랜잭션이 커밋될 때, Altibase 트랜잭션은 이 쓰레드가 관련 로그를 벌써 디스크에 쓰지 않았는지 검사하고, 기록되지 않은 로그만 디스크에 쓰게 된다.

즉, 이 쓰레드는 주기적으로 로그를 디스크에 기록함으로써 트랜잭션이 커밋되는 시점에 디스크에 기록할 로그의 수를 줄여주게 된다.

아카이브 로그 쓰레드 (Archive Log Thread)#

로그가 기록되고 있는 로그 파일이 가득 차게 되면 다른 새로운 로그 파일에 로그 기록이 계속된다. 이때, 아카이브 로그 쓰레드는 방금 전까지 로그가 기록되고 있던, 하지만 끝까지 다 기록되어 더이상 로그가 기록되지 않는 이전 로그 파일을 아카이브 로그 파일로 복사한다.

사용 예#

LFG에 관련된 프로퍼티는 아래의 2개가 있다.

LOG_DIR
ARCHIVE_DIR

Altibase는 한 개의 LFG만 사용하도록 설정된다. 그리고 LOG_DIR과 ARCHIVE_DIR프로퍼티를 사용해서 따로 로그 경로와 아카이브 로그 경로가 지정된다.

다음은 LFG를 구성한 경우의 Altibase 프로퍼티 파일의 일부를 보여준다.

LOG_DIR = ?/logs                   # 로그 경로
ARCHIVE_DIR = ?/arch_logs          # 아카이브 로그 경로

물음표(?)는 Altibase 홈($ALTIBASE_HOME) 디렉터리를 나타내므로, 로그가 기록되는 경로는 $ALTIBASE_HOME/logs가 된다.

데이터베이스를 생성한 후 로그 경로 안의 내용을 살펴보면 다음과 같이 logfile0부터 logfile2까지 세 개의 로그 파일이 존재하는 것을 볼 수 있다. 이들 중 오직 하나의 로그 파일에만 트랜잭션이 데이터베이스에 변경을 가하면서 발생하는 로그가 기록된다.

-rw-------   1 altibase altibase 10485760 Jun 22 15:46 logfile0
-rw-------   1 altibase altibase 10485760 Jun 22 15:46 logfile1
-rw-------   1 altibase altibase 10485760 Jun 22 15:46 logfile2

그룹 커밋#

이 절에서는 트랜잭션 처리 성능 향상을 위해서 Altibase가 제공하는 그룹 커밋 기능에 대해서 설명한다.

그룹 커밋의 개념#

그룹 커밋은 여러 트랜잭션들의 커밋 요청을 모아서 한번에 처리하여 I/O부하를 줄여주는 기능이다.

하나의 트랜잭션이 커밋한 후에는 해당 트랜잭션이 수정한 내용이 어떠한 상황에서도 유실되어서는 안 된다. 이를 보장하기 위해서는 해당 트랜잭션이 기록한 로그가 모두 디스크에 반영된 후에, 클라이언트에게 트랜잭션의 커밋이 완료되었음을 알려주어야 한다.

하지만 이러한 과정에서 수행되는 디스크 I/O는 메모리 기록에 비해 시간이 많이 걸리기 때문에, 여러 트랜잭션이 동시에 디스크 I/O를 각자 처리하게 될 경우 시스템의 성능 저하 정도는 더욱 심해질 것이다.

디스크 I/O를 수행하는데 소요되는 시간은 I/O의 양보다는 횟수에 더 큰 영향을 받는다. 즉, 여러 번에 걸쳐서 수행할 I/O를 한번에 몰아서 수행한다면, 시스템의 성능을 향상시킬 수 있을 것이다.

그룹커밋은 커밋을 하려는 여러 트랜잭션들의 로그에 대한 디스크 I/O를 몰아서 한번의 I/O로 처리하는 것으로, 시스템의 성능을 향상시킬 수 있다.

그룹 커밋 동작 원리#

여러 트랜잭션의 커밋을 위한 디스크 I/O수행을 한번에 몰아서 처리하기 위해 Altibase는 마지막으로 디스크 I/O를 수행한 시각을 기억해두고 있다가 이후 일정 시간이 지나기 전에는 디스크 I/O를 허용하지 않고 트랜잭션들을 대기하도록 한다.

이와 같은 디스크 I/O대기 시간이 너무 작게 설정되어 있으면 디스크 I/O가 빈번하게 수행되어 그룹 커밋을 하지 않은 것과 별반 다름 없게 되고, 너무 크게 설정되어 있으면 디스크 I/O를 수행하려는 트랜잭션들이 불필요하게 오래 대기하게 되어 오히려 시스템의 성능이 저하된다.

그룹 커밋을 위한 디스크 I/O대기시간을 튜닝하는 방법에 대해서는 본 장의 '그룹 커밋 관련 프로퍼티 튜닝'을 참조한다.

그룹 커밋이 지정되어 있다면, Altibase 서버가 어떤 트랜잭션이 커밋을 위해 로그를 디스크로 내릴지를 결정할 때, 다음의 단계대로 작업을 수행한다.

  1. 이 트랜잭션이 디스크로 기록하려는 로그가 이미 다른 트랜잭션에 의해 디스크로 내려간 경우, 디스크 I/O를 수행하지 않는다. 그렇지 않을 경우, 2번을 수행한다.
  2. 데이터베이스에 변경을 가한 트랜잭션의 수가 LFG_GROUP_COMMIT_UPDATE_TX_COUNT 프로퍼티에 지정된 값보다 작을 경우, 디스크 I/O를 수행하지 않고 대기한다. 그렇지 않을 경우 3번을 수행한다.
  3. 가장 최근에 로그를 디스크로 기록한 이후로 LFG_GROUP_COMMIT_INTERVAL_USEC 프로퍼티에 지정한 시간이 경과하지 않은 경우, 디스크 I/O를 수행하지 않고 대기한다. 그렇지 않을 경우 4번을 수행한다.
  4. 디스크 I/O가 발생한 시각을을 기록하고 디스크 I/O를 수행하여, 모든 대기하던 로그를 디스크에 기록한다.

그룹 커밋 수행 단위#

트랜잭션이 기록한 로그를 디스크로 기록하는 작업은 LFG 단위로 수행된다.

그룹 커밋 관련 프로퍼티#

COMMIT_WRITE_WAIT_MODE가 0으로 설정된 경우, 트랜잭션 커밋시에 커밋 로그가 디스크에 반영되는 것을 기다리지 않기 때문에 정전시의 영속성(Durability)은 보장되지 않는다.

그룹 커밋 기능은 트랜잭션의 영속성(Durability) 보장을 위한 디스크 I/O를 모아서 처리하는 최적화 기법이다. 그러므로 이는 COMMIT_WRITE_WAIT_MODE가 1로 설정되어 있을 경우에 의미가 있다. 이 프로퍼티가 1로 설정된 경우에만 트랜잭션 커밋시 커밋 로그가 디스크에 반영될 때까지 트랜잭션이 기다리기 때문이다.

그룹 커밋시 고려사항#

그룹 커밋은 여러 트랜잭션이 동시에 커밋을 하려고 할 때에만 그 효과를 발휘한다. 예를 들어 시스템상에 오직 하나의 트랜잭션만이 커밋하려고 하는 경우, 즉 커밋하려는 다른 트랜잭션이 존재하지 않는 경우, 이 때에는 함께 모아서 디스크 I/O를 처리할 트랜잭션이 없다. 이런 경우 그룹커밋을 하지 않고 바로 디스크 I/O를 수행하는 것이 더 좋은 성능을 낸다.

앞서 그룹 커밋 수행 단위에 기술한 바와 같이, 그룹 커밋은 LFG 단위로 이루어진다. 그룹 커밋을 수행할지의 여부도 LFG내에 커밋되지 않은 트랜잭션의 개수를 기반으로 독립적으로 결정하게 된다. Altibase는 데이터베이스에 변경을 가한 트랜잭션 수를 LFG 단위로 센다.

DBA는 시스템의 특성을 고려해 LFG_GROUP_COMMIT_UPDATE_TX_COUNT의 최적값을 찾아야 한다. 이 프로퍼티의 기본값은 80이다.

그룹 커밋은 시스템이 특정 시간동안 가능한한 많은 트랜잭션의 커밋 요청을 처리할 수 있도록 돕는다. 하지만 그룹 커밋을 사용할 경우 여러 트랜잭션의 커밋 요청을 몰아서 한번에 처리하기 때문에, 개별 트랜잭션에 대한 응답 시간은 그룹 커밋을 사용하지 않을 때보다 길어질 수 있다.

그룹 커밋 관련 통계치#

Altibase는 DBA가 그룹 커밋의 동작을 모니터링 할 수 있는 통계치를 제공한다. 그룹 커밋은 LFG 단위로 이루어지기 때문에, 그룹 커밋의 통계치는 V$LFG성능 뷰에 존재한다.

V$LFG성능 뷰의 그룹 커밋 관련 통계값들은 다음과 같다.

UPDATE_TX_COUNT#

데이터베이스에 변경을 가한 트랜잭션의 개수를 실시간으로 보여주는 통계치이다. 이 값이 LFG_GROUP_COMMIT_UPDATE_TX_COUNT 프로퍼티에 설정된 값보다 클 때에만 그룹 커밋을 실시한다.

GC_WAIT_COUNT#

이 통계값은 가장 최근 디스크 I/O 발생 이후 디스크 I/O가 연기된 회수를 보여준다. 이 카운트는 LFG_GROUP_COMMIT_INTERVAL_USEC 프로퍼티에 지정한 만큼의 시간이 지나지 않아서 디스크 I/O를 수행하지 못할 때마다 1씩 증가한다.

GC_ALREADY_SYNC_COUNT#

트랜잭션이 커밋을 위해 디스크로 기록해야 하는 로그의 내용이 이미 다른 트랜잭션에 의해 디스크로 기록된 경우에는 추가적인 디스크 I/O를 수행할 필요가 없다. 이와 같이 디스크 I/O를 수행하지 않고 바로 커밋 완료 응답 신호를 보내는 경우에 1씩 증가하는 카운트 값이다.

GC_REAL_SYNC_COUNT#

실제 디스크 I/O를 수행하여 로그를 디스크로 기록한 경우 1씩 증가되는 카운트 값이다. 이는 다음 두 가지 경우 중 하나일 때 증가된다.

  • 하나의 트랜잭션이 커밋을 위해 로그를 디스크로 기록하려 하려는 시점에 V$LFG 성능 뷰의 UPDATE_TX_COUNT 값이 LFG_GROUP_COMMIT_UPDATE_TX_COUNT 프로퍼티의 값보다 작으면 그룹 커밋 기능이 활성화 되지 않고, 따라서 직접 로그 기록을 위한 디스크 I/O를 수행한 경우
  • 그룹 커밋이 활성화된 상황에서 마지막으로 디스크 I/O를 수행한 시각 이후로 LFG_GROUP_COMMIT_INTERVAL_USEC 프로퍼티에 지정한 만큼의 시간이 지나서 실제 디스크 I/O를 수행한 경우

그룹 커밋 관련 프로퍼티 튜닝#

그룹 커밋 기능을 이용하기 위해서는 시스템 자체의 성능과 다수의 커밋하려는 트랜잭션이 발생하는 상황에서의 시스템의 부하를 종합적으로 고려하여 관련 프로퍼티를 최적값으로 설정해야 한다. 이 절에서는 각각의 그룹 커밋 관련 프로퍼티값을 튜닝하는 방법에 대해 알아본다.

LFG_GROUP_COMMIT_UPDATE_TX_COUNT#

이 프로퍼티의 값이 너무 작으면 데이터베이스에 변경을 가한 트랜잭션 수가 그다지 많지 않아도 그룹 커밋이 활성화된다. 이 경우, 로그를 기록하기 위한 디스크 I/O의 횟수가 증가하여 시스템 성능이 저하된다.

반면, 이 프로퍼티의 값이 너무 크면 비록 데이터베이스에 변경을 가한 트랜잭션의 수가 충분히 많더라도 그룹커밋이 활성화되지 못한다.

데이터베이스 시스템에 여러개의 트랜잭션이 몰리는 때에 DBA는 V$LFG 성능 뷰의 UPDATE_TX_COUNT 값을 실시간으로 모니터링 하여 이 프로퍼티의 값을 적정한 값으로 결정하면 된다.

LFG_GROUP_COMMIT_INTERVAL_USEC#

이 프로퍼티의 값이 너무 작으면 빈번하게 디스크 I/O가 수행되어 시스템 성능이 저하된다. 이러한 상황에서는 커밋을 위해 실제로 디스크 I/O를 수행하는 횟수가 많아지므로 V$LFG 성능 뷰의 GC_REAL_SYNC_COUNT 값이 빠른 속도로 증가한다.

반대로, 이 프로퍼티의 값이 너무 크면 이용 가능한 디스크 I/O 용량이 충분히 활용하지 못하여 시스템의 성능이 저하된다. 이러한 상황에서는 디스크 I/O를 위해 대기하는 횟수가 많아지므로 V$LFG 성능 뷰의 GC_WAIT_COUNT 값이 빠른 속도로 증가한다.

이 프로퍼티를 최적으로 설정하려면 우선 이 프로퍼티의 값을 기본값인 1000 (1ms)에서부터 시작하여 2배씩 증가시켜가면서 시스템의 전체 성능 (TPS - Transaction Per Second)을 측정해 본다.

GC_REAL_SYNC_COUNT의 값이 점점 작아지면서 최적의 성능을 낼 때 이 프로퍼티가 최적화 됐음을 의미한다. GC_REAL_SYNC_COUNT의 값이 작아지는 것이 곧 최적의 성능을 내는 상황을 의미하지는 않는다.

앞서 설명한 대로 이 프로퍼티의 값이 너무 크면 커밋을 하려는 트랜잭션들이 디스크 I/O를 위해 불필요하게 많은 시간을 기다리게 되어 디스크 I/O를 수행할 수 있는데도 디스크 I/O를 수행하지 않고 대기하는 상황이 발생하기 때문이다. 이 경우에는 위와 같은 방법으로 기본값인 1000에서 절반씩 감소시켜 가면서 최적의 TPS를 내는 상황을 찾아낸다.

LFG_GROUP_COMMIT_RETRY_USEC#

이 프로퍼티의 값이 너무 작으면 디스크 I/O를 대기하는 트랜잭션들이 더 빈번하게 깨어나서 디스크 I/O를 수행해야 하는지 체크하게 된다. 이 경우 개별 트랜잭션의 커밋에 대한 응답시간은 짧아질 수 있지만, 디스크 I/O가능 여부 체크를 너무 빈번하게 하게 되어서 CPU 사용율이 높아지게 된다. 또한 이러한 상황에서는 빈번하게 디스크 I/O가능 여부를 체크한후 디스크 I/O를 위한 대기상태로 들어갈 수 있기 때문에 이 프로퍼티의 값이 클 때에 비해서 V$LFG 성능 뷰의 GC_WAIT_COUNT 값이 빠른 속도로 증가할 것이다.

반면, 이 프로퍼티의 값이 너무 크면 디스크 I/O를 대기하는 트랜잭션들이 디스크 I/O가 가능한지의 여부를 체크하는 횟수가 줄어들게 되며, CPU사용율이 낮아지게 된다. 하지만 디스크 I/O 가능 여부를 체크하기까지의 대기시간이 길어져서 개별 트랜잭션의 커밋에 대한 응답시간은 길어진다.

DBA는 이 프로퍼티의 값을 변경할 때, Unix의 top 명령으로 Altibase 프로세스의 CPU 사용율을 모니터링하거나 개별 트랜잭션의 응답시간의 평균값을 측정하는 방법으로 이 프로퍼티 값을 최적의 값으로 설정할 수 있다.