Postgresql 을 사용해보자.
Database 를 접해본 사람이라면 누구나 Postgresql 이라는 이름을 한번쯤은 들어보았을 것이다.
Postgres 가 상당히 유연하게 잘 만들어진 Opensource 제품임에도 불구하고, 이상하게도 우리나라에서는 이를 사용하는 시스템을 거의 본 적이 없는 것 같다.
이는 아마도 유지보수문제 때문일 듯 한데, 듣기로는 일본에서는 이러한 Postgresql 에 대한 연구가 꽤 많이 진행되었고, 이를 통해 유지보수로 먹고 사는 업체도 상당수 있는 듯 하다.
하지만, 우리나라에서는 아직 그런 단계는 아닌 것 같다.
어쨌건, 회사일로 잠깐 맛을 본 Postgresql 은 꽤나 이용이 편한 괜찮은 DB 였던 것 같다.
물론 DB 를 직접 개발하는 전문가의 눈으로 본다면 Storage Manager 의 구조 등에 어느 정도 단점들이 보이겠으나 어쨌건 공짜 Database 가 아니겠는가 ?
그것도 웬만한 상용 Disk DB 에 결코 뒤지지않는...
맛보기로 사용해 보면서 나중에 또 생각이 안날까봐 좀 적어둔 내용을 이곳에 옮긴다.
아마 다른 사이트에서 찾아보기 힘든 내용도 있을 것이다.
왜냐하면, 내가 직접 경험하고 소스 찾아본 내용들을 정리한 것이기 때문에...
다만, 좀더 많이 진행해보지 못한 점이 좀 아쉽다.
소스를 초기 기동부터 쭈욱 따라가보려는데 다른 일이 생겨서 중간에 멈추게 되었다.
중간에 그림이 짤린 부분이 있는 것 같아서 파일도 함께 첨부한다.
cfile7.uf.2115C83A527A517A3470B3.doc
- Download 및 설치
- 기동 및 중지
- 접속
- Postgresql 내부 구조
- Utility Process
- Postgres 기동 과정 분석 (코드 분석)
- Stat Collector 의 통계 Data 수집 방법 분석
- Shared Preload Library 이용 방법
- 소스 directory 구조
- 참고자료
Download 및 설치
- http://www.postgresql.org/ 에 가서 source 또는 package 를 다운로드한다.
- http://www.postgresplus.co.kr/man/index.html (한글매뉴얼)에 가서 "서버의 관리" -> "설치 지시" 부분을 따라하면 된다.
해당 한글 매뉴얼은 http://www.postgresql.org 에 있는 Manual Document 중 일부를 번역해놓은 것이다.
정리하면 다음과 같은 순서...
a. ./configure --prefix=/home/dplee/postgres
b. gmake
c. gmake check
d. gmake install - PATH 및 LD_LIBRARY_PATH 설정
a. export PATH=$PATH:/home/dplee/postgres/bin
b. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/dplee/postgres/lib
기동 및 중지
- 기동
pg_ctl start -D /home/dplee/postgres/share/postgresql
처음부터 이렇게 띄우면 PG_VERSION 이나 postgresql.conf 등의 설정파일을 찾지 못해
기동이 실패한다.
이는 data directory 가 만들어져있지 않기 때문이다.
"data directory" 에는 Postgres 를 기동하기 위해 필요한 각종 설정 파일(postgresql.conf,
hba.conf, ident.conf 등)과 Lock file 이 위치하게 되고, Redo Log(WAL)나 Transaction 정보,
통계 정보 등을 관리하기 위한 각종 파일들이 위치하게 될 directory 이다.
이 directory 를 생성하려면 initdb 를 수행해야 한다. (user db 생성)
sh> initdb -D /home/dplee/postgres/share/dpleedata/ sh> pg_ctl start -D /home/dplee/postgres/share/dpleedata -l ./trc.log // 기동하면 아래와 같이 기본적으로 6 개의 프로세스가 기동된다. // 27188 프로세스가 postmaster 라는 전체 프로세스의 부모 프로세스이다. // 나머지는 해당 postmaster 프로세스가 fork 를 통해 생성하는 internal 프로세스들이다. // postmaster 프로세스는 Client 로부터의 접속요청이 들어오면 해당 Client 로부터의 요청을 // 처리할 전담 Process(User Backend Process)를 생성한 후 세션을 // 해당 프로세스에게 넘긴다. // 아래의 첫번째 postmaster 프로세스 이외의 internal 프로세스들을 통칭하여 utility process 라고 부른다. bitmyer 27188 1 0 11:19 pts/1 00:00:00 /home/bitmyer/work/post_dtrace/bin/postgres -D /home/bitmyer/work/post_dtrace/share/dpleedata bitmyer 27237 27188 0 11:20 ? 00:00:00 postgres: checkpointer process bitmyer 27238 27188 0 11:20 ? 00:00:00 postgres: writer process bitmyer 27239 27188 0 11:20 ? 00:00:00 postgres: wal writer process bitmyer 27240 27188 0 11:20 ? 00:00:00 postgres: autovacuum launcher process bitmyer 27241 27188 0 11:20 ? 00:00:00 postgres: stats collector process
pg_ctl 을 사용하지 않고 postgres 라는 binary 를 이용하여 직접 postgres -D /home/dplee/postgres/share/dpleedata 와 같이 기동해도 된다.pg_ctl 도 어차피 내부적으로 fork 를 통해 postgres 를 기동에 이용하는 손쉬운 기동/중지를 위한 툴일 뿐이다.-l ./trc.log 옵션을 주지 않으면 각종 trace log 가 standard out 으로 뿌려진다.
postgresql 에서 instance 라 함은 다음을 모두 종합한 개념이다. 오라클과 비슷하다 하겠다.Postmaster Process + 메모리(Shared, Local) + User Backend Process + Utility Process
- 중지
sh> pg_ctl stop -D /home/dplee/postgres/share/dpleedata
접속
- database 생성
psql 또는 client program 을 통해 postgres에 접속하려면 database 가 생성되어 있어야 한다.
sh> createdb mydb
- psql 을 통한 접속 및 sql 수행
dual 테이블은 직접 생성해주어야 한다.
sh> psql mydb psql (9.2.4) Type "help" for help. mydb=# create table dplee(c1 integer); CREATE TABLE mydb=# insert into dplee values(1); INSERT 0 1 mydb=# select * from dplee; c1 ---- 1 (1 row)
- psql 등 client 접속 시의 Process 상태
psql 을 통해 접속하면 9277 Process 가 하나 더 생성되어 있음을 확인할 수 있다. 이 프로세스가 바로 postmaster(27188) 프로세스가 fork 해서 생성한 User Backend Process 이다.
이 프로세스는 향후 psql 에서 수신하는 요청을 직접 처리하게 된다.
bitmyer 27188 1 0 11:19 pts/1 00:00:00 /home/bitmyer/work/post_dtrace/bin/postgres -D /home/bitmyer/work/post_dtrace/share/dpleedata ==> postmaster process bitmyer 27237 27188 0 11:20 ? 00:00:00 postgres: checkpointer process ==> checkpointer process bitmyer 27238 27188 0 11:20 ? 00:00:00 postgres: writer process ==> backgroud writer process bitmyer 27239 27188 0 11:20 ? 00:00:00 postgres: wal writer process ==> wal writer process bitmyer 27240 27188 0 11:20 ? 00:00:00 postgres: autovacuum launcher process ==> auto vacuum launcher process bitmyer 27241 27188 0 11:20 ? 00:00:00 postgres: stats collector process ==> statistics collector process bitmyer 9277 27188 0 12:11 ? 00:00:00 postgres: bitmyer mydb [local] idle ==> user backend process
Postgresql 내부 구조
아래의 두 그림은 Postgresql 의 내부 구조를 약간 다른 관점에서 간략히 그려본 것이다.
psql 을 통한 Query 요청의 처리과정을 아주 간단히 살펴보면 다음과 같다.
- psql 실행 : 5432(default) port 로 listen 하고 있는 postmaster 로 접속 요청
- postmaster 에서 접속 요청을 받아들인 후 fork 를 통해 User Backend Process 생성 및 메모리 준비
- 접속은 postmaster 에서 User Backend Process 로 넘김.
- psql 에서 Query 실행
- User Backend Process 가 해당 Query 를 Parsing / Generate Path,Plan / Execute Plan
Utility Process
Utility Process 는 postgres 에서 관리하는 backgroud process 들이다. Buffer Flush 나 WAL 로그 기록 등 Oracle 에서이 Log Writer 나 DB Writer, Archiver 등의
역할을 수행하는 Process 집합이다. 해당 Process 의 종류와 역할, 관련 설정을 간단히 살펴본다.
프로세스 이름 | 설 명 | 관련 설정 |
---|---|---|
BGWriter (Background Writer) |
buffer 의 변경 내용들을 Disk 로 내리는 역할을 담당한다 (checkpointer) Backend Process 는 Shared Buffer 에만 기록한다. |
|
WAL Writer | Redo Log(WAL)를 Disk 에 기록하는 역할을 담당한다. Backend Process 는 WAL Buffer 에만 기록한다. |
|
AutoVacuum | 삭제된 튜플이 차지하고 있는 공간을 청소해주는 역할을 담당한다. autovacuum launcher Process 는 실제 작업은 안하고 Worker Process 를 생성해주면 Worker Process 가 Vacuum 작업을 수행한다. |
|
Stats Collector | 각종 통계 정보 수집 Process. 수집한 정보는 pg_stat_xxxx view 들을 통해 확인 가능하다. |
|
Checkpointer | 모든 checkpoint 를 담당한다. (9.2 버전에서 checkpointer 가 새로 나옴) |
|
archiver | WAL archive 담당 |
|
Postgres 기동 과정 분석 (코드 분석)
pg_ctl -D /home/bitmyer/work/post_dtrace/share/dpleedata -l logfile start 와 같이 postgres 를 기동 시에 어떤 과정을 통해 instance 의 모든 프로세스들을 기동하고 어떤 작업들을 수행하느지 간략히 살펴보자.
- pg_ctl 시작
pg_ctl 은 인자로 받은 것들을 그대로 bin/postgres binary 에 전달하여 기동하고 중지하는 역할이외에 특별히 하는 일은 없다.
손쉽게 start/stop/restart/status 등을 수행할 수 있는 간단한 툴이다.
system() 함수를 이용하여 postgres binary, 즉 postmaster Process 를 기동한 후 자신은 exit 로 빠져나간다.postgresql-9.2.4/src/bin/pg_ctl/pg_ctl.c 소스 참조 - postmaster process 기동
postmaser process 및 backend process, utility process 들 모두는 postgres binary 를 이용하여 기동된다.
즉, 하나의 binary 를 기동하는 옵션에 따라 다른 동작을 하도록 구현되었다.
pg_ctl 을 이용하여 내부적으로 "postgres -D /home/dplee/..." 와 같은 명령으로 postmaster 프로세스가 구동되면 최초의 시작지점은 backend/main/main.c 이다.
해당 main 함수부터 postmaster 의 작업 내용을 따라가보자.gdb 나 ddd 를 통해 Backend Process 및 Utility Process 들을 trace 하고 싶을 때는
parent process 인 postmaster process 를 따라가지 말고 fork() 이후로 child process 를
따라가도록 설정해야 한다.gdb> set follow-fork-mode child
Shared Preload Library 이용 방법
postgres 는 pg_stat_statements 같은 외부 shared library 형태의 추가 기능을 preload 하여 사용할 수 있는 기능을 제공한다.
요 기능은 매뉴얼이나 다른데 찾아보면 잘 나온다.
소스 directory 구조
www.postgresql.org 사이트에서 다운로드한 소스파일의 압축을 풀면 postgresql-9.2.4/src/tools/backend/backend_dirs.html 파일을 볼 수 있다.
해당 파일을 explorer 로 열어보면 각 소스 directory 에 대한 간략한 설명을 볼 수 있다.
참고자료
- Postgres WAL Internal
http://www.google.co.kr/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=7&ved=0CGoQFjAG&url=http%3A%2F%2Fwww.pgcon.org%2F2012%2Fschedule%2Fattachments%2F258_212_Internals%2520Of%2520PostgreSQL%2520Wal.pdf&ei=4mXnUc2RB4z9lAWy5YDYBw&usg=AFQjCNHckOx_pYvhkfvfXFY8T0Lhm_A0Yw&sig2=g8SaKCde6FrCaqFmKcwX9Q&bvm=bv.49478099,d.dGI&cad=rjt - bgwriter 개념
http://ben.goodacre.name/tech/Background_Writer_(bgwriter)_(PostgreSQL) - Additional Supplied Module
http://www.postgresql.org/docs/8.4/static/pgstatstatements.html