Беда пришла откуда не ждали… У клиента завис процесс “Касса”, так что не смог снять процесс через Диспетчер задач. Рабочее место “Касса” — одновременно сервер всей системы.
Клиент принял решение ресетнуть через кнопку.
В итоге умерла DB. FireBird 2.5
Backup’ы настроены не были, так что последняя версия БД, которая случайно лежала у меня на винте, была минус 8 дней. Подняли по-быстрому с неё. Но суть дальше.
Как делать бекапы для FireBird.
Я написал скрипт, который, когда его запускают, делает резервное копирование базы данных с именем БазаДаннах_30_05_2017_23_07_51.fbk
@echo off
set "currentTime=%Time: =0%"
set now=%date:~-4%_%date:~3,2%_%date:~0,2%_%currentTime:~0,2%_%currentTime:~3,2%_%currentTime:~6,2%
set user=SYSDBA
set password=masterkey
set database_name=PARKDB.FDB
set backup_name=Backup\PARKDB
set ext=.fbk
set backup_filename=%backup_name%_%now%%ext%
echo %backup_filename%
nbackup -U %user% -P %password% -B 0 %database_name% %backup_filename%
%date:~3,2%
Это означает взять из результата date (это системная функция Windows), 2 символа, начиная с 3 позиции в строке. Обычный %date% = 31.05.2017
set "currentTime=%Time: =0%"
Означает брать время, учитывая 0, когда часы меньше 10, то есть без этой команды, мы при выполнении команд:
set now=%date:~-4%_%date:~3,2%_%date:~0,2%_%currentTime:~0,2%_%currentTime:~3,2%_%currentTime:~6,2%
получили бы, что now=2017_05_31_ 0_44_33, а имя файла выглядело бы так: Backup\PARKDB_2017_05_31_ 0_44_33.fbk. Пробел не сильно виден, но он неприемлем в названии файла для nbackup дата и время берутся из текущего времени системы. Это вроде рассказал :) Далее, чтобы скрипт выполнялся постоянно, я добавил задачу в планировщик задач виндовс, он каждые 4 часа запускает мой скрипт и создается новая БД, далее я научился создавать задачи в планировщике задач через командную строку:
@echo off
set script_name=e:\SoftBuild\Parking\DB\DB_Backup.bat
set task_name=LotParkingBackup
SCHTASKS /Create /SC DAILY /TN %task_name% /TR %script_name% /HRESULT /F /RI 240 /DU 24:00 /v1
Детали параметров можете посмотреть в хелпе. SCHTASKS /Create /?
Потом добавил в инсталлятор создание скрипта, который делает то, что я описал только что, и запуск из инсталлятора:
function NextButtonClick(CurPageID: Integer): Boolean;
var
ServerHost, ServerPort, DBFileName, FBDirPath: string;
ResultCode, ErrorCode: Integer;
UDFFrom, UDFTo, ReaderPort: string;
RegistryTaskFile, DBDirPath, BackupScriptPath, RegistryFileName: string;
begin
if CurPageID = SettingsPage.ID then
begin
ServerHost := SettingsPage.Values[0];
ServerPort := SettingsPage.Values[1];
DBFileName := SettingsPage.Values[2];
if IsComponentSelected(cDB) then
begin
DBDirPath := Copy(DBFileName, 1, Pos('PARKDB.FDB', DBFileName) - 1);
BackupScriptPath := DBDirPath + 'DB_Backup.bat'
RegistryTaskFile := '@echo off' + #13#10 +
'set script_name=' + BackupScriptPath + #13#10 +
'set task_name=LotParkingBackup' + #13#10 +
'SCHTASKS /Create /SC DAILY /TN %task_name% /TR %script_name% /HRESULT /F /RI 240 /DU 24:00 /v1' + #13#10;
RegistryFileName := DBDirPath + 'DB_RegistryBackup.bat';
SaveStringToFile(RegistryFileName, RegistryTaskFile, False);
Exec(ExpandConstant(RegistryFileName), '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
end;
end;
end;
Теперь у меня есть скрипт, который делает резервную копию, и скрипт, который регистрирует задачу, далее я научился удалять задачу из планировщика, опять же из командной строки:
@echo off
set task_name=LotParkingBackup
SCHTASKS /DELETE /TN %task_name% /F
И добавил в инсталлятор. что если мы делаем удаление программы Парковка, то нужно запустить скрипт, который удалит задачу из Планировщика:
[UninstallRun]
Filename: "{app}\DB\DB_DeleteTask.bat"; WorkingDir: "{app}\DB\"; Flags: runhidden waituntilterminated; Components: DB
В итоге у нас каждые 4 часа есть бекап, и если мы делаем UnInstall, то всё чисто :)
Оригинал.
Комментарии (29)
instigator21
31.05.2017 16:35Без сомнения, в данном случае за хранение бекапов отвечает заказчик. На объекте есть только мобильный интернет, который включается именно для таких случаев
old_bear
31.05.2017 17:35+3Рабочее место “Касса” — одновременно сервер всей системы.
Разве за такое не четвертуют сразу, не дожидаясь появления пушных зверей?
instigator21
31.05.2017 17:45+1пожелание заказчика ради экономии, ну и надежда на авось и так сойдет, все варианты ему озвучены были
aalebedev
31.05.2017 18:51+1Я же понимаю, что бекапы идут на тот же физический жесткий диск, что и БД?
Кстати, насчет планировщика, я заметил, что иногда с ним бывают проблемы, если задача выполняется чаще раза в день. Пропуски или двойное выполнение, редко но бывает.
Мы используем nnCron, тут хватит даже Lite.
Но главное, что надо разобраться почему завис процесс и его нельзя было вырубить.instigator21
31.05.2017 19:00судя по логам была проблема с считывателем карт mifare, но всё равно так зависнуть не могло, списываю на кривые руки охранников парковки
NakonechnyS
31.05.2017 19:56Двойное выполнение (параллельный запуск, правильно понял?) с nbackup вряд ли возможно, т.к. файл БД блокируется.
instigator21
31.05.2017 19:22как-то так, можно правда ещё батник написать который охранник просто запускает когда флешку вставляет
NakonechnyS
31.05.2017 19:40+1Зачем делаете nbackup уровня 0? Лучше уж тогда gbak, после него копия будет сжатой и проверенной на ошибки.
Я делаю ночью nbackup уровня 0, а в течение дня каждый час уровня 1. На одной БД nbackup ведет себя очень нестабильно, иногда снимая копию уровня 1 больше часа.instigator21
31.05.2017 19:41у меня довольно не большая БД, клиент забирает(будет забирать) бекапы вручную, парить ему мозг несколькими файлами, решил излишним
NakonechnyS
31.05.2017 19:49Ну у меня тоже 2 БД примерно по 2ГБ. Вот только бэкап от gbak весит мегов 600, а nbackup уровня 0 слепит точную копию БД исходного размера. Экономия места приличная получается.
Время снятия копии посредством nbackup — примерно минута, gbak — чуть дольше (минут 5), но она и целостность страниц проверяет, и сжимает на лету.instigator21
31.05.2017 20:05есть элегантное решение которое советую сами разработчики о том что бы выходной поток nbackup сразу отправлять в архиватор, у меня пока меньше 100 мб %)
Siemargl
31.05.2017 21:50-4Дельфи, Файрберд, Надежность — выберите любые два
FMA
31.05.2017 22:35+2А чем плох Delphi и Firebird? Наговнокодить можно на любом языке и любой СУБД. Сам много лет использовал Delphi и Firebird. И разработанные системы работаю до сих пор без нареканий и проблем.
Siemargl
01.06.2017 12:21А. Дельфи — слишком низкий порог входа приводит к избытку идиотских вопросов на форумах, а синтаксис и возможности языка — равны С++ без шаблонов. Синдром CheckBox28Click
Средняя квалификация коммунити в итоге весьма «впечатляет»
Б. Файрберд — хорошая СУБД для рабочих групп, но с ньюананасами —
1. Недуракоустойчивая. Можно сделать невосстановимый бэкап gbak, например (я даже сначала не поверил такому нонсенсу).
2. MVCC без лога приводит к тому, что при транзакциях нужно делать много изменений по всему файлу данных.
Соответственно, при сбое питания или внезапном ресете шанс похерить базу возрастает многократно.
Умножаем теперь А. на Б. и получаем Ннадежность
P.S. Автор топика, возможно, еще не знает, как на самом деле устроен nbackup, что на него полагается. Я даже не знаю, как пояснить. Упрощая — это эмуляция лога в БД, которая лог не использует. В целом — вполне можно получить бэкап, с которого не восстановишься.instigator21
01.06.2017 14:19Знаю только то что из мануала прочитал:
Несколько слов о внутренних механизмах
На заметку: то, что здесь будет описано, не является необходимыми знаниями для использования nbackup. Это описание дает грубое представление о том, что происходит при работе программы nbackup с параметром -B:
Прежде всего, основной файл базы данных блокируется установкой внутреннего флага состояния. С этого момента абсолютно все изменения в базе данных записываются во временный файл, называемый файлом разницы (difference file) или файлом дельты.
После этого создается резервная копия. Это не обычная копия файла базы данных — восстановление из полученной копии необходимо производить также при помощи nbackup.
По завершении резервирования содержимое файла дельты объединяется с основным файлом базы данных. После этого база данных разблокируется (флаг возвращается в «нормальное» состояние) и файл дельты удаляется.Siemargl
01.06.2017 15:51Именно. Только я предпочитаю читать в исходниках, а не в мануалах.
А резюме такое — после бекапа Птички обязательно надо делать тестовое восстановление и срочно орать «бадуга» если оно не проходит.
Собственно, скрипт надо прилично так дописать.
P.S А еще nbackup архивирует данные вместе с мусором (старые версии MVCC), который не успел убрать Garbage Collector. Да, это именно та же технология, за которую ругают Яву, дотнет и тп. Только для дисковых операций в СУБД это в сотни раз медленнее.
Lelik13a
01.06.2017 06:18+1* Необходимо добавить обработку кодов возврата иначе о том, что что-то пошло не так, узнаете внезапно.
* Желательно проверять размер получившегося бекапа на адекватность.
* Хорошо слать отчёт на почту, особенно если что-то не так.
* Можно добавить сжатие, лучше многопоточное, например через 7zip.
* А после этого добавить автоматическую очистку старых бекапов.
И будет вполне себе велосипед.
jo_b1ack
01.06.2017 09:05+2разве 3 строчки в cmd это уже статья на хабре? не в обиду… просто вспомнил какой раньше была жесткой редактура хабра.
hexman
01.06.2017 10:36Прекрасно это всё. Только до краха сервера или винтов на нём. Как я понял, бэкапы складываются там же, да небось ещё и на том же винте? Если это так, то всё плохо.
из замечаний:
1. Нет бэкапа на альтернативный носитель. В идеале, второй винт + облако.
2. Бэкапы никак не контролируются. Т.е. они только создаются, а подчищать кто будет?
aaalllsss
01.06.2017 10:37если база не большая, могли бы хоть настроить бекап в какую нибудь бесплатную mega.nz
aynur_safin
05.06.2017 12:18Для создания бекапов Firebird, есть прекрасная утилита «Time To Backup»,
бесплатна для пользователей экс-СССР.
http://www.sqlly.com/timetobackup.html
Серверная часть есть под Win и Linux, на Win работает как сервис, консоль только на Win.
Есть планировщик запуска, нотификация на емейл, сжатие бекапов, проверка бекапа на рестор, автоименование файлов по шаблонам (дата/время/инкремент).
instigator21
05.06.2017 12:25Спасибо, посмотрю. Вообще у нас есть написанный сервис для бекапа с множеством собственных фич, но в данном случае мне понадабился только бекап по времени, который бы легко можно было встроить в инсталятор.
nikolayvaganov
1. Оформление выглядит крайне вырвиглазно
2. Бекапы складывать на том же сервере, где находится БД — так себе затея.