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 環境でアクセス許可を開く
目次1. v-on指令1. 基本的な使い方2. 糖衣構文3. イベントパラメータ4. イベント修飾子...
バントリストコンポーネントをスクロールするときに、スクロールバーの位置が保持されます。これは、kee...
なぜ高さを設定できるのでしょうか。<h1 /> などの要素とは異なり、「セミインライン」...
この記事では、例を使用して、MySQL ストアド プロシージャの原理と使用方法を説明します。ご参考ま...
序文apt-get コマンドは、Ubuntu システムのパッケージ管理ツールです。パッケージのインス...
1 MVCCとは何かMVCC の正式名称は、マルチバージョン同時実行制御です。データベースへの同時ア...
例:場所のルートとエイリアスルートディレクティブは、ルートによって設定されたディレクトリに検索ルート...
目次事件の原因Node Scheduleを使用してスケジュールされたタスクを実装する1. node-...
Tomcat サーバーは、無料でオープン ソースの Web アプリケーション サーバーです。軽量のア...
最近プロジェクトが中断され、RageFrame の研究は一時的に終了しました。この記事では、シングル...
:動的コンポーネントv-bind:is="component name" を使用...
今日、インターフェースの同時実行の問題を検証したところ、これまでredisで解決していた同時実行のプ...
イメージをプルし、コンテナを作成してコンテナを実行するだけです。 docker run -d --r...
この記事の例では、カスタムスクロールバーを実装するためのjsの具体的なコードを参考までに共有していま...
パノラマビュー効果を見てみましょう: 住所を表示スクリーンショット: 体験してみると、周囲の環境がぐ...