Apakah ALTER INDEX ALL REBUILD menggunakan lebih banyak ruang log transaksi dengan model pemulihan sederhana daripada membangun kembali setiap indeks secara terpisah?


18

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?


2
Kecuali data eksplisit sebaliknya, saya akan berasumsi bahwa perintah SQL spesifik akan dianggap sebagai transaksi atom tunggal oleh mesin DB. Dalam hal ini, Anda dapat dengan mudah menguji teorinya. Ambil indeks terbesar Anda, dan coba untuk membangunnya kembali. Jika itu berhasil, maka masuk akal untuk menganggap bahwa log tersebut mengumpulkan informasi dari beberapa pembangunan kembali. Jika gagal, maka Anda perlu menambahkan ruang untuk log (karena Anda punya masalah juga), atau Anda perlu mencoba mengatur ulang indeks itu, bukan membangun kembali (jika Anda tidak dapat meningkatkan ruang untuk t- catatan).
RDFozz

Ya, pikiran itu terlintas di benak saya tepat ketika saya selesai mengetik ini (efek bebek karet), tetapi saya pikir akan lebih baik untuk mendapatkan konfirmasi, dan menyerahkannya kepada orang lain yang mungkin berpikir dengan cara yang sama. Saya tidak ingin bereksperimen dengan lingkungan ini, jadi saya mungkin akhirnya akan menambahkan ruang pada log.
Google Fail

Jawaban:


16

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?

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:

USE master
GO

CREATE DATABASE Test_RebuildLog
GO

ALTER DATABASE Test_RebuildLog
SET RECOVERY SIMPLE
GO

USE Test_RebuildLog
GO

CREATE TABLE IndexTest
(ID int identity(1,1),
a char(1),
b char(1))

CREATE CLUSTERED INDEX CIX_IndexTest_ID ON IndexTest(ID)
CREATE INDEX IX_IndexTest_a ON IndexTest(a)
CREATE INDEX IX_IndexTest_b ON IndexTest(b)

INSERT IndexTest
(a,b)
VALUES ('a','b'),('z','y'),('s','r')

Sekarang Anda dapat membandingkan aktivitas log antara REBUILD ALL dan membangun kembali secara individual

CHECKPOINT
GO
ALTER INDEX ALL ON IndexTest REBUILD

SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO

CHECKPOINT
GO
ALTER INDEX CIX_IndexTest_ID ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_a ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_b ON IndexTest REBUILD

SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO

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.


Wow, terima kasih atas tanggapan yang sangat terperinci! Itu cara yang bagus untuk melihat apa yang terjadi di bawah tenda, jadi untuk berbicara.
Google Fail

Dijelaskan dengan baik.
Ramakant Dadhichi

4

Seperti berdiri, ini adalah transaksi tunggal.


6
Selamat datang di DBA.SE! Secara umum, jawaban terbaik bukanlah pernyataan sederhana, tetapi didukung oleh informasi dari dokumentasi atau artikel, atau (sering bahkan lebih baik) pengalaman pribadi membuktikan jawaban yang disebutkan. Bisakah Anda memperluas jawaban Anda, untuk memberikan dukungan semacam itu?
RDFozz

2
@RDFozz Fair berkomentar, tetapi apakah Anda melihat profil Pedro ? Akses ke kode sumber mungkin dapat dianggap lebih otoritatif daripada pengalaman pribadi atau dokumentasi. :-)
Aaron Bertrand

3
@ AaronBertrand - Saya akui, saya tidak. Saya pasti berpikir menjadi bagian dari tim SQL Server memang akan memenuhi syarat. Namun, ada baiknya merujuk hal itu dalam jawabannya. +1, bagaimanapun juga.
RDFozz

3

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 .


0

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.


0

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


-1

Rdfozz benar itu adalah cara terbaik untuk memutuskan apakah indeks terbesar Anda dapat dibangun kembali berdasarkan penyimpanan saat ini. Jalankan saja dm_exec_requestsketika 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).aspx


2
Perhatikan bahwa OP menyatakan DB mereka sudah menggunakan model pemulihan SIMPLE; ini hanya membuat transaksi dalam log cukup lama untuk menyelesaikan transaksi. Tidak akan ada peningkatan jika mereka beralih ke log massal.
RDFozz

Anda benar. Permintaan maaf saya.
ADTJOB
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.