Backup ฐานข้อมูลด้วย Laravel อย่างง่าย ๆ ด้วย Spatie DB Snapshots

14 มีนาคม 2566
Backup ฐานข้อมูลด้วย Laravel อย่างง่าย ๆ ด้วย Spatie DB Snapshots

ใน Laravel รองรับ การสร้าง Schema ฐานข้อมูล ด้วย migration อยู่แล้ว ช่วยให้เราสามารถ เพิ่ม/ลด field หรือตารางใน database ของเราตาม feature ที่เรามีการพัฒนาขึ้นบนเวป ทีนี้ถ้าเราต้องการจะ backup ฐานข้อมูลเราสามารถใช้ package ของ Spatie ที่ชื่อว่า Laravel DB Snapshots เพื่อ ทำการ back up ฐานข้อมูลไว้ได้

จุดเด่นของ Package นี้มีตามนี้เลยครับ:

  • สามารถ back up database แต่ละ environment ที่เรามีได้ ไม่ว่าจะเป็น local, develop, หรือ production ตามที่เรา set ไว้ ใน .env
  • สามารถ back up หลาย ๆ database ได้ตามแต่ละ connection
  • สามารถ back up ให้เก็บข้อมูลย้อนหลังรายวันได้ และมี Artisan command ให้เคลียร์ไฟล์ back up เก่า ๆ ที่ไม่ต้องการแล้วได้อีกด้วย
  • รองรับหลากหลาย DBMS ทั้ง mysql, mariadb, และ postgres อย่างน้อย 3 DB นี้ที่ผมเคยใช้มาโดยตรงจาก project ที่พัฒนา
  • สามารถ เก็บเป็นไฟล์ SQL หรือให้ compress เป็น .zip เพื่อลดขนาดไฟล์ได้
  • สามารถ Restore โหลดไฟล์ backup กลับเข้า database ได้ง่าย ๆ เหมาะสำหรับต้องการ backup ข้อมูลจาก production เพื่อเอากลับมาทดสอบใน Local ก่อนได้

วิธีการติดตั้ง package:

composer require spatie/laravel-db-snapshots

ทำการ สร้างไฟล์ config ด้วยคำสั่ง vendor:publish

php artisan vendor:publish --provider="Spatie\DbSnapshots\DbSnapshotsServiceProvider"

โดย default package นี้จะสร้าง ไฟล์ back up ไว้ใน disk ที่ชื่อว่า snapshots ซึ่งแน่นอนว่าไม่ได้มี disk นี้ใน config เริ่มต้นของ Laravel ไปยัง app/config/filesystems.php เพื่อเพิ่ม disk snapshots และระบุ path ที่เราต้องการเก็บไฟล์ไว้

// ...
'disks' => [
    // ...
    'snapshots' => [
        'driver' => 'local',
        'root' => database_path('snapshots'),
    ],
// ...    

เมื่อเรา config เรียบร้อยแล้ว สามารถ run คำสั่ง artisan เพื่อ backup ฐานข้อมูลได้เลย

// default ชื่อไฟล์จะเป็น Y-m-d H:i:s `2023-03-17 14:31.sql`
php artisan snapshot:create

โดย package ทำการ back up ตารางทั้งหมด ใน default database connection ใน project ของเรา

ถ้าอยากตั้งชื่อไฟล์ backup สามารถระบุชื่อไฟล์ไว้เป็น parameter ในคำสั่งได้เลย

// ได้ไฟล์ชื่อ backup-1.sql
php artisan snapshot:create backup-1

หากฐานข้อมูลเรามีขนาดใหญ่ เราสามารถสั่งให้ command zip ไฟล์ backup ให้เราได้ โดยระบุ parameter --compress

// `2023-03-17 14:31.zip`
php artisan snapshot:create --compress

ถ้าไม่อยากต้องระบุ parameter นี้ทุกครั้งสามารถ กำหนดใน ไฟล์ config app/config/db-snapshots.php ได้เลย

return [

    'disk' => 'snapshots',

    /*
     * Create dump files that are gzipped
     */
    'compress' => true,

    // ....

];

โดยปกติเวลา run คำสั่ง schema:create บ่อย ๆ จะมีชื่อไฟล์ backup เกิดขึ้น ตาม วันที่และเวลาที่ run คำสั่งนั้นไว้ package นี้ก็มีคำสั่งช่วยให้เราเคลียร์ไฟล์ backup เก่า ๆ ที่ไม่ต้องการใช้แล้วออกไปได้

php artisan snapshot:cleanup --keep=2

จากคำสั่งด้านบน จะลบไฟล์ back up เก่า ๆ ออกทั้งหมดเหลือไว้เพียง 2 ไฟล์ล่าสุดที่เราเพิ่งสร้างขึ้นมา

เมื่อเรามีไฟล์ backup เรียบร้อยแล้ว เราสามารถทำการ restore database ได้ด้วยคำสั่ง

php artisan snapshot:load

ถ้าเรามีไฟล์ backup เก็บไว้หลายไฟล์ package นี้จะถามไฟล์ back up ที่เราต้องการ restore ไปยัง default database connection ที่ set ไว้ใน project ของเรา

ถ้าเราต้องการ restore ไปยังคนละ database จากที่เรา back up มา เราสามารถสั่งให้ restore ไปยัง environment หรือ connection อื่นที่เราต้องการได้

php artisan snapshot:load --env=local
php artisan snapshot:load --connection=staging

จากคำสั่งทั้งหมดข้างต้น เราสามารถให้ package นี้ ทำ daily backup ฐานข้อมูลให้เราเป็นรายวันได้เลย เพียงแค่เราเพิ่มคำสั่ง snapshot:create ไว้ใน Schedule ของ Console Kernel ใน Project

class Kernel extends ConsoleKernel
{

    protected function schedule(Schedule $schedule)
    {
        $schedule->command('snapshot:create')->daily();
        $schedule->command('snapshot:cleanup --keep 7')->daily();
        // run back up ทุกวันตอนเที่ยงคืน โดยเก็บไฟล์ไว้ 7 วันล่าสุด
        
    }

}

ศึกษาวิธีการ set cron และ Schedule เพิ่มเติมจาก Laravel Documentation

อีกประโยชน์หนึ่งของ package นี้นอกจากทำ Schedule back up แล้ว ถ้าใน project เรามีการทำ CI/CD หรือมีการใช้ migration ในการ update schema ฐานข้อมูล เราก็สามารถเพิ่ม คำสั่งนี้ไว้ใน deploy step ของเราได้ เพื่อป้องกัน การ run migrate ผิดพลาด ทำให้เรา restore database กลับมาได้ก่อนป้องกันข้อมูลเสียหายบน production นะครับ

สามารถศึกษารายละเอียดเพิ่มเติม package นี้จาก GitHub ได้โดยตรงครับ

https://github.com/spatie/laravel-db-snapshots

Phattarachai Chaimongkol

เกี่ยวกับ phattarachai.dev

มองหาคนช่วยทำ Web App ใช้ภายในธุรกิจอยู่มั้ยครับ
มีความชำนาญในการพัฒนา Web Application ด้วย Laravel รับพัฒนาโปรเจคให้ผู้ประกอบการ ธุรกิจ SME ทั้งขนาดเล็กและขนาดใหญ่ พัฒนาระบบใช้ในองค์กรทั้งภาครัฐและเอกชน เป็นพาร์ทเนอร์กับบริษัททางด้าน Digital Agency เพื่อพัฒนาโปรเจคให้แก่ลูกค้า ทักเข้ามาพูดคุยกันก่อนได้เลยครับ

เรื่องล่าสุด

วิธีการให้ git จดจำ password โดยไม่ต้องระบุใหม่ทุกครั้ง
14 มีนาคม 2566
วิธีการให้ git จดจำ password โดยไม่ต้องระบุใหม่ทุกครั้ง
วิธีการเช็ค Detect Browser ผู้ใช้จาก Laravel
14 มีนาคม 2566
วิธีการเช็ค Detect Browser ผู้ใช้จาก Laravel
ระบบแบบทดสอบประเมินบุคลิกภาพ
14 มีนาคม 2566
ระบบแบบทดสอบประเมินบุคลิกภาพ