ALTER INDEX ALL REBUILD, basit kurtarma modeliyle her bir dizini ayrı ayrı yeniden oluşturmaktan daha fazla işlem günlüğü alanı kullanıyor mu?


18

İşlem günlüğünde alan kalmadığından, SQL Server 2012'de bir "ALTER INDEX ALL REBUILD" işlemi başarısız oldu. Endeksler hiçbir zaman yeniden düzenlenmedi veya yeniden oluşturulmadı, bu yüzden parçalanma neredeyse hepsinde% 80'in üzerinde.

DB basit bir kurtarma modeli kullanır. Komutun "TÜMÜ" formu tarafından gerçekleştirilen her dizin işleminden sonra, işlem günlüğü verilerinin bir sonraki dizin yeniden oluşturmadan önce temizleneceğini varsaydım. Aslında bu şekilde mi çalışıyor, yoksa dizin yeniden oluşturma işlemleri tek bir işlemin parçası gibi mi günlüğe kaydediliyor?

Başka bir deyişle, her bir yeniden oluşturma işlemini tek tek gerçekleştirmek için bir komut dosyası yazarak işlem günlüğü büyümesini azaltabilir miyim? Dikkate alınacak başka faktörler var mı?


2
Açık verileri aksine engelleme, belirli bir SQL komut DB motoru tarafından tek bir atomik işlem olarak kabul olacağını varsayar. Bu durumda, teoriyi kolayca test edebilirsiniz. En büyük dizininizi alın ve bunu yeniden oluşturmaya çalışın. Bu başarılı olursa, günlüğün birden çok yeniden derlemeden bilgi biriktirdiğini varsaymak mantıklıdır. Başarısız olursa, günlük için alan eklemeniz gerekir (her iki durumda da bir sorun olduğu için) veya yeniden oluşturmak yerine bu dizini yeniden düzenlemeye çalışmanız gerekir (t- günlüğü).
RDFozz

Evet, bu düşünceyi yazmayı bitirdiğimde meydana geldi (lastik ördek etkisi), ama onay almanın ve aynı şekilde düşünebilecek başkaları için bırakmanın en iyi olacağını düşündüm. Bu ortamla denemek istemiyorum, bu yüzden günlüklere her iki şekilde de alan ekleyeceğim.
Google Başarısız

Yanıtlar:


16

Komutun "TÜMÜ" formu tarafından gerçekleştirilen her dizin işleminden sonra, işlem günlüğü verilerinin bir sonraki dizin yeniden oluşturmadan önce temizleneceğini varsaydım. Aslında bu şekilde mi çalışıyor, yoksa dizin yeniden oluşturma işlemleri tek bir işlemin parçası gibi mi günlüğe kaydediliyor?

1) Günlük temizleme: SIMPLE kurtarma modeli, her işlemden sonra günlüğü temizlemez, ancak kontrol noktalarında. ( daha fazla bilgi için bağlantı )

2a) TÜMÜNÜ YENİDEN OLUŞTUR: evet, TÜMÜNÜ TEKRAR İNDİR tek bir işlem olarak çalışır. İçinde dizin yeniden oluşturma kendi işlemleri vardır, ancak genel işlem sonuna kadar tam olarak taahhüt edilmez. Bu nedenle evet, tek tek dizinleri yeniden oluşturarak (ve muhtemelen CHECKPOINT komutları vererek) günlük dosyasının büyümesini sınırlayabilirsiniz.

2b) Kanıt! Burada bir demo betiği var. (2016 devinde oluşturuldu) İlk olarak, tablo ve dizinlerle bir test db oluşturun:

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')

Artık REBUILD ALL ile bireysel olarak yeniden oluşturma arasındaki günlük etkinliğini karşılaştırabilirsiniz

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

İlk açık işlemin (İşlem Kimliği 0000: 000002fa benim için) TÜMÜNÜ REBUILD sonuna kadar nasıl işlemediğine dikkat edin, ancak endeks bazında yeniden yapılandırmalar için ard arda taahhüt edilmiştir.


Vay be, gerçekten ayrıntılı yanıt için teşekkürler! Bu, tabiri caizse, kaputun altında neler olduğunu görmek için harika bir yoldur.
Google Başarısız

Güzel açıkladı.
Ramakant Dadhichi

4

Haliyle, bu tek işlemdir.


6
DBA.SE'ye Hoşgeldiniz! Genel olarak, en iyi cevaplar basit iddialar değildir, ancak belgelerin veya makalelerin bilgileri veya belirtilen cevabı kanıtlayan (genellikle daha iyi) kişisel deneyimlerle desteklenir. Bu tür bir destek sağlamak için cevabınızı genişletebilir misiniz?
RDFozz

2
@RDFozz Adil yorum, ancak Pedro'nun profiline baktın mı? Kaynak koduna erişim muhtemelen kişisel deneyim veya dokümantasyondan daha yetkili olarak kabul edilebilir. :-)
Aaron Bertrand

3
@AaronBertrand - İtiraf ettim, yapmadım. Kesinlikle SQL Server ekibinin bir parçası olmanın hak kazanacağını düşünürdüm. Yine de cevapta buna değinmeye değer. Her durumda +1.
RDFozz

3

Soru, çevrimdışı yeniden oluşturma için önemsizdir . Tabii ki tek bir işlemdir. İşlemin her bir dizini kendi işlemine ayırması durumunda ortaya çıkacak tahribatı düşünün, çünkü işlem yaparken kilitleri serbest bırakmak ve daha sonra bunları yeniden elde etmek zorunda kalacaktır . Kritik tablo SCH-M kilidi serbest bırakılırken, dizinler bırakılabilir ve yeni dizinler oluşturulabilirken, ifade bu gibi durumları nasıl ele alacaktı? Tablonun düşürülebileceğini ve hatta iki işlem arasında yeniden oluşturulabileceğini belirtmiyoruz ! Tablonun düşürüldüğü ve aynı nesne kimliğiyle farklı bir tablo oluşturulduğu durum dahil (evet, olabilir) ...

Dizin yeniden oluşturma çevrimiçi yeniden oluşturma ise ne olacağını soruyu artırırsanız ne olur ? Tek bir işlem mi yoksa çok mu? Aslında çok sayıda dahili işlem olduğundan yanıt karmaşıktır . Bununla birlikte, kilit nokta, tüm işlemi kapsayan (ALTER ifadesi) genel bir kemerleme işleminin olması ve bu günlüğün yerine sabitlenmesine (kesilemez), bu nedenle işlemin ~ 1.6x verilere izin verecek şekilde planlanması gerekir. TAM kurtarma modu için boyut veya BULK_LOGGED / SIMPLE modu için 0.2x veri boyutu. Daha fazla ayrıntı için bağlantılı makaleye bakın.

Çevrimdışı derlemenin neden çevrimiçi moddakiyle aynı dahili işlemleri kullanmadığını ve işlemi böldüğünü iddia edebilirsiniz? Bireysel indeks işlemleri arasında (yani tablo 'şema kararlılığı') arasında değişen / bırakılan tablonun bahsettiğim konular, ifadenin tüm süresi boyunca tabloda bir SCH-S tutan bir kapsayıcı işlem olmasını gerektirecektir. Bu işlem, kurtarma sırasında SCH-S'yi de tutması gerektiğinden, günlüğe kaydedilmelidir ve bu nedenle, günlüğü sabitleyen ve ifadenin tüm süresi boyunca kesmeyi önleyen bir BEGIN XACT günlük kaydı olacaktır. Bu özel sorunun SQL 2016-2017 zaman çerçevesinde (SQL Azure günlük boyutu sorunları nedeniyle) ele alındığını biliyorum, ancak ne ilerleme kaydedildiğinden emin değilim . Görünüşe göre şimdi önizlemede:Sürdürülebilir Çevrimiçi Dizin Yeniden Oluşturma, SQL Server 2017 CTP 2.0 için genel önizlemede .


0

Evet, aynı problemi çok büyük bir tablo ile yaşadım. Ne zaman ALTER INDEX ALL yayınlasam, işlem günlüğü çok büyür, ancak ALTER INDEX ayrı ayrı yayınlanırsa, günlük alanı kullanımı daha küçük olur.


0

Remus'un çevrimiçi indekslemenin TAM kurtarma modu altındaki indeks boyutunun 1,6x gerektirdiği yönündeki cevabı doğru değil. FULL altında çevrimiçi bir dizini yeniden oluşturmak için gereken işlem günlüğü alanının oranı çok daha yüksek olabilir ve özellikle işlem günlüğü sıkıştırılmadığından yeniden oluşturulan dizin sıkıştırıldığında, dizin boyutunun birçok katını gözlemledik. Bu tek başına, FULL altında çevrimiçi yeniden oluşturma sırasında işlem günlüğünün dizin boyutunun en az birkaç katı olabileceğini açıkça belirtmelidir. Microsoft tarafından tam olarak belgelenmeyen, ancak genellikle satır başına 60 bayt olarak tahmin edilen tlog kayıt ek yükü ekleyin ve tam kurtarma altında çevrimiçi bir dizin yeniden oluşturma sırasında oransal günlük boyutu, özellikle yeniden oluşturulduğunda dizinin boyutunun katları olabilir. dizin sıkıştırılır


-1

Rdfozz doğrudur, en büyük dizininizin mevcut depolamaya göre yeniden oluşturulabileceğine karar vermenin en iyi yolu budur. dm_exec_requestsTüm dizinlerin yeniden oluşturulup oluşturulmadığını görmek için işlem yapılırken (veya SQL Profiler) çalıştırın . Ayrıca kurtarma modeli toplu günlüğe değiştirmek düşünün. Bu benim yaptığım ve hala pencere sırasında işlem günlüğü yedekleme 's. Aşağıdaki makaleye bakın https://technet.microsoft.com/en-us/library/ms191484(v=sql.105).aspx


2
OP, DB'lerinin zaten SIMPLE kurtarma modelini kullandığını belirtti; bu yalnızca günlükteki işlemleri, işlemlerin tamamlanması için yeterince uzun tutar. Toplu günlüğe geçilirlerse herhangi bir gelişme olmazdı.
RDFozz

Çok haklısın. Özür dilerim.
ADTJOB
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.