为什么尽管内存足够,我的 Amazon RDS 数据库实例仍在使用交换内存?

2 分钟阅读
0

我正在运行一个 Amazon Relational Database Service (Amazon RDS) 数据库实例。尽管我分配了足够的可用内存,但该实例仍在使用大量的交换内存。我想解决这个问题。

简短描述

当系统需要的内存多于分配的内存时,运行 Linux 的 Amazon Elastic Compute Cloud (Amazon EC2) 实例会使用交换内存。有关详细信息,请参阅为 M1 和 C1 EC2 实例启用实例存储交换卷。由于大多数 RDS 数据库实例使用 Linux(SQL Server 除外),因此数据库可能会使用交换内存。

仅在页面正被访问时(例如在运行查询时),RDS 数据库实例才需要 RAM 中的页面。由先前运行的查询带入 RAM 的其他页面如果未使用,将会被刷新到交换空间。最佳做法是让操作系统 (OS) 交换旧页面,而不是强制操作系统将页面保留在内存中。这样可确保有足够的可用 RAM 用于未来的查询。

不会经常清除 Linux 使用的交换内存,因为清除使用的交换内存时,需要额外的开销来在需要时和重新加载页面时重新分配交换内存。因此,如果在 RDS 数据库实例上使用交换空间,即使仅使用过一次,SwapUsage 指标也不会恢复为零。当使用 Amazon RDS for Oracle 支持的 HugePagesAmazon RDS for PostgreSQL 上的 HugePages 时,也会使用交换内存。HugePages 大于 Linux 默认的两兆字节大小。

解决方法

要了解您的 RDS 数据库实例的交换内存使用行为,请首先根据应用程序工作负载检查数据库性能指标。检查 Amazon CloudWatch 指标 FreeableMemorySwapUsage,以了解 RDS 数据库实例的总体内存使用模式。查看 SwapUsage 指标增加的同时,FreeableMemory 指标是否减少。这可以表明 RDS 数据库实例在内存方面面临压力。有关详细信息,请参阅如何对 Amazon RDS for MySQL 数据库中可用内存不足的问题进行故障排除?

如果有足够的可用内存,则使用交换内存应该不会影响 RDS 数据库实例的性能。如果可用内存始终较低,请将 RDS 数据库实例类更改为具有更多内存的较大实例类。

要监控交换内存,请启用增强监控,以最短一秒的时间间隔检查指标。增强监控会收集主机级别的统计数据,CloudWatch 会每 60 秒收集虚拟机监控程序级别的数据。增强监控可识别仅在一秒钟内发生的增加或减少,并显示各个进程使用的 CPU 和内存。有关详细信息,请参阅使用 CloudWatch 日志查看操作系统指标

您还可以启用性能详情来识别在 RDS 数据库实例上消耗过多交换内存或内存的 SQL 事件和等待事件。性能详情将收集数据库级别的数据,并在性能详情控制面板中显示数据。使用性能详情可帮助您解决与数据库性能相关的问题。有关详细信息,请参阅在 Amazon RDS 上使用性能详情监控数据库负载

Amazon RDS for MySQL

如果您的可用内存较低,请运行 SHOW FULL PROCESSLIST 来查看在数据库上运行的所有线程。有关详细信息,请参阅 MySQL 网站上的 SHOW PROCESSLIST statementSHOW FULL PROCESSLIST 输出中的进程 ID 与增强监控显示的进程 ID 不匹配。要查看正确的进程 ID,请将与数据库关联的数据库参数组修改Performance_Schema 参数。这是一个静态参数,因此您必须重新启动 RDS 数据库实例

**注意:**为避免停机,请在非流量高峰时间修改参数并重新启动数据库。

在内存达到所需使用量后,完成以下步骤:

  1. 在“增强监控”页面中对进程 ID 进行排序,以查看 CPU 消耗最多的进程的 ID。
  2. 以主用户身份运行以下查询:
    select * from performance_schema.threads where THREAD_OS_ID in (ID shown in the Enhanced Monitoring window)\G
    例如,如果 Thread_OS_Id 10374 和 1432 消耗了最多的内存,则运行以下查询:
    select * from performance_schema.threads where THREAD_OS_ID in (10374, 1432)\G
    有关详细信息,请参阅 MySQL 网站上的 The threads table
  3. 从此查询的输出中获取 PROCESSLIST_ID 列。此列为您提供了与 SHOW FULL PROCESSLIST 中的进程 ID 值相匹配的进程 ID。
  4. 获取正确的进程 ID 后,将进程 ID 与查询进行映射。使用进程 ID 来确定导致内存和 CPU 使用率高的根本原因。

要查看操作系统进程,请使用增强监控。有关详细信息,请参阅在 RDS 控制台中查看操作系统指标

Amazon RDS for PostgreSQL

要识别消耗大量内存的进程,请将增强监控进程列表中的进程 ID 映射到确切的查询。要标识该进程,请运行以下 pg_stat_activity 视图:

select * from pg_stat_activity where pid=(the PID of your process);

然后,调整查询使其使用较少的计算资源。

Amazon RDS for SQL Server

增强监控可识别消耗大量内存的特定线程 ID。线程 ID 就是 RDS for SQL Server 中的内核进程 ID (KPID)。

在 RDS for SQL Server 中,运行以下查询以获取与 KPID 对应的服务器进程 ID (SPID):

select * from sys.sysprocesses where kpid = '<Value of Thread ID from Enhanced Monitoring>' ;

获取服务器进程 ID(例如 69)后,运行以下命令以查看 SPID 69 正在执行的操作:

dbcc inputbuffer(69)

Amazon RDS for Oracle

要识别消耗最多内存的进程,请使用增强监控中的操作系统进程 ID。然后,运行以下查询以获取会话的进程地址:

select ADDR from v$process where SPID=OS_PID;

要识别数据库中的会话,请使用进程地址运行以下查询:

select sid,serial#,username, status from v$session where PADDR='<ADDR from above query>';

启用增强监控后,比较 FreeMemoryFreeableMemory 指标。如果指标不同,则这可能表明缓存或非活动内存中使用了大量内存。这种内存使用可能会导致交换内存使用率过高。您可能需要清除缓存。有关如何清除缓存的详细信息,请参阅刷新缓冲区缓存

**注意:**清除缓冲区缓存可能会对数据库性能产生负面影响。

相关信息

Amazon RDS 的监控工具