MySQL JDBC Catalog
Doris JDBC Catalog は、標準の JDBC インターフェースを介した MySQL データベースへの接続をサポートします。このドキュメントでは、MySQL データベースへの接続方法を説明します。
JDBC Catalog の概要については、JDBC Catalog の概要を参照してください。
使用上の注意
MySQL データベースに接続するには、以下が必要です。
-
MySQL 5.7、8.0、またはそれ以降のバージョン。
-
MySQL 用の JDBC ドライバー。Maven Repositoryからダウンロードできます。MySQL Connector/J バージョン 8.0.31 以降の使用を推奨します。
-
各 Doris FE ノードおよび BE ノードと MySQL サーバーの間のネットワーク接続。デフォルトのポートは 3306 です。
MySQL への接続
CREATE CATALOG mysql_catalog PROPERTIES (
'type' = 'jdbc',
'user' = 'username',
'password' = 'pwd',
'jdbc_url' = 'jdbc:mysql://host:3306',
'driver_url' = 'mysql-connector-j-8.3.0.jar',
'driver_class' = 'com.mysql.cj.jdbc.Driver'
);
jdbc_url には、MySQL JDBC ドライバーに渡す接続情報とパラメーターを指定します。サポートされる URL パラメーターについては、MySQL Developer Guideを参照してください。
接続のセキュリティ
データソースにグローバルに信頼された証明書を使用する TLS が設定されている場合、jdbc_url プロパティの JDBC 接続文字列にパラメーターを追加すると、クラスターとデータソースの間で TLS を有効にできます。
たとえば、MySQL Connector/J 8.0 では、sslMode パラメーターを使用して TLS で接続を保護します。このパラメーターのデフォルト値は PREFERRED で、サーバー側で TLS が有効な場合に接続を保護できます。REQUIRED に設定すると、TLS 接続が確立されなかった場合に接続が失敗します。
jdbc_url に sslMode パラメーターを追加して設定できます。
'jdbc_url' = 'jdbc:mysql://host:3306/?sslMode=REQUIRED'
TLS の設定オプションについて詳しくは、MySQL JDBC セキュリティドキュメントを参照してください。
階層マッピング
MySQL をマッピングする場合、Doris のデータベースは MySQL のデータベースに対応します。Doris のデータベース内のテーブルは、MySQL の対応するデータベース内のテーブルに対応します。対応関係は次のとおりです。
| Doris | MySQL |
|---|---|
| Catalog | MySQL Server |
| Database | Database |
| Table | Table |
カラム型のマッピング
| MySQL の型 | Doris の型 | 備考 |
|---|---|---|
| boolean | tinyint | |
| tinyint | tinyint | |
| smallint | smallint | |
| mediumint | int | |
| int | int | |
| bigint | bigint | |
| unsigned tinyint | smallint | Doris は符号なしデータ型をサポートしていないため、対応する、より大きな Doris のデータ型にマッピングします。 |
| unsigned mediumint | int | 上記と同様です。 |
| unsigned int | bigint | 上記と同様です。 |
| unsigned bigint | largeint | 上記と同様です。 |
| float | float | |
| double | double | |
| decimal(P, S) | decimal(P, S) | |
| unsigned decimal(P, S) | decimal(P + 1, S) / string | Doris がサポートする最大精度を超える場合は、String として扱います。この型を String にマッピングした場合はクエリのみがサポートされ、MySQL への書き込みはできません。 |
| date | date | |
| timestamp(S) | TIMESTAMPTZ(S) | 4.1.5 以降、この型は常に TIMESTAMPTZ(S) にマッピングされます。enable.mapping.timestamp_tz プロパティは互換性のために残されていますが、false に設定しても DATETIME へのマッピングには戻りません。精度の上限は 6 で、それを超える精度は失われます。以前のバージョンでは、このプロパティで従来のマッピングを選択できます。 |
| datetime(S) | datetime(S) | |
| year | smallint | Doris は year 型をサポートしていないため、smallint にマッピングします。 |
| time | string | Doris は time 型をサポートしていないため、string にマッピングします。 |
| char | char | |
| varchar | varchar | |
| json | string | 読み取り性能と計算性能のバランスを取るため、Doris は json 型を string 型にマッピングします。 |
| set | string | |
| enum | string | |
| bit | boolean / string | Doris は bit 型をサポートしていないため、bit(1) は boolean に、それ以外は string にマッピングします。 |
| tinytext, text, mediumtext, longtext | string | |
| blob, mediumblob, longblob, tinyblob, binary, varbinary | VARBINARY | 4.1.5 以降、この型は常に VARBINARY にマッピングされます。enable.mapping.varbinary プロパティは互換性のために残されていますが、false に設定しても STRING へのマッピングには戻りません。以前のバージョンでは、このプロパティで従来のマッピングを選択できます。 |
| other | UNSUPPORTED |
付録
タイムゾーンに関する問題
JDBC Catalog を介してデータにアクセスする場合、BE の JNI 部分は JVM のタイムゾーンを使用します。JVM のタイムゾーンはデフォルトで BE のデプロイ先マシンのタイムゾーンになり、JDBC によるデータ読み取り時のタイムゾーン変換に影響します。タイムゾーンを一致させるため、be.conf の JAVA_OPTS で JVM のタイムゾーンを Doris のセッション変数 time_zone と同じ値に設定することを推奨します。
MySQL の timestamp 型を読み取る場合は、JDBC URL に connectionTimeZone=LOCAL と forceConnectionTimeZoneToSession=true を追加してください。これらのパラメーターは MySQL Connector/J バージョン 8 以降で使用でき、読み取った時刻に MySQL サーバーのタイムゾーンではなく Doris BE の JVM タイムゾーンが適用されます。
よくある問題
接続例外のトラブルシューティング
-
Communications link failure The last packet successfully received from the server was 7 milliseconds ago.
-
原因:
-
ネットワークの問題:
-
ネットワークが不安定、または接続が中断されている。
-
クライアントとサーバーの間のネットワーク遅延が大きい。
-
-
MySQL サーバーの設定
- MySQL サーバーで
wait_timeoutやinteractive_timeoutなどの接続タイムアウトパラメーターが設定され、タイムアウトによって接続が閉じられている可能性があります。
- MySQL サーバーで
-
ファイアウォールの設定
- ファイアウォールのルールがクライアントとサーバーの間の通信を遮断している可能性があります。
-
接続プールの設定
- 接続プールの
connection_pool_max_life_timeの設定によって、接続が閉じられるか再利用される、または適切なタイミングで接続を維持できていない可能性があります。
- 接続プールの
-
サーバーのリソースの問題
- MySQL サーバーに、新しい接続要求を処理するためのリソースが不足している可能性があります。
-
クライアントの設定
autoReconnectパラメーターが未設定、または不適切に設定されているなど、クライアントの JDBC ドライバーの設定に誤りがある可能性があります。
-
-
対処方法
-
ネットワーク接続を確認する:
- クライアントとサーバーの間のネットワーク接続が安定していること、およびネットワーク遅延が大きくないことを確認します。
-
MySQL サーバーの設定を確認する:
- MySQL サーバーの
wait_timeoutとinteractive_timeoutを確認し、適切な値に調整します。
- MySQL サーバーの
-
ファイアウォールの設定を確認する:
- ファイアウォールのルールでクライアントとサーバーの間の通信が許可されていることを確認します。
-
接続プールの設定を調整する:
- 接続プールの
connection_pool_max_life_timeを確認し、MySQL のwait_timeoutとinteractive_timeoutより短く、SQL の最長実行時間より長くなるように調整します。
- 接続プールの
-
サーバーのリソースを監視する:
- MySQL サーバーのリソース使用状況を監視し、接続要求を処理するためのリソースが十分にあることを確認します。
-
クライアントの設定を最適化する:
- 接続が中断された後に自動的に再接続できるよう、
autoReconnect=trueなど、JDBC ドライバーの設定パラメーターが正しいことを確認します。
- 接続が中断された後に自動的に再接続できるよう、
-
-
-
java.io.EOFException MESSAGE: Can not read response from server. Expected to read 819 bytes, read 686 bytes before connection was unexpectedly lost.
-
原因: MySQL によって接続が切断されたか、MySQL がクラッシュしました。
-
対処方法: MySQL に接続を能動的に切断する仕組みがあるか、または大規模なクエリによって MySQL がクラッシュしたかを確認します。
-
その他の問題
-
MySQL の絵文字を読み書きすると文字化けする
Doris から MySQL にクエリを実行する際、MySQL のデフォルトの utf8 エンコーディングは utf8mb3 であり、4 バイトのエンコーディングが必要な絵文字を表現できません。4 バイトのエンコーディングに対応するには、MySQL のエンコーディングを utf8mb4 に変更してください。
設定項目をグローバルに変更できます。
Modify the my.ini file in the mysql directory (for Linux systems, it is the my.cnf file in the etc directory)
[client]
default-character-set=utf8mb4
[mysql]
Set mysql default character set
default-character-set=utf8mb4
[mysqld]
Set mysql character set server
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4
Modify the type of the corresponding table and column
ALTER TABLE table_name MODIFY colum_name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name CHARSET=utf8mb4;
SET NAMES utf8mb4 -
MySQL の DATE/DATETIME 型を読み取る際に例外が発生する
ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.6)[INTERNAL_ERROR]UdfRuntimeException: get next block failed:
CAUSED BY: SQLException: Zero date value prohibited
CAUSED BY: DataReadException: Zero date value prohibitedJDBC では、不正な DATE/DATETIME 値に対してデフォルトで例外をスローします。この動作は URL パラメーター
zeroDateTimeBehaviorで制御できます。指定できる値はexception、convertToNull、roundで、それぞれ例外を発生させる、NULL値に変換する、"0001-01-01 00:00:00"に変換することを意味します。Catalog の作成時に、
jdbc_urlの末尾にある JDBC 接続文字列へzeroDateTimeBehavior=convertToNullを追加してください。たとえば、"jdbc_url" = "jdbc:mysql://127.0.0.1:3306/test?zeroDateTimeBehavior=convertToNull"と指定します。この場合、JDBC は 0000-00-00 または 0000-00-00 00:00:00 を null に変換します。その後、Doris は現在の Catalog のすべての Date/DateTime 型カラムを null 許容型として扱うため、正常に読み取れます。 -
MySQL Catalog またはほかの JDBC Catalog を読み取る際に、
failed to load driver class com.mysql.cj.jdbc.driver in either of hikariconfig class loaderのようなクラス読み込みエラーが発生する原因は、Catalog の作成時に指定した
driver_classが正しくないことです。上記の例では大文字と小文字が誤っているため、'driver_class' = 'com.mysql.cj.jdbc.Driver'と正しく指定してください。 -
MySQL の読み取り時に通信リンクの例外が発生する
ERROR 1105 (HY000): errCode = 2, detailMessage = PoolInitializationException: Failed to initialize pool: Communications link failure
The last packet successfully received from the server was 7 milliseconds ago. The last packet sent successfully to the server was 4 milliseconds ago.
CAUSED BY: CommunicationsException: Communications link failure
The last packet successfully received from the server was 7 milliseconds ago. The last packet sent successfully to the server was 4 milliseconds ago.
CAUSED BY: SSLHandshakeException
BE の be.out ログを確認し、次の情報が含まれているか調べてください。
WARN: Establishing SSL connection without server's identity verification is not recommended.
According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set.
For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'.
You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
jdbc_url に useSSL=false を追加できます。たとえば、'jdbc_url' = 'jdbc:mysql://127.0.0.1:3306/test?useSSL=false' と指定します。
-
MySQL から大量のデータをクエリする際、成功することもあれば次のエラーが発生することもあり、エラー発生時には MySQL へのすべての接続が切断されて MySQL Server に接続できなくなる場合があります。しばらくすると MySQL は正常に戻りますが、それまでの接続は失われます。
ERROR 1105 (HY000): errCode = 2, detailMessage = [INTERNAL_ERROR]UdfRuntimeException: JDBC executor sql has error:
CAUSED BY: CommunicationsException: Communications link failure
The last packet successfully received from the server was 4,446 milliseconds ago. The last packet sent successfully to the server was 4,446 milliseconds ago.この現象は、MySQL Server のメモリまたは CPU リソースが枯渇し、MySQL サービスが利用できなくなったために発生している可能性があります。MySQL Server のメモリまたは CPU の割り当てを増やしてみてください。
-
MySQL をクエリする際、クエリ結果が MySQL データベース内の結果と一致しない場合
まず、クエリ対象のフィールドで大文字と小文字の区別が関係しているか確認してください。たとえば、テーブルのフィールド
c_1に"aaa"と"AAA"という二件のデータがあるとします。MySQL データベースの初期化時に大文字と小文字を区別するよう指定していなければ、MySQL はデフォルトで区別しません。一方、Doris は厳密に区別するため、次のような違いが生じます。MySQL behavior:
select count(c_1) from table where c_1 = "aaa"; Does not distinguish case, so the result is: 2
Doris behavior:
select count(c_1) from table where c_1 = "aaa"; Strictly distinguishes case, so the result is: 1この現象が発生する場合は、要件に応じて次のように調整してください。
-
MySQL のクエリに "BINARY" キーワードを追加して、大文字と小文字を強制的に区別する:
select count(c_1) from table where BINARY c_1 = "aaa"; -
または、MySQL でテーブルを作成する際に指定する:
CREATE TABLE table (c_1 VARCHAR(255) CHARACTER SET binary); -
または、MySQL データベースの初期化時に、大文字と小文字を区別する照合順序を指定する:
```text
[mysqld]
character-set-server=utf8
collation-server=utf8_bin
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
```
-
-
MySQL のクエリが長時間停止して結果が返らない場合、または長時間停止して fe.warn.log に大量の書き込みロックのログが出力される場合
MySQL に接続を閉じられた後に JDBC クライアントが無期限に待機するのを防ぐため、URL に socketTimeout を追加してみてください。例:
jdbc:mysql://host:port/database?socketTimeout=30000。 -
MySQL Catalog の使用中に、FE の JVM メモリ使用量または Threads 数が増え続けて減らず、同時に Forward to master connection timed out エラーが報告される場合
jstack fe_pid > fe.jsで FE のスレッドスタックを出力してください。mysql-cj-abandoned-connection-cleanupスレッドが大量に見つかる場合は、MySQL JDBC ドライバーに問題があることを示しています。次のように対処してください。
-
MySQL JDBC ドライバーをバージョン 8.0.31 以降にアップグレードする
-
FE と BE の設定ファイルの
JAVA_OPTSに-Dcom.mysql.cj.disableAbandonedConnectionCleanup=trueを追加して、MySQL JDBC ドライバーの接続クリーンアップ機能を無効にし、クラスターを再起動する注: Doris のバージョンが 2.0.13 以降または 2.1.5 以降の場合、Doris ではデフォルトで MySQL JDBC ドライバーの接続クリーンアップ機能がすでに無効になっているため、このパラメーターを追加する必要はありません。MySQL JDBC ドライバーのバージョンを更新するだけで済みます。ただし、以前にリークしたスレッドをクリーンアップするには、Doris クラスターを再起動する必要があります。
-