使用PowerShell 命令集进行SQL Server 2012 备份和还原

最近心相不错,所以打算翻译一些英文文档做福利,原文在此,翻译有不足的地方还请各位兄弟指点.

讨论什么是DBA最重要的工作的时候,你最常听到就是一条就是DBA只要做好备份和恢复.事实如此,如果你不做备份,或者无法保证你的备份能够有效恢复,你和你的公司就会处于数据丢失危险下.

T-SQL 命令BACKUP DATABASE已经使用了相当长的一段时间(在这之前用的是DUMP DATABASE 命令,老人们都记得). 它仍然不失为备份数据库好方式.我们现在有一个新的方法来自动的做这些日常的备份处理任务.在本文中我会通过实例来介绍如何通过PowerShell脚本来备份.并告诉大家在SQL Server 2012 使用PowerShell Cmdlet的便利性.

在SQL Server 2012 中,微软增加了4个新的备份和还原的cmdlet

  • Backup-SqlDatabase
  • Restore-SqlDatabase
  • Backup-ASDatabase
  • Restore-ASDatabase

为什么要通过外部程序来做脚本备份?

当备份工作越来越复杂,越来越多文件系统要被牵涉进去的时候.这些工作可能需要建立并按放备份文件至某个目录,删掉不需要的旧备份,异地拷贝,检查备份完整性,写入日志等等. 你也可能想一步操作就把在不同服务器上的多个数据库进行备份或者拷贝数据库到几个服务器或者虚拟机上做测试.这个时候备份和还原就需要考虑使用脚本,而PowerShell擅长此道.

使用Powershell和SMO编写脚本

在2009年我发布了白皮书backup.ps1 ,使用SMO(Server Management Objects)库来备份你的数据库.SMO支持SQL Server versions 2000 ~ 2012, 微软在SQL Server 2012并没有给SMO增加多少新的特性.所以没多少新东西可学.

在白皮书中我讲述了SQL Server snapins , 还有SQL Server 2008 和 SQL Server 2008 R2 里面的迷你Shell (SQLPS.exe) ,PowerShell 团队为 SQL Server 2008 扩展的,现在技术已经改变 , 采用”模块”来扩展Powershell   因此, SQL Server 2012 安装的时候Powershell 最低版本是2.0 , 然后 SQLPS.exe 程序已经被替换掉了(叫SQLPS = =).

微软在SQLPS模块中提供了一些新的cmdlets, 多数专门用来管理可用性组和高可用性还有灾难恢复. 他们新增了备份和还原操作的 cmdlets , Backup-SqlDatabase, Restore-SqlDatabase, Backup-ASDatabase 还有 Restore-ASDatabase.

安装SQLPS模块

启动 PowerShell 并且想要使用SQLPS模块, 你需要导入相应的cmdlet. 开启PowerShell 2.0,当导入模块的时候微软会通过一个列表来进行动词的检查.Backup 和 Restore并不在这个列表里面,所以你执行模块导入的时候会报错. 你可以使用 -DisableNameChecking 参数来避免这个错误

(译者注:我执行的时候报错. 提示SQLPS不被信任,所以模块导入出错了, 此时要执行Set-ExecutionPolicy RemoteSigned 来开启)

使用Backup-SqlDatabase CmdLet来备份数据库

简单的 Backup-SQLDatabase 语句

当你导入模块以后,可以先简单的建立个备份数据库的脚本,如下:

{$dt = Get-Date -Format yyyyMMddHHmmss
$dbname = ‘AdventureWorks‘
Backup-SqlDatabase -ServerInstance TESTSQL -Database $dbname -BackupFile "E:\Backup\$($dbname)_db_$($dt).bak"

有很多的方法来调用这个指令,比如说你可以使用Get-ChildItem来获取你定位到的数据库实例的目录数据库名,然后通过管道发送给Backup-SqlDatabase命令,进行迭代的进行数据库备份 . 因为你已经连到你的实例这里所以就不需要在加 -ServerInstance 参数了.

简单打下面两句就了…

Set-Location SQLSERVER:\SQL\

TESTSQL

\DEFAULT\Databases
get-childitem|Backup-SqlDatabase

备份会放在默认的备份目录里面, 备份文件名也是默认的数据库名字. 如果你想指定备份文件的名字,或者其他一些阐述,可以用下面的代码

Set-Location SQLSERVER:\SQL\TESTSQL\DEFAULT\Databases
foreach ($db in (Get-ChildItem))
    {
        $dbname = $db.Name
        $dt = Get-Date -Format yyyyMMddHHmmss
        Backup-SqlDatabase -Database $dbname -BackupFile "$($dbname)_db_$($dt).bak"
    }

下面段会备份所有用户数据库被分到默认备份目录,并且以数据库的名字和当前日期时间作为备份文件的名字. (如果你使用 Get-ChildItem 加上-Force 参数,那就会包含系统数据库,当然 tempdb被Where过滤掉了.)

get-childitem -force|where name -ne ‘TempDB‘| Backup-SqlDatabase

你也可以建立一个包含 SMO Server 对象的脚本 , 用 -InputObject 代替-ServerInstance . 虽然我们示例是备份一个数据库,但是这个在处理多服务器上的数据库的时候会很有用.

$dt = Get-Date -Format yyyyMMddHHmmss
$dbname = ‘AdventureWorks‘
$svr =  new-object (‘Microsoft.SqlServer.Management.Smo.Server‘) ‘TESTSQL‘
Backup-SqlDatabase -InputObject $svr -Database $dbname -BackupFile "E:\Backup\$($dbname)_db_$($dt).bak"

另外你也可以使用一个包含SMO数据库的变量,然后使用 -DatabaseObject 参数.

$dt = Get-Date -Format yyyyMMddHHmmss
Set-Location SQLSERVER:\SQL\TESTSQL\DEFAULT\Databases\AdventureWorks
$db = Get-Item .
$dbname = $db.Name
Backup-SqlDatabase -DatabaseObject $db -BackupFile "E:\Backup\$($dbname)_db_$($dt).bak"

以上示例为了便于理解,均使用了最少的参数,实际操作的话,你应该看一下其他参数,使得备份方案符合你的需求.

SQL备份: 关键参数

我通常会加参数 -BackupAction. 选项可以是Database,Files和Log,默认是Database, 如果你想做差异备份,那么指定 BackupAction  为Database ,然后加上-Incremental参数.如果你想备份单个文件或者文件组,你可以使用 Files 选项.而 Log 选项允许你做事务日志备份.为了节省篇幅,因此去掉了这些参数. 所以例子直接备份了整个数据库.

举个例子,我总是会使用-CompressionOption 参数. 当然还有-ConnectionTimeout ,并且设置为0  ,因为你不想备份的时候因为超时而被中断.

我们用get-help 获得 Backup-SqlDatabase 的参数列表 :

Backup-SqlDatabase

[-Database] <string>

[-BackupFile] <string[]>]

[-ServerInstance <string[]> ]

[-BackupAction <BackupActionType>]

[-BackupDevice <BackupDeviceItem[]>]

[-BackupSetDescription <string>]

[-BackupSetName <string>]

[-BlockSize <int>]

[-BufferCount <int>]

[-Checksum]

[-CompressionOption <BackupCompressionOptions>]

[-ConnectionTimeout <int>]

[-ContinueAfterError]

[-CopyOnly]

[-Credential <PSCredential>]

[-DatabaseFile <string[]>]

[-DatabaseFileGroup <string[]>]

[-ExpirationDate <DateTime>]

[-FormatMedia]

[-Incremental]

[-Initialize]

[-LogTruncationType <BackupTruncateLogType>]

[-MaxTransferSize <int>]

[-MediaDescription <string>]

[-MediaName <string>]

[-MirrorDevices <BackupDeviceList[]>]

[-NoRecovery]

[-NoRewind]

[-Passthru]

[-Restart]

[-RetainDays <int>]

[-Script]

[-SkipTapeHeader]

[-UndoFileName <string>]

[-UnloadTapeAfter]

[-Confirm]

[-WhatIf]

[<CommonParameters>]

比SMO显著的优势

最明显的就是在命令集中增加了一些SMO没有的功能.比如通过Transact-SQL可以设置备份的块大小和缓冲区数而SMO没有.下图是等价功能的SMO的备份对象的属性和方法:

(上图是通过Visual Studio 的 Object Browser 载入SMOExtended DLL的截图)

使用Restore-SQLDatabase CmdLet 还原数据库

总归有各种各样的原因需要还原数据库, 所以…还原的选项比备份的还要多.

下面是恢复full backup一个简单示例, 选项设置直接覆盖现有数据库.

Restore-SqlDatabase -ServerInstance TESTSQL -Database AdventureWorks `
-BackupFile "E:\Backup\AdventureWorks_db_20130420153024.bak" -ReplaceDatabase

我还原数据库最频繁的理由之一就是用户不小心删掉了数据,随后又被事务更新,导致数据丢失.碰到这种情况我就要用另外一个名字还原该数据库,然后把需要的数据复制过去.

通过 SMO 还原数据库

下面是我们使用SMO还原的代码

# Connect to the specified instance
$srv = new-object (‘Microsoft.SqlServer.Management.Smo.Server‘) ‘TESTSQL‘

# Get the default file and log locations
# (If DefaultFile and DefaultLog are empty, use the MasterDBPath and MasterDBLogPath values)
$fileloc = $srv.Settings.DefaultFile
$logloc = $srv.Settings.DefaultLog
if ($fileloc.Length -eq 0) {
    $fileloc = $srv.Information.MasterDBPath
    }
if ($logloc.Length -eq 0) {
    $logloc = $srv.Information.MasterDBLogPath
    }

# Identify the backup file to use, and the name of the database copy to create
$bckfile = ‘E:\Backup\AdventureWorks_db_20101016135438.bak‘
$dbname = ‘AdventureWorks_20101016‘

# Build the physical file names for the database copy
$dbfile = $fileloc + ‘\‘+ $dbname + ‘_Data.mdf‘
$logfile = $logloc + ‘\‘+ $dbname + ‘_Log.ldf‘

# Use the backup file name to create the backup device
$bdi = new-object (‘Microsoft.SqlServer.Management.Smo.BackupDeviceItem‘) ($bckfile, ‘File‘)

# Create the new restore object, set the database name and add the backup device
$rs = new-object(‘Microsoft.SqlServer.Management.Smo.Restore‘)
$rs.Database = $dbname
$rs.Devices.Add($bdi)

# Get the file list info from the backup file
$fl = $rs.ReadFileList($srv)
foreach ($fil in $fl) {
    $rsfile = new-object(‘Microsoft.SqlServer.Management.Smo.RelocateFile‘)
    $rsfile.LogicalFileName = $fil.LogicalName
    if ($fil.Type -eq ‘D‘){
        $rsfile.PhysicalFileName = $dbfile
        }
    else {
        $rsfile.PhysicalFileName = $logfile
        }
    $rs.RelocateFiles.Add($rsfile)
    }

# Restore the database
$rs.SqlRestore($srv)

还原一个已存在的数据库的问题就是物理名称冲突,要解决这个问题SMO 可以使用RelocateFile 对象. 这和Transact-SQL 使用 WITH MOVE 条件一样. 有趣的是Restore-SqlDatabase 命令也使用SMO 对象处理这个事情.

使用纯SMO 和 Restore-SqlDatabase 命令的唯一区就是何存储和传递RelocateFile 对象. 建立一个空的集合,然后读取备份文件列表,并且把每个RelocateFile 的每个对象都添加到集合中.  随后调用 Restore-SqlDatabase命令. 下图中最后最后一部分用的是新的cmdlet,其他上面的例子都一样.

# Get the file list info from the backup file
$fl = $rs.ReadFileList($srv)
$rfl = @()
foreach ($fil in $fl) {
    $rsfile = new-object(‘Microsoft.SqlServer.Management.Smo.RelocateFile‘)
    $rsfile.LogicalFileName = $fil.LogicalName
    if ($fil.Type -eq ‘D‘) {
        $rsfile.PhysicalFileName = $dbfile
        }
    else {
        $rsfile.PhysicalFileName = $logfile
        }
    $rfl += $rsfile
    }

# Restore the database
Restore-SqlDatabase -ServerInstance TESTSQL -Database $dbname `
 -BackupFile "E:\Backup\AdventureWorks_db_20101016135438.bak" `
 -RelocateFile $rfl

在本例中我贴出了纯SMO的例子,应该已经很清楚了.

指定一个时间点来还原数据库

最后一个例子是通过一个时间点来还原数据库. 有时候你知道问题发生的时间,你可以恢复到那个时间点.

在这个情境中我们所有的被封文件都放在本地服务器的 E:\Backup 目录. 我们有很多完全备份,差异备份,还有一些事务日志备份文件用来做某一个时间点的还原.文件名格式为 DatabaseName_type_datetime.ext, 其中type是db, diff 和 tran ,ext是 bak 或 trn.

$dbname = ‘AdventureWorks‘
$restorept = ‘2013-04-20 15:30:00‘
Set-Location ‘E:\Backup‘
$fullfile = Get-ChildItem -Filter "$($dbname)_db_*" | Where-Object {$_.LastWriteTime -lt $restorept} | Sort-Object LastWriteTime Desc | Select-Object -First 1
$difffile = Get-ChildItem -Filter "$($dbname)_diff_*" | Where-Object {$_.LastWriteTime -lt $restorept} | Sort-Object LastWriteTime Desc | Select-Object -First 1
$tranfile = Get-ChildItem -Filter "$($dbname)_tran_*" | Where-Object {$_.LastWriteTime -gt $difffile.LastWriteTime} | Sort-Object LastWriteTime Asc

$fullfile 变量包含指定时间点前的完整备份文件信息,$difffile变量包含指定时间点前的差异备份文件信息 , $tranfile 包含差异备份后至指定时间点前的所有的事务日志文件信息

首先我们需要还原完整备份, 并且指定 no recovery选项.

Restore-SqlDatabase -ServerInstance TESTSQL -Database $dbname `
-BackupFile $fullfile.FullName -ReplaceDatabase `
-NoRecovery

然后我们还原最后一个差异备份,同样的,指定no recovery选项.

Restore-SqlDatabase -ServerInstance TESTSQL -Database $dbname `
-BackupFile $difffile.FullName -ReplaceDatabase `
-NoRecovery

最后我们通过循环来读取$tranfile变量中的文件来还原事务日志, 如果LastWriteTime 属性比 $restorept 变量小,那么恢复的时候指定no recovery,然后处理下一个,否则,则根据-ToPointInTime 参数指定的时间点来还原. 不加-NoRecovery 参数,至此整个还原过程结束.

$recovery = 0
foreach ($trnfile in $tranfile) {
     if ($trnfile.LastWriteTime -lt $restorept) {
         Restore-SqlDatabase -ServerInstance TESTSQL -Database $dbname `
-BackupFile $trnfile.FullName -ReplaceDatabase `
-NoRecovery
         }
    else {
         if ($recovery -eq 0) {
             Restore-SqlDatabase -ServerInstance TESTSQL -Database $dbname `
-BackupFile $trnfile.FullName -ReplaceDatabase `
-ToPointInTime $restorept
$recovery = 1
            }
        }
    }

还有很多特性,结合通过操作系统的一些功能来做备份和还原操作,比用Transact-SQL要方便许多

下图是SMO Restore 对象的属性和方法:

相应的下面是Restore-SqlDatabase的参数

Restore-SqlDatabase

[-Database] <string>

[[-BackupFile] <string[]>]

-ServerInstance <string[]>

[-BackupDevice <BackupDeviceItem[]>]

[-BlockSize <int>]

[-BufferCount <int>]

[-Checksum]

[-ClearSuspectPageTable]

[-ConnectionTimeout <int>]

[-ContinueAfterError]

[-Credential <PSCredential>]

[-DatabaseFile <string[]>]

[-DatabaseFileGroup <string[]>]

[-FileNumber <int>]

[-KeepReplication]

[-MaxTransferSize <int>]

[-MediaName <string>]

[-NoRecovery]

[-NoRewind]

[-Offset <Int64[]>]

[-Partial]

[-Passthru]

[-RelocateFile <RelocateFile[]>]

[-ReplaceDatabase]

[-Restart]

[-RestoreAction <RestoreActionType>]

[-RestrictedUser]

[-Script]

[-StandbyFile <string>]

[-StopAtMarkAfterDate <string>]

[-StopAtMarkName <string>]

[-StopBeforeMarkAfterDate <string>]

[-StopBeforeMarkName <string>]

[-ToPointInTime <string>]

[-UnloadTapeAfter]

[-Confirm]

[-WhatIf]

[<CommonParameters>]

使用Backup-ASDatabase备份 Analysis Services

Analysis Services 的数据库也是需要备份的,虽然没多少选项可用. 首先你需要载入Analysis Services  命令集的模块 .

Import-Module SQLASCMDLETS

我们先看下 Backup-ASDatabase的所有参数.

Backup-ASDatabase

[-BackupFile] <string>

[-Name] <string>

[-AllowOverwrite <SwitchParameter>]

[-BackupRemotePartitions <SwitchParameter>]

[-ApplyCompression <SwitchParameter>]

[-FilePassword <SecureString>]

[-Locations <Microsoft.AnalysisServices.BackupLocation[]>]

[-Server <string>]

[-Credentials <PSCredential>]

[<CommonParameters>]

注意:这里没有差异备份或者日志备份的选项.下面是备份AWDB database一个简单例子.

Backup-ASDatabase "E:\Backup\AWDB.abf" AWDB

如果需要覆盖已存在的数据库备份,可以加上 -AllowOverwrite 参数,需要压缩备份则加上-ApplyCompression参数, 要加密的话可以使用 -FilePassword 参数.

使用Restore-ASDatabase还原 Analysis Services数据库

同样的还原Analysis Services 数据库也没多少可用选项.

Restore-ASDatabase

[-RestoreFile] <string>

[-Name] <System.String>

[-AllowOverwrite <SwitchParameter>]

[-Locations <Microsoft.AnalysisServices.RestoreLocation[]>]

[-Security <Microsoft.AnalysisServices.RestoreSecurity>]

[-Password <System.SecureString>]

[-StorageLocation <System.String>]

[-Server <string>]

[-Credentials <PSCredential>] [<CommonParameters>]

下面是一个还原例子

Restore-ASDatabase "E:\Backup\AWDB.abf" AWDB -Security:CopyAll

还原的时候同事恢复roles和members

总结

组织数据的备份还原是至关重要的.使用Powershell和SMO编写脚本来管理SQL SERVER的备份还原是最好的,尤其是DBA需要完成更复杂,的重复性的任务的时候. 比如数据库需要高可用性, 我们可以创建脚本来重建他们,进行高可用性测试排练.总之 在 SQL Server 2012中使用他们最理想的,而且很方便.

使用PowerShell 命令集进行SQL Server 2012 备份和还原

时间: 2024-10-23 07:25:40

使用PowerShell 命令集进行SQL Server 2012 备份和还原的相关文章

SQL Server 数据库备份与还原

1.相同SQL Server版本(2008为例)之间数据库备份与还原 (1)数据库备份 相同SQL Server服务器版本之间数据库的备份还原操作相对来说比较简单. 首先找到需要备份的数据库实例,[右键]->[任务]->[备份...],界面下边选择备份路径,点击确定,备份成功后即可在选择的备份路径下找到后缀名为.bak的备份文件. (2)数据库还原 对于需要还原的.bak数据库文件,一般会先拷贝到 C:\Program Files\Microsoft SQL Server\MSSQL10.MS

SQL Server之备份和还原系统数据库

系统数据库是管理和维护SQL Server所必须的数据库,对服务器实例的运行至关重要.每次进行大量更新后必须备份多个系统数据库,包括master.model.msdb,备份这些系统数据库,就可以在发生系统故障(如硬盘丢失)时还原和恢复SQL Server系统 需要备份的系统数据库 1. 备份系统数据库 2. 模拟数据库损坏 (1)首先,停止SQL Server服务 (2)然后,删除系统数据库文件 (3)再次开启SQL Server服务,发现系统报错,SQL Server数据库系统瘫痪 3. 现在

SQL Server 数据库备份和还原——使用sqlcmd

备份 BACKUP DATABASE AbpFirst TO DISK='d:\AbpFirst.bak' 还原 RESTORE DATABASE AbpFirst FROM DISK='d:\AbpFirst.bak' 使用sqlcmd命令则要加上连接信息: 备份 sqlcmd -S . -E -Q "BACKUP DATABASE AbpFirst TO DISK='d:\AbpFirst.bak'" 还原 sqlcmd -S . -E -Q "RESTORE DATAB

技术分享之如何完整备份sql server 2012数据库?

博客已经建了几年了,但由于我是个外行,因此一开始就采用了zblog asp+access数据库的方式进行搭建,主要还是因为技术方面的缺陷嘛.但是经过几年的整理和写作,发现这套系统越来越卡了,咨询了很多博主,并且去ZBLOG论坛逛了很多次,发现是因为数据库的原因导致的,ACCESS数据库只能建一些小站,数据量已达就有明显的压力了,因此最近尝试了将ACCESS升级和转换为sql server2012的微软数据库,经过几天的折腾和请教了一些高人,终于解决了这个难题,现在访问起来畅快多了.我的博客:读后

SQL Server 2012 AlwaysOn集群配置指南

1. AlwaysOn介绍 AlwaysOn是SQL Server 2012提供的全新综合.灵活.高效经济的高可用性和灾难恢复解决方案.它整合了镜像和群集的功能,基于OS 故障转移群集(Windows Server FailOver Cluster),通过在同一个WSFC的不同Node上,安装独立的SQL Server实例,定义AlwaysOn Group,一个数据库最多可以部署4个镜像.当热备机出现故障时,可以手工或自动实现故障转移,交换主.辅数据库的角色. AlwaysOn的亮点在于镜像可读

在Windows Server 2012 R2中搭建SQL Server 2012故障转移集群

需要说明的是我们搭建的SQL Server故障转移集群(SQL Server Failover Cluster)是可用性集群,而不是负载均衡集群,其目的是为了保证服务的连续性和可用性,而不是为了提高服务的性能. SQL Server始终在负载均衡集群方面都缺少自己的产品,多由第三方厂家提供,但SQL Server故障转移集群却由来已久,在SQL Server 2012还提供了一个可用性组(AlwaysOn High Availability Groups)的新特性,我们知道微软的故障转移集群(W

Querying Microsoft SQL Server 2012 读书笔记:查询和管理XML数据 1 -使用FOR XML返回XML结果集

原文:Querying Microsoft SQL Server 2012 读书笔记:查询和管理XML数据 1 -使用FOR XML返回XML结果集 XML 介绍 <CustomersOrders> <Customer custid="1" companyname="Customer NRZBB"> <Order orderid="10692" orderdate="2007-10-03T00:00:00&

从0开始搭建SQL Server 2012 AlwaysOn 第二篇(配置故障转移集群)

本篇主要讲配置Windows 故障转移集群及遇到的相关问题(坑),因为AlwaysOn是基于Windows的故障转移集群的 在讲解步骤之前需要了解一下故障转移集群仲裁配置 四种集群的仲裁配置: 1.多数节点:这种配置不会用到仲裁磁盘,而所谓多数节点就是在正常节点数量占多数的情况下,集群才会提供服务,否则就停止服务.这种配置适用于奇数节点的集群,例如5个节点的集群,其正常节点数量必须至少3个,集群才会提供服务 2.多数节点和磁盘:适用于偶数节点的集群,他在计算法定数量时会将仲裁磁盘计算进来,例如,

SQL Server 2012实施与管理实战指南(笔记)——Ch3Alwayson可用组

3.AlwaysOn可用组 Alwayson支持的,是一个可用性组,每个可用性组是包含了多个用户数据库的容器,可用性组内的数据库可以作为一个整体进行故障转移. AlwaysOn关键特性: 一.类似集群的特性 1.多个数据库可以一起迁移 2.提供一个虚拟服务器名,这个虚拟服务器名始终是当前的primary. 3.可以有自动切换,手动切换和强制切换 4.一个primary,最多4个secondary(sql server 2014增加到了8个) 5.Dashborad可以监视alwayson运行状况