LabHub
배우기 러닝패스 코스

銀行現場の言葉

死んだ日次締めを冪等に蘇らせる

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

도중에 죽은 일마감을 재수행해 되살리되, 이중 반영도 누락도 없이 끝낼 수 있게 됩니다. 그리고 계정일자와 시스템 시각을 구분해 마감 대상을 고르는 손을 갖게 됩니다.

왜 중요한가

은행 시스템에는 시계가 가리키는 시각(posted_at)과 장부가 인정하는 날짜(biz_date)가 따로 있습니다. 계정일자는 마감 배치가 끝나야 넘어가므로, 마감이 도는 동안 들어온 거래는 어느 날짜에 잡을지가 애매해집니다. 여기서 나는 사고가 은행 배치 장애의 큰 몫입니다.

마감 배치는 반드시 멱등해야 합니다. 같은 계정일자에 대해 몇 번을 돌려도 결과가 같아야 한다는 뜻입니다. 그렇지 않으면 배치가 죽었을 때 다시 돌리는 것 자체가 새로운 장애가 됩니다. 재수행 방식은 두 가지뿐인데, 이미 반영된 것 위에 안 된 것만 더하는 증분 방식은 "이미 반영된 것이 전부 옳다" 를 전제합니다. 그 전제가 깨져 있으면 증분 방식은 잘못 들어간 것을 빼낼 수단이 없습니다.

이번 사건은 이렇습니다. 2026-08-25 일마감 배치가 22:10 에 시작해 도중에 죽었습니다. 계정일자 2026-08-25 의 분개행 240줄 중 153줄이 반영된 상태이고, 마감 산출물의 잔액 합이 0 이 아닙니다. 게다가 마감이 도는 동안 온라인 채널 하나가 계속 옛 계정일자를 찍고 있었습니다. 컷오프는 2026-08-25T22:10:00 이고 익영업일은 2026-08-26 입니다.

단계

  1. /root/bank/gen_eod.py 를 만들어 실행해 /root/bank/eod.db 를 만드세요. 분개행 372줄과 마감 이력이 들어갑니다.
  2. /root/bank/eod_state.txt 에 일곱 줄을 적으세요. business_date=, eod_status=sys_param 에서, txn_total=, applied=, unapplied= 는 그 계정일자의 txn 에서, balance_rows=, closing_sum=daily_balance 에서 냅니다.
  3. posted_at 이 컷오프 이후이면서 biz_date2026-08-25 인 줄을 /root/bank/misdated.csvtxn_id,posted_at,biz_date,eod_applied 머리글로 뜨세요. 그리고 /root/bank/misdated.txtmisdated=, misdated_applied=, naive_after_cutoff= 세 줄을 적습니다. 마지막 값은 계정일자를 보지 않고 posted_at 만으로 걸렀을 때의 줄 수입니다.
  4. 그 줄들의 biz_date2026-08-26 으로 옮기고 eod_applied0 으로 되돌리세요. 이미 마감이 끝난 2026-08-24 는 건드리지 않습니다.
  5. /root/bank/rerun_plan.md## 두 가지 재수행 방식, ## 선택과 근거, ## 멱등성을 어떻게 보장하나, ## 중단 기준 네 절로 계획을 쓰세요. 선택과 근거 절에는 재계산 대상 줄 수가 숫자로 들어가야 합니다.
  6. /root/bank/eod_rerun.sh 를 만들어 한 번 실행하고, 산출물을 /root/bank/db_run1.csvbiz_date,account,debit_total,credit_total,closing_balance 머리글로 뜨세요. eod_run 에 성공 이력도 남깁니다.
  7. 같은 스크립트를 한 번 더 실행하고 /root/bank/db_run2.csv 를 뜬 뒤, /root/bank/idempotency.txtrun1_rows=, run1_closing_sum=, run2_rows=, run2_closing_sum=, diff= 다섯 줄을 적으세요.
  8. sys_parameod_statusCLOSED 로, business_date2026-08-26 으로 넘기고, /root/bank/eod_report.md## 무엇이 멈췄나, ## 계정일자가 왜 어긋났나, ## 재수행을 어떻게 안전하게 만들었나, ## 검증, ## 남은 위험 다섯 절로 보고서를 쓰세요.

참고

마감이 죽은 순간 재현하기

/root/bank/gen_eod.py 를 만들어 실행해 /root/bank/eod.db 를 만드세요. 분개행 372줄과 마감 이력이 들어갑니다.

python3 로 /root/bank/eod.db 를 만듭니다. 표는 sys_param, txn, daily_balance, eod_run 네 개이고 분개행은 372줄입니다.

죽은 마감이 어디까지 갔는지 세기

/root/bank/eod_state.txt 에 일곱 줄을 적으세요. business_date=, eod_status=sys_param 에서, txn_total=, applied=, unapplied= 는 그 계정일자의 txn 에서, balance_rows=, closing_sum=daily_balance 에서 냅니다.

마감 대상은 posted_at 이 아니라 biz_date 로 고릅니다. 산출물의 closing_balance 합이 0 인지도 보세요 — 0 이 아니면 전표 한쪽만 반영된 것입니다.

계정일자가 잘못 찍힌 거래 찾기

posted_at 이 컷오프 이후이면서 biz_date2026-08-25 인 줄을 /root/bank/misdated.csvtxn_id,posted_at,biz_date,eod_applied 머리글로 뜨세요. 그리고 /root/bank/misdated.txtmisdated=, misdated_applied=, naive_after_cutoff= 세 줄을 적습니다. 마지막 값은 계정일자를 보지 않고 posted_at 만으로 걸렀을 때의 줄 수입니다.

조건이 두 개입니다. posted_at 이 컷오프 이후이고, 동시에 biz_date 가 마감일인 줄. 앞의 조건만으로 거르면 제대로 익일자를 찍은 다른 채널의 거래까지 딸려 옵니다.

계정일자를 익영업일로 옮기기

그 줄들의 biz_date2026-08-26 으로 옮기고 eod_applied0 으로 되돌리세요. 이미 마감이 끝난 2026-08-24 는 건드리지 않습니다.

biz_date 만 바꾸면 안 됩니다. 이미 마감 산출물에 반영된 줄이 섞여 있으니 eod_applied 도 함께 되돌려야 합니다. 이미 마감이 끝난 전날은 건드리지 마세요.

재수행 방식 정하고 근거 쓰기

/root/bank/rerun_plan.md## 두 가지 재수행 방식, ## 선택과 근거, ## 멱등성을 어떻게 보장하나, ## 중단 기준 네 절로 계획을 쓰세요. 선택과 근거 절에는 재계산 대상 줄 수가 숫자로 들어가야 합니다.

네 절이 필요합니다. 선택과 근거 절에는 재계산 대상이 몇 줄인지 숫자로 적고, 멱등성 절에는 어느 표를 어떻게 다루는지 적으세요.

재수행 스크립트 만들어 한 번 돌리기

/root/bank/eod_rerun.sh 를 만들어 한 번 실행하고, 산출물을 /root/bank/db_run1.csvbiz_date,account,debit_total,credit_total,closing_balance 머리글로 뜨세요. eod_run 에 성공 이력도 남깁니다.

손으로 SQL 을 치지 말고 스크립트로 만드세요. 두 번째 실행이 첫 번째와 문자 그대로 같아야 멱등성을 시험할 수 있습니다. 그리고 1회차 산출물을 CSV 로 떠 두세요.

한 번 더 돌려 멱등성 증명하기

같은 스크립트를 한 번 더 실행하고 /root/bank/db_run2.csv 를 뜬 뒤, /root/bank/idempotency.txtrun1_rows=, run1_closing_sum=, run2_rows=, run2_closing_sum=, diff= 다섯 줄을 적으세요.

같은 스크립트를 그대로 다시 실행하고 산출물을 다시 뜨세요. 두 CSV 를 줄 단위로 비교한 결과가 diff 입니다. 값이 두 배가 됐다면 지우지 않고 더한 것입니다.

마감 확정하고 계정일자 넘기기

sys_parameod_statusCLOSED 로, business_date2026-08-26 으로 넘기고, /root/bank/eod_report.md## 무엇이 멈췄나, ## 계정일자가 왜 어긋났나, ## 재수행을 어떻게 안전하게 만들었나, ## 검증, ## 남은 위험 다섯 절로 보고서를 쓰세요.

산출물을 만든 것과 마감을 확정한 것은 다른 일입니다. sys_param 의 마감 상태와 계정일자를 함께 넘기세요. 그리고 보고서 다섯 절을 쓰세요.