10
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OracleとMySQLでDB LINKをしてみる

Last updated at Posted at 2019-04-23

MySQLからOracleへmysqldump以外の方法でデータ移行ができないか模索するためDB LINKを作ってみました。

目指すのはOracleからMySQLのデータを取り出すこと。

手順はkenken0807さんの検証とほほ同じ。
ただUTF8環境の場合は独自のハマりポイントもあったためそちらについても記載しています。
調べてみるまではネット上にナレッジがいっぱい落ちていると思ってたのに、全然なかったしね。
少しでも参考になれば幸いです。

環境

RDBMS DB version OS OS version IP address DBの文字コード
Oracle 18.3.0.0.0 Oracle Linux 7.6 192.168.56.101 utf8
MySQL 5.7.25 Oracle Linux 7.6 192.168.56.111 utf8

MySQL側作業

先にDB LINK用ユーザの作成と権限の付与を行っておきます。

1. DB LINK用ユーザの作成

create user 'from_oracle'@'192.168.56.101' identified by 'from_oracle';

2. DB LINK用ユーザに接続先データベースへの権限付与

grant all privileges on db_migration.* to 'from_oracle'@'192.168.56.101';

Oracle側作業

MySQLとはODBCを経由してDB LINKを行います。

3. unixODBC (ODBC Driver Manager)のインストール

yum install unixODBC

unixODBCの設定を確認

odbcinst -j
[root@local01 ~]# odbcinst -j
unixODBC 2.3.1
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
[root@local01 ~]#

SYSTEM DATA SOURCESのパスを確認しておく。

4. mysql-connector-odbc (MySQL用ODBCドライバ) のインストール

Oracle Linuxのリポジトリ [ol7_latest] から入手するとドライバのバージョンが結構古い(5.2.5-8)ので、公式から最新版をインストール。

yum install https://dev.mysql.com/get/Downloads/Connector-ODBC/8.0/mysql-connector-odbc-8.0.15-1.el7.x86_64.rpm

最新版はこちらからも入手可能。
http://dev.mysql.com/downloads/connector/odbc/#downloads

5. unixODBCのMySQL用ODBC Driverの設定確認

unixODBCおよびmysql-connector-odbcのインストールを行うと、自動的に作成&エントリーの追加がされているはず。

cat /etc/odbcinst.ini
/etc/odbcinst.ini
[PostgreSQL]
Description=ODBC for PostgreSQL
Driver=/usr/lib/psqlodbcw.so
Setup=/usr/lib/libodbcpsqlS.so
Driver64=/usr/lib64/psqlodbcw.so
Setup64=/usr/lib64/libodbcpsqlS.so
FileUsage=1

[MySQL]
Description=ODBC for MySQL
Driver=/usr/lib/libmyodbc5.so
Setup=/usr/lib/libodbcmyS.so
Driver64=/usr/lib64/libmyodbc5.so
Setup64=/usr/lib64/libodbcmyS.so
FileUsage=1

[MySQL ODBC 8.0 Unicode Driver] # ★今回使用するのはこのODBCドライバ
Driver=/usr/lib64/libmyodbc8w.so
UsageCount=1

[MySQL ODBC 8.0 ANSI Driver]
Driver=/usr/lib64/libmyodbc8a.so
UsageCount=1

6. MySQLデータソースの設定

項番3で確認したSYSTEM DATA SOURCESのファイルを編集する。

vi /etc/odbc.ini

Driverには項番5で確認したドライバの名前を入れる。
データベース名の大文字小文字にも要注意。

/etc/odbc.ini
# 任意のデータソース名
[MYDB]
# /etc/odbcinst.iniのドライバ名
# 8.0系かつUnicodeのDriverを利用
Driver     = MySQL ODBC 8.0 Unicode Driver
# MySQLのホスト名またはIPアドレス
SERVER     = 192.168.56.111
# MySQLのポート番号
PORT       = 3306
# MySQLの接続するデータベース名
DATABASE   = db_migration
# MySQLへ接続するユーザ名
USER       = from_oracle
# MySQLへ接続するユーザのパスワード
PASSWORD   = from_oracle
# キャラクタセット
CHARSET    = utf8

7. ODBC接続チェック

isqlコマンドを使用してODBC接続してみる。

isql MYDB -v
[root@local01 ~]# isql MYDB -v
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> select user();
+----------------------------------------------------------------------------------------------+
| user()                                                                                       |
+----------------------------------------------------------------------------------------------+
| from_oracle@192.168.56.101                                                                   |
+----------------------------------------------------------------------------------------------+
SQLRowCount returns 1
1 rows fetched
SQL> show databases;
+-----------------------------------------------------------------+
| Database                                                        |
+-----------------------------------------------------------------+
| information_schema                                              |
| db_migration                                                    |
+-----------------------------------------------------------------+
SQLRowCount returns 2
2 rows fetched
SQL> quit
[root@local01 ~]#

8. ODBCドライバマネージャーライブラリのパスを確認

項番11のゲートウェイ初期化パラメータファイル設定時に使用するため事前に確認する。

ldd `which isql`
[root@local01 ~]# ldd `which isql`
        linux-vdso.so.1 =>  (0x00007fff38bb9000)
        libodbc.so.2 => /lib64/libodbc.so.2 (0x00007ffa4a18e000) # ★ここがODBCドライバマネージャーライブラリのパス
        libltdl.so.7 => /lib64/libltdl.so.7 (0x00007ffa49f84000)
        libreadline.so.6 => /lib64/libreadline.so.6 (0x00007ffa49d3d000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007ffa49b39000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007ffa4991d000)
        libc.so.6 => /lib64/libc.so.6 (0x00007ffa4954f000)
        libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007ffa49325000)
        /lib64/ld-linux-x86-64.so.2 (0x0000558bd097b000)
[root@local01 ~]#

9. listener.oraの編集

既存のリスナーに影響を与えぬよう、別途1522ポートでゲートウェイ用リスナーを作成してます。

vi ${ORACLE_HOME}/network/admin/listener.ora

下記エントリーを追記。
SID_NAMEには/etc/odbc.iniで定義したデータソース名を。
dg4odbcは小文字で。

${ORACLE_HOME}/network/admin/listener.ora
LISTENER2 =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.101)(PORT = 1522))
    )
  )

SID_LIST_LISTENER2 =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = MYDB)
      (ORACLE_HOME = /opt/oracle/product/18c/dbhome_1)
      (PROGRAM = dg4odbc)
    )
  )

10. tnsnames.oraの編集

vi ${ORACLE_HOME}/network/admin/tnsnames.ora

ゲートウェイ用の下記エントリーを追加する。
SIDにはlistener.oraで指定したSID_NAMEを。

${ORACLE_HOME}/network/admin/tnsnames.ora
MYDB =
  (DESCRIPTION=
      (ADDRESS=
         (PROTOCOL=TCP)
         (HOST=192.168.56.101)
         (PORT=1522)
      )
      (CONNECT_DATA=
         (SID = MYDB)
      )
      (HS=OK)
  )

11. ゲートウェイ初期化パラメータファイルを作成

ゲートウェイ初期化パラメータファイルは$ORACLE_HOME/hs/admin配下にinit<SID>.oraと言う名前で作成する。
initdg4odbc.oraというサンプルファイルがあるので、それをコピーして作ってもいい。
<SID>は/etc/odbc.iniのデータソース名(DSN)とイコール。
データソース名を大文字にしている場合は初期化パラメータファイルも大文字で作る必要がある。

vi ${ORACLE_HOME}/hs/admin/initMYDB.ora

以下の内容を記載。

${ORACLE_HOME}/hs/admin/initMYDB.ora
# /etc/odbc.iniのデータソース名
HS_FDS_CONNECT_INFO=MYDB
# Oracleの文字コードがUTF8の場合以下の通りに設定する
HS_NLS_NCHAR=UCS2
HS_LANGUAGE=JAPANESE_JAPAN.AL32UTF8
# 7.で確認したODBCドライバマネージャーライブラリのパス
HS_FDS_SHAREABLE_NAME=/lib64/libodbc.so.2
# ODBCINI変数に参照するiniファイルのパスを指定
set ODBCINI=/etc/odbc.ini

特にHS_NLS_NCHAR, HS_LANGUAGEの設定がうまくいっていないとDB LINK設定後、MySQLのデータを参照しようとしても以下のエラーが出てハマる。

ERROR at line 1: 
ORA-28500: connection from ORACLE to a non-Oracle system returned this message: 
[

うまくいかないときは、HS_FDS_TRACE_LEVEL=debugを設定すること。
$ORACLE_HOME/hs/logにトレースファイルが出力されるようになるのでエラー原因が掴めるかも…。

12. リスナー起動

作成したリスナーを起動する。

lsnrctl start listener2

13. DB LINK作成

今回はPDB上でDB LINKを作成してますが、特にPDBだからうまくいかないと言ったことはありませんでした。

CREATE PUBLIC DATABASE LINK DBLINK_MYSQL CONNECT TO "from_oracle" IDENTIFIED BY "from_oracle" USING 'MYDB';

14. MySQLのデータ参照

SQL> select count(*) from "emp"@DBLINK_MYSQL;

  COUNT(*)
----------
        10

SQL> select "id", "desc" from "emp"@DBLINK_MYSQL where rownum <= 1;

     id desc
------- ----------------------------------------
      1 説明あれこれ

終わりに

実際にはかなりの試行錯誤がありました。
DB LINKを使うことでmysqldumpではできない、段階的なデータ移行ができたらいいなと思ってます。

参考にしたサイト

OracleからMySQLへODBC経由のデータベースリンクで接続したメモ
http://kenken0807.hatenablog.com/entry/2015/07/27/144953
Oracle HS fails to operate on mysql-connector-odbc-5.3.4-1.el7
https://bugs.mysql.com/bug.php?id=78242
https://bugs.mysql.com/file.php?id=23311&bug_id=78242
Error Ora-28500 and Sqlstate I or Displays a Square Bracket - [ - Issuing Selects From a Unicode Oracle RDBMS With Dg4odbc To Non-Oracle Databases Using the UnixODBC Driver Manager (ドキュメントID 756186.1)
https://support.oracle.com/epmos/faces/DocumentDisplay?id=756186.1
(参照にはOTNアカウントが必要)

10
10
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
10
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?