Mysql 備份

来源:http://www.cnblogs.com/edwardlogs/archive/2016/11/16/mysqlbackup.html
-Advertisement-
Play Games

xtrabackup工具介紹1、完全備份# innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/如果要使用一個最小許可權的用戶進行備份,則可基於如下命令創建此類用戶:(不好用)mysql> CREATE USER '... ...


xtrabackup


工具介紹

1、完全備份
# innobackupex --user=DBUSER --password=DBUSERPASS  /path/to/BACKUP-DIR/

如果要使用一個最小許可權的用戶進行備份,則可基於如下命令創建此類用戶:(不好用)
mysql> CREATE USER 'backupupser'@'localhost' IDENTIFIED BY 'backupuser';
mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backupuser'@'localhost';
mysql> FLUSH PRIVILEGES;

使用innobakupex備份時,其會調用xtrabackup備份所有的InnoDB表,複製所有關於表結構定義的相關文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相關文件,同時還會備份觸發器和資料庫配置信息相關的文件。這些文件會被保存至一個以時間命令的目錄中。

在備份的同時,innobackupex還會在備份目錄中創建如下文件:
(1)xtrabackup_checkpoints ―― 備份類型(如完全或增量)、備份狀態(如是否已經為prepared狀態)和LSN(日誌序列號)範圍信息;

每個InnoDB頁(通常為16k大小)都會包含一個日誌序列號,即LSN。LSN是整個資料庫系統的系統版本號,每個頁面相關的LSN能夠表明此頁面最近是如何發生改變的。

(2)xtrabackup_binlog_info ―― mysql伺服器當前正在使用的二進位日誌文件及至備份這一刻為止二進位日誌事件的位置。

(3)xtrabackup_binlog_pos_innodb ―― 二進位日誌文件及用於InnoDB或XtraDB表的二進位日誌文件的當前position。

(4)xtrabackup_binary ―― 備份中用到的xtrabackup的可執行文件;

(5)backup-my.cnf ―― 備份命令用到的配置選項信息;

在使用innobackupex進行備份時,還可以使用--no-timestamp選項來阻止命令自動創建一個以時間命名的目錄;如此一來,innobackupex命令將會創建一個BACKUP-DIR目錄來存儲備份數據。

2、準備(prepare)一個完全備份

一般情況下,在備份完成後,數據尚且不能用於恢復操作,因為備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。因此,此時數據文件仍處理不一致狀態。“準備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至數據文件也使得數據文件處於一致性狀態。

innobakupex命令的--apply-log選項可用於實現上述功能。如下麵的命令:

# innobackupex --apply-log  /path/to/BACKUP-DIR
如果執行正確,其最後輸出的幾行信息通常如下:
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
120407  9:01:36  InnoDB: Starting shutdown...
120407  9:01:40  InnoDB: Shutdown completed; log sequence number 92036620
120407 09:01:40  innobackupex: completed OK!

在實現“準備”的過程中,innobackupex通常還可以使用--use-memory選項來指定其可以使用的記憶體的大小,預設通常為100M。如果有足夠的記憶體可用,可以多劃分一些記憶體給prepare的過程,以提高其完成速度。


3、從一個完全備份中恢複數據

innobackupex命令的--copy-back選項用於執行恢復操作,其通過複製所有數據相關的文件至mysql伺服器DATADIR目錄中來執行恢復過程。innobackupex通過backup-my.cnf來獲取DATADIR目錄的相關信息。

# innobackupex --copy-back  /path/to/BACKUP-DIR
如果執行正確,其輸出信息的最後幾行通常如下:
innobackupex: Starting to copy InnoDB log files
innobackupex: in '/backup/2012-04-07_08-17-03'
innobackupex: back to original InnoDB log directory '/mydata/data'
innobackupex: Finished copying back files.

120407 09:36:10  innobackupex: completed OK!

請確保如上信息的最行一行出現“innobackupex: completed OK!”。

當數據恢復至DATADIR目錄以後,還需要確保所有數據文件的屬主和屬組均為正確的用戶,如mysql,否則,在啟動mysqld之前還需要事先修改數據文件的屬主和屬組。如:

# chown -R  mysql:mysql  /mydata/data/

   增量備份還原
需要註意的是,增量備份僅能應用於InnoDB或XtraDB表,對於MyISAM表而言,執行增量備份時其實進行的是完全備份。

“準備”(prepare)增量備份與整理完全備份有著一些不同,尤其要註意的是:
(1)需要在每個備份(包括完全和各個增量備份)上,將已經提交的事務進行“重放”。“重放”之後,所有的備份數據將合併到完全備份上。
(2)基於所有的備份將未提交的事務進行“回滾”。

於是,操作就變成了:
# innobackupex --apply-log --redo-only BASE-DIR

接著執行:
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1(必須為絕對路徑)

而後是第二個增量:
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2

其中BASE-DIR指的是完全備份所在的目錄,而INCREMENTAL-DIR-1指的是第一次增量備份的目錄,INCREMENTAL-DIR-2指的是第二次增量備份的目錄,其它依次類推,即如果有多次增量備份,每一次都要執行如上操作;
例如:
innobackupex --apply-log --redo-only /backup/xtrabackup/2016-10-01_17-00-13/
innobackupex --apply-log --redo-only /backup/xtrabackup/2016-10-01_17-00-13/ --incremental-dir=/backup/xtrabackup/2016-10-01_17-15-00/
'''

腳本內容

#!/usr/bin/env python
# -*- coding: utf-8 -*- 
# Author EdwardLiu


import datetime
import os
from subprocess import Popen, PIPE
import logging

# 獲取當前時間
time = datetime.datetime.now().strftime("%Y-%m-%d-%H")
# 定義備份存放目錄
backup_directory = "/software/mysql_backup/"
# 定義完全備份目錄
full_dir = "%s" % backup_directory + "full" + "backup"+"/"
# 定義增量備份目錄
increment_dir = "%s" % backup_directory + "increment" + "/"
# 命令路徑
EXES = "/usr/bin/innobackupex"
EXES_increment = "/usr/bin/innobackupex"
# 備份使用的用戶密碼
mysql_user = "root"
mysql_password = "comall2014"
# 備份使用命令
backup_full_mysql_command = "%s --user=%s  --password=%s %s" % (EXES, mysql_user, mysql_password, full_dir)

class sunday:
    def backup_command(self):
        # 運行完整備份
        proc = Popen(backup_full_mysql_command, stdin=PIPE, stdout=PIPE, universal_newlines=True, shell=True)
        result = ""
        exit_code = proc.wait()
        if exit_code != 0:
            for line in proc.stderr:
                result = result + line
        else:
            for line in proc.stdout:
                result = result + line
        return result


    def full_backup_dir(self):
        # 判斷存放完整備份目錄是否存在
        if not os.path.exists(full_dir):
            os.makedirs(full_dir)
            self.backup_command()
        else:
            self.backup_command()

    def full_backup_run(self):
        # 判斷備份目錄是否存在
        if not os.path.exists(backup_directory):
            os.makedirs(backup_directory)
            self.full_backup_dir()
        else:
            self.full_backup_dir()


class Tuesday_Saturday:
    # 每次的增量部署拿上一次的增量部署進行備份
    def last_time_increment_name(self):
        last_backup_directory_name = "ls -lrt %s | grep ^d | awk '{print $9}' | tail -n 1" % increment_dir
        proc = Popen(last_backup_directory_name, stdin=PIPE, stdout=PIPE, universal_newlines=True, shell=True)
        exit_code = proc.wait()
        result = ""
        if exit_code != 0:
            for line in proc.stderr:
                result = result + line
        else:
            for line in proc.stdout:
                result = result + line
        return result

    def increment_every_backup(self):
        # 根據最後一次完整備份做增量備份
        last_full_dir = "%s/%s" % (increment_dir, self.last_time_increment_name())
        backup_increment_mysql_command = "%s --user=%s --password=%s --incremental %s --incremental-basedir=%s" % (
            EXES_increment, mysql_user, mysql_password, increment_dir, last_full_dir)
        proc = Popen(backup_increment_mysql_command, stdin=PIPE, stdout=PIPE, universal_newlines=True, shell=True)
        exit_code = proc.wait()
        result = ""
        if exit_code != 0:
            for line in proc.stderr:
                result = result + line
        else:
            for line in proc.stdout:
                result = result + line
        return result

    def increment_run(self):
        # 周2-周六使用增量備份進行增量備份
        if not os.path.exists(increment_dir):
            os.makedirs(increment_dir)
            self.increment_every_backup()
        else:
            self.increment_every_backup()


class Monday:
    def last_full_name(self):
        # 最後一次完整備份文件名
        last_backup_directory_name = "ls -lrt %s | grep ^d | awk '{print $9}' | tail -n 1" % full_dir
        proc = Popen(last_backup_directory_name, stdin=PIPE, stdout=PIPE, universal_newlines=True, shell=True)
        exit_code = proc.wait()
        result = ""
        if exit_code != 0:
            for line in proc.stderr:
                result = result + line
        else:
            for line in proc.stdout:
                result = result + line
        return result

    def increment_run(self):
        # 根據最後一次完整備份做增量備份
        last_full_dir = "%s/%s" % (full_dir, self.last_full_name())
        backup_increment_mysql_command = "%s --user=%s --password=%s --incremental %s --incremental-basedir=%s" % (
            EXES_increment, mysql_user, mysql_password, increment_dir, last_full_dir)
        proc = Popen(backup_increment_mysql_command, stdin=PIPE, stdout=PIPE, universal_newlines=True, shell=True)
        exit_code = proc.wait()
        result = ""
        if exit_code != 0:
            for line in proc.stderr:
                result = result + line
        else:
            for line in proc.stdout:
                result = result + line
        return result

    def increment(self):
        if not os.path.exists(increment_dir):
            os.makedirs(increment_dir)
            self.increment_run()
        else:
            self.increment_run()


if __name__ == '__main__':
    d = datetime.datetime.now()
    if d.weekday() == 6:
        print u'今天是星期%s'.encode('utf-8')%(d.weekday()+1)+u'執行全量備份'.encode('utf-8')
        full = sunday()
        full.full_backup_run()
    elif d.weekday() == 0:
        print u'今天執行上一次的全量的增量備份'.encode('utf-8')+u'星期%s'.encode('utf-8')%(d.weekday()+1)
        zl_full = Monday()
        zl_full.increment()
    elif d.weekday() >=1 and d.weekday() < 6:
        print u'今天是星期%s'.encode('utf-8')%(d.weekday()+1)+u'執行增量的增量備份'.encode('utf-8')
        zl = Tuesday_Saturday()
        zl.increment_run()
    else:
        print u'碰見鬼了,難道今天是星期8?????'.encode('utf-8')

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JSON常用與伺服器進行數據交互,JSON中“{}”表示JSONObject,“[]”表示JSONArray 如下json數據: 生成json數據代碼: 解析json數據代碼: ...
  • 轉自:Android View的繪製流程 寫得太好了,本來還想自己寫的,奈何肚裡墨水有限,直接轉吧。正所謂前人種樹,後人乘涼。。 View的繪製和事件處理是兩個重要的主題,上一篇《圖解 Android事件分發機制》已經把事件的分發機制講得比較詳細了,這一篇是針對View的繪製,View的繪製如果你有 ...
  • Android官方文檔介紹的數據存儲方式共有五種,sqlite,SharedPreferences,網路存儲,外儲存儲,文件存儲,但是這些數據都無法進行共用,那麼我們就引入了今天的主角:ContentProvider // 通過隱式意圖打開通訊錄 Intent intent =newIntent(I ...
  • 【RDA】使用RDA(Remote Diagnostic Agent)工具對資料庫進行健康檢查 分類: Linux RDA英文全稱叫做“Oracle Remote Diagnostic Agent”。 這個Oracle診斷工具是用perl編寫的,包含非常豐富的診斷腳本,使用它可以非常便利的採集到Or ...
  • 創建數據表、 打開資料庫、 創建數據表、 查看數據表結構、 插入記錄、 查找表數據、 表創建的基本約束、 欄位的NULL與NOT NULL、 自動編號、 設置主鍵、 唯一約束、 預設值DEFAULT ...
  • pl/sql執行SQL腳本文件,報錯如下: 百度尋找答案,認為是被鎖了。 select session_id from v$locked_object;結果沒有任何數據。 後來把pl/sql關閉掉,然後重新進入,執行腳本,OK了! ...
  • 轉載: Oracle 11g Release 1 (11.1) Data Pump 技術 http://docs.oracle.com/cd/B28359_01/server.111/b28319/dp_overview.htm#g1015896 本文內容 Oracle Data Pump 技術(O ...
  • 1.更改資料庫的名稱 2.表中有數據的情況下再添加列、刪除列 3.在SQLServer 中各種查詢語句的使用示例 4.模糊查詢的語句 5.排序語句、排序並查前三名的語句 聚合函數:sum,avg,max,min,count 使用方法示例: group by 分組的使用方法 分組的練習: 數學函數:A ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...