กู้คืนฐานข้อมูล mysql เดียวบนระบบที่ถูกจำลองแบบ master-slave ที่ไม่ว่าง


10

กำลังมองหากลยุทธ์หรือเครื่องมือในการจัดการกับการกู้คืนฐานข้อมูลเดียวไปยังจุดในเวลาในระบบจำลองแบบไม่ว่าง

ฉันมี 12 ฐานข้อมูลที่ทำงานบนเซิร์ฟเวอร์ MySQL 5.0.77 2 ตัวในการกำหนดค่าแบบจำลองต้นแบบทาส การถ่ายโอนข้อมูลเต็มรูปแบบถูกนำมาใช้เป็นทาสแบบอ่านอย่างเดียวทุกวันและมีการทิ้ง SQL ที่เพิ่มขึ้นพร้อมกับการสำรองข้อมูลเหล่านี้นอกสถานที่และตรวจสอบสถานะการจำลองแบบ

แก้ไข: ตารางเป็นส่วนผสมของ InnoDB และ myISAM ดังนั้นจึงไม่มีโซลูชันเฉพาะเครื่องยนต์

เมื่อได้รับความล้มเหลวอย่างสมบูรณ์ของเซิร์ฟเวอร์หลักฉันสามารถทำลายการจำลองแบบและส่งเสริมเซิร์ฟเวอร์ทาสฉันยังมีตัวเลือกในการสร้างเซิร์ฟเวอร์ใหม่และกำหนดค่าจากการสำรองข้อมูล FULL ล้ำหน้าแล้วใช้ส่วนต่างที่เกิดขึ้นจากทาสทุกชั่วโมง

อย่างไรก็ตามฉันกังวลว่าจะจัดการกับความล้มเหลวบางส่วนหรือความล้มเหลวของฐานข้อมูลเดียวได้อย่างไร ฉันคิดว่า 2 สถานการณ์ที่ค่อนข้างน่าจะเป็น

  1. ฐานข้อมูล 7 (ตัวอย่าง) เกิดความเสียหายยังคงให้บริการคำขอบางอย่างจนกว่าจะมีคนสังเกตว่ามันเสียหรือการแจ้งเตือนจากไฟล์บันทึก ...
  2. แบบสอบถามบางอย่างเช่นฐานข้อมูลแบบหล่นตารางวาง "อัปเดตที่ ... " พิมพ์แบบสอบถามแบบบอร์กเป็นฐานข้อมูลเดียวหรือบางส่วนในนั้น

ในขณะนี้ฉันมีไฟล์ดัมทั้งหมดเป็นไฟล์ FULL- $ DATE-all-database.sql.gz และดิฟเฟอเรนเชียลที่สามารถนำไปใช้กับการถ่ายโอนข้อมูล FULL ได้เช่น DIFF- $ DATE-all-database.sql.gz

ในการกู้คืนฐานข้อมูล 7 ไปยังจุดเวลาจะต้องมี grep ผ่านไฟล์ FULL และ DIFF และแอปพลิเคชันด้วยตนเองของ 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 เท่านั้นฉันมีข่าวดี

คุณควรทำการดัมพ์ฐานข้อมูลทั้งหมดพร้อมกันจากสเลฟ

ในความเป็นจริงคุณสามารถบังคับให้ฐานข้อมูลทั้งหมดเป็นจุดในเวลาเดียวกัน

สิ่งแรกที่ต้องจดจำเกี่ยวกับ Slave คือไม่จำเป็นต้องเปิดใช้งานการบันทึกแบบไบนารีหากไม่ใช่ Master สำหรับ Slaves อื่น

คุณไม่สามารถใช้--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 ที่ดำเนินการจากบันทึกไบนารีบนต้นแบบคุณสามารถใช้mysqlbinlogและกำหนดตำแหน่ง datetime และส่งออก SQL ไปยังไฟล์ข้อความอื่น ๆ คุณเพียงแค่ต้องทำการตรวจสอบสถานะอย่างละเอียดเพื่อหาปริมาณข้อมูลที่คุณต้องการจากบันทึกเวลาใดก็ตามที่มีในบันทึกของ bnary เพียงจำไว้ว่าการบันทึกเวลาไบนารีทุกรายการในระบบปฏิบัติการแสดงให้เห็นว่าครั้งล่าสุดที่มันถูกเขียน


คำตอบที่ยอดเยี่ยม thanx ฉันคิดว่าการมีทาสแบบอ่านอย่างเดียวบน xfs นั้นทำให้ฉันมีตัวเลือกมากมายและสคริปต์ของคุณก็ช่วยได้จริงๆ
Tom H

ในสถานการณ์ที่ฉันต้องการกู้คืนตารางขนาดใหญ่ไปยังต้นแบบจากการสำรองข้อมูลจากสลาฟ ฉันแค่ต้องสร้างตารางบนต้นแบบขึ้นมาใหม่และให้การเปลี่ยนแปลงทั้งหมดซ้ำไปที่ทาสแม้ว่าจะเป็นข้อมูล 20GB หรือเปล่า กระบวนการนี้จะเป็น 1) ปิดการใช้งานคีย์ 2) วางตารางบนต้นแบบและทาส 3) เรียกคืนตารางที่ต้นแบบ 4) เปิดใช้งานคีย์ - และให้ต้นแบบทำซ้ำทั้งหมด 20GB ลงไปที่ทาสหรือไม่
Tom H

หากฐานข้อมูลเหล่านี้ไม่ใช่ innodb ฉันจะยังสามารถทิ้งฐานข้อมูลเหล่านั้นแบบขนานได้หรือไม่
Tom H

ใช่ถ้าคุณ 1) การหยุดทำงานของตาราง 2) ระยะservice mysql restart --skip-networking3) ดำเนินการถ่ายโอนข้อมูลแบบขนาน 4) service mysql restartวิ่ง จากนั้นโหลดตารางที่คุณต้องการ
RolandoMySQLDBA

สันนิษฐานว่าถ้าวัตถุประสงค์ของการเริ่มต้นคือการป้องกันการเชื่อมต่อเครือข่ายการเขียนไปยังฐานข้อมูลแล้วผมสามารถบรรลุผลเช่นเดียวกันโดยใช้iptables i.e. iptables -I INPUT -p tcp --dport 3306 -j DROPบน eth0 และแท้จริง
ทอม H
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.