KB3074434 — ИСПРАВЛЕНИЕ: ошибка нехватки памяти, когда виртуальное адресное пространство SQL Server процесса очень мало доступной памяти

Применяется к
SQL Server 2012 Service Pack 3 SQL Server 2012 Developer SQL Server 2012 Enterprise SQL Server 2012 Enterprise Core SQL Server 2012 Standard

После применения этого обновления необходимо добавить флаг трассировки -T8075 в качестве параметра запуска, чтобы включить это изменение.

Проблема

При выполнении запроса в 64-разрядной версии Microsoft SQL Server 2012 в журнале ошибок SQL Server появляется сообщение об ошибке нехватки памяти, похожее на следующее:

Примечание

Не удалось выделить страницы: FAIL_PAGE_ALLOCATION 513

Выполнение запросов занимает много времени и SOS_MEMORY_TOPLEVELBLOCKALLOCATOR ожидания.

При изучении следующих информационных точек вы обнаружите, что доступное виртуальное адресное пространство очень мало:

  • DBCC MEMORYSTATUS — раздел Количество процессов и систем — доступная виртуальная память
  • Динамическое административное представление: sys.dm_os_process_memory — virtual_address_space_available_kb столбцов

Эти значения начинаются около 8 терабайт (ТБ) в процессе x64 и продолжают уменьшаться и достигать нескольких гигабайт (ГБ). 

Когда вы находитесь на этапе, когда доступное виртуальное адресное пространство очень мало, запросы, которые пытаются выполнить выделение памяти, также могут столкнуться с типом ожидания CMEMTHREAD.

Следующие точки данных будут продолжать увеличиваться с течением времени:

  • Динамическое административное представление: sys.dm_os_process_memory и sys.dm_os_memory_nodes — virtual_address_space_reserved_kb столбцов
  • DBCC MEMORYSTATUS — раздел диспетчера памяти — зарезервировано виртуальной машиной

Эти значения обычно увеличиваются в кратном значении "max server memory" до почти 8 ТБ.

Причина

Когда процесс SQL Server достигает состояния ,когда общая память сервера = целевая память сервера = максимальная память сервера, в диспетчере памяти SQL Server есть политики, позволяющие новым выделениям запрашивать несколько страниц размером 8 КБ для временного успешного выполнения. Повторяющееся распределение при таком условии может привести к фрагментации блоков памяти и использованию виртуального адресного пространства. Если этот процесс повторяется много раз, SQL Server виртуальное адресное пространство будет исчерпано, и вы заметите симптомы, упомянутые ранее.

Решение

Сведения о накопительных обновлениях

Эта проблема была исправлена в следующем накопительном обновлении SQL Server.

Рекомендация. Установите последнее накопительное обновление для SQL Server

Каждое новое накопительное обновление для SQL Server содержит все исправления и все исправления для системы безопасности, которые были включены в предыдущее накопительное обновление. Рекомендуется скачать и установить последние накопительные обновления для SQL Server:

Это исправление предотвращает нехватку памяти и непрерывное сокращение доступного виртуального адресного пространства.

Состояние

Корпорация Майкрософт подтвердила, что это проблема продуктов Microsoft, перечисленных в разделе «Относится к».

Дополнительные сведения

  • Windows 2012 R2 позволяет увеличить размер виртуального адресного пространства до 128 ТБ. Таким образом, вы можете не заметить эту проблему в средах Windows 2012 R2. Дополнительные сведения см. в следующем разделе в Центре разработки для Windows:

    Ограничения памяти для выпусков Windows и Windows Server

  • Если вы видите непрерывное увеличение виртуального адресного пространства даже после применения исправления, вы можете определить, какие запросы или операции запрашивают большие блоки памяти, используя расширенное событие Page_allocated. Пример скрипта выглядит следующим образом:

    CREATE EVENT SESSION [memory_tracking] ON SERVER
    ADD EVENT sqlos.page_allocated(
        ACTION(package0.callstack,sqlos.cpu_id,sqlos.task_address,sqlos.worker_address,sqlserver.database_id,sqlserver.query_hash,sqlserver.request_id,sqlserver.session_id,sqlserver.sql_text)
        WHERE ([number_pages]>(1)))
    ADD TARGET package0.event_file(SET filename=N'E:\Data\MSSQL11.MSSQLSERVER\MSSQL\Log\memory_tracking.xel')
    WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=PER_CPU,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
    GO
    
    
    

    Как правило, это операции резервного копирования журналов и обслуживания индексов, которые происходят часто.