Объектно-ориентированная СУБД (прототип)

этом получаются разные результаты, то каждый из них, тем не менее, является пра­виль­ным. Этот парадокс можно проиллюстрировать на следующем примере:

Положим, имеются две операции: увеличить сумму на счете вдвое и увеличить сумму на счете на 10%. Очевидно, что результат будет разным в зависимости от порядка следования операций. Но, поскольку операции независимы, в любом случае он считается правильным.

Влияние наличия позднего связывания на составление расписания операций в ООБД


Если объекты, которые доступны различным транзакциям, заранее известны, задача механизма согласованного управления относительно проста. Априорная инфор­мация облегчает статичное определение конфликтующих операций; следовательно, стра­тегия управления чередованием операций может быть сформулирована. Однако, позд­нее связывание (late binding), характерная черта объектно-ориентированных систем, приводит к трудности предварительного определения объектов доступа. При отсутствии такого знания, одним из выходов является блокировка некоторых транзакций до тех пор, пока вид объектов доступа не станет известен. Однако, для продолжительных (long-duration) транзакций (например, запись звука в мультимедийной БД) , такая блокировка может привести к слишком большому времени ожидания.

Протокол использует оптимистический подход, при котором априорные знания недоступны. Когда протокол использует оптимистичный подход, некорректное выпол­нение обнаруживается только когда все объекты доступа известны. При обнаружении некорректного чередования, для одной или более транзакций (операций) должен быть произведен обрыв (aborted) или откат (rolled back) к моменту перед некорректным выполнением. Это хорошо зарекомендовавший себя подход, но для продолжительных транзакций откат или обрыв приведет к значительной потери системных ресурсов, которые были использованы и времени, потраченного на бесполезные вычисления.

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


Спецификация точки проверки


Идея точки проверки используется для минимизации глубины отката в случае обрыва транзакций. Эти точки могут быть описаны пользователем. Точки проверки свя­заны с операциями на объектах и могут быть описаны как шаг операции. Нет необ­хо­димости иметь спецификацию точки проверки для каждого объекта в системе. Одна­ко пользователь может описать точки проверки в некоторых операциях на некоторых объ­ектах, так, что каждая точка представляет логическую единицу работы. Идея уста­новки точек проверки предоставляет базе данных возможность определять, находится ли она в согласованном состоянии. Точка проверки служит как механизмом синхро­низации, так и заботой о связности базы данных. Любая пользовательская транзакция может иметь зависимость от результатов других транзакций. Таким образом, точка проверки в транзакции имеет значение только если все другие активные операции также согласны с тем, что состояние базы данных в этой точке является непротиворечивым состоянием (consistent state). При этом точка проверки действует как точка встречи, в которой все активные транзакции системы фиксируют (commit) свою, возможно, частично сделан­ную, до этой точки работу.

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


Состояние пользовательских транзакций на объектах


Каждый объект O в системе хранит состояние каждой пользовательской транзакции в системе. Состояние пользовательской транзакции (т.е. операции на DBIO) может принимать одно из следующих значений:

Никогда не активировалась (Never Activated)
Любая пользовательская транзакция, которая не воздействовала на O прямо или косвенно, находится в этом состоянии на O. Это эквивалентно тому, что не имеется никакой информации о пользовательской транзакции в O.

Завершена (Completed)
Пользовательская транзакция находится в состоянии Завершена на O, если операция вызванная ей на O закончила выполнение всех своих шагов.

Находится в точке проверки (Chekpoint)
Пользовательская транзакция не произвела никаких действий с тех пор, как оказалась в точке проверки.

Задержана для проверки (BlockedForCheckPoint)
Пользовательская транзакция ожидает выполнения условий, которые будут удовлетворять переводу ее в Точку проверки.

Выполняется (Executing)
Пользовательская транзакция выполняется на O, если операция op(O), вызванная этой транзакцией выполняется.



Рис 4: Диаграмма переходов транзакции из состояния в состояние


Таблица 4: Пример изменения состояния транзакции при ее выполнении


Действия

Новое состояние транзакции


Никогда не активировалась

Объект O получил запрос на выполнение op(O) впервые для транзакции Tr(op(O)) и op(O) начинает выполняться

Выполняется

Операция транзакции достигла описанной для нее точки проверки, все остальные активные операции на O "никогда не активировались" в точке проверки

Находится в точке проверки

Операция транзакции достигла описанной для нее точки проверки, но активные операции не находятся в своих точках проверки

Блокирована для точки провер­ки

Tr(op(O)) закончила все свои шаги

Завершена


Таким образом, если объект имеет точки проверки, описанные для своих операций, то операции встречаются (рандеву) в точке проверки. Если операции в точке проверки произведены успешно, то в будущем нет необходимости любой операции откатываться (rollback) за точку проверки.


Шаги протокола согласованного управления


  1. Операция запрошена (requested)

  2. Операция вызывает другую операцию

  3. Вызванная операция возвращается

  4. Операция завершена

  5. Точка разрыва (breakpoint) достигнута

  6. Точка проверки (checkpoint) достигнута

  7. В точке проверки получено сообщение


Детально алгоритм выполнения шагов описан в [19].


4. Представление данных в ООБД


4.1 Базовые объекты системы


Системе известны следующие базовые объекты: ROOT, FAIL, NULL, SAME, ATOMIC, INT, STR, DATIME, BIO, AGG, SET, SEQ.


  1. ROOT – корень – предок всех объектов. Данных не имеет.

  2. FAIL, копия ROOT – возвращается, если при воздействии произошла ошибка.

  3. NULL, копия ROOT – объект-заменитель при отсутствующем значении. Эта проблема возникла недавно, но в теории реляционных баз данных пока не нашла приемлемого решения. Суть проблемы заключается в том, что при вводе данных, некоторые из них могут отсутствовать (например, не известен год рождения), поэтому нельзя сказать, чему они в точности равны. В некоторых случаях нуль может являться значением, для этого и вводится специальное обозначение (NULL).

  4. SAME, копия ROOT – объект, позволяющий создавать копии. Он означает, что для взаимодействующего с ним объекта создается копия.

  5. ATOMIC – предок всех атомарных объектов. Задает для них основные методы поведения.

  6. INT – целое.

  7. STR – строка.

  8. DATIME – дата и время

  9. BIO – условный объект

  10. AGG – агрегат

  11. SET – множество

  12. SEQ – последовательность


4.2 Строение объекта


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


Таблица 5: Заголовок объекта (все поля 32-битные)


Поле

Семантика

OID

Идентификатор объекта (уникальный в пределах системы)

OBJBHR

Идентификатор объекта-поведения (методы)

OBJKH

Идентификатор объекта-действия

TRCOOBJ

Идентификатор транзакционного сообъекта

VALUE

Адрес заголовка вложенного канала, хранящего значение

HISTORY

Адрес заголовка вложенного канала, хранящего историю изменений

Блок данных объекта


Атомарный объект хранит внутри блока данных свое значение.

Объект-условие хранит внутри блока данных три идентификатора в следующем порядке: идентификатор метода условия, идентификатор метода, выполняемого, если условие выполнено («истина») и идентификатор метода, выполняемого, если условие не выполнено ( «ложь»).

У объектов агрегат, список и множество первое слово блока данных – размер элемента. Для списка и множества он равен 4. Для агрегата – 12.

Элементом списка и множества является идентификатор объекта. Элементом агрегата является кортеж:

  • идентификатор объекта-значения (он обязательно является потомком объекта-образца)

  • идентификатор поля (FID)

  • идентификатор объекта-образца

Если идентификатор объекта-экземпляра в списке или множестве равен нулю, это означает, что элемент удален. Признаком конца списка, множества, полей объекта служит размер виртуальной памяти, выделенной для размещения данных.


Таблица 6: Строение данных для DATIME


Длина в байтах

Значение

2

Год

1

Месяц

1

День

1

Час

1

Минуты

1

Секунды

2

Доли секунд


Такая структура журнала позво­ляет фиксировать изменения не только данных, но и поведений, knowhow…


Таблица 7: Структура записи изменений во внутреннем журнале объекта


Число байт

Значение

4

Номер транзакции

2

Адрес размещения в заголовке

4

Замененное значение

2

Год

1

Месяц

1

День

1

Час

1

Минуты

1

Секунды

2

Доли секунд


Информация о транзакциях в системе


Все пользовательские объекты в системе имеют транзакционные сообъекты. Транзакционный сообъект – это объект, хранящий информацию о воздействии операций транзакций на состояние пользовательского объекта. Ссылка на сообъект находится внутри объекта, для которого отслеживаются воздействия.


Таблица 8: Структура транзакционного сообъекта (агрегата)

Имя поля

Значение

DSL

Множество локальных зависимостей

DSI

Множество унаследованных зависимостей

DSR

Множество приобретенных зависимостей

DS

Множество зависимостей


Множество зависимостей получается объединением множеств локальных, уна­сле­дованных и приобретенных зависимостей. Каждый элемент какого-либо из этих мно­жеств зависимостей – пара номеров транзакций (Ti,Tj). Если трактовать это мно­жест­во как множество ребер графа, в кото­ром вершины – номера транзакций, а реб­ра – зави­симости между транзакциями, то наличие цикла в графе означает некор­рект­ное выпол­нение транзакций.

В целях упрощения решено отказаться от таблицы конфликтов. Таблица кон­флик­тов описывает какие операции конфликтуют между собой, т.е. может ли выпол­нять­ся операция A, если в данных момент выполняется операция B. Ячейка таблицы может принимать одно из трех значений: «Конфликтует», «Не конфликтует», «Неизвестно». Значение «Неизвестно» вводится по причине наличия механизма позднего связывания, при котором заранее не известно, конфликтуют ли операции.

Транзакции и объекты-поведения


Объекты поведения представляют собой множество объектов, поле OBJKH кото­рых хранит идентификатор выполняемого действия. Это множество имеет ширину эле­мента не 4, как обычное множество, хранящее данные, а 8. В следующих четырех бай­тах может храниться идентификатор списка – строки таблицы чередований в точках разрыва (части подсистемы транзакций). Таблица чередований образуется из точек раз­рыва и группировки спецификаций для объекта. Она позволяет определить: в каких точ­ках разрыва каких операций можно переключиться на выполнение операции, соответ­ствующей этой строке таблицы чередований. Это статическая информация, ко­торая может быть сформирована перед началом работы системы. Элемент строки та­блицы чередований состоит из 2 значений: идентификатора операции и иденти­фикатора мно­жества, хранящего номера точек разрыва.


4.3 Контекст транзакции


В системе есть объект DBIO (Database User-Intarface Object), которому известны состояния всех транзакций. Этот объект представляет собой множество, элементами которого являются объекты-агрегаты, описывающие контекст транзакции.


Таблица 9: Контекст транзакции


Имя поля

Размер в байтах

Значение

TR_MESS

4

OID сообщения

TR_KH

4

OID knowhow

TR_PARAM

4

OID агрегата с параметрами

TR_TARGET

4

OID целевого объекта сообщения

TR_RES

4

OID результата

TR_STACK

4

OID стека

TR_N

4

Номер транзакции

TR_HOSTN

4

Номер вызвавшей транзакции

TR_STATUS

1

Состояние транзакции

TR_POINT

2

Точка разрыва, в которой находимся


Для каждой транзакции выделяется свой стек. Механизм сохранения и вос­ста­нов­ления стеков описан в [7]. Стеки сохраняются в атомарных объектах.


5. Описание операций над объектами в БД


[] DB.NEW [] -- создать новую БД

[] DB.OPEN [] -- открыть БД

[] DB.CLOSE [] -- закрыть БД


Операции клонирования:


[oid] CLONE [oid'] -- клонировать объект

[] CLONE_ROOT [oid'] -- Создать объект от "Корень"

[int] CLONE_INT [oid'] -- Создать объект "Целое"

["string"] CLONE_STR [oid'] -- Создать объект "Строка"

["string"] CLONE_AGG [oid'] -- Создать объек-агрегат

[oid_if oid_then oid_else]

CLONE_BIO [oid'] -- Создать объект-условие

[] CLONE_SET [oid'] -- Создать объект-множество

[] CLONE_SEQ [oid'] -- Создать объект-последовательность


OIDROOT, OIDINT, OIDAGG, …, OIDSEQ -– Узнать идентификаторы соотв. Объектов


[oid_bhr] SET_BHR [] -- переопределить поведение

[] GET_BHR [oid] -- узнать поведение

[oid_kh] SET_KH [] -- переопределить действие

[] GET_KH [oid] -- узнать действие

[oid] GET_INT [int] -- Получить целое число из объекта-целого

[int oid] SET_INT [] -- Занести целое число в объект-целое

[oid] PRINT_STR [] -- Печатать на экране содержимое строки

["string" oid] SET_STR [] -- Занести строку в объект-строку


[oid_super oid] SUPER+ [] -- наследовать данные из oid_super в oid

[oid] DELOBJ [] -- удалить объект


Операции над множеством:


[oid_el oid] SET+E [] -- добавить элемент в множество

[oid_el oid] SET-E [] -- удалить элемент из множества

[oid_el oid] SET?E [0/1] -- найти элемент в множестве

[oid1 oid] SET+ [] -- объединение

[oid1 oid] SET- [] -- разность

[oid1 oid] SET* [] -- пересечение


Операции над списком:


[oid_el n oid] SEQ+E [] -- добавить элемент в последовательность

[n oid] SEQ-E [] -- удалить n-й элемент из

последовательности

[oid_el oid] SEQ?E [0/n] -- найти позицию в последовательности

[n oid] SEQ?N [0/oid] -- определить oid n-го элемента послед-ти


Операции над агрегатом:


[fid oid_etalon oid] AGG+F [] -- добавить поле к объекту

[fid oid] AGG-F [] -- удалить поле из объекта

[fid oid] ETALON [oid] -- получить идентификатор объекта-эталона

[fid oid] FIELD [oid] -- получить идентификатор

объекта-значения


Операции над объектом-условием:


[oid] GET_BIO

[oid_else oid_then oid_if] -- Получить параметры объекта-условия

[oid_else oid_then oid_if oid]

SET_BIO [] -- Сохранить параметры объекта-условия


Специальные операции:


[oid_str oid] SET_NAMEOBJ [oid] -- именовать объект

[oid_str fid] SET_NAMEFID [fid] -- именовать поле

[oid_str] NAMEOBJ [oid] -- получить идентификатор по имени

[oid_str] NAMEFID [fid] -- получить идентификатор поля по имени

[oid_mess oid_par oid] SEND [] -- послать сообщение объекту

[oid_mess oid_obj] METHOD? [] -- определить идентификатор метода

[oid1 oid] CHIELD [1/0] -- определить, является ли oid1 потомком oid

[oid_kh] RUN_KH [] -- выполнить knowhow

[] NCHAN [chan] -- узнать номер текущего канала

[chan] !NCHAN [] -- переключиться на заданный канал


Операции просмотра:


[oid] JVIEW [] -- просмотр журнала

[] A.VIEW [] -- просмотр адресов объектов в БД

[] Q.VIEW [] -- просмотр очереди

[] IC [] -- просмотр состояния канала


6. Требования к техническим и программным средствам


ДССП реа­лизована на множестве компьютерных платформ (VAX, PDP-11, IBM PC, R3000, MC68020, SPARC) и операционных систем (MSDOS, MSDOS-экстендеры, UNIX, RT-11, RSX, OS9, CPM и др.). В дан­ный момент практически закон­чена разработка ДССП на Си, что обес­печивает перенос этой системы на любую платформу, где есть Си.


Аппаратные средства:

Любая платформа, на которой функционирует ДССП, с объемом оперативной памяти для нужд БД не менее 1 Мб.


Программные средства:

ДССП с диспетчером параллельных процессов (версия 4.42) и Операционная Система.


Разрабатываемая СУООБД может также работать в качестве host-программы на файл-сервере, обрабатывая команды с рабочих станций, поступающие в их персональные ящики на файл-сервере. Ответ рабочие станции получают также через почтовые ящики.


В дальнейшем, могут быть реализованы сетевые протоколы и тогда СУООБД будет являться сервером в клиент-серверных приложениях.


Использование отдельных почтовых ящиков для нескольких параллельно работающих пользователей позволяет возложить на СУООБД функции монитора [6], осуществляющего линеаризацию поступающих запросов к содержимому СУООБД.


7. Реализация прототипа


7.1 Построитель

LOAD TIMEM

LOAD M0

LOAD M2

LOAD Soms

LOAD CHMS

LOAD SYSOBJS

LOAD M3

LOAD LS_CASH

UNDEF


PROGRAM $KH_VOC


7.2 Заголовочный модуль для каналов


PROGRAM $M0

B16

1000 VALUE TOTMEMLEN

TOTMEMLEN BYTE VCTR MEMORY

: T-1 D -1 ;

: *4 SHL SHL ;

: &0FF 0FF & ;

: <= 1+ < ;

: >= 1- > ;

[20 WORD VCTR CHAN] [каналы. Начиная с 5-го]

VAR NCHAN [Номер текущего канала]

: !NCHAN ! NCHAN ;


5 VALUE NBASECH [Первый не базовый канал]


: GETDATA NCHAN 10 * + CHDATA ;

: PUTDATA NCHAN 10 * + ! CHDATA ;


[Размер заголовка блока в байтах]

FIX VAR HSIZE 10 ! HSIZE

: HSIZE+ HSIZE + ;


[Pred, Next, BusyLen, Len]

1 *4 VALUE ctfPREDADDR


[$M4] [как самодостаточный]

0 VALUE ctLOWCH [Нижний канал.]

[0=Оперативная/1=Дисковая память/2=Журнал/-1=свободен]

1 VALUE ctTEKADR [Логический адрес внутри участка (по данным)]

2 VALUE ctBUSYLEN [Длина фрагмента, занятая данными]

3 VALUE ctLEN [Максимальная допустимая длина данных фрагмента]

4 VALUE ctTEKADR0 [=TEKADR, когда TEKADR стоит на нулевом байте данных фрагм]


5 VALUE ctNEXTADDR [Адрес начала заголовка следующего фрагмента (пф)]

6 VALUE ctPREDADDR [Адрес начала заголовка предыдущего фрагмента (пф)]

7 VALUE ctSYNCADDR [Адрес начала заголовка фрагмента (пф)]

8 VALUE ctCHGCTX [признак изменения контекста]

9 VALUE ct1STLONG [Первое число в канале]

[в начальном блоке в начальном слове данных лежит адрес начала данных]


: LOWCH ctLOWCH GETDATA ; : !LOWCH ctLOWCH PUTDATA ;

: TEKADR ctTEKADR GETDATA ; : !TEKADR ctTEKADR PUTDATA ;

: TEKADR0 ctTEKADR0 GETDATA ; : !TEKADR0 ctTEKADR0 PUTDATA ;

: TEKADR++ TEKADR 1+ !TEKADR ; : !+TEKADR TEKADR + !TEKADR ;

: BUSYLEN ctBUSYLEN GETDATA ; : !BUSYLEN ctBUSYLEN PUTDATA ;

: LEN ctLEN GETDATA ; : !LEN ctLEN PUTDATA ;

: NEXTADDR ctNEXTADDR GETDATA ; : !NEXTADDR ctNEXTADDR PUTDATA ;

: PREDADDR ctPREDADDR GETDATA ; : !PREDADDR ctPREDADDR PUTDATA ;

: SYNCADDR ctSYNCADDR GETDATA ; : !SYNCADDR ctSYNCADDR PUTDATA ;

: CHGCTX ctCHGCTX GETDATA ; : !CHGCTX ctCHGCTX PUTDATA ;

: FSTLONG ct1STLONG GETDATA ; : !FSTLONG ct1STLONG PUTDATA ;


TRAP NOMEMORY NOMEMORY#

: NOMEMORY# ."

No free memory" ;


TRAP OUTDATA OUTDATA#

: OUTDATA# ."

Out of data. " ;


TRAP OUTMEM OUTMEM#

: OUTMEM# ."

Out of memory. " ;


TRAP UNKCH UNKCH#

: UNKCH# ."

Unknown primitive channel:" NCHAN .D CR ;


TRAP O_NOTFND NOTFND#


: NOTFND# ."

Object not found. OID=" . CR ;


[*** Информация по каналу ***]

: IC CR

." NCHAN=" NCHAN .D SP ." LOWCH=" LOWCH .D CR

."SYNCADDR=" SYNCADDR .D SP ."PREDADDR=" PREDADDR .D SP ."NEXTADDR="

NEXTADDR .D CR

." BUSYLEN=" BUSYLEN .D SP ." LEN=" LEN .D CR

." TEKADR0=" TEKADR0 .D SP ." TEKADR=" TEKADR .D CR ;


CHANNEL DATACH "DATA." CONNECT DATACH


7.3 Менеджер виртуальной памяти


PROGRAM $M2

B16 [физическая организация памяти]


[вычисление физического адреса и номера базового канала]

:: : POSIX [addr(i)] NCHAN C NBASECH <