sys.fn_filelog: An Undocumented Log-Reading Function Added in SQL Server 2022
An unfamiliar log-reading function appears in the system catalog, and its name suggests it may accept a file path. sys.fn_filelog is present in the SQL Server 2022 and SQL Server 2025 inventories, but not in the SQL Server 2019 inventory. It appears beside sys.fn_dblog and sys.fn_dump_dblog. Paul Randal wrote about both undocumented functions for transaction log investigations.[1]

This post follows the first post in this series. I started with the same inventory: SQL Server 2019 CU32, SQL Server 2022 CU25, and SQL Server 2025 CU9. CU means cumulative update, the regular servicing package for SQL Server. I also kept the SQL Server 2025 RTM inventory, where RTM means the first release build with no cumulative update applied.
sys.fn_filelog appears in the SQL Server 2022 inventory and has one parameter. On SQL Server 2022 and SQL Server 2025, it has the same 124 output columns as sys.fn_dblog and sys.fn_dump_dblog. It also has a module definition that I could read over the Dedicated Admin Connection (DAC). I found no Microsoft documentation for it, and the web searches I ran did not turn up a community article that explains how to use it. The read-only calls I was willing to run did not return rows from the 2025 instance.
What the catalog says
The inventory found sys.fn_filelog as a system inline table-valued function in SQL Server 2022 CU25 and SQL Server 2025 CU9. A table-valued function returns rows and columns. The same object is absent from the SQL Server 2019 CU32 inventory.
The definition text is the same in SQL Server 2022 and 2025 (the SHA-256 hashes match). It is short. This is the system definition as SQL Server returns it, not a script to run:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
create function sys.fn_filelog ( @fname nvarchar (260) = NULL ) returns table as return select * from OpenRowset (TABLE DBLOG, NULL, NULL, NULL, -1, 0, NULL,NULL,NULL,NULL, NULL,NULL,NULL, NULL,NULL,NULL, @fname,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL) |
The definition explains the output shape, but not how Microsoft expects the function to be used. The function wraps the internal OpenRowset (TABLE DBLOG, ...) call, the same internal entry point used by sys.fn_dblog and sys.fn_dump_dblog. sys.fn_dblog passes a start log sequence number (LSN), an end LSN, and a sequence number of 1. An LSN is SQL Server’s identifier for a position in the transaction log. sys.fn_filelog passes no start or end LSN, passes -1 for the sequence number argument, and passes its one parameter in the first file-name slot.
The definition still doesn’t tell me what Microsoft intends it for. I treated the wrapper call as evidence of shape only, not as evidence of supported use.
The columns are not new to log readers
My first pairwise diff showed sys.fn_filelog.Savepoint Name as a new inventory row. It looked like a new log reader column.
The diff row was a side effect of the inventory method. Because sys.fn_filelog is a new function, every column under that function name is new as an inventory item. The column itself is not new to SQL Server’s log readers.
On SQL Server 2022 CU25, all three functions return the same 124 columns with the same data types and nullability:
| Function | Column count | Difference from sys.fn_filelog |
|---|---|---|
sys.fn_filelog |
124 | n/a |
sys.fn_dblog |
124 | none |
sys.fn_dump_dblog |
124 | none |
The same result holds in SQL Server 2025 RTM and SQL Server 2025 CU9. sys.fn_filelog, sys.fn_dblog, and sys.fn_dump_dblog all have 124 output columns there too, with no type differences between the three functions.
The version change is in the older functions. On SQL Server 2019 CU32, sys.fn_dblog and sys.fn_dump_dblog each return 130 columns. In SQL Server 2022 CU25, each returns 124. The six columns present in 2019 and absent in 2022 are Repl CSN, Repl Epoch, Repl Flags, Repl Msg, Repl Partition ID, and Repl Source Commit Time. I did not find type changes among the 124 shared columns.
So sys.fn_filelog is not a richer version of sys.fn_dblog, at least by column list. It is a different wrapper over the same internal rowset provider, with one file-name parameter instead of a start and end LSN.
The parameter list is the main visible difference
I checked the parameter metadata on the 2025 instance with a read-only query against sys.all_parameters:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
SELECT [object_name] = o.name , p.parameter_id , [parameter_name] = p.name , [type_name] = TYPE_NAME(p.user_type_id) , p.max_length , p.has_default_value FROM sys.all_objects AS o JOIN sys.all_parameters AS p ON p.object_id = o.object_id WHERE o.object_id IN (OBJECT_ID(N'sys.fn_filelog'), OBJECT_ID(N'sys.fn_dblog')) ORDER BY o.name, p.parameter_id |
The result was:
|
1 2 3 4 5 |
object_name parameter_id parameter_name type_name max_length has_default_value ----------- ------------ -------------- --------- ---------- ----------------- fn_dblog 1 @start nvarchar 50 0 fn_dblog 2 @end nvarchar 50 0 fn_filelog 1 @fname nvarchar 520 0 |
The byte lengths match nvarchar(25) for sys.fn_dblog and nvarchar(260) for sys.fn_filelog. The extracted definitions show = NULL defaults for both functions, even though sys.all_parameters.has_default_value returned 0 for these system function parameters.
The parameter name and length are consistent with a file-path parameter. @fname nvarchar(260) looks like a file path parameter. sys.fn_dump_dblog also has file-name parameters because it can read log backup media sets.[2] By comparison, sys.fn_filelog exposes one file-name parameter. That difference is the visible surface I confirmed from metadata and the extracted definitions.
What happened when I called it
I ran only read-only SELECT probes on the 2025 instance, in master. I did not create a database, take backups, change trace flags, or write rows for a demo.
First, I tried the call pattern that works for sys.fn_dblog:
|
1 2 3 4 5 6 7 8 |
SELECT TOP (5) [Current LSN] , [Operation] , [Context] , [Transaction ID] , [Log Record Length] FROM sys.fn_filelog(NULL) ORDER BY [Current LSN] |
The NULL call failed with this error:
|
1 2 |
Msg 9005, Level 16, State 2 Invalid parameter passed to OpenRowset(DBLog, ...). |
Then I used the current database log file path from sys.database_files as the @fname value:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
DECLARE @log_file nvarchar(260) SELECT @log_file = [physical_name] FROM sys.database_files WHERE [type_desc] = N'LOG' SELECT TOP (5) [Current LSN] , [Operation] , [Context] , [Transaction ID] , [Log Record Length] FROM sys.fn_filelog(@log_file) ORDER BY [Current LSN] |
The file-path call also failed:
|
1 2 |
Msg 5120, Level 16, State 180 Unable to open the physical file "C:\SQLServer\the-2025-instance\MSSQL\DATA\mastlog.ldf". Operating system error 2: "32(The process cannot access the file because it is being used by another process.)". |
For comparison, sys.fn_dblog(NULL, NULL) returned rows from the same database log:
|
1 2 3 4 5 6 7 |
source Current LSN Operation Context Transaction ID Log Record Length -------- --------------------- --------------- ------------- -------------- ----------------- fn_dblog 0000010F:000000C8:0001 LOP_BEGIN_CKPT LCX_NULL 0000:00000000 96 fn_dblog 0000010F:000000C8:0002 LOP_COUNT_DELTA LCX_CLUSTERED 0000:00000000 208 fn_dblog 0000010F:000000C8:0003 LOP_COUNT_DELTA LCX_CLUSTERED 0000:00000000 208 fn_dblog 0000010F:000000C8:0004 LOP_COUNT_DELTA LCX_CLUSTERED 0000:00000000 208 fn_dblog 0000010F:000000C8:0005 LOP_COUNT_DELTA LCX_CLUSTERED 0000:00000000 208 |
I stopped there for this post. The failed call is consistent with a file-path parameter and with this test being unable to open the active log file. I did not establish that the function cannot read an active log file in general. I did not test it against a detached log file, a copied log file, or a log backup. A log backup is already covered by sys.fn_dump_dblog, and I don’t want to invent a use case from a function name.
Documentation and caution
I searched for sys.fn_filelog and fn_filelog as whole words in the MicrosoftDocs SQL Server, Azure, and Fabric documentation repositories. I found zero hits in all three repositories.[3] I also fetched web search result pages for the same name. I did not find a relevant result to use as documentation. That does not prove nobody wrote about it. It means I found no Microsoft documentation or reputable community article that explains how to use it.
The lack of documentation leaves less guidance than I found for sys.fn_dblog and sys.fn_dump_dblog in the cited SQLskills material. Paul Randal at SQLskills wrote that fn_dblog can search log records still present in the active portion of the transaction log. He also wrote that fn_dump_dblog can search log records in log backup files without restoring the database.[4] He also included a caution about an old fn_dump_dblog bug that created hidden SQLOS schedulers and threads on each call, fixed in later versions.[5]
I don’t have an equivalent body of evidence for sys.fn_filelog. If you experiment with it, do that on a test instance. Reading transaction log records can touch a large part of the log, and undocumented functions do not give you a public compatibility contract.
Where this leaves it
The evidence here is narrow. sys.fn_filelog is another wrapper around OpenRowset (TABLE DBLOG, ...). Its output columns match the other two log readers column for column in SQL Server 2022 and SQL Server 2025. Its parameter shape is the part that changed.
I couldn’t verify a successful read from it. sys.fn_filelog is an undocumented system inline table-valued function present in the tested SQL Server 2022 and 2025 builds. It takes one nvarchar(260) file-name parameter. It returns the same 124-column shape as the other log-reading functions on those builds. The two read-only call patterns I tested failed on the 2025 instance.
Next in the series, I’m looking at system procedures whose code changed in SQL Server 2022.
Do you know of a documented use for sys.fn_filelog, or a safe read-only repro that returns rows? Tell me on Bluesky or LinkedIn, and I’ll update the post.
References
- Using fn_dblog, fn_dump_dblog, and restoring with STOPBEFOREMARK to an LSN - SQLskills. Paul Randal describes
fn_dblogandfn_dump_dblogas undocumented functions used for transaction log investigation. ↩ - Using fn_dblog, fn_dump_dblog, and restoring with STOPBEFOREMARK to an LSN - SQLskills. Shows the file-name parameters used by
fn_dump_dblogfor log backup media. ↩ - MicrosoftDocs/sql-docs, MicrosoftDocs/azure-docs and MicrosoftDocs/fabric-docs - GitHub. The Markdown source of Microsoft Learn for SQL Server, Azure and Fabric. I searched all three repositories for
sys.fn_filelogandfn_filelogas whole words on 2026-09-26 and found zero hits. ↩ - Using fn_dblog, fn_dump_dblog, and restoring with STOPBEFOREMARK to an LSN - SQLskills. States that
fn_dblogcan search active log records andfn_dump_dblogcan search log backup files without restoring the database. ↩ - Using fn_dblog, fn_dump_dblog, and restoring with STOPBEFOREMARK to an LSN - SQLskills. Records the historical
fn_dump_dblogscheduler/thread caution and the later fix note. ↩