Optimizar el uso elevado de memoria en las instancias

En este documento se explica cómo identificar un uso elevado de memoria en las instancias de Cloud SQL y se ofrecen recomendaciones sobre cómo solucionar los problemas relacionados con la memoria.

Para saber cómo configurar el uso de memoria de una instancia de Cloud SQL, consulta las prácticas recomendadas para gestionar el uso de memoria.

Identificar un uso elevado de memoria

En las siguientes secciones se describen situaciones en las que se usa mucha memoria.

Usar el explorador de métricas para identificar el uso de memoria

Puedes consultar el uso de memoria de la instancia con la métrica database/memory/components.usage en Explorador de métricas.

Usa Estadísticas de consultas para analizar el plan de explicación de las consultas que consumen muchos recursos

Información valiosa sobre las consultas te ayuda a detectar, diagnosticar y evitar problemas de rendimiento de las consultas en las bases de datos de Cloud SQL. La información útil sobre las consultas te ofrece una lista de consultas de larga duración junto con su plan EXPLAIN (documentación de PostgreSQL). Revisa el plan de explicación e identifica la parte de la consulta que tiene un método de análisis con un uso de memoria elevado. Independientemente del tiempo de ejecución de la consulta, Estadísticas de consultas te proporciona el plan de explicación de todas las consultas. Identifica las consultas complejas que tardan más tiempo para saber cuáles bloquean la memoria durante más tiempo.

Entre los métodos de análisis de PostgreSQL habituales que usan mucha memoria se incluyen los siguientes:

  • Análisis de montículo de mapa de bits
  • Ordenación rápida
  • Combinación hash o Hash

Uso elevado de memoria y registros relevantes de instancias habilitadas para Gemini

Si tienes Gemini habilitado, en lugar de un error por falta de memoria (OOM) que provoque un tiempo de inactividad de la base de datos, se terminará una conexión que ejecute una consulta con un uso elevado de memoria, lo que evitará que la base de datos se quede inactiva. Para identificar la consulta predeterminada, puedes consultar los registros de la base de datos y buscar las siguientes entradas:

  (...timestamp….) db=postgres, user=customer FATAL: terminating connection due to administrator command

Se muestra el siguiente registro de la base de datos de Cloud SQL para PostgreSQL, que recoge la consulta de uso elevado de memoria que se ha terminado para evitar que se quede sin memoria. La consulta es una versión normalizada de la consulta original:

  db=postgres,user=customer LOG:  postgres process with PID 1734 for the query "SELECT COUNT(product) AS item_count FROM test_table WHERE product_type = $1 AND product LIKE $2 AND c6_2 IN ($3,$4,$5,$6,$7)" has been cancelled.

Las notificaciones también se muestran en la página Instancias de Cloud SQL para los siguientes eventos:

  • Uso de la memoria de la instancia durante las últimas 24 horas.
  • Lista de consultas normalizadas que se han cancelado en las últimas 24 horas.
  • Un enlace a la documentación de Google sobre cómo optimizar el uso de memoria.

Uso elevado de memoria: recomendaciones

Las siguientes recomendaciones abordan los problemas habituales relacionados con la memoria. Si la instancia sigue usando una gran cantidad de memoria, es muy probable que acabe teniendo un problema de out of memory. Si las demandas de memoria de PostgreSQL u otro proceso provocan que el sistema se quede sin memoria, verás un mensaje del kernel Out of Memory en los registros de PostgreSQL y la instancia de PostgreSQL se detendrá. Por ejemplo:

Out of Memory: Killed process 12345 (postgres)

El caso más habitual en el que se produce un problema de OOM es cuando se usa un valor más alto de work_mem con un gran número de conexiones activas. Por lo tanto, si recibes errores de falta de memoria con frecuencia o quieres evitarlos en tu instancia de Cloud SQL para PostgreSQL, te recomendamos que sigas estas recomendaciones:

  • Serie work_mem

    Las consultas que usan ordenación rápida son más rápidas que las que usan ordenación por fusión externa. Sin embargo, la primera opción puede provocar que se agote la memoria. Para solucionar este problema, asigne al valor de work_mem un valor razonable que equilibre las operaciones de ordenación que se producen en la memoria y en el disco. También puedes plantearte definir work_mem a nivel de sesión en lugar de hacerlo para toda la instancia.

  • Monitorizar las sesiones activas

    Cada conexión usa una cantidad determinada de memoria. Usa la siguiente consulta para comprobar el número de conexiones activas:

      SELECT
        state,
        usename,
        count(1)
      FROM
        pg_stat_activity
      WHERE
        pid <> pg_backend_pid()
      GROUP BY
        state,
        usename
      ORDER BY
        1;
    

    Si tiene un gran número de sesiones activas, analice la causa principal de este problema. Por ejemplo, los bloqueos de transacciones.

  • Serie shared_buffers

    Si shared_buffers tiene un valor más alto, considera la posibilidad de reducirlo para que la memoria se pueda usar en otras operaciones, como work_mem, o para establecer nuevas conexiones.shared_buffers

    Tasa de aciertos de caché

    Por lo general, PostgreSQL intenta mantener en la caché los datos a los que accedes con más frecuencia. Cuando un cliente solicita los datos, si ya están almacenados en caché en búferes compartidos, se le proporcionan directamente. Esto se denomina acierto de caché. Si los datos no están presentes en los búferes compartidos, primero se obtienen de un disco y se almacenan en los búferes compartidos, y luego se proporcionan al cliente. Esto se denomina fallo de caché. La proporción de aciertos de caché mide cuántas solicitudes de contenido ha gestionado la caché en comparación con las solicitudes recibidas. Ejecuta la siguiente consulta para comprobar la proporción de aciertos de caché de las solicitudes de tabla en la instancia de PostgreSQL:

    SELECT
      sum(heap_blks_read) as heap_read,
      sum(heap_blks_hit)  as heap_hit,
      sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) as ratio
    FROM
      pg_statio_user_tables;
    

    Ejecuta la siguiente consulta para comprobar la proporción de aciertos de caché de las solicitudes de índice en la instancia de PostgreSQL:

      SELECT
        sum(idx_blks_read) as idx_read,
        sum(idx_blks_hit)  as idx_hit,
        (sum(idx_blks_hit) - sum(idx_blks_read)) / sum(idx_blks_hit) as ratio
      FROM
        pg_statio_user_indexes;
    

    Por lo general, se considera que una proporción de aciertos de caché de entre el 95 y el 99% es un buen valor.

  • En Cloud SQL para PostgreSQL, la marca huge_pages está habilitada de forma predeterminada para mejorar la gestión de la memoria. Para obtener más información sobre huge_pages, consulta la documentación de PostgreSQL.

  • Serie max_locks_per_transaction

    El valor max_locks_per_transaction indica el número de objetos de base de datos que se pueden bloquear simultáneamente. En la mayoría de los casos, el valor predeterminado de 64 es suficiente. Sin embargo, si trabajas con un conjunto de datos grande, es posible que se produzcan errores de falta de memoria. Aumenta el valor de max_locks_per_transaction lo suficiente para evitar errores de falta de memoria.

    El valor de max_locks_per_transaction debe ser max_locks_per_transaction * (max_connections + max_prepared_transactions) objetos. Esto significa que, si tienes 300.000 objetos y el valor de max_connections es 200, max_locks_per_transaction debe ser 1500.

  • Serie max_pred_locks_per_transaction

    La transacción puede fallar si tiene clientes que tocan muchas tablas diferentes en una sola transacción serializable. En ese caso, te recomendamos que aumentes max_pred_locks_per_transaction a un valor razonablemente alto. Al igual que max_locks_per_transaction, max_pred_locks_per_transaction también usa memoria compartida, así que no le asignes un valor demasiado alto.

  • Si el uso de memoria sigue siendo elevado y crees que esas consultas son tráfico legítimo, plantéate aumentar el número de recursos de memoria de tu instancia para evitar que la base de datos falle o que se produzca un tiempo de inactividad.

Siguientes pasos