이슈 기록
실무에서 마주친 문제를 발생-원인-해결 순으로 정리했습니다.
Kafka 발행 실패로 DB에 유령 레코드가 남는 문제
저장은 성공했는데 Kafka 발행만 실패하면 DB에 처리되지 않을 레코드가 남았습니다. 발행을 트랜잭션에서 분리하고 프론트엔드가 재시도·취소를 직접 구동하는 구조로 바꿨습니다.
KafkaSpringTransactionFrontendKafka 브로커가 죽었을 뿐인데 로그가 초당 수십 줄씩 쌓인 이유
브로커 연결이 끊긴 상태에서 send() 예외가 처리된 뒤에도 재접속 로그가 끊임없이 쌓였습니다. 싱글턴 프로듀서의 IO 스레드가 응답과 무관하게 독립적으로 재시도한다는 게 원인이었습니다.
KafkaSpringLogging같은 요청인데 왜 87ms와 6.94초를 오갈까
동일한 파라미터로 요청했는데 응답시간이 80배 가까이 차이 났습니다. 계통별 순차 쿼리(N+1)와 DB 버퍼풀의 cold/warm 상태가 겹쳐 편차가 증폭되는 구조였습니다.
MyBatisMariaDBPerformanceN+1저장한 적 없는 조합까지 전부 등록되어 있었다
사용자가 선택하지 않은 조합까지 DB에 통째로 저장되고 있었습니다. 서버가 하나의 분류값만으로 전체 조합을 캐스케이드 생성하던 구조가 원인이었습니다.
SpringMyBatisValidation숫자가 미묘하게 작게 나온다면 단위를 의심하라
시간별부터 연별까지 통계 배치 결과값이 실제보다 작게 집계되고 있었습니다. 쿼리 하나에 숨어 있던 불필요한 단위 변환과 날짜 포맷 오류가 원인이었습니다.
MyBatisMariaDBBatchTesting다른 빌딩 값이 섞인 것 같은데, 어디서 섞였는지부터 찾아야 했다
이관된 태양광 데이터의 특정 포인트에서 다른 빌딩 값이 섞인 것으로 의심되는 이상값이 나타났습니다. 단계별 진단 로그로 데이터 흐름 전체를 추적해 원인을 찾고 무중단으로 보정했습니다.
MyBatisMariaDBMigrationDebugging화면마다 반복되던 페이징 버그를 DB에서 끝낸 이야기
다섯 달 동안 페이징 버그를 열 번 넘게 고쳤습니다. 매번 다른 화면에서 같은 증상이 반복된다는 건 코드가 아니라 검증 책임의 위치가 잘못됐다는 신호였습니다.
PostgreSQLReactPaginationRefactoring날짜 검색이 안 된다는 제보에서 시작된 세 줄짜리 버그
기간을 지정해도 결과가 나오지 않았습니다. 2024-04-25를 입력했는데 서버로는 25202404가 전송되고 있었습니다. 날짜 변환 함수의 배열 인덱스 순서가 뒤바뀐 탓이었습니다.
JavaScriptDebuggingDate삭제했는데 목록이 그대로 남아 있던 문제
삭제 성공 토스트는 뜨는데 목록에서 항목이 사라지지 않았습니다. 캐시 무효화 코드는 분명히 있었지만, 손으로 적은 쿼리 키가 프레임워크가 만드는 실제 키와 달랐습니다.
ReactTanStack QueryRefineCachePause 버튼을 눌러도 아무 일도 일어나지 않았다
백업 스케줄을 일시중지해도 상태가 바뀌지 않았습니다. 옵셔널 체이닝까지 붙어 안전해 보이던 spec.paused가, 실은 존재하지 않는 필드였습니다.
KubernetesTypeScriptVelero세션이 사라지지 않고 계속 쌓이던 이유
중복 로그인 시 기존 사용자가 아무 안내 없이 튕겨나갔고, 세션 관리 맵은 계속 커졌습니다. 세션 속성 키 하나가 실제 저장 키와 달랐던 게 시작이었습니다.
JavaSpringSessionDBMS를 바꿨더니 화면 절반이 죽었다
MariaDB에서 MySQL로 교체하자 여섯 개 넘는 화면이 줄줄이 SQL 오류를 냈습니다. 원래부터 표준에 어긋나던 쿼리가 MariaDB의 관용 아래 살아 있다가 일제히 드러난 것이었습니다.
MySQLMariaDBSQL수만 건짜리 파일을 올리면 브라우저가 멈췄다
수백 건까지는 괜찮았는데 수만 건이 되자 브라우저가 멈췄고, 진행률도 취소 수단도 없었으며 하나만 실패해도 전체가 실패했습니다. 기능을 고치는 게 아니라 다시 설계해야 했습니다.
ReactTypeScriptAbortControllerPerformance빈 그래프의 원인을 3주 만에 찾은 이야기
GPU 모니터링의 가상머신 탭 그래프가 비어 있었습니다. PromQL은 라벨 선택자가 틀려도 에러 없이 빈 결과를 반환하기 때문에, '데이터 없음'과 '쿼리 오류'가 구분되지 않았습니다.
PromQLPrometheusMonitoring하나가 실패하면 전부 사라지던 목록
VMF 목록이 가끔 통째로 비어 보였습니다. axios.all은 하나라도 실패하면 전체가 reject되어, 20개 중 하나가 500을 뱉으면 나머지 19개도 화면에서 사라지는 구조였습니다.
JavaScriptaxiosAsync네 달 동안 다섯 번 고친 함수
제어 스케줄 판정 함수를 네 달 동안 다섯 번 고쳤습니다. 시간 비교를 정수 시(hour) 단위로만 설계한 최초 결정이 요구사항과 어긋나 있었고, 이후 수정이 모두 그 위에 쌓였습니다.
PostgreSQLPL/pgSQLCronLTE와 5G를 하나로 합치기까지
LTE와 5G는 원천 테이블 구조가 달라, 조회 함수마다 cell_type 분기와 UNION ALL을 개별적으로 떠안고 있었습니다. 같은 분기가 함수마다 반복된다는 건 추상화가 빠져 있다는 신호였습니다.
PostgreSQLMaterialized ViewData Modeling멈추지 않던 폴링
폴링 문제를 두 번 겪었는데 원인이 같았습니다. 종료 조건이 성공 경로에만 있거나, 언마운트 정리가 빠져 있었습니다. 폴링은 성공·실패·언마운트 세 경로 모두에 종료 조건이 필요합니다.
ReactJavaScriptMemory Leak