[Java, Oracle] Репликация Oracle и UCP Fast Connection Failover
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Иногда в конфигурации 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) c CentOS 7 Minimal, каждая из которых имеет
- 2x vCPU
- 2048 Гб RAM (с временным увеличением до 8Гб, по очереди)
- 40 Гб HDD
- отключенное аудио, чтобы избежать загрузки CPU 100%
- Oracle Database 19c
Выполним следующие шаги:
- Настройка виртуальных машин
- Установка Oracle
- Репликация Oracle
- Установка и настройка Oracle Grid
- Демонстрация "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:
- Переключаемся в пользователя root с помощью команды ’sudo su -′.
- Разрешаем перенаправление трафика с помощью команды ’sysctl -w net.inet.ip.forwarding=1′.
- В файл /var/root/pfnat.conf добавляем содержательную часть файла /etc/pf.conf, в которую на место строки № 3 вставляем правило для NAT:
nat on enX from vboxnet0:network to any -> (enX)
где enX — имя сетевого интерфейса с маршрутом по умолчанию.
- Выполняем команду ’pfctl -f pfnat.conf -e′, чтобы обновить правила пакетного фильтра.
Шаги 2-4 можно выполнить в одну команду.
SPL
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.
Для настройки репликации воспользуемся немного дополненной инструкцией:
- Переводим БД на сервере oracle1 в "Archive Mode". Для этого в sqlplus выполняем команды:
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;
- Не выходя из sqlplus, включаем "Force logging" на сервере oracle1.
ALTER DATABASE FORCE LOGGING;
ALTER SYSTEM SWITCH LOGFILE;
- Создаем "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;
- Включаем "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;
- Включаем нечто автоматическое на сервере oracle1.
SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;
- Модифицируем tnsnames.ora и listener.ora на сервере oracle1 и oracle2 до следующих содержаний:
oracle1, файл $ORACLE_HOME/network/admin/tnsnames.ora
SPL
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
SPL
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
SPL
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
SPL
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
- На сервере oracle1 перезагружаем конфигурацию слушателя listener-а.
[oracle@oracle1 ~]$ lsnrctl reload
Было
SPL
[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)
SPL
[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
- Меняем пароль пользователю SYS на сервере oracle1.
SQL> alter user sys identified by "pa_SSw0rd";
- На сервере 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;
- На обоих серверах (oracle1 и oracle2) запускаем Data Guard.
SQL> ALTER SYSTEM SET dg_broker_start=true;
- На сервере 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 configuration
Configuration - my_dg_config
Protection Mode: MaxPerformance
Members:
orclcdb - Primary database
orclcdb_stby - Physical standby database
Warning: ORA-16854: apply lag could not be determined
Fast-Start Failover: Disabled
Configuration Status:
WARNING (status updated 40 seconds ago)
Это плохое состояние. Давайте подождем немного…
DGMGRL> show configuration
Configuration - my_dg_config
Protection Mode: MaxPerformance
Members:
orclcdb - Primary database
orclcdb_stby - Physical standby database
Fast-Start Failover: Disabled
Configuration 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: Disabled
Configuration 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 мы просто будем следовать официальной инструкции.
- На сервере 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
- Далее, переключаемся в пользователя 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 встал, а потом возвращать прежние значения.
- Выключаем сперва oracle2, затем oracle1.
SQL> shutdown immediate
# poweroff
- Добавляем оперативной памяти 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
- Вновь проверяем соответствие машины системным требованиям, чтобы убедиться, что все хорошо.
[oracle@oracle1 grid]$ cd /opt/oracle/product/19c/grid/ && ./runcluvfy.sh stage -pre hacfg
Pre-check for Oracle Restart configuration was successful.
Отлично! Теперь можно выполнить конфигурацию Oracle Grid.
- Под пользователем 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
- Выполняем скрипт по настройке oracle grid в консольном режиме.
./gridSetup.sh -silent \
-responseFile /opt/oracle/product/19c/grid/grid_configwizard.rsp
- По результатам настройки, oracle grid просит выполнить скрипт под пользователем root, что мы и делаем.
/opt/oracle/product/19c/grid/root.sh
- Далее, выполняем настройку oracle restart посредством запуска под пользователем root скрипта roothas.sh.
cd /opt/oracle/product/19c/grid/crs/install/ && ./roothas.sh
- Переключаемся в пользователя oracle и выполняем скрипт runInstaller.
cd /opt/oracle/product/19c/grid/oui/bin/ \
&& ./runInstaller -updateNodeList \
ORACLE_HOME=/opt/oracle/product/19c/grid \
-defaultHomeName CLUSTER_NODES= CRS=TRUE
- На машине oracle1 комментируем в /etc/fstab строчку, которая начинается на /swap_file, выключаем машину и возвращаем ей 2048 Мб RAM.
- Повторяем все предыдущие шаги раздела "Установка и настройка Oracle Grid" для VM oracle2.
- После того, как мы снова выдали виртуальным машинам вменяемое количество оперативной памяти, добавляем нужные сервисы в конфигурацию 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
- На сервере 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
- На обоих серверах, oracle1 и oracle2, под пользователем oracle добавляем listener в конфигурацию Oracle Restart.
srvctl add listener
- На сервере oracle1 под пользователем oracle добавляем в конфигурацию и запускаем сервис БД, ORCLCDB.
srvctl add service -db ORCLCDB -service orclpdb -l PRIMARY -pdb ORCLPDB1
srvctl start service -db ORCLCDB -service orclpdb
- На сервере oracle2 под пользователем oracle добавляем в конфигурацию сервис БД, ORCLCDB_STBY, и стартуем экземпляр БД
srvctl add service -db ORCLCDB_STBY -service orclpdb -l PRIMARY -pdb ORCLPDB1
srvctl start database -db ORCLCDB_STBY
- На сервере oracle1 и oracle2 запустим службу ons.
srvctl enable ons
srvctl start ons
Демонстрация "Switchover" на тестовом Java приложении
В итоге мы имеем 2 сервера oracle с репликацией в режиме active-standby и службой ons, в которую будут отправляться события о переключениях, и Java-приложение сможет обрабатывать эти события по мере их поступления.
Создаем тестового пользователя и таблицу в Oracle.
SPL
Подключаемся к серверу 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.
SPL
oracle1
Every 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"...))
oracle2
Every 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.
SPL
oracle1
Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v 22 Wed Aug 26 16:57:57 2020
ESTAB 0 0 [::ffff:192.168.56.78]:6200 [::ffff:192.168.56.1]:51457 users:(("ons"...))
oracle2
Every 1.0s: ss -tapn | grep 192.168.56.1 | grep ESTAB | grep -v ":22" Wed Aug 26 16:58:35 2020
ESTAB 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, но, пожалуй, в рамках отдельной статьи.
===========
Источник:
habr.com
===========
Похожие новости:
- [Карьера в IT-индустрии] Как НЕ надо начинать изучать программирование
- [JavaScript, Node.JS, Программирование, Разработка веб-сайтов] Руководство по Express.js. Часть 3 (перевод)
- [Java, Программирование] Что нового в Java 15? (перевод)
- [C#, Java, Ненормальное программирование] How to write Palindrome Polyglot Quines (перевод)
- [Программирование, Управление персоналом] Полюбите программиста
- [JavaScript, ReactJS, Программирование] Почему я разочаровался в хуках (перевод)
- [DevOps, Kubernetes] Как получить доступ к ресурсам Kubernetes Pod (перевод)
- [VueJS, Magento] Введение во Vue Storefront (перевод)
- [Oracle, Администрирование баз данных] Метод научного тыка, или как подобрать конфигурацию субд с помощью бенчмарков и оптимизационного алгоритма
- [JavaScript, Программирование, Браузеры, Стандарты связи] (Почти) бесполезный стриминг вебкамеры из браузера. Часть 2. WebRTC
Теги для поиска: #_java, #_oracle, #_oracle_database_19c, #_data_guard, #_oracle_ucp, #_fast_connection_failover, #_oracle_notification_service, #_ons, #_java, #_oracle
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:21
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Иногда в конфигурации Java-приложения есть IP-адрес "Primary" сервера базы данных, который может поменяться, например, в следующих случаях:
В обоих случаях приложение должно не только "знать" про IP-адрес нового "Primary" сервера, но и уметь к нему обратиться тогда, когда это нужно. Далее следует краткая инструкция того, как это можно сделать с помощью Oracle Universal Connection Pool (UCP), а также демонстрация "Switchover". Для эксперимента будем использовать:
Выполним следующие шаги:
Настройка виртуальных машин Создаем виртуальные машины (далее 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:
Шаги 2-4 можно выполнить в одну команду.SPLsysctl -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. Для настройки репликации воспользуемся немного дополненной инструкцией:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:21
Часовой пояс: UTC + 5