Forum: PC-Programmierung Brauche Hilfe in Batchdatei um MSSQL Server zu sichern


von batcherr (Gast)


Lesenswert?

Hey Leute,

Ich will die alle Datenbanken einen MSSQL Server in einzelne Dateien 
sichern.
Dafür habe ich mir folgende Batch file erstellt:
1
@echo off
2
cls
3
4
REM Set values as needed
5
set fpath= C:\BackupScript
6
set sqlservername= .\SQLEXPRESS
7
8
9
REM helpers
10
set DBList= %fpath%\DBList.txt
11
set bpath= %fpath%\BAK_temp
12
13
14
REM Build a list of databases to backup
15
IF EXIST %DBList% DEL /F /Q %DBList%
16
SqlCmd -E -S %sqlservername% -h-1 -W -Q "SET NoCount ON; SELECT Name FROM master.dbo.sysDatabases WHERE [Name] NOT IN ('master','model','msdb','tempdb')" > %DBList%
17
18
19
REM Backup each database, prepending the date to the filename
20
FOR /F "tokens=*" %%I IN (%DBList%) DO (
21
echo Backing up database: %%I to %bpath%\%%I.bak
22
SqlCmd -E -S %sqlservername% -Q "BACKUP DATABASE [%%I] TO Disk='%bpath%\%%I.bak'"
23
ECHO.)

Soweit so gut.

Die Datei C:\BackupScript\DBList.txt wird erstellt und enthält die 
richtigen Tabellennamen.

Die Sicherung funktioniert aber nicht, da z.Bsp. folgender Fehler 
ausgegeben wird:
1
Meldung '3201', Ebene '16', Status '1', Server 'HALELU\SQLEXPRESS', Zeile 1
2
'Das Sicherungsmedium 'c:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\Backup\  C:\BackupScript\BAK_temp\SQLEXPRESS_WUWUWU_24.bak' kann nicht geöffnet werden. Betriebssystemfehler 123(Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch.).'

Das heisst also, dass versucht wird in die Datei
1
'c:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\Backup\  C:\BackupScript\BAK_temp\SQLEXPRESS_WUWUWU_24.bak'
zu schreiben, statt in die Datei
1
'C:\BackupScript\BAK_temp\SQLEXPRESS_WUWUWU_24.bak'

AABER: Warum?
Sieht irgendwer den Fehler?
Sollte doch TO Disk='%bpath%\%%I.bak' lauten, oder?

von WIRO (Gast)


Lesenswert?

Mach in ALLEN set-Befehlen das Leerzeichen nach dem = raus!
Ergebnis?
Gruß
WIRO

von MaWin (Gast)


Lesenswert?

Den MsSql kann man so gar nicht sichern.

Anfängerfehler!

Für 500€ pauschal, richte ich dir ein Backup im Sql Server ein.

Schreib hier deine Email rein, oder melde dich endlich an!

von WIRO (Gast)


Lesenswert?

Ist das Problem gelöst oder welche Ausgabe erfolgt durch diese Zeile?:
  echo Backing up database: %%I to %bpath%\%%I.bak

von M. P. (matze7779)


Lesenswert?

Probier mal
1
SqlCmd -E -S %sqlservername% -Q "BACKUP DATABASE [%%I] TO DISK = N'%bpath%\%%I.bak'"

Das Verzeichnis muss aber auch existieren.

von batcherr (Gast)


Lesenswert?

WIRO schrieb:
> Mach in ALLEN set-Befehlen das Leerzeichen nach dem = raus!
> Ergebnis?
> Gruß
> WIRO

DAS war es

von Cartman (Gast)


Lesenswert?

Ein richtiges Backup ost das aber nicht.

Wenn die Datenbank aktiv ist, und Clients an den Daten drehen,
kann das Backup nahezu beliebig inkonsistent (aka korrupt) sein.

von c-hater (Gast)


Lesenswert?

Cartman schrieb:

> Ein richtiges Backup ost das aber nicht.

Doch, natürlich. Jedenfalls für alle Datenbanken, die korrekt benutzt 
werden, d.h.: einschließlich der eingebauten Transaktionssicherheit.

Nur bei den dümmlichen Datenbanken der agilen Entwickler, wo die 
Transaktionssicherheit erst auf Anwendungsebene erreicht wird (wenn 
überhaupt), könnte es ein Problem geben.

Das Backup der SQL-Server ist jedenfalls so gestrickt, dass nur 
committete Transaktionen gesichert werden. D.h.: auf der DB-Ebene ist 
das Backup garantiert konsistent.

von Cartman (Gast)


Lesenswert?

> dass nur committete Transaktionen gesichert werden

Das moechte ja wohl auch sein.

Aber:
Die Tabellen werden sequentiell gesichert.
Und wenn Tabelle A schon gesichert wurde, und jemand dreht
in seiner Applikation an Tabelle A und Tabelle Z,
dann ist das spaetere Backup von Z nicht mehr konsistent zu A.
Im Backup ist dann der Transaktionszaehler der Tabelle A
auf dem Wert N, und der von der Tabelle Z auf einem
vermutlich hoeheren Wert, der aber nicht N ist.

Moeglicherweise unterschaetze ich das Backup bzw. den (MS-)
Backupbefehl, aber um das obige Szenario konsistent
umzusetzen, lassen sich sonst die Hersteller von Backupsoftware
gut und teuer bezahlen. Das gibt es dann als sogenanntes
"Onlinebackup".

Die Situation ist vergleichbar mit der Situation bei Filesystemen.

von (prx) A. K. (prx)


Lesenswert?

Cartman schrieb:
> Die Tabellen werden sequentiell gesichert.

Normalerweise sind transaktionsorientierte Datenbanken, die mit ihren 
eigenen Backup-Mechanismen gesichert werden, so gebaut, dass der Restore 
trotz eines bei laufender Datenbank erfolgten Backups einen konsistenten 
Zustand wiederherstellen kann.

von (prx) A. K. (prx)


Lesenswert?

Cartman schrieb:
> Die Situation ist vergleichbar mit der Situation bei Filesystemen.

Und zwar mit Filesystemen, die über Snapshot-Mechnismen für sowohl 
Metadaten als auch Inhalte verfügen.

Das Stichwort für konsistente Sicherung von NTFS ist der Volume Shadow 
Copy Service. Bei Copy-On-Write Filesystemen wie WAFL, ZFS und btrfs ist 
das Transaktionsprinzip von Backups obendrein in deren grundlegender 
Arbeitsweise enthalten.

: Bearbeitet durch User
Beitrag #6944065 wurde von einem Moderator gelöscht.
von MaWin (Gast)


Lesenswert?

c-hater schrieb im Beitrag #6944065:
> Du hast keine Ahnung von Datenbanken, richtig?

Du hast keine Ahnung.
Ich habe DBs gwasi erfunden !

von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb im Beitrag #6944065:
> Dann wird entweder der Stand vor der Transaktion gesichert oder der
> danach, aber niemals der "mittendrin".

Man sollte man hier zwischen SQL-Transaktionen und dem Backup 
unterscheiden, der seinerseits eine Transaktion darstellt. Während ein 
Backup läuft können ja viele SQL-Transaktionen durchgeführt werden, die 
werden vom Backup nicht blockiert. Sonst wären Backups nicht parallel 
zum Normalbetrieb möglich.

Es läuft also darauf hinaus, dass die Datenbank während des Backups in 
einem Modus arbeitet, der nur Daten sichert, die bis zum Zeitpunkt des 
Beginns des Backups committed sind.

Beispiel für eine mögliche Arbeitsweise:

Es werden stets sämtliche Änderungen ausserhalb der DB-Container in 
Transaction-Logs protokolliert. Ist die DB nicht für Point-in-Time 
Recovery eingerichtet, werden die Inhalte dieser Logs mit COMMIT in die 
DB-Container nachgetragen und dann gelöscht. Ist die DB es aber (ist 
beim MS SQL Server wählbar), werden diese Logs frühestens gelöscht, wenn 
sie ebenfalls gesichert wurden.

Beim Point-in-Time Restore werden erst die DB-Container restored, danach 
werden die Transaktionen aus den gesicherten Logs bis zum gewünschten 
Zeitpunkt nachvollzogen.

Der ganze Trick beim Backup besteht nun darin, während eines laufenden 
Backups die Änderungen unbeschadet irgendwelcher COMMITs ausschliesslich 
in die Transaction-Logs zu schreiben, nicht aber in die DB-Container, 
und auch bei nicht auf Point-in-Time Recovery eingerichteter DB die Logs 
so lange nicht zu löschen, bis sie nach Ende des Backups in die 
DB-Container nachgetragen wurden.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

(prx) A. K. schrieb:

> Es werden stets sämtliche Änderungen ausserhalb der DB-Container in
> Transaction-Logs protokolliert. Ist die DB nicht für Point-in-Time
> Recovery eingerichtet, werden die Inhalte dieser Logs mit COMMIT in die
> DB-Container nachgetragen und dann gelöscht.

Nein. Das Backup friert das Löschen der Transaktionen für die Zeit 
seines Laufes ein, eben um während der gesamten Zeit seines Laufs den 
Stand zum Zeitpunkt des Starts des Backups rekonstruieren zu können. Das 
ist STANDARDVERHALTEN. Und es behindert den laufenden Betrieb in 
keinster Weise. Es erhöht aber natürlich ggf. temporär den Platzbedarf 
im Transaktions-Log.

Du verwechselst das mit Restore bei laufendem Betrieb. Dafür sind 
weitere Maßnahmen erforderlich. War hier aber nicht gefragt und ist hier 
auch nicht erforderlich. Es ging allein um das Backup.

: Wiederhergestellt durch Admin
von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
> Nein. Das Backup friert das Löschen der Transaktionen für die Zeit
> seines Laufes ein, eben um während der gesamten Zeit seines Laufs den
> Stand zum Zeitpunkt des Starts des Backups rekonstruieren zu können.

Genau das hatte ich mit anderen Worten vorhin geschrieben. ;-)

Ich hatte lediglich zusätzlich aufgeführt, dass beim beschriebenen 
Verfahren der generelle Backup-Mechnismus sich eng mit dem Verfahren für 
SQL-Transaktionen verzahnt, und sich auch die Fähigkeit zu Point-in-Time 
Recovery direkt daraus ableitet.

von c-hater (Gast)


Lesenswert?

(prx) A. K. schrieb:

> Genau das hatte ich mit anderen Worten vorhin geschrieben. ;-)

Tatsächlich?

>> Ist die DB nicht für Point-in-Time
>> Recovery eingerichtet, werden die Inhalte dieser Logs mit COMMIT in die
>> DB-Container nachgetragen und dann gelöscht.

Das liest sich nicht wirklich so...

: Wiederhergestellt durch Admin
von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
>>> Ist die DB nicht für Point-in-Time
>>> Recovery eingerichtet, werden die Inhalte dieser Logs mit COMMIT in die
>>> DB-Container nachgetragen und dann gelöscht.
>
> Das liest sich nicht wirklich so...

Das war der Absatz über den Normalbetrieb.

(prx) A. K. schrieb:
> DB die Logs
> so lange nicht zu löschen, bis sie nach Ende des Backups in die
> DB-Container nachgetragen wurden.

Und das war der Absatz zum Backup-Modus. Zugegeben, das war der 6. 
Absatz, und bis dahin muss man erst einmal durchhalten. ;-)

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.