postgresql에서 사용하는 스토리지 아키텍처는 실제 데이터의 스토리지 구조와 구성 형태를 건드리는 것으로, 데이터베이스에 저장된 데이터는 원래 여기에 있습니다.

스토리지 아키텍처

여기에 이미지 설명 삽입

칼럼 내용 :
postgresql 커널 소스 코드 분석
수기 데이터베이스 toadb
동시 프로그래밍
개인 홈페이지 : 내 홈페이지
좌우명: Tian Xingjian, a Gentleman Strengths for Self Improvement;

개요

postgresql 데이터베이스 서비스가 실행 중일 때 데이터는 디스크에 어떻게 저장됩니까? 여기에는 스토리지 아키텍처가 포함됩니다.
파일 시스템에서 우리는 디렉토리와 파일의 형태로 저장 장치를 볼 수 있습니다.이것이 물리적 저장 구조입니다.
이 디렉토리와 파일은 실제로 특정 연결과 조직 형식을 가집니다.예를 들어, 가장 바깥쪽 디렉토리는 클러스터 데이터 디렉토리입니다.각각 데이터베이스에는 논리적 스토리지 아키텍처인 디렉토리가 있습니다.

논리적 스토리지 아키텍처는 물리적 디스크 파일의 조직적 형태를 유지하고 물리적 스토리지 아키텍처는 특정 디스크 파일의 프레젠테이션입니다.

논리적 스토리지 아키텍처

네임스페이스

논리적으로 데이터베이스에는 여러 계층의 조직 관리 네임스페이스가 있습니다.

여기에 이미지 설명 삽입

Cluster->tablespace tablespace->database->schema
여기서 스키마는 데이터베이스 커널의 데이터 사전에 의해 구별되므로 처음 세 항목은 모두 스토리지 아키텍처의 구성을 통해 공간과 물리적으로 독립적입니다.
이는 이전 커널 분석 글에서도 언급한 바 있는데, 테이블 파일의 위치 역시 테이블스페이스/데이터베이스/관계의 3단계로 고유하게 식별된다.

클러스터의 개념상 클러스터는 데이터가 저장되는 디렉토리인 initdb에 의해 생성되며, 데이터베이스 서비스가 시작될 때 지정해야 하며 일반적으로 PGDATA라고 합니다.

데이터 파일

사용자 데이터 파일

테이블, 인덱스, 해당 vm 및 fsm 파일이 있으며 모두 네임스페이스의 계층적 디렉토리에 따라 저장됩니다.

거래 관련 데이터

클러스터 수준 공간에서 관리하며 클러스터 디렉터리 아래에 공용 디렉터리가 있습니다.

다른 조직 문서

테이블스페이스 파일, 데이터 사전 파일, 템플릿 라이브러리, 실행 로그 등의 파일은 모두 클러스터 수준에서 관리되며 클러스터 디렉터리 아래에 자체 디렉터리가 있습니다.

구성 파일

  • 데이터베이스 구성 파일

postgresql.conf

  • 클라이언트 액세스 제어 프로필

pg_hba.conf 및 pg_ident.conf

보조 문서

버전 파일, 실행 정보 파일 등은 모두 PGDATA의 루트 디렉토리에 있습니다.

물리적 스토리지 아키텍처

  1. 일반적으로 PGDATA로 참조됩니다(이를 정의하는 환경 변수의 이름 사용). PGDATA의 일반적인 위치는 /var/lib/pgsql/data입니다. 서로 다른 데이터베이스 인스턴스에서 관리하는 여러 클러스터가 동일한 시스템에 공존할 수 있습니다.
  2. 테이블이나 인덱스가 1GB를 초과하면 1G 크기의 세그먼트로 나뉩니다.
    첫 번째 세그먼트의 파일 이름은 파일 노드와 동일하며 후속 세그먼트의 이름은 filenode.1, filenode.2 등으로 지정됩니다. 이 배열은 파일 크기 제한이 있는 일부 플랫폼에서 문제를 방지합니다(실제로 1GB는 기본 세그먼트 크기입니다. 세그먼트 크기는 PostgreSQL을 컴파일할 때 --with-segsize 구성 옵션을 사용하여 조정할 수 있습니다). 원칙적으로 여유 공간 맵 및 가시성 맵 분기에도 여러 세그먼트가 필요할 수 있지만 실제로는 거의 발생하지 않습니다.
  3. 각 데이터베이스에는 라이브러리의 테이블 파일을 저장하는 별도의 디렉토리가 있습니다.

클러스터 파일 구조

먼저 완전히 새로운 데이터베이스 클러스터를 초기화한 다음 데이터베이스를 초기화하고 시작합니다.

# 初始化postgres数据库集簇 
/opt/postgres/bin/initdb -D pgtest -W

# 启动数据库,监听端口指定为 8888 
/opt/postgres/bin/pg_ctl -D pgtest -l logfile -o "-p 8888" start

# 以命令行客户端,登陆数据库,指定端口和数据库
/opt/postgres/bin/psql -p 8888 -d postgres

다음은 initdb가 완료되고 새로운 테이블스페이스가 생성된 후
일부 파일 형식을 보기 위해 임시 테이블, 언로그 테이블, 인덱스를 빌드한 후의 클러스터 디렉터리 구조이며,
일부 테이블의 파일 목록은 생략하였다. 중간, 디렉터리 계층 구조 및 키 파일이 유지됩니다.

-- 表空间 
create tablespace tblspc_test location '/mnt/sda1/data/pgdata/pgtblspc';

-- 普通表 
create table tbl_account(id integer, name varchar, address varchar, tel varchar);

-- 临时表 会话退出后就会删除 
create temporary table tmptbl_test(id int, c_id int);

-- unlogged 表,不会记录WAL,恢复时数据全部丢失 
create unlogged table unlogtbl_test(c_id int ,consumer varchar);
create index on unlogtbl_test (c_id);

위의 장면 구성 후 데이터베이스 클러스터 아래의 파일 및 디렉터리 계층 구조를 살펴보겠습니다.

[senllang@hatch pgdata]$ tree pgtest
pgtest
├── base
│   ├── 1
│   │   ├── 112
│   │   ├── 113
│   │   ├── 1247
│   │   ├── 1247_fsm
│   │   ├── 1247_vm
│   │   ├── 1249
......
│   │   ├── 827
│   │   ├── 828
│   │   ├── pg_filenode.map
│   │   ├── pg_internal.init
│   │   └── PG_VERSION
│   ├── 4
│   │   ├── 112
│   │   ├── 113
│   │   ├── 1247
│   │   ├── 1247_fsm
│   │   ├── 1247_vm
......
│   │   ├── 6238
│   │   ├── 6239
│   │   ├── 826
│   │   ├── 827
│   │   ├── 828
│   │   ├── pg_filenode.map
│   │   └── PG_VERSION
│   └── 5
│       ├── 112
│       ├── 113
│       ├── 1247
│       ├── 1247_fsm
│       ├── 1247_vm
│       ├── 16403
│       ├── 16403_init
│       ├── 16406
│       ├── 16406_init
│       ├── 16407
│       ├── 16407_init
│       ├── 16408
│       ├── 16408_init
│       ├── t3_16409
│       └── t3_16412
......
│       ├── 827
│       ├── 828
│       ├── pg_filenode.map
│       ├── pg_internal.init
│       └── PG_VERSION
├── global
│   ├── 1213
│   ├── 1213_fsm
│   ├── 1213_vm
│   ├── 1214
│   ├── 1232
│   ├── 1233
│   ├── 1260
│   ├── 1260_fsm
│   ├── 1260_vm
......
│   ├── pg_control
│   ├── pg_filenode.map
│   └── pg_internal.init
├── pg_commit_ts
├── pg_dynshmem
├── pg_hba.conf
├── pg_ident.conf
├── pg_logical
│   ├── mappings
│   ├── replorigin_checkpoint
│   └── snapshots
├── pg_multixact
│   ├── members
│   │   └── 0000
│   └── offsets
│       └── 0000
├── pg_notify
├── pg_replslot
├── pg_serial
├── pg_snapshots
├── pg_stat
├── pg_stat_tmp
├── pg_subtrans
│   └── 0000
├── pg_tblspc
│   └── 16388 -> /mnt/sda1/data/pgdata/pgtblspc
├── pg_twophase
├── PG_VERSION
├── pg_wal
│   ├── 000000010000000000000001
│   └── archive_status
├── pg_xact
│   └── 0000
├── postgresql.auto.conf
├── postgresql.conf
├── postmaster.opts
└── postmaster.pid

자세한 소개

파일 디렉토리 설명하다
PG_버전 PostgreSQL 주 버전 번호가 포함된 파일
베이스 각 데이터베이스에 대한 하위 디렉터리를 포함하는 하위 디렉터리
current_logfiles 로그 수집기에서 현재 작성 중인 로그 파일을 기록하는 파일
글로벌 pg_database와 같은 클러스터 전체 테이블을 포함하는 하위 디렉토리
pg_commit_ts 트랜잭션 커밋 타임스탬프 데이터가 포함된 하위 디렉터리
pg_dynshmem 동적 공유 메모리 서브시스템에서 사용하는 파일을 포함하는 서브디렉토리
pg_logical 논리적 복제를 위한 상태 데이터를 포함하는 하위 디렉터리
pg_multixact 다중 트랜잭션 상태 데이터를 포함하는 하위 디렉터리(공유 행 잠금용)
pg_notify LISTEN/NOTIFY 상태 데이터를 포함하는 하위 디렉토리
pg_replslot 복제 슬롯 데이터를 포함하는 하위 디렉터리
pg_serial 커밋된 직렬화 가능 트랜잭션 정보가 포함된 하위 디렉터리
pg_snapshots 내보낸 스냅샷이 포함된 하위 디렉토리
pg_stat 통계 서브시스템에 대한 영구 파일이 포함된 서브디렉토리
pg_stat_tmp 통계 서브시스템에 대한 임시 파일이 포함된 서브디렉토리
pg_subtrans 하위 트랜잭션 상태 데이터를 포함하는 하위 디렉터리
pg_tblspc 테이블스페이스에 대한 심볼릭 링크를 포함하는 하위 디렉토리
pg_twophase 트랜잭션 상태 파일 준비를 위한 하위 디렉터리 포함
pg_wal WAL(Write-ahead log) 파일을 포함하는 하위 디렉토리
pg_xact 트랜잭션 커밋 상태 데이터를 포함하는 하위 디렉터리
postgresql.auto.conf ALTER SYSTEM에서 설정한 구성 매개변수를 저장하는 데 사용되는 파일
포스트마스터.옵션 서버가 마지막으로 시작되었을 때 사용된 명령줄 인수를 기록하는 파일
포스트마스터.pid 현재 포스트마스터 프로세스 ID(PID), 클러스터 데이터 디렉토리 경로, 포스트마스터 시작 타임스탬프, 포트 번호, Unix 도메인 소켓 디렉토리 경로(Windows에서는 비어 있음), 사용 가능한 첫 번째 listen_address(IP 주소 또는 * 또는 비어 있음을 의미)를 기록하는 잠금 파일 TCP에서 수신하지 않음) 및 공유 메모리 세그먼트 ID(서버가 닫힌 후 파일이 존재하지 않음)

테이블스페이스

테이블스페이스에 임시 테이블, 일반 테이블, 데이터베이스 생성

-- 创建数据库,指定存储的表空间 
create database test tablespace tblspc_test ;

-- 在指定表空间创建临时表 
create temporary table tmptbl_test1(id int, c_id int) tablespace tblspc_test;

-- 在指定表空间创建普通表 
create table tbl_salary(id integer, level float, performance float) tablespace tblspc_test;

물리적 구조

테이블스페이스 디렉터리에 있는 파일을 보면 디렉터리 계층 구조와 파일 목록은 다음과 같습니다.

[senllang@hatch pgdata]$ tree pgtblspc/
pgtblspc/
└── PG_16_202306141
    ├── 16389
    │   ├── 112
    │   ├── 113
    │   ├── 1247
    │   ├── 1247_fsm
    │   ├── 1247_vm
    │   ├── 1249
    │   ├── 1249_fsm
    │   ├── 1249_vm
    ......
    │   ├── 826
    │   ├── 827
    │   ├── 828
    │   ├── pg_filenode.map
    │   └── PG_VERSION
    └── 5
        ├── 16395
        └── t3_16413

테이블스페이스의 디렉토리 아래에 PG_16_202306141 디렉토리가 있으며 이름은 PG로 시작하고 그 뒤에 데이터베이스 버전과 생성 날짜가 표시됩니다.
사용자 정의 테이블스페이스에는 물리적 테이블스페이스 디렉토리(즉, CREATE TABLESPACE 명령에 지정된 디렉토리)를 가리키는 PGDATA/pg_tblspc 디렉토리에 기호 링크가 있습니다.
심볼릭 링크는 테이블스페이스의 OID로 이름이 지정됩니다.

원리 설명

물리적 테이블스페이스 디렉토리에는 PG_16_202306141과 같이 PostgreSQL 서버의 버전에 따라 이름이 다른 하위 디렉토리가 있습니다(이 하위 디렉토리를 사용하는 이유는 데이터베이스의 후속 버전이 CREATE TABLESPACE를 사용하여 동일한 디렉토리 위치를 지정할 수 있기 때문입니다. 충돌을 일으킴).

이 버전별 하위 디렉터리 내에는 데이터베이스의 OID 이름을 따서 명명된 이 테이블스페이스의 요소가 있는 각 데이터베이스에 대한 하위 디렉터리가 있습니다. 이 디렉토리의 테이블과 인덱스는 파일 노드 명명 체계를 따릅니다.

클러스터 초기화 후 기본 테이블스페이스는 pg_default와 pg_global 두 가지가 있는데 테이블스페이스를 지정하지 않으면 생성된 데이터베이스, 테이블 등이 pg_default 테이블스페이스에 저장된다.
pg_default는 pg_tblspc를 통해 접근할 필요는 없지만 PGDATA/base에 해당한다. 마찬가지로 pg_global 테이블스페이스는 pg_tblspc를 통해 접근하지 않고 PGDATA/global에 해당한다.

데이터 베이스

여기에 이미지 설명 삽입

클러스터의 각 데이터베이스에 대해 PGDATA/base에 해당 하위 디렉터리가 있으며 하위 디렉터리의 이름은 pg_database에 있는 데이터베이스의 OID입니다.
이 하위 디렉토리는 데이터베이스 파일의 기본 위치이며 특히 데이터베이스의 시스템 카탈로그가 여기에 저장됩니다.

데이터 파일

pg_relation_filepath() 함수는 관계의 전체 경로(PGDATA에 상대적)를 표시합니다.
위의 많은 규칙을 암기하는 대신 사용할 수 있습니다.

그러나이 기능은 관계의 마스터 분기의 첫 번째 세그먼트 이름만 제공한다는 점을 기억하십시오. 관계와 관련된 모든 파일을 찾으려면 세그먼트 번호 또는 _fsm, _vm, _init를 추가해야 할 수도 있습니다.

테이블 및 인덱스 파일

각 테이블과 인덱스는 별도의 파일에 저장됩니다.
일반 테이블의 경우 이러한 파일은 pg_class.relfilenode에서 찾을 수 있는 테이블 또는 인덱스의 파일 노드 번호를 따라 이름이 지정됩니다.

임시 테이블

임시 테이블의 경우 파일 이름은 tBBB_FFF 형식입니다. 여기서 BBB는 파일을 만든 백엔드의 백엔드 ID이고 FFF는 파일 노드 번호입니다.

여유 공간 맵 fsm

각 경우에 마스터 파일 외부(a/k/a 마스터 브랜치)에는 테이블에서 사용 가능한 여유 공간에 대한 정보를 저장하는 각 테이블 및 인덱스에 대한 여유 공간 맵이 있습니다.
여유 공간 맵은 접미사가 _fsm인 노드 번호 다음에 이름이 지정된 파일에 저장됩니다.

가시성 지도 VM

이 테이블에는 _vm 접미사가 붙은 노드 번호가 있는 파일에 저장된 가시성 맵도 있습니다. 이 맵은 데드되지 않은 튜플을 포함하는 것으로 알려진 페이지를 추적하는 데 사용됩니다.

기록되지 않은 테이블

기록되지 않은 테이블과 인덱스, 즉 기록되지 않은 테이블에는 노드 번호와 접미사 _init가 있는 분기 파일에 저장되는 초기화 분기인 세 번째 분기도 있습니다.

초기화 분기는 적절한 유형의 빈 테이블 또는 인덱스입니다.
충돌로 인해 로깅되지 않은 테이블을 비워야 하는 경우 초기화 분기가 마스터 분기와 함께 복사되고 다른 분기는 지워집니다(필요할 때 자동으로 다시 작성됨).

토스트 테이블

테이블의 열이 상당히 큰 항목을 저장할 수 있는 경우 테이블에는
테이블 행에 보관할 수 없는 필드 값의 오프라인 저장에 사용되는 관련 TOAST 테이블이 있습니다.

테이블에 TOAST 테이블이 있으면 테이블의 pg_class.reltoastrelid가 해당 TOAST 테이블에 연결됩니다.

임시 파일

PGDATA/base/pgsql_tmp에는 임시 파일(메모리에 맞지 않는 데이터 정렬 등의 작업용)이 생성되며, 임시 파일이 pg_default 이외의 테이블스페이스에 지정된 경우 해당 테이블스페이스의 하위 디렉토리인 pgsql_tmp에 생성됩니다. 임시 파일의 이름은 pgsql_tmpPPP.NNN 형식이며 PPP는 해당 백엔드의 PID이며 NNN은 백엔드의 다른 임시 파일을 구분하는 데 사용됩니다.

많은 응원 부탁드립니다. 브라우징하면서 소중한 댓글 잊지마세요. 격려받을만 하다고 생각되시면 좋아요와 북마크 부탁드립니다. 더 열심히 하겠습니다!

저자 이메일: [email protected]
실수나 누락된 부분이 있으면 지적하고 서로 배우십시오.

참고: 동의 없이 전재하지 마십시오!

추천

출처blog.csdn.net/senllang/article/details/132129065