psycopg2.OperationalError:SSL SYSCALL错误:检测到EOF

时间:2018-06-05 21:05:24

标签: python amazon-redshift psycopg2

我在python脚本中使用psycopg2连接到Redshift数据库,偶尔我收到错误如下:

  

psycopg2.OperationalError:SSL SYSCALL错误:检测到EOF

此错误仅发生一次,脚本工作的时间占90%。

我试着把它放到试试中,除了块以捕捉错误,但似乎捕捉没有效果。例如,我尝试捕获错误,以便在发生这种情况时自动向我发送电子邮件。但是,错误发生时未发送电子邮件。以下是我的试用代码,除了:

try:
    conn2 = psycopg2.connect(host="localhost", port = '5439', 
    database="testing", user="admin", password="admin")

except psycopg2.Error as e:
    print ("Unable to connect!")
    print (e.pgerror)
    print (e.diag.message_detail)

    # Call check_row_count function to check today's number of rows and send 
      mail to notify issue
    print("Trigger send mail now")
    import status_mail
    print (status_mail.redshift_failed(YtdDate))

    sys.exit(1)
else:
    print("RedShift Database Connected")
    cur2 = conn2.cursor()
    rowcount = cur2.rowcount

我在日志中收到的错误:

  

追踪(最近一次通话):     文件" /home/ec2-user/dradis/dradisetl-daily.py" ;,第579行,在       load_from_redshift_to_s3()     文件" /home/ec2-user/dradis/dradisetl-daily.py",第106行,在load_from_redshift_to_s3中       分隔符为',&#39 ;; """ .format(YtdDate,s3location))   psycopg2.OperationalError:SSL SYSCALL错误:检测到EOF

所以问题是,是什么导致了这个错误,为什么我的尝试不会阻止它?

3 个答案:

答案 0 :(得分:2)

来自docs

  

psycopg2.OperationalError例外

     

由于与数据库的错误相关的错误而引发的异常   操作,并不一定要在程序员的控制下,   例如发生意外的断开连接,数据源名称不是   找到,无法处理事务,内存分配错误   在处理等过程中发生的。

这是一个错误,可能是许多不同原因导致的。

  • 慢查询
  • 该进程的内存不足
  • 其他正在运行的查询导致表被无限期锁定
  • 磁盘空间不足
  • 防火墙

(您绝对应该提供有关这些因素的更多信息和更多代码。)

您已成功连接,但稍后发生OperationalError。 尝试处理脚本中的这些断开连接: 将要执行的命令放入try-catch块中,如果连接断开,则尝试重新连接。

答案 1 :(得分:0)

如果您附加了您尝试的实际代码,那么它会有所帮助。在您附加的堆栈跟踪中:“文件”/home/ec2-user/dradis/dradisetl-daily.py“,第106行” 类似的除了代码对我来说很好。请注意,如果客户端发生错误,e.pgerror将为空,例如我的示例中的错误。在这种情况下,e.diag对象也将毫无用处。

try:
    conn = psycopg2.connect('')
except psycopg2.Error  as e:
    print('Unable to connect!\n{0}'.format(e))
else:
    print('Connected!')

答案 2 :(得分:0)

最近遇到了这个错误。就我而言,原因是使用数据库时网络不稳定。如果网络关闭的时间足够长,套接字检测到超时,您将看到此错误。如果停机时间不长,您就不会看到任何错误。

您可以使用此代码示例控制 Keepalive 和 RTO 功能的超时

s = socket.fromfd(conn.fileno(), socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 6)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 2)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 2)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_USER_TIMEOUT, 10000)

您可以在此post

中找到更多信息