Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

APPEND_ONLY_STORAGE_INSERT_POINT Kait

Melanjutkan rangkaian artikel saya tentang kait, kali ini saya akan membahas kait APPEND_ONLY_STORAGE_INSERT_POINT dan menunjukkan bagaimana hal itu dapat menjadi hambatan utama untuk beban kerja pembaruan yang berat di mana salah satu bentuk isolasi snapshot digunakan.

Saya sangat menyarankan Anda membaca posting awal dalam seri sebelum yang satu ini, sehingga Anda memiliki semua latar belakang pengetahuan umum tentang kait.

Apa itu APPEND_ONLY_STORAGE_INSERT_POINT Latch?

Untuk menjelaskan kait ini, saya perlu menjelaskan sedikit tentang cara kerja isolasi snapshot.

Saat Anda mengaktifkan salah satu dari dua bentuk pembuatan versi, SQL Server menggunakan mekanisme yang disebut pembuatan versi untuk mempertahankan versi pre pra-perubahan catatan di version store di tempdb. Ini dilakukan sebagai berikut:

  • Sebuah catatan diidentifikasi akan segera diubah.
  • Rekaman saat ini disalin ke penyimpanan versi.
  • Rekor diubah.
  • Jika rekaman belum memiliki tag versioning 14 byte , satu ditambahkan ke akhir rekaman. Tag berisi stempel waktu (bukan waktu nyata) dan penunjuk ke versi rekaman sebelumnya di penyimpanan versi.
  • Jika rekaman sudah memiliki tag pembuatan versi, rekaman tersebut diperbarui dengan stempel waktu dan penunjuk penyimpanan versi yang baru.

Stempel waktu pembuatan versi di seluruh instans bertambah setiap kali pernyataan atau kumpulan baru dimulai, atau versi baru catatan dibuat, di database mana pun di mana salah satu bentuk isolasi snapshot diaktifkan. Stempel waktu ini digunakan untuk memastikan kueri memproses versi rekaman yang benar.

Misalnya, bayangkan database yang telah membaca snapshot berkomitmen diaktifkan, sehingga setiap pernyataan dijamin untuk melihat catatan pada saat pernyataan dimulai. Stempel waktu pembuatan versi ditetapkan saat pernyataan dimulai, jadi catatan apa pun yang ditemuinya yang memiliki stempel waktu lebih tinggi adalah versi "salah", dan versi "benar", dengan stempel waktu sebelum stempel waktu pernyataan, harus diambil dari toko versi. Mekanisme proses ini tidak relevan untuk tujuan postingan ini.

Jadi, bagaimana versi disimpan secara fisik di toko versi? Seluruh catatan pra-perubahan, termasuk kolom off-row, disalin ke penyimpanan versi, dipecah menjadi potongan 8.000 byte, yang dapat menjangkau dua halaman jika perlu (mis., 2.000 byte di akhir satu halaman dan 6.000 byte di awal berikutnya). Penyimpanan tujuan khusus ini terdiri dari unit alokasi khusus tambahan dan hanya digunakan untuk operasi penyimpanan versi. Disebut demikian karena data baru hanya dapat ditambahkan segera setelah akhir versi yang paling baru dimasukkan. Unit alokasi baru sering dibuat, dan ini memungkinkan pembersihan penyimpanan versi reguler menjadi sangat efisien—karena unit alokasi yang tidak dibutuhkan dapat dibuang begitu saja. Sekali lagi, mekanismenya berada di luar cakupan postingan ini.

Dan sekarang kita sampai pada definisi kait:setiap utas yang perlu menyalin catatan pra-perubahan ke penyimpanan versi perlu mengetahui di mana titik penyisipan berada di unit alokasi khusus-tambahan saat ini. Informasi ini dilindungi oleh pengunci APPEND_ONLY_STORAGE_INSERT_POINT.

Bagaimana Kait Menjadi Penghalang?

Inilah masalahnya:hanya ada satu mode yang dapat diterima di mana kait APPEND_ONLY_STORAGE_INSERT_POINT dapat diperoleh:mode EX (eksklusif). Dan seperti yang akan Anda ketahui dari membaca postingan intro serial ini, hanya satu utas pada satu waktu yang dapat menahan kait dalam mode EX.

Menyatukan semua informasi ini:ketika satu atau lebih database mengaktifkan isolasi snapshot, dan ada beban kerja pembaruan yang cukup tinggi secara bersamaan untuk database tersebut, akan ada banyak versi yang dihasilkan oleh berbagai koneksi, dan kait ini akan menjadi sedikit hambatan, dengan ukuran hambatan meningkat seiring meningkatnya beban kerja pembaruan di mana pembuatan versi terlibat.

Menunjukkan Kemacetan

Anda dapat dengan mudah mereproduksi kemacetan untuk diri sendiri. Saya melakukannya sebagai berikut:

  • Membuat tabel dengan sekumpulan kolom integer bernama cXXX di mana XXX adalah angka dan indeks berkerumun pada kolom identitas int bernama DocID
  • Memasukkan 100.000 record, dengan nilai acak untuk semua kolom
  • Membuat skrip dengan loop tak terbatas untuk memilih DocID acak dalam rentang 1 hingga 10.000, memilih nama kolom acak, dan menambah nilai kolom sebesar 1 (sehingga membuat versi)
  • Membuat sembilan skrip identik, tetapi masing-masing memilih dari rentang kunci klaster 10.000 nilai yang berbeda
  • Setel DELAYED_DURABILITY ke FORCED untuk mengurangi waktu tunggu WRITELOG (tentu saja Anda jarang melakukan ini, tetapi ini membantu memperburuk kemacetan untuk tujuan demo)

Saya kemudian menjalankan semua sepuluh skrip secara bersamaan dan mengukur Metode Akses:Pencarian Indeks/penghitung detik untuk melacak berapa banyak pembaruan yang terjadi. Saya tidak dapat menggunakan Basis Data:Permintaan Batch/dtk karena setiap skrip hanya memiliki satu kumpulan (loop tak terbatas), dan saya tidak ingin menggunakan Transaksi/dtk karena mungkin menghitung transaksi internal serta yang membungkus setiap pembaruan.

Ketika isolasi snapshot tidak diaktifkan, pada laptop Windows 10 saya yang menjalankan SQL Server 2019, saya mendapatkan sekitar 80.000 pembaruan per detik di sepuluh koneksi. Kemudian ketika saya mengubah pengaturan READ_COMMMITED_SNAPSHOT ke ON untuk database dan menjalankan ulang pengujian, throughput beban kerja turun menjadi sekitar 60.000 pembaruan per detik (penurunan 25% dalam throughput). Dari melihat statistik menunggu, 85% dari semua menunggu adalah LATCH_EX, dan dari melihat statistik kait, 100% adalah untuk APPEND_ONLY_STORAGE_INSERT_POINT.

Ingatlah bahwa saya menyiapkan skenario untuk menunjukkan hambatan yang paling buruk. Dalam lingkungan kehidupan nyata dengan beban kerja campuran, panduan yang diterima secara umum untuk penurunan throughput saat menggunakan isolasi snapshot adalah 10-15%.

Ringkasan

Salah satu area potensial lain yang dapat terkena dampak kemacetan ini adalah ketersediaan sekunder yang dapat dibaca grup. Jika replika database diatur agar dapat dibaca, semua kueri yang menentangnya secara otomatis menggunakan isolasi snapshot, dan semua rekaman log replay dari primer akan menghasilkan versi. Dengan beban kerja pembaruan yang cukup tinggi yang berasal dari primer dan banyak database yang diatur agar dapat dibaca, dan dengan pengulangan paralel menjadi norma untuk sekunder grup ketersediaan, kait APPEND_ONLY_STORAGE_INSERT_POINT mungkin menjadi hambatan pada grup ketersediaan sekunder yang dapat dibaca juga, yang dapat menyebabkan sekunder tertinggal di belakang primer. Saya belum menguji ini, tetapi mekanismenya persis sama dengan yang saya jelaskan di atas, jadi sepertinya. Dalam hal ini, dimungkinkan untuk menonaktifkan pengulangan paralel menggunakan tanda pelacakan 3459, tetapi ini dapat menyebabkan throughput keseluruhan yang lebih buruk pada sekunder.

Mengesampingkan skenario grup ketersediaan, sayangnya, tidak menggunakan isolasi snapshot adalah satu-satunya cara untuk sepenuhnya menghindari kemacetan ini, yang bukan merupakan opsi yang layak jika beban kerja Anda bergantung pada semantik yang disediakan oleh isolasi snapshot, atau Anda memerlukannya untuk mengurangi masalah pemblokiran (karena isolasi snapshot berarti kueri baca tidak memperoleh kunci berbagi yang memblokir kueri perubahan).

Sunting:dari komentar di bawah, Anda *dapat* menghapus hambatan kait dengan menggunakan ADR di SQL Server 2019 tetapi kemudian kinerjanya jauh lebih buruk karena overhead ADR. Skenario di mana kait menjadi penghambat karena beban kerja pembaruan yang tinggi sama sekali bukan kasus penggunaan yang valid untuk ADR.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Menghapus Revisi Postingan menggunakan WP-CLI

  2. T-SQL Selasa #64 :Satu Pemicu atau Banyak?

  3. SQL ATAU Operator untuk Pemula

  4. SQL Always On Availability Groups:Computer Objects

  5. Menyimpan File dalam Database SQL Menggunakan FILESTREAM – Bagian 2