Русский
Русский
English
Статистика
Реклама

Data guard

Путеводитель по репликации баз данных

10.08.2020 14:22:42 | Автор: admin
Повторяться, но каждый раз по-новому разве не это есть искусство?

Станислав Ежи Лец, из книги Непричёсанные мысли

Словарь определяет репликацию как процесс поддержания двух (или более) наборов данных в согласованном состоянии. Что такое согласованное состояние наборов данных отдельный большой вопрос, поэтому переформулируем определение проще: процесс изменения одного набора данных, называемого репликой, в ответ на изменения другого набора данных, называемого основным. Совсем не обязательно наборы при этом будут одинаковыми.



Поддержка репликации баз данных одна из важнейших задач администратора: почти у каждой сколько-нибудь важной базы данных есть реплика, а то и не одна.

Среди задач, решаемых репликацией, можно назвать как минимум

  • поддержку резервной базы данных на случай потери основной;
  • снижение нагрузки на базу за счёт переноса части запросов на реплики;
  • перенос данных в архивные или аналитические системы.

В этой статье я расскажу о видах репликации и о том, какие задачи решает каждый вид репликации.


Можно выделить три подхода к репликации:

  • Блочная репликация на уровне системы хранения данных;
  • Физическая репликация на уровне СУБД;
  • Логическая репликация на уровне СУБД.

Блочная репликация


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



К достоинствам такой репликации можно отнести простоту настройки и надёжность. Записывать данные на удалённый диск может либо дисковый массив, либо нечто (устройство или программное обеспечение), стоящее между хостом и диском.

Дисковые массивы могут быть дополнены опциями, позволяющими включить репликацию. Название опции зависит от производителя массива:

Производитель Торговая марка
EMC SRDF (Symmetrix Remote Data Facility)
IBM Metro Mirror синхронная репликация
Global Mirror асинхронная репликация
Hitachi TrueCopy
Hewlett-Packard Continuous Access
Huawei HyperReplication

Если дисковый массив не способен реплицировать данные, между хостом и массивом может быть установлен агент, осуществляющей запись на два массива сразу. Агент может быть как отдельным устройством (EMC VPLEX), так и программным компонентом (HPE PeerPersistence, Windows Server Storage Replica, DRBD). В отличие от дискового массива, который может работать только с таким же массивом или, как минимум, с массивом того же производителя, агент может работать с совершенно разными дисковыми устройствами.

Главное назначение блочной репликации обеспечение отказоустойчивости. Если база данных потеряна, то можно перезапустить её с использованием зеркального тома.

Блочная репликация хороша своей универсальностью, но за универсальность приходится платить.

Во-первых, никакой сервер не может работать с зеркальным томом, поскольку его операционная система не может управлять записью на него; с точки зрения наблюдателя данные на зеркальном томе появляются сами собой. В случае аварии (отказ основного сервера или всего ЦОДа, где находится основной сервер) следует остановить репликацию, размонтировать основной том и смонтировать зеркальный том. Как только появится возможность, следует перезапустить репликацию в обратном направлении.

В случае использования агента все эти действия выполнит агент, что упрощает настройку, но не уменьшает время переключения.

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

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

Блочная репликация не может использоваться для распределения нагрузки, а для обновления хранилища данных используется похожая схема, когда зеркальный том находится в том же массиве, что и основной. У EMC и HP эта схема называется BCV, только EMC расшифровывает аббревиатуру как Business Continuance Volume, а HP как Business Copy Volume. У IBM на этот случай нет специальной торговой марки, эта схема так и называется mirrored volume.



В массиве создаются два тома, и операции записи синхронно выполняются на обоих (A). В определённое время зеркало разрывается (B), то есть тома становятся независимыми. Зеркальный том монтируется к серверу, выделенному для обновления хранилища, и на этом сервере поднимается экземпляр базы данных. Экземпляр будет подниматься так же долго, как и при восстановлении с помощью блочной репликации, но это время может быть существенно уменьшено за счёт разрыва зеркала в период минимальной нагрузки. Дело в том, что разрыв зеркала по своим последствиям эквивалентен аварийному завершению СУБД, а время восстановление при аварийном завершении существенно зависит от количества активных транзакций в момент аварии. База данных, предназначенная для выгрузки, доступна как на чтение, так и на запись. Идентификаторы всех блоков, изменённых после разрыва зеркала как на основном, так и на зеркальном томе, сохраняются в специальной области Block Change Tracking BCT.

После окончания выгрузки зеркальный том размонтируется (С), зеркало восстанавливается, и через некоторое время зеркальный том вновь догоняет основной и становится его копией.

Физическая репликация


Журналы (redo log или write-ahead log) содержат все изменения, которые вносятся в файлы базы данных. Идея физической репликации состоит в том, что изменения из журналов повторно выполняются в другой базе (реплике), и таким образом данные в реплике повторяют данные в основной базе байт-в-байт.

Возможность использовать журналы базы данных для обновления реплики появилась в релизе Oracle7.3, который вышел в 1996 году, а уже в релизе Oracle 8i доставка журналов с основной базы в реплику была автоматизирована и получила название DataGuard. Технология оказалась настолько востребованной, что сегодня механизм физической репликации есть практически во всех современных СУБД.

СУБД Опция репликации
Oracle Active DataGuard
IBM DB2 HADR
Microsoft SQL Server Log shipping/Always On
PostgreSQL Log shipping/Streaming replication
MySQL Alibaba physical InnoDB replication

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

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

Естественно, никаких ограничений на модели СХД физическая репликация не накладывает. Более того, файлы в базе-реплике могут располагаться совсем по-другому, чем на базе-источнике надо лишь описать соответствие между томами, на которых лежат эти файлы.

Oracle DataGuard позволяет удалить часть файлов из базы-реплики в этом случае изменения в журналах, относящиеся к этим файлам, будут проигнорированы.

Физическая репликация базы данных имеет множество преимуществ перед репликацией средствами СХД:

  • объём передаваемых данных меньше за счёт того, что передаются только журналы, но не файлы с данными; эксперименты показывают уменьшение трафика в 5-7 раз;
  • переключение на резервную базу происходит значительно быстрее: экземпляр-реплика уже поднят, поэтому при переключении ему нужно лишь откатить активные транзакции; более того, к моменту сбоя кеш реплики уже прогрет;
  • на реплике можно выполнять запросы, сняв тем самым часть нагрузки с основной базы. В частности, реплику можно использовать для создания резервных копий.

Возможность читать данные с реплики появилась в 2007 году в релизе Oracle 11g именно на это указывает эпитет active, добавленный к названию технологии DataGuard. В других СУБД возможность чтения с реплики также есть, но в названии это никак не отражено.

Запись данных в реплику невозможна, поскольку изменения в неё приходят побайтно, и реплика не может обеспечить конкурентное исполнение своих запросов. Oracle Active DataGuard в последних релизах разрешает запись в реплику, но это не более чем сахар: на самом деле изменения выполняются на основной базе, а клиент ждёт, пока они докатятся до реплики.

В случае повреждения файла в основной базе можно просто скопировать соответствующий файл с реплики (прежде, чем делать такое со своей базой, внимательно изучите руководство администратора!). Файл на реплике может быть не идентичен файлу в основной базе: дело в том, что когда файл расширяется, новые блоки в целях ускорения ничем не заполняются, и их содержимое случайно. База может использовать не всё пространство блока (например, в блоке может оставаться свободное место), но содержимое использованного пространства совпадает с точностью до байта.

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

В PostgreSQL есть возможность сконфигурировать репликацию так, чтобы commit завершался только после применения изменений к данным реплики (опция synchronous_commit = remote_apply), а в Oracle можно сконфигурировать всю реплику или отдельные сессии, чтобы запросы выполнялись только если реплика не отстаёт от основной базы (STANDBY_MAX_DATA_DELAY=0). Однако всё же лучше проектировать приложение так, чтобы запись в основную базу и чтение из реплик выполнялись в разных модулях.

При поиске ответа на вопрос, какой режим выбрать, синхронный или асинхронный, нам на помощь приходят маркетологи Oracle. DataGuard предусматривает три режима, каждый из которых максимизирует один из параметров сохранность данных, производительность, доступность за счёт остальных:

  • Maximum performance: репликация всегда асинхронная;
  • Maximum protection: репликация синхронная; если реплика не отвечает, commit на основной базе не завершается;
  • Maximum availability: репликация синхронная; если реплика не отвечает, то репликация переключается в асинхронный режим и, как только связь восстанавливается, реплика догоняет основную базу и репликация снова становится синхронной.

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

Во-первых, в случае репликации средствами дискового массива трафик идёт не по сети передачи данных (LAN), а по сети хранения данных (Storage Area Network). Зачастую в инфраструктурах, построенных давно, SAN гораздо надёжнее и производительнее, чем сеть передачи данных.

Во-вторых, синхронная репликация средствами СУБД стала надёжной относительно недавно. В Oracle прорыв произошёл в релизе 11g, который вышел в 2007 году, а в других СУБД синхронная репликация появилась ещё позже. Конечно, 10 лет по меркам сферы информационных технологий срок не такой уж маленький, но когда речь идёт о сохранности данных, некоторые администраторы до сих пор руководствуются принципом как бы чего не вышло

Логическая репликация


Все изменения в базе данных происходят в результате вызовов её API например, в результате выполнения SQL-запросов. Очень заманчивой кажется идея выполнять одну и ту же последовательность запросов на двух разных базах. Для репликации необходимо придерживаться двух правил:

  1. Нельзя начинать транзакцию, пока не завершены все транзакции, которые должны закончиться раньше. Так на рисунке ниже нельзя запускать транзакцию D, пока не завершены транзакции A и B.
  2. Нельзя завершать транзакцию, пока не начаты все транзакции, которые должны закончиться до завершения текущей транзакции. Так на рисунке ниже даже если транзакция B выполнилась мгновенно, завершить её можно только после того, как начнётся транзакция C.

Репликация команд (statement-based replication) реализована, например, в MySQL. К сожалению, эта простая схема не приводит к появлению идентичных наборов данных тому есть две причины.

Во-первых, не все API детерминированы. Например, если в SQL-запросе встречается функция now() или sysdate(), возвращающая текущее время, то на разных серверах она вернёт разный результат из-за того, что запросы выполняются не одновременно. Кроме того, к различиям могут привести разные состояния триггеров и хранимых функций, разные национальные настройки, влияющие на порядок сортировки, и многое другое.

Во-вторых, репликацию, основанную на параллельном исполнении команд, невозможно корректно приостановить и перезапустить.



Если репликация остановлена в момент T1 транзакция B должна быть прервана и откачена. При перезапуске репликации исполнение транзакции B может привести реплику к состоянию, отличному от состояния базы-источника: на источнике транзакция B началась до того, как закончилась транзакция A, а значит, она не видела изменений, сделанных транзакцией A.
Репликация запросов может быть остановлена и перезапущена только в момент T2, когда в базе нет ни одной активной транзакции. Разумеется, на сколько-нибудь нагруженной промышленной базе таких моментов не бывает.

Обычно для логической репликации используют детерминированные запросы. Детерминированность запроса обеспечивается двумя свойствами:

  • запрос обновляет (или вставляет, или удаляет) единственную запись, идентифицируя её по первичному (или уникальному) ключу;
  • все параметры запроса явно заданы в самом запросе.

В отличие от репликации команд (statement-based replication) такой подход называется репликацией записей (row-based replication).

Предположим, что у нас есть таблица сотрудников со следующими данными:

ID Name Dept Salary
3817 Иванов Иван Иванович 36 1800
2274 Петров Пётр Петрович 36 1600
4415 Кузнецов Семён Андреевич 41 2100

Над этой таблицей была выполнена следующая операция:

update employee set salary = salary*1.2 where dept=36;


Для того, чтобы корректно реплицировать данные, в реплике будут выполнены такие запросы:

update employee set salary = 2160 where id=3817;update employee set salary = 1920 where id=2274;


Запросы приводят к тому же результату, что и на исходной базе, но при этом не эквивалентны выполненным запросам.

База-реплика открыта и доступна не только на чтение, но и на запись. Это позволяет использовать реплику для выполнения части запросов, в том числе для построения отчётов, требующих создания дополнительных таблиц или индексов.

Важно понимать, что логическая реплика будет эквивалентна исходной базе только в том случае, если в неё не вносится никаких дополнительных изменений. Например, если в примере выше в реплике добавить в 36 отдел Сидорова, то он повышения не получит, а если Иванова перевести из 36 отдела, то он получит повышение, несмотря ни на что.

Логическая репликация предоставляет ряд возможностей, отсутствующих в других видах репликации:

  • настройка набора реплицируемых данных на уровне таблиц (при физической репликации на уровне файлов и табличных пространств, при блочной репликации на уровне томов);
  • построение сложных топологий репликации например, консолидация нескольких баз в одной или двунаправленная репликация;
  • уменьшение объёма передаваемых данных;
  • репликация между разными версиями СУБД или даже между СУБД разных производителей;
  • обработка данных при репликации, в том числе изменение структуры, обогащение, сохранение истории.

Есть и недостатки, которые не позволяют логической репликации вытеснить физическую:

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

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

Есть несколько способов реализации логической репликации, и каждый из этих способов реализует одну часть возможностей и не реализует другую:

  • репликация триггерами;
  • использование журналов СУБД;
  • использование программного обеспечения класса CDC (change data capture);
  • прикладная репликация.

Репликация триггерами


Триггер хранимая процедура, которая исполняется автоматически при каком-либо действии по модификации данных. Триггеру, который вызывается при изменении каждой записи, доступны ключ этой записи, а также старые и новые значения полей. При необходимости триггер может сохранять новые значения строк в специальную таблицу, откуда специальный процесс на стороне реплики будет их вычитывать. Объём кода в триггерах велик, поэтому существуют специальное программное обеспечение, генерирующее такие триггеры, например, Репликация слиянием (merge replication) компонент Microsoft SQL Server или Slony-I отдельный продукт для репликации PostgreSQL.

Сильные стороны репликации триггерами:

  • независимость от версий основной базы и реплики;
  • широкие возможности преобразования данных.

Недостатки:

  • нагрузка на основную базу;
  • большая задержка при репликации.

Использование журналов СУБД


Сами СУБД также могут предоставлять возможности логической репликации. Источником данных, как и для физической репликации, являются журналы. К информации о побайтовом изменении добавляется также информация об изменённых полях (supplemental logging в Oracle, wal_level = logical в PostgreSQL), а также значение уникального ключа, даже если он не меняется. В результате объём журналов БД увеличивается по разным оценкам от 10 до 15%.

Возможности репликации зависят от реализации в конкретной СУБД если в Oracle можно построить logical standby, то в PostgreSQL или Microsoft SQL Server встроенными средствами платформы можно развернуть сложную систему взаимных подписок и публикаций. Кроме того, СУБД предоставляет встроенные средства мониторинга и управления репликацией.

К недостаткам данного подхода можно отнести увеличение объёма журналов и возможное увеличение трафика между узлами.

Использование CDC


Существует целый класс программного обеспечения, предназначенного для организации логической репликации. Это ПО называется CDC, change data capture. Вот список наиболее известных платформ этого класса:

  • Oracle GoldenGate (компания GoldenGate приобретена в 2009 году);
  • IBM InfoSphere Data Replication (ранее InfoSphere CDC; ещё ранее DataMirror Transformation Server, компания DataMirror приобретена в 2007 году);
  • VisionSolutions DoubleTake/MIMIX (ранее Vision Replicate1);
  • Qlik Data Integration Platform (ранее Attunity);
  • Informatica PowerExchange CDC;
  • Debezium;
  • StreamSets Data Collector...

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

Сильные стороны:

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

Недостатков не так много:

  • увеличение объёма журналов, как при логической репликации средствами СУБД;
  • новое ПО сложное в настройке и/или с дорогими лицензиями.

Именно CDC-платформы традиционно используются для обновления корпоративных хранилищ данных в режиме, близком к реальному времени.

Прикладная репликация


Наконец, ещё один способ репликации формирование векторов изменений непосредственно на стороне клиента. Клиент должен формировать детерминированные запросы, затрагивающие единственную запись. Добиться этого можно, используя специальную библиотеку работы с базой данных, например, Borland Database Engine (BDE) или Hibernate ORM.



Когда приложение завершает транзакцию, подключаемый модуль Hibernate ORM записывает вектор изменений в очередь и выполняет транзакцию в базе данных. Специальный процесс-репликатор вычитывает векторы из очереди и выполняет транзакции в базе-реплике.
Этот механизм хорош для обновления отчётных систем. Может он использоваться и для обеспечения отказоустойчивости, но в этом случае в приложении должен быть реализован контроль состояния репликации.

Традиционно сильные и слабые стороны данного подхода:

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

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


Так что же лучше?


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

Блочная репликация СХД Блочная репликация агентом Физическая репликация Логическая репликация СУБД Репликация триггерами CDC Прикладная репликация
Воспроизведение источника Побайтно Побайтно Побайтно Логически Логически Логически Логически
Выборочная репликация На уровне томов На уровне томов На уровне файлов На уровне таблиц и строк На уровне таблиц и строк На уровне таблиц и строк На уровне таблиц и строк
Объём трафика X X X/7..X/5 X/7..X/5 X/10 X/10 X/10
Скорость переключения 5 мин часы 5 мин часы 1..10 мин 1..10 мин 1..2 мин 1..2 мин 1..2 мин
Гарантия переключения + + +++ +
Доступность реплики RO R/W R/W R/W R/W
Топология репликации точка-точка точка-точка
broadcast
точка-точка
broadcast
каскад
точка-точка
broadcast
каскад
встречная*
p2p*
точка-точка
broadcast
каскад
встречная*
p2p*
слияние
точка-точка
broadcast
каскад
встречная*
p2p*
слияние
точка-точка
broadcast
каскад
встречная*
p2p*
слияние
Нагрузка на источник
Простота настройки + + + + + + + + + +
Стоимость дополнительного ПО
Гетерогенные среды + + + + + + + + + + + + +

  • Блочная репликация имеет смысл, когда других способов репликации нет; для баз данных её лучше не использовать.
  • Физическая репликация хороша, когда требуется обеспечение отказоустойчивости инфраструктуры или перенос части читающих приложений на реплики.
  • Логическая репликация подходит для обеспечения отказоустойчивости только в том случае, если приложение знает об этой репликации и умеет в случае аварии ждать синхронизации реплик.
  • Логическая репликация идеальна для всевозможных отчётных баз.
  • Репликация триггерами имеет смысл в том случае, если база сильно нагружена, а реплицировать нужно крайне ограниченное количество информации.
  • Платформы CDC хороши, если у вас большое количество реплицируемых баз и/или есть необходимость сложных преобразований данных.
  • Разработка прикладной репликации оправдана только в случае разработки собственной платформы или фреймворка.
Подробнее..

Репликация Oracle и UCP Fast Connection Failover

12.09.2020 18:14:51 | Автор: admin

Иногда вконфигурации Java-приложения есть IP-адрес "Primary" сервера базы данных, который может поменяться, например, вследующих случаях:

  • Контролируемая смена ролей баз данных. "Primary" становится "Standby" инаоборот, "Standby" становится "Primary". Такая процедура обычно называется "Switchover".
  • Аварийная смена роли "Standby" на"Primary". Это обычно называется "Failover".

Вобоих случаях приложение должно нетолько "знать" про IP-адрес нового "Primary" сервера, ноиуметь кнему обратиться тогда, когда это нужно. Далее следует краткая инструкция того, как это можно сделать спомощью Oracle Universal Connection Pool (UCP), атакже демонстрация "Switchover".


Для эксперимента будем использовать:

  • MacBook cобъемом RAM 16Гб (для эксперимента нужно более 8Гб)
  • Virtual Box версии 6.1.12
  • 2xвиртуальные машины (далее VM) cCentOS 7Minimal, каждая изкоторых имеет
    • 2x vCPU
    • 2048 Гб RAM (с временным увеличением до 8Гб, по очереди)
    • 40 Гб HDD
    • отключенное аудио, чтобы избежать загрузки CPU 100%
  • Oracle Database 19c


Выполним следующие шаги:

  1. Настройка виртуальных машин
  2. Установка Oracle
  3. Репликация Oracle
  4. Установка и настройка Oracle Grid
  5. Демонстрация "Switchover" на тестовом Java приложении


Настройка виртуальных машин



Создаем виртуальные машины (далее VMs) стипом Linux Red Hat, стартуем. При запуске Virtual Box предлагает выбрать iso, скоторого запуститьVM (вэксперименте используется CentOS-7-x86_64-Minimal-1908.iso). Оставляем все поумолчанию, перезагружаем, обновляем, устанавливаем "Virtual Box Guest Additions", отключаем firewalld, чтобы немешался. "Как очищается политура это всякий знает", поэтому отметим только, что после обновления VMs переключаем ихсетевые интерфейсы садаптера NAT на"виртуальный адаптер хоста" vboxnet0. Этому адаптеру, который можно создать винструментах Virtual Box, вручную задаем адрес 192.168.56.1/24 иотключаем DHCP. Посути, это IP-адрес шлюза поумолчанию для VMs иадрес Java-приложения. Просто для наглядности. Аесли наCentOS все еще нужен интернет, томожно включить NAT наMacOS:

  1. Переключаемся впользователя root спомощью команды sudo su -.
  2. Разрешаем перенаправление трафика спомощью команды sysctl -w net.inet.ip.forwarding=1.
  3. Вфайл /var/root/pfnat.conf добавляем содержательную часть файла /etc/pf.conf, вкоторую наместо строки 3вставляем правило для NAT:
    nat on enX from vboxnet0:network to any -> (enX)

    где enX имя сетевого интерфейса с маршрутом по умолчанию.
  4. Выполняем команду pfctl -f pfnat.conf -e, чтобы обновить правила пакетного фильтра.


Шаги 2-4 можно выполнить в одну команду.
sysctl -w net.inet.ip.forwarding=1 \ && grep -v -E -e '^#.*' -e '^$' /etc/pf.conf | head -n2 > pfnat.conf \ && INET_PORT=$(netstat -nrf inet | grep default | tr -s ' ' | cut -d ' ' -f 4) \ && echo "nat on ${INET_PORT} from vboxnet0:network to any -> (${INET_PORT})" >> pfnat.conf \ && grep -v -E -e '^#.*' -e '^$' /etc/pf.conf | tail -n+3 >> pfnat.conf \ && pfctl -f pfnat.conf -e



В/etc/hosts всех VMs добавляем однообразные записи, чтобы они могли "пинговать" друг друга подоменным именам.

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.56.78 oracle1.localdomain oracle1
192.168.56.79 oracle2.localdomain oracle2


Установка Oracle



Выполняем "Software only" установку наoracle1 иoracle2 спомощью rpm-пакетов, директорию скоторыми можно расшарить сMacOS через Virtual Box (Machine->Settings->Shared Folder).

yum -y localinstall oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm

yum -y localinstall oracle-database-ee-19c-1.0-1.x86_64.rpm


Далее, выполняем создание экземпляра СУБД наVM"oracle1". Для этого под пользователем oralce запускаем соответствующий скрипт.

/etc/init.d/oracledb_ORCLCDB-19c configure


Эта процедура занимает некоторое время. После создания экземпляра на обоих хостах добавляем вфайл /home/oracle/.bash_profile вот эти строчки:

export ORACLE_HOME="/opt/oracle/product/19c/dbhome_1"
export ORACLE_BASE="/opt/oracle"
export ORACLE_SID="ORCLCDB"
export PATH=$PATH:$ORACLE_HOME/bin


Нуинастраиваем ssh для удобства, чтобы можно было сразу подключиться подпользователем oracle. Подключаемся кхосту поssh ипод пользователем oracle подключаемся кБД.

user@macbook:~$ ssh oracle@oracle1
Last login: Wed Aug 12 16:17:05 2020
[oracle@oracle1 ~]$ sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 Production on Wed Aug 12 16:19:44 2020
Version 19.3.0.0.0

Copyright 1982, 2019, Oracle. All rights reserved.

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 Production
Version 19.3.0.0.0

SQL>


Собственно, Oracle. Для эксперимента нам также нужно настроить репликацию.

Репликация Oracle.




Для настройки репликации воспользуемся немного дополненной инструкцией:

  1. ПереводимБД насервере oracle1в "Archive Mode". Для этого вsqlplus выполняем команды:

    SHUTDOWN IMMEDIATE;
    

    STARTUP MOUNT;
    

    ALTER DATABASE ARCHIVELOG;
    

    ALTER DATABASE OPEN;
    
  2. Не выходя из sqlplus, включаем "Force logging" насервере oracle1.

    ALTER DATABASE FORCE LOGGING;
    

    ALTER SYSTEM SWITCH LOGFILE;
    
  3. Создаем "redo log" файлы насервере oracle1.
    ALTER DATABASE      ADD STANDBY LOGFILE      THREAD 1 GROUP 10 ('/opt/oracle/oradata/ORCLCDB/standby_redo01.log')      SIZE 209715200;
    

    ALTER DATABASE      ADD STANDBY LOGFILE      THREAD 1 GROUP 11 ('/opt/oracle/oradata/ORCLCDB/standby_redo02.log')      SIZE 209715200;
    

    ALTER DATABASE      ADD STANDBY LOGFILE      THREAD 1 GROUP 12 ('/opt/oracle/oradata/ORCLCDB/standby_redo03.log')      SIZE 209715200;
    

    ALTER DATABASE      ADD STANDBY LOGFILE      THREAD 1 GROUP 13 ('/opt/oracle/oradata/ORCLCDB/standby_redo04.log')      SIZE 209715200;
    
  4. Включаем "FLASHBACK" на сервере oracle1, без него работать не будет.
    SQL> host
    [oracle@oracle1 ~]$ mkdir /opt/oracle/recovery_area
    [oracle@oracle1 ~]$ exit
    SQL> alter system set db_recovery_file_dest_size=2g scope=both;
    SQL> alter system set db_recovery_file_dest='/opt/oracle/recovery_area' scope=both;
    SQL> ALTER DATABASE FLASHBACK ON;
  5. Включаем нечто автоматическое насервере oracle1.
    SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;
  6. Модифицируем tnsnames.ora и listener.ora на сервере oracle1 и oracle2 до следующих содержаний:
    oracle1, файл $ORACLE_HOME/network/admin/tnsnames.ora
    LISTENER_ORCLCDB =  (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521))ORCLCDB =  (DESCRIPTION =    (ADDRESS_LIST =      (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521))    )    (CONNECT_DATA =      (SID = ORCLCDB)    )  )ORCLCDB_STBY =  (DESCRIPTION =    (ADDRESS_LIST =      (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521))    )    (CONNECT_DATA =      (SID = ORCLCDB)    )  )
    


    oracle1, файл $ORACLE_HOME/network/admin/listener.ora
    LISTENER =  (DESCRIPTION_LIST =    (DESCRIPTION =      (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521))      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))    )  )SID_LIST_LISTENER =  (SID_LIST =    (SID_DESC =      (GLOBAL_DBNAME = ORCLCDB_DGMGRL)      (ORACLE_HOME = /opt/oracle/product/19c/dbhome_1)      (SID_NAME = ORCLCDB)    )  )ADR_BASE_LISTENER = /opt/oracle
    


    oracle2, файл $ORACLE_HOME/network/admin/tnsnames.ora
    LISTENER_ORCLCDB =  (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521))ORCLCDB =  (DESCRIPTION =    (ADDRESS_LIST =      (ADDRESS = (PROTOCOL = TCP)(HOST = oracle1.localdomain)(PORT = 1521))    )    (CONNECT_DATA =      (SID = ORCLCDB)    )  )ORCLCDB_STBY =  (DESCRIPTION =    (ADDRESS_LIST =      (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521))    )    (CONNECT_DATA =      (SID = ORCLCDB)    )  )
    


    oracle2, файл $ORACLE_HOME/network/admin/listener.ora
    LISTENER =  (DESCRIPTION_LIST =    (DESCRIPTION =      (ADDRESS = (PROTOCOL = TCP)(HOST = oracle2.localdomain)(PORT = 1521))      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))    )  )SID_LIST_LISTENER =  (SID_LIST =    (SID_DESC =      (GLOBAL_DBNAME = ORCLCDB_STBY_DGMGRL)      (ORACLE_HOME = /opt/oracle/product/19c/dbhome_1)      (SID_NAME = ORCLCDB)    )  )ADR_BASE_LISTENER = /opt/oracle
    

  7. На сервере oracle1 перезагружаем конфигурацию слушателя listener-а.
    [oracle@oracle1 ~]$ lsnrctl reload

    Было
    [oracle@oracle1 ~]$ lsnrctl status

    LSNRCTL for Linux: Version 19.0.0.0.0 Production on 15-AUG-2020 08:17:24

    Copyright 1991, 2019, Oracle. All rights reserved.

    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle1.localdomain)(PORT=1521)))
    STATUS of the LISTENER
    Alias LISTENER
    Version TNSLSNR for Linux: Version 19.0.0.0.0 Production
    Start Date 15-AUG-2020 08:09:57
    Uptime 0 days 0 hr. 7 min. 26 sec
    Trace Level off
    Security ON: Local OS Authentication
    SNMP OFF
    Listener Parameter File /opt/oracle/product/19c/dbhome_1/network/admin/listener.ora
    Listener Log File /opt/oracle/diag/tnslsnr/oracle1/listener/alert/log.xml
    Listening Endpoints Summary
    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracle1.localdomain)(PORT=1521)))
    (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=oracle1.localdomain)(PORT=5500))(Security=(my_wallet_directory=/opt/oracle/admin/ORCLCDB/xdb_wallet))(Presentation=HTTP)(Session=RAW))
    Services Summary
    Service ORCLCDB has 1 instance(s).
    Instance ORCLCDB, status READY, has 1 handler(s) for this service
    Service ORCLCDBXDB has 1 instance(s).
    Instance ORCLCDB, status READY, has 1 handler(s) for this service
    Service ac8d8d741e3e2a52e0534e38a8c0602d has 1 instance(s).
    Instance ORCLCDB, status READY, has 1 handler(s) for this service
    Service orclpdb1 has 1 instance(s).
    Instance ORCLCDB, status READY, has 1 handler(s) for this service
    The command completed successfully

    Стало (появилась строчка для Data Guard: ORCLCDB_DGMGRL)
    [oracle@oracle1 ~]$ lsnrctl status

    LSNRCTL for Linux: Version 19.0.0.0.0 Production on 15-AUG-2020 08:17:32

    Copyright 1991, 2019, Oracle. All rights reserved.

    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle1.localdomain)(PORT=1521)))
    STATUS of the LISTENER
    Alias LISTENER
    Version TNSLSNR for Linux: Version 19.0.0.0.0 Production
    Start Date 15-AUG-2020 08:09:57
    Uptime 0 days 0 hr. 7 min. 34 sec
    Trace Level off
    Security ON: Local OS Authentication
    SNMP OFF
    Listener Parameter File /opt/oracle/product/19c/dbhome_1/network/admin/listener.ora
    Listener Log File /opt/oracle/diag/tnslsnr/oracle1/listener/alert/log.xml
    Listening Endpoints Summary
    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracle1.localdomain)(PORT=1521)))
    (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=oracle1.localdomain)(PORT=5500))(Security=(my_wallet_directory=/opt/oracle/admin/ORCLCDB/xdb_wallet))(Presentation=HTTP)(Session=RAW))
    Services Summary
    Service ORCLCDB has 1 instance(s).
    Instance ORCLCDB, status READY, has 1 handler(s) for this service
    Service ORCLCDBXDB has 1 instance(s).
    Instance ORCLCDB, status READY, has 1 handler(s) for this service
    Service ORCLCDB_DGMGRL has 1 instance(s).
    Instance ORCLCDB, status UNKNOWN, has 1 handler(s) for this service
    Service ac8d8d741e3e2a52e0534e38a8c0602d has 1 instance(s).
    Instance ORCLCDB, status READY, has 1 handler(s) for this service
    Service orclpdb1 has 1 instance(s).
    Instance ORCLCDB, status READY, has 1 handler(s) for this service
    The command completed successfully
  8. Меняем пароль пользователю SYS на сервере oracle1.
    SQL> alter user sys identified by "pa_SSw0rd";
  9. На сервере oracle2 запускаем listener и создаем реплику.
    [oracle@oracle2 ~]$ lsnrctl start
    [oracle@oracle2 ~]$ orapwd file=$ORACLE_BASE/product/19c/dbhome_1/dbs/orapwORCLCDB entries=10 password=pa_SSw0rd
    [oracle@oracle2 ~]$ echo "*.db_name='ORCLCDB'" > /tmp/initORCLCDB_STBY.ora
    [oracle@oracle2 ~]$ mkdir -p $ORACLE_BASE/oradata/ORCLCDB/pdbseed
    [oracle@oracle2 ~]$ mkdir -p $ORACLE_BASE/oradata/ORCLCDB/ORCLPDB1
    [oracle@oracle2 ~]$ mkdir -p $ORACLE_BASE/admin/ORCLCDB/adump
    [oracle@oracle2 ~]$ mkdir /opt/oracle/recovery_area
    [oracle@oracle2 ~]$ sqlplus / as sysdba
    SQL> STARTUP NOMOUNT PFILE='/tmp/initORCLCDB_STBY.ora'
    [oracle@oracle2 ~]$ rman TARGET sys/pa_SSw0rd@ORCLCDB AUXILIARY sys/pa_SSw0rd@ORCLCDB_STBY
    RMAN> DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE DORECOVER SPFILE SET db_unique_name='ORCLCDB_STBY' COMMENT 'Is standby' NOFILENAMECHECK;
  10. На обоих серверах (oracle1 и oracle2) запускаем Data Guard.
    SQL> ALTER SYSTEM SET dg_broker_start=true;
  11. На сервере oracle1 подключаемся к консоли управления Data Guard и создаем конфигурацию.
    [oracle@oracle1 ~]$ dgmgrl sys/pa_SSw0rd@ORCLCDB
    DGMGRL> CREATE CONFIGURATION my_dg_config AS PRIMARY DATABASE IS ORCLCDB CONNECT IDENTIFIER IS ORCLCDB;
    DGMGRL> ADD DATABASE ORCLCDB_STBY AS CONNECT IDENTIFIER IS ORCLCDB_STBY MAINTAINED AS PHYSICAL;
    DGMGRL> enable configuration;


Итак, врезультате создания реплики ивключения Data Guard мыимеем следующее состояние:

DGMGRL> show configurationConfiguration - my_dg_config  Protection Mode: MaxPerformance  Members:  orclcdb      - Primary database    orclcdb_stby - Physical standby database       Warning: ORA-16854: apply lag could not be determinedFast-Start Failover:  DisabledConfiguration Status:WARNING   (status updated 40 seconds ago)


Это плохое состояние. Давайте подождем немного

DGMGRL> show configurationConfiguration - my_dg_config  Protection Mode: MaxPerformance  Members:  orclcdb      - Primary database    orclcdb_stby - Physical standby database Fast-Start Failover:  DisabledConfiguration Status:SUCCESS   (status updated 55 seconds ago)


Вот теперь состояние хорошее! Правда, реплика весьма пассивна, она непринимает запросы начтение (OPEN MODE: MOUNTED).

SQL> show pdbs    CON_ID CON_NAME  OPEN MODE  RESTRICTED---------- ------------------------------ ---------- ----------  2 PDB$SEED  MOUNTED 3 ORCLPDB1  MOUNTED


Давайте сделаем реплику активной, чтобы она принимала запросы на чтение. Тогда мы, в перспективе, сможем разгрузить сервер с "Primary" базой. Это то, что называется "Active Data Guard", либо active standby. Насервере oracle2 выполняем следующую последовательность команд вsqlplus:
alter database       recover managed standby database cancel;

alter database open;

alter database       recover managed standby database       using current logfile       disconnect from session;

alter pluggable database all open;

Вот теперь можно и почитать с реплики (OPEN MODE: READ ONLY):
SQL> show pdbs;    CON_ID CON_NAME  OPEN MODE  RESTRICTED---------- ------------------------------ ---------- ----------  2 PDB$SEED  READ ONLY  NO 3 ORCLPDB1  READ ONLY  NO

Ивконсоли DataGuard насервере oracle1 все выглядит неплохо:
DGMGRL> show configuration;Configuration - my_dg_config  Protection Mode: MaxPerformance  Members:  orclcdb      - Primary database    orclcdb_stby - Physical standby database Fast-Start Failover:  DisabledConfiguration Status:SUCCESS   (status updated 19 seconds ago)


Несмотря нато, что Data Guard унас теперь Active, кластер все еще вомногом пассивен. Нам инашему восхитительному Java-приложению онпо-прежнему нескажет нислова отом, что Primary теперь неPrimary. Для этого насерверах кластера должна быть запущена еще одна служба, ONS (Oracle Notification Services). Ипохоже, что для запуска этой службы установки Oracle Database недостаточно, нам потребуется установить Oracle Grid.



Установка и настройка Oracle Grid.




Тут все достаточно просто: как и в процессе установки Oracle Database мы просто будем следовать официальной инструкции.

  1. Насервере oracle1 иoracle2 под пользователем root загружаем ираспаковываем архив сOracle Grid, ставим gcc-c++, добавляем пользователя oracle вгруппу asm. Вслучае Virtual Box, как при установке Oracle, просто монтируем распакованную директорию Oracle Grid кобеим виртуальным машинам икопируем.
    mkdir -p /opt/oracle/product/19c/grid \        && cp -r /mnt/oracle_grid_19300/LINUX/* /opt/oracle/product/19c/grid/ \        && chown -R oracle:oinstall /opt/oracle/product/19c/grid
    

    yum install -y gcc-c++
    

    groupadd asm && usermod -aG asm oracle
    

  2. Далее, переключаемся впользователя oracle, выполняем проверку соответствия машины системным требованиям Oracle Grid.
    cd /opt/oracle/product/19c/grid/ && ./runcluvfy.sh stage -pre hacfg
    

    Verifying Physical Memory ...FAILED
    Required physical memory = 8GB
    Verifying Swap Size ...FAILED
    Required = 2.6924GB (2823138.0KB); Found = 2GB (2097148.0KB)]

    Может это ограничение иможно как-то изящно обойти, номыбудем поочередно добавлять оперативной памяти иswap, только чтобы Oracle Grid встал, апотом возвращать прежние значения.
  3. Выключаем сперва oracle2, затем oracle1.
    SQL> shutdown immediate

    # poweroff
  4. Добавляем оперативной памяти oracle1 до8192Мб, включаемVM игенерируем swap под пользователем root.
    dd if=/dev/zero of=/swap_file bs=1G count=7 \            && chmod 600 /swap_file && mkswap /swap_file \            && echo '/swap_file  swap  swap  defaults  0 0' >> /etc/fstab \            && swapoff -a && swapon -a
    
  5. Вновь проверяем соответствие машины системным требованиям, чтобы убедиться, что все хорошо.
    [oracle@oracle1 grid]$ cd /opt/oracle/product/19c/grid/ && ./runcluvfy.sh stage -pre hacfg
    Pre-check for Oracle Restart configuration was successful.

    Отлично! Теперь можно выполнить конфигурацию Oracle Grid.
  6. Под пользователем oracle насервере oracle1в директории /opt/oracle/product/19c/grid/ создаем файл grid_configwizard.rsp.
    cd /opt/oracle/product/19c/grid/ && touch grid_configwizard.rsp
    

    Содержимое файла grid_configwizard.rsp будет весьма лаконично, потому что нас интересует только oracle restart, без всяких там ASM ипрочих восхитительных технологий.
    oracle.install.responseFileVersion=/oracle/install/rspfmt_crsinstall_response_schema_v19.0.0
    INVENTORY_LOCATION=/opt/oracle/oraInventory
    oracle.install.option=CRS_SWONLY
    ORACLE_BASE=/opt/oracle
    oracle.install.asm.OSDBA=oinstall
    oracle.install.asm.OSASM=asm
    oracle.install.asm.SYSASMPassword=oracle
    oracle.install.asm.diskGroup.name=data
    oracle.install.asm.diskGroup.redundancy=NORMAL
    oracle.install.asm.diskGroup.AUSize=4
    oracle.install.asm.diskGroup.disksWithFailureGroupNames=/dev/sdb
  7. Выполняем скрипт понастройке oracle grid вконсольном режиме.
    ./gridSetup.sh -silent \               -responseFile /opt/oracle/product/19c/grid/grid_configwizard.rsp
    
  8. Порезультатам настройки, oracle grid просит выполнить скрипт под пользователем root, что мыиделаем.
    /opt/oracle/product/19c/grid/root.sh
    
  9. Далее, выполняем настройку oracle restart посредством запуска под пользователем root скрипта roothas.sh.
    cd /opt/oracle/product/19c/grid/crs/install/ && ./roothas.sh
    

  10. Переключаемся впользователя oracle ивыполняем скрипт runInstaller.
    cd /opt/oracle/product/19c/grid/oui/bin/ \                            && ./runInstaller -updateNodeList \                                ORACLE_HOME=/opt/oracle/product/19c/grid \                                -defaultHomeName CLUSTER_NODES= CRS=TRUE
    
  11. На машине oracle1 комментируем в /etc/fstab строчку, которая начинается на /swap_file, выключаем машину и возвращаем ей 2048 Мб RAM.
  12. Повторяем все предыдущие шаги раздела "Установка и настройка Oracle Grid" для VM oracle2.
  13. После того, как мыснова выдали виртуальным машинам вменяемое количество оперативной памяти, добавляем нужные сервисы вконфигурацию Oracle Restart. Для этого включаем обе виртуальные машины инасервере oracle1 под пользователем oracle добавляем экземплярБД вконфигурацию Oracle Restart.
    srvctl add database -db ORCLCDB \            -oraclehome /opt/oracle/product/19c/dbhome_1 \            -role PRIMARY
    

    /opt/oracle/product/19c/grid/bin/crsctl modify \            res ora.cssd -attr "AUTO_START=always" -unsupported
    

    /opt/oracle/product/19c/grid/bin/crsctl stop has
    

    /opt/oracle/product/19c/grid/bin/crsctl start has
    
  14. Насервере oracle2 под пользователем oracle добавляем экземплярБД вконфигурацию Oracle Restart.
    /opt/oracle/product/19c/grid/bin/crsctl modify \            res ora.cssd -attr "AUTO_START=always" -unsupported
    

    /opt/oracle/product/19c/grid/bin/crsctl stop has
    

    /opt/oracle/product/19c/grid/bin/crsctl start has
    

    srvctl add database -db ORCLCDB_STBY \           -oraclehome /opt/oracle/product/19c/dbhome_1 \           -role PHYSICAL_STANDBY \           -spfile /opt/oracle/product/19c/dbhome_1/dbs/spfileORCLCDB.ora \           -dbname ORCLCDB -instance ORCLCDB
    
  15. Наобоих серверах, oracle1 иoracle2, под пользователем oracle добавляем listener вконфигурацию Oracle Restart.
    srvctl add listener
    
  16. Насервере oracle1 под пользователем oracle добавляем вконфигурацию изапускаем сервис БД, ORCLCDB.
    srvctl add service -db ORCLCDB -service orclpdb -l PRIMARY -pdb ORCLPDB1
    

    srvctl start service -db ORCLCDB -service orclpdb
    
  17. Насервере oracle2 под пользователем oracle добавляем вконфигурацию сервис БД, ORCLCDB_STBY, истартуем экземплярБД
    srvctl add service -db ORCLCDB_STBY -service orclpdb -l PRIMARY -pdb ORCLPDB1
    

    srvctl start database -db ORCLCDB_STBY
    
  18. Насервере oracle1 иoracle2 запустим службу ons.
    srvctl enable ons
    

    srvctl start ons
    


Демонстрация "Switchover" на тестовом Java приложении




Витоге мыимеем 2сервера oracle срепликацией врежиме active-standby ислужбой ons, вкоторую будут отправляться события опереключениях, иJava-приложение сможет обрабатывать эти события помере ихпоступления.

Создаем тестового пользователя и таблицу в Oracle.
Подключаемся ксерверу oracle1 под пользователем oracle ивsqlplus выполняем команду посозданию пользователя и таблицы
  • sqlplus / as sysdba
    
  • alter session set container=ORCLPDB1;
    
  • CREATE USER testus        IDENTIFIED BY test        DEFAULT TABLESPACE USERS        QUOTA UNLIMITED ON USERS;
    
  • GRANT CONNECT,       CREATE SESSION,       CREATE TABLE       TO testus;
    
  • CREATE TABLE TESTUS.MESSAGES (TIMEDATE TIMESTAMP, MESSAGE VARCHAR2(100));
    



После создания тестового пользователя и таблицы, подключаемся к серверу oracle2 и "открываем" экземпляр на чтение, чтобы убедиться, что репликация работает.
  [oracle@oracle2 ~]$ sqlplus / as sysdba SQL> alter pluggable database all open; SQL> alter session set container=ORCLPDB1; SQL> column table_name format A10; SQL> column owner format A10; SQL> select table_name, owner from dba_tables where owner like '%TEST%';TABLE_NAME OWNER---------- ----------MESSAGES   TESTUS


Тестовое приложение состоит из одного только класса Main, вцикле пытается добавить запись втестовую таблицу, азатем этуже запись прочитать (см. методы "putNewMessage()" и"getLastMessage()"). Еще имеется метод "getConnectionHost()", который изобъекта "connection" спомощью "Reflection API" получает IP-адрес подключения кБД. Как далее видно вконсоли, после "switchover" этот адрес меняется.

Запускаем тестовое приложение ивыполняем вконсоли Data Guard "switchover".

DGMGRL> switchover to orclcdb_stby;


Видим, как влоге приложения меняется IP-адрес подключения, простой составляет 1минуту:

[Wed Aug 26 23:56:55 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:56:55|Ты кто такой?[Wed Aug 26 23:56:56 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:56:56|Ты кто такой?[Wed Aug 26 23:56:57 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:56:57|Ты кто такой?[Wed Aug 26 23:56:58 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:02 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:06 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:10 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:14 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:18 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:23 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:27 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:31 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:35 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:39 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:43 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:47 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:57:51 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:57:52|Ты кто такой?[Wed Aug 26 23:57:53 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:57:53|Ты кто такой?[Wed Aug 26 23:57:54 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:57:54|Ты кто такой?


Переключаем обратно, для верности.

DGMGRL> switchover to orclcdb;


Ситуация симметричная.

[Wed Aug 26 23:58:54 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:58:54|Ты кто такой?[Wed Aug 26 23:58:55 MSK 2020]: Host 192.168.56.79: - 2020-08-26 23:58:55|Ты кто такой?[Wed Aug 26 23:58:56 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:00 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:04 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:08 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:12 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:16 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:20 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:24 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:28 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:32 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:36 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:40 MSK 2020]: SQLException: - Давай досвидания![Wed Aug 26 23:59:44 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:59:45|Ты кто такой?[Wed Aug 26 23:59:46 MSK 2020]: Host 192.168.56.78: - 2020-08-26 23:59:46|Ты кто такой?


Также, обратим внимание наTCP-соединения нахостах oralce1 иoracle2. Data-порт занят подключениями только на primary, ONS-порт занят и на primary, и на replica.

До switchover.
oracle1Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v ":22"ESTAB 0 0 192.168.56.78:1521 192.168.56.1:49819 users:(("oracle_21115_or"...))ESTAB 0 0 192.168.56.78:1521 192.168.56.1:49822 users:(("oracle_21117_or"...))ESTAB 0 0 [::ffff:192.168.56.78]:6200 [::ffff:192.168.56.1]:49820 users:(("ons"...))

oracle2Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v ":22"ESTAB 0 0 [::ffff:192.168.56.79]:6200 [::ffff:192.168.56.1]:49821 users:(("ons"...))

После switchover.
oracle1Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v 22  Wed Aug 26 16:57:57 2020ESTAB 0 0 [::ffff:192.168.56.78]:6200 [::ffff:192.168.56.1]:51457 users:(("ons"...))

oracle2Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v ":22" Wed Aug 26 16:58:35 2020ESTAB 0 0 192.168.56.79:1521 192.168.56.1:52259 users:(("oracle_28212_or"...))ESTAB 0 0 192.168.56.79:1521 192.168.56.1:52257 users:(("oracle_28204_or"...))ESTAB 0 0 [::ffff:192.168.56.79]:6200 [::ffff:192.168.56.1]:51458 users:(("ons"...))

Заключение


Таким образом, мысмоделировали влабораторных условиях кластер Data Guard сминимальным количеством настроек иреализовали отказоустойчивое подключение тестового Java-приложения. Теперь мызнаем что разработчик хочет отDBA, аDBA отразработчика. Осталось еще запустить ипротестировать Fast Start Failover, но,пожалуй, врамках отдельной статьи.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru