隆重推出 SQL Clone





0/5 (0投票)
SQL Clone 利用 Windows 中现有的虚拟化技术,大大减轻了传统数据库部署所带来的难题。
引言
为所有开发、测试和交付环境(如 UAT、预生产等)配置最新版本的生产数据库副本,或配置“生产级”数据,可能是一项耗时且令人沮丧的任务。移动大型数据库需要时间,并且不可避免地会出现磁盘空间、数据库配置、权限等方面的棘手问题。
我将介绍 Redgate 的新工具 SQL Clone 如何消除这些痛苦。我将演示一个夜间的 PowerShell 部署作业,该作业可为非生产环境提供多个数据库副本,数据与夜间备份同步。SQL Clone 允许我们从数据库或备份创建“数据映像”,然后多次重复使用该数据映像,在几秒钟内将数据库克隆部署到多个 SQL Server 实例,而每个克隆仅占用几兆字节的磁盘空间。从 SQL Server 的角度来看,克隆只是一个普通数据库,我们可以像查询和更新任何其他数据库一样查询和更新克隆,所有更改都隔离在一个本地的差异文件中。
有关更多信息并下载试用版,请访问 SQL Clone 产品页面。
数据库部署的痛苦
如今,开发人员越来越期望能够通过运行脚本来可靠、可预测地提供所有必需的数据库和应用程序资源。这包括在生产级环境中安装的数据库中,能够使用生产级数据进行开发和测试。这意味着他们可以尽早进行现实的负载、集成和验收测试,并了解其更改可能产生的真实影响,并且可以快速重现诊断错误和实施热修复所需的生产条件。
然而,数据库与其他资源不同;它们本质上是可变的,因此只在特定时间点存在;它们很大,根据我们最新的调查,平均约为 100GB;它们必须被挂载或附加到数据库管理系统中;使它们在应用程序上下文中可用的命令是复杂且特定的。
数据库部署的痛苦再熟悉不过了,磁盘空间的折腾,以及无休止的“刷新环境”的临时请求。我亲身经历过等待备份恢复到共享开发数据库的沮丧,然后在进行更改时互相干扰,并需要请求新的还原才能回退到基线。
然而,自动化这项任务到底有多难?实际上,创建一个将大型数据库复制到任何环境并以正确配置使其可用的解决方案,比您想象的要棘手。
让我们一探究竟。作为一名与软件团队合作的 DBA,我将从一个熟悉的地方开始,即我在 SSMS 中现有的数据库备份维护计划。
当然,我需要做的就是反转这个过程,恢复备份并运行完整性检查,但这次以一种可以安排或按需运行的方式进行?
回到维护向导,但似乎没有恢复数据库的选项。
没问题,我很有把握我无论如何都需要编写脚本。我将只使用 **Restore Database** 向导,然后点击 **Script** 按钮来获取我的起点。
这给了我以下 T-SQL 代码块。
USE [master]
RESTORE DATABASE [Forex-Copy] FROM DISK = N'E:\SQL\MSSQL12.MSSQLSERVER\MSSQL\Backup\Forex_backup_2017_02_20_092655_6408207.bak' WITH FILE = 1,
MOVE N'Forex' TO N'E:\SQL\MSSQL12.MSSQLSERVER\MSSQL\DATA\Forex-Copy.mdf',
MOVE N'Forex_log' TO N'E:\SQL\MSSQL12.MSSQLSERVER\MSSQL\DATA\Forex-Copy_log.ldf'
, NOUNLOAD, STATS = 5
GO
所以,**RESTORE DATABASE x FROM DISK= ' … '**。啊,我的文件带有时间戳。没关系,我将编写一些 PowerShell 来查询备份文件夹并找出我的文件名。
**WITH MOVE** … 嗯,但是对于我需要还原的每个服务器,驱动器都不同。好吧,现在我需要创建一个 PowerShell 函数,它接受一个环境名称,并将其解析为文件路径。应该不难。什么?有些有两个文件,有些有更多?没关系,我相信我的脚本技能可以处理它……尽管我希望目标路径有足够的磁盘空间!
当然,在我的生产服务器上,我的应用程序有各种服务帐户(订单服务、发票服务等)。因此,恢复后我需要删除这些生产登录名,然后创建特定于环境的登录名(UAT_Orders、UAT_Invoices 等),并将它们映射到该数据库中的用户和角色。我相信当他们需要一个新的服务帐户时,应用程序开发人员会及时通知我?
希望到目前为止,您已经明白了。虽然编写脚本来还原数据库然后对其进行调整以自动化部署到各种环境可能听起来很简单,但实际上并非如此。事实上,我个人遇到过的许多脚本化解决方案往往相当脆弱且不可靠。
SQL Clone 是一款专用的数据库部署工具,可以完全解决其中一些问题。例如,它使用 Windows 内置的 VM 技术提供存储虚拟化;您不再需要考虑磁盘。其 PowerShell 界面使得自动化克隆数据库的部署、更新和维护变得非常容易。
另一种方法 – 使用 SQL Clone
SQL Clone 使用 x64 Windows 中的虚拟磁盘服务,允许同一个字节(“数据映像”)被多次重复使用,并在多个 SQL Server 实例上作为“克隆”数据库使用。每个克隆上的更改都存储在本地克隆计算机上的 差异磁盘 中,因此数据映像是不可变的。换句话说,实际的数据库映像只保存一次,存储在网络中,并且永不更新:所有更改都本地保存在克隆中,并使用 Windows 中现有的虚拟化技术。
每个克隆的部署时间仅相当于设置 **.vhd** 和挂载数据库所需的时间(通常是几秒钟),并且初始克隆仅需要大约 40MB 的磁盘空间。
您可以在 此处 了解有关 SQL Clone 工作原理的更多信息,但我将向您展示它的实际应用。
数据库部署的工作示例
您需要一个数据库来试验。在此示例中,我使用了一个约 48GB 的外汇(Forex)数据库。但是,一个很棒的、公开可用的替代方案是使用 Brent Ozar 提供的 StackOverflow 数据库副本,该副本重达 95GB;虽然不算大,但足以成为复制的麻烦。以下屏幕显示了 SQL Clone UI 中的一些现有数据映像。
对许多用户而言,最初的常见方法是使用 UI 设置 SQL Clone,然后开始使用 PowerShell 进行自动化。这也是我在这里将采用的方法;我将通过 UI 创建一个初始数据映像,然后使用 PowerShell 自动化从该映像创建映像,以及从该映像部署克隆。
SQL Clone 的用户界面提供了一个简单的 **Create Image** 工作流。我可以选择备份或直接 SQL Server 连接作为源。在此示例中,我正在从备份创建数据映像,因此我提供了备份路径并指定了一个 SQL Server 实例(SQL Server 必须在此实例上初始化恢复操作,从而创建数据映像)。
之后,只需按照说明操作,然后点击 **Create Image**。
脚本化数据映像创建
开发人员希望使用最新数据,因此我需要自动化此任务,使其在维护时段内夜间批量运行。是时候转向 SQL Clone 的 PowerShell 界面了。
# Script to create a new SQL Clone data image from a backup file
$SQLCloneServer= "http://mysqlcloneserver.red-gate.com:14145"
$SQLCloneAgent = "rm-iclone1"
Connect-SqlClone -ServerUrl $myUrl
$SourceDatabase = 'Forex'
$BackupFolder = 'E:\SQL\MSSQL12.MSSQLSERVER\MSSQL\Backup'
if (!(Test-Path ($BackupFolder)))
{
write-host 'Backup folder not found. Exiting.'
break
}
# Get the latest backup file for our database (striped backups would be more complex)
$BackupFiles = Get-ChildItem -Path $BackupFolder |
Where-Object -FilterScript { $_.Name.Substring(0,$SourceDatabase.Length) -eq $SourceDatabase} # My backup files always start with the database name
# Now we have a filtered list, sort to get latest
$BackupFile = $BackupFiles |
Sort-Object -Property LastWriteTime |
Select-Object -Last 1 # I only want the most recent file for this database to be used
$BackupFileName = $BackupFile.Name
#Start a timer
$elapsed = [System.Diagnostics.Stopwatch]::StartNew()
"Started at {0}, creating data image for database ""{1}"" from backup file ""{2}""" -f $(get-date) , $SourceDatabase , $BackupFileName
$DataImageName = $SourceDatabase + "_" + (Get-Date -Format "yyyyMMdd") # Prepare a name for the data image, with a timestamp
$ImageDestination = Get-SqlCloneImageLocation -Path '\\is-filestore.red-gate.com\rm-iclone\RM\SQL Clone Beta Images' # Point to the file share we want to use to store the image
$CloneBackupLocation = Get-SqlCloneBackupLocation -Path $BackupFolder # Point to the backup folder we want to work with (this was 'registered' with SQL Clone when I used the UI above)
$NewImage = New-SqlCloneImage -Name $DataImageName -BackupLocation $CloneBackupLocation -BackupFileName $BackupFileName -Destination $ImageDestination | Wait-SqlCloneOperation # Create the data image and wait for completion
"Total Elapsed Time: {0}" -f $($elapsed.Elapsed.ToString())
如果我运行脚本,然后返回 SQL Clone UI,我可以看到映像创建正在进行中。我的 48GB 数据库花了 20 分钟,但请记住,我可以从此映像创建多个克隆数据库,而时间和磁盘空间成本很小。
脚本化将克隆部署到多个环境
在自动化了夜间数据映像创建之后,开发人员就可以按需自助服务从该映像创建克隆数据库,每份副本仅占用几兆字节的空间。
在这种情况下,我将仅将一个数据库从该夜间映像交付到几个环境,并在交付后调整一些权限。
# Script to create a new SQL Clone database on each of my connected machines
$SQLCloneServer= "http://rm-win10-sql201.testnet.red-gate.com:14145"
Connect-SqlClone -ServerUrl $myUrl
$SourceDataImage = Get-SqlCloneImage -Name 'StackOverflow 20170117'
$CloneName = 'StackOverflow_Latest'
# I have 3 SQL Server instances registered on my SQL Clone Server - I want to deliver a copy to all of them
$Destinations = Get-SqlCloneSqlServerInstance
# I'm only going to make a small adjustment to permissions in this example
$Query = "CREATE USER StackOverflowUser FROM LOGIN [RED-GATE\Richard.Macaskill];ALTER ROLE db_datareader ADD member [StackOverflowUser];"
# Start a timer
$elapsed = [System.Diagnostics.Stopwatch]::StartNew()
"Started at {0}, creating clone databases for image ""{1}""" -f $(get-date) , $SourceDataImage.Name
foreach ($Destination in $Destinations)
{
$SourceDataImage | New-SqlClone -Name $CloneName -Location $Destination | Wait-SqlCloneOperation
$ServerInstance = $Destination.Server + '\' +$Destination.Instance
Start-Sleep -s 10
Invoke-Sqlcmd -Query $Query -ServerInstance $ServerInstance -Database $CloneName
"Created clone in instance {0}" -f $Destination.Server + '\' + $Destination.Instance;
}
"Total Elapsed Time: {0}" -f $($elapsed.Elapsed.ToString())
如果我在 SQL Clone 的 UI 中查看,可以看到我的数据库已交付,每个实例占用几兆字节的空间。
为了获得真正流畅的工作流程,我在列表 2 的脚本中还有很多可以做的事情。例如,我可能想进行一些简单的脱敏。在此示例中,我们正在克隆一个生产数据库,因此我们假设没有数据敏感性问题,但仍然可能存在您不希望应用程序使用的数据(例如真实电子邮件地址)。我们可以通过在克隆数据库上运行 **invoke-sqlcmd** cmdlet 来轻松实现这一点。我们还可以构建自动化的数据库配置,以及可能的克隆维护。例如,一些早期用户设置了“‘灰姑娘’数据库克隆;基本上是 SQL Clone 脚本,用于删除任何超过 7 天的 SQL Clone 数据库(和映像)。
将克隆配置为满足特定环境的要求后,您可以选择在夜间批处理中从该克隆创建新的数据映像(当然,这会使作业花费更长时间)。
结论
SQL Clone 利用 Windows 中现有的虚拟化技术,大大减轻了传统数据库部署所带来的难题。
Redgate 将在未来几个月内致力于增加更多功能。现在,请 在此处获取您的试用副本,并了解它能为您的数据库部署工作流带来什么。