使用 Laravel 制定 MySQL 數據庫備份計劃任務

譯文首發於 使用 Laravel 制定 MySQL 數據庫備份計劃任務,轉載請註明出處。

你能夠在終端裏經過運行一行命令導出整個數據庫。這種方案不只簡單直接並且有效。不過有更加自動化的解決方案。讓咱們來看看到底是什麼!php

scheduling-mysql-backups-with-laravel

背景

幾天前,我登陸到錯誤的數據庫中而後幹掉了 18 000 行線上數據記錄。更糟糕的是,咱們沒有對這個數據庫進行備份。而後,我決定編寫一個可以自動完成數據庫導出並保存到 SQL 文件的腳本。html

另外,若是你須要一款功能強大的數據備份系統,你能夠看看 這個 擴展。這樣咱們就無需關注更多的數據庫備份細節而僅需將焦點放到數據庫導出和導出計劃上。mysql

導出命令

使用這個單行 snippet,你能夠快速的將數據庫導出到 SQL 文件。不少應用使用下面這個命令從數據庫導出數據。laravel

mysqldump -u[user] -p[pass] [db] > [file_path]

正如你所看到的那樣,咱們須要傳入用戶名、密碼和須要導出的 DB,而後將輸出重定向到指定的文件。食用簡單方便,功效顯著。git

如今讓咱們將這個命令經過使用 artisan 命令進行封裝,使其更易於運行和可加入計劃任務。github

Artiasn 控制檯接口熱身

經過使用 artisan 控制檯(console)集成 shell 命令的一個重要出發點是,可以一次編寫處處運行。咱們要作的是配置並使用這些配置。這意味着,一旦有參數被修改,咱們不須要經過命令自己進行調整。接下來,咱們能夠來建立這個控制檯命令。sql

經過運行 php artisan make:comman 命令來建立一個自定義命令。這裏咱們的命令命名爲 BackupDatabase。當建立完你的命令後,Laravel 會自動的將命令註冊到系統中。你須要作的,僅僅是去定義命令的簽名(signature)。shell

讓咱們來預覽一下這個命令文件;稍後會詳細解釋它是如何運行的:數據庫

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;

class BackupDatabase extends Command
{
    protected $signature = 'db:backup';

    protected $description = 'Backup the database';

    protected $process;

    public function __construct()
    {
        parent::__construct();

        $this->process = new Process(sprintf(
            'mysqldump -u%s -p%s %s > %s',
            config('database.connections.mysql.username'),
            config('database.connections.mysql.password'),
            config('database.connections.mysql.database'),
            storage_path('backups/backup.sql')
        ));
    }

    public function handle()
    {
        try {
            $this->process->mustRun();

            $this->info('The backup has been proceed successfully.');
        } catch (ProcessFailedException $exception) {
            $this->error('The backup process has been failed.');
        }
    }
}
你也看到了,咱們的命令簽名爲 db:backup。因爲 Laravel 已經有了 db 命令空間,這樣命令更加清晰命令。

在構造函數中,咱們實例化一個新的 Symfony\Component\Process\Process 實例。緣由是這裏咱們須要使用 Symfony 的 Process 組件 - 而不是簡單的調用 shell_exec 函數。這個組件提供了不少好讚的特性。好比,若是進程失敗,咱們能夠拋出異常,而後有效處理異常。服務器

若是你是用的是 process 的 run() 方法,你須要手動的去檢測運行錯誤而後拋出異常。而經過 mustRun() 方法,它會自動的給咱們拋出異常。你能夠從 文檔 中獲取更多信息。

咱們將 shell 命令和所需的參數傳入到 sprintf() 函數中,它會將佔位符替換成實際的參數。在處理完 process 實例後,咱們能夠進行下一步 handle)( 方法的處理。

在 handle 方法裏,咱們有個一 try-catch 代碼塊。首先,咱們調用 mustRun() 方法,若是沒有錯誤,咱們向控制檯中輸出綠色的信息;不然,拋出 ProcessFailedException 異常,並在 catch 代碼塊中捕獲,並向控制檯中輸出 error 信息。

接下來呢?若是咱們在控制檯執行 php artisan db:backup 命令,咱們就會到此處數據庫而後將其保存到 storage/backups/backup.sql 文件。運行良好,不過,咱們還有一些工做要作,就是編寫計劃任務。

編寫備份任務的計劃任務

首先,在 Laravel 中可以輕鬆建立計劃任務。它內置提供了既簡單又支持鏈式操做的定義任務的 API 接口。在繼續本文閱讀以前,強烈建議閱讀 它的文檔 中譯

而後,進入到 Console/Kernel.php 文件看看 schedule() 函數。咱們能夠定義任務和任務執行週期。好比,咱們但願在 每週一的 23:00 運行計劃,它的編碼以下:

protected function schedule(Schedule $schedule)
{
    $schedule->command('db:backup')->mondays()->at('23:00');
}

是否是很簡單?更棒的是,你能夠在這裏定義任意多個命令。調度器(scheduler)會在指定的時間分別處理這些任務。

若要運行這個調度器,咱們須要執行 php artisan schedule:run 命令,而後它會觸發全部須要運行的命令。這很棒,咱們僅需一行命令就能夠在指定的時間觸發對應的任意命令。

但如今的問題時,如何管理調度器自身。這個有點像雞生蛋蛋生雞的問題,可是相信我,沒有這麼複雜。

使用 Forge 設置調度器

若是你還須要掌握 CORN 執行原理相關基礎支持, Mohamed Said 有一個系列文章 深刻講解了 CRON 相關知識。其中關鍵點在於,咱們無需爲每一個計劃任務建立 CRON 定時器。咱們僅需向前面介紹的那樣定義任務執行手氣,而後運行任務調取器就行了。

不過,咱們須要設置運行 php artisan schedule:run 命令的時間。若是你使用了 Laravel Forge,那麼能夠很輕易的建立定時任務。只需進入到 Scheduler 選項卡,而後你就能建立任何你想要的計劃任務。

forge schedule

如你所見,默認的已將添加了 schedule:run 命令,你須要作的就是,定義任務週期(frequency)以及替換默認命令到你服務器的命令。

若是準備好了,調度器將每次在適當的時候運行,並觸發全部要執行的命令。

總結

很高興; 咱們能夠提供輕量級的解決方案,而不依賴於一個更大的包。在這裏,咱們也能夠利用 Laravel 的優點來知足需求。

咱們可使用 Process 組件輕鬆導出數據庫,並將其封裝在 artisan 命令中。而後,咱們能夠快速地爲咱們的命令設置一個執行週期,而 Laravel 的調度程序將負責剩下的工做。咱們能夠躺着就把活該幹了。

原文

Scheduling MySQL Backups with Laravel

相關文章
相關標籤/搜索