SELECT 查询的 TempDB GAM 争用

Sra*_*nda 3 tempdb sql-server-2019

我有以下问题,我的 TempDB 知识还没有涵盖这一点:

  • 在 SSMS 中运行约 200 毫秒的分析查询,从应用程序启动时在 SQL Server 上继续运行 60 秒以上 - 这种情况只是偶尔发生,大多数时候问题并不存在
  • 可运行/挂起查询的队列可能会增长到同一查询文本的数十个查询,其中一个 SELECT 查询是阻止其他相同 SELECT 的头阻塞程序
  • 当可运行/挂起队列与基线相比开始显着增长时,对于相同文本和参数值的特定查询,最主要的等待是 SOS_SCHEDULER_YIELD 和 PAGELATCH_UP
  • 当问题发生时,排队的数十个查询具有相同的文字参数值(轮班开始时间戳、员工 ID 和生产区域)
  • 被挂起的查询(在我们的监控快照期间 - DBA Dash)将 PAGELATCH_UP 等待作为最主要的等待,并且它们正在等待 tempdb 中的 GAM 页面
  • 当我使用在可运行/挂起队列中不断堆积的查询参数检查 SSMS 中的执行计划时,查询不会溢出到 tempdb

服务器、数据库和数据库流量的配置:

  • 4 到 6 个核心(问题独立发生在具有不同核心数的两台不同服务器上)
  • 4 - 6 个大小统一的 TempDB 文件
  • 分配给实例的 40GB RAM
  • 在特定数据库中,启用了 RCSI + 快照(因此 TempDB 受到攻击)
  • 运行查询的两个表上没有发生删除,只有 INSERT 和 SELECT - 当时仅插入 1 行
  • SELECT 通常会命中最年轻的记录(最近插入的记录)
  • 服务器通常每秒处理 400 - 700 个批量请求;当问题出现时,与正常操作相比,它会达到峰值 1500,从而产生较高的 IO + CPU 负载
  • 表中的数据或多或少具有均匀分布,即特定生产区域的无班次中没有员工 ID 的记录明显多于其他员工
  • 所附屏幕截图是一张表格,显示了问题完全显现时 DBA Dash 的快照
  • tempDB,尽管 RCSI+ 快照增长不多,但在 60GB 驱动器上只有几 GB(稳定状态持续了几个月,并且在我在这里描述的几集之后)
  • 屏幕截图中的所有 SELECT 查询都有 PAGELATCH_UP 等待,其中大约一半具有以下附加信息:
    • 等待资源类型:PAGE
    • 等待资源:2:3:2(我认为含义是:tempdb数据库,tempdb中的第三个文件,我们正在等待的第二页)
    • 等待文件:主| 温度2
    • 页面类型:GAM
    • 等待编译:False

除了明显努力找到根本原因并永久解决它之外,我的主要问题是:

  • 为什么 SELECT 查询可以大量访问 tempdb 中的 GAM 页面?
  • 如果我承认 SELECT 可以频繁接触 GAM 页面,那么什么可以阻止查询(头拦截器)进行(即读取 GAM 页面并使其立即可供其他人使用)?

任何相关学习资源/建议的指针将不胜感激

查询计划在这里

DBADash 运行查询快照

编辑:为了回答约翰的评论,我想添加以下内容:

  • CTFP:30
  • MAXDOP:4(为两台 SQL 服务器设置,其中一个有 6 个核心,另一个有 4 个)
  • 每个 SQL VM 有 2 个实例 - 发生问题的实例,然后是其他“办公室”实例,这对 SQL Server VM 造成的负载可以忽略不计
  • 表格

ManualPanelEntries:6933089 条记录,1221 MB 数据,2591 MB 索引 - 事实上,索引比数据本身消耗更多空间

权重:3108486条记录,178MB数据,170MB索引

  • 整个数据库:125GB

============

写完这篇文章后我发现,头阻止程序(许多并行的相同 SELECT 之一)也在等待 GAM,即特定 tempdb 文件的第二页。就好像其他东西(版本存储?)在特定的 GAM 页面上持有锁定,阻止使用 TempDB 的其他查询继续进行。

Pau*_*ite 8

减少 SQL Server tempdb 数据库中的分配争用的建议中的文档涵盖了问题的核心。您正在运行 SQL Server 2019,这意味着您将在 GAM 页面而不是 SGAM 上看到争用。

您的排序和散列操作可能不会溢出(尽管屏幕截图中的几个查询确实显示了写入),但 SQL Server 仍然必须分配结构(工作文件和工作表)来支持排序和散列,其中一些是必需的,以防出现运行时溢出。如果您足够快地执行足够多的这些操作,您可以看到 GAM 页锁存争用。

锁存器等待通常很短,但有可能遇到锁存器队列,有时会导致(很)长的等待。

如上面链接的文档中所述,主要解决方案是将文件添加到tempdb,直到争用消失或降低到可接受的水平。

可能与此处的具体问题无关,您还可以选择在 SQL Server 2019 中为tempdb启用内存优化元数据。该选项并非没有缺点,并且存在一些错误。

SQL Server 2022 引入了并发GAM 和 SGAM 更新,这用(共享)UP闩锁取代了(更新)SH闩锁。这大大减少了此类问题的范围。