QA@IT

Embulkを使って、OracleDBをBigqueryへバルクインサート

757 PV

Embulkを使って、OracleDBのデータをBigQueryへバルクインサートするように実装したいです。

OracleDBの特定のテーブルにinsert処理をしてcommitされたら、embulkが動くようにトリガーを作成しました。

しかし、検証中にinsert処理をしcommitしても、embulkは動作せず、エラーも出力せず、どのように対処すればよいか困っています。

動作環境:Windows7、OracleDB 12c、Embulk 0.9.8

※embulk定義

C:\Users\yazaki\Desktop\embulk>type seed_bq.yml
in:
  type: oracle
  driver_path: C:\Users\yazaki\Desktop\embulkDB\product\12.2.0\dbhome_1\sqldeveloper\jdbc\lib\ojdbc7.jar
  host: xxxx
  user: xxxx
  password: xxx
  database: xxx
  table: INPUT_TEST
out:
  type: bigquery
  auth_method: json_key
  json_keyfile: C:\Users\yazaki\Desktop\embulk\My First Project-xxxxxxxx.json
  project: xxxx
  dataset: xxxx
  auto_create_table: true
  table: users

※検証用のテーブル定義

SQL> desc INPUT_TEST
 名前                                      NULL?    型
 ----------------------------------------- -------- ----------------------
 ID                                        NOT NULL NUMBER(8)
 NUM                                                NUMBER(12,2)
 STR                                                CHAR(8)
 VARSTR                                             VARCHAR2(8)
 DT                                                 DATE
 TIME0                                              TIMESTAMP(0)
 TIME6                                              TIMESTAMP(6)
 TIME9                                              TIMESTAMP(9)

SQL>

※作成したトリガー

create or replace trigger embulk_tr

after insert on INPUT_TEST for each row

DECLARE pragma autonomous_transaction;

begin
IF INSERTING THEN

dbms_output.put_line('-------------------------');
dbms_output.put_line('OracleDB to BigQuery Bulk Insert Start');

DBMS_SCHEDULER.CREATE_JOB (
JOB_NAME   => 'EmbulkTest',
JOB_TYPE   => 'EXECUTABLE',
JOB_ACTION => 'C:\WINDOWS\system32\cmd.exe /c C:\Users\yazaki\Desktop\embulk\oracle_to_bigquery.bat',
start_date => TO_DATE('2018/11/13 00:00:00','yyyy/mm/dd hh24:mi:ss'),
end_date   => TO_DATE('2999/12/31 00:00:00','yyyy/mm/dd hh24:mi:ss'),
repeat_interval => 'FREQ=SECONDLY;interval=1',
auto_drop => TRUE,
enabled    => TRUE
);


dbms_output.put_line('OracleDB to BigQuery Bulk Insert End');
dbms_output.put_line('-------------------------');

END IF;
end;
/

※実行結果

SQL> select owner,job_name,state from dba_scheduler_jobs where job_name = 'EMBULKTEST';

OWNER                          JOB_NAME                       STATE
------------------------------ ------------------------------ ------------------------------
SYSTEM                         EMBULKTEST                     SCHEDULED

SQL>
SQL> select trigger_name,status,triggering_event,action_type,TRIGGER_BODY from dba_triggers where trigger_name = 'EMBULK_TR';

TRIGGER_NAME    STATUS          TRIGGERING_EVEN ACTION_TYPE     TRIGGER_BODY
--------------- --------------- --------------- --------------- --------------------------------------------------
EMBULK_TR       ENABLED         INSERT          PL/SQL          DECLARE pragma autonomous_transaction;

                                                                begin
                                                                IF INSERTING THEN

                                                                dbms_output.put


SQL> insert into INPUT_TEST (ID,NUM,STR) values ('312', '2849', 'chr1');

1行が作成されました。

SQL>
SQL> commit;

コミットが完了しました。

SQL>
SQL>  select owner,job_name,state from dba_scheduler_jobs where job_name = 'EmbulkTest';

レコードが選択されませんでした。

※insertを2回目実行するとエラー

SQL> insert into INPUT_TEST (ID,NUM,STR) values ('333', '2849', 'chr1');
insert into INPUT_TEST (ID,NUM,STR) values ('333', '2849', 'chr1')
            *
行1でエラーが発生しました。:
ORA-27477: "SYSTEM"."EMBULKTEST"はすでに存在します
ORA-06512: "SYS.DBMS_ISCHED", 行175
ORA-06512: "SYS.DBMS_SCHEDULER", 行288
ORA-06512: "SYSTEM.EMBULK_TR", 行9
ORA-04088: トリガー'SYSTEM.EMBULK_TR'の実行中にエラーが発生しました

回答

(さっき投稿したつもりで投稿できていなかったっぽいので再掲します。)
(やっぱりちゃんと掲載されており、同じ内容なので削除しました)

編集 履歴 (1)

こんにちは、Oracleは全くわかりませんが以下でなにかエラーがでたりするのではないでしょうか?
batファイルの中身が記載されていないので想像ですが構文が間違えているとかありますか?
ログをファイルに出力するとうして確認するのがよいように思います。

C:\WINDOWS\system32\cmd.exe /c C:\Users\yazaki\Desktop\embulk\oracle_to_bigquery.bat

余談ですが知人のコメントです。

Oracleのtriggerでレコードが挿入されたらEmbulk起動して逐次BQにexportしようとしてますが、insert文の数だけEmbulk起動しちゃうしBQのQuota Policyに引っ掛かるかもだし筋のいい設計ではないかなあ。他のRDBMSだとFluentd使うべきケースでしょうね

編集 履歴 (0)
  • ご回答有難うございます。参考にさせて頂きます。 -
  • 業務ロジック的にトリガーを使いたく、引き続き検証しています。
    スケジュールジョブの作成方法を変更して実行すると、アラートログにエラーが出力されていました。
    -

※ジョブ作成時に引数を与えてリトライ

create or replace trigger embulk_tr

after insert on INPUT_TEST for each row

DECLARE pragma autonomous_transaction;

begin

dbms_output.put_line('-------------------------');
dbms_output.put_line('OracleDB to BigQuery Bulk Insert Start');

        IF INSERTING THEN
                DBMS_SCHEDULER.CREATE_JOB (
                JOB_NAME   => 'Embulk_Test',
                JOB_TYPE   => 'EXECUTABLE',
                JOB_ACTION => 'C:\WINDOWS\system32\cmd.exe',
                number_of_arguments => 3,
                start_date => TO_DATE('2018/11/13 00:00:00','yyyy/mm/dd hh24:mi:ss'),
                end_date   => TO_DATE('2999/12/31 00:00:00','yyyy/mm/dd hh24:mi:ss'),
                repeat_interval => 'FREQ=SECONDLY;interval=1',
                auto_drop => FALSE
                );

                DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('Embulk_Test',1, '/q');
                DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('Embulk_Test',2, '/c');
                DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('Embulk_Test',3, 'C:\Users\yazaki\Desktop\embulk\test.bat');
                DBMS_SCHEDULER.ENABLE('Embulk_Test');
        END IF;

dbms_output.put_line('OracleDB to BigQuery Bulk Insert End');
dbms_output.put_line('-------------------------');

end;
/

トリガーが作成されました。

※アラートログ

2018-11-15T10:59:32.125731+09:00
Errors in file C:\USERS\YAZAKI\DESKTOP\EMBULKDB\diag\rdbms\orcl\orcl\trace\orcl_j001_4908.trc:
ORA-12012: ジョブ"SYSTEM"."EMBULK_TEST"の自動実行エラーが発生しました
ORA-27369: タイプEXECUTABLEのジョブが、次の終了コードで失敗しました: 1  A N Z X     ?  ?     B
編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。