Warten Sie! Warten Sie! Es ist wirklich kein weiterer Artikel ĂŒber SQL Server Backup-Typen. Ich werde nicht einmal auf die Unterschiede der Wiederherstellungsmodelle eingehen oder wie man mit einem gewachsenen âLogâ umgeht.
Möglicherweise (nur möglicherweise) können Sie nach dem Lesen dieses Beitrags so vorgehen, dass das Backup, das Sie mit den Standardwerkzeugen erstellen, morgen Nacht etwa 1,5-mal schneller ausgefĂŒhrt wird. Und das nur, weil Sie ein wenig mehr BACKUP DATABASE-Parameter verwenden.
Wenn der Inhalt des Beitrags fĂŒr Sie offensichtlich war â Entschuldigung. Ich habe alles gelesen, was Google zur Phrase âhabr sql server backupâ finden konnte, und in keinem Artikel fand ich einen Hinweis darauf, dass man das Backup mit Parametern irgendwie beeinflussen kann.
Ich möchte sofort auf den Kommentar von Alexander Gladtschenko hinweisen ():
Ăndern Sie niemals die Parameter BUFFERCOUNT, BLOCKSIZE, MAXTRANSFERSIZE im Produktivbetrieb. Sie sind nur fĂŒr das Schreiben solcher Artikel gedacht. In der Praxis werden Sie damit Probleme mit dem Speicher bekommen.
Es wĂ€re natĂŒrlich groĂartig, der KlĂŒgste zu sein und exklusiven Inhalt zu prĂ€sentieren, aber das ist leider nicht der Fall. Es gibt sowohl englisch- als auch russischsprachige Artikel/BeitrĂ€ge (ich verwirre mich immer, wie ich sie richtig nennen soll), die sich mit diesem Thema beschĂ€ftigen. Hier ist ein Teil dessen, was ich gefunden habe: , , .
Also werde ich zu Beginn eine etwas gekĂŒrzte Syntax fĂŒr BACKUP aus (ĂŒbrigens, ich habe da oben ĂŒber BACKUP DATABASE geschrieben, aber das gilt auch fĂŒr das Backup von Transaktionsprotokollen und fĂŒr inkrementelle Backups, aber vermutlich mit weniger offensichtlichem Effekt):
BACKUP DATABASE { database_name | @database_name_var }
TO [ ,...n ]
[ WITH {
| [ ,...n ] } ]
[;]
[ ,...n ]::=
--Media Set Options
| BLOCKSIZE = { blocksize | @blocksize_variable }
--Data Transfer Options
BUFFERCOUNT = { buffercount | @buffercount_variable }
| MAXTRANSFERSIZE = { maxtransfersize | @maxtransfersize_variable }â bedeutet, dass dort etwas war, ich es aber entfernt habe, weil es momentan nicht zum Thema gehört.
Wie erstellen Sie normalerweise ein Backup? Wie âlehrenâ Milliarden von Artikeln, ein Backup zu erstellen? Wenn ich einmal ein Backup einer nicht sehr groĂen Datenbank erstellen muss, wĂŒrde ich automatisch etwas in dieser Art schreiben:
BACKUP DATABASE smth
TO DISK = 'D:Backupsmth.bak'
WITH STATS = 10, CHECKSUM, COMPRESSION, COPY_ONLY;
-- okay, CHECKSUM habe ich nur geschrieben, um intelligenter zu wirkenUnd hier sind wahrscheinlich 75-90 % aller Parameter aufgezĂ€hlt, die normalerweise in Artikel ĂŒber Backups erwĂ€hnt werden. Da gibt es INIT, SKIP und so weiter. Waren Sie schon in MSDN? Haben Sie gesehen, dass es dort Optionen fĂŒr anderthalb Bildschirme gibt? Ich habe das auch gesehenâŠ
Sie haben wahrscheinlich schon verstanden, dass es im Folgenden um die drei Parameter geht, die im ersten Codeblock geblieben sind â BLOCKSIZE, BUFFERCOUNT und MAXTRANSFERSIZE. Hier sind deren Beschreibungen aus MSDN:
BLOCKSIZE = { blocksize | @ blocksize_variable } gibt die GröĂe des physischen Blocks in Bytes an. UnterstĂŒtzte GröĂen sind 512, 1024, 2048, 4096, 8192, 16 384, 32 768 und 65 536 Bytes (64 KB). Der Standardwert betrĂ€gt 65 536 fĂŒr BandgerĂ€te und 512 fĂŒr andere GerĂ€te. In der Regel ist es nicht erforderlich, diesen Parameter zu setzen, da der Befehl BACKUP automatisch die BlockgröĂe wĂ€hlt, die zum GerĂ€t passt. Eine explizite Einstellung der BlockgröĂe ĂŒberschreibt die automatische Auswahl der BlockgröĂe.
BUFFERCOUNT = { buffercount | @ buffercount_variable } bestimmt die Gesamtzahl der Eingabe-/Ausgabepuffer, die fĂŒr die Sicherungsoperation verwendet werden. Es kann jeder positive ganzzahlige Wert angegeben werden, allerdings kann eine groĂe Anzahl von Puffern einen Speichermangel aufgrund des ĂŒbermĂ€Ăigen virtuellen Adressraums im Sqlservr.exe-Prozess verursachen.
Das gesamte von den Puffern genutzte Volumen wird durch folgende Formel bestimmt:Â
BUFFERCOUNT * MAXTRANSFERSIZE.
MAXTRANSFERSIZE = { maxtransfersize | @ maxtransfersize_variable } gibt das maximale Datenpaketvolumen in Bytes an, das fĂŒr den Datenaustausch zwischen SQL Server und dem MediengerĂ€t des Sicherungssatzes verwendet wird. UnterstĂŒtzte Werte sind Vielfache von 65 536 Bytes (64 KB) bis zu 4 194 304 Bytes (4 MB).
Ich schwöre, ich habe das vorher schon gelesen, aber es ist mir nie in den Sinn gekommen, welchen Einfluss sie auf die Leistung haben können. DarĂŒber hinaus scheint es notwendig zu sein, eine Art "Coming-out" zu machen und zuzugeben, dass ich auch jetzt nicht ganz verstehe, was genau sie bewirken. Vielleicht sollte ich mehr ĂŒber die gepufferte Ein- und Ausgabe sowie die Arbeit mit Festplatten lesen. Irgendwann werde ich das tun, aber im Moment kann ich einfach ein Skript schreiben, das ĂŒberprĂŒft, wie sich diese Werte auf die Geschwindigkeit auswirken, mit der das Backup erstellt wird.
Ich habe eine kleine Datenbank erstellt, die etwa 10 GB groĂ ist, sie auf eine SSD gelegt und das Verzeichnis fĂŒr die Backups auf eine HDD gelegt.
Ich erstelle eine temporĂ€re Tabelle zur Speicherung der Ergebnisse (fĂŒr mich ist sie nicht temporĂ€r, damit ich die Ergebnisse genauer untersuchen kann, aber das mĂŒssen Sie selbst entscheiden):
DROP TABLE IF EXISTS ##bt_results;
CREATE TABLE ##bt_results (
id int IDENTITY (1, 1) PRIMARY KEY,
start_date datetime NOT NULL,
finish_date datetime NOT NULL,
backup_size bigint NOT NULL,
compressed_size bigint,
block_size int,
buffer_count int,
transfer_size int
);Das Prinzip des Skripts ist einfach â verschachtelte Schleifen, von denen jede den Wert eines Parameters Ă€ndert, ich ĂŒbergebe diese Parameter in den BACKUP-Befehl, speichere den letzten Datensatz mit der Historie aus msdb.dbo.backupset, lösche die Sicherungsdatei und mache mit der nĂ€chsten Iteration weiter. Da die Daten zur AusfĂŒhrung des Backups aus backupset stammen, verliert man etwas an Genauigkeit (es fehlen Bruchteile von Sekunden), aber das werden wir ĂŒberstehen.
Zuerst mĂŒssen Sie die Verwendung von xp_cmdshell erlauben, um Backups zu löschen (vergessen Sie nicht, es spĂ€ter abzuschalten, falls Sie es nicht benötigen):
EXEC sp_configure 'show advanced options', 1;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
EXEC sp_configure 'show advanced options', 0;
GONun, und tatsÀchlich:
DECLARE @tmplt AS nvarchar(max) = N'
BACKUP DATABASE [bt]
TO DISK = ''D:SQLServerbackupbt.bak''
WITH
COMPRESSION,
BLOCKSIZE = {bs},
BUFFERCOUNT = {bc},
MAXTRANSFERSIZE = {ts}';
DECLARE @sql AS nvarchar(max);
/* BLOCKSIZE values */
DECLARE @bs int = 4096,
@max_bs int = 65536;
\t/* BUFFERCOUNT values */
DECLARE @bc int = 7,
@min_bc int = 7,
@max_bc int = 800;
\t/* MAXTRANSFERSIZE values */
DECLARE @ts int = 524288, --512KB, default = 1024KB
@min_ts int = 524288,
@max_ts int = 4194304; --4MB
SELECT TOP 1
@bs = COALESCE (block_size, 4096),
@bc = COALESCE (buffer_count, 7),
@ts = COALESCE (transfer_size, 524288)
FROM ##bt_results
ORDER BY id DESC;
WHILE (@bs <= @max_bs)
BEGIN
WHILE (@bc <= @max_bc)
BEGIN
WHILE (@ts <= @max_ts)
BEGIN
SET @sql = REPLACE (REPLACE (REPLACE(@tmplt, N'{bs}', CAST(@bs AS nvarchar(50))), N'{bc}', CAST (@bc AS nvarchar(50))), N'{ts}', CAST (@ts AS nvarchar(50)));
EXEC (@sql);
INSERT INTO ##bt_results (start_date, finish_date, backup_size, compressed_size, block_size, buffer_count, transfer_size)
SELECT TOP 1 backup_start_date, backup_finish_date, backup_size, compressed_backup_size, @bs, @bc, @ts
FROM msdb.dbo.backupset
ORDER BY backup_set_id DESC;
EXEC xp_cmdshell 'del "D:SQLServerbackupbt.bak"', no_output;
SET @ts += @ts;
END
SET @bc += @bc;
SET @ts = @min_ts;
WAITFOR DELAY '00:00:05';
END
SET @bs += @bs;
SET @bc = @min_bc;
SET @ts = @min_ts;
ENDWenn Sie eine ErklĂ€rung dazu benötigen, was hier passiert â schreiben Sie in die Kommentare oder per privater Nachricht. Bis jetzt werde ich nur ĂŒber die Parameter sprechen, die ich in BACKUP DATABASE ĂŒbergebe.
FĂŒr BLOCKSIZE haben wir eine âgeschlosseneâ Liste von Werten, und ich habe kein Backup mit BLOCKSIZE < 4KB durchgefĂŒhrt. MAXTRANSFERSIZE kann jede Zahl, die ein Vielfaches von 64KB ist, von 64KB bis 4MB sein. StandardmĂ€Ăig sind es auf meinem System 1024KB, ich habe 512 â 1024 â 2048 â 4096 gewĂ€hlt.
Schwieriger war es mit BUFFERCOUNT â er kann eine beliebige positive Zahl sein, aber im Link steht, Dort steht auch, wie man Informationen darĂŒber erhĂ€lt, mit welchem BUFFERCOUNT tatsĂ€chlich ein Backup erstellt wird â bei mir sind das 7. Es hatte keinen Sinn, ihn zu verringern, und die obere Grenze wurde empirisch gefunden â bei BUFFERCOUNT = 896 und MAXTRANSFERSIZE = 4194304 schlug das Backup fehl mit einer Fehlermeldung (die im obigen Link beschrieben ist):
Msg 3013, Level 16, State 1, Line 7 BACKUP DATABASE wird abnormal beendet.
Msg 701, Level 17, State 123, Line 7 Es gibt nicht genĂŒgend Systemspeicher im Ressourcenpool âdefaultâ, um diese Abfrage auszufĂŒhren.
Zum Vergleich zeige ich zunĂ€chst die Ergebnisse der DurchfĂŒhrung eines Backups ohne Angabe von Parametern ĂŒberhaupt:
BACKUP DATABASE [bt]
TO DISK = 'D:SQLServerbackupbt.bak'
WITH COMPRESSION;Nun, ein Backup ist ein Backup:
Es wurden 1070072 Seiten fĂŒr die Datenbank âbtâ, Datei âbtâ in Datei 1 verarbeitet.
Es wurden 2 Seiten fĂŒr die Datenbank âbtâ, Datei âbt_logâ in Datei 1 verarbeitet.
BACKUP DATABASE hat erfolgreich 1070074 Seiten in 53,171 Sekunden verarbeitet (157,227 MB/sec).
Das Skript, das die Parameter testet, hat ein paar Stunden gebraucht, alle Messungen sind in Und hier ist eine Auswahl der Ergebnisse, die die drei besten AusfĂŒhrungszeiten haben (ich habe versucht, ein schönes Diagramm zu erstellen, aber im Beitrag muss ich mit einer Tabelle auskommen, und in den Kommentaren hinzugefĂŒgt ).
SELECT TOP 7 WITH TIES
compressed_size,
block_size,
buffer_count,
transfer_size,
DATEDIFF(SECOND, start_date, finish_date) AS backup_time_sec
FROM ##bt_results
ORDER BY backup_time_sec ASC;
Achtung, gleich eine sehr wichtige Anmerkung von aus :
man kann mit Sicherheit sagen, dass die Beziehung zwischen den Parametern und der Geschwindigkeit des Backups in diesen Grenzen zufĂ€llig ist, es gibt keine RegelmĂ€Ăigkeit. Aber die Abweichung von den Standardparametern hat offensichtlich die Ergebnisse positiv beeinflusst.
Das heiĂt, allein durch die Verwaltung der Standardparameter BACKUP wurde die Zeit fĂŒr die Erstellung des Backups um das Doppelte verkĂŒrzt: 26 Sekunden gegenĂŒber 53 zu Beginn. Das ist doch nicht schlecht, oder? Aber wir mĂŒssen sehen, wie es mit der Wiederherstellung aussieht. Was ist, wenn es jetzt viermal lĂ€nger dauert, um wiederherzustellen?
ZunÀchst messen wir, wie lange die Wiederherstellung des Backups mit den Standardeinstellungen dauert:
RESTORE DATABASE [bt]
FROM DISK = 'D:SQLServerbackupbt.bak'
WITH REPLACE, RECOVERY;Nun, das wisst ihr selbst, wie es dort ist, replace oder nicht replace, recovery oder nicht recovery. Und bei mir wird es so ausgefĂŒhrt:
Es wurden 1070072 Seiten fĂŒr die Datenbank âbtâ, Datei âbtâ in Datei 1 verarbeitet.
Es wurden 2 Seiten fĂŒr die Datenbank âbtâ, Datei âbt_logâ in Datei 1 verarbeitet.
DIE WIEDERHERSTELLUNG DER DATABANK wurde erfolgreich abgeschlossen: 1070074 Seiten in 40,752 Sekunden verarbeitet (205,141 MB/Sek).
Jetzt werde ich versuchen, die Backups wiederherzustellen, die mit geÀnderten BLOCKSIZE, BUFFERCOUNT und MAXTRANSFERSIZE erstellt wurden.
BLOCKSIZE = 16384, BUFFERCOUNT = 224, MAXTRANSFERSIZE = 4194304DIE WIEDERHERSTELLUNG DER DATABANK wurde erfolgreich abgeschlossen: 1070074 Seiten in 32,283 Sekunden verarbeitet (258,958 MB/Sek).
BLOCKSIZE = 4096, BUFFERCOUNT = 448, MAXTRANSFERSIZE = 4194304DIE WIEDERHERSTELLUNG DER DATABANK wurde erfolgreich abgeschlossen: 1070074 Seiten in 32,682 Sekunden verarbeitet (255,796 MB/Sek).
BLOCKSIZE = 16384, BUFFERCOUNT = 448, MAXTRANSFERSIZE = 2097152DIE WIEDERHERSTELLUNG DER DATABANK wurde erfolgreich abgeschlossen: 1070074 Seiten in 32,091 Sekunden verarbeitet (260,507 MB/Sek).
BLOCKSIZE = 4096, BUFFERCOUNT = 56, MAXTRANSFERSIZE = 4194304DIE WIEDERHERSTELLUNG DER DATABANK wurde erfolgreich abgeschlossen: 1070074 Seiten in 32,401 Sekunden verarbeitet (258,015 MB/Sek).
Der Befehl RESTORE DATABASE verĂ€ndert sich bei der Wiederherstellung nicht; diese Parameter werden nicht angegeben, SQL Server bestimmt sie automatisch anhand des Backups. Und es ist offensichtlich, dass sogar bei der Wiederherstellung Zeitersparnis möglich ist â praktisch 20 % schneller (Ehrlich gesagt habe ich nicht viel Zeit mit der Wiederherstellung verbracht, ich habe nur ein paar der "schnellsten" Backups getestet und festgestellt, dass es keine Verschlechterung gibt.).
Nur zur Sicherheit weise ich darauf hin â hier werden keine optimalen Parameter fĂŒr alle beschrieben. Optimale Werte fĂŒr sich selbst können Sie nur durch Tests erhalten. Ich habe solche Ergebnisse erzielt, Sie werden andere erhalten. Aber Sie sehen, dass Sie Ihre Backups âoptimierenâ können und sie tatsĂ€chlich schneller erstellt und wiederhergestellt werden können.
Ich empfehle Ihnen dringend, die Dokumentation vollstĂ€ndig zu lesen, denn fĂŒr Ihr System können besondere Anforderungen gelten.
Da ich gerade ĂŒber Backups schreibe, möchte ich sofort noch eine andere âOptimierungâ erwĂ€hnen, die hĂ€ufiger vorkommt als die âFeinabstimmungâ von Parametern (die, wie ich verstehe, von mindestens einem Teil der Backup-Utilities verwendet wird, möglicherweise zusammen mit den zuvor beschriebenen Parametern), aber auf HabrĂ© wurde sie bisher nicht behandelt.
Wenn man sich die zweite Zeile in der Dokumentation ansieht, direkt unter BACKUP DATABASE, sieht man:
TO [ ,...n ]Was denken Sie, passiert, wenn man mehrere backup_device angibt? Die Syntax erlaubt es. Und es wird eine sehr interessante Sache passieren â das Backup wird einfach auf mehrere GerĂ€te verteilt. Jedes âGerĂ€tâ wird fĂŒr sich genommen nutzlos sein, haben Sie eines verloren, haben Sie das gesamte Backup verloren. Aber wie wird sich diese Verteilung auf die Geschwindigkeit der Datensicherung auswirken?
Versuchen wir, ein Backup auf zwei âGerĂ€teâ zu machen, die nebeneinander in demselben Ordner liegen:
BACKUP DATABASE [bt]
TO
DISK = 'D:SQLServerbackupbt1.bak',
DISK = 'D:SQLServerbackupbt2.bak'
WITH COMPRESSION;Oh mein Gott, was geschieht hier?
Es wurden 1070072 Seiten fĂŒr die Datenbank âbtâ, Datei âbtâ in Datei 1 verarbeitet.
Verarbeitete 2 Seiten fĂŒr die Datenbank âbtâ, Datei âbtprotokolliertâ in Datei 1.
Datenbanksicherung erfolgreich mit 1070074 Seiten in 40,092 Sekunden (208,519 MB/Sek.) verarbeitet.
Wurde die Sicherung einfach so um 25 % schneller? Was passiert, wenn man noch ein paar GerĂ€te hinzufĂŒgt?
BACKUP DATABASE [bt]
TO
DISK = 'D:SQLServerbackupbt1.bak',
DISK = 'D:SQLServerbackupbt2.bak',
DISK = 'D:SQLServerbackupbt3.bak',
DISK = 'D:SQLServerbackupbt4.bak'
WITH COMPRESSION;Datenbanksicherung erfolgreich mit 1070074 Seiten in 34,234 Sekunden (244,200 MB/Sek.) verarbeitet.
Insgesamt betrĂ€gt die Zeitersparnis etwa 35 % beim Sichern, nur weil die Sicherung gleichzeitig in 4 Dateien auf derselben Festplatte geschrieben wird. Ich habe mehr getestet â auf meinem Laptop gab es keine Verbesserung, optimal sind 4 GerĂ€te. FĂŒr euch â ich weiĂ nicht, das muss man testen. Ăbrigens, wenn diese GerĂ€te wirklich verschiedene Festplatten sind, dann Herzlichen GlĂŒckwunsch, die Einsparung sollte noch erheblich sein.
Jetzt reden wir darĂŒber, wie man diesen GlĂŒcksfall wiederherstellt. DafĂŒr muss das Wiederherstellungskommando geĂ€ndert und alle GerĂ€te aufgelistet werden:
RESTORE DATABASE [bt]
FROM
DISK = 'D:SQLServerbackupbt1.bak',
DISK = 'D:SQLServerbackupbt2.bak',
DISK = 'D:SQLServerbackupbt3.bak',
DISK = 'D:SQLServerbackupbt4.bak'
WITH REPLACE, RECOVERY;Datenbankwiederherstellung erfolgreich mit 1070074 Seiten in 38,027 Sekunden (219,842 MB/Sek.) verarbeitet.
Ein bisschen schneller, aber nah dran, nicht signifikant. Insgesamt wird die Sicherung schneller durchgefĂŒhrt, und die Wiederherstellung erfolgt ebenso â Erfolg? Meiner Meinung nach ist das ein durchaus beachtlicher Erfolg. Das ist wichtig, daher wiederhole ich â wenn ihr auch nur eine dieser Dateien verliert â verliert ihr die gesamte Sicherung..
Wenn man die Informationen ĂŒber die Sicherung im Protokoll, die mittels Trace Flag 3213 und 3605 ausgegeben werden, betrachtet, kann man feststellen, dass bei der Sicherung auf mehrere GerĂ€te zumindest die Anzahl von BUFFERCOUNT steigt. Wahrscheinlich kann man versuchen, die optimaleren Parameter auch fĂŒr BUFFERCOUNT, BLOCKSIZE, MAXTRANSFERSIZE zu finden, aber ich habe es beim ersten Mal nicht geschafft, und erneut solche Tests mit unterschiedlichen Dateimengen wollte ich mir nicht antun. Und die Festplatten sind auch zu schade. Wenn ihr so ein Test bei euch organisieren möchtet, ist es nicht schwer, das Skript anzupassen.
Am Ende sprechen wir ĂŒber den Preis. Wenn die Sicherung parallel zum Benutzereinsatz erfolgt â muss man mit Ă€uĂerster Sorgfalt testen, da eine schnellere Sicherung die Festplatten stĂ€rker belastet und die CPU-Last steigt (man muss das alles auch in Echtzeit komprimieren), wodurch die allgemeine SystemreaktionsfĂ€higkeit abnimmt.
Witze hin oder her, ich verstehe durchaus, dass ich keine EnthĂŒllungen gemacht habe. Das, was oben geschrieben steht, ist einfach eine Demonstration, wie man optimale Parameter fĂŒr die Erstellung von Backups auswĂ€hlen kann.
Denken Sie daran, dass alles, was Sie tun, auf Ihr eigenes Risiko geschieht. ĂberprĂŒfen Sie Ihre Sicherungskopien und vergessen Sie nicht DBCC CHECKDB.
Quelle: habr.com
