Ich habe einen Job in SQL 2008, der einen gespeicherten Prozess ausführt, um alle Datenbanken zu sichern. Dies wird täglich über den SQL Server Agent-Job ausgeführt.
Es wird jeden Tag mit Erfolg beendet, aber an manchen Tagen wird es erst nach dem Sichern einiger Datenbanken mit Erfolg beendet. Es kann jedes Mal eine andere Anzahl von Datenbanken sein. An den meisten Tagen werden alle Datenbanken erfolgreich gesichert, manchmal jedoch 2 erfolgreich, manchmal 5 usw.
Ich sehe keine Fehler im Jobverlauf, in der Ereignisanzeige oder im SQL Server-Protokoll.
Sicherungen finden auf einer lokalen Festplatte statt, obwohl der Ordner eine "Verbindung" zu einem Ordner auf einem erweiterbaren Speichervolume ist.
Das Betriebssystem ist Windows 2003 64-Bit, auf dem SQL Server 2008 Web Edition 64-Bit als virtuelle Maschine ausgeführt wird, die auf dem Vmware ESXi 5-Host ausgeführt wird.
Gespeicherte Prozedur:
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
Irgendwelche Vorschläge bitte?
quelle
Suchen Sie nach dem Befehl "backup" nach Fehlern und senden Sie Ihre eigene E-Mail auf festgestellte Fehler.
Dies gibt Ihnen einen Ausgangspunkt, um zu sehen, was los ist, und garantiert Sie auf Probleme aufmerksam zu machen, bis Sie das Jobproblem gelöst haben.
quelle
Geben Sie eine Bestellung von auf den Cursor. Ich habe gesehen, dass Cursor auf sys.databases "Probleme" haben, wenn Sie SQL erlauben, die Reihenfolge auszuwählen, in der die Daten zurückgegeben werden. Die Bestellung nach Namen sollte ausreichen.
quelle
Wird die Sicherung gleichzeitig mit der Sicherung auf Band oder einem anderen Prozess ausgeführt, der die Sicherungsdateien kopiert oder darauf zugreift? Wenn ja, würde ich wetten, dass die Datei nicht überschrieben werden kann, weil sie verwendet wird. Wenn Sie Platz für mehrere Sicherungskopien haben, können Sie Ihren Prozess ändern, um der Ausgabedatei einen Datumsstempel hinzuzufügen. Dann benötigen Sie jedoch eine Bereinigungsroutine.
quelle
Mit der Einführung von SQL Server 2005 schien sich die Cursorschleife durch sysdatabases und sogar sys.databases zu ändern, sodass sie nicht zuverlässig war - und diese Verhaltensänderung konnte auch bei sp_foreachdb beobachtet werden.
Ich fand es hilfreich, den Cursortyp zu ändern (ich glaube, es war ein schneller Vorlauf), aber letztendlich wechselte ich zu Lösungen wie der Backup- und Wartungslösung von Ola Hallengren. Wie bei den meisten wichtigen Dingen wie Backups müssen Sie immer noch alle Datenbanken überprüfen, um sicherzustellen, dass sie auch mit diesen potenziellen Lösungen gesichert werden - und Sie haben es offensichtlich so gut gemacht!
Cursortypen: http://msdn.microsoft.com/en-us/library/ms378405(v=SQL.90).aspx
Olas Wartungslösung: http://ola.hallengren.com/
quelle
Ich hatte das gleiche Problem, insbesondere beim Sichern großer DBs.
@@fetch_status
ist eine GLOBAL-Variable, daher kann sie von einem anderen Cursor als Ihrem geändert (auf 0 gesetzt) werden. Ich habe es folgendermaßen gelöst (im Pseudocode):quelle
Ich habe versucht, dieses Problem herauszufinden, und es scheint, dass Benutzer häufig die Lösung veröffentlicht haben, dass die Cursor-Deklaration funktioniert, wenn Sie sie unempfindlich machen. Also habe ich es getestet und ja, es stellt nur sicher, dass die Cursor-Deklaration statisch ist und es funktioniert.
Die Tatsache, für die dies fehlschlägt, ist: - Überprüfen Sie die Cursor-Schwellenwerteinstellung auf Serverebene. Wenn sie als -1 konfiguriert ist, bedeutet dies, dass alle Cursor synchron gefüllt werden, mit anderen Worten, während versucht wird, die Cursortasten-Set-Daten zu lesen. Dies ist synchron und alles wird versucht gleichzeitig lesen. Wenn wir diesen Wert auf 0 ändern, der SQL Server anweist, eine asynchrone Auffüllung in einfachen Worten durchzuführen, kann der Cursor die Datensätze abrufen, während der Schlüsselsatz noch gefüllt ist, und Sie werden sehen, dass Sie nach dieser Änderung auf Serverebene niemals eine Datenbank verpassen werden, die verwendet wird Cursor.
Lösungen: Deklarieren Sie entweder Cursor statisch oder ändern Sie die Serverebeneneinstellung "Cursor Threshold" von -1 auf 0.
Danke, Gaurav Mishra | Senior DBA
quelle