InnoDB에서 PK 없는 테이블의 동작과 트레이드오프

개념과 배경 InnoDB는 데이터를 클러스터형 인덱스 기준으로 저장하는 스토리지 엔진임 대부분의 테이블에서 이 클러스터형 인덱스는 프라이머리 키가 담당함 사용자가 명시적으로 PK를 정의하지 않은 경우에도 InnoDB는 테이블에 클러스터 키를 반드시 갖도록 함 이때 결정 규칙이 존재함 먼저 NOT NULL 제약을 가진 유니크 인덱스가 있으면 그것을 클러스터형 인덱스로 사용 그런 인덱스가 없으면 내부 6바이트 row_id를 생성해 숨김 PK로 사용 세컨더리 인덱스는 항상 클러스터 키를 포함하여 룩업을 수행함 따라서 명시적 PK가 없더라도 내부적으로는 클러스터 키가 존재하며 저장과 탐색 경로의 기준으로 동작함 ...

October 26, 2025

Node.js 환경에서 디버깅하기

개요 Node.js에서 디버깅은 문제를 재현 가능한 최소 단위로 축소하고, 실행 흐름과 상태를 관찰해 원인을 단정하는 과정임. 이 글은 디버깅 기본 원리와 함께 Node.js 환경에서 자주 쓰는 세 가지 방법인 Chrome DevTools, node-inspect CLI, VS Code 디버거 사용법을 정리함 문제를 명확히 하기 작성한 코드의 기대 동작 정의 실제 관측된 동작과의 차이 정리 실패 조건과 재현 절차 고정 문제 정의가 모호하면 디버깅 범위가 불필요하게 커짐. 입력, 환경 변수, 의존성 버전, 네트워크 상태 등 외부 요인도 고정하는 편이 좋음 ...

October 23, 2025

TypeScript enum, const enum, as const 차이와 선택 기준

개요 TypeScript에서 enum, const enum, as const는 값 집합을 선언하고 타입으로 활용하기 위한 서로 다른 도구임 각 특성의 차이와 트레이드오프를 이해하면 가독성과 안정성을 챙기면서 번들 크기와 도구 호환성 문제도 피할 수 있음 enum 개념과 동작 열거형 타입을 선언하는 문법 숫자 기반과 문자열 기반 모두 지원 컴파일 결과로 양방향 매핑을 담은 JS 객체 생성 키로 값 조회, 값으로 키 역조회 가능 예시 enum BooleanType { False = 0, True = 1, }컴파일 결과는 즉시실행함수 형태로 양방향 맵 객체 생성됨 ...

October 21, 2025

SQL LIMIT와 OFFSET 사용법 정리: 행 개수 제한과 페이징

기본 문법 LIMIT는 SELECT 결과에서 반환할 행 수를 제한하는 구문 WHERE와 ORDER BY 뒤, 즉 SELECT 문 끝에 위치 두 가지 형태 사용 SELECT 컬럼명 FROM 테이블명 LIMIT 개수 SELECT 컬럼명 FROM 테이블명 LIMIT 개수 OFFSET 시작_인덱스일부 dialect에서는 아래 축약형도 존재 -- MySQL, SQLite SELECT 컬럼명 FROM 테이블명 LIMIT 시작_인덱스, 개수1. LIMIT 개수 LIMIT 뒤 숫자는 인덱스가 아닌 개수 SELECT * FROM Book LIMIT 1현재 정렬 기준에서 맨 위 행 1개만 반환 ORDER BY가 없으면 반환되는 행은 비결정적일 수 있음 2. LIMIT 개수 OFFSET 시작 OFFSET은 0부터 시작 다음 예시는 4번째 행부터 1개 반환 ...

October 20, 2025

Node.js v8-inspector 디버깅 가이드 — --inspect와 node-inspect 사용법

개요 Node.js 디버깅 환경은 V8 인스펙터 도입 이후 일관된 방식으로 수렴했음 Node.js v6부터 V8 네이티브 인스펙터가 들어왔고 v8.0.0에서 v8-inspector를 본격 지원하면서 기존 –debug는 폐기, –inspect로 통일됨 CLI 디버거 node-inspect가 코어에 통합되어 브라우저 개발자도구와 커맨드라인 중 선택 가능함 이 글은 Node.js 8 이상에서 동작하는 v8-inspector 기반 디버깅 플로우를 요약함 핵심 개념 v8-inspector 프로토콜 V8이 노출하는 디버깅 프로토콜 Node 프로세스가 WebSocket 엔드포인트를 열고 디버거가 여기에 연결하는 구조 –inspect vs –inspect-brk –inspect는 바로 실행하면서 디버거 접속 대기 –inspect-brk는 첫 줄에서 일시정지 후 시작, 초기화 로직부터 추적할 때 유용 포트 기본 포트 9229 사용 –inspect=PORT, –inspect-brk=PORT 형태로 변경 가능 프론트엔드 Chromium 기반 개발자도구로 연결 가능 chrome://inspect 에서 Node 대상 탐색 및 연결 node-inspect Node 내장 CLI 디버거 동일한 인스펙터 포트로 접속하여 터미널에서 스텝 실행과 REPL 수행 크롬 개발자도구로 디버깅 Express 같은 서버 앱을 예시로 실행 파일이 bin/www라고 가정 ...

October 19, 2025

쿠버네티스 컨트롤 플레인 핵심 개념과 EKS 비교

컨트롤 플레인은 쿠버네티스 클러스터의 두뇌이자 의사결정 계층으로, 워커 노드가 실제 워크로드를 돌리는 동안 전체 상태를 정의하고 조율하는 역할을 맡음 조직 비유로 보면 컨트롤 플레인은 본사와 경영진, 워커 노드는 지점과 현장 직원에 해당함 개념과 정의 컨트롤 플레인은 Desired State를 선언적으로 저장하고, Observed State와 비교해 일치하도록 끊임없이 조정하는 계층 사용자는 API를 통해 상태를 선언하고, 컨트롤 플레인은 스케줄링과 컨트롤 루프로 이를 만족하도록 시스템을 수렴시킴 핵심 구성요소 API 서버 kube-apiserver — 모든 요청의 진입점, 인증·인가·어드미션 수행 후 상태 변경을 etcd에 반영 ...

October 18, 2025

NestJS Guard로 요청 보호하기 — CanActivate, UseGuards, Bearer 인증 예시

개요 가드 Guard를 이용해 NestJS 애플리케이션을 위험한 요청으로부터 차단하는 방법 정리 컨트롤러에 도달하기 전 단계에서 인증과 접근 제어 수행하는 패턴 중심으로 설명 가드란 NestJS에서 가드는 애플리케이션에 들어오는 요청을 컨트롤러로 보내기 전에 통과 여부를 결정하는 구성 요소 미들웨어와 유사한 역할이지만 라우트 핸들러 실행 여부를 명시적으로 결정하는 책임에 초점 요청 수명주기에서 미들웨어 다음, 컨트롤러 이전에 실행됨 canActivate가 true 또는 Promise을 반환하면 다음 단계로 진행, false면 기본적으로 403 Forbidden 응답 발생 ...

October 17, 2025

Kubernetes 핵심 구성요소와 동작 흐름

개요 쿠버네티스는 제어 평면과 워커 노드, 그리고 그 사이를 매개하는 런타임과 커널 메커니즘이 맞물려 동작하는 분산 시스템 핵심은 단일 진실 소스에 원하는 상태를 기록하고, 이를 지속적으로 감시하고 조정해 실제 상태를 일치시키는 루프 각 컴포넌트의 역할과 상호작용을 이해하면 장애 대응, 스케일링, 성능 튜닝의 기준점 확보 가능 구성요소 관계 한눈에 kubectl / CI │ ▼ kube-apiserver ──> etcd │ ▲ │ └(상태 영속) │ ├─ kube-scheduler(어디 배치할지 결정) └─ kube-controller-manager(원하는 상태로 맞춤: ReplicaSet 등) [각 워커 노드] kubelet ──(CRI gRPC)──> container runtime ──(OCI)──> runc/crun ──> cgroup 설정 + 컨테이너 시작 │ │ ├─(CNI 호출) 네트워크/IP 할당 └─ 네임스페이스/마운트 등 격리 └─ kube-proxy(서비스 라우팅: iptables/ipvs) 모든 컴포넌트의 권위자이자 입구는 apiserver etcd와 직접 통신하는 주체는 apiserver만 존재 kubelet은 apiserver를 watch하여 자신에게 배정된 파드 감지 container runtime은 OCI 런타임을 통해 cgroup과 네임스페이스를 세팅하고 컨테이너 프로세스 실행 Pod 생성에서 Running까지 사용자가 kubectl apply 등으로 Desired State를 제출하면 apiserver가 인증과 유효성, 어드미션을 거쳐 etcd에 영속화 controller-manager가 오브젝트를 관찰하고 필요한 부수 리소스를 생성, 예 ReplicaSet과 Pod 등 scheduler가 Pending 파드에 대해 노드 배치를 결정, 리소스 요청, 어피니티, 토폴로지, taint와 tolerance 등을 고려해 Pod에 NodeName 바인딩 대상 노드의 kubelet이 apiserver watch로 자신에게 할당된 파드 탐지 kubelet이 이미지 풀, 볼륨 마운트, 네트워크 준비를 순차 수행, CNI 플러그인을 호출해 인터페이스와 IP 할당 kubelet이 CRI를 통해 container runtime에 파드와 컨테이너 생성 요청 전달 runtime이 OCI 런타임 runc 또는 crun을 호출하여 cgroup 생성과 리눅스 네임스페이스 PID NET MNT UTS IPC 설정 후 엔트리포인트 실행 kubelet이 liveness readiness 스타트업 프로브로 상태를 확인하고 apiserver로 주기 보고 kube-proxy가 Service와 Endpoints 변경을 반영해 iptables 혹은 ipvs 규칙 갱신, 서비스 트래픽 라우팅 경로 성립 클러스터 DNS와 Service IP를 통해 파드로 트래픽 전달 완료 cgroup과 리소스 제한 연결 PodSpec의 resources.requests와 limits가 kubelet을 거쳐 runtime에 전달되고, runtime과 OCI가 cgroup v1 또는 v2에 실제 quota와 limit 설정 CPU는 shares와 quota를 통해 스케줄러 가중치와 시간 쿼터 부여 메모리는 hard limit과 OOM killer 점수 조정으로 커널 레벨 강제 쿠버네티스 리소스 제한의 실체는 cgroup 설정이라는 점이 핵심 장애·스케일·자체 복구 흐름 컨테이너 크래시 발생 시 kubelet이 상태를 보고하고 컨트롤러가 Desired 수를 보장하기 위해 재시작 또는 재스케줄 수행 노드가 NotReady로 전환되면 스케줄러와 컨트롤러가 파드를 다른 노드로 이동시키는 복구 경로 선택 HPA VPA 클러스터 오토스케일러 등으로 Desired State를 조정하면 동일한 조율 루프로 반영되어 자원과 파드 수가 확장 또는 축소 용어 핵심 정리 control plane apiserver 권위와 입구, scheduler 배치, controller-manager 조율, etcd 단일 진실 저장소 worker node 파드를 실제로 실행하는 머신 풀 kubelet 각 노드의 현장 에이전트, 파드 라이프사이클 관리와 apiserver 동기화 담당 container runtime kubelet 지시로 컨테이너 생성과 삭제를 수행하는 실행기, CRI 인터페이스 준수 cgroup 컨테이너 자원 격리와 제한의 커널 메커니즘, OCI 런타임이 설정 마무리 apiserver는 진실의 관문, etcd는 진실의 저장소, 스케줄러와 컨트롤러는 계획과 조율, kubelet은 현장 실행, runtime과 OCI는 컨테이너 생성, cgroup은 자원 격리 담당 ...

October 16, 2025

MySQL EXPLAIN 실행 계획 해석 가이드

개요 EXPLAIN은 SELECT가 어떤 경로로 데이터를 읽는지 드러내는 도구 병목 파악과 인덱스 전략 점검에 사용 핵심 개념 select_type SIMPLE 단순 SELECT, 서브쿼리나 UNION 없음 PRIMARY 가장 바깥쪽 SELECT SUBQUERY 서브쿼리 DERIVED FROM 절의 서브쿼리 UNION UNION의 두 번째 이후 SELECT type 실행 품질 지표, 위에서 아래로 유리 system 테이블에 단 하나의 행 const PRIMARY KEY 또는 UNIQUE 인덱스 단건 조회 eq_ref 조인에서 PRIMARY KEY 또는 UNIQUE로 정확히 1행 매칭 ref 인덱스를 사용한 동등 조건 검색 range 인덱스를 사용한 범위 검색 index 인덱스 전체 스캔 ALL 테이블 전체 스캔, 최악 possible_keys 사용 가능한 인덱스 목록, NULL이면 후보 없음 key 실제 사용된 인덱스, NULL이면 인덱스 미사용 rows 옵티마이저가 읽을 것으로 추정한 행 수, 낮을수록 유리 filtered 조건 후 남는 행 비율 추정치, 높을수록 유리 Extra 추가 단서 Using index 커버링 인덱스 사용, 유리 Using where WHERE 조건으로 필터링 수행 Using filesort 추가 정렬 필요, 비용 큼 Using temporary 임시 테이블 사용, 비용 큼 해석 기준 type이 const, ref, range 범주에 위치 key가 NULL이 아니고 적절한 인덱스 선택 rows 추정치가 작고 filtered 비율이 높음 Extra에 Using filesort, Using temporary 부재 예시와 해석 type: ALL possible_keys: NULL rows: 3527425 Extra: Using where; Using filesort 테이블 전체 스캔으로 많은 행을 읽게 됨 인덱스 후보와 실제 사용 인덱스가 없음 WHERE로 필터링하고 추가 정렬까지 수행하여 비용 상승 현재 계획은 인덱스 설계와 조건식 재검토 필요 주의와 팁 rows와 filtered는 통계 기반 추정치라 실제와 오차 가능 filtered는 대략 rows × filtered%로 남는 행 규모 가늠에 사용 Using filesort가 항상 나쁜 것은 아님, 결과 집합이 매우 작으면 영향 미미할 수 있음 인덱스 생성 시 조건 컬럼의 선택도와 정렬·조인 키 우선 고려 커버링 인덱스 구성 시 Extra의 Using index로 확인 가능 마무리 EXPLAIN은 증상 관찰 도구, 원인은 스키마 설계와 조건식, 인덱스 전략에서 찾기 위 지표를 기준으로 스캔 범위를 줄이고 불필요한 정렬과 임시 테이블을 제거하는 방향으로 개선 시도 권장 ...

October 15, 2025

블록체인 인덱서 가이드

블록체인 인덱서 가이드 인덱서는 원장 데이터를 제품 요구에 맞게 재구성해 저지연으로 제공하는 데이터 레이어임 디앱 체감 속도와 신뢰도를 좌우하는 핵심 인프라임 왜 인덱서가 필요한가 블록체인 원장은 블록 단위 직렬 구조라 임의 접근과 조건 검색 비용 큼 디앱은 지갑 이력, 포지션, NFT 보유 등 사용자 맥락 데이터를 수십~수백 ms 내에 필요로 함 전체 원장을 매번 스캔하는 대신 목적형 보조 인덱스를 사전 구축해 API로 제공하는 전략이 효율적임 핵심 개념 인덱싱 대상 데이터 유형 블록 헤더와 트랜잭션 메타데이터 ...

October 13, 2025