我正在运行一个 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 支持的 HugePages 和 Amazon RDS for PostgreSQL 上的 HugePages 时,也会使用交换内存。HugePages 大于 Linux 默认的两兆字节大小。
解决方法
要了解您的 RDS 数据库实例的交换内存使用行为,请首先根据应用程序工作负载检查数据库性能指标。检查 Amazon CloudWatch 指标 FreeableMemory 和 SwapUsage,以了解 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 statement。SHOW FULL PROCESSLIST 输出中的进程 ID 与增强监控显示的进程 ID 不匹配。要查看正确的进程 ID,请将与数据库关联的数据库参数组修改为 Performance_Schema 参数。这是一个静态参数,因此您必须重新启动 RDS 数据库实例。
**注意:**为避免停机,请在非流量高峰时间修改参数并重新启动数据库。
在内存达到所需使用量后,完成以下步骤:
- 在“增强监控”页面中对进程 ID 进行排序,以查看 CPU 消耗最多的进程的 ID。
- 以主用户身份运行以下查询:
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。
- 从此查询的输出中获取 PROCESSLIST_ID 列。此列为您提供了与 SHOW FULL PROCESSLIST 中的进程 ID 值相匹配的进程 ID。
- 获取正确的进程 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>';
启用增强监控后,比较 FreeMemory 和 FreeableMemory 指标。如果指标不同,则这可能表明缓存或非活动内存中使用了大量内存。这种内存使用可能会导致交换内存使用率过高。您可能需要清除缓存。有关如何清除缓存的详细信息,请参阅刷新缓冲区缓存。
**注意:**清除缓冲区缓存可能会对数据库性能产生负面影响。
相关信息
Amazon RDS 的监控工具