运行以下命令时经常收到此错误
sp_whoisactive @get_locks = 1
消息 6841,级别 16,状态 1,过程 sp_WhoIsActive,第 4287 行 FOR XML 无法序列化节点“Lock/@resource_description”的数据,因为它包含 XML 中不允许的字符 (0x0001)。要使用 FOR XML 检索此数据,请将其转换为二进制、varbinary 或图像数据类型并使用 BINARY BASE64 指令。警告:空值被聚合或其他 SET 操作消除。
我相信这与抓取所持有的锁的 xml 有关,但是我注意到它在发生阻塞时经常发生。有什么办法可以解决这个问题还是一个已知问题?运行 SQL Server 2012 和最新版本 v11.32 的sp_whoisactive。
编辑
按照建议的选项,我无法找到这些数据。我主要是在服务器阻塞时遇到该消息,一旦遇到该消息,我会关闭参数并尝试查看它可能来自哪个对象,但这很困难,因为有很多线程在运行。有没有更简单的方法呢?我最初认为它不是数据而是对象名称,因为当我看到锁 xml 它通常只包含对象名称时,我没有意识到实际数据被放入其中可能导致此消息?
编辑 2
根据 Erik 的建议,我能够使用 SOH 字符输出#locks 表的结果来追踪对象。然而最终我发现最有用的是使用 get_task_info = 2 和 get_additional_info = 1 的变通方法,在运行这些参数时,我没有收到错误消息,但仍然收到我需要的信息。我仍将探索尝试将该字符添加到 sp_whoisactive 中的替换语句中,以便在需要查看完整 XML 的情况下仍然可以使用 get_locks 参数。
我无法完全回答您关于哪个对象导致问题的问题,但我可以为您提供一些故障排除和可能的解决方法。
请注意,由于其许可,我无法将“固定”脚本分发给您,但您可以自由地在本地尝试编辑。
故障排除
如果你 ctrl+f 通过 sp_WhoIsActive for
@get_locks = 1
,你会点击这个代码部分:再往下一点,您会看到一个相当复杂的选择插入到一个名为 的表中
#locks
:如果您向下滚动到第 1670 行左右(假设您在 SSMS 中启用了行号),您将到达
SELECT INTO
填充它的末尾。您可以尝试SELECT * FROM #locks;
在此处添加一个简单的内容,以查看表格中的内容。这至少可以潜在地将您指向正确的对象。解决方法
在不更改任何代码的情况下,一种解决方法可能是像这样运行该过程:
此处记录了这些参数的用途。
如果这不能正常运行,那么您将被困在 ctrl+f for
FETCH NEXT FROM locks_cursor
. 这会将您带到弹出错误的代码部分。在这个游标代码块中,您将找到一个动态查询、一个 catch 块和一个带有嵌套
REPLACE
块的更新,以清除坏字符(除了您的,它会出现)。我相信你必须REPLACE
在所有这些中添加一个额外的嵌套NCHAR(0x0001)
,以便修复它。我没有测试过这个,所以YMMV。希望这可以帮助!