

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Praktik terbaik dengan Amazon Aurora MySQL
<a name="AuroraMySQL.BestPractices"></a><a name="best_practices"></a>

Topik ini mencakup informasi tentang praktik terbaik dan opsi untuk menggunakan atau memigrasi data ke klaster DB Amazon Aurora MySQL. Informasi dalam topik ini merangkum dan mengulangi beberapa pedoman dan prosedur yang dapat Anda temukan di [Mengelola klaster DB Amazon Aurora](CHAP_Aurora.md).

**Contents**
+ [Menentukan ke instans DB mana Anda terhubung](#AuroraMySQL.BestPractices.DeterminePrimaryInstanceConnection)
+ [Praktik terbaik untuk performa dan penskalaan Aurora MySQL](AuroraMySQL.BestPractices.Performance.md)
  + [Menggunakan kelas instans T untuk pengembangan dan pengujian](AuroraMySQL.BestPractices.Performance.md#AuroraMySQL.BestPractices.T2Medium)
  + [Mengoptimalkan kueri join yang diindeks MySQL Aurora dengan prefetch kunci asinkron](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.AKP)
    + [Mengaktifkan prefetch kunci asinkron](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.AKP.Enabling)
    + [Mengoptimalkan kueri untuk prefetch kunci asinkron](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.AKP.Optimizing)
  + [Mengoptimalkan kueri join MySQL Aurora besar dengan hash join](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.HashJoin)
    + [Mengaktifkan hash join](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.HashJoin.Enabling)
    + [Mengoptimalkan kueri untuk hash join](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.HashJoin.Optimizing)
  + [Menggunakan Amazon Aurora untuk menskalakan baca untuk basis data MySQL Anda](AuroraMySQL.BestPractices.Performance.md#AuroraMySQL.BestPractices.ReadScaling)
  + [Mengoptimalkan operasi stempel waktu](AuroraMySQL.BestPractices.Performance.md#AuroraMySQL.BestPractices.Performance.TimeZone)
  + [Kesalahan luapan ID indeks virtual](AuroraMySQL.BestPractices.Performance.md#AuroraMySQL.BestPractices.Performance.VirtualIndexIDOverflow)
+ [Praktik terbaik untuk ketersediaan tinggi Aurora MySQL](AuroraMySQL.BestPractices.HA.md)
  + [Menggunakan Amazon Aurora untuk Pemulihan Bencana dengan basis data MySQL Anda](AuroraMySQL.BestPractices.HA.md#AuroraMySQL.BestPractices.DisasterRecovery)
  + [Bermigrasi dari MySQL ke Amazon Aurora MySQL dengan waktu henti yang lebih singkat](AuroraMySQL.BestPractices.HA.md#AuroraMySQL.BestPractices.Migrating)
  + [Menghindari performa lambat, pengaktifan ulang otomatis, dan failover untuk instans Aurora MySQL DB](AuroraMySQL.BestPractices.HA.md#AuroraMySQL.BestPractices.Avoiding)
+ [Rekomendasi untuk fitur MySQL di Aurora MySQL](AuroraMySQL.BestPractices.FeatureRecommendations.md)
  + [Menggunakan replikasi multithreaded di Aurora MySQL](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.MTReplica)
  + [Memanggil AWS Lambda fungsi menggunakan fungsi MySQL asli](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.Lambda)
  + [Menghindari transaksi XA dengan Amazon Aurora MySQL](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.XA)
  + [Mempertahankan kunci asing tetap aktif selama pernyataan DML](AuroraMySQL.BestPractices.FeatureRecommendations.md#Aurora.BestPractices.ForeignKeys)
  + [Mengonfigurasi seberapa sering buffer log di-flush](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.Flush)
  + [Meminimalkan dan memecahkan masalah deadlock Aurora MySQL](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.deadlocks)
    + [Meminimalkan deadlock InnoDB](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.deadlocks-minimize)
    + [Memantau deadlock InnoDB](AuroraMySQL.BestPractices.FeatureRecommendations.md#AuroraMySQL.BestPractices.deadlocks-monitor)
+ [Mengevaluasi penggunaan instans DB untuk Aurora MySQL dengan metrik Amazon CloudWatch](AuroraMySQL.BestPractices.CW.md)

## Menentukan ke instans DB mana Anda terhubung
<a name="AuroraMySQL.BestPractices.DeterminePrimaryInstanceConnection"></a>

Untuk menentukan ke instans DB mana sebuah koneksi terhubung di klaster DB Aurora MySQL, periksa variabel global `innodb_read_only`, seperti yang ditunjukkan dalam contoh berikut.

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

Variabel `innodb_read_only` diatur ke `ON` jika Anda terhubung ke instans DB pembaca. Pengaturan ini berstatus `OFF` jika Anda terhubung ke instans DB penulis, seperti instans primer dalam klaster terprovisi.

Pendekatan ini dapat membantu jika Anda ingin menambahkan logika ke kode aplikasi Anda untuk menyeimbangkan beban kerja atau untuk memastikan bahwa operasi tulis menggunakan koneksi yang tepat.

# Praktik terbaik untuk performa dan penskalaan Aurora MySQL
<a name="AuroraMySQL.BestPractices.Performance"></a>

Anda dapat menerapkan praktik terbaik berikut untuk meningkatkan performa dan skalabilitas klaster Aurora MySQL Anda.

**Topics**
+ [Menggunakan kelas instans T untuk pengembangan dan pengujian](#AuroraMySQL.BestPractices.T2Medium)
+ [Mengoptimalkan kueri join yang diindeks MySQL Aurora dengan prefetch kunci asinkron](#Aurora.BestPractices.AKP)
+ [Mengoptimalkan kueri join MySQL Aurora besar dengan hash join](#Aurora.BestPractices.HashJoin)
+ [Menggunakan Amazon Aurora untuk menskalakan baca untuk basis data MySQL Anda](#AuroraMySQL.BestPractices.ReadScaling)
+ [Mengoptimalkan operasi stempel waktu](#AuroraMySQL.BestPractices.Performance.TimeZone)
+ [Kesalahan luapan ID indeks virtual](#AuroraMySQL.BestPractices.Performance.VirtualIndexIDOverflow)

## Menggunakan kelas instans T untuk pengembangan dan pengujian
<a name="AuroraMySQL.BestPractices.T2Medium"></a>

Instans Amazon Aurora MySQL yang menggunakan kelas instans DB `db.t2`, `db.t3` atau `db.t4g` paling cocok untuk aplikasi yang tidak mendukung beban kerja yang tinggi untuk waktu yang lama. Instans T dirancang untuk memberikan performa dasar sedang dan kemampuan untuk melakukan burst performa yang secara signifikan lebih tinggi sesuai dengan yang dibutuhkan beban kerja Anda. Instans ini ditujukan untuk beban kerja yang tidak menggunakan CPU penuh secara sering atau konsisten, tetapi kadang-kadang memerlukan burst. Kami menyarankan penggunaan kelas instans DB T hanya untuk server pengembangan dan pengujian, atau server non-produksi lainnya. Untuk detail selengkapnya tentang kelas instans T, lihat [Instans performa yang dapat melonjak](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances.html).

Jika klaster Aurora Anda lebih besar dari 40 TB, jangan gunakan kelas instans T. Ketika basis data Anda memiliki volume data yang besar, overhead memori untuk mengelola objek skema dapat melebihi kapasitas instans T.

Jangan aktifkan Skema Performa MySQL pada instans T Amazon Aurora MySQL. Jika Skema Performa diaktifkan, instans ini dapat kehabisan memori.

**Tip**  
 Jika basis data Anda terkadang idle, tetapi di lain waktu memiliki beban kerja yang besar, Anda dapat menggunakan Aurora Serverless v2 sebagai alternatif untuk instans T. Dengan Aurora Serverless v2, Anda menentukan rentang kapasitas dan Aurora akan secara otomatis menaikkan atau menurunkan skala basis data Anda tergantung pada beban kerja saat ini. Untuk detail penggunaan, lihat [Menggunakan Aurora Serverless v2](aurora-serverless-v2.md). Untuk versi mesin basis data yang dapat Anda gunakan dengan Aurora Serverless v2, lihat [Persyaratan dan batasan untuk Aurora Serverless v2](aurora-serverless-v2.requirements.md). 

Saat Anda menggunakan instans T sebagai instans DB di klaster DB Aurora MySQL kami menyarankan hal berikut:
+ Gunakan kelas instans DB yang sama untuk semua instans di klaster DB Anda. Misalnya, jika Anda menggunakan `db.t2.medium` untuk instans penulis Anda, maka kami sarankan Anda menggunakan `db.t2.medium` untuk instans pembaca Anda juga.
+ Jangan sesuaikan pengaturan konfigurasi terkait memori apa pun, seperti `innodb_buffer_pool_size`. Aurora menggunakan serangkaian nilai default yang sudah sangat disesuaikan untuk buffer memori pada instans T. Default khusus ini diperlukan agar Aurora dapat berjalan pada instans yang dibatasi memori. Jika Anda mengubah pengaturan terkait memori pada instance T, Anda jauh lebih mungkin menghadapi out-of-memory kondisi, bahkan jika perubahan Anda dimaksudkan untuk meningkatkan ukuran buffer.
+ Pantau Saldo Kredit CPU Anda (`CPUCreditBalance`) untuk memastikannya berada pada tingkat yang layak. Artinya, kredit CPU diakumulasi pada kecepatan yang sama dengan yang digunakan.

  Ketika Anda telah menghabiskan kredit CPU untuk instans, Anda akan mengalami penurunan yang cepat pada CPU yang tersedia serta peningkatan latensi baca dan tulis untuk instans. Situasi ini menyebabkan penurunan yang parah dalam performa keseluruhan instans.

  Jika saldo kredit CPU Anda tidak berada pada tingkat yang layak, maka kami menyarankan untuk memodifikasi instans DB Anda agar menggunakan salah satu kelas instans DB R yang didukung (penskalaan komputasi).

  Untuk informasi selengkapnya tentang pemantauan metrik, lihat [Melihat metrik di konsol Amazon RDS](USER_Monitoring.md).
+ Pantau lag replika (`AuroraReplicaLag`) antara instans penulis dan instans pembaca.

  Jika instans pembaca kehabisan kredit CPU sebelum instans penulis, lag yang dihasilkan dapat menyebabkan instans pembaca sering diaktifkan ulang. Hasil ini biasa terjadi jika aplikasi memiliki beban operasi baca berat yang didistribusikan di antara instans pembaca, pada waktu yang sama saat instans penulis memiliki beban operasi tulis minimal.

  Jika Anda melihat peningkatan berkelanjutan dalam lag replika, pastikan saldo kredit CPU Anda untuk instans pembaca di klaster DB Anda tidak habis.

  Jika saldo kredit CPU Anda tidak berada pada tingkat yang layak, maka kami menyarankan untuk memodifikasi instans DB Anda agar menggunakan salah satu kelas instans DB R yang didukung (penskalaan komputasi).
+ Pertahankan jumlah penyisipan per transaksi di bawah 1 juta untuk klaster DB yang memiliki pencatatan log biner.

  Jika grup parameter cluster DB untuk cluster DB Anda memiliki `binlog_format` parameter yang disetel ke nilai selain`OFF`, maka cluster DB Anda mungkin mengalami out-of-memory kondisi jika cluster DB menerima transaksi yang berisi lebih dari 1 juta baris untuk disisipkan. Anda dapat memantau metrik memori yang dapat dibebaskan (`FreeableMemory`) untuk menentukan apakah klaster DB Anda kehabisan memori. Kemudian, Anda memeriksa metrik operasi tulis (`VolumeWriteIOPS`) untuk melihat apakah instans penulis menerima beban berat dari operasi tulis. Jika demikian, kami menyarankan agar Anda memperbarui aplikasi Anda untuk membatasi jumlah penyisipan dalam transaksi hingga kurang dari 1 juta. Alternatifnya, Anda dapat memodifikasi instans Anda untuk menggunakan salah satu dari kelas instans DB R yang didukung (penskalaan komputasi).

## Mengoptimalkan kueri join yang diindeks MySQL Aurora dengan prefetch kunci asinkron
<a name="Aurora.BestPractices.AKP"></a>

Aurora MySQL dapat menggunakan fitur prefetch kunci asinkron (AKP) untuk meningkatkan performa kueri yang menggabungkan tabel di seluruh indeks. Fitur ini meningkatkan performa dengan mengantisipasi baris yang diperlukan untuk menjalankan kueri yang mengharuskan kueri JOIN menggunakan fitur optimisasi Batched Key Access (BKA) dan Multi-Range Read (MRR). Untuk informasi selengkapnya tentang BKA dan MRR, lihat [Block nested-loop and batched key access joins](https://dev.mysql.com/doc/refman/5.6/en/bnl-bka-optimization.html) dan [Multi-range read optimization](https://dev.mysql.com/doc/refman/5.6/en/mrr-optimization.html) dalam dokumentasi MySQL.

Untuk memanfaatkan fitur AKP, kueri harus menggunakan BKA dan MRR. Biasanya, kueri tersebut terjadi saat klausa JOIN dari kueri menggunakan indeks sekunder, tetapi juga memerlukan beberapa kolom dari indeks primer. Misalnya, Anda dapat menggunakan AKP ketika klausa JOIN merepresentasikan equijoin pada nilai indeks antara tabel luar kecil dan tabel dalam besar, dan indeksnya sangat selektif pada tabel yang lebih besar. AKP beroperasi bersama dengan BKA dan MRR untuk melakukan pencarian indeks sekunder hingga primer selama evaluasi klausa JOIN. AKP mengidentifikasi baris yang diperlukan untuk menjalankan kueri selama evaluasi klausa JOIN. Kemudian, fitur ini menggunakan thread latar belakang untuk secara asinkron memuat halaman yang berisi baris tersebut ke dalam memori sebelum menjalankan kueri.

AKP tersedia untuk Aurora MySQL versi 2.10 dan lebih tinggi, serta versi 3. Untuk informasi selengkapnya tentang versi Aurora MySQL, lihat [Pembaruan mesin database untuk Amazon Aurora My SQLDukungan jangka panjang (LTS) dan rilis beta untuk Amazon Aurora MySQL](AuroraMySQL.Updates.md).

### Mengaktifkan prefetch kunci asinkron
<a name="Aurora.BestPractices.AKP.Enabling"></a>

Anda dapat mengaktifkan fitur AKP dengan mengatur `aurora_use_key_prefetch`, sebuah variabel server MySQL, ke `on`. Secara default, nilai ini diatur ke `on`. Namun, AKP tidak dapat diaktifkan sampai Anda juga mengaktifkan algoritma BKA Join dan menonaktifkan fungsionalitas MRR berbasis biaya. Untuk melakukannya, Anda harus menetapkan nilai berikut untuk `optimizer_switch`, sebuah variabel server MySQL:
+ Atur `batched_key_access` ke `on`. Nilai ini mengontrol penggunaan algoritma BKA Join. Secara default, nilai ini diatur ke `off`.
+ Atur `mrr_cost_based` ke `off`. Nilai ini mengontrol penggunaan fungsionalitas MRR berbasis biaya. Secara default, nilai ini diatur ke `on`.

Saat ini, Anda dapat mengatur nilai ini hanya di tingkat sesi. Contoh berikut menggambarkan cara menetapkan nilai-nilai ini untuk mengaktifkan AKP untuk sesi saat ini dengan mengeksekusi pernyataan SET.

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

Demikian pula, Anda dapat menggunakan pernyataan SET untuk menonaktifkan AKP dan algoritma BKA Join serta mengaktifkan ulang fungsi MRR berbasis biaya untuk sesi saat ini, seperti yang ditunjukkan dalam contoh berikut.

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

Untuk informasi selengkapnya tentang switch pengoptimisasi **batched\$1key\$1access** dan **mrr\$1cost\$1based** lihat [Switchable optimizations](https://dev.mysql.com/doc/refman/5.6/en/switchable-optimizations.html) dalam dokumentasi MySQL.

### Mengoptimalkan kueri untuk prefetch kunci asinkron
<a name="Aurora.BestPractices.AKP.Optimizing"></a>

Anda dapat mengonfirmasi apakah kueri dapat memanfaatkan fitur AKP. Untuk melakukannya, gunakan pernyataan `EXPLAIN` untuk membuat profil kueri sebelum menjalankannya. Pernyataan `EXPLAIN` memberikan informasi tentang rencana eksekusi yang akan digunakan untuk kueri tertentu.

Pada output pernyataan `EXPLAIN`, kolom `Extra` menjelaskan informasi tambahan, termasuk rencana eksekusi. Jika fitur AKP berlaku pada tabel yang digunakan dalam kueri, kolom ini mencakup salah satu nilai berikut:
+ `Using Key Prefetching`
+ `Using join buffer (Batched Key Access with Key Prefetching)`

Contoh berikut menunjukkan penggunaan `EXPLAIN` untuk melihat rencana eksekusi untuk kueri yang dapat memanfaatkan 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)
```

Untuk informasi selengkapnya tentang format output `EXPLAIN`, lihat [Extended EXPLAIN output format](https://dev.mysql.com/doc/refman/8.0/en/explain-extended.html) dalam dokumentasi MySQL.

## Mengoptimalkan kueri join MySQL Aurora besar dengan hash join
<a name="Aurora.BestPractices.HashJoin"></a>

Saat Anda harus menggabungkan sejumlah besar data dengan menggunakan equijoin, hash join dapat meningkatkan performa kueri. Anda dapat mengaktifkan hash join untuk Aurora MySQL.

Kolom hash join dapat berupa ekspresi rumit apa pun. Dalam kolom hash join, Anda dapat membandingkan jenis data dengan cara berikut:
+ Anda dapat membandingkan apa pun dalam kategori jenis data numerik yang tepat, seperti `int`, `bigint`, `numeric`, dan `bit`.
+ Anda dapat membandingkan apa pun dalam kategori perkiraan jenis data numerik, seperti `float` dan `double`.
+ Anda dapat membandingkan item di seluruh jenis string jika jenis string memiliki kumpulan karakter dan kolasi yang sama.
+ Anda dapat membandingkan item dengan jenis data tanggal dan stempel waktu jika jenisnya sama.

**catatan**  
Anda tidak dapat membandingkan jenis data dalam kategori yang berbeda.

Batasan berikut berlaku untuk hash join untuk Aurora MySQL:
+ Outer join kiri-kanan tidak didukung untuk Aurora MySQL versi 2, tetapi didukung untuk versi 3.
+ Semijoin seperti subkueri tidak didukung, kecuali jika subkueri dimaterialkan terlebih dahulu.
+ Pembaruan atau penghapusan multi-tabel tidak didukung.
**catatan**  
Pembaruan atau penghapusan satu tabel didukung.
+ Kolom jenis data spasial dan BLOB tidak dapat menjadi kolom join dalam hash join.

### Mengaktifkan hash join
<a name="Aurora.BestPractices.HashJoin.Enabling"></a>

Untuk mengaktifkan hash join:
+ Aurora MySQL versi 2 - Atur parameter DB atau parameter klaster DB `aurora_disable_hash_join` ke `0`. Menonaktifkan `aurora_disable_hash_join` akan menetapkan nilai `optimizer_switch` ke `hash_join=on`.
+ Aurora MySQL versi 3 - Atur parameter server MySQL `optimizer_switch` ke `block_nested_loop=on`.

Hash join diaktifkan secara default di Aurora MySQL versi 3 dan dinonaktifkan secara default di Aurora MySQL versi 2. Contoh berikut mengilustrasikan cara mengaktifkan hash join untuk Aurora MySQL versi 3. Anda dapat mengeluarkan pernyataan `select @@optimizer_switch` terlebih dahulu untuk melihat apa saja pengaturan lain yang ada dalam string parameter `SET`. Memperbarui satu pengaturan dalam parameter `optimizer_switch` tidak akan menghapus atau memodifikasi pengaturan lainnya.

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

**catatan**  
Untuk Aurora MySQL versi 3, dukungan hash join tersedia di semua versi minor dan diaktifkan secara default.  
Untuk Aurora MySQL versi 2, dukungan hash join tersedia di semua versi minor. Di Aurora MySQL versi 2, fitur hash join selalu dikendalikan oleh nilai `aurora_disable_hash_join`.

Dengan pengaturan ini, pengoptimisasi memilih untuk menggunakan hash join berdasarkan biaya, karakteristik kueri, dan ketersediaan sumber daya. Jika estimasi biaya salah, Anda dapat memaksa pengoptimisasi untuk memilih hash join. Caranya adalah dengan mengatur `hash_join_cost_based`, sebuah variabel server MySQL, ke `off`. Contoh berikut mengilustrasikan cara memaksa pengoptimisasi untuk memilih hash join.

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

**catatan**  
Pengaturan ini mengganti keputusan pengoptimisasi berbasis biaya. Meskipun pengaturan ini dapat berguna untuk pengujian dan pengembangan, kami menyarankan Anda untuk tidak menggunakannya dalam produksi.

### Mengoptimalkan kueri untuk hash join
<a name="Aurora.BestPractices.HashJoin.Optimizing"></a>

Untuk mengetahui apakah kueri dapat memanfaatkan hash join, gunakan pernyataan `EXPLAIN` untuk membuat profil kueri terlebih dahulu. Pernyataan `EXPLAIN` memberikan informasi tentang rencana eksekusi yang akan digunakan untuk kueri tertentu.

Pada output pernyataan `EXPLAIN`, kolom `Extra` menjelaskan informasi tambahan, termasuk rencana eksekusi. Jika hash join berlaku pada tabel yang digunakan dalam kueri, kolom ini akan mencakup nilai seperti yang berikut ini:
+ `Using where; Using join buffer (Hash Join Outer table table1_name)`
+ `Using where; Using join buffer (Hash Join Inner table table2_name)`

Contoh berikut menunjukkan penggunaan EXPLAIN untuk melihat rencana eksekusi untuk kueri hash join.

```
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)
```

Dalam output ini, `Hash Join Inner table` adalah tabel yang digunakan untuk membuat tabel hash, dan `Hash Join Outer table` adalah tabel yang digunakan untuk menyelidiki tabel hash.

Untuk informasi selengkapnya tentang format output `EXPLAIN` yang diperluas, lihat [Extended EXPLAIN Output Format](https://dev.mysql.com/doc/refman/8.0/en/explain-extended.html) dalam dokumentasi produk MySQL.

 Di Aurora MySQL 2.08 dan yang lebih tinggi, Anda dapat menggunakan petunjuk SQL untuk memengaruhi apakah kueri menggunakan hash join atau tidak, dan tabel mana yang digunakan untuk sisi build dan probe dari join. Untuk detailnya, lihat [Aurora Petunjuk saya SQL](AuroraMySQL.Reference.Hints.md). 

## Menggunakan Amazon Aurora untuk menskalakan baca untuk basis data MySQL Anda
<a name="AuroraMySQL.BestPractices.ReadScaling"></a>

Anda dapat menggunakan Amazon Aurora dengan instans DB MySQL Anda untuk memanfaatkan kemampuan penskalaan baca Amazon Aurora dan memperluas beban kerja baca untuk instans DB MySQL Anda. Untuk menggunakan Aurora untuk menskalakan baca instans DB MySQL Anda, buat klaster DB Aurora MySQL dan jadikan sebagai replika baca dari instans DB MySQL Anda. Kemudian, hubungkan ke klaster Aurora MySQL untuk memproses kueri baca. Basis data sumber dapat berupa instans DB RDS for MySQL, atau sebuah basis data MySQL yang dijalankan secara eksternal di luar Amazon RDS. Untuk informasi selengkapnya, lihat [Penskalaan bacaan untuk database MySQL Anda dengan Amazon Aurora](AuroraMySQL.Replication.ReadScaling.md).

## Mengoptimalkan operasi stempel waktu
<a name="AuroraMySQL.BestPractices.Performance.TimeZone"></a>

Ketika nilai variabel sistem `time_zone` diatur ke `SYSTEM`, setiap panggilan fungsi MySQL yang memerlukan perhitungan zona waktu akan membuat panggilan pustaka sistem. Saat Anda menjalankan pernyataan SQL yang menampilkan atau mengubah nilai `TIMESTAMP` tersebut pada konkurensi tinggi, Anda mungkin akan mengalami latensi, pertentangan kunci, dan penggunaan CPU yang meningkat. Untuk informasi selengkapnya, lihat [time\$1zone](https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_time_zone) dalam dokumentasi MySQL.

Untuk menghindari perilaku ini, sebaiknya Anda mengubah nilai parameter klaster DB `time_zone` menjadi `UTC`. Untuk informasi selengkapnya, lihat [Memodifikasi parameter dalam grup parameter cluster DB di Amazon Aurora](USER_WorkingWithParamGroups.ModifyingCluster.md).

Meskipun parameter `time_zone` bersifat dinamis (tidak memerlukan pengaktifan ulang server basis data), nilai baru hanya digunakan untuk koneksi baru. Untuk memastikan bahwa semua koneksi diperbarui untuk menggunakan nilai `time_zone` baru, kami sarankan Anda mendaur ulang koneksi aplikasi Anda setelah memperbarui parameter klaster DB.

## Kesalahan luapan ID indeks virtual
<a name="AuroraMySQL.BestPractices.Performance.VirtualIndexIDOverflow"></a>

Aurora MySQL membatasi nilai untuk indeks virtual IDs hingga 8 bit mencegah masalah yang disebabkan oleh format undo di MySQL. Jika indeks melebihi batas ID indeks virtual, klaster Anda mungkin tidak tersedia. Ketika indeks mendekati batas ID indeks virtual atau ketika Anda mencoba membuat indeks di atas batas ID indeks virtual, RDS mungkin membuang kode kesalahan `63955` atau kode `63955` peringatan. Untuk mengatasi kesalahan batas ID indeks virtual, kami sarankan Anda membuat ulang database Anda dengan dump dan restore logis.

Untuk informasi selengkapnya tentang dump logis dan restore untuk Amazon Aurora MySQL, [lihat Memigrasikan database yang sangat besar ke](https://aws.amazon.com/blogs/database/migrate-very-large-databases-to-amazon-aurora-mysql-using-mydumper-and-myloader/) Amazon Aurora MySQL menggunakan dan. MyDumper MyLoader Untuk informasi selengkapnya tentang mengakses log kesalahan di Amazon Aurora, lihat. [Memantau log Amazon Aurora Amazon](USER_LogAccess.md)

# Praktik terbaik untuk ketersediaan tinggi Aurora MySQL
<a name="AuroraMySQL.BestPractices.HA"></a>

Anda dapat menerapkan praktik terbaik berikut untuk meningkatkan ketersediaan klaster Aurora MySQL Anda.

**Topics**
+ [Menggunakan Amazon Aurora untuk Pemulihan Bencana dengan basis data MySQL Anda](#AuroraMySQL.BestPractices.DisasterRecovery)
+ [Bermigrasi dari MySQL ke Amazon Aurora MySQL dengan waktu henti yang lebih singkat](#AuroraMySQL.BestPractices.Migrating)
+ [Menghindari performa lambat, pengaktifan ulang otomatis, dan failover untuk instans Aurora MySQL DB](#AuroraMySQL.BestPractices.Avoiding)

## Menggunakan Amazon Aurora untuk Pemulihan Bencana dengan basis data MySQL Anda
<a name="AuroraMySQL.BestPractices.DisasterRecovery"></a>

Anda dapat menggunakan Amazon Aurora dengan instans DB MySQL Anda untuk membuat cadangan di luar lokasi untuk pemulihan bencana. Untuk menggunakan Aurora untuk pemulihan bencana instans DB MySQL Anda, buat klaster DB Amazon Aurora dan jadikan sebagai replika baca instans DB MySQL Anda. Hal ini berlaku untuk satu instans DB RDS for MySQL, atau basis data MySQL yang dijalankan secara eksternal di luar Amazon RDS.

**penting**  
Saat Anda mengatur replikasi i antara instans DB MySQL dan klaster DB Amazon Aurora MySQL, Anda harus memantau replikasi untuk memastikan kondisinya tetap baik dan memperbaikinya jika perlu.

Untuk petunjuk tentang cara membuat klaster DB Amazon Aurora MySQL dan menjadikannya sebagai replika baca dari instans DB MySQL Anda, ikuti prosedur dalam [Menggunakan Amazon Aurora untuk menskalakan baca untuk basis data MySQL Anda](AuroraMySQL.BestPractices.Performance.md#AuroraMySQL.BestPractices.ReadScaling).

Untuk informasi selengkapnya tentang model pemulihan bencana, lihat [Cara memilih opsi pemulihan bencana terbaik untuk klaster MySQL Amazon Aurora Anda](https://aws.amazon.com/blogs/database/how-to-choose-the-best-disaster-recovery-option-for-your-amazon-aurora-mysql-cluster/).

## Bermigrasi dari MySQL ke Amazon Aurora MySQL dengan waktu henti yang lebih singkat
<a name="AuroraMySQL.BestPractices.Migrating"></a>

Saat mengimpor data dari basis data MySQL yang mendukung aplikasi aktif ke klaster DB Amazon Aurora MySQL, Anda mungkin ingin mengurangi waktu gangguan layanan saat Anda bermigrasi. Untuk melakukannya, Anda dapat menggunakan prosedur yang didokumentasikan dalam [Mengimpor data ke instans Amazon RDS for MySQL DB dengan](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/mysql-importing-data-reduced-downtime.html) mengurangi waktu henti di Panduan Pengguna Layanan Amazon *Relational* Database Service. Prosedur ini terutama dapat membantu jika Anda beroperasi dengan basis data yang sangat besar. Anda dapat menggunakan prosedur ini untuk mengurangi biaya impor dengan meminimalkan jumlah data yang diteruskan melalui jaringan ke AWS.

Prosedur ini mencantumkan langkah-langkah untuk mentransfer salinan data basis data Anda ke instans Amazon EC2 dan mengimpor data ke instans DB RDS for MySQL baru. Karena Amazon Aurora kompatibel dengan MySQL, Anda dapat menggunakan klaster DB Amazon Aurora untuk instans DB Amazon RDS MySQL target.

## Menghindari performa lambat, pengaktifan ulang otomatis, dan failover untuk instans Aurora MySQL DB
<a name="AuroraMySQL.BestPractices.Avoiding"></a>

Jika Anda menjalankan beban kerja berat atau beban kerja yang melonjak melampaui sumber daya yang dialokasikan untuk instans DB Anda, Anda dapat menghabiskan sumber daya yang Anda gunakan untuk menjalankan aplikasi dan basis data Aurora. Untuk mendapatkan metrik pada instans database Anda seperti pemanfaatan CPU, penggunaan memori, dan jumlah koneksi database yang digunakan, Anda dapat merujuk ke metrik yang disediakan oleh Amazon, Performance CloudWatch Insights, dan Enhanced Monitoring. Untuk informasi selengkapnya tentang pemantauan instans DB, lihat [Memantau metrik di klaster Amazon Aurora](MonitoringAurora.md).

Jika beban kerja Anda menghabiskan sumber daya yang Anda gunakan, instans DB Anda mungkin akan menjadi lambat, diaktifkan ulang, atau bahkan melakukan failover ke instans DB lain. Untuk menghindari hal ini, pantau pemanfaatan sumber daya Anda, periksa beban kerja yang berjalan pada instans DB Anda, dan buat pengoptimalan jika diperlukan. Jika pengoptimalan tidak meningkatkan metrik instans dan mengurangi kehabisan sumber daya, pertimbangkan untuk menaikkan skala instans DB Anda sebelum mencapai batasnya. Untuk informasi selengkapnya tentang kelas instans DB yang tersedia dan spesifikasinya, lihat [Kelas instans Amazon Aurora DB](Concepts.DBInstanceClass.md).

# Rekomendasi untuk fitur MySQL di Aurora MySQL
<a name="AuroraMySQL.BestPractices.FeatureRecommendations"></a>

Fitur-fitur berikut tersedia di Aurora MySQL untuk kompatibilitas MySQL. Namun, fitur-fitur ini memiliki masalah performa, skalabilitas, stabilitas, atau kompatibilitas di lingkungan Aurora. Oleh karena itu, kami menyarankan Anda mengikuti pedoman tertentu dalam penggunaan fitur-fitur ini. Misalnya, kami sarankan Anda tidak menggunakan fitur tertentu untuk deployment Aurora produksi.

**Topics**
+ [Menggunakan replikasi multithreaded di Aurora MySQL](#AuroraMySQL.BestPractices.MTReplica)
+ [Memanggil AWS Lambda fungsi menggunakan fungsi MySQL asli](#AuroraMySQL.BestPractices.Lambda)
+ [Menghindari transaksi XA dengan Amazon Aurora MySQL](#AuroraMySQL.BestPractices.XA)
+ [Mempertahankan kunci asing tetap aktif selama pernyataan DML](#Aurora.BestPractices.ForeignKeys)
+ [Mengonfigurasi seberapa sering buffer log di-flush](#AuroraMySQL.BestPractices.Flush)
+ [Meminimalkan dan memecahkan masalah deadlock Aurora MySQL](#AuroraMySQL.BestPractices.deadlocks)

## Menggunakan replikasi multithreaded di Aurora MySQL
<a name="AuroraMySQL.BestPractices.MTReplica"></a>

Dengan replikasi log biner multi-thread, thread SQL membaca peristiwa dari log relai dan mengantrekannya agar thread pekerja SQL dapat diterapkan. Thread pekerja SQL dikelola oleh thread koordinator. Peristiwa log biner diterapkan secara paralel jika memungkinkan.

Replikasi multithreaded didukung di Aurora MySQL versi 3, dan di Aurora MySQL versi 2.12.1 dan lebih tinggi.

Untuk versi MySQL Aurora yang lebih rendah dari 3,04, Aurora menggunakan replikasi single-threaded secara default ketika cluster DB MySQL Aurora digunakan sebagai replika baca untuk replikasi log biner.

Versi sebelumnya dari Aurora MySQL versi 2 mewarisi beberapa masalah mengenai replikasi multithreaded dari MySQL Community Edition. Untuk versi tersebut, kami menyarankan Anda untuk tidak menggunakan replikasi multithreaded dalam produksi.

Jika Anda menggunakan replikasi multithreaded, kami sarankan Anda mengujinya secara menyeluruh.

Untuk informasi selengkapnya tentang replikasi di Amazon Aurora, lihat [Replikasi dengan Amazon Aurora](Aurora.Replication.md). Untuk informasi selengkapnya tentang replikasi multithreaded di Aurora MySQL, lihat. [Replikasi log biner multithreaded](binlog-optimization.md#binlog-optimization-multithreading) 

## Memanggil AWS Lambda fungsi menggunakan fungsi MySQL asli
<a name="AuroraMySQL.BestPractices.Lambda"></a>

Sebaiknya gunakan fungsi MySQL native `lambda_sync` dan `lambda_async` untuk menginvokasi fungsi Lambda.

Jika Anda menggunakan prosedur `mysql.lambda_async` yang sudah dihentikan, kami sarankan agar Anda menggabungkan panggilan ke prosedur `mysql.lambda_async` dalam prosedur tersimpan. Anda dapat memanggil prosedur tersimpan ini dari berbagai sumber, seperti pemicu atau kode klien. Pendekatan ini dapat membantu menghindari masalah ketidakcocokan impedansi dan memudahkan pemrogram basis data Anda untuk menginvokasi fungsi Lambda.

Untuk informasi selengkapnya tentang menginvokasi fungsi Lambda dari Amazon Aurora, lihat [Menginvokasi fungsi Lambda dari klaster DB Amazon Aurora MySQL](AuroraMySQL.Integrating.Lambda.md).

## Menghindari transaksi XA dengan Amazon Aurora MySQL
<a name="AuroraMySQL.BestPractices.XA"></a>

Sebaiknya jangan gunakan transaksi eXtended Architecture (XA) dengan Aurora MySQL karena dapat menyebabkan waktu pemulihan yang lama jika XA berada di status `PREPARED`. Jika Anda harus menggunakan transaksi XA dengan Aurora MySQL, ikuti praktik terbaik ini:
+ Jangan tinggalkan transaksi XA terbuka pada status `PREPARED`.
+ Pertahankan transaksi XA sekecil mungkin.

Untuk informasi selengkapnya tentang menggunakan transaksi XA dengan MySQL, lihat [XA transactions](https://dev.mysql.com/doc/refman/8.0/en/xa.html) dalam dokumentasi MySQL.

## Mempertahankan kunci asing tetap aktif selama pernyataan DML
<a name="Aurora.BestPractices.ForeignKeys"></a>

Kami sangat menyarankan agar Anda tidak menjalankan pernyataan bahasa definisi data (DDL) saat variabel `foreign_key_checks` diatur menjadi `0` (nonaktif).

Jika Anda perlu menyisipkan atau memperbarui baris yang memerlukan pelanggaran sementara terhadap kunci asing, ikuti langkah-langkah berikut:

1. Atur `foreign_key_checks` ke `0`.

1. Membuat perubahan bahasa manipulasi data (DML).

1. Pastikan bahwa perubahan yang telah Anda selesaikan tidak melanggar batasan kunci asing.

1. Atur `foreign_key_checks` ke `1` (aktif).

Selain itu, ikuti praktik terbaik lainnya untuk batasan kunci asing:
+ Pastikan bahwa aplikasi klien tidak mengatur variabel `foreign_key_checks` ke `0` sebagai bagian dari variabel `init_connect`.
+ Jika pemulihan dari cadangan logis seperti `mysqldump` gagal atau tidak selesai, pastikan bahwa `foreign_key_checks` diatur ke `1` sebelum memulai operasi lain pada sesi yang sama. Cadangan logis mengatur `foreign_key_checks` ke `0` saat dimulai.

## Mengonfigurasi seberapa sering buffer log di-flush
<a name="AuroraMySQL.BestPractices.Flush"></a>

Di MySQL Community Edition, untuk membuat transaksi durabel, buffer log InnoDB harus di-flush ke penyimpanan yang durabel. Anda menggunakan parameter `innodb_flush_log_at_trx_commit` untuk mengonfigurasi seberapa sering buffer log di-flush ke disk.

Saat Anda mengatur parameter `innodb_flush_log_at_trx_commit` ke nilai default 1, buffer log akan di-flush pada setiap commit transaksi. Pengaturan ini membantu menjaga basis data memenuhi persyaratan [ACID](https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_acid). Kami menyarankan Anda untuk tetap mempertahankan pengaturan default 1.

Mengubah `innodb_flush_log_at_trx_commit` ke nilai nondefault dapat membantu mengurangi latensi bahasa manipulasi data (DHTML), tetapi mengorbankan daya tahan catatan log. Kurangnya durabilitas ini membuat basis data tidak memenuhi persyaratan ACID. Kami menyarankan agar basis data Anda memenuhi persyaratan ACID untuk menghindari risiko data jika server diaktifkan ulang. Untuk informasi selengkapnya tentang parameter ini, lihat [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) dalam dokumentasi MySQL.

Di Aurora MySQL, pemrosesan log redo dialihkan ke lapisan penyimpanan, jadi tidak ada flushing ke file log yang terjadi pada instans DB. Ketika sebuah penulisan dikeluarkan, log redo akan dikirim dari instans DB penulis langsung ke volume klaster Aurora. Satu-satunya penulisan yang melintasi jaringan adalah catatan log redo. Tidak ada halaman yang akan ditulis dari tingkat basis data.

Secara default, setiap thread yang melakukan transaksi menunggu konfirmasi dari volume cluster Aurora. Konfirmasi ini menunjukkan bahwa catatan ini dan semua catatan log redo sebelumnya telah ditulis dan mencapai [kuorum](https://aws.amazon.com/blogs/database/amazon-aurora-under-the-hood-quorum-and-correlated-failure/). Mempersistensi catatan log dan mencapai kuorum akan membuat transaksi durabel, baik melalui commit otomatis maupun commit eksplisit. Untuk informasi selengkapnya tentang arsitektur penyimpanan Aurora, lihat [Amazon Aurora storage demystified](https://d1.awsstatic.com/events/reinvent/2020/Amazon_Aurora_storage_demystified_DAT401.pdf).

Aurora MySQL tidak mem-flush log ke file data seperti yang dilakukan MySQL Community Edition. Namun, Anda dapat menggunakan parameter `innodb_flush_log_at_trx_commit` untuk melonggarkan batasan durabilitas saat menulis catatan log redo ke volume klaster Aurora.

Untuk Aurora MySQL versi 2:
+ `innodb_flush_log_at_trx_commit`= 0 atau 2 — Database tidak menunggu konfirmasi bahwa catatan log ulang ditulis ke volume cluster Aurora.
+ `innodb_flush_log_at_trx_commit`= 1 — Database menunggu konfirmasi bahwa catatan redo log ditulis ke volume cluster Aurora.

Untuk Aurora MySQL versi 3:
+ `innodb_flush_log_at_trx_commit`= 0 — Database tidak menunggu konfirmasi bahwa catatan redo log ditulis ke volume cluster Aurora.
+ `innodb_flush_log_at_trx_commit`= 1 atau 2 — Database menunggu konfirmasi bahwa catatan log ulang ditulis ke volume cluster Aurora.

Oleh karena itu, untuk mendapatkan perilaku nondefault yang sama di Aurora MySQL versi 3 yang Anda lakukan dengan nilai yang disetel ke 0 atau 2 di Aurora MySQL versi 2, atur parameter ke 0.

Meskipun dapat menurunkan latensi DML ke klien, pengaturan ini juga dapat mengakibatkan kehilangan data jika terjadi failover atau pengaktifan ulang. Oleh karena itu, sebaiknya pertahankan parameter `innodb_flush_log_at_trx_commit` yang diatur ke nilai default 1.

Meskipun kehilangan data dapat terjadi di MySQL Community Edition dan Aurora MySQL, perilaku di setiap basis data berbeda karena arsitekturnya yang berbeda. Perbedaan arsitektur ini dapat menyebabkan berbagai tingkat kehilangan data. Untuk memastikan bahwa basis data Anda memenuhi persyaratan ACID, selalu atur `innodb_flush_log_at_trx_commit` ke 1.

**catatan**  
Di Aurora MySQL versi 3, sebelum Anda dapat mengubah `innodb_flush_log_at_trx_commit` ke nilai selain 1, Anda harus terlebih dahulu mengubah nilai `innodb_trx_commit_allow_data_loss` menjadi 1. Dengan melakukannya, berarti Anda memahami adanya risiko kehilangan data.

## Meminimalkan dan memecahkan masalah deadlock Aurora MySQL
<a name="AuroraMySQL.BestPractices.deadlocks"></a>

Pengguna yang menjalankan beban kerja yang secara rutin mengalami pelanggaran batasan pada indeks sekunder unik atau kunci asing, saat memodifikasi catatan pada halaman data yang sama secara konkuren, mungkin akan lebih sering mengalami deadlock dan kehabisan waktu tunggu kunci. Deadlock dan kehabisan waktu ini disebabkan oleh [perbaikan bug](https://bugs.mysql.com/bug.php?id=98324) MySQL Community Edition.

Perbaikan ini disertakan dalam MySQL Community Edition versi 5.7.26 dan lebih tinggi, serta di-backport ke Aurora MySQL versi 2.10.3 dan yang lebih tinggi. Perbaikan ini diperlukan untuk memberlakukan *kemampuan serialisasi*, dengan menerapkan penguncian tambahan untuk jenis operasi bahasa manipulasi data (DML) ini, pada perubahan yang dibuat terhadap catatan dalam tabel InnoDB. Masalah ini terungkap sebagai bagian dari penyelidikan masalah deadlock yang ditimbulkan oleh [perbaikan bug](https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-26.html) MySQL Community Edition sebelumnya.

Perbaikan ini mengubah penanganan internal untuk *rollback sebagian* pembaruan tuple (baris) di mesin penyimpanan InnoDB. Operasi yang menghasilkan pelanggaran batasan pada kunci asing atau indeks sekunder unik menyebabkan rollback sebagian. Ini termasuk, tetapi tidak terbatas pada, pernyataan `INSERT...ON DUPLICATE KEY UPDATE`, `REPLACE INTO,` dan `INSERT IGNORE` konkuren (*upsert*).

Dalam konteks ini, rollback sebagian tidak mengacu pada rollback transaksi tingkat aplikasi, melainkan rollback InnoDB internal terhadap perubahan ke indeks berklaster ketika pelanggaran batasan ditemui. Misalnya, nilai kunci duplikat ditemukan selama operasi upsert.

Dalam operasi penyisipan normal, InnoDB secara atomis membuat entri indeks [berklaster](https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html) dan sekunder untuk setiap indeks. Jika InnoDB mendeteksi nilai duplikat pada indeks sekunder unik selama operasi upsert, entri yang disisipkan dalam indeks berklaster harus dikembalikan (rollback sebagian), dan pembaruan kemudian harus diterapkan ke baris duplikat yang ada. Selama langkah rollback sebagian internal ini, InnoDB harus mengunci setiap catatan yang dilihat sebagai bagian dari operasi. Perbaikan ini memastikan kemampuan serialisasi transaksi dengan menerapkan penguncian tambahan setelah rollback sebagian.

### Meminimalkan deadlock InnoDB
<a name="AuroraMySQL.BestPractices.deadlocks-minimize"></a>

Anda dapat mengambil pendekatan berikut untuk mengurangi frekuensi deadlock dalam instans basis data Anda. Contoh lainnya dapat ditemukan dalam [dokumentasi MySQL](https://bugs.mysql.com/bug.php?id=98324).

1. Untuk mengurangi kemungkinan deadlock, lakukan transaksi segera setelah melakukan serangkaian perubahan terkait. Anda dapat melakukannya dengan memecah transaksi besar (beberapa pembaruan baris di antara commit) menjadi lebih kecil. Jika Anda memasukkan baris secara batch, cobalah untuk mengurangi ukuran penyisipan batch, terutama saat menggunakan operasi upsert yang disebutkan sebelumnya.

   Untuk mengurangi jumlah kemungkinan rollback sebagian, Anda dapat mencoba beberapa pendekatan berikut:

   1. Ganti operasi penyisipan batch dengan memasukkan satu baris pada satu waktu. Hal ini dapat mengurangi jumlah waktu saat kunci ditahan oleh transaksi yang mungkin memiliki konflik.

   1. Alih-alih menggunakan `REPLACE INTO`, tulis ulang pernyataan SQL sebagai transaksi multipernyataan seperti berikut ini:

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

   1. Alih-alih menggunakan `INSERT...ON DUPLICATE KEY UPDATE`, tulis ulang pernyataan SQL sebagai transaksi multipernyataan seperti berikut ini:

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

1. Hindari transaksi yang berjalan lama, aktif atau idle, yang mungkin menahan kunci. Hal ini termasuk sesi klien MySQL interaktif yang mungkin terbuka untuk waktu yang lama dengan transaksi yang tidak di-commit. Saat mengoptimalkan ukuran transaksi atau ukuran batch, dampaknya dapat bervariasi tergantung pada sejumlah faktor seperti konkurensi, jumlah duplikat, dan struktur tabel. Setiap perubahan harus diterapkan dan diuji berdasarkan beban kerja Anda.

1. Dalam beberapa situasi, deadlock dapat terjadi ketika dua transaksi mencoba mengakses set data yang sama, baik dalam satu maupun beberapa tabel, dalam urutan yang berbeda-beda. Untuk mencegah hal ini, Anda dapat memodifikasi transaksi untuk mengakses data dalam urutan yang sama, sehingga menserialisasi akses. Misalnya, buat antrean transaksi yang akan diselesaikan. Pendekatan ini dapat membantu menghindari deadlock ketika beberapa transaksi terjadi secara bersamaan.

1. Menambahkan indeks yang dipilih dengan cermat ke tabel Anda dapat meningkatkan selektivitas dan mengurangi kebutuhan untuk mengakses baris, sehingga mengurangi penguncian.

1. Jika Anda mengalami [penguncian celah](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-gap-locks), Anda dapat memodifikasi tingkat isolasi transaksi menjadi `READ COMMITTED` untuk sesi atau transaksi agar mencegahnya. Untuk informasi selengkapnya tentang tingkat isolasi InnoDB dan perilakunya, lihat [Transaction isolation levels](https://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-levels.html) dalam dokumentasi MySQL.

**catatan**  
Meskipun Anda dapat mengambil tindakan pencegahan untuk mengurangi kemungkinan deadlock terjadi, deadlock adalah perilaku basis data yang sudah diperkirakan dan tetap dapat terjadi. Aplikasi harus memiliki logika yang diperlukan untuk menangani deadlock ketika terjadi. Misalnya, terapkan logika percobaan ulang dan backing-off dalam aplikasi. Yang terbaik adalah mengatasi akar penyebab masalahnya, tetapi jika deadlock memang terjadi, aplikasi memiliki opsi untuk menunggu dan mencoba lagi.

### Memantau deadlock InnoDB
<a name="AuroraMySQL.BestPractices.deadlocks-monitor"></a>

[Deadlock](https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_deadlock) dapat terjadi di MySQL ketika transaksi aplikasi mencoba mengambil kunci tingkat tabel dan tingkat baris dengan cara yang menghasilkan peristiwa tunggu sirkular. Deadlock InnoDB yang sesekali tidak selalu menjadi masalah karena mesin penyimpanan InnoDB mendeteksi kondisi ini dengan segera dan melakukan rollback terhadap salah satu transaksi secara otomatis. Jika Anda sering mengalami deadlock, kami sarankan untuk meninjau dan memodifikasi aplikasi Anda untuk mengurangi masalah performa dan menghindari deadlock. Ketika [deteksi deadlock](https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_deadlock_detection) diaktifkan (default), InnoDB secara otomatis mendeteksi deadlock transaksi dan melakukan rollback transaksi untuk mengatasi deadlock. InnoDB mencoba memilih transaksi kecil untuk di-rollback. Ukuran transaksi akan ditentukan berdasarkan jumlah baris yang disisipkan, diperbarui, atau dihapus.
+ Pernyataan `SHOW ENGINE` – Pernyataan `SHOW ENGINE INNODB STATUS \G` berisi [detail](https://dev.mysql.com/doc/refman/5.7/en/show-engine.html) deadlock terbaru yang ditemui pada basis data sejak pengaktifan ulang terakhir.
+ Log kesalahan MySQL – Jika Anda sering mengalami deadlock dengan output pernyataan `SHOW ENGINE` yang tidak memadai, Anda dapat mengaktifkan parameter klaster DB [innodb\$1print\$1all\$1deadlocks](https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_print_all_deadlocks).

  Ketika parameter ini diaktifkan, informasi tentang semua deadlock dalam transaksi pengguna InnoDB dicatat dalam [log kesalahan](https://dev.mysql.com/doc/refman/8.0/en/error-log.html) Aurora MySQL.
+  CloudWatch Metrik Amazon — Kami juga menyarankan Anda memantau kebuntuan secara proaktif menggunakan metrik. CloudWatch `Deadlocks` Untuk informasi selengkapnya, lihat [Metrik tingkat instans untuk Amazon Aurora](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances).
+  CloudWatch Log Amazon — Dengan CloudWatch Log, Anda dapat melihat metrik, menganalisis data log, dan membuat alarm waktu nyata. Untuk informasi selengkapnya, lihat [Memantau kesalahan di Amazon Aurora MySQL dan Amazon RDS for MySQL menggunakan Amazon dan mengirim notifikasi menggunakan Amazon](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/) SNS. CloudWatch 

  Menggunakan CloudWatch Log dengan `innodb_print_all_deadlocks` dihidupkan, Anda dapat mengonfigurasi alarm untuk memberi tahu Anda ketika jumlah kebuntuan melebihi ambang batas yang diberikan. Untuk menentukan ambang batas, kami sarankan Anda mengamati tren Anda dan menggunakan nilai berdasarkan beban kerja normal Anda.
+ Wawasan Performa – Saat menggunakan Wawasan Performa, Anda dapat memantau metrik `innodb_deadlocks` dan `innodb_lock_wait_timeout`. Untuk informasi selengkapnya tentang metrik ini, lihat [Penghitung non-native untuk Aurora MySQL](USER_PerfInsights_Counters.md#USER_PerfInsights_Counters.Aurora_MySQL.NonNative).

# Mengevaluasi penggunaan instans DB untuk Aurora MySQL dengan metrik Amazon CloudWatch
<a name="AuroraMySQL.BestPractices.CW"></a>

Anda dapat menggunakan CloudWatch metrik untuk memantau throughput instans DB dan menentukan apakah kelas instans DB menyediakan sumber daya yang cukup untuk aplikasi Anda. Untuk informasi tentang batas kelas instans DB Anda, lihat[Spesifikasi perangkat keras untuk kelas instans DB untuk Aurora](Concepts.DBInstanceClass.Summary.md). Temukan spesifikasi untuk kelas instans DB Anda untuk menemukan kinerja jaringan.

Jika penggunaan instans DB Anda mendekati batas kelas instans, maka performa mungkin mulai melambat. CloudWatch Metrik dapat mengonfirmasi situasi ini sehingga Anda dapat merencanakan untuk meningkatkan skala secara manual ke kelas instance yang lebih besar. 

Gabungkan nilai CloudWatch metrik berikut untuk mengetahui apakah Anda mendekati batas kelas instance:
+ **NetworkThroughput**— Jumlah throughput jaringan yang diterima dan ditransmisikan oleh klien untuk setiap instance di cluster Aurora DB. Throughput ini tidak mencakup lalu lintas jaringan di antara instans dalam klaster DB dan volume klaster. 
+ **StorageNetworkThroughput**— Jumlah throughput jaringan yang diterima dan dikirim ke subsistem penyimpanan Aurora oleh setiap instance di cluster Aurora DB. 

Tambahkan ke **NetworkThroughput**StorageNetworkThroughput****untuk menemukan throughput jaringan yang diterima dari dan dikirim ke subsistem penyimpanan Aurora oleh setiap instance di cluster Aurora DB Anda. Batas kelas instans untuk instans Anda harus lebih besar dari jumlah kedua metrik gabungan ini. 

 Anda dapat menggunakan metrik berikut untuk meninjau detail tambahan lalu lintas jaringan dari aplikasi klien Anda saat mengirim dan menerima:
+ **NetworkReceiveThroughput**— Jumlah throughput jaringan yang diterima dari klien oleh setiap instans DB di cluster DB MySQL Aurora. Throughput ini tidak mencakup lalu lintas jaringan di antara instans dalam klaster DB dan volume klaster.
+ **NetworkTransmitThroughput**— Jumlah throughput jaringan yang dikirim ke klien oleh setiap instance di cluster Aurora DB. Throughput ini tidak mencakup lalu lintas jaringan di antara instans dalam klaster DB dan volume klaster.
+ **StorageNetworkReceiveThroughput**— Jumlah throughput jaringan yang diterima dari subsistem penyimpanan Aurora oleh setiap instance di cluster DB.
+ **StorageNetworkTransmitThroughput**— Jumlah throughput jaringan yang dikirim ke subsistem penyimpanan Aurora oleh setiap instance di cluster DB.

Tambahkan semua metrik ini bersama-sama untuk mengevaluasi bagaimana penggunaan jaringan Anda dibandingkan dengan batas kelas instans DB. Batas kelas instans harus lebih besar dari jumlah metrik gabungan ini.

Batas jaringan dan penggunaan CPU untuk penyimpanan terkait langsung. Ketika throughput jaringan meningkat, maka penggunaan CPU juga meningkat. Pemantauan penggunaan CPU dan jaringan memberikan informasi tentang bagaimana dan mengapa sumber daya habis.

Untuk membantu meminimalkan penggunaan jaringan, Anda dapat mempertimbangkan hal berikut:
+ Menggunakan kelas instans DB yang lebih besar.
+ Membagi permintaan tulis dalam batch untuk mengurangi keseluruhan transaksi.
+ Mengarahkan beban kerja hanya-baca ke instans hanya-baca.
+ Menghapus indeks yang tidak digunakan.