技术开发 频道

SQL技术问答:分布式事务、性能计数器

    【IT168 评论】问题:我们使用了大量分布式事务,正研究数据库镜像以使我们的关键数据库之一具备高可用性。在测试过程中我们发现,在尝试对镜像数据库进行故障转移后,分布式事务有时会失败。能否说明这是为什么?

  解答:这实际上是记录在案的使用分布式事务的限制。在使用数据库镜像或日志传送时会存在该限制,基本上对于在执行故障转移后 Windows 服务器名称会有所不同的任何技术,都存在该限制。

  在使用 Microsoft 分布式事务处理协调器 (MSDTC) 事务时,本地事务处理协调器具有资源 ID,用于标识运行该协调器的服务器。在进行镜像故障转移时,主体数据库会承载于另一个服务器上(镜像伙伴),因此事务处理协调器的资源 ID 会有所不同。

  如果某个分布式事务处于活动状态,镜像伙伴上的事务处理协调器会尝试识别该事务的状态,但是无法识别,因为它具有错误的资源 ID;MSDTC 无法识别该 ID,因为它最初未包含在该分布式事务中。在这种情况下,必须终止该分布式事务,这便是您所看到的行为。

  跨数据库事务(涉及多个数据库中的更新的简单事务)也存在类似问题。如果所涉及的一个数据库进行了镜像,另外一个没有镜像,则跨数据库事务可以在这两个数据库中提交。如果进行强制镜像故障转移(当主体与镜像未同步,且执行允许丢失数据的手动故障转移时),在镜像数据库中提交的事务可能会丢失,这会破坏跨数据库事务的完整性。

  这可能会在镜像数据库未同步时发生(有关详细信息,请参阅我发表的 2009 年 6 月专栏),因此提交的跨数据库事务的日志记录尚未发送到镜像。在强制故障转移后,新主体数据库中不存在该事务,因此会破坏跨数据库事务的完整性。

  问题:最近我对某些性能计数器进行监视,以解决一个数据库存储方面的问题。在这个过程中,我注意到了一些非常奇怪的现象:尽管数据库中未进行任何操作,数据库文件仍然存在写入活动。数据和日志文件都存在这种情况。甚至在我确保未连接到 SQL Server 的情况下,这种情况仍在继续。既然没有连接,怎么会存在 I/O 活动呢?

  解答:SQL Server 有很多需要运行的内部操作;这些操作称为后台任务。系统中会执行一个或多个后台任务,从而导致 I/O 活动。下面简单列出了可能的原因:

  虚影清理:删除操作仅将记录标记为已删除,以优化取消操作时的性能;该操作实际上不对空间清零。一旦提交了删除操作,便必须执行某种操作,以从数据库中实际移除被删除的记录。这是由虚影清理任务完成的。有关详细信息,请参阅我的博客文章,这篇文章还说明了如何检查虚影清理任务是否正在运行。

  自动缩减:启用此任务可以自动移除数据库中的空空间。此任务的工作方式是,将数据文件末尾的页面移动至开头,合并末尾的可用空间,然后截断文件。您当然可以启用此任务,但绝对不应这样做,因为这样会导致索引碎片问题(从而降低性能)并会占用大量资源。通常,还会为数据库启用自动增长,因此可能会陷入缩减-增长-缩减-增长的循环,这就做了大量无用功。您可以使用下面的查询检查所有数据库的状态:

SELECT name, is_auto_shrink_on FROM sys.databases;

 

  延迟丢弃:此任务负责执行丢弃或截断表和索引所需的工作(进行索引重新生成操作可能引起索引丢弃,即生成新索引,然后丢弃旧索引)。对于小型表和索引,会立即执行取消分配。对于较大的表和索性,会通过后台任务成批执行取消分配。这是为了确保获取所有必需的锁,而不致耗尽内存。您可以按照此处的联机丛书中所述,使用各种延迟丢弃性能计数器监视此任务。

  延迟写入:此任务负责从内存中缓存(称为缓冲池)移除旧页面。当服务器内存不足时,即使对页面进行了更改,也可能必须将其移除。在这种情况下,更改过的页面必须先写入磁盘,之后才能从内存中移除。您可以按照此处的联机丛书中所述,使用“Lazy writes/sec”性能计数器监视此任务。

  以上所有这些任务都可能对数据库进行更改。它们全都使用事务进行更改,只要提交事务,事务所生成的事务日志记录就必须写入磁盘上的数据库日志部分。因为会时常对数据库进行更改,所以还必须存在检查点,以将更改的数据文件页面刷新到磁盘。有关详细信息,请参阅我为 TechNet 杂志 2009 年 2 月刊撰写的文章了解 SQL Server 中的日志记录和恢复功能。

  可以看到,不存在活动的 SQL Server 连接,不一定意味着进程处于静止状态,它可能正忙于执行一个或多个后台任务。如果所有数据库活动都完成很久后,I/O 活动仍在进行,可能还需要检查是否在运行计划作业。

  问题:我是非自愿 DBA,正在尝试不同的任务以尽快熟悉工作。前任 DBA 设置作业将备份写入一个文件,但是我不知道如何还原这些备份。是否可以查看文件中的备份内容?我该如何正确地还原这些备份?

  解答:尽管可以将备份附加到同一个文件,但是大多数人将每个备份放在名称有意义的(通常还带日期/时间戳组合)的独立文件中。这样有助于避免您所面临的问题,也便于执行其他任务:

  每个备份都位于自己的文件中时,出于安全原因而复制备份会十分简单。如果所有备份都位于一个文件中,就只能通过复制整个备份文件来创建最新备份的副本。

  当所有备份都位于一个文件中时,不能删除旧备份。

  如果每个备份都有单独命名的文件,则不可能意外覆盖现有副本。

  遗憾的是,这一点对您毫无帮助,您已在一个文件中包含多个备份。不过,可以通过两种方式还原副本:手动还原或使用 SQL Server Management Studio (SSMS) 还原。

点击查看更多TechNet精彩文章

0
相关文章