本页面介绍了如何为 Cloud SQL 实例配置内存用量。
简介
创建 Cloud SQL 实例时,您可以为该实例选择内存量。随着 PostgreSQL 数据库的工作负载增加,实例的内存用量也会增加。消耗大量内存的实例可能会造成性能瓶颈,有时可能导致内存不足问题。
当 Cloud SQL 实例由于需求增加而耗尽内存时,可能会导致数据库停机。因此,请务必正确配置实例内存以及与内存相关的数据库标志,并监控内存用量,以确保实例运行状况良好。
PostgreSQL 内存大致由两部分组成:
- 全局内存:所有进程共享此内存以执行查询;例如
shared_buffers
和max_connections
。 - 本地内存:这是分配给每个连接的专用内存;例如,
work_mem
、maintenance_work_mem
和temp_buffers
。
内存用量和标志
每当 Cloud SQL 实例的内存用量较高时,可能需要解决以下问题:
- 哪个查询或进程使用的内存较高?
- 内存设置是否足以满足数据库活动?
- 如何更改内存设置?
当 PostgreSQL 数据库运行时,大多数内存用量发生在以下几个方面:
共享缓冲区:这是 PostgreSQL 分配的共享内存,用于保存
read
和write
操作的表数据。对于read
操作,从磁盘请求的所有数据首先会提取到 RAM,然后再提供给客户端。类似地,在 PostgreSQL 中,请求数据时(例如SELECT * from emp
),它首先从磁盘提取到shared_buffers
进行缓存,然后再提供给客户端。write
操作也会发生相同的情况。共享缓冲区也是所有进程和连接的共享内存区域,用于数据缓存、连接缓存和数据操纵语言 (DML) 操作等数据库活动。此区域可分配的最大值由
shared_buffers
标志指定,默认值为相应实例内存的 33%。shared_buffers
的值越高,内存中缓存的数据量越大。- 查询工作内存:运行查询时,PostgreSQL 会为每个操作(例如排序和哈希处理)分配本地内存。在写入临时磁盘文件之前,它可以为查询的每个操作分配的最大值由
work_mem
标志配置,默认值为 4 MB。work_mem
的值越高,内存中可以排序的数据量就越大。 - 维护工作内存:某些维护操作(例如
VACUUM
、CREATE INDEX
、ALTER TABLE
和ADD FOREIGN KEY
)需要 PostgreSQL 分配单独的本地内存。 这些操作使用的后端进程的最大数量可通过maintenance_work_mem
标志配置,默认值为 64 MB。请注意,autovacuum 工作器也会使用维护工作内存,并且最大值可以被autovacuum_work_mem
标志替换。maintenance_work_mem
的值越高,VACUUM
操作的执行速度越快。 - 临时缓冲区:在数据库会话中使用临时表时,PostgreSQL 会分配临时缓冲区来保存会话局部临时表。最大值可通过
temp_buffers
标志指定,默认值为 8 MB。 - 数据库连接:当客户端连接到数据库时,PostgreSQL 会创建一个后端进程来传送客户端会话。除了用于运行查询的内存之外,PostgreSQL 还会分配额外的内存来维护系统目录缓存和准备好的查询计划等信息。
max_connections
标志可以配置数据库服务器允许的最大并发连接数。每个空闲连接使用大约 2 MB 到 3 MB 的共享内存。 如果max_connections
的值较高,则实例可以建立更多连接,但会占用更多内存。
如需查看 PostgreSQL 中内存组件的完整列表,请参阅 PostgreSQL 文档。如需更改或修改本部分中列出的标志,请参阅配置数据库标志。
监控内存用量
定期在 Cloud Monitoring 中监控实例的内存,并确保其不超过内存容量上限。一种良好的做法是在 Cloud Monitoring 中设置提醒,以便在内存用量超过容量上限的 90% 并持续 6 小时的情况下发出提醒。当您的内存用量持续接近容量上限时,此提醒可以向您发出警告。
此外,请监控内存不足的突发事件。为此,请为 Cloud Monitoring 中的 server process .* was terminated by signal 9: Killed
消息设置基于日志的指标,以统计内存不足事件,然后在每次发生此类事件时发出提醒。
如果您的实例在运行时持续超出内存容量上限的 90% 或发生内存不足事件,您可以增加实例的内存。或者,您可以通过限制数据库连接数或降低数据库标志(例如 shared_buffers
、work_mem
或 max_connections
)的值来减少内存用量。降低这些标志的值可能会限制实例的性能。
内存不足
如果内存不足,无法处理数据库工作负载,作为最后的补救手段,底层 Linux 操作系统会使用 out-of-memory (OOM) killer
来结束进程以释放内存。Cloud SQL 经过配置,因此 OOM killer
仅针对 PostgreSQL 工作器进程。在这种情况下,postmaster 进程会被保留,因此只需结束所有现有数据库连接并运行恢复来保护数据库的完整性。如果发生这种情况,可能会出现服务中断和数据库停机的问题。PostgreSQL 数据库日志中会显示如下消息:
2021-10-24 23:34:22.265 UTC [7]: [663-1] db=,user= LOG: server process (PID 1255039) was terminated by signal 9: Killed 2021-10-24 23:34:22.265 UTC [7]: [664-1] db=,user= DETAIL: Failed process was running: SELECT * FROM tab ORDER BY col 2021-10-24 23:34:22.277 UTC [7]: [665-1] db=,user= LOG: terminating any other active server processes 2021-10-24 23:34:22.278 UTC [1255458]: [1-1] db=postgres,user=postgres WARNING: terminating connection because of crash of another server process 2021-10-24 23:34:22.278 UTC [1255458]: [2-1] db=postgres,user=postgres DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory. 2021-10-24 23:34:22.278 UTC [1255458]: [3-1] db=postgres,user=postgres HINT: In a moment you should be able to reconnect to the database and repeat your command. 2021-10-24 23:34:22.278 UTC [1255458]: [4-1] db=postgres,user=postgres CONTEXT: while updating tuple (27,18) in relation "tab" ... 2021-10-24 23:34:22.558 UTC [1255477]: [1-1] db=postgres,user=postgres FATAL: the database system is in recovery mode ... 2021-10-24 23:34:25.579 UTC [7]: [666-1] db=,user= LOG: all server processes terminated; reinitializing ... 2021-10-24 23:34:25.691 UTC [1255482]: [1-1] db=,user= LOG: database system was interrupted; last known up at 2021-10-24 23:31:53 UTC 2021-10-24 23:34:25.776 UTC [1255482]: [2-1] db=,user= LOG: database system was not properly shut down; automatic recovery in progress 2021-10-24 23:34:25.789 UTC [1255482]: [3-1] db=,user= LOG: redo starts at 227/AB359400 2021-10-24 23:34:38.957 UTC [1255482]: [4-1] db=,user= LOG: redo done at 229/4621F508 2021-10-24 23:34:38.959 UTC [1255482]: [5-1] db=,user= LOG: last completed transaction was at log time 2021-10-24 23:34:18.5535+00 2021-10-24 23:34:39.290 UTC [7]: [667-1] db=,user= LOG: database system is ready to accept connections
后续步骤
- 详细了解在 PostgreSQL 中配置内存用量。
- 调整 PostgreSQL 服务器。