设置:
- 视窗服务器 2008 R2
- SQL Server 2008 R2 SP1
- 240GB 内存
- TempDB 是 8x16GB 数据文件,没有自动增长(总共 128GB)
- 物理/独立服务器
此服务器用于 ETL 处理。我们刚刚在此服务器中安装了更多 RAM,总共 240GB RAM。SQL Server 服务是唯一运行的真实事物。
内存在 BIOS、OpenManage 和 Windows 中显示良好。
如果我将 SQL Server 配置为使用最小/最大 70/100GB 内存,我们就没有问题。但是,一旦我将其增加到 120/150GB,当我运行我们的 ETL 进程之一时,我会收到以下错误:
无法为数据库“tempdb”中的对象“<临时系统对象:422234507706368>”分配空间,因为“PRIMARY”文件组已满。通过删除不需要的文件、删除文件组中的对象、向文件组添加其他文件或为文件组中的现有文件设置自动增长来创建磁盘空间。(消息 1105,状态 2,过程未知,第 1 行)
在更改内存配置之前,我们从未遇到过这个问题。重新配置回原来的 70/100GB 后,我们没有收到此错误。
我尝试过的事情:
- 将 TempDB 数据文件设置为自动增长。这只会导致文件自动增长,直到达到磁盘容量然后失败。
- 添加更多 TempDB 数据文件。如图所示的相同错误。
- 将 TempDB 大小增加到 8x32GB(总共 256GB)
我不知道是什么导致了这个问题。
感谢大家的帮助。
在遍历了一些执行计划之后,事实证明有一个 JOIN 正在根据可用的 RAM 量进行不同的处理。使用更少的 RAM,它会使用 Hash 对其进行评估;使用更多 RAM,它使用一系列合并连接。
所以基本上它归结为写得不好的 T-SQL,我目前正在重构它。
这不是问题的答案,只是我不想在评论中发布的一些代码。要查看跨 NUMA 节点的调度程序和内存的平衡(以及查看是否有任何节点在线不可见):
(在 SQL Server 2012 中,最后一个
SUM
应该是SUM(pages_kb)
,因为不再有单独的单页和多页分配器。)