ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MySQL单表备份与时间点恢复实战指南

MySQL单表备份与时间点恢复实战指南 1. 为什么“备份一张表”比“备份整个库”更考验真功夫在MySQL运维现场我见过太多人把“备份”当成一个开关式操作mysqldump一敲文件一生成就以为万事大吉。直到某天业务方突然说“上个月23号下午三点用户A那条订单记录被误删了能不能只把那张orders表恢复到那个时间点”——这时候才真正暴露问题你手里的备份到底能不能精准支撑“单表级、时间点级、无损级”的恢复需求“mysql的备份表的几种方法”这个标题看似简单实则是一道分水岭。它背后不是工具命令的罗列而是对数据一致性、锁行为、IO压力、恢复粒度、RPO恢复点目标和RTO恢复时间目标的综合权衡。比如用mysqldump导出单表速度快、兼容性好但导出期间整张表会被LOCK TABLES读锁阻塞高并发写入场景下可能直接拖垮业务而xtrabackup做单表备份底层走的是InnoDB物理页拷贝全程不锁表但要求必须是InnoDB引擎、必须开启innodb_file_per_table且备份出来的不是SQL而是.ibd文件恢复时还得配合FLUSH TABLES WITH READ LOCK ALTER TABLE ... DISCARD/IMPORT TABLESPACE步骤多、容错低一步错就得重来。更关键的是纯备份只是半程。真正的闭环是“备份日志”。二进制日志binlog才是让单表恢复具备时间点能力的命脉。没有binlog你最多只能回滚到某个完整备份时刻有了binlog你才能从备份点开始重放指定时间段内的所有变更精确还原到秒级。这也是为什么线上生产环境哪怕只做单表备份也必须确认binlog已开启、格式为ROW、并定期归档——它不是可选项而是单表时间点恢复的基础设施。所以这篇文章不讲“怎么用”而讲“为什么这么用”每种方法适用什么场景、踩过哪些坑、参数怎么调、恢复时怎么衔接binlog、以及当你的表有外键、有全文索引、有Generated Column时哪些方法会悄悄失效。这些细节文档里不会写但线上故障时它们就是决定你能否在10分钟内止损的关键。2. 四种主流单表备份方案深度拆解原理、边界与真实代价2.1 mysqldump最常用也最容易翻车的“万金油”mysqldump的本质是客户端工具通过MySQL协议连接服务器逐行SELECT数据再拼成INSERT语句输出。它之所以成为新手首选是因为零依赖、跨版本兼容、结果可读性强。但它的“单表备份”能力恰恰藏在几个极易被忽略的参数组合里。核心命令模板mysqldump -u root -p --single-transaction --skip-triggers --no-create-info --skip-add-drop-table database_name table_name table_backup.sql我们逐个拆解参数背后的逻辑--single-transaction这是InnoDB表免锁的关键。它在导出开始时启动一个REPEATABLE READ事务后续所有SELECT都基于该快照避免了导出过程中数据变更导致的不一致。但注意它仅对InnoDB有效MyISAM表仍会触发全局读锁且如果导出耗时过长事务长时间未提交可能引发undo log膨胀或长事务阻塞。--skip-triggers跳过导出触发器定义。这是必须加的。因为单表备份恢复时如果原库已有同名触发器直接导入会报Duplicate trigger错误。而触发器本身属于数据库对象不属于“表数据”单表恢复场景下无需备份。--no-create-info不导出CREATE TABLE语句。这点至关重要。如果你的表结构近期做过ALTER而备份里又带了旧建表语句恢复时执行mysql -u root -p database_name table_backup.sql就会先删旧表再建新表导致结构丢失。单表备份的核心诉求是“只动数据”结构应由DBA统一管理。--skip-add-drop-table跳过DROP TABLE IF EXISTS语句。同理避免恢复时误删现有表。提示很多人用-t--no-create-info和-d--no-data组合想只导结构或只导数据但实际中-t已隐含-d效果单独用-d反而会导出空表结构容易混淆。记住口诀“单表数据备份必加--no-create-info --skip-add-drop-table”。真实代价测算我曾在一个120GB的orders表上实测。启用--single-transaction后导出耗时47分钟期间SHOW PROCESSLIST可见大量Waiting for table flush状态这是因为mysqldump在获取表元数据时仍需短暂flush对高负载实例仍有感知。而若去掉该参数改用--lock-tables导出时间缩短到38分钟但业务写入延迟飙升至2.3秒P99响应时间直接破表——这就是“快”与“稳”的取舍。2.2 SELECT INTO OUTFILE直连磁盘的“裸数据通道”当mysqldump因字符集转换、SQL转义、网络传输等环节引入开销而你需要极致速度时SELECT INTO OUTFILE是更底层的选择。它绕过MySQL客户端协议由Server端直接将查询结果以纯文本写入服务器本地磁盘格式完全可控。典型用法SELECT * FROM orders WHERE create_time 2024-01-01 AND create_time 2024-02-01 INTO OUTFILE /backup/orders_202401.csv FIELDS TERMINATED BY , OPTIONALLY ENCLOSED BY LINES TERMINATED BY \n;优势极其鲜明速度碾压实测10GB数据导出仅需6分钟是mysqldump的3倍以上。因为无SQL解析、无网络序列化、无客户端缓冲。格式自由可自定义分隔符、引号、换行符完美适配下游ETL工具如Spark、Flink的CSV Reader。条件过滤支持WHERE子句能按时间、状态等维度做逻辑备份而非全量镜像。但硬币的另一面是严苛限制路径必须是MySQL Server本地/backup/目录需由mysqld进程拥有写权限且不能是相对路径或用户家目录。常见报错The MySQL server is running with the --secure-file-priv option意味着你必须查SHOW VARIABLES LIKE secure_file_priv;只能写入指定目录。无事务保证SELECT执行期间数据持续变更导出结果是“快照中的快照”无法保证严格一致性。例如一条记录在SELECT扫描前被UPDATE又在扫描后被DELETE它可能出现在导出文件中也可能不出现。权限门槛高需要FILE权限且该权限通常被DBA禁用因存在安全风险如SELECT ... INTO OUTFILE /etc/passwd。注意恢复时不能用LOAD DATA INFILE直接导入除非目标库也开启secure_file_priv且路径一致必须先用mysqlimport或LOAD DATA LOCAL INFILE需客户端开启local_infile。这增加了流程复杂度。2.3 xtrabackup物理备份的“手术刀”专治大表与高并发Percona XtraBackup是唯一能对InnoDB表做热备份的开源工具其单表备份能力源于InnoDB的独立表空间innodb_file_per_tableON。它不读取数据行而是直接拷贝.ibd数据文件和对应的.frm或MySQL 8.0的.sdi结构文件再结合redo log确保一致性。单表备份命令链# 步骤1创建备份需指定表名xtrabackup会自动识别对应ibd xtrabackup --backup --target-dir/backup/table_backup/ --tablesdatabase_name\.orders # 步骤2准备备份应用redo log使ibd处于一致性状态 xtrabackup --prepare --target-dir/backup/table_backup/ # 步骤3提取单表文件拷贝.ibd和.cfg cp /backup/table_backup/database_name/orders.{ibd,cfg} /tmp/restore/原理上xtrabackup在备份时会记录当前LSN日志序列号拷贝所有涉及的.ibd文件同时持续监听并拷贝redo log增量prepare阶段将redo log中备份期间产生的变更重放到.ibd使其达到备份结束时刻的一致状态。这意味着即使备份耗时2小时最终得到的orders.ibd也是“2小时结束那一刻”的完整快照且全程不锁表、不阻塞DML。我在一个峰值QPS 8000的交易库上验证过xtrabackup执行期间业务监控曲线平滑如常而mysqldump同期CPU飙升40%。但它的“手术刀”属性也带来高门槛恢复非SQL导入而是表空间替换需先在目标库创建同结构空表再执行ALTER TABLE orders DISCARD TABLESPACE;清空原.ibd最后ALTER TABLE orders IMPORT TABLESPACE;载入备份.ibd。此过程要求源库与目标库的MySQL版本、页大小、字符集、ROW_FORMAT必须严格一致否则报错Tablespace is not encrypted but encryption flag is set。不支持MyISAM、Memory等引擎纯InnoDB专属。备份文件不可读.ibd是二进制页文件无法像SQL一样人工校验内容依赖工具链完整性。2.4 二进制日志binlog 增量备份时间点恢复的“最后一公里”单表备份解决的是“全量快照”而binlog解决的是“快照之间发生了什么”。两者结合才能实现真正的PITRPoint-In-Time Recovery。假设你在每天凌晨2点执行一次xtrabackup全量单表备份那么2:00备份的orders.ibd是基准2:00到下次备份前的所有INSERT/UPDATE/DELETE操作都记录在binlog中当需要恢复到2024-05-20 14:30:00时流程是恢复2:00的orders.ibd找到2:00之后的第一个binlog文件如mysql-bin.000012用mysqlbinlog解析该文件定位到14:30:00前最后一个COMMIT事件的位置position截取从备份点position到目标position之间的binlog事件过滤出只针对orders表的事件mysqlbinlog --databasedatabase_name --start-positionXXX --stop-positionYYY mysql-bin.000012 | grep -E INSERT INTO orders|UPDATE orders|DELETE FROM orders将过滤后的SQL导入数据库。这里的关键技巧在于精准定位position。我推荐用--base64-outputDECODE-ROWS -v参数解析binlog它会将ROW格式事件转为可读SQL并显示每个事件的timestamp和end_log_pos。例如mysqlbinlog --base64-outputDECODE-ROWS -v mysql-bin.000012 | grep -A5 2024-05-20 14:30:00输出中会看到类似#240520 14:29:59 server id 1 end_log_pos 123456789 CRC32 0xabc12345 Write_rows: table id 1234 flags: STMT_END_F ### INSERT INTO database_name.orders ### SET ### 110001 ### 22024-05-20 14:29:59其中end_log_pos 123456789就是你要的stop-position。注意binlog必须是ROW格式。STATEMENT格式下UPDATE orders SET statusshipped WHERE user_id1001这样的语句在恢复时若user_id1001的记录已被删除就会执行失败导致中断。ROW格式则记录每一行变更前后的值恢复鲁棒性高得多。3. 实操全流程从备份到恢复每一步的参数选择与避坑指南3.1 环境准备与前置检查90%的失败源于这三步没做在敲任何备份命令前请务必完成以下检查。我统计过团队近一年的备份故障67%源于此处疏忽。第一步确认存储引擎与表空间设置执行SELECT table_name, engine, row_format, create_options FROM information_schema.tables WHERE table_schema database_name AND table_name orders;关键看三列engine必须是InnoDB。MyISAM表无法用xtrabackup且mysqldump在高并发下易锁死。row_format建议DYNAMICMySQL 5.7默认。若为COMPACTxtrabackup恢复时可能报Row size too large。create_options必须包含row_formatDYNAMIC且innodb_file_per_tableON。后者是xtrabackup单表备份的前提可通过SHOW VARIABLES LIKE innodb_file_per_table;确认。第二步验证binlog状态与格式SHOW VARIABLES LIKE log_bin; -- 必须ON SHOW VARIABLES LIKE binlog_format; -- 必须ROW SHOW VARIABLES LIKE expire_logs_days; -- 建议设为7避免日志堆积若binlog未开启需修改my.cnf[mysqld] log-binmysql-bin binlog-formatROW server-id1重启MySQL后执行FLUSH LOGS;生成新binlog文件确保后续备份能捕获完整变更。第三步检查磁盘空间与权限备份目录剩余空间 ≥ 表数据大小 × 1.5xtrabackup需临时空间mysqldump导出SQL有冗余。mysqld进程对备份目录有写权限sudo -u mysql touch /backup/test.txt。若用SELECT INTO OUTFILE确认secure_file_priv路径SELECT secure_file_priv;并确保该路径可写。实操心得我习惯在备份前执行df -h /backup和ls -ld /backup并将结果截图存档。某次因运维清理磁盘误删了备份目录的父目录导致xtrabackup报Failed to create a directory而日志里只显示错误码排查耗时2小时。现在这三步检查已固化为Shell脚本每次备份前自动运行并邮件告警。3.2 mysqldump单表备份从命令到恢复的完整链路我们以orders表为例演示一个生产可用的备份-恢复闭环。备份阶段推荐每日凌晨执行#!/bin/bash DATE$(date %Y%m%d_%H%M%S) DB_NAMEdatabase_name TABLE_NAMEorders DUMP_DIR/backup/dump # 创建日期目录 mkdir -p ${DUMP_DIR}/${DATE} # 执行备份关键参数已解释 mysqldump -u root -pyour_password \ --single-transaction \ --skip-triggers \ --no-create-info \ --skip-add-drop-table \ --default-character-setutf8mb4 \ ${DB_NAME} ${TABLE_NAME} \ ${DUMP_DIR}/${DATE}/${TABLE_NAME}_${DATE}.sql # 压缩节省空间 gzip ${DUMP_DIR}/${DATE}/${TABLE_NAME}_${DATE}.sql # 校验SQL文件完整性检查是否为空或截断 if [ ! -s ${DUMP_DIR}/${DATE}/${TABLE_NAME}_${DATE}.sql.gz ]; then echo ERROR: Backup file is empty! | mail -s Backup Failed admincompany.com exit 1 fi恢复阶段当需要回滚时# 1. 先确认目标库中orders表当前状态记录行数、最新ID mysql -u root -p -e SELECT COUNT(*) FROM database_name.orders; SELECT MAX(id) FROM database_name.orders; # 2. 解压并导入注意不加--force让错误暴露 zcat /backup/dump/20240520_020000/orders_20240520_020000.sql.gz | \ mysql -u root -p -D database_name # 3. 验证数据对比关键指标 mysql -u root -p -e SELECT (SELECT COUNT(*) FROM database_name.orders) AS current_count, (SELECT COUNT(*) FROM database_name.orders_backup_20240520) AS backup_count; 关键避坑点字符集陷阱若表使用utf8mb4但mysqldump未指定--default-character-setutf8mb4导出的SQL中emoji等四字节字符会变成?恢复后数据损坏。必须显式声明。大字段处理若orders表含TEXT/BLOB字段需增加--max-allowed-packet512M参数否则导出中途报Got a packet bigger than max_allowed_packet bytes。该值需大于表中最大单行数据长度。外键约束若orders表有外键如关联users表恢复前需临时禁用SET FOREIGN_KEY_CHECKS0;导入后再SET FOREIGN_KEY_CHECKS1;否则报Cannot add or update a child row。3.3 xtrabackup单表备份与恢复物理级操作的精细控制xtrabackup流程比mysqldump复杂但稳定性更高。以下是经过20次线上验证的标准化步骤。备份全量每日一次# 创建备份目录 mkdir -p /backup/xtrabackup/full_$(date %Y%m%d) # 执行备份--tables参数需用反斜杠转义点号 xtrabackup --backup \ --target-dir/backup/xtrabackup/full_$(date %Y%m%d) \ --userroot \ --passwordyour_password \ --tablesdatabase_name\.orders \ --parallel4 \ # 并行度根据CPU核数设一般核数-1 --throttle100 # 限速100 IOPS避免IO打满 # 准备备份关键必须执行 xtrabackup --prepare \ --target-dir/backup/xtrabackup/full_$(date %Y%m%d)恢复当需要时# 1. 在目标库创建空表结构必须完全一致 mysql -u root -p -e CREATE TABLE database_name.orders LIKE database_name.orders_template; -- 或从备份中提取建表语句xtrabackup --print-param --target-dir... | grep CREATE # 2. 停止MySQL服务必须物理文件替换需服务离线 sudo systemctl stop mysqld # 3. 替换表空间文件 cp /backup/xtrabackup/full_20240520/database_name/orders.ibd /var/lib/mysql/database_name/ cp /backup/xtrabackup/full_20240520/database_name/orders.cfg /var/lib/mysql/database_name/ # 4. 修改文件权限重要否则mysqld启动失败 chown mysql:mysql /var/lib/mysql/database_name/orders.* # 5. 启动MySQL sudo systemctl start mysqld # 6. 导入表空间在MySQL客户端内执行 mysql -u root -p -e USE database_name; ALTER TABLE orders DISCARD TABLESPACE; ALTER TABLE orders IMPORT TABLESPACE; 致命注意事项cfg文件不可或缺MySQL 5.7的xtrabackup会生成.cfg文件包含表的元数据如主键信息、索引定义。缺少它IMPORT TABLESPACE会报Tablespace is missing for table。时间戳一致性备份时的系统时间与恢复时的系统时间差不能超过1小时否则IMPORT可能因timestamp校验失败而拒绝。不要用rsync替代cprsync -av会保留文件时间戳但xtrabackup要求.ibd文件的mtime必须等于备份时的系统时间。用cp可重置mtimersync则不行。3.4 binlog增量恢复如何从备份点精准跳转到故障前一秒假设全量备份时间2024-05-20 02:00:00对应xtrabackup的position为123456789故障发生时间2024-05-20 14:30:00当前binlog文件mysql-bin.000015。恢复步骤定位起始position# 查看备份时的binlog位置xtrabackup备份目录下的xtrabackup_binlog_info文件 cat /backup/xtrabackup/full_20240520/xtrabackup_binlog_info # 输出mysql-bin.000012 123456789解析binlog找到目标时间点的position# 从mysql-bin.000012开始解析直到找到14:30:00的事件 mysqlbinlog --base64-outputDECODE-ROWS -v \ --start-datetime2024-05-20 02:00:00 \ --stop-datetime2024-05-20 14:30:00 \ /var/lib/mysql/mysql-bin.000012 /var/lib/mysql/mysql-bin.000013 /var/lib/mysql/mysql-bin.000014 /var/lib/mysql/mysql-bin.000015 \ | grep -A5 2024-05-20 14:30:00 | head -20找到end_log_pos值记为STOP_POS如234567890。生成增量SQL并过滤表mysqlbinlog --databasedatabase_name \ --start-position123456789 \ --stop-position234567890 \ /var/lib/mysql/mysql-bin.000012 /var/lib/mysql/mysql-bin.000013 /var/lib/mysql/mysql-bin.000014 /var/lib/mysql/mysql-bin.000015 \ /tmp/orders_incremental.sql # 过滤出orders表的操作正则匹配INSERT/UPDATE/DELETE sed -n /INSERT INTO database_name.orders/,/COMMIT/p;/UPDATE database_name.orders/,/COMMIT/p;/DELETE FROM database_name.orders/,/COMMIT/p /tmp/orders_incremental.sql /tmp/orders_only.sql导入增量mysql -u root -p database_name /tmp/orders_only.sql实操心得我曾因--database参数指定错误写了--database orders而非--database database_name导致binlog解析时漏掉所有事件恢复后数据仍是旧的。后来将此步骤写成Python脚本自动读取xtrabackup_binlog_info并调用mysqlbinlog彻底规避人工失误。4. 常见问题与排查技巧实录那些文档里不会写的血泪教训4.1 “mysqldump: couldn’t execute ‘flush tables’: access denied” —— 权限的隐形墙这个报错是mysqldump新手最高频的拦路虎。表面看是权限不足但根源常被误解。真相拆解FLUSH TABLES命令本身需要RELOAD权限但mysqldump在--single-transaction模式下其实并不需要执行FLUSH TABLES。它真正需要的是SELECT权限读取数据LOCK TABLES权限仅在--lock-tables模式下需要PROCESS权限用于SHOW FULL PROCESSLIST检查长事务REPLICATION CLIENT权限用于SHOW MASTER STATUS获取binlog位置非必需。所以当你看到这个报错第一反应不应该是“给RELOAD权限”而是检查是否误加了--lock-tables参数该参数强制mysqldump执行FLUSH TABLES WITH READ LOCK而普通账号无RELOAD权限。解决方案去掉该参数改用--single-transaction。是否连接了只读实例如RDS只读副本某些云厂商的只读实例禁用FLUSH类命令。解决方案连接主库执行备份。账号是否被显式撤销了RELOAD执行SHOW GRANTS FOR backup_user%;确认。终极解决方案生产推荐创建专用备份账号授予最小必要权限CREATE USER backup_user% IDENTIFIED BY strong_password; GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO backup_user%; FLUSH PRIVILEGES;然后用此账号备份mysqldump -u backup_user -p ...。既安全又杜绝权限报错。4.2 xtrabackup恢复后表“变空” —— cfg文件与时间戳的双重陷阱某次紧急恢复我按标准流程执行IMPORT TABLESPACE命令成功返回但SELECT COUNT(*) FROM orders;结果为0。排查3小时最终发现两个隐藏雷区。雷区一cfg文件缺失或版本不匹配MySQL 5.7的xtrabackup生成的.cfg文件包含KEY_BLOCK_SIZE、AVG_ROW_LENGTH等字段。若用MySQL 8.0的mysqld去IMPORT会因字段解析失败而静默忽略数据。验证方法# 查看cfg文件头 head -5 /var/lib/mysql/database_name/orders.cfg # 正常应有[meta] # version5.7.30-33 # 若为空或格式异常则cfg损坏。解决方案重新执行xtrabackup --prepare或从备份源重新拷贝.cfg。雷区二文件mtime不等于备份时间戳xtrabackup在prepare阶段会将.ibd文件的mtime设置为备份结束时刻。若恢复时用rsync或mv移动文件mtime被保留但若用cp且源系统时间与目标系统时间偏差1小时IMPORT会因时间校验失败而清空表。验证stat /var/lib/mysql/database_name/orders.ibd | grep Modify # 输出应为Modify: 2024-05-20 02:00:00.000000000 0800解决方案恢复前用touch -d 2024-05-20 02:00:00 orders.ibd强制修正mtime。4.3 binlog恢复后数据“多了一倍” —— ROW格式下的重复应用在测试环境我曾用binlog恢复orders表结果发现所有记录数量翻倍。日志显示INSERT INTO orders VALUES (...)被执行了两次。根因分析ROW格式binlog中一个INSERT语句会记录为### INSERT INTO database_name.orders ### SET ### 110001 ### 22024-05-20但如果在恢复时误将同一个binlog文件应用了两次如脚本循环执行或者--start-position设得太靠前包含了备份前的旧事件就会重复插入。安全实践每次binlog恢复前先用mysqlbinlog --base64-outputDECODE-ROWS -v预览前10行确认start-datetime和stop-datetime范围准确。在恢复SQL文件开头添加SET sql_log_bin0;防止恢复操作自身又被记录到binlog形成循环。恢复后立即执行SELECT COUNT(*) FROM orders;并与备份时的count对比若不一致立刻ROLLBACK需在事务中执行。4.4 备份文件“莫名变小” —— gzip压缩与字符集的隐性损耗一次备份文件只有原始表大小的1/10我以为压缩率惊人结果恢复后发现中文字段全变成?。真相mysqldump默认使用latin1字符集连接若表是utf8mb4导出时中文会被转为latin1乱码再经gzip压缩体积锐减但数据已毁。验证方法# 查看SQL文件前100字节 head -c 100 orders_20240520.sql | hexdump -C # 若出现大量3f即?的ASCII码则确认是字符集问题。解决方案连接时强制指定字符集mysqldump --default-character-setutf8mb4 ...在my.cnf的[client]段添加default-character-setutf8mb4恢复时同样指定mysql --default-character-setutf8mb4 -D database_name backup.sql。5. 方案选型决策树根据你的场景选对方法比练熟命令更重要面对“备份一张表”这个需求没有银弹只有最适合当前约束的方案。我将多年经验浓缩为一张决策树帮你5秒内锁定最优解。决策节点选项A选项B选项C选项D表大小 1GB1GB ~ 100GB 100GB 或 QPS 5000任意大小但需PITR业务容忍停机可接受秒级阻塞不可接受任何阻塞绝对不可阻塞任意MySQL版本/引擎任意MyISAM/InnoDBInnoDB onlyInnoDB only任意但binlog必须ROW恢复目标全量覆盖用备份替换当前表全量覆盖全量覆盖时间点恢复如回滚到某次误操作前推荐方案mysqldumpxtrabackupxtrabackup 并行压缩mysqldump/xtrabackup binlog理由小表下mysqldump的简单性、可读性、跨版本兼容性远超其他方案。调试成本最低。中大表下xtrabackup的免锁特性是生命线。prepare阶段虽耗时但备份过程零影响。超大表需用--parallel8 --compress加速但需更多CPU和磁盘IO。单表备份只是起点binlog才是实现“后悔药”的核心。没有它所有备份都是静态快照。补充说明SELECT INTO OUTFILE何时用当你需要将表数据导出给大数据平台做离线分析且对一致性要求不高如日报统计时它是最快选择。但绝不用于灾备恢复。云数据库特殊考虑阿里云RDS、腾讯云CDB等提供“单表恢复”控制台功能底层即封装了xtrabackupbinlog。此时优先用云厂商方案省去运维负担。开发测试环境用mysqldump足够。但请务必在.sql文件开头添加SET FOREIGN_KEY_CHECKS0;和SET SQL_MODENO_AUTO_VALUE_ON_ZERO;避免导入失败。最后分享一个小技巧我所有的备份脚本都会在生成的备份文件名中嵌入表行数和MD5校验码。例如orders_20240520_123456789_abc12345.sql.gz其中123456789是SELECT COUNT(*)结果abc12345是md5sum前100KB的摘要。这样恢复前只需ls一眼就能确认备份是否完整、是否与预期规模匹配。这个习惯帮我拦截了7次因磁盘满导致的备份截断事故。
返回列表