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

讨论什么是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 备份和还原的更多相关文章

  1. SQL Server 数据库备份和还原

    一.SQL命令 备份BACKUP DATABASE TestDb TO DISK='d:\TestDb.bak'还原RESTORE DATABASE TestDb FROM DISK='d:\Test ...

  2. (图解版)SQL Server数据库备份与还原

        本文介绍了SQL Server数据库备份的两种方式.一种是直接拷贝数据库中的文件mdf 和日志文件ldf,另一种是生成脚本语言. 第一种方式:     选中需要备份的数据库,将数据库从运行的数 ...

  3. SQL Server 2012 AlwaysOn集群配置指南

    1. AlwaysOn介绍 AlwaysOn是SQL Server 2012提供的全新综合.灵活.高效经济的高可用性和灾难恢复解决方案.它整合了镜像和群集的功能,基于OS 故障转移群集(Windows ...

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

    需要说明的是我们搭建的SQL Server故障转移集群(SQL Server Failover Cluster)是可用性集群,而不是负载均衡集群,其目的是为了保证服务的连续性和可用性,而不是为了提高服 ...

  5. 在SQL Server 2012中如何使用分组集

    作者:Itzik Ben-Gan  翻译:张洪举 此文摘自作者的<Microsoft SQL Server 2012 T-SQL基础>. 分组集就是你据以分组的一个属性集.传统上,SQL中 ...

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

    XML 介绍 <CustomersOrders> <Customer custid="1" companyname="Customer NRZBB&qu ...

  7. 图文详解在Windows server 2008 R2上安装SQL Server 2012集群

    1.准备: 4台服务器(1台AD.2台SQL服务器.1台iSCSI存储服务器) 9个IP(1个AD的IP.2个SQL服务器的IP.2个心跳IP.1个iSCSI存储服务器的IP.1个集群IP.1个DTC ...

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

    OK~ WSFC 2012 R2 年度盛宴开始~ 在本文中,老王将用一系列的场景,把动态仲裁,动态见证,票数调整,LowerQuorumPriorityNodeID,阻止仲裁等群集仲裁技术串起来,完成 ...

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

    本篇主要讲配置Windows 故障转移集群及遇到的相关问题(坑),因为AlwaysOn是基于Windows的故障转移集群的 在讲解步骤之前需要了解一下故障转移集群仲裁配置 四种集群的仲裁配置: 1.多 ...

随机推荐

  1. python学习【一】基础入门

    Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC ...

  2. http://www.swoole.com/

    Swoole:重新定义PHP PHP语言的高性能网络通信框架,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,毫秒定时器, ...

  3. Gartner 认定 Microsoft 为具有远见卓识的云基础结构即服务提供商

    四个月前, Windows Azure 基础结构服务结束了预览版阶段,正式发布了,它具有业内领先的 SLA.随后, 凭借愿景的完整性和执行力,Gartner 很快认可了 Microsoft 在市场中的 ...

  4. 第一次当Uber司机,就拉到漂亮妹纸

    黑马哥的Uber司机端装上很久了,一次活儿也没拉,心里一直有一种当“张师傅”的冲动.黑马哥当Uber司机,肯定不是为了图挣钱,也不是因为Uber有“新约炮神器”的称号,能通过“拉活”来泡妹纸.黑马哥体 ...

  5. ArrayList和LinkedList的各项操作性能比较

          如果用java编写程序,我们通常存储易变的数据集合时用到的数据结构往往是ArrayList,不过,在JDK中还存在另一个结构--LinkedList,只不过我们通常不用,原因在于性能问题, ...

  6. Android 调用相册 拍照 实现系统控件缩放 切割图片

    android 下如果做处理图片的软件 可以调用系统的控件 实现缩放切割图片 非常好的效果 今天写了一个demo分享给大家. package cn.m15.test; import java.io.B ...

  7. Android Animation学习(二) ApiDemos解析:基本Animatiors使用

    Animator类提供了创建动画的基本结构,但是一般使用的是它的子类: ValueAnimator.ObjectAnimator.AnimatorSet ApiDemos中Animation部分是单独 ...

  8. OpenStack里的浮动ip

    缺省情况下实例会被赋予固定ip,这时并不能保证实例会马上可以从外面访问到,一般来说需要配置防火墙来允许公共ip,然后建立一条NAT规则从公共ip到私有ip的映射.OpenStack引入了一个叫浮动ip ...

  9. linux之iptable案例

    转自:http://blog.csdn.net/bill_lee_sh_cn/article/details/4401896 1.一对一流量完全DNAT 首先说一下网络环境,普通主机一台做防火墙用,网 ...

  10. linux之screen命令

    linux平台下想同时运行多个操作,执行多个程序或命令:命令行就一个,要想同时执行多个命令如何操作? 一个screen命令即可: Centos操作系统默认没有安装screen: 安装方法: Cento ...