meşgul bir master-slave çoğaltılmış sistemde tek bir mysql veritabanı kurtarmak


10

Yoğun bir çoğaltılmış sistemde tek bir veritabanını belirli bir zaman diliminde kurtarmayla ilgili bir strateji veya araç mı arıyorsunuz?

Master-slave çoğaltılmış yapılandırmada 2 MySQL 5.0.77 sunucusunda çalışan 12 veritabanım var. Günlük olarak salt okunur slave'in tam bir dökümü alınır ve bu yedeklemeler site dışında artımlı SQL dökümleri vardır ve çoğaltma durumu izlenir.

Düzenleme: Tablolar InnoDB ve myISAM karışımlarıdır, bu nedenle motora özel çözümler mevcut değildir.

Bu yüzden ana sunucunun tam bir başarısızlığı göz önüne alındığında, çoğaltmayı kırabilir ve slave sunucusunu tanıtabilirim, ayrıca yeni bir sunucu oluşturma ve ofsayt FULL yedeklemesinden yapılandırma seçeneğine sahibim ve daha sonra slave'den saatlik olarak alınan diferansiyelleri uygulayabilirim.

Ancak kısmi hata veya tek bir veritabanının başarısızlığı ile nasıl başa çıkacağım konusunda endişeliyim. Muhtemelen 2 senaryo düşünebilirim;

  1. veritabanı 7 (örneğin) bozulur, biri bozulduğunu fark edene veya günlük dosyalarından uyarı alana kadar bazı istekleri sunmaya devam eder ...
  2. Drop veritabanı, drop table, "burada güncelleme ..." tipi sorgu gibi bazı sorgu tek bir veritabanını ya da içindeki bir alt kümeyi alır.

Şu anda FULL- $ DATE-all-databases.sql.gz dosyaları olarak bir sürü FULL dökümüm ve DIFF- $ DATE-all-databases.sql.gz olarak TAM dökümlere uygulanabilen diferansiyeller var.

Veritabanı 7'yi belirli bir zamanda geri yüklemek için, FULL ve DIFF dosyaları aracılığıyla bir grep ve bu sql'in manuel uygulaması gerekir.

Ana veritabanındaki önceki DIFF dökümlerinden birine kurtarma yapabilmek için nasıl ilerlemeliyim?

Bireysel veritabanı dosyalarına, yani

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

ziyade..

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

Ayrı mysqldump dosyaları için gidersem, ana veri ikili günlüğüne ne olur ve hatta ana sunucu kurtarma dökümleri için --master-data ayarlamalıyım?

Yanıtlar:


7

Tüm veritabanınız sadece InnoDB kullanıyorsa, iyi haberlerim var.

Tüm veritabanını bir köle paralel olarak dökmek gerekir.

Aslında, tüm veritabanlarını aynı zamanda zorlayabilirsiniz.

Bir Slave hakkında hatırlanması gereken ilk şey, diğer Köleler için bir Master değilse, ikili günlüğü etkinleştirmenin gerekli olmadığıdır.

--master-dataParalel dökümler için seçeneği kullanamazsınız, çünkü her dökümü her döküm dosyasının 22 satırında farklı bir konuma sahip olacaktır. Master'ın son günlük dosyasını kaydetmek ve Slave'i kullanarak yürütmek daha iyidir SHOW SLAVE STATUS\G. Bu şekilde, tüm veritabanları aynı zaman noktasındadır.

Tüm veritabanlarını toplayabilir ve tüm veritabanının paralel dökümünü yazabilirsiniz.

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;"

Çok fazla veritabanı varsa, bunları bir kerede 10 veya 20 olarak aşağıdaki gibi boşaltın:

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;"

Tek bir tabloyu kurtarmanız gerekiyorsa, tabloları 20 sırayla bir kerede paralel dökümü yapabilirsiniz .

Bunu dene:

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;"

Artık veritabanlarını veya tek tek tabloları dökecek komut dosyalarına sahip olduğunuza göre, bu verileri kendi takdirinize bağlı olarak yükleyebilirsiniz. SQL'in master üzerindeki ikili günlüklerden çalıştırılması gerekiyorsa, bunu mysqlbinlogdatetime konumuna getirebilir ve SQL'i diğer metin dosyalarına gönderebilirsiniz. Tek günlüklerin sahip olduğu zaman damgalarından ihtiyacınız olan veri miktarını bulmak için gereken özeni göstermeniz yeterlidir. İşletim sistemindeki her ikili günlük zaman damgasının son yazıldığı zamanı temsil ettiğini unutmayın.


parlak cevaplar teşekkürler. Bence xfs üzerinde salt okunur bir köle sahip olmak bana bir sürü seçenek sunuyor ve komut dosyalarınız gerçekten yardımcı oldu.
Tom H

Ben köle kapalı bir yedek master için büyük bir tablo kurtarmak gerekir senaryoda. Sadece masanın üzerine yeniden inşa etmek zorundayım ve tüm değişiklikler 20GB veri olsa bile köle kopyalanıyor mu? İşlem 1) anahtarları devre dışı bırakır mı, 2) masayı master ve slave'e bırakır 3) masayı master'a geri yükler 4) enable tuşlarını --- ve master'ın 20GB'ı slave'e kopyalamasını ister misiniz?
Tom H

Bu veritabanları innodb DEĞİLSE, yine de paralel olarak dökümü yapabilir miyim?
Tom H

Evet, eğer 1) çalışmama süresini planlayın, 2) çalışın service mysql restart --skip-networking, 3) paralel dökümü gerçekleştirin, 4) çalışın service mysql restart. Ardından ihtiyacınız olan tabloları yeniden yükleyin.
RolandoMySQLDBA

muhtemelen yeniden başlatmanın amacı veritabanına ağ bağlantılarının yazılmasını önlemekse, o zaman iptables i.e. iptables -I INPUT -p tcp --dport 3306 -j DROPeth0 ve lo kullanarak aynı etkiyi elde edebilirim
Tom H
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.