Начало:
1. Необходимая предыстория, назад:
История SQL. 9. System R, Phase Two.
На протяжении всей серии я вольно обращался с темой «история SQL», то и дело отвлекаясь на соседние, интересные мне темы. Отвлекусь и сейчас, потому что история Оракла занятно переплетается с историей System R.
Вообще техническую информацию о ранних годах Оракла найти неизмеримо сложнее. Это не удивительно, ведь System R была исследовательским проектом и до 1979 года никаких ограничений на публикацию статей не имелось, а Оракл - изначально фирма коммерческая и закрытая. Что-то знают все, какие-то сведения менее известны, а некоторые еще ждут своего археолога. Пойдем, однако, по порядку.
В 1977 году Ларри Эллисон, имевший опыт работы над навигационной базой данных (для ЦРУ, проект назывался ORACL), прочитал статью Кодда и проникся реляционной идеей. Он основал компанию Software Development Laboratories вместе с Эдом Оатсом и Бобом Майнером, а вскоре к ним еще присоединился Брюс Скотт. Прочитав статьи про System R и язык Sequel (вспомним, что в статьях было все, вплоть до БНФ-синтаксиса), коллеги решили, что смогут достаточно быстро сделать свою реализацию реляционной СУБД. Ларри хотел сделать это раньше, чем IBM выпустит свою коммерческую реализацию, но при этом быть совместимым. Вспоминает Дон Чемберлин:
Он узнал о System R и хотел, чтобы его продукт был полностью совместим, вплоть до кодов ошибок. Мы спросили Франка [Кинга]: «Можем ли мы дать коды ошибок этому Эллисону?», но он сказал: «Нет, это конфиденциальная информация».
Тут я нарушу ход истории своим изысканием. Задумывались ли вы когда-нибудь, почему в Оракле исключение no_data_found имеет код +100, в то время, как остальным исключениям присвоен отрицательный номер? Фейерштейн пишет, что это, дескать, ANSI standard error number, но первый стандарт появился только в 1986 году! А теперь посмотрим внимательно на упоминавшийся ранее отчет «Support for Repetitive Transactions and Ad-hoc Query in System R» 1979 года. В нем промелькнул следующий фрагмент кода:
$SELECT DESCRIP,QOH,QOO INTO $DESCRIP,$QOH,$QOO
FROM PARTS WHERE PARTNO=$PARTNO;
IF SYR_CODE = 0 THEN
Write DESCRIP, QOH, QOO on terminal;
ELSE IF SYR_CODE = 100 THEN
Write 'THERE IS NO SUCH PART' on terminal;
ELSE CALL TROUBLE('SELECT');
Полагаю, что дело было так. Ларри, очевидно, читал все материалы по System R и видел этот фрагмент. Пусть ему не удалось получить все коды System R, но +100 ему ничего не могло помешать использовать. А уже потом стандарт «узаконил» получившуюся странность. В одном документе есть фрагмент диалога о трудностях стандартизации между Доном Чемберлином от IBM и Кеном Якобсом от Оракл (оба входили в комитет ANSI):
Чемберлин: - У нас также были проблемы с кодами ошибок.
Якобс: - Стало быть, они были не только у Оракла?
Кстати, вот такое определение кодам ошибок дается в ANSI SQL-1992 (на Аде):
type SQLCODE-TYPE is range bsc .. tsc;
subtype SQL_ERROR is SQLCODE-TYPE range SQL-TYPE'FIRST .. -1;
subtype NOT_FOUND is SQLCODE-TYPE range 100 .. 100;
В тему будет привести слова Роджера Бэмфорда, участнику команды System R, перешедшему затем в Оракл:
Насчет влияния System R на Оракл: некоторые идеи пришли из Esvel, некоторые из System R. Но исходный код выглядел так, словно они прочитали статью, описывавшую язык, сели за компьютер и начали программировать. И было понятно, как писали код: все структуры данных напрямую отображали язык в аппаратуру безо всяких промежуточных слоев. «Так, вот у нас блок запроса, вот у него часть select, а вот то-то и то-то».
Однако возвратимся к повествованию. Спустя два года, в 1979-м, фирма изменила название на Relational Software, Inc и выпустила первый релиз системы. Он получил название Oracle version 2, поскольку Ларри полагал, что первую версию никто не купит. Система была написана на ассемблере DEC PDP-11 и занимала порядка 100 КБ оперативной памяти (из 128).
В 1982 году компания переименовалась в Oracle Systems Corporation, и с тех пор, несмотря на последующие изменения названия, слово Oracle уже не покидало ее имя.
Третья версия появилась в 1983 году. Чтобы облегчить портирование СУБД на другую аппаратуру, весь код был переписан на C, тогда еще не слишком популярном языке. Выбор оказался правильным и с тех пор доступность базы на разных платформах стала одним из коньков Оракла. Версия 3 была написана преимущественно Брюсом Скоттом. Правда, он ушел из Оракла до выпуска релиза, так что часть работы доделывал Боб Майнер. Слово Роджеру Бэмфорду:
Когда я пришел, они были на третьей версии, практически завершенной парнем по имени Брюс Скотт... Он переписал ее и создал действительно красивый, компактный и хорошо структурированный код; многое из этого кода сохранилось и сейчас.
Кстати, Роджер - не единственный из System R, кого Ларри звал в свою команду (Дон Слац не принял предложения, а Франко Путцолу присоединился позже).
Система во времена версии 3 была нестабильной. Снова Роджер:
В то время использовать Оракл можно было единственным образом: каждый день экспортировать все данные, ждать, пока база накроется, и загружать данные обратно. И все были довольны. То есть, конечно заказчики были не в восторге, но не придавали этому большого значения, потому что СУБД не использовалась как транзакционная система.
Примерно тогда же был написан командный интерпретатор, который не долго думая назвали так же, как в System R: UFI - User Friendly Interface. Позже его переименовали в SQL*Plus.
Уйдя из Оракла, Брюс довольно оригинально увековечил память о себе: все знают аккаунт scott/tiger (правда, не все догадываются, что это тот самый Брюс Скотт).
В 1984 году была выпущена четвертая версия, интересная прежде всего появлением согласованных чтений.
Пятую пропустим (заметив в скобках, что в 1987 году в Оракле началась работа над Applications, ныне OEBS), зато остановимся на шестой, увидевшей свет в 1988 году. Ее ведущим архитектором был Роджер Бэмфорд и в этом релизе была переписана часть, отвечавшая за доступ к данным, а это грубо говоря половина всей системы. Был полностью изменен низкоуровневый формат данных и механизм согласованный чтений, появились журнализация, восстановление, блокировки уровня строк:
Строки в версиях 3, 4, 5 были просто конкатенированы в блоках, байт за байтом, безо всяких индексов или указателей. Если вам надо было попасть на строку 12, вы начинали с начала блока и сканировали столбцы, строки... и да, со временем попадали именно туда, куда вам было нужно. А как изменять строку, если значение в столбце увеличивается? Ну, вы брали и сдвигали остаток блока вправо. Поэтому в версии 6 мы все это поменяли. ... С тех пор оно и работает без кардинальных изменений.
До этого Оракл обеспечивал согласованные чтения без механизма мультиверсионности, сохраняя при изменениях образ всего блока (past image). Интересно, что похожая техника используется сейчас для Flashback Database.
Еще версия 6 интересна тем, что в ней впервые появился процедурный язык поверх SQL. PL/SQL основан на синтаксисе языка Ада. Ада была современным языком на пике популярности и к тому же поддерживалась на государственном уровне, так что в целом выбор выглядит логичным, вот только мне не удалось найти никакой достоверной информации о том, как принималось это решение. По-видимому, для PL/SQL был разработан свой собственный компилятор, хотя и в строгом соответствии с имевшимися опубликованными наработками (так же, как было и с SQL). К этому заключению приводят две мысли. Во-первых, многие идеи, заложенные в Аду, в PL/SQL не попали, хотя специально выбрасывать их поддержку было бы странно (особенно это коснулось типизации данных). Во-вторых, от Ады все-таки был унаследован не только синтаксис, но и внутреннее устройство компилятора. Вот что сообщает нам PL/SQL User’s Guide and Reference:
PL/SQL is based on the programming language Ada. As a result, PL/SQL uses a variant of Descriptive Intermediate Attributed Notation for Ada (DIANA), a tree-structured intermediate language. It is defined using a meta-notation called Interface Definition Language (IDL). DIANA is used internally by compilers and other tools.
At compile time, PL/SQL source code is translated into machine-readable m-code. Both the DIANA and m-code for a procedure or package are stored in the database. At run time, they are loaded into the shared memory pool. The DIANA is used to compile dependent procedures; the m-code is simply executed.
То есть, код PL/SQL компилируется в то же внутреннее представление, что и Ада (DIANA), а затем в m-код, исполняемый PL/SQL-машиной. DIANA представляет собой атрибутированное дерево разбора и записывается в виде IDL (в базе это представление можно увидеть в таблицах sys.idl_%$).
Ну что ж, на этом археология уступает место новейшей истории, а мой рассказ заканчиваются.
Почитать и посмотреть: