質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Q&A

解決済

1回答

4000閲覧

node.js でのmysql2 使用中のクエリエラー(Error: read ECONNRESET)

h451

総合スコア8

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

0グッド

0クリップ

投稿2020/03/26 09:18

編集2020/03/26 10:25

node.jsでmysql2を利用してデータベースサーバーからデータを取得しています。
いつも一回目の接続はうまくいくのですが、そこから5分30秒~6分(タイマーで測ったので5分以上もつのは間違いないです。)、時間をあけると下記の箇所で

Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:201:27) {
errno: 'ECONNRESET',
code: 'ECONNRESET',
syscall: 'read',
fatal: true
}

が発生します。
(5分30秒~6分経過するまでは何度クエリ送信しても通信できます。)

mysql(データベースサイド)のタイムアウトかもしれないと思い確認しました。
しかし、wait_timeout はデフォルトの8時間ですし、5分30秒~6分でタイムアウトする項目もありません。
このエラーはmysql側のタイムアウトエラーではないのでしょうか?
ほかの原因としてはどんなことが考えられるでしょうか?
どなたか詳しい方、お教えいただけないでしょうか。
よろしくお願いいたします。

mysqlConnectionjs

1var mysql = require('mysql2'); 2 3const dbConfig = { 4 host: xxxxxxx, 5 user: xxxxxx, 6 password:xxxxxxx, 7 port: xxxxx, 8 database: xxxxxx, 9 waitForConnections: true, 10}; 11 12// const dbConfig = mysql.createConnection(HhtmlConfig); 13 14var connection; 15 16function handleDisconnect() { 17 console.log('create mysql connection'); 18 connection = mysql.createPool(dbConfig); 19 20 //error時の処理 21 connection.on('error', function (err) { 22 console.log('db error', err); 23 if (err.code === 'PROTOCOL_CONNECTION_LOST') { 24 handleDisconnect(); 25 } else { 26 throw err; 27 } 28 }); 29 30 module.exports = connection; //connectionを(他のファイルから)requireで呼び出せるようにする 31} 32 33handleDisconnect();

実際にエラーが発生した箇所

server

1//略 2const connection = require('./mysqlConnection'); 3 4app.post('/getcreatorname', (req, res, err) => { 5 6 var sql = "SELECT user_name FROM users WHERE xxxxxxxxx"; 7 8 connection.query(sql, function (err, results) { 9 if(err){ 10 throw err 11 } 12 res.send(results); 13 }); 14}) 15 16//略

mysql のタイムアウト設定
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| have_statement_timeout | YES |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| rpl_stop_slave_timeout | 31536000 |
| slave_net_timeout | 60 |
| wait_timeout | 28800 |
+-----------------------------+----------+

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

これ再接続した時に死にそうですね。

色々すっ飛ばしますが、
とりあえず下記でやってみてください。

js

1var mysql = require('mysql2'); 2 3const dbConfig = { 4 host: xxxxxxx, 5 user: xxxxxx, 6 password:xxxxxxx, 7 port: xxxxx, 8 database: xxxxxx, 9 waitForConnections: true, 10}; 11 12// const dbConfig = mysql.createConnection(HhtmlConfig); 13 14var connection; 15 16function handleDisconnect() { 17 console.log('create mysql connection'); 18 connection = mysql.createPool(dbConfig); 19 20 //error時の処理 21 connection.on('error', function (err) { 22 console.log('db error', err); 23 if (err.code === 'PROTOCOL_CONNECTION_LOST') { 24 handleDisconnect(); 25 } else { 26 throw err; 27 } 28 }); 29} 30 31handleDisconnect(); 32 33// アロー関数で包む事で、欲しいタイミングで最新のものを受け取れるように修正 34module.exports = () => connection;

使う時はconnectionという形ではなく、
関数実行connection()にしてください。

これでとりあえず再接続耐性は上がるはずです。

投稿2020/03/26 09:49

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

h451

2020/03/26 10:24

回答いただきありがとうございます! 仰る通りに mysql module側 module.exports = () => connection; server側 const connection = require('./mysqlConnection')(); に変更いたしましたが、一回目の接続から6分たってクエリを送信するとやはり同じエラーがでてしまいました...
miyabi-sun

2020/03/26 10:40

> const connection = require('./mysqlConnection')(); これだと遅延評価するよう変更した意味がないので、 今SQLのクエリを送信したいんだ!!という該当行で`connection()`を実行して最新のconnectionを取り出すよう修正してみてください。
h451

2020/03/26 11:16

にわかで申し訳ありません、独学でやっておりまして、基礎的なところが歯抜けになっていますm(_ _)m なるほど、理解しました。 const connection = require('./mysqlConnection')(); では、const connectionはずっと初回に取得したconnectionになるということですね。 それを踏まえて以下のように変更しましたが、やはり6分たつと同じエラーが発生します... 変更後、サーバーは毎回リスタートしております。 ちなみにwebサーバーはノートパソコンで、dbサーバーはレンタルしたlinux centos7 です。 const connection = require('./mysqlConnection'); app.post('/getcreatorname', (req, res, err) => { var sql = "SELECT user_name FROM users WHERE xxxxxxxxx"; connection().query(sql, function (err, results) { if(err){ throw err } res.send(results); }); })
h451

2020/03/26 11:19

クライアントサイドのクロームデベロッパーツールでは以下のエラーが見られました。 Failed to load resource: net::ERR_CONNECTION_RESET
miyabi-sun

2020/03/26 14:17

伝わったようで良かったです。 ダメでしたか…… > webサーバーはノートパソコンで、dbサーバーはレンタルしたlinux centos7 です。 これちょっと詳しく教えて下さい。 基本的にMySQLのサーバはWANに出さず、LAN内で解決させるのが一般的です。 つまりレンタルしたMySQLがあるなら、同じマシンか同サービスの別マシンでアクセスするといった風です。
miyabi-sun

2020/03/26 14:31

「ノートPC」はWindowsだろうと検討を付けてちょっと調べてみたところ、 セキュリティソフト等の問題でこのエラーが出るみたいですね。 https://ja.thewordcracker.com/%E9%9B%91%E5%A4%9A/Chrome%E3%81%A7err_connection_reset%E3%82%A8%E3%83%A9%E3%83%BC%E3%82%92%E8%A7%A3%E6%B1%BA%E3%81%99%E3%82%8B/ Windows自体の設定やルータなんかに見当付けて作業するのが良いと思います。 最悪はConoHaみたいなVPSを借りて運用するのが良さそうですけどね。
h451

2020/03/27 02:57

後々webサーバーもvpsサーバーを借りてそこに移すつもりですが、いまは開発中のためwindows10でローカルでwebサーバーを立てていました。 現在dbサーバーのみvpsサーバーをレンタルして実験している最中です。 >基本的にMySQLのサーバはWANに出さず、LAN内で解決させるのが一般的です。 なるほど、僕の少ない経験からもwanで繋いでいるためこのようなエラーが出るのかもしれないと少し感じていました。lan環境でエラーが発生しないか試してみたいと思います。 色々とわかりやすくアドバイスいただきありがとうございました!経験の豊富な方の意見を聞くことができ大変為になりました。 仰っていただいたあたりに検討をつけて何とか解決方法を模索していきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問