'MySQL server has gone away' 具有持久的过程

'MySQL server has gone away' with longlasting processes

我们使用 Django 来 运行 建模模拟。代码 运行s 作为 cronscript(不是通过 wsgi)并注册模拟 运行 是否成功。 在模型模拟开始时,会创建状态对象 运行。在模型模拟结束时,此状态对象更新为 SUCCESS 或 FAILED。 (伪)代码如下所示:

def mainRoutine():
    myStatusObject = createStatusObject()
    try:
        runModelSimulation()  # this runs the modelsimulation
    except:
        updateStatus(myStatusObject,'FAILED')
    updateStatus(myStatusObject,'SUCCESS')

def createStatusObject():
    myStatusObject = models.StatusObject()
    myStatusObject.task = 'somename'
    myStatusObject.status = 'RUNNING'
    myStatusObject.save()
    return myStatusObject

def updateStatus(myStatusObject, newstatus):
    myStatusObject.status = newstatus
    myStatusObject.save()

当模型模拟需要很长时间(模拟几小时到几天是可能的)时,问题就开始了。然后 MySQL-数据库出现连接错误,错误为 'MySQL server has gone away'。我从其他帖子了解到,这与数据库中剩余的某些连接有关(这可以通过摆弄 MySQL 的服务器端配置来解决)。

目前我找到了一个解决方法,通过传递状态对象的 ID,而不是状态对象实例。在 updateStatus 子例程中,我然后使用 get(ID=thisID) 在更新之前检索正确的 statusObject 实例。这不会产生超时。

def updateStatus(myStatusObjectID, newstatus):
    myStatusObject = StatusObject.objects.get(id=myStatusObjectID)
    myStatusObject.status = newstatus
    myStatusObject.save()

问题解决了?!但是,我们还有其他类似于 statusobject 的对象,很可能会遇到类似的问题。所以我想了解为什么此连接保持打开状态。传递 StatusObject 实例和传递结合 .get() 的 StatusObject ID 有什么区别?连接是在什么时候建立的,我怎样才能阻止这个连接保持打开状态?我们可以告诉 django 在 .save() 之后关闭连接,并在实例的下一次更新时重新打开它吗? 还因为传递 StatusObject 实例比基于其属性搜索并重新打开它更容易。

在模型模拟之前关闭与 MySQL 的连接。 Django 将在 myStatusObject.save() 调用时自动重新连接到 sql 服务器。

from django.db import connection

def mainRoutine():
    myStatusObject = createStatusObject()
    connection.close()
    try:
        runModelSimulation()  # this runs the modelsimulation
    except:
        updateStatus(myStatusObject,'FAILED')
    updateStatus(myStatusObject,'SUCCESS')