2010년 12월 26일 일요일

MySQL(InnoDB) Clean shutdown



MySQL InnoDB MyISAM과는 달리 트랜잭션을 지원하는 스토리지 엔진이며,
또한, 내부적으로 여러 종류의 버퍼와 캐시들을 가지고 있어서 어떤 비 정상적인 상황에서도 트랜잭션이 보존될 수 있도록 "Redo log"라고 하는 트랜잭션 로그를 가지고 있으며, 이 트랜잭션 로그를 이용해서, 데이터 변경이 발생해도 즉시 그 변경 내용을 데이터 파일에 기록하지 않아도 ACID를 보장할 수 있게 된다.

일반적인 MySQL의 종료 또는 비 정상적인 종료가 발생하게 되면, 데이터 파일로 기록되지 못한 모든 작업 내용은 InnoDB의 시스템 테이블스페이스와 트랜잭션 로그 파일에 남아 있게 된다. MySQL이 다시 기동되면서 InnoDB 스토리지 엔진은 트랜잭션 로그와 데이터 파일의 동기화 여부 (체크포인트 지점)를 확인해서 재 시작 전에 마무리되지 못한 작업들을 Foreground 또는 Background로 진행하게 된다. 일부 작업은 Foreground로 진행되며, 이 작업 도중에서 InnoDB가 사용 불가능한 상태가 되며, 나머지 작업들은 Background로 진행되는데, 이 과정은 언제 완료될지 아무도 모르고 이 작업이 진행되는 중에서 사용자가 접속해서 쿼리를 실행할 수 있다.

그런데, MySQL 서버를 종료하면서 이러한 마무리되지 않은 모든 작업들을 완료시키고 종료하도록 변경할 수 있다. 이러한 종료 방식을 여기서는 "Clean shutdown" 이라고 표현하겠다. Clean shutdown으로 MySQL을 종료하면 MySQL이 다시 시작되었을 때, 위에서 이야기했던 대 부분의 작업들이 간단한 확인만 거치고 완료된다.

가끔 시스템의 벤치마킹이나 데이터베이스 이관 시에 이러한 Clean shutdown이 필요한 경우가 있는데, 각각의 케이스는 기회가 되면 그때 글을 쓰기로 하고, 여기에서는 MySQL Clean shutdown 방법을 알아보도록 하겠다. (생각보다 간단하다)

우선 MySQL에 로그인하여 "innodb_fast_shutdown" 글로벌 변수 값을 설정해 준다.
평상시 이 값은 "1"로 설정되어 있으며, 이는 빠른 종료 (데이터 파일 동기화 안함)를 위한 옵션값이며,
이 값을 "0"으로 변경하면 Clean shutdown (모든 로그와 버퍼를 데이터 파일로 동기화시킴)을 하도록 지시한다.

mysql> set global innodb_fast_shutdown=0;

설정 변수값 변경이 완료되면 MySQL 빠져나와서 mysqladmin 명령(mysqladmin –uroot –p shutdown) 또는 MySQL bootup script 이용(/etc/init.d/mysql stop)하여 MySQL 종료한다.
(kill -9 ${mysqld-process-id} 방식은 안됨)

이렇게 MySQL을 종료하면, InnoDB 엔진은 데이터 파일에 동기화되지 못한 트랜잭션 로그와 데이터 파일에 Merge되지 못한 Insert buffer등을 모두 데이터 파일로 동기화시킨 후 종료하게 된다.

댓글 없음:

댓글 쓰기