Lewis's Tech Keep
[PostgreSQL] cached plan must not change result type 에러 본문
에러 원인
- 앱이 스키마 업그레이드에 의해 변경된 테이블을 쿼리하는 경우
(즉, 앱이 변경된 테이블에서 업그레이드 전후에 쿼리를 실행 한 경우)
postgres 드라이버는 일부 스키마 세부 정보를 캐싱하기 때문에 오류를 반환한다.
https://stackoverflow.com/questions/34180932/error-cached-plan-must-not-change-result-type-when-mixing-ddl-with-select-via
- pg jdbc 에서 preparedStatement를 효율적으로 하기위한 caching 을 저장하는데 아무것도 설정하지 않았을 경우 prepareThresold 가 5개로 유지되고 요청이 많았을 경우
해당 5개에 저장된 preparedStatement의 스키마가 수정된 새로운 스키마와 다르기 때문에 난 오류라고 추측
해결책에 대하여
- 1. pgjdbc driver 의 autosave=conservative 옵션으로 설정
이 옵션을 사용하면 드라이버가 캐싱중인 모든 세부 정보를 flush 한다.
때문에 서버를 바운스하거나 커넥션 풀을 flush 할 필요가 없다.
https://access.crunchydata.com/documentation/pgjdbc/42.1.2/connect.html (적용 방법)
이 옵션을 설정 할 시 커넥션 풀이 지속적으로 flush를 하기 때문에
해당 옵션 적용 시에도 약간의 퍼포먼스 하락이 예상됨.
- autosave=conservative 모드로 설정 후 스키마가 맞지 않은 것이 왜 해결 되는 것인지의 답변
- rollback to savepoint only in case of "prepared statement does not exist" and
"cached plan must not change result type". Then the driver would re-execute the statement ant it would pass through- pgjdbc가 statement를 재실행 하기 때문 (아마도 이 때 flush를 한다는 것으로 예상)
- 세이브 포인트란?
- SQL 세이브포인트는 작업 단위(UOW) 내의 특정 시점에서 데이터 및 스키마의 상태
- 세이브 포인트란?
- pgjdbc가 statement를 재실행 하기 때문 (아마도 이 때 flush를 한다는 것으로 예상)
- rollback to savepoint only in case of "prepared statement does not exist" and
- autosave=conservative 모드로 설정 후 스키마가 맞지 않은 것이 왜 해결 되는 것인지의 답변
- 2. prepareThreshold 를 0으로 만들어 cache가 없게 한다.
https://stackoverflow.com/questions/34180932/error-cached-plan-must-not-change-result-type-when-mixing-ddl-with-select-via
그러나 기존 기능의 퍼포먼스에 영향이 있을 확률이 크므로
2번 해결책은 좋은 해결책은 아닌 것으로 판단. - 3. 스키마 조정 시에는 트래픽을 확인 후 괜찮은 시간대에 적용하고 시작한다.
퍼포먼스 하락은 없지만 스키마 수정 시 주의를 요하게 됨
해결책에 대한 개인적 판단
- 3번 스키마 조정 시에 트래픽 확인 후 적용을 최우선으로 하고
불가피한 경우 1번 autosave를 conservative 로하는 방법을 적용하여 나가는 것이 좋다고 생각함- 대신 conservative 적용을 위해 재부팅 과정이 필요로 하게 됨
여담
- pgjdbc에서 이에 대한 얘기가 생각보다 꽤 있음
- 관련 이슈 티켓 링크 https://github.com/pgjdbc/pgjdbc/issues/496
- 실제로 맞지 않아서 에러가 나는 부분은 SQL 서버 단에서부터 던지기 때문에 AWS를 사용하신다면 내부에서 log를 찾아본다면 실제 해당 시간에 내부 서버에서 던진 로그를 발견할 수 있음 ㅎㅎ
- 어느 포인트에서 발생하여 던졌는 지 찾기 위해 거의 4일을 탐험한 것 같음..
참고 링크
- https://stackoverflow.com/questions/34180932/error-cached-plan-must-not-change-result-type-when-mixing-ddl-with-select-via
- https://access.crunchydata.com/documentation/pgjdbc/42.1.2/connect.html
- https://github.com/pgjdbc/pgjdbc/issues/496
'Database' 카테고리의 다른 글
[Database] Spring Boot에서 Isolation level은 transaction 단위로 작동하는가? (0) | 2023.01.08 |
---|---|
[Database] locking 전략과 lock에 관한 이야기 (1) | 2023.01.08 |
Comments