Продолжается подписка на наши издания! Вы не забыли подписаться?

Создание резервных копий в Cache

Автор: Бакулин Сергей

Предисловие

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

Методы и возможности

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

Копирование cache.dat

Самый простой способ создать резервную копию – это скопировать непосредственно файл базы данных. Каждая база данных Cache – это файл с фиксированным именем сache.dat. Откройте папку CacheSys\Mgr\Samples, и вы увидите базу данных примеров, поставляемых с Cache. Вместе с файлом cache.dat в этой папке хранится файл cache.lck. Если первый содержит описания классов, программы и непосредственно сами данные, т.е. многомерные хранимые массивы Cache, то cache.lck представляет собой флаг, сигнализирующий о том, что БД в этой папке смонтирована, т.е. Cache в любой момент может производить какие-либо операции с файлом. Разумеется, если внешними средствами начать копирование файла cache.dat, то никто не сможет гарантировать целостности полученного результата. Прежде всего необходимо размонтировать БД, запретив тем самым доступ к ней из Cache, после чего можно осуществлять любые операции над файлом. Размонтировать БД можно из Панели управления (Control Panel), для этого необходимо дважды нажать кнопкой мыши на разделе Локальные базы данных (Local Databases), в появившемся списке правой кнопкой мыши нажать на имени требуемой БД и выбрать пункт меню Размонтировать (Dismount). При этом из папки, в которой находится размонтированная БД, будет удален файл cache.lck.

Переместив cache.dat на нужную машину, можно смонтировать его с любой БД в помощью того же самого пункта меню.

Это самый удобный способ создания резервных копий. В результате его использования получается готовый к использованию файл cache.dat, который можно смонтировать с любой БД, открывая тем самым доступ пользователям к данным и программам, при этом даже не требуется перекомпиляции проекта. С другой стороны, с момента размонтирования БД пользователи не смогут подключиться к БД, причем время простоя системы будет расти с ростом объема хранимых данных.

Единственная причина, по которой БД размонтируется при снятии копии с cache.dat – это необходимость запретить пользователям изменение содержимого этого файла. Можно сделать это и другими способами, например, выставить «ключ 13». Интерактивная утилита ^SWSET позволяет выставлять (устанавливать значение в 1) или снимать (устанавливать значение в 0) специальные системные ключи. Например, ключ 13 означает подавлять все команды set и kill Cache ObjectScript. Если выставить этот ключ при помощи интерактивной утилиты, Панели управления (пункт меню Файл->Лицензия->Системный доступ (File->License->System Access)), либо при помощи точки входа %swset^SWSET(13,1), то все процессы, кроме текущего, при выполнении команды set или kill (в Cache это единственные операции, изменяющие данные) “подвиснут” и продолжат свое выполнение только когда ключ 13 будет снят. Это можно использовать вместо размонтирования БД, но нужно понимать, что копия БД будет иметь точно такое же состояние, что и оригинал на момент включения 13-го ключа, в том числе незакрытые транзакции. При переносе копии cache.dat на другую машину незакрытые транзакции необходимо обработать.

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

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

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

На первом проходе Cache копирует все блоки данных из БД во временную копию. Процесс этот может занимать значительное время при больших объемах данных и вполне вероятно, что часть БД будет изменена во время копирования. При этом все изменения в БД с момента начала создания резервной копии помечаются (рисунок 2).


Рисунок 1. Начало резервного копирования.

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


Рисунок 2. Первый проход. Все данные копируются, изменения помечаются

Для этого на последнем проходе (рисунок 4) Cache замораживает всех пользователей. При этом все операции записи в БД "подвисают" и пользователи перестают получать отклик от сервера. В это время Cache копирует последние изменения, не давая изменять БД. Обычно на последнем проходе количество данных, которые необходимо копировать, минимально, так что пользователи практически не замечают момента “подвисания”.


Рисунок 3. Второй проход. Измененные данные копируются, изменения помечаются

В любом случае, запускать эту процедуру необходимо в периоды наименьшей загрузки системы, с тем, чтобы минимизировать нагрузку.

Этим способом можно создать один из трех типов резервных копий:

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


Рисунок 4. Последний проход. Пользователи «заморожены». Копируются все оставшиеся данные.

Кумулятивный (Cumulative Backup). При создании такой резервной копии сохраняются все изменения, произошедшие с момента создания последней полной резервной копии. Чем больше времени прошло с момента создания полной копии, тем больший размер будет иметь файл кумулятивной копии, по мере накопления изменений. Наконец, наступит момент, когда размер файла кумулятивной резервной копии начнет сравниваться с размером полной. Восстановление данных с использованием кумулятивной копии происходит в два этапа – после восстановления данных с полной резервной копии необходимо добавить данные с последней кумулятивной копии БД.

Инкрементальный (Incremental Backup). Данный вид резервной копии включает в себя изменения, произошедшие с момента создания последней резервной копии, вне зависимости от ее типа. Серия инкрементальных копий, каждая из которых имеет небольшой размер, позволит на протяжении дня постоянно снимать актуальные данные, оказывая небольшое влияние на работу пользователей. С другой стороны, восстановление данных при помощи инкрементальных Backup требует наличия всей серии файлов резервных копий и восстановления с каждой из них.


Рисунок 5. Панель управления, раздел Сохранение.

Разумеется, выбор типов Backup и расписания, по которому будет проводиться снятие резервных копий, зависит только от политики компании и личных пристрастий системного администратора.

Для создания резервной копии может использоваться утилита Панель Управления (Control Panel). Раздел Сохранение (Backup) этой утилиты содержит три подраздела (рисунок 5).

Список баз данных (Database List) определяет набор БД, подлежащих процедуре резервного копирования. Нажав на этом разделе правой кнопкой мыши и выбрав пункт Редактировать (Edit…) можно изменить этот список, оставив в нем только те БД, для которых действительно нужны резервные копии (рисунок 6).

После того, как такой список определен, можно воспользоваться разделом Задачи (Tasks) и выполнить либо Полную (FullDBList), либо инкрементальную (IncrementalDBList), либо кумулятивную (CumuIncrDBList) копию всех БД из указанного заранее списке.


Рисунок 6. Редактирование списка БД для резервного копирования.

Одновременно несколько разных списков БД хранить нельзя. Кроме того, нельзя делать резервные копии баз данных, не помещенных в список.


Рисунок 7. Список задач по созданию резервных копий.

Дополнительно предоставлена возможность создать полную резервную копию всех БД, независимо от объявленного списка. Нажав правой кнопкой мыши на любом из этих разделов, можно либо изменить параметры запуска процедуры создания резервной копии (пункт меню Редактировать (Edit)), либо запустить процедуру Backup в меню Запустить (Run). Отчет о создании резервной копии выводится в специальное окно (Рисунок8)

Кроме того, все отчеты обо всех произошедших в системе резервных копиях отображаются в третьем, последнем, разделе Журнале регистрации (Logs).

Разумеется, использование графической утилиты существенно упрощает процесс создания резервной копии, делает его наглядным и удобным, но у этого режима есть несколько существенных недостатков: во-первых, для работы с утилитой Панель управления требуется наличие машины под управлением операционной системы Windows (до версии Cache 5.1, в которой будут реализованы Web-утилиты администрирования). Во-вторых, для запуска резервной копии требуется присутствие администратора.


Рисунок 8. Отчет о формировании резервной копии.

Для решения этих проблем существуют терминальные программы администрирования. Для работы с резервными копиями применяется программа ^BACKUP – интерактивное приложение, которое можно запускать на любой платформе, поддерживаемой Cache. Обратите внимание на имя программы – оно не содержит символа %, следовательно, данную программу можно запустить только из области %SYS. Напомню, что смена области происходит при помощи команды ZN:

ZN “%SYS”


Рисунок 9. Меню программы BACKUP.

Меню, появляющееся в терминале при запуске процедуры ^BACKUP представлено на рисунке 9.


Рисунок 10. Запуск процедуры резервного копирования.

Пункт 4 (Management Information) позволяет редактировать список БД, для которых необходимо снимать резервные копии. Необходимо помнить, что список БД, созданный при помощи утилиты ^BACKUP, может отличаться от списка, сформированного в Панели Управления. После того, как этот список создан, можно запустить процедуру создания резервной копии, выбрав пункт 1 (Backup) и указав один из уже знакомых вариантов создания резервной копии.

Такой способ резервного копирования не избавляет от необходимости присутствия оператора, но интерактивная утилита, разумеется, имеет соответствующие точки входа, позволяющий автоматизировать процесс создания резервной копии. Эта точка входа – процедура BACKUP программы DBACK.INT области %SYS. Процедура требует следующего набора аргументов:

BACKUP(arg,type,desc,out,kiljrn,logfile,mode,clrjrn,swjrn,nwjrnfil) 

Среди них основные:

Пример использования:

d BACKUP^DBACK("", "F", ”AtMidinght”, ”C:\Back.bck”,"", ”C:\Back.log”, "NOISY","","","")

В листинге 1 приведена программа, которая создает полную резервную копию БД из списка, созданного программой ^BACKUP. Файлы резервной копии вместе с отчетами помещаются в директорию C:\backup\, при этом имена файлов включают в себя тип резервной копии, дату и время создания (например, “F 2004-11-23 15-07-34.cbk”)

Листинг 1. Программа %zBackup.
%zBackup public 
/*смена области на %SYS, иначе программа не будет иметь доступа к ^DBACK*/ 
zn "%SYS" 
/*Имена файлов резервной копии и журнала резервного копирования. Состоит из типа копии, текущей даты и времени. Символы «:» в текущем времени заменены на “-“ функцией $TRANSLATE*/ 
set type="F" // тип резервной копии - Full
set backname=type_$TRANSLATE($ZDateTime($H,3),":","-")_".cbk" 
set logname="Log"_type_$TRANSLATE($ZDateTime($H,3),":","-")_".log" 
/*запуск процедуры создания резервной копии указанного типа*/ 
do BACKUP^DBACK("",type,"autoback","C:\backup\"_backname,
" ","C:\backup\"_logname,"NOISY","","","") 
quit

Следующая задача – автоматически выполнять данную программу, например, каждые 5 минут. Задачу можно решить двумя способами – используя внутренние планировщики Cache, либо воспользовавшись внешними средствами.

В первом случае в качестве планировщика используется системный класс Cache %SYSTEM.Task. Класс унаследован от %Library.Persistent, следовательно, объекты его можно создавать в памяти и сохранять в БД. Каждый сохраненный в БД объект класса %SYSTEM.Task представляет собой один элемент расписания – одну задачу, которая выполняется в соответствии с сформированным планом.

Совокупность значений свойств объекта класса %SYSTEM.Task определяет код, который будет выполняться, дату и время следующего запуска, а также результаты последнего выполнения задания. Алгоритм установления даты и времени выполнения задания представлен на рисунках.


Рисунок 11. Свойства класса %SYSTEM.Task, определяющие время выполнения задания.


Рисунок 12. Свойства класса %SYSTEM.Task, определяющие дату выполнения задания.

Пример задания приведен в листинге 2.

Листинг 2. Создание задания для запуска процедуры резервного копирования каждые 5 минут.
// Создадим переменную MyTask, хранящую ссылку на объект класса %SYSTEM.Task
set MyTask=##Class(%SYSTEM.Task).%New()
// Определим код, который будет выполняться по таймеру
set MyTask.ExecuteCode="d ^%zBackup"
// Определим период запуска процедуры - каждые 5 минут
// Запуск производится больше одного раза в день: 
set MyTask.DailyFrequency=1
//Период будет указан в минутах

set MyTask.DailyFrequencyTime=0
// Количество минут в периоде =3
set MyTask.DailyIncrement=3
// Начало запуска -16 часов 12 минут во внутреннем формате Cachе
set MyTask.DailyStartTime=$ZTH("16:12")
//Сохраняем элемент расписания
set rc=MyTask.%Save()

Очевидно, что использование заданий дает в руки администратора не только мощный, но и опасный инструмент. В самом деле, легко видеть опасность, таящуюся в следующем задании:

Листинг 3. Пример неприятного задания.
set task=##Class(%SYSTEM.Task).%New() 
set task.Name="Some fun…" 
set task.NameSpace="%SYS" 
set task.ExecuteCode= "do $zf(-1,""echo Y | Format C: "") " 
set task.TimePeriod=1 
set task.TimePeriodEvery=1 
set task.TimePeriodDay=7 
set task.DailyStartTime=54000 
do task.%Save()

И до наступления указанной даты ничего страшного с системой не произойдет. Желательно иметь возможность контролировать имеющиеся в системе задания. Для этого следует применять атрибуты-запросы класса %SYSTEM.Task. Например, запрос TaskListDetail позволить узнать значения свойств всех имеющихся в системе объектов класса %SYSTEM.Task.

К примеру, следующий код выведет в терминал идентификатор, код и время следующего запуска всех заданий текущего сервера Cache.

Листинг 4. Процедура, выводящая в текущее устройство список всех заданий.
set res= ##class(%ResultSet).%New("%SYSTEM.Task:TaskListDetail")
do res.Execute()
while res.Next()
{
  write res.Get("ID")," ",res.Get("Routine")
  write "начнется ", res.Get("Next Scheduled Date"), 
    res.Get("Next Scheduled Time"),!
}

В данном листинге используется системный класс %Library.ResultSet для работы с запросом, определенным в классе %SYSTEM.Task. Более подробную информацию об этом классе и его атрибутах можно посмотреть в документации Cache, раздел Class Reference Information.

Многим администраторам такой метод задания расписания может показаться неудобным. В этом случае для решения проблемы можно воспользоваться открытостью СУБД Cache, в которой предоставляется возможность запуска процедуры Cache командой операционной системы. Под Windows такой программой является css.exe, расположенная в директории CacheSys\bin\. Для других операционных систем (Unix, Linux, OpenVMS) используется программа сcontrol. Синтаксис запуска программы: css.exe <“cterminal” | ”console” | ”run”> <Имя конфигурации> <Имя программы> <Область>

Чтобы запустить в терминальном режиме процедуру ^%zBackup, созданную выше, необходимо воспользоваться командой

C:\CacheSys\Bin\css.exe cterminal CACHE5 "^%zBackup" %SYS

Очевидно, что если эту команду указать в любом планировщике (например, Windows Scheduler, рисунок 13), можно сформировать расписание создания резервных копий внешними средствами

Каким бы способом вы не воспользовались, при запуске процедуры может произойти ошибка, например, обращение к неопределенной переменой. Очевидно, что можно заранее реализовать соответствующие проверки, но также очевидно, что чем сложнее код приложения, тем больше вероятность возникновения в нем ошибок. Недобросовестные пользователи вполне могут воспользоваться брешью в системе и использовать ошибки программы в своих целях. В любом случае, полезно тем или иным образом обрабатывать возникающие ошибки. В простейшем случае это может быть простой аудит, т.е. запись информации о произошедшей ошибке в БД. Для этого применяется системная переменная $ETRAP. Значением переменной $ETRAP является команда Cache ObjectScript, которая будет выполнена при возникновении ошибки. В общем случае эта команда – запуск пользовательской программы, которой передается управление. Дополним наш пример обработчиком ошибок:

Листинг 5. Добавление обработчика ошибок в процедуру создания резервной копии.
%zBackup public 
Set $ETRAP="do MyErr^%zBackup"
zn "%SYS" 
set type="F" // тип резервной копии - Full
set backname=type_$TRANSLATE($ZDateTime($H,3),":","-")_".cbk" 
set logname="Log"_type_$TRANSLATE($ZDateTime($H,3),":","-")_".log" 
/*запуск процедуры создания резервной копии указанного типа*/ 
do BACKUP^DBACK("",type,"autoback","C:\backup\"_backname,
" ","C:\backup\"_logname,"NOISY","","","") 
quit
MyErr
s ^MySysLog($ZDT($H),"Error")=$ZERROR
s ^MySysLog($ZDT($H),"User")=$ZU(67,11,$JOB)
quit


Рисунок 13. Работа внешних планировщиков с Cache.

Теперь запуск процедуры резервного копирования будет сопровождаться аудитом всех программных ошибок, записанных в глобал ^MySysLog, индексированный по текущей дате. В этот глобал будет записано описание произошедшей ошибки (тип ошибки+строка кода) и системное имя пользователя.

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

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

do CLRINC^DBACK(1). 

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

Идея такого подхода заключается в том, что процедуру копирования cache.dat внешними средствами можно произвести значительно быстрее, чем полную резервную копию средствами Cache. Это позволит существенно сократить время нагрузки на систему.

Как видите, Cache предоставляет довольно широкие возможности по обеспечению сохранности и целостности данных. Используя любой из представленных способов или их комбинацию можно строить действительно надежные системы.


Copyright © 1994-2016 ООО "К-Пресс"