Optimiza el uso elevado de memoria en las instancias

Es un problema común tener instancias que consumen mucha memoria o que generan eventos de memoria insuficiente (OOM). Una instancia de base de datos que se ejecuta con una utilización de memoria alta suele causar problemas de rendimiento, atascos o, incluso, tiempo de inactividad de la base de datos.

Algunos bloques de memoria de MySQL se usan en todo el mundo. Esto significa que todas las cargas de trabajo de consultas comparten ubicaciones de memoria, están ocupadas todo el tiempo y se liberan solo cuando se detiene el proceso de MySQL. Algunos bloques de memoria se basan en sesiones, lo que significa que apenas la sesión se cierra, la memoria que utiliza esa sesión también se libera y se devuelve al sistema.

Cuando una instancia de Cloud SQL para MySQL tiene un uso de memoria alto, Cloud SQL recomienda que identifiques la consulta o el proceso que usa mucha memoria y liberes esa memoria. El consumo de memoria de MySQL se divide en tres partes principales:

  • Consumo de memoria de subprocesos y procesos
  • Consumo de memoria del búfer
  • Consumo de memoria de la caché

Consumo de memoria de subprocesos y procesos

Cada sesión de usuario consume memoria según las consultas que se ejecutan, los búferes o la caché que usa esa sesión, y se controla mediante los parámetros de sesión de MySQL. Entre los parámetros principales, se incluyen los siguientes:

  • thread_stack
  • net_buffer_length
  • read_buffer_size
  • read_rnd_buffer_size
  • sort_buffer_size
  • join_buffer_size
  • max_heap_table_size
  • tmp_table_size

Si hay N cantidad de consultas en ejecución en un momento determinado, cada consulta consume memoria de acuerdo con estos parámetros durante la sesión.

Consumo de memoria del búfer

Esta parte de la memoria es común para todas las búsquedas y se controla con parámetros como innodb_buffer_pool_size, innodb_log_buffer_size y key_buffer_size.

El grupo de búferes de InnoDB, que se configura con la marca innodb_buffer_pool_size, ocupa una cantidad significativa de memoria en tu instancia de Cloud SQL para MySQL y funciona como una caché para mejorar el rendimiento. Para reducir el riesgo de eventos con falta de memoria (OOM), puedes habilitar el búfer de memoria administrado (vista previa).

Consumo de memoria de la caché

La memoria caché incluye una caché de consultas, que se usa para guardar las consultas y sus resultados, lo que permite lograr una recuperación de datos más rápida de las mismas consultas con posterioridad. También incluye la caché binlog para contener los cambios realizados en el registro binario mientras se ejecuta la transacción, y binlog_cache_size la controla.

Otros consumos de memoria

La memoria también se usa para las operaciones de unión y orden. Si tus consultas usan operaciones de orden o unión, esas consultas usan memoria en función de join_buffer_size y sort_buffer_size.

Además, si habilitas el esquema de rendimiento, consume memoria. Para verificar el uso de memoria del esquema de rendimiento, usa la siguiente consulta:

SELECT *
FROM
  performance_schema.memory_summary_global_by_event_name
WHERE EVENT_NAME LIKE 'memory/performance_schema/%';

Existen muchos instrumentos disponibles en MySQL que puedes configurar para supervisar el uso de memoria a través del esquema de rendimiento. Para obtener más información, consulta la documentación de MySQL.

El parámetro relacionado con MyISAM para la inserción de datos masivos es bulk_insert_buffer_size.

Para obtener información sobre cómo MySQL usa memoria, consulta la documentación de MySQL.

Recomendaciones

En las siguientes secciones, se ofrecen algunas recomendaciones para un uso óptimo de la memoria.

Habilita el grupo de búferes administrado

Si el uso de memoria es alto, es posible que tu instancia experimente eventos de memoria insuficiente (OOM). Para evitar eventos de OOM, habilita el grupo de búferes administrado para reducir el valor de innodb_buffer_pool_size y liberar memoria. Cuando el uso de memoria se estabiliza en un valor más bajo, MySQL aumenta el valor de innodb_buffer_pool_size de forma incremental hasta su valor original.

No puedes habilitar el búfer de memoria administrado para las instancias de núcleo compartido ni para MySQL 5.6 o MySQL 5.7.

Para habilitar el búfer de memoria administrado para tu instancia, establece la marca innodb_cloudsql_managed_buffer_pool en on. Para obtener más información sobre cómo configurar marcas de bases de datos, consulta Configura una marca de base de datos.

Cambiar el valor de la marca innodb_cloudsql_managed_buffer_pool no requiere que se reinicie la instancia de Cloud SQL.

De forma predeterminada, si tu base de datos de MySQL supera el 95% de la memoria asignada, Cloud SQL comienza a reducir el tamaño de su innodb_buffer_pool_size. Para modificar el umbral del 95%, establece la marca innodb_cloudsql_managed_buffer_pool_threshold_pct en un valor de porcentaje diferente. Por ejemplo, para ajustar el umbral al 97%, usa el siguiente comando:

gcloud sql instances patch INSTANCE_NAME
   --database-flags=EXISTING_FLAGS,innodb_cloudsql_managed_buffer_pool=on,\
     innodb_cloudsql_managed_buffer_pool_threshold_pct=97

Puedes establecer la marca innodb_cloudsql_managed_buffer_pool_threshold_pct en un valor entero entre 50 y 99. Cambiar el valor del umbral de uso de memoria no requiere reiniciar la instancia de Cloud SQL.

Reducir el tamaño del búfer no puede evitar los errores de OOM en todos los casos. Por ejemplo, algunas cargas de trabajo pueden consumir memoria de forma insostenible o aumentar a un ritmo repentino, algunas instancias de Cloud SQL pueden estar subaprovisionadas o es posible que el búfer de memoria no se haya calentado. Es posible que Cloud SQL no pueda liberar memoria con la suficiente rapidez para adaptarse a los cambios repentinos en la carga de trabajo de la memoria. Además, Cloud SQL no puede admitir valores mal configurados de otras marcas de memoria.

Usa el Explorador de métricas para identificar el uso de memoria

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

En general, si tienes menos del 10% de memoria combinada en database/memory/components.cache y database/memory/components.free, el riesgo de un evento de OOM es alto. Para supervisar el uso de memoria y evitar los eventos de OOM, te recomendamos que configures una política de alertas con una condición de límite de métrica en database/memory/components.usage.

En la siguiente tabla, se muestra la relación entre la memoria de tu instancia y el límite de alertas recomendado:

Memoria de la instancia Umbral de alertas recomendado
Menor o igual a 16 GB 90%
Más de 16 GB 95%

Calcula el consumo de memoria

Calcula el uso máximo de memoria de tu base de datos de MySQL a fin de seleccionar el tipo de instancia adecuado para tu base de datos de MySQL. Usa la siguiente fórmula:

Uso máximo de memoria de MySQL = innodb_buffer_pool_size + innodb_additional_mem_pool_size + innodb_log_buffer_size + tmp_table_size + key_buffer_size + ((read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size) x max_connections)

Estos son los parámetros que se usan en la fórmula:

  • innodb_buffer_pool_size: es el tamaño en bytes del grupo de búferes, el área de la memoria en la que InnoDB almacena en caché los datos de la tabla y los índices.
  • innodb_additional_mem_pool_size: es el tamaño en bytes de un grupo de memoria que InnoDB usa para almacenar información del diccionario de datos y otras estructuras de datos internas.
  • innodb_log_buffer_size: es el tamaño en bytes del búfer que InnoDB usa para escribir en los archivos de registro en el disco.
  • tmp_table_size: es el tamaño máximo de las tablas temporales internas en memoria que creó el motor de almacenamiento MEMORY y, a partir de MySQL 8.0.28, el motor de almacenamiento TempTable.
  • key_buffer_size: es el tamaño del búfer que se usa para los bloques de índice. Los bloques de índice para las tablas MyISAM se almacenan en búfer y se comparten en todos los subprocesos.
  • read_buffer_size: cada subproceso que realiza un análisis secuencial para una tabla MyISAM asigna un búfer de este tamaño (en bytes) para cada tabla que analiza.
  • read_rnd_buffer_size: esta variable se usa para las lecturas de tablas MyISAM, para cualquier motor de almacenamiento y para la optimización de lectura de varios rangos.
  • sort_buffer_size: cada sesión que debe realizar un orden asigna un búfer de este tamaño. sort_buffer_size no es específico de ningún motor de almacenamiento y se aplica de forma general para la optimización.
  • join_buffer_size: Es el tamaño mínimo del búfer que se usa para los análisis de índices sin formato, los análisis de índices de rango y las uniones que no usan índices y, por lo tanto, realizan análisis de tablas completos.
  • max_connections: es la cantidad máxima permitida de conexiones simultáneas de clientes.

Soluciona problemas de consumo elevado de memoria

  • Ejecuta SHOW PROCESSLIST para ver las consultas en curso que consumen memoria. Muestra todos los subprocesos conectados y sus instrucciones de SQL en ejecución, y, luego, intenta optimizarlas. Presta atención a las columnas de estado y duración.

    mysql> SHOW [FULL] PROCESSLIST;
    
    
  • Verifica SHOW ENGINE INNODB STATUS en la sección BUFFER POOL AND MEMORY para ver el uso actual del grupo de búferes y la memoria, lo que puede ayudarte a configurar el tamaño del grupo de búferes.

    mysql> SHOW ENGINE INNODB STATUS \G
    ----------------------
    BUFFER POOL AND MEMORY
    ----------------------
    Total memory allocated 398063986; in additional pool allocated 0
    Dictionary memory allocated 12056
    Buffer pool size 89129
    Free buffers 45671
    Database pages 1367
    Old database pages 0
    Modified db pages 0
    
  • Usa el comando SHOW variables de MySQL para verificar los valores del contador, que te brindan información como la cantidad de tablas temporales, la cantidad de subprocesos, la cantidad de cachés de tablas, las páginas sucias, las tablas abiertas y el uso del grupo de búferes.

    mysql> SHOW variables like 'VARIABLE_NAME'
    

Aplicar cambios

Después de analizar el uso de memoria de diferentes componentes, configura la marca adecuada en tu base de datos de MySQL. Para cambiar la marca en la instancia de Cloud SQL para MySQL, puedes usar la Google Cloud consola o la CLI de gcloud. Para cambiar el valor de la marca con la consola de Google Cloud , edita la sección Flags, selecciona la marca y, luego, ingresa el valor nuevo.

Por último, si el uso de memoria sigue siendo alto y crees que las consultas y los valores de marcas están optimizados, considera aumentar el tamaño de la instancia para evitar eventos OOM.

¿Qué sigue?