
1. 강력한 객체-관계형 기능과 확장성 (Extensibility)
PostgreSQL은 단순한 관계형 모델을 넘어선 **객체-관계형 데이터베이스(ORDBMS)**의 특성을 가집니다. 이는 데이터베이스의 핵심 기능을 사용자가 직접 확장하고 정의할 수 있는 유연성을 제공합니다.
- 사용자 정의 타입(User-Defined Types):
- 설명: 데이터베이스가 기본으로 제공하는 INTEGER, VARCHAR, TIMESTAMP 등의 타입 외에, 개발자가 직접 새로운 데이터 타입을 정의하여 사용할 수 있습니다. 이 타입에는 해당 타입에 맞는 연산자(+, 등), 함수, 인덱스 등을 함께 정의할 수 있습니다.
- 장점:
- 데이터의 의미 정확성: 특정 도메인의 데이터를 DB 스키마 수준에서 더 정확하게 표현할 수 있습니다. 예를 들어, ipv4_address나 email_address 같은 타입을 직접 만들어 유효성 검사 로직을 타입 정의에 포함시킬 수 있습니다.
- 코드의 재사용성 및 일관성: 애플리케이션 계층에서 반복적으로 처리해야 할 유효성 검사나 변환 로직을 DB 내부로 가져와 일관된 처리를 보장합니다.
- 성능 향상: DB가 해당 타입을 더 효율적으로 저장하고 처리할 수 있도록 최적화될 가능성이 있습니다.
- 예시: IP 주소 문자열을 저장하는 대신 inet 또는 cidr 타입으로 저장하여 IP 네트워크 연산(예: 특정 서브넷에 속하는지 확인)을 DB 내부에서 직접 수행할 수 있습니다.
- 사용자 정의 함수 및 연산자(User-Defined Functions & Operators):
- 설명: SQL, PL/pgSQL(PostgreSQL의 내장 절차형 언어), C, Python, Perl, R 등 다양한 프로그래밍 언어로 함수를 작성하여 데이터베이스에 등록할 수 있습니다. 이 함수들은 쿼리 내에서 일반 함수처럼 사용될 수 있으며, 새로운 연산자(예: @@ 같은 사용자 정의 검색 연산자)를 정의하여 특정 데이터 타입에 대한 동작을 확장할 수 있습니다.
- 장점:
- 비즈니스 로직 캡슐화: 복잡한 비즈니스 로직 일부를 DB 함수로 구현하여 쿼리 내에서 재사용하고, 클라이언트 애플리케이션의 부담을 줄일 수 있습니다.
- 확장성: 기존 SQL이 제공하지 않는 특정 계산이나 데이터 처리 로직을 DB에 직접 추가할 수 있습니다.
- 성능: DB 내부에서 실행되므로 클라이언트-서버 간 데이터 전송 없이 효율적인 처리가 가능합니다.
- 예시: 특정 좌표계 변환 함수를 C로 작성하여 PostgreSQL에 등록한 후, GIS 쿼리에서 이 함수를 직접 사용하여 효율적으로 지리 데이터를 처리할 수 있습니다.
- 강력한 확장 프로그램(Extensions):
- 설명: PostgreSQL은 모듈식 아키텍처를 채택하여, 코어 시스템을 수정하지 않고도 강력한 추가 기능을 "확장" 형태로 설치할 수 있습니다. 이는 마치 운영체제의 플러그인과 같습니다.
- 장점:
- 기능 확장 용이성: 특정 도메인에 특화된 기능을 DB에 쉽게 추가할 수 있습니다.
- 안정성: 코어 시스템에 영향을 주지 않으므로 안정성이 높습니다.
- 활발한 커뮤니티: 다양한 활용 사례에 대한 풍부한 확장 프로그램들이 개발되어 있습니다.
- 예시:
- PostGIS: 공간 데이터(지리 정보)를 저장, 쿼리, 분석하기 위한 업계 표준 확장입니다. POINT, LINE, POLYGON 같은 지리적 데이터 타입을 제공하고, 거리 계산, 포함 여부 확인 등 수백 가지의 공간 함수를 제공하여 지도, 위치 기반 서비스, 자율 주행 등에 필수적입니다.
- pg_trgm: 텍스트 유사성 검색을 위한 확장입니다. "trigram"(3개의 연속된 문자열) 기반 인덱스를 사용하여 스펠링 오류가 있는 텍스트나 부분 일치 텍스트를 빠르게 검색할 수 있게 해줍니다.
- hstore: 키-값 쌍을 단일 컬럼에 저장할 수 있는 데이터 타입입니다. JSONB와 유사하지만, 더 단순한 구조의 비정형 데이터를 저장할 때 유용합니다.
- pgvector: 최근 AI 애플리케이션에서 사용되는 벡터 임베딩을 저장하고, 유클리드 거리, 코사인 유사도 등을 기반으로 유사한 벡터를 빠르게 검색할 수 있게 해줍니다. 이를 통해 DB 내부에서 추천 시스템, 시맨틱 검색 등을 구현할 수 있습니다.
2. NoSQL급의 JSON 지원 (JSONB)
PostgreSQL의 JSONB 타입은 관계형 데이터베이스의 강점과 NoSQL 데이터베이스의 유연성을 결합한 매우 강력한 기능입니다.
- 설명: JSONB는 JSON 데이터를 텍스트 그대로 저장하는 JSON 타입과 달리, 바이너리 형태로 파싱하여 저장합니다. 이 바이너리 형식은 JSON 데이터를 검색하거나 조작할 때 더 효율적입니다.
- 장점:
- 유연한 스키마: 테이블의 특정 컬럼에 JSONB를 사용하여 고정된 스키마 없이 다양한 속성을 저장할 수 있습니다. 이는 특히 새로운 데이터 속성이 자주 추가되거나, 속성들이 모든 레코드에 일관되지 않은 경우에 매우 유용합니다.
- 강력한 쿼리 및 연산:
- JSONB 데이터 내부의 특정 키에 접근하거나(>, >>), 경로를 따라 데이터를 추출하고(#>, #>>), 배열을 조작하고(jsonb_array_elements), 특정 키나 값이 존재하는지 확인할 수 있는(?, @>, ?&) 등 다양한 연산자를 제공합니다.
- JSONB 데이터 내부의 특정 값에 대한 WHERE 절 조건을 사용하여 필터링할 수 있습니다.
- 인덱싱 가능: JSONB 컬럼 전체에 GIN(Generalized Inverted Index) 인덱스를 걸거나, 특정 JSON 경로(예: (data->'user'->'id'))에 인덱스를 걸 수 있습니다. 이는 JSONB 데이터에 대한 검색 성능을 획기적으로 향상시킵니다.
- 관계형 데이터와의 결합: 정형화된 관계형 데이터와 비정형 JSON 데이터를 한 쿼리에서 조인하고 분석할 수 있어, 복잡한 데이터 모델링을 단순화하고 애플리케이션 계층의 로직 부담을 줄일 수 있습니다.
- 예시:
- 전자상거래 플랫폼에서 products 테이블에 details라는 JSONB 컬럼을 만들어 상품별로 다른 추가 속성(예: 의류의 color, size, 전자기기의 processor, RAM)을 저장할 수 있습니다.
- 사용자 프로필 테이블에 user_preferences라는 JSONB 컬럼을 두어 사용자의 다양한 설정(예: theme, notifications.email, notifications.sms)을 저장하고, 이 데이터를 쉽게 쿼리하고 업데이트할 수 있습니다.
- 로그 데이터를 저장할 때, event_data 컬럼에 JSONB를 사용하여 다양한 형태의 로그 이벤트를 일관된 테이블 구조로 저장하면서도 각 이벤트의 세부 속성을 유연하게 관리할 수 있습니다.
3. 고도의 동시성 제어 (MVCC)
PostgreSQL은 **MVCC(Multi-Version Concurrency Control, 다중 버전 동시성 제어)**를 통해 높은 동시성을 제공하며, 특히 읽기 작업이 쓰기 작업을 방해하지 않는다는 큰 장점을 가집니다.
- 설명: 데이터베이스에 저장된 데이터의 여러 버전을 동시에 유지 관리하여, 어떤 트랜잭션이 데이터를 수정하는 동안에도 다른 트랜잭션이 그 데이터의 이전 버전을 읽을 수 있도록 합니다. 각 트랜잭션은 자신이 시작된 시점의 '데이터 스냅샷'을 보게 됩니다.
- 장점:
- 읽기 작업 시 잠금(Lock) 없음: 데이터 읽기 작업(SELECT)은 데이터를 수정하는 다른 트랜잭션에 의해 잠기지 않습니다. 이로 인해 읽기 작업이 쓰기 작업을 차단하지 않고, 쓰기 작업도 읽기 작업을 차단하지 않습니다. (MySQL의 InnoDB 등 다른 DB도 MVCC를 사용함. READ COMMITTED나 REPEATABLE READ와 같은 격리 수준을 제공하며 innoDB도 select 문이 update, delete와 같은 쓰기 작업을 차단히지 않도록 여러 버전의 데이터를 유지한다.)
- 높은 동시성: 동시에 많은 사용자가 데이터를 읽고 쓰는 환경에서, Lock 경합으로 인한 성능 저하 없이 높은 처리량을 유지할 수 있습니다. 웹 서비스처럼 읽기 요청이 많은 환경에 특히 유리합니다.
- 트랜잭션 격리: 트랜잭션 간의 간섭을 최소화하여 데이터의 일관성과 정확성을 보장합니다. 특히 SERIALIZABLE과 같은 높은 격리 수준에서도 성능 손실이 상대적으로 적습니다.
- 긴 쿼리의 안정성: 분석 쿼리처럼 실행 시간이 긴 SELECT 문이 실행되는 동안에도, 다른 트랜잭션들이 데이터를 자유롭게 수정할 수 있으며, SELECT 문은 자신이 시작된 시점의 일관된 데이터를 보장받습니다.
- MySQL과의 차이점
- Write Lock 방식
- Postgresql : update나 delete 시 일반적으로 해당 행에 대한 Exclusive Lock을 걸지만, 이는 다른 읽기 트랜잭션에는 영향을 주지 않는다. (오래된 버전을 읽게 함) 또한 update는 새 버전을 만들고 기존 버전을 ‘사용 불가능’ 으로 표시하는 방식
- MySQL : update나 delete 시 해당 행에 대한 Exclusive Lock을 걸며 Lock은 다른 쓰기 트랜잭션은 물론 경우에 따라 SELECT … FOR UPDATE 같은 특정 읽기 트랜잭션도 차단한다. Lcok 경합이 더 빈번하게 발생
- Vacuum 프로세스
- Postgresql : MVCC의 부산물로 dead tuples(즉 이전 버전의 데이터)이 발생한다. Postgresql은 이 죽은 튜플들을 주기적으로 정리하는 VACUUM이라는 별도의 프로세스가 필요하다. VACUUM은 시스템 오버헤드를 유발할 수 있으며, 이 과정이 적절히 관리 되지 않으면 테이블 파일 크기가 커지거나 성능 저하가 발생할 수 있다.
- MySQL : InnoDB는 PURGE 스레드를 통해 백그라운드에서 자동으로 이전 버전의 데이터를 정리한다. 사용자(DBA)가 직접 개입해야 하는 VACUUM 같은 명시적인 작업은 없다.
- 트랜잭션 격리 수준 구현의 강점
- Postgresql : SERIALIZABLE 격리 수준에서 발생하는 직렬화 실패(Serialization Failure)를 탐지하고 사용자에게 재시도를 요구하는 방식으로 구현되어, 가장 높은 수준의 트랜잭션 일관성을 강력하게 보장한다.
- MySQL : InnoDB는 REPEATABLE READ가 기본 격리 수준이며, 이 수준에서도 ‘팬텀 리드’ 문제가 발생하지 않도록 MVCC를 호가장하여 구현한다. SERIALIZABLE도 지원하지만 실제 애플리케이션에서는 겨의 사용되지 않는다.
- 결론 : Postgresql의 MVCC는 읽기와 쓰기가 서로 영향을 미치지 않도록 하는데 더 순수하고 강력한 접근 방식을 가진다. 다만 이로 인해 VACUUM이라는 관리 오버헤드가 발생한다는 트레이드오프가 있다. InnoDB는 이를 좀 더 자동화하고 간소화했지만, 특정 동시성 시나리오에서 Lock 경합이 더 발생할 수 있다.
- Write Lock 방식
- 예시:
- 사용자가 웹사이트에서 게시물을 읽는 동안(SELECT), 동시에 다른 사용자가 해당 게시물을 수정(UPDATE)하더라도 서로의 작업에 영향을 주지 않고 원활하게 서비스가 제공됩니다.
- 데이터 분석가가 대용량 보고서 쿼리를 실행하는 동안에도, 실시간으로 들어오는 거래 데이터가 문제없이 DB에 기록됩니다.
4. 복잡한 쿼리 및 분석 성능
PostgreSQL은 단순한 CRUD 작업을 넘어, 복잡한 데이터 분석 및 보고서 생성 쿼리에서 뛰어난 성능을 발휘합니다.
- 똑똑한 쿼리 최적화기(Query Optimizer):
- 설명: 사용자가 작성한 SQL 쿼리를 실행하기 전에, 데이터베이스는 쿼리 실행 계획을 수립합니다. PostgreSQL의 옵티마이저는 JOIN 순서, 인덱스 사용 여부, 임시 테이블 생성 여부 등 수많은 가능성 중에서 가장 효율적인 실행 경로를 찾아내는 데 매우 정교합니다. 통계 정보를 활용하여 데이터 분포를 이해하고 최적의 계획을 세웁니다.
- 장점: 개발자가 쿼리를 작성할 때 성능 최적화에 대한 부담을 덜고, 더 선언적인 방식으로 쿼리를 작성할 수 있도록 돕습니다. 복잡한 쿼리일수록 옵티마이저의 역할이 중요해집니다.
- 다양한 인덱스 타입:
- 설명: PostgreSQL은 B-Tree(가장 일반적), Hash, GiST(Generalized Search Tree), SP-GiST, GIN(Generalized Inverted Index), BRIN(Block Range Index) 등 매우 다양한 인덱스 타입을 제공합니다. 각 인덱스 타입은 특정 데이터 타입이나 쿼리 패턴에 최적화되어 있습니다.
- 장점:
- 쿼리 효율 극대화: 텍스트 검색(GIN), 지리 공간 검색(GiST), 대용량 시계열 데이터 검색(BRIN) 등 특정 목적에 맞는 인덱스를 선택하여 쿼리 성능을 비약적으로 향상시킬 수 있습니다.
- 유연성: 다양한 데이터 형태(JSONB, 배열, 텍스트 등)에 대해 효율적인 인덱싱을 지원합니다.
- 예시: JSONB 컬럼에 GIN 인덱스를 걸면, JSONB 내부의 특정 키나 값에 대한 검색(WHERE data @> '{"status": "completed"}')이 매우 빨라집니다.
- 병렬 쿼리(Parallel Query):
- 설명: PostgreSQL은 하나의 복잡한 쿼리(예: 대용량 테이블 스캔, JOIN, 집계 함수 등)를 여러 개의 독립적인 태스크로 분할하여 여러 CPU 코어에서 병렬로 실행할 수 있습니다.
- 장점: 멀티코어 CPU 환경에서 대용량 데이터에 대한 분석 쿼리나 보고서 생성 쿼리의 실행 시간을 획기적으로 단축시킵니다.
- 예시: 수백만 건의 트랜잭션 데이터에 대해 GROUP BY와 SUM 연산을 수행하는 쿼리가 있다면, 병렬 쿼리 기능을 통해 훨씬 빠르게 결과를 얻을 수 있습니다.
- 고급 분석 함수 (Window Functions, CTEs 등):
- 설명: WINDOW FUNCTIONS (예: ROW_NUMBER(), LAG(), LEAD(), RANK()), CTE (Common Table Expressions) (WITH 절), MATERIALIZED VIEWS 등 복잡한 데이터 분석과 보고서 작성을 위한 강력한 SQL 기능을 폭넓게 지원합니다.
- 장점: 애플리케이션 계층에서 복잡한 로직을 구현하지 않고도 SQL 쿼리만으로 복잡한 통계, 순위, 이동 평균 등을 계산할 수 있습니다.
- MySQL과의 차이점
- 쿼리 옵티마이저의 정교함
- Postgresql : 일반적으로 Postgresql의 옵티마이저가 더욱 정교하고 복잡한 쿼리에 대해 최적의 실행 계획을 찾아내는 능력이 뛰어나다. 특히 서브쿼리, 복잡한 조인, 윈도우 함수 등 다양한 고급 SQL 기능을 사용할 때 빛을 발한다.
- Mysql innodb : 많이 발전햇지만, 특정 복잡한 쿼리나 최적화 힌트가 필요한 상황에서 postgresql보다 덜 효율적인 계획을 세우는 경우가 있다.
- 인덱스 타입의 다양성과 유연성
- PostgreSQL: B-Tree 외에 GIN, GiST, SP-GiST, BRIN 등 다양한 특수 목적 인덱스를 제공합니다. 이는 텍스트 검색(pg_trgm), 지리 공간(PostGIS), JSONB 데이터 내부 검색(JSONB + GIN) 등 특정 데이터 형태와 쿼리 패턴에 대한 성능을 극대화할 수 있습니다.
- MySQL InnoDB: 주로 B-Tree 인덱스를 기반으로 하며, 전체 텍스트 검색을 위한 FULLTEXT 인덱스나 공간 검색을 위한 R-Tree 인덱스 등을 지원하지만, PostgreSQL의 확장성과 유연성에는 미치지 못합니다.
- 병렬 쿼리
- PostgreSQL: 9.6 버전부터 SELECT, CREATE TABLE AS, CREATE INDEX 등 다양한 작업에서 쿼리 자체를 병렬로 실행하는 기능을 적극적으로 활용합니다.
- MySQL InnoDB: 8.0부터 일부 병렬 쿼리 기능을 도입했지만, PostgreSQL만큼 광범위하고 깊이 있게 구현되지는 않았습니다. 특히 GROUP BY, ORDER BY 같은 작업의 병렬 처리에서는 PostgreSQL이 강점을 보입니다.
- 쿼리 옵티마이저의 정교함
5. 데이터 무결성과 표준 준수
PostgreSQL은 데이터의 신뢰성과 장기적인 유지보수성을 매우 중요하게 생각하는 DB입니다.
- 엄격한 ACID 준수:
- 설명: PostgreSQL은 트랜잭션의 4가지 속성인 **원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 영속성(Durability)**을 매우 엄격하게 준수합니다. 이는 데이터가 손실되거나 손상될 위험 없이 항상 정확하고 신뢰할 수 있음을 의미합니다.
- 장점:
- 데이터 신뢰성: 금융 시스템, 의료 기록, 재고 관리 등 데이터의 정확성이 생명인 애플리케이션에 필수적입니다.
- 예상 가능한 동작: 트랜잭션이 어떤 상황에서도 예측 가능한 방식으로 작동하므로 개발자가 데이터 관련 오류를 방지하기 용이합니다.
- SQL 표준 준수:
- 설명: PostgreSQL은 ANSI SQL 표준을 가장 잘 따르는 관계형 데이터베이스 중 하나입니다. 대부분의 표준 SQL 문법과 기능이 PostgreSQL에서 지원됩니다.
- 장점:
- 개발자 학습 곡선: 표준 SQL에 익숙한 개발자는 PostgreSQL에 쉽게 적응할 수 있습니다.
- 쿼리 이식성: PostgreSQL에서 작성된 쿼리는 다른 표준 SQL 데이터베이스(예: Oracle, SQL Server)로 이식하기가 비교적 쉽습니다. 이는 장기적인 유지보수와 기술 전환에 유리합니다.
- 문서 및 자료의 풍부함: 표준을 따르므로 관련 문서나 커뮤니티 자료를 찾기 용이합니다.
- 강력한 외래 키(Foreign Key) 제약:
- 설명: 테이블 간의 관계를 정의하는 외래 키 제약을 강력하게 지원하고 검증합니다.
- 장점:
- 참조 무결성: 참조하는 테이블의 데이터가 삭제되거나 변경될 때 참조되는 테이블의 데이터도 함께 일관되게 유지되도록 보장합니다(예: ON DELETE CASCADE, ON UPDATE RESTRICT).
- 데이터 일관성: 애플리케이션 수준에서 복잡한 참조 무결성 로직을 구현할 필요 없이 DB가 이를 자동으로 관리하여 데이터의 일관성을 유지합니다.
- MySQL과의 차이점
- ACID 준수의 엄격함:
- PostgreSQL: 전통적으로 ACID 속성을 매우 엄격하게, 보수적으로 준수하는 것으로 유명합니다. 특히 내구성(Durability) 측면에서 fsync와 같은 디스크 동기화 작업을 철저히 처리하여 데이터 손실 위험을 최소화합니다.
- MySQL InnoDB: MySQL 5.x 버전대에서는 기본 설정(예: innodb_flush_log_at_trx_commit = 0)에서 성능을 위해 ACID 준수(특히 내구성)를 일부 희생하는 경우가 있었습니다. 최신 버전에서는 많이 개선되었지만, 기본 철학에서 PostgreSQL이 좀 더 '안전'에 중점을 둡니다.
- SQL 표준 준수 및 기능 구현 깊이:
- PostgreSQL: SQL 표준을 가장 잘 따르는 오픈소스 DB 중 하나입니다. 거의 모든 표준 SQL 기능을 지원하며, 이를 일관되고 예측 가능한 방식으로 구현합니다.
- MySQL InnoDB: SQL 표준을 따르지만, 특정 기능(예: CHECK 제약 조건 - 8.0 이전에는 파싱만 하고 실제 검사 안 함, 특정 JOIN 문법)에서 표준과 다르거나 제한적인 구현이 있었습니다. 또한 PostgreSQL이 제공하는 WITH RECURSIVE, MATERIALIZED VIEWS 등 고급 표준 SQL 기능은 MySQL에서 뒤늦게 추가되거나 기능적 제한이 있는 경우가 많습니다.
- 데이터 타입의 엄격함:
- PostgreSQL: 데이터 타입에 대한 검증과 형 변환이 더 엄격합니다. 명시적인 형 변환을 요구하는 경우가 많습니다.
- MySQL InnoDB: 비교적 느슨한 타입 검사와 자동 형 변환을 제공합니다. 이는 때로는 개발 편의성을 높이지만, 예상치 못한 데이터 타입 변환으로 인한 오류나 성능 저하를 유발할 수 있습니다.
- CHECK 제약 조건:
- PostgreSQL: CHECK 제약 조건을 완벽하게 지원하며, 이를 통해 컬럼 값에 대한 복잡한 규칙을 DB 수준에서 강제할 수 있습니다.
- MySQL InnoDB: 8.0 이전 버전에서는 CHECK 제약 조건을 파싱은 하지만 실제로 검사하지 않아 기능하지 않았습니다. 8.0부터는 실제로 동작합니다.
- ACID 준수의 엄격함:
dml 쿼리에 대한 고찰
두 DB 모두 쓰기 작업(DML)에 Lock을 걸어 다른 쓰기 작업을 차단하는 것은 동일합니다. 하지만 PostgreSQL이 더 유연하다고 평가받는 근본적인 이유는 데이터를 수정하는 방식(MVCC 구현 방식)의 차이에 있습니다. 핵심은 PostgreSQL의 UPDATE가 데이터를 덮어쓰지 않고 새로운 행 버전을 생성한다는 점입니다.
1. PostgreSQL: '새 행 생성' 방식의 MVCC (Tuple-Based)
PostgreSQL은 데이터의 모든 버전을 테이블(heap) 내에 유지합니다.
작업 동작 방식 락(Lock)의 성격 및 기간
| UPDATE | 1. 기존 행을 '사용 불가'로 표시 (DELETE). 2. 새로운 행을 테이블의 다른 위치에 삽입 (INSERT). | 데이터 수정 작업 자체에 걸리는 Lock은 매우 짧습니다. 기존 행을 '사용 불가'로 표시하고 새 행을 삽입하는 트랜잭션 ID 관련 락만 빠르게 획득했다가 해제됩니다. |
| SELECT | Lock을 전혀 신경 쓰지 않고 쿼리가 시작된 시점의 이전 버전을 읽습니다. | Lock 경합(Contention)이 발생할 일이 없습니다. |
| 결론 | 읽기-쓰기 간에 Lock 경합이 없습니다. 쓰기-쓰기 간의 Lock 경합은 존재하지만, 데이터 변경 작업이 **논리적인 '추가'**에 가까워 Lock이 필요한 기간이 최소화됩니다. |
2. MySQL InnoDB: '제자리 수정' 방식의 MVCC (Undo Log-Based)
InnoDB는 데이터를 물리적으로 제자리에서 수정하고, 롤백을 위해 이전 데이터를 Undo Log라는 별도의 공간에 기록합니다.
작업 동작 방식 락(Lock)의 성격 및 기간
| UPDATE | 기존 데이터를 물리적으로 덮어쓰기 위해 해당 행에 **배타적 Lock (X-Lock)**을 겁니다. | 데이터 수정 작업이 완료될 때까지 Lock을 유지해야 합니다. |
| SELECT | Lock 없이 현재 데이터를 읽지만, 필요하면 Undo Log를 참조하여 이전 버전의 데이터를 재구성해 읽습니다. | Lock 경합이 발생하지 않습니다. |
| SELECT ... FOR UPDATE | Lock을 획득해야 하는 작업이므로, 만약 해당 행에 이미 UPDATE나 DELETE가 진행 중이라면 X-Lock이 해제될 때까지 반드시 기다려야 합니다. | Lock 경합이 발생합니다. |
3. PostgreSQL이 더 유연하다고 평가받는 이유
PostgreSQL의 장점은 Lock 경합이 발생할 수 있는 시간 창(Window)을 최소화하는 데 있습니다.
- Lock Duration (락 유지 기간 최소화): ◦ PostgreSQL: UPDATE 시 새로운 행을 만드는 것은 매우 빠른 작업입니다. Lock은 이 짧은 **'행을 무효화하고 새로운 행을 삽입하는 시점'**에만 집중됩니다. 따라서 다른 쓰기 트랜잭션이 Lock 해제를 기다려야 하는 시간이 매우 짧습니다. ◦ InnoDB: 데이터를 물리적으로 수정하는 시간 동안 Lock을 유지해야 하므로, 복잡한 로우일수록 Lock 유지 시간이 길어지고 Lock 경합 가능성도 높아집니다.
- Lock Scope (락 범위의 단순성): ◦ PostgreSQL은 UPDATE 시 Lock이 필요한 대상이 데이터 자체보다는 트랜잭션 ID 영역에 가깝기 때문에, Lock의 복잡성이 줄어듭니다.
- 관리 오버헤드의 트레이드오프: ◦ PostgreSQL은 Lock 경합을 줄이는 대신, 남겨진 '죽은 튜플'을 정리하는 **VACUUM**이라는 별도의 청소 프로세스가 필요하다는 관리적 오버헤드가 있습니다. ◦ MySQL InnoDB는 이 청소 작업을 자동으로 처리하지만, Lock 경합의 가능성이 더 높아지는 트레이드오프를 가집니다. 결론적으로, 두 DB 모두 SELECT ... FOR UPDATE 같은 명시적인 Locking Read에서는 Lock 경합을 피할 수 없습니다. 하지만 일반적인 UPDATE나 DELETE 작업에서 PostgreSQL은 MVCC 구현 방식 덕분에 Lock을 잡고 있는 시간을 최소화하여 쓰기-쓰기 및 Lock-획득 읽기(SELECT FOR UPDATE) 간의 동시성 경합을 InnoDB보다 더 효과적으로 줄일 수 있습니다.
'CS > DataBase' 카테고리의 다른 글
| 격리수준이란 (0) | 2026.03.12 |
|---|---|
| redo log(mysql 8.0) (0) | 2025.09.16 |
| [DB] Prepared Statement란? (0) | 2025.06.10 |
| [DataBase] 인덱스란? (1) | 2025.03.26 |
| [DB] MVCC(다중 버전 동시성 제어) (0) | 2025.03.26 |