

# Solución de problemas de uso de memoria de bases de datos Aurora MySQL
<a name="ams-workload-memory"></a>

Si bien CloudWatch, Supervisión mejorada e Información de rendimiento proporcionan una visión general óptima del uso de la memoria en el sistema operativo, por ejemplo, la cantidad de memoria que utiliza el proceso de la base de datos, no permiten desglosar qué conexiones o componentes del motor podrían estar causando este uso de memoria.

Para solucionar este problema, puede utilizar Performance Schema y el esquema de `sys`. En Aurora MySQL versión  3, la instrumentación de memoria se habilita de forma predeterminada cuando se habilita Performance Schema. En Aurora MySQL versión  2, solo se habilita por defecto la instrumentación de memoria para el uso de memoria de Performance Schema. Para obtener información sobre las tablas disponibles en Performance Schema para realizar un seguimiento del uso de la memoria y habilitar la instrumentación de memoria de Performance Schema, consulte la [tablas de resumen de memoria](https://dev.mysql.com/doc/refman/8.3/en/performance-schema-memory-summary-tables.html) en la documentación de MySQL. Para obtener más información sobre el uso de Performance Schema con Información de rendimiento, consulte [Descripción general de Performance Schema para Información de rendimiento en Aurora MySQL](USER_PerfInsights.EnableMySQL.md).

Si bien se encuentra disponible información detallada en Performance Schema para realizar un seguimiento del uso actual de la memoria, el [esquema sys](https://dev.mysql.com/doc/refman/8.0/en/sys-schema.html) de MySQL tiene vistas en la parte superior de las tablas de Performance Schema que puede utilizar para identificar rápidamente dónde se utiliza la memoria.

En el esquema `sys`, están disponibles las siguientes vistas para realizar un seguimiento del uso de la memoria por conexión, componente y consulta.


| Visualización | Descripción | 
| --- | --- | 
|  [memory\$1by\$1host\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-host-by-current-bytes.html)  |  Proporciona información sobre el uso de la memoria del motor por el host. Esto puede resultar útil para identificar qué servidores de aplicaciones o hosts de clientes consumen memoria.  | 
|  [memory\$1by\$1thread\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-thread-by-current-bytes.html)  |  Proporciona información sobre el uso de la memoria del motor por ID de subproceso. El ID de subproceso en MySQL puede ser una conexión de cliente o un subproceso en segundo plano. Puede asignar ID de subprocesos a ID de conexión de MySQL mediante la vista [sys.processlist](https://dev.mysql.com/doc/refman/8.0/en/sys-processlist.html) o la tabla [performance\$1schema.threads](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-threads-table.html).  | 
|  [memory\$1by\$1user\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-user-by-current-bytes.html)  |  Proporciona información sobre el uso de la memoria del motor por usuario. Esto puede resultar útil para identificar qué cuentas de usuario o clientes consumen memoria.  | 
|  [memory\$1global\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-global-by-current-bytes.html)  |  Proporciona información sobre el uso de la memoria del motor por componente del motor. Esto puede resultar útil para identificar el uso de memoria global por parte de búferes o componentes del motor. Por ejemplo, es posible que vea el evento `memory/innodb/buf_buf_pool` del conjunto de búferes de InnoDB o el evento `memory/sql/Prepared_statement::main_mem_root` de las instrucciones preparadas.  | 
|  [memory\$1global\$1total](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-global-total.html)  |  Proporciona una descripción general del uso total de memoria del que se ha hecho un seguimiento en el motor de base de datos.  | 

En Aurora MySQL versión  3.05 y versiones posteriores, también puede realizar un seguimiento del uso de memoria máximo mediante resumen de instrucciones en las [tablas de resumen de instrucciones de Performance Schema](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html). Las tablas de resumen de instrucciones contienen resúmenes normalizados de instrucciones y estadísticas agregadas sobre su ejecución. La columna `MAX_TOTAL_MEMORY` puede ayudarle a identificar la memoria máxima utilizada por el resumen de consultas desde la última vez que se restablecieron las estadísticas o desde que se reinició la instancia de la base de datos. Esto puede resultar útil para identificar consultas específicas que podrían estar consumiendo mucha memoria.

**nota**  
Performance Schema y el esquema `sys` muestran el uso actual de memoria en el servidor y los niveles máximos de memoria consumida por conexión y componente del motor. Como Performance Schema se mantiene en la memoria, la información se restablece cuando se reinicia la instancia de base de datos. Para mantener un historial a lo largo del tiempo, le recomendamos que configure la recuperación y el almacenamiento de estos datos fuera de Performance Schema.

**Topics**
+ [Ejemplo 1: uso elevado y continuo de memoria](#ams-workload-memory.example1)
+ [Ejemplo 2: picos de memoria de transitorios](#ams-workload-memory.example2)
+ [Ejemplo 3: la memoria liberable cae continuamente y no se recupera](#ams-workload-memory.example3)

## Ejemplo 1: uso elevado y continuo de memoria
<a name="ams-workload-memory.example1"></a>

Si observamos globalmente `FreeableMemory` en CloudWatch, podemos ver que el uso de memoria ha aumentado en gran medida a las 02:59 UTC del 26 de marzo de 2024.

![\[Gráfico de FreeableMemory que muestra un uso elevado de memoria.\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/AuroraUserGuide/images/ams-freeable-memory.png)


Esto no nos muestra el panorama completo. Para determinar qué componente está consumiendo más memoria, puede iniciar sesión en la base de datos y ver `sys.memory_global_by_current_bytes`. Esta tabla contiene una lista de eventos de memoria de los que hace seguimiento MySQL, junto con información sobre la asignación de memoria por evento. Cada evento de seguimiento de memoria comienza con `memory/%`, seguido de otra información sobre el componente o la característica del motor al que está asociado el evento.

Por ejemplo, `memory/performance_schema/%` es para eventos de memoria relacionados con Performance Schema, `memory/innodb/%` es para InnoDB, etc. Para obtener información sobre las convenciones de nomenclatura de los eventos, consulte [Performance Schema Instrument Naming Conventions](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-instrument-naming.html) en la documentación de MySQL.

A partir de la siguiente consulta, podemos encontrar al probable culpable en función de `current_alloc`, pero también podemos ver muchos eventos de `memory/performance_schema/%`.

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                                                  | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root                                |        512817 | 4.91 GiB      | 10.04 KiB         |     512823 | 4.91 GiB   | 10.04 KiB      |
| memory/performance_schema/prepared_statements_instances                     |           252 | 488.25 MiB    | 1.94 MiB          |        252 | 488.25 MiB | 1.94 MiB       |
| memory/innodb/hash0hash                                                     |             4 | 79.07 MiB     | 19.77 MiB         |          4 | 79.07 MiB  | 19.77 MiB      |
| memory/performance_schema/events_errors_summary_by_thread_by_error          |          1028 | 52.27 MiB     | 52.06 KiB         |       1028 | 52.27 MiB  | 52.06 KiB      |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name |             4 | 47.25 MiB     | 11.81 MiB         |          4 | 47.25 MiB  | 11.81 MiB      |
| memory/performance_schema/events_statements_summary_by_digest               |             1 | 40.28 MiB     | 40.28 MiB         |          1 | 40.28 MiB  | 40.28 MiB      |
| memory/performance_schema/memory_summary_by_thread_by_event_name            |             4 | 31.64 MiB     | 7.91 MiB          |          4 | 31.64 MiB  | 7.91 MiB       |
| memory/innodb/memory                                                        |         15227 | 27.44 MiB     | 1.85 KiB          |      20619 | 33.33 MiB  | 1.66 KiB       |
| memory/sql/String::value                                                    |         74411 | 21.85 MiB     |  307 bytes        |      76867 | 25.54 MiB  |  348 bytes     |
| memory/sql/TABLE                                                            |          8381 | 21.03 MiB     | 2.57 KiB          |       8381 | 21.03 MiB  | 2.57 KiB       |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
10 rows in set (0.02 sec)
```

Mencionamos anteriormente que Performance Schema se almacena en la memoria, lo que significa que también se realiza un seguimiento de ello en la instrumentación de memoria de `performance_schema`.

**nota**  
Si observa que Performance Schema utiliza mucha memoria y quiere limitar su uso, puede ajustar los parámetros de la base de datos en función de sus necesidades. Para obtener más información, consulte [The Performance Schema memory-allocation model](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-memory-model.html) en la documentación de MySQL.

Para facilitar la lectura, puede volver a ejecutar la misma consulta pero excluir los eventos de Performance Schema. En el resultado se observa lo siguiente:
+ El elemento que consume más memoria es `memory/sql/Prepared_statement::main_mem_root`.
+ La columna `current_alloc` nos indica que MySQL tiene 4,91 GiB actualmente asignados a este evento.
+ `high_alloc column` nos indica que 4,91 GiB es el nivel máximo de `current_alloc` desde que se restablecieron las estadísticas por última vez o desde que se reinició el servidor. Esto significa que `memory/sql/Prepared_statement::main_mem_root` está en su valor más alto.

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name NOT LIKE 'memory/performance_schema/%' LIMIT 10;

+-----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                    | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+-----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root  |        512817 | 4.91 GiB      | 10.04 KiB         |     512823 | 4.91 GiB   | 10.04 KiB      |
| memory/innodb/hash0hash                       |             4 | 79.07 MiB     | 19.77 MiB         |          4 | 79.07 MiB  | 19.77 MiB      |
| memory/innodb/memory                          |         17096 | 31.68 MiB     | 1.90 KiB          |      22498 | 37.60 MiB  | 1.71 KiB       |
| memory/sql/String::value                      |        122277 | 27.94 MiB     |  239 bytes        |     124699 | 29.47 MiB  |  247 bytes     |
| memory/sql/TABLE                              |          9927 | 24.67 MiB     | 2.55 KiB          |       9929 | 24.68 MiB  | 2.55 KiB       |
| memory/innodb/lock0lock                       |          8888 | 19.71 MiB     | 2.27 KiB          |       8888 | 19.71 MiB  | 2.27 KiB       |
| memory/sql/Prepared_statement::infrastructure |        257623 | 16.24 MiB     |   66 bytes        |     257631 | 16.24 MiB  |   66 bytes     |
| memory/mysys/KEY_CACHE                        |             3 | 16.00 MiB     | 5.33 MiB          |          3 | 16.00 MiB  | 5.33 MiB       |
| memory/innodb/sync0arr                        |             3 | 7.03 MiB      | 2.34 MiB          |          3 | 7.03 MiB   | 2.34 MiB       |
| memory/sql/THD::main_mem_root                 |           815 | 6.56 MiB      | 8.24 KiB          |        849 | 7.19 MiB   | 8.67 KiB       |
+-----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
10 rows in set (0.06 sec)
```

Por el nombre del evento, podemos decir que esta memoria se está utilizando para instrucciones preparadas. Si quiere ver qué conexiones utilizan esta memoria, puede consultar [memory\$1by\$1thread\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-thread-by-current-bytes.html).

En el siguiente ejemplo, cada conexión tiene aproximadamente 7 MiB asignados, con un nivel máximo de aproximadamente 6,29 MiB (`current_max_alloc`). Esto tiene sentido, ya que el ejemplo utiliza `sysbench` con 80 tablas y 800 conexiones con instrucciones preparadas. Si desea reducir el uso de memoria en este caso, puede optimizar el uso que hace su aplicación de las instrucciones preparadas para reducir el consumo de memoria.

```
mysql> SELECT * FROM sys.memory_by_thread_by_current_bytes;

+-----------+-------------------------------------------+--------------------+-------------------+-------------------+-------------------+-----------------+
| thread_id | user                                      | current_count_used | current_allocated | current_avg_alloc | current_max_alloc | total_allocated |
+-----------+-------------------------------------------+--------------------+-------------------+-------------------+-------------------+-----------------+
|        46 | rdsadmin@localhost                        |                405 | 8.47 MiB          | 21.42 KiB         | 8.00 MiB          | 155.86 MiB      |
|        61 | reinvent@10.0.4.4                         |               1749 | 6.72 MiB          | 3.93 KiB          | 6.29 MiB          | 14.24 MiB       |
|       101 | reinvent@10.0.4.4                         |               1845 | 6.71 MiB          | 3.72 KiB          | 6.29 MiB          | 14.50 MiB       |
|        55 | reinvent@10.0.4.4                         |               1674 | 6.68 MiB          | 4.09 KiB          | 6.29 MiB          | 14.13 MiB       |
|        57 | reinvent@10.0.4.4                         |               1416 | 6.66 MiB          | 4.82 KiB          | 6.29 MiB          | 13.52 MiB       |
|       112 | reinvent@10.0.4.4                         |               1759 | 6.66 MiB          | 3.88 KiB          | 6.29 MiB          | 14.17 MiB       |
|        66 | reinvent@10.0.4.4                         |               1428 | 6.64 MiB          | 4.76 KiB          | 6.29 MiB          | 13.47 MiB       |
|        75 | reinvent@10.0.4.4                         |               1389 | 6.62 MiB          | 4.88 KiB          | 6.29 MiB          | 13.40 MiB       |
|       116 | reinvent@10.0.4.4                         |               1333 | 6.61 MiB          | 5.08 KiB          | 6.29 MiB          | 13.21 MiB       |
|        90 | reinvent@10.0.4.4                         |               1448 | 6.59 MiB          | 4.66 KiB          | 6.29 MiB          | 13.58 MiB       |
|        98 | reinvent@10.0.4.4                         |               1440 | 6.57 MiB          | 4.67 KiB          | 6.29 MiB          | 13.52 MiB       |
|        94 | reinvent@10.0.4.4                         |               1433 | 6.57 MiB          | 4.69 KiB          | 6.29 MiB          | 13.49 MiB       |
|        62 | reinvent@10.0.4.4                         |               1323 | 6.55 MiB          | 5.07 KiB          | 6.29 MiB          | 13.48 MiB       |
|        87 | reinvent@10.0.4.4                         |               1323 | 6.55 MiB          | 5.07 KiB          | 6.29 MiB          | 13.25 MiB       |
|        99 | reinvent@10.0.4.4                         |               1346 | 6.54 MiB          | 4.98 KiB          | 6.29 MiB          | 13.24 MiB       |
|       105 | reinvent@10.0.4.4                         |               1347 | 6.54 MiB          | 4.97 KiB          | 6.29 MiB          | 13.34 MiB       |
|        73 | reinvent@10.0.4.4                         |               1335 | 6.54 MiB          | 5.02 KiB          | 6.29 MiB          | 13.23 MiB       |
|        54 | reinvent@10.0.4.4                         |               1510 | 6.53 MiB          | 4.43 KiB          | 6.29 MiB          | 13.49 MiB       |
.                                                                                                                                                          .
.                                                                                                                                                          .
.                                                                                                                                                          .
|       812 | reinvent@10.0.4.4                         |               1259 | 6.38 MiB          | 5.19 KiB          | 6.29 MiB          | 13.05 MiB       |
|       214 | reinvent@10.0.4.4                         |               1279 | 6.38 MiB          | 5.10 KiB          | 6.29 MiB          | 12.90 MiB       |
|       325 | reinvent@10.0.4.4                         |               1254 | 6.38 MiB          | 5.21 KiB          | 6.29 MiB          | 12.99 MiB       |
|       705 | reinvent@10.0.4.4                         |               1273 | 6.37 MiB          | 5.13 KiB          | 6.29 MiB          | 13.03 MiB       |
|       530 | reinvent@10.0.4.4                         |               1268 | 6.37 MiB          | 5.15 KiB          | 6.29 MiB          | 12.92 MiB       |
|       307 | reinvent@10.0.4.4                         |               1263 | 6.37 MiB          | 5.17 KiB          | 6.29 MiB          | 12.87 MiB       |
|       738 | reinvent@10.0.4.4                         |               1260 | 6.37 MiB          | 5.18 KiB          | 6.29 MiB          | 13.00 MiB       |
|       819 | reinvent@10.0.4.4                         |               1252 | 6.37 MiB          | 5.21 KiB          | 6.29 MiB          | 13.01 MiB       |
|        31 | innodb/srv_purge_thread                   |              17810 | 3.14 MiB          |  184 bytes        | 2.40 MiB          | 205.69 MiB      |
|        38 | rdsadmin@localhost                        |                599 | 1.76 MiB          | 3.01 KiB          | 1.00 MiB          | 25.58 MiB       |
|         1 | sql/main                                  |               3756 | 1.32 MiB          |  367 bytes        | 355.78 KiB        | 6.19 MiB        |
|       854 | rdsadmin@localhost                        |                 46 | 1.08 MiB          | 23.98 KiB         | 1.00 MiB          | 5.10 MiB        |
|        30 | innodb/clone_gtid_thread                  |               1596 | 573.14 KiB        |  367 bytes        | 254.91 KiB        | 970.69 KiB      |
|        40 | rdsadmin@localhost                        |                235 | 245.19 KiB        | 1.04 KiB          | 128.88 KiB        | 808.64 KiB      |
|       853 | rdsadmin@localhost                        |                 96 | 94.63 KiB         | 1009 bytes        | 29.73 KiB         | 422.45 KiB      |
|        36 | rdsadmin@localhost                        |                 33 | 36.29 KiB         | 1.10 KiB          | 16.08 KiB         | 74.15 MiB       |
|        33 | sql/event_scheduler                       |                  3 | 16.27 KiB         | 5.42 KiB          | 16.04 KiB         | 16.27 KiB       |
|        35 | sql/compress_gtid_table                   |                  8 | 14.20 KiB         | 1.77 KiB          | 8.05 KiB          | 18.62 KiB       |
|        25 | innodb/fts_optimize_thread                |                 12 | 1.86 KiB          |  158 bytes        |  648 bytes        | 1.98 KiB        |
|        23 | innodb/srv_master_thread                  |                 11 | 1.23 KiB          |  114 bytes        |  361 bytes        | 24.40 KiB       |
|        24 | innodb/dict_stats_thread                  |                 11 | 1.23 KiB          |  114 bytes        |  361 bytes        | 1.35 KiB        |
|         5 | innodb/io_read_thread                     |                  1 |  144 bytes        |  144 bytes        |  144 bytes        |  144 bytes      |
|         6 | innodb/io_read_thread                     |                  1 |  144 bytes        |  144 bytes        |  144 bytes        |  144 bytes      |
|         2 | sql/aws_oscar_log_level_monitor           |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         4 | innodb/io_ibuf_thread                     |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         7 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         8 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         9 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        10 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        11 | innodb/srv_lra_thread                     |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        12 | innodb/srv_akp_thread                     |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        18 | innodb/srv_lock_timeout_thread            |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |  248 bytes      |
|        19 | innodb/srv_error_monitor_thread           |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        20 | innodb/srv_monitor_thread                 |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        21 | innodb/buf_resize_thread                  |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        22 | innodb/btr_search_sys_toggle_thread       |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        32 | innodb/dict_persist_metadata_table_thread |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        34 | sql/signal_handler                        |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
+-----------+-------------------------------------------+--------------------+-------------------+-------------------+-------------------+-----------------+
831 rows in set (2.48 sec)
```

Como se mencionó antes, el valor de ID de subproceso (`thd_id`) aquí puede hacer referencia a subprocesos en segundo plano del servidor o a conexiones de bases de datos. Si desea asignar valores de ID de subprocesos a ID de conexión a la base de datos, puede utilizar la tabla `performance_schema.threads` o la vista `sys.processlist`, donde `conn_id` es el ID de conexión.

```
mysql> SELECT thd_id,conn_id,user,db,command,state,time,last_wait FROM sys.processlist WHERE user='reinvent@10.0.4.4';

+--------+---------+-------------------+----------+---------+----------------+------+-------------------------------------------------+
| thd_id | conn_id | user              | db       | command | state          | time | last_wait                                       |
+--------+---------+-------------------+----------+---------+----------------+------+-------------------------------------------------+
|    590 |     562 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    578 |     550 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    579 |     551 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    580 |     552 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    581 |     553 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    582 |     554 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    583 |     555 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    584 |     556 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    585 |     557 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    586 |     558 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    587 |     559 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
.                                                                                                                                     .
.                                                                                                                                     .
.                                                                                                                                     .
|    323 |     295 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    324 |     296 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    325 |     297 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    326 |     298 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    438 |     410 | reinvent@10.0.4.4 | sysbench | Execute | System lock    |    0 | wait/lock/table/sql/handler                     |
|    280 |     252 | reinvent@10.0.4.4 | sysbench | Sleep   | starting       |    0 | wait/io/socket/sql/client_connection            |
|     98 |      70 | reinvent@10.0.4.4 | sysbench | Query   | freeing items  |    0 | NULL                                            |
+--------+---------+-------------------+----------+---------+----------------+------+-------------------------------------------------+
804 rows in set (5.51 sec)
```

Ahora detenemos la carga de trabajo de `sysbench`, lo que cierra las conexiones y libera memoria. Al volver a comprobar los eventos, podemos confirmar que la memoria se ha liberado, pero `high_alloc` nos sigue indicando cuál es el nivel máximo. La columna `high_alloc` puede resultar muy útil para identificar picos breves en el uso de memoria, cuando no se pueda identificar inmediatamente el uso de `current_alloc`, ya que muestra solo la memoria actualmente asignada.

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name='memory/sql/Prepared_statement::main_mem_root' LIMIT 10;

+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                   | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root |            17 | 253.80 KiB    | 14.93 KiB         |     512823 | 4.91 GiB   | 10.04 KiB      |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
1 row in set (0.00 sec)
```

Si desea restablecer `high_alloc`, puede truncar las tablas de resumen de la memoria de `performance_schema`, pero esto restablece toda la instrumentación de la memoria. Para obtener más información, consulte [Performance Schema general table characteristics](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-table-characteristics.html) en la documentación de MySQL.

En el siguiente ejemplo, podemos observar que `high_alloc` se restablece tras el truncado.

```
mysql> TRUNCATE `performance_schema`.`memory_summary_global_by_event_name`;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name='memory/sql/Prepared_statement::main_mem_root' LIMIT 10;

+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                   | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root |            17 | 253.80 KiB    | 14.93 KiB         |         17 | 253.80 KiB | 14.93 KiB      |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
1 row in set (0.00 sec)
```

## Ejemplo 2: picos de memoria de transitorios
<a name="ams-workload-memory.example2"></a>

Los picos breves en el uso de memoria son algo habitual en un servidor de base de datos. Puede tratarse de descensos periódicos de la memoria que se puede liberar y que son difíciles solucionar mediante `current_alloc` en `sys.memory_global_by_current_bytes`, ya que la memoria ya se ha liberado.

**nota**  
Si se han restablecido las estadísticas de Performance Schema o se ha reiniciado la instancia de la base de datos, esta información no estará disponible en `sys` o p`erformance_schema`. Para conservar esta información, recomendamos que configure la recopilación de métricas externas.

El siguiente gráfico de la métrica de `os.memory.free` en Supervisión mejorada muestra breves picos de 7 segundos en el uso de la memoria. Supervisión mejorada permite supervisar a intervalos de tan solo un segundo, lo que resulta perfecto para detectar picos transitorios como estos.

![\[Gráfico que muestra picos transitorios de uso de memoria a lo largo del tiempo con un patrón periódico que indica posibles problemas de administración de la memoria.\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/AuroraUserGuide/images/ams-free-memory-spikes.png)


Para ayudar a diagnosticar la causa del uso de memoria en este caso, podemos utilizar una combinación de `high_alloc` en las vistas de resumen de memoria de `sys` y las [tablas de resumen de instrucciones de Performance Schema](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html) para tratar de identificar las sesiones y conexiones problemáticas.

Como era de esperar, dado que el uso de memoria no es elevado actualmente, no podemos detectar ningún infractor principal en la vista del esquema de `sys` bajo `current_alloc`.

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                                                  | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/innodb/hash0hash                                                     |             4 | 79.07 MiB     | 19.77 MiB         |          4 | 79.07 MiB  | 19.77 MiB      |
| memory/innodb/os0event                                                      |        439372 | 60.34 MiB     |  144 bytes        |     439372 | 60.34 MiB  |  144 bytes     |
| memory/performance_schema/events_statements_summary_by_digest               |             1 | 40.28 MiB     | 40.28 MiB         |          1 | 40.28 MiB  | 40.28 MiB      |
| memory/mysys/KEY_CACHE                                                      |             3 | 16.00 MiB     | 5.33 MiB          |          3 | 16.00 MiB  | 5.33 MiB       |
| memory/performance_schema/events_statements_history_long                    |             1 | 14.34 MiB     | 14.34 MiB         |          1 | 14.34 MiB  | 14.34 MiB      |
| memory/performance_schema/events_errors_summary_by_thread_by_error          |           257 | 13.07 MiB     | 52.06 KiB         |        257 | 13.07 MiB  | 52.06 KiB      |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name |             1 | 11.81 MiB     | 11.81 MiB         |          1 | 11.81 MiB  | 11.81 MiB      |
| memory/performance_schema/events_statements_summary_by_digest.digest_text   |             1 | 9.77 MiB      | 9.77 MiB          |          1 | 9.77 MiB   | 9.77 MiB       |
| memory/performance_schema/events_statements_history_long.digest_text        |             1 | 9.77 MiB      | 9.77 MiB          |          1 | 9.77 MiB   | 9.77 MiB       |
| memory/performance_schema/events_statements_history_long.sql_text           |             1 | 9.77 MiB      | 9.77 MiB          |          1 | 9.77 MiB   | 9.77 MiB       |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
10 rows in set (0.01 sec)
```

Al ampliar la vista para ordenar por `high_alloc`, ahora podemos ver que el componente `memory/temptable/physical_ram` es muy buen candidato en este caso. En su nivel más alto, consumía 515,00 MiB.

Tal y como indica su nombre, `memory/temptable/physical_ram` instrumenta el uso de memoria del motor de almacenamiento `TEMP` en MySQL, que se introdujo en MySQL 8.0. Para obtener más información sobre cómo utiliza MySQL las tablas temporales, consulte [Internal temporary table use in MySQL](https://dev.mysql.com/doc/refman/8.0/en/internal-temporary-tables.html) en la documentación de MySQL.

**nota**  
En este ejemplo, estamos utilizando la vista `sys.x$memory_global_by_current_bytes`.

```
mysql> SELECT event_name, format_bytes(current_alloc) AS "currently allocated", sys.format_bytes(high_alloc) AS "high-water mark"  
FROM sys.x$memory_global_by_current_bytes ORDER BY high_alloc DESC LIMIT 10;

+-----------------------------------------------------------------------------+---------------------+-----------------+
| event_name                                                                  | currently allocated | high-water mark |
+-----------------------------------------------------------------------------+---------------------+-----------------+
| memory/temptable/physical_ram                                               | 4.00 MiB            | 515.00 MiB      |
| memory/innodb/hash0hash                                                     | 79.07 MiB           | 79.07 MiB       |
| memory/innodb/os0event                                                      | 63.95 MiB           | 63.95 MiB       |
| memory/performance_schema/events_statements_summary_by_digest               | 40.28 MiB           | 40.28 MiB       |
| memory/mysys/KEY_CACHE                                                      | 16.00 MiB           | 16.00 MiB       |
| memory/performance_schema/events_statements_history_long                    | 14.34 MiB           | 14.34 MiB       |
| memory/performance_schema/events_errors_summary_by_thread_by_error          | 13.07 MiB           | 13.07 MiB       |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name | 11.81 MiB           | 11.81 MiB       |
| memory/performance_schema/events_statements_summary_by_digest.digest_text   | 9.77 MiB            | 9.77 MiB        |
| memory/performance_schema/events_statements_history_long.sql_text           | 9.77 MiB            | 9.77 MiB        |
+-----------------------------------------------------------------------------+---------------------+-----------------+
10 rows in set (0.00 sec)
```

En [Ejemplo 1: uso elevado y continuo de memoria](#ams-workload-memory.example1), comprobamos el uso de memoria actual de cada conexión para determinar qué conexión es responsable del uso de la memoria en cuestión. En este ejemplo, la memoria ya está liberada, por lo que comprobar el uso de memoria de las conexiones actuales no resulta útil.

Para profundizar y encontrar las instrucciones, los usuarios y los host infractores, utilizamos Performance Schema. Performance Schema contiene varias tablas de resumen de instrucciones divididas en diferentes dimensiones, como el nombre del evento, el resumen de instrucciones, el host, el subproceso y el usuario. Cada vista le permitirá profundizar en dónde se ejecutan determinadas instrucciones y qué es lo que hacen. Esta sección se centra en `MAX_TOTAL_MEMORY`, pero puede encontrar más información sobre todas las columnas disponibles en la documentación de las [tablas de resumen de instrucciones de Performance Schema](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html).

```
mysql> SHOW TABLES IN performance_schema LIKE 'events_statements_summary_%';

+------------------------------------------------------------+
| Tables_in_performance_schema (events_statements_summary_%) |
+------------------------------------------------------------+
| events_statements_summary_by_account_by_event_name         |
| events_statements_summary_by_digest                        |
| events_statements_summary_by_host_by_event_name            |
| events_statements_summary_by_program                       |
| events_statements_summary_by_thread_by_event_name          |
| events_statements_summary_by_user_by_event_name            |
| events_statements_summary_global_by_event_name             |
+------------------------------------------------------------+
7 rows in set (0.00 sec)
```

En primer lugar, comprobamos `events_statements_summary_by_digest` para ver `MAX_TOTAL_MEMORY`.

A partir de esto, podemos ver lo siguiente:
+ La consulta con el resumen `20676ce4a690592ff05debcffcbc26faeb76f22005e7628364d7a498769d0c4a` parece ser una buena candidata para este uso de memoria. El valor de `MAX_TOTAL_MEMORY` es 537450710, que coincide con el nivel máximo que vimos para el evento de `memory/temptable/physical_ram` en `sys.x$memory_global_by_current_bytes`.
+ Se ha ejecutado cuatro veces (`COUNT_STAR`), la primera a las 04:08:34,943256 del 26 de marzo de 2024 y, la última, a las 04:43:06,998310 del 26 de marzo de 2024.

```
mysql> SELECT SCHEMA_NAME,DIGEST,COUNT_STAR,MAX_TOTAL_MEMORY,FIRST_SEEN,LAST_SEEN
FROM performance_schema.events_statements_summary_by_digest ORDER BY MAX_TOTAL_MEMORY DESC LIMIT 5;

+-------------+------------------------------------------------------------------+------------+------------------+----------------------------+----------------------------+
| SCHEMA_NAME | DIGEST                                                           | COUNT_STAR | MAX_TOTAL_MEMORY | FIRST_SEEN                 | LAST_SEEN                  |
+-------------+------------------------------------------------------------------+------------+------------------+----------------------------+----------------------------+
| sysbench    | 20676ce4a690592ff05debcffcbc26faeb76f22005e7628364d7a498769d0c4a |          4 |        537450710 | 2024-03-26 04:08:34.943256 | 2024-03-26 04:43:06.998310 |
| NULL        | f158282ea0313fefd0a4778f6e9b92fc7d1e839af59ebd8c5eea35e12732c45d |          4 |          3636413 | 2024-03-26 04:29:32.712348 | 2024-03-26 04:36:26.269329 |
| NULL        | 0046bc5f642c586b8a9afd6ce1ab70612dc5b1fd2408fa8677f370c1b0ca3213 |          2 |          3459965 | 2024-03-26 04:31:37.674008 | 2024-03-26 04:32:09.410718 |
| NULL        | 8924f01bba3c55324701716c7b50071a60b9ceaf17108c71fd064c20c4ab14db |          1 |          3290981 | 2024-03-26 04:31:49.751506 | 2024-03-26 04:31:49.751506 |
| NULL        | 90142bbcb50a744fcec03a1aa336b2169761597ea06d85c7f6ab03b5a4e1d841 |          1 |          3131729 | 2024-03-26 04:15:09.719557 | 2024-03-26 04:15:09.719557 |
+-------------+------------------------------------------------------------------+------------+------------------+----------------------------+----------------------------+
5 rows in set (0.00 sec)
```

Ahora que conocemos el resumen infractor, podemos obtener más detalles, como el texto de la consulta, el usuario que la ejecutó y dónde se ejecutó. Según el texto del resumen devuelto, podemos ver que se trata de una expresión común de tabla (CTE) que crea cuatro tablas temporales y realiza cuatro análisis de tablas, lo que resulta muy ineficiente.

```
mysql> SELECT SCHEMA_NAME,DIGEST_TEXT,QUERY_SAMPLE_TEXT,MAX_TOTAL_MEMORY,SUM_ROWS_SENT,SUM_ROWS_EXAMINED,SUM_CREATED_TMP_TABLES,SUM_NO_INDEX_USED
FROM performance_schema.events_statements_summary_by_digest
WHERE DIGEST='20676ce4a690592ff05debcffcbc26faeb76f22005e7628364d7a498769d0c4a'\G;

*************************** 1. row ***************************
           SCHEMA_NAME: sysbench
           DIGEST_TEXT: WITH RECURSIVE `cte` ( `n` ) AS ( SELECT ? FROM `sbtest1` UNION ALL SELECT `id` + ? FROM `sbtest1` ) SELECT * FROM `cte`
     QUERY_SAMPLE_TEXT: WITH RECURSIVE cte (n) AS (   SELECT 1  from sbtest1 UNION ALL   SELECT id + 1 FROM sbtest1) SELECT * FROM cte
      MAX_TOTAL_MEMORY: 537450710
         SUM_ROWS_SENT: 80000000
     SUM_ROWS_EXAMINED: 80000000
SUM_CREATED_TMP_TABLES: 4
     SUM_NO_INDEX_USED: 4
1 row in set (0.01 sec)
```

Para obtener más información sobre la tabla `events_statements_summary_by_digest` y otras tablas de resumen de instrucciones de Performance Schema, consulte [Statement summary tables](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html) en la documentación de MySQL.

También puede ejecutar una instrucción [EXPLAIN](https://dev.mysql.com/doc/refman/8.0/en/explain.html) o [EXPLAIN ANALYZE](https://dev.mysql.com/doc/refman/8.0/en/explain.html#explain-analyze) para obtener más detalles.

**nota**  
`EXPLAIN ANALYZE` puede aportar más información que `EXPLAIN`, pero también ejecuta la consulta, así que debe tener cuidado.

```
-- EXPLAIN
mysql> EXPLAIN WITH RECURSIVE cte (n) AS (SELECT 1  FROM sbtest1 UNION ALL SELECT id + 1 FROM sbtest1) SELECT * FROM cte;

+----+-------------+------------+------------+-------+---------------+------+---------+------+----------+----------+-------------+
| id | select_type | table      | partitions | type  | possible_keys | key  | key_len | ref  | rows     | filtered | Extra       |
+----+-------------+------------+------------+-------+---------------+------+---------+------+----------+----------+-------------+
|  1 | PRIMARY     | <derived2> | NULL       | ALL   | NULL          | NULL | NULL    | NULL | 19221520 |   100.00 | NULL        |
|  2 | DERIVED     | sbtest1    | NULL       | index | NULL          | k_1  | 4       | NULL |  9610760 |   100.00 | Using index |
|  3 | UNION       | sbtest1    | NULL       | index | NULL          | k_1  | 4       | NULL |  9610760 |   100.00 | Using index |
+----+-------------+------------+------------+-------+---------------+------+---------+------+----------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)

-- EXPLAIN format=tree 
mysql> EXPLAIN format=tree WITH RECURSIVE cte (n) AS (SELECT 1 FROM sbtest1 UNION ALL SELECT id + 1 FROM sbtest1) SELECT * FROM cte\G;

*************************** 1. row ***************************
EXPLAIN: -> Table scan on cte  (cost=4.11e+6..4.35e+6 rows=19.2e+6)
    -> Materialize union CTE cte  (cost=4.11e+6..4.11e+6 rows=19.2e+6)
        -> Index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6)
        -> Index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6)
1 row in set (0.00 sec)

-- EXPLAIN ANALYZE 
mysql> EXPLAIN ANALYZE WITH RECURSIVE cte (n) AS (SELECT 1 from sbtest1 UNION ALL SELECT id + 1 FROM sbtest1) SELECT * FROM cte\G;

*************************** 1. row ***************************
EXPLAIN: -> Table scan on cte  (cost=4.11e+6..4.35e+6 rows=19.2e+6) (actual time=6666..9201 rows=20e+6 loops=1)
    -> Materialize union CTE cte  (cost=4.11e+6..4.11e+6 rows=19.2e+6) (actual time=6666..6666 rows=20e+6 loops=1)
        -> Covering index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6) (actual time=0.0365..2006 rows=10e+6 loops=1)
        -> Covering index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6) (actual time=0.0311..2494 rows=10e+6 loops=1)
1 row in set (10.53 sec)
```

Pero, ¿quién lo ha ejecutado? Podemos ver en Performance Schema que el usuario `destructive_operator` tenía un `MAX_TOTAL_MEMORY` de 537450710, lo que de nuevo coincide con los resultados anteriores.

**nota**  
Performance Schema se almacena en la memoria, por lo que no se debe confiar en él como la única fuente de auditoría. Si necesita mantener un historial de las instrucciones ejecutadas y qué usuarios las ejecutan, le recomendamos que habilite [Aurora Advanced Auditing](AuroraMySQL.Auditing.md). Si también necesita mantener información sobre el uso de la memoria, le recomendamos que configure la supervisión para exportar y almacenar estos valores.

```
mysql> SELECT USER,EVENT_NAME,COUNT_STAR,MAX_TOTAL_MEMORY FROM performance_schema.events_statements_summary_by_user_by_event_name
ORDER BY MAX_CONTROLLED_MEMORY DESC LIMIT 5;

+----------------------+---------------------------+------------+------------------+
| USER                 | EVENT_NAME                | COUNT_STAR | MAX_TOTAL_MEMORY |
+----------------------+---------------------------+------------+------------------+
| destructive_operator | statement/sql/select      |          4 |        537450710 |
| rdsadmin             | statement/sql/select      |       4172 |          3290981 |
| rdsadmin             | statement/sql/show_tables |          2 |          3615821 |
| rdsadmin             | statement/sql/show_fields |          2 |          3459965 |
| rdsadmin             | statement/sql/show_status |         75 |          1914976 |
+----------------------+---------------------------+------------+------------------+
5 rows in set (0.00 sec)

mysql> SELECT HOST,EVENT_NAME,COUNT_STAR,MAX_TOTAL_MEMORY FROM performance_schema.events_statements_summary_by_host_by_event_name
WHERE HOST != 'localhost' AND COUNT_STAR>0 ORDER BY MAX_CONTROLLED_MEMORY DESC LIMIT 5;

+------------+----------------------+------------+------------------+
| HOST       | EVENT_NAME           | COUNT_STAR | MAX_TOTAL_MEMORY |
+------------+----------------------+------------+------------------+
| 10.0.8.231 | statement/sql/select |          4 |        537450710 |
+------------+----------------------+------------+------------------+
1 row in set (0.00 sec)
```

## Ejemplo 3: la memoria liberable cae continuamente y no se recupera
<a name="ams-workload-memory.example3"></a>

El motor de base de datos InnoDB emplea una variedad de eventos de seguimiento de memoria especializados para diferentes componentes. Estos eventos específicos permiten un seguimiento detallado del uso de la memoria en los principales subsistemas de InnoDB, por ejemplo:
+ `memory/innodb/buf0buf`: dedicado a supervisar las asignaciones de memoria para el grupo de búferes de InnoDB.
+ `memory/innodb/ibuf0ibuf`: realiza un seguimiento específico de los cambios de memoria relacionados con el búfer de cambios de InnoDB.

Para identificar los principales consumidores de memoria, podemos consultar `sys.memory_global_by_current_bytes`:

```
mysql> SELECT event_name,current_alloc FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------+---------------+
| event_name                                                      | current_alloc |
+-----------------------------------------------------------------+---------------+
| memory/innodb/memory                                            | 5.28 GiB      |
| memory/performance_schema/table_io_waits_summary_by_index_usage | 495.00 MiB    |
| memory/performance_schema/table_shares                          | 488.00 MiB    |
| memory/sql/TABLE_SHARE::mem_root                                | 388.95 MiB    |
| memory/innodb/std                                               | 226.88 MiB    |
| memory/innodb/fil0fil                                           | 198.49 MiB    |
| memory/sql/binlog_io_cache                                      | 128.00 MiB    |
| memory/innodb/mem0mem                                           | 96.82 MiB     |
| memory/innodb/dict0dict                                         | 96.76 MiB     |
| memory/performance_schema/rwlock_instances                      | 88.00 MiB     |
+-----------------------------------------------------------------+---------------+
10 rows in set (0.00 sec)
```

Los resultados muestran que `memory/innodb/memory` es el principal consumidor, ya que utiliza 5,28 GiB de la memoria asignada actualmente. Este evento sirve como categoría para las asignaciones de memoria entre varios componentes de InnoDB no asociados a eventos de espera más específicos, como los `memory/innodb/buf0buf` mencionados anteriormente.

Una vez establecido que los componentes de InnoDB son los principales consumidores de memoria, podemos profundizar en los detalles con el siguiente comando de MySQL:

```
SHOW ENGINE INNODB STATUS \G;
```

El comando [SHOW ENGINE INNODB STATUS](https://dev.mysql.com/doc/refman/8.4/en/show-engine.html) proporciona un informe de estado completo del motor de almacenamiento de InnoDB, que incluye estadísticas detalladas de uso de memoria de los diferentes componentes de InnoDB. Puede ayudar a identificar qué estructuras u operaciones específicas de InnoDB consumen más memoria. Para obtener información, consulte [InnoDB in-memory structures](https://dev.mysql.com/doc/refman/8.0/en/innodb-in-memory-structures.html) en la documentación de MySQL.

Al analizar la sección `BUFFER POOL AND MEMORY` del informe de estado de InnoDB, vemos que se asignan 5 051 647 748 bytes (4,7 GiB) a la [caché de objetos del diccionario](https://dev.mysql.com/doc/refman/8.0/en/data-dictionary-object-cache.html), que representa el 89 % de la memoria rastreada por `memory/innodb/memory`.

```
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 0
Dictionary memory allocated 5051647748
Buffer pool size 170512
Free buffers 142568
Database pages 27944
Old database pages 10354
Modified db pages 6
Pending reads 0
```

La caché de objetos del diccionario es una caché global compartida que almacena en la memoria los objetos del diccionario de datos a los que se ha accedido anteriormente para permitir la reutilización de los objetos y mejorar el rendimiento. La elevada asignación de memoria a la caché de objetos del diccionario sugiere que hay una gran cantidad de objetos de base de datos en la caché del diccionario de datos.

Ahora que sabemos que la caché del diccionario de datos es un consumidor principal, procedemos a inspeccionar la caché del diccionario de datos para ver si hay tablas abiertas. Para encontrar el número de tablas en la caché de definiciones de tablas, consulte la variable de estado global [open\$1table\$1definitions](https://dev.mysql.com/doc/refman/8.4/en/server-status-variables.html#statvar_Open_table_definitions).

```
mysql> show global status like 'open_table_definitions';

+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Open_table_definitions | 20000 |
+------------------------+-------+
1 row in set (0.00 sec)
```

Para obtener más información, consulte [How MySQL Opens and Closes Tables](https://dev.mysql.com/doc/refman/8.0/en/table-cache.html) en la documentación de MySQL.

Puede limitar el número de definiciones de tablas en la caché del diccionario de datos limitando el parámetro `table_definition_cache` en el clúster de base de datos o en el grupo de parámetros de la instancia de base de datos. Para Aurora MySQL, este valor sirve como límite flexible para el número de tablas en la caché de definición de tablas. El valor predeterminado depende de la clase de instancia y se establece de la siguiente manera:

```
LEAST({DBInstanceClassMemory/393040}, 20000)
```

Cuando el número de tablas supera el límite de `table_definition_cache`, el mecanismo utilizado menos recientemente (LRU) expulsa y elimina las tablas de la memoria caché. Sin embargo, las tablas involucradas en relaciones de clave externa no se incluyen en la lista LRU, lo que impide su eliminación.

En nuestro escenario actual, ejecutamos [FLUSH TABLES](https://dev.mysql.com/doc/refman/8.4/en/flush.html) para borrar la caché de definiciones de tablas. Esta acción provoca una caída significativa de la variable de estado global [Open\$1table\$1definitions](https://dev.mysql.com/doc/refman/8.0/en/server-status-variables.html#statvar_Open_table_definitions), de 20 000 a 12, tal como se muestra a continuación:

```
mysql> show global status like 'open_table_definitions';

+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Open_table_definitions | 12    |
+------------------------+-------+
1 row in set (0.00 sec)
```

A pesar de esta reducción, observamos que la asignación de memoria para `memory/innodb/memory` sigue siendo alta, de 5,18 GiB, y la memoria del diccionario asignada también permanece sin cambios. Esto queda patente en los siguientes resultados de la consulta:

```
mysql> SELECT event_name,current_alloc FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------+---------------+
| event_name                                                      | current_alloc |
+-----------------------------------------------------------------+---------------+
| memory/innodb/memory                                            | 5.18 GiB      |
| memory/performance_schema/table_io_waits_summary_by_index_usage | 495.00 MiB    |
| memory/performance_schema/table_shares                          | 488.00 MiB    |
| memory/sql/TABLE_SHARE::mem_root                                | 388.95 MiB    |
| memory/innodb/std                                               | 226.88 MiB    |
| memory/innodb/fil0fil                                           | 198.49 MiB    |
| memory/sql/binlog_io_cache                                      | 128.00 MiB    |
| memory/innodb/mem0mem                                           | 96.82 MiB     |
| memory/innodb/dict0dict                                         | 96.76 MiB     |
| memory/performance_schema/rwlock_instances                      | 88.00 MiB     |
+-----------------------------------------------------------------+---------------+
10 rows in set (0.00 sec)
```

```
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 0
Dictionary memory allocated 5001599639
Buffer pool size 170512
Free buffers 142568
Database pages 27944
Old database pages 10354
Modified db pages 6
Pending reads 0
```

Este elevado uso de memoria de forma persistente se puede atribuir a las tablas implicadas en relaciones de claves externas. Estas tablas no se incluyen en la lista LRU para su eliminación, lo que explica por qué la asignación de memoria sigue siendo alta incluso después de vaciar la caché de definiciones de tablas.

Para solucionar este problema:

1. Revise y optimice el esquema de su base de datos, especialmente las relaciones de claves externas.

1. Considere la posibilidad de cambiar a una clase de instancia de base de datos más grande que tenga más memoria para acomodar los objetos de diccionario.

Si sigue estos pasos y comprende los patrones de asignación de memoria, podrá administrar mejor el uso de la memoria en su instancia de base de datos de Aurora MySQL y evitar posibles problemas de rendimiento debido a la presión sobre la memoria.