본문 바로가기
반응형

전체 글253

[Database] 재실행 가능한 백필과 데이터 교정은 왜 분리해야 할까 실시간 전송에서 빠진 데이터를 다시 채우는 백필을 구현하고, 보관본을 재실행해 보면서 누락 보충과 기존 값 교정이 서로 다른 작업이라는 사실을 확인한 과정을 정리했다.시작하며데이터는 평소 실시간 경로로 서버에 전달됐다. 하지만 네트워크가 끊기거나 전송 프로세스가 멈추면 일부 구간이 로컬에만 남을 수 있었다. 이 누락을 복구하기 위해 로컬에서 만든 일별 CSV를 서버에 보내 빈 구간을 채우는 백필 API를 구현했다.실시간 전송수집 장치 ──────────────▶ 중앙 저장소 일부 구간 누락백필수집 장치의 일별 CSV ───▶ 누락된 행 보충백필에서 가장 중요하게 본 조건은 재실행 가능성이었다. 전송하는 쪽은 중앙 저장소에 어떤 행이 이미 들어갔는지 알 수 없었고, 실패 지점도 정확히 알기.. 2026. 9. 6.
[Data] 서로 다른 저장소의 시계열 데이터를 외부 JSON 계약으로 만들기 메타데이터와 시계열 값이 서로 다른 저장소에 있을 때, 내부 식별자로 데이터를 결합하되 외부에는 필요한 의미만 남기는 JSON 계약을 만든 과정을 정리했다.시작하며외부 시스템에 하루치 시계열 데이터를 파일로 전달해야 했다. 처음에는 필요한 행을 조회해 파일로 저장하면 되는 작업처럼 보였다.하지만 실제 데이터는 한곳에 있지 않았다.항목의 이름, 단위와 활성 상태는 신규 메타데이터 저장소에 있었다.시각별 값은 기존 시계열 저장소에 있었다.시계열 저장 영역은 대상과 날짜에 따라 나뉘어 있었다.두 저장소를 연결하는 내부 ID는 외부 사용자가 알 필요가 없었다.값이 없는 항목도 “항목은 있지만 그날 값은 없음”으로 표현해야 했다.생성된 JSON은 이후 다른 파일과 함께 묶여 외부로 전달됐다.내부 테이블 구조를 그.. 2026. 9. 5.
[Trino] 같은 서버의 MySQL인데 왜 연결이 타임아웃됐을까 여러 서비스가 정상 실행 중인데도 대시보드 요청이 60초 뒤 503으로 끝난 상황에서, Gateway부터 Trino Catalog와 서버 방화벽까지 연결 경로를 좁혀 간 과정을 정리했다. 같은 서버의 MySQL을 공인 IP로 호출하던 JDBC 주소를 loopback으로 바꾼 뒤 동일한 요청이 정상화된 결과까지 다룬다.시작하며같은 시각에 서로 다른 대시보드 위젯 두 개가 모두 503을 반환했다.GET /dashboard/widgets/metric-aGET /dashboard/widgets/metric-bHTTP 503 Service Unavailable요청 전달에 실패했습니다.조회 서비스에 연결하지 못했습니다: 요청 시간이 초과되었습니다.처음에는 조회 API가 종료됐거나 Trino가 멈췄다고 생각했다. 하.. 2026. 9. 4.
[Trino] MySQL은 연결되는데 Trino Worker는 연결되지 않았던 이유 데이터베이스 연결 문제로 보였던 Trino 장애에서 타임존이라는 가설을 거쳐, 실제 원인이 서로 다른 VPC 사이의 Worker 통신이라는 것을 확인한 과정을 정리했다.시작하며여러 MySQL을 Trino Catalog로 연결하는 과정에서 일부 데이터 소스의 조회가 실패했다. 대상 MySQL에는 CLI로 바로 접속할 수 있었고 계정과 비밀번호도 정상이었다.mysql -h DB_HOST -u READ_ONLY_USER -p처음에는 JDBC Driver와 MySQL의 타임존 협상을 의심했다. JVM 타임존과 Trino 세션 타임존을 확인하고 설정도 변경했지만 장애는 해결되지 않았다.결국 문제는 MySQL 연결보다 앞선 곳에 있었다. 다른 VPC에 설치한 Trino Worker가 자신의 사설 IP로 등록됐고, .. 2026. 8. 30.
[Trino] MySQL SQL을 Trino로 옮길 때 문법보다 의미가 어려웠던 이유 MySQL 조회문을 Trino SQL로 변환하면서 단순한 Dialect 변환만으로 해결되지 않았던 시간대, 주차 계산, 사용자 지정 정렬 문제를 정리했다.시작하며여러 MySQL 데이터 소스를 Trino에서 통합 조회하려면 기존에 저장된 MySQL SQL도 Trino가 실행할 수 있는 형태로 바꿔야 했다.처음에는 이 작업을 문법 변환 문제로 생각했다.MySQL SQL → MySQL 문법으로 Parse → Trino Dialect로 출력 → Trino에서 실행실제로 identifier quoting이나 일부 함수명처럼 SQL Dialect만 지정해도 변환되는 부분이 있었다. 하지만 변환된 SQL이 문법적으로 유효하다고 해서 원래 SQL과 같은 결과를 반환하는 것은 아니었다.다음과 같은 문제가 남았다.같.. 2026. 8. 29.
[Trino] 여러 MySQL 데이터 소스를 Trino로 통합 조회하기 여러 MySQL 서버에 분산된 데이터를 Catalog로 추상화하고, 기존 MySQL 조회문을 별도 변환 서비스와 라우팅 로직을 거쳐 Trino SQL로 바꾼 과정을 정리했다.시작하며서비스가 처음 만들어졌을 때는 하나의 MySQL 연결만으로 필요한 데이터를 조회할 수 있었다. 이후 데이터 규모와 운영 단위가 늘어나면서 데이터가 여러 MySQL 서버로 나뉘었다.여러 운영 단위의 데이터 → 서로 다른 MySQL 서버에 분산 저장 → Trino를 통해 통합 조회애플리케이션이 각 MySQL에 직접 연결하도록 만들면 조회할 때마다 다음 작업이 필요하다.요청 대상의 데이터 위치를 확인한다.해당 서버의 연결 풀을 선택한다.쿼리를 실행한다.여러 서버에 걸친 결과를 애플리케이션에서 합친다.데이터 소스가 추가되면 연결 .. 2026. 8. 29.
[Git] 특정 폴더의 저장소에만 다른 사용자 정보 적용하기 개인 프로젝트와 업무 프로젝트를 한 컴퓨터에서 관리할 때, 저장소마다 설정을 반복하지 않고 상위 폴더를 기준으로 Git 커밋 작성자 정보를 분리하는 방법을 정리했다.시작하며한 컴퓨터에서 개인 프로젝트와 업무 프로젝트를 함께 관리하면 Git 커밋에 사용할 이름과 이메일을 구분해야 할 때가 있다.~/dev/personal/ → 개인 이름과 이메일~/dev/company/ → 업무용 이름과 이메일Git의 전역 사용자 정보를 업무 계정으로 바꾸면 개인 저장소에도 같은 정보가 적용된다. 반대로 저장소마다 로컬 설정을 추가하면 저장소를 새로 만들거나 내려받을 때마다 같은 작업을 반복해야 한다.원하는 동작은 다음과 같았다.기본적으로 개인 사용자 정보를 사용한다.특정 폴더 아래의 저장소에서는 업무용 사용자 정보를.. 2026. 8. 23.
[Database] 양방향 데이터 동기화에서 최신 데이터를 판단하는 방법 서로 다른 스키마를 사용하는 두 시스템이 동시에 운영될 때, 단순 복사와 무조건 덮어쓰기의 문제를 거쳐 데이터별 충돌 처리 기준을 정한 과정을 정리했다.시작하며기존 시스템을 새 구조로 전환하는 동안 두 시스템을 동시에 운영해야 했다. 신규 시스템으로 한 번에 모든 기능과 사용자를 옮길 수 없었기 때문에, 일정 기간에는 양쪽 모두에서 데이터가 생성되고 수정됐다.처음 필요한 기능은 단순해 보였다.기존 DB의 데이터를 읽는다. ↓신규 DB의 컬럼에 맞게 변환한다. ↓신규 DB에 INSERT 한다.하지만 반대 방향의 전달이 추가되고 이미 존재하는 데이터도 다시 맞춰야 하면서 이 작업은 일회성 마이그레이션이 아니게 됐다. 같은 식별자의 데이터가 양쪽에 모두 존재할 때 어느 값을 남겨야 하는지 판단해야 .. 2026. 8. 23.
[Design Pattern] 서로 다른 데이터 스키마를 하나의 API로 다루기 같은 API를 유지하면서 Legacy와 Current 데이터 스키마를 함께 지원하기 위해 Strategy, Resolver, Repository의 책임을 분리한 과정을 정리했다.시작하며여러 서버에 같은 데이터 서비스를 배포해야 했지만 모든 서버의 데이터베이스 구조가 같지는 않았다. 기존 서버는 Legacy 스키마를 사용하고, 이후 구축된 서버는 서로 다른 식별 체계와 테이블 구성을 가진 Current 스키마를 사용했다.예를 들어 Legacy 스키마는 소유자와 분류 코드를 별도 컬럼으로 관리했지만, Current 스키마는 이를 하나의 범위 식별자로 통합하고 컬럼 이름도 정리했다고 가정한다.Legacy legacy_records(owner_code, category_code, created_timestam.. 2026. 8. 18.
[Server] 보상 작업으로 다단계 생성 흐름의 실패 범위 줄이기 하나의 요청이 여러 저장소와 외부 시스템을 거칠 때, 완료된 단계를 기록하고 역순으로 보상하도록 구성한 과정과 그 한계를 정리했다.시작하며관리 화면에서 하나의 항목을 생성하더라도 서버 내부에서는 여러 작업이 이어질 수 있다.사용할 식별자를 예약한다.기본 정보를 저장한다.하위 자원을 생성한다.정책과 설정을 적용한다.사용자 접근 권한을 연결한다.외부 시스템에 결과를 동기화한다.각 단계가 같은 데이터베이스와 연결만 사용한다면 하나의 트랜잭션으로 묶을 수 있다. 하지만 실제 작업에는 서로 다른 저장소, 파일 변경, 네트워크 호출이 섞여 있었다. 모든 단계를 하나의 데이터베이스 트랜잭션으로 감싸는 것만으로는 실패를 되돌릴 수 없었다.이 글에서는 긴 생성 작업을 단계로 나누고, 중간 실패 시 이미 완료된 작업을 역.. 2026. 8. 15.
반응형