Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Утечка памяти? #15665 Значение ключа "name" не было задано..превысил бы ограничение в 1 МБ  [new]
Andret
Member

Откуда: Киев
Сообщений: 84
Приветствую! При использовании 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';
никаких утечек не показывают :(
4 дек 17, 14:09    [21004342]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти? #15665 Значение ключа "name" не было задано..превысил бы ограничение в 1 МБ  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
https://connect.microsoft.com/SQLServer/feedback/details/3133017

EXEC sys.sp_set_session_context N'context_debug', ''
4 дек 17, 14:23    [21004405]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти? #15665 Значение ключа "name" не было задано..превысил бы ограничение в 1 МБ  [new]
Andret
Member

Откуда: Киев
Сообщений: 84
Спасибо AlanDenton!

Пустые кавычки испробовал сразу, НО из-за того что критические переменные у меня типа datetimeoffset и int, то обнуление через КАВЫЧКИ не работает :(.

declare	@context_debug datetimeoffset = SysDateTimeOffset(), @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', '';
end
print concat(@i, ' context_debug=', @context_debug)


Результат:
10000 context_debug=2017-12-04 13:39:47.3968753 +02:00
4 дек 17, 14:42    [21004470]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти? #15665 Значение ключа "name" не было задано..превысил бы ограничение в 1 МБ  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Andret, а что мешает время кастовать к строке? Не спорю что костыль, но вариант рабочий.
4 дек 17, 14:44    [21004484]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти? #15665 Значение ключа "name" не было задано..превысил бы ограничение в 1 МБ  [new]
Andret
Member

Откуда: Киев
Сообщений: 84
AlanDenton,

Вы правы, придется что-то такое мутить:/
- несколько десятков процедур с логикой есть, плюс есть ещё своя автоматика, где теперь тип учитывать придётся ...
ломать совсем не охота :(
Думал, может что-то волшебное у
SqlClient.SQLConnection/SqlCommand/...
найдётся;
перепробовал разные опции с Pool, MARS, .. но всё это как мёртвому припарка :-(
4 дек 17, 15:01    [21004546]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти? #15665 Значение ключа "name" не было задано..превысил бы ограничение в 1 МБ  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Andret, ничего хитрого не будет - самое лучшее решение ANSI строки в SESSION_CONTEXT хранить. Меньше проблем будет
4 дек 17, 15:09    [21004579]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти? #15665 Значение ключа "name" не было задано..превысил бы ограничение в 1 МБ  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30829
AlanDenton
Andret, ничего хитрого не будет - самое лучшее решение ANSI строки в SESSION_CONTEXT хранить. Меньше проблем будет
+1

ЗЫ а почему не binary?
4 дек 17, 15:16    [21004607]     Ответить | Цитировать Сообщить модератору
 Re: Утечка памяти? #15665 Значение ключа "name" не было задано..превысил бы ограничение в 1 МБ  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
DECLARE @context DATETIMEOFFSET = SYSDATETIMEOFFSET()

EXEC sp_set_session_context N'context', @context
EXEC sp_set_session_context N'context', ''

SELECT SESSION_CONTEXT(N'context'), NULLIF(CAST(SESSION_CONTEXT(N'context') AS DATETIMEOFFSET), '19000101')

легкий изврат, но все же...
4 дек 17, 15:17    [21004612]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить