SQL Server 2014 CTP1 memperkenalkan opsi tunggu kunci prioritas rendah untuk digunakan dengan operasi indeks online dan sakelar partisi.
Bagi mereka yang memanfaatkan manajemen indeks online atau operasi partisi indeks dan sakelar partisi di SQL Server 2012 Enterprise Edition, Anda mungkin pernah mengalami pemblokiran operasi DDL karena operasi ini masih memiliki beberapa persyaratan penguncian.
Sebagai ilustrasi, bayangkan saya menjalankan pembangunan kembali indeks online partisi tunggal berikut di SQL Server 2014 CTP1:
ALTER INDEX [ClusteredIndex_on_ps_ShipDate]ON [dbo].[FactInternetSales]REBUILD PARTITION =(37)WITH (ONLINE=ON);
Dan mari kita lihat kunci yang diperoleh dan dilepaskan selama operasi pembangunan kembali ini menggunakan Acara yang Diperpanjang dan definisi sesi berikut (ini adalah sesi tanpa target dan saya melihat hasilnya melalui panel "Tonton Data Langsung" di SQL Server Management Studio):
BUAT SESI EVENT [Online_Index_Rebuild_Locks_Taken] PADA SERVER ADD EVENT sqlserver.lock_acquired( WHERE ([object_id]=(309576141))), ADD EVENT sqlserver.lock_released( WHERE ([object_id])=)(3095MOTH_141) 4096 KB, EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY=30 DETIK, MAX_EVENT_SIZE=0 KB, MEMORY_PARTITION_MODE=NONE, TRACK_CAUSALITY=OFF, STARTUP_STATE=OFF);GO
Nilai 309576141 mewakili ID objek tabel FactInternetSales.
Pembuatan kembali indeks online saya dari satu partisi membutuhkan waktu 56 detik untuk diselesaikan dan setelah selesai, saya melihat aktivitas akuisisi dan pelepasan kunci berikut:
Kunci aktivitas untuk pembuatan ulang online satu partisi
Seperti yang Anda lihat dari output, meskipun pembangunan kembali adalah operasi online, ini melibatkan perolehan kunci dalam berbagai mode selama siklus hidup operasi. Idealnya durasi penguncian minimal (misalnya – stempel waktu identik untuk SCH_S
pertama kunci diperoleh dan dilepaskan). Tetapi bahkan dengan jumlah penguncian yang minimal, Anda pasti dapat menghadapi masalah konkurensi tergantung pada transaksi yang berjalan terhadap indeks yang dibangun kembali atau dialihkan.
Saya sebutkan di awal posting ini bahwa Microsoft memperkenalkan opsi tunggu kunci prioritas rendah untuk operasi online dan operasi sakelar partisi di SQL Server 2014 CTP1. Pada subjek sakelar partisi, bayangkan saya menjalankan operasi berikut:
ALTER TABLE [AdventureWorksDW2012].[dbo].[FactInternetSales] SWITCH PARTITION 37 KE [AdventureWorksDW2012].[dbo].[staging_FactInternetSales];
Untuk melihat kunci yang diperoleh dan dilepaskan untuk operasi ini, saya memodifikasi sesi Acara Diperpanjang yang telah ditentukan sebelumnya untuk menyertakan objek yang berlaku (tabel sumber dan target). Saya melihat yang berikut:
Aktivitas kunci untuk operasi sakelar partisi
Operasi peralihan ke partisi kosong terjadi dalam waktu kurang dari satu detik, tetapi kita masih melihat bahwa SCH_S
dan SCH_M
kunci diperlukan selama siklus hidup operasi pada sumber dan tujuan (309576141 menjadi FactInternetSales dan 398624463 sebagai staging_FactInternetSales).
Jadi sekali lagi, sementara durasi penguncian bisa sangat singkat ketika tidak ada transaksi bersamaan yang mengakses objek yang dipermasalahkan, kami tahu ini tidak selalu memungkinkan sehingga operasi pembangunan kembali indeks online dan sakelar partisi kami memang bisa diblokir.
Jadi dengan kenyataan ini, SQL Server 2014 memperkenalkan WAIT_AT_LOW_PRIORITY
argumen yang dapat disesuaikan dengan MAX_DURATION
dan ABORT_AFTER_WAIT
opsi untuk ALTER INDEX
dan ALTER TABLE
perintah yang dapat kita gunakan untuk operasi pengindeksan dan pengalih partisi online.
Hal ini memungkinkan kita untuk melakukan apa? Pertama-tama, mari kita bicara tentang perilaku sebelum SQL Server 2014. Sebagai contoh, bayangkan saya memiliki transaksi berikut yang terbuka dan tidak terikat:
MULAI TRANSAKSI;HAPUS [dbo].[staging_FactInternetSales];
Jika saya mencoba melakukan ALTER TABLE SWITCH
ke tabel staging_FactInternetSales sebagai tujuan dalam sesi terpisah, saya akan diblokir dan permintaan hanya akan menunggu. Khusus untuk contoh ini, saya akan menunggu dengan LCK_M_SCH_M
tipe tunggu. Setelah saya mengembalikan atau melakukan transaksi saya, operasi dapat dilanjutkan dan diselesaikan.
Sekarang jika saya menggunakan WAIT_AT_LOW_PRIORITY
SQL Server 2014 dengan MAX_DURATION
dan ABORT_AFTER_WAIT
, saya dapat memanfaatkan beberapa opsi berbeda tergantung pada persyaratan aplikasi saya.
MAX_DURATION
memungkinkan saya untuk menentukan jumlah menit yang akan menunggu operasi pembangunan kembali indeks online atau sakelar partisi. Jika MAX_DURATION
nilai tercapai, kita dapat mengatur apa yang terjadi selanjutnya berdasarkan pengaturan ABORT_AFTER_WAIT
, yang dapat berupa nilai NONE
, SELF
atau BLOCKERS
:
NONE
berarti operasi indeks akan terus mencoba operasi.SELF
artinya jikaMAX_DURATION
tercapai, operasi (pembuatan kembali indeks online atau sakelar partisi) akan dibatalkan.- Jika
BLOCKERS
digunakan, itu akan membunuh semua transaksi yang memblokir indeks online membangun kembali atau operasi sakelar partisi (bukan pilihan, menurut saya, untuk digunakan dengan ringan).BLOCKERS
juga membutuhkanALTER ANY CONNECTION
izin untuk permintaan yang mengeluarkan operasi pembangunan kembali indeks online atau peralihan partisi.
Contoh kode berikut menunjukkan variasi konfigurasi yang berbeda.
Perilaku default sebelum 2014 (menunggu tanpa batas waktu)
- Mengeksekusi yang berikut ini akan menghasilkan perilaku yang biasa kita lihat sebelum SQL Server 2014 – dan mungkin tetap seperti yang Anda inginkan atau harapkan untuk skenario tertentu:
ALTER TABLE [AdventureWorksDW2012].[dbo].[FactInternetSales] SWITCH PARTITION 37 TO [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] WITH (WAIT_AT_LOW_PRIORITY (MAX_DURATION =0 MENIT, ABORT_AFTER));NONE_);
Tunggu 1 Menit dan Batalkan Operasi DDL
- Contoh berikut menunggu selama 1 menit jika ada transaksi pemblokiran dan akan mendapatkan “batas waktu permintaan penguncian terlampaui” untuk
SWITCH
operasi jika durasi maksimum tercapai: ALTER TABLE [AdventureWorksDW2012].[dbo].[FactInternetSales] SWITCH PARTITION 37 TO [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] WITH (WAIT_AT_LOW_PRIORITY (MAX_DURATION =1 MENIT, ABORT_AFTER)_);SELFTER_);
Tunggu 1 Menit dan Bunuh Pemblokir
- Contoh ini menunggu selama 1 menit jika ada transaksi pemblokiran dan kemudian akan mematikan transaksi pemblokiran (termasuk sumber atau tujuan), memungkinkan
SWITCH
operasi untuk diselesaikan. ALTER TABLE [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] SWITCH PARTITION 37 TO [AdventureWorksDW2012].[dbo].[FactInternetSales] WITH (WAIT_AT_LOW_PRIORITY (MAX_DURATION =1 MENIT, ABORT_AFTER_WAIT) = Dalam contoh saya tentangDELETE
di dalam transaksi yang tidak dikomit, tidak ada kesalahan di jendela SQL Server Management Studio saya karena saya tidak memiliki pernyataan yang berjalan secara aktif, tetapi mencoba pernyataan lain dalam sesi itu mengembalikan pesan kesalahan berikut (karena sesi saya telah dimatikan): Msg 233, Level 20, State 0, Line 3
Terjadi kesalahan tingkat transport saat mengirim permintaan ke server. (penyedia:Penyedia Memori Bersama, kesalahan:0 – Tidak ada proses di ujung pipa yang lain.)Segera Bunuh Pemblokir (Sumber atau Tujuan untuk SWITCH)
- Berikut ini adalah contoh membunuh pemblokir dengan segera – dan dalam contoh saya pergantian terjadi dalam hitungan detik dan memang sesi pemblokir itu terbunuh:
ALTER TABLE [AdventureWorksDW2012].[dbo].[FactInternetSales] SWITCH PARTITION 37 TO [AdventureWorksDW2012].[dbo].[staging_FactInternetSales]WITH (WAIT_AT_LOW_PRIORITY (MAX_DURATION =0 MINUTES, ABORT_AFTER_WAIT));LOCKERS =
Satu aspek positif terakhir yang ingin saya sebutkan…
Log Kesalahan SQL Server menyediakan beberapa audit default dari penggunaan menunggu kunci prioritas rendah, termasuk informasi tentang ABORT_AFTER_WAIT
operasi sejalan dengan informasi korban:
Log SQL Server (Saat ini – 10/9/2013 12:03:00)
Sumber spid51
Pesan
Proses ID 57 dibunuh oleh pernyataan ABORT_AFTER_WAIT =BLOCKERS DDL pada database_id =5, object_id =309576141.
Dan Anda juga akan melihat entri terpisah untuk operasi asli itu sendiri. Misalnya:
Pernyataan ALTER TABLE SWITCH dijalankan pada database 'AdventureWorksDW2012', tabel 'staging_FactInternetSales' dengan nama host 'WIN-4T7S36VMSD9', ID proses host 1360 dengan tabel target 'AdventureWorksDW2012.dbo.FactInternetSales' menggunakan opsi WAIT_AFTER_LOW_PRIORITY =AFTER_LOW_PRIORITY =BLOKER. Memblokir sesi pengguna akan dihentikan setelah durasi waktu tunggu maksimal.Logging semacam ini sangat berguna untuk tujuan pemecahan masalah dan audit, dan saya senang melihatnya.