SQLAlchemy 中的连接池回收不会从 pg_stat_activity 回收空闲状态的连接
Connection pool recycle in SQLAlchemy does not recycle idle stated connections from pg_stat_activity
我有一个 Flask 应用程序,它使 insert、select、update 使用 SQLAlchemy 作为其 ORM 和 PostgreSQL 作为数据库管理系统的查询。最小的工作示例是:
import config as cfg
from flask import Flask
from extensions import db
flask_app = Flask(__name__)
flask_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
flask_app.config['SQLALCHEMY_DATABASE_URI'] = cfg.POSTGRES_DB_CONNECT
flask_app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {"pool_pre_ping": True,
"pool_recycle": 600}
flask_app.secret_key = cfg.SECRET_KEY
db.init_app(flask_app)
if __name__=="__main__":
app.run()
如您所见,pool_recycle parameter is set to 600, so that it can close connections older than 10 minutes. However, when I check my pg_stat_activity,它显示 空闲状态 连接长达 2 小时。我使用此查询来检查 pg_stat_activity:
SELECT * FROM pg_stat_activity WHERE client_addr='my_service_hostname' ORDER BY query_start DESC;
我不明白为什么这些查询保持空闲状态,并且在查询开始后 10 分钟内没有消失。也许我的错误在于我对连接池的工作原理知之甚少。有没有办法让连接在10分钟内关闭?
更新 1:这是我使用任何查询的视图函数的最小工作示例:
import config as cfg
import os
from flask import request
from models.document import Document
from app import flask_app, ps_work
from extensions import db
from file_processors import common, documents
@flask_app.route("/files/<string:uuid>", methods=['POST'])
def upload(uuid):
file = request.files['file']
file_uuid = uuid.lower()
if file:
filename = common.Secure_Filename(request.form.get('name', file.filename)).secure_filename()
db_file = Document(file_uuid, filename)
db.session.add(db_file)
db.session.commit()
# HERE I DO SOME UPDATE
while not ps_work.check_file_exists(os.path.join(path,filename)):
file_vault_file_path = db_file.upload_file(path, filename)
db.session.commit()
# HERE I ALSO DO SOME UPDATE
db_file.extract_text(filename)
db_file.sooner_update(extension)
db.session.commit()
有没有可能我的错误是使用 db.session.commit 3 次,而不是使用 db.session.flush 2次,最后是db.session.commit?
我对池的细节没有太多经验,但文档表明连接似乎只有在请求时才会被回收。因此,如果未使用大量连接,则连接可能会持续超过回收限制。你能描述一下用法吗?
https://docs.sqlalchemy.org/en/14/core/pooling.html#setting-pool-recycle
Note that the invalidation only occurs during checkout - not on any
connections that are held in a checked out state.
实际上,我似乎没有正确理解连接池的工作原理。我的解决方案是将 NullPool
class 作为 pool_class
参数设置为 flask_app.config['SQLALCHEMY_ENGINE_OPTIONS']
.
我有一个 Flask 应用程序,它使 insert、select、update 使用 SQLAlchemy 作为其 ORM 和 PostgreSQL 作为数据库管理系统的查询。最小的工作示例是:
import config as cfg
from flask import Flask
from extensions import db
flask_app = Flask(__name__)
flask_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
flask_app.config['SQLALCHEMY_DATABASE_URI'] = cfg.POSTGRES_DB_CONNECT
flask_app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {"pool_pre_ping": True,
"pool_recycle": 600}
flask_app.secret_key = cfg.SECRET_KEY
db.init_app(flask_app)
if __name__=="__main__":
app.run()
如您所见,pool_recycle parameter is set to 600, so that it can close connections older than 10 minutes. However, when I check my pg_stat_activity,它显示 空闲状态 连接长达 2 小时。我使用此查询来检查 pg_stat_activity:
SELECT * FROM pg_stat_activity WHERE client_addr='my_service_hostname' ORDER BY query_start DESC;
我不明白为什么这些查询保持空闲状态,并且在查询开始后 10 分钟内没有消失。也许我的错误在于我对连接池的工作原理知之甚少。有没有办法让连接在10分钟内关闭?
更新 1:这是我使用任何查询的视图函数的最小工作示例:
import config as cfg
import os
from flask import request
from models.document import Document
from app import flask_app, ps_work
from extensions import db
from file_processors import common, documents
@flask_app.route("/files/<string:uuid>", methods=['POST'])
def upload(uuid):
file = request.files['file']
file_uuid = uuid.lower()
if file:
filename = common.Secure_Filename(request.form.get('name', file.filename)).secure_filename()
db_file = Document(file_uuid, filename)
db.session.add(db_file)
db.session.commit()
# HERE I DO SOME UPDATE
while not ps_work.check_file_exists(os.path.join(path,filename)):
file_vault_file_path = db_file.upload_file(path, filename)
db.session.commit()
# HERE I ALSO DO SOME UPDATE
db_file.extract_text(filename)
db_file.sooner_update(extension)
db.session.commit()
有没有可能我的错误是使用 db.session.commit 3 次,而不是使用 db.session.flush 2次,最后是db.session.commit?
我对池的细节没有太多经验,但文档表明连接似乎只有在请求时才会被回收。因此,如果未使用大量连接,则连接可能会持续超过回收限制。你能描述一下用法吗?
https://docs.sqlalchemy.org/en/14/core/pooling.html#setting-pool-recycle
Note that the invalidation only occurs during checkout - not on any connections that are held in a checked out state.
实际上,我似乎没有正确理解连接池的工作原理。我的解决方案是将 NullPool
class 作为 pool_class
参数设置为 flask_app.config['SQLALCHEMY_ENGINE_OPTIONS']
.