SQL 技术问答内部群集、神秘的挂起、SA 帐户及其他

编辑:Nancy Michell

问:我需要更好地了解群集是如何工作的。我们的环境将由以下几个部分组成:一个运行 SQL Server™ 2005 的 64 位 Windows Server® 2003、一个 SQL Server Reporting Services (SSRS) Web 场(一种报表服务器扩容部署)、一个 SSRS TempDB 编录服务器,以及通过链接服务器从第三方数据库中抽取数据,并为 SSRS 存储该数据的 SQL Server。

我们想要一个三节点的主动/主动/被动群集。节点 1 为主动节点,用于存储从第三方数据库中抽取的数据。节点 2 为主动节点,用于存储 SSRS 目录。节点 3 为被动节点,作为节点 1 或节点 2 的故障转移之用。您能否帮我们实现这样的群集?

答:很遗憾,许多人都对 SQL Server 群集的主动/主动和主动/被动这些术语存在误解。他们认为 SQL 群集可以支持跨多个服务器对一个数据库或 SQL 实例进行“扩容”。但事实并非如此。SQL Server 上并没有一种类似主动/主动数据库或实例的组件。“实例”是指安装了 SQL Server 及其相应的数据库。我们这种按 SQL Server 实例进行的群集始终为主动 (1)/被动 (n) 模式(请注意,n 的值介于 1-7 之间,依您的 SQL Server 的版本而定)。这就是为什么称之为故障转移群集的原因。

了解这一点之后,您就可以开始考虑在一组节点上安装多个故障转移群集实例了。例如,使用共享磁盘的三个物理服务器可以在节点 1 和节点 2 上分别有一个默认为主动模式的实例,而节点 3 则作为这两者的故障转移节点。这些实例是完全独立的,不共享数据,也非主动/主动模式。它们皆为主动/被动模式,并共享同一个故障转移实例。如果两个实例在发生故障时都转移至节点 3,那么就可以知道随着时间的推移,节点是否存在因负荷过重而崩溃的危险。根据设计,每个故障转移的处理能力是相等的。如果最大负荷在正常操作过程中需要两个节点来进行处理,那么节点 3 将不可能在最大负荷下被正常指派给两个节点。

尽管如此,因为能够运行一个群集的硬件的成本十分巨大,我们理解人们会如何衡量两个主要节点同时发生故障,并将整个负荷全部转移到一个节点上这种情况的可能性。出于这样的考虑,他们也许会决定承担这种风险,而不是购买全部的故障转移容量。

幸好,我们带来了一些好消息:SQL Server 2005 为获得高可用性 (HA) 提供了多种方案,包括一些替代方案,在发生故障时,它们可以比群集更快地进行故障转移,甚至能够均衡数据的重复备份(群集依赖的是单个 SAN)。这些选项包括镜像、对等复制等。有了那些新的替代方案,我们可以提供更多的选择以满足各种需求,包括一些组合了多种 HA 功能的方案。

Microsoft® 群集配置验证向导 (ClusPrep) 现已可下载,它代替了原先的“硬件认证列表 (HCL)”测试,可以用几个月的时间对整个配置进行验证,从而确认其在群集下是“受支持的”。这就将硬件验证工具交到了 DBA 手中,进一步降低了获得经认证的硬件的成本(金钱和时间)。它甚至使在一个群集节点集中验证和部署异构硬件成为可能。

问:在我的机器上进行的删除操作在 12 个小时后显示为挂起。它并没有被阻止。查看最慢的查询计划后,我发现有一个触发器的运行需要 87,327 秒,因此我怀疑该操作在这个触发器中被挂起了。如何才能确切地查看是哪个语句被挂起了?

答:很可能是触发器中的某个循环没有退出,其中原因有很多。如果挂起的时间较长,并且您想要查看正在执行哪个语句,则可运行图 1 中的代码。它将告诉您当前正在运行哪个语句,而这个语句应该就是导致您机器挂起的原因。

Figure 1 查找当前正在执行的语句

-- Look at the current statement being run:
-- Put results to text (Ctrl + T)
DECLARE @Handle binary(20), 
        @start int, 
        @end int,
        @SPID int

SET    @SPID = spid

SELECT @Handle = sql_handle, 
        @start = stmt_start, 
        @end = stmt_end 
FROM Master..sysProcesses(NOLOCK) 
WHERE SPID = @SPID

IF NOT EXISTS (SELECT * FROM ::fn_get_sql(@Handle))PRINT ‘Handle not found in cache’
ELSE
   SELECT ‘Current Statement’= substring(text, (@start + 2)/2, CASE @end WHEN -1 THEN (datalength(text))
       ELSE (@end -@start + 2)/2 END)
       FROM ::fn_get_sql(@Handle)

问:我需要支持通过防火墙的事务复制。发布服务器和分发服务器位于防火墙外,而订阅服务器则位于防火墙内。订阅服务器被设置为在 1433 上侦听,以下是我机器的名称:发布服务器:PUBMACHINE,分发服务器:DISTMACHINE,订阅服务器:SUBMACHINE。我需要打开哪些端口才能成功推送初始快照和发布?

答:如果您使用推送订阅,则只需打开 SQL Server 端口(即您的 1433 端口),因为分发代理将在分发机器上(防火墙外部)运行,并且也许可以对由快照代理生成的快照文件进行本地访问。但如果您使用请求订阅,则在订阅机器上运行的分发代理将需要穿过防火墙对快照文件进行访问。以下是一些您可以考虑使用的选项。

假设快照文件现已可从防火墙外的一个共享文件访问,则您可以打开 Windows® 穿过防火墙的文件共享端口,以便让在防火墙内部运行的分发代理可以访问位于防火墙外部的快照文件(注意,这可能会给基础结构的其他部分带来安全隐患)。请注意,如果您已将一个本地路径配置为默认的快照位置(SSMS 默认值),则可能需要使用分发代理的 /AltSnapshotFolder 选项来覆盖快照文件的拾取位置。

您也可以对复制进行配置,以使用 FTP 来传送快照文件(这时需要打开端口 21)。

问:我想知道停用 SQL Server 2005 中的 SA 帐户会带来哪些问题,以及停用 SA 是否真的可以增强安全性。是否有关于这个问题的白皮书?

答:在新的 SQL Server 2005 中,当未启用混合模式时,默认会停用 SA 帐户并会为其随机生成一个密码。您也可以手动将其停用。没有关于这个问题的白皮书,但最佳实践白皮书中对停用和重命名登录进行了讨论。

如果要防止 SA 帐户被破坏,可以对其进行重命名。只需记住,如果停用一个帐户,就需要为其设置一个新密码。

要回答您关于这是否提供了真正的安全性这个问题,请记住,停用帐户之所以能够增强安全性是因为当帐户停用时,对密码进行猜测是徒劳的。无论黑客或病毒有多长的时间,对一个被锁定的帐户进行强制攻击都不会成功。重命名或停用 SA 会破坏依靠此 SA 帐户进行连接的应用程序。因此首先应找出这些应用程序并对它们进行修复或清除。正如前面提到的,只有重新启用该帐户后,才可使用该帐户连接到数据库。此外,因为先前的身份验证过程失败,失败的尝试对受攻击系统产生的影响较小。

问:我的一个大型在线事务处理 (OLTP) 数据库的日志文件是数据文件的两倍大小。我已经尝试使用下面的命令将该日志文件缩小到合理的大小,但我需要进一步缩小该文件:

backup database syslogs to backupfile
DBCC SHRINKFILE (syslogs_log)

答:您应将您的备份数据库更改为一个备份日志语句。这样,就可以将该数据库置于简单恢复模式并执行 shrinkfile 语句。日志缩减完毕后,请将数据库设回其先前的恢复模式并对数据库进行备份。如果日志文件仍未缩减,请检查并确保没有打开的事务(使用 dbcc opentran 命令)。知识库文章“support.microsoft.com/kb/907511”提供了更多信息。

问:如果在执行计划的 SQL Server Agent 作业时发生故障转移,故障转移后会对该作业产生怎样的影响?是否需要手动重新启动该作业?

答:是的,如果没有其他处理程序,则需要手动启动该作业。如果不想手动重新启动作业,也可以编写一个脚本,在作业完成时更新表格。如果值为 1,则表示作业已经执行;其他值则表示作业尚未完成,另一个作业稍后将进入并发出启动命令。因此,当作业执行过程中因发生故障转移而需要重新运行时,通过编写一个脚本,可以减少对那些在午夜执行,且又必须在下一个工作日之前完成的重要作业所产生的担心。

提示:升级和 DBCC UPDATEUSAGE

要从 SQL Server 2000 升级到 SQL Server 2005 吗?

如果是,请务必在数据库完成升级后运行 DBCC UPDATEUSAGE。

DBCC UPDATEUSAGE 会报告并更正目录视图中错误的页数和行数。这些错误的数据需要进行更正,因为它们可能会导致 sp_spaceused 系统存储的程序返回错误的空间使用情况报告。在 SQL Server 2005 中,这些值始终能够被正确地维护,因此这些数据库从来不会出现错误的计数。但是,将数据库升级到 SQL Server 2005 可能会包含无效的计数,因此您需要在升级后运行 DBCC UPDATEUSAGE。

接下来将说明 DBCC UPDATEUSAGE 是如何工作的。它会更正表格或索引中每个分区的行、使用的页面、保留的页面、叶页面以及数据页面的计数。如果系统表格中的数据都正确,则 DBCC UPDATEUSAGE 不返回数据。如果发现并更正了错误的数据,并且您未使用 WITH NO_INFOMSGS,则 DBCC UPDATEUSAGE 会返回系统表格中被更新的行和列。

DBCC UPDATEUSAGE 也可用于同步空间使用计数。由于在大型表格或数据库上运行 DBCC UPDATEUSAGE 可能需要一些时间,因此它通常是在您怀疑 sp_spaceused 返回的值不正确时才使用。请注意,在返回表格或索引的空间信息前,sp_spaceused 在运行 DBCC UPDATEUSAGE 时可以接受一个可选的参数。

SQL Server 2005 中的 DBCC CHECKDB 已经得到了增强,它可以检测页数和行数何时变为负值。当检测到负值时,DBCC CHECKDB 会发出一条警告,并建议您通过运行 DBCC UPDATEUSAGE 来解决这个问题。虽然这个问题看似由数据库升级到 SQL Server 2005 引起,但实际上无效的计数在升级操作之前已经存在。

这里有一个如何更新当前数据库中所有对象的页数/或行数的示例。下面的命令将 0 指定为数据库的名称,DBCC UPDATEUSAGE 会报告当前数据库的更新信息:

DBCC UPDATEUSAGE (0);
GO

要更新页数和/或行数,如 AdventureWorks 的页数和/或行数,并且不显示信息性消息,您可以运行类似下面这个命令,该命令指定 AdventureWorks 为数据库的名称,然后不显示所有的信息性消息:

USE AdventureWorks;
GO
DBCC UPDATEUSAGE (‘AdventureWorks’) WITH NO_INFOMSGS; GO

更多信息,请在 SQL Server 联机丛书中查阅“DBCC UpdateUsage”。

Thanks to the following Microsoft IT pros for their technical expertise: Ken Adamson, Sunil Agarwal, Siggi Bjarnason, Shaun Cox, Laurentiu Cristofor, Ernie DeVore, Michael Epprecht, Lucien Kleijkers, Raymond Mak, Chat Mishra (MSLI), Niraj Nagrani, Rick Salkind, Jacco Schalkwijk, Vijay Sirohi, Vijay Tandra Sistla, Matthew Stephen, and Buck Woody. Thanks to Saleem Hakani for this month's tip.

© 2008 Microsoft Corporation 与 CMP Media, LLC.保留所有权利;不得对全文或部分内容进行复制.