我目前的 Python 脚本存在问题,当我从 cursor.execute() 为特定函数执行 SQL 函数时,它运行该函数,函数完成,然后脚本挂起近五个小时,然后恢复其余部分的程序。
我在 pgAdminIII 中观察我的函数的服务器状态,因为它是从 Python 调用的,当函数完成时,服务器只显示与我的 python 用户的打开连接。之前它会在事务中空闲,但在添加 conn.set_isolation_level(0) 之后,它只显示打开的连接。
我还在 cursor.execute() 周围放置了打印,但需要五个小时才能继续执行以下打印语句。我尝试终止连接并重新启动它无济于事。我完全从我的脚本中剥离了函数调用,所以它是我的脚本处理的唯一过程。没有任何效果。
困难在于双方都一直指向对方是问题的根源。我假设这是这个特定功能的某种交互效果。运行特定功能后,也许没有从 postgres 将信号发送回 python?其他功能都没有与相同的执行方法有关的问题。
想法?解决方案?-我正在考虑超时,但运行时间可以从 20 分钟到 2 小时不等。- 它运行的函数创建一个表并仅返回一个说明“完成”的字符串,所有操作在它作为服务器状态下的活动函数消失后都在数据库中进行说明。
这是我用于复制问题的代码,与我的主脚本隔离:
#!/usr/bin/env python
import sys
import os
import smtplib
import ftplib
import gzip
import logging
import shutil
import argparse
import traceback
import subprocess
from email.mime.text import MIMEText
import psycopg2
import psycopg2.extras
import psycopg2.extensions
from psycopg2 import OperationalError
pg_db = "ppl"
pg_port = "5432"
pg_user = "<user>"
pg_pass = "<pass>"
pg_host = "<host>"
# connect to database
try:
conn = psycopg2.connect(database=pg_db,
port=pg_port,
user=pg_user,
password=pg_pass,
host=pg_host)
conn.set_isolation_level(0)
except:
print "Unable to connect to the database."
cur = conn.cursor()
print 'Starting select <function1>'
cur.execute("select <function1>(999999, null );")
print 'Assign variable...'
a = cur.fetchall()
print 'Done'
print 'Starting select <function2>'
cur.execute("select <function2>(999999, null );")
print 'Assign variable...'
b = cur.fetchall()
print 'Done'
print a
print b
conn.close()
sys.exit()
然后我按照这些结果的建议运行了一个 strace:
<previous function statements for about 4k lines>
write(1, "Starting select <function>"..., 45) = 45
sendto(3, "Q\0\0\0009select <function>"..., 58, MSG_NOSIGNAL, NULL, 0) = 58
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "T\0\0\0001\0\1<function_name>\0"..., 16384, 0, NULL, NULL) = 500
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0mSINFO\0C00000\0Mv_eval_table "..., 16384, 0, NULL, NULL) = 110
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\4\247SINFO\0C00000\0Mcmd := CREATE"..., 16384, 0, NULL, NULL) = 1192
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\23hSINFO\0C00000\0Mcmd := \t--For"..., 16384, 0, NULL, NULL) = 4969
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 84
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 672
...
brk(0xbe9000) = 0xbe9000
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 84
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 168
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 1008
...
<does this for about 600k more lines before executing the rest of the script, I am assuming it is indefinitely looping until a timeout>
接下来,我为一个函数运行了一个 cProfile,该函数包装了调用第二个函数的第二个代码块:
Tue Jan 15 16:04:50 2013 function2_prof
7 function calls in 15755.988 CPU seconds
Random listing order was used
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 {method 'cursor' of 'psycopg2._psycopg.connection' objects}
1 0.000 0.000 15755.988 15755.988 test_sql_sub2.py:48(LR2)
1 15755.988 15755.988 15755.988 15755.988 {method 'execute' of 'psycopg2._psycopg.cursor' objects}
1 0.000 0.000 15755.988 15755.988 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {method 'close' of 'psycopg2._psycopg.cursor' objects}
1 0.000 0.000 0.000 0.000 {method 'fetchall' of 'psycopg2._psycopg.cursor' objects}