是对TempDB的写入始终导致对磁盘的实际物理写入,还是由SQL Server缓存TempDB的写入以像Windows文件系统缓存一样延迟写入?
他们总是吗?绝对不是。他们曾经吗?是的,但不是典型机制的结果。这里参考的是checkpoint对tempdb有什么作用?。
在“行为良好”的系统中,对用户数据库文件的写操作发生在检查点上。在行为不佳的系统中,当惰性写入器需要从缓冲池中刷新页面以为其他页面腾出空间时,也会发生写操作。
仅当tempdb日志文件已满70%时,才为tempdb执行一个检查点-这是为了尽可能防止tempdb日志增长(请注意,长时间运行的事务本质上仍可以保留日志人质并防止其清除,就像在用户数据库中一样)。
但是,无需将tempdb刷新到磁盘,因为崩溃恢复永远不会在tempdb上运行,它总是在启动时重新创建。
崩溃时不会恢复Tempdb,因此不需要将脏的tempdb页面强制到磁盘,除非在惰性写入器进程(缓冲池的一部分)必须为其他数据库的页面腾出空间的情况下。
值得注意的是(这让我感到惊讶)是将tempdb页面写入磁盘的唯一机制。如果存在缓冲池压力,则可以将tempdb页面刷新到磁盘。如果没有,则不应发生。
编辑:对于正在编写检查点之外的页面的用户数据库,是否恰当地描述“行为不良”是否值得商bat。可能是异常,非典型或不理想?
附加编辑(在@PaulWhite后面进行评论/聊天):
上面明显的遗漏是临时表不是tempdb通信的唯一来源。引用了解哈希,排序和交换溢出事件:
通过使用(某种)大量的内存作为中间存储,对某些SQL Server查询执行操作进行了校准,以使其表现最佳。查询优化器将使用这些内存暂存器根据这些运算符选择一个计划并估算成本。但这当然只是一个估计。在执行时,估计可能证明是错误的,并且尽管没有足够的内存,该计划也必须继续。在这种情况下,这些运算符会溢出到磁盘上。
我错误地认为,对溢出操作进行物理写操作的机制与前面所述完全相同,即,由于缓冲池上的压力(由溢出引起),惰性写入器将tempdb页面强制到磁盘。
@PaulWhite解释了我错了的地方(感谢Paul!):
我想您是在问为什么查询超出其工作空间内存授予量时会发生物理tempdb活动,而不是仅使用tempdb-in-memory如果这样做,查询将使用比其授予量更多的内存,从而无法达到限制内存的目的首先授予。
从写到存储,泄漏确实很特殊。即使在大量空闲内存和tempdb压力为零的情况下,也可以看到tempdb的物理活动。
保罗还向我指出了他的博客文章“ 高级TSQL调优:为什么要了解内部知识”,其中包括一些示例脚本,用于向希望深入研究的人员演示溢出。