อันนี้เป็น Script สำหรับ Backup ข้อมูลผ่าน rsync โดย Backup ย้อนหลัง 7 วัน (สามารถปรับได้)
<?php chdir(__DIR__); $SOURCE_HOST = 'user@192.168.0.1'; $SOURCE_PATH = '/home/user/'; $MYSQL_USERNAME = "DATABASE_USERNAME"; $MYSQL_PASSWORD = "DATABASE_PASSWORD"; $dateFormat = 'Ymd'; $before = date($dateFormat,strtotime('yesterday')); $dateKey = date($dateFormat); $delDate = date($dateFormat,strtotime('-7 days')); $excludeDirs = [ 'cache1/*', 'cache2/*', ]; system("ssh {$SOURCE_HOST} \"mysqlcheck --all-databases -u{$MYSQL_USERNAME} -p{$MYSQL_PASSWORD} -r\""); system("ssh {$SOURCE_HOST} \"mysqldump -u {$MYSQL_USERNAME} -p{$MYSQL_PASSWORD} --lock-tables=false --all-databases | gzip --rsyncable -f -c - > {$SOURCE_PATH}/backupdb/backup.sql.gz\""); system("cp -al {$before} {$dateKey}"); $excludeStr = ''; foreach($excludeDirs as $dir){ $excludeStr .= " --exclude '{$dir}'"; } system("rsync -a --delete {$excludeStr} {$SOURCE_HOST}:{$SOURCE_PATH} {$dateKey}/"); if(!empty($delDate)){ system("rm -rf ./{$delDate}"); } echo "COMPLETE";
บรรทัดที่ 1 – 14 เป็นการตั้งค่าเครื่องเป้าหมาย ว่าจะ backup จาก host ใดและ path ใด ข้อมูลการเข้าถึง Database และจำนวนวันที่ backup ย้อนหลัง โดยสามารถตั้งวันที่ backup สูงสุดได้ในบรรทัดที่ 14
บรรทัดที่ 16-19 เป็นการตั้งค่าว่าจะไม่ backup file ใด้บ้าง เช่นพวก cache เราอาจจะไม่ backup เป็นต้น
บรรทัดที่ 21-22 เป็นการสั่ง backup ฐานข้อมูล ให้ออกมาเป็น file.sql
บรรทัดที่ 24 เป็นการสั่งคัดลอก folder เมื่อวาน แบบ Hardlink มาเป็นโฟลเดอร์วันที่ปัจจุบัน โดยการทำ Hardlink จะช่วยประหยักเนื้อที่ได้มากในกรณีที่ไม่เปลี่ยนแปลง เช่นถ้าเราสั่งคัดลอก a.zip ขนาด 1GB ไปเป็น b.zip แบบ Hardlink ขนาดที่จะถูกใช้บน Harddisk จะถูกใช้แค่ 1GB เท่านั้น ไม่ใช่ 2GB แบบปกติ เพราะไฟล์เก็บที่เดียวกัน (อ่านเพิ่มเติมได้ที่นี่)
บรรทัดที่ 26-29 เป็นการสร้าง exclude parameter หรือก็คือเอา บรรทัด 16-19 มาแปลงให้ rsync เข้าใจได้
บรรทัดที่ 31 เป็นการสั่ง rsync จากต้นฉบับมาโฟลเดอร์ปัจจุบัน โดยจะดึงเฉพาะไฟล์ที่มีการเปลี่ยนแปลงหลังจากเมื่อวานเท่านั้น ทำให้ Backup ได้อย่างรวดเร็ว
บรรทัดที่ 33-35 คือสั่งให้ลบโฟลเดอร์ backup ที่เกิน 7 วันทิ้ง
อย่าใช้ script นี้ผ่าน http เพราะมันจะ timeout ให้ตั้ง cronjob เป็นประมาณ php backup.php
ในกรณที่ MySQL เราใช้แต่ InnoDB และไม่มี MyISAM สามารถเอาบรรทัดที่ 21 ออกได้ (บรรทัด mysqlcheck) เพราะ check ไปก็ทำไรไม่ได้ InnoDB ไม่ Support
ในบรรทัดที่ 22 เราจะเห็นว่ามี –lock-tables=false ซึ่งหมายถึงเราจะไม่ lock table ในการเขียน ซึ่งทำให้เว็บสามารถทำงานได้ปกติตอน dump ข้อมูลออก แต่ข้อมูลที่ได้อาจจะไม่ตรงกัน เช่น table a ถึก dump เสร็จแล้ว ในระหว่างที่ dump table b ออกมา มีการเขียนที่ table a และ c ซึ่ง table c ต้องใช้ข้อมูลจาก table a แบบนี้จตะเกิดปัญหาได้ เพราะ table c ที่ถูก dump มีข้อมูลบางอย่างที่ต้องพึ่ง table a แต่ตอน dump table a ตัว table a ยังไม่มีข้อมูลนั้น ทางแก้มี 2 แบบ