사용량이 많은 마스터-슬레이브 복제 시스템에서 단일 MySQL 데이터베이스 복구


10

사용량이 많은 복제 시스템에서 단일 데이터베이스를 특정 시점으로 복구하는 전략 또는 도구를 찾고 있습니다.

마스터-슬레이브 복제 구성의 2 개의 MySQL 5.0.77 서버에서 12 개의 데이터베이스를 실행하고 있습니다. 전체 덤프는 매일 읽기 전용 슬레이브에서 가져 오며 증분 SQL 덤프가 사용 가능하며 이러한 백업은 오프 사이트에 있으며 복제 상태가 모니터링됩니다.

편집 : 테이블은 InnoDB와 myISAM의 혼합이므로 엔진 특정 솔루션을 사용할 수 없습니다.

따라서 마스터 서버가 완전히 고장 나면 복제를 중단하고 슬레이브 서버를 승격시킬 수 있으며 새 서버를 재구성하고 오프사이드 FULL 백업에서 구성한 다음 슬레이브에서 매시간 차이를 적용하는 옵션도 있습니다.

그러나 부분 실패 또는 단일 데이터베이스의 실패를 처리하는 방법에 대해 걱정하고 있습니다. 나는 두 가지 시나리오를 생각할 수있다.

  1. 데이터베이스 7 (예 :)이 손상되거나 누군가 요청이 깨지거나 로그 파일에서 경고가 표시 될 때까지 일부 요청을 계속 처리합니다.
  2. 데이터베이스 삭제, 테이블 삭제, "update where ..."유형 쿼리와 같은 일부 쿼리는 단일 데이터베이스 또는 그 안에 일부 하위 집합을 생성합니다.

현재 FULL- $ DATE-all-databases.sql.gz 파일로 FULL 덤프를 많이 사용하고 DIFF- $ DATE-all-databases.sql.gz로 FULL 덤프에 적용 할 수있는 차등이 있습니다.

데이터베이스 7을 특정 시점으로 복원하려면 FULL 및 DIFF 파일을 통한 grep과 해당 SQL의 수동 적용이 필요합니다.

이전 DIFF 덤프 중 하나를 마스터 데이터베이스로 복구 할 수 있도록하려면 어떻게해야합니까?

개별 데이터베이스 파일로 백업해야합니까?

mysqldump --databases "database1" | gzip > database1.sql.gz
mysqldump --databases "database2" | gzip > database2.sql.gz
mysqldump --databases "database3" | gzip > database3.sql.gz

오히려 ..

mysqldump --master-data --lock--all-databases --all-databases | gzip > all-databases.sql.gz

별도의 mysqldump 파일을 찾으면 마스터 데이터 이진 로그는 어떻게되며 마스터 서버 복구 덤프에 대해 --master-data를 설정해야합니까?

답변:


7

모든 데이터베이스가 InnoDB 만 사용한다면 좋은 소식이 있습니다.

슬레이브로부터 모든 데이터베이스를 병렬로 덤프해야합니다.

실제로 모든 데이터베이스를 동일한 시점으로 강제 설정할 수 있습니다.

슬레이브에 대해 가장 먼저 기억해야 할 것은 다른 슬레이브의 마스터가 아닌 경우 바이너리 로깅을 활성화 할 필요가 없다는 것입니다.

--master-data각 덤프는 각 덤프 파일의 22 행에서 작성된 다른 위치를 가지므로 병렬 덤프 에는 옵션을 사용할 수 없습니다 . 마스터의 마지막 로그 파일을 기록하고를 사용하여 슬레이브가 실행 된 위치를 지정하는 것이 좋습니다 SHOW SLAVE STATUS\G. 이렇게하면 모든 데이터베이스가 동일한 특정 시점 위치를 갖습니다.

모든 데이터베이스를 수집하고 모든 데이터베이스의 병렬 덤프를 스크립팅 할 수 있습니다.

DBLIST=/tmp/ListOfDatabasesToParallelDump.txt
BACKUP_BASE=/backups
BACKUP_DATE=`date +"%Y%m%d_%H%M%S"`
BACKUP_HOME=${BACKUP_BASE}/${BACKUP_DATE}
mkdir ${BACKUP_HOME}
cd ${BACKUP_HOME}

mysql -h... -u... -p... -e"STOP SLAVE;"
mysql -h... -u... -p... -e"SHOW SLAVE STATUS\G" > ${SSS}
LOGFIL=`cat ${SSS} | grep "Relay_Master_Log_File" | awk '{print $2}'`
LOGPOS=`cat ${SSS} | grep "Exec_Master_Log_Pos"   | awk '{print $2}'`
echo "Master was at ${LOGFIL} Position ${LOGPOS} for this Backup" > Master_Log_FilePos.txt

mysql -h... -u... -p... -AN -e"SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema')" > ${DBLIST}

for DB in `cat ${DBLIST}` 
do 
    mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} | gzip > ${DB}.sql.gz & 
done 
wait 

mysql -h... -u... -p... -e"START SLAVE;"

단순히 너무 많은 데이터베이스가있는 경우 다음과 같이 한 번에 10 또는 20 개의 데이터베이스를 덤프하십시오.

DBLIST=/tmp/ListOfDatabasesToParallelDump.txt
SSS=/tmp/ShowSlaveStatusDisplay.txt
BACKUP_BASE=/backups
BACKUP_DATE=`date +"%Y%m%d_%H%M%S"`
BACKUP_HOME=${BACKUP_BASE}/${BACKUP_DATE}
mkdir ${BACKUP_HOME}
cd ${BACKUP_HOME}

mysql -h... -u... -p... -e"STOP SLAVE;"
mysql -h... -u... -p... -e"SHOW SLAVE STATUS\G" > ${SSS}
LOGFIL=`cat ${SSS} | grep "Relay_Master_Log_File" | awk '{print $2}'`
LOGPOS=`cat ${SSS} | grep "Exec_Master_Log_Pos"   | awk '{print $2}'`
echo "Master was at ${LOGFIL} Position ${LOGPOS} for this Backup" > Master_Log_FilePos.txt

mysql -h... -u... -p... -AN -e"SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema')" > ${DBLIST}

COMMIT_LIMIT=20
COMMIT_COUNT=0    
for DB in `cat ${DBLIST}` 
do 
    mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} | gzip > ${DB}.sql.gz & 
    (( COMMIT_COUNT++ ))
    if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
    then
        COMMIT_COUNT=0
        wait
    fi
done 
wait 
if [ ${COMMIT_COUNT} -gt 0 ]
then
    wait
fi

mysql -h... -u... -p... -e"START SLAVE;"

단일 테이블을 복구해야하는 경우 크기 순서대로 한 번에 덤프 테이블 20을 병렬 처리 할 수 ​​있습니다 .

이 시도:

TBLIST=/tmp/ListOfTablesToParallelDump.txt
SSS=/tmp/ShowSlaveStatusDisplay.txt
BACKUP_BASE=/backups
BACKUP_DATE=`date +"%Y%m%d_%H%M%S"`
BACKUP_HOME=${BACKUP_BASE}/${BACKUP_DATE}
mkdir ${BACKUP_HOME}
cd ${BACKUP_HOME}

mysql -h... -u... -p... -e"STOP SLAVE;"
mysql -h... -u... -p... -e"SHOW SLAVE STATUS\G" > ${SSS}
LOGFIL=`cat ${SSS} | grep "Relay_Master_Log_File" | awk '{print $2}'`
LOGPOS=`cat ${SSS} | grep "Exec_Master_Log_Pos"   | awk '{print $2}'`
echo "Master was at ${LOGFIL} Position ${LOGPOS} for this Backup" > Master_Log_FilePos.txt

mysql -h... -u... -p... -AN -e"SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql','performance_schema') ORDER BY data_length" > ${DBLIST}

COMMIT_LIMIT=20
COMMIT_COUNT=0    
for DBTB in `cat ${TBLIST}` 
do
    DB=`echo "${DBTB}" | sed 's/\./ /g' | awk '{print $1}'`
    TB=`echo "${DBTB}" | sed 's/\./ /g' | awk '{print $2}'`
    DUMPFILE=$DB-{DB}-TBL-${TB}.sql.gz
    mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} ${TB} | gzip >  ${DUMPFILE} & 
    (( COMMIT_COUNT++ ))
    if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
    then
        COMMIT_COUNT=0
        wait
    fi
done 
wait 
if [ ${COMMIT_COUNT} -gt 0 ]
then
    wait
fi

mysql -h... -u... -p... -e"START SLAVE;"

이제 데이터베이스 또는 개별 테이블을 덤프하는 스크립트가 있으므로 재량에 따라 해당 데이터를로드 할 수 있습니다. 마스터의 이진 로그에서 SQL을 실행해야하는 경우 mysqlbinlogdatetime에 위치를 지정하고 다른 텍스트 파일로 SQL을 출력 할 수 있습니다. 20 억 개의 로그가있는 타임 스탬프에서 필요한 양의 데이터를 찾으려면 실사를 수행하면됩니다. OS의 모든 이진 로그 타임 스탬프는 마지막으로 작성된 시간을 나타냅니다.


화려한 답변 고맙습니다. xfs에서 읽기 전용 슬레이브를 사용하면 많은 옵션을 얻을 수 있으며 스크립트가 실제로 도움이되었다고 생각합니다.
Tom H

슬레이브의 백업에서 대규모 테이블을 마스터로 복구 해야하는 시나리오에서. 마스터에서 테이블을 다시 작성하고 20GB의 데이터라도 모든 변경 사항을 슬레이브에 복제해야합니까? 프로세스가 1) 비활성화 키, 2) 마스터 및 슬레이브에서 테이블 삭제 3) 마스터로 테이블 복원 4) 활성화 키 --- 마스터가 20GB를 슬레이브로 모두 복제하도록합니까?
Tom H

이 데이터베이스가 innodb가 아닌 경우에도 병렬로 덤프 할 수 있습니까?
Tom H

예, 1) 가동 중지 시간 예약, 2) 실행 service mysql restart --skip-networking, 3) 병렬 덤프 수행, 4) 실행 service mysql restart. 그런 다음 필요한 테이블을 다시로드하십시오.
RolandoMySQLDBA

아마도 재시작의 목적이 네트워크 연결이 데이터베이스에 기록되는 것을 막기위한 것이라면, iptables i.e. iptables -I INPUT -p tcp --dport 3306 -j DROPeth0과 lo 를 사용하여 동일한 효과를 얻을 수 있습니다.
Tom H
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.