왜 MySQL 테이블이 충돌합니까? 어떻게 방지합니까?


9

사용자 테이블이 손상되어 사용할 수 없게 된 무들 사이트 의 관리자입니다 .

운 좋게도 간단한 REPAIR TABLE mdl_user작업으로 다시 작동했습니다. 문제는 그것이 실제로 충돌하여 사용할 수 없게 된 이유를 모르겠으며 다음에 더 잘 준비되도록하고 싶습니다.

나는 경험이 풍부한 DBA가 아닙니다. 저는 많은 일을하는 개발자 일뿐입니다.

백업 만 복원 할 수는 있지만 충돌을 방지 할 수있는 방법이 있다고 생각합니다.

이 테이블은 utf8_general_ci이며 MyISAM을 사용합니다.

왜 MySQL 테이블이 충돌합니까? 그 일이 발생하지 않도록 어떻게해야합니까?

답변:


11

MyISAM 테이블이 충돌하기 쉽습니다.

모든 MyISAM 테이블의 헤더에는 테이블에 대해 열린 파일 핸들 수를 추적하는 카운터가 있습니다.

mysql을 시작하고 헤더의 숫자가 실제 파일 핸들 수와 일치하지 않으면 mysqld는 테이블이 손상된 것으로 처리합니다.

REPAIR TABLE mdl_user데이터 손실없이 매번 간단 하게 데이터를 다시 사용할 수있게되면 사이트에 트래픽이 매우 많은 사이트가있는 것 mdl_user입니다.

수십 개의 테이블에 this가 필요한 경우 REPAIR TABLE모든 테이블을 InnoDB로 변환합니다. 그러나 mdl_user테이블이이 문제점을 가진 유일한 테이블 인 경우 수행 할 수있는 작업이 있습니다 (이 예에서는 데이터베이스가이라고 가정하십시오 moodle).

모든 테이블을 MyISAM으로 남겨 두려면

STEP 01 : 복구 테이블 스크립트 생성

echo "REPAIR TABLE moodle.mdl_user;" > /var/lib/mysql/MoodleStartUp.sql

STEP 02 : 복구 스크립트를 시작 파일로 선언

이것을 /etc/my.cnf에 추가하십시오

[mysqld]
init-file=/var/lib/mysql/MoodleStartUp.sql

STEP 03 : mysql 재시작

mysql을 다시 시작할 때마다 복구 테이블 스크립트가 트리거됩니다.

모든 테이블을 InnoDB로 만들려면

이 코드를 실행하여 MyISAM 테이블의 대량 변환 스크립트를 InnoDB로 만들고 확인하십시오.

MYSQL_USER=root
MYSQL_PASS=password
MYSQL_CONN="-u${MYSQL_USER} -p ${MYSQL_PASS}"
echo "SET SQL_LOG_BIN = 0;" > /root/ConvertMyISAMToInnoDB.sql
mysql ${MYSQL_CONN} -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBConversionSQL FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema') ORDER BY (data_length+index_length)" > /root/ConvertMyISAMToInnoDB.sql
less /root/ConvertMyISAMToInnoDB.sql

변환 스크립트의 내용에 만족하면 실행하십시오.

mysql ${MYSQL_CONN} < /root/ConvertMyISAMToInnoDB.sql

업데이트 2012-03-15 14:00 EDT

@Kevin , MyISAM을 사용하는 동안 디스크 공간이 부족한 경우 어떻게해야합니까?

고려해야 할 사항은 다음과 같습니다. MySQL 5.0 Certification Study Guide 에 따르면 ,

여기에 이미지 설명을 입력하십시오

글 머리 기호 # 11 은 페이지 408,409 섹션 29.2에 다음과 같이 나와 있습니다.

MyISAM 테이블에 행을 추가하는 동안 디스크 공간이 부족하면 오류가 발생하지 않습니다. 서버는 공간이 확보 될 때까지 작업을 일시 중단 한 다음 작업을 완료합니다.

디스크 공간이 부족한 경우 mysql을 종료하거나 종료하지 마십시오. 현재 사용중인 MyISAM에서 열린 파일 핸들 수는 지워지지 않습니다. 따라서 MyISAM 테이블이 다운 된 것으로 표시됩니다. mysqld가 여전히 실행중인 상태에서 데이터 볼륨의 디스크 공간을 확보 할 수 있으면 디스크 공간을 사용할 수있게되면 mysqld가 시작됩니다.


탁월한 반응. 파일 핸들의 비트를 몰랐으며 문제가 발생했을 때 어떻게 방지 (또는 자동 복구) 할 수 있는지 이미 해결했습니다. 사이트가 실제로 mdl_user (또는 다른 테이블)에 많은 쓰기를하는 경우 안전을위한 제안이 있습니까?
AeroCross

1) RAM 증가, 2) max_connections 증가, 3) InnoDB로 전환하는 세 가지 작업을 수행해야합니다.
RolandoMySQLDBA

멍청한 놈 이 코드를 어디에서 "실행"합니까? 서버로 업로드 된 파일이나 명령 줄에서?
UncaughtTypeError

0

또한 mysql에서 무들 사이트를 관리하며 가장 일반적인 테이블 손상 원인은 디스크 공간이 부족하기 때문입니다.


@RolandoMySQLDBA-예, 디스크 공간은 확실히 문제입니다 (다른 프로세스와 관련이 있으며 일반적으로 관리 철학). 불행히도 공간이 비워 졌을 때 문제가 스스로 해결되거나 적시에 충분히 해결되지는 않습니다. 내 대답은 moodle / mysql 인스턴스를 사용하면 mysql / myisam이 수행 해야하는 작업에 관계없이 디스크 공간 문제로 인해 테이블 ​​충돌이 발생할 수 있음을 지적했습니다.
Kevin

-3

모든 테이블을 InnoDB로 변환하는 좋은 줄이 하나 있습니다.

mysql -u root -p dbName -e "show table status where Engine='MyISAM';" | 
    awk 'NR>1 {print "ALTER TABLE "$1" ENGINE = InnoDB;"}'  | 
    mysql -u root -p dbName

코드는 괜찮을지 모르지만 첫 번째 질문에 대답하지 않습니다 (MySQL 테이블이 왜 충돌합니까?). 두 번째 부분에 답한다는 것을 의미한다면 (예방하는 방법?) 좀 더 설명을 추가하십시오.
ypercubeᵀᴹ

또한 자세한 내용을 추가하십시오. 이것을 실행하면 데이터베이스의 모든 테이블이 변환됩니까? 아니면 전체 서버? 테이블 변환에 실패하고 오류가 발생하면 어떻게됩니까? 일부 테이블이 변환되고 일부 테이블이 MyiSAM에 남아있을 수 있습니까? 일반적으로이를 실행하기 전에 DBA가 고려해야 할 다른 사항은 무엇입니까?
ypercubeᵀᴹ
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.