MS SQL сервері: стероидтердегі САҚТЫҚ КҮШІ

Күте тұрыңыз! Күте тұрыңыз! Рас, бұл SQL серверінің сақтық көшірмелерінің түрлері туралы басқа мақала емес. Қалпына келтіру үлгілерінің арасындағы айырмашылықтар мен өсіп кеткен бөренелермен қалай күресуге болатыны туралы айтпаймын.

Мүмкін (бәлкім, мүмкін), осы жазбаны оқығаннан кейін сіз стандартты құралдармен жойылған сақтық көшірме ертең түнде 1.5 есе жылдам жойылатынына көз жеткізе аласыз. Және ДЕРЕКТЕР ҚОРЫНЫҢ САҚТЫҚ КӨШІРМЕГІ параметрлерін сәл көбірек пайдаланғаныңызға байланысты.

Егер посттың мазмұны сізге түсінікті болса, кешіріңіз. Мен Google «habr sql серверінің сақтық көшірмесі» деген сөз тіркесі үшін қол жеткізген барлық нәрселерді оқыдым және бірде-бір мақалада сақтық көшірме уақытына параметрлерді пайдалану арқылы қандай да бір түрде әсер етуі мүмкін екендігі туралы ешқандай ескерту таппадым.

Мен сіздің назарыңызды бірден Александр Гладченконың пікіріне аударамын (@mssqlhelp):

Өндірісте BUFFERCOUNT, BLOCKSIZE, MAXTRANSFERSIZE параметрлерін ешқашан өзгертпеңіз. Олар тек осындай мақалаларды жазу үшін жасалған. Іс жүзінде сіз есте сақтау проблемаларынан тез арада құтыласыз.

Ең ақылды және эксклюзивті мазмұнды жариялау, әрине, керемет болар еді, бірақ, өкінішке орай, олай емес. Бұл тақырыпқа арналған ағылшын тіліндегі және орыс тіліндегі мақалалар/жазбалар (мен оларды қалай дұрыс атауға болатынын білмеймін) әрқашан бар. Міне, мен кездестіргендердің кейбірі: рет, два, үш (sql.ru сайтында).

Сонымен, бастау үшін мен аздап қысқартылған САҚТЫҚ КҮШІ синтаксисін қосамын MSDN (Айтпақшы, мен ДЕРЕКТЕРДІҢ САҚТЫҚ КӨШІРУ БАЗАСЫ туралы жоғарыда жаздым, бірақ мұның бәрі транзакциялар журналының сақтық көшірмесіне де, дифференциалды сақтық көшірмеге де қатысты, бірақ анық емес әсер етуі мүмкін):

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

<general_WITH_options> [ ,...n ]::=
<...>
--Media Set Options
 <...>
 | BLOCKSIZE = { blocksize | @blocksize_variable }

--Data Transfer Options
   BUFFERCOUNT = { buffercount | @buffercount_variable }
 | MAXTRANSFERSIZE = { maxtransfersize | @maxtransfersize_variable }
<...>

<…> - бұл жерде бірдеңе бар екенін білдіреді, бірақ мен оны алып тастадым, себебі ол қазір тақырыпқа қатысты емес.

Әдетте сақтық көшірмені қалай жасайсыз? Олар миллиардтаған мақалалардың сақтық көшірмесін жасауды қалай «үйретеді»? Жалпы, кейбір өте үлкен емес дерекқордың бір реттік сақтық көшірмесін жасау керек болса, мен автоматты түрде келесідей нәрсені жазамын:

BACKUP DATABASE smth
TO DISK = 'D:Backupsmth.bak'
WITH STATS = 10, CHECKSUM, COMPRESSION, COPY_ONLY;
--ладно, CHECKSUM я написал только чтобы казаться умнее

Жалпы алғанда, резервтік көшірмелер туралы мақалаларда әдетте айтылған барлық параметрлердің 75-90% осында берілген. Сонымен қатар INIT, SKIP бар. MSDN сайтына кірдіңіз бе? Бір жарым экранға арналған опциялар бар екенін көрдіңіз бе? Мен де көрдім...

Сіз бұдан әрі кодтың бірінші блогында қалған үш параметр - BLOCKSIZE, BUFFERCOUNT және MAXTRANSFERSIZE туралы айтатынымызды түсінген боларсыз. Міне, олардың MSDN-тен сипаттамалары:

BLOCKSIZE = { блок өлшемі | @ блок өлшемі_айнымалысы } - байттағы физикалық блок өлшемін көрсетеді. Қолдау көрсетілетін өлшемдер: 512, 1024, 2048, 4096, 8192, 16, 384 және 32 байт (768 КБ). Әдепкі мән таспа құрылғылары үшін 65 және басқа құрылғылар үшін 536 болып табылады. Әдетте бұл параметр қажет емес, себебі BACKUP мәлімдемесі құрылғы үшін сәйкес блок өлшемін автоматты түрде таңдайды. Блок өлшемін орнату автоматты блок өлшемін таңдауды анық түрде қайта анықтайды.

BUFFERCOUNT = { буфер саны | @ буфер_саны_айнымалысы } - сақтық көшірме әрекеті үшін пайдаланылатын енгізу/шығару буферлерінің жалпы санын анықтайды. Кез келген оң бүтін мәнді көрсетуге болады, бірақ буферлердің үлкен саны Sqlservr.exe процесіндегі шамадан тыс виртуалды мекенжай кеңістігіне байланысты жадта жоқ қатені тудыруы мүмкін.

Буферлер пайдаланатын кеңістіктің жалпы көлемі келесі формуламен анықталады: BUFFERCOUNT * MAXTRANSFERSIZE.

MAXTRANSFERSIZE = { maxtransfersize | @ maxtransfersize_айнымалысы } SQL сервері мен сақтық көшірме жиынының медиасы арасында алмасу үшін байттағы ең үлкен деректер пакетінің өлшемін көрсетеді. 65 536 байттан (64 КБ) 4 194 304 байтқа (4 МБ) дейінгі бірнеше мәндерге қолдау көрсетіледі.

Ант етемін, мен мұны бұрын оқығанмын, бірақ олардың өнімділікке қаншалықты әсер ететіні ешқашан ойлаған емес. Оның үстіне, мен «шығу» түрін жасауым керек және қазірдің өзінде олардың не істеп жатқанын толық түсінбейтінімді мойындауым керек. Маған буферленген енгізу/шығару және қатты дискімен жұмыс туралы көбірек оқу керек шығар. Бір күні мен мұны істеймін, бірақ қазір мен бұл мәндердің сақтық көшірме жасау жылдамдығына қалай әсер ететінін тексеретін сценарий жаза аламын.

Мен өлшемі шамамен 10 ГБ болатын шағын дерекқорды жасадым, оны SSD дискісіне салып, сақтық көшірмеге арналған каталогты қатты дискіге қойдым.

Мен нәтижелерді сақтау үшін уақытша кесте жасаймын (менде ол уақытша емес, сондықтан мен нәтижелерді егжей-тегжейлі зерттей аламын, бірақ сіз өзіңіз шешесіз):

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

Сценарийдің принципі қарапайым – кірістірілген циклдар, олардың әрқайсысы бір параметрдің мәнін өзгертеді, бұл параметрлерді САҚТЫҚ КҮШІРУ пәрменіне кірістіреді, msdb.dbo.backupset сайтынан тарихпен соңғы жазбаны сақтайды, сақтық көшірме файлын және келесі итерацияны жояды. . Сақтық көшірменің орындалу деректері сақтық көшірмеден алынғандықтан, дәлдік біршама жоғалады (секундтардың бөліктері жоқ), бірақ біз бұл жағдайдан аман қаламыз.

Сақтық көшірмелерді жою үшін алдымен xp_cmdshell қосу керек (содан кейін қажет болмаса, оны өшіруді ұмытпаңыз):

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

Ал, шын мәнінде:

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;

/* BUFFERCOUNT values */
DECLARE @bc     int = 7,
        @min_bc int = 7,
        @max_bc int = 800;

/* 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;
END

Егер сізге кенеттен мұнда не болып жатқаны туралы түсініктеме қажет болса, түсініктемелерде немесе PM-ге жазыңыз. Әзірге мен сізге САҚТЫҚ КӨШІРУ ДЕРЕКТЕР ҚОРЫНА енгізген параметрлер туралы ғана айтамын.

BLOCKSIZE үшін бізде мәндердің «жабық» тізімі бар және мен BLOCKSIZE < 4КБ сақтық көшірме жасамадым. MAXTRANSFERSIZE 64КБ еселі кез келген санды – 64КБ-тан 4МБ-қа дейін. Менің жүйемдегі әдепкі 1024 КБ, мен 512 - 1024 - 2048 - 4096 алдым.

BUFFERCOUNT көмегімен қиынырақ болды - бұл кез келген оң сан болуы мүмкін, бірақ сілтемеде айтылған ол САҚТЫҚ ДЕРЕКТЕР ҚОРЫНДА қалай есептеледі және үлкен мәндер неге қауіпті?. Сондай-ақ ол сақтық көшірменің қай BUFFERCOUNT көмегімен жасалғаны туралы ақпаратты қалай алуға болатынын айтады - мен үшін бұл 7. Оны азайтудың қажеті жоқ, ал жоғарғы шегі эксперименталды түрде анықталды - BUFFERCOUNT = 896 және MAXTRANSFERSIZE = 4194304 сақтық көшірме төмендеді. қате (жоғарыдағы сілтемеде жазылған):

3013 хабары, 16-деңгей, 1-күй, 7-жолдың САҚТЫҚ КӨШІРУ ДЕРЕКТЕР БАЗАСЫ әдеттен тыс аяқталуда.

Хабар 701, 17-деңгей, 123-күй, 7-жол Бұл сұрауды орындау үшін «әдепкі» ресурс пулында жүйелік жады жеткіліксіз.

Салыстыру үшін, мен алдымен ешқандай параметрлерді көрсетпей, сақтық көшірме жасаудың нәтижелерін көрсетемін:

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

Ал, сақтық көшірме және сақтық көшірме:

'bt' дерекқоры үшін 1070072 бет өңделді, 1-файлдағы 'bt' файлы.

'bt' дерекқоры үшін 2 бет өңделді, 1-файлдағы 'bt_log' файлы.

САҚТЫҚ КӨШІРУ ДЕРЕКТЕР ҚОРЫ 1070074 секундта (53.171 МБ/сек) 157.227 бетті сәтті өңдеді.

Сценарийдің өзі параметрлерді сынап, бірнеше сағатта жұмыс істеді, барлық өлшемдер болды Google электрондық кестесі. Міне, ең жақсы үш орындалу уақыты бар нәтижелердің таңдауы (мен жақсы график жасауға тырыстым, бірақ постта кестемен және түсініктемелерде орындауға тура келеді. @mixsture қосылды өте керемет графика).

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 сервері: стероидтердегі САҚТЫҚ КҮШІ

Назар аударыңыз, өте маңызды ескерту @mixsture -дан Пікірлер:

Осы мәндер ауқымындағы параметрлер мен сақтық көшірме жылдамдығы арасындағы байланыс кездейсоқ, ешқандай үлгі жоқ деп сенімді түрде айта аламыз. Бірақ кірістірілген параметрлерден алыстау нәтижеге жақсы әсер еткені анық

Анау. Сақтық көшірме жасаудың стандартты параметрлерін басқару арқылы ғана сақтық көшірмелерді жою уақыты 2 есе артты: 26 секунд, басындағы 53 секунд. Бұл жаман емес, солай ма? Бірақ біз қалпына келтірумен не болатынын көруіміз керек. Енді қалпына келтіру 4 есе ұзағырақ болса ше?

Алдымен сақтық көшірмені әдепкі параметрлермен қалпына келтіруге қанша уақыт кететінін өлшеп көрейік:

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

Ал, сіз өзіңіз білесіз, оның жолдары бар, ауыстыру ауыстырмайды, қалпына келтіру қалпына келтіру емес. Және мен мұны былай істеймін:

'bt' дерекқоры үшін 1070072 бет өңделді, 1-файлдағы 'bt' файлы.

'bt' дерекқоры үшін 2 бет өңделді, 1-файлдағы 'bt_log' файлы.

ДЕРЕКТЕР ҚОРЫН ҚАЛПЫНА ҚАЛПЫНА 1070074 секундта (40.752 МБ/сек) 205.141 бетті сәтті өңдеді.

Енді BLOCKSIZE, BUFFERCOUNT және MAXTRANSFERSIZE өзгертілген сақтық көшірмелерді қалпына келтіруге тырысамын.

BLOCKSIZE = 16384, BUFFERCOUNT = 224, MAXTRANSFERSIZE = 4194304

ДЕРЕКТЕР ҚОРЫН ҚАЛПЫНА ҚАЛПЫНА 1070074 секундта (32.283 МБ/сек) 258.958 бетті сәтті өңдеді.

BLOCKSIZE = 4096, BUFFERCOUNT = 448, MAXTRANSFERSIZE = 4194304

ДЕРЕКТЕР ҚОРЫН ҚАЛПЫНА ҚАЛПЫНА 1070074 секундта (32.682 МБ/сек) 255.796 бетті сәтті өңдеді.

BLOCKSIZE = 16384, BUFFERCOUNT = 448, MAXTRANSFERSIZE = 2097152

ДЕРЕКТЕР ҚОРЫН ҚАЛПЫНА ҚАЛПЫНА 1070074 секундта (32.091 МБ/сек) 260.507 бетті сәтті өңдеді.

BLOCKSIZE = 4096, BUFFERCOUNT = 56, MAXTRANSFERSIZE = 4194304

ДЕРЕКТЕР ҚОРЫН ҚАЛПЫНА ҚАЛПЫНА 1070074 секундта (32.401 МБ/сек) 258.015 бетті сәтті өңдеді.

RESTORE DATABASE операторы қалпына келтіру кезінде өзгермейді, бұл параметрлер онда көрсетілмеген, оларды SQL Server өзі сақтық көшірмеден анықтайды. Тіпті қалпына келтіру кезінде де пайда болуы мүмкін екені анық - 20% тезірек (Шынымды айтсам, мен қалпына келтіруге көп уақыт жұмсамадым, мен бірнеше «ең жылдам» сақтық көшірмелерден өтіп, нашарлаудың жоқтығына көз жеткіздім.).

Қалай болғанда да, бұл барлық адамдар үшін оңтайлы параметрлер емес екенін түсіндірейін. Сіз өзіңіз үшін оңтайлы параметрлерді тек тестілеу арқылы ала аласыз. Мен бұл нәтижелерді алдым, сіз әртүрлі нәтиже аласыз. Бірақ сіз сақтық көшірмелерді «баптай» алатыныңызды және олар шынымен тезірек қалыптасып, орналаса алатынын көресіз.

Сондай-ақ, мен сізге құжаттаманы толығымен оқып шығуды ұсынамын, себебі сіздің жүйеңізге тән нюанстар болуы мүмкін.

Мен сақтық көшірмелер туралы жаза бастағандықтан, мен бірден «баптау» параметрлеріне қарағанда жиі кездесетін тағы бір «оңтайландыру» туралы жазғым келеді (менің түсінуімше, оны кем дегенде кейбір сақтық көшірме утилиталары пайдаланады, мүмкін параметрлермен бірге. бұрын сипатталған), бірақ ол әлі Хабреде де сипатталған жоқ.

Егер біз құжаттамадағы екінші жолды қарасақ, ДЕРЕКТЕР ҚОРЫНЫҢ САҚТЫҚ КӨШІРМЕГІ астында дәл сол жерде біз мынаны көреміз:

TO <backup_device> [ ,...n ]

Бірнеше резервтік_құрылғыларды көрсетсеңіз, не болады деп ойлайсыз? Синтаксис оған мүмкіндік береді. Және өте қызықты нәрсе болады - сақтық көшірме жай ғана бірнеше құрылғыларға «таралады». Анау. әрбір «құрылғы» жеке-жеке пайдасыз болады, біреуі жоғалады, бүкіл сақтық көшірмесін жоғалтады. Бірақ мұндай жағу сақтық көшірме жылдамдығына қалай әсер етеді?

Бір қалтада қатар орналасқан екі «құрылғыда» сақтық көшірме жасауға тырысайық:

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

Әлемнің әкелері, бұл не үшін жасалып жатыр?

'bt' дерекқоры үшін 1070072 бет өңделді, 1-файлдағы 'bt' файлы.

'bt' дерекқоры, 'bt' файлы үшін 2 бет өңделді1-файлдағы журнал.

САҚТЫҚ КӨШІРУ ДЕРЕКТЕР ҚОРЫ 1070074 секундта (40.092 МБ/сек) 208.519 бетті сәтті өңдеді.

Сақтық көшірме күтпеген жерден 25% жылдам болды ма? Тағы бірнеше құрылғы қоссақ ше?

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

САҚТЫҚ КӨШІРУ ДЕРЕКТЕР ҚОРЫ 1070074 секундта (34.234 МБ/сек) 244.200 бетті сәтті өңдеді.

Жалпы алғанда, резервтік көшірме бірден бір дискідегі 35 файлға жазылатындықтан, пайда сақтық көшірме жасау уақытының шамамен 4% құрайды. Мен үлкенірек санды тексердім - ноутбукта ешқандай пайда жоқ, оңтайлы - 4 құрылғы. Сіз үшін - білмеймін, тексеру керек. Айтпақшы, егер сізде бұл құрылғылар болса - бұл шын мәнінде әртүрлі дискілер, құттықтаймыз, табыс одан да маңызды болуы керек.

Енді осы бақытты қалай қалпына келтіруге болатынын айтайық. Мұны істеу үшін сізге қалпына келтіру пәрменін өзгерту және барлық құрылғыларды тізімдеу керек:

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

ДЕРЕКТЕР ҚОРЫН ҚАЛПЫНА ҚАЛПЫНА 1070074 секундта (38.027 МБ/сек) 219.842 бетті сәтті өңдеді.

Біраз жылдамырақ, бірақ жақын жерде, маңызды емес. Жалпы алғанда, сақтық көшірме тезірек жойылады және дәл осылай қалпына келтіріледі - сәттілік пе? Маған келетін болсақ, бұл өте сәтті. Бұл маңызды, сондықтан қайталаймын - егер сіз егер сіз осы файлдардың кем дегенде біреуін жоғалтсаңыз, бүкіл сақтық көшірмені жоғалтасыз.

Trace Flags 3213 және 3605 көмегімен көрсетілетін сақтық көшірме ақпаратындағы журналды қарасаңыз, бірнеше құрылғыларға сақтық көшірме жасау кезінде, кем дегенде, BUFFERCOUNT саны көбейетінін байқайсыз. Бәлкім, сіз BUFFERCOUNT, BLOCKSIZE, MAXTRANSFERSIZE үшін оңтайлы параметрлерді таңдауға тырысуға болады, бірақ мен бірден сәтті болмадым, мен мұндай сынақты қайта өткізуге тым жалқау болдым, бірақ файлдардың басқа саны үшін. Ал дөңгелектерге қатысты ұят. Егер сіз үйде осындай тестілеуді ұйымдастырғыңыз келсе, сценарийді қайта жасау қиын емес.

Ақырында, баға туралы сөйлесейік. Егер сақтық көшірме пайдаланушылардың жұмысымен қатар жойылса, сіз тестілеуге өте жауапкершілікпен қарауыңыз керек, өйткені сақтық көшірме тезірек жойылса, дискілер көбірек тартылады, процессорға жүктеме артады (сіз әлі де қысуыңыз керек ол ұшуда) және сәйкесінше жүйенің жалпы жауап беру қабілеті төмендейді.

Жай әзіл, бірақ мен ешбір ашу жасамағанымды жақсы түсінемін. Жоғарыда жазылғандар сақтық көшірмелерді алу үшін оңтайлы параметрлерді қалай таңдауға болатынын көрсету.

Есіңізде болсын, сіз жасаған барлық нәрсе сіздің тәуекеліңіз бен тәуекеліңізбен жасалады. Сақтық көшірмелерді тексеріңіз және DBCC CHECKDB туралы ұмытпаңыз.

Ақпарат көзі: www.habr.com

пікір қалдыру