MyISAM에서 InnoDB로 온라인 변환 후 행이 누락 됨


16

우리는 MyISAM에서 InnoDB로 변환하고자하는 상당히 작은 데이터베이스를 가지고 있습니다. 데이터베이스 멍청한 놈이기 때문에 사이트를 중단시키지 않고 방금 변환 테이블을 사용하여 변환했습니다.

변환이 완료되었으므로 많은 간헐적 인 행이 누락 된 것 같습니다. 변환 중 작업 때문일 수 있습니까? 아니면 다른 곳에 문제가 있습니까?


행이 누락 된 테이블은 무엇입니까? 당신이 변환 한 것 또는 다른 테이블?
longneck

답변:


20

스토리지 엔진을 변경하기 위해 ALTER를 수행해도 행이 사라지지 않습니다. 그러나 귀하가 귀하의 질문에 '데이터베이스 멍청한 놈'이라고 말했기 때문에 조언을 드리겠습니다.

기존 스키마를 수정하거나 데이터에 영향을 줄 있는 작업을 수행 할 때 몇 가지 기본 조언이 있습니다.

  1. 먼저 백업하십시오.
  2. 변경 계획을 세우십시오.
  3. 오프라인 호스트에서 계획을 테스트하십시오.
  4. 데이터 전과 후를 비교할 테스트 계획을 세우십시오.
  5. 가동 중지 시간을 예약하십시오.
  6. 가동 중지 시간이 적용되고 트래픽이 중지되었는지 확인한 후 즉시 백업 및 스냅 샷을 만듭니다.
  7. MYISAM을 사용하는 경우 'CHECK TABLE'을 사용하여 ALTER 전에 처리중인 내용을 평가하십시오.
  8. 만일의 경우를 대비하여 백업 외에 테이블을 로컬로 복사하십시오.
  9. 주의해서 진행하여 "--show warnings"및 기타 출력을 활성화하여 변경시 전체 그림을 확보하십시오.
  10. 데이터가 중요한 경우, 마이그레이션 중에 상담을 받더라도 DBA를 고용하십시오.

아마 더 많이 들어갈 수 있지만 위의 내용은 무언가 잘못되었을 때 옵션을 제공합니다.

누락 된 데이터 / 행까지는 비교하기 위해 "전 / 후"스냅 샷을 알 수있는 방법이 없습니다. 최신 백업과 비교하여 최소한 그 정도를 확인할 수 있습니다.


나는 이것을 읽었다. 좋은 DR 계획. 귀하의 답변은 진행 계획에 추가 된 것보다 질문에보다 민감하게 반응하여 +1을받습니다.
RolandoMySQLDBA

1
@randy 좋은 답변 때문에 좋아하는 질문으로 표시
techExplorer

8

많은 다운 타임없이 MyISAM을 InnoDB로 변환하는 가장 좋은 방법 중 하나는 하나의 전제 조건입니다. 복제 슬레이브 사용.

계획의 조감도입니다

  1. 복제 마스터 / 슬레이브 설정 작성
  2. 슬레이브의 모든 MyISAM 테이블을 InnoDB로 변환
  3. 앱을 슬레이브로 지정

간단하게 들리나요? 이것 뒤에 많은 세부 사항이 있습니다.

복제 마스터 / 슬레이브 설정 작성

마스터에게 많은 방해를받지 않고 슬레이브를 만드는 매끄러운 방법이 있습니다. 나는 두 개의 게시물을 썼다.

rsync 사용법을 자세히 설명하지 말고이 두 게시물을 읽으십시오.

슬레이브의 모든 MyISAM 테이블을 InnoDB로 변환

DB Slave에서 다음 SQL 문을 수행 할 수 있습니다.

MySQL 5.5의 경우 :

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

MySQL 5.5 이전의 MySQL 버전

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

쿼리의 출력을 사용하여 슬레이브에 대한 변환 스크립트가 있습니다.

이 두 줄을 스크립트 맨 위에 놓아야합니다.

SET SQL_LOG_BIN = 0;
STOP SLAVE;

스크립트는 먼저 이진 로깅 (슬레이브가 이진 로그를 갖도록 구성한 경우)을 비활성화하고 복제를 중지하며 각 MyISAM 테이블을 InnoDB로 변환합니다.

해당 스크립트를 작성하고 실행하는 방법은 다음과 같습니다.

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

앱을 슬레이브로 지정

슬레이브에서 SELECT 쿼리를 수행하십시오. 슬레이브의 데이터 콘텐츠에 만족하면 다음과 같이 앱을 슬레이브로 지정하십시오.

  1. 슬레이브에서 실행 SHOW SLAVE STATUS\G하고 Seconds_Behind_Master가 0인지 확인하십시오.
  2. 슬레이브에서 mysqldump -h (IP of Slave) -u ... -p ... --single-transaction --routines --triggers --all-databases> MySQLBackup.sql (이봐, 백업이 좋을 것이다 지금 쯤)
  3. 마스터에서 실행 service mysql stop(다운 타임 시작)
  4. 1 단계 반복
  5. 앱이 슬레이브를 가리킴 (다운 타임은 앱의 첫 번째 연결에서 종료 됨)

당신이이 지점을 훼손하지 않으면 축하합니다 !!!

추가 보너스 : Master / Slave 대신 Master / Master Replication (일명 Circular Replication)을 설정하면 다음과 같이 할 수 있습니다.

  1. 슬레이브에서 실행 SHOW SLAVE STATUS\G하고 Seconds_Behind_Master가 0인지 확인하십시오.
  2. 슬레이브에서 mysqldump -h (IP of Slave) -u ... -p ... --single-transaction --routines --triggers --all-databases> MySQLBackup.sql (이봐, 백업이 좋을 것이다 지금 쯤)
  3. 앱이 슬레이브를 가리킴 (다운 타임은 앱의 첫 번째 연결에서 시작 및 종료 됨)
  4. 새로운 마스터에서 STOP SLAVE;
  5. 새로운 마스터에서 CHANGE MASTER TO MASTER_HOST='';

현재 가지고있는 것은 Master / Slave입니다. New Master에는 InnoDB 데이터가 있으며 이전 Master는 이제 MyISAM 데이터의 슬레이브입니다. 읽기와 쓰기를 분리하면 슬레이브에서 읽기가 가능하고 (InnoDB보다 MyISAM에서 읽기가 더 빠름) 쓰기는 마스터 (InnoDB에 대한 트랜잭션 지원)로 이동합니다. Hannah Montana가 노래하는 것처럼, 당신은 두 세계의 최고를 얻습니다 (예, 나는 쇼를 좋아하는 두 딸이 있습니다) !!!

또 다른 추가 보너스 : Master는 이제 InnoDB이므로 가동 중지 시간없이 트랜잭션을 방해하지 않고 Master에서 mysqldump를 수행 할 수 있습니다. 단점은 CPU 및 디스크 I / O 증가입니다. 따라서 마스터 (InnoDB)에서만 mysqldump 테이블 구조와 슬레이브에서만 데이터 mysqldump (이 덤프는 InnoDB 또는 MyISAM에 대한 참조가 없습니다. 데이터 일뿐입니다)와 mysqldump 슬레이브가 MyISAM 레이아웃을 갖도록 테이블 구조.

이 새로운 설정으로 인해 가능성이 계속 될 수 있습니다 ...

업데이트 2011-08-27 19:50 EDT

사과드립니다. 나는 그 질문을 완전히 읽지 않았다. 이미 대화를 수행했습니다 .

이진 로깅이 이미 설정된 경우에만 있고 사전 백업이있는

  • / var / lib / mysql2와 같은 다른 위치로 / var / lib / mysql 복원
  • 운영 service mysql stop
  • 운영 service mysql start --datadir=/var/lib/mysql2
  • 해당 백업에서 /root/olddata.sql로 데이터베이스를 mysqldump
  • /root/changes.sql 로의 마지막 백업 이후 특정 시점에서 / var / lib / mysql (/ var / lib / mysql2 아님)의 모든 이진 로그에 대해 mysqlbinlog를 실행합니다.
  • changes.sql을 mysql에로드하십시오 (여전히 / var / lib / mysql2를 가리키고 있기 때문에)

이것은 기록 된 모든 것을 포착해야하고 변환이 시작되어야합니다. 다시 말하지만, 이것은 마지막 백업 이전에 이미 바이너리 로깅이 설정되어있는 모든 것입니다 . 그렇지 않으면 내 애도.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.