8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MySQLクライアントからRDSへ大量データをインポートしようとしたら処理が途中で終了した

Posted at

はじめに

MySQLクライアントからRDSへ大量データをインポートしようとしたところ異常終了しました。この記事はその時の対応メモです。

注意

この記事では、RDSのサーバーシステム変数の調整を行なっています。サーバーシステム変数はRDSの挙動に大きな影響を与えるので、それぞれの環境において、その影響を検討の上、適用するようにしてください。

状況

  • MySQLクライアントから大量データをインポートしていたら処理が途中で終了した
  • データは途中までしか入っていなかった
  • クライアントには何のエラー表示もされずにスッと終わっていた
  • データベースサーバーのログを探すと次のようなエラーが見つかった
エラーメッセージ
Aborted connection XXXXX to db: 'データベース名' user: 'ユーザー名' host: 'IPアドレス'
 (Got an error reading communication packets). (sql_connect.cc:828)
インポート処理
mysql -h ホスト名 -u ユーザー名 --password=パスワード データベース名 < インポート.sql

インポートしようとしたSQLファイルのサイズは数GB
エラー発生後、再度インポート処理すると問題なく終了することがあったりして、必ず再現するわけではなかった。

環境

AWS RDS

データ検証のために用意したRDS
エンジンバージョン:8.0.mysql_aurora.3.05.2

MySQLクライアント

AWS EC2上のシェルで実行

mysql --version
mysql Ver 15.1 Distrib 10.5.23-MariaDB, for Linux (x86_64) using EditLine wrapper

【補足】公式ページでAurora MySQLへの接続にMariaDBクライアントが指定されている。

対応

1. RDSのサーバーシステム変数の変更

初期値 変更値
connect_timeout 10 600
net_read_timeout 30 600
net_write_timeout 60 600
max_allowed_packet 67108864(64MB) 1073741824(1GB)

AWS RDSはパラメータグループによってシステム変数を指定することができる。

パラメータグループを直接変更するのではなく、

  • パラメータグループの複製
  • 値の変更
  • RDSへ適用

といったステップを踏んだ。

2. インポート処理時のオプション変更

「max_allowed_packet」の指定はサーバーだけでなくクライアント側にも必要

インポート処理
mysql -h ホスト名 -u ユーザー名 --password=パスワード --max_allowed_packet=1G データベース名 < インポート.sql

これらの対応を行うことでエラーなくインポートできるようになった。

原因

エラーメッセージを元に検索してみると次の記事が見つかった。

記事では次の要因が挙げられていた。

  1. クライアントまたはドライバーの非互換性
  2. アイドル状態の接続を閉じたり、接続をブロックしたりできるファイアウォールまたはプロキシ
  3. クライアント/サーバー接続が不適切に閉じられると、RDS for MySQL 内のスリープ接続の数が増えます
  4. 接続を不適切に終了するクライアントアプリケーション。接続が一定時間アイドル状態になると、MySQL はこれらの接続を強制的に閉じます。次に、「接続が中止されました」というメッセージが表示されます
  5. wait\ _timeout または interactive_timeout のしきい値を超えるアイドル接続
  6. 接続パケットの取得時に connect_timeout 秒のしきい値を超えるクライアント接続
  7. net_write_timeout や net_read_timeout などのパラメータの不十分な値
  8. max_allowed_packet パラメータ値を超過している。値が小さすぎる場合、またはクエリがRDS for MySQL に割り当てられているメモリよりも多くのメモリを必要とする場合、接続の中断警告がトリガーされます

今回の状況では、途中までインポートが進んでいることから1〜4は考え難く
可能性がないわけではないが、他の項目に比べて優先度は低いと判断した。

5〜8について確認した。

サーバーシステム変数の確認

mysqlクライアントから以下を実行

サーバーシステム変数の確認
show variables 
where false
or variable_name = 'connect_timeout'
or variable_name = 'wait_timeout'
or variable_name = 'interactive_timeout'
or variable_name = 'net_read_timeout'
or variable_name = 'net_write_timeout' 
or variable_name = 'max_allowed_packet'
設定されていた値
connect_timeout 10
wait_timeout 28800
interactive_timeout 28800
net_read_timeout 30
net_write_timeout 60
max_allowed_packet 134217728(128MB)

max_allowed_packetだけ64MBの初期値から128MBに変更している状況だった。

wait_timeoutとinteractive_timeoutに指定されている時間を超えてエラー発生している状況ではなかったので、connect_timeout、net_read_timeout、net_write_timeout、max_allowed_packet に絞って設定値を増やすことにした。

MySQLサーバーシステム変数のリファレンス

余談

データ検証を行うためにエクスポート、インポート、スナップショットの保管・復元を何度も行なっている時に、冒頭で書いたエラーに遭遇しました。とりあえず処理をやり直すことでエラーが解消したのですが、そこでエラーが再発せずに解消したことによって根本解決に取り組むのが遅れました。

その後、エラーの頻度が増えたため、ようやく調査を始めました。再現性の乏しいエラーはいつ対応すべきか判断が難しいですが、サクッと調査・解決できるようになりたいなと思いました。

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?