본문 바로가기

728x90

Programming/Database 10

MariaDB 트랜잭션 격리수준과 데드락 원인 진단법

MariaDB 트랜잭션 격리수준과 데드락 원인 진단법재고 차감이나 포인트 적립처럼 여러 트랜잭션이 같은 행을 동시에 건드리는 로직에서 Deadlock found when trying to get lock 예외를 만난 적이 있을 겁니다. 인덱스도 걸려 있고 코드도 틀린 곳이 없어 보이는데 왜 이런 일이 생길까요. 원인은 대부분 트랜잭션 격리수준과 잠금 순서에 있습니다.트랜잭션 격리수준 4단계SQL 표준은 네 가지 격리수준을 정의합니다. 격리수준이 낮을수록 동시성은 좋아지지만 아래 세 가지 이상 현상이 발생할 여지가 커집니다.격리수준Dirty ReadNon-repeatable ReadPhantom ReadREAD UNCOMMITTED발생발생발생READ COMMITTED방지발생발생REPEATABLE READ방..

JPA 대량 INSERT 성능 개선: Hibernate JDBC 배치와 flush·clear 설정

JPA 대량 INSERT 성능 개선: Hibernate JDBC 배치와 flush·clear 설정메타 설명: Spring Boot와 MariaDB에서 JPA 대량 INSERT를 JDBC 배치로 묶고, IDENTITY 제약과 영속성 컨텍스트 메모리 문제를 해결하는 설정·코드·검증 방법을 설명합니다.CSV에서 회원 10만 건을 가져오거나 야간 집계 결과를 저장할 때 repository.saveAll()만 호출하면 충분하다고 생각하기 쉽습니다. 하지만 Hibernate의 JDBC 배치가 꺼져 있거나 기본 키가 IDENTITY라면 INSERT가 한 건씩 전송될 수 있습니다. 한 트랜잭션에서 엔티티를 계속 관리하면 1차 캐시도 커집니다.대량 저장 성능은 세 가지를 함께 봐야 합니다.JDBC 드라이버에 INSERT..

Spring Boot 4.1 + Testcontainers로 MariaDB 통합 테스트하기: H2를 운영 DB처럼 믿지 말아야 하는 이유

Spring Boot 4.1 + Testcontainers로 MariaDB 통합 테스트하기: H2를 운영 DB처럼 믿지 말아야 하는 이유메타 설명: Spring Boot 4.1과 Testcontainers 2.0으로 실제 MariaDB를 띄워 JPA 통합 테스트를 실행하고, @ServiceConnection으로 연결 설정을 자동화합니다.최종 확인: 2026년 7월 31일로컬 테스트에서는 모두 통과했는데 운영 MariaDB에서만 SQL 문법 오류가 발생하거나, 대소문자 중복 데이터가 들어가거나, 락 동작이 달라지는 경우가 있습니다.테스트에서 H2를 사용하고 운영에서는 MariaDB를 사용한다면 충분히 가능한 일입니다. H2의 MySQL 호환 모드는 유용하지만, H2가 MariaDB로 바뀌는 것은 아닙니다...

OFFSET 페이지네이션이 느려지는 이유: MariaDB 커서 방식과 Spring Data JPA 구현

OFFSET 페이지네이션이 느려지는 이유: MariaDB 커서 방식과 Spring Data JPA 구현도입부게시글이 적을 때는 LIMIT 20 OFFSET 0과 LIMIT 20 OFFSET 100000의 차이가 잘 보이지 않습니다. 하지만 데이터가 쌓이면 뒤 페이지로 갈수록 느려집니다. DB가 10만 번째 행으로 순간 이동하는 것이 아니라 앞의 행을 찾고 건너뛴 뒤 필요한 20건을 반환하기 때문입니다.이 문제를 줄이는 대표적인 방법이 커서 기반 페이지네이션입니다. 마지막으로 본 데이터의 위치를 다음 요청에 전달하고 그다음부터 조회합니다. 무한 스크롤이나 피드처럼 “다음 목록”이 중요한 화면에 적합합니다.OFFSET 페이지네이션이란?OFFSET 방식은 페이지 번호를 시작 위치로 바꿉니다. 한 페이지가 20..

낙관적 락 vs 비관적 락, 재고 차감에서 뭘 써야 하나

낙관적 락 vs 비관적 락, 재고 차감에서 뭘 써야 하나결론부터동시에 여러 요청이 같은 데이터를 건드리는 상황(재고 차감, 선착순 쿠폰,잔액 차감)에서는 트랜잭션 격리 수준만으로 부족하다. 비관적 락은"일단 잠그고 시작", 낙관적 락은 "일단 진행하고 충돌 나면그때 재시도"다. 충돌이 잦고 정합성이 최우선이면 비관적 락, 충돌이드물고 처리량이 중요하면 낙관적 락을 쓴다. 재고 차감처럼 짧고 자주 충돌하는작업은 대개 비관적 락 쪽이 실무에서 더 무난하다.문제 상황: 동시 요청이 재고를 함께 깎아 먹는다재고 100개인 상품에 동시에 두 요청이 들어와 "재고 있음 → 1개 차감"을각자 확인하고 실행하면, 두 요청 모두 "차감 전 재고 100"을읽은 채로 각각 99로 갱신해버릴 수 있다. 실제로는 2개가 나갔는..

인덱스를 타지 않는 쿼리, 원인과 점검

인덱스를 타지 않는 쿼리, 원인과 점검결론부터인덱스를 걸었는데 쿼리가 느리다면, 십중팔구 옵티마이저가 인덱스를 안 쓰기로 결정한 것이다. 인덱스 존재와 인덱스 사용은 다르다. 원인은 대개 정해져 있다 — 인덱스 컬럼을 가공하거나, 타입이 어긋나거나, 복합 인덱스의 선두 컬럼을 빠뜨렸거나, 선택도가 낮은 경우다. 추측하기 전에 EXPLAIN으로 실제 실행 계획부터 확인하는 게 순서다.확인: EXPLAIN부터EXPLAINSELECT * FROM orders WHERE customer_id = 1001;type 컬럼이 ALL이면 풀 테이블 스캔, ref·range·const면 인덱스를 탄 것이다. key 컬럼에서 실제로 어떤 인덱스가 선택됐는지도 함께 본다. 여기서 ALL이 보이면 아래 원인들을 하나씩 대조한..

Flyway로 끝내는 Spring Boot DB 마이그레이션 실전 가이드

ddl-auto: update로 운영 DB를 관리하다가 컬럼 하나가 조용히 사라지는 경험, 한 번쯤 있으실 겁니다. JPA의 자동 DDL은 편하지만 "언제, 누가, 무엇을" 바꿨는지 기록이 남지 않습니다. 코드에는 Git이 있는데 DB 스키마에는 버전 관리가 없는 셈이죠. 이 공백을 메우는 도구가 바로 Flyway입니다.Flyway가 하는 일Flyway는 SQL 마이그레이션 파일을 버전 순서대로 실행하고, 실행 이력을 flyway_schema_history 테이블에 기록합니다. 애플리케이션이 시작될 때 아직 적용되지 않은 버전만 골라 실행하므로, 어느 환경에서든 스키마가 동일한 상태로 수렴합니다.핵심 개념은 세 가지입니다.Versioned Migration (V): 한 번만 실행되는 변경. V1__cre..

MariaDB vs MySQL 차이와 선택 기준

MariaDB vs MySQL 차이와 선택 기준 (2026)2026년 기준 결론부터 정리하면, 신규 프로젝트에서 선택지는 MySQL 8.4 LTS와 MariaDB 11.8 LTS(또는 12.3 LTS) 두 갈래입니다. MySQL 8.0은 2026년 4월에 지원이 종료(EOL)되어 더 이상 프로덕션 선택지가 아닙니다. 두 DB는 같은 뿌리(MySQL 5.5)에서 갈라졌지만 이제는 서로의 드롭인(drop-in) 대체재가 아니며, 라이선스·클라우드 지원·기능 방향이 뚜렷하게 달라졌습니다.이 글에서는 2026년 시점의 버전 현황과 실질적인 차이, 그리고 프로젝트 성격별 선택 기준을 정리합니다.2026년 버전 현황구분MySQLMariaDB현재 LTS8.4 LTS11.8 LTS, 12.3 LTS지원 종료8.0 → ..

MariaDB 버전 선택 가이드

2026년 7월 기준 MariaDB의 최신 LTS는 12.3입니다. 2026년 5월에 출시됐고 2029년 6월까지 지원되므로, 신규 프로젝트라면 12.3 LTS가 기본 선택입니다. 반대로 10.6 LTS는 2026년 7월 6일자로 커뮤니티 지원이 종료됐기 때문에, 아직 운영 중이라면 지금이 업그레이드를 계획할 시점입니다.이 결론의 배경이 되는 MariaDB의 릴리스 모델과 버전별 지원 기간, 그리고 상황별 선택 기준을 차례로 정리합니다.LTS와 롤링 릴리스, 무엇이 다른가MariaDB는 두 종류의 릴리스를 냅니다.LTS(Long Term Support): 매년 1회 나오는 장기 지원 버전입니다. 11.4까지는 5년, 11.8부터는 3년간 버그·보안 패치가 제공됩니다.롤링(rolling) 릴리스: 분기마다..

MariaDB 복합 인덱스로 느린 목록 조회 개선하기

MariaDB 복합 인덱스로 느린 목록 조회 개선하기인덱스는 붙였는데 왜 안 빨라질까커뮤니티 서비스를 운영하다 보면 가장 먼저 느려지는 곳이 목록 조회다. 게시글이 수천, 수만 건으로 쌓이면 "특정 카테고리의 글을 최신순으로 20개" 같은 단순한 쿼리조차 눈에 띄게 버벅인다.이럴 때 흔히 하는 대응이 "일단 인덱스를 걸어보자"다. 그런데 인덱스를 붙였는데도 속도가 그대로인 경우가 많다. 원인은 대부분 조회 패턴과 맞지 않는 인덱스를 만들었기 때문이다. 인덱스는 무작정 컬럼에 붙인다고 효과가 나는 게 아니라, 쿼리가 데이터를 찾고 정렬하는 방식에 맞춰 설계해야 한다.실제로 Kraft(kraft.io.kr)를 운영하면서도 데이터가 늘자 게시글 목록이 느려진 적이 있는데, category_id로 필터링하면서 ..

728x90