

# Prácticas recomendadas con Amazon Aurora MySQL
<a name="AuroraMySQL.BestPractices"></a><a name="best_practices"></a>

En este tema se proporciona información acerca de las prácticas recomendadas y las opciones para usar o migrar datos en un clúster de base de datos de Amazon Aurora MySQL. La información de este tema resume y reitera algunas de las directrices y procedimientos que puede encontrar en [Administración de un clúster de base de datos de Amazon Aurora](CHAP_Aurora.md).

**Contents**
+ [Determinar a qué instancia de base de datos está conectado](#AuroraMySQL.BestPractices.DeterminePrimaryInstanceConnection)
+ [Prácticas recomendadas de escalado y rendimiento de Aurora MySQL](AuroraMySQL.BestPractices.Performance.md)
  + [Utilización de clases de instancia T para el desarrollo y la prueba](AuroraMySQL.BestPractices.Performance.md#AuroraMySQL.BestPractices.T2Medium)
  + [Optimización de las consultas de combinación indexadas de Aurora MySQL con la captura previa de claves asíncronas](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.AKP)
    + [Habilitación de la captura previa de clave asíncrona](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.AKP.Enabling)
    + [Optimización de consultas para la captura previa de clave asíncrona](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.AKP.Optimizing)
  + [Optimización de grandes consultas combinadas de Aurora MySQL con combinaciones hash](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.HashJoin)
    + [Habilitación de las combinaciones hash](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.HashJoin.Enabling)
    + [Optimización de consultas para combinaciones hash](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.HashJoin.Optimizing)
  + [Uso de Amazon Aurora para escalar las lecturas de una base de datos de MySQL](AuroraMySQL.BestPractices.Performance.md#AuroraMySQL.BestPractices.ReadScaling)
  + [Optimización de las operaciones de marca temporal](AuroraMySQL.BestPractices.Performance.md#AuroraMySQL.BestPractices.Performance.TimeZone)
  + [Errores de desbordamiento de ID de índice virtual](AuroraMySQL.BestPractices.Performance.md#AuroraMySQL.BestPractices.Performance.VirtualIndexIDOverflow)
+ [Prácticas recomendadas para obtener una elevada disponibilidad de Aurora MySQL](AuroraMySQL.BestPractices.HA.md)
  + [Uso de Amazon Aurora para la recuperación de desastres con sus bases de datos de MySQL](AuroraMySQL.BestPractices.HA.md#AuroraMySQL.BestPractices.DisasterRecovery)
  + [Migración de MySQL a Amazon Aurora MySQL con un tiempo de inactividad reducido](AuroraMySQL.BestPractices.HA.md#AuroraMySQL.BestPractices.Migrating)
  + [Prevención del rendimiento lento, el reinicio automático y la conmutación por error de las instancias de base de datos Aurora MySQL](AuroraMySQL.BestPractices.HA.md#AuroraMySQL.BestPractices.Avoiding)
+ [Recomendaciones para características de MySQL en Aurora MySQL](AuroraMySQL.BestPractices.FeatureRecommendations.md)
  + [Uso de la replicación de varios subprocesos en Aurora MySQL](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.MTReplica)
  + [Invocación de funciones de AWS Lambda mediante funciones de MySQL nativas](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.Lambda)
  + [Evitar las transacciones de XA con Amazon Aurora MySQL](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.XA)
  + [Mantenimiento de las claves externas activadas durante las instrucciones DML](AuroraMySQL.BestPractices.FeatureRecommendations.md#Aurora.BestPractices.ForeignKeys)
  + [Configuración de la frecuencia de vaciado del búfer de registro](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.Flush)
  + [Minimización y solución de problemas de los interbloqueos de Aurora MySQL](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.deadlocks)
    + [Minimización de interbloqueos de InnoDB](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.deadlocks-minimize)
    + [Supervisión de interbloqueos de InnoDB](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.deadlocks-monitor)
+ [Evaluación de la utilización de instancias de base de datos para Aurora MySQL con métricas de Amazon CloudWatch](AuroraMySQL.BestPractices.CW.md)

## Determinar a qué instancia de base de datos está conectado
<a name="AuroraMySQL.BestPractices.DeterminePrimaryInstanceConnection"></a>

Puede determinar a qué instancia de base de datos un clúster de base de datos Aurora MySQL está conectado comprobando la variable global `innodb_read_only`, como se muestra en el siguiente ejemplo.

```
SHOW GLOBAL VARIABLES LIKE 'innodb_read_only'; 
```

La variable `innodb_read_only` se establece en `ON` si está conectado a una instancia de base de datos de lector. Este ajuste estará en `OFF` si está conectado a una instancia de base de datos de escritor, como, por ejemplo, la instancia principal de un clúster aprovisionado.

Este método puede resultar útil si se desea añadir lógica al código de la aplicación para equilibrar la carga de trabajo o para garantizar que una operación de escritura utilice la conexión correcta.

# Prácticas recomendadas de escalado y rendimiento de Aurora MySQL
<a name="AuroraMySQL.BestPractices.Performance"></a>

Aplique las prácticas recomendadas que se describen a continuación para mejorar el rendimiento y la escalabilidad de los clústeres de Aurora MySQL.

**Topics**
+ [Utilización de clases de instancia T para el desarrollo y la prueba](#AuroraMySQL.BestPractices.T2Medium)
+ [Optimización de las consultas de combinación indexadas de Aurora MySQL con la captura previa de claves asíncronas](#Aurora.BestPractices.AKP)
+ [Optimización de grandes consultas combinadas de Aurora MySQL con combinaciones hash](#Aurora.BestPractices.HashJoin)
+ [Uso de Amazon Aurora para escalar las lecturas de una base de datos de MySQL](#AuroraMySQL.BestPractices.ReadScaling)
+ [Optimización de las operaciones de marca temporal](#AuroraMySQL.BestPractices.Performance.TimeZone)
+ [Errores de desbordamiento de ID de índice virtual](#AuroraMySQL.BestPractices.Performance.VirtualIndexIDOverflow)

## Utilización de clases de instancia T para el desarrollo y la prueba
<a name="AuroraMySQL.BestPractices.T2Medium"></a>

Las instancias de Amazon Aurora MySQL que utilizan las clases de instancia de base de datos `db.t2`, `db.t3` o `db.t4g` son más adecuadas para las aplicaciones que no admiten una carga de trabajo elevada durante un periodo de tiempo largo. Las instancias T se han diseñado para ofrecer un desempeño de referencia moderado y la capacidad de poder ampliarlo a un nivel considerablemente superior si así lo exige la carga de trabajo. Están pensadas para las cargas de trabajo que no utilizan toda la CPU con frecuencia o de forma continua, pero que de vez en cuando necesitan ampliar sus procesos. Recomendamos que las clases de instancia de base de datos T se utilicen solo para los servidores de desarrollo y de pruebas, o para otros servidores que no se utilicen para la producción. Para obtener más detalles sobre las clases de instancia T, consulte [Instancias de rendimiento ampliable](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances.html).

Si el clúster de Aurora tiene más de 40 TB, no utilice las clases de instancia T. Cuando la base de datos tiene un gran volumen de datos, la sobrecarga de memoria para administrar objetos de esquema puede exceder la capacidad de la instancia T.

No habilite el esquema de rendimiento de MySQL en instancias T de Amazon Aurora MySQL. Si el esquema de desempeño está habilitado, la instancia T podría quedarse sin memoria.

**sugerencia**  
 Si la base de datos a veces está inactiva pero en otras ocasiones tiene una carga de trabajo sustancial, puede utilizar Aurora Serverless v2 como alternativa a las instancias T. Con Aurora Serverless v2, define un rango de capacidad y Aurora escala automáticamente la base de datos vertical y horizontalmente según la carga de trabajo actual. Para obtener más información sobre el uso, consulte [Uso de Aurora Serverless v2](aurora-serverless-v2.md). Para conocer las versiones del motor de base de datos que puede utilizar con Aurora Serverless v2, consulte [Requisitos y limitaciones para Aurora Serverless v2](aurora-serverless-v2.requirements.md). 

Cuando utilice una instancia T como una instancia de base de datos en un clúster de base de datos de Aurora MySQL, recomendamos lo siguiente:
+ Utilice la misma clase de instancia de base de datos para todas las instancias del clúster de base de datos. Por ejemplo, si utiliza `db.t2.medium` para su instancia de escritor, le recomendamos que utilice `db.t2.medium` también para las instancias de lector.
+ No ajuste ninguna configuración relacionada con la memoria, como, por ejemplo, `innodb_buffer_pool_size`. Aurora utiliza un conjunto de valores predeterminados muy ajustados para búferes de memoria en las instancias T. Estos valores predeterminados especiales son necesarios para que Aurora se pueda ejecutar en instancias con restricción de memoria. Si cambia cualquier configuración relacionada con la memoria en una instancia T, es mucho más probable que encuentre condiciones de falta de memoria, incluso si el cambio está destinado a aumentar el tamaño del búfer.
+ Monitorice el saldo de crédito de su CPU (`CPUCreditBalance`) para asegurarse de que está en un nivel sostenible. Es decir, que los créditos de la CPU se están acumulando a la misma velocidad a la que se usan.

  Cuando se agotan los créditos de CPU correspondientes a una instancia, se percibe una disminución inmediata en la CPU disponible y un incremento en la latencia de lectura y escritura de la instancia. Esta situación provoca una grave reducción del desempeño general de la instancia.

  Si el saldo de crédito de la CPU no está en un nivel sostenible, es recomendable que modifique la instancia de base de datos para que use una de las clases de instancia de base de datos R disponibles (escalado del cálculo).

  Para obtener más información acerca de las métricas de monitorización, consulte [Consulta de métricas en la consola de Amazon RDS](USER_Monitoring.md).
+ Supervise el retardo de réplica (`AuroraReplicaLag`) entre la instancia de escritor y las instancias de lector.

  Si una instancia de lector se queda sin créditos de CPU antes de la instancia de escritor, el retraso resultante puede provocar que la instancia de lector se reinicie con frecuencia. Este resultado es habitual cuando una aplicación mantiene una carga elevada de operaciones de lectura distribuidas entre las instancias de lector al mismo tiempo que la instancia de escritor tiene una carga mínima de operaciones de escritura.

  Si ve un aumento sostenido del retardo de las réplicas, asegúrese de que no se está agotando el saldo de crédito de la CPU para las instancias de lector en su clúster de base de datos.

  Si el saldo de crédito de la CPU no está en un nivel sostenible, es recomendable que modifique la instancia de base de datos para que use una de las clases de instancia de base de datos R disponibles (escalado del cálculo).
+ Mantenga el número de inserciones por transacción por debajo de 1 millón para los clústeres de base de datos que tengan habilitado el registro binario.

  Si el grupo de parámetros de su clúster de base de datos tiene el parámetro `binlog_format` definido en un valor distinto de `OFF`, dicho clúster de base de datos puede experimentar condiciones de falta de memoria si recibe transacciones que contengan más de 1 millón de filas para insertar. Puede monitorizar la métrica de la memoria que se puede liberar (`FreeableMemory`) para determinar si su clúster de base de datos se está quedando sin memoria. Luego puede comprobar la métrica de operaciones de escritura (`VolumeWriteIOPS`) para ver si la instancia de escritura recibe una carga pesada de operaciones de escritura. En ese caso, es recomendable que actualice su aplicación para limitar el número de inserciones de una transacción a menos de 1 millón o que modifique la instancia para que utilice una de las clases de instancia de base de datos R compatibles (escalado del cálculo).

## Optimización de las consultas de combinación indexadas de Aurora MySQL con la captura previa de claves asíncronas
<a name="Aurora.BestPractices.AKP"></a>

Amazon MySQL puede usar la característica de captura previa de claves asíncronas (AKP, por sus siglas en inglés) para mejorar el desempeño de las consultas que unen las tablas a través de los índices. Esta característica mejora el rendimiento al prever las filas necesarias para ejecutar consultas en las que una consulta JOIN requiere el uso del algoritmo de combinación Batched Key Access (BKA) y las características de optimización Multi-Range Read (MRR). Para obtener más información acerca de BKA y MRR, consulte [Block Nested-Loop and Batched Key Access Joins](https://dev.mysql.com/doc/refman/5.6/en/bnl-bka-optimization.html) y [Multi-Range Read Optimization](https://dev.mysql.com/doc/refman/5.6/en/mrr-optimization.html) en la documentación de MySQL.

Para sacar máximo partido de la característica AKP, una consulta debe utilizar BKA y MRR. Por lo general, dicho tipo de consulta se produce cuando la cláusula JOIN de una consulta utiliza un índice secundario, pero requiere también algunas columnas del índice primario. Por ejemplo, puede usar la AKP cuando una cláusula JOIN represente a un equijoin en los valores de índice entre una tabla exterior pequeña y una interior grande, y el índice sea sumamente selectivo en la tabla grande. AKP trabaja conjuntamente con BKA y MRR para llevar a cabo una búsqueda del índice secundario al primario durante la evaluación de la cláusula JOIN. AKP identifica las filas necesarias para ejecutar la consulta durante la evaluación de la cláusula JOIN. Seguidamente, utiliza un subproceso en segundo plano para cargar de manera asíncrona las páginas que contienen dichas filas en la memoria antes de ejecutar la consulta.

AKP está disponible para la versión 2.10 y posteriores y la versión 3 de Aurora MySQL. Para obtener más información acerca de las versiones de Aurora MySQL, consulte [Actualizaciones del motor de base de datos de Amazon Aurora MySQLVersiones beta y de soporte a largo plazo (LTS) para Amazon Aurora MySQL](AuroraMySQL.Updates.md).

### Habilitación de la captura previa de clave asíncrona
<a name="Aurora.BestPractices.AKP.Enabling"></a>

Para habilitar la característica de AKP, establezca la configuración `aurora_use_key_prefetch`, una variable de MySQL Server, en `on`. De forma predeterminada, este valor se establece en `on`. No obstante, AKP no podrá habilitarse hasta que no active el algoritmo de combinación BKA y deshabilite la característica MRR basada en el costo. Para ello, debe ajustar los valores siguientes de `optimizer_switch`, una variable de MySQL Server:
+ Establece `batched_key_access` en `on`. Este valor controla el uso del algoritmo de combinación BKA. De forma predeterminada, este valor se establece en `off`.
+ Establece `mrr_cost_based` en `off`. Este valor controla el uso de la característica MRR basada en el costo. De forma predeterminada, este valor se establece en `on`.

En la actualidad, puede configurar estos valores únicamente en el nivel de sesión. El siguiente ejemplo ilustra cómo configurar estos valores a fin de habilitar AKP para la sesión actual ejecutando las instrucciones SET.

```
mysql> set @@session.aurora_use_key_prefetch=on;
mysql> set @@session.optimizer_switch='batched_key_access=on,mrr_cost_based=off';
```

Del mismo modo, puede usar las instrucciones SET para deshabilitar AKP y el algoritmo de combinación BKA, y volver a habilitar la característica MRR basada en el costo para la sesión actual, como se muestra en el ejemplo siguiente.

```
mysql> set @@session.aurora_use_key_prefetch=off;
mysql> set @@session.optimizer_switch='batched_key_access=off,mrr_cost_based=on';
```

Para obtener más información acerca de los cambios del optimizador **batched\$1key\$1access** y **mrr\$1cost\$1based**, consulte [Switchable Optimizations](https://dev.mysql.com/doc/refman/5.6/en/switchable-optimizations.html) en la documentación de MySQL.

### Optimización de consultas para la captura previa de clave asíncrona
<a name="Aurora.BestPractices.AKP.Optimizing"></a>

Puede confirmar si una consulta puede beneficiarse de la característica AKP. Para ello, utilice la instrucción `EXPLAIN` con el fin de perfilar la consulta antes de ejecutarla. La instrucción `EXPLAIN` ofrece información acerca del plan de ejecución que se va a utilizar para una consulta especificada

En el resultado de la instrucción `EXPLAIN`, la columna `Extra` describe información adicional que se incluye con el plan de ejecución. Si la característica AKP se aplica a una tabla que se ha utilizado en la consulta, esta tabla incluye uno de los siguientes valores:
+ `Using Key Prefetching`
+ `Using join buffer (Batched Key Access with Key Prefetching)`

En el siguiente ejemplo se muestra el uso de `EXPLAIN` para ver el plan de ejecución de una consulta que puede beneficiarse de AKP.

```
mysql> explain select sql_no_cache
    ->     ps_partkey,
    ->     sum(ps_supplycost * ps_availqty) as value
    -> from
    ->     partsupp,
    ->     supplier,
    ->     nation
    -> where
    ->     ps_suppkey = s_suppkey
    ->     and s_nationkey = n_nationkey
    ->     and n_name = 'ETHIOPIA'
    -> group by
    ->     ps_partkey having
    ->         sum(ps_supplycost * ps_availqty) > (
    ->             select
    ->                 sum(ps_supplycost * ps_availqty) * 0.0000003333
    ->             from
    ->                 partsupp,
    ->                 supplier,
    ->                 nation
    ->             where
    ->                 ps_suppkey = s_suppkey
    ->                 and s_nationkey = n_nationkey
    ->                 and n_name = 'ETHIOPIA'
    ->         )
    -> order by
    ->     value desc;
+----+-------------+----------+------+-----------------------+---------------+---------+----------------------------------+------+----------+-------------------------------------------------------------+
| id | select_type | table    | type | possible_keys         | key           | key_len | ref                              | rows | filtered | Extra                                                       |
+----+-------------+----------+------+-----------------------+---------------+---------+----------------------------------+------+----------+-------------------------------------------------------------+
|  1 | PRIMARY     | nation   | ALL  | PRIMARY               | NULL          | NULL    | NULL                             |   25 |   100.00 | Using where; Using temporary; Using filesort                |
|  1 | PRIMARY     | supplier | ref  | PRIMARY,i_s_nationkey | i_s_nationkey | 5       | dbt3_scale_10.nation.n_nationkey | 2057 |   100.00 | Using index                                                 |
|  1 | PRIMARY     | partsupp | ref  | i_ps_suppkey          | i_ps_suppkey  | 4       | dbt3_scale_10.supplier.s_suppkey |   42 |   100.00 | Using join buffer (Batched Key Access with Key Prefetching) |
|  2 | SUBQUERY    | nation   | ALL  | PRIMARY               | NULL          | NULL    | NULL                             |   25 |   100.00 | Using where                                                 |
|  2 | SUBQUERY    | supplier | ref  | PRIMARY,i_s_nationkey | i_s_nationkey | 5       | dbt3_scale_10.nation.n_nationkey | 2057 |   100.00 | Using index                                                 |
|  2 | SUBQUERY    | partsupp | ref  | i_ps_suppkey          | i_ps_suppkey  | 4       | dbt3_scale_10.supplier.s_suppkey |   42 |   100.00 | Using join buffer (Batched Key Access with Key Prefetching) |
+----+-------------+----------+------+-----------------------+---------------+---------+----------------------------------+------+----------+-------------------------------------------------------------+
6 rows in set, 1 warning (0.00 sec)
```

Para obtener más información acerca del formato de salida `EXPLAIN`, consulte el tema sobre el [Formato de salida de EXPLAIN ampliado](https://dev.mysql.com/doc/refman/8.0/en/explain-extended.html) en la documentación de MySQL.

## Optimización de grandes consultas combinadas de Aurora MySQL con combinaciones hash
<a name="Aurora.BestPractices.HashJoin"></a>

Si necesita unir una gran cantidad de datos mediante equijoin, una combinación hash puede mejorar el desempeño de las consultas. Puede habilitar las combinaciones hash para Aurora MySQL.

Una columna de combinación hash puede ser cualquier expresión compleja. En una columna de combinación hash puede realizar comparaciones entre distintos tipos de datos de las formas siguientes:
+ Puede comparar cualquier cosa en la categoría de tipos de datos numéricos precisos, como `int`, `bigint`, `numeric` y `bit`.
+ Puede comparar cualquier cosa en la categoría de tipos de datos numéricos aproximados, como `float` y `double`.
+ Puede comparar elementos en distintos tipos de cadena que tengan el mismo conjunto de caracteres y la misma intercalación.
+ Puede comparar elementos con tipos de datos de marca de fecha y hora si los tipos son los mismos.

**nota**  
No se pueden comparar tipos de datos de categorías distintas.

Las siguientes restricciones se aplican a las combinaciones hash de Aurora MySQL:
+ Las uniones exteriores izquierda y derecha no son compatibles con la versión 2 de Aurora MySQL, pero sí con la versión 3.
+ No se admiten las semicombinaciones, como las subconsultas, a no ser que las subconsultas se materialicen primero.
+ No se admiten las actualizaciones o supresiones de varias tablas.
**nota**  
Se admiten las actualizaciones o supresiones de una sola tabla.
+ Las columnas de tipos de datos especiales y BLOB no pueden ser columnas de unión en una combinación hash.

### Habilitación de las combinaciones hash
<a name="Aurora.BestPractices.HashJoin.Enabling"></a>

Para habilitar combinaciones hash:
+ Aurora MySQL versión 2: establezca el parámetro de base de datos o el parámetro del clúster de base de datos `aurora_disable_hash_join` en `0`. Si `aurora_disable_hash_join` está desactivado, se establece el valor de `optimizer_switch` en `hash_join=on`.
+ Aurora MySQL versión 3: establezca el parámetro del servidor MySQL `optimizer_switch` en `block_nested_loop=on`.

Las combinaciones hash están activadas de forma predeterminada en la versión 3 de Aurora MySQL y están desactivadas de forma predeterminada en la versión 2 de Aurora MySQL. En el siguiente ejemplo, se ilustra cómo habilitar las combinaciones hash para la versión 3 de Aurora MySQL. Puede emitir la declaración `select @@optimizer_switch` primero para ver qué otras configuraciones están presentes en la cadena del parámetro `SET`. La actualización de un ajuste en el parámetro `optimizer_switch` no borra ni modifica las demás configuraciones.

```
mysql> SET optimizer_switch='block_nested_loop=on';
```

**nota**  
Para Aurora MySQL, versión 3, se admite la combinación hash en todas las versiones secundarias y se activa de forma predeterminada.  
Para la versión 2 de Aurora MySQL, se admiten combinaciones hash en todas las versiones secundarias. En Aurora MySQL versión 2, la característica de combinación hash siempre está controlada por el valor `aurora_disable_hash_join`.

Con esta configuración, el optimizador elige usar una combinación hash basada en el costo, las características de la consulta y la disponibilidad de los recursos. Si la estimación del costo es incorrecta, puede forzar al optimizador a elegir una combinación hash. Para ello, establezca `hash_join_cost_based`, una variable de MySQL Server, en `off`. En el siguiente ejemplo se ilustra cómo forzar al optimizador a elegir una combinación hash.

```
mysql> SET optimizer_switch='hash_join_cost_based=off';
```

**nota**  
Esta configuración anula las decisiones del optimizador basado en costos. Aunque esta configuración puede ser útil para las pruebas y el desarrollo, le recomendamos que no la utilice en producción.

### Optimización de consultas para combinaciones hash
<a name="Aurora.BestPractices.HashJoin.Optimizing"></a>

Para averiguar si una consulta puede beneficiarse de usar una combinación hash, utilice antes la instrucción `EXPLAIN` para perfilar la consulta. La instrucción `EXPLAIN` ofrece información acerca del plan de ejecución que se va a utilizar para una consulta especificada

En el resultado de la instrucción `EXPLAIN`, la columna `Extra` describe información adicional que se incluye con el plan de ejecución. Si se aplica una combinación hash a las tablas utilizadas en la consulta, esta columna incluye valores similares a los siguientes:
+ `Using where; Using join buffer (Hash Join Outer table table1_name)`
+ `Using where; Using join buffer (Hash Join Inner table table2_name)`

En el siguiente ejemplo se muestra el uso de EXPLAIN para ver el plan de ejecución de una consulta hash join (con combinación hash).

```
mysql> explain SELECT sql_no_cache * FROM hj_small, hj_big, hj_big2
    ->     WHERE hj_small.col1 = hj_big.col1 and hj_big.col1=hj_big2.col1 ORDER BY 1;
+----+-------------+----------+------+---------------+------+---------+------+------+----------------------------------------------------------------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows | Extra                                                          |
+----+-------------+----------+------+---------------+------+---------+------+------+----------------------------------------------------------------+
|  1 | SIMPLE      | hj_small | ALL  | NULL          | NULL | NULL    | NULL |    6 | Using temporary; Using filesort                                |
|  1 | SIMPLE      | hj_big   | ALL  | NULL          | NULL | NULL    | NULL |   10 | Using where; Using join buffer (Hash Join Outer table hj_big)  |
|  1 | SIMPLE      | hj_big2  | ALL  | NULL          | NULL | NULL    | NULL |   15 | Using where; Using join buffer (Hash Join Inner table hj_big2) |
+----+-------------+----------+------+---------------+------+---------+------+------+----------------------------------------------------------------+
3 rows in set (0.04 sec)
```

En la salida, la `Hash Join Inner table` es la tabla utilizada para crear la tabla hash y la `Hash Join Outer table` es la tabla usada para sondear la tabla hash.

Para obtener más información acerca del formato de salida ampliado `EXPLAIN`, consulte [Extended EXPLAIN Output Format](https://dev.mysql.com/doc/refman/8.0/en/explain-extended.html) (Formato de salida ampliado de EXPLAIN) en la documentación de producto de MySQL.

 En Aurora MySQL 2.08 y versiones posteriores, puede usar sugerencias SQL para influir en si una consulta usa combinación hash o no, y las tablas que usar para los lados de compilación y sondeo de la combinación. Para obtener más información, consulte [Sugerencias de Aurora MySQL](AuroraMySQL.Reference.Hints.md). 

## Uso de Amazon Aurora para escalar las lecturas de una base de datos de MySQL
<a name="AuroraMySQL.BestPractices.ReadScaling"></a>

Puede usar Amazon Aurora con su instancia de base de datos MySQL para aprovechar las capacidades de escalado de lectura de Amazon Aurora y ampliar la carga de trabajo de lectura para su instancia de base de datos MySQL. Si desea usar Aurora para leer la escala de su instancia de base de datos de MySQL, cree un clúster de base de datos de Aurora MySQL y haga que sea una réplica de lectura de su instancia de base de datos de MySQL. A continuación, conéctese al clúster Aurora MySQL para procesar las consultas de lectura. La base de datos de origen puede ser una instancia de base de datos de RDS for MySQL o una base de datos de MySQL que se ejecute fuera de Amazon RDS. Para obtener más información, consulte [Escalado de lecturas para su base de datos MySQL con Amazon Aurora](AuroraMySQL.Replication.ReadScaling.md).

## Optimización de las operaciones de marca temporal
<a name="AuroraMySQL.BestPractices.Performance.TimeZone"></a>

Cuando el valor de la variable de sistema `time_zone` se establece en `SYSTEM`, cada llamada a una función de MySQL que requiera un cálculo de zona horaria realiza una llamada a la biblioteca del sistema. Al ejecutar instrucciones SQL que devuelvan o modifiquen dichos valores de `TIMESTAMP` con una alta concurrencia, es posible que aumente la latencia, la contención de bloqueos y el uso de la CPU. Para obtener más información, consulte [time\$1zone](https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_time_zone) en la documentación de MySQL.

Para evitar este comportamiento, se recomienda cambiar el valor del parámetro `time_zone` del clúster de base de datos a `UTC`. Para obtener más información, consulte [Modificación de los parámetros en un grupo de parámetros de clúster de base de datos en Amazon Aurora](USER_WorkingWithParamGroups.ModifyingCluster.md).

Si bien el parámetro `time_zone` es dinámico (no requiere el reinicio del servidor de base de datos), el nuevo valor solo se usará para las conexiones nuevas. Para asegurarse de que todas las conexiones se actualicen y utilicen el nuevo valor de `time_zone`, se recomienda que recicle las conexiones de la aplicación después de actualizar el parámetro del clúster de base de datos.

## Errores de desbordamiento de ID de índice virtual
<a name="AuroraMySQL.BestPractices.Performance.VirtualIndexIDOverflow"></a>

Aurora MySQL limita los valores de los ID de índice virtuales a 8 bits para evitar un problema provocado por el formato de deshacer de MySQL. Si un índice supera el límite de ID de índice virtual, es posible que el clúster no esté disponible. Cuando un índice se acerca al límite de ID de índice virtual o cuando intenta crear un índice por encima del límite de ID de índice virtual, es posible que RDS arroje un código de error `63955` o un código de advertencia `63955`. Para solucionar un error de límite de ID de índice virtual, le recomendamos que vuelva a crear la base de datos con un volcado lógico y una restauración.

Para obtener más información sobre el volcado lógico y la restauración de Amazon Aurora MySQL, consulte [Migrar bases de datos muy grandes a Amazon Aurora MySQL mediante MyDumper y MyLoader](https://aws.amazon.com/blogs/database/migrate-very-large-databases-to-amazon-aurora-mysql-using-mydumper-and-myloader/). Para obtener más información sobre cómo acceder a los registros de errores en Amazon Aurora, consulte [Supervisión de archivos de registro de Amazon Aurora](USER_LogAccess.md).

# Prácticas recomendadas para obtener una elevada disponibilidad de Aurora MySQL
<a name="AuroraMySQL.BestPractices.HA"></a>

Aplique las prácticas recomendadas que se describen a continuación para mejorar la disponibilidad de los clústeres de Aurora MySQL.

**Topics**
+ [Uso de Amazon Aurora para la recuperación de desastres con sus bases de datos de MySQL](#AuroraMySQL.BestPractices.DisasterRecovery)
+ [Migración de MySQL a Amazon Aurora MySQL con un tiempo de inactividad reducido](#AuroraMySQL.BestPractices.Migrating)
+ [Prevención del rendimiento lento, el reinicio automático y la conmutación por error de las instancias de base de datos Aurora MySQL](#AuroraMySQL.BestPractices.Avoiding)

## Uso de Amazon Aurora para la recuperación de desastres con sus bases de datos de MySQL
<a name="AuroraMySQL.BestPractices.DisasterRecovery"></a>

Puede usar Amazon Aurora con su instancia de base de datos MySQL para crear una copia de sseguridad fuera del sitio para la recuperación de desastres. Para usar Aurora para la recuperación de desastres de su instancia de base de datos de MySQL, cree un clúster de base de datos de Amazon Aurora y haga que sea una réplica de lectura de su instancia de base de datos de MySQL. Esto es válido para una instancia de base de datos de RDS for MySQL o una base de datos de MySQL que se ejecute fuera de Amazon RDS.

**importante**  
Cuando configure la replicación entre una instancia de base de datos MySQL y un clúster de base de datos Amazon Aurora MySQL, debe monitorizar la replicación para asegurarse de que sigue estando en un estado correcto y repararla si es necesario.

Para obtener instrucciones acerca de cómo crear un clúster de base de datos de Amazon Aurora MySQL y convertirlo en una réplica de lectura de su instancia de base de datos de MySQL, siga el procedimiento que se describe en [Uso de Amazon Aurora para escalar las lecturas de una base de datos de MySQL](AuroraMySQL.BestPractices.Performance.md#AuroraMySQL.BestPractices.ReadScaling).

Para obtener más información acerca de los modelos de recuperación de desastres, consulte [How to choose the best disaster recovery option for your Amazon Aurora MySQL cluster](https://aws.amazon.com/blogs/database/how-to-choose-the-best-disaster-recovery-option-for-your-amazon-aurora-mysql-cluster/).

## Migración de MySQL a Amazon Aurora MySQL con un tiempo de inactividad reducido
<a name="AuroraMySQL.BestPractices.Migrating"></a>

Al importar datos desde una base de datos de MySQL que admita una aplicación en directo a un clúster de base de datos de Amazon Aurora MySQL, puede que desee reducir la cantidad de tiempo que se interrumpe el servicio mientras se produce la migración. Para ello, puede usar el procedimiento documentado en [Importación de datos a una instancia de base de datos de Amazon RDS para MySQL con tiempo de inactividad reducido](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/mysql-importing-data-reduced-downtime.html) que figura en la *Guía del usuario de Amazon Relational Database Service*. Este procedimiento puede resultar especialmente útil al trabajar con una base de datos de gran tamaño. Puede usar dicho procedimiento para reducir el costo de la importación, ya que minimiza la cantidad de datos que se transfieren a por la red AWS.

El procedimiento muestra los pasos necesarios para transferir una copia de los datos de la base de datos a una instancia de Amazon EC2 e importar los datos en una nueva instancia de base de datos de RDS for MySQL. Dado que Amazon Aurora es compatible con MySQL, puede usar un clúster de base de datos Amazon Aurora para la instancia de base de datos MySQL en Amazon RDS de destino.

## Prevención del rendimiento lento, el reinicio automático y la conmutación por error de las instancias de base de datos Aurora MySQL
<a name="AuroraMySQL.BestPractices.Avoiding"></a>

Si ejecuta una carga de trabajo pesada o cargas de trabajo que superan los recursos asignados a su instancia de base de datos, puede agotar los recursos en los que ejecuta la aplicación y la base de datos de Aurora. Para obtener métricas de su instancia de base de datos, como el uso de la CPU, el uso de la memoria y el número de conexiones de base de datos utilizadas, puede consultar las métricas proporcionadas por Amazon CloudWatch, Performance Insights y Enhanced Monitoring. Para obtener más información acerca de la monitorización de las métricas de las instancias de base de datos, consulte [Supervisión de métricas en un clúster de Amazon Aurora](MonitoringAurora.md).

Si su carga de trabajo agota los recursos que utiliza, su instancia de base de datos podría ralentizarse, reiniciarse o incluso realizar una conmutación por error a otra instancia de base de datos. Para evitarlo, supervise la utilización de los recursos, examine la carga de trabajo que se ejecuta en la instancia de base de datos y realice las optimizaciones necesarias. Si las optimizaciones no mejoran las métricas de la instancia ni mitigan el agotamiento de los recursos, considere la posibilidad de ampliar la instancia de base de datos antes de alcanzar sus límites. Para obtener más información sobre las clases de instancias de base de datos disponibles y sus especificaciones, consulte [Clases de instancia de base de datos de Amazon Aurora](Concepts.DBInstanceClass.md).

# Recomendaciones para características de MySQL en Aurora MySQL
<a name="AuroraMySQL.BestPractices.FeatureRecommendations"></a>

A continuación se describen las funciones que están disponibles en Aurora MySQL para ofrecer compatibilidad con MySQL. Sin embargo, tienen problemas de rendimiento, escalabilidad, estabilidad o compatibilidad en el entorno de Aurora. Por lo tanto, le recomendamos que siga determinadas directrices en el uso de estas características. Por ejemplo, le recomendamos que no utilice determinadas funciones para las implementaciones de Aurora de producción.

**Topics**
+ [Uso de la replicación de varios subprocesos en Aurora MySQL](#AuroraMySQL.BestPractices.MTReplica)
+ [Invocación de funciones de AWS Lambda mediante funciones de MySQL nativas](#AuroraMySQL.BestPractices.Lambda)
+ [Evitar las transacciones de XA con Amazon Aurora MySQL](#AuroraMySQL.BestPractices.XA)
+ [Mantenimiento de las claves externas activadas durante las instrucciones DML](#Aurora.BestPractices.ForeignKeys)
+ [Configuración de la frecuencia de vaciado del búfer de registro](#AuroraMySQL.BestPractices.Flush)
+ [Minimización y solución de problemas de los interbloqueos de Aurora MySQL](#AuroraMySQL.BestPractices.deadlocks)

## Uso de la replicación de varios subprocesos en Aurora MySQL
<a name="AuroraMySQL.BestPractices.MTReplica"></a>

Con la replicación de registros binarios de múltiples procesos, un subproceso SQL lee los eventos del registro de retransmisión y los pone en cola para que se apliquen los subprocesos de trabajo de SQL. Los subprocesos de trabajo SQL se administran mediante un subproceso coordinador. Los eventos de registros binarios se aplican en paralelo cuando es posible.

La replicación de varios subprocesos se admite en la versión 3 de Aurora MySQL y la versión 2.12.1 de Aurora MySQL y versiones posteriores.

Para versiones de Aurora MySQL anteriores a 3.04, Aurora utiliza de forma predeterminada la replicación de subproceso único cuando se utiliza un clúster de base de datos de Aurora MySQL como réplica de lectura para la replicación de registros binarios.

Las versiones anteriores a la versión 2 de Aurora MySQL heredó de MySQL Community Edition varios problemas relativos a la replicación con varios subprocesos. Para esas versiones, no es recomendable usar la replicación con varios subprocesos en entornos de producción.

Si utiliza la replicación de varios subprocesos, le recomendamos que realice pruebas exhaustivas.

Para obtener más información acerca del uso de la replicación en Amazon Aurora, consulte [Replicación con Amazon Aurora](Aurora.Replication.md). Para obtener más información sobre la replicación de varios subprocesos en Aurora MySQL, consulte [Replicación de registros binarios de varios subprocesos](binlog-optimization.md#binlog-optimization-multithreading). 

## Invocación de funciones de AWS Lambda mediante funciones de MySQL nativas
<a name="AuroraMySQL.BestPractices.Lambda"></a>

Recomendamos utilizar las funciones nativas de MySQL `lambda_sync` y `lambda_async` para invocar las funciones de Lambda.

Si utiliza el procedimiento obsoleto `mysql.lambda_async`, es recomendable integrar las llamadas al procedimiento `mysql.lambda_async` en un procedimiento almacenado. Puede llamar a este procedimiento almacenado desde distintos orígenes, como los disparadores o el código cliente. Este método puede ayudar a evitar los problemas de discrepancia de la impedancia y facilitar a los programadores de bases de datos la invocación de las funciones de Lambda.

Para obtener más información acerca de la invocación de funciones de Lambda desde Amazon Aurora, consulte [Invocación de una función de Lambda desde un clúster de base de datos de Amazon Aurora MySQL](AuroraMySQL.Integrating.Lambda.md).

## Evitar las transacciones de XA con Amazon Aurora MySQL
<a name="AuroraMySQL.BestPractices.XA"></a>

No es recomendable usar transacciones de eXtended Architecture (XA) con Aurora MySQL, ya que pueden provocar tiempos de recuperación prolongados si la transacción de XA se encuentra en el estado `PREPARED`. Si debe usar transacciones de XA con Aurora MySQL, siga estas prácticas recomendadas:
+ No deje ninguna transacción de XA abierta en el estado `PREPARED`.
+ Mantenga las transacciones de XA tan pequeñas como sea posible.

Para obtener más información acerca del uso de transacciones de XA con MySQL, consulte [XA Transactions](https://dev.mysql.com/doc/refman/8.0/en/xa.html) en la documentación de MySQL.

## Mantenimiento de las claves externas activadas durante las instrucciones DML
<a name="Aurora.BestPractices.ForeignKeys"></a>

Le recomendamos encarecidamente que no ejecute instrucciones en lenguaje de definición de datos (DDL) cuando la variable `foreign_key_checks` está definida en `0` (apagada).

Si tiene que insertar o actualizar filas que requieran una infracción transitoria de claves externas, siga estos pasos:

1. Establece `foreign_key_checks` en `0`.

1. Realice sus cambios de lenguaje de manipulación de datos (DML).

1. Asegúrese de que los cambios completados no infrinjan ninguna restricción de claves externas.

1. Establezca `foreign_key_checks` en `1` (activado).

Además, siga estas otras prácticas recomendadas para restricciones de clave externa:
+ Asegúrese de que sus aplicaciones cliente no establezcan la variable `foreign_key_checks` en `0` como parte de la variable `init_connect`.
+ Si una restauración a partir de una copia de seguridad lógica `mysqldump` deja de funcionar o está incompleta, asegúrese de que `foreign_key_checks` esté definido en `1` antes de iniciar alguna otra operación en la misma sesión. Una copia de seguridad lógica establece `foreign_key_checks` en `0` cuando se inicia.

## Configuración de la frecuencia de vaciado del búfer de registro
<a name="AuroraMySQL.BestPractices.Flush"></a>

En MySQL Community Edition, para que las transacciones sean duraderas, el búfer de registro de InnoDB debe vaciarse en un almacenamiento duradero. Utilice el parámetro `innodb_flush_log_at_trx_commit` para configurar la frecuencia con la que se vacía el búfer de registro en un disco.

Al establecer el parámetro `innodb_flush_log_at_trx_commit` en el valor predeterminado de 1, el búfer de registro se vacía en cada confirmación de transacción. Esta configuración ayuda a mantener la base de datos compatible con [ACID](https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_acid). Le recomendamos que utilice el ajuste predeterminado de 1.

Cambiar `innodb_flush_log_at_trx_commit` a un valor no predeterminado puede ayudar a reducir la latencia del lenguaje de manipulación de datos (DML), pero se sacrifica la durabilidad de los registros. Esta falta de durabilidad hace que la base de datos ACID no sea compatible. Recomendamos que sus bases de datos cumplan con ACID para evitar el riesgo de pérdida de datos si se reinicia el servidor. Para obtener más información sobre este parámetro, consulte [innodb\$1flush\$1log\$1at\$1trx\$1commit](https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit).

En Aurora MySQL, el procesamiento de un registro de rehacer se descarga a la capa de almacenamiento, por lo que no se descargan los archivos de registro en la instancia de base de datos. Cuando se emite una escritura, los registros de rehacer se envían desde la instancia de base de datos del escritor directamente al volumen del clúster de Aurora. Las únicas escrituras que cruzan la red son los registros de rehacer. Nunca se escribe ninguna página desde el nivel de base de datos.

De manera predeterminada, cada subproceso que confirma una transacción espera la confirmación del volumen del clúster de Aurora. Esta confirmación indica que este registro y todos los registros anteriores de rehacer están escritos y han alcanzado el [quórum](https://aws.amazon.com/blogs/database/amazon-aurora-under-the-hood-quorum-and-correlated-failure/). Si se conservan los registros y se alcanza el quórum, la transacción es duradera, ya sea mediante confirmación automática o explícita. Para obtener más información sobre la arquitectura de almacenamiento de Aurora, consulte [Amazon Aurora storage demystified](https://d1.awsstatic.com/events/reinvent/2020/Amazon_Aurora_storage_demystified_DAT401.pdf).

Aurora MySQL no vacía los registros en los archivos de datos como lo hace MySQL Community Edition. Sin embargo, puede usar el parámetro `innodb_flush_log_at_trx_commit` para relajar las restricciones de durabilidad al escribir registros de rehacer en el volumen del clúster de Aurora.

Para Aurora MySQL, versión 2.
+ `innodb_flush_log_at_trx_commit` = 0 o 2: la base de datos no espera a que se confirme que los registros redo se han escrito en el volumen del clúster de Aurora.
+ `innodb_flush_log_at_trx_commit` = 1: la base de datos espera a que se confirme que los registros redo se han escrito en el volumen del clúster de Aurora.

Para Aurora MySQL, versión 3:
+ `innodb_flush_log_at_trx_commit` = 0: la base de datos no espera a que se confirme que los registros redo se han escrito en el volumen del clúster de Aurora.
+ `innodb_flush_log_at_trx_commit` = 1 o 2: la base de datos espera a que se confirme que los registros redo se han escrito en el volumen del clúster de Aurora.

Por lo tanto, para obtener el mismo comportamiento no predeterminado en Aurora MySQL versión 3 que con el valor establecido en 0 o 2 de Aurora MySQL versión 2, establezca el parámetro en 0.

Si bien estas configuraciones pueden reducir la latencia de DML para el cliente, también pueden provocar la pérdida de datos en caso de una conmutación por error o un reinicio. Por lo tanto, le recomendamos que mantenga el parámetro `innodb_flush_log_at_trx_commit` establecido en el valor predeterminado de 1.

Si bien la pérdida de datos puede ocurrir tanto en MySQL Community Edition como en Aurora MySQL, el comportamiento difiere en cada base de datos debido a sus diferentes arquitecturas. Estas diferencias arquitectónicas pueden provocar diversos grados de pérdida de datos. Para asegurarse de que su base de datos es compatible con ACID, establezca siempre `innodb_flush_log_at_trx_commit` en 1.

**nota**  
En la versión 3 de Aurora MySQL, antes de poder cambiar `innodb_flush_log_at_trx_commit` a un valor distinto de 1, primero debe cambiar el valor de `innodb_trx_commit_allow_data_loss` a 1. Al hacerlo, acepta el riesgo de una posible pérdida de datos.

## Minimización y solución de problemas de los interbloqueos de Aurora MySQL
<a name="AuroraMySQL.BestPractices.deadlocks"></a>

Los usuarios que ejecutan cargas de trabajo que sufren regularmente infracciones de las restricciones en índices secundarios únicos o claves externas, al modificar registros de la misma página de datos de forma simultánea, podrían experimentar un aumento de los interbloqueos y los tiempos de espera de bloqueo. Estos interbloqueos y tiempos de espera se deben a una [corrección de errores](https://bugs.mysql.com/bug.php?id=98324) de MySQL Community Edition.

Esta corrección se incluye en las versiones 5.7.26 y posteriores de MySQL Community Edition, y se ha introducido también en las versiones 2.10.3 y posteriores de Aurora MySQL. La corrección es necesaria para aplicar la *serialización* mediante la implementación de un bloqueo adicional para este tipo de operaciones del lenguaje de manipulación de datos (DML) en los cambios realizados en los registros de una tabla de InnoDB. Este problema se descubrió como parte de una investigación sobre los problemas de interbloqueos introducidos en una [corrección de errores](https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-26.html) anterior de MySQL Community Edition.

La corrección cambió el manejo interno de la *reversión parcial* de una actualización de tuplas (filas) en el motor de almacenamiento de InnoDB. Las operaciones que generan infracciones de restricciones en claves externas o índices secundarios únicos provocan una reversión parcial. Esto incluye, entre otras, instrucciones `INSERT...ON DUPLICATE KEY UPDATE`, `REPLACE INTO,` y `INSERT IGNORE` simultáneas (*upserts*).

En este contexto, la reversión parcial no se refiere a la reversión de las transacciones a nivel de la aplicación, sino a la reversión interna de InnoDB de los cambios en un índice en clúster cuando se detecta una infracción de una restricción. Supongamos que se encuentra un valor de clave duplicado durante una operación upsert.

En una operación de inserción normal, InnoDB crea de forma atómica entradas de índice secundario y [en clúster](https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html) para cada índice. Si InnoDB detecta un valor duplicado en un índice secundario único durante una operación upsert, la entrada insertada en el índice en clúster debe revertirse (reversión parcial) y, a continuación, debe aplicarse la actualización a la fila duplicada existente. Durante este paso de reversión parcial interna, InnoDB debe bloquear cada registro que se detecte como parte de la operación. La solución garantiza la serialización de las transacciones al introducir un bloqueo adicional después de la reversión parcial.

### Minimización de interbloqueos de InnoDB
<a name="AuroraMySQL.BestPractices.deadlocks-minimize"></a>

Puede adoptar los siguientes métodos para reducir la frecuencia de los interbloqueos en la instancia de base de datos. Encontrará más ejemplos en la [documentación de MySQL](https://bugs.mysql.com/bug.php?id=98324).

1. Para reducir las probabilidades de que se produzcan interbloqueos, confirme las transacciones inmediatamente después de realizar un conjunto de cambios relacionados. Para ello, puede dividir las transacciones de gran tamaño (actualizaciones de varias filas entre confirmaciones) en transacciones más pequeñas. Si va a insertar filas por lotes, intente reducir el tamaño de las inserciones por lotes, especialmente cuando utilice las operaciones upsert mencionadas anteriormente.

   Para reducir el número de posibles reversiones parciales, puede probar algunos de los siguientes métodos:

   1. Sustituya las operaciones de inserción por lotes por inserciones de filas de una en una. Esto puede reducir el tiempo durante el que las transacciones mantienen bloqueos que pueden generar conflictos.

   1. En lugar de usar `REPLACE INTO`, reescriba la instrucción SQL como una transacción de múltiples instrucciones, como la siguiente:

      ```
      BEGIN;
      DELETE conflicting rows;
      INSERT new rows;
      COMMIT;
      ```

   1. En lugar de usar `INSERT...ON DUPLICATE KEY UPDATE`, reescriba la instrucción SQL como una transacción de múltiples instrucciones, como la siguiente:

      ```
      BEGIN;
      SELECT rows that conflict on secondary indexes;
      UPDATE conflicting rows;
      INSERT new rows;
      COMMIT;
      ```

1. Evite las transacciones de larga duración, activas o inactivas, que podrían mantener bloqueos. Esto incluye sesiones interactivas de clientes MySQL que podrían estar abiertas durante un periodo de tiempo prolongado con una transacción no confirmada. Al optimizar los tamaños de las transacciones o los tamaños de lotes, el resultado puede variar en función de varios factores, como la simultaneidad, el número de duplicados y la estructura de la tabla. Cualquier cambio debe implementarse y probarse en función de su carga de trabajo.

1. En algunas situaciones, pueden producirse interbloqueos cuando dos transacciones intentan acceder a los mismos conjuntos de datos, ya sea en una o varias tablas, en órdenes diferentes. Para evitarlo, puede modificar las transacciones para que accedan a los datos en el mismo orden, serializando así el acceso. Por ejemplo, cree una cola de transacciones que deben completarse. Este método puede ayudar a evitar interbloqueos cuando se realizan varias transacciones al mismo tiempo.

1. Añadir índices cuidadosamente seleccionados a las tablas puede mejorar la selectividad y reducir la necesidad de acceder a las filas, lo que disminuye los bloqueos.

1. Si se encuentra con un [bloqueo de espacio](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-gap-locks), puede modificar el nivel de aislamiento de las transacciones por `READ COMMITTED` para la sesión o la transacción para evitarlo. Para obtener más información sobre los niveles de aislamiento de InnoDB y sus comportamientos, consulte [Transaction isolation levels](https://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-levels.html) (Niveles de aislamiento de las transacciones) en la documentación de MySQL.

**nota**  
Aunque puede tomar medidas para reducir la posibilidad de que se produzcan interbloqueos, son un comportamiento normal de la base de datos y pueden producirse a pesar de todo. Las aplicaciones deben tener la lógica necesaria para gestionar los interbloqueos cuando se encuentren. Por ejemplo, implemente lógica de reintento e interrupción en la aplicación. Es mejor solucionar la causa principal del problema, pero si se produce un interbloqueo, la aplicación tiene la opción de esperar y volver a intentarlo.

### Supervisión de interbloqueos de InnoDB
<a name="AuroraMySQL.BestPractices.deadlocks-monitor"></a>

Pueden producirse [interbloqueos](https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_deadlock) en MySQL cuando las transacciones de la aplicación intentan aceptar bloqueos a nivel de tabla y fila de una forma que da lugar a una espera circular. Un interbloqueo ocasional de InnoDB no tiene por qué ser necesariamente un problema, ya que el motor de almacenamiento de InnoDB detecta la condición inmediatamente y anula una de las transacciones automáticamente. Si se encuentra con interbloqueos con frecuencia, le recomendamos que revise y modifique la aplicación para reducir los problemas de rendimiento y evitar los interbloqueos. Cuando la [detección de interbloqueos](https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_deadlock_detection) está activada (opción predeterminada), InnoDB detecta automáticamente los interbloqueos de transacciones y revierte una transacción o transacciones para salir del interbloqueo. InnoDB intenta seleccionar transacciones pequeñas para revertirlas, donde el tamaño de una transacción viene determinado por el número de filas insertadas, actualizadas o eliminadas.
+ Instrucción `SHOW ENGINE`: la instrucción `SHOW ENGINE INNODB STATUS \G` contiene [detalles](https://dev.mysql.com/doc/refman/5.7/en/show-engine.html) del último interloqueo encontrado en la base de datos desde el último reinicio.
+ Registro de errores de MySQL: si se encuentra interbloqueos frecuentes en los que la salida de la instrucción `SHOW ENGINE` no es adecuada, puede activar el parámetro del clúster de base de datos [innodb\$1print\$1all\$1deadlocks](https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_print_all_deadlocks).

  Cuando este parámetro está activado, la información sobre todos los interbloqueos en las transacciones de los usuarios de InnoDB se registra en el [registro de errores](https://dev.mysql.com/doc/refman/8.0/en/error-log.html) de Aurora MySQL.
+ Métricas de Amazon CloudWatch: también le recomendamos que supervise de forma proactiva los interbloqueos mediante la métrica de CloudWatch `Deadlocks`. Para obtener más información, consulte [Métricas de nivel de instancia para Amazon Aurora](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances).
+ Registros de Amazon CloudWatch: con Registros de CloudWatch, puede ver métricas, analizar datos de registro y crear alarmas en tiempo real. Para obtener más información, consulte [Monitor errors in Amazon Aurora MySQL and Amazon RDS for MySQL using Amazon CloudWatch and send notifications using Amazon SNS](https://aws.amazon.com/blogs/database/monitor-errors-in-amazon-aurora-mysql-and-amazon-rds-for-mysql-using-amazon-cloudwatch-and-send-notifications-using-amazon-sns/) (Supervisión de errores en Amazon Aurora MySQL y Amazon RDS para MySQL mediante Amazon CloudWatch y envío de notificaciones mediante Amazon SNS).

  Si utiliza Registros de CloudWatch con la opción `innodb_print_all_deadlocks` activada, puede configurar alarmas para que le notifiquen cuando el número de interbloqueos supere un umbral determinado. Para definir un umbral, le recomendamos que observe las tendencias y utilice un valor basado en su carga de trabajo normal.
+ Información sobre rendimiento: al utilizar Información sobre rendimiento, puede supervisar las métricas `innodb_deadlocks` y `innodb_lock_wait_timeout`. Para obtener más información sobre estas métricas, consulte [Contadores no nativos para Aurora MySQL](USER_PerfInsights_Counters.md#USER_PerfInsights_Counters.Aurora_MySQL.NonNative).

# Evaluación de la utilización de instancias de base de datos para Aurora MySQL con métricas de Amazon CloudWatch
<a name="AuroraMySQL.BestPractices.CW"></a>

Puede usar las métricas de CloudWatch para supervisar el rendimiento de su instancia de base de datos y determinar si su clase de instancia de base de datos proporciona recursos suficientes para sus aplicaciones. Para obtener más información acerca de los límites de las clases de instancia de base de datos, consulte [Especificaciones de hardware para clases de instancia de base de datos para Aurora](Concepts.DBInstanceClass.Summary.md). Busque las especificaciones de la clase de instancia de base de datos para encontrar el rendimiento de la red.

Si el uso de la instancia de base de datos está cerca del límite de las clases de instancia, es posible que el rendimiento comience a disminuir. Las métricas de CloudWatch pueden confirmar esta situación para que pueda planificar el escalado vertical manual a una clase de instancia más grande. 

Combine los siguientes valores de métricas de CloudWatch para averiguar si se acerca al límite de clases de instancia:
+ **NetworkThroughput**: rendimiento de red que reciben y transmiten los clientes para cada instancia en el clúster de base de datos de Aurora. Este valor de rendimiento no incluye el tráfico de red entre las instancias del clúster de bases de datos y el volumen de clúster. 
+ **StorageNetworkThroughput**: rendimiento de red que recibe el subsistema de almacenamiento de Aurora y que cada instancia del clúster de bases de datos de Aurora envía al subsistema de almacenamiento de Aurora. 

Sume la métrica **NetworkThroughput** a **StorageNetworkThroughput** para determinar el rendimiento de red recibido y enviado al subsistema de almacenamiento de Aurora por cada instancia del clúster de base de datos de Aurora. El límite de clases de instancia para su instancia debe ser mayor que la suma de estas dos métricas combinadas. 

 Puede utilizar las siguientes métricas para revisar detalles adicionales del tráfico de red de las aplicaciones cliente al enviar y recibir:
+ **NetworkReceiveThroughput**: rendimiento de la red recibido de los clientes por cada instancia de base de datos del clúster de base de datos de Aurora MySQL. Este desempeño no incluye el tráfico de red entre las instancias del clúster de bases de datos de y el volumen de clúster.
+ **NetworkTransmitThroughput**: rendimiento de red enviado a los clientes por cada instancia del clúster de bases de datos de Aurora. Este desempeño no incluye el tráfico de red entre las instancias del clúster de bases de datos de y el volumen de clúster.
+ **StorageNetworkReceiveThroughput**: rendimiento de red recibido del subsistema de almacenamiento de Aurora por cada instancia del clúster de bases de datos.
+ **StorageNetworkTransmitThroughput**: rendimiento de red enviado al subsistema de almacenamiento de Aurora por cada instancia del clúster de bases de datos.

Sume todas estas métricas para evaluar cuál es el uso de su red con respecto al límite de las clases de instancia de base de datos. El límite de las clases de instancias debe ser mayor que la suma de estas métricas combinadas.

Los límites de la red y el uso de la CPU para el almacenamiento están directamente relacionados. Cuando aumenta el rendimiento de la red, también aumenta el uso de la CPU. La supervisión del uso de la CPU y la red proporciona información sobre cómo y por qué se agotan los recursos.

Para ayudar a minimizar el uso de la red, puede plantearse lo siguiente:
+ Utilizar una clase de instancia de base de datos mayor.
+ Dividir las solicitudes de escritura en lotes para reducir las transacciones generales.
+ Redirigir la carga de trabajo de solo lectura a una instancia de solo lectura.
+ Eliminar los índices no utilizados.