4

MySQLデータベースと通信するCycloneWebサービスがあります。しばらく(推測で8時間以上)アクティビティがない場合、Webサービスを再起動するまで次のエラーが発生します。

_mysql_exceptions.OperationalError:(2006、'MySQLサーバーがなくなりました')

cp_reconnectに関するこの投稿を見ましたが、接続プールを作成するときにこれを実装しました。

pool = adbapi.ConnectionPool("MySQLdb", host=self.host, user=self.user,
    passwd=self.password, db=self.database, cursorclass=MySQLdb.cursors.DictCursor,
    cp_reconnect=True)

これで修正できると思っていたのですが、しばらくはそうだったのですが、しばらくサーバー上でアクティビティがなかったので、「MySQLサーバーがなくなった」というエラーが再び表示されます。

私はwait_timeoutに関するこのMySQLのドキュメントを読み、私が思うようにそれを修正することができましたが、なぜcp_reconnect機能が機能しないのですか?私はadbapiドキュメントを解釈して、cp_reconnectパラメータを指定すると、そのadbadpiがMySQLによって送信されたエラーを処理し、クエリを再試行することを意味します。したがって、基本的には、コードでエラーを直接処理する必要はありません。私はそれを誤解していますか?

4

3 に答える 3

5

私は数年前にこれに対する解決策を探していました。私がWebのどこかで見つけて解決した解決策は、サブクラス化ConnectionPoolとオーバーライドでし_runInteractionた。ここでは、特定のエラーコードで強制的に再接続します。クイックグーグル検索は私をこのウェブサイトに導きました:http://www.gelens.org/2009/09/13/twisted-connectionpool-revisited/コードが含まれています。MySQL接続が停止することを二度と考える必要はありませんでした。

于 2012-10-02T08:00:55.343 に答える
3

ツイストメー​​リングリストでいくつかの議論を行い、ツイストバグトラッカーを調べたところ、これはまだ修正されていない既知のバグであることがわかりました。

メーリングリストのディスカッションへのリンクは次のとおりです。

ツイストバグトラッカーの問題へのリンクは次のとおりです。

可能な解決策:

  1. サーバーのwait_timeout値を増やします。
  2. 上記で参照したConnectionPoolクラスのメソッドをオーバーライドします。
  3. 各接続に定期的な「ping」を設定して、接続を維持します。
  4. adbapiのバグを自分で修正します。

これらのうち、私はおそらく#1で行くつもりです。

于 2012-10-05T16:54:47.840 に答える
2

リンクhttp://www.gelens.org/2009/09/13/twisted-connectionpool-revisited/は、Webアーカイブバージョンでさえも機能しなくなりました。これは、同じソリューションを参照するTwistar1.3からの抜粋です。

https://pypi.python.org/pypi/twistar

class ReconnectingMySQLConnectionPool(adbapi.ConnectionPool):
    """
    This connection pool will reconnect if the server goes away.  This idea was taken from:
    http://www.gelens.org/2009/09/13/twisted-connectionpool-revisited/
    """
    def _runInteraction(self, interaction, *args, **kw):
        try:
            return adbapi.ConnectionPool._runInteraction(self, interaction, *args, **kw)
        except MySQLdb.OperationalError, e:
            if e[0] not in (2006, 2013):
                raise
            log.err("Lost connection to MySQL, retrying operation.  If no errors follow, retry was successful.")
            conn = self.connections.get(self.threadID())
            self.disconnect(conn)
            return adbapi.ConnectionPool._runInteraction(self, interaction, *args, **kw)
于 2016-02-03T13:46:19.073 に答える