需求
(1)需要把現有test庫備份,修改成test_當前日期,加入現在是 20200716,就改成 test_200716。
(2)然后重新創建數據庫test,把原來的表結構和存儲過程函數一類的全部構建到新建的 test 庫上。
(3)把現有用戶對新建的這個 test 庫授權讀寫訪問
(4)把 test_200716 的一些數據清理掉,並且把一部分數據比如某些表的三天內數據插入到新建的 test 庫中
(5)然后以為有多個操作,每次我們新建一個 test_200716 這樣的,我們就把最老的 比如 test_200602庫 給刪掉(刪之前腳本里有操作先備份避免誤刪和無法找回)
(6)操作完之后對線上數據庫備份,並且刪除4個月前的備份文件
【0】bat架構結構
【1】bat腳本
@echo off set today=%date:~0,4%%date:~5,2%%date:~8,2% set logfile=log_%today%.log set errorfile=error_%today%.log echo --------------------- >>%logfile% echo %date%%time%>>%logfile% echo 測試引擎服務是否啟動...... set /p="測試引擎服務是否啟動......"<nul >>%logfile% sqlcmd -S 127.0.0.1,1433 -Q "declare @i int;select @i=1;" 2>%errorfile% IF ERRORLEVEL 1 echo fail>>%logfile% IF ERRORLEVEL 0 echo ok>>%logfile% echo 開始重命名數據庫/創建數據庫...... set /p="開始重命名數據庫/創建數據庫......"<nul >>%logfile% sqlcmd -S 127.0.0.1,1433 -i 1_DB_renameAndCreate.sql -E -b 2>>%errorfile% 1>db_log_%today%.log IF ERRORLEVEL 1 echo fail......請檢查db_log_%today%.log 文件>>%logfile% IF ERRORLEVEL 0 echo ok>>%logfile% echo 新建表和存儲過程_修改存儲過程...... set /p="新建表和存儲過程_修改存儲過程......"<nul >>%logfile% sqlcmd -S 127.0.0.1,1433 -i 2_新建表和存儲過程_修改存儲過程.sql -E -b 2>>%errorfile% 1>>db_log_%today%.log IF ERRORLEVEL 1 echo fail......請檢查db_log_%today%.log 文件>>%logfile% IF ERRORLEVEL 0 echo ok>>%logfile% echo 授權_收縮日志...... set /p="授權_收縮日志......"<nul >>%logfile% sqlcmd -S 127.0.0.1,1433 -i 3_授權_收縮日志.sql -E -b 2>>%errorfile% 1>>db_log_%today%.log IF ERRORLEVEL 1 echo fail......請檢查db_log_%today%.log 文件>>%logfile% IF ERRORLEVEL 0 echo ok>>%logfile% echo 維護...... set /p="維護......"<nul >>%logfile% sqlcmd -S 127.0.0.1,1433 -i 4_維護.sql -E -b 2>>%errorfile% 1>>db_log_%today%.log IF ERRORLEVEL 1 echo fail......請檢查db_log_%today%.log 文件>>%logfile% IF ERRORLEVEL 0 echo ok>>%logfile% echo 刪除最早的庫_刪除4個月前的備份文件...... set /p="刪除最早的庫_刪除4個月前的備份文件......"<nul >>%logfile% sqlcmd -S 127.0.0.1,1433 -i 5_刪除最早的庫_刪除4個月前的備份文件.sql -E -b 2>>%errorfile% 1>>db_log_%today%.log IF ERRORLEVEL 1 echo fail......請檢查db_log_%today%.log 文件>>%logfile% IF ERRORLEVEL 0 echo ok>>%logfile% echo 啟動sql server代理服務...... set /p="啟動sql server代理服務......"<nul >>%logfile% net start "SQLSERVERAGENT" 1>>%logfile% net start "SQLSERVERAGENT" 2>>%logfile% echo 執行完畢,請查看%errorfile%與%logfile%! timeout /t 100
【2】1_DB_renameAndCreate.sql(重命名與創建數據庫)
修改老數據庫 test為 test_當前日期,新建一個test
begin try use master; set nocount on; print '----------------------------------------------' print '~~~~~~~~~~1_DB_renameAndCreate.sql~~~~~~~~~~~~' print '----------------------------------------------' ---------------------------------------------- print ' ' print '------renameDB------' print ' ' declare @db_name varchar(100),@new_db_name varchar(100) declare @sql varchar(3000),@mdf varchar(500),@ldf varchar(500) -- 設置需要修改的數據庫名稱 --默認 PQDL_LogCenter set @db_name='test' select @new_db_name=@db_name+'_'+right(convert(varchar(8),getdate(),112),6) print '修改信息----老數據庫名:'+@db_name+',修改后的數據庫名:'+@new_db_name -- 判斷@db_name指定的數據庫是否存在 if not exists(select 1 from master.sys.master_files where database_id=db_id(@db_name)) begin declare @error_msg varchar(200) set @error_msg='renamedb.sql => 指定的數據庫'+@db_name+'不存在!...' RAISERROR (@error_msg, 16, 1); return end -- 殺需要重命名的數據庫進程 set @sql='' select @sql=@sql+';kill '+cast(spid as varchar)+';' from master.dbo.sysprocesses where dbid=db_id(@db_name) exec(@sql) -- 重命名操作 set @sql='sp_renamedb '+@db_name+','+@new_db_name+';' exec(@sql) -- 收縮日志 DBCC SHRINKDATABASE (@new_db_name, TRUNCATEONLY) ------------------------------------------------- print ' ' print '------createDB------' print ' ' declare @path_dir nvarchar(500) declare @mdf_path nvarchar(500),@ldf_path nvarchar(500) select top(1) @path_dir=filename from master.sys.sysdatabases where name like '%'+@db_name+'%' set @path_dir=left(@path_dir,len(@path_dir)-charindex('\',reverse(@path_dir))+1) select @mdf_path=@path_dir+@db_name+'_'+convert(char(8),getdate(),112)+'.mdf' select @ldf_path=@path_dir+@db_name+'_'+convert(char(8),getdate(),112)+'_log.ldf' print '創建數據庫'+@db_name print 'MDF文件路徑為:'+@mdf_path print 'MDF文件路徑為:'+@ldf_path set @sql=' create database '+@db_name+' on primary ( name='+@db_name+', filename='''+@mdf_path+''', size=10MB, filegrowth=32MB ) log on ( name='+@db_name+'_log, filename='''+@ldf_path+''', size=10MB, filegrowth=10MB ); alter database '+@db_name+' set recovery simple with no_wait ' exec(@sql) end try begin catch DECLARE @ErrorMessage NVARCHAR(4000); DECLARE @ErrorSeverity INT; DECLARE @ErrorState INT; SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); print @errorMessage RAISERROR (@ErrorMessage, -- Message text. @ErrorSeverity, -- Severity. @ErrorState -- State. ); END CATCH; --
【3】2_新建表和存儲過程_修改存儲過程.sql
比較機密,就不貼具體代碼了
set nocount on; print ' ' print '----------------------------------------------' print '~~~~~~~~~~2_新建表和存儲過程_修改存儲過程.sql~~~~~~~~~~~~' print '----------------------------------------------' print ' ' print '------創建表和存儲過程------' print ' ' ----------------------------------------------[2] print ' ' print '------更新存儲過程------' print ' ' ----------------------------------------------[3]導入前三天的日志 print ' ' print '------導入前三天日志------' print ' '
【4】3_授權_收縮日志.sql
set nocount on; print ' ' print '----------------------------------------------' print '~~~~~~~~~~3_授權_收縮日志.sql~~~~~~~~~~~~' print '----------------------------------------------' print ' ' print '------授權------' print ' ' USE master; if not exists(select 1 from master.sys.syslogins where name='test_user') CREATE USER [test_user] FOR LOGIN [test_user] USE [test] if not exists(select 1 from sysusers where name ='test_user') begin CREATE USER [test_user] FOR LOGIN [test_user] end EXEC sp_addrolemember N'db_datareader', N'test_user' EXEC sp_addrolemember N'db_datawriter', N'test_user' EXEC sp_addrolemember N'db_owner', N'test_user' USE [master] if not exists(select 1 from master.sys.syslogins where name='testQuery') CREATE LOGIN testQuery with password='a123456!' USE [test] if not exists (select 1 from sysusers where name ='testQuery') begin CREATE USER [testQuery] FOR LOGIN [testQuery] end EXEC sp_addrolemember N'db_datareader', N'testQuery' ---------------------------------------------- print ' ' print '------收縮------' print ' ' declare @db_name varchar(100) declare @logic_name varchar(100) set @db_name='test' select top(1) @logic_name=name from master.sys.master_files where type_desc='LOG' and database_id=db_id(@db_name) print @logic_name dbcc shrinkfile(@logic_name,10)
【5】4_維護.sql
use master; set nocount off; print ' ' print '----------------------------------------------' print '~~~~~~~~~~4_維護.sql~~~~~~~~~~~~' print '----------------------------------------------' print ' ' print '------備份數據庫------' begin try begin tran print ' ' print '------操作------' run sp commit tran end try BEGIN CATCH DECLARE @ErrorMessage NVARCHAR(MAX) , @ErrorSeverity INT , @ErrorState INT , @exception NVARCHAR(255); SELECT @ErrorMessage = ERROR_MESSAGE() , @ErrorSeverity = ERROR_SEVERITY() , @ErrorState = ERROR_STATE(); SET @exception = '(State ' + CAST(@ErrorState AS NVARCHAR(20)) + ', Severity ' + CAST(@ErrorSeverity AS NVARCHAR(20)) + ') ' + @ErrorMessage; RAISERROR (@exception,16,1); ROLLBACK tran; PRINT '回滾成功'
end catch
【6】5_刪除最早的庫_刪除4個月前的備份文件.sql
use master go PRINT ' ' print '----------------------------------------------' print '~~~~~~~~~~5_刪除最早的庫_刪除4個月前的備份文件.sql~~~~~~~~~~~~' print '----------------------------------------------' ---------------------------------------------- DECLARE @drop_dbname VARCHAR(300),@Bak_dir VARCHAR(500),@bak_filename VARCHAR(500) DECLARE @delete_Day_before datetime, @flag INT,@db_name varchar(200) set @db_name='test' SELECT TOP(1) @drop_dbname=name FROM sys.databases WHERE name LIKE @db_name+'_%' ORDER BY CAST(right(name,6) AS INT) ASC SELECT top(1) @Bak_dir=left(bmf.physical_device_name,len(bmf.physical_device_name)-charindex('\',reverse(bmf.physical_device_name))+1) --, -- bs.backup_set_id, -- bs.database_name, -- bs.backup_start_date, -- bs.backup_finish_date, -- CAST(CAST(bs.backup_size/1000000 AS INT) AS VARCHAR(14)) + ' ' + 'MB' AS [Size], -- CAST(DATEDIFF(second, bs.backup_start_date, -- bs.backup_finish_date) AS VARCHAR(4)) + ' ' + 'Seconds' [TimeTaken], -- CASE bs.[type] -- WHEN 'D' THEN 'Full Backup' -- WHEN 'I' THEN 'Differential Backup' -- WHEN 'L' THEN 'TLog Backup' -- WHEN 'F' THEN 'File or filegroup' -- WHEN 'G' THEN 'Differential file' -- WHEN 'P' THEN 'Partial' -- WHEN 'Q' THEN 'Differential Partial' -- END AS BackupType, -- CAST(bs.first_lsn AS VARCHAR(50)) AS first_lsn, -- CAST(bs.last_lsn AS VARCHAR(50)) AS last_lsn, -- bs.server_name, -- bs.recovery_model FROM msdb.dbo.backupset bs INNER JOIN msdb.dbo.backupmediafamily bmf ON bs.media_set_id = bmf.media_set_id ORDER BY bs.backup_start_date desc; SET @bak_filename=@Bak_dir+@drop_dbname+'_'+CONVERT(CHAR(8),GETDATE(),112)+'_recovery.bak' PRINT '要刪除的數據庫是:'+@drop_dbname+',為了防止誤刪備份文件在:'+@bak_filename print ' ' print '------備份要刪除的數據庫 '+@drop_dbname+'------' print ' ' BACKUP DATABASE @drop_dbname TO DISK=@bak_filename WITH init print ' ' print '------刪除數據庫 '+@drop_dbname+',以及刪除'+@bak_dir+'目錄下超過半年的bak備份文件------' print ' ' EXEC master.dbo.xp_fileexist @bak_filename,@flag OUTPUT IF @flag!=0 begin EXEC('DROP DATABASE '+@drop_dbname) END ELSE BEGIN RAISERROR('刪除數據庫失敗!因為備份文件不存在,為了安全,不允許刪除該數據庫!',16,1) END SET @delete_Day_before=GETDATE()-120 --4個月 EXEC master.dbo.xp_delete_file 0,@Bak_dir,'bak',@delete_Day_before
【7】log_20200716.log (流程日志)
--------------------- 2020/07/16 周四16:06:53.13 測試引擎服務是否啟動......ok 開始重命名數據庫/創建數據庫......ok 新建表和存儲過程_修改存儲過程......ok 授權_收縮日志......ok 維護......fail......請檢查db_log_20200716.log 文件 ok 刪除最早的庫_刪除4個月前的備份文件......ok 啟動sql server代理服務......請求的服務已經啟動。 請鍵入 NET HELPMSG 2182 以獲得更多的幫助。
【8】db_log_20200716(輸出日志)
已將數據庫上下文更改為 'master'。 ---------------------------------------------- ~~~~~~~~~~1_DB_renameAndCreate.sql~~~~~~~~~~~~ ---------------------------------------------- ------renameDB------ 修改信息----老數據庫名:test,修改后的數據庫名:test_200716 數據庫 名稱 'test_200716' 已設置。 DBCC SHRINKDATABASE: 已跳過數據庫 ID 13 的文件 ID 1,因為該文件沒有足夠的可用空間可以回收。 DBCC 執行完畢。如果 DBCC 輸出了錯誤信息,請與系統管理員聯系。 ------createDB------ 創建數據庫test MDF文件路徑為:D:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\test_20200716.mdf MDF文件路徑為:D:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\test_20200716_log.ldf 已將數據庫上下文更改為 'test'。 ---------------------------------------------- ~~~~~~~~~~2_新建表和存儲過程_修改存儲過程.sql~~~~~~~~~~~~ ---------------------------------------------- ------創建表和存儲過程------ ------更新存儲過程------ today:200716 ------復制老數據庫的數據到新數據庫------ ---------------------------------------------- ~~~~~~~~~~3_授權_收縮日志.sql~~~~~~~~~~~~ ---------------------------------------------- ------授權------ 已將數據庫上下文更改為 'master'。 已將數據庫上下文更改為 'test'。 已將數據庫上下文更改為 'master'。 已將數據庫上下文更改為 'test'。 ------收縮------ test_log DbId FileId CurrentSize MinimumSize UsedPages EstimatedPages ------ ----------- ----------- ----------- ----------- -------------- 10 2 1280 1280 1280 1280 DBCC 執行完畢。如果 DBCC 輸出了錯誤信息,請與系統管理員聯系。 已將數據庫上下文更改為 'master'。 ---------------------------------------------- ~~~~~~~~~~4_維護.sql~~~~~~~~~~~~ ---------------------------------------------- ------備份數據庫------ 消息 911,級別 16,狀態 1,服務器 BF-DBP-01,第 15 行 在 sysdatabases 中找不到數據庫 'BOX_ServerCenter' 所對應的條目。沒有找到具有該名稱的條目。請確保正確地輸入了該名稱。 已將數據庫上下文更改為 'master'。 ---------------------------------------------- ~~~~~~~~~~5_刪除最早的庫_刪除4個月前的備份文件.sql~~~~~~~~~~~~ ---------------------------------------------- 要刪除的數據庫是:test_200716,為了防止誤刪備份文件在:D:\backup_bak\test_200716_20200716_recovery.bak ------備份要刪除的數據庫 test_200716------ 已為數據庫 'test_200716',文件 'test' (位於文件 1 上)處理了 232 頁。 已為數據庫 'test_200716',文件 'test_log' (位於文件 1 上)處理了 1 頁。 BACKUP DATABASE 成功處理了 233 頁,花費 0.609 秒(3.134 MB/秒)。 ------刪除數據庫 test_200716,以及刪除D:\backup_bak\目錄下超過半年的bak備份文件------ (1 行受影響)
【9】error_20200716.log (錯誤日志)
只有在有sqlcmd語法錯誤的時候才會有內容