SQL Server 快照和同名引用(Synonyms)
--Jade翻译整理,转贴请注明出自微软BI开拓者www.windbi.com
--原帖地址概要:在使用数据库快照的时候,一个被抱怨最多的问题就是如何才能在最短时间内将查询切换到最新的快照上。基本上,有三种方法:1,
删除旧的快照然后重命名新建的。如果在这期间两个快照数据库都没人用的话,这种方法可以使用。2,
修改连接串。这种方法的优点是最后的报表可以直接访问新的数据库快照。但缺点在于如果你需要同时修改很多处的话就不很好用。3,
使用对象的同名引用,指向新的数据库快照。这就是这篇文章想讨论的执行同名引用数据库快照的步骤如下:
1 。创建数据库快照
2 。在主数据库创建同名引用,指向快照的对象
3 。再创建一个新的快照
4 。用DDL更新的同名引用。警告:可能会发生阻塞,使阅读下面顶的阻塞。
注意: •
有可能造成Application
超时错误,如果在更新同名引用时被锁死。 •
如果你有可能用到的查询包含join
语句, READ_UNCOMMITTED
可能造成同时join
新的快照和旧的快照。 •
可以将同名引用与可缩放共享数据库结合起来。当你有一个SAN
属于多台服务器时,你可以使用同名引用来指向当前SAN
正确的快照潜在的阻塞可能使用DDL
事务将所有同名引用更新到新的快照时将更新系统表。这个事务有可能被其他访问者阻塞,这样就会产生问题。并且这个事务在执行过程中也将阻塞任何试图访问同名引用的查询操作。如果这个时间太长就有可能造成前端程序超时。将所有的访问设置为READ_UNCOMMITTED
也许可以解决这个问题,但我们不推荐这样做。我们可以想象一个场景,当一个查询join
两个表,一个在新的快照中,而另一个在旧的快照中。这也就是为什么我们希望同名引用的更新最好在一个事务中完成。这样的话,阻塞也许是件好事只要它不会造成前端程序超时。DDL
事务运行的很快。在我的笔记本上,我更新3000
个同名引用大约需要1
秒。有些核心的ERP
系统中的表可能会超过10000
个。这样就有可能造成问题。澄清一下:查询如果已经开始运行,将会继续。新的查询将会被阻塞。直到同名引用更新完成。
示例代码:使用这种方法,我们需要着眼于原始数据库。三种不通的方式:1
)真正的原始数据库我们叫 SourceDB 2
)原始数据库的快照,我们叫 SnapshotDB 3
)报表数据库,我们叫ReportDB。创建的时间点记录在快照数据库上。脚本类似:USE SourceDB
CREATE DATABASESourceDB_<timestamp>_Snapshot ON
( NAME = SourceDB, FILENAME =
'C:\SourceDB\SourceDB_<timestamp>_Snapshot.ss' )
AS SNAPSHOT OF SourceDB;
GO
报表数据库不包含原始数据库中的任何内容,只有同名引用。其中这些同名引用全部指向快照数据库中对应的表或视图。脚本类似USE ReportDB
CREATE SYNONYM dbo.TableName FOR
SourceDB_<timestamp>_Snapshot.dbo.TableName
在简单的配置好之后,所有的报表查询都可以在ReportDB上执行,并且使用和SourceDB相同的架构名,对象名。可以返回与原始数据库创建最新快照时一致的数据。在ReportDB中也创建引用这些同名引用对象的其他对象,比如视图,或者存储过程之类的。大多数情况,我们希望周期性的删除以及重新创建SnapshotDB来满足我们需要最近数据来进行查询的需要。然而,要保持一个24 X 7
应用程序的访问,并且是在无需更改连接字符串的情况下,我们不能简单地删除SnapshotDB。这会导致查询的同义引用ReportDB的语句立即失败,并且删除还没有连接到这个数据库的查询。因此,我们必须首先建立第二个更新的SnapshotDB,在一个事务中删除并重建所有的同义引用指向新的SnapshotDB,然后再删除旧的SnapshotDB。同时,有可能有仍然在运行在旧的快照上的查询,因此你可能需要先注释掉Drop DATABASE
命令,并有一个单独的Job
在一段时间以后再进行这个操作。注意,拥有更多的数据库快照将对性能造成更多的影响。见本文最后的白皮书。
所附的存储过程usp_ReportingSynoSnap
配合适当的SourceDB数据,可以用来实现这个逻辑。这个存储过程将在ReportDB中创建SourceDB中所有Schema
,并在对应的Schemas上创建的同名引用。如果对于SnapshotDB的访问全部来自于ReportDB中的同名引用,那么就不会有连接直接连到ShapshotDB上,只会连接到ReportDB上。如果这些连接还是在Active
的状态执行对于同名引用的查询,这将会阻塞这个存储过程,直到语句结束。但是一旦存储过程可以执行,它将删除旧的ShapshotDB
这个存储过程假设ReportDB 已经存在,并且包含指向SnapshotDB的同名引用,他会删除所有的同名引用以确保不会有遗留的。SnapshotDB在是模板中的命名<SourceDB> _Rpt_YYYYMMDD_HHMMSS_ss ,当快照被建立时YYYYMMDD_HHMMSS改为实际时间戳。创建快照需要列举SourceDB的所有逻辑数据文件,为每个快照定义了相应的物理文件的。存储过程将在与物理文件相同的位置创建快照的物理文件,后缀采用.Rpt_YYYMMDD_HHMMSS_ss(例如; AdventureWorks.mdf.Rpt_20080101_010101_ss),在这里YYYYMMDD_HHMMSS 将用做制定作这个快照创建的时间以及SnapshotDB名称。最后,存储过程将删除旧SnapshotDB ,到快照数据库中找到和新快照命名相同的但是YYYYMMDD_HHMMSS(排序)最高的以确定旧快照数据库名称。使用存储过程,创建 SourceDB或ReportDB ,并调用……………………………………
后面的内容见附件:
附件: 您所在的用户组无法下载或查看附件