"İndeks commit edilemiyor" veya kısmen geri yüklenmiş (tutarsız) veritabanından veri nasıl pompalanır
Alexey Kovyazin, son güncelleme 30-Mart-2014
Bozulmaları düzelttikten sonra, geri yükleme adımında sık sık “Cannot commit index” hatasıyla karşılaşılır. Firebird 2.0 ve sonrasında bu bir uyarı olarak gelir ve veritabanı çevrimiçi duruma getirilmez; Firebird 1.0-1.5 ve InterBase’de ise bu, geri yükleme sürecini durduran çok hoş olmayan bir hata olarak ortaya çıkar (200GB’lık bir veritabanı geri yüklemesinin sonunda bu hatayı görmek etkileyicidir).
“Cannot commit index..” hatasının nedeni açıktır: bozulma, veritabanının referans bütünlüğünü etkiler ve kayıtlar (sunucu bakış açısından) sihirli bir şekilde kaybolur.
Örneğin, “Customers” tablonuz ve Foreign key ile ilişkilendirilmiş “Orders” tablonuz var. Bozulma olmadan, belirli bir müşteriye ait tüm siparişleri silmeden Foreign key’i ihlal etmek ve Customers tablosundan kayıt silmek mümkün değildir. Bozulma, veritabanı dosyasını düşük seviyede etkiler ve kayıtları doğrudan öldürür. Sunucunun, foreign key kayıtlarından ana kayıtlara çözümlenemeyen bağlantılar görmesi ne kadar hoş bir sürpriz.
Burada geri yükleme süreci hakkında bir ipucu eklemem gerekiyor: motor, tüm tabloları etkinleştirilmemiş indekslerle geri yükler (bu, tabloların kayıtlarla doldurulmasını çok daha hızlı yapar) ve ardından indeksleri tek tek etkinleştirmeye (yani oluşturmaya) başlar. Bu, geri yükleme süreci indeks oluşturma adımına başladığında tüm verilerin zaten veritabanında olduğu ve “Cannot commit index..” hatasını gördüğünüz anlamına gelir.
“Cannot commit index” hatasını gördüğünüzde ilk istek, geri yüklemenin tamamlanmasına izin vermek için ilgili Foreign key kısıtlamasını kaldırmaktır. Soru şu: tutarsız ama başarıyla geri yüklenmiş veritabanıyla ne yapacağız? Kaldırılan foreign key, iş mantığının önemli bir parçası olabilir.
Burada 2 yaklaşım vardır: eksik verileri yeniden oluşturmak veya tutarsız verileri kaldırmak. Bunun yukarıdaki Customers-Orders örneğinde ne anlama geldiğini görelim.
Eksik Verilerin Yeniden Oluşturulması
Tutarsız Orders için eksik Customers kayıtlarını yeniden oluşturmanız gerektiğine karar verdiniz. Bu durumda kayıp ID’leri belirlemeniz gerekir. Genellikle şöyle bir SQL sorgusu kullanırım (uygun olana uyarlamanın kolay olacağını düşünüyorum):
SELECT O.Customer_ID FROM ORDERS O WHERE NOT EXISTS ( SELECT C.Customer_ID FROM CUSTOMERS C WHERE O.Customer_ID=C.Customer_ID)
Bundan sonra, eksik birincil anahtarların listesiyle kayıtları manuel olarak ekleyebilir ve backup/restore işlemini tekrar çalıştırabilirsiniz.
Tutarlı Verilerin Aktarılması
Tutarsız kayıtları kaybetmenin kabul edilebilir olduğunu düşünüyorsanız, aşağıdaki yaklaşımı kullanarak tüm verileri kısmen geri yüklenmiş veritabanından boş veritabanına aktarabilir ve tutarsız kayıtları atlayabilirsiniz:
-
Ücretsiz aracı IBDataPump indirin http://www.clevercomponents.com/demo/datapump/IBPump.zip
-
Onarılmış veritabanının yedeğinden (IBFirstAID sonrası) yalnızca meta veri veritabanı oluşturmak için şu komutu kullanın:
gbak -c -m -user SYSDBA -pass masterkey Disk:\Path\backup.fbk Disk:\Path\fresh.fdb
-
IBDataPump’ı çalıştırın ve kısmen onarılmış veritabanını Kaynak, boş yeni veritabanını Hedef olarak ayarlayın
-
Sonraki sekmelere tıklayın, uygun düğmelere tıklayın ve 3. sekmede “Pump” düğmesine tıklayın. Tamamlanmasını bekleyin (uzun bir süreç olabilir, hedef veritabanı boyutunun büyüme dinamiklerini kontrol ederek bir fikir edinebilirsiniz).
-
Sonuç olarak, tutarlı foreign key ilişkilerine sahip fresh.fdb veritabanına sahip olacaksınız - bu tamamen sorunsuzdur.
Veritabanında foreign key’lerle bir döngü varsa, IBDataPump sizi uyaracak ve bu tür kısıtlamaların bir listesini verecektir - aktarma işlemi kullanılabilir olmadan önce bunlardan bir veya daha fazlası kaldırılmalıdır.
Elbette, aktarma işleminin özel bir yaklaşım gerektirdiği durumlar da olmuştur ve böyle bir durumla karşılaşırsanız, lütfen destek ekibimizle iletişime geçin.