【发布时间】:2019-05-06 07:04:20
【问题描述】:
我最近将我正在开发的软件的一些后台功能从使用 Python 线程模块切换到多处理模块,以便利用更多 CPU 内核。大部分转移都顺利进行,但数据库集成给我带来了重大问题。
最初,我使用来自 Python psycopg2 的单个 SimpleConnectionPool 对象,它作为一个全局变量存在于一个名为 db 的模块中,该模块还处理一些样板数据库操作。据我了解,创建第二个 Python 进程只是将当前内存堆栈复制到新进程位置。因为这会导致数据库连接出现问题,所以我在我的 db 模块中添加了一个名为 init() 的函数,它只是重新初始化 SimpleConnectionPool 并将其设置为全局变量。我的想法是,如果我在第二个进程中调用这个 init 函数,它会为第二个进程上的池创建一组新的连接。因此,主进程将保持自己的一组连接,与第二个进程分开。
但是,使用这种方法时,我经常遇到以下异常:
OperationalError: SSL error: decryption failed or bad record mac
这直接源自 psycopg2_patcher.py 中的“state = conn.poll()”。我做了一些挖掘,据我所知,只有在主进程和辅助进程都尝试同时执行查询时才会抛出错误。我正在考虑只是恢复到主进程中的一个连接池,并使用队列将查询从辅助进程传递到主进程以执行。尽管我宁愿避免这样做,但会带来很多头痛。
我还尝试在辅助进程上远离连接池,并使用仅在需要执行查询时建立的单个连接,然后直接关闭。当主进程几乎在同一时间尝试执行查询时,也会发生同样的错误。
我需要对 PGSQL 服务器或我的实现做些什么来允许不同的进程使用相同的凭据同时发布查询?我感觉我正在以一种完全不必要和复杂的方式处理进程之间的数据库连接。
【问题讨论】:
-
您是否查看过现有的连接池,例如 PgBouncer ?
标签: python postgresql psycopg2 python-multiprocessing