All Products
Search
Document Center

PolarDB:Optimasi baris panas

Last Updated:Mar 29, 2026

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 autocommit atau dapat disesuaikan untuk menggunakan petunjuk COMMIT_ON_SUCCESS

  • Database 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 UPDATE dalam 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.

image

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

ParameterDeskripsi
hotspotMengaktifkan 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.

HintWajibDeskripsi
COMMIT_ON_SUCCESSWajibMelakukan commit transaksi jika pembaruan berhasil
ROLLBACK_ON_FAILOpsionalMelakukan rollback transaksi jika pembaruan gagal
TARGET_AFFECT_ROW(1)OpsionalGagal 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.

ParameterDeskripsiDefault
hotspot_for_autocommitMenerapkan optimasi baris panas ke pernyataan UPDATE dalam mode autocommit. Nilai valid: ON / OFFOFF
hotspot_update_max_wait_timeWaktu maksimum Leader menunggu Followers bergabung ke grup. Satuan: mikrodetik (µs)100 µs
hotspot_lock_typeMengaktifkan 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 / OFFOFF

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

VersiPeningkatan 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

image.png
Keserentakan181632641282565121024
Optimasi dinonaktifkan1365,311863,941866,61862,641867,321832,511838,311819,521833,2
Optimasi diaktifkan1114,797000,1912717,3222029,4843096,0661349,783098,6990860,9487689

PolarDB for MySQL 5.7

QPS

QPS

image.png
Keserentakan181632641282565121024
Optimasi dinonaktifkan1348,491892,291889,771895,861875,21850,261843,621849,921835,68
Optimasi diaktifkan1104,96886,8912485,1716003,2316460,3116548,8627920,8947893,9666500,92

lat95th (latensi persentil ke-95)

Latensi persentil ke-95 (ms)

image
Konkurensi181632641282565121024
Optimasi dinonaktifkan0,95,479,9118,9536,8973,13164,45297,92590,56
Optimasi diaktifkan1,081,441,583,255,289,5612,0813,2218,28

PolarDB for MySQL 8.0

QPS

QPS

image
Konkurensi181632641282565121024
Optimasi dinonaktifkan1559,142103,822116,42082,12079,742031,641993,091977,61983,61
Optimasi diaktifkan1237,287443,0412244,1915529,5223041,1533931,1853924,2454598,650988,22

lat95th (latensi persentil ke-95)

Latensi persentil ke-95 (ms)

image
Keserentakan181632641282565121024
Optimasi dinonaktifkan0,858,917,3233,1266,84153,02287,38549,52
Optimasi diaktifkan0,971,341,893,194,825,887,1713,4628,16

Lampiran: Menjalankan pengujian performa

  1. Siapkan instance ECS dan instal Sysbench.

  2. Buat file bernama oltp_inventory.lua di folder src/lua kode 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()
    end
  3. Hubungkan ke kluster.

  4. Siapkan 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 prepare
  5. Jalankan 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

ParameterDeskripsi
mysql-hostTitik akhir kluster
mysql-portPort dari titik akhir kluster
mysql-userUsername untuk kluster
mysql-passwordPassword untuk pengguna kluster
mysql-dbNama database

Parameter output

ParameterKonten yang ditampilkanDeskripsi
tablesJumlah tabel dataTotal jumlah tabel yang digunakan dalam pengujian
table_sizeJumlah baris per tabelJumlah catatan dalam setiap tabel
Data sizeUkuran data tabel (MB atau GB)Ukuran data dalam tabel
threadsJumlah thread konkurenJumlah thread yang dikonfigurasi
Thread statusStatus thread real-timeStatus jalannya thread selama pengujian