Управление данными в оперативной памяти
В этом подразделе приводится классификация СУБД, и рассматриваются основные их функции. В качестве основных классификационных признаков можно использовать следующие: вид программы, характер использования, модель данных. Названные признаки существенно влияют на целевой выбор СУБД и эффективность использования разрабатываемой информационной системы.
Система управления базами данных (СУБД) – это важнейший компонент АИС, основанной на базе данных. СУБД необходима для создания и поддержки базы данных информационной системы в той же степени, как для разработки программы на алгоритмическом языке – транслятор. Программные составляющие СУБД включают в себя ядро и сервисные средства (утилиты).
Ядро СУБД – это набор программных модулей, необходимый и достаточный для создания и поддержания БД, то есть универсальная часть, решающая стандартные задачи по информационному обслуживанию пользователей. Сервисные программы предоставляют пользователям ряд дополнительных возможностей и услуг, зависящих от описываемой предметной области и потребностей конкретного пользователя.
Классификация СУБД.
В общем случае под СУБД можно понимать любой программный продукт, поддерживающий процессы создания, ведения и использования БД. Рассмотрим какие из имеющихся на рынке программ имеют отношение к БД и в какой мере они связаны с базами данных.
К СУБД относятся следующие основные виды программ:
- средства разработки программ работы с БД.
Полнофункциональные СУБД (ПФСУБД) представляют собой традиционные СУБД, которые сначала появились для больших машин, затем для мини-машин и для ПЭВМ. Из числа всех СУБД современные ПФСУБД являются наиболее многочисленными и мощными по своим возможностям. К ПФСУБД относятся, например, такие пакеты как: Clarion Database Developer, DataBase, Dataplex, dBase IV, Microsoft Access, Microsoft FoxPro и Paradox R: BASE.
Обычно ПФСУБД имеют развитый интерфейс, позволяющий с помощью команд меню выполнять основные действия с БД: создавать и модифицировать структуры таблиц, вводить данные, формировать запросы, разрабатывать отчеты, выводить их на печать и т. п. Для создания запросов и отчетов не обязательно программирование, а удобно пользоваться языком QBE (Query By Example - формулировки запросов по образцу, см. подраздел 3.8). Многие ПФСУБД включают средства программирования для профессиональных разработчиков.
Некоторые системы имеют в качестве вспомогательных и дополнительные средства проектирования схем БД или CASE-подсистемы. Для обеспечения доступа к другим БД или к данным SQL-серверов полнофункциональные СУБД имеют факультативные модули.
Серверы БД предназначены для организации центров обработки данных в сетях ЭВМ. Эта группа БД в настоящее время менее многочисленна, но их количество постепенно растет. Серверы БД реализуют функции управления базами данных, запрашиваемые другими (клиентскими) программами обычно с помощью операторов SQL.
Примерами серверов БД являются следующие программы: NetWare SQL (Novell), MS SQL Server (Microsoft), InterBase (Borland), SQLBase Server (Gupta), Intelligent Database (Ingress).
В роли клиентских программ для серверов БД в общем случае могут использоваться различные программы: ПФСУБД, электронные таблицы, текстовые процессоры, программы электронной почты и т. д. При этом элементы пары "клиент - сервер" могут принадлежать одному или разным производителям программного обеспечения.
В случае, когда клиентская и серверная части выполнены одной фирмой, естественно ожидать, что распределение функций между ними выполнено рационально. В остальных случаях обычно преследуется цель обеспечения доступа к данным "любой ценой". Примером такого соединения является случай, когда одна из полнофункциональных СУБД играет роль сервера, а вторая СУБД (другого производителя) - роль клиента. Так, для сервера БД SQL Server (Microsoft) в роли клиентских (фронтальных) программ могут выступать многие СУБД, такие как: dBASE IV, Biyth Software, Paradox, DataEase, Focus, 1-2-3, MDBS III, Revelation и другие.
Средства разработки программ работы с БД могут использоваться для создания разновидностей следующих программ:
- серверов БД и их отдельных компонентов;
Программы первого и второго вида довольно малочисленны, так как предназначены, главным образом, для системных программистов. Пакетов третьего вида гораздо больше, но меньше, чем полнофункциональных СУБД.
К средствам разработки пользовательских приложений относятся системы программирования, например Clipper, разнообразные библиотеки программ для различных языков программирования, а также пакеты автоматизации разработок (в том числе систем типа клиент-сервер). В числе наиболее распространенных можно назвать следующие инструментальные системы: Delphi и Power Builder (Borland), Visual Basic (Microsoft), SILVERRUN (Computer Advisers Inc.), S-Designor (SDP и Powersoft) и ERwin (LogicWorks).
Кроме перечисленных средств, для управления данными и организации обслуживания БД используются различные дополнительные средства, к примеру, мониторы транзакций
По характеру использования СУБД делят на персональные и многопользовательские.
Персональные СУ БД обычно обеспечивают возможность создания персональных БД и недорогих приложений, работающих с ними. Персональные СУБД или разработанные с их помощью приложения зачастую могут выступать в роли клиентской части многопользовательской СУБД. К персональным СУБД, например, относятся Visual FoxPro, Paradox, Clipper, dBase, Access и др
Многопользовательские СУБД включают в себя сервер БД и клиентскую часть и, как правило, могут работать в неоднородной вычислительной среде (с разными типами ЭВМ и операционными системами). К многопользовательским СУБД относятся, например, СУБД Oracle и Informix.
По используемой модели данных СУБД (как и БД), разделяют на иерархические, сетевые, реляционные, объектно-ориентированные и другие типы. Некоторые СУБД могут одновременно поддерживать несколько моделей данных.
С точки зрения пользователя, СУБД реализует функции хранения, изменения (пополнения, редактирования и удаления) и обработки информации, а также разработки и получения различных выходных документов.
Для работы с хранящейся в базе данных информацией СУБД предоставляет программам и пользователям следующие два типа языков :
- язык описания данных - высокоуровневый непроцедурный язык декларативного типа, предназначенный для описания логической структуры данных;
- язык манипулирования данными - совокупность конструкций, обеспечивающих выполнение основных операций по работе с данными: ввод, модификацию и выборку данных по запросам.
Названные языки в различных СУБД могут иметь отличия. Наибольшее распространение получили два стандартизованных языка: QBE (Query By Example) - язык запросов по образцу и SQL (Structured Query Language) - структурированный язык запросов. QBE в основном обладает свойствами языка манипулирования данными, SQL сочетает в себе свойства языков обоих типов - описания и манипулирования данными.
Перечисленные выше функции СУБД, в свою очередь, используют следующие основные функции более низкого уровня, которые назовем низкоуровневыми:
- управление данными во внешней памяти;
- управление буферами оперативной памяти;
- ведение журнала изменений в БД;
- обеспечение целостности и безопасности БД. Дадим краткую характеристику необходимости и особенностям реализации перечисленных функций в современных СУБД.
Реализация функции управления данными во внешней памяти в разных системах может различаться и на уровне управления ресурсами (используя файловые системы ОС или непосредственное управление устройствами ПЭВМ), и по логике самих алгоритмов управления данными. В основном методы и алгоритмы управления данными являются "внутренним делом" СУБД и прямого отношения к пользователю не имеют. Качество реализации этой функции наиболее сильно влияет на эффективность работы специфических ИС, например, с огромными БД, со сложными запросами, большим объемом обработки данных.
Необходимость буферизации данных и как следствие реализации функции управления буферами оперативной памяти обусловлено тем, что объем оперативной памяти меньше объема внешней памяти.
Буферы представляют собой области оперативной памяти, предназначенные для ускорения обмена между внешней и оперативной памятью. В буферах временно хранятся фрагменты БД, данные из которых предполагается использовать при обращении к СУБД или планируется записать в базу после обработки. Механизм транзакций используется в СУБД для поддержания целостности данных в базе.
Транзакцией называется некоторая неделимая последовательность операций над данными БД, которая отслеживается СУБД от начала и до завершения. Если по каким-либо причинам (сбои и отказы оборудования, ошибки в программном обеспечении, включая приложение) транзакция остается незавершенной, то она отменяется.
Говорят, что транзакции присущи три основных свойства:
- атомарность (выполняются все входящие в транзакцию операции или ни одна);
- сериализуемость (отсутствует взаимное влияние выполняемых в одно и то же время транзакций);
- долговечность (даже крах системы не приводит к утрате результатов зафиксированной транзакции).
Примером транзакции является операция перевода денег с одного счета на другой в банковской системе. Здесь необходим, по крайней мере, двухшаговый процесс. Сначала снимают деньги с одного счета, затем добавляют их к другому счету. Если хотя бы одно из действий не выполнится успешно, результат операции окажется неверным и будет нарушен баланс между счетами.
Контроль транзакций важен в однопользовательских и в многопользовательских СУБД, где транзакции могут быть запущены параллельно. В последнем случае говорят о сериализуемости транзакций. Под сериализацией параллельно выполняемых транзакций понимается составление такого плана их выполнения (сериального плана), при котором суммарный эффект реализации транзакций эквивалентен эффекту их последовательного выполнения.
При параллельном выполнении смеси транзакций возможно возникновение конфликтов (блокировок), разрешение которых является функцией СУБД. При обнаружении таких случаев обычно производится "откат" путем отмены изменений, произведенных одной или несколькими транзакциями.
Ведение журнала изменений в БД (журнализация изменений) выполняется СУБД для обеспечения надежности хранения данных в базе при наличии аппаратных сбоев и отказов, а также ошибок в программном обеспечении.
Журнал СУБД - это особая БД или часть основной БД, непосредственно недоступная пользователю к используемая для записи информации обо всех изменениях базы данных. В различных СУБД в журнал могут заноситься записи, соответствующие изменениям в СУБД на разных уровнях: от минимальной внутренней операции модификации страницы внешней памяти до логической операции модификации БД (например, вставки записи, удаления столбца, изменения значения в поле) и даже транзакции.
Для эффективной реализации функции ведения журнала изменений в БД необходимо обеспечить повышенную надежность хранения и поддержания в рабочем состоянии самого журнала. Иногда для этого в системе хранят несколько копий журнала.
Обеспечение целостности БД составляет необходимое условие успешного функционирования БД, особенно для случая использования БД в сетях. Целостность БД, есть свойство базы данных, означающее, что в ней содержится полная, непротиворечивая и адекватно отражающая предметную область информация.
Поддержание целостности БД включает проверку целостности и ее восстановление в случае обнаружения противоречий в базе данных. Целостное состояние БД описывается с помощью ограничений целостности в виде условий, которым должны удовлетворять хранимые в базе данные. Примером таких условий может служить ограничение диапазонов возможных значений атрибутов объектов, сведения о которых хранятся в БД, или отсутствие повторяющихся записей в таблицах реляционных БД.
Обеспечение безопасности достигается в СУБД шифрованием прикладных программ, данных, защиты паролем, поддержкой уровней доступа к базе данных и к отдельным ее элементам (таблицам, формам, отчетам и т. д.).
Универсальные СУБД — фундамент ИТ-инфраструктуры современного предприятия — часто оказываются не в состоянии обеспечить операционные характеристики, требуемые для решения целого ряда задач оперативной обработки информации в распределенной вычислительной среде. Должную производительность, время отклика и пропускную способность могут гарантировать механизмы, обеспечивающие работу с базами в оперативной памяти компьютера.
Среди подобных решений особое место занимают реляционные системы управления базами данных в оперативной памяти (in-memory/main memory database, IMDB/MMDB). Благодаря стандартизованным интерфейсам они могут обслуживать множество программ, обеспечивая высокую реактивность и пропускную способность систем при пиковых нагрузках, позволяя тем самым решать задачи сбора, интеграции, обработки и анализа информации в близком к реальному масштабе времени, которые централизованные СУБД поддерживать просто не в состоянии. В традиционной трехзвенной архитектуре «клиент — сервер приложений — мощный сервер реляционных СУБД» приложение далеко не всегда в состоянии предоставить и обработать всю необходимую информацию тогда и там, где это необходимо: по мере роста систем централизованные сервисы доступа к информационным ресурсам оказываются чрезмерно ресурсоемкими и дефицитными, причем экстенсивное наращивание мощностей корпоративных серверов и систем хранения данных проблему не снимает.
Высокопроизводительные системы, поддерживающие базы данных в оперативной памяти, предлагают сегодня корпорации IBM (solidDB), Oracle (TimesTen) и Sun Microsystems (SQL Cluster), специализированные компании ENEA (Polyhedra), McObject (eXtremeDB), Birdstep Technology (Raima Data Manager), Altibase (Altibase), а также представители сообщества Open Source (в том числе CSQL, MonetDB, H2 DBMS и HSQLDB). Именно с помощью таких продуктов в информационных системах операторов связи, фондовых бирж и банков, авиакомпаний, торговых и транспортных сетей, промышленных предприятий, научно-исследовательских организаций, оборонных и специальных структур сегодня ежесекундно выявляются и регистрируются миллионы фактов, анализируются происходящие события, принимаются обоснованные решения и перераспределяются потоки данных и работ.
Освободиться от дисков
Как известно, общая производительность традиционных систем ограничена скоростью выполнения операции обмена с внешними устройствами, поэтому применяются механизмы управления буферами и кэширования, индексирования, оптимизации обработки запросов, распределение баз данных во внешней памяти, распараллеливание обработки запросов на мультипроцессорах, кластерные решения, сегментирование и даже специализированные аппаратно-программные решения.
Техника кэширования основана на временном хранении копии данных в буферной памяти. Например, процессорный кэш обеспечивает эффективный обмен между процессором и оперативной памятью, благодаря дисковому кэшу сокращается число обращений к внешней памяти, сетевой кэш за счет сохранения HTML-страниц и их фрагментов позволяет сократить сетевой трафик и нагрузку на Web-серверы и серверы приложений. Буферный кэш СУБД и механизм управления им обеспечивает своевременное считывание и возврат страниц баз данных во внешнюю память. Именно в этой области памяти прозрачно для прикладной программы осуществляются операции манипулирования данными: программа обращается к исполнительной системе СУБД, та, оптимизировав запрос, определяет адреса нужных страниц на диске, перемещает их целиком в кэш, выполняет необходимые преобразования и передает нужные данные программе. Измененные данные возвращаются на диск, и они проделывают обратный путь (рис. 1а).
Конечно, чем большую часть базы данных удастся разместить в буферном кэше, тем с большей скоростью будет происходить обработка. Однако, несмотря на то, что современные серверы, операционные системы и СУБД позволяют полностью кэшировать базы данных объемом в десятки и сотни гигабайт, предельная производительность системы по-прежнему определяется традиционной архитектурой механизма управления данными, нацеленного на минимизацию числа операций обмена данными между медленной внешней памятью и прикладными программами. До сих пор в кэше приходится держать полные образы страниц данных на диске, структура индексов соответствует страничной организации данных, а доступ осуществляется через менеджер буферного пула.
Радикально улучшить производительность можно, освободив СУБД на время исполнения программы от необходимости обращаться к внешним запоминающим устройствам (рис. 1б). В «бездисковой» СУБД все пользовательские и системные таблицы, каталоги, индексы, буферы системного журнала, таблицы блокировок, временные области и другие объекты эффективно располагаются в оперативной памяти, что позволяет существенно «облегчить» архитектуру. Структура индексов также претерпевает изменения — они становятся компактнее, поскольку при доступе к данным не требуется минимизация количества операций ввода-вывода. В алгоритмах обработки запросов главным критерием выбора оптимального плана становится не число обращений к внешней памяти, а вычислительная «стоимость» операции и эффективная загрузка процессора. Наконец, более эффективно решается ряд задач администрирования, например борьба с фрагментацией памяти. В результате по времени реакции и пропускной способности система, в которой работа базы данных происходит в оперативной памяти, значительно выигрывает даже по сравнению с решением с полностью кэшированной базой традиционной «дисковой» СУБД. Так, например, в тесте Telecom One, имитирующем рабочую нагрузку в телекоммуникационных приложениях при 100 тыс. мобильных абонентах, пропускная способность системы IBM solidDB оказалась в среднем в десять раз выше, чем у традиционных СУБД.
Долговременное хранение
Но как обеспечить физическую целостность базы данных, если оперативная память компьютера энергозависима, и при отключении или отказе сервера СУБД данные будут потеряны? Для этого применяются локальные или сетевые процедуры резервного копирования и восстановления, а в качестве оперативных механизмов — периодическое сохранение «моментальных снимков» состояния базы данных и ведение системных журналов изменений на диске, а также репликация и синхронизация баз данных. При открытии состояние базы данных восстанавливается по контрольной точке, и дальнейшая обработка в памяти поддерживается эффективными механизмами управления конкурентным доступом, обработки транзакций и блокирования ресурсов. При записи контрольной точки все зафиксированные транзакции сбрасываются из буфера журнала во внешнюю память, а между контрольными точками в журнал вносятся транзакции по мере фиксации, что обеспечивает возможность восстановления в случае системного отказа. Применение механизма контрольных точек без ведения системного журнала обеспечивает более высокую производительность, но в аварийной ситуации дает возможность вернуться только к предыдущему целостному состоянию. В зависимости от специфики приложения и требуемого баланса между производительностью и обеспечением сохранности данных в промежутках между контрольными точками запись изменений в журнал относительно момента фиксации транзакции может осуществляться синхронно или асинхронно. В системах Altibase и IBM solidDB реализовано гибридное решение — сервер СУБД содержит два механизма управления данными: один оптимизирован для доступа к диску, а другой ориентирован на хранение данных в оперативной памяти. Прикладная программа может обращаться и к тем, и к другим данным с помощью одного оператора SQL.
Уровень изоляции определяется спецификой прикладных задач: одни должны монопольно «захватывать» обрабатываемые данные, в других допускается определенная степень вмешательства со стороны выполняемых параллельно программ. В СУБД в оперативной памяти чтение результатов незафиксированных транзакций не предусмотрено, поэтому поддерживаются три уровня изоляции транзакций: Read Committed (чтение результатов только зафиксированных транзакций — это достаточный уровень изоляции для большинства приложений); Repeatable Read (чтение результатов только зафиксированных транзакций с гарантией того, что данные остаются неизменными до фиксации транзакции); Serializable (наивысший уровень изолированности — результат конкурирующих транзакций должен быть таким же, как после их последовательного выполнения).
В традиционной СУБД изоляция транзакций реализуется с помощью хэш-таблиц, указывающих на блокируемые объекты, а при хранении баз данных в оперативной памяти соответствующие признаки могут встраиваться непосредственно в объекты базы данных, и это дает возможность оптимизировать алгоритмы управления блокировками. В ряде систем, например в Oracle TimesTen, с целью поддержки распределенных транзакций предусмотрен интерфейс для программного мониторинга изменений, регистрируемых в журнале (Transaction Log API, XLA), и инициализации соответствующих действий (применения изменений к внешним базам данных, рассылки уведомлений и т.п.).
Архитектура передового развертывания
На рис. 2 представлена укрупненная схема взаимодействия компонентов системы баз данных, поддерживаемых в оперативной памяти.
СУБД в оперативной памяти могут применяться как в компактных решениях, встраиваемых в специализированные приложения и устройства, так и в крупных проектах масштаба предприятия, в которых множество приложений в сервис-ориентированной архитектуре (Service-Oriented Architecture, SOA) обеспечивают решение задач по периметру сетевой инфраструктуры компании. Сбор, обработка и предоставление данных в реальном масштабе времени нужны для поддержки персонализированных форм взаимодействия с пользователями, гармонизации бизнес-процессов и упрощения внутренних операций, обработки информационных потоков и доставки данных мультимедиа. Организациям практически любого масштаба и направления деятельности необходимы приложения, развертываемые как можно ближе к источникам и местам потребления информации, причем дополнительные выгоды для заказчиков могут обеспечить средства поддержки баз данных в оперативной памяти, интегрируемые с корпоративными СУБД.
В дополнение к основному уровню хранения данных (back-end) целесообразно, опираясь на совокупные ресурсы оперативной памяти распределенной серверной платформы, иметь облегченные и в то же время более производительные механизмы управления и среду хранения данных на «переднем плане» (front-end) непосредственно на серверах приложений и периферийных узлах. Для этого используются различные архитектурные схемы развертывания решения: библиотека функций СУБД, подключаемая непосредственно к прикладной программе, сервер IMDB, обслуживающий прикладные программы; дополнительно могут применяться функциональные компоненты, обеспечивающие кэширование основной базы данных, и отказоустойчивые конфигурации. Во всех этих схемах действует единый интерфейс прикладного программирования.
Такие решения могут быть относительно автономными, например, в телекоммуникационных приложениях реального времени и интеллектуальных устройствах для сбора и обмена данными о поступающих вызовах, состоянии сети, перемещении абонентов и т.п. В системах обработки потоков данных, поступающих по коммерческим, новостным и технологическим каналам, в интеграционных решениях и системах бизнес-аналитики усиленные с их помощью узлы хранения данных и управления транзакциями позволяют распределить нагрузку и разгрузить корпоративные серверы, а в системах резервирования билетов, мест в гостиницах, в электронной торговле и системах поддержки коллективной работы они могут обеспечить вертикальное или горизонтальное партиционирование баз данных и ускорение доступа к их интенсивно используемым подмножествам. Наконец, на их базе может быть развернут синхронизируемый с основной «дисковой» базой данных быстродействующий локальный или распределенный кэш основной базы данных, способный справляться с пиковыми нагрузками на корпоративные системы.
Отказоустойчивость
Системы управления базами данных в оперативной памяти позволяют реализовать отказоустойчивые конфигурации с основным и резервным узлами СУБД, в которых обеспечивается постоянная автоматическая синхронизация на уровне системы, сеанса или транзакции, что позволяет сбалансировать пропускную способность, сохранность данных и время восстановления системы, а при отказе практически мгновенно переключать ресурсы (рис. 3). К тому же наличие постоянно готовой копии системы позволяет, не отключая основной сервер, параллельно выполнять вспомогательные работы: формирование отчетности, резервное копирование, установку обновлений программного обеспечения и т.д.
Кэширование баз данных
Механизм управления данными в оперативной памяти позволяет поддерживать локальный или распределенный кэш основной базы данных в виде копий ее фрагментов, реплицируемых в памяти на серверах приложений, «приближенных» к месту создания или использования данных. Кэшируемые фрагменты основной базы данных, в качестве которых могут выступать одна или несколько таблиц, их «горизонтальные» проекции или «вертикальные» подмножества строк, определяются в рамках установленных структурных ограничений администратором баз данных с помощью операторов расширения SQL или дополнительных инструментов.
Прикладным программам доступны высокопроизводительные сервисы СУБД в оперативной памяти для хранения и обработки данных, управления конкурентным доступом и транзакциями и обеспечения отказоустойчивости, причем благодаря использованию аналогичных с основной СУБД интерфейсов, взаимодействие с кэшем и основной базой данных «прозрачно» для приложения. После загрузки из основной базы данные могут считываться или обновляться непосредственно в кэше подключенными к нему (локально или по сети) прикладными программами. Двусторонний трафик при загрузке, периодической подкачке, синхронизации данных (в синхронном или асинхронном режиме) обрабатывает специальный программный агент — коннектор кэша и основной базой данных. Управление осуществляется автоматически в соответствии с параметрами, установленными по умолчанию или задаваемыми администратором баз данных, а также на уровне прикладной программы, при этом обеспечивается восстановление системы в аварийных ситуациях.
Такое решение позволяет разгрузить корпоративные серверы хранения данных и обеспечить необходимые операционные характеристики для высоко реактивных масштабируемых приложений реального времени, обработки транзакций, а также ведения условно-постоянной, нормативно-справочной информации, профилей пользователей, данных о конфигурации и т.д.
Распределенные базы данных
Сервисы управления базами данных должны быть непрерывными, в особенности для критических задач. Благодаря возможности репликации баз данных непосредственно в оперативной памяти на узлах сети, данные можно расположить настолько «близко» к приложениям, насколько этого требует быстродействие, пропускная способность или доступность решения, например, в сетях доставки мультимедиа-контента, телекоммуникационных системах и устройствах и т.д.
Высокопроизводительные механизмы синхронной и асинхронной (на основе модели публикации и подписки) репликации и синхронизации баз данных встраиваются в СУБД в оперативной памяти и используют такие их возможности, как управление транзакциями и поддержка расширений SQL, позволяющих достаточно быстро разрабатывать распределенные приложения, максимально отражающие специфику реальной задачи, например, способность выявлять и разрешать конфликты, исходя из бизнес-правил и логики.
В распределенной системе основная база содержит «эталонные» данные, которые реплицируются на одну или несколько копий. Копия может иметь несколько таблиц, одни из которых содержат только копии эталонных данных, другие — только локальные значения, а третьи некоторую их смесь. Изменения, внесенные в какую-либо из копий передаются на главный сервер, который верифицирует их в соответствии с заданными правилами, и после проверки рассылаются на остальные копии (рис. 4). При этом в зависимости от требований решаемой задачи поддерживаются различные по производительности, организации взаимодействия и отказоустойчивости схемы репликации, разрешения конфликтов, восстановления баз данных и проводки изменений в реальном времени, в том числе ориентированные на решения, встраиваемые в устройства без дисков. Для управления репликацией применяются соответствующие операторы расширения SQL.
После приобретения в 2005 году «ветерана» СУБД в оперативной памяти компании TimesTen корпорацией Oracle последняя предлагает решение Oracle TimesTen, в состав которого входит сервер СУБД Oracle Timesten In-Memory Database и дополняющие его опции Replication — TimesTen to TimesTen для создания отказоустойчивых конфигураций и равномерного распределения нагрузки и Cache Connect to Oracle для кэширования баз данных Oracle на серверах приложений.
Объявленные в начале лета 2008 года три решения IBM SolidDB 6.1, работающие под управлением ОС Linux, HP/UX, AIX, Solaris и Z/OS — результат первого этапа интеграции технологий финской компании Solid Information Technology, приобретенной IBM годом ранее, в стек решений по управлению информацией по требованию. Два из них — IBM solidDB Cache для DB2 и IBM solidDB Cache для Informix Dynamic Server могут быть развернуты в дополнение к серверам СУБД для увеличения производительности за счет кэширования основной базы данных, а третье — IBM solidDB — благодаря сдвоенному гибридному механизму СУБД поддерживает базы данных в оперативной памяти и на дисках.
На рынке систем управления базами данных в оперативной памяти заметно присутствие не только лидеров, но и «чистых» игроков, таких как шведская компания ENEA, которая с 1993 года предлагает семейство реляционных СУБД в оперативной и флэш-памяти Polyhedra для мобильных устройств и клиент-серверных приложений, требующих максимальной производительности и надежности в системах с интенсивными информационными потоками, например в беспроводных сетях и промышленных системах управления. К таким игрокам относятся и южнокорейская компания Altibase с одноименной гибридной системой, и поставщики встраиваемых СУБД McObject с eXtremeDB и Birdstep Technology с Raima Data Manager (в эту группу следует включить и поставляемую Oracle систему Berkley DB), а также таких систем категории Open Source, как CSQL, FastDB, MonetDB, H2 и HSQLDB.
На системы управления базами данных в оперативной памяти приходится от 0,5 до 1% современного рынка СУБД, и этот сегмент, по мнению аналитиков IDC, еще только формируется. Решения этого класса не следует рассматривать как альтернативу корпоративным СУБД — их применение оправданно в особо ответственных ситуациях в качестве инструмента существенного повышения производительности, надежности и пропускной способности, дополняющего корпоративный портфель средств управления данными.
Рис. 1. Доступ приложения к базе данных: а) в традиционной системе; б) в СУБД в оперативной памяти (Oracle TimesTen)
Рис. 2. Схема взаимодействия компонентов системы баз данных, поддерживаемых в оперативной памяти с репликацией и кэшированием основной базы данных. Решение Oracle TimesTen
Рис. 3. Отказоустойчивые конфигурации: а) основной и резервный сервер: б) два активных сервера; в) активный и несколько резервных серверов IMDB. Решение Altibase
Рис. 4. Различные схемы репликации баз данных: односторонняя а) с одной копией, б) с несколькими копиями, в) двусторонняя, г) многосторонняя. Решение Oracle TimesTen Replication
Всем привет. Кто-то из вас, возможно, уже знаком с СУБД для данных в оперативной памяти, но на всякий случай — по ссылке можно найти их общее описание. Если вкратце, такие СУБД хранят данные целиком в оперативной памяти. Что это означает? Каждый раз, отправляя запрос на поиск или обновление данных, вы обращаетесь только к оперативной памяти в обход жесткого диска — на нем никакие операции не производятся. И это хорошо, потому что оперативная память работает намного быстрее любого диска. Примером такой СУБД является Memcached.
Секундочку, скажете вы, а как же восстановить данные после перезагрузки или поломки машины с такой СУБД? Если на машине установлена СУБД для хранения данных только в оперативной памяти, о них можно забыть: при отключении питания данные бесследно исчезнут.
Можно ли объединить достоинства хранения данных в оперативной памяти с надежностью проверенных временем СУБД вроде MySQL или Postgres? Конечно! Повлияет ли это на производительность? Вы удивитесь, но нет!
Встречайте СУБД для данных в оперативной памяти, обеспечивающие их сохранность: Redis, Aerospike, Tarantool.
Вы можете спросить, как же эти СУБД обеспечивают сохранность данных? Фокус в том, что все данные по-прежнему хранятся в оперативной памяти, но каждая операция вдобавок записывается в расположенный на диске журнал транзакций. Посмотрите на изображение ниже:
Транзакции всегда записываются в самый конец журнала. В чем плюс такого подхода? Диск работает довольно быстро. Если говорить о классическом жестком диске (HDD), он может записывать данные в конец файла со скоростью до 100 Мбайт/с. Не верите? Запустите этот тест из командной строки в Unix/Linux/macOS:
И посмотрите, как быстро увеличивается размер some_file . Итак, жесткий диск весьма проворен при последовательной записи, однако его скорость резко падает при произвольной записи: обычно он способен выполнить около 100 таких операций.
При побайтовой записи, когда каждый байт записывается в произвольное место на жестком диске, вы можете увидеть, что реальная максимальная производительность диска составляет 100 байтов/с. Еще раз, всего-навсего 100 байтов/с! Разница в шесть порядков между пессимистичной (100 байтов/с) и оптимистичной (100 000 000 байтов/с) оценками скорости доступа к диску столь велика потому, что для поиска по произвольному сектору на диске требуется физическое движение головки диска, тогда как при последовательном доступе можно считывать данные по мере вращения диска; головка при этом остается неподвижной.
Если говорить о твердотельном накопителе (SSD), здесь ситуация лучше из-за отсутствия движущихся частей. Однако соотношение пессимистичной (1—10 тысяч операций в секунду) и оптимистичной (200—300 Мбайт/с) оценок остается практически неизменным: четыре-пять порядков. Подробнее с этими показателями можно ознакомиться по ссылке.
Таким образом, наша СУБД для данных в оперативной памяти, по сути, наводняет журнал транзакциями со скоростью до 100 Мбайт/с. Достаточно ли это быстро? Очень быстро. Предположим, размер транзакции составляет 100 байтов, тогда скорость будет равняться миллиону транзакций в секунду! Это настолько хороший показатель, что вам абсолютно точно не придется волноваться о производительности диска при использовании подобной СУБД. По ссылке ниже находится подробный тест производительности одной СУБД в оперативной памяти при обработке миллиона транзакций в секунду, где проблемным элементом является не диск, а процессор:
Подведем итог всему вышесказанному о дисках и СУБД в оперативной памяти:
- СУБД в оперативной памяти не обращаются к диску при обработке запросов, не изменяющих данные.
- СУБД в оперативной памяти все-таки обращаются к диску при обработке запросов, изменяющих данные, но работают с ним на максимальной скорости.
Во-вторых, дисковые СУБД должны сохранять данные таким образом, чтобы измененные данные можно было немедленно считать, в отличие от СУБД в оперативной памяти, которые не считывают с диска, за исключением случаев, когда при старте запускается восстановление. Именно поэтому для быстрого считывания дисковым СУБД нужны особые структуры данных, чтобы избежать полного сканирования журнала транзакций.
Одна из таких структур — B/B+-дерево, ускоряющее считывание данных. Недостатком этого дерева является необходимость изменять его при каждом меняющем данные запросе, что может привести к падению производительности из-за произвольного доступа к диску. Довольно много движков СУБД основано на B/B+-деревьях, из популярных можно назвать InnoDB от MySQL и движок Postgres.
Существует другая структура, которая лучше справляется с записью данных, — LSM-дерево. Это относительно новый тип деревьев, который не решает проблему произвольного считывания, но помогает избавиться от части проблем, связанных с произвольной записью. Примерами движков, использующих такие деревья, могут служить RocksDB, LevelDB или Vinyl. На изображении ниже приведена сводная информация о типах СУБД и используемых ими деревьях:
Резюмируем вышесказанное: СУБД в оперативной памяти, обеспечивающие сохранность данных, как при считывании, так и при записи могут работать очень быстро, а точнее — так же быстро, как и СУБД в оперативной памяти, которые не сохраняют данные на диске: первые используют диск настолько эффективно, что он никогда не становится проблемным местом.
Последняя — по порядку, но не по значимости — тема, которую я хотел бы затронуть в статье, посвящена снимкам состояния. Снятие таких снимков необходимо для компактификации журналов транзакций. Снимок состояния базы данных — это копия всех имеющихся данных. Снимка и журналов с последними транзакциями достаточно для восстановления состояния вашей базы данных. Поэтому, имея свежий снимок состояния, можно удалять все старые журналы транзакций, предшествующие дате снимка.
Зачем компактифицировать журналы? Потому что чем больше журналов, тем дольше будет восстановление базы данных. И потом, вам ведь не хочется захламлять диск устаревшей и бесполезной информацией (ну хорошо, старые журналы иногда здорово выручают, но давайте поговорим об этом в отдельной статье).
По сути, периодически делая снимки состояния, вы целиком копируете базу данных из оперативной памяти на диск. Как только копирование закончилось, можно смело удалять все журналы, в которых нет транзакций, записанных позже последней транзакции в вашем снимке состояния. Довольно просто, не так ли? А все потому, что все транзакции начиная с самого первого дня попадают в снимок.
Вы могли задаться вопросом: как сохранить консистентное состояние базы данных на диск и как определить последнюю зафиксированную в снимке транзакцию при условии постоянного поступления новых транзакций? Об этом мы поговорим в следующей статье.
Для понимания принципов построения систем управления базами данных напомним ряд известных определений.
База данных— это набор структурированной информации, предназначенной для совместного употребления несколькими пользователями одновременно. Отдельные элементы данных связаны между собой логически. Структурированность означает, что данные имеют некоторую логическую структуру, некоторую схему, модель, которая связывает между собой отдельные данные. БД предполагает наличие некоторого программного обеспечения, позволяющего пользователю работать с ней (рис. 3.1) [1, 2].
Рис. 3.1. Компоненты системы баз данных
Система управления базами данных (СУБД)позволяет создавать БД, модифицировать в них данные, разрабатывать пользовательские приложения без учета физического представления данных.
Прикладные программыотносятся к категории приложений.
Банк данных— обычно БД или несколько БД, связанных между собой логически.
Схема базыданных описывает взаимоотношения между данными, структуру отдельных компонентов, правила модификации и взаимозависимость между данными.
Модель данных— описание принципов, на основе которых построена БД. При разработке БД используют инструментальные программные средства СУБД [3].
Известно, что к числу основных функций СУБД принято относить следующие [4].
Непосредственное управление данными во внешней памяти.Эта функция включает обеспечение необходимых структур внешней памяти как для хранения данных, непосредственно входящих в БД, так и для служебных целей, например, для повышения скорости доступа к данным в некоторых случаях (индексирование). В некоторых реализациях СУБД активно используются возможности существующих файловых систем, в других работа производится вплоть до уровня устройств внешней памяти. В развитых СУБД пользователи в любом случае не обязаны знать, использует ли СУБД файловую систему, и если использует, то не обязаны знать, как организованы файлы. В частности, СУБД поддерживает собственную систему именования объектов БД [5].
Управление буферами оперативной памяти.СУБД обычно работают с БД значительного размера (много больше доступного объема оперативной памяти). Если при обращении к любому элементу данных производится обмен с внешней памятью, то вся система будет работать со скоростью устройства внешней памяти. Практически единственным способом реального увеличения этой скорости является буферизация данных в оперативной памяти. При этом, даже если операционная система производит общесистемную буферизацию (как в случае ОС UNIX), этого недостаточно для целей СУБД, которая располагает гораздо большей информацией о полезности буферизации той или иной части БД. Поэтому в развитых СУБД поддерживается собственный набор буферов оперативной памяти с собственной дисциплиной замены буферов.
Существует отдельное направление СУБД, которое ориентировано на постоянное присутствие в оперативной памяти всей БД. Это направление основано на предположении, что в будущем объем оперативной памяти компьютеров будет настолько велик, что позволит не беспокоиться о буферизации. Пока эти работы находятся в стадии исследований.
Управление транзакциями.Транзакция — это последовательность операций над БД, рассматриваемых СУБД как единое целое. Либо транзакция успешно выполняется, и СУБД фиксирует (COMMIT) изменения БД, произведенные этой транзакцией, во внешней памяти, либо ни одно из этих изменений никак не отражается на состоянии БД. Понятие транзакции необходимо для поддержания логической целостности БД [3].
Таким образом, поддержание механизма транзакций является обязательным условием даже однопользовательских СУБД, в многопользовательских СУБД он строго обязателен.
То свойство, что каждая транзакция начинается при целостном состоянии БД и оставляет это состояние целостным после своего завершения, делает очень удобным использование понятия транзакции как единицы активности пользователя по отношению к БД. При соответствующем управлении параллельно выполняющимися транзакциями со стороны СУБД каждый из пользователей может в принципе ощущать себя единственным пользователем СУБД (на самом деле, иногда в многопользовательских СУБД заметно наличие нескольких пользователей).
С управлением транзакциями в многопользовательской СУБД связаны важные понятия сериализации транзакций и сериального плана выполнения смеси транзакций. Под сериализацией параллельно выполняющихся транзакций понимается такой порядок планирования их работы, при котором суммарный эффект смеси транзакций эквивалентен эффекту их некоторого последовательного выполнения. Сериальный план выполнения смеси транзакций — это такой план, который приводит к сериализации транзакций. Понятно, что если удается добиться действительно сериального выполнения смеси транзакций, то для каждого пользователя, по инициативе которого образована транзакция, присутствие других транзакций будет незаметно (если не считать некоторого замедления работы по сравнению с однопользовательским режимом).
Существует несколько базовых алгоритмов сериализации транзакций. В централизованных СУБД наиболее распространены алгоритмы, основанные на синхронизационных захватах объектов БД. При использовании любого алгоритма сериализации возможны конфликты между двумя или более транзакциями по доступу к объектам БД. В этом случае для поддержания сериализации необходимо выполнить откат (ликвидировать все изменения, произведенные в БД) одной или более транзакций. Это один из случаев, когда пользователь многопользовательской СУБД может реально ощутить присутствие в системе транзакций других пользователей [4].
Журнализация и восстановление БД после сбоев.Одним из основных требований к СУБД является надежность хранения данных во внешней памяти. Под надежностью хранения понимают то, что СУБД в состоянии восстановить последнее согласованное состояние БД после любого аппаратного или программного сбоя. Обычно рассматривают два возможных вида аппаратных сбоев: так называемые мягкие сбои, которые можно трактовать как внезапную остановку работы компьютера (например, аварийное выключение питания), и жесткие сбои, характеризуемые потерей информации на носителях внешней памяти. Примерами программных сбоев являются аварийное завершение работы СУБД (по причине ошибки в программе или в результате некоторого аппаратного сбоя) или аварийное завершение пользовательской программы, в результате чего некоторая транзакция остается незавершенной. Первую ситуацию можно рассматривать как особый вид мягкого аппаратного сбоя; при возникновении последней требуется ликвидировать последствия только одной транзакции.
В любом случае для восстановления БД нужно располагать некоторой дополнительной информацией. Другими словами, поддержание надежности хранения данных в БД требует избыточности хранения данных, причем та часть данных, которая используется для восстановления, должна храниться особо надежно. Наиболее распространенным методом поддержания такой избыточной информации является ведение журнала изменений БД.
Журнал — это особая часть БД, недоступная пользователям СУБД и поддерживаемая с особой тщательностью (иногда поддерживаются две копии журнала, располагаемые на разных физических дисках), в которую поступают записи обо всех изменениях основной части БД. В разных СУБД изменения БД журнализуются на разных уровнях: иногда запись в журнале соответствует некоторой логической операции изменения БД (например, операции удаления строки из таблицы реляционной БД), иногда — минимальной внутренней операции модификации страницы внешней памяти; в некоторых системах одновременно используются оба подхода.
Во всех случаях придерживаются стратегии «упреждающей» записи в журнал (так называемого протокола Write Ahead Log — WAL). Эта стратегия заключается в том, что запись об изменении любого объекта БД должна попасть во внешнюю память журнала раньше, чем измененный объект попадет во внешнюю память основной части БД. Известно, что если в СУБД корректно соблюдается протокол WAL, то с помощью журнала можно решить все проблемы восстановления БД после любого сбоя.
Самая простая ситуация восстановления — индивидуальный откат транзакции. Строго говоря, для этого не требуется общесистемный журнал изменений БД. Достаточно для каждой транзакции поддерживать локальный журнал операций модификации БД, выполненных в этой транзакции, и производить откат транзакции путем выполнения обратных операций, следуя от конца локального журнала. В некоторых СУБД так и делают, но в большинстве систем локальные журналы не поддерживают, а индивидуальный откат транзакции выполняют по общесистемному журналу, для этого все записи от одной транзакции связывают обратным списком (от конца к началу).
При мягком сбое во внешней памяти основной части БД могут находиться объекты, модифицированные транзакциями, не закончившимися к моменту сбоя, и могут отсутствовать объекты, модифицированные транзакциями, которые к моменту сбоя успешно завершились (по причине использования буферов оперативной памяти, содержимое которых при мягком сбое пропадает). При соблюдении протокола WAL во внешней памяти журнала должны гарантированно находиться записи, относящиеся к операциям модификации обоих видов объектов. Целью процесса восстановления после мягкого сбоя является состояние внешней памяти основной части БД, которое возникло бы при фиксации во внешней памяти изменений всех завершившихся транзакций и которое не содержало бы никаких следов незаконченных транзакций. Для того чтобы этого добиться, сначала производят откат незавершенных транзакций (undo), а потом повторно воспроизводят (redo) те операции завершенных транзакций, результаты которых не отображены во внешней памяти. Этот процесс содержит много тонкостей, связанных с обшей организацией управления буферами и журналом.
Для восстановления БД после жесткого сбоя используют журнал и архивную копию БД. Грубо говоря, архивная копия — это полная копия БД к моменту начала заполнения журнала (известно несколько вариантов более гибкой трактовки смысла архивной копии). Конечно, для нормального восстановления БД после жесткого сбоя необходимо, чтобы журнал не пропал. Как уже отмечалось, к сохранности журнала во внешней памяти в СУБД предъявляются особо повышенные требования. Тогда восстановление БД состоит в том, что исходя из архивной копии по журналу воспроизводится работа всех транзакций, которые закончились к моменту сбоя. В принципе, можно даже воспроизвести работу незавершенных транзакций и продолжить их работу после завершения восстановления. Однако в реальных системах это обычно не делается, поскольку процесс восстановления после жесткого сбоя является достаточно длительным.
Поддержка языков БД.Для работы с БД используются специальные языки, в целом называемые языками баз данных. В ранних СУБД поддерживалось несколько специализированных по своим функциям языков; чаще всего выделялись два — язык описания данных Schema Definition Language (SDL) и язык манипулирования данными Data Manipulation Language (DML). SDL служил главным образом для определения логической структуры БД, т. е. той структуры БД, какой она представляется пользователям. DML содержал набор операторов манипулирования данными, т. е. операторов, позволяющих заносить/удалять данные в/из БД, модифицировать или выбирать существующие данные.
В современных СУБД обычно поддерживается единый интегрированный язык, содержащий все необходимые средства для работы с БД (начиная от ее создания) и обеспечивающий базовый пользовательский интерфейс с БД. Стандартным языком наиболее распространенных в настоящее время реляционных СУБД является язык Structured Query Language (SQL).
Язык SQL, прежде всего, сочетает средства SDL и DML, т. е. позволяет определять структуру реляционной БД и манипулировать данными. При этом именование объектов БД (для реляционной БД — именование таблиц и их столбцов) поддерживается на языковом уровне в том смысле, что компилятор языка SQL производит преобразование имен объектов в их внутренние идентификаторы на основании специально поддерживаемых служебных таблиц-каталогов. Внутренняя часть СУБД (ядро) вообще не работает с именами таблиц и их столбцов.
Язык SQL содержит специальные средства определения ограничений целостности БД. Ограничения целостности хранятся в специальных таблицах-каталогах, и обеспечение контроля целостности БД производится на языковом уровне, т. е. при компиляции операторов модификации БД компилятор SQL на основании имеющихся в БД ограничений целостности генерирует соответствующий программный код.
Специальные операторы языка SQL позволяют определять так называемые представления БД, фактически являющиеся хранимыми в БД запросами (результатом любого запроса к реляционной БД является таблица) с именованными столбцами. Для пользователя представление является такой же таблицей, как любая базовая таблица, хранимая в БД, но с помощью представлений можно ограничить или, наоборот, расширить видимость БД для конкретного пользователя. Поддержание представлений производится также на языковом уровне.
Наконец, авторизация доступа к объектам БД производится также на основе специального набора операторов SQL. Суть состоит в том, что для выполнения операторов SQL разного вида пользователь должен обладать различными полномочиями. Пользователь, создавший таблицу БД, обладает полным набором полномочий для работы с этой таблицей, в число которых входит право на передачу всех или части полномочий другим пользователям, включая право на передачу полномочий. Полномочия пользователей описываются в специальных таблицах-каталогах, контроль полномочий поддерживается на языковом уровне.
Организация типичной СУБД и состав ее компонентов соответствует рассмотренному набору функций (управление данными во внешней памяти; управление буферами оперативной памяти; управление транзакциями; журнализация и восстановление БД после сбоев; поддержание языков БД).
Логически в современной реляционной СУБД выделяют внутреннюю часть — ядро СУБД (часто его называют Data Base Engine), компилятор языка БД (обычно SQL), подсистему поддержки времени выполнения, набор утилит. В некоторых системах эти части выделяются явно, в других — нет, но логически такое разделение можно провести во всех СУБД.
Ядро СУБД отвечает за управление данными во внешней памяти, управление буферами оперативной памяти, управление транзакциями и журнализацию. Соответственно, выделяют такие компоненты ядра (по крайней мере, логически, хотя в некоторых системах эти компоненты выделяются явно), как менеджер данных, менеджер буферов, менеджер транзакций и менеджер журнала. Функции этих компонентов взаимосвязаны, и для обеспечения корректной работы СУБД все компоненты должны взаимодействовать по тщательно продуманным и проверенным протоколам. Ядро СУБД обладает собственным интерфейсом, не доступным пользователям напрямую и используемым в программах, производимых компилятором SQL (или в подсистеме поддержки выполнения таких программ), и утилитах БД. Ядро СУБД является основной резидентной частью СУБД. При использовании архитектуры «клиент — сервер» ядро является основной составляющей серверной части системы.
Основная функция компилятора языка БД — компиляция операторов языка в некоторую выполняемую программу. Как правило, языки реляционных СУБД, в частности SQL, являются непроцедурными, т. е. в операторе такого языка специфицируется некоторое действие над БД, но эта спецификация лишь описывает в некоторой форме условия совершения желаемого действия. Поэтому компилятор должен определить, каким образом выполнять оператор языка, прежде чем произвести программу. Результат компиляции — выполняемая программа, представленная в некоторых системах в машинном коде (чаще в выполняемом внутреннем машинно-независимом коде). В последнем случае реальное выполнение оператора производится с привлечением подсистемы поддержки времени выполнения, т. е., по сути дела, интерпретатора этого внутреннего языка.
В отдельные утилиты БД обычно выделяют такие процедуры, которые слишком накладно выполнять с использованием языка БД, например загрузка и выгрузка БД, сбор статистики, глобальная проверка целостности БД и т. д. Утилиты программируются с использованием интерфейса ядра СУБД, а иногда даже с проникновением внутрь ядра [4].
Читайте также: