我的公司目前正在运行 SQL Server 2000,并且即将跳转到 SQL Server 2012,但在我们进行升级之前,我们想尝试解决最近出现并困扰我们开展业务能力的性能问题.
几个月前,我们决定向我们的一个 sql server 表添加一个文本字段,以尝试捕获特定事件。我想我会在白天尝试添加该列,回想起来这可能是第一个错误,但我认为如果人们使用该表,SQL Server 将不允许我添加该列。在此尝试中,额外的列被接受并添加到表中。然后我编写了我们的 Access 前端以写入这个新列。
不久之后,用户开始体验 Access GUI “锁定”,并最终引发查询超时错误。
这是错误发生的方式。单击 Access 前端中的保存按钮后,将在 VBA 中构建 T-SQL 语句以更新或保存新记录,用户将不会看到显示保存成功或发生错误的 Access 消息框. 相反,他们会得到一个 Access 系统对话框,显示查询超时。此时我删除了我添加的列,希望能解决问题。
我通过让每个人关闭他们的 Access 程序开始分析,然后让遇到问题的人重新打开并再次尝试保存。这适用于该用户,此时我将允许其他所有人重新进入系统。当然,当时我不确定为什么这会奏效,所以我尝试更多地研究这个问题。进一步的分析使我找到了 sp_who2。运行它会给我所有的用户和谁被阻止的 SPID。这给了我一个更快的方法让事情重新开始,因为我可以杀死有问题的 SPID 并允许其他人继续工作。当然,杀死会导致回滚,因此并非所有数据都被保存,我必须告诉被杀死进程的所有者,他们必须再次重新输入所有数据。到目前为止,我一直以这种方式监控这个数据库,如果我发现有什么被阻塞的,
我知道问题出在这个数据库中的一个表上,首先是因为只有在我尝试输入新列之后才会出现问题,而且还因为每次执行保存或更新时,它都会在写入这个特定表时锁定。当时,我诊断出这种情况是因为我询问了我的用户他们试图执行什么操作,并且在所有情况下,他们都试图对这个特定的表做些什么。事实上,对同一个 Db 中其他表的更改执行没有问题。所以我觉得这个问题可能与这张表的损坏有关。
我做的第一件事是运行 CHECKDB 和 CHECKTABLE,但是这些都没有返回表的问题。所以我们决定重建表。我手动重建了表,然后将数据从原始表复制到新表。我相信我为此使用了一个 sql 工具,但我可能已经运行了一个插入操作。(已经有一段时间了,我没有记录。)无论哪种方式,它都不起作用。该组织继续遭遇封锁。然后我重新索引了表,这似乎工作了大约一天,然后错误“回来了”。从那以后我发现了 INPUTBUFFER,我每次都在阻塞用户的 SPID 上运行一段时间。几乎每次,INPUTBUFFER 都会返回一个 SELECT 语句,尽管我认为这不是抛出块的原因。我不认为 SELECT 正在抛出块,因为在 Access GUI 中发生的事情是您点击保存按钮,它运行保存或更新,然后运行选择以刷新 Access 屏幕。我认为如果 SELECT 抛出了保存会发生的块,但是在进程开始阻塞后调用记录并且进程被终止时,用户更改永远不会保存到记录中。我不完全确定 INPUTBUFFER 是如何工作的。我知道它应该返回发送到 SQL Server 的最后一条语句,但是如果保存没有提交,Access 是否仍然可以将 SQL 发送到 SQL Server?但是在进程开始阻塞后调用记录并且进程被终止时,用户更改永远不会保存到记录中。我不完全确定 INPUTBUFFER 是如何工作的。我知道它应该返回发送到 SQL Server 的最后一条语句,但是如果保存没有提交,Access 是否仍然可以将 SQL 发送到 SQL Server?但是在进程开始阻塞后调用记录并且进程被终止时,用户更改永远不会保存到记录中。我不完全确定 INPUTBUFFER 是如何工作的。我知道它应该返回发送到 SQL Server 的最后一条语句,但是如果保存没有提交,Access 是否仍然可以将 SQL 发送到 SQL Server?
我还要补充一点,当我在 SQL Server Management Studio 本身中工作时,我似乎从来没有遇到过障碍。我显然已经感受到了现有块的影响,它会挂起我的 sql 语句,但我从来没有抛出一个块据我所知。为此,我还将每个用户的 ODBC 连接器更新为 10.0。这似乎对这个问题没有负面或正面的影响。
所以我不确定下一步该怎么做。任何建议,将不胜感激。