Extensible Storage Engine ( ESE ), также известный как JET Blue , — это технология хранения данных ISAM (индексированный последовательный метод доступа) от Microsoft . ESE является ядром Microsoft Exchange Server , Active Directory и Windows Search . Он также используется рядом компонентов Windows, включая клиент Windows Update и Центр справки и поддержки . Его цель — позволить приложениям хранить и извлекать данные с помощью индексированного и последовательного доступа.
ESE обеспечивает обновление и извлечение транзакционных данных. Механизм восстановления после сбоя обеспечивает сохранение согласованности данных даже в случае сбоя системы. Транзакции в ESE являются высокопараллельными, что делает ESE подходящим для серверных приложений. ESE интеллектуально кэширует данные, обеспечивая высокопроизводительный доступ к данным. Кроме того, ESE является легким, что делает его подходящим для вспомогательных приложений.
ESE Runtime (ESENT.DLL) поставляется с каждым выпуском Windows , начиная с Windows 2000 , с собственной x64-версией ESE Runtime, поставляемой с x64-версиями Windows XP и Windows Server 2003. Microsoft Exchange , вплоть до Exchange 2003, поставлялся только с 32-разрядной версией, поскольку это была единственная поддерживаемая платформа. С Exchange 2007 он поставляется с 64-разрядной версией.
База данных — это как физическая, так и логическая группировка данных. База данных ESE выглядит как один файл для Windows. Внутри база данных представляет собой набор страниц размером 2, 4, 8, 16 или 32 КБ (варианты страниц размером 16 и 32 КБ доступны только в Windows 7 и Exchange 2010), [1] организованных в сбалансированную структуру B-дерева . [2] Эти страницы содержат метаданные для описания данных, содержащихся в базе данных, сами данные, индексы для сохранения интересных порядков данных и другую информацию. Эта информация перемешана в файле базы данных, но прилагаются усилия для того, чтобы данные, используемые вместе, были сгруппированы вместе в базе данных. База данных ESE может содержать до 2 32 страниц или 16 терабайт данных, [3] для страниц размером 8 килобайт .
Базы данных ESE организованы в группы, называемые экземплярами. Большинство приложений используют один экземпляр, но все приложения могут также использовать несколько экземпляров. Важность экземпляра заключается в том, что он связывает одну серию журналов восстановления с одной или несколькими базами данных. В настоящее время к экземпляру ESE в любое время может быть присоединено до 6 пользовательских баз данных. Каждый отдельный процесс, использующий ESE, может иметь до 1024 экземпляров ESE.
База данных является переносимой, поскольку ее можно отсоединить от одного работающего экземпляра ESE и затем присоединить к тому же или другому работающему экземпляру. В отсоединенном состоянии базу данных можно копировать с помощью стандартных утилит Windows. Базу данных нельзя копировать, пока она активно используется, поскольку ESE открывает исключительно файлы базы данных. Физически база данных может находиться на любом устройстве, поддерживаемом Windows для операций ввода-вывода с прямой адресацией.
Таблица — это однородная коллекция записей, где каждая запись имеет одинаковый набор столбцов. Каждая таблица идентифицируется именем таблицы, область действия которого является локальной для базы данных, в которой содержится таблица. Объем дискового пространства, выделенного для таблицы в базе данных, определяется параметром, заданным при создании таблицы с помощью операции CreateTable. Таблицы автоматически увеличиваются в ответ на создание данных.
Таблицы имеют один или несколько индексов. Должен быть по крайней мере один кластеризованный индекс для данных записи. Если приложение не определяет кластеризованный индекс, используется искусственный индекс, который упорядочивает и кластеризует записи в хронологическом порядке вставки записей. Индексы определяются для сохранения интересных порядков данных и позволяют как последовательный доступ к записям в порядке индекса, так и прямой доступ к записям по значениям столбцов индекса. Кластеризованные индексы в ESE также должны быть первичными, что означает, что ключ индекса должен быть уникальным.
Кластеризованные и некластеризованные индексы представлены с помощью деревьев B+ . Если операция вставки или обновления приводит к переполнению страницы, страница разделяется: выделяется новая страница и логически связывается между двумя ранее соседними страницами. Поскольку эта новая страница физически не соседствует со своими логическими соседями, доступ к ней не так эффективен. ESE имеет функцию сжатия в режиме онлайн, которая повторно сжимает данные. Если ожидается, что таблица будет часто обновляться, можно зарезервировать место для будущих вставок, указав соответствующую плотность страниц при создании таблицы или индекса. Это позволяет избегать или откладывать операции разделения.
Запись — это связанный набор значений столбцов. Записи вставляются и обновляются с помощью операций Update и могут быть удалены с помощью операций Delete. Столбцы устанавливаются и извлекаются с помощью операций SetColumns и RetrieveColumns соответственно. Максимальный размер записи составляет 8110 байт для страниц по 8 килобайт, за исключением столбцов длинных значений. Типы столбцов LongText и LongBinary не вносят существенного вклада в это ограничение размера, и записи могут содержать данные, намного превышающие размер страницы базы данных, если данные хранятся в столбцах длинных значений. Когда ссылка на длинное значение хранится в записи, требуется только 9 байт данных в записи. Эти длинные значения сами по себе могут иметь размер до 2 гигабайт (ГБ).
Записи обычно однородны в том смысле, что каждая запись имеет набор значений для одного и того же набора столбцов. В ESE также возможно определить много столбцов для таблицы, и при этом любая заданная запись будет содержать только небольшое количество ненулевых значений столбцов. В этом смысле таблица также может быть набором разнородных записей.
ESE поддерживает широкий диапазон значений столбцов, размером от 1 бита до 2 ГБ. Выбор правильного типа столбца важен, поскольку тип столбца определяет многие его свойства, включая его порядок для индексов. ESE поддерживает следующие типы данных:
Каждая таблица ESE может определять до 127 столбцов фиксированной длины, 128 столбцов переменной длины и 64 993 помеченных столбцов.
Для данной таблицы столбцы попадают в одну из двух категорий: те, которые либо встречаются ровно один раз в каждой записи, возможно, с несколькими значениями NULL; и те, которые встречаются редко, или которые могут иметь несколько вхождений в одной записи. Фиксированные и переменные столбцы относятся к первой категории, в то время как помеченные столбцы относятся ко второй. Внутреннее представление двух категорий столбцов отличается, и важно понимать компромиссы между категориями столбцов. Фиксированные и переменные столбцы обычно представлены в каждой записи, даже если вхождение имеет значение NULL. К этим столбцам можно быстро обратиться с помощью таблицы смещений. Вхождениям помеченных столбцов предшествует идентификатор столбца, и столбец находится с помощью двоичного поиска набора помеченных столбцов.
Типы столбцов Long Text и Long Binary являются большими двоичными объектами. Они хранятся в отдельном B+дереве из кластеризованного индекса, ключ к которому — идентификатор длинного значения и смещение байта. ESE поддерживает добавление, перезапись диапазона байтов и установку размера для этих столбцов. Кроме того, ESE имеет функцию хранилища одного экземпляра, где несколько записей могут ссылаться на один и тот же большой двоичный объект, как если бы каждая запись имела свою собственную копию информации, т. е. без конфликтов блокировки между записями. Максимальный размер значения столбца Long Text или Long Binary составляет 2 ГБ.
Столбцы версии автоматически увеличиваются ESE каждый раз, когда запись, содержащая этот столбец, изменяется с помощью операции обновления. Этот столбец не может быть установлен приложением, но может быть только прочитан. Приложения столбцов версии включают использование для определения необходимости обновления копии данной записи в памяти. Если значение в записи таблицы больше значения в кэшированной копии, то кэшированная копия считается устаревшей. Столбцы версии должны иметь тип Long.
Столбцы с автоинкрементом автоматически устанавливаются ESE таким образом, что значение, содержащееся в столбце, уникально для каждой записи в таблице. Эти столбцы, как и столбцы версий, не могут быть установлены приложением. Столбцы с автоинкрементом доступны только для чтения и автоматически устанавливаются при вставке новой записи в таблицу с помощью операции обновления. Значение в столбце остается постоянным в течение всего срока действия записи, и на таблицу допускается только один столбец с автоинкрементом. Столбцы с автоинкрементом могут иметь тип Long или тип Currency.
Столбцы Escrow могут быть изменены с помощью операции EscrowUpdate. Депонированные обновления являются числовыми дельта-операциями. Столбцы Escrow должны быть типа Long. Примерами числовых дельта-операций являются добавление 2 к значению или вычитание 1 из значения. ESE отслеживает изменение значения, а не конечное значение обновления. Несколько сеансов могут иметь невыполненные изменения, внесенные с помощью EscrowUpdate в одно и то же значение, поскольку ESE может определить фактическое конечное значение независимо от того, какие транзакции фиксируются, а какие откатываются. Это позволяет нескольким пользователям одновременно обновлять столбец, выполняя числовые дельта-изменения. При желании ядро базы данных может стирать записи с нулевым значением столбца. Распространенным применением такого депонированного столбца является счетчик ссылок: множество потоков увеличивают/уменьшают значение без блокировок, и когда счетчик достигает нуля, запись автоматически удаляется.
Индекс — это постоянный порядок записей в таблице. Индексы используются как для последовательного доступа к строкам в определенном порядке, так и для прямой навигации по записям на основе индексированных значений столбцов. Порядок, определяемый индексом, описывается в терминах массива столбцов в порядке приоритета. Этот массив столбцов также называется ключом индекса. Каждый столбец называется сегментом индекса. Каждый сегмент индекса может быть как восходящим, так и нисходящим с точки зрения его вклада в упорядочивание. Для таблицы может быть определено любое количество индексов. ESE предоставляет богатый набор функций индексирования.
Один индекс может быть указан как кластеризованный или первичный индекс. В ESE кластеризованный индекс должен быть уникальным и называется первичным индексом. Другие индексы описываются как некластеризованные или вторичные индексы. Первичные индексы отличаются от вторичных индексов тем, что запись индекса является самой записью, а не логическим указателем на запись. Вторичные индексы имеют первичные ключи на своих листьях для логической связи с записью в первичном индексе. Другими словами, таблица физически кластеризована в первичном индексном порядке. Извлечение неиндексированных данных записи в первичном индексном порядке, как правило, намного быстрее, чем во вторичном индексном порядке. Это связано с тем, что один доступ к диску может перенести в память несколько записей, к которым будет осуществляться доступ близко друг к другу по времени. Один и тот же доступ к диску удовлетворяет нескольким операциям доступа к записям. Однако вставка записи в середину индекса, как определено первичным индексным порядком, может быть намного медленнее, чем добавление ее в конец индекса. Частота обновления должна тщательно учитываться с шаблонами извлечения при выполнении проектирования таблицы. Если для таблицы не определен первичный индекс, то создается неявный первичный индекс, называемый индексом ключа базы данных (DBK). DBK — это просто уникальный возрастающий номер, увеличивающийся каждый раз при вставке записи. В результате физический порядок записей в индексе DBK — это хронологический порядок вставки, и новые записи всегда добавляются в конец таблицы. Если приложение хочет кластеризовать данные по неуникальному индексу, это возможно путем добавления столбца автоинкремента в конец определения неуникального индекса.
Индексы могут быть определены по многозначным столбцам. В этих индексах может существовать несколько записей для записей с несколькими значениями для индексированного столбца. Многозначные столбцы могут индексироваться вместе с однозначными столбцами. Когда два или более многозначных столбца индексируются вместе, то многозначное свойство учитывается только для первого многозначного столбца в индексе. Столбцы с более низким приоритетом обрабатываются так, как если бы они были однозначными.
Индексы также могут быть определены как разреженные. Разреженные индексы не имеют по крайней мере одной записи для каждой записи в таблице. Существует ряд опций определения разреженного индекса. Существуют опции для исключения записей из индексов, когда весь ключ индекса равен NULL, когда любой сегмент ключа равен NULL или когда только первый сегмент ключа равен NULL. Индексы также могут иметь условные столбцы. Эти столбцы никогда не появляются в индексе, но могут привести к тому, что запись не будет индексирована, когда условный столбец равен NULL или не равен NULL.
Индексы также могут быть определены для включения одной записи для каждой подстроки столбца Text или Long Text. Эти индексы называются индексами кортежей. Они используются для ускорения запросов с предикатами сопоставления подстрок. Индексы кортежей могут быть определены только для столбцов Text. Например, если значение столбца Text равно «I love JET Blue» , а индекс настроен на минимальный размер кортежа в 4 символа и максимальную длину кортежа в 10 символов, то будут проиндексированы следующие подстроки:
Несмотря на то, что индексы кортежей могут быть очень большими, они могут значительно ускорить запросы вида: найти все записи, содержащие «JET Blue» . Их можно использовать для подстрок длиннее максимальной длины кортежа, разделив подстроку поиска на строки поиска максимальной длины кортежа и пересечь результаты. Их можно использовать для точных совпадений для строк длиной с максимальную длину кортежа или такой же короткой, как минимальная длина кортежа, без пересечения индексов. Для получения дополнительной информации о выполнении пересечения индексов в ESE см. Пересечение индексов. Индексы кортежей не могут ускорить запросы, где строка поиска короче минимальной длины кортежа.
Транзакция — это логическая единица обработки, ограниченная операциями BeginTransaction и CommitTransaction, или Rollback. Все обновления, выполняемые во время транзакции, являются атомарными; они либо все появляются в базе данных одновременно, либо ни одно не появляется. Любые последующие обновления другими транзакциями невидимы для транзакции. Однако транзакция может обновлять только данные, которые не изменились за это время; в противном случае операция сразу же завершается неудачей без ожидания. Только для чтения транзакции никогда не нуждаются в ожидании, а транзакции обновления могут мешать только друг другу, обновляя транзакции. Транзакции, которые завершаются Rollback или сбоем системы, не оставляют следов в базе данных. Как правило, состояние данных восстанавливается при Rollback до того состояния, которое было до BeginTransaction.
Транзакции могут быть вложенными до 7 уровней, с одним дополнительным уровнем, зарезервированным для внутреннего использования ESE. Это означает, что часть транзакции может быть откачена без необходимости отката всей транзакции; CommitTransaction вложенной транзакции просто обозначает успешность одной фазы обработки, а внешняя транзакция может еще потерпеть неудачу. Изменения фиксируются в базе данных только тогда, когда фиксируется самая внешняя транзакция. Это известно как фиксация на уровне транзакции 0. Когда транзакция фиксируется на уровне транзакции 0, данные, описывающие транзакцию, синхронно сбрасываются в журнал, чтобы гарантировать, что транзакция будет завершена даже в случае последующего сбоя системы. Синхронная очистка журнала делает транзакции ESE долговечными. Однако в некоторых случаях приложения хотят заказать свои обновления, но не гарантировать немедленное внесение изменений. Здесь приложения могут фиксировать изменения с помощью JET_bitIndexLazyFlush.
ESE поддерживает механизм управления параллелизмом, называемый многоверсионностью. При многоверсионности каждая транзакция запрашивает согласованное представление всей базы данных, какой она была на момент начала транзакции. Единственные обновления, с которыми она сталкивается, — это те, которые она сама делает. Таким образом, каждая транзакция работает так, как будто она является единственной активной транзакцией, запущенной в системе, за исключением случаев конфликтов записи. Поскольку транзакция может вносить изменения на основе считанных данных, которые уже были обновлены в другой транзакции, многоверсионность сама по себе не гарантирует сериализуемость транзакций. Однако сериализуемость может быть достигнута при желании простым использованием явных блокировок чтения записей для блокировки считанных данных, на которых основаны обновления. Как блокировки чтения, так и блокировки записи могут быть явно запрошены с помощью операции GetLock.
Кроме того, ESE поддерживает расширенную функцию управления параллелизмом, известную как блокировка эскроу. Блокировка эскроу — это чрезвычайно параллельное обновление, при котором числовое значение изменяется относительным образом, т. е. путем добавления или вычитания другого числового значения. Обновления эскроу не конфликтуют даже с другими параллельными обновлениями эскроу для тех же данных. Это возможно, поскольку поддерживаемые операции являются коммутируемыми и могут быть независимо зафиксированы или откатены. В результате они не мешают параллельным транзакциям обновления. Эта функция часто используется для поддерживаемых агрегаций.
ESE также расширяет семантику транзакций от операций манипулирования данными до операций определения данных. Можно добавить индекс к таблице и заставить параллельно работающие транзакции обновлять ту же таблицу без какого-либо конфликта блокировки транзакций. Позже, когда эти транзакции будут завершены, вновь созданный индекс будет доступен для всех транзакций и будет содержать записи для обновлений записей, сделанных другими транзакциями, которые не могли обнаружить присутствие индекса, когда обновления имели место. Операции определения данных могут выполняться со всеми функциями, ожидаемыми от механизма транзакций для обновлений записей. Операции определения данных, поддерживаемые таким образом, включают AddColumn, DeleteColumn, CreateIndex, DeleteIndex, CreateTable и DeleteTable.
Курсор — это логический указатель в индексе таблицы. Курсор может быть расположен на записи, перед первой записью, после последней записи или даже между записями. Если курсор расположен перед или после записи, то текущей записи нет. Возможно наличие нескольких курсоров в одном индексе таблицы. Многие операции с записями и столбцами основаны на позиции курсора. Позиция курсора может быть перемещена последовательно с помощью операций Move или напрямую с помощью клавиш индекса с операциями Seek. Курсоры также могут быть перемещены в дробную позицию в индексе. Таким образом, курсор можно быстро переместить в позицию полосы большого пальца. Эта операция выполняется с той же скоростью, что и операция Seek. Не требуется доступа к промежуточным данным.
Каждый курсор имеет буфер копирования для создания новой записи или изменения существующей записи, столбец за столбцом. Это внутренний буфер, содержимое которого можно изменить с помощью операций SetColumns. Изменения буфера копирования не изменяют автоматически сохраненные данные. Содержимое текущей записи можно скопировать в буфер копирования с помощью операции PrepareUpdate, а операции Update сохраняют содержимое буфера копирования как запись. Буфер копирования неявно очищается при фиксации или откате транзакции, а также при операциях навигации. RetrieveColumns может использоваться для извлечения данных столбцов либо из записи, либо из буфера копирования, если таковой существует.
Приложения ESE неизменно запрашивают свои данные. В этом разделе документа описываются функции и методы для приложений, которые пишут логику обработки запросов на ESE.
ESE предоставляет возможность сортировки в виде временных таблиц. Приложение вставляет записи данных в процесс сортировки по одной записи за раз, а затем извлекает их по одной записи за раз в отсортированном порядке. Сортировка фактически выполняется между последней вставкой записи и первым извлечением записи. Временные таблицы могут использоваться для частичных и полных наборов результатов. Эти таблицы могут предлагать те же функции, что и базовые таблицы, включая возможность последовательной или прямой навигации по строкам с использованием ключей индекса, соответствующих определению сортировки. Временные таблицы также могут быть обновляемыми для вычисления сложных агрегатов. Простые агрегаты могут быть вычислены автоматически с помощью функции, аналогичной сортировке, где желаемый агрегат является естественным результатом процесса сортировки.
Извлечение данных столбцов напрямую из вторичных индексов является важной оптимизацией производительности. Столбцы могут быть извлечены напрямую из вторичных индексов, без доступа к записям данных, с помощью флага RetrieveFromIndex в операции RetrieveColumns. Гораздо эффективнее извлекать столбцы из вторичного индекса, чем из записи, при навигации по индексу. Если данные столбцов были извлечены из записи, то для поиска записи по первичному ключу необходима дополнительная навигация. Это может привести к дополнительным обращениям к диску. Когда индекс предоставляет все необходимые столбцы, он называется покрывающим индексом. Обратите внимание, что столбцы, определенные в первичном индексе таблицы, также находятся во вторичных индексах и могут быть аналогичным образом извлечены с помощью JET_bitRetrieveFromPrimaryBookmark.
Индексные ключи хранятся в нормализованной форме, которая во многих случаях может быть денормализована до исходного значения столбца. Нормализация не всегда обратима. Например, типы столбцов Text и Long Text не могут быть денормализованы. Кроме того, индексные ключи могут быть усечены, если данные столбца очень длинные. В случаях, когда столбцы не могут быть извлечены напрямую из вторичных индексов, запись всегда может быть доступна для извлечения необходимых данных.
Запросы часто включают комбинацию ограничений на данные. Эффективным средством обработки ограничения является использование доступного индекса. Однако, если запрос включает несколько ограничений, то приложения часто обрабатывают ограничения, проходя по всему диапазону индекса наиболее ограничительного предиката, удовлетворяемого одним индексом. Любой оставшийся предикат, называемый остаточным предикатом, обрабатывается путем применения предиката к самой записи. Это простой метод, но его недостатком является потенциальная необходимость выполнять множество обращений к диску для переноса записей в память для применения остаточного предиката.
Пересечение индексов — важный механизм запроса, в котором несколько индексов используются вместе для более эффективной обработки сложного ограничения. Вместо использования только одного индекса диапазоны индексов по нескольким индексам объединяются, что приводит к гораздо меньшему количеству записей, к которым может быть применен любой остаточный предикат. ESE упрощает это, предоставляя операцию IntersectIndexes. Эта операция принимает ряд диапазонов индексов по индексам из одной и той же таблицы и возвращает временную таблицу первичных ключей, которую можно использовать для перехода к записям базовой таблицы, удовлетворяющим всем предикатам индексов.
Объединение — это обычная операция в нормализованной таблице, где логически связанные данные объединяются для использования в приложении. Объединения могут быть дорогостоящими операциями, поскольку для помещения связанных данных в память может потребоваться много доступов к данным. В некоторых случаях эти усилия можно оптимизировать, определив одну базовую таблицу, содержащую данные для двух или более логических таблиц. Набор столбцов базовой таблицы представляет собой объединение наборов столбцов этих логических таблиц. Тегированные столбцы делают это возможным благодаря хорошей обработке как многозначных, так и разреженных данных. Поскольку связанные данные хранятся вместе в одной записи, к ним осуществляется доступ одновременно, что минимизирует количество доступов к диску для выполнения объединения. Этот процесс можно распространить на большое количество логических таблиц, поскольку ESE может поддерживать до 64 993 тегированных столбцов. Поскольку индексы могут быть определены по многозначным столбцам, все еще возможно индексировать «внутренние» таблицы. Однако существуют некоторые ограничения, и приложениям следует тщательно рассмотреть возможность предварительного объединения перед использованием этого метода.
Функция регистрации и восстановления ESE поддерживает гарантированную целостность и согласованность данных в случае сбоя системы. Регистрация — это процесс избыточной записи операций обновления базы данных в файл журнала. Структура файла журнала очень устойчива к сбоям системы. Восстановление — это процесс использования этого журнала для восстановления баз данных в согласованное состояние после сбоя системы.
Операции транзакций регистрируются, и журнал сбрасывается на диск во время каждой фиксации на уровне транзакции 0. Это позволяет процессу восстановления повторять обновления, сделанные транзакциями, которые фиксируются на уровне транзакции 0, и отменять изменения, сделанные транзакциями, которые не фиксируются на уровне транзакции 0. Этот тип схемы восстановления часто называют схемой восстановления «накат вперед/назад». Журналы могут храниться до тех пор, пока данные не будут безопасно скопированы с помощью процесса резервного копирования, описанного ниже, или журналы могут повторно использоваться циклическим образом, как только они больше не нужны для восстановления после сбоя системы. Циклическое ведение журнала минимизирует объем дискового пространства, необходимого для журнала, но влияет на возможность воссоздания состояния данных в случае сбоя носителя.
Ведение журнала и восстановление также играют роль в защите данных от сбоя носителя. ESE поддерживает резервное копирование в режиме онлайн, при котором копируются одна или несколько баз данных вместе с файлами журналов таким образом, чтобы это не влияло на операции базы данных. Базы данных могут продолжать запрашиваться и обновляться во время создания резервной копии. Резервная копия называется «нечеткой резервной копией», поскольку процесс восстановления должен выполняться как часть восстановления резервной копии для восстановления согласованного набора баз данных. Поддерживаются как потоковое, так и теневое резервное копирование.
Потоковое резервное копирование — это метод резервного копирования, при котором копии всех желаемых файлов базы данных и необходимых файлов журнала создаются в процессе резервного копирования. Копии файлов могут быть сохранены непосредственно на ленту или могут быть сделаны на любом другом устройстве хранения. При потоковом резервном копировании не требуется приостанавливать какую-либо активность. И база данных, и файлы журнала проходят контрольную сумму, чтобы гарантировать отсутствие повреждений данных в наборе данных во время процесса резервного копирования. Потоковое резервное копирование также может быть инкрементным резервным копированием. Инкрементное резервное копирование — это такое, при котором копируются только файлы журнала, и которое можно восстановить вместе с предыдущей полной резервной копией, чтобы привести все базы данных в недавнее состояние.
Резервные копии теневых копий — это новый высокоскоростной метод резервного копирования. Резервные копии теневых копий значительно быстрее, поскольку виртуальная копия создается после короткого периода заморозки приложения. По мере последующих обновлений данных виртуальная копия материализуется. В некоторых случаях аппаратная поддержка резервных копий теневых копий означает, что фактическое сохранение виртуальных копий не требуется. Резервные копии теневых копий всегда являются полными резервными копиями.
Восстановление может использоваться для применения одной резервной копии или для применения комбинации одной полной резервной копии с одной или несколькими инкрементными резервными копиями. Кроме того, любые существующие файлы журналов могут быть воспроизведены, а также для воссоздания всего набора данных вплоть до последней транзакции, зарегистрированной как зафиксированная на уровне транзакции 0. Восстановление резервной копии может быть выполнено в любой системе, способной поддерживать исходное приложение. Это не обязательно должна быть та же машина или даже та же конфигурация машины. Расположение файлов может быть изменено в рамках процесса восстановления.
При создании базы данных ESENT размер сектора физического диска сохраняется вместе с базой данных. Ожидается, что размер физического сектора останется неизменным между сеансами; в противном случае будет выдано сообщение об ошибке. Когда физический диск клонируется или восстанавливается из образа диска на диск, который использует другой размер физического сектора ( диски Advanced Format ), ESENT будет выдавать сообщения об ошибках. [4]
Это известная проблема, и у Microsoft есть исправления. Для Windows Vista или Windows Server 2008 см. KB2470478. [5] Для Windows 7 или Windows Server 2008 R2 см. KB982018. [6]
JET Blue изначально был разработан Microsoft как перспективное обновление для ядра базы данных JET Red в Microsoft Access , но никогда не использовался в этой роли. Вместо этого он продолжал использоваться Exchange Server, Active Directory, File Replication Service (FRS), Security Configuration Editor, Certificate Services, Windows Internet Name Service (WINS) и множеством других служб, приложений и компонентов Windows Microsoft. [7] В течение многих лет это был частный API, используемый только Microsoft, но с тех пор стал опубликованным API, который может использовать любой.
Работа над Data Access Engine (DAE) началась в марте 1989 года, когда Аллен Рейтер присоединился к Microsoft. В течение следующего года команда из четырех разработчиков работала на Аллена, чтобы в значительной степени завершить ISAM. У Microsoft уже был BC7 ISAM (JET Red), но она начала работу над Data Access Engine (DAE) для создания более надежного движка базы данных в качестве входа в тогдашнюю новую область архитектуры клиент-сервер. Весной 1990 года команды BC7 ISAM и DAE объединились, чтобы стать проектом Joint Engine Technology (JET); ответственным за создание двух движков v1 ( JET Red ) и v2 (JET Blue), которые соответствовали бы одной и той же спецификации API (JET API). DAE стал JET Blue в честь цвета флага Израиля. BC7 ISAM стал JET Red в честь цвета флага России. Хотя JET Blue и JET Red были написаны по одной и той же спецификации API, они вообще не имели общего кода ISAM. Они оба поддерживали общий процессор запросов QJET, который позже вместе с BC7 ISAM стал синонимом JET Red.
JET Blue впервые был поставлен в 1994 году как ISAM для WINS, DHCP и ныне несуществующих служб RPL в Windows NT 3.5. Он снова был поставлен как механизм хранения для Microsoft Exchange в 1996 году. Дополнительные службы Windows выбрали JET Blue в качестве своей технологии хранения, и к 2000 году каждая версия Windows начала поставляться с JET Blue. JET Blue использовался Active Directory и стал частью специального набора кода Windows, называемого Trusted Computing Base (TCB). Количество приложений Microsoft, использующих JET Blue, продолжает расти, и API JET Blue был опубликован в 2005 году для упрощения использования постоянно растущим числом приложений и служб как в Windows, так и за ее пределами.
В записи веб-блога Microsoft Exchange [8] указано, что в разработку JET Blue внесли свой вклад следующие разработчики: Чин Ляо, Стивен Хект, Мэтью Беллью, Ян Хосе, Эдвард «Эдди» Гилберт, Кеннет Кин Лам, Баласубраманиан Шрирам, Джонатан Лием, Эндрю Гудселл, Лорион Берчалл, Андрей Маринеску, Адам Фоксман, Иван Триндев, Спенсер Лоу и Бретт Ширли.
В январе 2021 года Microsoft открыла исходный код ESE. [9] Он был опубликован на GitHub с разрешительной лицензией MIT .
Несмотря на общую родословную, между JET Red и ESE существуют огромные различия.