进程里面有IfxPsdSv.exe,这ctfmon.exe是什么进程,有没有危险?

当前位置: >>
故障排除(数据库引擎)
故障排除(数据库引擎)1. 故障排除概念本节包含有关排除 SQL Server 数据库引擎 故障的信息。1.1 数据收集器故障排除提供有关数据收集器常见问题的疑难解答信息。 本主题解决以下类别的疑难问题:? ? ?错误情况。此类别包含对象模型和运行时错误。 性能问题。此类别包含一般和特定的性能情况。 系统挂起。此类别包含数据收集过程中发生的子组件挂起。1.1.1错误情况错误可能会由对象模型或在运行时引发。1.1.1.1对象模型错误数据收集器对象模型是一种托管 API, 它提供一种编程方式来管理数据收集器属 性和数据收集组。 对象模型是为数据收集器提供配置机制的一组存储过程和视图 周围的薄包装。有关详细信息,请参阅数据收集器编程。 对象模型错误可能来自对象模型的下列组件之一:?Transact-SQL 错误由从其中一个数据收集器存储过程调用的存储过程或 Transact-SQL 代码引发。 Transact-SQL 错误由数据收集器存储过程直接引发。 托管异常由对象模型直接引发。? ?下表说明了对象模型可能引发的错误。 错误消息错误 号说明无法更新活动收集 组 '%s' 的名称、 目 标、proxy_id 或 试图更新活动收集组。必须先停止收集组,然后才能 collection_mode。 14669 进行任何该类型的更新。当收集组处于活动状态时, 请停止该收集组, 然 只能更改上载计划。 后再次尝试将其更 新。 无法删除活动收集 组 '%s'。请停止该 14670 试图删除正在运行的收集组。 收集组, 然后再次尝 试将其删除。 无法更新活动收集 组 '%s' 中收集项 '%s' 的名称或参 14671 试图更新正在运行的收集组中的收集项。 数。请停止该收集 组, 然后再次尝试更 新该收集项。 无法删除活动收集 组 '%s' 中的收集 项 '%s'。请停止该 14672 试图删除正在运行的收集组中的收集项。 收集组, 然后再次尝 试删除该收集项。 无法删除收集器类 型 '%s'。请删除与 此收集器类型关联 14673 试图删除具有关联的收集项的收集器类型。 的所有收集项, 然后 再次尝试将其删除。 无法上载非活动收 集组 '%s' 的数据。 请启动该收集组, 然 14674 试图上载由未在运行的收集组收集的数据。 后再次尝试上载数 据。 无法更新名称、目 标、proxy_id、 logging_level 或 collection_mode, 或者无法向活动收 14675 试图更新正在运行的收集组。 集组 '%s' 添加收 集项。 请停止该收集 组, 然后再次尝试将 其更新。 该用户无权更改 '%s'。 该用户必须是 用户试图更新只能由特定数据收集器角色更改的属 14676 数据收集器角色 性。 '%s' 的成员。 该用户无权执行此 操作。 该用户必须是 用户试图执行某操作,但不是所需的数据收集器角色 14677 数据收集器角色 的成员。 '%s' 的成员。 外部用户已停止并 关闭了 ID 为 %d 的 SQL Server 跟 由数据收集器创建并使用的跟踪已在收集器运行时之 14678 踪。SQL Server 跟 外停止和关闭。 踪收集器将尝试重 新创建该跟踪。 此数据仓库中指定 传递给管理数据仓库中某个存储过程的参数的值与仓 14679 的 %s (%s) 无效。 库中的其他条目不匹配。 只能对运行 SQL Server 2005 或更 试图在运行 SQL Server 2000 或早期版本的服务器上 高版本的服务器执 14680 安装管理数据仓库。 行此版本的 instmdw.sql。 禁用收集器时不能 执行此过程。 请启用 14681 试图执行与收集器的状态相冲突的操作。 收集器,然后重试。 收集组的状态已更 改, 但是只有在启用 14682 试图在未启用收集器时启动或停止收集组。 收集器后, 它才能启 动或停止。 快照中或连续模式 在快照中或连续模式下创建或更新收集组而未提供计 下的收集组需要一 14683 划。 个计划。 捕捉到错误,编 号: %d,级别: %d, 数据收集器组件中发生一般性错误; 在 catch 块中捕 14684 状态: %d, 过程: %s, 获到该错误并再次引发该错误。 行: %d,消息: %s 操作无效。 ID 为 %d 针对 is_running 状态为 0 的收集组调用 的收集组的状态当 14685 sp_syscollector_create_set_queue_and_service。 前为“未运行”。 配置存储区的 MDWInstance 和 MDWInstance 或 MDWDatabase 参数的管理数据仓库 14686 MDWDatabase 参数 连接字符串为 Null。 不能为 Null。 @cache_window 参 14687 试图将收集器配置存储区的 CacheWindow 参数的值 数的值 (%d) 无效。 设置为小于 -1 的值。 允许的值为: -1 (缓 存以前上载失败的 所有上载数据)、0 (不缓存上载数据)、 N (缓存以前 N 次 上载失败的数据, 其 中 N &= 1) SQL Server 代理停 止时收集组无法启 14688 试图在未启用 SQL Server 代理时启动收集组。 动。请启动 SQL Server 代理。 如果未配置管理数 据仓库, 则收集组无 法启动。请运行 14689 试图在未设置管理数据仓库时启动收集组。 instmdw.sql 脚本 以创建并配置管理 数据仓库。 启用收集器时无法 执行此过程。 请禁用 14690 试图执行与收集器的状态相冲突的操作。 收集器,然后重试。 收集器的状态不能 对 sp_syscollector_verify_collector_state 的调 为 Null。这可能表 14691 用发现 CollectorEnabled 参数的值为 Null。 这可能 示收集器配置数据 表示收集器的配置数据发生内部损坏。 发生内部损坏。1.1.1.2运行时错误当收集包或上载包在运行中遇到问题时便会发生运行时错误。 这些错误可能来自 下列组件之一:?SQL Server 2008 Integration Services (SSIS) 包的数据流。这些错误可能是由于数据转 换失败或出现数据截断导致的。数据收集器会记录受错误影响的行号,并将其记录 在数据收集器日志表中。 SSIS 包的控制流。这些错误记录在 msdb 数据库的 SSIS 日志表 (msdb.dbo.sysssislog) 中,并冒泡到数据收集器日志表中。 数据收集器运行时组件 (dcexec.exe)。这些错误直接记录在数据收集器日志表中。??有关详细信息,请参阅数据收集器日志记录。 我们建议采用以下方法之一获取有关运行时错误的状态信息。 1.1.1.2.1 Transact-SQL 存储过程和视图若要查看所有当前正在运行和已完成的收集组或包的状态,请运行以下查询:复制代码use msdb select * from syscollector_execution_log_full 上述查询将返回以下结果集。列名 说明每个收集组执行的唯一 ID。它用于将此视图与其他详细 日志联接起来。 父包或收集组的 ID。对于收集组而言,此值为 NULL。 各个 ID 以父子关系链接在一起,以便可以轻松确定哪 parent_log_id 个收集组启动了哪个包。此外,此视图将日志条目按其 父子链接进行分组并缩进包的名称,从而使调用链清晰 可见。 name 该日志条目所表示的收集组或包的名称。 collection_mode 记录该条目时的收集组活动,即收集或上载。 start_time 收集组或包启动的时间。 last_iteration_time 对于连续运行的包而言,是包上次捕获快照的时间。 finish_time 对于已完成的包和收集组而言,是运行完成的时间。 duration 包或收集组已经运行的时间(以毫秒为单位)。 operator 启动该收集组或包的操作员。 收集组或包的状态。此值可以为: log_id?0 - 正在运行 1 - 已完成 2 - 失败status? ?当收集组或包失败时,导致失败的 SSIS 包中的任务的 名称。 package_execution_id 指向 SSIS 日志表的链接。 指向数据收集器配置表的链接。 failure_task collection_set_id注意: 您可以使用 collection_set_id 作为筛选器以专注于日志中的特定 收集组。 有关详细信息,请参阅 syscollector_execution_log_full (Transact-SQL)。 您可以通过执行数据收集器提供的函数之一获取有关收集组和包执行的其他信 息。 以下函数将返回有关收集组或包的详细统计信息,包括由包记录的错误行的数 目。复制代码select * from fn_syscollector_get_execution_stats(@log_id) 下一个函数将返回与某个包的 package_execution_id 相匹配的 SSIS 日志 (sysdtslog90) 部分。如果该包失败,则这是找出错误根源的最好方式。复制代码select * from fn_syscollector_get_execution_details(@log_id)1.1.1.2.2 数据收集器状态报表您可以通过查看 SQL Server Management Studio 中提供的日志获取与前面的 Transact-SQL 查询返回的信息相同的信息。有关详细信息,请参阅如何查看收 集组日志。1.1.2 性能问题有三个主要的数据源可用于检查和诊断性能。 首先,上一部分介绍的日志表还提供了可用于解决性能问题的有用信息。 fn_syscollector_get_execution_stats 函数可返回以下信息。列名 说明avg_row_count_in min_row_count_in max_row_count_in avg_row_count_out min_row_count_out max_row_count_out avg_duration min_duration进入包的数据流任务的平均行数。 进入包的数据流任务的最小行数。 进入包的数据流任务的最大行数。 退出包的数据流任务的平均行数。 退出包的数据流任务的最小行数。 退出包的数据流任务的最大行数。 在包的数据流组件中消耗的平均时间(以毫秒为单位)。 在包的数据流组件中消耗的最短时间(以毫秒为单位)。 max_duration在包的数据流组件中消耗的最长时间(以毫秒为单位)。第二个性能数据源是 syscollector_execution_log_full 表,该表提供有关已 经完成运行或正在运行的收集组所用时间的信息。 最后,可以使用性能计数器来帮助评估性能问题。尤其是,数据收集器进程 (dcexec.exe) 实例的标准进程计数器为数据收集器运行时组件使用了多少系统 资源提供了非常好的指示器。1.1.2.1性能问题具体情况运行数据收集器时最有可能出现两种性能问题情况:? ?数据收集器消耗的系统资源过多。 数据收集器无法承受收集负荷。1.1.2.1.1 系统资源过度消耗如果进程性能计数器的分析表明 dcexec.exe 进程使用的系统资源过多, 则需要 进行以下调查。 首先,确定是否大部分资源都由一个收集组占用。?若要标识该收集组, 请将进程 ID 映射到 syscollector_execution_log_full 中的收集组 ID,然后在 syscollector_collection_sets 表中查找该收集组。 确定该收集组所收集的内容。使用以下查询列出该收集组中的所有收集项:?复制代码select * from syscollector_collection_set_items where collection_set_id = &id&?使用来自上述查询的信息,考虑以下问题:o o o o收集项是否过多? 大部分问题是否都由一个收集项所导致? 收集的数据是否过多? 如果对上述任何问题的回答为“是”,请考虑修改收集或收集项以减少所收集 的数据量。这将减少资源消耗。 其次,确定问题是否由活动收集组的数量过多所导致。?使用以下查询查看系统中定义的收集组数:复制代码select count(*) from syscollector_collection_sets?使用以下查询查看当前正在运行的收集组数:复制代码select count(*) from syscollector_execution_log_full where parent_log_id is null and status = 1?如果性能问题是间歇性的,请检查问题是否映射到任何收集或上载活动。如果所有 计划都完全相同,则这可能是导致问题的原因。通过调整收集或上载计划或许就可 以解决问题。1.1.2.1.2 无法承受负荷这种情况只发生在连续运行的收集组中。 如果收集频率较高并且要收集的数据量 较大, 则收集包可能无法在为单个快照迭代分配的时间内处理数据。可以通过将 日志表中的 avg_duration 和 max_duration 列与为特定收集项定义的收集频 率进行比较来检测这种情况。 如果 max_duration 值大于频率值,则收集包可能无法始终满足配置的频率要 求。如果 avg_duration 值大于频率值,则收集包会一直出现相同的问题。对于 后一种情况,应减小频率或修改收集项以限制所收集的数据量。1.1.3 系统挂起如果作为数据收集器的一部分运行的某个包停止处理但并未退出而是停留在该 状态, 则会出现系统挂起。 多数系统挂起问题都可以通过停止并重新启动收集组 得到解决。 区分真正挂起和预期行为非常重要。?连续运行的收集包多数时间处于等待状态,它会定期醒来收集数据快照。收集数据 后,该包会回到等待状态。这种等待状态可能看似系统挂起,实际并不是。若要对 此进行验证,请检查可疑包的 syscollector_execution_log_full 表。如果 last_iteration_time 不晚于当前时间,则该情况不属于挂起。 ?包可能会设计为等待某个将触发收集操作的事件。这种情况下,包将会等待该事件。 这种情况并不是挂起。若要验证是否有与数据收集器相关的系统挂起,请执行以下检查:? ?首先,标识与要调查的收集组相对应的 dcexec.exe 进程 ID。 接下来,检查该进程是否正在运行以及是否使用了任何资源。任何挂起进程的 CPU 占用率通常都为 0% 并且不会分配较多内存。该进程也可能会占用高百分比的 CPU。如果是这种情况,则它可能正在进行循环并且未退出内存。 最后,检查进程的日志表以查看它上次更新的时间。如果更新时间长于收集项的频 率,则该进程可能已挂起。?有多种原因可导致数据收集器进程挂起。下面列出了最常见的原因:? ? ?包等待发出下一个迭代信号,但没有信号发出。 包等待由另一个包所占有的共享锁,但该锁未释放。 包执行过程中出现错误且未得到适当处理,控制流中断,但包未完全失败。在上述任何情况下, 日志中都会有与系统挂起相关的特定条目。请查看是否有任 何指示原因的消息。 出现系统挂起时,请创建 dcexec.exe 进程的转储并做进一 步调查。1.2 对数据库引擎连接进行故障排除包含有关解决数据库引擎连接问题的信息。1.2.1 故障排除:超时时间已到当 SQL Server 数据库引擎实例未运行、服务器名称键入错误或者存在网络问题 或防火墙时,通常会发生“超时时间已到”错误。1.2.1.1错误文本在 SQL Server Management Studio 中,此错误显示为: “无法连接到 &服务器名&。” “超时时间已到。在操作完成之前超时时间已过或服务器未响应。(Microsoft SQL Server,错误: -2)” 在 sqlcmd 中,可能出现的超时错误包括: “SQL 网络接口: 定位指定的服务器/实例时出错” “Sqlcmd: 错误: Microsoft SQL Server Native Client : 客户端无法建立连 接。” “Sqlcmd: 错误: Microsoft SQL Server Native Client : 登录超时时间已到。 ” “无法与 SQL Server 建立连接” “建立与服务器的连接时出错。当连接到 SQL Server 时,此故障可能会因为 SQL Server 在默认设置下不允许进行远程连接而引发的。”1.2.1.2此错误的常见原因原因 解决方法键入的服务器名称不正确。 服务器中的 SQL Server 服务未 运行。 数据库引擎实例的 TCP/IP 端口 被防火墙阻塞。 数据库引擎由于已被更改或者不 是默认实例而不侦听端口 1433, 并且没有运行 SQL Server Browser 服务。 SQL Server Browser 服务正在运 行,但 UDP 端口 1434 被防火墙 阻塞。 客户端和服务器未配置为使用相 同的网络协议。使用正确的服务器名称,然后重试。 启动 SQL Server 数据库引擎实例。 将防火墙配置为允许访问数据库引擎。 要么启动 SQL Server Browser 服务,要么指 定 TCP/IP 端口号进行连接。 将防火墙配置为允许访问服务器上的 UDP 端 口 1434,或者连接指定 TCP/IP 端口号。使用 SQL Server 配置管理器,确认服务器和 客户端计算机至少有一个通用的启用协议。 修复网络上的计算机名称解析问题, 或者使用 网络无法将服务器名称解析为 IP 服务器的 IP 地址连接。这不是 SQL Server 地址。 可使用 PING 程序对此进行 问题。有关帮助,请参阅 Windows 文档或与 测试。 网络管理员联系。 修复网络上的 TCP/IP 问题。这不是 SQL 无法使用 IP 地址连接到网络。 可 Server 问题。有关帮助,请参阅 Windows 文 使用 PING 程序对此进行测试。 档或与网络管理员联系。 1.2.1.3不常见错误1.2.1.3.1 多个服务器 IP 地址在连接到群集或具有多个 IP 地址的非群集计算机上安装的 SQL Server 命名 实例时,Windows Vista 或 Windows Server 2008 上的客户端可能会收到此错 误。所有 SQL Server 版本都可能会出现这种问题。 原因 在连接到远程计算机上的命名实例时,客户端使用用户数据报协议 (UDP) 连接 到 SQL Server 计算机或群集上的 SQL Server Browser 服务以获取连接端点 (TCP 端口号或命名管道)。 Windows Vista 或 Windows Server 2008 客户端上的防火墙不允许对 UDP 进行 松散源映射。即,响应必须是从所查询的相同 IP 地址中返回的。如果响应不是 从最初针对的 IP 地址中返回的,客户端防火墙将删除数据包。在尝试连接到群 集服务器或具有多个 IP 地址的非群集服务器计算机时,可能会出现这种问题。 下表介绍可导致 UDP 数据包被删除的操作系统组合。这可以阻止连接到 SQL Server 的命名实例或未在 TCP 端口 1433 上侦听的 SQL Server 默认实例。客户端操作系统 运行 SQL Server 的操作系统 SQL Server 2008 结果 SQL Server 2005 结果Windows XP 或 Windows XP 或 Windows Windows Server 2003 Server 2003 Windows XP 或 Windows Vista 或 Windows Server 2003 Windows Server 2003UDP 数据包未 被删除。 UDP 数据包未 被删除。 UDP 数据包被 Windows Vista 或 Windows XP 或 Windows 删除。无法连 Windows Server 2008 Server 2003 接。 Windows Vista 或 UDP 数据包被 Windows Vista 或 UDP 数据包未 Windows Server 2008 (x86、 删除。无法连 Windows Server 2008 被删除。 IA64) 接。 Windows Vista 或 UDP 数据包被 UDP 数据包被 Windows Vista 或 Windows Server 2008 删除。无法连 删除。无法连 Windows Server 2008 (x64) 接。 接。 解决方法 若要解决此问题,请执行以下操作之一:?UDP 数据包未 被删除。 UDP 数据包未 被删除。 UDP 数据包被 删除。无法连 接。在连接字符串中,将 TCP 端口号或命名管道名称指定为服务器名称的一部分。 ?在客户端计算机上具有高级安全功能的 Windows 防火墙中创建例外。注意: 如果在防火墙中创建例外, 可能会使计算机或网络更容易受到恶意用户或恶意软件 (如病毒) 的攻击。建议您不要使用这种解决方法,此处提供该信息的目的是,如果没有切实可行的替 代方法,您可以自行决定是否采用这种解决方法。?例外可以是以下任一情况:o o为连接到 SQL Server 的应用程序添加例外规则。 添加一个入站规则,以允许来自 SQL Server 计算机或群集的所有可能的 IP 地址的通信。1.2.2 故障排除:强行关闭的连接使用 TCP/IP 连接到 SQL Server 时,可能会出现此错误。1.2.2.1错误文本该错误出现时可能具有以下格式:? ?TCP_PROV: 现有连接被远程主机强行关闭。 访问接口编号: 7, 错误: 10054, 错误消息:“TCP 访问接口: 现有连接已被远程主机强 行关闭…” 未处理的异常: 在向服务器发送请求时发生传输级错误。(访问接口: TCP 访问接口, 错误: 0 - 现有连接已被远程主机强行关闭。)?1.2.2.2此错误的常见原因下表列出了此错误的常见原因和解决方法。原因 解决方法客户端已与不支持的 SQL Server Native Client 版本连接。 发生故障的网络硬件正在删除部分 TCP 通信。将客户端计算机更新为 SQL Server Native Client 的服务器版本。 使用网络监视程序分析 TCP SYN、ACK 和 FIN 消息。 请参阅后面的“在 Windows Server 2003 SynAttackProtect 设置可能正在删 SP1 上运行时,连接可能被强行关闭”部 除连接。 分。1.2.2.2.1 在 Windows Server 2003 SP1 上运行时,连接可能被强行 关闭当使用大量到 Windows Server 2003 Service Pack 1 上运行的 SQL Server 数 据库引擎实例的客户端连接尝试测试可伸缩性时, 如果请求到达的速度快于 SQL Server 提供的连接速度,则 Windows 可能会删除这些连接。这是 Windows Server 2003 Service Pack 1 的一项安全功能,可实现有限的传入 TCP 连接请 求队列。 若要解决此问题,请使用 regedit.exe 实用工具添加以下注册表项:项 类 型 名称 值HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Serv DWO SynAttackPr 00000 ices\Tcpip\Parameters\ RD otect 000安全说明: 设置此注册表项可能会使服务器面临 SYN 泛滥和拒绝服务攻击的威胁。只有在必要并且了 解这些安全风险的情况下,才可以添加此注册表值。完成测试后,请删除此注册表值。1.2.3 故障排除:在管道的另一端没有进程连接到 SQL Server 的客户端如果在 SQL Server 上未启用命名管道支持时连接 到该服务器(即使可以使用其他协议,如 TCP/IP),可能会遇到此命名管道错 误。 如果服务器上未启用命名管道, 则拒绝客户端试图使用命名管道进行连接。以下 两种情况下会出现此错误:? ?客户端试图只使用命名管道进行连接,而服务器上未启用命名管道协议。 客户端试图使用任何可用的协议进行连接, 但在客户端协议顺序中, named pipes 列 在 TCP 之前。 1.2.3.1错误文本named pipes 提供程序:在管道的另一端没有进程。 Microsoft SQL Server Native Client:通信链接失败。 Microsoft SQL Server Native Client:在与服务器建立连接时出现错误。当连 接到 SQL Server 时,此故障可能是因为 SQL Server 在默认设置下不允许进行 远程连接而引发的。1.2.3.2此错误的常见原因原因 解决方法客户端试图使用 named pipes 进行连接, 使用 TCP/IP 进行连接,或使用 SQL 而服务器没有配置为允许使用 named Server 配置管理器通过 named pipes pipes 进行远程连接。 进行远程连接。 客户端协议顺序是在尝试 TCP 协议之前 在客户端计算机上使用 SQL Server 试图使用 named pipes 协议进行连接, 而 配置管理器,在协议顺序列表中将 服务器上未启用 named pipes。 TCP 移动到 Named Pipes 之前。1.2.4 故障排除:用户 'x' 登录失败因密码或用户名错误而使身份验证失败并导致连接尝试被拒时, 类似下面的消息 将返回到客户端: “用户 '&user_name&' 登录失败”。 (Microsoft SQL Server, 错误: 18456)”。 返回到客户端的其他信息有: “用户 '&user_name&' 登录失败。(.Net SqlClient 数据访问接口)” -----------------------------“服务器名称: &computer_name&” “错误号: 18456” “严重性: 14” “状态: 1” “行号: 65536” 也可能返回以下消息: “消息 18456,级别 14,状态 1,服务器 &computer_name&,第 1 行” “用户 '&user_name&' 登录失败。”1.2.4.1其他错误信息为了增强安全性, 返回到客户端的错误消息有意隐藏身份验证错误的本质。 但是, 在 SQL Server 错误日志中,对应的错误包含映射到身份验证失败条件的错误状 态。将错误状态与以下列表进行比较以确定登录失败的原因。状态 说明2 5 6 7 8 9 11 12 18用户 ID 无效。 用户 ID 无效。 尝试同时使用 SQL Server 身份验证与 Windows 登录名。 登录已禁用,密码不正确。 密码不正确。 密码无效。 登录有效,但服务器访问失败。 登录是有效的登录,但服务器访问失败。 必须更改密码。存在其他错误状态,并表示一个意外的内部处理错误。1.2.4.2示例在此示例中,身份验证错误状态为 8。这指示密码不正确。日期 来源 消息 20:12:56.34
20:12:56.34注意:登 录 登 录错误: 18456,严重性: 14,状态: 8。 用户 '&user_name&' 登录失败。[CLIENT: &IP 地 址&]如果 SQL Server 使用 Windows 身份验证模式进行安装,并随后更改为 SQL Server 和 Windows 身份验证模式,则最初禁用 sa 登录名。这会导致状态 7 错误:“用户 'sa' 登录 失败”。要启用 sa 登录名,请参阅如何更改服务器身份验证模式。 1.2.5 故障排除:在系统管理员被锁定时如何连接到 SQL Server本主题介绍作为系统管理员如何可以重新获得对 SQL Server 数据库引擎的访 问权限。系统管理员可能会由于下列原因之一失去对 SQL Server 实例的访问权 限:? ? ?作为 sysadmin 固定服务器角色成员的所有登录名都已经被误删除。 作为 sysadmin 固定服务器角色成员的所有 Windows 组都已经被误删除。 作为 sysadmin 固定服务器角色成员的登录名用于已经离开公司或者无法找到的个 人。 sa 帐户被禁用或者没有人知道密码。?可以让您重新获得访问权限的一种方法是重新安装 SQL Server 并将所有数据 库附加到新实例。这种解决方案很耗时,并且若要恢复登录名,可能还需要从备 份中还原 master 数据库。 如果 master 数据库的备份较旧,则它可能未包含所 有信息。 如果 master 数据库的备份较新,则它可能与前一个实例具有同样的登 录名;因此管理员仍将被锁定。1.2.5.1解决方法使用 -m 或 -f 选项在单用户模式下启动 SQL Server 的实例。计算机的本地 Administrators 组的任何成员都可以随后作为 sysadmin 固定服务器角色的成 员连接到 SQL Server 实例。注意: 在单用户模式下启动 SQL Server 实例时,请首先停止 SQL Server Agent 服务。否则,SQL Server 代理可能会首先连接,并阻止您作为第二个用户连接。当您将 -m 选项与 sqlcmd 或 SQL Server Management Studio 一起使用时,可 以将连接限制为指定的客户端应用程序。例如,-m&sqlcmd& 将连接限制为单个 连接并且该连接必须将自身标识为 sqlcmd 客户端程序。 当您正在单用户模式下 启动 SQL Server 并且未知的客户端应用程序正在占用这个唯一的可用连接时, 使用此选项。若要通过 Management Studio 中的查询编辑器进行连接,请使用 -m&Microsoft SQL Server Management Studio - Query&。 重要提示: 不要将此选项作为安全功能使用。 客户端应用程序提供客户端应用程序名称, 并且提供假名 称来作为连接字符串的一部分。有关如何在单用户模式下启动 SQL Server 的分步说明,请参阅如何配置服务器 启动选项(SQL Server 配置管理器)。1.3 对数据库邮件进行故障排除提供有关数据库邮件常见问题的疑难解答信息。1.3.1 数据库邮件故障排除:常规步骤数据库邮件故障排除涉及到对数据库邮件系统进行下列方面的常规检查。 这些过 程按逻辑顺序介绍,但可以按任何顺序进行评估。1.3.1.1确定是否启用了数据库邮件1. 在 SQL Server Management Studio 中,使用查询编辑器窗口连接到 SQL Server 的实例,然后执行下面的代码:复制代码sp_configure 'show advanced', 1; GO RECONFIGURE; GO sp_ GO 2. 在“结果”窗格中,确认 Database Mail XPs 的 run_value 设置为 1。 3. 如果 run_value 不为 1,将不会启用数据库邮件。数据库邮件不会自动 启用,以减少恶意用户可用来发起攻击的功能数。有关详细信息,请参阅 了解外围应用配置器。 4. 如果您确定可以启用数据库邮件,请执行下面的代码:复制代码sp_configure 'Database Mail XPs', 1; GO RECONFIGURE; GO 5. 要将 sp_configure 过程还原为不显示高级选项的默认状态, 请执行下面 的代码:复制代码sp_configure 'show advanced', 0; GO RECONFIGURE; GO1.3.1.2确定是否对用户进行了正确的配置以发送数据库邮件1. 若要发送数据库邮件,用户必须是 DatabaseMailUserRole 的成员。 sysadmin 固定服务器角色和 msdb db_owner 角色的成员将自动成为 DatabaseMailUserRole 角色的成员。若要列出 DatabaseMailUserRole 的所有其他成员,请执行以下语句:复制代码EXEC msdb.sys.sp_helprolemember 'DatabaseMailUserRole'; 2. 若要将用户添加到 DatabaseMailUserRole 角色中,请使用以下语句:复制代码sp_addrolemember @rolename = 'DatabaseMailUserRole' ,@membername = '&database user&'; 3. 若要发送数据库邮件,用户必须有权访问至少一个数据库邮件配置文件。 若要列出用户(主体)及其有权访问的配置文件,请执行以下语句:复制代码EXEC msdb.dbo.sysmail_help_principalprofile_ 4. 使用数据库邮件配置向导创建配置文件并授予用户访问这些配置文件的 权限。 1.3.1.3确定是否已启动数据库邮件1. 当有电子邮件要处理时, 将激活数据库邮件外部程序。当指定的超时期限 内没有要发送的电子邮件时,将退出该程序。若要确定是否已启动数据库 邮件激活,请执行以下语句:复制代码EXEC msdb.dbo.sysmail_help_status_ 2. 如果未启动数据库邮件激活,请执行以下语句将其启动:复制代码EXEC msdb.dbo.sysmail_start_ 3. 如果已启动数据库邮件外部程序,请使用以下语句检查邮件队列的状态:复制代码EXEC msdb.dbo.sysmail_help_queue_sp @queue_type = 'mail'; 4. 邮件队列的状态应为 RECEIVES_OCCURRING。邮件队列的状态可能会不时 发生改变。如果邮件队列的状态不是 RECEIVES_OCCURRING,请使用 sysmail_stop_sp 尝试停止队列,然后再使用 sysmail_start_sp 启动 队列。注意: 使用 sysmail_help_queue_sp 结果集中的 length 列确定邮件队列中的电子邮件数量。1.3.1.4确定数据库邮件中的问题是影响配置文件中的所有帐户, 还是只影响某些帐户1. 如果确定只有某些配置文件可以发送邮件,而不是所有配置文件都可以, 则可能是有问题的配置文件所使用的数据库邮件帐户存在问题。 若要确定 哪些帐户可以成功发送邮件,请执行以下语句:复制代码SELECT sent_account_id, sent_date FROM msdb.dbo.sysmail_ 2. 如果有问题的配置文件未使用列出的任何帐户, 那么可能是该配置文件可 以使用的所有帐户都不能正常工作。若要测试各个帐户,请使用数据库邮 件配置向导创建一个只包含一个用户的新配置文件, 然后通过“发送测试 电子邮件”对话框使用新帐户发送邮件。 3. 若要查看数据库邮件返回的错误消息,请执行以下语句:复制代码SELECT * FROM msdb.dbo.sysmail_event_注意: 当邮件被成功传递到 SMTP 邮件服务器上时,数据库邮件即认为邮件 已被发送。虽然后续错误(例如,收件人的电子邮件地址无效)仍然可 能会使邮件无法传递,但是不会包含在数据库邮件日志中。1.3.1.5配置数据库邮件以重试邮件传递1. 如果确定数据库邮件失败是由于无法可靠地到达 SMTP 服务器而导致的, 则可以通过增大数据库邮件尝试发送每封邮件的次数来增加邮件传送的 成功率。 启动数据库邮件配置向导, 然后选择“查看或更改系统参数”选 项。还可以将更多帐户与配置文件相关联,这样,当从主帐户进行故障转 移时,数据库邮件将使用故障转移帐户发送电子邮件。 2. 在“配置系统参数”页上,“帐户重试次数”的默认值为 5 次,“帐户 重试延迟时间”的默认值为 60 秒,这意味着如果在 5 分钟之内不能到 达 SMTP 服务器, 邮件传递将失败。增大这些参数可以延长邮件传递失败 之前的时间。注意: 当发送大量邮件时,虽然较大的默认值可以提高可靠性,但会显著增加资源的使用量,因为 会一遍又一遍地尝试传递大量邮件。若要从根本上解决问题,需要解决阻碍数据库邮件与 SMTP 服务器快速建立联系的网络问题或 SMTP 服务器问题。1.3.1.6安全性只有 sysadmin 固定服务器角色的成员才能对数据库邮件的所有方面进行故障 排除。 如果用户不是 sysadmin 固定服务器角色的成员, 则只能获得他们尝试发 送的电子邮件的有关信息,而不能获得其他用户发送的电子邮件的有关信息。 1.3.2 数据库邮件故障排除:发送测试电子邮件使用“发送测试电子邮件”对话框来测试使用特定配置文件发送邮件的能力。1.3.2.1 1.3.2.1.1过程 发送测试电子邮件1. 使用对象资源管理器,连接到配置了数据库邮件的 SQL Server 数据库引 擎实例,展开“管理”,右键单击“数据库邮件”,然后单击“发送测试 电子邮件”。 如果不存在数据库邮件配置文件, 将通过一个对话框提示用 户创建配置文件,同时还会打开数据库邮件配置向导。 2. 在“从 &实例名& 发送测试电子邮件”对话框中, 从“数据库邮件配置文 件”框中选择要测试的配置文件。 3. 在“收件人”框中,键入测试电子邮件收件人的电子邮件名称。 4. 在“主题”框中,键入测试电子邮件的主题行。更改默认主题,以便更好 地标识电子邮件以进行故障排除。 5. 在“正文”框中,键入测试电子邮件的正文。更改默认主题,以便更好地 标识电子邮件以进行故障排除。 6. 单击“发送测试电子邮件”,将测试电子邮件发送到数据库邮件队列。 7. 发送测试电子邮件将打开“数据库邮件测试电子邮件”对话框。请记下 “发送电子邮件”框中显示的数字。这是测试电子邮件的 mailitem_id。 单击“确定”。 8. 在工具栏上, 单击“新建查询”以打开“查询编辑器”窗口。 执行以下语 句以确定测试电子邮件的状态:复制代码SELECT * FROM msdb.dbo.sysmail_allitems WHERE mailitem_id = &the mailitem_id from the previous step& ; 9. sent_status 列将指示是否已发送测试电子邮件。 10.如果发生错误,则执行以下语句以查看错误消息:1.3.2.2权限只有 sysadmin 固定服务器角色的成员才能使用“发送测试电子邮件”对话框。 如果用户不是 sysadmin 固定服务器角色的成员, 可以使用 sp_send_dbmail 过 程来测试数据库邮件。 1.3.3 数 据 库 邮 件 故 障 排 除 : 找 不 到 存 储 过 程 “sp_send_dbmail”sp_send_dbmail 存储过程安装在 msdb 数据库中。您必须从 msdb 数据库执行 sp_send_dbmail,或为存储过程指定一个由三部分构成的名称。 使用数据库邮件配置向导启用并配置数据库邮件。1.3.4 数据库邮件故障排除:配置文件无效本主题说明如何排除报告配置文件无效的错误消息的故障。 导致出现此消息的可能原因有两个。指定的配置文件不存在,或者运行 sp_send_dbmail (Transact-SQL) 的用户没有访问配置文件的权限。 若要检查配置文件的权限,请使用配置文件名作为参数来运行存储过程 sysmail_help_principalprofile_sp (Transact-SQL)。使用存储过程 sysmail_add_principalprofile_sp (Transact-SQL) 或数据库邮件配置向导向 msdb 用户或组授予访问配置文件的权限。1.3.5 数据库邮件故障排除:拒绝了对 sp_send_dbmail 的 权限本主题介绍如何对报告尝试发送数据库邮件的用户不具有执行 sp_send_dbmail 的权限的错误消息进行故障排除。 错误文本如下:复制代码 EXECUTE permission denied on object 'sp_send_dbmail', database 'msdb', schema 'dbo'. 若要发送数据库邮件, 用户必须是 msdb 数据库中的用户, 并且是 msdb 数据库 中的 DatabaseMailUserRole 数据库角色的成员。 若要将 msdb 用户或组添加到 此角色中,请使用 SQL Server Management Studio 或对需要发送数据库邮件的 用户或角色执行以下语句。复制代码 EXEC msdb.dbo.sp_addrolemember @rolename = 'DatabaseMailUserRole' ,@membername = '&user or role name&'; GO1.3.6 数据库邮件故障排除:邮件已排队,但未传递本主题说明如何解决电子邮件已成功排队但没有传送的问题。1.3.6.1诊断问题数据库邮件外部程序在 msdb 数据库中记录电子邮件活动。 首先,要确认数据库邮件是否已启用,应使用 sp_configure 系统存储过程的 Database Mail XPs 选项。 然后在 msdb 数据库中执行下面的语句,检查邮件队列的状态:复制代码sysmail_help_queue_sp @queue_type = 'Mail' ; 有关列的详细说明,请参阅 sysmail_help_queue_sp (Transact-SQL) 中的“结 果集”部分。 检查 sysmail_event_log 视图中的活动。该视图应当包含这样一项,声明数据 库邮件外部程序已经启动。如果 sysmail_event_log 视图中没有任何项,则可 以看到“消息已排队,但 sysmail_event_log 中没有任何项”。如果 sysmail_event_log 视图中存在错误,请解决特定的错误。 如果 sysmail_event_log 视图中有一些项,请在 sysmail_allitems 视图中检 查邮件的状态。 1.3.6.1.1 “未发送”邮件状态“未发送”状态表示数据库邮件外部程序还没有处理电子邮件。 数据库邮件外部 程序可能在处理邮件方面滞后; 外部程序处理邮件的速度取决于网络条件、重试 超时、邮件量以及 SMTP 服务器的容量。如果仍然存在问题,请考虑使用多个配 置文件在多个 SMTP 服务器之间分配邮件。 检查已成功传送的邮件的最新修改日期。如果上次成功传送发生在一段时间以 前, 请检查 sysmail_event_log 视图, 验证外部程序是否由 Service Broker 成 功启动。 如果上一次尝试没有启动外部程序,请验证数据库邮件外部程序是否位 于正确目录,并且 SQL Server 服务帐户是否具有运行可执行文件的权限。注意: 若要删除旧的未发送邮件,请等待无法传送的邮件成为队列中最早的邮件,然后使用 sysmail_delete_mailitems_sp 删除它们。1.3.6.1.2 “正在重试”邮件状态正在重试的状态表示数据库邮件外部程序已经尝试将邮件传送到 SMTP 服务器, 但没有成功。这通常是由网络中断、SMTP 服务器故障或数据库邮件帐户配置不 正确导致的。邮件传送最终不是成功就是失败,并在事件日志中记录一条消息。1.3.6.1.3 “已发送”邮件状态“已发送”状态表示数据库邮件外部程序已将电子邮件成功传送给 SMTP 服务 器。 如果邮件没有抵达目标地址,说明 SMTP 服务器从数据库邮件外部程序接受 了邮件, 但未将邮件传送给最终收件人。 请检查 SMTP 服务器的日志, 或与 SMTP 服务器的管理员联系。您还可以使用另外的客户端(如 Outlook Express)来测 试 SMTP 邮件服务器。1.3.6.1.4 “失败”邮件状态“失败”状态表示数据库邮件外部程序无法将邮件传送给 SMTP 服务器。 在这种 情况下, sysmail_event_log 视图中会包含来自外部程序的详细信息。 有关用于 联接 sysmail_faileditems 和 sysmail_event_log 以检索详细的错误消息的 示例查询,请参阅如何检查使用数据库邮件发送的电子邮件的状态 (Transact-SQL)。 最常见的失败原因是目标地址不正确,或者由于网络问题而导 致外部程序无法到达一个或多个故障转移帐户。SMTP 服务器的问题也可能会导 致该服务器拒绝邮件。 可以使用数据库邮件配置向导,将“日志记录级别”更改 为“详细”,然后发送一封测试邮件来查找故障点。 1.3.7 数 据 库 邮 件 故 障 排 除 : 邮 件 已 排 队 , 但 sysmail_event_log 或 Windows 应用程序事件日志 中没有任何条目本主题说明如何解决下面的问题:电子邮件已成功排队,但 sysmail_event_log 视图或 Windows 应用程序事件日志中没有显示外部程序的任何活动。 数据库邮件使用 Service Broker 来对电子邮件进行排队。如果数据库邮件已停 止,或者尚未在 msdb 数据库中激活 Service Broker 消息传递功能,数据库邮 件将对消息进行排队,但无法传递消息。在这种情况下,Service Broker 消息 将保留在 Service Broker 邮件队列中。 由于 Service Broker 未激活外部程序, 因此 sysmail_event_log 中没有日志项,并且 sysmail_allitems 和相关视图 中的项状态也没有更新。 执行下面的语句检查数据库邮件是否已启用:复制代码 SELECT is_broker_enabled FROM sys.databases WHERE name = 'msdb'; 值为 0 表示未在 msdb 数据库中激活 Service Broker 消息传递功能。若要解 决此问题, 请在此数据库中激活 Service Broker。有关激活 Service Broker 消 息传递功能的信息,请参阅如何在数据库中激活 Service Broker 消息传递 (Transact-SQL)。 数据库邮件依赖于多个内部存储过程。为了减少外围应用,在新安装的 SQL Server 中,这些存储过程是禁用的。若要启用这些存储过程,请使用 sp_configure 系统存储过程的数据库邮件 XP 选项。 可以在 msdb 数据库中停止数据库邮件。若要检查数据库邮件的状态,请执行下 面的语句:复制代码 EXECUTE dbo.sysmail_help_status_ 若要在邮件主机数据库中启动数据库邮件,请在 msdb 数据库中运行以下命令: 复制代码 EXECUTE dbo.sysmail_start_ 激活 Service Broker 后,它将检查消息对话框生存期;因此,已处于 Service Broker 传递队列中的对话框生存期长于已配置的对话框生存期的任何消息将立 即失败。数据库邮件会在 sysmail_allitems 和相关视图中更新失败邮件的状 态。 必须决定是否再次发送电子邮件。有关配置数据库邮件使用的对话框生存期 的详细信息,请参阅 sysmail_configure_sp (Transact-SQL)。1.4 数据库镜像部署故障排除包含有关信息以帮助您解决设置数据库镜像会话时遇到的问题。 本主题提供有关信息以帮助您解决设置数据库镜像会话时遇到的问题。注意: 请确保满足所有数据库镜像的必备条件。 问题 摘要帐户介绍了正确配置运行 SQL Server 所用帐户的要求。 介绍了正确配置每个服务器实例的数据库镜像端点的要 端点 求。 概述了在数据库镜像配置中指定服务器实例的系统名称的 系统地址 备选方法。 记录了允许每个服务器实例通过 TCP 访问其他一个或多 网络访问 个服务器实例的端口的要求。 镜像数据库准备 概述了准备镜像数据库以开始镜像的要求。 失败的创建文件操作 说明如何响应失败的创建文件操作。 开始镜像 说明 ALTER DATABASE database_name SET PARTNER = (Transact-SQL) 'partner_server' 语句的要求顺序。1.4.1帐户必须正确配置运行 SQL Server 所用的帐户。1. 帐户是否具有正确的权限? 1. 如果这些帐户在相同的域帐户中运行,则会减少配置错误的几率。 2. 如果这些帐户在不同的域中运行或不属于域帐户,则必须在其他计算机的 master 中创建一个登录帐户,并且必须授予该登录帐户端点的 CONNECT 权限。有关详细信息,请参阅当数据库在其他服务器实例上可用时管理元数 据。这包括网络服务帐户。 2. 如果使用本地系统帐户将 SQL Server 作为服务运行,则必须使用证书进行身份验 证。有关详细信息,请参阅使用数据库镜像证书。1.4.2 端点必须正确配置端点。1. 确保每个服务器实例(主体服务器、镜像服务器和见证服务器,如果有的话)都有 数据库镜像端点。有关详细信息,请参阅 sys.database_mirroring_endpoints (Transact-SQL),同时根据身份验证的形式,请参阅如何创建使用 Windows 身份验 证的镜像端点 (Transact-SQL) 或如何允许数据库镜像使用证书进行出站连接 (Transact-SQL)。 2. 检查端口号是否正确。 若要标识当前与服务器实例的数据库镜像端点关联的端口,请使用以下 Transact-SQL 语句。复制代码SELECT type_desc, port FROM sys.tcp_ GO3. 对于难以解释的数据库镜像设置问题,建议您检查每个服务器实例以确定它是否正 在侦听相应的端口。有关验证端口可用性的信息,请参阅 MSSQLSERVER_1418。 4. 确保已启动端点 (STATE = STARTED)。对于各个服务器实例,使用以下 Transact-SQL 语句。复制代码SELECT state_desc FROM sys.database_mirroring_endpoints5. 有关 state_desc 列的详细信息,请参阅 sys.database_mirroring_endpoints (Transact-SQL)。 若要启动端点,请使用以下 Transact-SQL 语句。复制代码 ALTER ENDPOINT Endpoint_Mirroring STATE = STARTED AS TCP (LISTENER_PORT = &port_number&) FOR database_mirroring (ROLE = ALL); GO6. 有关详细信息,请参阅 ALTER ENDPOINT (Transact-SQL)。 7. 检查 ROLE 是否正确。对每个服务器实例使用以下 Transact-SQL 语句。复制代码SELECT role FROM sys.database_mirroring_ GO8. 有关详细信息,请参阅 sys.database_mirroring_endpoints (Transact-SQL)。 9. 确保其他服务器的登录帐户具有 CONNECT 权限。若要确定哪个登录帐户拥有对端 点的 CONNECT 权限,请对每个服务器实例使用以下 Transact-SQL 语句。复制代码SELECT 'Metadata Check'; SELECT EP.name, SP.STATE, CONVERT(nvarchar(38), suser_name(SP.grantor_principal_id)) AS GRANTOR, SP.TYPE AS PERMISSION, CONVERT(nvarchar(46),suser_name(SP.grantee_principal_id)) AS GRANTEE FROM sys.server_permissions SP , sys.endpoints EP WHERE SP.major_id = EP.endpoint_id ORDER BY Permission,grantor, GO1.4.3 系统地址对于数据库镜像配置中服务器实例的系统名称, 可以使用明确标识系统的任何名 称。服务器地址可以是系统名称(如果各系统都在同一个域中)、完全限定域名 或 IP 地址(最好是静态 IP 地址)。保证使用完全限定域名的有效性。有关详 细信息,请参阅指定服务器网络地址(数据库镜像)。 1.4.4网络访问必须允许每个服务器实例都能通过 TCP 访问其他一个或多个服务器实例的端 口。当服务器实例位于相互不信任的不同域(不可信的域)中时,这尤为重要。 这会限制服务器实例之间大部分的通信。1.4.5 镜像数据库准备无论是首次开始镜像还是在删除镜像后再次开始镜像, 都要验证镜像数据库是否 可以进行镜像。 在镜像服务器上创建镜像数据库时,请确保指定相同数据库名称 WITH NORECOVERY 来还原主体数据库备份。此外,还必须再次使用 WITH NORECOVERY 应用进行该备份之后创建的所有日志备份。 另外,我们建议,如有可能,镜像数据库的路径(包括驱动器号)应该与主体数 据库的路径相同。 如果文件布局必须互不相同 (例如, 如果主体数据库位于“F:” 驱动器上, 但镜像系统没有“F:”驱动器) , 则必须在 RESTORE 语句中加入 MOVE 选项。重要提示: 如果在创建镜像数据库时移动了数据库文件, 则可能导致以后不挂起镜像就无法向数据库添 加文件。如果数据库镜像已经停止, 则必须将对主体数据库执行的所有后续日志备份应用 到镜像数据库中,然后才可以重新启动镜像。 有关详细信息,请参阅如何为镜像准备镜像数据库 (Transact-SQL)。1.4.6 失败的创建文件操作在不影响镜像会话的情况下添加文件要求该文件路径同时存在于两个服务器上。 因此, 如果在创建镜像数据库时移动了数据库文件,则随后在镜像数据库上的添 加文件操作可能会失败,并可能会导致镜像挂起。 修复此问题:1. 数据库所有者必须删除此镜像会话,并还原包含所添加文件的文件组的完整备份。 2. 然后,所有者必须备份主体服务器上包含添加文件操作的日志,并使用 WITH NORECOVERY 和 WITH MOVE 选项在镜像数据库上手动还原此日志备份。执行此操 作可在镜像服务器上创建指定的文件路径,并将相应的新文件还原到该位置。 3. 若要准备数据库以进行新的镜像会话,数据库所有者还必须使用 WITH NO RECOVERY 选项还原主体服务器上所有其他未完成的日志备份。有关详细信息,请参阅删除数据库镜像、如何为镜像准备镜像数据库 (Transact-SQL)、如何建立使用 Windows 身份验证的数据库镜像会话 (Transact-SQL)、使用数据库镜像证书或如何配置数据库镜像会话 (SQL Server Management Studio)。1.4.7 开始镜像 (Transact-SQL)发出 ALTER DATABASE database_name SET PARTNER = 'partner_server' 语句 的顺序非常关键。1. 第一个语句必须在镜像服务器上运行。发出此语句时,镜像服务器不会尝试联系任 何其他服务器实例。相反,镜像服务器指示其数据库先进行等待,直到主体服务器 与镜像服务器建立联系。 2. 第二个 ALTER DATABASE 语句必须在主体服务器上运行。此语句使主体服务器尝试 连接到镜像服务器。创建此连接之后,镜像服务器随后将尝试通过其他连接与主体 服务器建立连接。有关详细信息,请参阅 ALTER DATABASE (Transact-SQL)。1.4.8错误消息 1418此 SQL Server 消息指示无法到达服务器网络地址或该地址不存在,同时建议您 确认网络地址名称并重新发出命令。有关详细信息,请参阅 MSSQLSERVER_1418。1.4.9 跨数据库事务在具有自动故障转移功能的高安全性模式下镜像数据库时, 自动故障转移可能会 导致自动解析并且可能错误解析有疑问的事务。 如果提交跨数据库事务时在任一 数据库中进行自动故障转移,则数据库之间可能发生逻辑上的不一致。 自动故障转移可能影响的跨数据库事务类型包括:? ?正在同一 SQL Server 实例中更新多个数据库的事务。 使用 Microsoft 分布式事务处理协调器 (MS DTC) 的事务。有关详细信息,请参阅数据库镜像和跨数据库事务。 1.5 解决事务日志已满的问题(错误 9002)讨论对已满事务日志可以采取的几种应对措施, 并就以后如何避免此问题给出建 议。 本主题讨论对已满事务日志可以采取的几种应对措施, 并就以后如何避免出现已 满事务日志给出建议。如果事务日志已满,则 SQL Server 数据库引擎会发出 9002 错误。当数据库联机或恢复时,日志可能会满。如果数据库联机时日志已 满,则数据库保持联机状态,但是只能进行读取而不能更新。如果恢复过程中日 志已满,则数据库引擎将数据库标记为 RESOURCE PENDING。不管哪种情况,都 需要用户执行操作才能使日志空间可用。1.5.1应对已满事务日志正确响应已满事务日志在某种程度上取决于导致日志已满的情况。 若要在给定情 况下查找阻止日志截断的原因,请使用 sys.database 目录视图的 log_reuse_wait 列和 log_reuse_wait_desc 列。有关详细信息,请参阅 sys.databases (Transact-SQL)。有关延迟日志截断的因素的说明,请参阅可能 延迟日志截断的因素。重要提示: 如果数据库在恢复过程中出现 9002 错误,则在解决此问题后,可使用 ALTER DATABASE database_name SET ONLINE 恢复数据库。响应已满事务日志的备选方法包括:? ? ? ? ? ?备份日志。 释放磁盘空间以便日志可以自动增长。 将日志文件移到具有足够空间的磁盘驱动器。 增加日志文件的大小。 在其他磁盘上添加日志文件。 完成或取消长时间运行的事务。下列部分介绍了这些备选方法。请选择最适用于您情况的响应。 1.5.1.1备份日志在完整恢复模式或大容量日志恢复模式下,如果最近尚未备份事务日志,则请立 即进行备份以免发生日志截断。如果从未备份日志,则必须创建两个日志备份, 以允许数据库引擎将日志截断到上次的备份点。 截断日志可释放空间以供新的日 志记录使用。若要防止日志再次填满,请经常执行日志备份。 创建事务日志备份重要提示: 如果数据库被损坏,请参阅结尾日志备份。? ? ?如何备份事务日志 (SQL Server Management Studio) 如何创建事务日志备份 (Transact-SQL) SqlBackup (SMO)1.5.1.2释放磁盘空间您可以通过删除或移动其他文件的方法来释放包含数据库事务日志文件的磁盘 驱动器上的磁盘空间。释放磁盘空间后,恢复系统将自动扩大日志文件。1.5.1.3将日志文件移至其他磁盘如果在当前包含日志文件的驱动器上无法释放足够的磁盘空间, 请考虑将该文件 移至空间充足的其他驱动器上。重要提示: 日志文件决不要放在压缩文件系统中。移动日志文件?移动数据库文件1.5.1.4增加日志文件的大小如果日志磁盘上具有可用空间, 则可以增加日志文件的大小。日志文件的最大大 小是每个日志文件 2 TB。 增加文件大小 如果禁用自动增长,数据库处于联机状态,并且磁盘上有足够的可用空间,则可 采用以下方法之一:? ?手动增加文件大小以生成单个增量。 使用 ALTER DATABASE 语句启用自动增长以针对 FILEGROWTH 选项设置非零增量。注意: 不管哪种情况,如果已达到当前大小限制,则应增加 MAXSIZE 值。1.5.1.5在其他磁盘上添加日志文件使用 ALTER DATABASE &database_name& ADD LOG FILE,向具有足够空间的其他 磁盘上的数据库中添加新日志文件。 添加日志文件? ?添加和删除数据文件和事务日志文件 (Transact-SQL) 如何向数据库中添加数据或日志文件 (SQL Server Management Studio)1.5.1.6标识和管理长时间运行的事务有关详细信息,请参阅管理长时间运行的事务。1.6 GROUP BY 错误故障排除列出 GROUP BY 错误消息并建议解决方案 下表列出了 GROUP BY 错误消息以及帮助解决错误的建议。 错误 号 错误消息 如何解决错误 重写查询,以便分组集作为显式 GROUPING SETS 列表的一部分显示在 GROUP BY 子句 中。例如,GROUP BY C1, (C2,?, Cn) 将会 引发此错误。将该查询重写为 GROUP BY C1, GROUPING SETS( ((C2,?, Cn) ) 或 GROUP102“,”附近有语法错误。 130147157 158 162 174 175 189101513 8161BY C1, (C2,?, Cn。 不能对包含聚合或子查询的 重写查询,以便分组函数聚合或子查询不会 表达式执行聚合函数。 显示为另一分组函数或聚合的参数。 聚合不应出现在 WHERE 子句 中,除非该聚合位于 HAVING 子句或选择列表所包含的子 从 WHERE 子句中删除该分组函数或聚合。 查询中, 并且要对其进行聚合 的列是外部引用。 聚合不应出现在 UPDATE 语 从 UPDATE 语句的集合列表中删除该分组函 句的集合列表中。 数或聚合。 聚合不应出现在 OUTPUT 子 从 OUTPUT 子句中删除该分组函数或聚合。 句中。 TOP 子句中的表达式无效。 从 TOP 子句中删除该分组函数或聚合。 GROUPING 函数要求有 1 个 修改 GROUPING () 函数的参数列表,以便刚 参数。 好有 1 个参数。 聚合不应出现在计算列表达 从 DDL 语句中的计算列或 CHECK 约束中删 式或检查约束中。 除该分组函数或聚合。 GROUPING_ID 函数要求有 0 将 GROUPING_ID () 函数的参数个数减少为 至 32 个参数。 32 个或更少。 聚合不能出现在 ON 子句中, 除非该子句位于 HAVING 子 句或选择列表所包含的子查 从 ON 子句中删除该分组函数或聚合。 询中, 并且所聚合的列是外部 引用。 在 GROUP BY ALL 子句中,不 重写查询,以便不使用 GROUPING SETS、 允许使用 CUBE、ROLLUP 和 CUBE、 ROLLUP、 WITH CUBE 或 WITH ROLLUP 关 GROUPING SETS 构造。 键字指定 GROUP BY ALL 选项。 位于 APPLY 右侧的聚合无法 从 APPLY 子句的右侧删除该分组函数或聚 引用左侧的列。 合。 GROUPING | GROUPING_ID 不 重写查询,以便 GROUPING () 或 是有效的开窗函数,无法与 GROUPING_ID () 函数不与 OVER 子句一起 OVER 子句一起使用。 使用。 RECEIVE 列表中不允许有聚 从 RECEIVE 列表中删除分组函数或聚合。 合。 INSERT 语句的 VALUES 列表 从 INSERT 语句的 VALUES 列表中删除该分 中不允许聚合。 组函数或聚合。 检查以确保 GROUPING 或 GROUPING_ID 函 数的每个参数均与 GROUP BY 子句中的分组 [GROUPING | GROUPING_ID] 元素相匹配,并且 GROUPING 或 函数的参数 [n] 与 GROUP GROUPING_ID 函数的所有元素的作用域均相 BY 子句中的任何表达式都不 同。 匹配。 在下例中,子查询中对表 T(来自主查询) 的引用将引发错误。复制代码 SELECT T.b, SUM(T.x) FROM T GROUP BY T.b HAVING EXISTS (SELECT 1 FROM T1 GROUP BY T1.a HAVING GROUPING_ID(T1.a, T.b) = 1 ) 无法对视图 &视图名称& 创 建聚集索引 &索引名称&,因 为索引键包含不在 GROUP BY 当视图定义包含仅含有总计元素 () 的 8661 子句中的列。 请考虑从索引键 GROUP BY 子句时,无法创建索引视图。 中消除不在 GROUP BY 子句 中的列。 无法对视图 &视图名称& 创 建聚集索引 &索引名称&,因 当视图定义包含一般 GROUP BY 子句时,无 10119 为其中包含 CUBE、 ROLLUP 或 法创建索引视图。 GROUPING SETS 运算符。请考 虑不对此视图进行索引。 WITH CUBE 和 WITH ROLLUP 重写查询,以便不存在非 ISO WITH CUBE 或 选项不允许与 ROLLUP、CUBE 10702 WITH ROLLUP 关键字与 ISO 兼容 GROUPING 或 GROUPING SETS 规范一起 SETS、CUBE 或 ROLLUP 关键字的组合。 使用。 分组集太多。最大数目为 将一般 GROUP BY 子句中分组集的个数减少 。 为 4096 个或更少。 GROUP BY 子句中指定的表达 将一般 GROUP BY 子句中的非重复分组元素 10706 式太多。当提供了分组集时, 减少为 32 个或更少。 最大数目为 32。 当前兼容模式下不允许使用 不能在 90 兼容模式下使用 CUBE () 和 CUBE() 和 ROLLUP() 分组构 10708 ROLLUP ()。 使用 WITH CUBE、 WITH ROLLUP 或 造。只有 100 或更高模式下 GROUPING SETS 语法。 才允许使用这些构造。1.7 解决数据磁盘空间不足的问题讨论如何应对数据库引擎在恢复期间磁盘空间不足以保存数据文件的情况。 在恢复过程中,SQL Server 数据库引擎可能需要更多的磁盘空间保存数据文件。 如果操作过程中没有足够的磁盘空间, 则数据库引擎会发出 1101 或 1105 错误 (分别取决于它无法为区分配空间或为对象分配空间)。如果数据库联机时磁盘 已满,则数据库保持联机状态,但是不能插入数据。如果恢复过程中磁盘已满, 则数据库引擎将数据库标记为“资源挂起”。不管哪种情况,都需要用户执行操 作才能使磁盘空间可用。1.7.1解决空间问题下列操作之一可能会将空间用于文件组:? ? ? ?释放已满磁盘上的磁盘空间。 将数据文件移到另一个磁盘。 在其他磁盘上添加文件。 启用自动增长。注意: 如果数据库恢复过程中出现错误,则必须在解决问题后恢复数据库。1.7.2 释放已满磁盘上的磁盘空间?在错误消息中提及的文件组内包含文件的磁盘上,通过删除所有不需要的索引或表 来释放磁盘空间。释放磁盘空间允许文件组中的文件增长。1.7.3 将数据文件移到另一个磁盘?请参阅移动数据库文件。1.7.4 在其他磁盘上添加文件 (Transact-SQL)?使用 ALTER DATABASE &数据库名称& ADD FILE TO FILEGROUP &文件组名&,将更多的 文件添加到其他磁盘上的文件组。注意: 有关详细信息,请参阅添加和删除数据文件和事务日志文件。 1.7.4.1.1 在其他磁盘上添加文件 (SQL Server Management Studio)?请参阅如何向数据库中添加数据或日志文件 (SQL Server Management Studio)1.7.5 增加文件大小如果禁用自动增长,数据库处于联机状态,并且磁盘上有足够的可用空间,则可 采用以下方法之一:? ?手动增加文件大小以生成单个增量。 使用 ALTER DATABASE 语句启用自动增长以针对 FILEGROWTH 选项设置非零增量。注意: 不管哪种情况,如果已达到当前大小限制,则应增加 MAXSIZE 值。1.7.5.1.1 恢复数据库如果数据库在恢复过程中用完了磁盘空间,则可使用 ALTER DATABASE &数据库 名称& SET ONLINE 恢复数据库。1.8 解决 tempdb 中磁盘空间不足的问题提供一些帮助诊断和解决 tempdb 数据库磁盘空间不足而导致问题的步骤和建 议。 本主题提供了一些步骤和建议, 可帮助您诊断和解决 tempdb 数据库中磁盘空间 不足导致的问题。如果 tempdb 中的磁盘空间用尽,可能会导致 SQL Server 生 产环境受到严重破坏,并且可能会阻止正在运行的应用程序完成操作。1.8.1tempdb 空间要求tempdb 系统数据库是可供连接到 SQL Server 实例的所有用户使用的全局资 源。tempdb 数据库用于存储下列对象:用户对象、内部对象和版本存储区。 您可以使用 sys.dm_db_file_space_usage 动态管理视图监视 tempdb 文件中 的用户对象、内部对象和版本存储区使用的磁盘空间。此外,若要在会话级或任 务级监视 tempdb 中的页分配或页释放活动,可以使用动态管理视图 sys.dm_db_session_space_usage 和 sys.dm_db_task_space_usage。这些视图 可用于标识使用大量 tempdb 磁盘空间的大型查询、临时表或表变量。1.8.2诊断 tempdb 磁盘空间问题下表列出了指示 tempdb 数据库中磁盘空间不足的错误消息。可以在 SQL Server 错误日志中找到这些错误,也可以将它们返回到任何正在运行的应用程 序。错误 引发错误的情况1101 或 67 3958 或 3966任何会话都必须分配 tempdb 中的空间。 版本存储区已满。此错误在日志中通常出现在错误 1105 或 1101 之后。 由于 tempdb 已满,版本存储区被强制收缩。 事务在 tempdb 中找不到所需的版本记录。数据库设置为自动增长且数据库大小快速增长时, 也会指示出现 tempdb 磁盘空 间问题。1.8.3 监视 tempdb 磁盘空间下列示例说明了如何确定 tempdb 中的可用空间量,以及如何确定版本存储区、 内部对象和用户对象使用的空间量。1.8.3.1确定 tempdb 中的可用空间量下面的查询将返回 tempdb 中所有文件的总可用页数和总可用空间量 (MB)。复制代码SELECT SUM(unallocated_extent_page_count) AS [free pages], (SUM(unallocated_extent_page_count)*1.0/128) AS [free space in MB] FROM sys.dm_db_file_space_1.8.3.2确定版本存储区使用的空间量下面的查询将返回 tempdb 中版本存储区使用的总页数和总空间量 (MB)。 复制代码SELECT SUM(version_store_reserved_page_count) AS [version store pages used], (SUM(version_store_reserved_page_count)*1.0/128) AS [version store space in MB] FROM sys.dm_db_file_space_1.8.3.3确定运行时间最长的事务如果版本存储区使用了 tempdb 中的大量空间,则必须确定运行时间最长的事 务。使用下面的查询可按顺序(事务的最长运行时间)列出活动事务。复制代码SELECT transaction_id FROM sys.dm_tran_active_snapshot_database_transactions ORDER BY elapsed_time_seconds DESC; 与联机索引操作无关的长时间运行的事务需要很大的版本存储区。 此版本存储区 保存自事务启动以来生成的所有版本。 联机索引生成事务可能需要较长时间才能 完成,但是使用了专用于联机索引操作的单独的版本存储区。因此,这些操作不 会防止删除其他事务的版本。 有关详细信息, 请参阅行版本控制资源的使用情况。1.8.3.4确定内部对象使用的空间量下面的查询将返回 tempdb 中内部对象使用的总页数和总空间量 (MB)。复制代码SELECT SUM(internal_object_reserved_page_count) AS [internal object pages used], (SUM(internal_object_reserved_page_count)*1.0/128) AS [internal object space in MB] FROM sys.dm_db_file_space_1.8.3.5确定用户对象使用的空间量下面的查询将返回 tempdb 中用户对象使用的总页数和总空间量。复制代码 SELECT SUM(user_object_reserved_page_count) AS [user object pages used], (SUM(user_object_reserved_page_count)*1.0/128) AS [user object space in MB] FROM sys.dm_db_file_space_1.8.3.6确定总空间量(可用空间和已用空间)下面的查询将返回 tempdb 中所有文件使用的磁盘空间总量。复制代码SELECT SUM(size)*1.0/128 AS [size in MB] FROM tempdb.sys.database_files1.8.4 监视查询使用的空间最常见的 tempdb 空间使用量问题中,有一种与使用大量空间的大型查询相关 联。通常,此空间用于内部对象,例如工作表或工作文件。虽然监视内部对象使 用的空间可以使您了解空间的使用情况,但不会直接标识出使用该空间的查询。 下列方法可帮助您标识出使用了 tempdb 中的大多数空间的查询。 第一种方法是 检查批处理级数据, 此方法比第二种方法使用的数据少。第二种方法可用于标识 占用磁盘空间的特定查询、临时表或表变量,但要获得答案必须收集更多数据。1.8.4.1方法 1:批处理级信息如果批处理请求只包含少量查询,并且其中只有一个查询是复杂查询,则此信息 通常仅能确定占用空间的批处理,而无法确定特定的查询。 若要继续使用此方法,必须通过使用大约几分钟的轮询间隔,将 SQL Server 代 理作业设置为从动态管理视图 sys.dm_db_session_space_usage 和 sys.dm_db_task_space_usage 轮询。下面的示例使用了三分钟的轮询间隔。由 于 sys.dm_db_session_space_usage 不包括当前活动任务的分配活动,因此必 须从两个视图轮询。 通过比较在两个时间间隔分配的页数之差,可以计算出在这 两个间隔之间分配的页数。 下列示例提供了 SQL Server 代理作业所需的查询。 1.8.4.1.1 A. 获取每个会话中当前运行的所有任务中的内部对象占 用的空间下面的示例创建视图 all_task_usage。执行查询后,视图将返回 tempdb 中当 前运行的所有任务中的内部对象使用的总空间量。复制代码CREATE VIEW all_task_usage AS SELECT session_id, SUM(internal_objects_alloc_page_count) AS task_internal_objects_alloc_page_count, SUM(internal_objects_dealloc_page_count) AS task_internal_objects_dealloc_page_count FROM sys.dm_db_task_space_usage GROUP BY session_ GO1.8.4.1.2 B. 获取当前会话中正在运行的任务和已完成任务的内部 对象占用的空间下面的示例创建视图 all_session_usage。 执行查询后, 视图将返回 tempdb 中 正在运行的任务和已完成任务中的所有内部对象使用的空间。复制代码CREATE VIEW all_session_usage AS SELECT R1.session_id, R1.internal_objects_alloc_page_count + R2.task_internal_objects_alloc_page_count AS session_internal_objects_alloc_page_count, R1.internal_objects_dealloc_page_count + R2.task_internal_objects_dealloc_page_count AS session_internal_objects_dealloc_page_count FROM sys.dm_db_session_space_usage AS R1 INNER JOIN all_task_usage AS R2 ON R1.session_id = R2.session_ GO 假设查询这些视图的时间间隔为三分钟,结果集将提供下列信息。 ? ?在下午 5:00 时,会话 71 自会话开始后分配了 100 页并释放了 100 页。 在下午 5:03 时,会话 71 自会话开始后分配了 20100 页并释放了 100 页。分析此信息时,您可以由这两个度量得出以下结论:会话为内部对象分配了 20,000 页,并且没有释放任何页。这指示了存在一个潜在问题。注意: 作为数据库管理员,您可以决定将轮询的时间间隔改为小于三分钟。但是,如果查询运行时 间少于三分钟,则该查询可能不会占用 tempdb 中的大量空间。若要确定在此期间运行的批处理,请使用 SQL Server 事件探查器来捕获 RPC:Completed 和 SQL:BatchCompleted 事件类。 除了使用 SQL Server Profiler 之外,还可以选择每三分钟为所有会话运行一 次 DBCC INPUTBUFFER,如下面的示例所示。复制代码DECLARE @ DECLARE @ SELECT @max = max (session_id) FROM sys.dm_exec_sessions SET @i = 51 WHILE @i &= @max BEGIN IF EXISTS (SELECT session_id FROM sys.dm_exec_sessions WHERE session_id=@i) DBCC INPUTBUFFER (@i) SET @i=@i+1 END;1.8.4.2方法 2:查询级信息有时, 仅查看输入缓冲区或 SQL Server Profiler 事件 SQL:BatchCompleted 并 不能确定哪一查询使用了 tempdb 中的大多数磁盘空间。 下列方法可用于查找此 答案,但是这些方法要收集的数据比方法 1 中定义的过程多。 若要继续使用此方法,请将 SQL Server 代理作业设置为从动态管理视图 sys.dm_db_task_space_usage 轮询。与方法 1 相比,轮询间隔应该更短(每分 钟一次)。使用这样短的间隔的原因为:如果当前未运行查询(任务),则 sys.dm_db_task_space_usage 不会返回数据。 在轮询查询中, 将动态管理视图 sys.dm_db_task_space_usage 上定义的视图与 sys.dm_exec_requests 联接在一起,以返回 sql_handle、 statement_start_offset、statement_end_offset 和 plan_handle 列。复制代码CREATE VIEW all_request_usage AS SELECT session_id, request_id, SUM(internal_objects_alloc_page_count) AS request_internal_objects_alloc_page_count, SUM(internal_objects_dealloc_page_count)AS request_internal_objects_dealloc_page_count FROM sys.dm_db_task_space_usage GROUP BY session_id, request_ GO CREATE VIEW all_query_usage AS SELECT R1.session_id, R1.request_id, R1.request_internal_objects_alloc_page_count, R1.request_internal_objects_dealloc_page_count, R2.sql_handle, R2.statement_start_offset, R2.statement_end_offset, R2.plan_handle FROM all_request_usage R1 INNER JOIN sys.dm_exec_requests R2 ON R1.session_id = R2.session_id and R1.request_id = R2.request_ GO 如果查询计划位于缓存中,则可以随时检索查询的 Transact-SQL 文本和 XML 显示计划格式的查询执行计划。 若要获得已执行查询的 Transact-SQL 文本,请 使用值 sql_handle 和动态管理函数 sys.dm_exec_sql_text。若要获得查询执 行计划,请使用值 plan_handle 和动态管理函数 sys.dm_exec_query_plan。复制代码SELECT * FROM sys.dm_exec_sql_text(@sql_handle); SELECT * FROM sys.dm_exec_query_plan(@plan_handle); 如果查询计划不在缓存中,则可以使用下列方法之一来获得查询的 Transact-SQL 文本和查询执行计划。1.8.4.2.1 A. 使用轮询方法从视图 all_query_usage 轮询,并运行下面的查询以获得查询文本: 复制代码SELECT R1.sql_handle, R2.text FROM all_query_usage AS R1 OUTER APPLY sys.dm_exec_sql_text(R1.sql_handle) AS R2; 由于 sql_handle 对每个唯一的批处理都应该是唯一的,因此不必保存重复的 sql_handle 项。 若要保存计划句柄和 XML 计划,请运行下面的查询。复制代码SELECT R1.plan_handle, R2.query_plan FROM all_query_usage AS R1 OUTER APPLY sys.dm_exec_query_plan(R1.plan_handle) AS R2;1.8.4.2.2 B. 使用 SQL Server 事件探查器事件除了轮询 sys.dm_exec_sql_text 和 sys.dm_exec_query_plan 函数之外,还 可以使用 SQL Server Profiler 事件。有一些事件探查器事件可用于捕获查询 计划和生成的查询文本。例如,事件 165 将返回跟踪、SQL 文本、查询计划和 查询统计信息的性能统计信息。1.8.5 监视临时表和表变量使用的空间可以使用一种类似于轮询查询的方法来监视临时表和临时变量使用的空间。 在临 时表或临时变量中获取大量用户数据的应用程序可能会导致 tempdb 的空间使 用问题。这些表或变量属于用户对象。可以使用动态管理视图 sys.dm_db_session_space_usage 中的 user_objects_alloc_page_count 和 user_objects_dealloc_page_count 列并按照前面介绍的方法进行操作。1.8.6监视会话的页分配和页释放下表显示了动态管理视图 sys.dm_db_file_space_usage、 sys.dm_db_session_space_usage 和 sys.dm_db_task_space_usage 返回的指 定会话的结果。 每行表示 tempdb 中一个指定会话的一次分配或释放活动。 活动 在“事件”列中列出。其他列显示动态管理视图的列中将返回的值。 对于此情况,假设开始时 tempdb 数据库的未分配区中有 872 页,用户对象保 留区中有 100 页。 会话为一个用户表分配了 10 页, 然后将它们全部释放。 前 8 页位于混合区中。其余 2 页位于统一区中。 dm_db_session_spac dm_db_session_space dm_db_file_space_us dm_db_file_space_usag e_usage 和 _usage 和 age e dm_db_task_space_ dm_db_task_space_us 事 usage age 件 unallocated_extent_p user_object_reserved_p user_object_alloc_pa user_object_dealloc_p age_count 列 age_count 列 ge_count 列 age_count 列开 872 始 从 现 有 混 合 872 区 分 配 页 1 分 配 页 2 到 8: 占 用 864 一 个 新 的 混 合 区 分 配 页 9: 占 用 856 一 个 新 的 统10000100108080108160 一 区 从 现 有 统 一 856 区 分 配 页 10 从 现 有 统 一 856 区 释 放 页 10 释 放 页 9 864 和 统 一 区 释 放 864 页 8 释 放 页 7 到 872 1, 并 在 混 合1081601081601001681001691001616 区 释 放1.9 元数据可见性故障排除讨论如何通过查看元数据来解决问题。 使用本主题可以解决查看元数据时出现的问题。 用户只能查看用户拥有的元数据或用户被授予其某些权限的元数据。 此策略阻止 拥有最低特权的用户查看 SQL Server 实例中所有对象的元数据。有关元数据可 见性的详细信息,请参阅元数据可见性配置。1.9.1允许用户查看元数据若要允许具有最低特权的用户查看所有元数据,请运行下列语句之一:?GRANT VIEW ANY DEFINITION TO此语句将覆盖实例级的元数据可见性限制。 实例中的所有元数据对 public 都将是可 见的。?GRANT VIEW DEFINITION TO此语句将覆盖数据库级的元数据可见性限制。 数据库中的所有元数据对 public 都将 是可见的。?GRANT VIEW DEFINITION ON SCHEMA :: &schema_name& TO此语句将覆盖架构级的元数据可见性限制。 架构中的所有元数据对 public 都将是可 见的。?GRANT VIEW DEFINITION ON OBJECT :: &object_name& TO此语句将覆盖对象级的元数据可见性限制。 对象的所有元数据对 public 都将是可见 的。如果对象是一个表,则表的所有列、索引、统计信息和约束对 public 都将是可 见的。此行为也适用于 GRANT VIEW DEFINITION ON ASSEMBLY 和其他类似 GRANT 语句。若要允许具有最低特权的特定用户或某个角色查看所有元数据, 请使用具体的用 户名或角色名作为被授权者,而不要使用 public。 1.9.2 允许用户彼此查看默认情况下,具有最低特权的用户无法在 sys.database_principals 和 sys.server_principals 目录视图中看到其他用户。 这意味着拥有表的最低特权 用户无法查看他们可能想要授予其权限的其他用户。 若要允许具有最低特权的用 户 user_X 查看另一个用户 user_Y,可以运行以下 GRANT 语句:?GRANT VIEW DEFINITION ON USER :: &user_Y& TO &user_X&必须为每个用户运行此语句。可以通过创建与以下触发器类似的 DDL 触发器来 自动完成此过程:复制代码CREATE TRIGGER grant_view_definition_on_principal ON DATABASE FOR CREATE_USER, CREATE_ROLE AS DECLARE @event_type sysname, @principal_name sysname, @sql nvarchar(max); SELECT @event_type = eventdata().value('(/EVENT_INSTANCE/EventType) [1]','sysname'); SELECT @principal_name = eventdata().value('(/EVENT_INSTANCE/ObjectName)[1]','sysname'); IF (@event_type = 'CREATE_USER') SELECT @sql = 'GRANT VIEW DEFINITION ON USER :: ' + @principal_name + ' TO PUBLIC ' ; ELSE SELECT @sql = 'GRANT VIEW DEFINITION ON ROLE :: ' + @principal_name + ' TO PUBLIC ' ; EXEC (@sql) ; GO1.9.3 让应用程序角色看到服务器级元数据应用程序角色无法访问其自身数据库外部的元数据, 因为应用程序角色与服务器 级主体不相关。应用程序角色可以使用下列方法查看服务器级元数据。 设置跟踪标志 若要允许应用程序角色访问服务器级元数据,请设置全局标志 4616。有关设置 跟踪标志的信息, 请参阅 DBCC TRACEON (Transact-SQL)。 有关跟踪标志 4616 的 信息,请参阅跟踪标志 (Transact-SQL)。 使用证书签名存储过程 建议使用证书签名过程访问服务器级系统表。证书签名过程具有下列优点:? ?不必使用跟踪标志。 可能公开较少的服务器级信息。基于应用程序角色的应用程序必须使用存储过程而 不是常规查询。存储过程更可能仅返回应用程序所需的特定数据。 以下示例创建证书签名存储过程,并演示应用程序角色如何使用此过程查看服务器 级元数据。?复制代码USE GO CREATE DATABASE approle_ GO CREATE LOGIN some_login WITH PASSWORD = '&enterStrongPasswordHere&'; GO USE approle_ GO CREATE USER some_user FOR LOGIN some_ GO EXEC sp_addapprole 'an_approle', '&enterStrongPasswordHere&'; GO ---------------------------------------------------------------------- This section shows how to use a certificate to authenticate -- a signed procedure. --------------------------------------------------------------------CREATE LOGIN execute_as_login WITH PASSWORD = '&enterStrongPasswordHere&'; GO USE GO GRANT VIEW ANY DEFINITION TO execute_as_ GRANT VIEW SERVER STATE TO execute_as_ GO USE approle_ GO CREATE USER execute_as_user FOR LOGIN execute_as_ GO --- You must use EXECUTE AS 'authenticator' here because the application role -- does not have a server identity. Therefore, the application role cannot use -- the certificate permissions on the server. Therefore, you -- need a new execution context to which you can grant -- the needed VIEW* permissions. -CREATE PROC access_server_system_tables WITH EXECUTE AS 'execute_as_user' AS SELECT sid, status, name, dbname, hasaccess, loginname FROM master.dbo. SELECT spid, kpid, lastwaittype, waitresource, dbid FROM master.dbo. GO GRANT EXECUTE ON access_server_system_tables TO an_ GO CREATE CERTIFICATE signing_cert ENCRYPTION BY PASSWORD = '&enterStrongPasswordHere&' WITH SUBJECT = 'Signing Cert'; GO BACKUP CERTIFICATE signing_cert TO FILE = 'signing_cert.cer'; GO ADD SIGNATURE TO access_server_system_tables BY CERTIFICATE signing_cert WITH PASSWORD = '&enterStrongPasswordHere&'; GO ---------------------------------------------------------------------- Create a copy of the signing certificate in the target -- database. In this case, the target database is the master database. -- This copy of the signing certificate vouches for the execution context -- that enters this database from the signed procedure. --------------------------------------------------------------------USE GO CREATE CERTIFICATE signing_cert FROM FILE = 'signing_cert.cer'; GO ---------------------------------------------------------------------- Because the VIEW permissions in question are server-level permissions, -- we need to grant AUTHENTICATE SERVER permission on a login-mapped certificate. --------------------------------------------------------------------CREATE LOGIN signing_cert_login FROM CERTIFICATE signing_ GO GRANT AUTHENTICATE SERVER TO signing_cert_login GO ---------------------------------------------------------------------- Now you can open a new connection as &some_login& and -- set the application role. Then, call the &access_server_system_tables& -- procedure, and obtain verification that you can access server-level information -- when the application role-based application runs. -- For an example, see the Demo usage.sql code below. ------------------------------------------------------------------------------------------------------------------------------------------ Clean up. -- The following statements remove the objects created above. --------------------------------------------------------------------USE master GO DROP DATABASE approle_ DROP LOGIN some_ GO DROP LOGIN execute_as_ GO DROP LOGIN signing_cert_ GO DROP CERTIFICATE signing_ GO --- Delete the certificate file. -EXEC sp_configure 'show advanced options', 1; GO RECONFIGURE; GO EXEC sp_configure 'xp_cmdshell', 1; GO RECONFIGURE; GO EXEC xp_cmdshell 'del &C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Data\signing_cert.cer&'; GO EXEC sp_configure 'xp_cmdshell', 0; GO RECONFIGURE; GO -===================================================================== ======= -- - Application role access to server information - Demo usage.sql --- This code is companion code that shows an example of application role access -- to server information by using a certificate-signed procedure. --===================================================================== ======= -- --------------------------------------------------- Connect as some_login first. -- -----------------------------------------------USE approle_ GO EXEC sp_setapprole 'an_approle', '&enterStrongPasswordHere&'; GO -- Display the server-level information the application role can currently view. SELECT sid, status, name, dbname, hasaccess, loginname FROM master.dbo. SELECT spid, kpid, lastwaittype, waitresource, dbid FROM master.dbo. GO -- Display the server-level information the application role -- can view by running the certificate-signed stored procedure. EXEC access_server_system_ GO1.10 孤立用户故障排除说明如何检测和解决数据库用户的 SQL Server 登录未定义或在服务器实例中错 误定义(创建孤立用户)的情况。 要登录到 Microsoft SQL Server 的实例,主体必须有一个有效的 SQL Server 登录名。 在身份验证过程中会使用此登录名,以验证是否允许主体连接到该 SQL Server 实例。可在 sys.server_principals 目录视图和 sys.syslogins 兼容 性视图中查看服务器实例上的 SQL Server 登录名。 SQL Server 登录名使用映射到 SQL Server 登录名的数据库用户访问各个数据 库。此规则有两种例外情况:?guest 帐户。 这个帐户在数据库中启用后, 能够使未映射到数据库用户的 SQL Server 登录名作为 guest 用户进入数据库。?Microsoft Windows 组成员身份。 如果某 Windows 用户是 Windows 组的成员,并且此组也是数据库中的用户,则 基于该 Windows 用户创建的 SQL Server 登录名可以进入数据库。有关 SQL Server 登录名与数据库用户的映射关系的信息存储在数据库中。其中 包括数据库用户的名称以及对应 SQL Server 登录名的 SID。该数据库用户的权 限用于在数据库中进行授权。 在服务器实例上未定义或错误定义了其相应 SQL Server 登录名的数据库用户 无法登录到实例。这样的用户被称为此服务器实例上的数据库的“孤立用户”。 如果删除了对应的 SQL Server 登录名,则数据库用户可能会变为孤立用户。另 外,在数据库还原或附加到 SQL Server 的其他实例之后,数据库用户也可能变 为孤立用户。 如果未在新服务器实例中提供数据库用户映射到的 SID,则该用户 可能变为孤立用户。注意: 如果 SQL Server 登录名在某个数据库中没有对应的数据库用户,则除非该数据库中启用了 guest ,否则,该登录名将无法访问该数据库。有关创建数据库用户帐户的信息,请参阅 CREATE USER (Transact-SQL)。1.10.1检测孤立用户若要检测孤立用户,请执行下列 Transact-SQL 语句:复制代码USE &database_name&; GO; sp_change_users_login @Action='Report'; GO; 输出中列出了当前数据库中未链接到任何 SQL Server 登录名的用户以及对应 的安全标识符 (SID)。有关详细信息,请参阅 sp_change_users_login (Transact-SQL)。 注意: sp_change_users_login 不能与从 Windows 中创建的 SQL Server 登录名一起使用。1.10.2 解决孤立用户问题若要解决孤立用户问题,请执

我要回帖

更多关于 petal.exe是什么进程 的文章

 

随机推荐