公司的环境是win2003r2 64位加 mssql2005.
数据每天都要备份。
刚开始用的是mssql自带的排程备份功能。感觉不太好用。(出现过恢复失败的情况)
就写了以下脚本做计划任务备份。供大家参考。
@Echo %date% %time% DEBUG ********** 开始执行 **********
@set NowTime=%time%
@echo off
Rem 1. 产生命令档 %SQLFILE% (Generate %SQLFILE%)
Rem 2. 执行命令档 %SQLFILE% (Execute %SQLFILE%)
Echo %date% %time% DEBUG *** 执行身份 %USERDOMAIN%\%USERNAME%
Echo %date% %time% DEBUG *** 执行命令 %*
:_DateStuff
REM **********
REM *** 日期分割
REM **********
Echo %date% %time% DEBUG *** 日期分割 ***
REM 依日期/时间格式进行修改 yy, mm, dd, wd
REM yy=年
REM mm=月
REM dd=日
REM wd=星期
REM dt=年-月-日-星期 (依系统日期格式而定)
REM 注意: date /t 的传回值会依据 [标准及格式(Standards and Formats)] 的设定值而有所不同
REM 若为English, 则为 星期 月/日/年
REM 若为Chinese, 则为 年/月/日 星期
Rem 侦测日期格式为 日期+星期 还是 星期+日期
set CheckNumber=%date:~0,1%
If "%CheckNumber%" == "0" Goto _DateWeekdayAfter
If "%CheckNumber%" == "1" Goto _DateWeekdayAfter
If "%CheckNumber%" == "2" Goto _DateWeekdayAfter
If "%CheckNumber%" == "3" Goto _DateWeekdayAfter
If "%CheckNumber%" == "4" Goto _DateWeekdayAfter
If "%CheckNumber%" == "5" Goto _DateWeekdayAfter
If "%CheckNumber%" == "6" Goto _DateWeekdayAfter
If "%CheckNumber%" == "7" Goto _DateWeekdayAfter
If "%CheckNumber%" == "8" Goto _DateWeekdayAfter
If "%CheckNumber%" == "9" Goto _DateWeekdayAfter
Goto _DateWeekdayBefore
:_DateWeekdayAfter
for /F "tokens=1-4 delims=/ " %%i in ('date /t') do (
for /f "skip=1 tokens=2-4 delims=/-,()." %%x in ('echo.^|date') do (
set %%x=%%i
set %%y=%%j
set %%z=%%k
)
set wd=%%l
)
Goto _DateStuffContinue
:_DateWeekdayBefore
for /F "tokens=1-4 delims=/ " %%i in ('date /t') do (
set wd=%%i
for /f "skip=1 tokens=2-4 delims=/-,()." %%x in ('echo.^|date') do (
set %%x=%%j
set %%y=%%k
set %%z=%%l
)
)
:_DateStuffContinue
Rem 将星期改为英文, 以避免乱码
If "%wd%" == "星期一" set wd=Mon
If "%wd%" == "星期二" set wd=Tue
If "%wd%" == "星期三" set wd=Wed
If "%wd%" == "星期四" set wd=Thu
If "%wd%" == "星期五" set wd=Fri
If "%wd%" == "星期六" set wd=Sat
If "%wd%" == "星期日" set wd=Sun
set dt=%yy%-%mm%-%dd%-%wd%
Echo %date% %time% DEBUG yy=%yy%
Echo %date% %time% DEBUG mm=%mm%
Echo %date% %time% DEBUG dd=%dd%
Echo %date% %time% DEBUG wd=%wd%
Echo %date% %time% DEBUG dt=%dt%
REM **********
REM *** 时间分割
REM **********
Echo %date% %time% DEBUG *** 时间分割 ***
REM hh=时
REM nn=分
REM ss=秒
REM ms=毫秒
REM tm=时-分-秒-毫秒
REM dtt=%dt%-%tm%
rem for /f "Tokens=1-4 Delims=:. " %%i in ("%time%") do (
rem set hh=%%i
rem set nn=%%j
rem set ss=%%k
rem set ms=%%l
rem )
rem set tm=%hh%-%nn%-%ss%-%ms%
set hh=%NowTime:~0,2%
If "%hh:~0,1%" == " " set hh=0%hh:~1,1%
set nn=%NowTime:~3,2%
set ss=%NowTime:~6,2%
set ms=%NowTime:~9,2%
set tm=%hh%-%nn%-%ss%-%ms%
set dtt=%dt%-%tm%
Echo %date% %time% DEBUG hh=%hh%
Echo %date% %time% DEBUG nn=%nn%
Echo %date% %time% DEBUG ss=%ss%
Echo %date% %time% DEBUG ms=%ms%
Echo %date% %time% DEBUG tm=%tm%
Echo %date% %time% DEBUG dtt=%dtt%
REM **********
REM *** 定义邮件变量
REM **********
Echo %date% %time% DEBUG *** 定义邮件变量 ***
REM blatpath=传送电子邮件的程序
REM relayserver=电子邮件服务器
REM email=收件者的电子邮件地址
REM fromemail=寄件者的电子邮件地址
REM emailuser=电子邮件服务器的认证使用者
REM emailpass=电子邮件服务器的密码
set blatpath=C:\blat.exe
set relayserver='你的邮件服务器(要开启匿名服务哦!)'
if "%COMPUTERNAME%" == "主机名" set email=‘你要接受的邮件的邮箱地址’
set fromemail=MSSQLSERVER@%COMPUTERNAME%.%USERDNSDOMAIN%
set emailuser=
set emailpass=
Echo %date% %time% DEBUG blatpath=%blatpath%
Echo %date% %time% DEBUG relayserver=%relayserver%
Echo %date% %time% DEBUG email=%email%
Echo %date% %time% DEBUG fromemail=%fromemail%
Rem **********
Rem *** 定义SQL变量
Rem **********
Echo %date% %time% DEBUG *** 定义 SQL 变量
Rem SQLFILE=SQL命令�n
Rem BACKUPDIR=备份文件路径
Rem OUTFILE=执行记录文件
Rem SERVER=服务器名称, 预设同%COMPUTER%
Rem USERNAME=登入数据库的账号, 预设sa
Rem PASSWORD=登入账号的密码
Rem ToDo:
Rem 尽量不要使用sa账号, 以免做错的话, 影响太大
Set OUTFILE=sql.backup.%dtt%.out.txt
REM ***
REM *** 检查锁定档是否存在 (避免重复执行.)
REM ***
Echo %date% %time% DEBUG *** 检查是否有锁定档, 以避免重复执行 ***
set LockFile=sqlcmd.backup.%COMPUTERNAME%.lck.txt
if exist "%LockFile%" goto _isLock
set >> "%LockFile%"
Set SQLFILE=sql.backup.%dtt%.sql.txt
Set BACKUPDIR=‘你要存放备份文件的路径’
if NOT exist "%BACKUPDIR%" mkdir "%BACKUPDIR%"
Set SERVER=%COMPUTERNAME%
Set USERNAME=‘db 用户名’
Set PASSWORD=‘db pw’
Set DATABASE=%1
If '%DATABASE%' == '' (
Goto _BackupAllDatabase
)
Echo %date% %time% DEBUG OUTPUTFILE=%OUTPUTFILE%
Echo %date% %time% DEBUG LockFile=%LockFile%
Echo %date% %time% DEBUG SQLFILE=%SQLFILE%
Echo %date% %time% DEBUG BACKUPDIR=%BACKUPDIR%
Echo %date% %time% DEBUG SERVER=%SERVER%
:_BackupSingleDatabase
Rem **********
Rem *** Backup Single Database
Rem **********
:_BackupSingleDatabaseDifferential
Echo %date% %time% DEBUG *** 产生 BackupSingleDatabaseDifferential 备份命令档 ***
for %%d in ( %* ) do (
Echo print '-------------------------------------------------------' >> %SQLFILE%
Echo print '1^> backup database [%%d] to disk = ''%BACKUPDIR%\%%d.%dtt%.bak' >> %SQLFILE%
Echo print '2^> go' >> %SQLFILE%
Echo go >> %SQLFILE%
Echo backup database [%%d] to disk = '%BACKUPDIR%\%%d.%dtt%.bak' >> %SQLFILE%
Echo go >> %SQLFILE%
Echo if @@ERROR != 0 print 'Error!' >> %SQLFILE%
Echo go >> %SQLFILE%
Echo print '1^> backup log [%%d] with truncate_only' >> %SQLFILE%
Echo print '2^> go' >> %SQLFILE%
Echo go >> %SQLFILE%
Echo backup log [%%d] with truncate_only >> %SQLFILE%
Echo go >> %SQLFILE%
Echo if @@ERROR != 0 print 'Error!' >> %SQLFILE%
Echo go >> %SQLFILE%
Echo print '1^> dbcc shrinkdatabase ^( ''%%d'', 0, TRUNCATEONLY ^)' >> %SQLFILE%
Echo print '2^> go' >> %SQLFILE%
Echo go >> %SQLFILE%
Echo dbcc shrinkdatabase ^( '%%d', 0, TRUNCATEONLY ^) >> %SQLFILE%
Echo go >> %SQLFILE%
Echo if @@ERROR != 0 print 'Error!' >> %SQLFILE%
Echo go >> %SQLFILE%
)
Goto _Run
:_BackupAllDatabase
Rem **********
Rem *** Backup All Database
Rem **********
Echo %date% %time% DEBUG *** 产生 BackupAllDatabase 备份命令档 ***
Echo declare curs1 cursor for select name from master..sysdatabases where name != 'tempdb' and name not like 'bk_^%%' order by 1 > %SQLFILE%
Echo go >> %SQLFILE%
Echo declare @dbname nvarchar(128) >> %SQLFILE%
Echo declare @filename nvarchar(128) >> %SQLFILE%
Echo open curs1 >> %SQLFILE%
Echo fetch curs1 into @dbname >> %SQLFILE%
Echo while @@fetch_status = 0 >> %SQLFILE%
Echo begin >> %SQLFILE%
Echo select @filename = '%BACKUPDIR%\' + @dbname + '.%dtt%.bak' >> %SQLFILE%
Echo print '-------------------------------------------------------' >> %SQLFILE%
Echo print '1^> backup database [' + @dbname + '] to disk = ''' + @filename + '' >> %SQLFILE%
Echo print '2^> go' >> %SQLFILE%
Echo backup database @dbname to disk = @filename >> %SQLFILE%
Rem ECHO if @@ERROR != 0 >> %SQLFILE%
Rem ECHO begin >> %SQLFILE%
Rem ECHO print '***************' >> %SQLFILE%
Rem ECHO print 'Error Occured!!' >> %SQLFILE%
Rem ECHO print '***************' >> %SQLFILE%
Rem ECHO end >> %SQLFILE%
Echo fetch curs1 into @dbname >> %SQLFILE%
Echo end >> %SQLFILE%
Echo go >> %SQLFILE%
Echo close curs1 >> %SQLFILE%
Echo go >> %SQLFILE%
Echo deallocate curs1 >> %SQLFILE%
Echo go >> %SQLFILE%
Goto _Run
:_Run
Rem **********
Rem *** RUN
Rem **********
Type %SQLFILE%
Echo %date% %time% DEBUG *** 正在进行备份 ***
Rem sqlcmd -S %SERVER% -U %username% -P %PASSWORD% -i %SQLFILE% -o %OUTFILE% -w 256
sqlcmd -i %SQLFILE% -o %OUTFILE% -w 256
REM **********
REM *** 搜寻 %OUTFILE% 内的错误字符串
REM **********
Echo %date% %time% DEBUG *** 检查是否有错误讯息 ***
REM errmsg=错误讯息
SET errmsg=
type "%OUTFILE%" | findstr /i /c:"Msg " > NUL
if %errorlevel% == 0 set errmsg=(ERROR)
type "%OUTFILE%" | findstr /i /c:"failed" > NUL
if %errorlevel% == 0 set errmsg=(ERROR)
type "%OUTFILE%" | findstr /i /c:"Error" > NUL
if %errorlevel% == 0 set errmsg=(ERROR)
type "%OUTFILE%" | findstr /i /c:"异常" > NUL
if %errorlevel% == 0 set errmsg=(ERROR)
REM **********
REM *** 发送电子邮件
REM **********
Echo %date% %time% DEBUG *** 发送电子邮件 ***
REM %blatpath% "%SQLFILE%" -attach "%OUTFILE%" -t %email% -s "%errmsg%%COMPUTERNAME%-%wd%-%backupmode% (%dtt%)" -i %fromemail% -f "%fromemail%" -q -server "%relayserver%" -u "%emailuser%" -pw "%emailpass%" -charset big5
%blatpath% "%OUTFILE%" -attach "%SQLFILE%" -t %email% -s "%errmsg%SQL.Backup.%dtt% (%wd%)" -f "%fromemail%" -server "%relayserver%" -charset big5
if "%errmsg%" == "(ERROR)" %blatpath% "%OUTFILE%" -attach "%SQLFILE%" -t 你的邮箱地址 -s "%errmsg%SQL.Backup.%dtt% (%wd%)" -f "%fromemail%" -server "%relayserver%" -charset big5
Echo %date% %time% DEBUG *** 删除备份命令档 ***
DEL %SQLFILE%
Echo %date% %time% DEBUG *** 备份备份结果输出档 ***
MOVE "%OUTFILE%" "%BACKUPDIR%"
if "%errmsg%" == "(ERROR)" Goto _DelLockFile
if "%DATABASE%" == "" Goto _DelLockFile
Goto _DelLockFile
:_isLock
Echo %date% %time% DEBUG *** %LockFile% 已存在 ***
echo %LockFile% 已存在. >> "%OUTFILE%"
Rem %blatpath% "%OUTFILE%" -attach "%LockFile%" -t %email% -s "(错误)%COMPUTERNAME% 已在执行中. %yy%-%mm%-%dd% (%wd%) at %hh%:%nn%:%ss%.%ms%" -i %fromemail% -f "%fromemail%" -q -server "%relayserver%" -u "%emailuser%" -pw "%emailpass%" -charset big5
%blatpath% "%OUTFILE%" -attach "%LockFile%" -t %email% -s "(错误)%COMPUTERNAME% 已在执行中. %yy%-%mm%-%dd% (%wd%) at %hh%:%nn%:%ss%.%ms%" -f "%fromemail%" -server "%relayserver%" -charset big5
%blatpath% "%OUTFILE%" -attach "%LockFile%" -t 你的邮箱地址 -s "(错误)%COMPUTERNAME% 已在执行中. %yy%-%mm%-%dd% (%wd%) at %hh%:%nn%:%ss%.%ms%" -f "%fromemail%" -server "%relayserver%" -charset big5
goto _End
:_DelLockFile
Echo %date% %time% DEBUG *** 删除锁定档 ***
if Exist "%LockFile%" Del "%LockFile%"
Goto _End
:_End
Echo %date% %time% DEBUG ********** 结束执行 **********
blat.exe 这个邮件发送程序在附件里面。
脚本中有详细的注释。
如有不明请留言。
仓促之间,若有何失误,还请不吝指教。