📌

Embulk v0.9.24+MySQL 8.0.29のローカル環境構築

2022/06/18に公開

概要

embulkでcsv->MySQLのimportを試したかったのでdocker-composeで簡単に動かせる環境を作りました。

サンプル

https://github.com/kishii4726/local-embulk

サンプルデータ投入までの流れ

$ git clone https://github.com/kishii4726/local-embulk.git
$ cd local-embulk

## .env.sampleをベースに.envを作成する
## DB_DATABASEとDB_PASSWORDの値を任意の値に書き換える
$ cp .env.sample .env
$ vi .env
$ cat .env
MYSQL_DATABASE=embulk
MYSQL_PASSWORD=passw0rd

# 起動
$ docker-compose up -d                                                              
Starting embulk       ... done
Starting embulk-mysql ... done

# コンテナに入る
$ docker exec -it embulk /bin/bash
# データ投入
root@xxxxxxxx:/embulk# embulk run config.yml.liquid
・
・
・
2022-06-18 13:12:40.114 +0900 [INFO] (0001:transaction): TransactionIsolation=repeatable_read
2022-06-18 13:12:40.115 +0900 [INFO] (0001:transaction): SQL: DROP TABLE IF EXISTS `sample_table_0000018175034ddf_embulk`
2022-06-18 13:12:40.118 +0900 [INFO] (0001:transaction): > 0.00 seconds
2022-06-18 13:12:40.119 +0900 [INFO] (main): Committed.
2022-06-18 13:12:40.120 +0900 [INFO] (main): Next config diff: {"in":{"last_path":"./csv/sample.csv"},"out":{}}

# 一度ローカルに戻る
root@xxxxxxxx:/embulk# exit

# mysqlコンテナに入る
$ docker exec -it embulk-mysql bash
root@bae03bcc5a2c:/# mysql -u embulk -p$MYSQL_PASSWORD
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 8.0.29 MySQL Community Server - GPL

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

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 * from embulk.sample_table;
+------+-------+
| id   | name  |
+------+-------+
|    1 | test  |
|    2 | test2 |
|    3 | test3 |
+------+-------+
3 rows in set (0.01 sec)

MySQL8の認証プラグインについて

MySQL8.04からデフォルトの認証プラグインがmysql_native_passwordからcaching_sha2_passwordに変更されています。
そのためデフォルトの設定で作成されたユーザを使用してembulk runを実行するとエラーになります。

root@01e102d492c8:/embulk# embulk run config.yml.liquid
2022-06-18 13:47:54.663 +0900: Embulk v0.9.24
2022-06-18 13:47:55.417 +0900 [WARN] (main): DEPRECATION: JRuby org.jruby.embed.ScriptingContainer is directly injected.
2022-06-18 13:47:57.684 +0900 [INFO] (main): Gem's home and path are set by default: "/root/.embulk/lib/gems"
2022-06-18 13:47:59.665 +0900 [INFO] (main): Started Embulk v0.9.24
2022-06-18 13:47:59.760 +0900 [INFO] (0001:transaction): Loaded plugin embulk-output-mysql (0.10.2)
2022-06-18 13:47:59.813 +0900 [INFO] (0001:transaction): Listing local files at directory './csv' filtering filename by prefix 'sample.csv'
2022-06-18 13:47:59.814 +0900 [INFO] (0001:transaction): "follow_symlinks" is set false. Note that symbolic links to directories are skipped.
2022-06-18 13:47:59.815 +0900 [INFO] (0001:transaction): Loading files [./csv/sample.csv]
2022-06-18 13:47:59.851 +0900 [INFO] (0001:transaction): Using local thread executor with max_threads=12 / output tasks 6 = input tasks 1 * 6
2022-06-18 13:47:59.877 +0900 [WARN] (0001:transaction): "UTC" is recognized as "Z" to be compatible with the legacy style.
2022-06-18 13:47:59.888 +0900 [INFO] (0001:transaction): JDBC Driver = /root/.embulk/lib/gems/gems/embulk-output-mysql-0.10.2-java/default_jdbc_driver/mysql-connector-java-5.1.44.jar
2022-06-18 13:47:59.896 +0900 [INFO] (0001:transaction): Connecting to jdbc:mysql://embulk-mysql:3306/embulk options {user=root, password=***, tcpKeepAlive=true, useSSL=false, useCompression=true, rewriteBatchedStatements=true, connectTimeout=300000, socketTimeout=1800000}
2022-06-18 13:48:00.075 +0900 [ERROR] (0001:transaction): Operation failed (0:null)
org.embulk.exec.PartialExecutionException: java.lang.RuntimeException: java.sql.SQLException: Unable to load authentication plugin 'caching_sha2_password'.

対策として以下のようなクエリでユーザの認証プラグインを変更することも可能ですが面倒なので

alter table <user> identified with auth_plugin by mysql_native_password <password>;

今回はmysqlの設定ファイルでデフォルトの認証プラグインを指定することで対応しました。

mysql.cnf
[mysqld]
default-authentication-plugin = mysql_native_password

その他

embulk runするまでに必要なものは起動時に作成されるようにしました。

docker-compose.yml
version: "3"
services:

  mysql:
    container_name: embulk-mysql
    # rate limitが気にしてECRのパブリックイメージを使います
    image: public.ecr.aws/docker/library/mysql:8.0.29
    volumes:
      - type: volume
        source: db-data
        target: /var/lib/mysql
      - type: bind
        source: ./mysql/mysql.cnf
        target: /etc/mysql/conf.d/mysql.cnf
      # ローカルの./mysql/initdb.dにテーブル作成用のSQLを置いてあります
      # 起動時にdocker-entrypoint-initdb.d以下のSQLが実行されてテーブルが作られます
      - type: bind
        source: ./mysql/initdb.d
        target: /docker-entrypoint-initdb.d
    ports:
      - "13306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
      # MYSQL_DATABASEに指定したDBが起動時に作成されます
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      # MYSQL_USER,MYSQL_PASSWORDで指定したユーザが作成されます
      MYSQL_USER: embulk
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      TZ: Asia/Tokyo
    # mbind: Operation not permittedを防ぐためプロセスのnice値を上げます
    cap_add:
      - SYS_NICE

  embulk:
    container_name: embulk
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    # ローカルをそのままbind mountしているため、config.yml等の変更はそのままコンテナに反映されます
    volumes:
    - type: bind
      source: .
      target: /embulk
    # embulkコンテナが落ちないようにします
    tty: true

volumes:
  db-data:

サンプル以外のcsvからconfig.ymlを作りたい場合は以下の手順で作成できます。

# csvを用意
$ vi csv/sample_2.csv

# configを生成
# embulkコンテナで実行
$ embulk guess seed.yml -o config_2.yml

# 生成されたDBの向き先等をconfig.ymlを参考に書き換える
$ vi config_2.yml

Discussion