使用 CockRoach 備份保護您的數據

已發表: 2019-07-24

隨著公司開始擴大規模,它將開始以更快的速度收集數據。 必須為此數據制定適當的備份和恢復程序來計劃緊急情況。

想像一下,如果沒有計劃如何將其恢復到可用狀態,那麼所有用戶數據都被清除是多麼災難性的。

今天,我將指導您完成一個簡單的備份和恢復計劃,利用我們在 Justuno 使用的一些技術。 CockRoachDB、Google Cloud Storage 和 Golang a Google 創建了一種編程語言。

如果您沒有聽說過 CockRoachDB,但使用過 Postgres 或 MySQL 等其他數據庫系統,您會感到賓至如歸。 根據 GitHub,CockRoach 具有作為分佈式系統的額外好處,它“建立在事務性和強一致的鍵值存儲之上。 它可以水平擴展,在磁盤、機器、機架甚至數據中心故障中倖存下來,延遲中斷最小且​​無需人工干預,並支持高度一致的 ACID 事務。”

如果您想繼續前進,請前往 CockRoach 安裝指南並在本地設置免費的 30 天企業版試用版。 此外,您需要註冊一個 Google Cloud Storage 帳戶並在您的系統上安裝 Golang。

設置完成後,前往 GCS 控制台並從創建項目開始。

CockRoach 創建項目

之後,您會看到一個顯示創建存儲桶的屏幕,單擊該選項。

CockRoach 創建存儲桶

您需要選擇一個唯一的名稱、區域、位置,然後選擇設置對象級和存儲桶級權限。 如果成功,您應該會在下面看到類似於我的圖像。 同樣,您的設置將根據您的用例而有所不同,但要遵循,使用默認值就可以了。

CockRoach 項目設置

接下來,您需要解決一些數據庫配置設置,這些設置將使 CockRoach 備份能夠直接上傳到您的 Google 雲存儲。 如果您對使用 GCS 不感興趣。 CockRoach 還支持 Amazon、Azure、Http 和 NFS/本地備份文件 URL。 更多信息可以在這裡找到。

打開位於屏幕左側的菜單,然後選擇 APIs & Services 和選項 Credentials。 您現在應該會看到一個顯示創建憑據的屏幕。 為此,我們對服務帳戶密鑰感興趣。

CockRoach 證書

在下一個屏幕上,您將選擇新建服務帳戶; 創建服務帳戶名稱; 選擇角色類型並確保選擇 JSON 作為密鑰類型。 對於這個特定的教程,我將選擇項目和所有者。 在生產環境中,您需要一個限制性更強的角色。

CockRoach 屏幕截圖

完成後,應從您的 JSON 內容開始自動下載,該內容應類似於下圖。

蟑螂 JSON

接下來,使用您選擇的工具連接到您的 cockroach 實例,我更喜歡 SQLPro for Postgres。 您可以使用大多數 Psql 驅動程序連接到您的 Cockroach 實例。 如果您想在運行本地實例的情況下通過終端連接,您可以運行:

=> 蟑螂 sql –insecure –host=localhost

您要做的第一件事是使用 JSON 文件的內容更新您的 cloudstorage.gs.default.key。

CockRoach JSON 內容

首先檢查當前設置,如上圖所示:

顯示集群設置 cloudstorage.gs.default.key;

接下來,我將 gs.default.key 設置為我的 JSON 文件的內容:

設置集群設置 cloudstorage.gs.default.key = 'Json 內容'

現在我們已經完成了設置和配置,是時候進入有趣的東西,實際的代碼了。

首先創建一個 Go 項目; 我已經命名了我的備份經理。 接下來,在你的根目錄中創建一個 main.go 文件,一個管理器目錄和一個名為 crdb.go 的文件,在你的管理器目錄中。 manager 目錄將包含應用程序邏輯的內容,您的文件結構應該與我的類似。

CockRoach 經理目錄

接下來,我們需要安裝幾個包,打開終端,然後導航到項目的根目錄。 運行以下命令:

去獲取“github.com/lib/pq”

去獲取“數據庫/sql”

去獲取 github.com/lib/pq

去獲取“cloud.google.com/go/storage”

去獲取“github.com/snabb/isoweek”

安裝這些之後,我們將在文件頂部設置一些常量來建立我們的數據庫連接。 這些常量將是主機、端口、用戶、密碼和數據庫名。

CockRoach 常量

在 main 內部,我們將使用剛剛設置的常量來構建 psql 連接字符串並嘗試建立與數據庫的連接。 如果發生錯誤,我們會驚慌失措。

CockRoach psql 連接

您的文件應該與我的文件相似,但您的常量與您的設置相匹配。 繼續並通過在終端中運行以下命令來執行您的應用程序:

“去運行 main.go”

如果沒有發生錯誤,則說明您的連接良好。

CockRoach 應用程序運行

離開 main.go 片刻,然後轉到我們之前創建的 crdb.go 文件。 在我們討論正在發生的事情之前,請複制您在下圖中看到的內容。

CockRoach crdb.go

首先,聲明一個包名和文件頂部:

包管理器

首先創建一個名為 CrdbManager 的接口。 如果您不熟悉接口,它們允許您指定所需的行為。 在這種情況下,我們專注於備份數據、執行增量備份和執行恢復。

CockRoach CrdbManager

接下來,創建一個:crdbManagerStruct{}

CockRoach crdb 結構

您可以將結構想像為其他語言中的對象。 通常,您會創建一個類,然後顯式聲明該類將實現創建的接口。 但是在 Go 中,您使用以下語法應用方法,Go 將推斷您的結構是接口類型。

CockRoach 結構體語法

在我們開始備份代碼之前,在處理 Cockroach 時需要記住一些怪癖。 Cockroach 提供兩種形式的備份:完全備份和增量備份。 完整備份非常簡單,需要您傳遞數據庫名稱和您的谷歌云存儲位置。

例如:備份數據庫銀行到 'gs://acme-co-backup/database-bank-2017-03-27-weekly' AS OF SYSTEM TIME '-10s';

增量備份可能有點棘手,因為它們需要列出所有以前的完整備份和增量備份。 首先,您必須聲明備份的存儲位置,然後列出所有以前的備份,從完整備份開始,然後是下一個增量備份

例如:將數據庫銀行備份到 'gs://acme-co-backup/db/bank/2017-03-29-nightly' 自系統時間 '-10s' 增量從 'gs://acme-co-backup/ database-bank-2017-03-27-weekly','gs://acme-co-backup/database-bank-2017-03-28-nightly';

話雖如此,您可以創建一個存儲模式,以允許您動態創建上述命令。 對於此示例,我們將創建一個每日備份的模式,一周的第一個備份是完整備份,並使用年-月-日的命名模式。 例如,我們的第一個備份將命名為:2019-7-8-full,第二天將命名為 2019-7-9-nightly。 一周的所有備份都將存儲在該數據庫名稱下以“weekly”結尾的每週 dir 目錄下。 例如:

2019-7-8-weekly/dbName/2019-7-8-full and nightly location

將會

2019-7-8-weekly/dbName/2019-7-9-nightly。

現在在我們項目的根目錄中創建一個名為 util 的新目錄,並創建一個名為 util.go 的文件; 您的目錄結構應該如下所示。

CockRoach 目錄結構

我們的 util.go 文件將包含自動生成每週、每晚和完整值的助手。 您的 util.go 應該類似於下面的屏幕截圖。

CockRoach util.go

讓我們回到我們的 crdb.go 文件。 我們需要添加一些導入,調整您的代碼以類似於下圖。

CockRoach crdb代碼調整

我已將 CrdManager 接口簽名更新到現在,但數據庫實例和數據庫名稱除外。 我還通過調用我們之前創建的 util 方法以及將保存我們的 Google 雲備份名稱的 const 來創建每週、每週完整​​和每晚的 var。

CockRoach CrdbManager 更新

現在我們可以繼續使用備份方法。

CockRoach 備份方法

我們的備份方法將使用 db 實例值和我們正在備份的數據庫作為參數。 然後我們將生成備份的保存位置,如前所述。 請記住,每週目錄採用一周開始的名稱,所有後續的完整和增量都存儲在該目錄下的一周。 您生成的 gsStorage 位置應如下所示:

gs://test-crdb-backup/2019-7-8-weekly/testdb/2019-7-8-full

生成完整的查詢以運行、執行它,並在查詢失敗時恐慌。 請注意,查詢以以下結尾:

`'截至系統時間'-10S';`

Cockroach 建議從 10 秒前開始備份。 現在我們可以繼續使用增量備份方法。

CockRoach 增量備份

增量備份首先生成我們的 gcs 增量保存位置,就像我們剛剛做的那樣。 這次在創建查詢後,我們需要一個以前備份的列表來生成完整的查詢。 這是通過調用 listDir 方法完成的,最後檢查。

查看備份列表後,您將完成生成查詢並運行它。 如果恐慌失敗,最終,您的查詢應該類似於以下查詢:

將數據庫銀行備份到 'gs://test-crdb-backup/2019-7-8-weekly/testdb/2019-7-10-nightly' AS OF

系統時間'-10s'增量來自'gs://test-crdb-backup/2019-7-8-weekly/testdb/2019-7-8-full',

'gs://test-crdb-backup/2019-7-8-weekly/testdb/2019-7-9-nightly;

接下來是還原方法。

CockRoach 恢復方法

還原類似於增量備份。 我們將生成一個查詢,然後調用目錄列表並將我們的數據庫列表附加到我們的原始查詢中。 之後,如果我們的查詢失敗,運行查詢並恐慌。

請記住,對於增量和恢復,備份列表的順序很重要。 從完整備份開始,然後是下一個增量備份,然後是增量備份。 如果您沒有正確排序它們,還原和增量備份將失敗。 如果您想了解有關恢復功能的更多信息,請單擊此處。

現在我們繼續我們的 List listDir 方法。

CockRoach Listdir 方法

首先你會注意到 listDir 沒有大寫,因為小寫的方法在 Go 中是私有的。 由於 listDir 是我們的接口方法中的幫助器,因此不需要公開該方法。

首先,我們將首先創建一個存儲桶對象,我們將使用它來查詢我們的存儲對象。 接下來,構建指向該特定數據庫實例的每周備份的查詢。 從那裡,生成一片 Dirs。 之後,運行檢查以確保完整備份是我們切片中列出的第一個,如果不是,則反轉切片。

在 Google 雲存儲中列出 Dirs 時,我看到了一些奇怪的行為。 有時調用會按升序然後降序返回列表。 確保您花時間使用此方法,專注於以正確的順序仔細檢查您的 dirs 返回列表。

另一種方法可能是更改您的命名模式並添加時間戳作為目錄名稱的一部分。 在這種情況下,您可以遍歷您的目錄列表並確保您的文件按時間升序正確排序。 listDir 方法在很大程度上取決於您的模式存儲設計。 同樣,如果您的 listDir 排序不正確,您的恢復和增量備份將失敗!

讓我們最後看一下 main.go 文件。

CockRoach main.go 文件

確保更新您的導入列表,並且您的常量都已正確填寫。 在 const 下添加以下代碼。

CockRoach main.go 文件添加代碼

首先,為指示我們應用程序邏輯的命令行參數創建一組 var。 一個命令標誌是“操作”,其值選項有備份、恢復或增量。 如果調用還原操作,另一個是您的數據庫名稱和表的數據庫。 我們的數據庫連接邏輯保持不變,在下面我們創建我們的 dbManager 實例來解析我們傳遞給應用程序的命令行參數。 然後根據調用的操作執行備份還原或增量。 如果您沒有使用命令行標誌的經驗,可以在此處找到更多信息。 運行應用程序時,您的命令應如下所示:

去運行 main.go -operation=backup -database=dbName

最後的想法

這不是一個生產就緒的應用程序。 這只是一個演示,可以讓您的思考過程繼續進行,並在理想情況下為您節省配置時間。 在整個應用程序中,當我們遇到任何形式的錯誤時,我們只會調用 panic,它會強制應用程序退出。 在生產環境中,您可能希望以不同方式處理此問題,添加某種形式的日誌記錄或通知邏輯類型(如電子郵件或 SMS 事件)以讓您了解作業的狀態。

此應用程序假定您手動將每個數據庫名稱傳遞到您的應用程序中。 雖然這可以通過編寫一個傳遞這些值的腳本來完成,然後設置一個 cron 作業來運行該腳本,但有更好的方法。 我的建議是編寫代碼來執行 Cockroach 實例中每個數據庫的備份,方法是調用“show databases”迭代返回結果並調用你的備份方法。 不要忘記您可以設置一個 cron 作業來每晚運行您的 Go 應用程序。

最後,需要注意的是,在對錶運行恢復時,Cockroach 會假定您的表不存在。 如果您嘗試在表上運行恢復並且該表存在,您將收到錯誤消息。 請記住在具有外鍵限制的表上運行還原的順序。 如果您嘗試恢復具有外鍵限制的表,但您的其他表不存在,您將遇到問題。

您可以通過添加以下內容來運行還原:

`使用 Skip_missing_foreign_keys'

這將刪除外鍵約束,但請確保之後重新添加外鍵約束。

希望這篇文章能闡明如何在緊急情況下備份和恢復公司的數據。 確保您已做好準備將有助於最大程度地減少影響並讓您快速恢復和運行。