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

上次更新时间:2020 年 5 月 13 日

我正在运行 Amazon Relational Database Service (Amazon RDS) 数据库实例,但即使我为其分配了足够的可用内存,Amazon RDS 数据库实例仍在使用大量的交换内存。内存足够时,为什么要使用交换内存?

简短描述

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

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

Linux 使用的交换内存不会经常清除,因为在清除使用的交换内存时,需要额外的开销来在需要时和重新加载页时重新分配交换内存。因此,如果 RDS 数据库实例使用了交换空间,即使交换空间仅使用过一次,SwapUsage 指标也不会回到零。如果您使用 Amazon RDS Oracle 支持的 HugePage 以及 Amazon RDS for PostgreSQL 上的 HugePage,那么也会消耗交换内存。HugePage 大于 Linux 默认的 2 兆字节大小。

解决方法

要了解 RDS 数据库实例的交换内存使用行为,请首先根据应用程序工作负载检查数据库性能指标。检查 Amazon CloudWatch 指标 FreeableMemorySwapUsage,以了解 RDS 数据库实例的整体内存使用模式。检查这些指标,留意 SwapUsage 指标上升的同时 FreeableMemory 指标减少的情况。这可以表明 RDS 数据库实例在内存方面面临压力。有关更多信息,请参阅如何解决 Amazon RDS for MySQL 或 MariaDB 数据库中的低可用内​​存问题? 如果有足够的可用内存,则交换内存的使用应该不会影响 RDS 数据库实例的性能。如果可用内存始终保持较低水平,则可以将 RDS 数据库实例大小更改为拥有更多内存的实例大小。

要监测交换内存,启用增强监测以以最短为一秒的时间间隔检查指标。增强监测在主机级别收集统计数据,CloudWatch 每 60 秒从管理程序级别收集数据。您可以使用增强监测来识别仅发生一秒钟的增加或减少,并查看各个进程使用的 CPU 和内存。有关更多信息,请参阅 CloudWatch 指标与增强监测指标的区别

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

Amazon RDS MySQL

如果可用内存较低,可执行 SHOW FULL PROCESSLIST; 查看数据库上运行的所有线程。有关更多信息,请参阅 MySQL 文档中的线程表部分。来自 SHOW 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

3.    从此查询的输出中获取 PROCESSLIST_ID 列。这为您提供了与 SHOW FULL PROCESSLIST 中的进程 ID 值相匹配的进程 ID。

拥有正确的进程 ID 后,您可以将进程 ID 映射到查询。您可以使用该 ID 来确定造成高内存和 CPU 利用率的根本原因。您可以使用增强监测查看操作系统进程。有关更多信息,请参阅查看增强监测

Amazon RDS PostgreSQL

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

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

然后,调整查询使其消耗更少的计算资源。

Amazon RDS SQL Server

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

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

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

获得服务器进程 ID 后,例如进程 ID 是 69,运行以下命令来查看 SPID 69 正在运行的内容:

dbcc inputbuffer(69)

Amazon RDS 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>';

这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助?