Zamanlanmış yedekleme görevi, her zaman işin başarılı olduğunu söylese de tüm veritabanlarını her zaman yedeklemez


9

SQL 2008'de, tüm veritabanlarını yedeklemek için depolanmış bir proc çalıştıran bir işim var. Bu günlük sql server aracısı işi üzerinden çalışır.

Her gün başarıyla bırakılıyor, ancak bazı günlerde sadece birkaç veritabanını yedekledikten sonra başarıyla çıkıyor. Her seferinde farklı sayıda veritabanı olabilir. Çoğu gün tüm veritabanlarını başarılı bir şekilde yedekler, ancak bazen 2, bazen 5 vb.

İş geçmişi, olay görüntüleyici veya sql sunucusu günlüğünde herhangi bir hata görmüyorum.

Klasör, genişletilebilir bir depolama birimindeki bir klasöre bir "bağlantı" olmasına rağmen, yedeklemeler yerel bir diske yapılır.

İşletim sistemi, Vqware ESXi 5 ana bilgisayarında çalışan bir sanal makine olarak Sql Server 2008 web sürümü 64 bit çalıştıran Windows 2003 64bit'tir.

Saklı yordam:

ALTER PROCEDURE [dbo].[backup_all_databases] 
@path VARCHAR(255)='c:\backups\'

AS

DECLARE @name VARCHAR(50) -- database name  
DECLARE @fileName VARCHAR(256) -- filename for backup  
DECLARE @fileDate VARCHAR(20) -- used for file name 
DECLARE @dbIsReadOnly sql_variant -- is database read_only?
DECLARE @dbIsOffline sql_variant -- is database offline?

DECLARE db_cursor CURSOR FOR  
SELECT name 
FROM master.dbo.sysdatabases 
WHERE name NOT IN ('tempdb')
AND version > 0 AND version IS NOT NULL

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @name   

WHILE @@FETCH_STATUS = 0   
BEGIN   
SET @fileName = @path + @name + '.bak'

SET @dbIsReadOnly = (SELECT DATABASEPROPERTY(@name, 'IsReadOnly')) -- 1 = Read Only
SET @dbIsOffline = (SELECT DATABASEPROPERTY(@name, 'IsOffline')) -- 1 = Offline

IF (@dbIsReadOnly = 0 OR @dbIsReadOnly IS NULL) AND @dbIsOffline =0
BEGIN
    BACKUP DATABASE @name TO DISK = @fileName  WITH INIT
    WAITFOR DELAY '00:00:20'
END

FETCH NEXT FROM db_cursor INTO @name 
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

Herhangi bir öneriniz lütfen?

Yanıtlar:


9

Hataları işlemek ve günlüğe kaydetmek için TRY / CATCH blokları eklerdim. DB tek kullanıcılı olabilir, geri yüklenebilir ya da her neyse.

Bu olmadan, hatalar hiçbir hata günlüğe kaydedilmeyecek şekilde iptal edilebilir (deyim, toplu iş, kapsam, bağlantı vb.)

TRY / CATCH ile derleme veya bağlantı iptali hataları hariç her şey günlüğe kaydedilir? ama durumun bu olduğundan şüpheliyim.

Ayrıca sysdatabases yerine sys.databases kullanmak ve daha fazla bayrak okumak:

-- declares etc

BEGIN TRY

    DECLARE db_cursor CURSOR FOR  
    SELECT name, state, user_access
    FROM sys.databases 
    WHERE name NOT IN ('tempdb')

    OPEN db_cursor   
    FETCH NEXT FROM db_cursor INTO @name, @state, @user_access

    WHILE @@FETCH_STATUS = 0   
    BEGIN   

        SET @fileName = @path + @name + '.bak'
        IF @state = 0 AND user_access = 0
        BEGIN
            BEGIN TRY
                BACKUP DATABASE @name TO DISK = @fileName  WITH INIT
            END TRY
            BEGIN CATCH
                -- log but do not rethrow so loop continues
            END CATCH
            WAITFOR DELAY '00:00:20'
        END
        ELSE
           --log user and/or state issues

        FETCH NEXT FROM db_cursor INTO @name 
    END   

    CLOSE db_cursor   
    DEALLOCATE db_cursor

END TRY
BEGIN CATCH
  -- some useful stuff here
END CATCH

Sys.databases kullanma tavsiyesi için +1
Peter Schofield

2

"Yedekle" komutundan sonra hataları kontrol edin, algılanan hatalar için kendi e-postanızı gönderin.

Bu, neler olup bittiğini görmek için bir başlangıç ​​noktası verecek ve iş sorunu çözülene kadar sizi herhangi bir sorun konusunda uyarmayı garanti edecektir.


2

İmlecin üzerine bir sipariş verin. SQL veri döndürme sırasını seçmek için izin verdiğinizde sys.databases imleçler "sorunları" gördüm. Ada göre sipariş vermek yeterli olmalıdır.


2

Yedekleme teybe yedekleme veya yedekleme dosyalarına kopyalama veya erişme işlemleriyle aynı anda mı çalışıyor? Eğer öyleyse, bahse girerim çünkü dosyanın üzerine yazılmaz. Birden fazla yedek kopya için yeriniz varsa, proc'unuzu çıktı dosyasına bir tarih damgası eklemek üzere değiştirebilirsiniz, ancak bir temizleme rutini gerekir.


Farkında olduğumdan değil. Yedekleme yerel olarak yapılır, sonra birkaç saat sonra rsync-ed.
Andy Davies

0

SQL Server 2005'in girişiyle, sysdatabases ve hatta sys.databases arasında imleç döngüsü değişti, bu yüzden güvenilir değildi - ve bu davranış değişikliği sp_foreachdb ile de görülebilir.

İmleç türünü değiştirmenin yardımcı olduğunu buldum (sanırım hızlı ilerliyordu), ama sonunda Ola Hallengren'in yedekleme ve bakım çözümü gibi çözümlere geçtim. Yedeklemeler gibi kritik olan çoğu şey gibi, bu potansiyel çözümlerle bile yedeklendiklerinden emin olmak için tüm veritabanlarını çapraz kontrol etmeniz gerekir - ve açık bir şekilde yaptınız!

İmleç türleri: http://msdn.microsoft.com/en-us/library/ms378405(v=SQL.90).aspx

Ola'nın bakım çözümü: http://ola.hallengren.com/


0

Özellikle büyük DB'leri yedeklerken aynı sorunu yaşadım.

@@fetch_statusGLOBAL değişkendir, bu nedenle sizinkinden başka bir imleç tarafından değiştirilebilir (0 olarak ayarlanmış). Aşağıdaki (sözde kod) yaparak çözdüm:

create a temp table with dbNames
select top 1 in a variable (use order by)
while variable is null
do your thing

set variable = null
delete top 1(use order by)
select top 1 in a variable (use order by)
loop

-1

Bu sorunu anlamaya çalıştım ve birçok kez kullanıcılar imleci bildirimi duyarsız yaparsanız o zaman çalışmaya başlar çözüm gönderdi gibi görünüyor. Bu yüzden test ettim ve evet sadece imleç beyanının statik olduğundan ve çalışmaya başladığından emin oluyor.

Başarısız olduğu gerçeği - Sunucu düzeyi imleç eşik ayarınızı kontrol edin - -1 olarak yapılandırılmışsa, imleç anahtarı kümesi verilerini okumaya çalışırken tüm imleçlerin başka bir deyişle eşzamanlı olarak doldurulduğu ve tümünün denendiği anlamına gelir. aynı anda okuyun. SQL sunucusuna basit sözcüklerle eşzamansız bir popülasyon yapmasını söyleyen bu değeri 0 olarak değiştirirsek, anahtar kümesi hala doldurulurken imleç kayıtları getirebilir ve sunucu düzeyinde bu değişikliği yaptıktan sonra hiçbir veritabanını asla kaçırmayacağınızı göreceksiniz. imleçleri.

Çözümler: İmleç Statik değerini belirtin veya Sunucu düzeyi ayarını "İmleç Eşiği" ni -1'den 0'a değiştirin.

Teşekkürler, Gaurav Mishra | Kıdemli DBA

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.