最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文分享MySQL數(shù)據(jù)庫備份恢復(fù)腳本

 更新時(shí)間:2026年06月03日 09:06:24   作者:Oneslide  
在日常業(yè)務(wù)場(chǎng)景,通常情況下,我們不需要進(jìn)行全庫備份,而是只備份需要的數(shù)據(jù)庫,本文分享一個(gè)MySQL數(shù)據(jù)庫備份恢復(fù)腳本,用于備份和恢復(fù)指定的數(shù)據(jù)庫,希望對(duì)大家有所幫助

本人親測(cè)可用

在日常業(yè)務(wù)場(chǎng)景,通常情況下,我們不需要進(jìn)行全庫備份,而是只備份需要的數(shù)據(jù)庫。本文分享一個(gè)MySQL數(shù)據(jù)庫備份恢復(fù)腳本,用于備份和恢復(fù)指定的數(shù)據(jù)庫。

備份腳本

#!/bin/bash
# MySQL 連接參數(shù)
MYSQL_HOST="127.0.0.1"
MYSQL_PORT="3306"
MYSQL_USER="root"
MYSQL_PASS='your_password'
# 備份目錄
BACKUP_DIR="mysql-backup/$(date +%Y%m%d_%H%M%S)"
LOG_FILE="${BACKUP_DIR}/backup.log"
# 創(chuàng)建備份目錄
mkdir -p "${BACKUP_DIR}"
# 日志函數(shù)
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "${LOG_FILE}"
}
# 開始備份
log "開始 MySQL 分表備份"
# 獲取所有數(shù)據(jù)庫列表(排除系統(tǒng)數(shù)據(jù)庫)
# 檢查是否提供了數(shù)據(jù)庫參數(shù)
if [ $# -eq 0 ]; then
    echo "用法: $0 <數(shù)據(jù)庫1> [數(shù)據(jù)庫2] [數(shù)據(jù)庫3] ..."
    echo "例如: $0 db1 db2 db3"
    exit 1
fi
# 指定的數(shù)據(jù)庫列表
DATABASES=("$@")
# 驗(yàn)證指定的數(shù)據(jù)庫是否存在
for DB in "${DATABASES[@]}"; do
    # 檢查數(shù)據(jù)庫是否存在
    DB_EXISTS=$(mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \
        -e "SHOW DATABASES LIKE '${DB}';" -s --skip-column-names)
    if [ -n "$DB_EXISTS" ]; then
        log "[INFO]數(shù)據(jù)庫存在: $DB"
    else
        log "[ERROR]: 數(shù)據(jù)庫 '$DB' 不存在,跳過"
        exit 1
    fi
done
if [ $? -ne 0 ]; then
    log "錯(cuò)誤: 無法連接到 MySQL 服務(wù)器或獲取數(shù)據(jù)庫列表"
    exit 1
fi
log "找到數(shù)據(jù)庫: $(echo ${DATABASES} | tr '\n' ' ')"
# 遍歷每個(gè)數(shù)據(jù)庫
for DB in ${DATABASES[@]}; do
    log "正在處理數(shù)據(jù)庫: ${DB}"
    # 創(chuàng)建數(shù)據(jù)庫目錄
    DB_DIR="${BACKUP_DIR}/${DB}"
    mkdir -p "${DB_DIR}"
    # 獲取數(shù)據(jù)庫中的所有表
    TABLES=$(mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \
        -e "SHOW TABLES FROM \`${DB}\`;" -s --skip-column-names)
    if [ $? -ne 0 ]; then
        log "錯(cuò)誤: 無法獲取數(shù)據(jù)庫 ${DB} 的表列表"
        continue
    fi
    log "數(shù)據(jù)庫 ${DB} 中找到表: $(echo ${TABLES} | tr '\n' ' ')"
    # 遍歷每個(gè)表進(jìn)行備份
    for TABLE in ${TABLES}; do
        log "正在備份表: ${DB}.${TABLE}"
        BACKUP_FILE="${DB_DIR}/${TABLE}.sql"
        # 執(zhí)行表備份(不包含存儲(chǔ)過程、函數(shù)和事件)
        mysqldump \
            -h "${MYSQL_HOST}" \
            -P "${MYSQL_PORT}" \
            -u "${MYSQL_USER}" \
            -p${MYSQL_PASS} \
            --single-transaction \
            --triggers \
            --hex-blob \
            --opt \
            --set-gtid-purged=OFF \
            --default-character-set=utf8mb4 \
            --lock-tables=FALSE \
            --add-locks=FALSE \
            --skip-triggers \
            "${DB}" "${TABLE}" > "${BACKUP_FILE}" 2>> "${LOG_FILE}"
        if [ $? -eq 0 ]; then
            # 檢查文件大小,如果太小可能是空表或備份失敗
            FILE_SIZE=$(stat -c%s "${BACKUP_FILE}" 2>/dev/null || stat -f%z "${BACKUP_FILE}")
            if [ "${FILE_SIZE}" -lt 100 ]; then
                log "警告: 表 ${DB}.${TABLE} 的備份文件可能為空或異常"
            else
                log "成功備份表 ${DB}.${TABLE} 到 ${BACKUP_FILE} (大小: ${FILE_SIZE} 字節(jié))"
            fi
        else
            log "錯(cuò)誤: 備份表 ${DB}.${TABLE} 失敗"
        fi
    done
done
# 備份完成統(tǒng)計(jì)
TOTAL_TABLES=0
for DB in ${DATABASES}; do
    if [ -d "${BACKUP_DIR}/${DB}" ]; then
        DB_TABLES=$(ls "${BACKUP_DIR}/${DB}"/*.sql 2>/dev/null | wc -l)
        TOTAL_TABLES=$((TOTAL_TABLES + DB_TABLES))
    fi
done
log "備份完成! 總共備份了 ${TOTAL_TABLES} 個(gè)表"
log "備份文件保存在: ${BACKUP_DIR}"

備份目錄結(jié)構(gòu)如下:

mysql-backup/
└── YYYYMMDD_HHMMSS/
    ├── backup.log
    ├── db1/
    │   ├── table1.sql
    │   ├── table2.sql
    │   └── ...
    ├── db2/
    │   ├── table1.sql
    │   ├── table2.sql
    │   └── ...
    └── ...

其中:

  • YYYYMMDD_HHMMSS 是備份時(shí)間戳(年、月、日、時(shí)、分、秒)
  • backup.log 是備份過程的日志文件
  • 每個(gè)數(shù)據(jù)庫都有自己的目錄,目錄名與數(shù)據(jù)庫名相同
  • 每個(gè)表都以 .sql 文件格式單獨(dú)備份,文件名與表名相同

恢復(fù)腳本

這個(gè)恢復(fù)腳本是和上面?zhèn)浞菽_本配套使用的,用于恢復(fù)指定數(shù)據(jù)庫的備份。只能恢復(fù)一個(gè)數(shù)據(jù)庫,但是也夠用了。

restore-onedb.sh

#!/bin/bash
# MySQL 連接參數(shù)
MYSQL_HOST="127.0.0.1"
MYSQL_PORT="3306"
MYSQL_USER="root"
MYSQL_PASS="your_mysql_password"
# 檢查參數(shù)
if [ $# -ne 2 ]; then
    echo "用法: $0 <備份目錄路徑> <數(shù)據(jù)庫名>"
    echo "例如: $0 /opt/mysql-backup/20231201_143022 mydatabase"
    exit 1
fi
BACKUP_DIR="$1"
DB_NAME="$2"
DB_BACKUP_DIR="$BACKUP_DIR/$DB_NAME"
# 檢查備份目錄和數(shù)據(jù)庫備份是否存在
if [ ! -d "$BACKUP_DIR" ]; then
    echo "錯(cuò)誤: 備份目錄不存在: $BACKUP_DIR"
    exit 1
fi
if [ ! -d "$DB_BACKUP_DIR" ]; then
    echo "錯(cuò)誤: 在備份目錄中未找到數(shù)據(jù)庫 '$DB_NAME' 的備份"
    echo "可用的數(shù)據(jù)庫備份:"
    find "$BACKUP_DIR" -maxdepth 1 -type d -not -path "$BACKUP_DIR" -not -name ".*" -exec basename {} \; | grep -v -E "(backup|log)"
    exit 1
fi
echo "開始恢復(fù)指定數(shù)據(jù)庫"
echo "備份目錄: $BACKUP_DIR"
echo "數(shù)據(jù)庫名: $DB_NAME"
echo "MySQL 主機(jī): $MYSQL_HOST:$MYSQL_PORT"
echo "=========================================="
# 確認(rèn)操作
read -p "確認(rèn)要恢復(fù)數(shù)據(jù)庫 '$DB_NAME' 嗎?這將刪除現(xiàn)有數(shù)據(jù)庫并重新導(dǎo)入!(y/N): " confirm
case "$confirm" in
    [yY]|[yY][eE][sS])
        echo "開始恢復(fù)..."
        ;;
    *)
        echo "操作已取消"
        exit 0
        ;;
esac
# 記錄整個(gè)恢復(fù)過程的開始時(shí)間
OVERALL_START_TIME=$(date +%s)
# 檢查數(shù)據(jù)庫是否存在
DB_EXISTS=$(mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \
    -e "SHOW DATABASES LIKE '${DB_NAME}';" -s --skip-column-names 2>/dev/null)
if [ -n "$DB_EXISTS" ]; then
    echo "數(shù)據(jù)庫 '$DB_NAME' 已存在,正在刪除..."
    mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \
        -e "DROP DATABASE \`${DB_NAME}\`;" 2>/dev/null
    if [ $? -ne 0 ]; then
        echo "錯(cuò)誤: 無法刪除數(shù)據(jù)庫 '$DB_NAME'"
        exit 1
    fi
    echo "數(shù)據(jù)庫 '$DB_NAME' 已成功刪除"
fi
# 創(chuàng)建新數(shù)據(jù)庫
echo "創(chuàng)建數(shù)據(jù)庫 '$DB_NAME'..."
mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \
    -e "CREATE DATABASE \`${DB_NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null
if [ $? -ne 0 ]; then
    echo "錯(cuò)誤: 無法創(chuàng)建數(shù)據(jù)庫 '$DB_NAME'"
    exit 1
fi
# 恢復(fù)所有表
TABLE_COUNT=0
FAILED_COUNT=0
echo "開始恢復(fù)表數(shù)據(jù)..."
echo "------------------------------------------"
for TABLE_FILE in "$DB_BACKUP_DIR"/*.sql; do
    if [ -f "$TABLE_FILE" ]; then
        TABLE_NAME=$(basename "$TABLE_FILE" .sql)
        # 記錄單個(gè)表恢復(fù)的開始時(shí)間
        TABLE_START_TIME=$(date +%s)
        # 獲取SQL文件大小
        FILE_SIZE=$(du -h "$TABLE_FILE" | cut -f1)
        echo "恢復(fù)表: $DB_NAME.$TABLE_NAME (文件大小: $FILE_SIZE)"
        # 恢復(fù)表
        mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \
            "$DB_NAME" < "$TABLE_FILE"
        if [ $? -eq 0 ]; then
            # 記錄單個(gè)表恢復(fù)的結(jié)束時(shí)間
            TABLE_END_TIME=$(date +%s)
            TABLE_DURATION=$((TABLE_END_TIME - TABLE_START_TIME))
            # 查詢表的行數(shù)
            ROW_COUNT=$(mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \
                -e "SELECT COUNT(*) FROM \`${DB_NAME}\`.\`${TABLE_NAME}\`;" -s --skip-column-names 2>/dev/null)
            if [ $? -eq 0 ]; then
                echo "? 成功恢復(fù)表: $DB_NAME.$TABLE_NAME | 耗時(shí): ${TABLE_DURATION}秒 | 行數(shù): $ROW_COUNT"
            else
                echo "? 成功恢復(fù)表: $DB_NAME.$TABLE_NAME | 耗時(shí): ${TABLE_DURATION}秒 | 行數(shù): 查詢失敗"
            fi
            TABLE_COUNT=$((TABLE_COUNT + 1))
        else
            echo "? 錯(cuò)誤: 恢復(fù)表 $DB_NAME.$TABLE_NAME 失敗"
            FAILED_COUNT=$((FAILED_COUNT + 1))
        fi
    fi
done
# 記錄整個(gè)恢復(fù)過程的結(jié)束時(shí)間
OVERALL_END_TIME=$(date +%s)
OVERALL_DURATION=$((OVERALL_END_TIME - OVERALL_START_TIME))
echo "=========================================="
echo "數(shù)據(jù)庫 '$DB_NAME' 恢復(fù)完成!"
echo "成功恢復(fù)表: $TABLE_COUNT 個(gè)"
if [ $FAILED_COUNT -gt 0 ]; then
    echo "恢復(fù)失敗表: $FAILED_COUNT 個(gè)"
fi
echo "總耗時(shí): ${OVERALL_DURATION} 秒"
echo "備份目錄: $BACKUP_DIR"
# 顯示數(shù)據(jù)庫總行數(shù)統(tǒng)計(jì)
echo "------------------------------------------"
echo "數(shù)據(jù)庫行數(shù)統(tǒng)計(jì):"
TOTAL_ROWS=0
for TABLE_FILE in "$DB_BACKUP_DIR"/*.sql; do
    if [ -f "$TABLE_FILE" ]; then
        TABLE_NAME=$(basename "$TABLE_FILE" .sql)
        ROW_COUNT=$(mysql -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USER}" -p${MYSQL_PASS} \
            -e "SELECT COUNT(*) FROM \`${DB_NAME}\`.\`${TABLE_NAME}\`;" -s --skip-column-names 2>/dev/null)
        if [ $? -eq 0 ] && [ -n "$ROW_COUNT" ]; then
            echo "  $TABLE_NAME: $ROW_COUNT 行"
            TOTAL_ROWS=$((TOTAL_ROWS + ROW_COUNT))
        fi
    fi
done
echo "  總計(jì): $TOTAL_ROWS 行"

restore-onedb.sh 腳本代碼分析

該恢復(fù)腳本設(shè)計(jì)用于恢復(fù)單個(gè)數(shù)據(jù)庫的備份,并提供了完善的錯(cuò)誤處理、用戶交互和統(tǒng)計(jì)功能。

  • 記錄了整個(gè)恢復(fù)過程的開始和結(jié)束時(shí)間,以及每個(gè)表恢復(fù)的單獨(dú)時(shí)間,便于性能分析和優(yōu)化,特別是在處理大型數(shù)據(jù)庫時(shí)。
  • 腳本會(huì)檢查目標(biāo)數(shù)據(jù)庫是否存在,如果存在則先刪除再創(chuàng)建,確?;謴?fù)環(huán)境干凈。創(chuàng)建數(shù)據(jù)庫時(shí)指定了字符集和排序規(guī)則為utf8mb4,支持完整的Unicode字符,確保數(shù)據(jù)編碼正確性。
  • 腳本會(huì)查詢每個(gè)恢復(fù)后的表的行數(shù),用于驗(yàn)證數(shù)據(jù)恢復(fù)的完整性。

到此這篇關(guān)于一文分享MySQL數(shù)據(jù)庫備份恢復(fù)腳本的文章就介紹到這了,更多相關(guān)MySQL數(shù)據(jù)庫備份恢復(fù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mysql 記錄不存在時(shí)插入 記錄存在則更新的實(shí)現(xiàn)方法

    mysql 記錄不存在時(shí)插入 記錄存在則更新的實(shí)現(xiàn)方法

    相信很多人都需要用到這個(gè)語句,請(qǐng)看下文:(在4.1以后的版本才有效)
    2008-08-08
  • MySQL從一個(gè)表中查出數(shù)據(jù)并插入到另一個(gè)表的詳細(xì)處理方案

    MySQL從一個(gè)表中查出數(shù)據(jù)并插入到另一個(gè)表的詳細(xì)處理方案

    這篇文章主要給大家介紹了關(guān)于MySQL從一個(gè)表中查出數(shù)據(jù)并插入到另一個(gè)表的詳細(xì)處理方案,文中通過圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MySQL具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-12-12
  • Linux連接mysql報(bào)錯(cuò):Access denied for user ‘root’@‘localhost’(using password: YES)的解決方法

    Linux連接mysql報(bào)錯(cuò):Access denied for user ‘root’@‘localhost’(usi

    這篇文章主要給大家介紹了關(guān)于Linux連接mysql數(shù)據(jù)庫報(bào)錯(cuò):Access denied for user ’root‘@’localhost‘(using password: YES)的解決方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • MySQL故障切換筆記之應(yīng)用無感知設(shè)計(jì)詳解

    MySQL故障切換筆記之應(yīng)用無感知設(shè)計(jì)詳解

    這篇文章主要給大家介紹了關(guān)于MySQL故障切換筆記之應(yīng)用無感知設(shè)計(jì)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用mysql具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • MySQL的兩種分頁方式之Offset/Limit分頁和游標(biāo)分頁詳解

    MySQL的兩種分頁方式之Offset/Limit分頁和游標(biāo)分頁詳解

    這篇文章主要對(duì)比了MySQL的Offset/Limit分頁與游標(biāo)分頁,指出前者簡(jiǎn)單但存在數(shù)據(jù)漂移和性能缺陷,后者通過游標(biāo)避免這些問題且更高效,建議根據(jù)業(yè)務(wù)場(chǎng)景選擇分頁方式,深度分頁或動(dòng)態(tài)數(shù)據(jù)宜用游標(biāo)分頁,而延遲聯(lián)結(jié)可優(yōu)化Offset/Limit性能,需要的朋友可以參考下
    2025-09-09
  • mysql千萬級(jí)數(shù)據(jù)大表該如何優(yōu)化?

    mysql千萬級(jí)數(shù)據(jù)大表該如何優(yōu)化?

    如何設(shè)計(jì)或優(yōu)化千萬級(jí)別的大表?此外無其他信息,個(gè)人覺得這個(gè)話題有點(diǎn)范,就只好簡(jiǎn)單說下該如何做,對(duì)于一個(gè)存儲(chǔ)設(shè)計(jì),必須考慮業(yè)務(wù)特點(diǎn),收集的信息如下
    2011-08-08
  • MySQL快速插入大量數(shù)據(jù)的解決方案和代碼示例

    MySQL快速插入大量數(shù)據(jù)的解決方案和代碼示例

    在這篇博客中,我們將深入探討如何高效插入大量數(shù)據(jù)到MySQL數(shù)據(jù)庫,無論你是數(shù)據(jù)庫新手還是經(jīng)驗(yàn)豐富的開發(fā)者,這篇文章都將為你提供實(shí)用的解決方案和代碼示例,幫助你解決插入3萬條數(shù)據(jù)需要20多秒的問題,需要的朋友可以參考下
    2024-08-08
  • SQL字符串以及數(shù)字常用操作匯總

    SQL字符串以及數(shù)字常用操作匯總

    本篇文章是對(duì)SQL字符串以及數(shù)字的常用操作進(jìn)行了詳細(xì)的總結(jié)與分析,需要的朋友參考下
    2013-06-06
  • MySQL insert 記錄后查詢亂碼問題解決方法

    MySQL insert 記錄后查詢亂碼問題解決方法

    文章通過分析一個(gè)MySQL插入數(shù)據(jù)后查詢亂碼的問題,探討了亂碼的原因,并提出了解決方法,問題的根本原因是MySQL客戶端和服務(wù)器之間的字符集不一致,導(dǎo)致插入的中文字符被錯(cuò)誤解碼為亂碼,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • 免安轉(zhuǎn)MySQL服務(wù)的啟動(dòng)與停止方法

    免安轉(zhuǎn)MySQL服務(wù)的啟動(dòng)與停止方法

    免安轉(zhuǎn)MySQL服務(wù)的啟動(dòng)與停止方法,可以不用安裝解壓以后即可執(zhí)行,對(duì)于老手推薦,新手建議用安裝版本。
    2011-03-03

最新評(píng)論

双峰县| 洛扎县| 剑河县| 新乡市| 青冈县| 盐亭县| 赤峰市| 民县| 旬阳县| 阜宁县| 布拖县| 桃园市| 台北市| 中江县| 改则县| 长武县| 武隆县| 双峰县| 偃师市| 潞西市| 泸定县| 深圳市| 保靖县| 孝昌县| 北辰区| 班玛县| 方山县| 榕江县| 中牟县| 江阴市| 桑日县| 浏阳市| 井研县| 临沭县| 牡丹江市| 上饶市| 专栏| 濮阳县| 宜兰市| 太和县| 秭归县|