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 플래그로 구성되며 기본값은 4MB입니다. work_mem 값이 높으면 메모리에 정렬할 수 있는 데이터 양이 많습니다.
유지보수 작업 메모리:VACUUM, CREATE INDEX, ALTER TABLE, ADD FOREIGN KEY와 같은 일부 유지보수 작업에는 PostgreSQL이 할당하는 별도의 로컬 메모리가 필요합니다.
이러한 작업에서 사용하는 백엔드 프로세스의 최대 크기는 maintenance_work_mem 플래그로 구성할 수 있으며 기본값은 64MB입니다. autovacuum 작업자도 유지보수 작업 메모리를 사용하며 최댓값은 autovacuum_work_mem 플래그로 재정의할 수 있습니다. maintenance_work_mem 값이 높으면 VACUUM 작업의 성능 속도가 높습니다.
임시 버퍼: 데이터베이스 세션에서 임시 테이블이 사용되는 경우 PostgreSQL은 세션 로컬 임시 테이블을 저장할 임시 버퍼를 할당합니다. 최대 용량은 temp_buffers 플래그로 지정할 수 있으며 기본값은 8MB입니다.
데이터베이스 연결: 클라이언트가 데이터베이스에 연결하면 PostgreSQL은 클라이언트 세션을 제공하기 위한 백엔드 프로세스를 만듭니다. PostgreSQL은 쿼리를 실행할 메모리 외에도 시스템 카탈로그 캐시 및 준비된 쿼리 계획과 같은 정보를 유지관리하기 위해 추가 메모리를 할당합니다. 데이터베이스 서버에 허용되는 최대 동시 연결 수는 max_connections 플래그로 구성할 수 있습니다. 각 유휴 연결은 약 2MB~3MB의 공유 메모리를 사용합니다.
max_connections 값이 높으면 인스턴스가 더 많은 연결을 설정할 수 있지만 메모리가 사용됩니다.
Cloud Monitoring에서 인스턴스 메모리를 정기적으로 모니터링하고, 메모리 한도 미만으로 유지합니다. 6시간 동안 사용량이 한도의 90%를 초과할 경우 알림을 받도록 Cloud Monitoring에서 알림을 설정하는 것이 좋습니다. 이 알림은 메모리 사용량이 한도에 지속적으로 가까워질 때 경고를 보낼 수 있습니다.
또한 메모리 부족 이슈를 모니터링합니다.
이를 위해 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 데이터베이스 로그에 다음과 같은 메시지가 표시됩니다.
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["이해하기 어려움","hardToUnderstand","thumb-down"],["잘못된 정보 또는 샘플 코드","incorrectInformationOrSampleCode","thumb-down"],["필요한 정보/샘플이 없음","missingTheInformationSamplesINeed","thumb-down"],["번역 문제","translationIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-08-18(UTC)"],[],[],null,["# Best practices for managing memory usage\n\n\u003cbr /\u003e\n\nMySQL \\| PostgreSQL \\| SQL Server\n\n\u003cbr /\u003e\n\n|\n| **Preview**\n|\n|\n| This product or feature is subject to the \"Pre-GA Offerings Terms\" in the General Service Terms section\n| of the [Service Specific Terms](/terms/service-terms#1).\n|\n| Pre-GA products and features are available \"as is\" and might have limited support.\n|\n| For more information, see the\n| [launch stage descriptions](/products#product-launch-stages).\n\nThis page describes how to configure memory usage for a Cloud SQL\ninstance.\n\nIntroduction\n------------\n\nWhen you create a Cloud SQL instance, you select an amount of\nmemory for the instance. As a PostgreSQL database's workload increases, the instance's memory usage increases. Instances that consume lots of memory can create a\nperformance bottleneck that can sometimes lead to out-of-memory issues.\n\nWhen a Cloud SQL instance runs out of memory because of an increased demand, it can cause database downtime. Therefore, it's important to configure the instance memory and the memory-related database flags properly and monitor the memory usage so that the instance operates in a healthy state.\n\nPostgreSQL memory components are broadly divided into two sections:\n\n- **Global memory:** this is shared across all processes to execute queries; for example, `shared_buffers` and `max_connections`.\n- **Local memory:** this is dedicated memory assigned to each connection; for example, `work_mem`, `maintenance_work_mem`, and `temp_buffers`.\n\nFor other configuration considerations, see [General best practices](/sql/docs/postgres/best-practices) and\n[Operational guidelines](/sql/docs/postgres/operational-guidelines).\n\nMemory usage and flags\n----------------------\n\nWhenever there's high memory usage by Cloud SQL instances, the following\nquestions might arise:\n\n- Which query or process is using high memory?\n- Are the memory settings adequate for the database activity?\n- How do you change the memory settings?\n\nWhen a PostgreSQL database operates, most memory usage occurs in a few areas:\n\n- **Shared buffer:** this is the shared memory that PostgreSQL allocates to hold\n table data for `read` and `write` operations. For the `read` operation, any data that's requested from disk is first fetched to RAM and then it's given to the client. Similarly, in PostgreSQL, when the data is requested (for example, `SELECT * from emp`), it's first fetched from disk to [`shared_buffers`](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-SHARED-BUFFERS) for caching, and then it's given to the client. The same thing happens with the `write` operation.\n\n Shared buffer is also the shared memory area for\n all processes and connections for database activities such as data caching, connection caching, and Data Manipulation Language (DML) operations. The maximum that this area can\n allocate is\n specified by the `shared_buffers` flag and the default is 33% of the instance's memory. If the value of `shared_buffers` is high, the size of the data cached in memory is high.\n- **Query work memory:** as a query is run, PostgreSQL allocates local memory for each operation such as sorting and hashing. The maximum it can allocate for each operation of a query before writing to temporary disk files is configured by the [`work_mem`](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-WORK-MEM) flag, and the default value is 4 MB. If the value of `work_mem` is high, the amount of data that can be sorted in the memory is high.\n- **Maintenance work memory:** some maintenance operations such as `VACUUM`, `CREATE INDEX`, `ALTER TABLE`, and `ADD FOREIGN KEY` require separate local memory that PostgreSQL allocates. The maximum amount for the back-end process that these operations use can be configured by the [`maintenance_work_mem`](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) flag and the default value is 64 MB. Note that autovacuum workers also use maintenance work memory and the maximum can be overridden by the [`autovacuum_work_mem`](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM) flag. If the value of `maintenance_work_mem` is high, the performance speed of the `VACUUM` operation is high.\n- **Temporary buffers:** when a temporary table is used in a database session, PostgreSQL allocates temporary buffers to hold the session-local temporary table. The maximum amount can be specified by the [`temp_buffers`](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-TEMP-BUFFERS) flag and the default value is 8 MB.\n- **Database connection:** when a client connects to the database, PostgreSQL creates a back-end process to serve the client session. Besides the memory to run the query, PostgreSQL allocates additional memory to maintain information such as system catalog cache and prepared query plans. The maximum number of concurrent connections allowed to the database server can be configured by the [`max_connections`](https://www.postgresql.org/docs/current/static/runtime-config-connection.html#GUC-MAX-CONNECTIONS) flag. Each idle connection uses approximately 2 MB to 3 MB of shared memory. If the value of `max_connections` is high, the instance can make more connections, but at the cost of the memory.\n\n\u003cbr /\u003e\n\nFor the complete list of memory components in PostgreSQL, see the [PostgreSQL documentation](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY). To change or modify the flags listed in this section, see [Configure database flags](/sql/docs/postgres/flags).\n\nMonitor memory usage\n--------------------\n\n[Monitor your instance's memory](/sql/docs/postgres/monitor-instance)\nin [Cloud Monitoring](/sql/docs/postgres/monitor-instance#cloud-monitoring)\nregularly and keep it below the memory limit. A good practice is to\n[set an alert](/monitoring/alerts/using-alerting-ui#create-policy)\nin Cloud Monitoring to alert when the usage exceeds 90% of the limit for 6\nhours. This alert can warn you when your memory usage is close to the\nlimit constantly.\n\nAdditionally, monitor for out-of-memory incidents.\nTo do that, set up a [log-based metric](https://cloud.google.com/logging/docs/logs-based-metrics)\nfor the `server process .* was terminated by signal 9: Killed`\nmessage in Cloud Monitoring to count the out-of-memory events, and then alert each time such an event happens.\n\nIf your instance operates constantly above 90% of the memory's limit or an out-of-memory\nevent occurs, you can increase the instance's memory.\nAlternatively, you can reduce the memory usage by limiting the number of\ndatabase connections or lowering database flags such as\n`shared_buffers`, `work_mem`, or `max_connections`. Lowering these\nflags can limit the performance of your instance.\n\nOut of memory\n-------------\n\nWhen there's insufficient memory to handle the database workload, as a last resort, the\nunderlying Linux operating system uses the [`out-of-memory (OOM) killer`](https://linux-mm.org/OOM_Killer)\nto end a process to release memory. Cloud SQL is\nconfigured so that the `OOM killer` targets only the PostgreSQL worker\nprocesses. The postmaster process is preserved in this situation so that it\nonly has to end all existing database connections and run a recovery\nto protect the integrity of the database. If this happens, there are moments of\nservice disruption and downtime to the database. In the PostgreSQL database log,\nmessages like the following appear: \n\n```bash\n2021-10-24 23:34:22.265 UTC [7]: [663-1] db=,user= LOG: server process (PID 1255039) was terminated by signal 9: Killed\n2021-10-24 23:34:22.265 UTC [7]: [664-1] db=,user= DETAIL: Failed process was running: SELECT * FROM tab ORDER BY col\n2021-10-24 23:34:22.277 UTC [7]: [665-1] db=,user= LOG: terminating any other active server processes\n2021-10-24 23:34:22.278 UTC [1255458]: [1-1] db=postgres,user=postgres WARNING: terminating connection because of crash of another server process\n2021-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.\n2021-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.\n2021-10-24 23:34:22.278 UTC [1255458]: [4-1] db=postgres,user=postgres CONTEXT: while updating tuple (27,18) in relation \"tab\"\n...\n2021-10-24 23:34:22.558 UTC [1255477]: [1-1] db=postgres,user=postgres FATAL: the database system is in recovery mode\n...\n2021-10-24 23:34:25.579 UTC [7]: [666-1] db=,user= LOG: all server processes terminated; reinitializing\n...\n2021-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\n2021-10-24 23:34:25.776 UTC [1255482]: [2-1] db=,user= LOG: database system was not properly shut down; automatic recovery in progress\n2021-10-24 23:34:25.789 UTC [1255482]: [3-1] db=,user= LOG: redo starts at 227/AB359400\n2021-10-24 23:34:38.957 UTC [1255482]: [4-1] db=,user= LOG: redo done at 229/4621F508\n2021-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\n2021-10-24 23:34:39.290 UTC [7]: [667-1] db=,user= LOG: database system is ready to accept connections\n```\n\nWhat's next\n-----------\n\n- Learn more about [configuring memory usage](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY) in PostgreSQL.\n- [Tuning your PostgreSQL server](https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server)."]]