はじめに
Oracle GoldenGate とは
Oracle GoldenGate は異種DB間のリアルタイムデータ複製のためのソフトウェア・パッケージです。
今回利用する Oracle GlodenGate Free には制限事項がありますが、今回は検証目的ということで Free を利用します。
確認すること
Oracle DB 間でデータ同期ができることを確認します。
具体的な手順は 21.3 -> 21.3 を記載し、それ以外は差分を記載します。
- 21.3 -> 21.3
- 23.5 -> 23.5
- 21.3 -> 23.5
確認
環境
今回は以下の環境を利用しました。
- Oracle Enterprise Linux 8.10
- CPU: 8v
- Memory: 16GiB
- パッケージ関係は以下
containerd.io.x86_64 1.6.32-3.1.el8
docker-buildx-plugin.x86_64 0.14.0-1.el8
docker-ce.x86_64 3:26.1.3-1.el8
docker-ce-cli.x86_64 1:26.1.3-1.el8
docker-ce-rootless-extras.x86_64 26.1.3-1.el8
docker-compose-plugin.x86_64 2.27.0-1.el8
container-registry へのログイン
Free のみの利用でしたらログインは不要ですが、それ以外を利用する場合はログインして規約に同意が必要になります。
規約への同意はこのページの右側から可能ですので、実施してください。
同意したらdocker login container-registry.oracle.com
を実施してログインしてください。
21.3 -> 21.3の検証
ファイル配置
作業ディレクトリにて以下のファイルを配置します。
ディレクトリ構成は以下の感じです。
<作業ディレクトリ>
├ compose.yaml
└ startupScript
├ 01_user.sql
└ 02_data.sql
compose.yaml
docker compose用の設定ファイルです。
ulimitの設定と環境変数の設定をしています(Oracle GoldenGateも含まれてます)。
以下の点にご注意ください。
- ORACLE_SID と ORACLE_PDB が free のものなっています
- これは検証の手間を考えて固定したいのですが、 free 側でこれらの環境変数が設定できないため free 側に合わせるようしています
- ulimit 系は Oracle公式のリポジトリの起動コマンドに合わせています
- DBのデータの永続化は考えていません、したい場合は以下を実施してください
-
/opt/oracle/oradata
に対して volume をマウントするようにしてください - マウントするホスト側のディレクトリに対して
chown 54321:54321
を実行してください
-
- パスワード管理を考慮していません、検証目的以外の場合は適宜 KMS などにキーは格納するようにしてください
compose.yaml
x-ulimits: &ulimits
nofile:
soft: 1024
hard: 65536
nproc:
soft: 2047
hard: 16384
stack:
soft: 10485760
hard: 33554432
memlock: 3221225472
x-oraenvs: &oraenvs
- ORACLE_PWD=welcome##1
- ENABLE_ARCHIVELOG=true
- INIT_SGA_SIZE=4096
- INIT_PGA_SIZE=1024
- ORACLE_SID=FREE
- ORACLE_PDB=FREEPDB1
services:
source-db:
image: container-registry.oracle.com/database/enterprise:21.3.0.0
container_name: source-db
ulimits: *ulimits
environment: *oraenvs
volumes:
- ./startupScript:/opt/oracle/scripts/startup
ports:
- "1521:1521"
target-db:
image: container-registry.oracle.com/database/enterprise:21.3.0.0
container_name: target-db
ulimits: *ulimits
environment: *oraenvs
ports:
- "1621:1521"
ogg:
image: container-registry.oracle.com/goldengate/goldengate-free:latest
container_name: ogg
ports:
- "8080:80"
startupScript
初期データ投入用のSQLを配置します。
導入先は FREEPDB1 になっています。
startupScript/01_init.sql
alter session set container = FREEPDB1;
CREATE USER project_manager IDENTIFIED BY welcome##2;
GRANT CONNECT, RESOURCE TO project_manager;
GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE PROCEDURE, CREATE SEQUENCE, CREATE TRIGGER, CREATE SYNONYM TO project_manager;
ALTER USER project_manager QUOTA UNLIMITED ON USERS;
startupScript/02_data.sql
-- プロジェクト管理データベーススキーマ
alter session set container = FREEPDB1;
alter session set current_schema = project_manager;
-- プロジェクト情報テーブル
CREATE TABLE PROJECTS (
PROJECT_ID NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
PROJECT_NAME VARCHAR2(100) NOT NULL,
START_DATE DATE NOT NULL,
END_DATE DATE,
BUDGET NUMBER(15, 2)
);
-- 初期データ
INSERT INTO PROJECTS (PROJECT_NAME, START_DATE, END_DATE, BUDGET) VALUES
('New Website Launch', TO_DATE('2024-08-01', 'YYYY-MM-DD'), TO_DATE('2024-12-31', 'YYYY-MM-DD'), 50000),
('Mobile App Development', TO_DATE('2024-09-15', 'YYYY-MM-DD'), NULL, 150000),
('Marketing Campaign', TO_DATE('2024-10-01', 'YYYY-MM-DD'), TO_DATE('2025-03-31', 'YYYY-MM-DD'), 30000);
-- 従業員情報テーブル
CREATE TABLE EMPLOYEES (
EMPLOYEE_ID NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
FIRST_NAME VARCHAR2(50) NOT NULL,
LAST_NAME VARCHAR2(50) NOT NULL,
EMAIL VARCHAR2(100),
PHONE_NUMBER VARCHAR2(20),
HIRE_DATE DATE
);
-- 初期データ
INSERT INTO EMPLOYEES (FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE) VALUES
('John', 'Doe', 'john.doe@example.com', '123-456-7890', TO_DATE('2022-01-15', 'YYYY-MM-DD')),
('Jane', 'Smith', 'jane.smith@example.com', '123-456-7891', TO_DATE('2023-04-23', 'YYYY-MM-DD')),
('Emily', 'Davis', 'emily.davis@example.com', '123-456-7892', TO_DATE('2021-07-30', 'YYYY-MM-DD')),
('Michael', 'Brown', 'michael.brown@example.com', '123-456-7893', TO_DATE('2020-11-10', 'YYYY-MM-DD'));
-- プロジェクトメンバーテーブル
CREATE TABLE PROJECT_MEMBERS (
MEMBER_ID NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
PROJECT_ID NUMBER NOT NULL,
EMPLOYEE_ID NUMBER NOT NULL,
ROLE VARCHAR2(50),
CONSTRAINT FK_PROJECT FOREIGN KEY (PROJECT_ID) REFERENCES PROJECTS(PROJECT_ID),
CONSTRAINT FK_EMPLOYEE FOREIGN KEY (EMPLOYEE_ID) REFERENCES EMPLOYEES(EMPLOYEE_ID)
);
-- 初期データ
INSERT INTO PROJECT_MEMBERS (PROJECT_ID, EMPLOYEE_ID, ROLE) VALUES
(1, 1, 'Project Manager'),
(1, 2, 'Web Developer'),
(2, 3, 'App Developer'),
(3, 4, 'Marketing Specialist');
-- タスクテーブル
CREATE TABLE TASKS (
TASK_ID NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
PROJECT_ID NUMBER NOT NULL,
TASK_NAME VARCHAR2(100) NOT NULL,
ASSIGNED_TO NUMBER,
STATUS VARCHAR2(20) DEFAULT 'Pending',
DEADLINE DATE,
CONSTRAINT FK_PROJECT_TASK FOREIGN KEY (PROJECT_ID) REFERENCES PROJECTS(PROJECT_ID),
CONSTRAINT FK_ASSIGNEE FOREIGN KEY (ASSIGNED_TO) REFERENCES EMPLOYEES(EMPLOYEE_ID)
);
-- 初期データ
INSERT INTO TASKS (PROJECT_ID, TASK_NAME, ASSIGNED_TO, STATUS, DEADLINE) VALUES
(1, 'Design Homepage', 2, 'In Progress', TO_DATE('2024-09-15', 'YYYY-MM-DD')),
(1, 'Develop Backend', 2, 'Pending', TO_DATE('2024-10-01', 'YYYY-MM-DD')),
(2, 'Create App Prototype', 3, 'Pending', TO_DATE('2024-11-30', 'YYYY-MM-DD')),
(3, 'Launch Social Media Ads', 4, 'Pending', TO_DATE('2024-12-01', 'YYYY-MM-DD'));
docker compose の起動
docker compose コマンドを利用して Oracle DB と GoldenGate を起動していきます。
## 起動
docker compose up -d
## ログ確認
docker compose logs
## oggadminのパスワード確認
### Password for OGG administrative user 'oggadmin' is '***' という列を見る
docker compose logs ogg | head
## source-dbにデータが入っている(ユーザがいる)こと確認&archivelog modeか確認
docker compose exec -T source-db sqlplus -S / as sysdba << EOF
alter session set container = FREEPDB1;
select username from dba_users where username = 'PROJECT_MANAGER';
select count(*) from PROJECT_MANAGER.PROJECTS;
select count(*) from PROJECT_MANAGER.EMPLOYEES;
select count(*) from PROJECT_MANAGER.PROJECT_MEMBERS;
select count(*) from PROJECT_MANAGER.TASKS;
archive log list
EOF
sqlplus -S project_manager/welcome##2@localhost:1521/FREEPDB1 << EOF
select systimestamp from dual;
EOF
## target-dbにデータが入っていない(ユーザがいない)こと確認&archivelog modeか確認
docker compose exec -T target-db sqlplus -S / as sysdba << EOF
alter session set container = FREEPDB1;
select username from dba_users where username = 'PROJECT_MANAGER';
archive log list
EOF
## archivelog modeではなかったら以下の手順でONにしてください。
docker compose exec -T <source-db or target-db> sqlplus -S / as sysdba << EOF
shutdown immediate;
startup mount;
alter database archivelog;
alter database open;
EOF
GoldenGate でデータ同期設定を入れる
全て起動したら GoldenGate の WebUI(localhost:8080でアクセスできます) に入ってデータ同期の設定を入れます。
ここからは実際に行った画像と共に確認していきます。
1. WebUI アクセス
- ユーザ名とパスワード入力
- oggadminとさっき確認したパスワードを入力してください
- connection 作成の選択
2. Source DB の Connection 作成
同期元のDBへの接続を作成します。
- source db connection 作成 - 1つ目
- 基本情報を入れます
- source db connection 作成 - 2つ目
- 対象のホスト名など入れます
-
SYSDBA priviledges available
を選択して開いたウィンドウはSYSとORACLE_PWDに設定したパスワードを入力してください
- source db connection 作成 - 3つ目
- ggadmin作成します(パスワードは適切に入力してください)
- source db connection 作成 - 3つ目
- ggadminを実際に作成&権限付与します
-
Run analysis
を選択して出てきた SQL 確認したらRun SQL
選択します - 成功したら
prepare database result
が表示されます
- source db connection 作成 - 4つ目
- 確認して終わりです
3. Target DB の Connection 作成
同期先のDBへの接続を作成します。
設定画面は Source DB とほぼ同じなので割愛します。
ここまでで以下のようになっていればOKです。
4. 複製設定( Pipeline )作成
- pipeline 作成の選択
- pipeline 作成 - 1つ目
- Recipe 選択します
- 今回は一方通行の複製を試します
- pipeline 作成 - 2つ目
- Name などを入力します
- pipeline 作成 - 3つ目
- 同期元と先を指定します
5. 複製設定編集~同期開始まで
Pipeline を作成したので、複製の設定を確認して同期開始します。
- PDBADMINの同期を外して Save を押します
- Start を押して Status が全て Completed になればOKです
- 認証作成やExtract/Replicatの作成・NWimportでの初期同期をやってくれます
- 完了したら Runtime 画面に遷移します
同期確認
source-db にデータを投入して伝搬されているか確認します。
## まずはtarget-dbにデータが入っているか確認(source-dbとtarget-dbで件数確認)
sqlplus -S sys/welcome##1@localhost:1521/FREEPDB1 as sysdba << EOF
select username from dba_users where username = 'PROJECT_MANAGER';
select count(*) from PROJECT_MANAGER.PROJECTS;
select count(*) from PROJECT_MANAGER.EMPLOYEES;
select count(*) from PROJECT_MANAGER.PROJECT_MEMBERS;
select count(*) from PROJECT_MANAGER.TASKS;
EOF
sqlplus -S sys/welcome##1@localhost:1621/FREEPDB1 as sysdba << EOF
select username from dba_users where username = 'PROJECT_MANAGER';
select count(*) from PROJECT_MANAGER.PROJECTS;
select count(*) from PROJECT_MANAGER.EMPLOYEES;
select count(*) from PROJECT_MANAGER.PROJECT_MEMBERS;
select count(*) from PROJECT_MANAGER.TASKS;
EOF
## データ伝搬確認
### source-db更新
sqlplus -S sys/welcome##1@localhost:1521/FREEPDB1 as sysdba << EOF
select username from dba_users where username = 'PROJECT_MANAGER';
INSERT INTO PROJECT_MANAGER.EMPLOYEES (FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE) VALUES ('Alice', 'Doe', 'alice.doe@example.com', '444-333-2222', TO_DATE('2022-03-13', 'YYYY-MM-DD'));
commit;
set lines 500 pages 300 tab off
col EMAIL for a50
col TASK_NAME for a50
select EMPLOYEE_ID, EMAIL from PROJECT_MANAGER.EMPLOYEES;
EOF
### target-db確認
sqlplus -S sys/welcome##1@localhost:1621/FREEPDB1 as sysdba << EOF
set lines 500 pages 300 tab off
col EMAIL for a50
col TASK_NAME for a50
select EMPLOYEE_ID, EMAIL from PROJECT_MANAGER.EMPLOYEES;
EOF
## DDL伝搬確認
### source-db更新
sqlplus -S sys/welcome##1@localhost:1521/FREEPDB1 as sysdba << EOF
desc PROJECT_MANAGER.TASKS
alter table PROJECT_MANAGER.TASKS add (priority number(1) default 0);
desc PROJECT_MANAGER.TASKS
EOF
### target-db確認
sqlplus -S sys/welcome##1@localhost:1621/FREEPDB1 as sysdba << EOF
desc PROJECT_MANAGER.TASKS
EOF
また Runtime 画面を見ると以下のように同期されていることが確認できます。
そのほかのバージョン同士の検証
以下のバージョン間の検証については手順上の差異を記載します。
- 23.5 -> 23.5
- 21.3 -> 23.5
23.5 -> 23.5
compose.yaml
compose.yaml の image 部分を以下のようにご修正ください。
あとは同じ手順で行けます。
compose.yaml
x-ulimits: &ulimits
nofile:
soft: 1024
hard: 65536
nproc:
soft: 2047
hard: 16384
stack:
soft: 10485760
hard: 33554432
memlock: 3221225472
x-oraenvs: &oraenvs
- ORACLE_PWD=welcome##1
- ENABLE_ARCHIVELOG=true
- INIT_SGA_SIZE=4096
- INIT_PGA_SIZE=1024
- ORACLE_SID=FREE
- ORACLE_PDB=FREEPDB1
services:
source-db:
image: container-registry.oracle.com/database/free:23.5.0.0
container_name: source-db
ulimits: *ulimits
environment: *oraenvs
volumes:
- ./startupScript:/opt/oracle/scripts/startup
ports:
- "1521:1521"
target-db:
image: container-registry.oracle.com/database/free:23.5.0.0
container_name: target-db
ulimits: *ulimits
environment: *oraenvs
ports:
- "1621:1521"
ogg:
image: container-registry.oracle.com/goldengate/goldengate-free:latest
container_name: ogg
ports:
- "8080:80"
21.3 -> 23.5
compose.yaml
こちらも source-db の image を変更すれば、あとは同じ手順で行けます。
まとめ
Oracle GoldenGate Free を用いて以下の Oracle DB 間でデータ同期(+DDL同期)ができることを確認できました。
- 21.3 -> 21.3
- 23.5 -> 23.5
- 21.3 -> 23.5
検証目的で利用するなら Free は手軽に開始できるのでおすすめかと思います。
ただ、はじめにで記載しましたが Free には制限事項が多いので本番で利用する場合には Free ではない方のご利用を検討が必要そうです。
参考
- GoldenGate Free
- GoldenGate Microservice Architecture