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__' の場合: マイテスト() 正しい結果が得られる
接続タイムアウト後のクエリ リンク作成後、すぐにクエリが実行され、そのタイムアウト期間を超えていないため、上記の結果が正常に得られます。しばらくスリープすると、どのような効果があるかを確認します。 #コーディング: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をサポートしていただければ幸いです。 以下もご興味があるかもしれません:
|
<<: ElementUI el-select の過剰なデータに対する解決策についての簡単な説明
>>: MySQL を使用してポート 3306 を開いたり変更したり、Ubuntu/Linux 環境でアクセス許可を開く
私は最近、最も安い Tencent クラウド サーバーを購入しました。これは主に、Web テクノロジ...
伝統的な方法は、正方形を固定形式で書くことです。長さ=幅を直接書き、次のように固定値を書きます。 。...
序文レイアウトの点では、Gobang はランダムな動きを目的とするゲームよりも実装がはるかに簡単で、...
序文この記事には1. データベースのいくつかの主要な制約2. テーブル間の関係制約:主キー制約: 機...
目次序文一般的な方法1. 親コンポーネントを介して子コンポーネントの発行イベントをリッスンしてpro...
1. まずシステムにmysqlがインストールされているかどうかを確認します rpm -qa | gr...
<br />私はこの問題で気が狂いそうです。症状は次のとおりです。 症状の説明: Int...
Linux で Go 環境を構築するのは非常に簡単です。 1. go1.2.1.linux-386....
効果効果は以下のとおりです実装のアイデアbox-shadow プロパティを使用して、複数の灰色の円...
Vue スキャフォールディングでは、エントリ ファイル main.js の新しい Vue コードに、...
質問:最近、プロジェクトの統計を行っていたときに、テーブルを上下にスクロールしたときにテーブルの先頭...
tomcat はオープンソースの Web サーバーです。Tomcat ベースの Web は実行効率...
CSS の優先順位について話す前に、CSS とは何か、CSS が何に使用されるのかを理解する必要があ...
最近、特に異常なビジネス需要があり、テーブルがあります テーブル「デモ」を作成します( `id` i...
フォルダー内のすべての txt ファイルのファイル名の前に「gt_」を追加する必要があります。つまり...