我目前正在查询sys.dm_db_log_info()
DMV 以从数据库中检索 VLF,以确定何时可以缩小、重组和减少 TLOG 文件中的碎片(10 MB VLF)数量。
这样做的原因是,如果事务位于 TLOG 文件的末尾并导致活动的 VLF,则无法缩小 TLOG 文件。类似的情况,如果一个活动事务位于 TLOG 文件的中间,那么您不能缩小到该 VLF。
当前声明
我目前有这个语句来检索MAX(vlf_begin_offset)
记录、MIN(vlf_begin_offset)
记录和任何具有活动的记录vlf_active = 1
:
SELECT ddli.vlf_begin_offset,
ddli.vlf_sequence_number,
ddli.vlf_active,
ddli.vlf_status,
ddli.vlf_first_lsn
FROM sys.dm_db_log_info(DB_ID()) AS ddli
WHERE ddli.vlf_begin_offset = (
SELECT MIN(ddli2.vlf_begin_offset)
FROM sys.dm_db_log_info(DB_ID()) AS ddli2
)
OR ddli.vlf_active = 1
OR ddli.vlf_begin_offset = (
SELECT MAX(ddli3.vlf_begin_offset)
FROM sys.dm_db_log_info(DB_ID()) AS ddli3
)
ORDER BY
ddli.vlf_begin_offset ASC
返回所有记录后,结果集如下所示:
+------------------+---------------------+------------+------------+------------------------+
| vlf_begin_offset | vlf_sequence_number | vlf_active | vlf_status | vlf_first_lsn |
+------------------+---------------------+------------+------------+------------------------+
| 8192 | 253978 | 0 | 0 | 00000000:00000000:0000 |
| 262144 | 253979 | 0 | 0 | 00000000:00000000:0000 |
| 516096 | 253980 | 0 | 0 | 00000000:00000000:0000 |
| 770048 | 253977 | 0 | 0 | 00000000:00000000:0000 |
| 1048576 | 253981 | 0 | 0 | 00000000:00000000:0000 |
| 17563648 | 253982 | 0 | 0 | 00000000:00000000:0000 |
| 34078720 | 253983 | 1 | 2 | 0003e01f:00000010:0001 |
| 50593792 | 253970 | 0 | 0 | 00000000:00000000:0000 |
| 67108864 | 253971 | 0 | 0 | 00000000:00000000:0000 |
| 75497472 | 253972 | 0 | 0 | 00000000:00000000:0000 |
| 83886080 | 253973 | 0 | 0 | 00000000:00000000:0000 |
| 92274688 | 253974 | 0 | 0 | 00000000:00000000:0000 |
| 100663296 | 253975 | 0 | 0 | 00000000:00000000:0000 |
| 109051904 | 253976 | 0 | 0 | 00000000:00000000:0000 |
| 117440512 | 0 | 0 | 0 | 00000000:00000000:0000 |
| 236978176 | 0 | 0 | 0 | 00000000:00000000:0000 |
| 356515840 | 0 | 0 | 0 | 00000000:00000000:0000 |
| 476053504 | 0 | 0 | 0 | 00000000:00000000:0000 |
| 595591168 | 0 | 0 | 0 | 00000000:00000000:0000 |
| 715128832 | 0 | 0 | 0 | 00000000:00000000:0000 |
| 834666496 | 0 | 0 | 0 | 00000000:00000000:0000 |
| 954204160 | 0 | 0 | 0 | 00000000:00000000:0000 |
+------------------+---------------------+------------+------------+------------------------+
使用我当前的脚本,我得到:
+------------------+---------------------+------------+------------+------------------------+
| vlf_begin_offset | vlf_sequence_number | vlf_active | vlf_status | vlf_first_lsn |
+------------------+---------------------+------------+------------+------------------------+
| 8192 | 253978 | 0 | 0 | 00000000:00000000:0000 |
| 34078720 | 253983 | 1 | 2 | 0003e01f:00000010:0001 |
| 954204160 | 0 | 0 | 0 | 00000000:00000000:0000 |
+------------------+---------------------+------------+------------+------------------------+
附加信息
可以在不同的vlf_active = 1
位置弹出。可以有多个岛屿vlf_active = 1
。
问题
在任何活动的 vlf ( ) 之前有一个记录并在之后有一个记录会很好vlf_active = 1
。
我怎样才能做到这一点?
+------------------+---------------------+------------+------------+------------------------+ | vlf_begin_offset | vlf_sequence_number | vlf_active | vlf_status | vlf_first_lsn | +------------------+---------------------+------------+------------+------------------------+ | 8192 | 253978 | 0 | 0 | 00000000:00000000:0000 | | 17563648 | 253982 | 0 | 0 | 00000000:00000000:0000 | | 34078720 | 253983 | 1 | 2 | 0003e01f:00000010:0001 | | 50593792 | 253970 | 0 | 0 | 00000000:00000000:0000 | | 954204160 | 0 | 0 | 0 | 00000000:00000000:0000 | +------------------+---------------------+------------+------------+------------------------+
如果有数百条记录,那么在两者之间需要什么摘要记录?例如这样的:
+------------------+---------------------+------------+------------+------------------------+ | vlf_begin_offset | vlf_sequence_number | vlf_active | vlf_status | vlf_first_lsn | +------------------+---------------------+------------+------------+------------------------+ | 8192 | 253978 | 0 | 0 | 00000000:00000000:0000 | | (4 res clipped) | | | | | | 17563648 | 253982 | 0 | 0 | 00000000:00000000:0000 | | 34078720 | 253983 | 1 | 2 | 0003e01f:00000010:0001 | | 50593792 | 253970 | 0 | 0 | 00000000:00000000:0000 | | (13 res clipped) | | | | 00000000:00000000:0000 | | 954204160 | 0 | 0 | 0 | | +------------------+---------------------+------------+------------+------------------------+
窗口函数是您需要的。
LAG
并将LEAD
告诉前一行和下一行的值是什么,NULL
如果没有这样的行(换句话说,第一行或最后一行),将返回。如果使用 and 的参数,可以简化
default
逻辑LEAD
LAG
另一种选择是在前行和后行上使用条件
COUNT
或, 窗口化。SUM
您仍然需要LEAD
LAG
或ROW_NUMBER
识别第一行和最后一行,因此它不会给您带来太多好处。要求
使用您的样本数据:
你想看:
解决方案
我们可以使用最多覆盖三行的偏移排序窗口框架来完成所有这些操作:前一行、当前行和下一行。
第一行和最后一行的帧中只有两行。第一行缺少前一行,最后一行缺少后续行。无论活动值如何,我们总是对这些行感兴趣。其他有趣的行将在其框架的行中具有 active = 1。
注意:如果只有一个 VLF,则该帧将只有一行,但该行必须处于活动状态。活动行将始终是“有趣的”。
另一种表达方式是说我们对两者都感兴趣:
我们可以将其封装在以下逻辑中:
结果:
有摘要记录
生成问题中显示的隐藏记录的摘要只会稍微困难一些。我们首先需要一种方法来识别我们想要跳过的连续行组。
这可以通过在当前行之前并包括当前行的偏移排序帧中求和感兴趣的行数来完成:
结果:
所需的输出不显示无意义的行的数据,因此用空值替换它们:
结果:
我们需要总结的所有不感兴趣的行现在在它们的组中都是相同的。我们可以删除重复项并使用 plain 计算行数
GROUP BY
。最终查询
最后润色会生成自定义的偏移列文本,并确保行以正确的顺序出现:
结果:
用 DMV 调用替换对表变量的单个引用,以在您的服务器上试用它。