mariaDB-Optimization and Tuning(Table)

OPTIMIZE TABLE

OPTIMIZE TABLE 구문은 두 개의 함수로 이루어져 있다. 각각 테이블의 조각화 현상을 해결하거나 전문인덱스를 업데이트하는데 사용된다.

Defragmenting

OPTIMIZE TABLE 명령은 InnoDB, Aria, MyISAM, ARCHIVE 테이블에서 동작 가능하며 많은 양의 레코드를 삭제하였거나 가변길이 row(VARCHAR나 VARBINARY, BLOB, Text 컬럼등)를 대량 변경하였을 경우 수행해야 한다. (MariaDB 10.1.1 이전에는 innodb_file_per_table 파라미터가 ON 된 경우에만 가능했었음) 삭제된 row는 링크된채로 리스트에 보관되며 insert 동작이 오면 해당 row위치를 재사용한다.

이 구문은 테이블에 대해 SELETE와 INSERT 권한이 필요하다.

기본적으로 OPTIMIZE TABLE 명령은 바이너리 로그에 남고 복제본에 전달되는데 NO_WRITE_TO_BINLOG 키워드를 (혹은 별칭으로 그냥 LOCAL만 쳐도 됨) 사용하면 바이너리 로그를 남기지 않게 된다.

OPTIMIZE TABLE은 또한 파티셔닝 된 테이블에도 지원된다. ALTER TABLE … OPTIMIZE PARTITION 명령을 사용하면 다수의 파티셔닝도 최적화할 수 있다.

Updating an InnoDB fulltext index

전문 인덱스에 row가 추가되거나 삭제되어도 전문인덱스의 재구성 작업은 비용이 크기 때문에 즉시 수행되지 않는다. 변경된 통계정보는 다른 위치에 저장된다. 전문 인덱스는 오직 OPTIMIZE TABLE 명령을 통해서만이 재구성된다.

기본적으로 OPTIMIZE TABLE 명령은 테이블의 조각화 현상을 해결한다. 만약 전문 인덱스의 통계정보를 업데이트하려면 innodb_optimize_fulltext_only 시스템 변수를 1로 셋팅해야 한다. 이것은 반드시 임시적으로만 쓰여야 하며 전문인덱스의 재구성이 완료되면 0으로 돌려놔야 한다. 전문인덱스의 재구성 작업은 시간이 꽤 오래 걸리기 때문에 innodb_ft_num_word_optimize 변수는 재구성하려는 단어의 값을 제한하고 있다. (기본적으로 2000) 전문인덱스 재구성 명령을 동시에 여러 개 수행해도 된다.

Defragmenting InnoDB Tablespaces

mariaDB 10.1.1 에서 페이스북과 카카오의 조각모음 방식 패치를 받아들여 InnoDB 테이블스페이스에 대해서도 조각모음이 가능하게 되었다. 이 기능을 사용하려면 innodb_defragment 변수를 활성화시켜야 한다.

InnoDB 테이블에서 row가 삭제되면 물리적으로 제거하는 대신 delete maker가 새겨놓는다. 그리고 삭제된 영역의 재사용을 위해 OS로 반환하지 않는다. purge 쓰레드가 인덱스의 키와 row를 지우기 위해 수행되는데, 이렇게 지워진 free 여역도 OS에 반환되지 않는다. 이것은 page에 빈 공간을 유발하게 된다. 만약 당신이 가변길이 row를 사용하고 있을 때 새로운 row의 길이가 방금 지운 row의 길이보다 크다면 지운 영역을 재사용할 수 없게 된다.

OPTIMIZE TABLE이나 ALTER TABLE … ENGINE=InnoDB 명령은 테이블을 재구성하도록 해준다. 그런데 불행히도 공통 테이블스페이스 파일인 ibdata1에 대해 최적화를 수행하면 아래와 같은 현상이 일어난다.

  • 테이블의 데이터와 인덱스를 연속적으로 만든다.
  • 연속적인 데이터와 인덱스 페이지가 ibdata1에 이어써지기 때문에 ibdata1의 크기가 증가한다. (?)

MariaDB 10.1 에서는 페이스북의 Matt, Kakao의 이성욱에 의해 제공된 조각모음 패치를 포함하였다. 페이스북의 코드와 Matt코드의 차이점은 MariaDB는 새로운 literal을 SQL에 포함하지 않았고 서버 코드를 변경하지 않았다는 것이다. 대신 InnoDB/XtraDB 스토리지 엔진 내부에만 코 변경을 하였다.

OPTIMIZE TABLE의 동작 원리는 기본적으로 변하지 않았다. 새로 추가된 이 기능을 사용하려면 innodb_defragment 시스템 변수를 1로 설정해야 한다.

새로운 테이블을 만들어서 데이터를 이전 테이블에서 새로운 테이블로 옮기는 작업이 필요없어졌다. 대신 n개의 새로운 page를 만들어서 record를 새로운 page로 옮기게 된다. 새로운 page가 꽉 차면 기존 record가 있던 page는 빈 영역이 된다. 이와 관련하여 새로 소개된 시스템 변수는 아래와 같다. (이 변수들도 10.1.1부터 추가됨)

System variables

  • Innodb_defragment: InnoDB의 조각모음을 활성화한다.
  • innodb_defragment_n_pages: 조각모음시 한 타임에 몇 개의 page를 가지고 작업할 것인지를 결정하는 파라미터이다. 기본 값: 7
  • innodb_defragment_stats_accuracy:  조각모음 통계의 개수… (?)
  • innodb_defragment_fill_factor_n_recs: 조각모음 수행시 추후 사용을 위해 남겨놓을 페이지 여유분으로 record 건수를 기준으로 함. 기본 값: 20
  • innodb_defragment_fill_factor: 조각모음 수행시 페이지를 얼마나 채울 지 비율을 결정하는 변수. 기본 값: 0.9
  • innodb_defragment_frequency: 단일 인덱스에 대해 조각모음을 수행할 수 있는 초당 횟수의 최대값. 기본 값: 40

Status variables

  • innodb_defragment_compression_failures: 조각모음 재압축의 실패 횟수
  • innodb_defragment_failures: 조각모음 실패 횟수
  • innodb_defragment_count: 조각모음 수행 횟수

 

ANALYZE TABLE

ANALYZE TABLE은 테이블의 키 분포에 대해 분석하고 저장하는 구문이다. MyISAM, Aria, InnoDB 테이블에서 모두 수행 가능한데, MyISA 엔진에서 수행하면 테이블에 read 락이 걸리며 InnoDB 엔진에서 수행하면 write 락이 걸린다. MyISAM 테이블 같은 경우 myisamchk –analyze 명령을 수행한 것과 동일한 효과를 보인다.

Join 수행시 MariaDB는 키의 분포도를 보고 테이블의 조인 순서를 결정한다. 그리고 키 분포를 보고 특정 테이블에서 어떤 인덱스를 사용할 것인지를 결정하기도 한다. ANALYZE 문을 수행하기 위해선 SELECT와 INSERT 권한이 필요하다. 기본적으로 ANALYZE문은 바이너리 로그에 남고 replication에 전달되기 때문에 만약 바이너리 로그에 남기지 않으려면 NO_WRITE_TO_BINLOG 키워드를 추가하면 된다.

※ MariaDB 10.0.1에서 ANALYZE시 스토리지 엔진과 무관한 통합 통계정보를 수집하도록 되었으며 현재 이러한 통계정보는 풀 테이블 스캔이나 풀 인덱스 스캔시 수집된다. 물론 비용은 꽤 크다.

MariaDB 10.0.1부터 ANALYZE TABLE 명령은 PERSISTENT FOR 키워드를 이용하여 특정 컬럼이나 인덱스를 선택할 수 있도록 되었다. 아래는 사용법에 대한 예제이다. 그리고 BLOB이나 텍스트 컬럼은 통계정보 수집되지 않는다.

ANALYZE TABLE tbl PERSISTENT FOR ALL;
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS (col1,col2,...) INDEXES (idx1,idx2,...);
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS () INDEXES (idx1,idx2,...);
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS () INDEXES ();
--> 컬럼과 인덱스에 대한 통계는 빼고 테이블의 통계 정보만 수집함.
use_stats_tables 변수가 never로 설정되어 있지 않은 한 단순 ANALYZE TABLE 명령은
통합 통계 테이블에 저장되게 된다.
SET SESSION use_stat_tables='COMPLEMENTARY';
ANALYZE TABLE tbl;

테이블 옵션에 STATS_PERSISTENT=1이 설정되어 있다 하더라도 통합 통계정보를 업데이트하도록 하려면 PERSISTENT FOR 키워드를 써야 한다.

 

Converting Tables from MyISAM to InnoDB

MyISAM 을 InnoDB로 옮기는 것은 ALTER TABLE … ENGINE=innoDB 명령으로 간단히 바꿀수는 있다. 그러나 스토리지 엔진을 변경하는 것은 미처 알아채기 힘든 여러 이슈들을 포함하고 있다.

인덱스가 어떻게 작동하는지 이해하는 것은 InnoDB에서 무엇이 더 빠르고 무엇이 더 느릴지 이해하는데에 도움을 줄 것이다.

INDEX Issues

모든 InnoDB 테이블은 PK를 갖는다. 만약 별도로 지정하지 않았다면, Not null & Unique 속성을 갖는 컬럼이 PK가 될 것이며, 그것도 없으면 6바이트의 숨겨진 컬럼이 내부적으로 생성된다.
별도로 PK컬럼을 지정하지 않은 테이블을 생각해보자. 비록 인위적인 AUTO_INCREMENT 속성이 포함된다 하더라도 PK를 명시적으로 지정하자. 이것은 강제적인 사항은 아니지만 MyISAM이 아닌 InnoDB를 사용할  강력한 권고사항이다. 아래는 PK에 대해 몇 가지 사실들을 이야기하고 있다.

Fact: 모든 세컨더리 인덱스의 키는 PK를 포함하고 있다.

PRIMARY KEY(id),
INDEX(b), -- effectively the same as INDEX(b, id)
INDEX(b, id) -- effectively the same as INDEX(b)

Index(b)를 만드나 Index(b, id)를 만드나 동일하기 때문에 하나는 삭제해도 좋다.

PRIMARY KEY(id),
UNIQUE(b), -- keep for uniqueness constraint
INDEX(b, id) -- DROP this one

이런 경우도 동일한 인덱스이지만 UNIQUE(b)는 b가 Unique하다는 것을 알려주기 때문에 좀 더 많은 정보를 담고 있다. 따라서 INDEX(b,id)를 삭제하는 것이 좋다.

PRIMARY KEY(id),
INDEX(id, b) -- DROP this one; it adds almost nothing

이 경우에도 인덱스는 삭제하는 것이 좋다.

Contrast: MyISAM의 특성이 InnoDB에서는 발현되지 않는 케이스도 있다. MyISAM에서 아래 케이스의 경우 ‘abc’의 값마다 별도의 ‘id’의 값을 가지며 1씩 증가하게 된다.

id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (abc, id)

이런 MyISAM의 특성을 흉내내기 위해 아마 당신은 아래와 같이 코딩할 것이다.

INSERT INTO foo
    (other, id, ...)
    VALUES
    (123, (SELECT MAX(id)+1 FROM foo WHERE other = 123), ...);

그러나 테이블을 두 번 언급하였기 때문에 아래와 같이 에러를 반환하게 된다.

ERROR 1093 (HY000): Table ‘foo’ is specified twice, both as a target for ‘INSERT’ and as a separate source for data

따라서 변수를 이용하여 아래와 같이 만들어야 할 것이다.

BEGIN;
SELECT @id := MAX(id)+1 FROM foo WHERE other = 123;
INSERT INTO foo
    (other, id, ...)
    VALUES
    (123, @id, ...);
COMMIT;

다른 쓰레드에서 중복된 id값을 가져가는 것을 방지하기 위해 반드시 트랜잭션을 형성해야 한다.

 

 

mariaDB-Optimization and Tuning(OS)

1. Configuring Swappiness

Why to avoid swapping

  • mariaDB는 메모리가 스왑되지 않았다고 가정한다. 만약 swap이 발생한 상태라면 단순히 최초 access로 disk에서 로딩하는 것보다 성능에 더 좋지 않은 영향을 미친다.

 

스와핑을 피할 수 있는 가장 좋은 방법은 충분한 RAM을 확보하는 것이다. 시스템 변수를 너무 높게 잡으면 서버의 메모리가 부족해지면서 스왑을 일으킬 수도 있게 된다. 따라서 어떤 셋팅 값을 사용할 것인지, 이것이 메모리에 어떤 영향을 미칠지 이해하는 것이 매우 중요하다.

Setting swappiness on Linux

리눅스는 swappiness 라는 셋팅값을 가지고 있는데 이것은 RAM에서 하드디스크에 존재하는 스왑영역으로 스왑하는 정도를 의미한다. 0부터 100까지 설정이 가능하며 낮은 값은 잘 스왑하지 않는 다는 의미이다. 기본 값은 60이며 아래 커맨드로 확인해 볼 수 있다.

sysctl vm.swappiness

이 기본값은 서버로 하여금 스왑하도록 권장하고 있다고 볼 수 있다. 왠만해선 MariaDB에서 스왑하는 상황을 원치 않을 것이므로 이 값을 0으로 하는 것이 좋다. sysctl.conf 파일을  (대부분 /etc/sysctl.conf에 존재) 아래와 같이 swappniess를 0으로 만드는 설정을 추가하면 된다.

vm.swappiness = 0

/etc/sysctl.conf 파일에 적용하는 것은 리부팅 이후에도 지속된다.

데이터베이스 워크로드에는 낮은 수준의 swappiness를 추천한다. mariaDB 데이터베이스에 대해서 이 값을 1로 설정하는 것을 추천한다.

vm.swappiness = 1

 

Disabling swap altogether

스와핑을 완전히 비활성화 함으로써 데이터베이스 프로세스가 스와핑되는 것을 원천봉쇄하고자 하는 유혹이 있을 것이다. 그러나 조금의 스왑 기능을 남겨놓아야 실행중인 프로세스가 kill 되는 상황을 방지할 수 있다.

 

2. Filesystem Optimizations

Which filesystem is best?

사실 MariaDB 성능에 있어서 파일시스템은 중요한 포인트가 아니다. RAM이나 Disk drive의 속도, 시스템 변수의 셋팅이 더 중요하다고 볼 수 있다.

그러나 파일시스템의 최적화에 따라 큰 차이를 보일 수도 있다. 현재 리눅스 파일시스템 중 가장 훌륭한 성능을 보이는 것은 ext4와 XFS, Btrfs 이다. 이들은 모두 리눅스 커널에 포함돼있고 대부분의 리눅스 배포판에서 사용 가능하다. (Redhat제품에서 Brtfs는 미리 보기만 가능하고 아직 운영환경에 사용할 수 있는 준비는 되지 않음)

 

 

 

 

시스템 파라미터(스토리지 엔진)

innodb_purge_threads=1 ~ 32(기본 값: 1)
innoDB엔진에 생성된 테이블은 오라클과 비슷하게 undo 세그먼트를 사용한다. 버퍼 캐시의 변경된 내용은 주기적으로 디스크로 써야 하는데, 오라클의 경우 1개 이상의 DBWn라는 대몬이 전담하여 이를 처리하고 있는 것처럼 mariaDB도 디스크로 내려쓰는 역할을 전담하는 thread의 개수를 지정할 수 있다.


UNDO

innodb_undo_directory=경로(기본 값: .)
기본적으로 mariaDB에서 undo 영역은 시스템 테이블 스페이스의 일부 영역을 사용하고 있지만 별도의 테이블 스페이스 공간을 만들어 사용할 수도 있다. 점(.)은 버전 5.5 이전에서와 같이 시스템 테이블스페이스의 일부 영역을 사용하겠다는 의미이고, 다른 경로를 입력하면 undo 영역으로 사용할 테이블 스페이스 공간의 위치를 설정하게 된다. 보통 undo영역은 SSD와 같이 빠른 저장장치가 존재하는 위치로 지정하면 좋다.

innodb_undo_tablespaces=0 ~ 126(기본 값: 0)
하나의 undo 테이블스페이스 파일로 운영하면 경합이 발생할 수 있기 때문에 파일을 분할하여 부하가 분산될 수 있도록 한다. 이 파라미터로 지정한 값 만큼 innodb_undo_directory로 지정한 경로에 undoN (N은 숫자)로 undo 용 파일이 생성된다.

innodb_undo_logs=0 ~ 128(기본 값: 128)
하나의 언두 세그먼트에는 다수의 트랜잭션이 저장될 수 있다. innoDB에서는 하나의 언두 세그먼트당 최대 1023개의 트랜잭션이 저장될 수 있다. 이 파라미터는 세그먼트의 개수를 지정하는 것으로 최대innodb_undo_logs * 1023 개의 트랜잭션이 실행될 수 있는 것이다. 이 값은 늘리 수만 있고 줄일 수는 없으므로 처음부터 너무 큰 값을 주지 않도록 한다.


Buffer Pool

 innodb_buffer_pool_populate=ON or OFF (기본 값: OFF)
리눅스에서는 사용자가 지정한 버퍼 풀 사이즈를 처음부터 모두 할당하지 않는다. 버퍼 풀 사용량이 늘어나면서 차츰 늘려주는 방식인데, 이로 인해 실제 메모리가 얼마나 할당되었는지 모니터링 하기 쉽지가 않고 잘못된 메모리 할당으로 인한 부작용이 종종 있어왔다. 따라서 버퍼 풀 사이즈를 DB 기동시부터 모두 할당받을 수 있는 기능을 제공한다. 이 값을 ON으로 하면 된다.

 innodb_buffer_pool_load_at_startup=0 or 1 (기본 값: 0)
MariaDB를 재시작하면 버퍼캐시가 비게 되는데, 이 상태에서 서비스를 재개하면 Disk read가 심해지면서 부하가 심해질 수 있다. 이를 방지하기 위해 버퍼 캐시의 내용을 파일로 저장했다가 재기동시 읽어들여 버퍼 캐시를 복구하도록 할 수 있다(오라클에는 없는 신박한 기능인듯)
이 기능을 사용하려면 innodb_buffer_pool_dump_at_shutdown 파라미터에 의해 서버를 내릴 때 dump를 떨구도록 해야 한다.

innodb_buffer_pool_dump_at_shutdown=0 or 1(기본 값: 0)
MariaDB 를 내릴 때 버퍼캐시의 내용을 파일로 떨구도록 한다. innodb_buffer_pool_load_at_startup파라미터와 함께 쓰도록 한다.

innodb_blocking_buffer_pool_restore=0 or 1(기본 값: 0)
Dump로 버퍼 캐시의 데이터를 파일로 떨군 후 mariaDB 재기동 하면서 버퍼 캐시를 복구하는 도중에 XtraDB 스토리지 엔진을 참조하는 사용자 쿼리가 수행되면 복구작업이 늦어질 수 있다. 따라서 이 파라미터를 통해 쿼리 수행을 허용할 수 있을지 없을지를 결정한다. 1이면 블로킹한다.

innodb_buffer_pool_dump_now=0 or 1(기본 값: 0)
위에 언급한 innodb_buffer_pool_dump_at_shutdown 파라미터는 mariaDB를 내릴 때 dump 하는 것이지만 이 파라미터는 값을 1로 변경하는 순간 dump를 뜬다. 덤프가 완료되면 값이 다시 0으로 바뀐다.

innodb_buffer_pool_load_now=0 or 1(기본 값: 0)
innodb_buffer_pool_dump_now 파라미터와 비슷하게 이 파라미터는 값을 1로 변경하는 순간 dump파일에 있는 내용으로 버퍼 캐시를 복구한다. 완료되면 값이 다시 0으로 변경된다.

innodb_buffer_pool_load_abort=0 or 1(기본 값: 0)
innodb_buffer_pool_load_now에 의해 페이지를 버퍼 캐시에 로딩중 예상보다 시간이 오래 걸려 중지해야 할 경우 이 파라미터로 작업을 중지시킬 수 있다. 값을 1로 변경하는 순간 작업이 중지되며 파타미터 값도 다시 0으로 돌아온다.

innodb_flush_method= ‘O_DSYNC’ | ‘O_DIRECT’ | ‘O_DIRECT_NO_FSYNC’ | ‘ALL_O_DIRECT’ (기본 값: null)
기본적으로 리눅스 환경에서는 페이지를 버퍼캐시로 로드할 때 서버의 메모리로 올린 후 DB의 버퍼 캐시로 적재하게 된다. 이 과정에서 서버의 메모리와 DB의 버퍼 캐시가 동일한 페이지를 보관함으로써 더블 버퍼링이라고 하는 비효율성이 발생하게 된다. 따라서 서버의 캐시를 거치지 않고 바로 Disk로 write하거나 Disk로부터 바로 버퍼캐시로 read할 수 있도록 옵션을 제공하고 있다.
아래는 파라미터 값 별로 어떻게 동작하는지를 정리한 표이다.

DIRECIO.jpg

Read란 Disk에서 페이지를 읽어 버퍼 캐시에 적재하는 상황을 의미하며, Flush란LRU 및 더티 페이지 write, 체크포인트에 의해 write이 발생했을 때를 의미한다.
O_DSYNC는 서버의 data/log에 상관없이, 그리고 read/flush에 상관없이 항상 메모리를 거쳐가며 O_DIRECT는 Data에 대해서만 메모리를 거치지 않고 direct로 I/O를 수행하게 된다.
O_DIRECT_NO_FSYNC는 O_DIRECT와 비슷하지만 OS 내부적으로 fsync() 시스템 콜을 발행하지 않고 연기하는 메커니즘을 가지고 있다.
ALL_O_DIRECT는 data/log에 상관없이 항상 메모리를 거치지 않고 disk로 바로 I/O하도록 한다.

innodb_read_ahead_threshold=0~64 (기본 값: 56)
mariaDB는 오라클과 비슷하게 테이블 Full 스캔시 MBRC(Multi block Read Count)로 정의된, 여러 블록을 한꺼번에 읽는 방식이 존재한다. 그러나 오라클에서는 세션이 쿼리문을 보고 disk에서 멀티 블록을 읽어들인 후 가공하여 클라이언트에 반환하기 때문에 sync방식으로 처리된다. 하지만 mariaDB에서는 sync 방식으로 처리되지 않고 백그라운드에 의해 미리미리 멀티 블록을 읽어 적재하는 방식을 사용하고 있다. 이 때 최소 몇 개의 블록을 읽어 적재할 것인지를 설정하는 파라미터가 이것이다. 단위는 페이지의 개수이다.

 


 

Buffer Pool – Flush

update/Delete/Insert 등의 DML 작업으로 인해 값이 변경되었지만 아직 Disk로 write 되지 않은 블록이 버퍼 풀 내에 존재할 수 있다. 오라클의 경우 기본적으로 fast commit 매커니즘이라하여 사용자가 commit을 하면 redo file에만 기록을 하고 즉시 디스크로 sync하지 않는다. 대신 redo group change가 발생하면 체크 포인트가 발행되어 디스크로 일괄 write하는 매커니즘을 가지고 있다. 그러나 MariaDB는 오라클과 같이 redo file change로 인한 체크포인트가 발행되지 않는다. MariaDB는 여러 개의 redo file을 논리적으로 하나의 파일로 관리하며 redo group이 변경되었다고 체크포인트를 발행하지도 않는다. 그러나 지속적인 로그를 쌓기 위해선 redo file 도 정리하고 그 전에 버퍼 내용도 디스크로 flush하는 작업이 필요할텐데 언제 어떻게 할까?

어떻게 하긴.. 오라클처럼 명시적인 체크포인트가 따로 없으므로 평상시 지속적으로 버퍼를 flush하고 redo file을 정리해주어야 겠다. 이를 위해 몇 가지 파라미터를 제공한다. 버전 5.5 이전에서는 버퍼 풀을 보고 free공간이 없으면 LRU알고리즘을 통해 flush 하는 것을 사용자 스레드가 담당했었다. 그러나 5.6 버전부터는 백그라운드 스레드에 의해 flush하고 있다.

innodb_max_dirty_pages_pct=0~99.999 (기본 값: 75)
버퍼 풀에서 더티 페이지를 몇 프로까지 허용할 수 있을지 결정한다. 이 비율을 넘어가면 innodb_io_capacity 파라미터로 정한 값 만큼 한번에 페이지를 flush시킨다.
이 값을 낮추면 좀 더 자주 더티 페이지를 flush해주겠지만 버퍼 풀의 효율성이 떨어지게 되어 Disk I/O가 높아줄 수도 있다. 반면 너무 높으면 redo file에 더티 페이지가 꽉 차게 되고 더 이상 로그를 기록할 수 없는 지경에 이르게 될 수 있다. (mariaDB내에서는 redo file에 dirty 페이지가 얼마나 쌓였는지를 기록하고 있으며 그 비율에 따라 DB를 비상운용하게 된다)

innodb_io_capacity=100 ~ 2^64-1 (기본 값: 200)
innodb_max_dirty_pages_pct 파라미터로 명시한 값 만큼 버퍼 풀 내 dirty 페이지가 늘어나면 이 파라미터 값 만큼 한번에 페이지를 flush 시킨다. 보통 이 값은 서브디스크의 IOPS만큼 설정해주면 좋다. 예를 들어 IOPS가 200인 디스크가 Raid 1+0으로 4개로 묶여있다면 IOPS성능이 400이기 때문에 이 파라미터의 값도 400정도로 하면 좋다.

innodb_io_capacity_max=100 ~ 2^64-1 (기본 값: 2000)
innodb_io_capacity 파라미터에 설정된 만큼 페이지들을 flush 하는데도 dirty 페이지가 많이 생기면 이 파라미터에 명시된 값 만큼 페이지들을 공격적으로 flush한다. 너무 큰 값을 설정하면 I/O에 모든 자원을 소모시켜 문제가 될 수 있으니 적당히 높은 값으로 설정하도록 한다.

innodb_old_blocks_pct=5 or 95 (기본 값: 37)
버퍼 캐시에 존재하는 페이지의 LRU 리스트를 작성할 때 MRU(Most Recently Used) 부분과 LRU(Least recently used) 부분으로 나뉘는데 이 중 LRU의 비중을 몇 퍼센트로 할지를 정하는 파라미터이다. 기본 값인 37을 예로 들어보자. 이것은 버퍼 캐시에 존재하는 모든 페이지를 최근 사용한 순서로 나열했을 때 하위 37%에 해당하는 페이지들이 LRU 대상이라는 뜻이다.


 

리두로그

MariaDB에서는 오라클에서의 리두로그와 같은 역할을 하는 로그를 WAL(Write ahead log)라고 부르며 사이즈와 파일의 개수 및 위치를 모두 파라미터로 정의한다.

innodb_log_file_size = 108576(106KB) ~ 4294967295(4096MB)  (기본 값: 50331648)
로그 파일의 사이즈를 결정하는 파라미터이며 기본 값은 48M이며 최대 4G까지 지정할 수 있다.

innodb_log_file_in_group = 2~100 (기본 값: 2)
로그 파일의 개수를 몇 개로 할 것인지를 결정하는 파라미터로 기본 값은 2이다. 파일명은 ib_logfileN (N은 숫자)로 지정된다.

innodb_log_group_home_dir = 경로 (기본 값: ./)
로그 파일이 위치할 경로를 결정하는 파라미터이며 디폴트 값은 ${HOME}/data 디렉토리이다.

innodb_log_archive=ON or OFF (기본 값: OFF)
기본적으로 아카이빙은 OFF되어 있다. ON하면 innodb_log_arch_dir 디렉토리에 저장하게 된다.

innodb_log_arch_dir= 경로 (기본 값: ./)
아카이브 파일의 저장 위치에 대한 파라미터이며 값을 설정하지 않으면 ${HOME} 디렉토리에 생성된다.

innodb_log_arch_expire_sec=  (기본 값: 0)
아카이브 파일이 자동적으로 삭제되도록 타이머를 설정할 수 있다. 초 단위로 입력하면 되며 기본 값은 0으로 자동 삭제 기능을 이용하지 않게 된다.


기타

innodb_print_all_deadlocks=0 or 1 (기본 값: 0)
MariaDB에서 데드락에 대한 정보는 SHOW ENGINES INNODB STATUS 명령으로 확인할 수 있는데 이것은 마지막 데드락에 대한 정보만 보관하기 때문에 이전에 발생했던 데드락 정보는 확인할 수 없다. 이 파라미터를 1로 하면 모든 데드락 내용을 에러 로그파일에 기록한다.

 

 

커넥션

thread_handling=’one-thread-per-connection’ or ‘no-threads’ or ‘pool-of-threads’ (기본 값: one-thread-per-connection)
mariaDB에서는 쓰레드 풀을 사용할 수 있다. 이 파라미터의 값을 pool-of-threads로 하면 쓰레드 풀 기능을 사용하며 기본 값으로 두면 커넥션 당 하나씩 쓰레드를 제공하게 된다.

thread_pool_min_threads=1~ (기본 값: 1)
쓰레드 풀에 존재할 최소한의 쓰레드. 윈도우 전용의 파라미터이다.
thread_handling 파라미터가 pool-of-threads로 설정되었을 때 작동한다.

thread_pool_max_threads=1~65536 (기본 값: 1000)
쓰레드 풀이 이 파라미터의 값에 도달하면 더 이상 접속을 할 수 없게 된다. 이런 비상상황에서 관리자가 접근할 수 있도록 별도의 port를 만들 수 있으며 port 번호는 extra_port 파라미터로 지정한다.
thread_handling 파라미터가 pool-of-threads로 설정되었을 때 작동한다.

thread_pool_size=1~64 (기본 값: 장착된 core의 개수)
얼마나 많은 작업을 동시에 처리할 수 있는지에 대한 파라미터이다. 보통 Core 당 하나씩의 쓰레드가 돌아갈 때 최적의 성능을 낼 수 있으므로 장착된 Core 개수대로 설정한다.
thread_handling 파라미터가 pool-of-threads로 설정되었을 때 작동한다.

thread_pool_stall_limit=4~600 (기본 값: 500)
스레드 풀에 스레드가 하나도 남지 않았을 때 얼마나 더 기다렸다가 새로운 스레드를 생성할지를 결정하는 변수로 밀리 세컨드 단위로 값을 지정한다. 이 값이 너무 작으면 스레드 풀 자체의 효과가 줄어들고, 너무 크면 사용자가 커넥션을 맺기 위해 대기해야 하는 시간이 늘어나게 된다.
thread_handling 파라미터가 pool-of-threads로 설정되었을 때 작동한다.

thread_pool_idle_timeout= (기본 값: 60)
thread_pool_stall_limit 파라미터와는 반대로 유휴 쓰레드가 있을 경우 얼마나 대기했다가 없앨 것인지를 결정하는 파라미터이다. 단위는 초 이며 윈도우에는 없는 UNIX계열 전용의 파라미터이다.
thread_handling 파라미터가 pool-of-threads로 설정되었을 때 작동한다.

extra_port= (기본 값: 0)
쓰레드가 꽉 차서 추가로 커넥션을 만들 수 없을 경우를 대비하여, 관리자용 접속포트를 별도로 둘 수 있는 파라미터이다. 0이면 별도 포트를 두지 않는 것이며, 입력한 값에 대해 포트가 생성된다.

extra_max_connections= 1~100000(기본 값: 1)
extra_port 에 대해 설정된 포트에 최대 몇 개의 커넥션을 허용할 것인지를 결정하는 파라미터이다. 관리자용 포트는 기본적으로 커넥션마다 쓰레드가 생성되는 방식으로, 이 파라미터에 의해 결정된 값 만큼 쓰레드가 생성된다.