Bocha (bochafreebsd) wrote,
Bocha
bochafreebsd

Как я встретил Oracle. Страшилка для тех, кто никогда его в глаза не видел.



Когда-то давно, в 2011м году я устанавливал Oracle Database Express десятой версии на пятый CentOS для одной команды программистов, и было это довольно просто, база встала, пароли передал ребятам, они дальше всё сделали сами, я получил свои бабки и забыл.

И вот случилось мне на днях снова ввязаться в историю с Oracle. На этот раз надо было поставить Oracle Database 12c, с которой будет работать сайт на PHP. Ну, так уж получилось. Что я вообще знаю о базах данных? Да не многое. Всё, что я напишу дальше, будет вызывать у нормального Oracle-админа только смех и презрение, так что таковых прошу срочно закрыть этот пост. Но меня эта хрень довела неподетски.

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

Oracle же - это Дивный Новый Мир. Она напомнила мне игру на Atari Jaguar "Атака Пингвинов-мутантов": по карте ходят пингвины, они покупают билеты и идут в будку трансформации, откуда они выходят злыми пингвинами-мутантами, идут к Пещере Забвения, прыгают в её пасть и попадают на платформу, вам нужно остановить пингвинов используя оружие, например бейсбольной битой. Как получить биту? Нужно собрать буквы, которые напишут слово "БИТА". Где найти буквы? Внутри сундуков с сокровищами, конечно. Как отрыть такой сундук? Гремлинами, конечно! Нужно собрать много гремлинов и кинуть их в сундук. Но он не откроется сразу, а только через 10 секунд. Чем больше гремлинов, тем быстрее откроется. А точнее взорвется. Вы получите биту и будете бить пингвинов, но они от этого не умирают, вместо этого из них выпрыгивают Сферы Силы. Нужно собрать эти Сферы, чтобы зарядить биту. Но бить нужно только тех пингвинов, которые в шляпе, потому что пингвины без шляпы борются с пингвинами, которые в шляпе. Если количество пингвинов в шляпе на платформе превысит количество пингвинов без шляпы, то Пещера начнет кричать и Гейм Овер. Всё же логично и интуитивно понятно, так?

Ну так вот представьте, что до сих пор вы работали с MySQL или в лучшем случае с Postgres. Если вы хотите подключиться из PHP к своей базе, то что вам нужно? Наверное адрес, логин, пароль и имя базы. Ничего похожего. Начнем с того, что, во-первых всё, что вы хотите сделать (например запустить веб-сервер доступа к базе, именуемый Application Express или просто ApEx, APEX) - делается через транзакцию внутри командной строки SQLplus. Думаете, это делается командой а-ля "SERVICE APEX START;" ? Ничего похожего. Командой к запуску является указание его порта. Саму команду приводить не буду. Там всё круто начиная с логина в SQLplus и заканчивая синтаксисом.

Предположим, вам удалось запустить APEX, и вы подключаетесь к базе через веб. Логично для входа использовать юзернэйм основного админа и его пароль. Но кто из них главный админ, если вы заводили как минимум три внутрибазовых аккаунта SYS, SYSDBA и SYSTEM, и еще как минимум пять-семь аккаунтов в самой системе, у всех разные пароли разумеется. Правильный ответ - ни один из них не является админом APEX. Вы должны руками создать пользователя ADMIN внутри базы APEX_0X00X000, где X зависит от версии вашей базы.

Но поговорим о базе APEX_0X00X000. Для начала вы должны вообще осознать, что это - база. Потому что я вижу, что с точки зрения ORACLE это - SCHEMA. Что же такое SCHEMA? Пользователь или база данных? Правильный ответ - и то и другое. Так значит пользователь и база в Оракле - одно и то же? "Короткий ответ - да. Ответ по-длиннее - нет." (с) Симпсоны. Серьёзно, исходя из документации это - разные вещи, но границы за 30 лет существования Оракла давно стёрлись и для вас же будет проще, если вы будете считать, что в Оракле юзер и база данных - это одно и то же. Вы вполне можете создать базу данных, назначить ей пароль, дать ей, то есть базе, внимание, права на редактирование другой базы, и она будет вашим юзером для доступа извне в какую-то другую базу данных.

Так значит, надо создать базу данных с паролем и по этим реквизитам входить в APEX? Конечно нет. Нужно внутри юзера-базы APEX_0X00X000 создать запись о юзере ADMIN с паролем, который может быть любым, но обязательно должен быть сменён при первом входе на любой другой, отвечающий как минимум вот этим требованиям:
- он должен отличаться от старого на два символа
- он должен содержать маленькую букву, большую букву и, внимание, знак препинания.
Безопасность, все дела.

И когда вы наконец зайдете на ваш http://127.0.0.1/apex вы получите возможность залогиниться под админом? Не смешите меня, конечно же нет. Он будет у вас спрашивать логин и пароль снова и снова. Почему? Да потому что у вас есть база-юзер ANONYMOUS, который у вас LOCKED & EXPIERED. Вы должны его разлочить и задать ему пароль. Ну, разумеется, а как еще Анонимус - и без пароля? Безопасность же! Какое отношение, спросите вы, имеет пользователь ANONYMOUS ко всему происходящему и как вы должны были догадаться что дело в нем? Ах, задайте этот вопрос техподдержке Oracle. Если она у вас есть, конечно. Скажу сразу, что я ставлю базу, купленную за деньги, есть лицензия, есть цена, но нет абсолютно никакой поддержки. И еще: никогда и нигде при установке и эксплуатации базы она не спрашивала меня ни про какую лицензию. Надо ли было её покупать в таком случае? Ну, пожалуй, нет.

Думаете, теперь-то вы попадете под своими реквизитами админа в админку APEX? Чёрта с два! Немного помучившись вы поймете, что УРЛ тупо не тот. Для доступа в админку нужно указывать в УРЛе http://127.0.0.1/apex/apex_admin
И там можно создавать новых юзеров и новые SCHEMA. "Но ведь это одно и то же" скажите вы. Ничего похожего. В APEX-е это вещи разные. "Ну и ладно", - снова скажете вы, "ведь главное теперь ясно какая схема-база из-под какого заведенного юзера доступна, и с каким паролем то же, а это главное". Вынужден снова вас разочаровать. Всё, что вы будете творить в вашем APEX Workspace - виртуально, и нигде, кроме как в самом АПЕКСе роли не играет. Я вам больше скажу, перезагрузите базу, и ваши пароли к вашим апексовским аккаунтам больше не подойдут.

А что вообще такое APEX Workspace спросите вы. Отличный вопрос, отвечу я вам. Какое отношение он имеет к SCHEMA, к базе данных, к юзерам и их паролям? Ответ вполне уже обычный - абсолютно никакого. Можно создавать воркспейсы, называть их как угодно и прикручивать к ним какие угодно "схемы", у них будут разные админы с разными паролями, разные юзеры, но куда девается всё, что наработано в виртуальных схемах этих виртуальных рабочих пространств - честно, я понятия не имею. Такое впечатление, что никуда, в /dev/null. Если уж на то пошло, меня куда больше интересует вот что: если админы для каждого воркспейса разные, и нет никакой особой иерархии воркспейсов - они все равны - то не ясно тогда, если я меняю пароль админа через sqlplus, то пароль какого именно админа, то есть админа какого именно воркспейса, я всё-таки меняю? Ответа у меня нет.

Так как же в АПЕКСе редактировать базу, в которую можно уже наконец будет попасть из PHP? Ну, теоретически делается это так: админ АПЕКСа через админку АПЕКСа создает новый Воркспэйс, привязывает его к созданному в SQLPlus SCHEMA, и вот тогдаааа.... Понятно, скажете вы, значит можно в SQLPlus-е создать схему SITE, задать ей пароль password, затем надобавлять таблиц в APEX-е из-под апексовского юзера, а затем подключиться к этой базе из PHP с логином SITE, и паролем password?

Давайте я перечислю хотя бы минимальный список того, что встанет на пути у такой идеи вот просто сразу же. Во-первых, ну разумеется, имя базы не может быть SITE, как вы могли такое подумать. Оно обязательно должно начинаться с символов C##, то есть имя базы должно быть как минимум C##SITE. Это раз. Во-вторых синтаксис подключения к базе в PHP через библиотеку OCI8 таков, что адрес хоста указывается через <хост>/<имя базы>. И <имя базы> тут не имеет никакого отношения к вашему C##SITE. Всё это время вы работаете внутри, по сути, одной большой базы, имя которой вы задали при установке Оракла. По умолчанию это будет что-то вроде orcl.ru или просто orcl. При этом Оракл при установке настаивает, что имя базы должно иметь вид имя.домен, но если вы так и сделаете, то помните, что в переменных окружения вашего шелла, например баша, ORACLE_CID должен иметь вид <имя> безо всякого домена, то есть вместе с <.домен> это всё работать не будет, SQLplus вас не пустит. Но когда вы будете подключаться из OCI8, ситуация будет обратной - только localhost/orcl.ru будет работать, localhost/orcl работать не будет. Ну и самое главное - это всё будет работать только при консольном использовании php из-под шелла, где все эти переменные прописаны в окружении, Apache этот же самый php-скрипт обрабатывать не будет, будет жаловаться, что понятия не имеет, где находится ваш ORACLE_HOME, хотя вам не просто пришлось указать эту переменную не раз - вам даже пришлось собирать с этой переменной саму библиотеку OCI8, она не может поставляться в precompiled-виде просто потому, что параметр с путём до базы должен быть hard-compiled в каждом конкретном случае. И это, блин, разрыв шаблона. Вы даже будете наблюдать этот путь в phpinfo(), но Апачу это как об стенку горох. Ищите способ сообщить ему этот путь сами.

Вы, вероятно, захотите прописать эти переменные в /etc/environment и перезагрузить сервак - вперёд. Только если вам придется перезагрузить сервер, чтобы какие-то изменения вступили силу - берегитесь. База, разумеется, сама после ребута не поднимется. И у неё на это масса причин. Первая и, я думаю, основная - это systemd, о его, Дивного Нового Мира by itself, поддержке в Оракле, я уверен, даже и не думали. В конце-концов у Оракла есть свой собственный Unbreakable Linux, который они, видимо, только и поддерживают, а остальное, ну, как повезет. Читал, как везёт Убунтушникам, мама дорогая. Так вот после ребута вы можете проверить, что в netstat не слушается ни порт 1521, основной порт Оракла, ни порт АПЕКСа (обычно 8080). Вы найдете в интернете, несомненно, что за слушание порта 1521 отвечает TNSlistener, вы для его аж три пользователя завели на стадии установки, но подняв его и увидев в netstat-е заветный порт вы обнаружите, что ничего по сути не изменилось. Поднять сетевую слушалку - не значит поднять базу. Чтобы поднять базу, нужно запустить скрипт поднятия базы, который тоже опирается на кучу переменных окружения, скорее всего прописанных у вас только под пользователем oracle, и root поднять вашу базу не может никак. Это дурной сон какой-то, ей богу. В общем, вы разберетесь в dbstart/dbshut и это перестанет быть для вас проблемой, но время на это обязательно уйдет, а ведь ничего сложного автоматизировать этот процесс самими программистами Оракла вроде бы не было. И, да, забыл сказать, прописывание переменных в /etc/environment ничего не даст. Абсолютно ничего.

Теоретически, и даже - вполне практически, после всех мучений, я добился того, что я могу из консольной утилиты SQLplus создать таблицу в базе C##SITE и затем из консольного PHP её успешно прочитать. То есть в принципе для того, чтобы сайт работал на оракле - этого вполне достаточно. Загрузите туда базу через SQLplus и затем вызывайте из PHP. Но APEX после рестарта сервера больше не пускает меня в админку, а когда я сменил пароль админа через SQLPlus, он стал в ответ на вход просто писать password must be changed, но не предлагает больше поле для введения нового пароля. Это тупик. Программисты для разработки сайта без вариантов требуют именно APEX, а у меня тупо кончились идеи, как снова в него попасть.

Короче, блин. Кто всё это придумал и зачем?

Оптимизма не добавляет и типичный ответ на форуме поддержки Оракл, цитирую "Вы столкнулись в процессе настройки с ошибкой <такой-то>? Добро пожаловать в ад!" Большое спасибо, я в нем уже три дня.
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

  • 5 comments