ssl error decryption failed or bad record mac 에러... 이전에 uWSGI에서도 문제가 발생한 적이 있었습니다. 이번에는 PostgreSQL 파이썬 모듈인 psycopg2에서 발생했습니다. 원인을 찾아보니 이러한 에러가 발생한 것은 PostgreSQL쪽이 아니라 ProcessPoolExecutor (병렬처리) 부분이였습니다.

 원인

DB connection과 cursor를 전역변수로 선언한 다음, 병렬처리를 실행하려 할 때 아래와 같이 함수에서 공통적으로 cursor, conn을 사용하려 하면 위와 같은 에러가 발생합니다.

from concurrent.futures import ProcessPoolExecutor
 
 
def concurrent(list):
	for i in list:
		query = 'insert into test (id) values ({0})'.format(list[i])
		cursor.execute(query)
	conn.commit()
 
db = Database() 
cursor, conn = db.connect() # 입력된 정보를 바탕으로 db 연결을 하여 cursor, connection을 반환해주는 함수가 있다고 가정
_list = ['1','11','111','1111','11111','111111']
 
 
pool = ProcessPoolExecutor(max_workers=4)
pool.map(concurrent, _list)


위 코드를 실행하는 순간 ssl error decryption failed or bad record mac를 발생하게 됩니다. 이유는 여러 프로세스가 동일한 데이터베이스의 공유하게되기 때문입니다.

해결책

해결방법은 다소 간단합니다.

아래와 같이 여러 프로세스가 동일한 데이터베이스를 공유하지 않도록 추가적으로 생성해주면 끝입니다. 

from concurrent.futures import ProcessPoolExecutor

def concurrent(list):
	cursor, conn = db.connect() # 각 프로세스마다 다른 데이터베이스 객체 생성
	for i in list:
		query = 'insert into test (id) values ({0})'.format(list[i])
		cursor.execute(query)
	conn.commit()
 
db = Database() 

_list = ['1','11','111','1111','11111','111111']

pool = ProcessPoolExecutor(max_workers=4)
pool.map(concurrent, _list)


위와 같이 cursor와 connection을 multiProcessing을 실행할 함수 내에 생성해주면 됩니다.

  1. JW 2018.07.05 17:22

    저도 비슷한 문제를 겪고 있습니다. 만약 Django 에서는 ORM을 쓰는데 `db.connect()` 부분은 어떻게 처리해야될까요?ㅠ direct하게 ORM을 쓰게되면 계속 에러가 발생하네요...

+ Random Posts