Bewaak het geheugengebruik en los problemen op met in-memory OLTP

Van toepassing op:SQL Server

In-Memory OLTP verbruikt geheugen in andere patronen dan schijfgebaseerde tabellen. Je kunt de hoeveelheid geheugen die wordt toegewezen en gebruikt door geheugengeoptimaliseerde tabellen en indexen in je database monitoren met behulp van de DMV's of prestatietellers die zijn verstrekt voor geheugen en het afvalverzamelingssubsysteem. Dit geeft je zicht op zowel systeem- als databaseniveau en stelt je in staat problemen door geheugenverlies te voorkomen.

Dit artikel behandelt het monitoren van het gebruik van je In-Memory OLTP-geheugen voor SQL Server.

Note

Deze tutorial is niet van toepassing in Azure SQL Managed Instance of Azure SQL Database. Voor een demonstratie van in-memory OLTP in Azure SQL, zie in plaats daarvan:

Voor meer informatie over het monitoren van OLTP-gebruik in het geheugen, zie:

1. Maak een voorbeelddatabase met geheugengeoptimaliseerde tabellen

De volgende stappen maken een database aan voor onze oefening.

  1. Start SQL Server Management Studio.

  2. Selecteer Nieuwe query.

    Note

    Je kunt deze volgende stap overslaan als je al een database hebt met geheugengeoptimaliseerde tabellen.

  3. Plak deze code in het nieuwe queryvenster en voer elke sectie uit om de testdatabase voor deze oefening te creëren, IMOLTP_DB.

    -- create a database to be used  
    CREATE DATABASE IMOLTP_DB  
    GO
    
  4. Het voorbeeldscript hieronder gebruikt C:\Data, maar jouw instantie gebruikt waarschijnlijk andere mappenlocaties voor databasegegevensbestanden. Werk het volgende script bij zodat het een juiste locatie voor het in-memory bestand gebruikt en voer het uit.

    ALTER DATABASE IMOLTP_DB ADD FILEGROUP IMOLTP_DB_xtp_fg CONTAINS MEMORY_OPTIMIZED_DATA  
    ALTER DATABASE IMOLTP_DB ADD FILE( NAME = 'IMOLTP_DB_xtp' , FILENAME = 'C:\Data\IMOLTP_DB_xtp') TO FILEGROUP IMOLTP_DB_xtp_fg;  
    GO
    
  5. Het volgende script maakt drie geheugen-geoptimaliseerde tabellen die je in de rest van dit onderwerp kunt gebruiken. In het voorbeeld hebben we de database gekoppeld aan een resource pool zodat we kunnen bepalen hoeveel geheugen geheugen-geoptimaliseerde tabellen kunnen innemen. Voer het volgende script uit in de IMOLTP_DB database.

    -- create some tables  
    USE IMOLTP_DB  
    GO  
    
    -- create the resource pool  
    CREATE RESOURCE POOL PoolIMOLTP WITH (MAX_MEMORY_PERCENT = 60);  
    ALTER RESOURCE GOVERNOR RECONFIGURE;  
    GO  
    
    -- bind the database to a resource pool  
    EXEC sp_xtp_bind_db_resource_pool 'IMOLTP_DB', 'PoolIMOLTP'  
    
    -- you can query the binding using the catalog view as described here  
    SELECT d.database_id  
         , d.name  
         , d.resource_pool_id  
    FROM sys.databases d  
    GO  
    
    -- take database offline/online to finalize the binding to the resource pool  
    USE master  
    GO  
    
    ALTER DATABASE IMOLTP_DB SET OFFLINE  
    GO  
    ALTER DATABASE IMOLTP_DB SET ONLINE  
    GO  
    
    -- create some tables  
    USE IMOLTP_DB  
    GO  
    
    -- create table t1  
    CREATE TABLE dbo.t1 (  
           c1 int NOT NULL CONSTRAINT [pk_t1_c1] PRIMARY KEY NONCLUSTERED  
         , c2 char(40) NOT NULL  
         , c3 char(8000) NOT NULL  
         ) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA)  
    GO  
    
    -- load t1 150K rows  
    DECLARE @i int = 0  
    BEGIN TRAN  
    WHILE (@i <= 150000)  
       BEGIN  
          INSERT t1 VALUES (@i, 'a', replicate ('b', 8000))  
          SET @i += 1;  
       END  
    Commit  
    GO  
    
    -- Create another table, t2  
    CREATE TABLE dbo.t2 (  
           c1 int NOT NULL CONSTRAINT [pk_t2_c1] PRIMARY KEY NONCLUSTERED  
         , c2 char(40) NOT NULL  
         , c3 char(8000) NOT NULL  
         ) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA)  
    GO  
    
    -- Create another table, t3   
    CREATE TABLE dbo.t3 (  
           c1 int NOT NULL CONSTRAINT [pk_t3_c1] PRIMARY KEY NONCLUSTERED HASH (c1) WITH (BUCKET_COUNT = 1000000)  
         , c2 char(40) NOT NULL  
         , c3 char(8000) NOT NULL  
         ) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA)  
    GO  
    

2. Monitor het geheugengebruik

Monitor het geheugengebruik met SQL Server Management Studio

Sinds SQL Server 2014 (12.x) heeft SQL Server Management Studio ingebouwde standaardrapporten om het geheugenverbruik van tabellen in het geheugen te monitoren. Je kunt deze rapporten openen met Objectverkenner. Je kunt de objectverkenner ook gebruiken om het geheugen te monitoren dat wordt verbruikt door individuele geheugengeoptimaliseerde tabellen.

Verbruik op databaseniveau

Je kunt het geheugengebruik op databaseniveau als volgt monitoren.

  1. Start SQL Server Management Studio en maak verbinding met je SQL Server of SQL beheerde instantie.

  2. Klik in Objectverkenner met de rechtermuisknop op de database waarop je rapporten wilt hebben.

  3. Selecteer in het contextmenu: Rapporten ->Standaardrapporten ->Geheugengebruik door geheugengeoptimaliseerde objecten

Schermopname van de Objectverkenner met Rapporten > Standaardrapporten > Geheugengebruik per geheugengeoptimaliseerd object geselecteerd.

Dit rapport toont geheugenverbruik door de database die we hierboven hebben gemaakt.

Screenshot van het rapport over het totale geheugengebruik door geheugengeoptimaliseerde objecten.

Monitor het geheugengebruik met DMV's

Er zijn veel DMV's beschikbaar om geheugen te monitoren dat wordt verbruikt door geheugengeoptimaliseerde tabellen, indexen, systeemobjecten en door run-time structuren.

Geheugenverbruik door geheugengeoptimaliseerde tabellen en indexen

Je kunt het geheugenverbruik voor alle gebruikerstabellen, indexen en systeemobjecten vinden door te queryen sys.dm_db_xtp_table_memory_stats zoals hier getoond.

SELECT object_name(object_id) AS [Name]
     , *  
   FROM sys.dm_db_xtp_table_memory_stats;

Voorbeelduitvoer

Name       object_id   memory_allocated_for_table_kb memory_used_by_table_kb memory_allocated_for_indexes_kb memory_used_by_indexes_kb  
---------- ----------- ----------------------------- ----------------------- ------------------------------- -------------------------  
t3         629577281   0                             0                       128                             0  
t1         565577053   1372928                       1200008                 7872                            1942  
t2         597577167   0                             0                       128                             0  
NULL       -6          0                             0                       2                               2  
NULL       -5          0                             0                       24                              24  
NULL       -4          0                             0                       2                               2  
NULL       -3          0                             0                       2                               2  
NULL       -2          192                           25                      16                              16  

Voor meer informatie, zie sys.dm_db_xtp_table_memory_stats.

Geheugenverbruik door interne systeemstructuren

Geheugen wordt ook verbruikt door systeemobjecten, zoals transactionele structuren, buffers voor data en deltabestanden, garbage collection-structuren en meer. Je kunt het geheugen dat voor deze systeemobjecten wordt gebruikt vinden door te queryen sys.dm_xtp_system_memory_consumers zoals hier getoond.

SELECT memory_consumer_desc  
     , allocated_bytes/1024 AS allocated_bytes_kb  
     , used_bytes/1024 AS used_bytes_kb  
     , allocation_count  
   FROM sys.dm_xtp_system_memory_consumers  

Voorbeelduitvoer

memory_consumer_ desc allocated_bytes_kb   used_bytes_kb        allocation_count  
------------------------- -------------------- -------------------- ----------------  
VARHEAP                   0                    0                    0  
VARHEAP                   384                  0                    0  
DBG_GC_OUTSTANDING_T      64                   64                   910  
ACTIVE_TX_MAP_LOOKAS      0                    0                    0  
RECOVERY_TABLE_CACHE      0                    0                    0  
RECENTLY_USED_ROWS_L      192                  192                  261  
RANGE_CURSOR_LOOKSID      0                    0                    0  
HASH_CURSOR_LOOKASID      128                  128                  455  
SAVEPOINT_LOOKASIDE       0                    0                    0  
PARTIAL_INSERT_SET_L      192                  192                  351  
CONSTRAINT_SET_LOOKA      192                  192                  646  
SAVEPOINT_SET_LOOKAS      0                    0                    0  
WRITE_SET_LOOKASIDE       192                  192                  183  
SCAN_SET_LOOKASIDE        64                   64                   31  
READ_SET_LOOKASIDE        0                    0                    0  
TRANSACTION_LOOKASID      448                  448                  156  
PGPOOL:256K               768                  768                  3  
PGPOOL: 64K               0                    0                    0  
PGPOOL:  4K               0                    0                    0  

Voor meer informatie, zie sys.dm_xtp_system_memory_consumers).

Geheugenverbruik tijdens runtime bij het benaderen van geheugengeoptimaliseerde tabellen

Je kunt het geheugen bepalen dat wordt verbruikt door runtime-structuren, zoals de procedurecache, met de volgende query: voer deze query uit om het geheugen te krijgen dat wordt gebruikt door run-time structuren, zoals voor de procedurecache. Alle run-time structuren zijn getagd met XTP.

SELECT memory_object_address  
     , pages_in_bytes  
     , bytes_used  
     , type  
   FROM sys.dm_os_memory_objects WHERE type LIKE '%xtp%'  

Voorbeelduitvoer

memory_object_address pages_ in_bytes bytes_used type  
--------------------- ------------------- ---------- ----  
0x00000001F1EA8040    507904              NULL       MEMOBJ_XTPDB  
0x00000001F1EAA040    68337664            NULL       MEMOBJ_XTPDB  
0x00000001FD67A040    16384               NULL       MEMOBJ_XTPPROCCACHE  
0x00000001FD68C040    16384               NULL       MEMOBJ_XTPPROCPARTITIONEDHEAP  
0x00000001FD284040    16384               NULL       MEMOBJ_XTPPROCPARTITIONEDHEAP  
0x00000001FD302040    16384               NULL       MEMOBJ_XTPPROCPARTITIONEDHEAP  
0x00000001FD382040    16384               NULL       MEMOBJ_XTPPROCPARTITIONEDHEAP  
0x00000001FD402040    16384               NULL       MEMOBJ_XTPPROCPARTITIONEDHEAP  
0x00000001FD482040    16384               NULL       MEMOBJ_XTPPROCPARTITIONEDHEAP  
0x00000001FD502040    16384               NULL       MEMOBJ_XTPPROCPARTITIONEDHEAP  
0x00000001FD67E040    16384               NULL       MEMOBJ_XTPPROCPARTITIONEDHEAP  
0x00000001F813C040    8192                NULL       MEMOBJ_XTPBLOCKALLOC  
0x00000001F813E040    16842752            NULL       MEMOBJ_XTPBLOCKALLOC  

Voor meer informatie, zie sys.dm_os_memory_objects (Transact-SQL).

Geheugen verbruikt door In-Memory OLTP-engine over de hele instantie

Geheugen toegewezen aan de In-Memory OLTP-engine en de geheugengeoptimaliseerde objecten wordt op dezelfde manier beheerd als elke andere geheugenconsument binnen een SQL Server instantie. De klerken van type MEMORYCLERK_XTP houden rekening met al het geheugen dat aan In-Memory OLTP-engine is toegewezen. Gebruik de volgende query om alle geheugen te vinden dat door de In-Memory OLTP-engine wordt gebruikt.

-- This DMV accounts for all memory used by the in-memory engine  
SELECT type  
   , name  
   , memory_node_id  
   , pages_kb/1024 AS pages_MB   
   FROM sys.dm_os_memory_clerks WHERE type LIKE '%xtp%'  

De volgende voorbeelduitvoer toont dat het toegewezen geheugen 18 MB systeemniveau geheugen is en 1358 MB toegewezen aan database_id = 5. Omdat deze database is toegewezen aan een toegewijde resource pool, wordt dit geheugen in die resource pool meegenomen.

type                 name       memory_node_id pages_MB  
-------------------- ---------- -------------- --------------------  
MEMORYCLERK_XTP      Default    0              18  
MEMORYCLERK_XTP      DB_ID_5    0              1358  
MEMORYCLERK_XTP      Default    64             0  

Zie sys.dm_os_memory_clerks voor meer informatie.

3. Beheer van geheugen dat wordt verbruikt door geheugengeoptimaliseerde objecten

Je kunt het totale geheugenverbruik van geheugengeoptimaliseerde tabellen aansturen door het te binden aan een benoemde resource pool. Voor meer informatie, zie Bind een database met geheugengeoptimaliseerde tabellen aan een resource pool.

Geheugenproblemen oplossen

Het oplossen van geheugenproblemen is een proces in drie stappen:

  1. Identificeer hoeveel geheugen de objecten in je database of instantie verbruiken. Je kunt een rijke set monitoringtools gebruiken voor geheugengeoptimaliseerde tabellen zoals eerder beschreven. Zie bijvoorbeeld de voorbeeldqueries op de DMV's sys.dm_db_xtp_table_memory_stats of sys.dm_os_memory_clerks.

  2. Bepaal hoe het geheugenverbruik groeit en hoeveel hoofdruimte je nog hebt. Door het geheugenverbruik periodiek te monitoren, kun je weten hoe het geheugengebruik groeit. Als je bijvoorbeeld de database hebt toegewezen aan een benoemde resource pool, kun je de prestatieteller Used Memory (KB) monitoren om te zien hoe het geheugengebruik groeit.

  3. Neem maatregelen om mogelijke geheugenproblemen te beperken. Voor meer informatie, zie Out of Memory-problemen oplossen.