I'm currently querying the sys.dm_db_log_info()
DMV to retrieve the VLFs from a database to determine when I can shrink, reorganise and reduce the amount of fragmented (10 MB VLFs) in the TLOG file.
The reason for this is that you can't shrink the TLOG file if a transaction is at the end of the TLOG file and results in an active VLF. Similar situation if an active transaction resides in the middle of the TLOG file, then you can't shrink past that VLF.
Current Statement
I currently have this statement to retrieve the MAX(vlf_begin_offset)
record, the MIN(vlf_begin_offset)
record and any record with an active 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
When all the records are returned the result set looks like this:
+------------------+---------------------+------------+------------+------------------------+
| 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 |
+------------------+---------------------+------------+------------+------------------------+
With my current script I get:
+------------------+---------------------+------------+------------+------------------------+
| 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 |
+------------------+---------------------+------------+------------+------------------------+
Additional Information
The vlf_active = 1
can pop up in various locations. There can be more than one island with vlf_active = 1
.
Questions
It would be nice to have a record before any active vlf (vlf_active = 1
) and one record after.
How can I achieve this?
+------------------+---------------------+------------+------------+------------------------+ | 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 | +------------------+---------------------+------------+------------+------------------------+
What would be required to have a summary record in between if there are hundreds of records? e.g. something like this:
+------------------+---------------------+------------+------------+------------------------+ | 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 | | +------------------+---------------------+------------+------------+------------------------+