SQL Server 数据库基于备份文件的【一键还原】
1. 备份与还原的基础说明
我们知道在DBA的日常工作中,SQL Server 数据库的恢复请求偶有发生,可能是用作数据的追踪,可也可能能是数据库的灾难恢复。
数据库常用的备份命令如下:
----完整备份
Declare @FullFileName Varchar(200)
Declare @FileFlag varchar(20)
Set @FileFlag=REPLACE(CONVERT(VARCHAR(10), GETDATE(), 120), '-','')+ REPLACE(CONVERT(VARCHAR(10), GETDATE(), 8), ':', '')
Set @FullFileName='文档路径\数据库名字_FULL'+@FileFlag+'.bak'
BackUp DataBase 数据库名字 To Disk=@FullFileName with init ----差异备份
Declare @DiffFileName varchar(200)
Declare @FileFlag varchar(200)
Set @FileFlag=REPLACE(CONVERT(VARCHAR(10), GETDATE(), 120), '-','')+ REPLACE(CONVERT(VARCHAR(10), GETDATE(), 8), ':', '')
Set @DiffFileName='文档路径\数据库名字_Diff_'+@FileFlag+'.bak'
BackUp DataBase 数据库名字 To Disk=@DiffFileName with init,differential ----事务日志备份
Declare @FileName Varchar(200)
Declare @FileFlag varchar(20)
Set @FileFlag=REPLACE(CONVERT(VARCHAR(10), GETDATE(), 120), '-','')+ REPLACE(CONVERT(VARCHAR(10), GETDATE(), 8), ':', '')
Set @FileName='文档路径\数据库名字_Trn_'+@FileFlag+'.trn'
BackUp Log 数据库名字 To Disk=@FileName with init
备份文件的命名格式为:数据库名字_备份类型(Full或Diff或Trn的一种)_时间格式.文件类型(bak或trn的一种)
其中的时间格式为:年月日时分秒 ,例如:20190423140813。
例如,数据库TestRestoreOP的备份文件如下:
我们花费篇章来说明备份文件的格式化,主要是因为【一键】还原的基础是文件的标准化。
相应的还原命令如下:
----完整备份还原
RESTORE DATABASE 数据库名字 FROM
DISK = '完整备份的文件'---'TTTTTTT.BAK'
WITH NORECOVERY, MOVE '数据库名字_Data' TO 'D:\指定路径\数据库名字_Data.mdf',
MOVE '数据库名字_Log' TO 'D:\指定路径\数据库名字_Log.ldf' ----差异备份还原
RESTORE DATABASE 数据库名字 FROM
DISK = '差异备份的文件'------'SSSSSSSSS.BAK'
WITH NORECOVERY, MOVE '数据库名字_Data' TO 'D:\指定路径\数据库名字_Data.mdf',
MOVE '数据库名字_Log' TO 'D:\指定路径\数据库名字_Log.ldf' ----log备份还原
RESTORE Log 数据库名字
FROM DISK ='事务日志备份的文件' -----'XXXXXXXX.trn'
WITH NORECOVERY
2.远程备份文件的【一键】还原
实际的生产中,我们常将备份文件Copy至远程服务器上,所以还原的时候,还要将这些文件Copy到指定服务上再进行还原。还有一种情况,就是Log还原可能需要逐一还原多个日志文件,有时候,甚至十几个文件需要还原。
针对这种这种情况,日常工作中,我们逐渐提炼成了以下SQL,替换参数后,基本实现 一键还原。
主要实现的功能有四点:
(1)将远程Server 上的指定备份路径下的文件Copy值本地指定路径;(如果文件以Copy值本地,这一步可以省略,对应的代码为1和2部分)
(2) 将这些文件属性读到表BackupFile;
(3)根据文件命名的时间属性,还原最近的一个完整备份 和一个差异备份;
(4)还原差异备份后产生的所有日志备份。
3.代码实现
---0 --定义要还原的数据库名字
DECLARE @Cmd varchar (1024)
DECLARE @dbName sysname
Set @dbName='TestRestoreOP' --- 1 --定义远程备份文件所在目录
DECLARE @sourceFile NVARCHAR(500)
SET @sourceFile = '\\169.XXX.XXX.XXX\d$\SQL_BackFile' ----2 -- 将远程备份的目录,Copy至本地 D:\SQL_RestoreFile 目录下,MAXAGE:3 代表Copy最近3天的文件
SET @Cmd=('master.dbo.xp_cmdshell '+'''ROBOCOPY.exe "'+@sourceFile+'" "D:\SQL_RestoreFile" *.* /E /XC /XN /X /MAXAGE:3 /MINAGE:0 ''')
print @Cmd
EXEC (@Cmd) Print '将远程需要还原的文件Copy至本地' ----3 -- 获取还原文件List
DECLARE @Path VARCHAR(260)
SET @Path = 'D:\SQL_RestoreFile'
IF RIGHT(@Path, 1) <> '\'
SET @Path = @Path + '\'
Print @Path
----判断表BackupFile是否已经存在,不存在则创建
IF (SELECT COUNT(*) FROM SYS.sysobjects WHERE name='BackupFile'and xtype='U')=0
BEGIN
CREATE TABLE BackupFile
(
id INT , --编号
directory VARCHAR(260) , --路径
depth INT , --深度,相对与@path
IsFile BIT ,
filename VARCHAR(260),
IsRestore int ,--是否还原
)--0文件夹1文件名成
END Truncate table BackupFile -----判断表TMP_BackupFile是否已经存在,存在则删除再创建
IF (SELECT COUNT(*) FROM SYS.sysobjects WHERE name='TMP_BackupFile'and xtype='U')<>0
BEGIN
DROP TABLE TMP_BackupFile
END
CREATE TABLE TMP_BackupFile
(
id INT IDENTITY , --编号
directory VARCHAR(260) , --路径
depth INT , --深度,相对与@path
IsFile BIT ,
filename VARCHAR(260),
IsRestore int ,--是否还原
)--0文件夹1文件名成 ----将@Path 目录下结构读入到表TMP_BackupFile中
INSERT TMP_BackupFile
( directory ,
depth ,
IsFile
) EXEC master.dbo.xp_dirtree @path = @Path, @depth = 0, @file = 1 update TMP_BackupFile set filename=directory,IsRestore=0 Print '将需要还原的文件信息读入到表TMP_BackupFile中' -----设置不需要还原的数据库文件,即删除
DELETE FROM dbo.TMP_BackupFile WHERE directory NOT LIKE '%'+@dbName+'%' ----设置删除不符合日期规则的文件
DELETE FROM dbo.TMP_BackupFile WHERE left(right([filename],18),14)<'' -----更新目录 UPDATE TMP_BackupFile
SET directory = @Path + directory
WHERE depth = 1 ------
if exists( select * from TMP_BackupFile WHERE depth > 1)
begin Print 'Error:备份文件所在的路径不对,或者@Path包含了不应该存在的文件夹目录!' end
------- INSERT INTO BackupFile (directory, depth, IsFile, [filename], IsRestore)
SELECT B.directory, B.depth, B.IsFile, B.[filename], B.IsRestore FROM TMP_BackupFile B
left join BackupFile e on B.[filename]=e.[filename] where e.[filename] is null ---4 --定义5/6/7 步骤需要的参数 DECLARE @filename NVARCHAR(500)
DECLARE @backupPath NVARCHAR(500) -- 5 -- 找到需要还原的完整备份文件,进行完整还原 SELECT top 1 @filename =[filename] FROM BackupFile WHERE IsRestore=0 AND directory LIKE '%FULL%.bak' ORDER BY left(right([filename],18),14) desc
Print @filename Print 'Msg:完整备份文件:' + @filename + '开始还原!' SELECT @backupPath=directory
FROM BackupFile WHERE filename=@filename AND IsRestore=0
print @dbName
SET @cmd = 'RESTORE DATABASE [' + @dbName + '] FROM DISK = '''
+ @backupPath + ''' WITH FILE = 1, MOVE N'''+@dbName+''' TO N''D:\sql_data\'+@dbName+'.MDF'', MOVE N'''+@dbName+'_Log'' TO N''D:\sql_log\'+@dbName+'.LDF'',NORECOVERY, NOUNLOAD, STATS = 5'
exec (@cmd)
PRINT @cmd UPDATE BackupFile SET IsRestore=1 WHERE filename=@filename AND IsRestore=0 Print 'Msg:完整备份文件:' + @filename + '还原完成!' -- 6 --- 找到需要还原的差异备份文件,进行增量还原 SELECT top 1 @filename=[filename] FROM BackupFile WHERE IsRestore=0 AND directory LIKE '%Diff%.bak' ORDER BY left(right([filename],18),14) desc
print @filename Print 'Msg:获取得知需要还原的差异备份文件:' + @filename + ',此时将不需要还原的差异文件/日志文件设置为不需要还原'
update BackupFile set IsRestore=10
WHERE IsRestore=0 AND
(directory LIKE '%Diff%.bak' or directory LIKE '%TRN%.TRN' ) and left(right([filename],18),14)<left(right( @filename,18),14) Print 'Msg:差异备份文件:' + @filename + '开始还原!' SELECT @backupPath=directory FROM BackupFile WHERE filename=@filename AND IsRestore=0 SET @cmd = 'RESTORE DATABASE [' + @dbName + '] FROM DISK = '''
+ @backupPath + ''' WITH NORECOVERY'
exec(@cmd)
PRINT @cmd UPDATE BackupFile SET IsRestore=1 WHERE filename=@filename AND IsRestore=0 Print 'Msg:差异备份文件:' + @filename + '还原完成!' -- 7 --日志备份文件还原
DECLARE filenames CURSOR FOR
SELECT [filename] FROM BackupFile WHERE IsRestore=0 AND directory LIKE '%TRN%.TRN' ORDER BY left(right([filename],18),14) asc
OPEN filenames
-- Loop through all the files for the database
FETCH NEXT FROM filenames INTO @filename
WHILE @@FETCH_STATUS = 0
BEGIN Print 'Msg:日志备份文件:' + @filename + '开始还原!' SELECT @backupPath=directory FROM BackupFile WHERE filename=@filename AND IsRestore=0
SET @cmd = 'RESTORE LOG [' + @dbName + '] FROM DISK = '''
+@backupPath+ ''' WITH NORECOVERY'
exec(@cmd) UPDATE BackupFile SET IsRestore=1 WHERE filename=@filename AND IsRestore=0 Print 'Msg:日志备份文件:' + @filename + '还原完成!' PRINT @cmd
FETCH NEXT FROM filenames INTO @filename
END
CLOSE filenames
DEALLOCATE filenames -- 8 -- 将数据库的状态由真正还原Restore正常状态! Print '将数据库的状态由真正还原Restore正常状态!'
SET @cmd = 'RESTORE DATABASE [' + @dbName + '] WITH RECOVERY'
exec(@cmd)
PRINT @cmd Print '数据库所有的还原操作都已完成!'
如果在您工作中也有类似需求,需要执行上述代码,则需要替换的参数如下
需要替换的参数数据 | |
参数 | 代表含义 |
@dbName | 需还原的数据库名字,本例为;
TestRestoreOP |
@sourceFile |
备份文件在远程Server路径;本例为
\\169.XXX.XXX.XXX\d$\SQL_BackFile |
没有设置参数 | 备份文件copy至本地的路径;本例为
D:\SQL_RestoreFile |
没有设置参数 |
设置删除不符合日期规则的文件,指的是把旧的文件也Copy到本地了,这还原表中因删除;本例为 20190413015000 |
没有设置参数 |
设置还原数据库的数据文件所在文档路径:本例为 D:\sql_data\。建议不要修改,执行前请先创建。 |
没有设置参数 |
设置还原数据库的日志文件所在文档路径;本例为 D:\sql_log\ 。建议不要修改,执行前请先创建。 |
4.ROBOCOPY.exe知识补充
备份文件的远程Copy通过ROBOCOPY.exe来实现。
Robocopy.exe 是 微软在Windows server 2003 Resource Kit Tools 里面提供的程序来做备份的,Vista,Win2008已经自带了。Microsoft Windows 中内置的传统的“复制和粘贴”功能有一些局限性:它在执行简单的任务(将一个文档从一个目录移动到另一个目录等)时处理得还好,但缺乏 IT 专业人员在工作场所所需的高级功能。例如,复制和粘贴操作不包括任何高级复原功能,所以不允许从短暂的网络中断后进行恢复。Robocopy 支持更多重要的文件复制任务,从而能够简化工作。Robocopy 还允许保留所有相关文件信息,包括日期和时间戳、安全访问控制列表 (ACL) 及更多内容。[更多内容请参考网络分享]
现在主要留意下ROBOCOPY.exe的一些参数,因为我们在代码中有用到他们。
参数 | 含义 |
/MAXAGE | 最长的文件存在时间 - 排除早于 n 天/日期的文件。(n代表指定参数) |
/MINAGE | 最短的文件存在时间 - 排除晚于 n 天/日期的文件。 |
/S | 复制子目录,但不复制空的子目录。 |
/XC | 排除已更改的文件。 |
/XN | 排除较新的文件。 |
/X | 报告所有多余的文件,而不只是选中的文件。 |
感谢:以上代码由作者本人和同事Fly Chen共同完成。
未经作者同意不得转载,谢谢配合!!!
SQL Server 数据库基于备份文件的【一键还原】的更多相关文章
- SQL Server 数据库本地备份文件通过OSS工具上阿里云(恢复还原数据库)
SQL Server数据库上云,通过备份文件上传进行恢复. 1.通过OSS工具上传备份文件. 相关知识和操作步骤请参考: https://blog.csdn.net/weixin_35773751/a ...
- SQL Server 数据库bak备份文件还原操作和mdf文件附加操作
前言:现在任何软件都离不开数据的支持,数据的价值是无价的,因此数据目前显得尤为重要,日常软件生产库的数据定时或实时备份必不可少,备份出的文件也需要进行验证,下边我将介绍SQL Server数据的的备份 ...
- 第一章、关于SQL Server数据库的备份和还原(sp_addumpdevice、backup、Restore)
在sql server数据库中,备份和还原都只能在服务器上进行,备份的数据文件在服务器上,还原的数据文件也只能在服务器上,当在非服务器的机器上启动sql server客户端的时候,也可以通过该客户端来 ...
- SQL Server数据库的备份和还
转:http://blog.csdn.net/zwj7612356/article/details/8188025 在sql server数据库中,备份和还原都只能在服务器上进行,备份的数据文件在服务 ...
- 《SQL Server企业级平台管理实践》读书笔记——关于SQL Server数据库的还原方式
本篇是继上篇的备份方式,本篇介绍的是还原方案,在SQL Server在2005以上现有的还原方案一般分为以下4个级别的数据还原: 1.数据库完整还原级别: 还原和恢复整个数据库.数据库在还原和恢复操作 ...
- SQL Server 数据库使用备份还原造成的孤立用户和对象名‘xxx’无效的错误的解决办法
SQL Server 数据库使用备份还原造成的孤立用户和对象名‘xxx’无效的错误的解决办法 在使用数据库的过程中,经常会遇到数据库迁移或者数据迁移的问题,或者有突然的数据库损坏,这时需要从数据库的备 ...
- 数据库开发基础 SQL Server 数据库的备份、还原与分离、附加
认识数据库备份和事务日志备份 数据库备份与日志备份是数据库维护的日常工作,备份的目的是 一.在于当数据库出现故障或者遭到破坏时可以根据备份的数据库及事务日志文件还原到最近的时间点将损失降到最低点 二. ...
- SQL Server数据库还原:"因为数据库正在使用,所以无法获得对数据库的独占访问权"
如题,网上找了一些客套的方法,如果不想去折腾,请看我的方法: 1.先脱机数据库,这个目的就是为了停掉所有链接 2.选择还原数据库,如果提示日志尾部不完整,请选择数据库属性的选项,覆盖现有数据. 还可以 ...
- (图解版)SQL Server数据库备份与还原
本文介绍了SQL Server数据库备份的两种方式.一种是直接拷贝数据库中的文件mdf 和日志文件ldf,另一种是生成脚本语言. 第一种方式: 选中需要备份的数据库,将数据库从运行的数 ...
随机推荐
- MySql Query Cache 优化
query cache原理 当mysql接收到一条select类型的query时,mysql会对这条query进行hash计算而得到一个hash值,然后通过该hash值到query cache中去匹配 ...
- swagger-ui生成api文档并进行测试
一.Swagger UI简介 Swagger UI是一个API在线文档生成和测试的利器,目前发现最好用的.它的源码也开源在GitHub上,地址:GitHub: https://github.com/s ...
- 阿里云被挖矿进程wnTKYg入侵的解决方法
杀wnTKYg病毒分两步,第一是找到它的来源,切断入口,第二步,找到它的守护进程并杀死,然后再去杀死病毒进程,有的守护进程很隐蔽,唤醒病毒之后,自动消亡,这时候top就看不到了,要留心. 最近项目在做 ...
- ZooKeeper的使用---命令端
一.进入命令行 ./bin/zkCli.sh 二.常用命令 命令 作用 范例 备注 connect host:port 连接其他zookeeper客户端 connect hadoop2:21 ...
- React官方文档笔记之快速入门
快速开始 JSFiddle 我们建议在 React 中使用 CommonJS 模块系统,比如 browserify 或 webpack. 要用 webpack 安装 React DOM 和构建你的包: ...
- 从零开始学习 Docker
这篇文章是我学习 Docker 的记录,大部分内容摘抄自 <<Docker - 从入门到实践>> 一书,并非本人原创.学习过程中整理成适合我自己的笔记,其中也包含了我自己的 ...
- Java开源生鲜电商平台-异常模块的设计与架构(源码可下载)
Java开源生鲜电商平台-异常模块的设计与架构(源码可下载) 说明:任何一个软件系统都会出现各式各样的异常与错误,我们需要根据异常的情况进行捕获与分析,改善自己的代码,让其更加的稳定的,快速的运行,那 ...
- RabbitMQ分布式集群架构和高可用性(HA)
(一) 功能和原理 设计集群的目的 允许消费者和生产者在RabbitMQ节点崩溃的情况下继续运行 通过增加更多的节点来扩展消息通信的吞吐量 1 集群配置方式 RabbitMQ可以通过三种方法来部署分布 ...
- Error【0002】:YUM本地源配置问题
1.1 问题背景 通过VMware workstation创建虚拟机,在虚拟机的CDROM设备中,装载操作系统镜像.然后通过mount -o loop的方式,将CDROM设备挂载到系统的/mnt/cd ...
- vue+axios访问本地json数据踩坑点
当我们想在vue项目中模拟后台接口访问json数据时,我们发现无论如何也访问不到本地的json数据. 注意:1.在vue-cli项目中,我们静态资源只能放在static文件夹中,axios使用get请 ...