Database Connector のトラブルシューティング - Mule 4

データベース用 Anypoint Connector (Database Connector) をトラブルシューティングするために、冗長ログの有効化、プーリングプロファイル接続のトラブルシューティング、Snowflake JDBC ドライバーのトラブルシューティング、スローされる一般的なメッセージの解釈に関する情報について説明します。

Database Connector は、JDBC ライブラリ (Java SE JDK 1.8 を使用) に記載されている標準およびガイドラインに従います。

冗長ログの有効化

アプリケーションとデータベースのやりとりが失敗する理由の理解を深めるには、Database Connector の冗長ログを一時的に有効にします。
手動で ​log4j2.xml​ ファイルを変更するか、CloudHub API を使用している場合は Anypoint Runtime Manager を使用して、冗長ログを有効にします。
Mule アプリケーションのパフォーマンスに影響するため、トラブルシューティングが完了したら、必ず拡張された冗長性を無効にしてください。

設定ファイルで冗長ログを有効にする手順は、次のとおりです。

  1. Anypoint Studio にアクセスし、​[Package Explorer]​ ビューに移動します。

  2. アプリケーションのプロジェクト名を開きます。

  3. src/main/resources​ パスフォルダーを開きます。

  4. フォルダー内の ​log4j2.xml​ ファイルを開きます。

  5. <Loggers>​ タグ内に ​<AsyncLogger>​ タグを追加します。

    			<Loggers>
    				...
    				<AsyncLogger name="org.mule.extension.db" level="DEBUG"/>
    				<AsyncLogger name="org.mule.db.commons" level="DEBUG"/>
    				...
    			</Loggers>
    xml
  6. アプリケーションの変更を保存します。

  7. Package Explorer​ でプロジェクト名をクリックし、​[Run (実行)]​ > ​[Run As (別のユーザーとして実行)]​ > ​[Mule Application (Mule アプリケーション)]​ をクリックします。

Anypoint Runtime Manager で冗長ログを有効にする手順は、次のとおりです。

  1. Anypoint Runtime Manager にアクセスします。

  2. [API configuration (API 設定)] に移動します。

  3. [Logging (ログ)]​ サブタブで、DEBUG レベルで ​org.mule.extension.db​ および ​org.mule.db.commons​ パッケージを追加します。

  4. 変更を適用します。

プーリングプロファイル接続によるフローのハングのトラブルシューティング

フローで必要とされる接続数よりも少ない接続を提供するプーリングプロファイルを使用すると、フロー全体がハングする可能性があります。

この問題を解決する手順は、次のとおりです。

解決策の 1 つとして、プールのサイズを増やすことが挙げられます。この方法が使用できない場合、仮想マシン用 Anypoint Connector (VM Connector) を使用して、VM メッセージの有効期間に一致するように接続の有効期間を短くします。こうすることで、​Stored procedure​ 操作へのすべてのコールが実行されて、その結果がコンシュームされ、操作に関連付けられている接続が終了してプールに戻ります。

次の例は、​Stored procedure​ 操作と VM Connector でプーリングプロファイルを使用する方法を示しています。この例では、​foreach​ 要素が 11 番目の反復に到達しても、プールで接続を提供できるため、​Stored procedure​ 操作はハングしません。

	<db:config name="Database_Config">
		<db:generic-connection url="someUrl" user="someUser" password="somePassword" driverClassName="someDriver">
			<db:pooling-profile maxPoolSize="10">
			</db:pooling-profile>
		</db:generic-connection>
	</db:config>

	<vm:config name="VM_Config">
		<vm:queues >
			<vm:queue queueName="testQueue" />
		</vm:queues>
	</vm:config>

	<flow name="processingFlow">
		<foreach collection="#[1 to 11]">
			<logger level="INFO" message="#['Starting Iteration ' ++ payload as String]" />
			<vm:publish config-ref="VM_Config" queueName="testQueue"/>
			<logger level="INFO" message="#['Finishing Iteration ' ++ payload as String]"/>
		</foreach>
	</flow>

	<flow name="coolFlow">
		<vm:listener config-ref="VM_Config" queueName="testQueue" numberOfConsumers="1"/>
		<db:stored-procedure config-ref="Database_Config">
				<db:sql><![CDATA[{call testProc2()}]]></db:sql>
			</db:stored-procedure>
		<logger level="INFO" message="#[output application/json --- payload.resultSet1]" />
	</flow>
xml

Select 操作と Stored Procedure 操作の警告例外について

Database Connector の ​Select​ および ​Stored procedure​ 操作が適切に実行され、結果が返されない場合、Mule Runtime Engine (Mule) では、例外がスローされるのではなく ​WARN​ 例外メッセージが返されます。

Select​ 操作では、この動作は無効な SQL ステートメントが実行された場合に発生します。​Store procedure​ 操作では、プロシージャーを崩す可能性があるエラーが一連のステートメント内にある場合に発生します。実際には、JDBC で一連の ​ResultSets​、​UpdateCounts​、および ​Exceptions​ が返されます。

根本原因がドライバーの動作にあるため、Mule ではフローでキャッチされる例外はスローされません。一部のドライバーは JDBC に厳格に準拠して実行時にスローを適切にスローしますが、そうでないドライバーもあります。このため、例外をスローする動作をコネクタのコードに追加すると、例外を想定していない Mule アプリケーションの後方互換性が失われることになります。

Select​ 操作の場合、サブクエリで複数の値が返され、その結果が絞り込みや式として使用される場合、Mule で ​WARN​ 例外が記録されます。Mule は、操作が実行されたときではなく、操作の結果がページ分割されるとすぐに警告を返します。

たとえば、次の SQL ステートメントがあるとします。

		<db:select doc:name="Select" config-ref="Database_Config">
			<db:sql ><![CDATA[
						SELECT *
						FROM SomeTable
						WHERE SomeColumn = (SELECT DISTINCT SomeColumn2 from SomeTable2)
					 ]]>
			</db:sql>
		</db:select>
xml

Mule で次の ​WARN​ 例外が記録されます。

	WARN  2021-06-01 10:04:33,323 [[MuleRuntime].io.10: [some-mule-app].some-mule-app.BLOCKING @...] [event: ...] org.mule.extension.db.internal.result.resultset.ResultSetIterator: Unable to determine if there are more records
	com.microsoft.sqlserver.jdbc.SQLServerException: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
xml

Stored procedure​ 操作の場合、ストアドプロシージャーに複数のステートメントが含まれ、その 1 つ以上が失敗すると、Mule で ​WARN​ 例外が記録されます。Mule は、操作が実行されたときではなく、操作の結果がコンシュームされるとすぐに警告を返します。たとえば、次の SQL ストアドプロシージャーがあるとします。

CREATE PROCEDURE dbo.SomeProcedure
AS
BEGIN
	BEGIN TRY
	select 1/0;
	END TRY
	BEGIN CATCH
	THROW 50000, 'Divide by zero error encountered.', 255;
	END CATCH
END
xml

Mule で次の ​WARN​ 例外が記録されます。

	WARN  2021-06-02 09:38:14,624 [[MuleRuntime].io.10: [some-mule-app].some-mule-app.BLOCKING @...] [event: ...] org.mule.extension.db.internal.result.statement.StatementResultIterator: Unable to determine if there are more statement results
	com.microsoft.sqlserver.jdbc.SQLServerException: 'The record does not exist.'
xml

ストアドプロシージャーの例外をスローする Snowflake JDBC ドライバーのトラブルシューティング

一部のドライバーには、ストアドプロシージャーをコールするときの独自の仕様があります。中括弧 (​{​ および ​}​) を使用してコール可能なステートメントを設定している場合 (例: {call doubleMyInt(:myInt)}​)、アプリケーションを実行すると Snowflake JDBC ドライバーで次の例外がスローされます。

net.snowflake.client.jdbc.SnowflakeSQLException: Unsupported feature 'call'

この問題を解決する手順は、次のとおりです。

Snowflake JDBC ドライバーでは、中括弧 ​{​ および ​}​ を使用せずにコール可能なステートメントを設定します。例:

call doubleMyInt(:myInt)

デプロイ時における静的 IP を使用する CloudHub の失敗のトラブルシューティング

静的 IP を使用する CloudHub アプリケーションをデプロイすると、データベーステスト接続エラーがスローされ、プロセスが失敗します。これは、静的 IP が割り当てられる前にテストが実行されているために発生します。

次のスタックトレースにテスト接続エラー ​Could not obtain connection from data source​ が示されています。

[2021-03-05 00:26:11.262] INFO    org.mule.runtime.module.extension.internal.runtime.config.LifecycleAwareConfigurationInstance [[MuleRuntime].uber.02: [iagsatellite-snowflake-sys-api-v1-dev].uber@org.mule.runtime.module.extension.internal.runtime.config.LifecycleAwareConfigurationInstance.testConnectivity:179 @10f9d7dc]: Connectivity test failed for config 'Database_Config'. Application deployment will continue. Error was: Could not obtain connection from data source
org.mule.runtime.api.connection.ConnectionException: Could not obtain connection from data source
xml

この問題を解決する手順は、次のとおりです。

次のシステムプロパティをデプロイメントに設定します: -DdoTestConnectivity=false

システムプロパティを使用した Oracle の XML 拡張機能のトラブルシューティング

Oracle XML 拡張機能を使用するには、Oracle jar ファイルを連動関係として追加する必要があります。これらの jar ファイルの 1 つに ​xmlparserv2.jar​ があります。このファイルは、Java SPI (サービスプロバイダーインターフェース) 経由で XML パーサー機能をエクスポートします。Mule の内部でこのパーサーを使用していると、Mule コンポーネントの想定と一致しなくなるため、次のような XML 解析エラーとなる場合があります。

	<Line 43, Column 57>: XML-24509: (Error) Duplicated definition for: 'identifiedType' <Line 60, Column 28>: XML-24509: (Error) Duplicated definition for: 'beans' <Line 140, Column 34>: XML-24509: (Error) Duplicated definition for: 'description'
xml

この問題には、次のいずれかの方法で対処できます。

  • xmlparserv2.jar​ ファイルを Database Connector の追加のプラグイン連動関係として追加し、連動関係がコネクタ内でのみ表示されるようにします。
    ただし、データソースを Spring で設定された Bean として提供するために Oracle 接続をモジュール間で共有する必要がある場合には、この方法は使用できません。

  • Mule の内部コンポーネントが常に想定する XML パーサーを取得するように、次のシステムプロパティを設定して XML パーサー SPI ルックアップを無効にします。

システムプロパティ:
-Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
-Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
xml

これらのプロパティにより、Oracle .jar ファイルを共有ライブラリとしてセットアップする場合などには問題を回避できます。

システムプロパティの設定方法についての詳細は、​『システムプロパティ』​のドキュメントを参照してください。

一般的なスローの理解

スローされる一般的なメッセージのリストとその解釈方法を次に示します。

  • DB:BAD_SQL_SYNTAX

    指定された SQL クエリの構文が無効です。
  • DB:CANNOT_LOAD_DRIVER

    Database Connector で JDBC ドライバーを読み込むことができません。
  • DB:CANNOT_REACH

    Database Connector で RDBMS との接続を確立できません。
  • DB:CONNECTIVITY

    いくつかの考えられる接続の問題 (不適切な接続の設定、行のフェッチ結果を待機しているときのデータベース応答の欠落、データベース接続の切断など)。
  • DB:INVALID_DATABASE

    RDBMS への接続は確立されましたが、データベースが存在していません。
  • DB:INVALID_CREDENTIALS

    データベースで指定されたログイン情報が拒否されました。
  • DB:QUERY_EXECUTION

    クエリの実行に失敗しました。
  • DB:RETRY_EXHAUSTED

    すべての再接続の試行に失敗しました。