为什么代码在连接中断时不重新连接到远程mysql服务器?

0 投票
1 回答
787 浏览
提问于 2025-04-17 22:28

我有一个Python脚本,用在我的树莓派上,记录我自酿啤酒的温度数据。这个脚本会把温度数据存储在本地的MySQL数据库和一个远程的MySQL数据库(我个人的网站)里,这样我在外面的时候也能查看这些数据。

不过,大约每天会有一到两次(有时是两天)远程连接会掉线。我猜是我在GoDaddy上托管的远程网站的服务器会在连接超过某个时间限制后自动断开。我在调用数据库时用了一种叫做try/catch的方式,如果数据库调用失败,我会尝试重新连接数据库并再次调用。(在这之前我会等10次,以防远程服务器真的宕机了)。

但是,代码并没有重新连接,远程数据库也再也没有成功更新。如果我强制重启这个脚本,它就能正常工作,所以我知道远程服务器并没有宕机。

那下面的代码里有什么逻辑错误呢?

import MySQLdb

class Connection:
    MYSQL = -1
    MONGO = -2
    def __init__(self, name, type):
        self.name = name
        self.type = type


class MySQLConnection(Connection):
    def __init__(self, name, type):
        Connection.__init__(self, name, type)

class DB:
    local_mysql = None
    remote_mysql = None
    local_mongo = None
    connections = []
    count = 0

   @staticmethod
    def connect(name, host, user, password, database):
        print 'database = ' + database
        try:
            con = MySQLConnection(name, Connection.MYSQL)
            con.con = MySQLdb.connect(host,user,password,database)
            con.host = host
            DB.connections.append(con)
            return con
       except Exception, ex:
            print("Mysql connection to " + host + " failed to initialize.")
            print("Reason: " + str(ex))
            return False

    @staticmethod
    def execute(connection, temperature_list):
        try:
            cursor = connection.con.cursor()
            for temperature in temperature_list:
                cursor.execute(temperature.sql, temperature.values_clause)

            connection.con.commit()
        except Exception, ex:
            print(connection.host + " mysql not updated. Retry in " + str(DB.count))
            print("reason = " + str(ex))
            # retry with same connection 10 times in case remote server is just down
            if DB.count < 10:
                DB.count = DB.count + 1
            else:
                DB.count = 0
                if connection.name == "remote_mysql":
                    # This doesn't establish a new connection
                    DB.remote_mysql = DB.connect('remotemysql', 'www.url.com', 'user', 'passwd', 'dnmae')

#Start script here

DB.local_mysql = DB.connect('localmysql', 'www.url.com', 'user', 'passwd', 'dnmae')
DB.remote_mysql = DB.connect('remotemysql', 'www.url.com', 'user', 'passwd', 'dnmae')

while True: 
    #... Do stuff here, namely parse and convert temperature data

    DB.execute(DB.local_mysql, temperature_list)
    DB.execute(DB.remote_mysql, temperature_list)

更新:

具体的异常信息是:

20006, 'MySQL server has gone away'

我觉得上面的代码应该能重置数据库,但实际上并没有。有趣的是,我有两个树莓派,代码完全一样,但现在只有一个出现了这个错误信息,而另一个则仍然连接正常,没问题。

1 个回答

1

我也遇到过同样的问题。即使我先用ping命令检查了一下mysql服务器,确认数据库是否还可以连接,但当我准备强制重新连接时,还是收到了“MySql服务器已经断开连接”的提示。

我通过在执行我的代码之前添加了一些查询来解决了这个问题。

SET SESSION connect_timeout=28800
SET SESSION wait_timeout=28800
SET SESSION interactive_timeout=28800

希望这能帮助到遇到同样问题的人。祝好。

撰写回答