Приложение 2. Примеры применения утилиты lhb

Создание инкрементного архива и его поддержка

Необходимо нам это для того, чтобы в течение определенного времени иметь наиболее полный резервный архив БД, но место на жестком диске ограничено, т.е. мы не можем держать сразу несколько копий полностью сохраненной БД.

Пример

Производим запуск инкрементного сохранения:

lhb s -u SYSTEM/MANAGER8 -f db.lhb -startinc

В файле db.lhb будет находиться полностью сохраненная БД, и в самой БД будет установлена контрольная точка, указывающая, с какого места необходимо продолжать инкрементное наращивание. С этого момента все вновь создаваемые файлы журнала также будут оставаться в БД (поэтому, если БД очень быстро разрастается в объеме, то лучше все-таки воспользоваться периодическим полным сохранением БД).

Далее, по прошествии определенного времени, нам необходимо дописать к файлу архива те изменения, которые произошли в БД со времени последнего инкрементного архивирования:

lhb s -u SYSTEM/MANAGER8 -f db.lhb -inc

Файл следует указывать именно тот, для которого мы начинали инкрементный архив. Утилита проверит соответствие контрольной точки, записанной в файл, той, которая находится в БД, и в случае соответствия допишет в конец файла архива те файлы журнала, которые были добавлены за время от последнего сохранения. Контрольная точка в БД будет обновлена для того, чтобы освободить уже ненужные файлы журнала (они впоследствии в ходе работы ядра будут удалены), и следующее инкрементное архивирование будет уже производиться от момента нашего последнего сохранения.

Операцию можно повторять необходимое число раз.

Впоследствии при возникновении каких-либо неприятностей можно будет восстановить данные из этого архива. При старте на восстановленной БД ядро произведет запись всех изменений из журнала в БД, и она будет готова к работе. Если резервное сохранение производилось достаточно регулярно, она будет наиболее близка к изначальной.

По прошествии определенного (возможно длительного) времени необходимо будет начать новый инкрементный архив БД. Ведь если БД довольно сильно разрослась в объеме за это время, то лучше будет произвести полное или начать новое инкрементное резервное сохранение, т.к. последующее восстановление можно осуществить более быстро, нежели произвести восстановление первоначальной БД и всех накопленных файлов журнала, и предоставить ядру СУБД ЛИНТЕР переносить изменения из файлов журнала в файлы самой БД. При определенных условиях это может потребовать значительного времени.

Исходя из всего вышесказанного, прежде чем начать новое инкрементное сохранение, лучше закрыть старое.

Пример

Если все еще существует файл db.lhb (в который мы накапливали инкрементные изменения), то подаем команду:

lhb s -u SYSTEM/MANAGER8 -f db.lhb -stopinc

После чего контрольная точка, соответствовавшая файлу архива, удалится из БД. Никакие новые данные при этом в файл архива сохранены не будут. Дальнейшее инкрементное наращивание этого файла станет невозможным.

Другой вариант, как удалить более не используемую контрольную точку (необходимость может возникнуть в случае, если, например, файл архива был поврежден):

lhb cp -u SYSTEM/MANAGER8 -list

Результатом будет примерно следующее:

Linter On-line BACKUP utility v.4.1.0.893
for RDBMS Linter SQL v. 6.20.0 for Unix
Copyright (C) 1990-2023 Relex, Inc. All rights reserved.
CP(00): Fri Jul 19 10:18:41.04 2023 BACKUP (LongLived) File: 0
CP(01): Fri Jul 19 10:20:05.19 2023 BACKUP (LongLived) File: 0

Т.е. в БД установлены две контрольные точки, каждая из которых была создана в результате старта инкрементного архивирования. Допустим, что первая из них нами уже не будет использоваться для инкрементного архивирования, и поэтому вполне логично её удалить:

lhb cp -u SYSTEM/MANAGER8 -clear 0

В результате первая контрольная точка удалится, а файлы журнала освободятся, и если они нигде больше не нужны, будут удалены.

Создание полного архива БД

Преимущества использования метода полного архивирования данных:

  • наиболее быстрое последующее восстановление БД из файла архива;

  • сохранение информации о фразовых индексах поддерживается только для полного сохранения;

  • не используются контрольные точки, и, как следствие, не остаются более не используемые файлы журнала.

Недостатки:

  • относительно длительный процесс архивации;

  • т.к. БД может достигать значительного размера, то хранение нескольких файлов архива может потребовать немало места;

  • по вышеуказанным причинам относительно затруднительно вести частое резервное сохранение БД.

Поэтому метод, применяемый при резервном архивировании, должен выбираться системным администратором в каждом случае индивидуально. Наиболее оптимальный – комбинирующий методы полного резервного сохранения и инкрементного.

Пример

Необходимо произвести полное сохранение БД в файл full.lhb, который в свою очередь следует разбить на тома по 650Мб (например, для хранения на CD). Хотелось бы, чтобы утилита не выдавала запрос на создание нового тома и чтобы сохранилась информация об имеющихся фразовых индексах. Подаем следующую команду:

lhb s -u SYSTEM/MANAGER8 -f full.lhb -v 650M -qc NV -pi

Другой вариант запуска: имеется текстовый файл run.txt, в котором написана эта строка:

s -u SYSTEM/MANAGER8 -f full.lhb -v 650M -qc NV -pi

Тогда подаем команду читать параметры из внешнего файла:

lhb ef run.txt

Результат будет аналогичен предыдущему.

Восстановление из полного архива БД

При восстановлении не имеет значения, какое было сохранение БД – полное или инкрементное.

Ядро СУБД ЛИНТЕР может быть не запущено.

Перед восстановлением желательно создать/очистить каталог, в который будет производиться восстановление БД (настоятельно рекомендуется, чтобы восстанавливаемый каталог не был каталогом существующей БД). Также желательно убедиться в наличии свободного места на диске, исходя из того, что его может потребоваться в два-три раза больше, чем занимает сам файл архива, из-за используемой в нем компрессии данных.

Пример

Подаем команду на восстановление (предположим, что файл архива был разбит на тома, и мы не хотим подтверждать открытие каждого нового тома) в каталог NEW_DB:

lhb r -u SYSTEM/MANAGER8 -f full.lhb -qc NV -p NEW_DB

В результате все файлы восстановленной БД будут помещены в каталог NEW_DB. Можно производить запуск ядра СУБД ЛИНТЕР на восстановленной БД.

Если восстановленная БД содержала информацию о фразовых индексах, то при старте ядро проанализирует эту информацию и создаст заново необходимые фразовые индексы (что может потребовать определенного времени). Затем БД будет готова к работе.

Сохранение и восстановление отдельных объектов БД из архива БД

Сохранение отдельных объектов отличается от полного сохранения структурой создаваемого файла архива. При сохранении отдельных объектов файлы журнала не сохраняются.

Для восстановления объектов необходимо работающее ядро СУБД ЛИНТЕР на уже существующей БД. Также желательно, чтобы восстанавливаемые объекты отсутствовали в БД.

При сохранении объектов сохраняется их структура, а для таблиц также сохраняются данные (если не указан ключ -otwd при сохранении таблиц).

Случаи необходимости сохранения и восстановления отдельных объектов БД:

  • какой-либо из объектов БД очень часто меняется по сравнению с другими (например, таблица), и поэтому её периодическое сохранение более выгодно, чем создание полного архива БД или инкрементного;

  • для переноса в другую БД некоторых объектов (например, таблиц и их триггеров, пользователей и ролей);

  • при сильной нехватке свободного места на диске.

Пример

Допустим, необходимо сохранить таблицу CUSTOMER со всеми её зависимыми объектами и внешними ссылками. Файл архива customer.lhb зашифруем по паролю < password > и снабдим комментарием, что это таблица CUSTOMER.

lhb s -u SYSTEM/MANAGER8 -f customer.lhb -g password -c "CUSTOMER table" -ot CUSTOMER -oref -d

Для последующего восстановления данной таблицы в БД вводим команду:

lhb r -u SYSTEM/MANAGER8 -f customer.lhb

Утилита предложит ввести пароль и попытается восстановить таблицу в БД. Если таблица с таким именем уже существует у данного пользователя, то будет выдано соответствующее предупреждение.

Другой возможный вариант: у пользователя < BOLT > есть таблица CLIENTS, и он желает передать её со всем содержимым пользователю < SYSTEM >. Для этого пользователь < BOLT > сохраняет данную таблицу в файл:

lhb s -u BOLT/ITALIC -f clients.lhb -ot CLIENTS

и передает созданный файл архива пользователю < SYSTEM >, а тот уже восстанавливает эту таблицу как свою по команде:

lhb s -u SYSTEM/MANAGER8 -f clients.lhb -ot CLIENTS -own

Следует всегда в подобных случаях стараться переносить объекты, от которых эта таблица зависит.

Пример использования языка сценариев для проведения регулярного инкрементного архивирования данных

Преимущества от использования языка сценариев для архивирования данных: можно гибко настроить график сохранения по конкретным временным условиям в определенные файлы архива.

Пример листинга файла сценариев, который позволяет сохранять БД при запуске и затем каждый день в 02:00; при этом предыдущие файлы переименовываются соответственно в arc1.lhb...arc4.lhb. Свежий файл имеет имя db.lhb. Если при запуске lhb задать ключ -fl FILE.LOG, то история сохранения будет накапливаться в файле FILE.LOG. Содержимое файла script.bsl:

/* --------------------------------------------------------------- */
variables:
   USERNAME     ="SYSTEM";  /* user name */
   USERPASSWORD ="MANAGER8"; /* user password */
   ARCDEVICE    ="./";      /* for new files */
   ARCFNAME     ="";        /* new name for old file */
   CHKSUF       = ".lhb";   /* suffix for checkpoint file */
   NUMFILE      = 1;
/* --------------------------------------------------------------- */
rights:
everyday (time = '02:00')
   {
   NUMFILE = 1;
   while (NUMFILE <  5)
      {
      if (exist (ARCDEVICE+"arc" + TOSTR(NUMFILE) +
                 ".lhb"))
         {
         if (NUMFILE == 1)
            delete (ARCDEVICE+"arc" + TOSTR(NUMFILE) +
                  ".lhb");
         Else
            rename (ARCDEVICE+"arc" + TOSTR(NUMFILE) +
                  ".lhb",
                  ARCDEVICE+"arc" + TOSTR(NUMFILE-1) + ".lhb");
         } /* if */
      NUMFILE = NUMFILE + 1;
      } /* while */
   rename (ARCDEVICE+"db.lhb", ARCDEVICE+"arc" +
         TOSTR(NUMFILE-1) + ".lhb");
   backup ("s -u "+USERNAME+"/"+USERPASSWORD+"
         -f "+ARCDEVICE+"db.lhb"+" -qc DF");
   logprint (CTIMESTAMP() + "---File" + "db" + CHKSUF +
         "created.\n");
exception: /* for everyday */
   print ("Error=" + TOSTR(CERROR) +
      ",LinError=" + TOSTR(LINERROR) +
      ",SysError=" + TOSTR(SYSERROR));
   logprint (CTIMESTAMP() + "---Error=" +
      TOSTR(CERROR) +
      ",LinError=" + TOSTR(LINERROR) +
      ",SysError=" + TOSTR(SYSERROR));
   stop;
   } /* everyday */
/* ---------------------------------------------------------------- */
special:
before /* just after the start */
   {
   NUMFILE = 1;
   while (NUMFILE <  5)
      {
      if (exist (ARCDEVICE+"arc" + TOSTR(NUMFILE) +
               ".lhb" ))
         {
         if (NUMFILE == 1)
            delete (ARCDEVICE+"arc" + TOSTR(NUMFILE) +
                  ".lhb" );
         Else
            rename (ARCDEVICE+"arc" + TOSTR(NUMFILE) +
                  ".lhb",
               ARCDEVICE+"arc" + TOSTR(NUMFILE-1) + ".lhb" );
      } /* if */
   NUMFILE = NUMFILE + 1;
   } /* while */
   rename (ARCDEVICE+"db.lhb", ARCDEVICE+"arc" +
      TOSTR(NUMFILE-1) + ".lhb");
   backup ("s -u "+USERNAME+"/"+USERPASSWORD+"
      -f "+ARCDEVICE+"db.lhb"+" -qc DF");
   logprint (CTIMESTAMP() + "---File" + "db"+ CHKSUF +
      "created.\n");
   }
after /* after stop or Ctrl-C */
   {
   print ("---Stop backup system");
   if (CERROR != 0)
      logprint (CTIMESTAMP() + "---Error present:" +
               TOSTR(CERROR));
   logprint (CTIMESTAMP() + "---Stop backup system\n");
   }
iferr /* global */
   {
   print ("Error=" + TOSTR(CERROR) +
         ",LinError=" + TOSTR(LINERROR) +
         ",SysError=" + TOSTR(SYSERROR));
   logprint (CTIMESTAMP() + "---Error=" +
         TOSTR(CERROR) +
         ",LinError=" + TOSTR(LINERROR) +
         ",LinError=" + TOSTR(LINERROR));
   stop;
   }
/* ---------------------------------------------------------------- */

Для запуска данного файла сценария вводим команду:

lhb script -ft script.bsl -fl FILE.LOG

Утилита выполнит полное сохранение БД и затем будет ожидать 2:00, после чего повторит очередное полное сохранение в новый файл архива.