ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • PostgreSQL 1장
    카테고리 없음 2019. 11. 25. 08:54

    다음 주제에 대해 알아본다.

    • Database Cluster의 논리 구조(Logical Structure)
    • Database Cluster의 물리 구조(Physical Structure)
    • Heap Table File의 Internal Layout
    • Table의 Data를 Write 및 Read하는 방법

    논리 구조

    데이터베이스 클러스터는 데이터베이스들의 Collection이다.

    하나의 PostgreSQL 서버는 단일 호스트에서 실행되며 단일 데이터베이스 클러스터를 관리한다.

    논리 구조는 다음과 같다.

    하나의 데이터베이스는 데이터베이스 오브젝트들의 Collection이다. 

    데이터베이스 오브젝트는 데이터를 자정하는데 사용되는 데이터 구조 또는 데이터를 참조하는데 사용되는 데이터 구조 중 하나이다.

    하나의 테이블이 데이터베이스 오브젝트의 일반적인 예이고, 인덱스, 시퀀스, 뷰, 펑션 등이 있다.

    PostgreSQL에서 데이터베이스 자체는 데이터베이스 오브젝트들이고, 서로 논리적으로 분리되어 있다.

    데이터베이스 오브젝트들은 데이터베이스마다 존재한다.

    PostgreSQL에서 데이터베이스 오브젝트는 오브젝트 식별자(OID: Object IDentifier)로 관리된다. 

    OID 간의 관계는 오브젝트 타입에 따라 시스템 카탈로그에 저장된다.

    (bylee@[local]:5432) 16:33:37 [postgres] > select datname, oid from pg_database where datname = 'postgres';
     datname  |  oid  
    ----------+-------
     postgres | 13354
    (1 row)
    
    Time: 3.403 ms
    
    (bylee@[local]:5432) 16:34:33 [postgres] > select datname, oid from pg_database where datname = 'bylee';
     datname |  oid  
    ---------+-------
     bylee   | 16384
    (1 row)
    
    Time: 0.667 ms

    물리 구조

    하나의 데이터베이스 클러스터는 하나의 디렉토리이고, 이는 베이스 디렉토리(base directory)라고 한다. 이 디렉토리에는 하위 디렉토리와 파일들이 포함되어 있다.

    새로운 데이터베이스 클러스터를 생성하기 위해서는 initdb 명령어를 수행해 만들어야 한다. 보통 PGDATA 환경 변수를 참조하여 디렉토리 위치를 설정하고 PGDATA 환경 변수가 빈 값이면 initdb 명령어는 현재 디렉토리 위치에 생성한다.

    물리 구조는 다음과 같다.

    하나의 데이터베이스는 base 디렉토리 하위의 디렉토리이고, 각각의 테이블과 인덱스는 해당 데이터베이스 하위 디렉토리에 파일로 저장된다.

    PostgreSQL은 테이블스페이스을 지원하지 않지만 다른 RDBMS와 다른 의미로 사용된다. PostgreSQL에서 하나의 테이블스페이스는 베이스 디렉토리 외부에 데이터를 포함하는 하나의 디렉토리이다.

     

    PGDATA 디렉토리

    Item Description
    PG_VERSION A file containing the major version number of PostgreSQL
    base Subdirectory containing per-database subdirectories
    current_logfiles File recording the log file(s) currently written to by the logging collector
    global Subdirectory containing cluster-wide tables, such as pg_database
    pg_commit_ts Subdirectory containing transaction commit timestamp data
    pg_dynshmem Subdirectory containing files used by the dynamic shared memory subsystem
    pg_logical Subdirectory containing status data for logical decoding
    pg_multixact Subdirectory containing multitransaction status data (used for shared row locks)
    pg_notify Subdirectory containing LISTEN/NOTIFY status data
    pg_replslot Subdirectory containing replication slot data
    pg_serial Subdirectory containing information about committed serializable transactions
    pg_snapshots Subdirectory containing exported snapshots
    pg_stat Subdirectory containing permanent files for the statistics subsystem
    pg_stat_tmp Subdirectory containing temporary files for the statistics subsystem
    pg_subtrans Subdirectory containing subtransaction status data
    pg_tblspc Subdirectory containing symbolic links to tablespaces
    pg_twophase Subdirectory containing state files for prepared transactions
    pg_wal Subdirectory containing WAL (Write Ahead Log) files
    pg_xact Subdirectory containing transaction commit status data
    postgresql.auto.conf A file used for storing configuration parameters that are set by ALTER SYSTEM
    postmaster.opts A file recording the command-line options the server was last started with
    postmaster.pid A lock file recording the current postmaster process ID (PID), cluster data directory path, postmaster start timestamp, port number, Unix-domain socket directory path (empty on Windows), first valid listen_address (IP address or *, or empty if not listening on TCP), and shared memory segment ID (this file is not present after server shutdown)

    더 자세한 내용은 여기를 참조하라.

    데이터베이스 디렉토리

    하나의 데이터베이스는 base 폴더 하위의 디렉토리이다. 이 디렉토리는 OID를 디렉토리명으로 사용이고, 각각의 OID로 식별된다.

    예를 들어, bylee 데이터베이스의 OID가 16384라면 디렉토리명은 16384이다.

    $ ls -ld data/base/16384
    drwx------. 2 bylee bylee 12288 11월 19 16:05 data/base/16384

    테이블 파일과 인덱스 파일

    1GB보다 작은 크기의 테이블과 인덱스는 데이터베이스 디렉토리 아래에 하나의 파일로 저장된다.

    테이블과 인덱스는 데이터베이스 오브젝트로서 OID를 파일명으로 사용하고 relfilenode 변수로 관리된다.

    테이블과 인덱스의 relfilenode 값은 개별 OID와 항상 일치하지 않는다.

    tbl_a 테이블을 만들고, table_a 테이블의 OID와 relfilenode를 조회해보자.

    (bylee@[local]:5432) 17:16:22 [bylee] > select relname, oid, relfilenode from pg_class where relname = 'tbl_a';
     relname |  oid  | relfilenode 
    ---------+-------+-------------
     tbl_a   | 16553 |       16553
    (1 row)

    위 결과는 OID와 relfilenode 값이 같다. tbl_a 테이블의 데이터 파일 경로가 base/16384/16553이다.

    [bylee@bylee5 agensgraph]$ ls -ld data/base/16384/16553
    -rw-------. 1 bylee bylee 0 11월 19 10:01 data/base/16384/16553

    테이블과 인덱스 relfilenode 값을 TRUNCATE, REINDEX, CLUSTER와 같은 명령어를 실행해 변경한다.

    예를 들어, tbl_a 테이블을 TRUNCATE하면 PostgreSQL은 relfilenode(16635)에 새로운 값을 할당하며, 이전 데이터 파일(16553)을 제거하고 새로운 파일(16635)을 생성한다. 

    (bylee@[local]:5432) 17:27:55 [bylee] > truncate tbl_a;
    TRUNCATE TABLE
    (bylee@[local]:5432) 17:28:00 [bylee] > select relname, oid, relfilenode from pg_class where relname = 'tbl_a';
     relname |  oid  | relfilenode 
    ---------+-------+-------------
     tbl_a   | 16553 |       16635
    (1 row)

    9.2 버전부터 pg_relation_filepath 내장함수는 지정된 OID 또는 이름을 인자로 호출하면 파일 경로를 반환한다.

    (bylee@[local]:5432) 17:28:12 [bylee] > select pg_relation_filepath('tbl_a');
     pg_relation_filepath 
    ----------------------
     base/16384/16635
    (1 row)

    테이블과 인덱스의 크기가 1GB를 넘어가면 PostgreSQL은 새로운 파일을 생성한다. 이 파일은 relfilenode.1과 같은 이름을 갖는다. 새로운 파일이 가득차면 다음 새로운 파일은 relfilenode.2와 같은 이름을 갖는다.

    테이블과 인덱스의 최대 크기는 PostgreSQL을 빌드할 때 --with-segsize 옵션으로 변경할 수 있다.

     

    데이터베이스 디렉토리에는 _fsm, _vm이 붙은 파일을 볼 수 있다.

    fsm은 free space map이고 vm은 visibility map이다. 이는 테이블 파일의 각 페이지의 free space capatity와 visibility 정보를 저장한다.

     

    테이블 스페이스

     

     

     

     

     

     

     

     

    Heap Table File의 Internal Layout

     

     

     

Designed by Tistory.