备份和还原

概述

在实际生活和工作情况下,为了保证数据库安全需要经常进行数据库的备份和还原操作.我们可能会遇到各种各样的数据库异常状态,如何判别异常状态,如何迅速而安全有效地把系统和数据恢复到正常状态,是系统管理员不可缺少的工作,是衡量系统管理员水平高低的一把尺子.在本章我们将会讲到数据库的恢复模式、几种备份操作和几种还原操作.

数据库的恢复模式

数据库的恢复模式是指数据库遭到破坏时还原数据的策略,一般地,SQL server提供了以下三种恢复模式:

  • 完整恢复模式.
  • 大容量日志记录的恢复模式.
  • 简单恢复模式.

完整恢复模式是等级最高的恢复模式.在完整恢复模式中,对数据库的任何操作都记录在事务日志里.当数据库遭到破坏后,可以使用该事务日志迅速恢复数据库.由于事务日志巨细无遗地记录下了对数据库的所有操作,因此完整恢复模式可以将数据库恢复至任意一个时间点.但是,这种恢复模式将带来巨大的事务日志文件,极其消耗磁盘空间.因此,若不是事务日志非常重要的数据库,一般不采用完整恢复模式.

大容量日志记录的恢复模式的事务日志文件远小于完整恢复模式,这是因为它不记录一些非常消耗空间的操作,如:CREATE INDEXBULK INSERTBCPSELECT…INTO.这种备份方式是最常用的,虽然不可以完全还原数据库,但是可以在事务日志消耗空间和还原完整程度上取一个折中,是非常划算的.

简单恢复模式适用于一些小型数据库,这些数据库通常不会有大量数据变更.数据只能还原到进行备份的时刻点,而备份之后的操作数据将会丢失并需要重建.这种模式的特点是数据库不维护事务日志,好处是最小的磁盘空间占用,以及简单的恢复操作.

备份基础

备份前的准备

为了将数据库安全完整地备份下来,应该在备份之前制定一个完善的备份计划,确保数据库安全.备份计划的制定应考虑如下内容:

  • 备份的频率.即每隔多长时间进行一次备份.这要考虑两个因素: 一是系统还原时的工作量,二是系统活动的事务量.例如对数据库的完全备份,可以每一月、每一周甚至每一天备份一次,对于事务日志的备份,可以是每一周、每一天甚至每一小时.
  • 备份的内容.即要备份的对象.包括系统数据库和用户数据库的数据.
  • 备份使用的介质.即用什么存储备份文件.一般使用的是磁盘(DISK)或磁带(TAPE).
  • 备份工作的负责人.即谁来进行和管理数据库备份.
  • 在线还是脱机备份.在线备份就是动态备份,允许备份时使用数据库,脱机备份不允许备份时使用数据库.
  • 是否使用备份服务器.有条件当然要使用备份服务器,这样在系统故障时,可以快速恢复系统.
  • 备份存储位置.一般将备份文件异地存放(不在被备份的服务器里),且应该多保留几份一样的副本,放在不同的地方.
  • 备份存储的期限.备份数据保留期限越长,需要的备份介质就越多,成本就越高,建议重要数据备份存储期限调高一些.

备份的对象

备份的目的在于当系统出现故障时快速而完整地恢复系统,因此有必要将数据完整备份下来.大体上看,备份对象分为两个方面: 系统数据库和用户数据库.统数据库存储了SQL server系统和全部用户数据库的信息,对系统数据库的备份主要指对mastermsdbmodel数据库的备份.master数据库保存了SQL server系统和全部用户数据库的信息,如用户账户、可配置的环境变量、系统错误信息等.msdb数据库保存了有关SQL server Agent服务的记录.model数据库为新的用户数据库提供了模板.

用户数据库保存了一切用户相关的业务数据,其内容一定不可以丢失,必须充分保护用户数据库的数据安全.从某种意义上说,系统数据库可以丢失,用户数据库一定不能丢失.建议在以下操作进行后,对用户数据库进行备份:

  • 创建数据库后,这是备份和还原的基础.
  • 加载大量数据后.
  • 创建索引后.
  • 清除事务日志后.
  • 执行不记录日志的操作后.

动态备份的特点

动态备份时允许用户在备份时使用数据库.动态备份时,SQL server执行如下操作:

  • 检查点机制检查数据库,记录最早的事务日志记录的日志序列号.
  • 直接读取磁盘,把全部的数据页写进备份介质中.
  • 从捕捉到的序列号到日志结尾,写全部的事务日志记录.

虽然说动态备份允许备份时操作数据库,但是多用户操纵数据库必然会对备份的性能有所影响,同样也会反作用于数据操作的性能,使得两边都进行得慢,因此,应该将备份安排在用户操作不那么活跃的时间段.且以下的操作不允许在备份时进行:

  • CREATE DATABASEALTER DATABASE语句.
  • 创建索引,执行不记录日志的操作,执行数据压缩操作等.

如果在执行这些禁止的操作时启动备份,则备份失败,如果在备份时执行这些禁止的操作,则这些操作执行失败.

执行备份操作

在执行备份操作时,既可以指定永久备份文件,也可以指定临时备份文件.选择好备份文件的类型,在将其备份到指定文件上即可.

创建永久的备份文件

在SQL server中,永久的备份文件,也称为备份设备.如果希望所创建的备份文件反复使用或执行系统的自动化操作,例如: 自动备份数据库,则需要使用备份设备.有两种创建备份设备的方法: T-SQL语句或SSMS,这里使用T-SQL进行操作,其基本语法如下:

sp_addumpdevice 'device_type', 'logical_name', 'physical_name';

其中divece_type有两种(DISK或TAPE),然后指定备份设备逻辑文件名和物理存储位置,如下例:

USE ElecTravelCom;
GO
 
EXEC sp_addumpdevice 'DISK','ElecTravelComBackupFile','F:\MyBackupDataBase\ElecTravelComBackupFile';
GO

运行结果如下:

注意: 创建备份设备之后并不会马上在磁盘内写入,只有执行备份操作后磁盘内才有备份设备文件.

使用BACKUP语句创建备份文件

如果希望创建临时备份文件,并希望灵活地备份,则应该使用BACKUP语句,其备份的基本语法如下:

--Backing Up a Whole Database
BACKUP DATABASE { database_name | @database_name_var }
  TO <backup_device> [ ,...n ]
  [ <MIRROR TO clause> ] [ next-mirror-to ]
  [ WITH { DIFFERENTIAL
           | <general_WITH_options> [ ,...n ] } ]
[;]

--Backing Up Specific Files or Filegroups
BACKUP DATABASE { database_name | @database_name_var }
 <file_or_filegroup> [ ,...n ]
  TO <backup_device> [ ,...n ]
  [ <MIRROR TO clause> ] [ next-mirror-to ]
  [ WITH { DIFFERENTIAL | <general_WITH_options> [ ,...n ] } ]
[;]

--Creating a Partial Backup
BACKUP DATABASE { database_name | @database_name_var }
 READ_WRITE_FILEGROUPS [ , <read_only_filegroup> [ ,...n ] ]
  TO <backup_device> [ ,...n ]
  [ <MIRROR TO clause> ] [ next-mirror-to ]
  [ WITH { DIFFERENTIAL | <general_WITH_options> [ ,...n ] } ]
[;]

--Backing Up the Transaction Log (full and bulk-logged recovery models)
BACKUP LOG
  { database_name | @database_name_var }
  TO <backup_device> [ ,...n ]
  [ <MIRROR TO clause> ] [ next-mirror-to ]
  [ WITH { <general_WITH_options> | <log-specific_optionspec> } [ ,...n ] ]
[;]

<backup_device>::=
 {
  { logical_device_name | @logical_device_name_var }
 | {   DISK
     | TAPE
     | URL } =
     { 'physical_device_name' | @physical_device_name_var | 'NUL' }
 }

<MIRROR TO clause>::=
 MIRROR TO <backup_device> [ ,...n ]

<file_or_filegroup>::=
 {
   FILE = { logical_file_name | @logical_file_name_var }
 | FILEGROUP = { logical_filegroup_name | @logical_filegroup_name_var }
 }

<read_only_filegroup>::=
FILEGROUP = { logical_filegroup_name | @logical_filegroup_name_var }

<general_WITH_options> [ ,...n ]::=
--Backup Set Options
   COPY_ONLY
 | { COMPRESSION | NO_COMPRESSION }
 | DESCRIPTION = { 'text' | @text_variable }
 | NAME = { backup_set_name | @backup_set_name_var }
 | CREDENTIAL
 | ENCRYPTION
 | FILE_SNAPSHOT
 | { EXPIREDATE = { 'date' | @date_var }
        | RETAINDAYS = { days | @days_var } }

--Media Set Options
   { NOINIT | INIT }
 | { NOSKIP | SKIP }
 | { NOFORMAT | FORMAT }
 | MEDIADESCRIPTION = { 'text' | @text_variable }
 | MEDIANAME = { media_name | @media_name_variable }
 | BLOCKSIZE = { blocksize | @blocksize_variable }

--Data Transfer Options
   BUFFERCOUNT = { buffercount | @buffercount_variable }
 | MAXTRANSFERSIZE = { maxtransfersize | @maxtransfersize_variable }

--Error Management Options
   { NO_CHECKSUM | CHECKSUM }
 | { STOP_ON_ERROR | CONTINUE_AFTER_ERROR }

--Compatibility Options
   RESTART

--Monitoring Options
   STATS [ = percentage ]

--Tape Options
   { REWIND | NOREWIND }
 | { UNLOAD | NOUNLOAD }

--Log-specific Options
   { NORECOVERY | STANDBY = undo_file_name }
 | NO_TRUNCATE

--Encryption Options
 ENCRYPTION (ALGORITHM = { AES_128 | AES_192 | AES_256 | TRIPLE_DES_3KEY } , encryptor_options ) <encryptor_options> ::=
   SERVER CERTIFICATE = Encryptor_Name | SERVER ASYMMETRIC KEY = Encryptor_Name

这里是微软对于BACKUP语句的说明文档,因篇幅所限,这里只介绍几个选项参数的作用:

  • CHECKSUM | NO_CHECKSUM指定将页写入介质前是否检查和校验,默认是不检验: NO_CHECKSUM.
  • STOP_ON_ERROR | CONTINUE_AFTER_ERROR指定发现错误是是停止备份还是继续备份.
  • DESCRIPTION是备份的描述信息,可以自由指定,不能超过255个字符.
  • DIFFERENTIAL指定增量备份,仅备份上一次备份后有改动的数据.
  • EXPIREDATE指定备份集失效和可被覆盖的时间和日期.
  • RETAINDATE指定失效和可被覆盖的天数.
  • FORMAT | NOFORMAT指定是否格式化原备份集的内容,默认是不格式化: NOFORMAT.
  • INIT | NOINIT指定备份内容是否追加在原备份集之后,不追加则从头覆盖备份集,默认是追加: NOINIT.
  • PASSWORD指定恢复操作时应输入的密钥.
  • MEDIAPASSWORD指定备份介质的密钥,和PASSWORD相同的是都需要在还原操作时输入该密钥,不同的是PASSWORD可以通过覆盖备份集的形式抹除,MEDIAPASSWORD只能通过格式化备份介质使其失效.
  • SKIP | NOSKIP指定系统读或不读备份集的标题信息,默认是不读: SKIP.
  • NAME指定备份集的名称,最大128个字符.
  • MEDIANAME指定用于整个备份集的备份介质的名称,最大128个字符.
  • COPY_ONLY指定仅复制备份操作,此备份不影响正常的备份序列.

备份数据库

下面我们对数据库进行备份,并写入一个备份设备中:

USE ElecTravelCom;
GO

BACKUP DATABASE ElecTravelCom TO ElecTravelComBackupFile;
GO

运行结果如下(此时备份文件已经写入,因此备份设备也存在与磁盘上了):

创建临时备份文件

前面说过,建立备份设备是创建永久备份文件,可以重复备份到同一个备份设备,现在我们创建临时备份文件,如下:

USE ElecTravelCom;	--创建临时备份文件必须指定介质类型和完整的路径和文件名称;
GO

BACKUP DATABASE ElecTravelCom TO DISK = 'F:\MyBackupDataBase\Tmp\ElecTravelComBackupFile.bak';
GO

运行结果如下:

使用多个文件进行备份

除了可以创建一个备份文件,SQL server可以向多个文件中写入备份数据,此时的备份称为并行备份.在执行并行备份时,数据库的数据就分散在这一个或多个文件中,这些文件组成一个备份集.

使用并行备份可以降低备份时间,例如一个备份文件备份数据库需要12小时,则两个备份文件也许只需6小时,三个也许只需4小时.

使用多个文件进行备份时,应考虑以下因素:

  • 在一次并行备份过程中,所使用的文件必须来自同一种存储介质,不允许混搭使用.
  • 在执行并行备份操作时,可以同时指定永久备份的备份设备和临时备份的备份文件.但是从性能角度分析,不建议这么做.
  • 在一个备份集中的文件应同时使用.除非格式化文件,否则不能单独使用备份集中的文件.
  • 如果格式化备份集中的某个文件,则整个备份集都无法使用了.

备份方法

SQL server提供了四种不同的备份方法,以满足企业和数据库活动的需要,它们分别是:

完全备份数据库增量备份数据库事务日志备份数据库文件或文件组备份


完全备份数据库: 备份数据库中的所有数据和结构.数据库的第一次备份应该要是完全备份,这种备份是其它备份的基础.使用完全备份数据库时,SQL server将备份发生在备份过程中的任何活动,备份事务日志中的任何内容,包括未提交的事务.根据本章开头的内容,我们知道完全备份数据库的语法如下(其下提及的各参数请参见本章开头部分):

--Backing Up a Whole Database
BACKUP DATABASE { database_name | @database_name_var }
  TO <backup_device> [ ,...n ]
  [ <MIRROR TO clause> ] [ next-mirror-to ]
  [ WITH { DIFFERENTIAL
           | <general_WITH_options> [ ,...n ] } ]
[;]

增量备份数据库: 备份上一次完全数据库备份后改变的数据.可以降低数据库备份的时间.这种方法必须基于先完全备份数据库,且适用于经常变更的数据库,增量备份数据库的语法如下(其下提及的各参数请参见本章开头部分):

--Backing Up a Whole Database
BACKUP DATABASE { database_name | @database_name_var }
  TO <backup_device> [ ,...n ]
  [ <MIRROR TO clause> ] [ next-mirror-to ]
  WITH DIFFERENTIAL
[;]

我们执行一次增量备份,如下:

USE ElecTravelCom;
GO

BACKUP DATABASE ElecTravelCom TO DISK = 'F:\MyBackupDataBase\Tmp\ElecTravelComBackupFile.bak'
	WITH DIFFERENTIAL;
GO

运行结果如下:

事务日志备份: 备份数据库中事务日志发生变化的过程.当执行完全备份数据库后,可以执行事务日志备份.使用事务日志备份时,应考虑如下因素:

  • 这种备份必须基于完全备份数据库.
  • 没有完全数据库的还原,不能执行事务日志的还原.
  • 数据库备份若使用了简单恢复模式,则不能使用事务日志备份.
  • 事务日志备份的内容是从上一次执行事务日志备份到当前事务日志结束.

事务日志备份的语法如下(其下提及的各参数请参见本章开头部分):

--Backing Up the Transaction Log (full and bulk-logged recovery models)
BACKUP LOG
  { database_name | @database_name_var }
  TO <backup_device> [ ,...n ]
  [ <MIRROR TO clause> ] [ next-mirror-to ]
  [ WITH { <general_WITH_options> | <log-specific_optionspec> } [ ,...n ] ]
[;]

下面对AdventureWorks2017进行一次完全数据库备份,再进行事务日志备份:

首先将AdventureWorks2017的恢复模式由简单改到完整:

然后创建两个永久备份设备,进行备份:

USE AdventureWorks2017;
GO

EXEC sp_addumpdevice 'DISK','AdventureWorks2017BackupFile','F:\MyBackupDataBase\AdventureWorks2017\AdventureWorks2017BackupFile.bak';
EXEC sp_addumpdevice 'DISK','AdventureWorks2017BackupLogFile','F:\MyBackupDataBase\AdventureWorks2017\AdventureWorks2017BackupLogFile.bak';
GO

BACKUP DATABASE AdventureWorks2017 TO AdventureWorks2017BackupFile;
GO

BACKUP LOG AdventureWorks2017 TO AdventureWorks2017BackupLogFile;
GO

运行结果如下:

创建的备份文件如下:

再多说一句:事务日志备份时,可以使用TRUNCATE_ONLYNO_LOG选项,它们的作用如下:

  • TRUNCATE_ONLY仅仅清除事务日志,不进行备份,该选项仅在数据库的事务日志正常的情况下起作用.
  • NO_LOG选项用来清除事务日志,不过它可以清除数据库中不正常的(已满的)事务日志.

数据库文件或文件组备份: 对于海量数据的大型数据库,可以指定若干个数据库文件/文件组进行备份,这种备份也需要先进行完全数据库备份.使用数据库文件或文件组备份时,应当指定数据库文件的逻辑名称或文件组的名称,且数据库文件或文件组应该进行周期性的备份,数据库文件或文件组备份的基本语法如下(其下提及的各参数请参见本章开头部分):

--Backing Up Specific Files or Filegroups
BACKUP DATABASE { database_name | @database_name_var }
 <file_or_filegroup> [ ,...n ]
  TO <backup_device> [ ,...n ]
  [ <MIRROR TO clause> ] [ next-mirror-to ]
  [ WITH { DIFFERENTIAL | <general_WITH_options> [ ,...n ] } ]
[;]

如下,将AdventureWorks2017数据库的主数据文件AdventureWorks2017做一个备份,备份到一个临时备份文件中:

USE AdventureWorks2017;
GO

BACKUP DATABASE AdventureWorks2017 FILE = 'AdventureWorks2017' 
	TO DISK = 'F:\MyBackupDataBase\Tmp\AdventureWorks2017.bak';
GO

运行结果如下:

还原

还原的特征

还原是和备份相对应的操作,备份是为了防止意外发生,还原则是处理已经发生的意外.因此,备份是还原的基础,没有备份就谈不上还原,还原时备份的目的,备份是为了还原而备份,不是为了备份而备份.

还原是指将数据从备份中加载到系统的过程,在还原之前,应检查备份的安全性,这些安全性检查包括:

  • 指定的数据库是否存在.
  • 数据库文件是否变化.
  • 数据库文件是否兼容.
  • 重建数据库及相关文件.

针对不同的数据库,应采用不同的还原方法.使用完全数据库备份还原时,系统将自动重建原来的数据库文件,并将这些文件放在备份数据库时这些文件所在的位置.这种进程是自动的,用户无需手动重建数据库.

验证备份的内容

在还原之前,应先验证备份文件是否有效,可以使用如下语句来验证备份的内容(点击语句获取详细信息):

如下,我们使用RESTORE VERIFYONLY语句验证备份:

USE ElecTravelCom;
GO

RESTORE VERIFYONLY FROM ElecTravelComBackupFile;
GO

备份集有效,结果如下:

使用RESTORE语句

使用RESTORE语句可以还原BACKUP创建的备份,下面是来自微软的文档:

--To Restore an Entire Database from a Full database backup (a Complete Restore):
RESTORE DATABASE { database_name | @database_name_var }
 [ FROM <backup_device> [ ,...n ] ]
 [ WITH
   {
    [ RECOVERY | NORECOVERY | STANDBY =
        {standby_file_name | @standby_file_name_var }
       ]
   | ,  <general_WITH_options> [ ,...n ]
   | , <replication_WITH_option>
   | , <change_data_capture_WITH_option>
   | , <FILESTREAM_WITH_option>
   | , <service_broker_WITH options>
   | , <point_in_time_WITH_options-RESTORE_DATABASE>
   } [ ,...n ]
 ]
[;]

--To perform the first step of the initial restore sequence of a piecemeal restore:
RESTORE DATABASE { database_name | @database_name_var }
   <files_or_filegroups> [ ,...n ]
 [ FROM <backup_device> [ ,...n ] ]
   WITH
      PARTIAL, NORECOVERY
      [  , <general_WITH_options> [ ,...n ]
       | , <point_in_time_WITH_options-RESTORE_DATABASE>
      ] [ ,...n ]
[;]  

--To Restore Specific Files or Filegroups:
RESTORE DATABASE { database_name | @database_name_var }
   <file_or_filegroup> [ ,...n ]
 [ FROM <backup_device> [ ,...n ] ]
   WITH
   {
      [ RECOVERY | NORECOVERY ]
      [ , <general_WITH_options> [ ,...n ] ]
   } [ ,...n ]
[;]  

--To Restore Specific Pages:
RESTORE DATABASE { database_name | @database_name_var }
   PAGE = 'file:page [ ,...n ]'
 [ , <file_or_filegroups> ] [ ,...n ]
 [ FROM <backup_device> [ ,...n ] ]
   WITH
       NORECOVERY
      [ , <general_WITH_options> [ ,...n ] ]
[;]

--To Restore a Transaction Log:
RESTORE LOG { database_name | @database_name_var }
 [ <file_or_filegroup_or_pages> [ ,...n ] ]
 [ FROM <backup_device> [ ,...n ] ]
 [ WITH
   {
     [ RECOVERY | NORECOVERY | STANDBY =
        {standby_file_name | @standby_file_name_var }
       ]
    | , <general_WITH_options> [ ,...n ]
    | , <replication_WITH_option>
    | , <point_in_time_WITH_options-RESTORE_LOG>
   } [ ,...n ]
 ]
[;]

--To Revert a Database to a Database Snapshot:
RESTORE DATABASE { database_name | @database_name_var }
FROM DATABASE_SNAPSHOT = database_snapshot_name

<backup_device>::=
{
   { logical_backup_device_name |
      @logical_backup_device_name_var }
 | { DISK
     | TAPE
     | URL
   } = { 'physical_backup_device_name' |
      @physical_backup_device_name_var }
}
Note: URL is the format used to specify the location and the file name for the Microsoft Azure Blob. Although Microsoft Azure storage is a service, the implementation is similar to disk and tape to allow for a consistent and seamless restore experience for all the three devices.
<files_or_filegroups>::=
{
   FILE = { logical_file_name_in_backup | @logical_file_name_in_backup_var }
 | FILEGROUP = { logical_filegroup_name | @logical_filegroup_name_var }
 | READ_WRITE_FILEGROUPS
}

<general_WITH_options> [ ,...n ]::=
--Restore Operation Options
   MOVE 'logical_file_name_in_backup' TO 'operating_system_file_name'
          [ ,...n ]
 | REPLACE
 | RESTART
 | RESTRICTED_USER | CREDENTIAL

--Backup Set Options
 | FILE = { backup_set_file_number | @backup_set_file_number }
 | PASSWORD = { password | @password_variable }

--Media Set Options
 | MEDIANAME = { media_name | @media_name_variable }
 | MEDIAPASSWORD = { mediapassword | @mediapassword_variable }
 | BLOCKSIZE = { blocksize | @blocksize_variable }

--Data Transfer Options
 | BUFFERCOUNT = { buffercount | @buffercount_variable }
 | MAXTRANSFERSIZE = { maxtransfersize | @maxtransfersize_variable }

--Error Management Options
 | { CHECKSUM | NO_CHECKSUM }
 | { STOP_ON_ERROR | CONTINUE_AFTER_ERROR }

--Monitoring Options
 | STATS [ = percentage ]

--Tape Options.
 | { REWIND | NOREWIND }
 | { UNLOAD | NOUNLOAD }

<replication_WITH_option>::=
 | KEEP_REPLICATION

<change_data_capture_WITH_option>::=
 | KEEP_CDC

<FILESTREAM_WITH_option>::=
 | FILESTREAM ( DIRECTORY_NAME = directory_name )

<service_broker_WITH_options>::=
 | ENABLE_BROKER
 | ERROR_BROKER_CONVERSATIONS
 | NEW_BROKER

<point_in_time_WITH_options-RESTORE_DATABASE>::=
 | {
   STOPAT = { 'datetime'| @datetime_var }
 | STOPATMARK = 'lsn:lsn_number'
                 [ AFTER 'datetime']
 | STOPBEFOREMARK = 'lsn:lsn_number'
                 [ AFTER 'datetime']
   }

<point_in_time_WITH_options-RESTORE_LOG>::=
 | {
   STOPAT = { 'datetime'| @datetime_var }
 | STOPATMARK = { 'mark_name' | 'lsn:lsn_number' }
                 [ AFTER 'datetime']
 | STOPBEFOREMARK = { 'mark_name' | 'lsn:lsn_number' }
                 [ AFTER 'datetime']
   }

具体的参数信息可以看这里,本文只挑几个选项参数来说:

  • FILE指定要还原的备份集中备份文件的标志号.
  • KEEP_REPUBLIC作用是当还原某个配置为出版的数据库时,指定保留数据复制的设置.
  • MEDIANAME指定备份集的名称,若在备份时制定了该选项,则还原时必须提供,否则无法进行还原.
  • PASSWORD提供备份集的密钥.
  • MEDIAPASSWORD提供备份集介质的密钥.
  • MOVE TO指定还原后数据库物理文件存放路径,使用该选项可以改变原数据库的路径.
  • RECOVERY | NORECOVERY是否处于提交还原完成事务,RECOVERY表示提交,此时用户可以操作数据库,不可继续进行还原操作.NORECOVERY表示未提交,此时用户无法使用数据库,但可继续进行还原操作.
  • STANDBY指定允许恢复撤销效果的备用文件.该备用文件允许用户在数据库还原时以只读方式访问数据库.
  • REPLACE指定系统重新创建数据库和相关文件.目的是防止覆盖其它数据库.如: 备份的数据库是Human,希望还原成Sales,则需要指定该选项,备份和还原数据库名称一致则无需指定该选项.
  • RESTART指示系统从上一中断点继续执行还原操作.
  • RESTRICTED_USER限制只有db_ownerdbcreatorsysadmin角色的成员才可访问新还原的数据库.
  • STATS指示系统显示还原的各项统计信息.
  • STOPAT指定数据库还原到特定日期和时间的状态.
  • STOPMARK指定数据库还原到指定的标记,STOPBEFOREMARK指定数据库还原到指定标记的上一个标记.

RECOVERY/NORECOVERY选项

在执行还原操作时,必须指定RECOVERY | NORECOVERY中的一个,默认选项是RECOVERY,使用后数据库还原到正常状态:

  • SQL server取消事务日志中所有未完成的事物,提交所有已完成的事务.
  • 数据库可以使用.

如果有多个备份内容需要还原,则应该指定NORECOVERY选项,使用时应该注意:

  • 除了最后一个要还原的操作,前面所有还原操作都应指定NORECOVERY选项.
  • RECOVERY选项下,SQL server既不取消未完成的事务,也不提交已完成的事务.
  • 数据库不可使用.

还原数据库

如果数据库受到了损坏,此时需要对其进行还原操作.应该先从一个完整的备份中还原,这是所有还原的基础,此时应该指定RECOVERY选项.当进行一次完整还原时,以后的还原可以从多个备份内容还原,此时指定NORECOVERY选项.

如下是一个完整数据库还原操作:

USE master;
GO

RESTORE Database ElecTravelCom FROM ElecTravelComBackupFile WITH RECOVERY,REPLACE;
GO

运行结果如下:

上文指定了选项,注意如果不指定选项,就可能会提示没有备份日志文件尾部,此时如果确保日志文件中没有什么特别重要的内容,建议直接使用选项覆盖(还原本身就是回到之前的状态,自然不可能保留所有数据,因此建议直接覆盖),否则就会终止还原:

注意不可在进行还原操作时使用数据库,否则还原操作将会失败,如下图所示:

从增量备份中还原数据库,使用的语句与从完全备份中还原数据库完全相同.如果从增量备份中还原,系统会进行如下操作:

  • 只还原从上一次完全备份之后变化的内容.
  • 把数据库还原到执行增量备份时完全一致的状态.
  • 增量还原所用时间相对完全还原大大缩短,但是增量还原要以完全还原为基础.

从事务日志备份中还原,可以使用RESTORE LOG语句,执行事务日志还原的起点可以是完全还原数据库、增量还原数据库或上一次事务日志还原数据库之后.下面进行一个事务日志还原操作:

USE master;
GO

RESTORE Database AdventureWorks2017 FROM AdventureWorks2017BackupFile WITH NORECOVERY,REPLACE;
GO

RESTORE LOG AdventureWorks2017 FROM AdventureWorks2017BackupFile WITH RECOVERY,REPLACE;
GO

运行结果如下:

另外可以使用STOPAT选项指定数据库的还原点(具体时间):

USE master;
GO

RESTORE DATABASE AdventureWorks2017 FROM AdventureWorks2017BackupFile WITH NORECOVERY;
RESTORE LOG AdventureWorks2017 FROM AdventureWorks2017BackupFile WITH NORECOVERY,REPLACE,
	STOPAT = '04 14, 2019 9:30 AM';
RESTORE DATABASE AdventureWorks2017 WITH RECOVERY;
GO

运行结果如下:


关于RECOVERYNORECOVERY选项,已经说过很多遍了,但是对于一些操作(如时间点还原)不管是否在最后指定RECOVERY,系统都不会将事务日志进行提交,这样是为了方便用户回滚之前的操作,数据库此时处于还原状态(不可用),但是一旦用户确定了这样的还原是正确的,不需要进行回滚操作,则可以将数据库手动置为可用状态,按照官方文档,我们可以这样写:

RESTORE DATABASE db_name FROM ... WITH NORECOVERY,...;
RESTORE LOG db_name FROM ... WITH NORECOVERY,...;
...
RESTORE DATABASE db_name WITH RECOVERY;
GO

即对所有的还原操作都指定NORECOVERY,直到最后确定所有的备份都还原完成,再用如下语句:

RESTORE DATABASE db_name WITH RECOVERY;

将数据库置为可用(已还原)状态,详情可以参考上面的一个时间点还原的例子.

上一篇: 存储过程、触发器和函数
下一篇: 事务

猜你喜欢

转载自blog.csdn.net/AAMahone/article/details/89301144