【问题标题】:Windows Batch Script to backup local MySQL databases & only keep N latest FOLDERS with backup files用于备份本地 MySQL 数据库的 Windows 批处理脚本 & 仅保留 N 个带有备份文件的最新文件夹
【发布时间】:2015-08-03 12:16:50
【问题描述】:

我正在使用adityasatrio's batch file 来备份本地 MySQL 数据库,并且希望只能保留 30 个最新的备份文件。在这个例子中使用 root:root。

    @echo off

 set dbUser=root
 set dbPassword=root
 set backupDir="D:\MySQLDumps\dbs\"
 set mysqldump="C:\wamp\bin\mysql\mysql5.6.17\bin\mysqldump.exe"
 set mysqlDataDir="C:\wamp\bin\mysql\mysql5.6.17\data"
 set zip="C:\Program Files\7-Zip\7z.exe"

 :: get date
 for /F "tokens=2-4 delims=/ " %%i in ('date /t') do (
      set yy=%%i
      set mon=%%j
      set dd=%%k
 )

 :: get time
 for /F "tokens=5-8 delims=:. " %%i in ('echo.^| time ^| find "current" ') do (
      set hh=%%i
      set min=%%j
 )

 echo dirName=%yy%%mon%%dd%_%hh%%min%
 set dirName=%yy%%mon%%dd%_%hh%%min%

 :: switch to the "data" folder
 pushd %mysqlDataDir%

 :: iterate over the folder structure in the "data" folder to get the databases
 for /d %%f in (*) do (

 if not exist %backupDir%\%dirName%\ (
      mkdir %backupDir%\%dirName%
 )

 %mysqldump% --host="localhost" --user=%dbUser% --password=%dbPassword% --single-transaction --add-drop-table --databases %%f > %backupDir%\%dirName%\%%f.sql

 %zip% a -tgzip %backupDir%\%dirName%\%%f.sql.gz %backupDir%\%dirName%\%%f.sql

 del %backupDir%\%dirName%\%%f.sql

 )
 popd

现在我已经很好地了解了以下问题:

Batch file to delete files older than N days

https://serverfault.com/questions/49614/delete-files-older-than-x-days

Batch file that keeps the 7 latest files in a folder

Windows batch file only keeping the last 30 files

现在想知道我是否可以简单地添加 (https://stackoverflow.com/a/14267137/1010918)

for /f "skip=30 delims=" %%A in ('dir /a:-d /b /o:-d /t:c *.sql ^2^>nul') do if exist "%%~fA" echo "%%~fA"

(是的,我稍后会将 echo 更改为 del,但首先我想看看会发生什么)

或 (https://stackoverflow.com/a/13368077)

for /f "skip=30 eol=: delims=" %%F in ('dir /b /o-d *.sql') do @del "%%F"

在批处理文件的末尾,正下方

 del %backupDir%\%dirName%\%%f.sql

要做到这一点?

我以前从未这样做过,但已经搜索了 MySQL dbs 的自动本地备份应用程序/php 脚本/mysqldump 命令/等,甚至使用 Workbench 只是发现无法在社区版中设置调度(谢谢你甲骨文)。

所有其他应用要么需要有人打开应用并点击“立即运行”,要么需要您为设置时间表付费(不,谢谢)。

我认为这可以在 Windows 7 和更高版本的机器上使用手头的工具来完成。请帮我将此功能添加到脚本中,那太好了,谢谢。

edit1:

添加引号命令时没有任何反应。 此外,创建的备份目录只显示时间,不显示年月日。做进一步的研究以找出原因。有什么想法吗?

这条评论delete all but X most recent folders 谈到删除 5 个最新文件夹,虽然当我这样使用它时

for /f "skip=2 delims=" %%a in ('dir %backupDir%\%dirName% /o-d /b') do rd /S /Q "%backupDir%\%dirName%\%%a"

错误如下。

The system cannot find the file specified.
The system cannot find the path specified.

edit2: 下面是使用@foxidrive帮助设置文件夹名称的代码,但最后一点,尝试只保留3个最新文件夹(仅用于测试目的3个)并删除backupDir中的其余文件夹好像不行。

感谢您的帮助。

     @echo off

 set dbUser=root
 set dbPassword=root
 set "backupDir=D:\MySQLDumps\dbs\"
 set "mysqldump=C:\wamp\bin\mysql\mysql5.6.17\bin\mysqldump.exe"
 set "mysqlDataDir=C:\wamp\bin\mysql\mysql5.6.17\data"
 set "zip=C:\Program Files\7-Zip\7z.exe"

rem The four lines below will give you reliable YY DD MM YYYY HH Min Sec MS variables in XP Pro and higher.

for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" & set "MS=%dt:~15,3%"

 set "dirname=%YY%-%MM%-%DD% %HH%-%Min%-%Sec%"

 echo "dirName"="%dirName%"
 pause

 :: switch to the "data" folder
 pushd "%mysqlDataDir%"

 :: create backup folder if it doesn't exist
 if not exist "%backupDir%\%dirName%\" mkdir "%backupDir%\%dirName%"

 :: iterate over the folder structure in the "data" folder to get the databases




 for /d %%f in (*) do (
 echo processing folder "%%f"

 "%mysqldump%" --host="localhost" --user=%dbUser% --password=%dbPassword% --single-transaction --add-drop-table --databases %%f > "%backupDir%\%dirName%\%%~nxf.sql"

 "%zip%" a -tgzip "%backupDir%\%dirName%\%%~nxf.sql.gz" "%backupDir%\%dirName%\%%~nxf.sql"

  del "%backupDir%\%dirName%\%%~nxf.sql"

 )
 popd

 :: delete all but the latest 3 folders

 for /f "skip=3 delims=" %%A in ('dir /b /ad /o-n "%backupDir%\%dirName%\*"')  do @echo rd /s /q "%backupDir%\%dirName%\%%~A"

pause

【问题讨论】:

  • 当你使用引用的命令时会发生什么?
  • @wOxxOm 意识到我没有 7zip 而是 WinRAR,只是安装 7zip。这对已经安装的 WinRAR 也可行吗?我猜是这样,但为了方便起见,我也很乐意使用 7zip,因为它是开源的。
  • @wOxxOm 问题是我不确定我在做什么,我想添加仅保留最新 30 个的功能,或者对于测试用例 3 MySQL 备份的 .sql 文件在备份目录中。据我了解,数据库是用 7zip 压缩的,对吧?所以我不应该在备份目录中没有 .sql 文件,而是 .7z 文件,对吧?确实发生了一些事情,但我在备份目录中看不到任何 .sql 或 .7z 文件。批处理文件运行后,如何阻止 cmd 窗口关闭? cmd窗口中有信息,也许这会帮助我更好地理解。谢谢
  • @wOxxOm OK with pause and @echo off 我可以看到命令,它在最后停止!谢谢!该脚本虽然创建了一个只有当前时间的文件夹,例如_1500,而不是当前年份月份日期和时间。告诉我为什么?尚未添加引用的命令。现在执行此操作并设置skip=2。是的,使用引用的命令,创建的文件夹仍然存在。不知何故,我必须告诉它在备份目录中查找,并且只保留 3 个最新的文件夹,以进行此测试。当我删除 - 并有 %yy%%mon%%dd%%hh%%min%only 时设置一个备份目录名称。为什么会这样?

标签: mysql windows batch-file wampserver


【解决方案1】:

在上面@foxidrive 的帮助下,我设法获得了我想要的文件夹日期,它们是 YYYY-MM-DD HH-MIN-SEC。

由于adityasatrio's MySQL Backup Batch Script,在这些文件夹中存储了 gzip 压缩的 .sql 数据库。

在@Magoo 从这个答案 https://stackoverflow.com/a/17521693/1010918 的帮助下,我设法删除了所有文件夹(nameDir)同时保留最新的 N 个文件夹(nameDir)并且 触摸目录中可能存在的任何文件 (backupDir)。

这是完整的工作脚本。

随意删除任何出现的pauseecho查看命令提示符内发生的情况。

另外将它添加到 Windows 任务计划程序中,您就可以为使用 MySQL 数据库的本地开发环境提供可靠的备份解决方案。

请感谢帮助我完成这项工作的人。如果没有你们,我将不得不使用昂贵的 Windows 应用程序来本地保存 MySQL 数据库。

(..对于我们的下一个技巧,如果在备份 .sql 文件时出现错误,我们将通过电子邮件将错误日志发送给自己。但这是另一天的另一个问题和故事..)

 @echo off

 set dbUser=root
 set dbPassword=root
 set "backupDir=D:\MySQLDumps"
 set "mysqldump=C:\wamp\bin\mysql\mysql5.6.17\bin\mysqldump.exe"
 set "mysqlDataDir=C:\wamp\bin\mysql\mysql5.6.17\data"
 set "zip=C:\Program Files\7-Zip\7z.exe"

 :: https://stackoverflow.com/a/31789045/1010918 foxidrive's answer helped me get the folder with the date and time I wanted

rem The four lines below will give you reliable YY DD MM YYYY HH Min Sec MS variables in XP Pro and higher.

for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" & set "MS=%dt:~15,3%"

 set "dirname=%YYYY%-%MM%-%DD% %HH%-%Min%-%Sec%"

 :: remove echo here if you like
 echo "dirName"="%dirName%"

 :: switch to the "data" folder
 pushd "%mysqlDataDir%"

 :: create backup folder if it doesn't exist
 if not exist "%backupDir%\%dirName%\" mkdir "%backupDir%\%dirName%"

 :: iterate over the folder structure in the "data" folder to get the databases

 for /d %%f in (*) do (
 :: remove echo here if you like
 echo processing folder "%%f"

 "%mysqldump%" --host="localhost" --user=%dbUser% --password=%dbPassword% --single-transaction --add-drop-table --databases %%f > "%backupDir%\%dirName%\%%~nxf.sql"

 "%zip%" a -tgzip "%backupDir%\%dirName%\%%~nxf.sql.gz" "%backupDir%\%dirName%\%%~nxf.sql"

  del "%backupDir%\%dirName%\%%~nxf.sql"

 )
 popd

 :: delete all folders but the latest 2


 :: https://stackoverflow.com/a/17521693/1010918 Magoo's answer helped me get what I wanted to do with the folders
 :: for /f "skip=2 delims=" %G in ('dir /B /ad-h /o-d') DO echo going to delete %G

 :: below following my version with rd (remove dir) command and /s and /q
 :: remove echo before rd to really delete the folders in question!!
 :: attention they will be deleted with content in them!!

 :: change the value after skip= to what you like, this is the amount of latest folders to keep in your backup directory
    for /f "skip=2 delims=" %%a in (' dir "%backupDir%\" /b /ad-h /o-d') do echo rd /s /q "%backupDir%\%%a"

:: remove pause here if you like and add the file to Windows Task Manager
 pause

【讨论】:

    【解决方案2】:

    这对文件夹名称中的空格更具弹性,并且日期和时间例程已更改
    - 运行它并首先检查"dirName"= 文件夹的格式是否正确
    - 最后的行应回显del 命令以保留最新的 3 个备份。

    测试存档例程,然后
    如果您觉得一切正常,请删除 del 关键字之前的 echo

     @echo off
    
     set dbUser=root
     set dbPassword=root
     set "backupDir=D:\MySQLDumps\dbs\"
     set "mysqldump=C:\wamp\bin\mysql\mysql5.6.17\bin\mysqldump.exe"
     set "mysqlDataDir=C:\wamp\bin\mysql\mysql5.6.17\data"
     set "zip=C:\Program Files\7-Zip\7z.exe"
    
    rem The four lines below will give you reliable YY DD MM YYYY HH Min Sec MS variables in XP Pro and higher.
    
    for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
    set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
    set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" & set "MS=%dt:~15,3%"
    
     set "dirname=%YY%%MM%%DD%_%HH%%Min%"
    
     echo "dirName"="%dirname%"
     pause
    
     :: switch to the "data" folder
     pushd "%mysqlDataDir%"
    
     :: create backup folder if it doesn't exist
     if not exist "%backupDir%\%dirName%\" mkdir "%backupDir%\%dirName%"
    
     :: iterate over the folder structure in the "data" folder to get the databases
    
    
    
    
     for /d %%f in (*) do (
     echo processing folder "%%f"
    
     "%mysqldump%" --host="localhost" --user=%dbUser% --password=%dbPassword% --single-transaction --add-drop-table --databases %%f > "%backupDir%\%dirName%\%%~nxf.sql"
    
     "%zip%" a -tgzip "%backupDir%\%dirName%\%%~nxf.sql.gz" "%backupDir%\%dirName%\%%~nxf.sql"
    
     del "%backupDir%\%dirName%\%%~nxf.sql"
    
     )
     popd
    
    
     ::keep 3 newest backup *.sql files
    for /f "skip=3 delims=" %%a in ('dir "%backupDir%\%dirName%\*.sql" /b /o-d /a-d') do echo del "%backupDir%\%dirName%\%%a"
    pause
    

    【讨论】:

    • 谢谢。 dirName 再次仅显示例如_1550 但不是年月日时间。最后自然会说File Not Found。仅供参考,我使用的是 Win 7 64 SP1 英文版,长日期和长时间显示为 dddd, d。 MMMM yyyy - HH:mm:ss。 Windows 批处理文件脚本是否以某种方式依赖于区域?我可以在此处提供来自系统的更多信息,以便您更好地了解错误发生的原因吗?
    • 将第 11 行更改为 for /F "tokens=2-4 delims=. " %%i in ("%date%") do ( 给我一个带有 082015_1614 的文件夹。虽然我需要先来年。
    • wOxxOm 在聊天中告诉我“该循环中的 i j k 个变量期望年、月、日,因此您应该更改顺序。” cmd date /t 在这里显示日-月-年。
    • 我添加了一个可靠的例程来获取日期和时间戳,它适用于所有位置。日期和时间变量的格式会根据区域设置和机器偏好而变化,因此这些是不可靠的 - 除非在单台机器上使用,否则您可以依赖于在这方面不会发生变化。
    • 我有set dirName="%date:~6,4%-%date:~3,2%-%date:~0,2% %hh%:%min%" echo "dirName"="%dirname%" pause mkdir %dirname%,但由于dirName 中有空格,它找不到指定的文件夹。立即尝试您的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-04
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-02-26
    相关资源
    最近更新 更多