배경

우리 팀의 DB는 MySQL 과 PostgreSQL 모두 포함하는데, 왜 MySQL 과 PostgreSQL로 분리하여 관리하게 되었는지 궁금하여 두 관계형 DB의 차이를 조사해보았다.

데이터 저장 방식과 그에 따른 MVCC 구현

MySQL InnoDB는 InnoDB는 모든 테이블을 클러스터형 인덱스로 관리한다. 따라서 조회시 보조 인덱스를 사용하더라도 마지막에는 기본 인덱스를 이용하여 동작한다.

  • 프라이머리 키가 있으면 이를 클러스터링 인덱스로 사용
  • 프라이머리 키가 없을 때 숨겨진 클러스터링 인덱스(내부 인덱스, ROWID)를 생성하고 이를 이용하여 정렬한 형태로 저장
    • SQL로 조회하여 관리할 수 없으므로 실무에서 권장하지 않음

 

 데이터를 업데이트하면 기존 데이터를 덮어쓰면서 그 직전 데이터를 Undo 로그에 저장한다. MVCC 지원을 위해 인덱스 리프 노드 레코드에 trx_id와 roll_pointer를 함께 저장하며 트랜잭션이 데이터를 읽을 때 다음 작업을 한다.

  • trx_id 가 내 스냅샷의 아이디보다 작거나 같은 경우 데이터를 바로 사용
  • 아니면 roll_pointer를 이용하여 Undo 로그를 찾아 이전 버전 복원

 

 

반면 PostgreSQL은 힙이라는 구조에 무작위로 저장한다(table's heap). 삽입/삭제가 빠르다는 장점이 있다. 업데이트 시 새 튜플(postgresql에서의 로두,레코드 개념)을 삽입하고 기존 튜플를 죽은 튜플로 처리한다. 즉 새 튜플은 다른 식별자(CTID)를 가지며, 죽은 튜플을 처리하는 vaccum 관리가 필요하다. 각 튜플은 xmin, xmax 트랜잭션 ID를 가지고 있어 트랜잭션이 데이터를 읽을 때 자신의 스냅샷과 비교해서 어떤 튜플을 볼지 결정함으로써 MVCC 지원이 가능하다. undo 와 같은 추가작업이 필요없으므로 읽기 성능이 빠르다.

  • xmin: 이 튜플을 만든 트랜잭션 ID.
  • xmax: 이 튜플을 무효화한(삭제/수정한) 트랜잭션 ID.

PostgreSQL 만이 지원하는 기능 중 GIN 인덱스는 역인덱스 구조로서 다대다와 인덱스키가 여러 튜플을 가리키는 특성이 있다. 이중 후자의 특성은 1:1을 전제로 하는 InnoDB에서 불가능하다.

 

 

 

결론

동시 요청이 많은 서비스의 DB이기에 PostgreSQL을 사용하지 않았나 하는 결론을 내렸다.

참고 개념

B- 트리 (또는 B 트리)

이진검색트리(Binary Search Tree)의 skew로 인한 조회 시간복잡도 문제와 자식 노드 개수 제한을 보완한 다진 트리로, (최대 자식 노드 -1) 만큼의 키값을 가진다. 예를 들어 키가 k1, k2 라면 자식노드는 value < k1 또는 k1< value < k2 또는 k2< value 의 값을 갖는 세 개일 수 있다. 

B+ 트리

리프노드에만 실제 데이터를 저장함. 리프노드끼리 연결되어 리프 간 탐색 가능하다. MySQL InnoDB와 PostgreSQL에서 인덱스를 저장하는 데 쓰인다.

역인덱스

레코드 한 건을 찾기 위함이 아니라, 레코드의 일부 값을 중심으로 하여, 그 키를 가진 모든 레코드를 찾는 것이 목적이기에 역인덱스로 명명한다. 한 컬럼에 여러 개의 값이 들어가는 경우 (배열, JSON, 텍스트 등) 유용하다.

 

참고

mysql docs

https://dev.mysql.com/doc/refman/8.0/en/innodb-physical-structure.html

https://dev.mysql.com/doc/refman/8.0/en/innodb-index-types.html

https://dev.mysql.com/doc/refman/8.0/en/innodb-multi-versioning.html

 

postgresql docs

https://www.postgresql.org/docs/current/routine-vacuuming.html

https://www.postgresql.org/docs/current/mvcc-intro.html

https://www.postgresql.org/docs/current/storage-page-layout.html

 

기타

https://medium.com/quadcode-life/structure-of-heap-table-in-postgresql-d44c94332052

https://use-the-index-luke.com/sql/anatomy/the-tree

+ Recent posts