It doesn't really make sense to track version store by session, or by transaction, or by query. If two different users are making use of the same version of a row/table, who owns it?
You can track this by object, though, which can help you narrow down which modules are causing the churn. Have a look at sys.dm_tran_top_version_generators
:
USE [your database];
GO
SELECT obj =
QUOTENAME(OBJECT_SCHEMA_NAME(p.object_id))
+ '.' + QUOTENAME(OBJECT_NAME(p.object_id)),
vs.aggregated_record_length_in_bytes
FROM sys.dm_tran_top_version_generators AS vs
INNER JOIN sys.partitions AS p
ON vs.rowset_id = p.hobt_id
WHERE vs.database_id = DB_ID()
AND p.index_id IN (0,1);
And on SQL Server 2008+, you can also figure out which modules reference these tables by adding sys.dm_sql_referencing_entities
:
SELECT
obj = QUOTENAME(OBJECT_SCHEMA_NAME(p.object_id))
+ '.' + QUOTENAME(OBJECT_NAME(p.object_id)),
referenced_by = QUOTENAME(r.referencing_schema_name)
+ '.' + QUOTENAME(r.referencing_entity_name),
vs.aggregated_record_length_in_bytes AS size
FROM sys.dm_tran_top_version_generators AS vs
INNER JOIN sys.partitions AS p
ON vs.rowset_id = p.hobt_id
CROSS APPLY sys.dm_sql_referencing_entities
(
QUOTENAME(OBJECT_SCHEMA_NAME(p.object_id))
+ '.' + QUOTENAME(OBJECT_NAME(p.object_id)), 'OBJECT'
) AS r
WHERE vs.database_id = DB_ID()
AND p.index_id IN (0,1)
ORDER BY size DESC, referenced_by;
This assumes that none of the version store could be created by ad hoc queries. However, it doesn't tell you which of those modules could be causing it - hopefully the naming scheme is logical and helps you narrow it down a bit.
(On 2005 you might be able to go through sysdepends
and other old-style dependency views but I'm not 100% sure how reliable that would be.)
(Note: this isn't a 100% certain answer, and I don't have references, so let me know if you can prove otherwise.)
The version store can only clear versions based on the oldest active transaction within the entire instance, to support the use of transaction-level snapshot isolation across multiple databases simultaneously. That simply wouldn't work if "old" versions within one database were cleared out in the middle of another database's snapshot transaction.
So, if there's a very old open transaction, the version store will not be able to clear until that transaction either commits or rolls back.
Best Answer
Perhaps triggers are involved, which use the version store to provide the before/after row images exposed by the
inserted
anddeleted
virtual tables. As a first step, check active queries using the version store based on thesession_id
: