Quantcast
Channel: SQL.ru: Microsoft SQL Server
Viewing all articles
Browse latest Browse all 7251

Утечка памяти? #15665 Значение ключа "name" не было задано..превысил бы ограничение в 1 МБ

$
0
0
Приветствую! При использовании sp_set_session_context/SESSION_CONTEXT на нашем продуктиве регулярно стала появляться ошибка (из сабжа).
При попытке её повторить выяснил как она появляется.
Если вызвать любой подобный "тепличный" код из Microsoft SQL Server Management Studio, то всё будет замечательно:

declare	@context_debug nvarchar(4000) =  replicate('Z', 2000), @i int = 0
while	@i < 10000
begin
	set	@i+=1
	exec	sp_set_session_context N'context_debug', @context_debug;
	exec	sp_set_session_context N'context_debug', null;
	-- if @i % 1000 = 0 print concat(@i, ' @context_debug=', @context_debug)
end
print concat(@i, ' last context_debug=', cast(isNull(session_context(N'context_debug'), 'NULL') as nvarchar(4000)))


Но! Если это сделать вот таким кодом из клиента (пример на PowerShell для ясности), то легко добиться ошибки:

Clear-Host
$ServerName = ".\SQL2017"
$SqlConnection = New-Object system.data.SqlClient.SQLConnection("App=test-context;Server=$ServerName; Integrated Security=SSPI;Pooling=false");
$SqlCommand2 = New-Object System.Data.SqlClient.SqlCommand("exec sp_set_session_context N'context_debug', null;", $SqlConnection)
try {
    $SqlConnection.Open();
    for ($i = 1; $i -le 10000; $i++) {
        $r = $SqlCommand2.ExecuteNonQuery()
        if ($i % 1000 -eq 0) {
            Write-Host "i = $i; "  -NoNewline -ForegroundColor Green
        }
    }
}
catch {
    Write-Host "ERROR Code = " -NoNewline -ForegroundColor Yellow
    Write-Host $_.Exception.InnerException.Number -ForegroundColor Yellow
    Write-Host $_.Exception.Message -ForegroundColor Red
}
finally {
    Write-Host  "Last i = $i" -ForegroundColor Blue
    $SqlConnection.Close()
    $SqlConnection.Dispose()
}


Результат из PS
i = 1000; i = 2000; ERROR Code = 15665
Исключение при вызове "ExecuteNonQuery" с "0" аргументами: "Значение ключа "context_debug" не было задано, так как общий размер ключей и значений в контексте сеанса превысил бы ограничение в 1 МБ."
Last i = 2820
PS C:\Scripts>



Ключевой момент: Для повторяемости ошибки должен быть вызов обнуления контекстной переменной отдельной командой! Первичное присвоение значения на ошибку не влияет. В реальности переменные присваиваются в процедурах, многие из них не очищать не могу :(
Проверял на
<= SQL Server 2016 (SP1-CU6) (KB4037354) - 13.0.4457.0
и SQL Server 2017 (RTM) - 14.0.1000.169

Похоже есть какая-то утечка в SQL Server при обнулении сессионных переменных :( Может кто-то знает как обойти эту беду?
Диагностические запросы, наподобие
SELECT * FROM sys.dm_os_memory_cache_counters WHERE type = 'CACHESTORE_SESSION_CONTEXT';
никаких утечек не показывают :(

Viewing all articles
Browse latest Browse all 7251

Trending Articles