Phase 2b: 11개 모듈 전량 실동작 (333 서비스, 전서버 부팅)

- 10개 모듈 추가/확장(au py rc st lg cl mm vl mg cm), 각 30 서비스 = 330 + tmsrv
- build.sh 자동발견으로 11 모듈서버 + dbio 라이브러리 23 + 배치 22 빌드
- schema.d 11파일 → 75 테이블, 모듈별 disjoint
- 부팅 리소스 규명: fs.mqueue.queues_max=8192(330큐>256), NDRX_MSGSIZEMAX 16000·
  MSGMAX 50(큐당 5.6MB→0.8MB), msgqueue ulimit 2GB → 전 12서버 runok
- 검증: xadmin psc 333 AVAIL, 매입체인 XA 커밋, prepared_xacts=0

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
forge-bot 2026-07-19 09:58:39 +00:00
parent 8219b85f14
commit bec83c721e
73 changed files with 10705 additions and 35 deletions

View file

@ -0,0 +1,71 @@
/*
* cl_daily_batch.pgc - cl 일 마감 배치 (미마감 점검 + 커서 M->S + XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction. 먼저 당일 대사완료(M) 미마감 매입 건수를 점검하고, 커서로 각 건을
* 정산완료(S)로 마감 전환한 뒤, 당일 마감이력(close_log, DAILY)을 집계와 함께
* 기록한다. tpcommit 이 XA 2PC 를 구동. Usage: cl_daily_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "cl_dbio.h"
int main(int argc, char **argv)
{
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
long closed = 0, cid;
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16];
long h_pid, h_unclosed, h_cnt, h_amt;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
/* 1) 미마감(대사완료 M) 점검 */
EXEC SQL SELECT count(*) INTO :h_unclosed FROM purchase
WHERE biz_date = :h_bizdate AND status = 'M';
if (sqlca.sqlcode < 0) { fprintf(stderr, "COUNT FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
printf(">>> cl_daily_batch 미마감(M) 점검: bizdate=%s 대상=%ld건\n", bizdate, h_unclosed);
/* 2) 커서로 M -> S 마감 전환 */
EXEC SQL DECLARE cdc CURSOR FOR
SELECT purchase_id FROM purchase
WHERE biz_date = :h_bizdate AND status = 'M'
ORDER BY purchase_id;
EXEC SQL OPEN cdc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
for (;;) {
EXEC SQL FETCH cdc INTO :h_pid;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE cdc; tpabort(0); return 1; }
EXEC SQL UPDATE purchase SET status = 'S', updated_at = now() WHERE purchase_id = :h_pid;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE cdc; tpabort(0); return 1; }
closed++;
}
EXEC SQL CLOSE cdc;
/* 3) 당일 집계 + 마감이력(DAILY) 기록 (via dbio) */
EXEC SQL SELECT count(*), coalesce(sum(amount),0) INTO :h_cnt, :h_amt
FROM purchase WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { tpabort(0); return 1; }
cid = cldb_next_close_id();
if (cid < 0) { tpabort(0); return 1; }
if (cldb_insert_close(cid, "DAILY", bizdate, bizdate, "C", h_cnt, h_amt, "일마감(배치)") < 0) {
tpabort(0); return 1;
}
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cl_daily_batch COMMIT: bizdate=%s 마감전환=%ld cid=%ld 총건수=%ld\n",
bizdate, closed, cid, h_cnt);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,66 @@
/*
* cl_snapshot_batch.pgc - cl 마감 스냅샷 배치 (커서 + XA).
*
* 당일 마감(close_log, DAILY)에 대해 merchant_summary 를 가맹점별로 커서 순회하여
* cl_snapshot 에 고정 복사(스냅샷)한다. 마감 시점의 가맹점별 집계를 불변 기록으로
* 남긴다. 모두 ONE global XA transaction 하에서 수행.
* Usage: cl_snapshot_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "cl_dbio.h"
int main(int argc, char **argv)
{
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
long rows = 0, sid;
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16], h_merch[64];
long h_cid, h_gross, h_fee, h_net, h_cnt;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
/* 당일 최종 DAILY 마감 id 조회 (없으면 스냅샷 생략) */
EXEC SQL SELECT coalesce(max(close_id), 0) INTO :h_cid FROM cl_close_log
WHERE close_type = 'DAILY' AND biz_date = :h_bizdate AND status <> 'X';
if (sqlca.sqlcode < 0) { fprintf(stderr, "CID FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (h_cid == 0) {
printf(">>> cl_snapshot_batch: bizdate=%s DAILY 마감 없음 -> 스냅샷 생략\n", bizdate);
tpabort(0); tpclose(); tpterm(); return 0;
}
EXEC SQL DECLARE csc CURSOR FOR
SELECT merchant_id, gross_amount, fee_amount, net_amount, txn_count
FROM merchant_summary WHERE biz_date = :h_bizdate
ORDER BY merchant_id;
EXEC SQL OPEN csc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
for (;;) {
EXEC SQL FETCH csc INTO :h_merch, :h_gross, :h_fee, :h_net, :h_cnt;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE csc; tpabort(0); return 1; }
sid = cldb_next_snapshot_id();
if (sid < 0) { EXEC SQL CLOSE csc; tpabort(0); return 1; }
if (cldb_insert_snapshot(sid, h_cid, bizdate, bizdate, h_merch,
h_gross, h_fee, h_net, h_cnt) < 0) {
EXEC SQL CLOSE csc; tpabort(0); return 1;
}
rows++;
}
EXEC SQL CLOSE csc;
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> cl_snapshot_batch COMMIT: bizdate=%s cid=%ld 스냅샷=%ld건\n", bizdate, h_cid, rows);
tpclose(); tpterm();
return 0;
}