Statistik kunci

Spanner menyediakan statistik kunci yang memungkinkan Anda mengidentifikasi baris key dan kolom tabel yang merupakan sumber utama konflik kunci transaksi di database Anda selama jangka waktu tertentu. Anda dapat mengambil statistik ini dari tabel sistem SPANNER_SYS.LOCK_STATS* menggunakan pernyataan SQL.

Ketersediaan

Data SPANNER_SYS hanya tersedia melalui antarmuka SQL; misalnya:

Metode pembacaan tunggal lainnya yang disediakan Spanner tidak mendukung SPANNER_SYS.

Kunci statistik berdasarkan tombol baris

Tabel berikut melacak kunci baris dengan waktu tunggu tertinggi:

  • SPANNER_SYS.LOCK_STATS_TOP_MINUTE: Tombol baris dengan waktu tunggu kunci tertinggi selama interval 1 menit.

  • SPANNER_SYS.LOCK_STATS_TOP_10MINUTE: Tombol baris dengan waktu tunggu kunci tertinggi selama interval 10 menit.

  • SPANNER_SYS.LOCK_STATS_TOP_HOUR: Tombol baris dengan waktu tunggu kunci tertinggi selama interval 1 jam

Tabel ini memiliki properti berikut:

  • Setiap tabel berisi data untuk interval waktu yang tidak tumpang-tindih dari panjang yang ditentukan oleh nama tabel.

  • Interval didasarkan pada waktu jam. Interval 1 menit berakhir pada menit, interval 10 menit berakhir setiap 10 menit dimulai pada jam, dan interval 1 jam berakhir pada jam. Setelah setiap interval, Spanner akan mengumpulkan data dari semua server, lalu membuat data tersebut tersedia di tabel SPANNER_SYS tidak lama setelahnya.

    Misalnya, pada pukul 11.59.30, interval terbaru yang tersedia untuk kueri SQL adalah:

    • 1 menit: 11.58.00–11.58.59
    • 10 menit: 11.40–11.49.59
    • 1 jam: 10.00–10.59.59
  • Spanner mengelompokkan statistik dengan memulai rentang kunci baris.

  • Setiap baris berisi statistik untuk total waktu tunggu penguncian untuk rentang kunci baris awal tertentu yang statistiknya ditangkap Spanner selama interval yang ditentukan.

  • Jika Spanner tidak dapat menyimpan informasi tentang setiap rentang kunci baris untuk waktu tunggu kunci selama interval, sistem akan memprioritaskan rentang kunci baris dengan waktu tunggu kunci tertinggi selama interval yang ditentukan.

Skema tabel

Nama kolom Jenis Deskripsi
INTERVAL_END TIMESTAMP Akhir interval waktu saat terjadi konflik kunci yang disertakan.
ROW_RANGE_START_KEY BYTES(MAX) Tombol baris tempat terjadinya konflik kunci. Jika konflik melibatkan rentang baris, nilai ini merepresentasikan kunci awal dari rentang tersebut. Tanda plus, +, menandakan rentang. Untuk informasi selengkapnya, lihat Apa yang dimaksud dengan kunci awal rentang baris.
LOCK_WAIT_SECONDS FLOAT64 Waktu tunggu penguncian kumulatif konflik penguncian yang dicatat untuk semua kolom dalam rentang tombol baris, dalam detik.
SAMPLE_LOCK_REQUESTS ARRAY<STRUCT<
  column STRING,
  lock_mode STRING,
   transaction_tag STRING>>
Setiap entri dalam array ini sesuai dengan contoh permintaan kunci yang berkontribusi pada konflik kunci dengan menunggu kunci atau memblokir transaksi lain agar tidak mengambil kunci, pada kunci baris tertentu (rentang). Jumlah maksimum sampel dalam array ini adalah 20.
Setiap sampel berisi tiga kolom berikut:
  • lock_mode: Mode kunci yang diminta. Untuk mengetahui informasi selengkapnya, lihat Mode kunci .
  • column: Kolom yang mengalami konflik kunci. Format nilai ini adalah tablename.columnname.
  • transaction_tag: Tag transaksi yang mengajukan permintaan. Untuk mengetahui informasi selengkapnya tentang penggunaan tag, lihat Memecahkan masalah dengan tag transaksi.
Semua permintaan kunci yang berkontribusi pada konflik kunci diambil sampelnya secara seragam dan acak, sehingga mungkin hanya setengah konflik (baik pemegang atau pelayan) yang tercatat dalam array ini.

Mode kunci

Operasi Spanner memperoleh kunci saat operasi tersebut menjadi bagian dari transaksi baca-tulis. Transaksi hanya baca tidak mendapatkan kunci. Spanner menggunakan mode kunci yang berbeda untuk memaksimalkan jumlah transaksi yang memiliki akses ke sel data tertentu pada waktu tertentu. Kunci yang berbeda memiliki karakteristik yang berbeda. Misalnya, beberapa kunci dapat digunakan bersama di antara beberapa transaksi, sedangkan kunci lainnya tidak dapat digunakan.

Konflik kunci dapat terjadi saat Anda mencoba mendapatkan salah satu mode kunci berikut dalam transaksi.

  • ReaderShared Kunci - Kunci yang memungkinkan pembacaan lain tetap mengakses data hingga transaksi Anda siap di-commit. Kunci bersama ini diperoleh saat transaksi baca-tulis membaca data.

  • Kunci WriterShared - Kunci ini diperoleh saat transaksi baca-tulis mencoba meng-commit penulisan.

  • Exclusive Kunci - kunci eksklusif diperoleh saat transaksi baca-tulis, yang telah memperoleh kunci ReaderShared, mencoba menulis data setelah penyelesaian pembacaan. Kunci eksklusif adalah upgrade dari kunci ReaderShared. Kunci eksklusif adalah kasus khusus dari suatu transaksi yang menyimpan kunci ReaderShared dan kunci WriterShared secara bersamaan. Tidak ada transaksi lain yang dapat memperoleh kunci apa pun di sel yang sama.

  • Kunci WriterSharedTimestamp - jenis khusus kunci WriterShared yang diperoleh saat menyisipkan baris baru ke dalam tabel yang memiliki stempel waktu commit sebagai bagian dari kunci utama. Jenis kunci ini mencegah peserta transaksi membuat baris yang sama persis, dan oleh karena itu, saling bertentangan. Spanner memperbarui kunci baris yang disisipkan agar cocok dengan stempel waktu commit transaksi yang melakukan penyisipan.

Untuk informasi selengkapnya tentang jenis transaksi dan jenis kunci yang tersedia, lihat Transaksi.

Mode kunci bentrok

Tabel berikut menunjukkan kemungkinan konflik antara mode kunci yang berbeda.

Mode Kunci ReaderShared WriterShared Exclusive WriterSharedTimestamp
ReaderShared Tidak Ya Ya Ya
WriterShared Ya Tidak Ya Tidak berlaku
Exclusive Ya Ya Ya Tidak berlaku
WriterSharedTimestamp Ya Tidak berlaku Tidak berlaku Ya

Kunci WriterSharedTimestamp hanya digunakan saat menyisipkan baris baru dengan stempel waktu sebagai bagian dari kunci utamanya. Kunci WriterShared dan Exclusive digunakan saat menulis ke sel yang ada atau menyisipkan baris baru tanpa stempel waktu. Akibatnya, WriterSharedTimestamp tidak dapat bertentangan dengan jenis kunci lainnya, dan skenario tersebut ditampilkan sebagai Tidak berlaku dalam tabel sebelumnya.

Satu-satunya pengecualian adalah ReaderShared, yang dapat diterapkan ke baris yang tidak ada dan, oleh karena itu, berpotensi bertentangan dengan WriterSharedTimestamp. Misalnya, pemindaian tabel penuh mengunci seluruh tabel bahkan untuk baris yang belum dibuat, sehingga ada kemungkinan ReaderShared bertentangan dengan WriterSharedTimestamp.

Apa yang dimaksud dengan tombol awal rentang baris?

Kolom ROW_RANGE_START_KEY mengidentifikasi kunci utama gabungan, atau kunci utama awal rentang baris, yang memiliki konflik kunci. Skema berikut digunakan untuk mengilustrasikan sebuah contoh.

CREATE TABLE Singers (
  SingerId   INT64 NOT NULL,
  FirstName  STRING(1024),
  LastName   STRING(1024),
  SingerInfo BYTES(MAX),
) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
  SingerId     INT64 NOT NULL,
  AlbumId      INT64 NOT NULL,
  AlbumTitle   STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId),
  INTERLEAVE IN PARENT Singers ON DELETE CASCADE;

CREATE TABLE Songs (
  SingerId     INT64 NOT NULL,
  AlbumId      INT64 NOT NULL,
  TrackId      INT64 NOT NULL,
  SongName     STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId, TrackId),
  INTERLEAVE IN PARENT Albums ON DELETE CASCADE;

CREATE TABLE Users (
  UserId     INT64 NOT NULL,
  LastAccess TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true),
  ...
) PRIMARY KEY (UserId, LastAccess);

Seperti yang ditampilkan dalam tabel berikut, {i>row key<i} dan {i>row key range<i}, rentang diwakili dengan tanda tambah, '+', pada kunci. Kunci dalam kasus tersebut mewakili kunci awal rentang kunci tempat terjadinya konflik kunci.

ROW_RANGE_START_KEY Penjelasan
penyanyi(2) Tabel penyanyi pada kunci SingerId=2
album(2;1) Tabel album di kunci SingerId=2,AlbumId=1
lagu(2;1;5) Tabel lagu di kunci SingerId=2,AlbumId=1,TrackId=5
lagu(2,1,5+) Rentang kunci tabel lagu dimulai pada SingerId=2,AlbumId=1,TrackId=5
album(2,1+) Rentang kunci tabel album dimulai pada SingerId=2,AlbumId=1
users(3, 2020-11-01, 12:34:56,426426+00:00) Tabel pengguna di kunci UserId=3, LastAccess=commit_timestamp

Statistik agregat

SPANNER_SYS juga berisi tabel untuk menyimpan data gabungan bagi statistik kunci yang diambil oleh Spanner dalam jangka waktu tertentu:

  • SPANNER_SYS.LOCK_STATS_TOTAL_MINUTE: Statistik gabungan untuk semua kunci menunggu selama interval 1 menit.

  • SPANNER_SYS.LOCK_STATS_TOTAL_10MINUTE: Statistik gabungan untuk semua kunci menunggu selama interval 10 menit.

  • SPANNER_SYS.LOCK_STATS_TOTAL_HOUR: Statistik gabungan untuk semua waktu tunggu kunci selama interval 1 jam.

Tabel statistik gabungan memiliki properti berikut:

  • Setiap tabel berisi data untuk interval waktu yang tidak tumpang-tindih dari panjang yang ditentukan oleh nama tabel.

  • Interval didasarkan pada waktu jam. Interval 1 menit berakhir pada menit, interval 10 menit berakhir setiap 10 menit dimulai pada jam, dan interval 1 jam berakhir pada jam.

    Misalnya, pada pukul 11.59.30, interval terbaru yang tersedia untuk kueri SQL pada statistik kunci agregat adalah:

    • 1 menit: 11.58.00–11.58.59
    • 10 menit: 11.40–11.49.59
    • 1 jam: 10.00–10.59.59
  • Setiap baris berisi statistik untuk semua waktu tunggu di database selama interval yang ditentukan, yang digabungkan bersama. Hanya ada satu baris per interval waktu.

  • Statistik yang diambil dalam tabel SPANNER_SYS.LOCK_STATS_TOTAL_* menyertakan waktu tunggu kunci yang tidak dicatat Spanner dalam tabel SPANNER_SYS.LOCK_STATS_TOP_*.

  • Beberapa kolom dalam tabel ini ditampilkan sebagai metrik di Cloud Monitoring. Metrik yang diekspos adalah:

    • Waktu tunggu kunci

    Untuk informasi selengkapnya, lihat Metrik Spanner.

Skema tabel

Nama kolom Jenis Deskripsi
INTERVAL_END TIMESTAMP Akhir interval waktu saat konflik kunci terjadi.
TOTAL_LOCK_WAIT_SECONDS FLOAT64 Total waktu tunggu kunci untuk konflik kunci yang direkam untuk seluruh database, dalam detik.

Contoh kueri

Berikut adalah contoh pernyataan SQL yang dapat Anda gunakan untuk mengambil statistik kunci. Anda dapat menjalankan pernyataan SQL ini menggunakan library klien, gcloud spanner, atau Konsol Google Cloud.

Tampilkan daftar statistik kunci untuk interval 1 menit sebelumnya

Kueri berikut menampilkan informasi waktu tunggu kunci untuk setiap kunci baris yang mengalami konflik kunci, termasuk fraksi total konflik kunci, selama interval waktu 1 menit terakhir.

Fungsi CAST() mengonversi kolom row_range_start_key myactivity menjadi STRING.

SELECT CAST(s.row_range_start_key AS STRING) AS row_range_start_key,
       t.total_lock_wait_seconds,
       s.lock_wait_seconds,
       s.lock_wait_seconds/t.total_lock_wait_seconds frac_of_total,
       s.sample_lock_requests
FROM spanner_sys.lock_stats_total_minute t, spanner_sys.lock_stats_top_minute s
WHERE t.interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.lock_stats_total_minute)
AND s.interval_end = t.interval_end
ORDER BY s.lock_wait_seconds DESC;
Output kueri
row_range_start_key total_lock_wait_seconds lock_wait_seconds frac_of_total sample_lock_requests
Lagu(2;1;1) 2,37 1,76 0,7426 LOCK_MODE: ReaderShared

KOLOM: Singers.SingerInfo

LOCK_MODE: WriterShared

KOLOM: Singers.SingerInfo
Pengguna(3, 01-11-2020 12:34:56,426426+00:00) 2,37 0,61 0,2573 LOCK_MODE: ReaderShared

KOLOM: users._exists1

LOCK_MODE: WriterShared

KOLOM: users._exists1

1 _exists adalah kolom internal yang digunakan untuk memeriksa apakah ada baris tertentu atau tidak.

Retensi data

Setidaknya, Spanner menyimpan data untuk setiap tabel selama jangka waktu berikut:

  • SPANNER_SYS.LOCK_STATS_TOP_MINUTE dan SPANNER_SYS.LOCK_STATS_TOTAL_MINUTE: Interval yang mencakup 6 jam sebelumnya.

  • SPANNER_SYS.LOCK_STATS_TOP_10MINUTE dan SPANNER_SYS.LOCK_STATS_TOTAL_10MINUTE: Interval yang mencakup 4 hari sebelumnya.

  • SPANNER_SYS.LOCK_STATS_TOP_HOUR dan SPANNER_SYS.LOCK_STATS_TOTAL_HOUR: Interval yang mencakup 30 hari sebelumnya.

Memecahkan masalah konflik kunci di database Anda menggunakan statistik kunci

Anda dapat menggunakan SQL atau dasbor Kunci insight untuk melihat konflik kunci di database Anda.

Topik berikut menunjukkan cara menyelidiki konflik kunci tersebut menggunakan kode SQL.

Pilih jangka waktu untuk diselidiki

Anda memeriksa Metrik latensi untuk database Spanner dan menemukan jangka waktu saat aplikasi Anda mengalami latensi dan penggunaan CPU yang tinggi. Misalnya, masalah ini mulai terjadi sekitar pukul 22.50 pada 12 November 2020.

Menentukan apakah latensi commit transaksi meningkat bersama dengan waktu tunggu penguncian selama periode yang dipilih

Kunci diperoleh oleh transaksi. Jadi, jika konflik kunci menyebabkan waktu tunggu yang lama, kita akan dapat melihat peningkatan latensi commit transaksi beserta peningkatan waktu tunggu penguncian.

Setelah memilih jangka waktu untuk memulai penyelidikan, kami akan menggabungkan statistik transaksi TXN_STATS_TOTAL_10MINUTE dengan statistik kunci LOCK_STATS_TOTAL_10MINUTE pada sekitar waktu tersebut untuk membantu kami memahami apakah peningkatan latensi commit rata-rata disebabkan oleh peningkatan waktu tunggu penguncian.

SELECT t.interval_end, t.avg_commit_latency_seconds, l.total_lock_wait_seconds
FROM spanner_sys.txn_stats_total_10minute t
LEFT JOIN spanner_sys.lock_stats_total_10minute l
ON t.interval_end = l.interval_end
WHERE
  t.interval_end >= "2020-11-12T21:50:00Z"
  AND t.interval_end <= "2020-11-12T23:50:00Z"
ORDER BY interval_end;

Mari kita ambil data berikut sebagai contoh hasil yang kita dapat dari kueri.

interval_end avg_commit_latency_seconds total_lock_wait_seconds
12-11-2020 21.40.00-07.00 0,002 0,090
12-11-2020 21.50:00-07.00 0,003 0,110
12-11-2020 22:00:00-07:00 0,002 0,100
12-11-2020 22.10.00-07.00 0,002 0,080
12-11-2020 22.20.00-07.00 0,030 0,240
12-11-2020 22.30.00-07.00 0,034 0,220
12-11-2020 22.40:00-07.00 0,034 0,218
12-11-2020 22.50.00-07.00 3,741 780,193
12-11-2020 23:00:00-07:00 0,042 0,240
12-11-2020 23.10.00-07.00 0,038 0,129
12-11-2020 23.20.00-07.00 0,021 0,128
12-11-2020 23.30.00-07.00 0,038 0,231

Hasil sebelumnya menunjukkan peningkatan dramatis dalam avg_commit_latency_seconds dan total_lock_wait_seconds selama jangka waktu yang sama dari 2020-11-12 22:40:00 menjadi 2020-11-12 22:50:00, dan menurun setelahnya. Satu hal yang perlu diperhatikan adalah bahwa avg_commit_latency_seconds adalah waktu rata-rata yang dihabiskan hanya untuk langkah commit. Di sisi lain, total_lock_wait_seconds adalah waktu penguncian agregat untuk periode tersebut, sehingga waktu terlihat jauh lebih lama daripada waktu commit transaksi.

Setelah mengonfirmasi bahwa waktu tunggu kunci terkait erat dengan peningkatan latensi tulis, kita akan menyelidiki pada langkah berikutnya baris dan kolom mana yang menyebabkan waktu tunggu yang lama.

Menemukan kunci baris dan kolom yang memiliki waktu tunggu penguncian yang lama selama periode yang dipilih

Untuk mengetahui kunci baris dan kolom mana yang mengalami waktu tunggu penguncian yang tinggi selama periode yang kami selidiki, kami membuat kueri tabel LOCK_STAT_TOP_10MINUTE, yang mencantumkan kunci baris dan kolom yang paling banyak berkontribusi untuk waktu tunggu kunci.

Fungsi CAST() dalam kueri berikut mengonversi kolom row_range_start_key myactivity menjadi STRING.

SELECT CAST(s.row_range_start_key AS STRING) AS row_range_start_key,
       t.total_lock_wait_seconds,
       s.lock_wait_seconds,
       s.lock_wait_seconds/t.total_lock_wait_seconds frac_of_total,
       s.sample_lock_requests
FROM spanner_sys.lock_stats_total_10minute t, spanner_sys.lock_stats_top_10minute s
WHERE
  t.interval_end = "2020-11-12T22:50:00Z" and s.interval_end = t.interval_end;
row_range_start_key total_lock_wait_seconds lock_wait_seconds frac_of_total sample_lock_requests
Penyanyi(32) 780,193 780,193 1 LOCK_MODE: WriterShared

KOLOM: Singers.SingerInfo

LOCK_MODE: ReaderShared

KOLOM: Singers.SingerInfo

Dari tabel hasil ini, kita dapat melihat konflik yang terjadi di tabel Singers pada kunci SingerId=32. Singers.SingerInfo adalah kolom tempat konflik kunci terjadi antara ReaderShared dan WriterShared.

Ini adalah jenis konflik umum ketika ada satu transaksi yang mencoba membaca sel tertentu dan transaksi lainnya mencoba menulis ke sel yang sama. Sekarang kita mengetahui sel data yang tepat untuk transaksi yang bersaing dalam kunci, sehingga pada langkah berikutnya kita akan mengidentifikasi transaksi yang bersaing untuk kunci.

Menemukan transaksi mana yang mengakses kolom yang terlibat dalam konflik kunci

Untuk mengidentifikasi transaksi yang mengalami latensi commit yang signifikan dalam interval waktu tertentu karena konflik kunci, Anda perlu membuat kueri untuk kolom berikut dari tabel SPANNER_SYS.TXN_STATS_TOTAL_10MINUTE:

  • fprint
  • read_columns
  • write_constructive_columns
  • avg_commit_latency_seconds

Anda harus memfilter kolom terkunci yang diidentifikasi dari tabel SPANNER_SYS.LOCK_STATS_TOP_10MINUTE:

  • Transaksi yang membaca kolom mana pun yang menyebabkan konflik kunci saat mencoba mendapatkan kunci ReaderShared.

  • Transaksi yang menulis ke kolom mana pun yang menyebabkan konflik kunci saat mencoba mendapatkan kunci WriterShared.

SELECT
  fprint,
  read_columns,
  write_constructive_columns,
  avg_commit_latency_seconds
FROM spanner_sys.txn_stats_top_10minute t2
WHERE (
  EXISTS (
    SELECT * FROM t2.read_columns columns WHERE columns IN (
      SELECT DISTINCT(req.COLUMN)
      FROM spanner_sys.lock_stats_top_10minute t, t.SAMPLE_LOCK_REQUESTS req
      WHERE req.LOCK_MODE = "ReaderShared" AND t.interval_end ="2020-11-12T23:50:00Z"))
OR
  EXISTS (
    SELECT * FROM t2.write_constructive_columns columns WHERE columns IN (
      SELECT DISTINCT(req.COLUMN)
      FROM spanner_sys.lock_stats_top_10minute t, t.SAMPLE_LOCK_REQUESTS req
      WHERE req.LOCK_MODE = "WriterShared" AND t.interval_end ="2020-11-12T23:50:00Z"))
)
AND t2.interval_end ="2020-11-12T23:50:00Z"
ORDER BY avg_commit_latency_seconds DESC;

Hasil kueri diurutkan menurut kolom avg_commit_latency_seconds sehingga Anda akan melihat transaksi yang mengalami latensi commit tertinggi terlebih dahulu.

fprint read_columns write_constructive_columns avg_commit_latency_seconds
1866043996151916800


['Singers.SingerInfo',
'Singers.FirstName',
'Singers.LastName',
'Singers._exists']
['Singers.SingerInfo'] 4,89
4168578515815911936 [] ['Singers.SingerInfo'] 3,65

Hasil kueri menunjukkan bahwa dua transaksi mencoba mengakses kolom Singers.SingerInfo, yaitu kolom yang mengalami konflik kunci selama jangka waktu tertentu. Setelah mengidentifikasi transaksi yang menyebabkan konflik kunci, Anda dapat menganalisis transaksi menggunakan sidik jarinya, fprint, untuk mengidentifikasi potensi masalah yang berkontribusi pada konflik kunci tersebut.

Setelah meninjau transaksi dengan fprint=1866043996151916800, Anda dapat menggunakan kolom read_columns dan write_constructive_columns untuk mengidentifikasi bagian mana dari kode aplikasi Anda yang memicu transaksi. Anda kemudian dapat melihat DML dasar yang tidak difilter pada kunci utama, SingerId. Hal ini menyebabkan pemindaian tabel penuh dan mengunci tabel hingga transaksi di-commit.

Untuk mengatasi konflik kunci, Anda dapat melakukan hal berikut:

  1. Gunakan transaksi hanya baca untuk mengidentifikasi nilai SingerId yang diperlukan.
  2. Gunakan transaksi baca-tulis terpisah guna memperbarui baris untuk nilai SingerId yang diperlukan.

Menerapkan praktik terbaik untuk mengurangi pertentangan kunci

Dalam contoh skenario, kita dapat menggunakan statistik kunci dan statistik transaksi untuk mempersempit masalah pada transaksi yang tidak menggunakan kunci utama tabel saat melakukan pembaruan. Kami memiliki ide untuk meningkatkan transaksi berdasarkan apakah kami mengetahui kunci baris yang ingin kami perbarui sebelumnya atau tidak.

Saat melihat potensi masalah dalam solusi Anda, atau bahkan saat mendesain solusi, pertimbangkan praktik terbaik ini untuk mengurangi jumlah konflik kunci dalam database Anda.

  • Menghindari pembacaan dalam jumlah besar di dalam transaksi baca-tulis.

  • Jika memungkinkan, gunakan transaksi hanya-baca karena transaksi tersebut tidak mendapatkan kunci apa pun.

  • Hindari pemindaian tabel penuh dalam transaksi baca-tulis. Hal ini termasuk menulis kondisional DML pada kunci utama atau menetapkan rentang kunci tertentu saat menggunakan Read API.

  • Pertahankan periode penguncian dengan melakukan perubahan segera setelah Anda membaca data dalam transaksi baca-tulis. Transaksi Baca-tulis menjamin bahwa data tetap tidak berubah setelah Anda membaca data hingga Anda berhasil meng-commit perubahan. Untuk mencapai hal ini, transaksi memerlukan penguncian sel data selama pembacaan dan selama commit. Akibatnya, jika Anda dapat mempertahankan periode penguncian agar tetap singkat, transaksi mungkin tidak akan mengalami konflik kunci.

  • Lebih mengutamakan transaksi kecil daripada transaksi besar, atau pertimbangkan DML Terpartisi untuk transaksi DML yang berjalan lama. Transaksi yang berjalan lama akan mendapatkan kunci untuk waktu yang lama, jadi pertimbangkan untuk memecah transaksi yang menyentuh ribuan baris menjadi beberapa transaksi yang lebih kecil yang memperbarui ratusan baris jika memungkinkan.

  • Jika Anda tidak memerlukan jaminan yang diberikan oleh transaksi baca-tulis, hindari membaca data apa pun dalam transaksi baca-tulis sebelum melakukan perubahan, misalnya, dengan membaca data dalam transaksi hanya baca yang terpisah. Sebagian besar konflik kunci terjadi karena jaminan yang kuat, untuk memastikan data tetap tidak berubah antara operasi baca dan commit. Jadi, jika transaksi baca-tulis tidak membaca data apa pun, transaksi tersebut tidak perlu mengunci sel untuk waktu yang lama.

  • Hanya menentukan kumpulan kolom minimal yang diperlukan dalam transaksi baca-tulis. Karena kunci Spanner dihitung per sel data, saat transaksi baca-tulis membaca kolom yang berlebihan, kunci ReaderShared di sel ini akan diperoleh. Hal ini dapat menyebabkan konflik kunci saat transaksi lain mendapatkan kunci WriterShared saat operasi tulis di kolom yang berlebihan. Misalnya, pertimbangkan untuk menentukan kumpulan kolom, bukan * saat dibaca.

  • Minimalkan panggilan API dalam transaksi baca-tulis. Latensi panggilan API dapat menyebabkan pertentangan kunci di Spanner, karena panggilan API dapat mengalami penundaan jaringan serta penundaan sisi layanan. Sebaiknya lakukan panggilan API di luar transaksi baca-tulis jika memungkinkan. Jika Anda harus menjalankan panggilan API di dalam transaksi baca-tulis, pastikan untuk memantau latensi panggilan API guna meminimalkan dampak pada periode penguncian akuisisi.

  • Ikuti praktik terbaik desain skema.

Langkah selanjutnya