Baris panas adalah baris database yang sering diperbarui oleh banyak transaksi konkuren. Setiap pembaruan mengunci baris tersebut hingga transaksi di-commit atau di-rollback, sehingga permintaan antri secara berurutan — sharding tabel dan peningkatan perangkat keras memberikan sedikit bantuan. Pada beban kerja dengan konkurensi tinggi seperti penjualan kilat dan pengurangan inventaris, persaingan kunci ini menyebabkan latensi melonjak dan throughput mencapai batas maksimum.
PolarDB mengatasi masalah ini di tingkat kernel dengan secara otomatis mengelompokkan pembaruan konkuren ke baris yang sama menjadi batch dan memproses batch tersebut melalui pipeline. Pendekatan ini menghilangkan waktu tunggu kunci berlebihan dan traversal Pohon-B, meningkatkan throughput hingga 50x dalam kondisi konkurensi tinggi.
Kapan menggunakan optimasi baris panas
Optimasi baris panas paling efektif ketika semua kondisi berikut terpenuhi:
Banyak transaksi konkuren berulang kali memperbarui baris yang sama — misalnya, pengurangan inventaris selama penjualan kilat
Beban kerja menggunakan mode
autocommitatau dapat disesuaikan untuk menggunakan petunjukCOMMIT_ON_SUCCESSDatabase berjalan pada CPU multi-core di mana paralelisme pipeline memberikan manfaat
Fitur ini tidak berlaku dalam skenario berikut:
Tabel yang berisi baris panas adalah partitioned table
Trigger didefinisikan pada tabel
Statement queue digunakan untuk baris panas
Binary logging global diaktifkan tetapi binary logging tingkat session dinonaktifkan — pernyataan
UPDATEdalam konfigurasi ini melewati optimasi baris panas
Cara kerja
PolarDB mengidentifikasi pernyataan UPDATE yang ditandai dengan autocommit atau petunjuk COMMIT_ON_SUCCESS. Dalam jendela waktu singkat, sistem mengumpulkan pembaruan yang cocok dan meng-hash-nya ke dalam bucket berdasarkan primary key atau unique key. Pembaruan yang memiliki hash ke bucket yang sama membentuk Group Update.
Pemrosesan pipeline — dari berurutan ke paralel
Dua unit eksekusi bergantian: saat Unit A melakukan commit grup, Unit B mengumpulkan batch pembaruan berikutnya. Hal ini menghilangkan waktu idle antar commit dan memanfaatkan sepenuhnya CPU multi-core.
Sebagai contoh: 200 pembaruan konkuren ke inventory WHERE id = 1 tiba dalam jendela 100 µs. Alih-alih 200 siklus lock-acquire → update → commit secara berurutan, PolarDB mengelompokkannya menjadi dua grup masing-masing 100 dan memprosesnya melalui pipeline. Latensi keseluruhan turun dari O(n) menjadi O(1) untuk batch tersebut.
Akuisisi kunci instan untuk Followers
Dalam setiap grup, operasi pembaruan pertama adalah Leader — ia membaca baris target dan mengambil kunci baris. Semua operasi berikutnya dalam grup tersebut adalah Followers. Saat Follower meminta kunci dan mendeteksi bahwa Leader telah memegangnya, kunci tersebut langsung diperoleh tanpa menunggu. Ini menghilangkan overhead waktu tunggu kunci dan pendeteksian deadlock untuk seluruh grup.
Lebih sedikit traversal Pohon-B melalui Row Cache
Hanya Leader yang melakukan traversal indeks Pohon-B untuk menemukan baris target. Baris tersebut kemudian disimpan dalam Row Cache di memori. Followers dalam grup yang sama mengambil baris langsung dari Row Cache, sehingga melewati traversal indeks sepenuhnya.
Prasyarat
Sebelum mengaktifkan optimasi baris panas, pastikan bahwa:
Kluster PolarDB Anda menjalankan salah satu versi berikut:
PolarDB for MySQL 5.6, versi mesin minor 20200601 atau lebih baru
PolarDB for MySQL 5.7, versi mesin minor 5.7.1.0.17 atau lebih baru
PolarDB for MySQL 8.0, versi mesin minor 8.0.1.1.10 atau lebih baru
Binary logging diaktifkan pada kluster
Parameter kluster rds_ic_reduce_hint_enable diatur ke OFF:
PolarDB for MySQL 5.6 dan 8.0: OFF secara default — tidak perlu tindakan tambahan
PolarDB for MySQL 5.7: ON secara default — ubah nilai parameter menjadi OFF sebelum melanjutkan
Semua parameter kluster di Konsol PolarDB menggunakan awalan loose_ untuk kompatibilitas konfigurasi MySQL. Untuk mengubah rds_ic_reduce_hint_enable, pilih loose_rds_ic_reduce_hint_enable di konsol.
Aktifkan optimasi baris panas
Langkah 1: Aktifkan parameter fitur
Di Konsol PolarDB, konfigurasikan parameter kluster hotspot (nama di konsol: loose_hotspot):
| Parameter | Deskripsi |
|---|---|
| hotspot | Mengaktifkan atau menonaktifkan optimasi baris panas. Nilai valid: ON (diaktifkan) / OFF (dinonaktifkan, default) |
Untuk mengubah hotspot di konsol, pilih parameter dengan awalan loose_: loose_hotspot.
Langkah 2: Tambahkan sintaks hint ke pernyataan UPDATE Anda
Tambahkan hint berikut ke pernyataan UPDATE yang menargetkan baris panas. Hint harus muncul di pernyataan SQL terakhir dalam transaksi, karena COMMIT_ON_SUCCESS secara otomatis melakukan commit jika berhasil.
| Hint | Wajib | Deskripsi |
|---|---|---|
| COMMIT_ON_SUCCESS | Wajib | Melakukan commit transaksi jika pembaruan berhasil |
| ROLLBACK_ON_FAIL | Opsional | Melakukan rollback transaksi jika pembaruan gagal |
| TARGET_AFFECT_ROW(1) | Opsional | Gagal jika pembaruan memengaruhi lebih dari satu baris |
Contoh — menambah nilai kolom counter pada baris tertentu:
UPDATE /*+ COMMIT_ON_SUCCESS ROLLBACK_ON_FAIL TARGET_AFFECT_ROW(1) */ sbtest SET c = c + 1 WHERE id = 1;Langkah 3: Verifikasi fitur aktif
Jalankan kueri berikut untuk memastikan optimasi baris panas sedang memproses Group Update:
SHOW GLOBAL STATUS LIKE 'Group_update%';Nilai hitungan bukan nol pada hasil menunjukkan bahwa fitur tersebut aktif.
Atur parameter
Lihat nilai parameter hot row saat ini:
SHOW VARIABLES LIKE "hotspot%";Contoh output:
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| hotspot | OFF |
| hotspot_for_autocommit | OFF |
| hotspot_lock_type | OFF |
| hotspot_update_max_wait_time | 100 |
+------------------------------+-------+Parameter berikut tidak dapat diubah di Konsol PolarDB. Untuk mengubahnya, buka Pusat Kuota, temukan kuota PolarDB hotspot row parameter adjustment, lalu klik Apply di kolom Actions.
| Parameter | Deskripsi | Default |
|---|---|---|
| hotspot_for_autocommit | Menerapkan optimasi baris panas ke pernyataan UPDATE dalam mode autocommit. Nilai valid: ON / OFF | OFF |
| hotspot_update_max_wait_time | Waktu maksimum Leader menunggu Followers bergabung ke grup. Satuan: mikrodetik (µs) | 100 µs |
| hotspot_lock_type | Mengaktifkan jenis kunci baris baru selama Group Update. Saat ON, Followers yang meminta kunci pada baris panas yang sama langsung memperolehnya tanpa menunggu. Nilai valid: ON / OFF | OFF |
Pengujian performa
Lingkungan pengujian
Tool: Sysbench — tool benchmark open-source multi-threaded yang mendukung skrip uji berbasis Lua
Skenario uji: Satu baris panas, CPU 8-core
Definisi tabel:
CREATE TABLE sbtest (id INT UNSIGNED NOT NULL, c BIGINT UNSIGNED NOT NULL, PRIMARY KEY (id));Pernyataan uji:
UPDATE /*+ COMMIT_ON_SUCCESS ROLLBACK_ON_FAIL TARGET_AFFECT_ROW(1) */ sbtest SET c = c + 1 WHERE id = 1;
Rangkuman hasil
| Versi | Peningkatan puncak (konkurensi tinggi) |
|---|---|
| PolarDB for MySQL 5.6 | ~50x peningkatan QPS |
| PolarDB for MySQL 5.7 | ~35x peningkatan QPS |
| PolarDB for MySQL 8.0 | ~26x peningkatan QPS |
PolarDB for MySQL 5.6
QPS

| Keserentakan | 1 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 |
|---|---|---|---|---|---|---|---|---|---|
| Optimasi dinonaktifkan | 1365,31 | 1863,94 | 1866,6 | 1862,64 | 1867,32 | 1832,51 | 1838,31 | 1819,52 | 1833,2 |
| Optimasi diaktifkan | 1114,79 | 7000,19 | 12717,32 | 22029,48 | 43096,06 | 61349,7 | 83098,69 | 90860,94 | 87689 |
PolarDB for MySQL 5.7
QPS
QPS

| Keserentakan | 1 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 |
|---|---|---|---|---|---|---|---|---|---|
| Optimasi dinonaktifkan | 1348,49 | 1892,29 | 1889,77 | 1895,86 | 1875,2 | 1850,26 | 1843,62 | 1849,92 | 1835,68 |
| Optimasi diaktifkan | 1104,9 | 6886,89 | 12485,17 | 16003,23 | 16460,31 | 16548,86 | 27920,89 | 47893,96 | 66500,92 |
lat95th (latensi persentil ke-95)
Latensi persentil ke-95 (ms)

| Konkurensi | 1 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 |
|---|---|---|---|---|---|---|---|---|---|
| Optimasi dinonaktifkan | 0,9 | 5,47 | 9,91 | 18,95 | 36,89 | 73,13 | 164,45 | 297,92 | 590,56 |
| Optimasi diaktifkan | 1,08 | 1,44 | 1,58 | 3,25 | 5,28 | 9,56 | 12,08 | 13,22 | 18,28 |
PolarDB for MySQL 8.0
QPS
QPS

| Konkurensi | 1 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 |
|---|---|---|---|---|---|---|---|---|---|
| Optimasi dinonaktifkan | 1559,14 | 2103,82 | 2116,4 | 2082,1 | 2079,74 | 2031,64 | 1993,09 | 1977,6 | 1983,61 |
| Optimasi diaktifkan | 1237,28 | 7443,04 | 12244,19 | 15529,52 | 23041,15 | 33931,18 | 53924,24 | 54598,6 | 50988,22 |
lat95th (latensi persentil ke-95)
Latensi persentil ke-95 (ms)

| Keserentakan | 1 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 |
|---|---|---|---|---|---|---|---|---|---|
| Optimasi dinonaktifkan | 0,8 | 5 | 8,9 | 17,32 | 33,12 | 66,84 | 153,02 | 287,38 | 549,52 |
| Optimasi diaktifkan | 0,97 | 1,34 | 1,89 | 3,19 | 4,82 | 5,88 | 7,17 | 13,46 | 28,16 |
Lampiran: Menjalankan pengujian performa
Siapkan instance ECS dan instal Sysbench.
Buat file bernama
oltp_inventory.luadi foldersrc/luakode sumber Sysbench:#!/usr/bin/env sysbench -- it is to test inventory_hotspot performance sysbench.cmdline.options= { inventory_hotspot = {"enable ali inventory hotspot", 'off'}, tables = {"table number", 1}, table_size = {"table size", 1}, oltp_skip_trx = {'skip trx', true}, hotspot_rows = {'hotspot row number', 1} } function cleanup() drv = sysbench.sql.driver() con = drv:connect() for i = 1, sysbench.opt.tables do print(string.format("drop table sbtest%d ...", i)) drop_table(drv, con, i) end end function drop_table(drv, con, table_id) local query query = string.format("drop table if exists sbtest%d ", table_id) con:query(query) end function create_table(drv, con, table_id) local query query = string.format("CREATE TABLE sbtest%d (id INT UNSIGNED NOT NULL, c BIGINT UNSIGNED NOT NULL, PRIMARY KEY (id))", table_id) con:query(query) for i=1, sysbench.opt.table_size do con:query("INSERT INTO sbtest" .. table_id .. "(id, c) values (" ..i.. ", 1)") end end function prepare() drv = sysbench.sql.driver() con = drv:connect() for i = 1, sysbench.opt.tables do print(string.format("Creating table sbtest%d ...", i)) create_table(drv, con, i) end end function thread_init() drv = sysbench.sql.driver() con = drv:connect() begin_query = 'BEGIN' commit_query = 'COMMIT' end function event() local table_name table_name = "sbtest" .. sysbench.rand.uniform(1, sysbench.opt.tables) local min_line = math.min(sysbench.opt.table_size, sysbench.opt.hotspot_rows) local row_id = sysbench.rand.uniform(1, min_line) if not sysbench.opt.oltp_skip_trx then con:query(begin_query) end if (sysbench.opt.inventory_hotspot == "on") then con:query("UPDATE COMMIT_ON_SUCCESS ROLLBACK_ON_FAIL TARGET_AFFECT_ROW 1 " .. table_name .. " SET c=c+1 WHERE id =" .. row_id) else con:query("UPDATE " .. table_name .. " SET c=c+1 WHERE id = " .. row_id) end if not sysbench.opt.oltp_skip_trx then if (sysbench.opt.inventory_hotspot == "on") then con:query(commit_query) end end end function thread_done() con:disconnect() endSiapkan data uji:
sysbench --hotspot_rows=1 --histogram=on --mysql-user=<user> --inventory_hotspot=on --mysql-host=<host> --threads=1 --report-interval=1 --mysql-password=<password> --tables=1 --table-size=1 --oltp_skip_trx=true --db-driver=mysql --percentile=95 --time=300 --mysql-port=<port> --events=0 --mysql-db=<database> oltp_inventory prepareJalankan pengujian:
sysbench --db-driver=mysql --mysql-host=<host> --mysql-port=<port> --mysql-user=<user> --mysql-password=<password> --mysql-db=<database> --range-selects=0 --table_size=25000 --tables=250 --events=0 --time=600 --rand-type=uniform --threads=<threads> oltp_read_only run
Parameter input
| Parameter | Deskripsi |
|---|---|
mysql-host | Titik akhir kluster |
mysql-port | Port dari titik akhir kluster |
mysql-user | Username untuk kluster |
mysql-password | Password untuk pengguna kluster |
mysql-db | Nama database |
Parameter output
| Parameter | Konten yang ditampilkan | Deskripsi |
|---|---|---|
tables | Jumlah tabel data | Total jumlah tabel yang digunakan dalam pengujian |
table_size | Jumlah baris per tabel | Jumlah catatan dalam setiap tabel |
Data size | Ukuran data tabel (MB atau GB) | Ukuran data dalam tabel |
threads | Jumlah thread konkuren | Jumlah thread yang dikonfigurasi |
Thread status | Status thread real-time | Status jalannya thread selama pengujian |