모르지 않다는 것은 아는것과 다르다.

Database

PostgreSQL Logical Structure 이해하기

채마스 2023. 12. 11. 19:24

개요

  • 이번 글에서는 PostgreSQL의 Logical Structure에 대해서 정리해보려고 한다.
  • DBMS마다 약간씩 Structure가 다르기 때문에 이번 글에서는 PostgreSQL에 초점을 맞춰서 설명해 보려고 한다.



PostgreSQL Logical Structure

PostgreSQL Logical Structure를 정리하면 아래와 같다.

이제 각각의 구성요소에 대해서 정리해 보자.

 

데이터베이스 클러스터

  • PostgreSQL은 여러 개의 데이터베이스와 Role, 테이블스페이스의 집합이다.
  • 각 클러스터는 고유한 포트 번호와 시스템 카탈로그를 가지며, 서로 다른 클러스터의 데이터베이스들은 독립적으로 작동한다.
  • 데이터베이스 클러스터가 생성되면 PGDATA 라는 환경변수가 생기는데, 해당 환경변수에 담긴 경로가 Base 디렉토리가 된다.

  • Base 디렉토리에는 아래와 같은 파일들이 존재한다.
  • 또한, Base 디렉토리에는 아래와 같은 디렉토리가 존재한다.

 

데이터베이스

  • PostgreSQL에서 데이터베이스는 Schema의 집합이다.
  • PostgreSQL 초기화 시(initDB), \l 명령어를 치면 아래와 같이 3개의 데이터베이스가 기본적으로 생성되어 있다.

  • 데이터베이스는 $PGDATA/base 디렉토리에 저장되어 있다.
  • 위 사진에서 1, 4, 5와 같은 디렉토리명은 데이터베이스의 OID이다. (이 부분은 뒤에서 좀 더 살명한다.)
  • 위 3개의 데이터베이스의 역할은 아래와 같다.
  • template1
    • 시스템 표준 데이터베이스(Standard System Database)이다.
    • 새로운 데이터베이스를 생성할 때 기본 템플릿으로 사용되는 데이터베이스다.
    • 데이터베이스를 신규로 생성 시 template 옵션을 따로 주지 않으면 template1을 복제하여 생성한다.
    • template1은 사용자에 의한 변경 및 접속이 가능하다.
  • template0
    • 원시 데이터베이스(Pristine Database)이다.
    • template0은 template1과 유사하게 새 데이터베이스의 템플릿으로 사용되지만, 수정되지 않은 상태를 유지하는 데 사용된다.
    • template0은 주로 template1이 사용자에 의해 변경되었을 때원래 상태로 새 데이터베이스를 생성하는 데 사용된다.
  • postgres
    • postgres 데이터베이스는 template1 데이터베이스를 이용해서 생성된 기본 데이터베이스이다.
    • 접속 시 데이터베이스를 지정하지 않으면 postgres 데이터베이스로 접속된다.
  • 그럼 한번 template1 데이터베이스에 테이블을 생성해 보자.

  • template1 데이터베이스에 test_tb라는 테이블을 만들었다.
  • 그리고 test_db라는 테이블을 만들었다.
    • 그렇게 되면 template1로 test_db가 생성되기 때문에 test_db에도 test_tb라는 테이블이 만들어져 있는 것을 확인할 수 있다.



테이블스페이스

  • PostgreSQL 서버가 설치되면 pg_defaultpg_global 테이블스페이스가 생성된다.
  • 아래와 같이 쿼리를 통해서도 확인해 볼 수 있다.

  • 테이블 생성 시에 테이블스페이스를 지정하지 않으면 pg_default 테이블스페이스에 테이블이 저장된다.
  • 데이터베이스 클러스터 레벨에서 관리되는 테이블은 pg_global 테이블스페이스에 저장된다.
  • pg_default 테이블스페이스의 물리적 위치는 $PGDATA/base이고 pg_global 테이블스페이스의 물리적 위치는 $PGDATA/globl이다.
    • 따라서 $PGDATA/base 하위에 존재하는 데이터베이스들은 모두 pg_default라는 테이블스페이스를 사용하고 있는 것이다.
    • $PGDATA/base 하위에는 테이블, 인덱스, 뷰, 시퀀스, 함수와 같은 오브젝트가 실제로 저장되는 공간이며, 저장경로는 $PGDATA/base/{database_oid}/{object_oid} 로 구성된다.
  • 1개의 테이블스페이스를 여러 개의 데이터베이스가 사용할 수 있다. 이때, 테이블스페이스 디렉토리 내에 데이터베이스별로 서브 디렉토리가 생성된다.
  • 따라서 해당 파일시스템은 PostgreSQL의 시스템 사용자(OS User)가 소유해야 한다. (읽기/쓰기 권한)
  • 테이블스페이스 생성 시 위치를 지정할 수 있다. 이러한 점을 활용하면 성능 최적화를 할 수도 있다.
    • 예를 들어, 자주 사용되는 오브젝트는 SSD에 위치시키고 자주 사용되지 않는 오브젝트는 Disk에 위치시킬 수 있다.
  • 사용자 테이블스페이스를 생성하게 되면 $PGDATA/tblspc 디렉토리에 사용자 테이블스페이스와 관련된 심볼릭 링크가 생성된다.
  • 테이블스페이스를 생성하는 User(Role)이 테이블스페이스의 Owner가 되며, 생성 시 Owner를 지정할 수 있다.



Role

  • PostgreSQL에서 Role은 데이터베이스 사용자 또는 그룹의 권한들을 특정 이름으로 모아둔 것이다.
  • PostgreSQL에서는 USER = ROLE 이라고 생각하면 된다.
  • Role은 데이터베이스 레벨이 아닌 클러스터 레벨에서 공통으로 사용된다.
  • Role은 오브젝트를 소유할 수 있으며, 오브젝트에 대한 권한 처리를 할 수 있다.
  • Role 삭제 시 Role이 소유한 오브젝트에 대한 처리가 필요하다.
  • Role의 종류는 아래와 같다.
Role Type Description
SUPERUSER 데이터베이스 시스템의 모든 권한을 가지며, 보안 제약을 무시할 수 있는 역할
LOGIN 데이터베이스에 로그인할 수 있는 권한을 가진 역할
CREATEDB 새로운 데이터베이스를 생성할 수 있는 권한을 가진 역할
CREATEROLE 새로운 역할을 생성할 수 있는 권한을 가진 역할
NOLOGIN 로그인이 불가능한 역할, 주로 그룹 역할로 사용
REPLICATION 데이터베이스 복제를 수행할 수 있는 권한을 가진 역할
BYPASSRLS 행 수준 보안 정책을 무시할 수 있는 권한을 가진 역할
INHERIT 부모 역할의 권한을 상속받는 기능
CONNECTION LIMIT 역할에 대한 동시 데이터베이스 연결 수 제한
PASSWORD 역할 로그인에 사용되는 비밀번호



Schema

  • PostgreSQL에서 스키마는 Object의 집합이며 일종의 네임스페이스 역할을 한다.
  • 하나의 데이터베이스는 여러 개의 스키마를 가질 수 있다.
    • public 스키마는 기본으로 제공되는 스키마이며 모든 권한이 부여된 스키마다.
  • PostgreSQL에서의 스키마는 Oracle의 스키마와 아래와 같은 차이점이 있다.
    • Oracle에서 스키마는 특정 사용자 계정에 바인딩된다.
    • 사용자 계정이 생성되면 해당 사용자의 스키마도 함께 생성되며 이 사용자는 스키마의 소유자가 되며, 스키마 내의 모든 오브젝트를 관리한다.
    • 즉, Oracle에서는 Owner = Schema 로 인식된다.
    • 하지만 PostgreSQL에서의 스키마와 사용자(또는 데이터베이스 역할)가 직접적으로 연결되지 않는다.
    • 따라서 사용자가 여러 스키마를 소유할 수 있으며, 하나의 스키마는 여러 사용자에 의해 공유될 수 있다.
  • PostgreSQL에서의 스키마의 장점은 아래와 같다.
    • 여러 사용자가 서로 간섭 없이 하나의 데이터베이스를 사용할 수 있다.
    • 관련된 데이터와 오브젝트를 스키마별로 나누어 관리함으로써, 시스템의 복잡성을 줄이고 유지보수를 용이하다.
    • 동일한 데이터베이스 내에서 동일한 이름의 오브젝트를 여러 개 만들 수 있다.
    • 스키마별로 다른 사용자 또는 역할에게 다른 접근 권한을 부여해서 데이터베이스 보안을 강화하고, 접근을 세밀하게 제어할 수 있다.



오브젝트

  • PostgreSQL에서 오브젝트는 데이터를 참조하거나 저장하기 위해 사용되는 객체를 말한다.
  • 오브젝트의 타입에는 Tables, Views, Indexes, Sequences, Functions, Triggers, Domains, Schemas, Materialized Views, Foreign Keys 등이 있다.
  • 또한, 데이터베이스에 포함된 오브젝트들은 아래와 같이 pg_class에서 조회할 수 있다.
SELECT oid AS OID, relname AS object_name, relkind AS object_type
FROM pg_class
WHERE relname = 'test_tb' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');
  • 여기서 relkind 값에는 오브젝트의 타입 정보가 담긴다. 대표적으로 쓰이는 값들은 아래와 같다.
Object Type relkind
Tables r
TOAST Tables t
Views v
Indexes i
Sequences S
Materialized Views m
Composite Types c
Foreign Tables f
Partitioned Tables p
Partitioned Indexes I
  • PostgreSQL의 오브젝트들은 각각 oid(Object Id)를 가지고 있으며, oid를 이름으로 하는 파일로 자신이 속한 데이터베이스의 디렉토리에 저장된다.
  • pg_database, pg_class 테이블에서 데이터베이스의 oid와 테이블의 oid를 확인할 수 있다.
  • ls $PGDATA/base/{데이터베이스의 OID}/ | grep {테이블의 OID} 를 통해서 데이터베이스 디렉토리에 해당 테이블이 있는지 확인해 보면 아래와 같다.

  • 또한 Tables 오브젝트는 테이블 별로 3개의 파일이 존재한다.
  • 실제로 $PGDATA/base 디렉토리에서 데이터베이스 내의 파일들을 보자.

  • OID(Object ID): 테이블 데이터를 저장하기 위한 파일이다.
  • OID_fsm: 테이블 여유 공간을 관리하기 위한 파일이다.
  • OID_vm: 테이블 블록의 visibility를 관리하기 위한 파일이다.
  • 테이블도 아래에서 설명할 오브젝트의 일종이다.



References