У меня в настоящее время проблема с моим скриптом Python, когда я выполняю функцию SQL из cursor.execute() для определенной функции, она выполняет функцию, завершает работу и то скрипт зависает где-то около пяти часов, прежде чем возобновить оставшуюся часть программы.Python зависает во время cursor.execute() с помощью Psycopg2
Я смотрю статус сервера своей функции в pgAdminIII, так как он вызывается из Python, и когда функция завершается, сервер просто показывает открытое соединение с моим пользователем python. Прежде чем он будет работать в транзакции, но после добавления conn.set_isolation_level (0), он показывает только открытое соединение.
Я также разместил отпечатки, окружающие cursor.execute(), но для перехода к следующему оператору печати требуется пять часов. Я попытался убить соединение и перезапустить его безрезультатно. Я полностью отключил вызов функции из моего сценария, поэтому это был единственный процесс, который обрабатывал мой скрипт. Ничего не сработало.
Сложность состоит в том, что обе стороны продолжают указывать на другую как на источник проблемы. Я предполагаю, что это какой-то эффект взаимодействия от этой конкретной функции. Возможно, сигнал не отправляется обратно на python из postgres после запуска конкретной функции? Ни одна из других функций не имеет проблемы с одним и тем же способом выполнения.
Идеи? Решения? -Я рассматривал таймаут, но время работы может варьироваться от 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()
Тогда я побежал Трассирование как предложено с этими результатами:
<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}
Пробовал создавать отдельные курсоры для каждого вызова функции, все еще не увенчались успехом. – BagoDev
, поскольку он возобновляет (в конечном итоге), а не вешает навсегда, вы можете попробовать обнюхивать трафик, привязать strace к python и т. Д. И посмотреть, что на самом деле происходит за эти пять часов – Eevee
несколько рекомендаций: вы действительно должны включать информацию о версии в свой вопрос (ОС, Postgresql, Python и т. Д.); Люди обычно просят об этом. Затем вы должны дать определения функций. Наконец, я попробую назвать вашу функцию параметрами. это просто хорошая идея. Я не уверен, что это поможет, но я надеюсь на это. –