Pull to refresh
62.63
Инфосистемы Джет
российская ИТ-компания

Только хардкор, только мануал: репликация данных

Level of difficultyMedium
Reading time24 min
Views1.6K

Привет, Хабр!

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

Репликация данных между 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

На этом все! Делитесь в комментариях, что получилось, а что — нет. Какой репликацией чаще всего пользуетесь?

До встречи!

Tags:
Hubs:
Total votes 7: ↑7 and ↓0+14
Comments3

Articles

Information

Website
jet.su
Registered
Founded
1991
Employees
1,001–5,000 employees
Location
Россия