SQL Server 2016 R Services:sp_execute_external_script 返回 0x80004005 错误

Posted

技术标签:

【中文标题】SQL Server 2016 R Services:sp_execute_external_script 返回 0x80004005 错误【英文标题】:SQL Server 2016 R Services: sp_execute_external_script returns 0x80004005 error 【发布时间】:2016-05-28 13:53:43 【问题描述】:

我在查询100M记录后运行了一些R代码,进程运行超过6小时后出现以下错误:

Msg 39004, Level 16, State 19, Line 300
A 'R' script error occurred during execution of 'sp_execute_external_script'     
with HRESULT 0x80004005.

HRESULT 0x80004005 在 Windows 中似乎与连接、权限或“未指定”错误相关联。

我通过登录我的 R 代码知道该进程根本不会到达 R 脚本。我还知道整个过程在 4 分钟后完成,记录数量较少,例如 1M。这让我相信这是一个缩放问题或数据的一些问题,而不是我的 R 代码中的错误。由于专有原因,我没有包含 R 代码或完整查询。

但是,如果出现这种情况,我预计磁盘或内存错误会显示 0x80004004 Out of memory 错误。

我在 SQL ERRORLOG 中注意到的一条线索如下:

SQL Server received abort message and abort execution for major error : 18 
and minor error : 42

然而,这个日志行的时间与进程的中断并不重合,尽管它确实发生在它开始之后。不幸的是,网上关于“重大错误 18”的信息很少。

从 SSMS 运行时的 SQL 跟踪显示客户端每 6 分钟左右登录和注销一次,但我只能假设这是正常的保活行为。

经过净化的 sp_execute_external_script 调用:

      EXEC sp_execute_external_script
                    @language = N'R'
                  , @script = N'#We never get here
                                #returns name of output data file'
                  , @input_data_1 = N'SELECT TOP 100000000 FROM DATA'   
                  , @input_data_1_name = N'x'
                  , @output_data_1_name = N'output_file_df'
                  WITH RESULT SETS ((output_file varchar(100) not null))

服务器规格: 8核 256 GB 内存 SQL Server 2016 CTP 3

任何想法、建议或调试提示将不胜感激!

更新: 在 rlauncher.config 中设置 TRACE_LEVEL=3 以打开更高级别的日志记录并重新运行该过程。日志显示了一个清理进程,该进程在 6.5 小时后整个进程失败时运行,删除了会话文件。

[2016-05-30 01:35:34.419][00002070][00001EC4][Info] SQLSatellite_LaunchSatellite(1, A187BC64-C349-410B-861E-BFDC714C8017, 1, 49232, nullptr) 完成:00000000

[2016-05-30 01:35:34.420][00002070][00001EC4][信息]

[2016-05-30 08:04:02.443][00002070][00001EC4][Info] > SQLSatellite_LauncherCleanUp,dllmain.cpp,309

[2016-05-30 08:04:07.443][00002070][00001EC4][警告] 会话 A187BC64-C349-410B-861E-BFDC714C8017 清理等待失败,出现 258 和错误 0

[2016-05-30 08:04:07.444][00002070][00001EC4][Info] Session(A187BC64-C349-410B-861E-BFDC714C8017) 记录了 2 个输出文件

[2016-05-30 08:04:07.444][00002070][00001EC4][警告] TryDeleteSingleFile(C:\PROGRA~1\MICROS~1\MSSQL1~1.MSS\MSSQL\EXTENS~1\MSSQLSERVER06 \A187BC64-C349-410B-861E-BFDC714C8017\Rscript1878455a2528) 失败,32

[2016-05-30 08:04:07.445][00002070][00001EC4][警告] TryDeleteSingleDirectory(C:\PROGRA~1\MICROS~1\MSSQL1~1.MSS\MSSQL\EXTENS~1\MSSQLSERVER06 \A187BC64-C349-410B-861E-BFDC714C8017) 失败,32

[2016-05-30 08:04:08.446][00002070][00001EC4][Info] 会话 A187BC64-C349-410B-861E-BFDC714C8017 从 MSSQLSERVER06 用户中删除

[2016-05-30 08:04:08.447][00002070][00001EC4][Info] SQLSatellite_LauncherCleanUp(A187BC64-C349-410B-861E-BFDC714C8017) 完成:00000000

看来,让我的长期运行进程继续下去的唯一方法是: a) 延长作业清理等待时间以允许作业完成 b) 禁用作业清理进程

到目前为止,我一直无法在 MSSQLLaunchpad 服务中找到设置作业清理等待时间的值。 虽然 rlauncher.config 中存在 JOB_CLEANUP_ON_EXIT 标志,但将其设置为 0 无效。该服务似乎在重新启动时将其重置为 1。

再次感谢任何建议或帮助!

【问题讨论】:

【参考方案1】:

默认情况下,SQL Server 在开始执行 R 脚本之前将所有数据作为数据帧读入 R 内存。基于脚本使用 1M 行并且无法从 100M 行开始这一事实,这可能是内存不足错误。要解决内存问题(除了增加机器内存/减少数据大小),您可以尝试其中一种解决方案

    使用sys.resource_governor_external_resource_pools max_memory_percent 设置增加R 进程执行的内存分配。默认情况下,SQL Server 将 R 进程执行限制为内存的 20%。 Streaming execution for R script 而不是将所有数据加载到内存中。请注意,此参数只能在 R 脚本的输出不依赖于读取或查看整组行的情况下使用。

RLauncher.log 中关于数据清理的警告发生在 R 脚本执行之后可以安全地忽略,并且可能不是您所看到的失败的根本原因。

【讨论】:

感谢您的回复,但我不同意。内存不足错误将返回 0x80004004 错误“无法分配或重新分配内存”。我还有 256 GB 的内存,数据只有 11 GB。我已经授予 R 50% 的可用内存。流式执行是不可能的,因为我需要整个集合的手段。执行 6.5 小时后的清理错误与脚本失败完全一致。【参考方案2】:

无法在 SQL 中解决此问题,我只是避免使用 SQL Server Launchpad 服务中断处理,并使用 R RODBC 库从 SQL 中提取数据。拉取只用了 3 个多小时(而不是使用 sp_execute_external_procedure 的 6+)。

这可能与 SQL Launchpad 服务有关,并表明内存不是问题。

【讨论】:

【参考方案3】:

请在 SQL Server 2016 RTM 中尝试您的方案。自 CTP3 以来,已经进行了许多功能和性能修复。

有关如何获取 SQL Server 2016 RTM 结帐SQL Server 2016 is generally available today 博文的更多信息。

【讨论】:

谢谢,我试试看。如果它解决了问题,我仍然需要至少 6.5 小时才能将数据提取到 R 中。使用 RODBC 包,我在 2 中做了同样的事情。【参考方案4】:

我在使用 SQL Server 2016 RTM-CU1 时遇到了几乎相同的问题。我的查询失败,错误为 0x80004004 而不是 0x80004005。它从 10,000,000 条记录开始就失败了,但这可能与只有 16 GB 的内存和/或不同的数据有关。

我通过使用字段列表而不是“*”来解决它。即使字段列表包含数据源中的所有字段(在我的例子中是一个相当复杂的视图),具有字段列表的查询总是成功的,而“SELECT TOP x * FROM ...”对于一些大的 x 总是失败.

【讨论】:

【参考方案5】:

我遇到了类似的错误(0x80004004),问题是其中一列中的一行包含“非常”特殊字符(我说“非常”是因为其他特殊字符没有导致此错误)。

因此,当我将 'Folkelånet Telefinans' 替换为 'Folkelanet Telefinans' 时,问题就消失了。

在您的情况下,最后 99M 行中的至少一个值可能包含类似该字符的内容,您只需替换它即可。我希望微软能在某个时候解决这个问题。

【讨论】:

以上是关于SQL Server 2016 R Services:sp_execute_external_script 返回 0x80004005 错误的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server R 多个结果集

我的 R 代码没有从 SQL Server 获取数据

如何使用 R 向 SQL Server 表中插入数据?

无法在 R 中使用 sqlSave 追加到 SQL Server 表

我装sql server2016失败了, 现在想安装2014版,需要先将2016卸载吗

SQL Server 2016 存储过程中的串联 OPENJSON