Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EitanBlumin/bb55dc229d383f731a72fc9d9c1f85dc to your computer and use it in GitHub Desktop.
Save EitanBlumin/bb55dc229d383f731a72fc9d9c1f85dc to your computer and use it in GitHub Desktop.
psst! hey, kid! wanna see an access violation error? here, run this on a SQL Server with MAXDOP != 1
/*
=================================================
Reproduce an access violation error in SQL Server
=================================================
The following script reproduces an Access Violation error
caused by a parallelism plan involving specific system table functions.
The error occurses ONLY with parallel execution plans.
Discovered by Eitan Blumin and Nathan Lifshes on 2020-09-06
The error has been reproduced in multiple SQL Server versions that were tested:
SQL Server 2012 SP4
SQL Server 2014 SP1
SQL Server 2017 RTM
SQL Server 2019 RTM
SQL Server 2019 CU8
Azure SQL Database
(other version were not tested as of yet, but so far it's 100 % failure)
Prerequisites:
SQL Server instance with configured MAXDOP != 1
at least 2 available CPU cores
One you run the script, you will see the following error:
Msg 0, Level 11, State 0, Line 0
A severe error occurred on the current command. The results, if any, should be discarded.
Unless you're connected to Azure SQL DB, in which case the error would be:
Msg 64, Level 20, State 0, Line 0
A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The specified network name is no longer available.)
After you get the error here, look in the "Results" pane to
see a list of recently created SQLDump files.
You can also look in your SQL Server Error Log,
and in your LOG folder of your SQL Server installation, to find the SQLDump files
and see the EXCEPTION_ACCESS_VIOLATION in the corresponding .txt file(s).
=================================================
*/
IF OBJECT_ID('tempdb..#objects') IS NOT NULL DROP TABLE #objects;
CREATE TABLE #objects
(
[object_id] INT
, [index_id] INT NULL
, [partition_number] INT NULL
);
INSERT INTO #objects
SELECT TOP (20000) -- Change this TOP number to as high as needed to trigger parallelism
p.object_id
, p.index_id
, p.partition_number
FROM sys.partitions AS p WITH(NOLOCK)
CROSS JOIN sys.all_columns c1
CROSS JOIN sys.all_columns c2
-- Use CROSS APPLY with some kind of aggregate function to trigger parallelism:
SELECT
DB_NAME()
, p.object_id
, p.index_id
, p.partition_number
, COUNT(*)
FROM #objects AS p WITH(NOLOCK)
CROSS APPLY sys.dm_db_index_operational_stats(db_id(),p.object_id,p.index_id,p.partition_number) AS dmf
--CROSS APPLY sys.dm_db_stats_properties(p.object_id, p.index_id) AS dmf -- this function also causes the same error
GROUP BY
p.object_id
, p.index_id
, p.partition_number
--OPTION (MAXDOP 1); -- uncomment this to prevent the access violation error
--OPTION(QUERYTRACEON 8649); -- uncomment this to try and force a parallel plan if you're stuck with a serial plan
GO
-- Check for recently created SQLDump files
IF object_id('sys.dm_server_memory_dumps') IS NOT NULL
BEGIN
SELECT *
, log_filename = REPLACE([filename], '.mdmp', '.log')
, txt_filename = REPLACE([filename], '.mdmp', '.txt')
FROM sys.dm_server_memory_dumps
WHERE creation_time > DATEADD(hour, -24, GETDATE())
ORDER BY creation_time DESC
END
ELSE
BEGIN
PRINT 'sys.dm_server_memory_dumps was not found. Please look in the LOG directory or use an alternative method to find the dump files.'
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment