Operasi "ALTER INDEX ALL REBUILD" pada SQL Server 2012 gagal karena log transaksi kehabisan ruang. Indeks tidak pernah direorganisasi atau dibangun kembali, sehingga fragmentasi lebih dari 80% pada hampir semua indeks.
DB menggunakan model pemulihan sederhana. Saya berasumsi bahwa mengikuti setiap operasi indeks yang dilakukan oleh bentuk "ALL" dari perintah, data log transaksi akan memerah sebelum indeks berikutnya dibangun kembali. Apakah itu cara kerjanya sebenarnya, atau apakah indeks dibangun kembali seolah-olah mereka adalah bagian dari satu transaksi?
Dengan kata lain, dapatkah saya mengurangi pertumbuhan log transaksi dengan menulis skrip untuk melakukan setiap pembangunan kembali secara individual? Apakah ada faktor lain yang perlu dipertimbangkan?
sumber
Jawaban:
1) Pembilasan log: model pemulihan SEDERHANA tidak menghapus log setelah setiap transaksi, tetapi di pos-pos pemeriksaan. ( tautan untuk info lebih lanjut)
2a) REBUILD ALL: yes, REBUILD ALL berfungsi sebagai satu transaksi. Indeks dibangun kembali dalam memiliki transaksi sendiri, tetapi operasi keseluruhan tidak sepenuhnya berkomitmen sampai akhir. Jadi ya, Anda dapat membatasi pertumbuhan file log dengan membangun kembali indeks individual (dan mungkin mengeluarkan perintah CHECKPOINT).
2b) Bukti! Di sini, miliki skrip demo. (Dibangun pada tahun 2016 dev) Pertama, siapkan test db, dengan tabel dan indeks:
Sekarang Anda dapat membandingkan aktivitas log antara REBUILD ALL dan membangun kembali secara individual
Perhatikan bagaimana transaksi terbuka pertama (ID Transaksi 0000: 000002fa untuk saya) tidak dilakukan sampai akhir BUANG KEMBALI SEMUA, tetapi untuk indeks-demi-indeks dibangun kembali, mereka berhasil dilakukan.
sumber
Seperti berdiri, ini adalah transaksi tunggal.
sumber
Pertanyaannya sepele untuk pembangunan kembali offline . Tentu saja adalah satu transaksi. Bayangkan kekacauan yang akan terjadi jika operasi membagi setiap indeks menjadi transaksi sendiri, karena harus melepaskan kunci ketika melakukan dan kemudian memperoleh kembali. Sementara kunci tabel kritis SCH-M dirilis, indeks mungkin turun dan indeks baru bisa dibuat, bagaimana pernyataan menangani kasus-kasus seperti itu? Belum lagi meja yang mungkin jatuh, dan bahkan dibuat ulang antara dua transaksi! Termasuk kasus ketika tabel dijatuhkan dan tabel yang berbeda akan dibuat dengan id objek yang sama (ya, itu bisa terjadi) ...
Bagaimana jika Anda menambah pertanyaan untuk mengatakan apa yang terjadi jika indeks membangun kembali adalah pembangunan kembali online ? Apakah ini transaksi tunggal atau banyak? Jawabannya rumit, karena sebenarnya ada beberapa transaksi internal yang terlibat . Namun, titik kuncinya adalah bahwa ada transaksi lengkung keseluruhan yang merentang seluruh operasi (pernyataan ALTER) dan ini menyematkan log di tempat (tidak dapat terpotong), sehingga operasi perlu direncanakan sesuai untuk memungkinkan ~ 1,6x data ukuran untuk mode pemulihan LENGKAP, atau ukuran data 0,2x untuk mode BULK_LOGGED / SIMPLE. Lihat kertas tertaut untuk detail lebih lanjut.
Anda dapat berdebat bahwa mengapa bangunan offline tidak menggunakan transaksi internal yang sama dengan mode online, dan membagi operasi? Masalah yang saya sebutkan tentang tabel yang diubah / dijatuhkan antara operasi indeks individu (mis. Tabel 'skema stabilitas') masih akan mengharuskan ada transaksi mencakup yang memegang SCH-S di atas meja untuk seluruh durasi pernyataan. Karena transaksi ini harus memegang SCH-S juga selama pemulihan, itu harus dicatat, dan dengan demikian akan ada catatan log BEGIN XACT yang akan menyematkan log dan mencegah pemotongan selama seluruh durasi pernyataan. Saya tahu masalah khusus ini sedang ditangani dalam kerangka waktu SQL 2016-2017 (karena masalah ukuran log SQL Azure),
tapi saya tidak yakin kemajuan apa yang dibuat. Sepertinya sedang dalam pratinjau sekarang:Resumable Online Index Rebuild dalam pratinjau publik untuk SQL Server 2017 CTP 2.0 .sumber
Ya, saya punya masalah yang sama dengan meja yang sangat besar. Setiap kali saya mengeluarkan ALTER INDEX ALL, log transaksi akan tumbuh banyak, tetapi jika diterbitkan ALTER INDEX secara individual, penggunaan ruang log akan lebih kecil.
sumber
Respons sebelumnya oleh Remus bahwa pengindeksan online membutuhkan 1,6x ukuran indeks dalam mode pemulihan LENGKAP tidak benar. Proporsi ruang pencatatan transaksi yang diperlukan untuk membangun kembali indeks online di bawah FULL bisa jauh lebih tinggi dan kami telah mengamati berkali-kali ukuran indeks, terutama ketika indeks yang sedang dibangun kembali dikompresi karena pencatatan transaksi tidak dikompresi. Ini saja harus menjelaskan bahwa pencatatan transaksi selama pembangunan kembali online di bawah LENGKAP bisa setidaknya beberapa kali ukuran indeks. Tambahkan overhead catatan tlog yang tidak sepenuhnya didokumentasikan oleh Microsoft tetapi sering diperkirakan 60 byte per baris dan ukuran proporsional dari logging selama indeks online yang dibangun kembali di bawah pemulihan penuh dapat berkali-kali ukuran indeks yang sedang dibangun kembali, terutama jika indeks dikompresi
sumber
Rdfozz benar itu adalah cara terbaik untuk memutuskan apakah indeks terbesar Anda dapat dibangun kembali berdasarkan penyimpanan saat ini. Jalankan saja
dm_exec_requests
ketika operasi sedang berlangsung (atau SQL Profiler) untuk melihat apakah semua indeks sedang dibangun kembali. Saya juga akan mempertimbangkan untuk mengubah model pemulihan ke log massal. Inilah yang saya lakukan dan ada cadangan transaksi log selama jendela masih. Lihat artikel di bawah ini https://technet.microsoft.com/en-us/library/ms191484(v=sql.105).aspxsumber