Skip to content

Commit 1e12e29

Browse files
committed
inside tlog demos
1 parent 991aff6 commit 1e12e29

19 files changed

+92
-66
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
USE defaultdb;
2+
GO
3+
SELECT name, size*8192/(1024*1024) AS size_in_MB, growth*8192/(1024*1024) AS growth_in_MB
4+
FROM sys.database_files
5+
WHERE file_id = 2;
6+
GO
7+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SELECT * FROM sys.dm_db_log_info(DB_ID('model'));
2+
GO
3+
SELECT * FROM sys.dm_db_log_info(DB_ID('defaultdb'));
4+
GO
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
list "C:\Program Files\Microsoft SQL Server\MSSQL17.MSSQLSERVER\MSSQL\DATA\defaultdb_log.ldf"

demos/insidetlog/Demo 1 - Transaction Log File/lookatvlfs.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
SELECT * FROM sys.dm_db_log_info(DB_ID('dbmediumlog'));
2+
GO
13
SELECT * FROM sys.dm_db_log_info(DB_ID('dbbiglog'));
24
GO
35
SELECT * FROM sys.dm_db_log_info(DB_ID('dbbiggerlog'));

demos/insidetlog/Demo 1 - Transaction Log File/readme.md

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,8 @@ SQL Server 2022 will be used for examples.
1010
CREATE DATABASE defaultdb;
1111
GO
1212
```
13+
2. Examine the default size and autogrow using the following query using the script **lookatlogfilesize.sql** in SSMS:
1314

14-
2. Examine the default size and autogrow using the following query
15-
16-
```sql
17-
USE defaultdb;
18-
GO
19-
SELECT name, size*8192/(1024*1024) AS size_in_MB, growth*8192/(1024*1024) AS growth_in_MB
20-
FROM sys.database_files
21-
WHERE file_id = 2;
22-
GO
23-
```
24-
25-
3. Let's look at the file header page of the log file using the following query:
26-
27-
```sql
28-
DBCC TRACEON(3604);
29-
GO
30-
DBCC PAGE(defaultdb, 2, 0, 3);
31-
GO
32-
```
33-
34-
This is identical to the file header page of the data file except for details about the log file.
3515

3616
## Example 1.2 - Virtual Log File
3717

@@ -47,11 +27,11 @@ Let's break down the output of this query:
4727
- The first VLF is "active" and the rest are "inactive" as you can see from vlf_active = 1 and vlf_status = 2. The active VLF is the one that is currently being written to.
4828
- Notice the first VLF starts at physical offset 8192 bytes into the file because of the log file header page.
4929
- Because the log header page takes up 8192 bytes the VLFs cannot be divided evenly so the first 3 VLFs are 1.92MB and the last one if 2.17MB. vlf_size_mb is "rounded" but if you calculate the differences for each vlf_begin_offset you can see the actual byte difference and it adds up to 8388608 which is 8MB.
50-
- The vlf_sequence number is 39 for the active VLF because the last vlf_sequence_number for model was 38.
30+
- The vlf_sequence number is 43 for the active VLF because the last vlf_sequence_number for model was 42.
5131
- The vlf_parity is 64 which is 0x40 or 01000000.
5232
- The vlf_first_lsn is the first log record in the VLF which we will examine later
5333

54-
2. Let's see what VLFs look like for other sized databases.
34+
2. Let's see what VLFs look like for other sized databases. Bring up the script **lookatvlfs.sql** in SSMS and execute it. This script will create a database with a specific size and autogrow settings, then it will show the VLFs for that database.
5535

5636
-- A database log file of 64MB has 4 VLFs roughly 16Mb each
5737
-- A database log file of 1GB has 8 VLFs roughly 128Mb each
@@ -60,28 +40,45 @@ Let's break down the output of this query:
6040

6141
3. Let's see the VLF log header information in each VLF and what the "empty" VLFs look like
6242

63-
Here are the offsets for each VLF
43+
Here are the offsets for each VLF (your dbid may not be 5):
6444

6545
database_id file_id vlf_begin_offset
6646

67-
14 2 8192
68-
14 2 2039808
69-
14 2 4071424
70-
14 2 6103040
47+
5 2 8192
48+
5 2 2039808
49+
5 2 4071424
50+
15 2 6103040
7151

7252
a. Shutdown SQL Server
7353
b. Use the list.exe program in hex mode to look at the log file
7454

7555
The first 2000 (hex) bytes are the log file header. So let's go at 2000 (hex) to see the VLF header.
7656

77-
The VLF header is actually 8192 bytes even though it does not take up a page but it is written as a page. So the first log block is at 4000 (hex).
57+
The VLF header is actually 8192 bytes even though it does not take up a page but it is written as a page. Let's take a look at the first few bytes of the VLF header:
58+
59+
AB 40 05 00 2B 00 00 00
60+
61+
AB = This is the log file header signature used to see if there is disk sectore remapping. 1 byte
62+
40 = This is the parity byte which is 0x40 used for this file.
63+
00 05 (swapped) = This is a log format "version number". 2 bytes
7864

79-
At 4000 hex, notice the first byte is 0x50. This is the parity bytes of 0x40 OR'd with 0x10 which indicates this the first 512 sector of the log block. Go to 4200 which is the next 512 bytes and now you see 0x40. Go to 4E00 (hex) and you will see 0x48. The last sector of the log block is OR'd with 0x08.
65+
00 00 00 2B (swapped) - This is the seqno of the VLF. 0x2B = 43 decimal which lines up in our DMV.
66+
67+
Notice at 0x3000 a bunch of 0xC0 values. This is how we "zero" the log to put in a known signature instead of just "00". TODO: Check with log grow looks like when we use IFI and how are we ok if we don't write 0xC0?. This blog post exlains why we use 0xC0 now https://learn.microsoft.com/en-ca/archive/blogs/psssql/sql-2016-it-just-runs-faster-ldf-stamped but how can we rely on IFI now if we don't write 0xC0? I've asked Peter and Purvi.
68+
69+
So the first log block is at 4000 (hex).
70+
At 4000 hex, notice the first byte is 0x50. This is the parity bytes of 0x40 OR'd with 0x10 which indicates this the first 512 sector of the log block.
71+
72+
Go to 4200 which is the next 512 bytes and now you see 0x40. Go to 4E00 (hex) and you will see 0x48. The last sector of the log block is OR'd with 0x08.
8073

8174
This means the 1st log block is 4KB in size. You can see at 5000 at new log block.
8275

8376
iF you start scrolling down on the right side you can see strings which are part of log records.
8477

8578
Note: Use in later lab on LSN. You can find a log block physically in a log file by using this formula:
8679

87-
log block offset*0x200 (512 bytes)+0x2000 (first page of VLF). this is the physical offset of the log block in the log file.
80+
log block offset
81+
*0x200 (512 bytes)+
82+
sys.dm_db_log_info.vlf_begin_offset
83+
84+
This is the physical offset of the log block in the log file.
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
USE simplerecoverydb;
2+
GO
13
SELECT * FROM sys.fn_dblog(NULL,NULL);
24
GO

demos/insidetlog/Demo 2 - Log Records/heap_insert.sql renamed to demos/insidetlog/Demo 2 - Log Records/4_heap_insert.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ BEGIN TRAN;
77
INSERT INTO asimpletable VALUES (1);
88
COMMIT TRAN;
99

10-
-- Show the logrecs
10+
-- Show the logrecs for just an INSERT (implicit COMMIT)
11+
INSERT INTO asimpletable VALUES (1);
12+
GO

0 commit comments

Comments
 (0)