监视和排查内存使用情况问题

SQL Server In-Memory OLTP 使用与基于磁盘的表不同的模式的内存。 可以使用内存和垃圾回收子系统提供的 DMV 或性能计数器监视数据库中内存优化表和索引的内存分配和使用量。 这样,便可以在系统和数据库级别查看,并让你防止内存耗尽导致的问题。

本主题介绍如何监视 In-Memory OLTP 内存使用情况。

使用内存优化表创建示例数据库

如果已有具有内存优化表的数据库,则可以跳过本部分。

以下步骤创建一个数据库,其中包含三个内存优化表,可在本主题的其余部分使用。 在此示例中,我们将数据库映射到资源池,以便控制内存优化表可以占用多少内存。

  1. 启动 SQL Server Management Studio。

  2. 单击 “新建查询”

  3. 将此代码粘贴到新的查询窗口中,并执行每个部分。

    -- create a database to be used
    CREATE DATABASE IMOLTP_DB
    GO
    
    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
    
    USE IMOLTP_DB
    GO
    
    -- create the resoure 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
    

监视内存使用情况

使用 SQL Server Management Studio

SQL Server 2014 附带内置标准报表,用于监视内存中表使用的内存。 可以使用对象资源管理器访问这些报表。 还可以使用对象资源管理器监视单个内存优化表使用的内存。

数据库级别的消耗量

可以在数据库级别监视内存使用情况,如下所示。

  1. 启动 SQL Server Management Studio,连接到一个服务器。

  2. 在对象资源管理器中,右键单击要报告的数据库。

  3. 在上下文菜单中,选择“报表 ->标准报表 ->内存使用情况(内存优化对象)”

HK_MM_SSMS

此报表显示上面创建的数据库的内存消耗量。

HK_MM_SSMS

使用动态管理视图

有许多 DMV 可用于监视内存优化表、索引、系统对象和运行时结构消耗的内存。

内存优化表和索引的内存消耗

可以通过查询 sys.dm_db_xtp_table_memory_stats 来查找所有用户表、索引和系统对象的内存消耗,如下所示。

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

示例输出

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

有关详细信息,请参阅 sys.dm_db_xtp_table_memory_stats

内部系统结构的内存消耗

系统对象也消耗内存,例如事务结构、数据和增量文件的缓冲区、垃圾回收结构等。 可以通过查询 sys.dm_xtp_system_memory_consumers 来查找用于这些系统对象的内存,如下所示。

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

示例输出

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

有关详细信息,请参阅 sys.dm_xtp_system_memory_consumers(Transact-SQL)

访问内存优化表时运行时的内存消耗

可以使用以下查询确定运行时结构(如过程缓存)消耗的内存:运行此查询以获取运行时结构(如过程缓存)使用的内存。 所有运行时结构都用 XTP 标记。

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

示例输出

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

有关详细信息,请参阅sys.dm_os_memory_objects(Transact-SQL)。

跨实例 In-Memory OLTP 引擎消耗的内存

分配给 In-Memory OLTP 引擎和内存优化对象的内存与 SQL Server 实例中任何其他内存使用者的托管方式相同。 类型MEMORYCLERK_XTP的职员负责分配给 In-Memory OLTP 引擎的所有内存。 使用以下查询查找 In-Memory OLTP 引擎使用的所有内存。

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

示例输出显示,分配的总内存为 18 MB 系统级内存消耗,1358MB 分配给数据库 ID 为 5。 由于此数据库映射到专用资源池,因此此内存将计入该资源池中。

示例输出

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

有关详细信息,请参阅 sys.dm_os_memory_clerks (Transact-SQL)

内存优化对象所消耗的内存管理

可以控制内存优化表消耗的总内存,方法是将其绑定到命名资源池,如主题“将 具有 Memory-Optimized 表的数据库绑定到资源池”中所述。

排查内存问题

排查内存问题的过程有三个步骤:

  1. 标识您的数据库或实例中对象所使用的内存量。 可以使用适用于内存优化表的丰富监视工具集,如前所述。 例如 DMV sys.dm_db_xtp_table_memory_statssys.dm_os_memory_clerks

  2. 确定内存消耗量如何增长,以及剩余的头部空间。 通过定期监视内存消耗,可以知道内存使用量是如何增长的。 例如,如果将数据库映射到命名资源池,则可以监视性能计数器“已用内存”(KB),了解内存使用量的增长情况。

  3. 采取措施来缓解潜在的内存问题。 有关详细信息,请参阅 “解决内存不足问题”。

另请参阅

将具有 Memory-Optimized 表的数据库绑定到现有的资源池更改现有池上的 MIN_MEMORY_PERCENT 和 MAX_MEMORY_PERCENT