Atualmente estou consultando o sys.dm_db_log_info()
DMV para recuperar os VLFs de um banco de dados para determinar quando posso reduzir, reorganizar e reduzir a quantidade de fragmentados (10 MB VLFs) no arquivo TLOG.
A razão para isso é que você não pode reduzir o arquivo TLOG se uma transação estiver no final do arquivo TLOG e resultar em um VLF ativo. Situação semelhante, se uma transação ativa residir no meio do arquivo TLOG, você não poderá reduzir esse VLF.
Extrato atual
Atualmente tenho esta declaração para recuperar o MAX(vlf_begin_offset)
registro, o MIN(vlf_begin_offset)
registro e qualquer registro com um ativo 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
Quando todos os registros são retornados, o conjunto de resultados fica assim:
+------------------+---------------------+------------+------------+------------------------+
| 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 |
+------------------+---------------------+------------+------------+------------------------+
Com meu script atual, recebo:
+------------------+---------------------+------------+------------+------------------------+
| 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 |
+------------------+---------------------+------------+------------+------------------------+
informação adicional
O vlf_active = 1
pode aparecer em vários locais. Pode haver mais de uma ilha com vlf_active = 1
.
Perguntas
Seria bom ter um registro antes de qualquer vlf ativo ( vlf_active = 1
) e um registro depois.
Como posso conseguir isso?
+------------------+---------------------+------------+------------+------------------------+ | 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 | +------------------+---------------------+------------+------------+------------------------+
O que seria necessário para ter um registro resumido no meio se houver centenas de registros? por exemplo, algo assim:
+------------------+---------------------+------------+------------+------------------------+ | 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 | | +------------------+---------------------+------------+------------+------------------------+
Funções de janela são o que você precisa aqui.
LAG
eLEAD
dirá quais são os valores das linhas anteriores e seguintes, e retornaráNULL
se não houver tal linha (em outras palavras, a primeira ou a última linha).Você pode simplificar a lógica se usar o
default
parâmetro deLEAD
eLAG
Outra opção é usar um condicional
COUNT
ou umSUM
, janelado sobre a linha anterior e a linha posterior. Você ainda precisa identificar a primeiraLEAD
LAG
eROW_NUMBER
a última linhas, então não ganha muito.Requerimento
Usando seus dados de amostra:
Você quer ver:
Solução
Podemos fazer tudo isso com um quadro de janela ordenado por deslocamento cobrindo no máximo três linhas: a linha anterior, a linha atual e a linha seguinte.
A primeira e a última linha têm apenas duas linhas em seus quadros. A primeira linha não possui uma linha anterior e a última linha não possui uma linha seguinte. Estamos sempre interessados nessas linhas, independentemente do valor ativo. Outras linhas interessantes terão active = 1 em uma das linhas de seus quadros.
Nota: Se houver apenas um VLF, o quadro terá apenas uma linha, mas essa linha deverá estar ativa. A linha ativa sempre será 'interessante'.
Outra maneira de expressar isso para dizer que estamos interessados em ambos:
Podemos encapsular isso na seguinte lógica:
Resultados:
Com registros de resumo
É apenas um pouco mais difícil produzir o resumo dos registros ocultos mostrados na pergunta. Primeiro, precisamos de uma maneira de identificar grupos contíguos de linhas que queremos pular.
Isso pode ser feito somando o número de linhas interessantes no quadro ordenado por deslocamento antes e incluindo a linha atual:
Resultados:
A saída desejada não mostra dados para linhas desinteressantes, portanto, substitua-as por nulos:
Resultados:
Todas as linhas desinteressantes que precisamos resumir agora são idênticas dentro de seus grupos. Podemos remover as duplicatas e contar as linhas usando um arquivo
GROUP BY
.Consulta final
Os toques finais produzem o texto da coluna de deslocamento personalizado e garantem que as linhas apareçam na ordem correta:
Resultados:
Substitua a única referência à variável de tabela pela chamada DMV para experimentá-la em seu servidor.