600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 从创建数据库到备份恢复还原详解

从创建数据库到备份恢复还原详解

时间:2020-09-14 10:05:10

相关推荐

从创建数据库到备份恢复还原详解

之前在做公司的数据库备份,然后就想到了用代码从创建数据库开始,再备份再恢复再定期清理备份巴拉巴拉的全套

先膜拜一下大神/gaizai/p/3535567.html 这个博主真心牛叉,主要是在跟着他的博学习的,

非常感谢博主的分享。。。

另外里面的数据库名是我有些在测试库上弄得,有些在正式库上弄得,就不是很统一,反正没差,只要看懂了可以自己修改的

一、创建数据库

create database web_1

on PRIMARY

(

NAME = web,

FILENAME='E:\test\web.mdf', --此路径必须存在才能建成功

SIZE = 10,

MAXSIZE = UNLIMITED,

FILEGROWTH = 5

)

LOG ON

(

NAME='web_dat',

FILENAME='E:\test\web.ldf', --此路径必须存在才能建成功

SIZE =5MB,

MAXSIZE = 25MB,

FILEGROWTH =5MB

)

GO

这个代码创建跟从数据库可视化界面操作有一些参数的区别,详情说明本宝已经写在另外一篇文章里面的

/liu-shiliu/p/5557210.html

二 创建备份日志记录表

USE [msdb]

GO

CREATE TABLE [dbo].[JobLog](

[Id] [int] IDENTITY(1,1) NOT NULL,

[DB_Name] [varchar](50) NULL,

[Backup_Date] [int] NULL,

[Backup_Time] [int] NULL ,

[Backup_Duration] [int] NULL,

[Backup_Type] [char](4) NULL,

CONSTRAINT [PK_JobLog] PRIMARY KEY CLUSTERED

(

[Id] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

) ON [PRIMARY] --备份数据库表

--错误记录表

USE [msdb]

GO

CREATE TABLE [dbo].[ErrorLog](

[Id] [int] IDENTITY(1,1) NOT NULL,

[DB_Name] [varchar](50) NOT NULL,

[Backup_Time] [datetime] NOT NULL CONSTRAINT [DF_ErrorLog_Backup_Time] DEFAULT (getdate()),

[Messages] [nvarchar](500) NULL,

CONSTRAINT [PK_ErrorLog] PRIMARY KEY CLUSTERED

(

[Id] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

) ON [PRIMARY]

select * from [msdb].[dbo].[ErrorLog]

select * from [msdb].[dbo].[JobLog]

三、创建备份的文件夹,由于可能有多个数据库,按数据库名称建文件夹,再依次备份到对应的文件夹里面

EXEC sp_configure 'show advanced options', 1 --若不开启此项,会提示不能对系统时间进行即时更新

RECONFIGURE WITH override -- 有些sql版本不加WITH override这个参数就会报错

EXEC sp_configure 'xp_cmdshell', 1 --此选项开启有风险,操作完一定要关闭

RECONFIGURE WITH override

DECLARE @DBName VARCHAR(100)

DECLARE CurDBName CURSOR FOR

SELECT name FROM sys.databases WHERE name not in('master','tempdb','model','msdb','ReportServer','ReportServerTempDB') --要备份的数据库文件

OPEN CurDBName

FETCH NEXT FROM CurDBName INTO @DBName

WHILE @@FETCH_STATUS = 0

BEGIN

--临时表用于存错误信息

if (OBJECT_ID('tempdb..#tb01') is not null)

drop table #tb01 --drop table tempdb..#tb01 --ok too

create table #tb01([dosCMDResult] varchar(4000)) --save DOS cmd result

--//3,检查指定的路径是否存在,如果不存在则建立之,存在则提示

declare @strPath varchar(4000)

declare @dosCMD varchar(50)

declare @cmdLine varchar(4000)

set @strPath = 'E:\BACKUP_' + @DBName--指定路径 ,可以用'E:\BACKUP\111'这种方式指定二级或更多级目录,但是下面的找不到要改为 where dosCMDResult like '%找不到文件%'

set @dosCMD = 'dir ' --dos cmd

select @strPath

set @cmdLine = @dosCMD+@strPath

insert into #tb01 exec master..xp_cmdshell @cmdLine

--select * from #tb01

if exists(select 1 from #tb01 where dosCMDResult = '找不到文件') --路径不存在

begin

set @dosCMD = 'md ' --若上面置顶的路径是二级或者多级目录,也能实现创建

set @cmdLine = @dosCMD + @strPath

exec master..xp_cmdshell @cmdLine

end

drop table #tb01

set @cmdLine = null

set @dosCMD = null

set @strPath = null

FETCH NEXT FROM CurDBName INTO @DBName

END

CLOSE CurDBName

DEALLOCATE CurDBName

EXEC sp_configure 'xp_cmdshell', 0

RECONFIGURE WITH override

EXEC sp_configure 'show advanced options', 0

RECONFIGURE WITH override

四、批量备份数据库,并将数据库备份到指定的文件夹下面

DECLARE @DBName VARCHAR(100)

DECLARE @CurrentTime VARCHAR(50)

DECLARE @FileName VARCHAR(200)

DECLARE @WithType CHAR(20)

DECLARE @Backup_Date VARCHAR(50)

DECLARE @Backup_Time VARCHAR(50)

DECLARE @Backup_Duration VARCHAR(50)

DECLARE @Backup_Start DATETIME

DECLARE @Backup_End DATETIME

DECLARE @BackupType CHAR(4)

DECLARE @SQL VARCHAR(MAX)

--防止作业遗漏备份

INSERT INTO [msdb].[dbo].[JobLog]([DB_Name],[Backup_Date],[Backup_Time],[Backup_Duration],[Backup_Type])

SELECT name,0,0,0,NULL FROM sys.databases WHERE name not in('master','tempdb','model','msdb','ReportServer','ReportServerTempDB')

AND name NOT IN (SELECT DISTINCT [DB_Name] FROM [msdb].[dbo].[JobLog])

ORDER BY name

DECLARE CurDBName CURSOR FOR

SELECT name FROM sys.databases WHERE name not in('master','tempdb','model','msdb','ReportServer','ReportServerTempDB') ORDER BY name

OPEN CurDBName

FETCH NEXT FROM CurDBName INTO @DBName

WHILE @@FETCH_STATUS = 0

BEGIN

--Execute Backup

--捕获异常

BEGIN TRY

PRINT @DBName

SET @CurrentTime = REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR, GETDATE(), 120 ),'-','_'),' ','_'),':','')

IF(DATEPART(DW, GETDATE()) = 2)--星期一全备份

BEGIN

SET @FileName = 'E:\BACKUP_'+@DBName+'\'+@DBName+'_Full_' + @CurrentTime+'.bak'

SET @WithType = ' FORMAT'

SET @BackupType = 'Full'

END

ELSE

BEGIN

SET @FileName = 'E:\BACKUP_'+@DBName+'\'+@DBName+'_Diff_' + @CurrentTime+'.bak'

SET @WithType = ' DIFFERENTIAL,FORMAT'

SET @BackupType = 'Diff'

END

SET @Backup_Start = GETDATE()

SET @SQL = '

--1设置完整模式

ALTER DATABASE ['+@DBName+'] SET RECOVERY FULL WITH NO_WAIT;

--2备份主分区

BACKUP DATABASE ['+@DBName+'] /*FILEGROUP=''PRIMARY''*/ TO DISK='''+@FileName+''' WITH '+@WithType+',COMPRESSION; --新加,COMPRESSION 压缩备份

--3设置简单模式

ALTER DATABASE ['+@DBName+'] SET RECOVERY SIMPLE WITH NO_WAIT;

'

EXEC(@SQL)

SET @Backup_End = GETDATE()

SET @Backup_Date = CONVERT(VARCHAR, GETDATE(),112)

SET @Backup_Time = REPLACE(CONVERT(VARCHAR, GETDATE(),24),':','')

SET @Backup_Duration = CONVERT(VARCHAR,DATEDIFF(ss,@Backup_Start,@Backup_End))

PRINT @Backup_Date +@Backup_Time +@Backup_Duration

SET @SQL = '

INSERT INTO [msdb].[dbo].[JobLog]([DB_Name],[Backup_Date],[Backup_Time],[Backup_Duration],[Backup_Type])

VALUES('''+@DBName+''','+@Backup_Date+','+@Backup_Time+','+@Backup_Duration+','''+@BackupType+''');

'

EXEC(@SQL)

END TRY

BEGIN CATCH

INSERT INTO [msdb].[dbo].[ErrorLog]([DB_Name],[Messages])

VALUES(@DBName,ERROR_MESSAGE())

--ROLLBACK TRANSACTION

END CATCH

--Get Next DataBase

FETCH NEXT FROM CurDBName INTO @DBName

END

CLOSE CurDBName

DEALLOCATE CurDBName

针对这一段备份,又要再次膜拜/gaizai/p/3535567.html这篇博客的博主了,太牛叉了,就是按照他的思路稍微修改了一点点,博主很威武

当时操作完这段的时候,瞬间觉得人生圆满,毕竟之前我只是一个只会操作可视化界面的菜鸟,读懂那篇博客再修改了一丢丢,好激动。。。

五、删除数据库

先解释下为什么要删除数据库,我只是想在试试我备份的东西有没有问题,所以我就把数据库删除了,然后再用上面的备份文件恢复的

切记切记这步有风险,最好先在本地实践了确定Ok了再操作或者不删除。删除有风险,请谨慎

/*可以用sql语句使删除数据库时不会弹出“无法删除数据库 ,因为该数据库当前正在使用”的提示吗?*/

--找出要删除的数据库的进程

SELECT 'kill ' + CAST(spid AS VARCHAR)

FROM MASTER..sysprocesses

WHERE dbid = DB_ID('new_web')

-- 删除进程

Use master

kill 54

GO

--删除数据库

drop database new_web

--------方法二(方法二我并没有实践,是从网上找的方法,有兴趣的可以自己实践)------------------------

USE MASTER

GO

DECLARE @dbname SYSNAME

SET @dbname = 'webcenter' --这个是要删除的数据库库名

DECLARE @s NVARCHAR(1000)

DECLARE tb CURSOR LOCAL

FOR

SELECT s = 'kill ' + CAST(spid AS VARCHAR)

FROM MASTER..sysprocesses

WHERE dbid = DB_ID(@dbname)

OPEN tb

FETCH NEXT FROM tb INTO @s

WHILE @@fetch_status = 0

BEGIN

EXEC (@s)

FETCH NEXT FROM tb INTO @s

END

CLOSE tb

DEALLOCATE tb

EXEC ('drop database [' + @dbname + ']')

六、还原数据库

RESTORE FILELISTONLY FROM DISK = N'E:\DBBackup\tttt_1\tttt_1_Full__06_04_155332.bak' --备份文件存放路径 先用这段找到名称

RESTORE DATABASE [new_ttttt] --新库名字

FROM DISK = N'E:\DBBackup\tttt_1\tttt_1_Full__06_04_155332.bak' --备份文件

WITH FILE = 1,

MOVE N'tttt_1' TO N'E:\test\new_tttt.mdf', --原始数据库名字 新的附加位置

MOVE N'tttt_1_log' TO N'E:\test\new_tttt_1.LDF', --原始数据库名字 新的附加位置

NORECOVERY,

NOUNLOAD, STATS = 10

GO --完整备份还原

RESTORE DATABASE [new_ttttt] --新库名字

FROM DISK = N'E:\DBBackup\tttt_1\tttt_1_Diff__06_04_160529.bak' --备份文件

WITH FILE = 1,

MOVE N'tttt_1' TO N'E:\test\new_tttt.mdf', --原始数据库名字 新的附加位置

MOVE N'tttt_1_log' TO N'E:\test\new_tttt_1.LDF', --原始数据库名字 新的附加位置

NOUNLOAD, STATS = 10

GO--差异备份还原

/*

如果代码还原数据库,明明操作界面已经提示完成了,但是数据库的地方一直显示“正在还原”,

这个是因为恢复进程被挂起了。这个时候假设你要恢复并且回到可访问状态,要执行:

RESTORE database dbname with recovery

如果你要不断恢复后面的日志文件,的确需要使数据库处于“正在还原状态”

RESTORE database dbname with norecovery

*/

还原数据库这步,有可能会报错误,主要是红色框那部分的名字是之前数据库的名字,

这个怎么说喃,我目前就是各种蒙的,呃呃呃,找到解决方法了,就是加前面一句,不过也不要担心,即使真的蒙不对,还可以用可视化界面操作。这样会自动生成的

七、删除备份文件

将上面的操作完以后,就把备份的这些加入到作业里面,让它每天自动备份,关于备份计划,本宝以前的公司就是每天差异备份,每周完全备份。然后现在本宝在游戏公司,有些运营数据比较及时,

所以本宝采用的是6小时一差异备份,每周一完整备份,并将备份的数据发到SVN上面去(不过这个是游戏上线后的策略哈,目前其实就是备份一次)。

因为本宝很怕数据出问题了然后恢复不了。反正就考虑尽量周全一点。

备份文件还是比较多,所以还是要定期清理备份文件的,但是每天自己点也是麻烦,所以又找了一些方法来自动删除。

EXEC sp_configure 'show advanced options', 1--不加这个会提示不能对系统时间进行及时更新

RECONFIGURE WITH override

EXEC sp_configure 'xp_cmdshell', 1 --此选项开启有风险,操作完一定要关闭

RECONFIGURE WITH override

DECLARE @DBName VARCHAR(100)

declare @time varchar(100)=REPLACE(REPLACE(CONVERT(varchar(100), dateadd(day,-15,GETDATE()), 23 ),'-','_'),' ','_')+'_4' --4固定的时间小时 删除前十五天的差异备份,因为我现在目前是每天定时备份一次的,所以时间就写死了。后期还要修改

declare CurDBname cursor for--不加参数默认为Forward_Only

select name from sys.sysdatabases where name not in('master','tempdb','model','msdb','ReportServer','ReportServerTempDB')

open CurDBname

FETCH NEXT FROM CurDBName INTO @DBName

while @@FETCH_STATUS=0

begin

declare @strPath varchar(4000)

declare @dosCMD varchar(50)

declare @cmdLine varchar(4000)

---------------1 -----------判断要删除的文件是否存在---------------

--创建临时表,记录查询文件的结果

if (OBJECT_ID('tempdb..#tb01') is not null)

drop table #tb01 --drop table tempdb..#tb01 --ok too

create table #tb01([dosCMDResult] varchar(4000))

set @dosCMD='dir '

set @strPath='E:\BACKUP_' + @DBName+'\'+@DBName+'_Diff_'+@time+'.bak' --构建差异备份的路径

select @strPath

set @cmdLine = @dosCMD+@strPath

insert into #tb01 exec master..xp_cmdshell @cmdLine

if not exists(select 1 from #tb01 where dosCMDResult = '找不到文件')

begin

set @dosCMD='del '

set @cmdLine= @dosCMD+@strPath

exec master..xp_cmdshell @cmdLine

end

drop table #tb01

FETCH NEXT FROM CurDBName INTO @DBName

end

Close CurDBName

DEALLOCATE CurDBName

EXEC sp_configure 'xp_cmdshell', 0

RECONFIGURE WITH override

EXEC sp_configure 'show advanced options', 0

RECONFIGURE WITH override

需要说明一下,我只写了差异备份的删除,因为完全备份很重要,我还是放弃了自动删除的方式,还是决定定期手动清理,本宝怕刚好出问题了,然后完全备份又被删除了,这样就蒙圈了。

所以还是选择麻烦一点,手动删除完全备份。

八、就是这些,欢迎转载,但是请注明出处。若是有问题神马的,欢迎留言交流哦。。。。。。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。