
文章目录1.手动备份2.win下自动备份3.centos下自动备份3.1 使用crond执行定时任务3.2 使用Systemd Timers执行定时任务4.docker下自动备份5.使用LUA脚本自动备份1.手动备份mysqldump-uroot-proot123testC:/Users/Administrator/Desktop/temp/test/test.sql上面的命令已经可以完成最基本的数据库备份。实际使用时还可以根据数据库类型和备份内容增加一些常用参数参数作用适用场景 / 注意事项--single-transaction使用一致性事务快照进行导出适合以 InnoDB 为主的在线备份可以减少备份过程中对正常读写的影响。主要保证事务型表的一致性备份期间应尽量避免ALTER TABLE、DROP TABLE等 DDL 操作--quick一边读取数据一边写入备份文件避免一次性将大量结果缓存在客户端内存中适合大表备份。mysqldump默认开启的--opt已包含--quick显式写出主要是为了让含义更加直观--routines同时备份存储过程和存储函数普通备份默认不会包含存储过程、函数数据库中使用了这些对象时建议添加--events同时备份 Event Scheduler 定时事件数据库中使用了 MySQL Event 时需要添加默认不会导出--triggers同时备份触发器mysqldump默认已经启用一般不需要额外指定对于主要使用 InnoDB 的普通业务数据库可以写成mysqldump--single-transaction --quick -uroot -p 数据库名 backup.sql2.win下自动备份echo off :: 您的dump工具所在目录cd/d D:\mysql\mysql-8.0.19-winx64\bin mysqldump-uroot-proot123testC:/Users/Administrator/Desktop/temp/test/test.sql调出任务计划程序一直下一步填写就行直接在命令行中明文使用账号和密码会产生警告mysqldump: [Warning] Using a password on the command line interface can be insecure.虽然能成功执行但是毕竟不安全。可以将账号密码配置在配置文件my.ini中降低风险[mysqldump] userroot passwordroot123然后从外部引入echo off :: 您的dump工具所在目录cd/d D:\mysql\mysql-8.0.19-winx64 :: 注意文件路径要与自己路径相符 bin\mysqldump.exe --defaults-filemy.initestC:/Users/Administrator/Desktop/temp/test/test.sql还可以在外部灵活配置要导出的数据库名在外面新建一个文件保存数据库名然后在bat中引用echo off :: 读取外部文件内容,注意外部文件所在路径set/pNAMEdbname.txt :: 您的dump工具所在目录cd/d D:\mysql\mysql-8.0.19-winx64 bin\mysqldump.exe --defaults-filemy.ini%NAME%C:/Users/Administrator/Desktop/temp/test/test.sql将bat文件略做修改可以进行批量备份echo off REM 请替换以下路径为实际的文件路径setfilenamedbname.txtechofilenamefor/ftokens*%%ain(%filename%)do(echoContent: %%a D:\mysql\mysql-8.0.19-winx64\bin\mysqldump.exe --defaults-fileD:\mysql\mysql-8.0.19-winx64\my.ini%%aC:/Users/Administrator/Desktop/temp/test/%%a.sql)pause如果不想出现黑窗口的话可以将bat转exe将pause换成exit。可以动态获取保存目录↓echo offcd/d %MYSQL_HOME% REM 请替换以下路径为实际的文件路径setfilenamedbname.txt REM 请替换以下路径为实际的文件路径setbackup_dir./backupREM 检测 backup 目录是否存在不存在则新建ifnot exist%backup_dir%(mkdir%backup_dir%)for/ftokens*%%ain(%filename%)do(echoContent: %%a bin\mysqldump.exe --defaults-filemy.ini%%a./backup/%%a.sql)::pause 用timeout暂停后自动退出更好timeout/t5/nobreaknulexit有时我们要每天备份一次保留近一周或者近一月的备份可以这样做。循环周备份echo offcd/d %MYSQL_HOME% REM 请替换以下路径为实际的文件路径setfilenamedbname.txt REM 请替换以下路径为实际的文件路径setbackup_dir./backupREM 检测 backup 目录是否存在不存在则新建ifnot exist%backup_dir%(mkdir%backup_dir%):: 获取当前星期几(0-6)for/ftokens1 delims %%ain(wmic path win32_localtime get dayofweek ^| findstr /r [0-6])dosetdow%%a :: 调整星期日(0)为7其他天数(1-6)保持不变if%dow%0(setdow7)for/ftokens*%%ain(%filename%)do(echoContent: %%a bin\mysqldump.exe --defaults-filemy.ini%%a./backup/%%a-week%dow%.sql)::pause 用timeout暂停后自动退出更好timeout/t5/nobreaknulexit执行结果↓循环月备份↓echo offcd/d %MYSQL_HOME% REM 请替换以下路径为实际的文件路径setfilenamedbname.txt REM 请替换以下路径为实际的文件路径setbackup_dir./backupREM 检测 backup 目录是否存在不存在则新建ifnot exist%backup_dir%(mkdir%backup_dir%):: 获取当前几日并移除前导零for/ftokens2 delims%%ain(wmic OS Get localdatetime /value)dosetdow%%asetdow%dow:~6,2%set/adowdow*1for/ftokens*%%ain(%filename%)do(echoContent: %%a bin\mysqldump.exe --defaults-filemy.ini%%a./backup/%%a-day%dow%.sql)::pause 用timeout暂停后自动退出更好timeout/t5/nobreaknulexit我们可以做的更加灵活首先们建立一个配置文件backup_config.txt在里面配置表名和备份模式内容如下↓#数据库名称,逗号分隔dbnamestest,test1,test2#备份模式填写备份周期参数包括1-保存最近一天、2-保存最近一周、3-保存最近一月backup_mode3支持多种模式备份的BAT命令↓echo off setlocal enabledelayedexpansioncd/d %MYSQL_HOME% REM 设置配置文件路径和备份目录setconfig_filebackup_config.txtsetbackup_dir./backupREM 检查 MYSQL_HOME 是否设置ifnot defined MYSQL_HOME(echoError: MYSQL_HOME is not set!timeout/t5/nobreaknulexit/b1)REM 检测备份目录是否存在不存在则新建ifnot exist%backup_dir%(mkdir%backup_dir%)REM 检查配置文件是否存在ifnot exist%config_file%(echoError: %config_file% not found!timeout/t5/nobreaknulexit/b1)REM 读取 backup_config.txt解析 dbnames 和 backup_modesetdbnamessetbackup_modefor/ftokens1* delims%%ain(%config_file%)do(if%%adbnamessetdbnames%%bif%%abackup_modesetbackup_mode%%b)REM 检查 dbnames 和 backup_mode 是否已设置ifnot defined dbnames(echoError: dbnames not foundin%config_file%!timeout/t5/nobreaknulexit/b1)ifnot defined backup_mode(echoError: backup_mode not foundin%config_file%!timeout/t5/nobreaknulexit/b1)REM 根据备份模式设置参数if%backup_mode%2(setbackup_typeWeekly Rotational BackupsetsuffixweekREM 获取当前星期几0-6并调整为1-7for/ftokens1 delims %%din(wmic path win32_localtime get dayofweek ^| findstr /r [0-6])dosetdow%%d REM 调整星期日(0)为7其他天数(1-6)保持不变 REMif!dow!0setdow7)elseif%backup_mode%3(setbackup_typeMonthly Rotational BackupsetsuffixdayREM 获取当前日期的日1-31for/ftokens2 delims%%din(wmic OS Get localdatetime /value)dosetdow%%dsetdow!dow:~6,2!set/adowdow*1)else(setbackup_typeDaily Backupsetdowsetsuffix)REM 备份数据库for%%ain(%dbnames%)do(ifnot defined dow(REM 每日备份无后缀echo%backup_type%: %%a to %%a.sql bin\mysqldump.exe --defaults-filemy.ini%%a%backup_dir%\%%a.sql)else(REM 周或月备份添加 suffix 和 dowecho%backup_type%: %%a to %%a-%suffix%%dow%.sql bin\mysqldump.exe --defaults-filemy.ini%%a%backup_dir%\%%a-%suffix%%dow%.sql)if%errorlevel% neq0(echoError: Failed to backup %%a))REM 暂停5秒后自动退出timeout/t5/nobreaknulexit三种模式各执行一遍3.centos下自动备份vimbackup-sql.sh新建脚本#!/bin/shcd/usr/local/mysql/bin ./mysqldump --defaults-file/etc/my.cnftest/home/volume/test.sql别忘了可执行权限chmodx backup-sql.sh3.1 使用crond执行定时任务编辑一个定时任务#查看当前用户的定时任务crontab-l#编辑定时任务crontab-e如03* * * /path/to/backup-sql.sh保存后即可3.2 使用Systemd Timers执行定时任务先编写service服务vim/etc/systemd/system/sqlBc.service内容如下[Unit]DescriptionMysql Backup[Service]TypesimpleExecStart/home/volume/backup-sql.sh编写timer定时器vim/etc/systemd/system/sqlBc.timer内容如下[Unit]Descriptionsql Backup Timer[Timer]OnCalendar*-*-*12:32:00UnitsqlBc.service[Install]WantedBytimers.target#重载配置生效systemctl daemon-reload#允许自启systemctlenablesqlBc.timer systemctl restart sqlBc.timer systemctl status sqlBc.timer4.docker下自动备份5.使用LUA脚本自动备份有时候我们可能遇到无法调用系统的定时任务的情况比方说一个win系统中没有管理员的权限无法创建任务计划这时可以利用已经安装的软件来进行定时任务调度。先创建lua脚本↓-- test_cmd.lua -- 执行 CMD 命令的主函数localfunctionrun_cmd(premature)ifprematurethenngx.log(ngx.INFO,Task terminated prematurely)returnend -- 记录脚本开始执行 ngx.log(ngx.INFO,Starting command execution)-- 设置工作目录并执行 BAT 文件localcmdcd /d %MYSQL_HOME% week.batngx.log(ngx.INFO,Executing command: , cmd)localresultos.execute(cmd)ngx.log(ngx.INFO,Command result type: , type(result),, value: , tostring(result))-- 根据Lua版本不同判断执行结果ifresult0or resulttruethenngx.log(ngx.INFO,BAT文件执行成功)elsengx.log(ngx.ERR,BAT文件执行失败结果: , tostring(result))end end -- 设置定时任务每60秒执行一次localok, errngx.timer.every(60, run_cmd)ifnot okthenngx.log(ngx.ERR,Failed to create timer: , err)returnend -- 记录定时任务创建成功的日志 ngx.log(ngx.INFO,CMD timer created successfully)nginx配置在http块里添加↓lua_package_pathD:/openresty/lua/?.lua;D:/openresty/lualib/resty/?.lua;;;# 设置 Lua 脚本路径init_worker_by_lua_block{ngx.log(ngx.INFO,Loading LUA)require(test_cmd)}以上并没指定时间现在可以来指定时间↓-- test_cmd.lua -- 执行 CMD 命令的主函数localrun_cmd -- 计算并调度下一次任务执行时间localfunctionschedule_next_run()localnowngx.time()localtarget_hour15-- 目标小时下午3点localtarget_min02 -- 目标分钟40分 -- 计算今天目标时间的时间戳localtodayos.date(*t, now)today.hourtarget_hour today.mintarget_min today.sec0localtarget_timeos.time(today)-- 如果当前时间已经过了今天的目标时间则设置为明天的目标时间ifnowtarget_timethentarget_timetarget_time (24*60*60)-- 加一天 end -- 计算延迟时间秒localdelaytarget_time - now -- 创建定时器localok, errngx.timer.at(delay, run_cmd)ifnot okthenngx.log(ngx.ERR,Failed to schedule next run: , err)elsengx.log(ngx.INFO,Next run scheduled at: , os.date(%Y-%m-%d %H:%M:%S, target_time), (, math.floor(delay/3600),小时, math.floor((delay%3600)/60),分钟后))end end--定义执行命令的函数实现 run_cmdfunction(premature)if premature then ngx.log(ngx.INFO,Task terminated prematurely)return end--记录脚本开始执行 ngx.log(ngx.INFO,Starting command execution at: .. os.date(%Y-%m-%d%H:%M:%S))-- 设置工作目录并执行 BAT 文件使用绝对路径localcmdcd /d %MYSQL_HOME% week.batngx.log(ngx.INFO,Executing command: , cmd)localresultos.execute(cmd)ngx.log(ngx.INFO,Command result type: , type(result),, value: , tostring(result))-- 根据Lua版本不同判断执行结果ifresult0or resulttruethenngx.log(ngx.INFO,BAT文件执行成功)elsengx.log(ngx.ERR,BAT文件执行失败结果: , tostring(result))end -- 调度下一次任务 schedule_next_run()end -- 初始化调度第一次运行 schedule_next_run()-- 记录定时任务创建成功的日志 ngx.log(ngx.INFO,Daily backup scheduler initialized successfully)如果os.execute不可用使用io.popen替代os.execute↓-- backup.lua -- 执行外部程序的主函数localrun_cmd -- 计算并调度下一次任务执行时间localfunctionschedule_next_run()localnowngx.time()localtarget_hour15-- 目标小时下午3点localtarget_min40-- 目标分钟40分 -- 计算今天目标时间的时间戳localtodayos.date(*t, now)today.hourtarget_hour today.mintarget_min today.sec0localtarget_timeos.time(today)-- 如果当前时间已经过了今天的目标时间则设置为明天的目标时间ifnowtarget_timethentarget_timetarget_time (24*60*60)-- 加一天 end -- 计算延迟时间秒localdelaytarget_time - now -- 创建定时器localok, errngx.timer.at(delay, run_cmd)ifnot okthenngx.log(ngx.ERR,Failed to schedule next run: , err)elsengx.log(ngx.INFO,Next run scheduled at: , os.date(%Y-%m-%d %H:%M:%S, target_time), (, math.floor(delay/3600),小时, math.floor((delay%3600)/60),分钟后))end end--定义执行命令的函数实现 run_cmdfunction(premature)if premature then ngx.log(ngx.INFO,Task terminated prematurely)return end--记录脚本开始执行 ngx.log(ngx.INFO,Starting command execution at: .. os.date(%Y-%m-%d%H:%M:%S))localcmdcd /d %MYSQL_HOME% week.batngx.log(ngx.INFO,Executing command: , cmd)-- 使用io.popen捕获输出localhandle, errio.popen(cmd)ifnot handlethenngx.log(ngx.ERR,Failed to execute command: , err)elselocalresulthandle:read(*a)localclose_status, close_reasonhandle:close()ifclose_statusthenngx.log(ngx.INFO,Command executed successfully, exit code: , close_reason)ngx.log(ngx.INFO,Command output: , result)elsengx.log(ngx.ERR,Command execution failed, reason: , close_reason)ngx.log(ngx.ERR,Command output: , result)end end -- 调度下一次任务 schedule_next_run()end -- 初始化立即执行一次用于测试localok, errngx.timer.at(0, run_cmd)ifnot okthenngx.log(ngx.ERR,Failed to create immediate timer: , err)end -- 记录定时任务创建成功的日志 ngx.log(ngx.INFO,Backup scheduler initialized successfully)