본문 바로가기
MySql

MySQL python MySQLDB 쿼리 시간 초과

by 베이스 공부 2021. 1. 11.
반응형

파이썬 MySQLDB에서 쿼리에 시간 제한을 적용하려고합니다. 쿼리를 제어 할 수 없지만 설정된 시간 제한을 초과하지 않도록해야하는 상황이 있습니다. signal.SIGALRM을 사용하여 실행 호출을 중단하려고 시도했지만 작동하지 않는 것 같습니다. 신호가 전송되지만 실행 호출이 완료 될 때까지 포착되지 않습니다.

이 동작을 증명하기 위해 테스트 케이스를 작성했습니다.

#!/usr/local/bin/python2.6

import time
import signal

from somewhere import get_dbc

class Timeout(Exception):
    """ Time Exceded """

def _alarm_handler(*args):
    raise Timeout

dbc = get_dbc()

signal.signal(signal.SIGALRM, _alarm_handler)
signal.alarm(1)

try:
    print "START:  ", time.time()
    dbc.execute("SELECT SLEEP(10)")
except Timeout:
    print "TIMEOUT!", time.time()'

"SELECT SLEEP (10)"은 느린 쿼리를 시뮬레이션하고 있지만 실제 느린 쿼리에서도 동일한 동작이 나타납니다.

결과:

START:   1254440686.69
TIMEOUT! 1254440696.69

보시다시피 10 초 동안 잠자고 있는데 Timeout Exception이 발생합니다.

질문 :

 

해결 방법

 


import multiprocessing

def query_with_timeout(dbc, timeout, query, *a, **k):
  conn1, conn2 = multiprocessing.Pipe(False)
  subproc = multiprocessing.Process(target=do_query,
                                    args=(dbc, query, conn2)+a, 
                                    kwargs=k)
  subproc.start()
  subproc.join(timeout)
  if conn1.poll():
    return conn1.recv()
  subproc.terminate()
  raise TimeoutError("Query %r ran for >%r" % (query, timeout))

def do_query(dbc, query, conn, *a, **k):
  cu = dbc.cursor()
  cu.execute(query, *a, **k)
  return cu.fetchall()

 

참조 페이지 https://stackoverflow.com/questions/1507091

 

 

반응형

댓글