국민연금 추납제도, 신청조건과 손해 보는 경우 총정리

국민연금 추납제도, 신청만 하면 연금이 무조건 늘어날까요? 꼭 그렇지는 않습니다. 과거에 내지 못한 보험료를 지금 채워 가입 기간을 늘려주는 제도이지만, 현재 가입 상태와 소득 수준에 따라 오히려 손해로 이어지는 경우도 있습니다. 국민연금 추납제도를 신청하기 전에 조건과 계산 방식, 그리고 손해 보는 경우를 먼저 짚어두는 편이 안전합니다. 국민연금 추납제도의 기본 구조 추후납부, 줄여서 추납이라고 부르는 이 … Read more

종부세 특례신청 대상과 요건, 9월 신고기간에 놓치면 끝입니다

9월 중순이 지나면 관할 세무서 민원창구 앞에 평소보다 줄이 길게 늘어선 모습을 보신 적 있으실 겁니다. 그 줄의 대부분은 종부세 특례신청을 하러 온 분들입니다. 결론을 먼저 말씀드리면, 종부세 특례신청은 매년 9월 16일부터 9월 30일까지만 받아주고 이 기간을 넘기면 그해 세금은 일반 계산방식으로 그대로 확정되어 되돌릴 방법이 없습니다. 종합부동산세는 매년 6월 1일 기준 주택 소유 현황을 … Read more

국민연금 유족연금 수급조건과 지급률, 중복수급 여부까지

이 글에서는 국민연금 유족연금을 누가 받을 수 있는지, 가입기간에 따라 지급률이 어떻게 달라지는지, 본인이 노령연금을 받고 있을 때 두 연금을 동시에 받을 수 있는지까지 한 번에 확인하실 수 있습니다. 결론만 먼저 말씀드리면, 유족연금은 가입기간에 따라 기본연금액의 40~60%를 받는 구조이고, 본인이 이미 노령연금을 받고 있다면 본인 연금과 유족연금을 동시에 전액 받는 것이 아니라 둘 중 하나를 … Read more

한국어 검색이 LIKE ‘%키워드%’로 버틸 때, pg_bigm과 전문검색 비교

게시판 검색창에 LIKE ‘%키워드%’ 조건을 넣어두고 서비스를 시작했는데, 글이 몇만 건쯈 쌓이자 검색 버튼만 누르면 화면이 몇 초씩 멈추는 경험을 겪어보신 분들이 적지 않을 겁니다. 한국어 검색이 LIKE ‘%키워드%’로 버티는 구간은 의외로 금방 끝나는데, 이때 바로 풀 텍스트 검색 엔진으로 갈아타기보다 pg_bigm 확장을 올려서 기존 LIKE 쿼리에 인덱스만 태우는 선택지를 먼저 검토해 볼 만합니다. 이 … Read more

deadlock detected 로그를 받았을 때 잠금 순서 복원하는 법

결론부터 말씀드리면, deadlock detected 로그를 받았을 때 가장 먼저 할 일은 에러 메시지를 지우거나 재시도 로직을 추가하는 게 아니라 로그에 적힌 두 트랜잭션의 잠금 순서를 그대로 복원하는 것입니다. 어느 트랜잭션이 어떤 리소스를 먼저 잠그고 어떤 리소스를 기다리다가 되돌아갔는지를 종이에 그려보면, 코드에서 잠금 순서를 어디부터 맞춰야 하는지가 보입니다. 이 글에서는 MySQL InnoDB와 PostgreSQL을 기준으로 로그를 읽는 … Read more

페이지가 뒤로 갈수록 느려질 때 쓰는 커서 페이지네이션

게시판이나 상품 목록에서 1페이지는 빠른데 50페이지, 100페이지로 넘어갈수록 응답이 눈에 띄게 느려지는 현상은 대부분 OFFSET을 쓰는 쿼리 구조 때문에 생깁니다. 페이지가 뒤로 갈수록 느려지는 이유는 간단합니다. DB가 매 요청마다 앞쪽 행을 전부 읽어서 세고, 그중 필요 없는 부분을 버린 다음에야 실제로 원하는 20개를 돌려주기 때문입니다. 이 글에서는 왜 이런 구조가 생기는지, 그리고 커서(키셋) 페이지네이션으로 바꾸면 … Read more

로그 테이블이 수억 행일 때, 파티셔닝이 정말 이득인지 따져봅니다

결론부터 말씀드리면, 로그 테이블이 수억 행 규모로 커졌다고 해서 파티셔닝부터 꺼내 드는 게 항상 정답은 아닙니다. 조회 조건이 거의 매번 날짜 범위로 걸리고, 오래된 로그를 주기적으로 지워야 하는 구조라면 파티셔닝이 확실한 효과를 냅니다. 반대로 전체 기간을 가로지르는 집계 쿼리가 많거나 파티션 관리를 자동화할 여력이 없다면, 이득보다 운영 부담이 먼저 커질 수 있습니다. 수억 행 로그 … Read more

JSONB에 다 넣기 전에 점검할 GIN 인덱스·TOAST 갈림길

테이블 설계를 할 때 속성을 JSONB에 다 넣기로 정하면 당장은 편합니다. 하지만 조회량이 늘어나는 순간부터 정규 컬럼과 체감 성능 차이가 벌어지기 시작합니다. 자주 필터링하거나 정렬하는 값을 JSONB 안에 묻어두면 GIN 인덱스가 생각보다 커지고, 값 하나가 조금만 길어져도 TOAST 테이블로 분리 저장되면서 읽기 비용이 따라붙습니다. 이 글은 PostgreSQL 12 이상, 기본 페이지 크기(8KB) 환경을 기준으로 정규 … Read more

SQLite 파일을 cp로 백업하면 깨지는 이유, VACUUM INTO와 백업 API로 해결하기

“SQLite는 파일 하나짜리 DB니까 cp 명령으로 복사만 해두면 백업이 끝난다”고 생각하는 분이 많습니다. 하지만 SQLite 파일을 cp로 백업하면 깨지는 경우가 실제로 있고, 그 이유는 cp가 SQLite 엔진의 잠금 상태나 WAL(Write-Ahead Log) 파일을 전혀 알지 못하기 때문입니다. 결과만 먼저 말씀드리면, 쓰기 작업이 전혀 없는 완전히 닫힌 DB를 복사할 때는 cp로도 문제가 없지만, 서비스가 돌아가는 중이거나 체크포인트가 … Read more

백업은 있는데 복구를 못 할 때, pg_dump와 PITR 중 무엇을 써야 할까요

백업은 있는데 복구를 못 하는 상황은 대부분 백업 방식과 복구 시간(RTO)을 미리 맞춰보지 않아서 생깁니다. pg_dump로 받은 백업은 논리적 스냅숏이라 특정 시점을 골라서 복구할 수 없고, PITR(Point-In-Time Recovery)은 원하는 시점을 고를 수 있는 대신 장애가 나기 전부터 WAL 아카이빙을 켜두지 않았다면 아예 쓸 수 없습니다. 이 글은 PostgreSQL 13 이상에서 recovery.signal / standby.signal 방식을 쓰는 … Read more