MTU lab

強化版!MySQLへのデータ移行術(2/2)

MTUの準備

  1. MTU v4.2 サンプル版をこちらからダウンロードして取扱説明書(4.28MB)に解説された方法に従ってインストールしてください。32-bit 版、64-bit 版のどちらも使うことが出来ます。但し、16メガ (2の24乗)バイトを超える LONG型かLONG RAW型のデータを扱う場合は 64-bit版をお使いください。
  2. トピック前半の表1と表2で示した環境変数の値を設定して下さい。環境変数設定ファイル:env.bat は下記の場所にあります。
    C:\ProgramData\PLUMSIX\mtu_4.2\x86 (32-bit版)
    C:\ProgramData\PLUMSIX\mtu_4.2\x64 (64-bit版)

MTU adaptor for MySQLの準備

  1. MySQLのサイトから Windows (x86, 32-bit), ZIP Archive (mysql-5.x.x-win32.zip) を入手し、任意の場所へ解凍して下さい。
  2. マイクロソフト社のVisual C++ 2013 がバンドルされた製品を用意してください。Visual Studio は こちらから入手できます。例えば、Microsoft Visual Studio Express 2013 for Windows Desktop がビルドに利用可能です。
  3. MTU adaptor for MySQL が含まれた書庫ファイルをこちらからダウンロードして任意のフォルダへ解凍してください。この記事では C:\path\to\AdpMysql を解凍先としています。
    ※本稿で提供するソフトウエアの著作権は株式会社プラムシックスが所有します。このソフトウエアを取り扱う際は GPLv2 に定められた条項を遵守するものとします。
  4. Visual Studio の製品のメニューに含まれる「開発者コマンド プロンプト for VS2013」を表示し、MTU adaptor for MySQLを解凍した場所へディレクトリを移動します。
    cd /d "MTU adaptor for MySQLの解凍先ディレクトリ名"
  5. ソース・コードが含まれている AdpMysql.cpp というファイルをスクリーン・エディタで開き、ご利用の環境に合わせて #define ディレクティブのマクロ定義を変更後、ファイルを保存して下さい。
    マクロ 変更前 摘要
    HOST “localhost” sshポート転送を利用した暗号化対策が不要な場合は、接続先のMySQL データベースが稼働するホスト名か、またはIPアドレスを記述して下さい。暗号化対策が必要な場合は、localhost を指定してください。
    PORT 13306 ssh ポート転送を利用した暗号化対策が不要な場合は MySQL のデフォルトポート番号の 3306 を記述して下さい。暗号化対策が必要である場合 Tera Term の準備(後述)で説明する、「ローカルのポート」の番号を記述して下さい。
    USER “scott” 接続先 MySQL のユーザ名を記述して下さい。
    PASSWD “tiger” 接続先 MySQL のパスワードを記述して下さい。
    DB “scott” 接続先 MySQL のデータベース名を記述して下さい。
  6. コマンドプロンプトからnmakeコマンドを発行してプログラムをビルドします。path_to_mysql_home_dir の部分は MySQL を解凍した先のディレクトリ名に読み替えてください。
    nmake EXE="AdpMysql.exe" OBJS="AdpMysql.obj" CPPFLAGS="/EHsc /nologo /O2 /MD /DNDEBUG /I path_to_mysql_home_dir\include"

    実際にビルドした時の様子を示します。

    C:\path\to\AdpMysql>nmake EXE="AdpMysql.exe" OBJS="AdpMysql.obj" CPPFLAGS="/EHsc /nologo /O2 /MD /DNDEBUG /I C:\oracle\mysql-5.6.16-win32\include"
    
    Microsoft(R) Program Maintenance Utility Version 11.00.61030.0
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
            cl /EHsc /nologo /O2 /MD /DNDEBUG /I C:\oracle\mysql-5.6.16-win32\include /c AdpMysql.cpp
    AdpMysql.cpp
            cl /EHsc /nologo /O2 /MD /DNDEBUG /I C:\oracle\mysql-5.6.16-win32\include /FeAdpMysql.exe AdpMysql.obj
    
    C:\path\to\AdpMysql>

テスト用データの準備

  1. 検証に必要なデータを格納するためのテーブルを準備してください。データ移行元のOracle Databaseの任意のスキーマ(記事ではSCOTTとします)と、移行先のMySQL ユーザ(記事ではscottとします)へ次のSQLを適用するとこの検証に必要なテーブルを作ることができます。
    Oracle Database (移行元) MySQL (移行先)
    CREATE TABLE DB_MIG_TEST
    ( NUM_10_0       NUMBER(13)
    , CLOB_DATA      CLOB
    , VC2_10         VARCHAR2(13)
    , NCLOB_DATA     NCLOB
    , NUM_10_5       NUMBER(13,5)
    , DATE_VAL       DATE
    , BLOB_DATA      BLOB
    , LONG_STR       LONG
    , CHAR_10        CHAR(13)
    );
    create table DB_MIG_TEST
    ( NUM_10_0       decimal(13)
    , CLOB_DATA      longtext
    , VC2_10         varchar(13)
    , NCLOB_DATA     longtext
    , NUM_10_5       decimal(13,5)
    , DATE_VAL       datetime
    , BLOB_DATA      longblob
    , LONG_STR       longtext
    , CHAR_10        char(13)
    );
  2. 移行元 Oracle Database で次の無名PL/SQLブロックを実行して検証用データを10万件作成して下さい。10万件はサンプル版で扱える最大の行数です。終わったらトランザクションをコミットして下さい。
    declare
    	i binary_integer;
    	clob_loc CLOB;
    	nclob_loc NCLOB;
    	blob_loc BLOB;
    	clob_tmp CLOB;
    begin
    	for i in 1 .. 100000 loop
    		insert into DB_MIG_TEST values (i
    			, EMPTY_CLOB()
    			, '#_' || i
    			, EMPTY_CLOB()
    			, i - i * 0.00001, sysdate
    			, EMPTY_BLOB()
    			, '@ABCDEFGHI'
    			, '$_' || i)
    			returning clob_data, nclob_data, blob_data 
    			into clob_loc, nclob_loc, blob_loc;
    		clob_tmp := EMPTY_CLOB();
    		for j in 1 .. 5 loop
    			clob_tmp := clob_tmp || to_clob(to_char(i,'fm00000')
    			|| to_char(j, 'fm00000')
    			|| 'あいうえおかきくけこさしすせそたちつてとなにぬねの'
    			|| 'はひふへほまみむめもやゐゆゑよらりるれろわをん'
    			|| chr(10));
    		end loop;
    		dbms_lob.copy(clob_loc, clob_tmp, dbms_lob.getlength(clob_tmp));
    		dbms_lob.copy(nclob_loc, clob_tmp, dbms_lob.getlength(clob_tmp));
    		declare
    			max_lob_size integer := dbms_lob.lobmaxsize;
    			dest_offset  integer := 1;
    			src_offset   integer := 1;
    			blob_csid    number := dbms_lob.default_csid;
    			lang_context number := dbms_lob.default_lang_ctx;
    			warning      integer;
    			length       number;
    		begin
    			dbms_lob.converttoblob(blob_loc, clob_tmp, max_lob_size
    				, dest_offset, src_offset, blob_csid, lang_context, warning);
    		end;
    		if mod(i, 50000) = 0 then
    			commit;
    		end if;
    	end loop;
    	update DB_MIG_TEST set CLOB_DATA = NULL where NUM_10_0 = 892;
    	update DB_MIG_TEST set VC2_10 = NULL where NUM_10_0 = 12543;
    	update DB_MIG_TEST set NCLOB_DATA = NULL where NUM_10_0 = 24543;
    	update DB_MIG_TEST set NUM_10_5 = NULL where NUM_10_0 = 33975;
    	update DB_MIG_TEST set DATE_VAL = NULL where NUM_10_0 = 45432;
    	update DB_MIG_TEST set BLOB_DATA = NULL where NUM_10_0 = 54910;
    	update DB_MIG_TEST set LONG_STR = NULL where NUM_10_0 = 67543;
    	update DB_MIG_TEST set CHAR_10 = NULL where NUM_10_0 = 78853;
    end;
    /

    PL/SQL の終わりの方で8行分の update 文がありますが、これは MySQL へデータをコピーした後で、NULL が正しく伝達されているかどうかを確認する為の物です。

Tera Term の準備

MTU adaptor for MySQL から MySQL データベースまでの経路上 WAN が存在して、データの暗号化対策を行わなければならない時に、このセクションで説明する準備をして下さい。正確には Tera Term の TTSSH (Tera Term Secure Shell extension) を使用します。

  1. Tera Term を こちらからダウンロードしてインストールします。
  2. Tera Term を起動し、「設定」→「SSH転送」→「追加」を選択し、ポート転送のルールを作成して下さい。「ローカルのポート」には、未使用のポートを任意に選ぶことが出来ます。下記画像にlocalhost:13306 への着信を宛先ホスト:3306 へ転送するようなルールの設定事例を示します。
    02_TetaTerm_SSH_FW
  3. サーバー側のOpenSSL 構成や、公開鍵/秘密鍵のの配置等sshを利用する為の準備は事前に済ませておいてください。その後、Tera Term で移行先サーバへログインします。データ移行が終わるまで、接続を維持し続けてください。

    03_TetaTerm_SSH_AUTH

実行

  1. これで準備が整いました。データ移動を開始してみましょう。まずは、MTU を実行する為のコマンドプロンプトを開きます。デスクトップに「PLUMSIX」フォルダがあります。「MTU v4.2 xx-bit サンプル版」→「コマンド・プロンプト (MTU)」と順に選択してください。
    04_MTU_PROMPT
  2. カレントディレクトリにある Query.bat を実行すると、次のような表示が現れて動作が一時的に停止します。停止は MTU adaptor for MySQL の実行後データ移動が開始されるまで続きます。
    C:\ProgramData\PLUMSIX\mtu_4.2\x86>query
    Multi-threaded Unloader (SAMPLE) version 4.2.1
    (c) 2003 Plumsix Co.,Ltd. All rights reserved.
    Windows 8 Professional (build 9200), 64-bit WOW64
    Number of NUMA nodes 1
    Number of physical processor packages 1
    Number of processor cores 4
    Number of logical processors 8
    Number of processor L1/L2/L3 caches 8/4/1
    任意問合せファイル出力を実行します...
    クライアント・キャラクタセットID は 838 (JA16SJISTILDE) です。
    ネット・サービス名:local_xe へユーザ名:SYSTEM として接続します。
    しばらくお待ちください...
    Oracle Database 11g Express Edition Release 11.2.0.2.0 - Production
    接続先は SYSTEM@XE (ネット・サービス名:local_xe) です。
    サーバー・タイプは DEDICATED です。
    監査接続IDは 990485 です。
    サーバーの日付時刻は 2014-04-18 14:05:50 です。
    対象スキーマは SCOTT です。
    任意問い合わせを読取りました。(QUERYVAR) select * from DB_MIG_TEST
    キー・バリュー対定義ファイルを読込みます。C:\ProgramData\PLUMSIX\mtu_4.2\x86\input\bind.dat
    :b_job                        :SALESMAN
    :b_sal                        :        1,300
    :b_hiredate                   :1980-01-01
    複数の接続を確立します。要求された並列度は 4 です。
    空領域サイズチェックの閾値は 1024Mバイトです。
    データファイルと制御ファイルを出力中です。[71G] C:\ProgramData\PLUMSIX\mtu_4.2\x86\output
    ストリームの位置:named_pipe://\\.\pipe\{C}.{X}
    TableName                     :      NumRows:  Elapse:Rows/s:Bytes:  B/s:   Len
    DB_MIG_TEST                   :    Executing (← ここで一時停止)
  3. MTU adaptor for MySQL をビルドした時のコマンドプロンプトを使うか、閉じてしまった場合はもう一つコマンドプロンプトを開いてください。MySQL のライブラリが置いてある場所へ環境変数PATHなどを設定した後、プログラムを起動します。
    C:\path\to\AdpMysql>PATH=C:\oracle\mysql-5.6.16-win32\lib;%PATH%
    
    C:\path\to\AdpMysql>AdpMysql DB_MIG_TEST 20 libmysql.dll

    各引数には次の意味があります。

    引数 摘要
    第一引数 環境変数 QUERYVAR へ記述したSQL上のキーワード into に続く識別子を指定してください。
    第二引数 multiple lists of column values: INSERT 文の VALUES に続く構文要素を繰り返す回数。LOBを含むクエリーの場合は、環境変数 BULK_SIZE の値と一致させてください。
    第三引数 libmysql.dll 自身を含むパス。フォルダ名がPHTHに含まれていれば libmysql.dll のみでOKです。

    表3.MTU adaptor for MySQL の引数

  4. 下記に起動後の事例を示します。
    MTU adaptor for MySQL version 1.0, Copyright (c) 2014 Plumsix Co.,Ltd.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    Loading library libmysql.dll
    Client version 5.6.16
    Attempting to connect to scott@localhost:13306
    Server version 5.6.17
    Thread safety is true.
    Current charset is latin1, but changed to charset cp932.
    Waiting for \\.\pipe\DB_MIG_TEST.ctl...
    Waiting for \\.\pipe\DB_MIG_TEST.dat...
    Reading records...
    10000 rows processed.
    20000 rows processed.
    30000 rows processed.
    40000 rows processed.
    50000 rows processed.
    60000 rows processed.
    70000 rows processed.
    80000 rows processed.
    90000 rows processed.
    100000 rows processed.
    Elapsed time = 38.47 sec.
    Completed successfully.
    
    C:\path\to\AdpMysql>
  5. 一方、MTU の Query.bat も同時に完了し引き続き次のような表示が現れます。
    ***** 前方省略 *****
    複数の接続を確立します。要求された並列度は 4 です。
    空領域サイズチェックの閾値は 1024Mバイトです。
    データファイルと制御ファイルを出力中です。[58G] C:\ProgramData\PLUMSIX\mtu_4.2\x86\output
    ストリームの位置:named_pipe://\\.\pipe\{C}.{X}
    TableName                     :      NumRows:  Elapse:Rows/s:Bytes:  B/s:   Len
    DB_MIG_TEST                   :      100,000:   43.18: 2315.: 199M:4739k: 2095. CAN
    処理対象となった表の総数      :            1
    ラウンドトリップ(回)        :       50,075
    出力バイト総数(kbytes)      :    204645.72
    所要時間(秒)                :        43.59
    処理速度(kbytes/秒)         :      4694.57
    正常終了しました。
    
    C:\ProgramData\PLUMSIX\mtu_4.2\x86>
  6. MySQLが正しくデータを受け取れたかどうか確認してみましょう。mysql コマンドライン・ツールから次のようなSQLを実行してみて下さい。
    select count(*) from DB_MIG_TEST;
    select NUM_10_0 from DB_MIG_TEST
    where (  CLOB_DATA IS NULL 
          or VC2_10 IS NULL 
          or NCLOB_DATA IS NULL 
          or NUM_10_5 IS NULL 
          or DATE_VAL IS NULL 
          or BLOB_DATA IS NULL 
          or LONG_STR IS NULL 
          or CHAR_10 IS NULL 
    )
    order by NUM_10_0 ;
  7. 1つ目のSQLは件数を数えるためのもので、2つ目のSQLはNULLが正しく伝達されているかどうかを確認する為のものです。実施例を下記に示します。
    C:\path\to\AdpMysql>mysql -u scott -p scott --compress --port 13306
    Enter password: *****
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 18
    Server version: 5.6.17-log MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> select count(*) from DB_MIG_TEST;
    +----------+
    | count(*) |
    +----------+
    |   100000 |
    +----------+
    1 row in set (0.89 sec)
    
    mysql> select NUM_10_0 from DB_MIG_TEST
        -> where (  CLOB_DATA IS NULL
        ->       or VC2_10 IS NULL
        ->       or NCLOB_DATA IS NULL
        ->       or NUM_10_5 IS NULL
        ->       or DATE_VAL IS NULL
        ->       or BLOB_DATA IS NULL
        ->       or LONG_STR IS NULL
        ->       or CHAR_10 IS NULL
        -> )
        -> order by NUM_10_0 ;
    +----------+
    | NUM_10_0 |
    +----------+
    |      892 |
    |    12543 |
    |    24543 |
    |    33975 |
    |    45432 |
    |    54910 |
    |    67543 |
    |    78853 |
    +----------+
    8 rows in set (1.19 sec)
    
    mysql>

    問題なくデータは移行されました。

トラブル・シューティング

まとめ

by 開発1号

強化版!MySQLへのデータ移行術(1/2)へ戻る