LoginSignup
1
2
お題は不問!Qiita Engineer Festa 2023で記事投稿!

OracleDBのマテリアライズド・ビューによるデータ移行を試す

Posted at

概要

DBLINKとマテリアライズド・ビューを組み合わせたデータ同期について検証するために、DockerでOracleDBを2台立て、OracleDB間でのデータ移行とリフレッシュを試してみます。

実行環境

Dockerイメージの利用には自身でのDockerビルドが必要になりますが割愛します。

docker-composeを利用してDock上でOracleDBを2台立ち上げます。

ディレクトリoradata1、oradata2の所有者のユーザIDは54321にchownで変更しています。

oracle1が移行元、oracle2が移行先になります。

version: '3'
services:

  oracle1:
    image: oracle/database:19.3.0-ee
    environment:
      - ORACLE_SID=ORCLCDB1
      - ORACLE_PWD=p@ssw0rd
      - ORACLE_CHARACTERSET=AL32UTF8
    ports:
      - 11521:1521
      - 15500:5500
    volumes:
      - ./oradata1:/opt/oracle/oradata

  oracle2:
    image: oracle/database:19.3.0-ee
    environment:
      - ORACLE_SID=ORCLCDB2
      - ORACLE_PWD=p@ssw0rd
      - ORACLE_CHARACTERSET=AL32UTF8
    ports:
      - 21521:1521
      - 25500:5500
    volumes:
      - ./oradata2:/opt/oracle/oradata

作業概要

以下のシナリオで作業を進めます。

  1. (共通)ユーザ、スキーマ、表領域を用意
  2. (Oracle1)テーブルの作成とデータを挿入
  3. (Oracle2)データベースリンクの設定
  4. (Oracle1)マテリアライズド・ビューログを作成
  5. (Oracle2)マテリアライズド・ビューの作成
  6. (Oracle1)データの追加挿入確認

作業詳細

(共通)ユーザ、スキーマ、表領域を用意

(Oracle1)まずは、テーブルを作成する下準備をします。CDBに接続します。

sqlplus / as sysdba;

PDBに接続して表領域作成します。

ALTER SESSION SET CONTAINER = ORCLPDB1;

CREATE TABLESPACE TABLE_SPACE_MONSTER_GAME /*表領域名*/
DATAFILE '/opt/oracle/oradata/ORCLCDB1/ORCLPDB1/monster_game_1.dbf'
SIZE 100M /*サイズ*/
AUTOEXTEND OFF /*自動拡張*/
;

CREATE TEMPORARY TABLESPACE TEMP_SPACE_MONSTER_GAME /*表領域名*/
TEMPFILE '/opt/oracle/oradata/ORCLCDB1/ORCLPDB1/temp_monster_game_2.dbf'
SIZE 100M /*サイズ*/
;

ユーザ作成して権限付与します。

CREATE USER MONSTER_GAME
IDENTIFIED BY password123
DEFAULT TABLESPACE TABLE_SPACE_MONSTER_GAME
TEMPORARY TABLESPACE TEMP_SPACE_MONSTER_GAME
QUOTA 100M ON TABLE_SPACE_MONSTER_GAME
PROFILE DEFAULT
ACCOUNT UNLOCK
;

GRANT CREATE SESSION, 
 CREATE TABLE,
 CREATE VIEW,
 CREATE SEQUENCE,
 CREATE TRIGGER,
 CREATE SYNONYM,
 UNLIMITED TABLESPACE TO MONSTER_GAME;

作成したユーザでPDBにログインします。

sqlplus MONSTER_GAME@//localhost:1521/ORCLPDB1

同様のことをOracle2でも実施します。

sqlplus / as sysdba;
ALTER SESSION SET CONTAINER = ORCLPDB1;

CREATE TABLESPACE TABLE_SPACE_MONSTER_GAME /*表領域名*/
DATAFILE '/opt/oracle/oradata/ORCLCDB2/ORCLPDB1/monster_game_1.dbf'
SIZE 100M /*サイズ*/
AUTOEXTEND OFF /*自動拡張*/
;

CREATE TEMPORARY TABLESPACE TEMP_SPACE_MONSTER_GAME /*表領域名*/
TEMPFILE '/opt/oracle/oradata/ORCLCDB2/ORCLPDB1/temp_monster_game_2.dbf'
SIZE 100M /*サイズ*/
;
CREATE USER MONSTER_GAME
IDENTIFIED BY password123
DEFAULT TABLESPACE TABLE_SPACE_MONSTER_GAME
TEMPORARY TABLESPACE TEMP_SPACE_MONSTER_GAME
QUOTA 100M ON TABLE_SPACE_MONSTER_GAME
PROFILE DEFAULT
ACCOUNT UNLOCK
;

GRANT CREATE SESSION, 
 CREATE TABLE,
 CREATE VIEW,
 CREATE SEQUENCE,
 CREATE TRIGGER,
 CREATE SYNONYM,
 UNLIMITED TABLESPACE TO MONSTER_GAME;

(Oracle1)テーブルの作成とデータを挿入

同期したいテーブルを作成し適当にデータを入れておきます。

CREATE TABLE PLAYER(
  NAME VARCHAR2(100) NOT NULL,
  HP NUMBER(4, 0) NOT NULL,
  STR NUMBER(3,0) NOT NULL,
  DEF NUMBER(3,0) NOT NULL
);

INSERT INTO PLAYER VALUES ('MAGICIAN', 10, 10, 30);
INSERT INTO PLAYER VALUES ('THIEF', 20, 40, 30);
INSERT INTO PLAYER VALUES ('ASSASSIN', 20, 60, 30);
INSERT INTO PLAYER VALUES ('FIGHTER', 40, 30, 30);

(Oracle2)データベースリンクの設定

Oracle2にSYSでログインしてOracle2のMONSTER_GAMEに権限を追加します。

GRANT CREATE DATABASE LINK TO MONSTER_GAME;

Oracle2のMONSTER_GAMEにログインしてOracle1のMONSTER_GAMEに対してデータベースリンクを設定します。

CREATE DATABASE LINK DBLINK_PLAYER
CONNECT TO MONSTER_GAME IDENTIFIED BY password123 
USING '//oracle1:1521/ORCLPDB1';

SELECTしてみるとOracle1から無事データを取得できていることを確認できました。

SQL> COL NAME FORMAT A10
SQL> SELECT * FROM PLAYER@DBLINK_PLAYER;

NAME               HP        STR        DEF
---------- ---------- ---------- ----------
MAGICIAN           10         10         30
THIEF              20         40         30
ASSASSIN           20         60         30
FIGHTER            40         30         30

(Oracle1)マテリアライズド・ビュー・ログを作成

リフレッシュに必要なマテリアライズド・ビュー・ログを作成します。

CREATE MATERIALIZED VIEW LOG ON PLAYER WITH ROWID;

(Oracle2)マテリアライズド・ビューの作成

Oracle2にSYSでログインしてOracle2のMONSTER_GAMEに権限を追加します。

GRANT CREATE MATERIALIZED VIEW TO MONSTER_GAME;

Oracle2のMONSTER_GAMEでマテリアライズド・ビューを作成します。

CREATE MATERIALIZED VIEW PLAYER
AS SELECT * FROM PLAYER@DBLINK_PLAYER;

SELECT文でOracle1のテーブルと同期できていることを確認できました。

SQL> COL NAME FORMAT A10
SQL> SELECT * FROM PLAYER;

NAME               HP        STR        DEF
---------- ---------- ---------- ----------
MAGICIAN           10         10         30
THIEF              20         40         30
ASSASSIN           20         60         30
FIGHTER            40         30         30

(Oracle1)データの追加挿入確認

Oracle1のMONSTER_GAMEでデータ挿入します。

INSERT INTO PLAYER VALUES ('KNIGHT', 80, 30, 20);
INSERT INTO PLAYER VALUES ('BISHOP', 30, 30, 50);

Oracle2のMONSTER_GAMEでリフレッシュします。

EXECUTE DBMS_MVIEW.REFRESH('PLAYER', 'c');

Oracle2のMONSTER_GAMEでSELECT文を実施し、同期できていることを確認できました。

SQL>  SELECT * FROM PLAYER;

NAME               HP        STR        DEF
---------- ---------- ---------- ----------
MAGICIAN           10         10         30
THIEF              20         40         30
ASSASSIN           20         60         30
FIGHTER            40         30         30
KNIGHT             80         30         20
BISHOP             30         30         50

6 rows selected.

後片付け

(Oracle2)DBLINK削除

DROP DATABASE LINK DBLINK_PLAYER;

(共通)スキーマと表領域削除

DROP USER MONSTER_GAME CASCADE;
DROP TABLESPACE TABLE_SPACE_MONSTER_GAME INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS;
DROP TABLESPACE TEMP_SPACE_MONSTER_GAME INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS;

感想

実際に試してみることでどちらのサーバで何をする必要があるかがわかりました。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2