MS SQL Server: BACKUP steroididel

Oodake! Oodake! TĂ”eliselt, see ei ole ĐŸŃ‡Đ”Ń€Đ”ĐŽnĂœ artikli SQL Serveri varundamise tĂŒĂŒpide kohta. Ma ei kavatse isegi rÀÀkida taastamismudelite erinevustest ja sellest, kuidas toime tulla „logi” kasvuga.

VÔib-olla (ainult vÔib-olla), pÀrast selle postituse lugemist, suudate seadistada, et varundamine, mis toimub teie tavadega, toimuks homme öösel umbes 1,5 korda kiiremini. Ja ainult selle tÔttu, et kasutate veidi rohkem BACKUP DATABASE parameetreid.

Kui postituse sisu oli teie jaoks ilmne — vabandust. Lugesin lĂ€bi kĂ”ik, mis Google'is leidus fraasiga „habr sql server varundamine”, ja ĂŒhegi artikli juures ei leidnud mainimist, et varundamise ajal saaks millegagi parameetrite abil mĂ”jutada.

TÔmban kohe teie tÀhelepanu Aleksandr Gladƥenko kommentaarile (@mssqlhelp):

Ärge kunagi muutke parameetreid BUFFERCOUNT, BLOCKSIZE, MAXTRANSFERSIZE tootmisĂŒksustes. Need on loodud ainult selliste artiklite kirjutamiseks. Praktikas saate mĂ€luprobleeme.

Oks seonduda selle kĂ”ige targemana ja jagada eksklusiivset sisu oleks muidugi Ă€ge, aga kahjuks ei ole see nii. On olemas nii ingliskeelseid kui venekeelseid artikleid/postitusi (ma alati segaduses, kuidas neid Ă”igesti nimetada), mis on sellele teemale pĂŒhendatud. Siin on osa neist, mis mulle ette jĂ€id: ĂŒks, kaks, kolm (sql.ru-s).

Nii et alustuseks jagan paar lĂŒhendatud BACKUP sĂŒntaksit MSDN (muide, seal ĂŒleval rÀÀkisin BACKUP DATABASE-st, kuid kĂ”ik see kehtib ka tehingu logi ja erineva varundamise kohta, kuid tĂ”enĂ€oliselt vĂ€hem selgete tulemustega):

BACKUP DATABASE { database_name | @database_name_var }
  TO  [ ,...n ]
  
  [ WITH { 
           |  [ ,...n ] } ]
[;]

 [ ,...n ]::=

--Meedia komplekti valikud
 
 | BLOCKSIZE = { blocksize | @blocksize_variable }

--Andmete edastamise valikud
   BUFFERCOUNT = { buffercount | @buffercount_variable }
 | MAXTRANSFERSIZE = { maxtransfersize | @maxtransfersize_variable }

— tĂ€hendab, et seal oli midagi, kuid ma eemaldasin selle, kuna see ei ole hetkel teemasse.

Kuidas te tavaliselt varundate? Kuidas „Ôpetatakse” varundama tohutute artiklites? Üldiselt, kui peab ĂŒksainus kord varundama mĂ”nest mitte vĂ€ga suurest andmebaasist, kirjutaksin automaatselt midagi sellist:

BACKUP DATABASE smth
TO DISK = 'D:Backupsmt.bak'
WITH STATS = 10, CHECKSUM, COMPRESSION, COPY_ONLY;
--nojah, CHECKSUM-i mainisin ainult, et nÀida targem

Ja, ja, siin on loetletud ilmselt 75-90% kÔigist parameetritest, mida tavaliselt mainitakse varundamise artiklites. Seal on INIT, SKIP jne. Kas te olete MSDN-is kÀinud? Kas nÀgite, et seal on poolteist ekraani valikuid? Mina olen ka nÀinud


Nagu arvatavasti juba mĂ”istsite, rÀÀgime nĂŒĂŒd kolmest parameetrist, mis jĂ€id esimesse koodiblokki — BLOCKSIZE, BUFFERCOUNT ja MAXTRANSFERSIZE. Siin on nende kirjeldused MSDN-ist:

BLOCKSIZE = { blocksize | @ blocksize_variable } mÀÀrab fĂŒĂŒsilise ploki suuruse baitides. Toetatakse suurusi 512, 1024, 2048, 4096, 8192, 16384, 32768 ja 65536 baiti (64 KB). Vaikimisi vÀÀrtus on 65536 lindiseadmete jaoks ja 512 teiste seadmete jaoks. Selle parameetri seadmine ei ole tavaliselt vajalik, kuna BACKUP kĂ€sk valib automaatselt seadmele sobiva ploki suuruse. Ploki suuruse selge mÀÀramine ĂŒletab automaatse ploki suuruse valiku.

BUFFERCOUNT = { buffercount | @ buffercount_variable } mÀÀrab kokkuvÔttes sisendi-vÀljundi puhverde arvu, mida varundamise operatsioon kasutab. Saate mÀÀrata mis tahes positiivse tÀisarvu, kuid suur hulk puhreid vÔib pÔhjustada mÀlu nappuse vea, kuna Sqlservr.exe protsessis on liiga suur virtuaalne aadressiruum.

Puhvrite poolt kasutatava ruumi kogus mÀÀratakse jÀrgmise valemi abil: BUFFERCOUNT * MAXTRANSFERSIZE.

MAXTRANSFERSIZE = { maxtransfersize | @ maxtransfersize_variable } mÀÀrab kÔige suurema andmepaketi mahu baitides andmete vahetamiseks SQL Serveri ja varundusseadmestiku vahel. Toetatakse vÀÀrtusi, mis on 65 536 baitide (64 KB) kordajad, kuni 4 194 304 baitideni (4 MB).

Ma vandun — ma olen seda varem lugenud, aga mulle ei tulnud pĂ€he, millist mĂ”ju need jĂ”udlusele avaldada vĂ”ivad. Veelgi enam, tundub, et pean tegema teatud «tulemuslikkuse avalduse» ja tunnistama, et isegi praegu ei saa ma tĂ€pselt aru, mida nad teevad. Ilmselt peaksin rohkem lugema puhverdatud sisendi-vĂ€ljundi ja kĂ”vaketta töö kohta. Kord ma teen seda, aga praegu vĂ”in lihtsalt kirjutada skripti, mis kontrollib, kuidas need vÀÀrtused mĂ”jutavad varundamise kiirus.

Tegin vÀikese andmebaasi, mille suurus on umbes 10 GB, panin selle SSD-le ja varunduse jaoks mÔeldud katalooge HDD-le.

Loon ajutine tabel tulemuste salvestamiseks (mul ei ole see ajutine, et saaksin tulemusi pÔhjalikumalt uurida, aga eks te otsustage ise):

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
);

Skripti tööpĂ”himĂ”te on lihtne — pesastavad tsĂŒklid, millest igaĂŒks muudab ĂŒhe parameetri vÀÀrtust, edastan need parameetrid BACKUP kĂ€sule, salvestan viimase sissekande ajaloost msdb.dbo.backupset, kustutan varundusfaili ja jĂ€rgneb jĂ€rgmine iteratsioon. Kuna varunduse teostamise andmed pĂ€rinevad backupset'ist, kaotatakse tĂ€psus veidi (seal pole sekundite murdeosi), aga sellest me ĂŒle saame.

Esmalt on vaja lubada xp_cmdshelli kasutamine, et varundused kustutada (Ă€rge unustage hiljem keelata, kui seda ei ole vaja):

EXEC sp_configure 'show advanced options', 1;  
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
EXEC sp_configure 'show advanced options', 0;  
GO

Ja nĂŒĂŒd, tegelikult:

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 vÀÀrtused */
DECLARE @bs     int = 4096, 
        @max_bs int = 65536;

/* BUFFERCOUNT vÀÀrtused */
DECLARE @bc     int = 7,
        @min_bc int = 7,
        @max_bc int = 800;

/* MAXTRANSFERSIZE vÀÀrtused */
DECLARE @ts     int = 524288,   --512KB, vaikimisi = 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;
END

Kui teil on kĂŒsimusi selle kohta, mis siin toimub, kirjutage kommentaaridesse vĂ”i isiklikult. Praegu rÀÀgin ainult parameetritest, mida edastan BACKUP DATABASE-le.

BLOCKSIZE jaoks on meil "suletud" vÀÀrtuste loetelu, mistĂ”ttu ei tehtud minu poolelt varukoopiaid BLOCKSIZE < 4KB. MAXTRANSFERSIZE on igasugune number, mis on jagatav 64KB-ga — vahemikus 64KB kuni 4MB. Oletuslikult on minu sĂŒsteemis 1024KB, mina valisin 512 — 1024 — 2048 — 4096.

Raskem oli BUFFERCOUNT — see vĂ”ib olla igasugune positiivne number, kuid link rÀÀgib, kuidas see arvutatakse BACKUP DATABASE puhul ja milliseks on suured vÀÀrtused ohtlikud.Seal on kirjas ka, kuidas saada teavet selle kohta, millise BUFFERCOUNT-i korral varukoopia tegelikult tehakse — minul on see 7. Selle vĂ€hendamine pole mĂ”istlik, kuid ĂŒlemine piir avastati katse-eksituse meetodil — BUFFERCOUNT = 896 ja MAXTRANSFERSIZE = 4194304 korral kukkus varukoopia vea tĂ”ttu (millest on juttu ĂŒlaltoodud lingil):

Msg 3013, Level 16, State 1, Line 7 BACKUP DATABASE lÔppes ebanormaalselt.

Msg 701, Level 17, State 123, Line 7 SĂŒsteemimĂ€lu on ressursside grupis 'default' piisav, et seda pĂ€ringut kĂ€itada.

VÔrdluseks nÀitan kÔigepealt varukoopia tegemise tulemusi ilma parameetreid mÀÀramata:

BACKUP DATABASE [bt]
TO DISK = 'D:SQLServerbackupbt.bak'
WITH COMPRESSION;

Noh, varukoopia ja varukoopia:

Töödeldi 1070072 lehekĂŒlge andmebaasist 'bt', fail 'bt' failis 1.

Töödeldi 2 lehekĂŒlge andmebaasist 'bt', fail 'bt_log' failis 1.

BACKUP DATABASE töötles edukalt 1070074 lehekĂŒlge 53,171 sekundiga (157,227 MB/sec).

Kogu skript, mis testib parameetreid, töötas paaritunniga, kĂ”ik mÔÔtmised on Google'i tabelis.Kuid siin on tulemuste valik, millel on kolm parimat kĂ€itusaega (ĂŒritasin teha ilusat graafikut, kuid postituses tuleb leppida tabeliga, ja kommentaarides @mixsture lisatud vĂ€ga lahedad graafikud.).

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;

MS SQL Server: BACKUP steroididel

TÀhelepanu, kohe vÀga oluline mÀrkus @mixsture API-s kommentaarist:

saab kindlalt öelda, et seos parameetrite ja varukoopia kiiruste vahel nende vÀÀrtuste piirides on juhuslik, mingeid seaduspÀrasusi ei ole. Kuid kÔrvalekalle sisseehitatud parameetritest nÀib, et see on selgelt mÔjutanud tulemust.

St. ainult standardsete BACKUP parameetrite haldamise kaudu saavutati varukoopia tegemise ajal kahekordne kasu: 26 sekundit, vĂ”rreldes 53-ga alguses. Ja see pole ju halb, eks? Kuid peab uurima, kuidas seal taastamine on. Äkki nĂŒĂŒd taastamine kestab 4 korda kauem?

Esiteks mÔÔdame, kui kaua kulub vaikeseadete korral varukoopia taastamiseks:

RESTORE DATABASE [bt]
FROM DISK = 'D:SQLServerbackupbt.bak'
WITH REPLACE, RECOVERY;

Noh, seda te teate, seal on teed, replace- ja recovery-funktsioonid. Ja mul kÀib see nii:

Töödeldi 1070072 lehekĂŒlge andmebaasist 'bt', fail 'bt' failis 1.

Töödeldi 2 lehekĂŒlge andmebaasist 'bt', fail 'bt_log' failis 1.

RESTORE DATABASE edukalt 1070074 lehte 40.752 sekundiga (205.141 MB/sek).

NĂŒĂŒd proovin taastada varukoopiaid, mis on tehtud muudetud BLOCKSIZE, BUFFERCOUNT ja MAXTRANSFERSIZE seadistustega.

BLOCKSIZE = 16384, BUFFERCOUNT = 224, MAXTRANSFERSIZE = 4194304

RESTORE DATABASE edukalt 1070074 lehte 32.283 sekundiga (258.958 MB/sek).

BLOCKSIZE = 4096, BUFFERCOUNT = 448, MAXTRANSFERSIZE = 4194304

RESTORE DATABASE edukalt 1070074 lehte 32.682 sekundiga (255.796 MB/sek).

BLOCKSIZE = 16384, BUFFERCOUNT = 448, MAXTRANSFERSIZE = 2097152

RESTORE DATABASE edukalt 1070074 lehte 32.091 sekundiga (260.507 MB/sek).

BLOCKSIZE = 4096, BUFFERCOUNT = 56, MAXTRANSFERSIZE = 4194304

RESTORE DATABASE edukalt 1070074 lehte 32.401 sekundiga (258.015 MB/sek).

RESTORE DATABASE juhis taastamisel ei muutu, need parameetrid ei ole seal mÀÀratletud, SQL Server mÀÀrab need ise varukoopiatest. Ja on nĂ€ha, et isegi taastamisel vĂ”ib olla kasu — peaaegu 20% kiiremini (Ausalt öeldes ei kulutanud ma taastamisele palju aega, proovisin vaid mĂ”ningaid kĂ”ige "kiiremaid" varukoopiaid ja veendusin, et halvenemist ei ole.).

Igaks juhuks tĂ€psustan — siin ei ole kirjeldatud mingisuguseid optimaalseid parameetreid. Optimaalsed parameetrid leiate ainult katsetamise teel. Mina sain sellised tulemused, teie saate teised. Aga nĂ€ete, et oma varukoopiaid saab "tuunida" ja need vĂ”ivad tĂ”esti luua ja taastada kiiremini.

Soovitan tungivalt lugeda dokumentatsiooni pĂ”hjalikult, kuna teie sĂŒsteemi jaoks vĂ”ivad olla spetsiifilised nĂŒansid.

Kuna alustasin varukoopiate kirjutamisega, tahan kohe mainida veel ĂŒhte "optimeerimist", mis esineb sagedamini, kui parameetrite "tĂŒĂŒnimine" (nii kasutab vĂ€hemalt osa varundusvahendeid, vĂ”ib-olla koos varem kirjeldatud parameetritega), kuid seda ei ole hetkel Habr's veel kirjeldatud.

Kui vaadata dokumentatsiooni teist rida, kohe pÀrast BACKUP DATABASE, siis nÀeme:

TO  [ ,...n ]

Kuidas arvate, mis juhtub, kui mÀÀrata mitu backup_device'i? SĂŒntaks ju lubab. Ja juhtub vĂ€ga huvitav asi — varukoopia lihtsalt "jaotub" mitme seadme vahel. St. Iga "seade" eraldi on kasutuks, kui ĂŒks kadus, kadus kogu varukoopia. Kuid kuidas mĂ”jutas see jaotamine varundamise kiirust?

Proovime teha varukoopia kahe "seadmest", mis asuvad lĂ€hedal ĂŒhes kaustas:

BACKUP DATABASE [bt]
TO 
    DISK = 'D:SQLServerbackupbt1.bak',
    DISK = 'D:SQLServerbackupbt2.bak'   
WITH COMPRESSION;

Issand, mis siin toimub?

Töödeldi 1070072 lehekĂŒlge andmebaasist 'bt', fail 'bt' failis 1.

KĂ€ideldi 2 lehte andmebaasis 'bt', fail 'btlog' failil 1.

ANDMEBASE BACKUP edukalt töödeldud 1070074 lehte 40,092 sekundi jooksul (208,519 MB/sek).

Kas varukoopia tehti 25% kiiremini lihtsalt niisama? Ent kui lisada veel paar seadet?

BACKUP DATABASE [bt]
TO 
    DISK = 'D:SQLServerbackupbt1.bak',
    DISK = 'D:SQLServerbackupbt2.bak',
    DISK = 'D:SQLServerbackupbt3.bak',
    DISK = 'D:SQLServerbackupbt4.bak'
WITH COMPRESSION;

ANDMEBASE BACKUP edukalt tööteldi 1070074 lehte 34,234 sekundi jooksul (244,200 MB/sek).

Seega on kokkuvĂ”tteks ajavalitsemise sÀÀst umbes 35% ainult seetĂ”ttu, et varukoopia kirjutatakse kohe 4 faili ĂŒhte diskile. Olen kontrollinud suuremat arvu — minu lĂ€ptopis ei olnud kasu, optimaalne on 4 seadet. Teie jaoks — ei tea, tuleb kontrollida. Ja jah, kui need seadmed on tĂ”eliselt erinevad kettad, siis Ă”nnitleme, kasu peaks olema veelgi suurem.

RÀÀgime nĂŒĂŒd, kuidas seda vÀÀrtust taastada. Selleks tuleb muuta taastamise kĂ€sku ja loetleda kĂ”ik seadmed:

RESTORE DATABASE [bt]
FROM 
    DISK = 'D:SQLServerbackupbt1.bak',
    DISK = 'D:SQLServerbackupbt2.bak',
    DISK = 'D:SQLServerbackupbt3.bak',
    DISK = 'D:SQLServerbackupbt4.bak'
WITH REPLACE, RECOVERY;

EDASIMINE ANDMEBASE taastamine edukalt tööteldi 1070074 lehte 38,027 sekundi jooksul (219,842 MB/sek).

Natuke kiirem, aga kuskil lĂ€hedal, mitte mĂ€rgatavalt. Üldiselt, varukoopia vĂ”etakse kiiremini, ent taastatakse samamoodi — edu? Minu arvates — on see igati positiivne. See on oluline, seega kordustan — kui te kaotate vĂ€hemalt ĂŒhe neist failidest — kaotate kogu varukoopia.

Kui vaadata varukoopia teavet ajaloos, mis vĂ€ljastatakse Trace Flag 3213 ja 3605 kaudu, vĂ”ib mĂ€rgata, et mitmes seadmes varukoopia tegemisel suureneb vĂ€hemalt BUFFERCOUNT. Arvatavasti vĂ”ib proovida valida ka paremaid parameetreid BUFFERCOUNT, BLOCKSIZE, MAXTRANSFERSIZE jaoks, kuid mul ei Ă”nnestunud ning viitsisin veel ĂŒhte tĂŒĂŒpi teste teha erinevate failide arvu jaoks. Ja kettad on kahju. Kui soovite selliseid teste korraldada, pole skripti ĂŒmber tegemine keeruline.

LĂ”puks rÀÀgime hinnast. Kui varukoopia vĂ”etakse paralleelselt kasutajate tööga — tuleb testimisele vĂ€ga tĂ”siselt lĂ€heneda, kuna kui varukoopia vĂ”etakse kiiremini — kettad koormavad rohkem, protsessori koormus tĂ”useb (kuna seda tuleb samuti kĂ€rpida), vastavalt sellele vĂ€heneb kogu sĂŒsteemi reaktsioonikiirus.

NaljapĂ€eva naljad naljadeks, aga ma saan tĂ€pselt aru, et ma ei teinud mingit avastust. Ülaltoodud, mis on kirjutatud, on lihtsalt nĂ€idis sellest, kuidas saab valida optimaalseid parameetreid varukoopiate tegemiseks.

Pidage meeles, et kĂ”ik, mida teete — teete oma riski eest. Kontrollige oma varukoopiaid ja Ă€rge unustage DBCC CHECKDB-d.

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster