MySQL 數據恢復

前言

前兩天因爲沒注意的誤操作, 直接把某個數據表清掉了, 心慌慌. 怪自己學藝不精, 當時整了一下午也沒把數據找回來. 當晚回來閉關研究, 終於在凌晨1點多整出來了, 特此記錄, 以備不時之需.

對於 MySQL 數據的備份, 主要有兩種: 全量備份和增量備份.

  • 全量備份: 將數據庫中的所有數據全部進行備份. 相當於複製粘貼的步驟. 全量備份要保存所有數據, 佔用空間大, 必然不可能精確到每一秒.
  • 增量備份: 對數據庫的所有變動進行備份. 增量備份可以將數據庫的變動全部保存下來, 但也不可能一直保存, 否則備份文件的體積超級大.

而對數據庫數據的恢復操作, 思路也很簡單, 使用全量備份和增量備份相配合, 以某個時間點的全量備份爲基礎, 通過增量備份使數據庫數據恢復到具體的某個時間節點.

爲了防止下次遇到這種情況再抓狂, 我決定對數據庫進行定時備份. 通過全量和增量的備份文件來面對下一次事故的發生(當然, 我是肯定不會再出現了, 防止之後其他人誤操作吧)

數據的備份操作基本如下:

  1. 每天對數據庫進行全量備份
  2. 保持 binlog 的增量備份

當需要恢復時, 找到當天的全量備份數據恢復, 然後在這基礎上進行增量恢復即可恢復到某個特定的時間點. 好, 開搞.

定時全量備份

思路很簡單, 通過mysqldump命令進行全量備份, 一個簡單的定時 shell 腳本即可滿足. 腳本如下:

#!/bin/bash
# 備份文件保留天數
FileRetainDay=30
# 備份目錄
BakDir=/Users/hujing/dir/tmp/mysqldump_log
# 數據庫用戶名
User=root
# 數據庫密碼
Password=root
# 今天的日期
Date=`date +%Y-%m-%d`
cd $BakDir
mysqldump -u$User -p$Password --quick --all-databases --flush-logs > $Date.sql
# --quit: 不使用緩存
# --flush-logs: 刷新數據庫的 logbin 文件
# --all-databases: 備份所有數據庫
# 刪除30天前的備份文件
find $BakDir -mtime +$FileRetainDay -type f -name "*.sql" | xargs rm

腳本很簡單. 接下來通過crontab定時每天跑一次:

1 0 * * * bash /Users/hujing/dir/tmp/mysql_back.sh

每天的12點1分跑一次. 這樣30天以內的數據備份文件就有了.

增量備份

全量備份搞定了, 剩下增量備份. 增量備份就是 mysql 的binlog了.

以下幾個 MySQL 的命令行查詢命令可查看當前binlog狀態:

  • show binary logs 查看當前存在的 log 文件
  • show variables like '%log_bin%' 查看 binlog 是否開啓及文件位置
  • show master status 查看當前使用的 binlog
  • show binlog events in 'binlog.000001' 查看日誌文件內容

binlog相關配置:

# 開啓 binlog
log_bin=ON
# binlog 日誌文件前綴
log_bin_basename=/var/lib/mysql/binlog
# 索引文件
log_bin_index=/var/lib/mysql/binlog.index
# 文件過期時間, 過期文件會自動刪除
expire_logs_days=7
# 每個文件的最大保存大小
max_binlog_size=1024M

很好, 現在我們也有了增量備份文件.

數據恢復

當需要恢復數據時, 如何根據這兩個備份文件進行恢復呢?

打個比方, 當前時間是: 2020-9-4 23:00:00. 此時, 我做了清表的瘋狂操作. 如何恢復數據?

1. 通過全量備份, 將數據恢復到今天凌晨的時刻

進入 MySQL命令行, 執行數據恢復文件:

source /Users/hujing/dir/tmp/mysqldump_log/2020-09-04.sql

此時, 數據庫已經恢復到本日凌晨的時刻. 請注意, 這步操作會將今日生成的數據刪除.

2. 通過增量備份, 將數據恢復到指定時間節點

通過mysqlbin工具, 將指定時間的數據庫變更操作導出:

mysqlbinlog -v --start-datetime="2020-09-04 00:00:00" --stop-datetime="2020-09-04 23:00:00" /var/lib/mysql/binlog.0000* > s.sql

同樣通過source命令執行此sql文件. 此時, 數據就已經恢復了.


膚淺的記錄一下, 雖然現在可以恢復數據了, 但是還有很多問題沒有解決, 比如, 如何只恢復一張表的數據等等.

喫一塹長一智, 之後對數據庫的操作要慎之又慎.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章