178 lines
51 KiB
JavaScript
178 lines
51 KiB
JavaScript
import{_ as i,o as a,c as n,a2 as l}from"./chunks/framework.BbmSSMjL.js";const B=JSON.parse('{"title":"11.9 备份与恢复","description":"","frontmatter":{},"headers":[],"relativePath":"zh/deploy/backup.md","filePath":"zh/deploy/backup.md"}'),h={name:"zh/deploy/backup.md"};function k(p,s,t,e,E,d){return a(),n("div",null,[...s[0]||(s[0]=[l(`<h1 id="_11-9-备份与恢复" tabindex="-1">11.9 备份与恢复 <a class="header-anchor" href="#_11-9-备份与恢复" aria-label="Permalink to "11.9 备份与恢复""></a></h1><div class="danger custom-block"><p class="custom-block-title">生产环境必须备份</p><p>数据库和上传文件必须定期备份,建议每天自动备份。备份文件应存储在独立于服务器的安全位置。</p></div><h2 id="数据库备份" tabindex="-1">数据库备份 <a class="header-anchor" href="#数据库备份" aria-label="Permalink to "数据库备份""></a></h2><h3 id="手动备份" tabindex="-1">手动备份 <a class="header-anchor" href="#手动备份" aria-label="Permalink to "手动备份""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># MySQL 全量备份(结构 + 数据)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -u root → 数据库用户名</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -proot → 数据库密码(生产环境建议用 -p 后不跟密码,交互式输入)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># rxthinkcmf... → 要备份的数据库名</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># > backup_*.sql → 输出到文件,$(date +%Y%m%d) 自动生成日期后缀</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysqldump</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -proot</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> backup_</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +%Y%m%d</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.sql</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 压缩备份(推荐 — 可节省 70%+ 磁盘空间)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># | gzip → 将 mysqldump 输出通过管道传给 gzip 压缩</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysqldump</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -proot</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> |</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> gzip</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> backup_</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +%Y%m%d</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.sql.gz</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 仅备份表结构(不含数据 — 用于对比表结构变更)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --no-data → 只导出 CREATE TABLE 语句,不导出数据</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysqldump</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -proot</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --no-data</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> schema_</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +%Y%m%d</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.sql</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 仅备份数据(不含表结构 — 用于数据迁移)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --no-create-info → 只导出 INSERT 语句,不导出 CREATE TABLE</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysqldump</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -proot</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --no-create-info</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> data_</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +%Y%m%d</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.sql</span></span></code></pre></div><div class="info custom-block"><p class="custom-block-title">大库提示</p><p>本项目初始化数据约 216MB(导出后更大),全量备份建议使用压缩(gzip),并避开业务高峰时段。</p></div><h3 id="自动备份脚本" tabindex="-1">自动备份脚本 <a class="header-anchor" href="#自动备份脚本" aria-label="Permalink to "自动备份脚本""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">#!/bin/bash</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># backup_db.sh — 数据库自动备份脚本</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 用途:自动备份 MySQL 数据库,压缩存储,自动清理过期备份</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 用法:crontab 定时调用,或手动执行 bash backup_db.sh</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 配置参数(按实际环境修改)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">BACKUP_DIR</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">/backup/mysql</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 备份文件存放目录</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">DB_NAME</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 要备份的数据库名</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">DB_USER</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">root</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 数据库用户名</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">DB_PASS</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">root</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 数据库密码</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">DATE</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +%Y%m%d_%H%M%S</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 当前时间戳(年月日_时分秒)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">KEEP_DAYS</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">30</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 保留最近 N 天的备份</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 创建备份目录(-p 参数:目录不存在时自动创建)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mkdir</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -p</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;"> $BACKUP_DIR</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 执行备份(mysqldump 输出通过管道传给 gzip 压缩)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysqldump</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;"> $DB_USER</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -p</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B56959;">$DB_PASS</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;"> $DB_NAME</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> |</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> gzip</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ></span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;"> $BACKUP_DIR</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">/backup_</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">$DATE</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.sql.gz</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 检查备份结果($? 为上一条命令的退出码,0=成功)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">if</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> [</span><span style="--shiki-dark:#BF9EEE;--shiki-dark-font-style:italic;--shiki-light:#A65E2B;--shiki-light-font-style:inherit;"> $?</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> -eq</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 0</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> ];</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> then</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> echo</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">[</span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">] 备份成功: backup_</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B56959;">$DATE</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.sql.gz</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">else</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> echo</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">[</span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">] 备份失败!</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> exit</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 1</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 非零退出码表示失败,便于监控系统捕获</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">fi</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 清理过期备份</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># find 参数说明:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -name "backup_*.sql.gz" → 匹配备份文件名格式</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -mtime +$KEEP_DAYS → 修改时间超过 N 天的文件</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -delete → 删除匹配的文件</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">find</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;"> $BACKUP_DIR</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -name</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">backup_*.sql.gz</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -mtime</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">$KEEP_DAYS</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -delete</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">echo</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">[</span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">] 清理完成,保留最近 </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B56959;">$KEEP_DAYS</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> 天的备份</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span></code></pre></div><h3 id="配置定时备份" tabindex="-1">配置定时备份 <a class="header-anchor" href="#配置定时备份" aria-label="Permalink to "配置定时备份""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 编辑当前用户的 crontab 定时任务</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">crontab</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -e</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 定时备份规则</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 格式:分 时 日 月 周 命令</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 0 3 * * * → 每天凌晨 3:00 执行</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 0 4 * * 0 → 每周日凌晨 4:00 执行(0=周日)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># >> /var/log/backup.log 2>&1 → 追加日志(2>&1 将错误也写入日志)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">0</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 3</span><span style="--shiki-dark:#BF9EEE;--shiki-dark-font-style:italic;--shiki-light:#A65E2B;--shiki-light-font-style:inherit;"> *</span><span style="--shiki-dark:#BF9EEE;--shiki-dark-font-style:italic;--shiki-light:#A65E2B;--shiki-light-font-style:inherit;"> *</span><span style="--shiki-dark:#BF9EEE;--shiki-dark-font-style:italic;--shiki-light:#A65E2B;--shiki-light-font-style:inherit;"> *</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /www/scripts/backup_db.sh</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> >></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /var/log/backup.log</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> 2>&1</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">0</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 4</span><span style="--shiki-dark:#BF9EEE;--shiki-dark-font-style:italic;--shiki-light:#A65E2B;--shiki-light-font-style:inherit;"> *</span><span style="--shiki-dark:#BF9EEE;--shiki-dark-font-style:italic;--shiki-light:#A65E2B;--shiki-light-font-style:inherit;"> *</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 0</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /www/scripts/backup_db_full.sh</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> >></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /var/log/backup.log</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> 2>&1</span></span></code></pre></div><h2 id="上传文件备份" tabindex="-1">上传文件备份 <a class="header-anchor" href="#上传文件备份" aria-label="Permalink to "上传文件备份""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 备份上传目录为压缩包</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># tar 参数说明:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -c → 创建新归档</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -z → 用 gzip 压缩</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -f → 指定输出文件名</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># $(date +%Y%m%d) → 自动生成日期后缀</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 本项目上传目录默认在 public/uploads/(FILE_UPLOAD_DIR=uploads)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">tar</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -czf</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /backup/uploads_</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +%Y%m%d</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.tar.gz</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /www/api/public/uploads/</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 上传文件自动备份脚本</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">#!/bin/bash</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">BACKUP_DIR</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">/backup/uploads</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 备份存放目录</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">DATE</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +%Y%m%d</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 日期后缀</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mkdir</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -p</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;"> $BACKUP_DIR</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 创建目录(如不存在)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">tar</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -czf</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;"> $BACKUP_DIR</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">/uploads_</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">$DATE</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.tar.gz</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /www/api/public/uploads/</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 压缩打包</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">find</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;"> $BACKUP_DIR</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -name</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">uploads_*.tar.gz</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -mtime</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +30</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -delete</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 清理 30 天前的备份</span></span></code></pre></div><h2 id="恢复" tabindex="-1">恢复 <a class="header-anchor" href="#恢复" aria-label="Permalink to "恢复""></a></h2><h3 id="恢复数据库" tabindex="-1">恢复数据库 <a class="header-anchor" href="#恢复数据库" aria-label="Permalink to "恢复数据库""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 从 SQL 文件恢复(全量覆盖)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># < backup_*.sql → 将文件内容作为 mysql 命令的输入</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -proot</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> <</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> backup_20260920.sql</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 从压缩文件恢复(gunzip 解压后传给 mysql)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># gunzip < file.sql.gz → 解压并输出到标准输出</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># | mysql → 通过管道传给 mysql 命令执行</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">gunzip</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> <</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> backup_20260920.sql.gz</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> |</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -proot</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf.laravel13.naivevue</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 恢复到新数据库(安全起见 — 先验证再切换)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 1. 创建临时验证数据库</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -proot</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -e</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">CREATE DATABASE </span><span style="--shiki-dark:#F286C4;--shiki-light:#A65E2B;">\\\`</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">rxthinkcmf.laravel13.naivevue_restore</span><span style="--shiki-dark:#F286C4;--shiki-light:#A65E2B;">\\\`</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">;</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 2. 恢复备份到临时库</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -proot</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf.laravel13.naivevue_restore</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> <</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> backup_20260920.sql</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 3. 验证数据无误后,重命名数据库(需停机操作)</span></span></code></pre></div><div class="warning custom-block"><p class="custom-block-title">恢复后清理缓存</p><p>恢复数据库后务必执行 <code>php artisan cache:clear</code>(或 <code>php artisan dict:clear-cache</code>),避免 Redis 中的旧字典/参数缓存与新数据不一致。</p></div><h3 id="恢复上传文件" tabindex="-1">恢复上传文件 <a class="header-anchor" href="#恢复上传文件" aria-label="Permalink to "恢复上传文件""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 恢复上传目录到原始位置</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># tar 参数说明:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -x → 解压归档</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -z → 解压 gzip</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -f → 指定归档文件</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -C → 解压到指定目录(/ 表示按归档内的绝对路径还原)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">tar</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -xzf</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /backup/uploads_20260920.tar.gz</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -C</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 仅恢复特定子目录(如只恢复文章附件)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 在归档文件名后追加要解压的路径前缀</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">tar</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -xzf</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /backup/uploads_20260920.tar.gz</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -C</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> www/api/public/uploads/article/</span></span></code></pre></div><h2 id="备份验证" tabindex="-1">备份验证 <a class="header-anchor" href="#备份验证" aria-label="Permalink to "备份验证""></a></h2><div class="warning custom-block"><p class="custom-block-title">必须定期验证备份</p><p>备份文件必须定期恢复验证,确保备份可用。建议每月进行一次恢复测试。</p></div><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">#!/bin/bash</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># verify_backup.sh — 备份验证脚本</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 用途:将备份恢复到临时数据库,验证数据完整性后清理</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 用法:bash verify_backup.sh backup_20260920.sql.gz</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">BACKUP_FILE</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#FFB86C;--shiki-dark-font-style:italic;--shiki-light:#B07D48;--shiki-light-font-style:inherit;">$1</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 第一个参数:备份文件路径</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">VERIFY_DB</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">rxthinkcmf.laravel13.naivevue_verify</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 临时验证数据库名</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 创建验证数据库(先删除旧的,再创建新的)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># DROP DATABASE IF EXISTS → 如果存在则删除(避免同名冲突)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -p</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -e</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">DROP DATABASE IF EXISTS </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B56959;">$VERIFY_DB</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">; CREATE DATABASE </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B56959;">$VERIFY_DB</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">;</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 恢复备份到验证数据库</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">gunzip</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> <</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;"> $BACKUP_FILE</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> |</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -p</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;"> $VERIFY_DB</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 验证数据完整性</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -N → 不输出表头(只输出数据值)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># information_schema.tables → MySQL 系统表,存储所有表的元信息</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">TABLE_COUNT</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -p</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -N</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -e</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B56959;">$VERIFY_DB</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">';</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">echo</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">恢复的表数量: </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B56959;">$TABLE_COUNT</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 检查用户表数据量(验证核心数据是否完整,注意本项目表前缀为 laravel_)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">USER_COUNT</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -p</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -N</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -e</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">SELECT COUNT(*) FROM </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B56959;">$VERIFY_DB</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.laravel_user;</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">echo</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">用户数量: </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B56959;">$USER_COUNT</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 清理验证数据库(验证完毕后删除临时库)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> root</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -p</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -e</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">DROP DATABASE </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B56959;">$VERIFY_DB</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">;</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">echo</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">备份验证完成</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span></code></pre></div><h2 id="备份存储建议" tabindex="-1">备份存储建议 <a class="header-anchor" href="#备份存储建议" aria-label="Permalink to "备份存储建议""></a></h2><table tabindex="0"><thead><tr><th>存储方式</th><th>优点</th><th>缺点</th></tr></thead><tbody><tr><td>本地磁盘</td><td>速度快</td><td>服务器故障可能丢失</td></tr><tr><td>NAS / 网络存储</td><td>独立于服务器</td><td>需要网络</td></tr><tr><td>云存储(OSS/S3)</td><td>高可靠、异地</td><td>需要付费</td></tr><tr><td>异地服务器</td><td>灾难恢复</td><td>需要维护</td></tr></tbody></table><div class="tip custom-block"><p class="custom-block-title">最佳实践</p><ul><li>本地保留最近 7 天的备份</li><li>异地保留最近 30 天的备份</li><li>每月进行一次恢复测试</li><li>备份文件加密存储(如含敏感数据)</li><li>数据库与 <code>public/uploads/</code>、<code>.env</code> 一并纳入备份范围(.env 单独加密保管)</li></ul></div>`,24)])])}const A=i(h,[["render",k]]);export{B as __pageData,A as default};
|