操作タイムアウトがないときにMySQLサーバーがアクティブに切断される問題を解決します

操作タイムアウトがないときにMySQLサーバーがアクティブに切断される問題を解決します

MySQL サービスを使用する場合、通常の状況では、MySQL のタイムアウト設定は 8 時間 (28800 秒) です。つまり、接続が 8 時間操作されない場合、MySQL は積極的に接続を切断します。接続が再度クエリを実行しようとすると、「MySQL サーバーが切断されました」というエラーが報告されます。ただし、MySQL サーバーの設定によっては、多くの場合、より多くの接続が利用できるように、接続タイムアウトが短縮されることがあります。設定が異常で、非常に短い 30 秒になる場合があり、その場合はクライアントが何らかの操作を行って、MySQL がアクティブに切断されないようにする必要があります。

MySQLのタイムアウトを表示

クライアント ツールまたは Mysql コマンド ライン ツールを使用して、「%timeout%」などのグローバル変数を表示すると、タイムアウトに関連するプロパティが表示されます。ここでは、docker を使用してテスト環境をシミュレートします。

mysql> '%timeout%' のような変数を表示します。 
+-----------------------------+----------+
| 変数名 | 値 |
+-----------------------------+----------+
| 接続タイムアウト | 10 |
| 遅延挿入タイムアウト | 300 |
| ステートメントタイムアウトがある | はい |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | オフ |
| インタラクティブタイムアウト | 30 |
| ロック待機タイムアウト | 31536000 |
| ネット読み取りタイムアウト | 30 |
| ネット書き込みタイムアウト | 60 |
| rpl_stop_slave_timeout | 31536000 |
| スレーブネットタイムアウト | 60 |
| 待機タイムアウト | 30 |
+-----------------------------+----------+
13行セット

wait_timeout: 非対話型接続を閉じる前にサーバーがアクティビティを待機する秒数。これは、プロジェクトでプログラムを呼び出す時間です。

interactive_timeout: 対話型接続を閉じる前にサーバーがアクティビティを待機する秒数。これは、cmd などのローカル マシンで MySQL クライアントを開いた時間です。

pymysql によるクエリ

データベースにランダムテーブルを作成し、2つのデータを挿入しました

mysql> person から * を選択します。
+----+------+-----+
| ID | 名前 | 年齢 |
+----+------+-----+
| 1 | 陽 | 18 |
| 2 | ファン | 16 |
+----+------+-----+
2行セット

pymysqlライブラリを使ってクエリを実行します。とても簡単です

#コーディング:utf-8
pymysqlをインポートする

デフmytest():
  接続 = pymysql.connect(
  ホスト='localhost',
  ポート=3306、
  ユーザー='root'、
  パスワード='123456',
  db='mytest',
  文字セット='utf8')

  カーソル = connection.cursor()
  cursor.execute("人から*を選択")
  データ = カーソル.fetchall()
  カーソルを閉じる()
  データ内のiについて:
    印刷(i)
  カーソルを閉じる()
  接続を閉じる()

__name__ == '__main__' の場合:
  マイテスト()

正しい結果が得られる

(1、「陽」、18)

(2、「ファン」、16)

接続タイムアウト後のクエリ

リンク作成後、すぐにクエリが実行され、そのタイムアウト期間を超えていないため、上記の結果が正常に得られます。しばらくスリープすると、どのような効果があるかを確認します。

#コーディング:utf-8

pymysqlをインポートする
インポート時間


デフmytest():
  接続 = pymysql.connect(
  ホスト='localhost',
  ポート=3306、
  ユーザー='root'、
  パスワード='123456',
  db='mytest',
  文字セット='utf8')
  カーソル = connection.cursor()
  cursor.execute("人から*を選択")
  データ = カーソル.fetchall()
  データ内のiについて:
    印刷(i)
  カーソルを閉じる()

  時間.睡眠(31)
  カーソル = connection.cursor()
  cursor.execute("人から*を選択")
  data2 = カーソル.fetchall()
  データ2のiの場合:
    印刷(i)
  カーソルを閉じる()
  接続を閉じる()

__name__ == '__main__' の場合:
  マイテスト()

ここでは2つのクエリが実行されました。mysqlのwait_timeoutを30秒に設定していたため、最初のクエリの後に31秒間停止し、mysqlサービスが作成した接続から積極的に切断されるようにしました。結果は次のとおりです。

(1、「陽」、18)
(2、「ファン」、16)
トレースバック(最新の呼び出しが最後):
 ファイル "F:/python/python3Test/mysqltest.py"、行 29、<module>
  マイテスト()
 ファイル「F:/python/python3Test/mysqltest.py」、行 22、mytest
  cursor.execute("人から*を選択")
 ...
 ...
 ファイル "C:\Python35\lib\site-packages\pymysql\connections.py"、行 702、_read_bytes 内
  CR.CR_SERVER_LOST、「クエリ中に MySQL サーバーへの接続が失われました」
pymysql.err.OperationalError: (2013、「クエリ中に MySQL サーバーへの接続が失われました」)

プロセスは終了コード 1 で終了しました

31 秒間停止した後、再度接続を使用してクエリを実行すると、2013 の「クエリ中に MySQL サーバーへの接続が失われました」というエラーがスローされることがわかります。

解決

解決策は 2 つあります。ここでのタイムアウトは、指定された時間内に操作が行われなかったために発生するため、MySQL は積極的に接続を閉じます。pymysql 接続オブジェクトには、接続が有効かどうかを確認する ping() メソッドがあります。各クエリ操作の前に ping() メソッドを実行します。このメソッドにはデフォルトで reconnect パラメータがあり、デフォルトでは True になっています。接続が失われた場合は再接続されます。

#コーディング:utf-8

pymysqlをインポートする
インポート時間


デフmytest():
  接続 = pymysql.connect(
  ホスト='localhost',
  ポート=3306、
  ユーザー='root'、
  パスワード='123456',
  db='mytest',
  文字セット='utf8')
  接続.ping()
  カーソル = connection.cursor()
  cursor.execute("人から*を選択")
  データ = カーソル.fetchall()
  データ内のiについて:
    印刷(i)
  カーソルを閉じる()
  
  時間.睡眠(31)
  接続.ping()
  カーソル = connection.cursor()
  cursor.execute("人から*を選択")
  data2 = カーソル.fetchall()
  データ2のiの場合:
    印刷(i)
  カーソルを閉じる()
  接続を閉じる()

__name__ == '__main__' の場合:
  マイテスト()

別のスレッドを使用して ping() 操作を継続的に実行しようとしましたが、これを行うと接続が失われ、後続の操作を実行できなくなります。私はこの問題についてさらに研究するつもりです。

#コーディング:utf-8

pymysqlをインポートする
インポート時間
インポートスレッド
インポート トレースバック

定義ping(接続):
  真の場合:
    試す:      
      接続ping()
    を除外する:
      印刷(traceback.format_exc())
    ついに:
      時間.睡眠(1)

デフmytest():
  接続 = pymysql.connect(
  ホスト='localhost',
  ポート=3306、
  ユーザー='root'、
  パスワード='123456',
  db='mytest',
  文字セット='utf8')
  カーソル = connection.cursor()
  # ここでは動作しません。実行する前にカーソルの実行を待つ必要があります。 # th = threading.Thread(target=ping, args=(connection,))
  # th.setDaemon(True)
  # th.start()
  cursor.execute("人から*を選択")
  データ = カーソル.fetchall()
  データ内のiについて:
    印刷(i)
  カーソルを閉じる()

  # ここでスレッドを開始できます th = threading.Thread(target=ping, args=(connection,))
  th.setDaemon(True)
  th.start()
  
  時間.睡眠(31)
  カーソル = connection.cursor()
  cursor.execute("人から*を選択")
  data2 = カーソル.fetchall()
  データ2のiの場合:
    印刷(i)
  カーソルを閉じる()
  接続を閉じる()

__name__ == '__main__' の場合:
  マイテスト()

もう1つの方法は、接続プールを使用することです。これは、指定された数の利用可能な接続を保持し、クエリ操作ごとに有効な接続を再取得します。Pymysql自体には接続プール機能がないため、DBUtilsを使用する必要があります。

#コーディング:utf-8
pymysqlをインポートする
インポート時間
DBUtils.PooledDB から PooledDB、SharedDBConnection をインポートします


デフmytest():
  プール = PooledDB(
    作成者=pymysql、
    # 初期化時に、接続プールは少なくともアイドル接続を作成します。0 は作成しないことを意味します。maxconnections=3、 
    # 接続プール内のアイドル接続の最大数。0 および None は制限なしを示します。mincached=2、
    # 接続プール内の共有接続の最大数。0 または None はすべてが共有されることを意味します (実際には役に立ちません)
    最大キャッシュ=5、    
    最大共有数=3、
    ホスト='localhost',
    ポート=3306、
    ユーザー='root'、
    パスワード='123456',
    db='mytest',
    文字セット='utf8'
  )
  接続 = pool.connection()
  カーソル = connection.cursor()
  cursor.execute("人から*を選択")
  データ = カーソル.fetchall()
  データ内のiについて:
    印刷(i)

  時間.睡眠(40)
  cursor.execute("人から*を選択")
  data2 = カーソル.fetchall()
  データ2のiの場合:
    印刷(i)
  カーソルを閉じる()
  接続を閉じる()

__name__ == '__main__' の場合:
  マイテスト()

この方法では結果を正しく取得できますが、実際のプロジェクトでは使用されません。代わりに、クエリ ステートメントの実行後に接続を閉じる必要があります。ここでの接続を閉じることは、実際に接続を閉じることではなく、他のユーザーが使用できるように接続を接続プールに返すだけであることに注意してください。

#コーディング:utf-8
pymysqlをインポートする
インポート時間
DBUtils.PooledDB から PooledDB、SharedDBConnection をインポートします


デフmytest():
  プール = PooledDB(
    作成者=pymysql、
    最大接続数=3、
    # 初期化時に、接続プールは少なくともアイドル接続を作成します。0はmincached=2がないことを意味します。
    # 接続プール内のアイドル接続の最大数。0 および None は制限なしを示します。maxcached=5,
    # 接続プール内の共有接続の最大数。0 または None はすべて共有されることを意味します (実際には役に立ちません)
    最大共有数=3、
    ホスト='localhost',
    ポート=3306、
    ユーザー='root'、
    パスワード='123456',
    db='mytest',
    文字セット='utf8'
  )
  接続 = pool.connection()
  カーソル = connection.cursor()
  cursor.execute("人から*を選択")
  データ = カーソル.fetchall()
  データ内のiについて:
    印刷(i)
  カーソルを閉じる()
  # 接続を閉じると、実際には接続が閉じられるわけではなく、接続を接続プールに返すだけです。connection.close()

  時間.睡眠(40)
  接続 = pool.connection()
  カーソル = connection.cursor()
  cursor.execute("人から*を選択")
  data2 = カーソル.fetchall()
  データ2のiの場合:
    印刷(i)
  カーソルを閉じる()
  接続を閉じる()

__name__ == '__main__' の場合:
  マイテスト()

操作タイムアウトがないときにMySQLサーバーがアクティブに切断される問題を解決する方法に関する上記の記事は、編集者があなたと共有するすべての内容です。これが参考になることを願っており、123WORDPRESS.COMをサポートしていただければ幸いです。

以下もご興味があるかもしれません:
  • WeChatサーバーにリクエストするミニプログラムサーバーのタイムアウトの解決策
  • PHP での curl および soap リクエスト サービスのタイムアウト問題の解決方法
  • Java の非同期マルチスレッド タイムアウトによって発生するサービス例外についての簡単な説明
  • Nginxサーバーでタイムアウトを設定する方法の詳細な説明
  • 構成された DNS サーバーが応答しないため、Win7 システム ログに「ドメイン名」の名前解決のタイムアウトが期限切れになったことが示されます。
  • ORA-12170 TNS の解決策: Oracle リモート サーバーへの接続時に接続タイムアウトが発生する
  • FileZilla を使用してサーバーに接続するとタイムアウトが発生する
  • SNMP4J サーバー接続タイムアウト問題の解決策

<<:  ElementUI el-select の過剰なデータに対する解決策についての簡単な説明

>>:  MySQL を使用してポート 3306 を開いたり変更したり、Ubuntu/Linux 環境でアクセス許可を開く

推薦する

Docker-compose インストール yml ファイルの設定方法

目次1. オフラインインストール2. オンラインインストール3. アンインストール4. ymlファイ...

JS を使用して要素が配列であるかどうかを判断する例

検証できるデータの種類は次のとおりです a = [1,2,3,4,5,6]とします。 b = [とし...

MySQLの3つの用途と違いは同等ではない

MySQLでは判定記号がよく使われますが、等しくない記号はもっと一般的に使われます。次の3つの等しく...

div が contentEditable=true に設定されている場合、コンテンツをリセットした後にカーソルを配置することはできません。

最近、絵文字にコメントする機能が必要なコメント機能に取り組んでいたため、 contentEditab...

W3C チュートリアル (8): W3C XML スキーマのアクティビティ

XML スキーマは、DTD に代わる XML ベースのものです。 XML スキーマは、DTD に代わ...

Vue は無限ロードウォーターフォールフローを実装します

この記事では、参考までに、無限ロードウォーターフォールフローを実現するためのVueの具体的なコードを...

mysql 5.7.11 winx64.zip インストールと設定方法のグラフィックチュートリアル

MySql データベース システムをインストールして構成します。 1. ダウンロード http://...

MySQL 8.0 の新機能 - チェック制約の紹介

目次序文チェック制約作成、削除、表示制限要約する序文MySQL 8.0 では、チェック制約という非常...

Vue.js の watch メソッドと computed メソッドの違いの詳細な例

目次序文導入1. 作用機序2. 自然から3. 時計と計算の比較4. メソッドはデータロジックの関係を...

Jenkins + Docker + ASP.NET Core の自動デプロイメントの問題について (落とし穴を避ける)

このブログを書くつもりはなかったのですが、実際の操作中に、ネットワークの問題に圧倒されたこと (ネッ...

jsネイティブ構文プロトタイプ、__proto__、コンストラクタの徹底的な理解

目次1 はじめに2 前提条件2.1 データ型2.2 それが自身のプロパティであるかどうかを判断する ...

ページのキャッシュを防ぐソリューション

解決: <head> に次のコードを追加します。コードをコピーコードは次のとおりです。 ...

アイデアコンパイラvueインデントエラー問題シナリオの分析

プロジェクトシナリオ: Vueプロジェクトを実行したらインデントエラーが出ました。ideaコンパイラ...

ウェブサイトのデザインでは色の階層感覚に注意を払う必要があります

最近、私はデザインには階層感覚が必要だと言っています。この階層感覚には、色の重ね合わせや要素の重ね合...

VMware での Ubuntu Docker のインストール (コンテナ構築)

1. マインドマップ 2. コンテナの構築方法2.1 実験環境の準備(1)環境選択管理ツール: D...