Привет, Хабр!
Каждая компания стремится к тому, чтобы данные были не только доступны в нужный момент, но и надежно защищены (спасибо, КЭП!). Более того, необходимость обеспечения безопасности ЗОКИИ и требований по импортозамещению ставит новые задачи в области интеграции систем и миграции данных. Один из способов разобраться с этими вызовами — репликация данных. Она помогает компаниям справляться с растущими нагрузками, обеспечивает защиту данных и облегчает миграцию между различными платформами. Однако ее успешное внедрение требует тщательной подготовки, внимательного выбора стратегии и регулярного мониторинга. Хватит слов – за дело! В этой статье мы покажем сразу несколько технических решений.

Репликация данных между Oracle и PostgreSQL с помощью Oracle GoldenGate
Начнем с самого актуального на данный момент кейса репликации Oracle -> Postgres.
Сначала готовим сервер-источник (Oracle). Помним, база должна быть в режиме Archive Logging — это позволит нам отслеживать данные.
Подключаемся к Oracle через Sqlplus, поднимаем БД в mount и делаем следующие действия:
— включаем архивацию логов:
SQL> ALTER DATABASE ARCHIVELOG; ALTER DATABASE OPEN;
— принудительно включаем логирование всех изменений:
SQL> ALTER DATABASE FORCE LOGGING;
— включаем дополнительное логирование:
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
— проверяем:
SQL> SELECT log_mode, supplemental_log_data_min, force_logging FROM v$database;
— создаем в БД пользователя для GoldenGate:
SQL> CREATE USER ggadmin IDENTIFIED BY ggpassword DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
— выдаем привилегии для работы с GoldenGate
SQL> GRANT CONNECT, RESOURCE TO ggadmin; GRANT CREATE SESSION TO ggadmin; GRANT SELECT ANY DICTIONARY TO ggadmin; GRANT EXECUTE ON DBMS_LOGMNR TO ggadmin; GRANT EXECUTE ON DBMS_LOGMNR_D TO ggadmin; GRANT EXECUTE ON DBMS_FLASHBACK TO ggadmin; GRANT SELECT ON V_$DATABASE TO ggadmin; GRANT SELECT ON ALL_TABLES TO ggadmin; GRANT SELECT ON DBA_REGISTERED_ARCHIVED_LOG TO ggadmin; GRANT SELECT ON DBA_CAPTURE TO ggadmin; GRANT SELECT ON DBA_APPLY TO ggadmin;
— разрешаем пользователю GGADMIN использовать репликацию GoldenGate:
SQL> EXEC dbms_goldengate_auth.grant_admin_privilege('GGADMIN'); ALTER SYSTEM SET ENABLE_GOLDENGATE_REPLICATION=TRUE SCOPE=BOTH;
— настраиваем логирование на уровне реплицируемой таблицы:
SQL> ALTER TABLE schema_name.table_name ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS.
Теперь переходим к установке и настройке GoldenGate Extract на сервере Oracle.
Для начала скачиваем cам GG. Перемещаем архив на целевой хост с нашей базой-источником и разархивируем его:
bash> mkdir -p /u01/app/ogg mv ~/ggs_*.zip /u01/app/ogg cd /u01/app/ogg unzip ggs_*.zip
Запускаем ggsci:
bash> cd /u01/app/ogg ./ggsci ./ggsci
Создаем каталоги:
GGSCI> CREATE SUBDIRS
Рекомендуем добавить OGG в PATH — так удобнее запускать команды:
bash> echo "export OGG_HOME=/u01/app/ogg" >> ~/.bashrc echo "export PATH=\$OGG_HOME:\$PATH" >> ~/.bashrc source ~/.bashrc
Теперь настраиваем параметры процесс-менеджера. Он нам нужен для управления процессами, которые отслеживают изменения и передают их в Postgres:
GGSCI> EDIT PARAM MGR
Добавляем его:
PORT 7809 DYNAMICPORTLIST 7810-7820 ACCESSRULE, PROG *, IPADDR *, ALLOW
А теперь запускаем:
GGSCI> START MGR
Задаем учетные данные для подключения к БД-источнику:
GGSCI> ADD CREDENTIALSTORE ALTER CREDENTIALSTORE ADD USER ggadmin@ORACLE_TNS_ALIAS ALIAS ggadmin
Настраиваем сам процесс Extract:
GGSCI> DBLOGIN USERIDALIAS ggadmin ADD EXTRACT eORACLE TRANLOG, INTEGRATED TRANLOG, BEGIN NOW ADD EXTTRAIL ./dirdat/lt, EXTRACT eORACLE REGISTER EXTRACT eORACLE DATABASE
Редактируем его параметры:
GGSCI> EDIT PARAM eORACLE
Добавляем процесс экстрактора:
EXTRACT eORACLE USERIDALIAS ggadmin TRANLOGOPTIONS INTEGRATEDPARAMS (DOWNSTREAM_REAL_TIME_MINE Y) EXTTRAIL ./dirdat/lt TABLE schema_name.table_name;
Запускаем его:
GGSCI> START eORACLE
Теперь настраиваем процесс, который передает изменения по сети, — PUMP:
GGSCI> ADD EXTRACT pORACLE EXTTRAILSOURCE ./dirdat/lt ADD RMTTRAIL ./dirdat/rt, EXTRACT pORACLE
Редактируем параметры:
GGSCI> EDIT PARAM pORACLE
Добавляем процесс пампа:
EXTRACT pORACLE USERIDALIAS ggadmin RMTHOST target_host, MGRPORT 7810 RMTTRAIL ./dirdat/rt PASSTHRU TABLE schema_name.table_name;
Запускаем его:
GGSCI> START pORACLE
Теперь переходим к серверу-приемнику — PostgreSQL. Создаем пользователя и выдаем ему права.
Подключаемся к PostgreSQL при помощи команды psql -U postgres и переходим в нужную БД \c dbname
Затем выполняем:
CREATE USER ggadmin WITH LOGIN PASSWORD 'ggpassword'; GRANT CONNECT ON DATABASE target_db TO ggadmin; GRANT USAGE ON SCHEMA target_schema TO ggadmin; GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON ALL TABLES IN SCHEMA target_schema TO ggadmin;
Автоматически выдаем права на будущие таблицы:
ALTER DEFAULT PRIVILEGES IN SCHEMA target_schema GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON TABLES TO ggadmin;
Устанавливаем GoldenGate по аналогии, как делали с сервером ORACLE, и настраиваем ODBC. Редактируем odbc.ini:
[ODBC Data Sources] GG_Postgres=DataDirect 9.6 PostgreSQL Wire Protocol [GG_Postgres] Driver=/ogg/lib/ggpsql25.so Description=PostgreSQL Wire Protocol Database=target_db HostName=localhost PortNumber=5432 LogonID=ggadmin Password=ggpassword
Отлично, подготовка выполнена. Теперь устанавливаем и переходим к настройке Replicat на сервере PostgreSQL.
Первым делом создаем каталоги:
GGSCI> CREATE SUBDIRS
Редактируем параметры менеджера:
GGSCI> EDIT PARAM MGR PORT 7810 DYNAMICPORTLIST 7811-7820 ACCESSRULE, PROG REPLICAT, IPADDR *, ALLOW
Запускаем менеджер:
GGSCI> START MGR
Добавляем процесс Replicat:
GGSCI> DBLOGIN USERID ggadmin PASSWORD ggpassword ADD REPLICAT rPOSTGRES EXTTRAIL ./dirdat/rt, CHECKPOINTTABLE ggadmin.checkpoint
Редактируем параметры:
GGSCI> EDIT PARAM rPOSTGRES REPLICAT rPOSTGRES SETENV (PGCLIENTENCODING = "UTF8") SETENV (ODBCINI="/ogg/odbc.ini") SETENV (NLS_LANG="AMERICAN_AMERICA.AL32UTF8") TARGETDB GG_Postgres, USERID ggadmin, PASSWORD ggpassword MAP schema_name.table_name, TARGET target_schema.table_name;
Запускаем репликат:
GGSCI> START rPOSTGRES
Проверяем состояние:
GGSCI> INFO ALL
Теперь нам нужно убедиться, что все работает. На стороне Oracle вставляем строку в таблицу:
SQL> INSERT INTO schema_name.table_name VALUES (...); COMMIT;
На стороне PostgreSQL проверяем результат:
SELECT * FROM target_schema.table_name;
Если данные появились — репликация работает. Контролировать процесс работы репликатора можно с помощью команды GGSCI> VIEW REPORT rPOSTGRES
Good job!
Репликация данных PostgreSQL→ORACLE с помощью Oracle GoldenGate
Для репликации на первом этапе настраиваем средство — Oracle GoldenGate.
Скачиваем и устанавливаем Oracle GoldenGate на целевой сервер, где будет выполняться репликация.
Распаковываем архив с файлами Oracle GoldenGate в выбранный каталог.
Теперь настраиваем Oracle GoldenGate. Для этого переходим в домашний каталог Oracle GoldenGate, запускаем консоль управления GGSCI (./ggsci) и создаем поддиректории:
GGSCI> create subdirs
В настройках MANAGER прописываем порт, который он будет слушать:
GGSCI> edit param MGR PORT 7800 GGSCI> start MGR
Создаем файл GLOBALS и добавляем схему ggs, где будут храниться технические данные GoldenGate со стороны PostgreSQL. Файл Globals содержит в себе глобальные настройки, которые влияют на работу всей инсталляции:
GGSCI> edit param ./GLOBALS GGSCHEMA ggadmn
Теперь подготавливаем PostgreSQL для настройки репликации OGG. Включаем журналирование WAL в файле конфигурации PostgreSQL postgresql.conf: wal_level = logical.
Примечание автора: Этот параметр устанавливает уровень логирования WAL (Write-Ahead Logging) на «logical», который необходим для логической репликации. Она передает изменения данных через логические слоты. Таким образом, в WAL-файлы начинают попадать дополнительные данные, которые используются процессами репликации.
Теперь включаем параметр max_replication_slots для поддержки репликации: max_replication_slots = 5.
Он определяет максимальное количество слотов репликации, которые PostgreSQL может поддерживать одновременно. Это необходимо для работы GoldenGate, который использует слот для отслеживания изменений. Остальные слоты могут использоваться для физической репликации и бэкапов, поэтому их количество нужно увеличивать.
Перезапускаем PostgreSQL для применения изменений. Сначала входим в PostgreSQL: psql -U postgres. Подключаемся к базе Postgres от его системного пользователя.
Создаем пользователя:
CREATE ROLE ggadmn LOGIN PASSWORD ‘password’; Создаем пользователя ggadmn с паролем.
Назначаем права репликации:
ALTER ROLE ggadmn REPLICATION;
Это нужно для того, чтобы у вас появились права на выполнение операций репликации.
Теперь создаем пользователя для репликации на приемнике (Oracle БД).
Для этого выполняем:
SQL>create user ggadmn identified by ggadmn default tablespace users temporary SQL>tablespace temp; -- Создает пользователя в Oracle с указанным паролем и таблицами по умолчанию.
SQL>grant connect to ggadmn; -- Разрешает пользователю подключаться к базе данных.
SQL>grant resource to ggadmn; -- Предоставляет базовые права для работы с объектами базы данных.
SQL>exec dbms_goldengate_auth.grant_admin_privilege ('ggadmn'); --Назначает административные привилегии для GoldenGate.
SQL>alter system set enable_goldengate_replication=TRUE scope=both; --включает поддержку репликации GoldenGate.
Переходим к настройке GoldenGate со стороны источника (PostgreSQL). Создаем файл параметров для источника (PostgreSQL). Для этого настраиваем odbc.ini исходя из своих локальных настроек. Затем создаем файл параметров для PostgreSQL:
bash> vi dirprm/extname.prm
Добавляем в него следующие строки:
EXTRACT extname --Имя Extract-процесса.
SOURCEDB dsn_name USERIDALIAS alias --Подключение к базе PostgreSQL через DSN и алиас пользователя.
RMTHOST <TARGET_IP_ADDRESS>, MGRPORT 7809 --казывает IP-адрес и порт менеджера GoldenGate на стороне Oracle.
RMTTRAIL /u01/app/oracle/product/gg/dirdat/pg --указывает путь для временных файлов данных (trail-файлы).
GETTRUNCATES --Включает обработку команд TRUNCATE.
TABLE schema.object; --Указывает, какие таблицы должны быть реплицированы.
Теперь нам необходимо подключиться к БД-источнику при помощи утилиты GGSCI:
GGSCI>
DBLOGIN SOURCEDB dsn USERIDALIAS alias --Устанавливает соединение с PostgreSQL для GoldenGate.
Далее регистрируем Extract с помощью команды GGSCI. Она создает слот репликации. Помним, что имя extract не может содержать более восьми буквенно-цифровых символов:
GGSCI>
REGISTER EXTRACT extname --Создает слот репликации для логической репликации PostgreSQL.
Делаем Extract и соответствующий ему trail-файл:
GGSCI>
ADD EXTRACT extname, TRANLOG, BEGIN NOW --Создает Extract-процесс для получения данных из транзакционного лога.
GGSCI>
ADD RMTTRAIL /u01/app/oracle/product/gg/dirdat/pg, extract extname --Указывает, где сохранять trail-файлы.
Включаем расширенное логирование для таблицы-источника:
ADD TRANDATA schema.object --Включает расширенное логирование для указанных таблиц, чтобы отслеживать изменения на уровне строк.
Теперь принимаемся за Golden Gate.
Переключаемся на настройку GoldenGate со стороны источника (Oracle).
Добавляем checkpoint table:
GGSCI>
add checkpointtable ggadmn.repchkpt -- Создает таблицу контрольных точек для синхронизации репликации.
Создаем Replicat:
GGSCI>
add replicat ORAREP, exttrail /u01/app/oracle/product/gg/dirdat/pg --Создает процесс Replicat, который считывает trail-файлы и применяет изменения в Oracle.
GGSCI>
edit param ORAREP
REPLICAT ORAREP --Имя процесса Replicat.
USERID ggadmn, PASSWORD ggadmn --Данные для подключения к Oracle.
MAP schema.object, TARGET schema.object;-- Указывает сопоставление схем и таблиц между источником и приемником.
Запускаем Extract и Replicat:
GGSCI>
start extract extname
start replicat ORAREP
Важно: типы полей в Оracle и PostgreSQL должны совпадать и поддерживаться GoldenGate. Подробнее можно прочитать здесь.
Репликация данных Oracle→CockroachDB
Начинаем с переноса структуры таблиц в CockroachDB. На ноде CockroachDB (sourceDB) в БД создаем пользователя ggadmin (нужен для репликата) и выдаем грант admin.
Выпускаем клиентский сертификат для ggadmin:
cockroach cert create-client ggadmin --certs-dir=/cockroach/cert/ --ca-key=/cockroach/cert/ca.key
Проверяем подключение к БД под УЗ ggadmin при помощи команды:
cockroach sql --certs-dir=/var/lib/cockroach/certs --user=ogg
Теперь создаем пользователя oracle и назначаем группу cockroach. Устанавливаем GoldenGate for PostgreSQL и создаем структуру каталогов для GG командой create subdirs. Настраиваем и запускаем менеджера GG:
PORT 7800 DYNAMICPORTLIST 7800-7810 ACCESSRULE, PROG REPLICAT, IPADDR *, ALLOW
Настраиваем odbc.ini в $GG_HOME:
[ODBC Data Sources] PostgreSQL on pgsql [ODBC] IANAAppCodePage=4 InstallDir=/cockroach/ogg [cockdb] Driver=/cockroach/ogg/lib/GGpsql25.so Description=DataDirect 7.1 PostgreSQL Wire Protocol Database={dbname} HostName=localhost PortNumber=26257 LogonID=ggadmin Password={password} EncryptionMethod=1 ValidateServerCertificate=1 TrustStore=/cockroach/cert/ca.crtДелаем репликат для таблицы TABLE_NAME, но не запускаем (сделаем позже):
Делаем репликат для таблицы TABLE_NAME, но не запускаем (сделаем позже):
GGSCI> edit param REP1 REPLICAT REP1 SETENV ( PGCLIENTENCODING = "UTF8" ) SETENV (ODBCINI="/cockroach/ogg/odbc.ini" ) SETENV (NLS_LANG="AMERICAN_AMERICA.AL32UTF8") TARGETDB {dbname} DISCARDFILE ./dirrpt/rep1.dsc, purge, MEGABYTES 1024 MAP owner.table, TARGET public.table;
Добавляем репликат:
GGSCI> add replicat REP1, NODBCHECKPOINT, exttrail ./dirdat/ee
На даунстриме сервера downstream_hostname настраиваем памп для трейл-файлов экстракта:
GGSCI> edit param ENAME EXTRACT ENAME USERIDALIAS ggadmin RMTHOST REMOTE_HOST, MGRPORT 7800 TCPBUFSIZE 200000000, TCPFLUSHBYTES 200000000 RMTTRAIL ./dirdat/ee PASSTHRU TABLE TABLE_NAME;
Добавляем памп:
GGSCI> Add extract PNAME, EXTTRAILSOURCE ./dirdat/ee Add rmttrail /cockroach/ogg/dirdat/ee, extract PNAME
Запускаем процесс пампа и проверяем, что он запустился и начал отправлять файлы на ноду CockroachDB:
GGSCI> start PNAME
Конфигурируем экстракты для Initial load. Для таблицы TABLE_NAME:
GGSCI> edit param INAME EXTRACT INAME SOURCEDB SOURCEDBNAME USERIDALIAS ggadmin RMTHOST rmthost, mgrport 7800 RMTTASK REPLICAT, GROUP INITLR TABLE TABLE_NAME;
Добавляем экстракт:
GGSCI> ADD EXTRACT INAME, SOURCEISTABLE
На sourceDB останавливаем накат логов. Снимаем и запоминаем/записываем SCN. Мы же не хотим получить неконсистентные данные. Поэтому требование обязательное.
На даунстриме запускаем процессы Initial load:
GGSCI> start INAME
И наблюдаем за нагрузкой на CockroachDB.
После завершения первоначальной заливки, если требуется, создаем индексы, Primary Key (очень желательно, потому что его отсутствие негативно влияет на производительность)
и проверяем статистику по таблицам. Если нужно, пересобираем ее.
На ноде с DESTDB запускаем репликаты с запомненного SCN:
GGSCI> start replicat RNAME, aftercsn <scn_number>
Репликация данных MSSQL→ORACLE с помощью Oracle GoldenGate CDC
Загружаем необходимый дистрибутив GoldenGate for SQL Server, распаковываем его на диск и инсталлируем. Подробную инструкцию по инсталляции читаем на сайте вендора. Для подключения Oracle GoldenGate к SQL Server необходим DSN. Для этого настраиваем ODBC Data Sources (64-bit).

Нажимаем на Add и выбираем ODBC Driver for SQL Server для вашей версии:

Вводим имя, которое потом будет прописываться для подключения в настройках. Указываем Server:

Далее необходимо настроить параметры подключения:

В следующем окне выбираем БД, к которой будут подключаться:

Далее завершаем настройку. По итогу мастер настройки покажет окно с результатом, там же можно протестировать подключение по DSN:

Теперь переходим к настройке Oracle GoldenGate. Открываем директорию с распакованным дистрибутивом GoldenGate, запускаем консоль управления GGSCI и создаем поддиректории:
GGSCI> Create subdirs
В настройках MANAGER прописываем порт, который он будет слушать:
GGSCI> edit param MGR PORT 7800 GGSCI> start MGR
Создаем файл GLOBALS и добавляем схему ggs, в которой будут храниться технические данные GoldenGate со стороны SQL Server:
GGSCI> edit param ./GLOBALS GGSCHEMA ggs
Включаем расширенное логирование для таблицы со стороны MS SQL, участвующей в репликации:
GGSCI> dblogin sourcedb GG add trandata hr.source_table
Теперь начинаем первоначальную загрузку данных таблицы из SQL Server в Oracle (первичная инициализация). Если в таблице источника есть данные и необходимость перенести эти данные на приемник. Копируем их в целевую базу данных с помощью штатного инструмента. В GoldenGate можно использовать функцию Initial Load для предварительной загрузки данных.
Перед проведением работ в файл параметров mgr добавляем строку:
ACCESSRULE, PROG *, IPADDR *, ALLOW
На источнике SQL Server:
GGSCI> ADD EXTRACT INITEX, SOURCEISTABLE EDIT PARAMS INITEX EXTRACT INITEX SOURCEDB GG RMTHOST <TARGET_IP_ADDRESS>, MGRPORT 7809 RMTTASK REPLICAT, GROUP INITRE TABLE hr.source_table;
На приемнике:
GGSCI> ADD REPLICAT INITRE, SPECIALRUN EDIT PARAMS INITRE REPLICAT INITRE USERID ogg, PASSWORD ogg MAP hr.source_table, TARGET hr.target_table;
После запускаем INITEX. На приемнике INITRE это происходит автоматически:
GGSCI> START INITEX
Теперь настраиваем Extract и Replicat.
На источнике SQL Server:
GGSCI> ADD EXTRACT EXTSQL, TRANLOG, BEGIN NOW add exttrail E:\gg\dirdat\ms, extract EXTSQL edit param EXTSQL EXTRACT EXTSQL SOURCEDB GG EXTTRAIL E:\gg\dirdat\ms TABLE hr.source_table;
Добавляем процесс PUMP:
GGSCI> Add extract DPSQL, EXTTRAILSOURCE E:\gg\dirdat\ms Add rmttrail /u01/app/oracle/product/gg/dirdat/ms, extract DPSQL edit param DPSQL EXTRACT DPSQL SOURCEDB GG RMTHOST <TARGET_IP_ADDRESS>, MGRPORT 7809 RMTTRAIL /u01/app/oracle/product/gg/dirdat/ms TABLE hr.source_table;
Запускаем Extract:
GGSCI> start EXTSQL
На приемнике Oracle добавляем checkpoint table:
GGSCI> add checkpointtable ogg.repchkpt
Создаем Replicat:
GGSCI> add replicat ORAREP, exttrail /u01/app/oracle/gg/dirdat/ms edit param ORAREP REPLICAT ORAREP USERID ogg, PASSWORD ogg MAP hr.source_table, TARGET hr.target_table;
Запускаем Replicat:
GGSCI> start ORAREP
Теперь создаем задания по очистке данных. Со стороны SQL Server для расширенного логирования данных в таблице используется функция Change Data Capture (CDC). При его включении GoldenGate сам включает CDC и создает задания по захвату и очистке данных. Но стандартное задание по очистке не подходит для работы GoldenGate, поэтому в дистрибутиве есть штатный скрипт по созданию задания, учитывающий функционал GoldenGate.
Именно поэтому для начала необходимо удалить стандартное задание из CDC.
Подключаемся к SQL Server c административными правами и выполняем команду в БД, в которой находятся таблицы источника:
EXEC sys.sp_cdc_drop_job 'cleanup'
Запускаем CMD от имени администратора, переходим в директорию с GoldenGate и выполняем:
ogg_cdc_cleanup_setup.bat createJob user1 pword1 dbname1 HOSTNAME\INSTANCE oggschema
Репликацируем в SQL Server. Для этого из других источников в SQL Server концептуально процесс остается аналогичным.
Настраиваем Replicat:
GGSCI> EDIT PARAMS cdcrep REPLICAT cdcrep TARGETDB targetdsn USERID username PASSWORD password MAP dbo.*, TARGET dbo.*
Создаем схему для объектов GoldenGate:
CREATE SCHEMA [ogg];
А затем создаем таблицу чекпоинта и добавляем Replicat:
GGSCI> DBLOGIN SOURCEDB targetdsn USERID username PASSWORD password ADD CHECKPOINTTABLE ogg.ggcheck ADD REPLICAT cdcrep, EXTTRAIL ./dirdat/ce, CHECKPOINTTABLE ogg.ggcheck
Запускаем Replicat:
GGSCI> START REPLICAT cdcrep INFO ALL
Репликация данных Oracle→Kafka
В этом разделе мы не будем описывать настройку источника, так как мы описали этот процесс выше.
Устанавливаем GoldenGate 19 for BigData. Для работы потребуется Java — устанавливаем командой: [root@server01 ~]# yum install java-1.8.0-openjdk.x86_64
Добавляем переменные окружения:
bash> export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64/jre export PATH=$JAVA_HOME/bin:$PATH export LD_LIBRARY_PATH=$JAVA_HOME/lib/amd64/server:$LD_LIBRARY_PATH
Распаковываем дистрибутив GoldenGate for BigData:
bash> mkdir -p /u01/app/oracle/product/19.1.0/oggbigdata_1 cd /u01/app/oracle/product/19.1.0/oggbigdata_1 cp /u01/V983760-01.zip . unzip V983760-01.zip tar xvf OGG_BigData_Linux_x64_19.1.0.0.1.tar
Для удобства быстрого доступа прописываем Alias:
bash> alias gg='cd /u01/app/oracle/product/19.1.0/oggbigdata_1; ./ggsci'
Подключаемся и создаем поддиректории:
bash> gg GGSCI> create subdirs
Добавляем порт в файл параметра менеджера:
GGSCI> edit params mgr port 7801 GGSCI> start mgr
Настраиваем Kafka. У нас уже установлена и настроена Kafka, но если у вас нет, ниже описываем простой способ развертывания и запуска Kafka:
bash> tar -xzf /tmp/kafka_2.13-2.7.0.tgz cd kafka_2.13-2.7.0/ nohup /home/kafka/kafka_2.13-2.7.0/bin/zookeeper-server-start.sh config/zookeeper.properties > zookeeper.log nohup /home/kafka/kafka_2.13-2.7.0/bin/kafka-server-start.sh config/server.properties > broker_service.log &
Обычно Kafka располагается на отдельном сервере. В данном случае для работы GoldenGate потребуются библиотеки из Kafka. Ищем с помощью <kafka_install_dir>/libs/*. Эту директорию со всеми файлами копируем на сервере, где будет располагаться GoldenGate. В дальнейшем она понадобится для настроек.
Теперь настраиваем Handler. Первым делом смотрим в директорию AdapterExamples. Она расположена внутри дистрибутива GoldenGate for BigData. В данном случае нас интересует подпапка AdapterExamples/big-data/kafka:
Содержимое папки необходимо перенести в директорию dirprm для дальнейшей настройки Replicat.
Из скопированных файлов открываем custom_kafka_producer.properties, здесь нужно указать адрес сервера Kafka:
bootstrap.servers=kafka:9092 acks=1 reconnect.backoff.ms=1000 value.serializer=org.apache.kafka.common.serialization.ByteArraySerializer key.serializer=org.apache.kafka.common.serialization.ByteArraySerializer # 100KB per partition batch.size=16384 linger.ms=0
Следующим шагом открываем файл kafka.props и в параметре gg.classpath прописываем путь до библиотек Kafka. Также здесь можно указать формат выгружаемых данных: xml, delimitedtext, json, json_row, avro_row, avro_op. Формат данных определяется разработчиками или техзаданием.
gg.handlerlist = kafkahandler gg.handler.kafkahandler.type=kafka gg.handler.kafkahandler.KafkaProducerConfigFile=custom_kafka_producer.properties #The following resolves the topic name using the short table name gg.handler.kafkahandler.topicMappingTemplate=${tableName} #The following selects the message key using the concatenated primary keys gg.handler.kafkahandler.keyMappingTemplate=${primaryKeys} gg.handler.kafkahandler.format=avro_op gg.handler.kafkahandler.SchemaTopicName=mySchemaTopic gg.handler.kafkahandler.BlockingSend =false gg.handler.kafkahandler.includeTokens=false gg.handler.kafkahandler.mode=op gg.handler.kafkahandler.MetaHeaderTemplate=${alltokens} goldengate.userexit.writers=javawriter javawriter.stats.display=TRUE javawriter.stats.full=TRUE gg.log=log4j gg.log.level=INFO gg.report.time=30sec #Sample gg.classpath for Apache Kafka gg.classpath=dirprm/:/u01/kafka_2.13-2.7.0/libs/* #Sample gg.classpath for HDP #gg.classpath=/etc/kafka/conf:/usr/hdp/current/kafka-broker/libs/*
В файле rkafka.prm указываем нужные таблицы для репликации:
REPLICAT rkafka -- Trail file for this example is located in "AdapterExamples/trail" directory -- Command to add REPLICAT -- add replicat rkafka, exttrail AdapterExamples/trail/tr TARGETDB LIBFILE libggjava.so SET property=dirprm/kafka.props REPORTCOUNT EVERY 1 MINUTES, RATE GROUPTRANSOPS 10000 MAP appuser.test01, TARGET appuser.test01;
После настроек остается только добавить Replicat привычным способом:
GGSCI> add replicat rkafka, exttrail /u01/app/oracle/product/19.1.0/oggcore_1/dirdat/ex start rkafka
После включения данные начнут передаваться — это можно увидеть со стороны Kafka:
bash> bin/kafka-topics.sh --list --bootstrap-server kafka:2181 TEST01 __consumer_offsets mySchemaTopic quickstart-events bash> bin/kafka-console-consumer.sh --topic TEST01 --from-beginning --bootstrap-server kafka:9092 APPUSER.TEST01I42021-01-22 11:32:20.00000042021-01-22T15:20:51.081000(00000000000000001729ID$@Ten APPUSER.TEST01I42021-01-22 15:24:55.00000042021-01-22T15:25:00.665000(00000000000000001872ID$@One
Репликация данных Oracle→Oracle с помощью Oracle GoldenGate
Примечание автора: нам важно сконфигурировать репликацию как downstream, то есть как вынесенную систему, для отслеживания изменений. Делается это в первую очередь для увеличения отказоустойчивости системы и снижения нагрузки на сервер источника. Обязательное требование при этом — одинаковая архитектура серверов. То есть невозможно будет настроить прием логов на downstream mining БД, которая расположена на Solaris Sparc64, при том что БД-источник на Linux x86-64. Если планируется использовать REAL_TIME_CAPTURE (репликация в реальном времени), то на Mining БД нужно создать standby-redo-логи такого же размера, как и на БД-источнике. Число логов на один больше, чем на источнике.
Включаем режим archivelog, forcelogging, supplemental_logging на БД-источнике:
SQL ALTER DATABASE ARCHIVELOG; ALTER DATABASE FORCE LOGGING; ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
К сведению инженера: для включения этого режима лучше перезагрузить БД и не выполнять на бою. Включение может привести к деградации производительности вплоть до остановки работы СУБД. Активация режима FORCE LOGGING принудительно логирует все изменения, даже те, которые выполнялись с опцией NOLOGGING. Режим Supplemental Log data добавляет метаданные в вектора изменений, которые позволяют работать режиму CDC. Включение этих режимов может привести к увеличению генерируемых изменений БД — генерации архивных логов. По нашему опыту, рост составляет 15–25%.
Проверяем:
SQL> SELECT log_mode, supplemental_log_data_min, force_logging FROM v$database;
Создаем пользователя для репликации на источнике и downstream БД:
SQL> create user ggadmшn identified by ggadmin default tablespace users temporary tablespace temp;exec dbms_goldengate_auth.grant_admin_privilege (' ggadmшn'); alter system set enable_goldengate_replication=TRUE scope=both;
Добавляем db_unique_name downstream БД в log_archive_config на источнике:
SQL> ALTER SYSTEM SET LOG_ARCHIVE_CONFIG='DG_CONFIG=([SOURCEDB], [MININGDB])' scope=both;
Копируем файл паролей с источника на Mining DB. Здесь добавляем LAD для хранения архивных логов источника и собственных архивных логов:
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=[archive_log_location] VALID_FOR=(ONLINE_LOGFILE,PRIMARY_ROLE)' scope=both; ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='LOCATION=[archive_log_location]/REMOTE VALID_FOR=(STANDBY_LOGFILE,PRIMARY_ROLE)' scope=both; ALTER SYSTEM SET LOG_ARCHIVE_DEST_state_2=enable scope=both;
На источнике и Mining DB добавляем TNS записи БД. Проверяем, что сетевой доступ открыт и удается подключиться с каждого сервера с БД на каждый.
Добавляем новый LAD для downstream БД:
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=[MININGDB_SERVICE] ASYNC NOREGISTER VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=[MININGDB]' scope=both; ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=enable scope=both;
Проверяем, что нет ошибок передачи логов:
select destination,status,error from v$archive_dest_status where rownum < 3;
Устанавливаем Oracle GoldenGate нужной версии на сервер с Mining DB и выполняем первоначальную настройку. Добавляем credential для подключения к источнику:
GGSCI> Create subdirs – создаем необходимую структуру директорий edit param MGR – правим параметры менеджера PORT 7800 GGSCI> start MGR – запускаем менеджер create wallet – создаем валлет, где будут хранится параметры аутентификации пользователей Created wallet at location 'dirwlt'. Opened wallet at location 'dirwlt'.GGSCI> add credentialstore Credential store created in ./dircrd/. GGSCI> alter credentialstore add user ggadmin@[sourcedb_tns] alias ggadmin_[sourcedb] Password: *********** Credential store in ./dircrd/ altered. GGSCI> alter credentialstore add user ggadmin@[mining_tns] alias ggadmin_[miningdb] Password: *********** Credential store in ./dircrd/ altered. GGSCI> dblogin useridalias ggadmin_[sourcedb] – пробуем залогинится в БД источник Successfully logged into database.
На БД-источнике включаем режим расширенного логирования для таблиц, которые будем реплицировать:
SQL> alter table [OWNER].[TABLE_NAME] add supplemental log data (all) columns;
Данная команда требует эксклюзивной блокировки на время выполнения. Рекомендуем выполнять в период наименьшей нагрузки.
Настраиваем процессы Extract и PUMP для получения и передачи изменений:
GGSCI> dblogin useridalias ggadmin_[sourcedb] Successfully logged into database. GGSCI> miningdblogin useridalias ggadmin_[miningdb] Successfully logged into mining database. GGSCI> add extract eSOURCEDB integrated tranlog begin now – добавляем процесс экстракт (процесс, собирающий изменения) EXTRACT added. GGSCI> add exttrail ./dirdat/SOURCEDB/lt extract eSOURCEDB – добавляем файловый путь, куда будут складываться изменения, добытые нашим экстрактом EXTTRAIL added. GGSCI> add extract pSOURCEDB exttrailsource ./dirdat/SOURCEDB/lt – создаем необязательный процесс PUMP, который будет передавать добытые изменения на другой сервер. EXTRACT added. GGSCI> add rmttrail ./dirdat/SOURCEDB/rt extract pSOURCEDB RMTTRAIL added. GGSCI> register extract eSOURCEDB database Extract ESOURCEDB successfully registered with database at SCN 261106958. GGSCI> add replicat rSOURCEDB integrated exttrail ./dirdat/SOURCEDB/rt REPLICAT (Integrated) added. GGSCI> edit param eSOURCEDB EXTRACT eSOURCEDB useridalias ggadmin_[sourcedb] TRANLOGOPTIONS MININGUSERALIAS ggadmin_[miningdb] TRANLOGOPTIONS INTEGRATEDPARAMS (downstream_real_time_mine Y) EXTTRAIL ./dirdat/SOURCEDB/lt TABLE [OWNER].[TABLE_NAME]; GGSCI> edit param pSOURCEDB EXTRACT pSOURCEDB useridalias ggadmin_[sourcedb] RMTHOST host02, MGRPORT 7800 RMTTRAIL ./dirdat/SOURCEDB/rt PASSTHRU TABLE *.*;
Запускаем процесс Extract и PUMP:
GGSCI> start eSOURCEDB start pSOURCEDB
Перейдем к приемнику.
На БД-приемнике устанавливаем и конфигурируем Oracle GoldenGate и создаем процесс репликата:
GGSCI> edit param rSOURCEDB REPLICAT rSOURCEDB ASSUMETARGETDEFS USERIDALIAS oggsuser_PRODDB MAP [OWNER].[TABLE_NAME, TARGET [TARGET_OWNER].[TARGET_TABLE_NAME], FILTER (@getenv ('TRANSACTION' , 'CSN') > SCN_консистентности)
Выполняем первичную инициализацию реплицируемой таблицы.
Для уверенности, что все изменения будут перенесены при первичной инициализации, мы временно блокируем таблицу, получаем SCN, когда точно никакие процессы не меняют данные (т.н. SCN-консистентности). С него потом запускаем репликацию.
Получаем SCN-консистентности для таблицы на источнике:
SQL> SET SERVEROUTPUT ON; declare v_tab_name varchar2(32000); v_scn number; v_ku$status ku$_status1020; begin execute immediate 'alter session set ddl_lock_timeout=20'; for i in (select * from dba_tables dt where dt.owner = '[OWNER]' and dt.table_name in ('[TABLE_NAME]'} loop execute immediate 'lock table '||i.owner||'.'||i.table_name||' in share mode'; v_tab_name := v_tab_name || ','''||i.table_name||''''; end loop; v_tab_name := ltrim(v_tab_name,','); select current_scn into v_scn from v$database; dbms_lock.sleep(3); commit; dbms_output.put_line('SCN: '||to_char(v_scn)); dbms_output.put_line('FILTER (@getenv (''TRANSACTION'' , ''CSN'') > '||to_char(v_scn)||')'); end;
Выгружаем таблицу с источника при помощи datapump. Примерный файл параметров ниже:
USERID="/ as sysdba" DIRECTORY=EXPGG LOGFILE=ibs_zrecords.log DUMPFILE=ibs_zrecords%U.dmp TABLES=IBS.Z\#RECORDS exclude=RLS_POLICY,CONSTRAINT,GRANT,REF_CONSTRAINT,STATISTICS,TRIGGER,INDEX FLASHBACK_SCN={SCN} STATUS=60 PARALLEL=4
Загружаем дамп с таблицей в приемник. Переименовываем при необходимости, если на источнике и приемнике таблицы назывались по-разному.
Создаем Primary KEY и другие индексы, если нужно.
Заметка авторов на полях: уникальные ключи PK или UK являются необходимыми для работы репликации.
Запускаем репликат на приемнике:
GGSCI> start rSOURCEDB info rSOURCEDB
Контролируем работу процессов и устраняем возникающие ошибки. Готово.
Репликация данных Sybase→Oracle с помощью Sybase RS
Для создания нового коннекта и репликации таблиц из Sybase в Oracle выполняем следующие шаги.
Создаем на стороне Оracle приемную схему:
SQL>
create user USERNAME identified by PASSWORD default tablespace USERS temporary tablespace TEMP quota unlimited on USERS;
Затем заводим в базе Oracle пользователя, под кем реплика будет подключаться к БД:
SQL>
create user USERNAME_RS identified by PASSWORD default tablespace USERS temporary tablespace TEMP quota unlimited on USERS;
Создаем в Oracle в нужной схеме приемные таблицы нужной структуры.
Убеждаемся, что на стороне Оracle в таблицах создан PK или уникальный индекс. Если нет — создаем.
Убеждаемся в наличии сетевого доступа с RS на новый Oracle БД.
Прописываем на RS в файле interfaces новое подключение к приемной базе Оracle с помощью уже настроенного отдельного ECDA сервера.
Пример записи в файле interfaces:
dco_tst_01 query tcp ether server-name 9035
Данная запись означает, что на ECDA сервере server-name, на порту 9035, настроено подключение к нужной приемной базе, и данное подключение называется dco_tst_01
ECDA (Enterprise Connect Data Access) — это гетерогенный шлюз (gateway), который является отдельно приобретаемым и отдельно лицензируемым продуктом для репликации Sybase баз данных в Non-ASE базы данных. ECDA позволяет установить драйвера для подключения к различным СУБД, таким как Oracle, MSSQL, PostgreSQL и др., и реплицировать в другие СУБД данные из Sybase ASE. Драйверы для каждой новой СУБД приобретаются отдельно. Инсталляция и настройка ECDA — отдельная тема и в данной статье рассматриваться не будет.
В Sybase RS 15.5 и позже появилась возможность напрямую подключаться через ECO (ExpressConnect for Oracle) в Oracle БД без разворачивания ECDA. Для этого необходимо прописать локально на RS параметры подключения к Oracle в файле:
$RS_HOME/REP-16_0/connector/oraoci/network/admin/tnsnames.ora SOURCEDB= (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = hostname)(PORT = 1521)) ) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = SOURCEDB) ) )
Настраиваем репликации. Создаем новый connection в RS для указания приемника репликационных данных (сервер и база).
-- Create Database Connection eco.dwh create connection to "eco"."dwh" set error class to "err_class_IgnorDubli" set function string class to "rs_oracle_function_class" set username "USERNAME_RS" set password "PASSWORD_USERNAME_RS" go -- Set connection configuration parameters for eco.dwh alter connection to eco.dwh set cmd_direct_replicate to 'off' alter connection to eco.dwh set exec_sqm_write_request_limit to '4194304'
Создаем replication definition в RS. Немного о терминах: replication definition — это специальный объект на RS-сервере, который описывает, из какой схемы, какая таблица –> в какую приемную схему и таблицу будет реплицироваться. Описываются, какие поля в таблице, типы данных и размерность подлежат реплицированию. Также в replication definition указан PK, который будет использоваться системой репликации для идентификации строк. Одним словом, это «правила» для репликационного сервера, какие таблицы опубликованы для репликации и как будут передаваться данные.
Первой создаем KEY repdef:
create replication definition RDNAME dFRONT_KEY_f_oper_card with primary at SOURCE with primary table named TABLE_NAME with replicate table named TARGET_TABLE_NAME ("f_oper" int) primary key("f_oper") replicate minimal columns go
Затем — основной repdef новой таблицы:
create replication definition RDNAME with primary at SOURCEDB with primary table named TABLE_NAME with replicate table named TARGET_TABLE_NAME( "f_oper" int, "f_req" int, "f_cardhandreason" smallint, "type_return" tinyint, "inn" varchar(12), "acc_num" varchar(20), "bik" varchar(10), "service_name" varchar(100), "service_adress" varchar(100), "date_decision" date, "way_decision" varchar(255), "contact_decision" varchar(255), "result_decision" varchar(255), "comment_reason" varchar(255), "descr" varchar(100) ) primary key("f_oper") replicate minimal columns go
Важно. Если в таблице ключевое поле IDENTITY, создаем KEY repdef только для одного поля с типом IDENTITY.
create replication definition RDNAME with primary at SOURCEDB with primary table named TABLE_NAME with replicate table named TARGET_TABLE_NAME (f_kurs identity) primary key (f_kurs) replicate minimal columns with dynamic sql
Основной repdef должен быть «identity map to rs_oracle_float» (или «ident_id identity map to numeric») — в Oracle нет типа IDENTITY. Здесь это поле должно быть типом NUMBER(10):
create replication definition RDNAME with primary at SOURCEDB with primary table named TABLE_NAME with replicate table named TARGET_TABLE_NAME (f_kurs identity map to rs_oracle_float, c_kurstype tinyint, c_currency_1 smallint, c_currency_2 smallint, f_bank int, f_user int, rate numeric, date_begin datetime, date_create datetime, username varchar(30), workstation varchar(50), f_office int, special tinyint) primary key (f_kurs) replicate minimal columns with dynamic sql
Создаем подписку на созданный основной repdef на RS:
create subscription SUBS_NAME for RDNAME with replicate at eco.dwh without materialization go
Теперь включаем репликацию новой таблицы в Sybase Front. После выполнения нижеуказанной команды RepAgent начнет отслеживать в транзакционном логе Sybase базы источника все изменения по указанной таблице и передавать их на RS для дальнейшей обработки и передачи их на приемник:
sp_setreptable SOURCE_TABLE_NAME, true go
Выполняем начальную материализацию новых таблиц, если в источнике есть данные.
Выгружаем данные из Sybase через bcp.exe:
rem %1-Server rem %2-Passw_SA rem %3-Database Name rem %4-Table Name bcp.exe %3.dbo.%4 out %4.dat -c -td6vWf7 -rd1K6t7 -Jcp1251 -eErr.txt -S%1 -Usa -P%2
Создаем файл загрузки данных в Oracle и загружаем данные через sqlldr.
Пример загрузки таблицы F_KURS.ctl:
LOAD DATA CHARACTERSET CL8MSWIN1251 INFILE 'f_kurs.dat' "STR 'd1K6t7'" BADFILE 'f_kurs.BAD' DISCARDFILE 'f_kurs.DSC' APPEND INTO TABLE TARGET_TABLE_NAME FIELDS TERMINATED BY "d6vWf7" TRAILING NULLCOLS ( F_KURS CHAR(255), C_KURSTYPE CHAR(255), C_CURRENCY_1 CHAR(255), C_CURRENCY_2 CHAR(255), F_BANK CHAR(255), F_USER CHAR(255), RATE CHAR(255), DATE_BEGIN CHAR(255) "TO_DATE(SUBSTR(:DATE_BEGIN,1,20)||SUBSTR(:DATE_BEGIN,25,2),'Mon DD YYYY HH:MI:SSAM')", DATE_CREATE CHAR(255) "TO_DATE(SUBSTR(:DATE_CREATE,1,20)||SUBSTR(:DATE_CREATE,25,2),'Mon DD YYYY HH:MI:SSAM')", USERNAME CHAR(255), WORKSTATION CHAR(255), F_OFFICE CHAR(255), SPECIAL CHAR(255) ) bash#: sqlldr USERNAME/PASSW control={location}/F_KURS.ctl
Поднимаем очередь, смотрим и устраняем возникающие ошибки репликации:
resume connection to server.db
На этом все! Делитесь в комментариях, что получилось, а что — нет. Какой репликацией чаще всего пользуетесь?
До встречи!
ссылка на оригинал статьи https://habr.com/ru/articles/902708/
Добавить комментарий