DBMS 2

DA, SQL, DB보안 등 실무자를 위한 위한 DB기술 바이블!

백업 및 복구

DBMS 2
MySQL 가이드
데이터 베이스 관리
백업 및 복구
작성자
admin
작성일
2021-02-19 10:52
조회
1968

백업 및 복구

데이터 베이스 백업
백업 및 복구 전략 예제
시점(Point-in-Time) 복구
테이블 관리와 크래시(Crash) 복구

이 섹션에서는 데이터 베이스 백업 (전체 그리고 증분 (incremental))을 만드는 방법과 테이블 관리를 하는 방법에 대해 설명을 하기로 한다. 여기에서 설명하는 SQL 명령문 신텍스는 Chapter 13, SQL 명령문 신텍스 에서 설명 하기로 한다. 여기에서 주로 MyISAM에 관련되어 설명을 한다. nnoDB 백업 과정은 Section 14.2.8, “InnoDB 데이터 베이스 백업 및 복구”에서 하기로 한다.


데이터 베이스 백업

MySQL 테이블은 파일 형태로 저장되기 때문에, 백업을 하기가 쉽다. 일관된 백업을 하기 위해서는, 연관된 테이블에 LOCK TABLES을 한 다음에 FLUSH TABLES을 한다. Section 13.4.5, “LOCK TABLES 및 UNLOCK TABLES 신텍스”, 그리고 Section 13.5.5.2, “FLUSH 신텍스”를 참조할 것. 여러분은 읽기 잠금만 하면 된다; 이렇게 하면 여러분이 데이터 베이스 디렉토리에 파일 복사를 하는 동안에도 다른 클라이언트가 테이블에 쿼리를 계속 할 수 있도록 해 준다. 여러분이 백업을 시작하기 전에 모든 액티브 인덱스 페이지를 디스크에 쓰기 위해서는 FLUSH TABLES 명령문이 필요하다.

테이블에 대해서 SQL-레벨 백업을 만들기 위해서는, SELECT INTO ... OUTFILE을 사용한다.

데이터 베이스 백업에 대한 또 다른 방법은 mysqldump 프로그램 또는 mysqlhotcopy script 스크립트를 사용하는 것이다. Section 8.10, “mysqldump - 데이터 베이스 백업 프로그램”, 및 Section 8.11, “mysqlhotcopy - 데이터 베이스 백업 프로그램”을 참조할 것.


  1. 데이터 베이스 전체 백업을 만든다.
    shell> mysqldump --tab=/path/to/some/dir --opt db_name
    또는:
    shell> mysqlhotcopy db_name /path/to/some/dir
    서버가 아무것도 업데이트를 하지 않는다면, 간단하게 전체 테이블 파일 (*.frm, *.MYD, 및 *.MYI 파일)을 복사해서 바이너리 백업을 만들 수도 있다. mysqlhotcopy 스크립트는 이 방법을 사용한다. (하지만, 데이터 베이스가 InnoDB 테이블을 가지고 있다면, 이 방법을 사용할 수가 없다. InnoDB는 데이터 디렉토리에 테이블 내용을 저장하지 않으며, 또한 mysqlhotcopy은 MyISAM 테이블에 대해서만 동작을 한다.)
  2. mysqld가 구동 중이라면 종료를 시킨 후에, --log-bin[=file_name] 옵션을 사용해서 다시 구동 시킨다. Section 5.12.3, “바이너리 로그” 참조. 바이너리 로그 파일은 여러분이 mysqldump를 실행 시킨 시점에 만들어진 변경 사항을 데이터베이스에 복제하기 위해 필요한 정보를 제공해 준다.

InnoDB 테이블의 경우에는 테이블 잠금을 하지 않고서도 온라인 백업을 실행할 수가 있다; Section 8.10, “mysqldump - 데이터 베이스 백업 프로그램”을 참조할 것.

MySQL은 증분 (incremental) 백업을 지원한다: 이것을 사용하기 위해서는 --log-bin 옵션으로 서버를 구동 시켜서 바이너리 로깅을 활성화 시킬 필요가 있다; Section 5.12.3, “바이너리 로그”를 참조. 증분 백업을 하고자 원할 경우에는 (마지막 전체 또는 증분 백업을 한 이후에 변경된 모든 것을 포함), FLUSH LOGS를 사용해서 바이너리 로그를 바꿔야 (rotate) 한다. 이것을 실행하고 나면, 모든 바이너리 로그를 백업 위치에 복사할 필요가 있게 된다. 이러한 바이너리 로그들은 증분 백업본이다; 복원 (restore) 시점이 되면, 여러분은 이후의 섹션에서 설명하는 방법으로 이것들을 사용한다. 그 다음으로 전체 백업을 하고자 한다면, 역시 FLUSH LOGS, mysqldump --flush-logs, 또는 mysqlhotcopy --flushlog를 사용해서 바이너리 로그를 바꿔야 한다. Section 8.10, “mysqldump - 데이터 베이스 백업 프로그램”, 및 Section 8.11, “mysqlhotcopy - 데이터 베이스 백업 프로그램”을 참조.

여러분이 사용하는 서버가 슬레이브 리플리케이션 서버라면, 여러분이 선택한 백업 방법에 관계없이, 슬레이브의 데이터를 백업할 때에는 반드시 master.info 와 relay-log.info 파일도 함께 백업해야 한다. 이 파일들은 슬레이브 데이터를 복원한 후에 리플리케이션을 다시 시작하기 위해 항상 필요한 것들이다. 만약에 슬레이브가 LOAD DATA INFILE 명령어를 리플리케이트 해야 한다면, 여러분은 --slave-load-tmpdir 옵션이 지정하는 디렉토리에 있는 모든 SQL_LOAD-* 파일들도 함께 백업해야 한다. (이 위치가 지정이 되지 않으면, tmpdir 변수 값이 디폴트로 사용된다.) 슬레이브는 인터럽트된 LOAD DATA INFILE 연산의 리플리케이션을 재 구동 시키기 위해 이 파일들이 필요하게 된다.

만약에 MyISAM 테이블을 복원 해야 한다면, 우선 REPAIR TABLE 또는 myisamchk -r를 사용해서 테이블을 복구하도록 한다. 이렇게 하면 99.9%가 복구 된다. 만약에 myisamchk가 실패한다면, 아래의 프로시저를 시도해 본다. --log-bin 옵션을 사용해서 MySQL을 구동 시켜서 바이너리 로깅을 활성화 시켰을 경우에만 이것이 동작한다는 것을 명심하기 바란다.


  1. 테이블을 덤프하기 위해서는, SELECT * INTO OUTFILE 'file_name' FROM tbl_name를 사용한다.
  2. 테이블을 재 로드하기 위해서는, LOAD DATA INFILE 'file_name' REPLACE .... 를 사용한다. 열 중복을 피하기 위해서는, 테이블은 반드시 PRIMARY KEY 또는 UNIQUE 인덱스를 가지고 있어야 한다. REPLACE 키워드는 고유 키 값에 이전 열을 새로운 열로 중복시킬 때 이전 열이 새로운 열로 대체되도록 만든다.

백업을 진행하는 중에 시스템의 성능에 문제가 발생한다면, 리플리케이션을 설정을 한 다음에 서버가 아닌 슬레이브에서 백업을 실행 하는 것이 도움이 될 것이다. Section 6.1, “리플리케이션 소개”를 참조.

여러분이 Veritas 파일 시스템을 사용한다면, 아래와 같이 백업을 만들 수가 있다:


  1. 클라이언트 프로그램에서, FLUSH TABLES WITH READ LOCK를 실행한다.
  2. 다른 쉘에서, mount vxfs snapshot를 실행한다.
  3. 첫 번째 클라이언트에서, UNLOCK TABLES를 실행한다.
  4. 스냅샷에서 파일을 복사한다.
  5. 스냅샷 마운트를 해제한다.
백업 및 복구 전략 예제
백업 정책
복구를 위한 백업 사용
백업 전략 정리

이 섹션은 데이터 크래시가 여러 가지 형태로 발생한 후에 데이터를 복구할 수 있는 백업 실행 과정을?

?
  • 파워(Power) 문제
  • 파일 시스템 크래시
  • 하드웨어 문제 (하드 드라이브, 마더 보드, 및 기타 등등)
?

예제에 나와 있는 명령어들은 mysqldump 와 mysql 프로그램에 대한 --user 및 --password 와 같은 옵션을 포함하고 있지 않다. 여러분이 MySQL 서버에 접속을 하기 위해서는 필요한 옵션들을 함께 넣어야 한다.

우리는 데이터가 InnoDB 스토리지 엔진에 저장되어 있다고 가정하는데, 이 엔진은 트랜젝션과 자동 크래시 복구를 지원한다. 우리는 또한 크래시가 되는 시점에 MySQL 서버가 로드중에 있다는 가정을 한다. 그런 상황이 아니라면, 아무런 복구도 필요 없게 된다.

OS 크래시 또는 시스템 파워에 문제가 발생하는 경우에는, 서버를 재 구동 시키면 MySQL 데이터는 사용할 수 있다고 가정할 수 있다. InnoDB 데이터 파일은 크래시로 인해 일관된 데이터를 가지고 있지 않을 수도 있으나, InnoDB는 자신의 로그를 읽고, 그 로그에서 데이터 파일에 플러시 되지 않은 실행된 (committed) 트랜젝션과 실행되지 않고 (non-committed) 지연 된 트랜젝션 리스트를 찾게 된다. InnoDB 는 자동으로 실행되지 않은 트랜젝션으로 롤백이 되고, 이미 실행된 트랜젝션을 자신의 데이터 파일에 플러시 한다. 이러한 복구 과정에 대한 정보는 MySQL 에러 로그를 통해 사용자에게 전달 된다. 아래의 것은 예제 로그에서 발췌한 것이다:



InnoDB: Database was not shut down normally.
InnoDB: Starting recovery from log files...
InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 0 13674004
InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
...
InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
InnoDB: 1 uncommitted transaction(s) which must be rolled back
InnoDB: Starting rollback of uncommitted transactions
InnoDB: Rolling back trx no 16745
InnoDB: Rolling back of trx no 16745 completed
InnoDB: Rollback of uncommitted transactions completed
InnoDB: Starting an apply batch of log records to the database...
InnoDB: Apply batch completed
InnoDB: Started
mysqld: ready for connections


파일 시스템 크래시 또는 하드웨어에 문제가 있는 경우에는, 서버를 재 구동 시켜도 MySQL데이터는 사용할 수 없을 것이라고 생각한다. 이와 같은 경우에는, 디스크를 재 포맷시키거나, 다른 디스크를 설치하거나, 또는 다른 조치를 취할 필요가 있게 된다. 그런 다음에 백업 파일에서 복구를 해야 한다. 이러한 경우를 대비하기 위해, 우리는 백업 정책을 만들어 두어야 한다.


백업 정책

백업은 주기적으로 실행해야 한다. 전체 백업 (특정 시점 데이터 스냅 샷)은 여러 가지 툴을 사용해서 할 수가 있다. 예를 들면, InnoDB Hot Backup 툴은 InnoDB 데이터 파일을 온라인에서 논-블록킹 (non-blocking) 백업 (믈리적으로) 할 수 있으며, mysqldump는 온라인 논리 백업을 할 수 있는 툴이다. 여기에서는 mysqldump를 설명하기로 한다.

일요일 오후 1시에 백업을 한다고 가정을 하자. 아래에 있는 명령어는 모든 데이터베이스에 있는 전체 InnoDB 테이블에 대해서 전체 백업을 실행한다:



shell> mysqldump --single-transaction --all-databases > backup_sunday_1_PM.sql 

이것은 테이블에서 읽기 및 쓰기가 방해 받지 않고서 온라인, 논-블록킹 백업을 실행한다. 우리는 위에서 테이블은 InnoDB 테이블이라고 가정을 했기 때문에, --single-transaction은 일관성 있는 읽기 연산을 사용하고 mysqldump가 처리하는 데이터는 변경되는 것이 없다고 생각할 수 있다.

mysqldump가 만든 결과 파일 .sql에는 덤프한 파일을 나중에 다시 읽어 오기 위한 SQL INSERT 명령문이 들어 있다.

전체 백업이 필요하기는 하지만, 항상 편리한 것은 아니다. 일단 전체 백업을 만들었다면, 다음에는 증분 (incremental) 백업을 하는 것이 더욱 효과적이다.

증분 백업을 하기 위해서는, 증분 변경을 저장해야 한다. MySQL 서버를 항상 --log-bin 옵션으로 시작해서 데이터를 업데이트할 때마다 변경된 사항을 저장하게끔 만든다. 이 옵션은 바이너리 로깅을 활성화 시키기 때문에, 서버는 데이터를 업데이트 시키는 각각의 SQL 명령문을 MySQL 바이너리 로그 파일에 기록하게 된다. Looking at the data directory of a MySQL server that was started with the --log-bin 옵션으로 시작된 MySQL 서버와 몇 일 동안 구동을 했던 MySQL 서버의 디렉토리를 살펴 보면, MySQL 바이너리 로그 파일을 찾을 수 있을 것이다:



rw-rw---- 1 guilhem  guilhem 1277324 Nov 10 23:59 gbichot2-bin.000001 

-rw-rw---- 1 guilhem guilhem 4 Nov 10 23:59 gbichot2-bin.000002

-rw-rw---- 1 guilhem guilhem 79 Nov 11 11:06 gbichot2-bin.000003

-rw-rw---- 1 guilhem guilhem 508 Nov 11 11:08 gbichot2-bin.000004

-rw-rw---- 1 guilhem guilhem 2247446 Nov 12 16:47 gbichot2-bin.000005

-rw-rw---- 1 guilhem guilhem 998412 Nov 14 10:08 gbichot2-bin.000006

-rw-rw---- 1 guilhem guilhem 361 Nov 14 10:07 gbichot2-bin.index


서버는 재 시작을 할 때마다, 순차적인 번호를 사용해서 새로운 바이너리 로그 파일을 생성한다. 서버가 구동 중일 때일 경우라도, FLUSH LOGS SQL 명령문을 실행하거나 또는 mysqladmin flush-logs 명령어를 사용해서 현재 사용 중인 바이너리 로그 파일을 닫고 새로운 바이너리 로그 파일을 만들도록 할 수도 있다. mysqldump에는 로그를 플러시 (flush)하는 옵션이 있다. 데이터 디렉토리 안에 있는 .index 파일에는 모든 MySQL 바이너리 로그가 들어 있다. 이 파일은 리플리케이션용으로 사용된다.

MySQL 바이너리 로그가 증분 백업을 수행하기 때문에 복구용으로 매우 중요한 것이 된다. 여러분이 전체 백업을 만들 때 로그를 확실하게 플러시 하였다면, 나중에 생성되는 바이너리 로그 파일은 백업 이후에 변경된 모든 데이터를 가지게 된다. 위에서 사용했던 mysqldump 명령어를 약간 수정해서 전체 백업을 하는 시점에 바이너리 로그를 플러시하고, 덤프 파일이 새로운 현재 바이너리 로그 이름을 가지도록 만들어 보자:



shell> mysqldump --single-transaction --flush-logs --master-data=2 \ 

--all-databases > backup_sunday_1_PM.sql


이 명령어를 실행하고 나면, 데이터 디렉토리는 새로운 바이너리 로그 파일 gbichot2-bin.000007를 가지게 된다. 결과 파일 .sql에는 다음과 같은 라인이 추가된다:



-- Position to start replication or point-in-time recovery from 

-- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',

MASTER_LOG_POS=4;


mysqldump 명령어가 전체 백업을 수행했기 때문에, 위의 라인들은 다음과 같은 의미를 가지게 된다:


  • .sql 파일에는 gbichot2-bin.000007 바이너리 로그 파일 또는 그 이후 파일에 기록된 변경 사항 이전에 만들어진 모든 변경 사항이 들어 있다.
  • 백업이 gbichot2-bin.000007 바이너리 로그 파일 또는 그 이후 파일에는 존재하지만, .sql 파일에는 아직 존재하지 않을 때 모든 데이터 변경 사항이 로그된다.

월요일 오후 1시에, 새로운 바이너리 로그 파일을 시작하기 위해 로그를 플러시해서 증분 백업을 만들 수가 있다. 예를 들면, mysqladmin flush-logs 명령어를 실행하면 gbichot2-bin.000008를 만들 수가 있다.

일요일 오후 1시에 행한 전체 백업과 월요일 오후 1시 사이의 변경 내용은 gbichot2-bin.000007 파일에 저장되어 있을 것이다. 이 증분 백업 파일은 매우 증요하기 때문에 안전한 곳에 보관해 두도록 한다.

화요일 오후 1시에 또 다른 mysqladmin flush-logs 명령어를 실행한다. 월요일 오후 1시와 화요일 오후 1시 사이에 발생한 모든 변경 사항은 gbichot2-bin.000008 파일에 있을 것이다.

MySQL 바이너리 로그는 디스크 공간을 많이 차지한다. 더 이상 필요없는 바이너리 로그를 디스크에서 삭제하기 위해서는, 전체 백업을 진행할 때 다음과 같이 실행을 한다:



shell> mysqldump --single-transaction --flush-logs --master-data=2 \ 

--all-databases --delete-master-logs > backup_sunday_1_PM.sql


복구용으로 백업 사용하기

자 이제, 수요일 오전 8시에 예기치 못한 데이터 크래시가 발생하였다고 가정을 하자. 데이터 복구를 하기 위해서는, 우선 마지막으로 실행했던 전체 백업을 복구 시켜야 한다 (일요일 오후 1시 버전). 전체 백업 파일은 SQL 명령문 셋이기 때문에, 복구는 간단히 진행된다:



shell> mysql < backup_sunday_1_PM.sql 

이것을 실행하면, 데이터는 일요일 오후 1시 시점 상태로 복구된다. 그 시점 이후에 변경된 내용을 복구하기 위해서는, 증분 백업 파일을 사용해야 한다; 즉, gbichot2-bin.000007 및 gbichot2-bin.000008 바이너리 로그 파일. 다음과 같이 진행한다:



shell> mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql 

이제, 화요일 오후 1시 시점까지 데이터를 복구하였다. 하지만, 여전히 크래시가 발생한 시점까지의 데이터는 복구하지 못하였다. 이것을 복구하기 위해서는, MySQL 서버가 바이너리 로그를 자신의 데이터 파일 저장 위치가 아닌 별도의 안전 공간 (RAID 디스크와 같은)에 저장하도록 만들어야 한다. 이렇게 하였다면, gbichot2-bin.000009 파일이 그곳에 생성되어 있을 것이며, mysqlbinlog 및 mysql을 사용해서 그 파일을 복구시키면 모든 문제를 해결할 수 있게 된다.


백업 전략 정리

OS 크래시 및 파워 시스템 문제로 인한 문제가 발생할 경우에는, InnoDB 자체가 모든 데이터 복구를 진행한다. 하지만, 다음과 같은 가이드 라인을 준수하기 바란다:


  • 서버는 항상 --log-bin 옵션과 함께 구동한다. 데이터 디렉토리 저장 위치와는 다른 디스크에 로그 파일 이름을 저장하는 경우에는 --log-bin=log_name를 사용하도록 한다.
  • mysqldump 명령어를 사용해서 주기적으로 전체 백업을 받도록 한다.
  • FLUSH LOGS 또는 mysqladmin flush-logs를 사용해서 로그를 플러시 함으로써 주기적으로 증분 백업을 받도록 한다.
시점(Point-in-Time) 복구
복구 시간 지정하기
복구 위치 지정하기

MySQL 서버가 바이너리 로그를 활성화 시키기 위해 --log-bin 옵션을 가지고 시작되었다면, 여러분은 mysqlbinlog 유틸리티를 사용하여 지정된 시점에서부터 바이너리 로그 파일에서 데이터를 복구할 수가 있다. 바이너리 로그 활성화와 mysqlbinlog 사용에 대한 정보는 Section 5.12.3, “바이너리 로그” 와 Section 8.8, “mysqlbinlog - 바이너리 로그 파일 처리를 위한 유틸리티”를 참조할 것.

바이너리 로그에서 데이터를 복구하기 위해서는, 현재 바이너리 로그의 정확한 이름과 저장 위치를 알고 있어야 한다. 디폴트로, 서버는 바이너리 로그를 데이터 디렉토리에 생성하지만, 다른 위치에 파일을 저장하기 위해서는 --log-bin 옵션을 사용해서 경로 이름을 지정해야 한다. 전형적으로 옵션은 옵션 파일에서 주게 된다 (즉, my.cnf 또는 my.ini). 옵션은 서버가 시작될 때 명령어 라인에서 줄 수도 있다. 현재 디렉토리 이름을 알아 보기 위해서는, 아래의 명령어를 사용한다:



mysql> SHOW BINLOG EVENTS\G

아래의 명령어를 명령어 라인에 대신 입력할 수도 있다:



shell> mysql -u root -p -E -e "SHOW BINLOG EVENTS"

mysql 프롬프트가 나오면 root 패스워드를 입력한다.


복구 시간 지정하기

복구 시작 시점과 종료 시점을 지정하기 위해서는, DATETIME 포맷에서 mysqlbinlog에 대한--start-date 와 --stop-date 옵션을 지정한다. 예를 들면, 정확히 2005년 4월 20일 오전 10시 정각에 테이블을 삭제하는 SQL 명령문을 실행했다고 가정하자. 이 테이블과 데이터를 복구하기 위해서는, 전날 밤에 백업해 놓은 파일을 복원한 다음에, 아래의 명령어를 실행한다:



shell> mysqlbinlog --stop-date="2005-04-20 9:59:59" \
/var/log/mysql/bin.123456 | mysql -u root -p


이 명령어는 --stop-date 옵션이 지정하는 날짜와 시간 이전의 모든 데이터를 복구한다. 만약에 여러분이 10시 이후에 잘못 입력한 SQL 명령문을 검사하지 않았다면, 아마도 그 후에 발생한 서버의 동작도 함께 복구하고 싶을 것이다. 이러한 가정하에, 아래와 같이 시작 날짜와 시간을 다시 입력하여 mysqlbinlog을 재 구동 시킬 수가 있다:



shell> mysqlbinlog --start-date="2005-04-20 10:01:00" \
/var/log/mysql/bin.123456 | mysql -u root -p


이 명령어에서 보면, 10시 1초에 로그된 SQL 명령문이 재 동작할 것이다. 전날 밤에 덤프한 파일과 두 개의 mysqlbinlog 명령어를 조합하면 10시 1초 전까지의 모든 것과 10시 1초 후의 모든 것을 복구하게 된다. 명령어에 지정할 시간을 정확히 하기 위해서는 로그를 조사해야 한다. 로그 파일을 실행하지 않고 내용물을 보기 위해서는, 아래의 명령어를 실행한다:



shell> mysqlbinlog /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql

그런 다음에 텍스트 편집기를 사용해서 파일을 검사한다.


복구 위치 지정하기

날짜와 시간을 지정하는 대신에, mysqlbinlog에 대한 --start-position 과 --stop-position 옵션을 사용하여 로그 위치를 지정할 수가 있다. 이것들은 시작 날짜와 종료 날짜 지정 옵션과 동일한 동작을 하는데, 이때 날짜 대신에 로그 위치 번호를 지정 해주어야 한다. 로그 위치를 사용하는 것은 복구할 로그 부분을 보다 정확하게 지정할 수 있게끔 해 주는 것인데, 특히 옳지 못한 SQL 명령문으로 인해 동시에 많은 트랜젝션이 발생하는 경우에 유용하게 사용된다. 로그 위치 번호를 알아내기 위해서는, 원하지 않은 트랜젝션이 발생했던 시간 전후로 mysqlbinlog을 구동 시킨다. 결과는 텍스트 파일 형태로 나온다. 아래와 같이 실행할 수가 있다:



shell> mysqlbinlog --start-date="2005-04-20 9:55:00" \
--stop-date="2005-04-20 10:05:00" \
/var/log/mysql/bin.123456 > /tmp/mysql_restore.sql


이 명령어는 /tmp 디렉토리 안에 작은 텍스트 파일을 하나 생성하는데, 이 파일은 옳지 않은 SQL 명령문이 실행 되었던 시점 주변의 SQL 명령문을 가지게 된다. 텍스트 편집기를 사용해서 이 파일을 연 다음에 반복되지 말아야 할 명령문을 찾아낸다. 바이너리 로그에서 종료를 하고 다시 구동 시킬 위치를 찾아 낸다. 로그 위치는 log_pos 다음에 숫자를 사용해서 표시 되어 있다. 이전 백업 파일을 복원한 다음에, 이 위치 번호를 사용해서 바이너리 로그 파일을 처리한다. 예를 들면, 여러분은 아래와 비슷한 명령어를 사용할 것이다: s



shell> mysqlbinlog --stop-position="368312" /var/log/mysql/bin.123456 \
| mysql -u root -p

shell> mysqlbinlog --start-position="368315" /var/log/mysql/bin.123456 \
| mysql -u root -p


첫 번째 명령어는 지정된 종료 위치 전까지 나타난 모든 트랜젝션을 복구한다. 두 번째 명령어는 지정된 시작 시점에서부터 바이너리 로그 끝까지 있는 모든 트랜젝션을 복구한다. mysqlbinlog의 결과 값에는 SQL 명령문이 기록되기 전의 SET TIMESTAMP 명령문을 포함하고 있기 때문에, 복구된 데이터와 이에 관련된 MySQL로그는 트랜젝션이 실행된 원래의 시점에 반영이 된다.


테이블 관리와 크래시(Crash) 복구
myisamchk를 사용해서 크래시 복구하기
에러에 대해 MyISAM 테이블 검사하는 방법
테이블 리페어하는 방법
테이블 최적화
테이블 정보 가져오기
테이블 관리 (Maintenance) 스케쥴 설정

이 섹션에서는 MyISAM 테이블 (이 테이블은 데이터와 인덱스를 저장하기 위한 .MYD 와 .MYI 파일을 가지고 있음)을 검사하거나 또는 리페어하기 위해 myisamchk를 사용하는 방법에 대해 설명을 한다. 일반적인 myisamchk에 대해서는 Section 8.2, “myisamchk - MyISAM 테이블-관리 유틸리티”를 참조할 것.

여러분은 myisamchk를 사용해서 데이터 베이스 테이블에 대한 정보를 얻거나, 이 테이블을 검사, 리페어, 또는 최적화 할 수가 있다. 다음에 나오는 섹션에서는 이러한 동작을 어떻게 실행 시키는지 그리고 테이블 관리 스케쥴을 어떻게 설정하는지에 대해 설명하기로 한다.

myisamchk를 사용하는 테이블 리페어 방식이 안전하기는 하지만, 테이블을 리페어하거나 또는 테이블의 내용을 많이 변경시키는 관리 동작 이전에 백업을 받아 두는 것이 현명하다.

인덱스에 영향을 주는 myisamchk 연산은 MySQL 서버가 사용하는 값들과 호환성이 없는 전체-텍스트 파라미터를 가지고 FULLTEXT 인덱스가 재 구축되도록 만든다. 이러한 문제를 피하기 위해서는, Section 8.2.1, “myisamchk 일반 옵션”에 나와 있는 가이드 라인을 따르기 바란다.

대부분의 경우, MyISAM 테이블 관리는 myisamchk 연산보다는 SQL 명령문을 사용하는 것이 보다 수월하다:


  • MyISAM 테이블을 검사 또는 리페어하기 위해서는, CHECK TABLE 또는 REPAIR TABLE를 사용한다.
  • MyISAM 테이블을 최적화 하기 위해서는, OPTIMIZE TABLE을 사용한다.
  • MyISAM 테이블을 분석하기 위해서는, ANALYZE TABLE을 사용한다.

위의 명령문들은 직접 또는 mysqlcheck 클라이언트 프로그램을 통해서 사용할 수가 있다. myisamchk에 비해 이러한 명령문들이 가지고 있는 장점 중의 하나는 서버가 모든 작업을 실행한다는 점이다. myisamchk를 사용한다면, myisamchk와 서버가 동시에 테이블을 사용해서 원하지 않는 상호 작용이 발생하지 않도록 만드는 것이 불가능하다. Section 13.5.2.1, “ANALYZE TABLE 신텍스”, Section 13.5.2.3, “CHECK TABLE 신텍스”, Section 13.5.2.5, “OPTIMIZE TABLE 신텍스”, 그리고 Section 13.5.2.6, “REPAIR TABLE 신텍스”를 참조할 것.


myisamchk를 사용해서 크래시 복구하기

이 섹션은 MySQL 데이터 베이스의 데이터 크래시를 검사하고 처리하는 방법에 대해 설명을 한다. 테이블이 자주 깨진다면, 그 이유를 분명히 알아 두어야 한다.

MyISAM 테이블이 어떻게 깨지는지를 설명하기 위해서는 Section 14.1.4, “MyISAM 테이블 문제”를 참조하기 바란다.

외부 잠금을 사용하지 않은 채로 mysqld를 구동 시킨다면 (4.0 이후에는 디폴트임), myisamchk를 사용해서 mysqld가 사용하고 있는 테이블을 안정적으로 검사할 수는 없게 된다. myisamchk를 사용하는 중에는 아무도 mysqld 를 통해서 테이블에 접근하지 않는다고 확신을 한다면, 테이블 검사를 하기 전에 mysqladmin flush-tables를 실행 시키기만 하면 된다. 이것을 확신하지 못하는 경우에는, 반드시 mysqld를 종료시킨 후에 테이블을 검사하도록 한다. 만약에 myisamchk를 구동 시켜서 mysqld가 똑 같은 시간에 업데이트를 하고 있는 테이블을 검사한다면, 테이블이 깨진다는 경고문을 받게 될 것이다.

만약에 서버를 외부 잠금 활성화 상태로 구동 시킨다면, 어느 때라도 myisamchk를 사용해서 테이블을 검사할 수가 있다. 이와 같은 경우에 myisamchk가 사용하고 있는 테이블을 서버가 업데이트 하고자 시도하면, 서버는 myisamchk가 마치기를 기다리게 된다.

만약에 myisamchk를 사용해서 테이블을 리페어 또는 최적화 시킨다면, 반드시 mysqld 서버가 그 테이블을 사용하고 있지 않음을 확인해야 한다 (이것은 외부 잠금이 비활성화된 상태에도 동일하게 적용된다). 만약에 mysqld를 종료하지 않는다면, 최소한 myisamchk를 구동하기 전에 mysqladmin flush-tables를 실행해야 한다. 만약에 서버와 myisamchk가 동시에 테이블에 접근을 한다면, 테이블은 깨지게 될 것이다.

크래시 복구를 할 때에는, 데이터 베이스에 있는 각 MyISAM 테이블 tbl_name 은 데이터 베이스 디렉토리에 있는 세 개의 파일에 대응한다는 것을 이해하는 것이 중요하다:



File Purpose
tbl_name.frm 정의문(포맷) 파일
tbl_name.MYD 데이터 파일
tbl_name.MYI 인덱스 파일

이 세 개의 파일 타입은 각각 다양한 방식의 데이터 크래시와 관련이 되지만, 대부분의 크래시는 데이터 파일과 인덱스 파일에서 발생하게 된다.

myisamchk는 .MYD 데이터 파일을 열 단위로 복사 하면서 실행을 한다. 이것은 구형 .MYD파일을 제거 하고 새로운 파일을 원래의 파일 이름으로 변경을 한 다음에 리페어 과정을 종료한다. 만약에 여러분이 -quick 옵션을 사용한다면, myisamchk는 임시 .MYD파일을 생성하지 않으며, 대신에 .MYD 파일이 정확하다고 가정으로 하고 .MYD 파일은 그대로 놓은 상태에서 새로운 인덱스 파일을 만들게 된다. 이렇게 하는 것이 보다 안전한데, 그 이유는 myisamchk는 자동적으로 .MYD파일이 깨졌는지 그리고 리페어를 해야 하는지를 검사하기 때문이다. 여러분은 --quick 옵션을 myisamchk에 두 번 사용할 수도 있다. 이렇게 하면, myisamchk는 어떤 에러 (중복-키 에러 와 같은)에서는 종료를 하지 않는 대신에 .MYD 파일을 수정해서 문제를 해결하려는 시도를 하게 된다. 일반적으로 --quick 옵션을 두 번 사용하는 것은, 일반적인 리페어를 진행하기에는 여유 공간이 너무 부족한 경우에 매우 유용하게 된다. 이와 같은 경우, 여러분은 myisamchk를 구동하기 전에 최소한 한 번은 백업을 해 두는 것이 좋다.


에러에 대해 MyISAM 테이블 검사하는 방법

MyISAM 테이블을 검사하기 위해서는, 아래의 명령어를 사용한다:


  • myisamchk tbl_name
    이것은 모든 에러의 99.99%를 찾아 낸다. 하지만 데이터 파일에만 포함되어 있는 데이터 크래시는 발견하지 못한다 (매우 드문 경우임). 테이블을 검사하고자 한다면, 옵션 없이 myisamchk를 구동 시키거나 또는 -s (silent) 옵션을 사용해서 구동 시키는 것이 일반적이다.
  • myisamchk -m tbl_name
    이것은 모든 에러의 99.999%를 찾아낸다. 우선 에러에 대한 모든 인덱스 엔트리를 검사하고, 그 다음에 모든 열을 읽는다. 열에 있는 모든 키 값의 체크 섬을 계산하고 인덱스 트리에 있는 키 값의 체크 섬과 서로 비교를 한다.
  • myisamchk -e tbl_name
    이것은 모든 데이터를 완벽하고 철저하게 검사한다 (-e는 “확장 검사 (extended check)”를 의미함). 모든 키가 올바른 열을 가리키고 있는지를 검증하기 위해 각 열에 대한 모든 키 값을 검사-읽기 (check-read) 한다. 많은 인덱스를 가지고 있는 대형 테이블의 경우에는 시간이 오래 걸리게 된다. 일반적으로, myisamchk는 첫 번째 에러가 발견되면 즉시 종료를 한다. 만약에 보다 많은 정보를 얻고자 한다면, -v (verbose) 옵션을 추가한다. 이렇게 하면 myisamchk가 20개의 에러를 발견할 때 까지 계속 진행을 하도록 만든다.
  • myisamchk -e -i tbl_name
    이것은 앞의 명령어와 비슷한 것이지만, -i 옵션은 myisamchk가 추가적인 통계 정보를 기록 하도록 만든다.

대부분의 경우, 테이블 이름을 사용하지 않고 단순히 myisamchk 명령어를 사용해서도 충분히 테이블을 검사할 수 있다.


테이블 리페어하는 방법

이 섹션에서는 MyISAM 테이블 (확장자 .MYI 와 .MYD)에서 myisamchk를 사용하는 방법을 설명하기로 한다.

CHECK TABLE 와 REPAIR TABLE 명령문을 사용해서 MyISAM 테이블을 검사하고 리페어할 수도 있다. Section 13.5.2.3, “CHECK TABLE 신텍스”, 그리고 Section 13.5.2.6, “REPAIR TABLE 신텍스”를 참조할 것.

테이블이 깨지게 되면 쿼리가 예상과 다르게 종료 하게 되며 아래와 같은 에러가 발생하기도 한다:


  • tbl_name.frm이 데이터 변경에 대해 잠기게 된다.
  • tbl_name.MYI (Errcode: nnn)를 찾을 수 없다.
  • 기대하지 않은 파일의 마지막 부분으로 이동
  • 레코드 파일이 크래시됨
  • 테이블 핸들러에서 nnn 번호의 에러를 갖게 됨

에러에 대해 보다 많은 정보를 얻기 위해서는, perror nnn를 구동 시키는데, nnn 는 에러 번호가 된다. 아래의 예제는 테이블 문제를 가리키는 가장 일반적인 에러 번호가 의미하는 것을 알아 내기 위해 perror를 어떻게 사용하는지를 보여 준다:



shell> perror 126 127 132 134 135 136 141 144 145
126 = Index file is crashed / Wrong file format
127 = Record-file is crashed
132 = Old database file
134 = Record was already deleted (or record file crashed)
135 = No more room in record file
136 = No more room in index file
141 = Duplicate unique key or constraint on write or update
144 = Table is crashed and last repair failed
145 = Table was marked as crashed and should be repaired


에러 135 (no more room in record file)과 에러 136 (no more room in index file)는 간단하게 수정할 수가 없는 것이다. 이와 같은 경우에는, ALTER TABLE을 사용해서 MAX_ROWS 와 AVG_ROW_LENGTH 테이블 옵션 값을 늘려주어야 한다:



ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;

만약에 현재의 테이블 옵션 값을 모른다면, SHOW CREATE TABLE을 실행한다.

다른 에러에 대해서는, 테이블을 리페어해야 한다. myisamchk는 테이블에서 발생된 에러들을 검사하고 리페어하는데 일반적으로 사용할 수 있는 것이다.

리페어 과정은 네 단계로 이루어진다. 우선 시작을 하기 전에, 데이터 디렉토리로 이동해서 테이블 파일을 검사할 수 있는 권한을 검사하기로 한다.

만약에 명령어 라인에서 테이블을 리페어하고자 한다면, 우선 mysqld 서버를 종료 시켜야 한다. 리모트 서버에서 mysqladmin shutdown을 실행하면, mysqld 서버는 mysqladmin이 리턴 된 후에도 모든 명령문 프로세스가 종료 하고 모든 인덱스 변경이 디스크에 플러시 될 때까지 당분간 살아 있게 된다는 점을 알기 바란다.

Stage 1: 테이블 검사

myisamchk *.MYI 또는 myisamchk -e *.MYI를 구동 시킨다. -s (silent) 옵션을 사용해서 불필요한 정보를 없애도록 한다.

mysqld 서버가 종료 되면, --update-state 옵션을 사용해서 myisamchk가 테이블을 “checked”로 표시하도록 만든다.

여러분은 myisamchk에 의해 에러가 있다고 표시된 테이블만 리페어해야 한다. 그런 테이블에 대해서만 Stage 2를 진행한다.

만약에 검사를 하는 도중에 예상하지 못한 에러가 나오게 되거나 (out of memory 에러와 같은), 또는 myisamchk가 크래시가 되면, Stage 3를 실행한다.

Stage 2: 간단하고 안전한 리페어

우선, myisamchk -r -q tbl_name (-r -q은 “quick recovery mode”를 의미함)를 시도해 본다. 이것은 데이터 파일을 손대지 않고 인덱스 파일을 리페어 한다. 만약에 데이터 파일이 모든 것을 가지고 있고 삭제 링크가 데이터 파일 안에 있는 올바른 위치를 가리키고 있다면, 제대로 동작을 하는 것이고, 테이블은 수정이 된다. 다음 테이블을 리페어하도록 한다. 그렇지 않은 경우에는, 아래의 과정을 진행한다:


  1. 계속 진행을 하기 전에 데이터 파일의 백업을 한다.
  2. myisamchk -r tbl_name (-r 은 “recovery mode”를 의미함)을 사용한다. 이것은 올바르지 못한 열을 제거하고 데이터 파일에서 열을 삭제하고 인덱스 파일을 재 구성한다.
  3. 만약에 앞의 과정이 실패를 한다면, myisamchk --safe-recover tbl_name를 사용한다. 안전 복구 모드 (Safe recovery mode)는 레귤러 복구 모드가 지원하지 않는 경우를 구형 모드를 사용해서 처리한다.

Note: 리페어를 보다 빠르게 하고자 한다면, myisamchk을 구동 시킬 때 사용 가능한 메모리의 약 25% 정도를 sort_buffer_size 와 key_buffer_size 변수에 각각 할당하면 된다

리페어를 하는 도중에 예상하지 못한 에러를 만나게 되거나 (out of memory 에러와 같은), 또는 myisamchk가 크래시 되면, Stage 3으로 간다.

Stage 3: 보다 어려운 리페어

만약에 인덱스 파일의 처음 16KB블록이 깨졌거나, 잘못된 정보를 가지고 있거나, 또는 인덱스 파일이 빠져 있는 경우에만 이 단계의 과정을 진행한다. 아래와 같이 진행한다:


  1. 데이터 파일을 안전한 곳으로 이동 시킨다.
  2. 테이블 설명 파일을 사용해서 새로운 (빈) 데이터 파일과 인덱스 파일을 만든다:
    shell> mysql db_name
    mysql> SET AUTOCOMMIT=1;
    mysql> TRUNCATE TABLE tbl_name;
    mysql> quit

  3. 이전 데이터 파일을 새로운 데이터 파일로 복사한다. (단순히 이동을 하지 말고, 복사를 하기 바란다. 다른 에러에 대비해서 복사본은 계속 보관을 해야 한다.)

Stage 2로 돌아 간다. 이제 myisamchk -r -q이 제대로 동작을 할 것이다.

여러분은 REPAIR TABLE tbl_name USE_FRM SQL 명령문을 사용할 수도 있는데, 이것은 자동으로 전체 과정을 수행한다. Section 13.5.2.6, “REPAIR TABLE 신텍스”를 참조.

Stage 4: 매우 어려운 리페어

이 단계는 .frm 설명 파일이 크래시 되었을 경우에만 해당한다. 그런 일은 결코 일어 나지 않는데, 그 이유는 테이블이 생성된 후에는 설명 파일 (description file)이 변경되지 않기 때문이다:


  1. 백업에서 설명 파일을 복원한 다음에 Stage 3로 돌아 간다. 인덱스 파일을 복원한 다음에 Stage 2으로 갈 수도 있다. 두 번째 경우, myisamchk -r을 가지고 시작해야 한다.
  2. 만약에 여러분이 백업을 가지고 있지는 않지만, 테이블을 어떻게 생성했는지 정확히 알고 있다면, 다른 데이터 베이스에 있는 테이블을 복사한다. 새로운 데이터 파일을 삭제하고, 다른 데이터 베이스에 있는 .frm 설명 파일과 .MYI 인덱스 파일을 깨진 데이터 베이스로 복사한다. 이렇게 하면 새로운 설명 파일과 인덱스 파일은 만들어지지만, .MYD 데이터 파일은 남게 된다. Stage 2로 가서 인덱스 파일을 재 구축하도록 한다.
테이블 최적화

열을 삭제하거나 업데이트를 하면서 생기는 소비 공간을 없애고 조각 나 있는 열을 합치기 위해서는, myisamchk를 복구 모드로 실행한다:



shell> myisamchk -r tbl_name

여러분은 OPTIMIZE TABLE SQL 명령문을 사용해서 동일한 방식으로 테이블을 최적화 시킬 수도 있다. OPTIMIZE TABLE은 테이블을 리페어하고 키 분석을 하며, 또한 키를 빨리 검색하기 위해 인덱스 트리를 정렬해 준다. Section 13.5.2.5, “OPTIMIZE TABLE 신텍스”를 참조.

myisamchk에는 테이블 성능을 개선하는데 사용할 수 있는 여러 가지의 옵션이 있다:


  • --analyze, -a
  • --sort-index, -S
  • --sort-records=index_num, -R index_num

모든 사용 가능 옵션을 보기 위해서는 Section 8.2, “myisamchk - MyISAM 테이블-관리 유틸리티”를 참조할 것.


테이블 정보 가져오기

테이블에 대한 설명이나 통계 자료를 얻기 위해서는, 아래에 있는 명령어들을 사용한다. 나중에 보다 상세한 설명을 하기로 한다.


  • myisamchk -d tbl_name
    myisamchk를 “describe mode” 상태로 구동 시켜서 테이블에 대한 설명을 표시하도록 한다. 만약에 MySQL 서버를 외부 잠금을 사용하지 않은 채로 시작하였다면, myisamchk가 실행되는 동안에 업데이트된 테이블에 대해서는 에러를 보고한다. 하지만, myisamchk는 설명 모드(describe mode)에 있는 테이블을 변경 시키지 않기 때문에, 데이터가 손상될 염려는 없다.
  • myisamchk -d -v tbl_name
    myisamchk에 -v를 추가 해서 “verbose mode”로 구동 시켜서 보다 많은 정보를 보이게 끔 만든다.
  • myisamchk -eis tbl_name
    테이블에서 가장 중요한 정보만을 보이도록 한다. 이것은 테이블 전체를 읽어야만 하기 때문에 속도가 느려진다.
  • myisamchk -eiv tbl_name
    이것은 -eis와 비슷하지만, 이제 막 마친 동작을 보여준다.

위에 있는 명령어에 대한 샘플 결과가 아래에 있다. 이 명령어들은 아래와 같은 데이터와 인덱스 파일 크기를 가지고 있다고 가정을 한다:



-rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.MYD
-rw-rw-r-- 1 davida tcx 96482304 Jan 12 18:35 company.MYI
myisamchk -d 결과 샘플:

MyISAM file: company.MYI
Record format: Fixed length
Data records: 1403698 Deleted blocks: 0
Recordlength: 226

table description:
Key Start Len Index Type
1 2 8 unique double
2 15 10 multip. text packed stripped
3 219 8 multip. double
4 63 10 multip. text packed stripped
5 167 2 multip. unsigned short
6 177 4 multip. unsigned long
7 155 4 multip. text
8 138 4 multip. unsigned long
9 177 4 multip. unsigned long
193 1 text
myisamchk -d -v 결과 샘플:

MyISAM file: company
Record format: Fixed length
File-version: 1
Creation time: 1999-10-30 12:12:51
Recover time: 1999-10-31 19:13:01
Status: checked
Data records: 1403698 Deleted blocks: 0
Datafile parts: 1403698 Deleted data: 0
Datafile pointer (bytes): 3 Keyfile pointer (bytes): 3
Max datafile length: 3791650815 Max keyfile length: 4294967294
Recordlength: 226

table description:
Key Start Len Index Type Rec/key Root Blocksize
1 2 8 unique double 1 15845376 1024
2 15 10 multip. text packed stripped 2 25062400 1024
3 219 8 multip. double 73 40907776 1024
4 63 10 multip. text packed stripped 5 48097280 1024
5 167 2 multip. unsigned short 4840 55200768 1024
6 177 4 multip. unsigned long 1346 65145856 1024
7 155 4 multip. text 4995 75090944 1024
8 138 4 multip. unsigned long 87 85036032 1024
9 177 4 multip. unsigned long 178 96481280 1024
193 1 text
myisamchk -eis 결과 샘플:

Checking MyISAM file: company
Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 98% Packed: 17%

Records: 1403698 M.recordlength: 226
Packed: 0%
Recordspace used: 100% Empty space: 0%
Blocks/Record: 1.00
Record blocks: 1403698 Delete blocks: 0
Recorddata: 317235748 Deleted data: 0
Lost space: 0 Linkdata: 0

User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 639, Involuntary context switches 28966
myisamchk -eiv 결과 샘플:

Checking MyISAM file: company
Data records: 1403698 Deleted blocks: 0
- check file-size
- check delete-chain
block_size 1024:
index 1:
index 2:
index 3:
index 4:
index 5:
index 6:
index 7:
index 8:
index 9:
No recordlinks
- check index reference
- check data record references index: 1
Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
- check data record references index: 2
Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
- check data record references index: 3
Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
- check data record references index: 4
Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
- check data record references index: 5
Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 6
Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 7
Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 8
Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 9
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 9% Packed: 17%

- check records and index references
*** LOTS OF ROW NUMBERS DELETED ***

Records: 1403698 M.recordlength: 226 Packed: 0%
Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00
Record blocks: 1403698 Delete blocks: 0
Recorddata: 317235748 Deleted data: 0
Lost space: 0 Linkdata: 0

User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 10604, Involuntary context switches 122798


myisamchk가 만들어 내는 정보 타입에 대한 설명이 아래에 있다. “Keyfile”은 인덱스 파일을 참조한다. “Record” 와 “row”는 동의어다.


  • MyISAM file
    MyISAM (index) 파일의 이름.
  • File-version
    MyISAM 포맷 버전. 현재는 항상 2.
  • Creation time
    데이터 파일이 생성된 시점.
  • Recover time
    인덱스/데이터 파일이 마지막으로 재 구성된 시점.
  • Data records
    테이블에 있는 열의 수.
  • Deleted blocks
    삭제된 블록이 여전히 점유하고 있는 공간의 크기. 이 공간을 최소로 만들어서 테이블을 최적화 시킨다. Section 5.10.4.4, “테이블 최적화” 참조.
  • Datafile parts
    동적-열 포맷의 경우, 이것은 데이터 블록이 얼마나 있는지를 가리킨다. 조각이 난 열이 없는 최적화된 테이블의 경우에는 Data records와 같게 된다.
  • Deleted data
    삭제된 후에 다시 복구되지 않은 데이터의 크기 (바이트). 이 공간을 최소로 해서 테이블을 최적화 시켜야 한다. Section 5.10.4.4, “테이블 최적화”를 참조.
  • Datafile pointer
    데이터 파일 포인터의 크기 (바이트). 보통은 2, 3, 4, 또는 5 바이트가 된다. 대부분의 테이블은 2 바이트를 가지고 관리하지만, 아직은 MySQL에 의해 제어되지는 않는다. 고정 테이블의 경우, 이것은 열의 주소가 된다. 동적 테이블의 경우에는 바이트 주소가 된다.
  • Keyfile pointer
    인덱스 파일 포인터의 크기 (바이트). 보통은 1, 2, 또는 3 바이트가 된다. 대부분의 테이블은2 바이트를 가지고 관리하지만, 이것은 MySQL이 자동으로 계산을 한다. 이것은 항상 블록 주소가 된다.
  • Max datafile length
    테이블 데이터 파일의 최대 길이 (바이트).
  • Max keyfile length
    테이블 인덱스 파일의 최대 길이 (바이트).
  • Recordlength
    각 열이 차지하고 있는 공간의 길이 (바이트).
  • Record format
    테이블 열을 저장하는데 사용되는 포맷. 앞의 예제에서는 Fixed length를 사용했다. 다른 사용 가능한 값으로는 Compressed 와 Packed가 있다.
  • table description
    테이블에 있는 모든 키의 리스트. 각 키에 대해서, myisamchk는 다소 하위-레벨의 정보를 보여준다:
    • Key
      이 키의 번호.
    • Start
      열에서 인덱스의 이 부분이 시작하는 곳.
    • Len
      인덱스의 이 부분의 길이. 팩 (packed) 숫자일 경우, 이것은 항상 컬럼의 전체 길이가 된다. 스트링의 경우, 이것은 인덱스된 컬럼의 전체 길이보다는 작게 된다. 그 이유는 스트링 컬럼의 접두사를 인덱스하기 때문이다.
    • Index
      키 값이 인덱스에 여러 번 존재할 수 있는지를 검사. 사용 가능한 값은 unique 또는 multip이다.
    • Type
      인덱스의 이 부분이 가지는 데이터 타입. 이것은 가능한 값으로 packed, stripped, 또는 empty를 가지고 있는 MyISAM 데이터 타입이 된다.
    • Root
      루트 인덱스 블록의 주소.
    • Blocksize
      각 인덱스 블록의 크기. 디폴트로는 1024이지만, 소스를 가지고 MySQL을 구성할 때에는 컴파일시에 그 값이 변할 수도 있다.
    • Rec/key
      이것은 옵티마이저가 사용하는 통계 값이다. 이것은 이 인덱스에 대한 값 별로 얼마나 많은 열이 있는지를 알려준다. 고유의 인덱스는 항상 그 값이 1이다. 테이블이 myisamchk -a를 가지고 로드된 후에는 변경될 수 있다. 이것이 전혀 업데이트가 되지 않았다면, 디폴트 값은 30으로 지정된다.
    이 예제에서 보여진 테이블의 경우, 9번째 인덱스에 대해 두 개의 table description 라인이 있다. 이것은 두 개의 부분을 가지고 있는 다중-파트 인덱스라는 것을 알려 주는 것이다.
  • Keyblocks used
    Keyblocks 중의 몇 퍼센트가 사용되었는지 나타낸다. 테이블이 myisamchk를 사용해서 이제 막 재 구성되었을 경우, 그 값은 매우 높게 된다 (이론적인 최대 값에 거의 근접).
  • Packed
    MySQL이 공통의 접미사를 가지고 있는 키 값들을 팩 (pack)하려고 한다. 이것은 CHAR 와 VARCHAR 컬럼에 있는 인덱스에 대해서만 사용된다. 가장 왼쪽으로 치우쳐 있는 스트링을 인덱스 한 경우, 이것은 사용 공간을 현격하게 줄여 준다. 앞의 예제 중에 세 번째의 경우, 네 번째 키는 10개 문자 길이로 되어 있고 사용 공간의 60%를 줄여 주고 있다.
  • Max levels
    이 키에 대한 B-트리의 깊이. 기다란 키 값을 가지고 있는 대형 테이블은 높은 값을 가진다.
  • Records
    테이블에 있는 열의 수.
  • M.recordlength
    평균 열 길이. 이것은 고정-길이 열을 가지고 있는 테이블에 대해서는 정확한 열 길이가 되는데, 그 이유는 모든 열이 동일한 길이를 가지고 있기 때문이다.
  • Packed
    MySQL이 스트링의 끝에서 공간을 삭제한다. 팩이 된 값은 이것을 실행해서 얻게 된 절약 공간의 퍼센트를 가리킨다.
  • Recordspace used
    사용된 데이터 파일의 퍼센트.
  • Empty space
    사용되지 않은 데이터 파일의 퍼센트.
  • Blocks/Record
    열 당 블록의 평균 숫자 (즉, 조각난 열을 구성하고 있는 링크의 숫자). 고정-포맷 테이블에 대해서는 항상 1.0이 된다. 이 값은 가능한 한 1.0에 가깝게 되어 있어야 한다. 만약에 이 값이 너무 크게 되면, 여러분은 테이블을 재 구성해야 한다. Section 5.10.4.4, “테이블 최적화”를 참조할 것.
  • Recordblocks
    사용된 블록 (링크)의 숫자. 고정-포맷 테이블의 경우, 열의 숫자와 동일하게 된다.
  • Deleteblocks
    삭제된 블록 (링크)의 숫자.
  • Recorddata
    데이터 파일에서 사용된 바이트.
  • Deleted data
    데이터 파일에서 삭제된 (사용하지 않은) 바이트.
  • Lost space
    만약에 열이 보다 짧게 업데이트가 되었다면, 공간의 일부가 손실된 것이다. 이것은 모든 손실 공간의 합이며, 바이트로 표시된다.
  • Linkdata
    동적 테이블 포맷이 사용될 때, 열 조각들은 포인터를 가지고 링크된다 (4에서 7 바이트). Linkdata는 이러한 모든 포인터가 사용하는 스토리지의 총 합이 된다.

테이블이 myisampack, myisamchk -d로 압축 되어졌다면, 각 테이블 컬럼에 대한 추가 정보를 알려주게 된다. Section 8.4, “myisampack - 압축된, 읽기 전용 MyISAM 테이블 만들기”를 참조.


테이블 관리 (Maintenance) 스케쥴 설정

테이블 검사는 문제가 발생한 다음에 하는 것 보다 정상적인 상태에서 실행하는 것이 바람직하다. MyISAM 테이블을 검사하고 리페어하는 방법 중에 하나는 CHECK TABLE 과 REPAIR TABLE 명령문을 사용하는 것이다. Section 13.5.2.3, “CHECK TABLE 신텍스”, 그리고 Section 13.5.2.6, “REPAIR TABLE 신텍스”를 참조.

테이블을 검사하는 또 다른 방법으로는 myisamchk를 사용하는 것이다. 관리 목적인 경우, myisamchk -s를 사용한다. -s 옵션은 (--silent) myisamchk를 침묵 모드 (silent mode)로 동작 시키며, 에러가 발생했을 때에만 메시지를 출력한다.

자동으로 MyISAM 테이블 검사를 실행하도록 하는 것도 좋은 생각이다. 예를 들면, 시스템이 업데이트 도중에 재 시작을 할 때마다, 각 테이블을 검사하도록 한다. MyISAM 테이블을 자동으로 검사하기 위해서는, --myisam-recover 옵션을 가지고 서버를 구동한다. Section 5.2.1, “mysqld 명령어 옵션”을 참조할 것.

서버가 정상적으로 구동을 하는 중에도 주기적으로 테이블을 검사 해야 한다. MySQL AB사의 경우, cron 잡 (job)을 돌려서 모든 중요 테이블을 일주일에 한번씩 검사하도록 하고 있다. crontab 파일에 아래와 같은 링크를 사용한다:



35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

이렇게 하면 크래시된 테이블에 대한 정보가 나오게 되며, 필요할 경우 그러한 테이블을 검사하고 리페어할 수가 있다.

우리는 여러분이 지난 24시간 동안 업데이트가 된 모든 파일에 대해서, 매일 밤마다 myisamchk -s 를 사용해서 검사하기를 권장한다.

일반적으로는, MySQL 테이블은 거의 유지 관리가 필요 없다. 만약에 여러분이 동적 크기의 열을 가지고 있는 MyISAM 테이블에 많은 업데이트를 하거나 (VARCHAR, BLOB, 또는TEXT 컬럼을 가지고 있는 테이블) 또는 많은 열을 삭제한 테이블을 가지고 있가 있다. 의심이 가는 테이블에 대해서는 OPTIMIZE TABLE을 가지고 최적화를 할 수가 있다. 다른 방법으로는, mysqld 서버를 당분간 종료해 놓을 수 있다면, 데이터 디렉토리로 이동을 해서 서버가 멈추어 있는 동안 아래의 명령어를 실행하도록 한다:



shell> myisamchk -r -s --sort-index --sort_buffer_size=16M */*.MYI


출처 : MySQL 코리아