Timed out fetching a new connection from the connection pool. More info: http://pris.ly/d/connection-pool (Current connection pool timeout: 10, connection limit: 9)
이라는 에러가 나왔다.
커넥션 풀에서 타임에러가 났다는 것 같은데..
프리즈마 도큐먼트에 가면 자세하게 설명이 돼있다.
Connection Pool
커넥션 풀은 데이터베이스와 연결되는 창구같은 것인데
프리즈마에서 SQL문을 생성한 후 데이터베이스에 보내기위해 있는 연결이다.
아무런 설정을 안해뒀다면
물리적 CPU 코어 수 × 2 + 1
에 맞게 자동으로 설정된다.
나는 9였고.. 9가 다 차서 커넥션 풀에서 새로운 연결을 가져오려고 시도하다가 타임아웃이 난 것..
설정을 조정해서 해결하는 방법은 두 개가 있다.
부하만 견딜 수 있다면 pool size을 맘껏 늘리고싶지만~~
어디까지 견딜 수 있을지 모르니까 pool timeout도 적절히 늘리면 조절해야할 것 같다.
mysql://...@...:.../..._DB?connection_limit=15&pool_timeout=15
을 붙여두면 해결은 된다.
(pool_timeout=0을 넣어 타임아웃을 아예 비활성화할 수도 있다.)
타임아웃이 나면 같이 sql문으로 재시도하는 게 아니라 그냥 다음 연결로 넘어가버리니 주의해야한다!
P2024코드가 던져진다. (타임아웃된 쿼리를 재시도 하고싶다면 코드를 확인해서 재시도 해야할듯!)설정을 조절했는데도 너무 자주 난다면 (하드웨어 업그레이드를 할 수 없다면..)
Promise.all()을 너무 많이 사용한 건 아닌지 확인해보자🥹
// 1. 순차적 실행 (하나씩 실행)
const user1 = await prisma.user.findUnique({ where: { id: 1 }});
const user2 = await prisma.user.findUnique({ where: { id: 2 }});
const user3 = await prisma.user.findUnique({ where: { id: 3 }});
// 총 실행 시간 = 1초 + 1초 + 1초 = 3초
// 2. 병렬 실행 (Promise.all 사용)
const users = await Promise.all([
prisma.user.findUnique({ where: { id: 1 }}),
prisma.user.findUnique({ where: { id: 2 }}),
prisma.user.findUnique({ where: { id: 3 }}) //대기해야할 수도 있다..
]);
// 총 실행 시간 = 1초 (동시에 실행)
Promise.all()특성 상 내부에서 하나라도 실패하면 전체가 실패하게 된다.!
풀만 넉넉하다면 성능에는 좋겠지만 그렇지않다면 실패했을때 리스크가 커지니까 조심히 사용하자!!(일부라도 성공해야하면 Promise.allSettled() 사용)
const chunks = _.chunk(queries, 2); // 2개씩 나누기
for (const chunk of chunks) {
await Promise.all(chunk);
}
쿼리를 청크로 나눠 처리해도될 듯하다.
여러 요청이 들어왔다는 건 좋은 소식이기도하지만 따라오는 문제가 생기기 시작했다 ㅠ_ㅠ 점검을 해볼 타이밍인 것 같다.