알림: PostgreSQL 17 공식 문서를 한글로 번역한 글입니다.
이 책은 PostgreSQL의 공식 문서다. PostgreSQL 개발자들과 자원봉사자들이 PostgreSQL 소프트웨어 개발과 함께 작성했다. 현재 버전의 PostgreSQL이 공식적으로 지원하는 모든 기능을 상세히 설명한다.
방대한 PostgreSQL 관련 정보를 체계적으로 다루기 위해 이 책은 여러 부분으로 구성했다. 각 부분은 서로 다른 사용자층 또는 PostgreSQL 경험 수준이 다른 독자를 대상으로 한다:
제1부는 새로운 사용자를 위한 친근한 입문서다.
제2부는 SQL 쿼리 언어 환경을 다룬다. 데이터 타입, 함수, 사용자 수준의 성능 최적화를 포함한다. 모든 PostgreSQL 사용자가 반드시 읽어야 할 부분이다.
제3부는 서버 설치와 관리 방법을 설명한다. 개인용이든 다수의 사용자를 위해서든 PostgreSQL 서버를 운영하는 모든 이가 이 부분을 읽어야 한다.
제4부는 PostgreSQL 클라이언트 프로그램을 위한 프로그래밍 인터페이스를 설명한다.
제5부는 고급 사용자를 위한 서버 확장 기능을 다룬다. 사용자 정의 데이터 타입과 함수 같은 주제를 포함한다.
제6부는 SQL 명령어, 클라이언트와 서버 프로그램에 대한 참조 정보를 담고 있다. 명령어나 프로그램별로 체계적으로 정리된 정보로 다른 부분의 이해를 돕는다.
제7부는 PostgreSQL 개발자에게 유용한 다양한 정보를 담고 있다.
PostgreSQL은 객체-관계형 데이터베이스 관리 시스템(ORDBMS)이다. 버클리 대학교 컴퓨터 과학과에서 개발한 POSTGRES 버전 4.2를 기반으로 한다. POSTGRES는 여러 혁신적인 개념을 선보였는데, 이러한 기능 중 일부는 훨씬 후에야 상용 데이터베이스 시스템에 도입되었다.
PostgreSQL은 이 버클리 코드를 기반으로 한 오픈소스 프로젝트다. SQL 표준을 광범위하게 지원하며 다음과 같은 현대적인 기능을 제공한다:
또한 PostgreSQL은 사용자가 다양한 방식으로 확장할 수 있다. 예를 들어 다음과 같은 요소를 추가할 수 있다:
자유로운 라이선스 정책 덕분에 PostgreSQL은 개인, 상업, 학술 목적 구분 없이 누구나 무료로 사용, 수정, 배포할 수 있다.
현재 객체 관계형 데이터베이스 관리 시스템(ORDBMS)으로 알려진 PostgreSQL은 캘리포니아 버클리 대학교에서 개발한 POSTGRES 패키지에서 시작됐다. 수십 년에 걸친 발전을 거듭한 끝에 PostgreSQL은 이제 세계 어디에서도 찾아볼 수 없는 가장 진보된 오픈소스 데이터베이스가 됐다.
Michael Stonebraker 교수가 이끈 POSTGRES 프로젝트는 미국 국방고등연구계획국(DARPA), 육군연구소(ARO), 국립과학재단(NSF), 그리고 ESL사의 지원을 받았다. 1986년에 POSTGRES 구현이 시작되었다. 시스템의 초기 개념은 [ston86]에서 처음 소개되었으며, 초기 데이터 모델의 정의는 [rowe87]에서 발표되었다. 당시 규칙 시스템의 설계는 [ston87a]에서 설명되었고, 저장소 관리자의 설계 근거와 아키텍처는 [ston87b]에서 자세히 다루었다.
이후 POSTGRES는 여러 차례 주요 릴리스를 거쳤다. 첫 번째 “데모웨어” 시스템은 1987년에 작동을 시작했고 1988년 ACM-SIGMOD 컨퍼런스에서 공개되었다. [ston90a]에서 설명된 버전 1은 1989년 6월에 일부 외부 사용자에게 공개되었다. 첫 번째 규칙 시스템에 대한 비평([ston89])에 대응하여 규칙 시스템을 재설계했고([ston90b]), 1990년 6월에 새로운 규칙 시스템을 탑재한 버전 2를 출시했다. 1991년에 등장한 버전 3은 다중 저장소 관리자 지원, 개선된 쿼리 실행기, 그리고 재작성된 규칙 시스템을 추가했다. Postgres95가 나오기 전까지 이후 릴리스들은 대부분 이식성과 안정성 향상에 집중했다.
POSTGRES는 다양한 연구와 실제 응용 프로그램 구현에 활용되었다. 금융 데이터 분석 시스템, 제트 엔진 성능 모니터링 패키지, 소행성 추적 데이터베이스, 의료 정보 데이터베이스, 여러 지리 정보 시스템 등이 그 예다. 또한 여러 대학에서 교육 도구로도 사용되었다. Illustra Information Technologies(후에 Informix에 합병되었으며, 현재는 IBM이 소유)는 이 코드를 가져가 상용화했다. 1992년 말, POSTGRES는 Sequoia 2000 과학 컴퓨팅 프로젝트의 주요 데이터 관리자가 되었다.
1993년에는 외부 사용자 커뮤니티가 거의 두 배로 성장했다. 프로토타입 코드의 유지보수와 지원에 많은 시간이 소요되어 데이터베이스 연구에 투자해야 할 시간이 줄어드는 것이 점점 더 분명해졌다. 이러한 지원 부담을 줄이기 위해 버클리 POSTGRES 프로젝트는 버전 4.2를 끝으로 공식적으로 종료되었다.
1994년 Andrew Yu와 Jolly Chen이 POSTGRES에 SQL 언어 해석기를 추가했다. 이후 Postgres95라는 새로운 이름으로 공개되어 Berkeley의 원본 POSTGRES 코드를 기반으로 한 오픈소스 프로젝트로 발전하기 시작했다.
Postgres95 코드는 완전한 ANSI C로 작성되었으며, 코드 크기가 25% 줄어들었다. 많은 내부 구조 변경을 통해 성능과 유지보수성이 크게 향상되었다. Wisconsin Benchmark 테스트 결과, Postgres95 1.0.x 버전은 POSTGRES 4.2 버전보다 30-50% 더 빠른 성능을 보여주었다. 버그 수정 외에도 다음과 같은 주요 기능이 개선되었다:
PostQUEL 쿼리 언어를 SQL로 대체했다(서버에서 구현). (인터페이스 라이브러리 libpq는 PostQUEL의 이름을 따왔다.) 서브쿼리는 PostgreSQL에서 지원될 때까지 구현되지 않았지만, 사용자 정의 SQL 함수를 통해 비슷한 기능을 구현할 수 있었다. 집계 함수를 새롭게 구현했으며, GROUP BY
쿼리절 지원도 추가했다.
GNU Readline을 사용하는 새로운 프로그램(psql)을 도입하여 대화형 SQL 쿼리를 가능하게 했다. 이는 기존의 모니터 프로그램을 크게 개선했다.
새로운 프론트엔드 라이브러리인 libpgtcl
을 도입하여 Tcl 기반 클라이언트를 지원했다. 샘플 셸인 pgtclsh
는 Tcl 프로그램과 Postgres95 서버를 연동하는 새로운 Tcl 명령어를 제공했다.
대용량 객체 인터페이스를 전면 개편했다. 인버전 대용량 객체가 대용량 객체 저장을 위한 유일한 메커니즘이 되었다. (인버전 파일 시스템은 제거됐다.)
인스턴스 수준의 규칙 시스템을 제거했다. 규칙은 재작성 규칙으로만 사용할 수 있게 되었다.
Postgres95의 기능과 함께 일반 SQL 기능을 소개하는 간단한 튜토리얼을 소스 코드와 함께 배포했다.
빌드 시스템을 BSD make 대신 GNU make를 사용하도록 변경했다. 또한 패치되지 않은 GCC로도 Postgres95를 컴파일할 수 있게 되었다(double 타입의 데이터 정렬 문제 해결).
1996년에 이르러 “Postgres95”라는 이름이 시대의 흐름에 맞지 않는다는 점이 분명해졌다. 원래의 POSTGRES와 SQL 기능이 추가된 최신 버전 사이의 관계를 표현하기 위해 PostgreSQL이라는 새로운 이름을 선택했다. 동시에 버전 번호를 6.0부터 시작하도록 설정했는데, 이는 버클리 POSTGRES 프로젝트에서 시작된 원래의 버전 순서를 이어가기 위한 결정이었다.
많은 사람들이 전통을 이어가거나 발음하기 쉽다는 이유로 PostgreSQL을 “Postgres”로 부르곤 한다(현재는 모두 대문자로 쓰는 경우가 드물다). 이러한 사용은 별칭이나 애칭으로 널리 인정받고 있다.
Postgres95 개발 과정에서는 서버 코드의 기존 문제점을 찾고 이해하는 데 중점을 두었다. PostgreSQL에서는 개발 중점이 기능과 성능 향상으로 옮겨갔지만, 모든 영역에서 개선 작업은 계속되고 있다.
그 이후 PostgreSQL에서 일어난 자세한 변화는 부록 E에서 확인할 수 있다.
커맨드 사용법을 설명할 때 다음과 같은 규칙을 적용한다:
[
와 ]
)는 선택적 요소를 표시한다{
와 }
)와 세로 막대(|
)는 여러 선택지 중 하나를 반드시 선택해야 함을 의미한다...
)은 앞의 요소를 반복할 수 있음을 나타낸다가독성을 높이기 위해 SQL 명령어 앞에는 =>
프롬프트를, 셸 명령어 앞에는 $
프롬프트를 표시한다. 일반적으로는 이러한 프롬프트를 생략한다.
*관리자*는 서버를 설치하고 운영하는 책임자를 의미한다. *사용자*는 PostgreSQL 시스템의 일부를 사용하거나 사용하고자 하는 모든 사람을 지칭한다. 이러한 용어들은 지나치게 좁은 의미로 해석하지 않아야 한다. 이 책은 시스템 관리 절차에 대해 특정한 가정을 두지 않는다.
이 책에서 다루는 문서 외에도 PostgreSQL에 대한 다양한 자료가 있다. 각각의 자료는 다음과 같다:
PostgreSQL 위키는 프로젝트의 자주 묻는 질문(FAQ), 향후 계획(TODO) 목록을 포함하고 있으며, 더 많은 주제에 대한 상세한 정보를 제공한다.
PostgreSQL 공식 웹사이트는 최신 릴리스에 대한 세부 정보와 함께 PostgreSQL을 더 생산적으로 활용할 수 있는 다양한 정보를 제공한다.
메일링 리스트는 질문에 대한 답변을 얻고, 다른 사용자들과 경험을 공유하며, 개발자들과 소통할 수 있는 좋은 공간이다. 자세한 내용은 PostgreSQL 웹사이트에서 확인할 수 있다.
PostgreSQL은 오픈소스 프로젝트다. 따라서 사용자 커뮤니티의 지속적인 지원이 매우 중요하다. PostgreSQL을 사용하기 시작하면서 문서나 메일링 리스트를 통해 다른 사람들의 도움을 받게 될 것이다. 이제는 여러분이 가진 지식을 다시 커뮤니티에 환원할 차례다. 메일링 리스트를 읽고 다른 사람의 질문에 답변하자. 문서에 없는 새로운 내용을 알게 되면 작성해서 공유하자. 코드에 새로운 기능을 추가했다면 그것도 기여하자.
PostgreSQL에서 버그를 발견하면 즉시 알려주기 바란다. 아무리 철저한 관리를 한다 해도 모든 환경과 상황에서 PostgreSQL의 모든 기능이 완벽하게 동작한다고 보장할 수 없기 때문에, 버그 리포트는 PostgreSQL의 안정성을 높이는 데 매우 중요한 역할을 한다.
다음 제안 사항들은 효율적으로 처리할 수 있는 버그 리포트를 작성하는 데 도움을 줄 것이다. 이를 반드시 따라야 하는 것은 아니지만, 이 가이드라인을 준수하면 모두에게 유익하다.
모든 버그를 즉시 해결할 수는 없다. 버그가 명백하거나 심각하거나 많은 사용자에게 영향을 미치는 경우라면 누군가가 신속히 검토할 가능성이 높다. 때로는 최신 버전으로 업데이트해서 버그가 여전히 발생하는지 확인을 요청할 수도 있다. 또는 계획 중인 주요 재작성 작업 이전에는 수정이 불가능하다고 판단할 수도 있다. 혹은 단순히 버그 수정이 너무 어렵거나 더 중요한 작업이 있을 수도 있다. 긴급한 도움이 필요하다면 상용 지원 계약을 고려해 보기 바란다.
버그를 보고하기 전에 문서를 꼼꼼히 읽고 시도하려는 작업이 실제로 가능한지 확인한다. 문서에서 특정 기능의 가능 여부가 명확하지 않다면 이 또한 문서의 버그이므로 보고한다. 프로그램이 문서의 설명과 다르게 동작한다면 이는 버그다. 다음과 같은 상황이 버그에 해당한다:
프로그램이 치명적인 시그널이나 운영체제 오류 메시지와 함께 종료되는 경우. (단, “디스크 공간 부족”과 같이 사용자가 직접 해결해야 하는 문제는 제외한다.)
프로그램이 주어진 입력에 대해 잘못된 출력을 생성하는 경우
프로그램이 문서에 명시된 올바른 입력을 거부하는 경우
프로그램이 잘못된 입력을 알림이나 오류 메시지 없이 받아들이는 경우. 다만, 사용자가 잘못된 입력이라고 생각하는 것이 확장 기능이나 기존 관행과의 호환성을 위한 것일 수 있음을 유의한다.
PostgreSQL이 지원되는 플랫폼에서 문서의 지침대로 컴파일, 빌드 또는 설치되지 않는 경우
여기서 “프로그램”은 백엔드 프로세스뿐만 아니라 모든 실행 파일을 지칭한다.
실행 속도가 느리거나 리소스를 많이 사용하는 것이 반드시 버그는 아니다. 애플리케이션 성능 최적화에 대한 도움이 필요하다면 문서를 참고하거나 메일링 리스트에 문의한다. SQL 표준을 따르지 않는 것도 반드시 버그는 아니다. 단, 특정 기능이 명시적으로 표준 준수를 주장하는 경우는 예외다.
계속 진행하기 전에 TODO 목록과 FAQ를 확인하여 해당 버그가 이미 알려져 있는지 확인한다. TODO 목록의 정보를 이해할 수 없다면 문제를 보고한다. 최소한 TODO 목록을 더 명확하게 개선할 수 있다.
버그 리포트 작성에서 가장 중요한 원칙은 사실만을 명확하게 기술하는 것이다. 무엇이 잘못됐는지 추측하거나, “이렇게 동작하는 것처럼 보였다”는 식의 표현, 또는 프로그램의 어느 부분에 문제가 있는지 짐작하는 내용을 포함하지 않는다. 구현 방식에 익숙하지 않다면 잘못된 추측을 할 가능성이 높고, 이는 전혀 도움이 되지 않는다. 설령 구현 방식을 잘 알고 있더라도, 전문적인 설명은 좋은 보완 자료가 될 수는 있지만 실제 사실을 대체할 수는 없다. 개발자가 버그를 수정하려면 먼저 직접 문제 상황을 재현해 봐야 하기 때문이다. 단순한 사실을 보고하는 것은 비교적 간단하지만(화면에서 복사하여 붙여넣기만 하면 된다), 중요한 세부사항이 누락되는 경우가 많다. 이는 보고자가 그 내용이 중요하지 않다고 판단하거나, 보고서를 보면 알아서 이해할 것이라고 생각하기 때문이다.
버그 리포트에는 다음 항목을 반드시 포함해야 한다:
SELECT
문장만 보내는 것으로는 부족하고 이전의 CREATE TABLE
과 INSERT
문장도 함께 포함해야 한다. 개발자가 데이터베이스 스키마를 역설계할 시간이 없으며, 임의로 데이터를 만들어 테스트하면 실제 문제를 놓칠 수 있다.SQL 관련 문제의 테스트 케이스는 psql 프론트엔드로 실행할 수 있는 파일 형식이 가장 좋다. (~/.psqlrc
시작 파일에 내용이 없어야 한다.) 이러한 파일을 만드는 쉬운 방법은 pg_dump를 사용해 필요한 테이블 선언문과 데이터를 덤프한 다음, 문제가 되는 쿼리를 추가하는 것이다. 예제의 크기를 최소화하면 좋지만, 이는 필수 사항은 아니다. 버그가 재현 가능하다면 어떤 방식으로든 문제를 찾아낼 것이다.
PHP와 같은 다른 클라이언트 인터페이스를 사용하는 애플리케이션이라면, 문제가 되는 쿼리를 분리해서 보고하기를 권장한다. 개발팀이 웹 서버를 구성해서 문제를 재현하기는 어렵기 때문이다. 어떤 경우든 정확한 입력 파일을 제공해야 한다. “대용량 파일” 또는 “중간 크기의 데이터베이스”와 같이 모호한 표현은 실제 문제 해결에 도움이 되지 않는다.
#### 참고
오류 메시지를 보고할 때는 가장 상세한 형태의 메시지를 확보해야 한다. psql에서는 set VERBOSITY verbose
명령을 미리 실행한다. 서버 로그에서 메시지를 추출할 때는 실행 시 매개변수 log_error_verbosity를 verbose
로 설정해 모든 세부 정보가 기록되도록 한다.
#### 참고
치명적인 오류의 경우, 클라이언트가 보고하는 오류 메시지에 모든 정보가 포함되지 않을 수 있다. 데이터베이스 서버의 로그 출력도 반드시 확인한다. 서버 로그를 보관하지 않고 있다면, 지금부터라도 시작하는 것이 좋다.
예상했던 결과를 명시하는 것이 매우 중요하다. “이 명령어가 저런 출력을 보여줍니다” 또는 “이것은 내가 예상한 것이 아닙니다”라고만 작성하면, 개발자가 직접 실행해 보고 출력을 검토한 뒤 문제없이 예상대로 동작한다고 판단할 수 있다. 명령어의 정확한 의미를 해석하는 데 시간을 낭비하지 않도록 해야 한다. 특히 “이는 SQL 표준/Oracle의 동작과 다릅니다”라는 식의 표현은 피해야 한다. SQL 표준에서 올바른 동작을 찾아내는 것은 즐거운 작업이 아니며, 모든 개발자가 다른 관계형 데이터베이스의 동작 방식을 알고 있는 것도 아니다. (프로그램이 충돌하는 경우라면 이 항목은 생략할 수 있다.)
모든 명령줄 옵션과 기타 시작 옵션. 기본값에서 변경한 환경 변수나 설정 파일도 포함한다. 이 역시 정확한 정보를 제공해야 한다. 부팅 시 데이터베이스 서버를 시작하는 미리 패키징된 배포판을 사용한다면, 어떻게 시작되는지 확인하도록 한다.
설치 지침과 다르게 수행한 모든 작업.
PostgreSQL 버전 정보. 연결된 서버의 버전을 확인하려면 SELECT version();
명령을 실행하면 된다. 대부분의 실행 파일은 --version
옵션도 지원한다. 최소한 postgres --version
과 psql --version
은 동작할 것이다. 해당 함수나 옵션이 존재하지 않는다면, 업그레이드가 필요할 만큼 오래된 버전이라는 의미다. RPM과 같은 미리 패키징된 버전을 사용한다면 그 사실을 명시하고, 하위 버전 정보도 포함한다. Git 스냅샷을 사용한다면 커밋 해시와 함께 그 사실을 언급한다.
17.2보다 오래된 버전이라면 거의 확실히 업그레이드를 권장할 것이다. 각 새로운 릴리스에는 많은 버그 수정과 개선 사항이 포함되므로, 이전 버전의 PostgreSQL에서 발견한 버그가 이미 수정되었을 가능성이 높다. 이전 버전의 PostgreSQL에 대해서는 제한된 지원만 제공할 수 있다. 더 많은 지원이 필요하다면 상용 지원 계약을 고려해보는 것이 좋다.
버그 리포트가 길어지더라도 걱정하지 않는다. 이는 자연스러운 현상이다. 처음부터 모든 것을 보고하는 것이 나중에 개발자가 사실을 하나씩 확인해야 하는 상황보다 낫다. 반면, 입력 파일이 매우 큰 경우에는 먼저 누군가가 검토할 의향이 있는지 물어보는 것이 좋다. 버그 리포트 작성에 대한 더 많은 팁을 원한다면 이 문서를 참고하면 된다.
입력값을 어떻게 변경하면 문제가 사라지는지 알아내는 데 모든 시간을 쓰지 않는다. 이는 문제 해결에 도움이 되지 않을 것이다. 버그를 즉시 수정할 수 없다면, 나중에 해결 방법을 찾아 공유할 시간이 있을 것이다. 또한 버그가 왜 발생하는지 추측하는 데 시간을 낭비하지 않는다. 개발자가 충분히 빨리 원인을 찾아낼 것이다.
버그 리포트를 작성할 때는 혼란스러운 용어 사용을 피한다. 전체 소프트웨어 패키지는 “PostgreSQL”, 줄여서 “Postgres”라고 부른다. 백엔드 프로세스를 특정해서 언급하고 싶다면 그렇게 명시해야 하며, “PostgreSQL이 충돌했다”라고만 표현하지 않는다. 단일 백엔드 프로세스의 충돌은 부모 “postgres” 프로세스의 충돌과 매우 다르다. 단일 백엔드 프로세스가 종료된 것을 두고 “서버가 충돌했다”라고 하거나, 그 반대의 경우도 마찬가지다. 또한 대화형 프론트엔드 “psql”과 같은 클라이언트 프로그램은 백엔드와 완전히 분리되어 있다. 문제가 클라이언트 측인지 서버 측인지 구체적으로 명시하도록 한다.
일반적인 버그는 <pgsql-bugs@lists.postgresql.org>
메일링 리스트로 제출한다. 메일 제목에는 오류 메시지의 일부와 같이 버그를 잘 설명하는 내용을 포함한다.
프로젝트 웹사이트에서 제공하는 웹 양식을 통해 버그를 제출할 수도 있다. 이 방법으로 제출한 버그 리포트는 자동으로 <pgsql-bugs@lists.postgresql.org>
메일링 리스트로 전달된다.
보안 관련 버그의 경우 공개 아카이브에 즉시 노출되지 않기를 원한다면, pgsql-bugs
로 보내지 않는다. 보안 문제는 <security@postgresql.org>
로 비공개 제출할 수 있다.
<pgsql-sql@lists.postgresql.org>
또는 <pgsql-general@lists.postgresql.org>
와 같은 사용자 메일링 리스트로는 버그 리포트를 보내지 않는다. 이러한 메일링 리스트는 사용자 질문에 답변하는 용도이며, 구독자들은 버그 리포트를 받기를 원하지 않는다. 더욱 중요한 점은 이 리스트의 구독자들이 버그를 수정할 가능성이 낮다는 것이다.
또한 개발자 메일링 리스트인 <pgsql-hackers@lists.postgresql.org>
로도 버그 리포트를 보내지 않는다. 이 리스트는 PostgreSQL 개발 논의를 위한 공간이며, 버그 리포트는 별도로 관리하는 것이 좋다. 다만 버그에 대한 추가 검토가 필요한 경우 pgsql-hackers
에서 논의할 수 있다.
문서와 관련된 문제는 문서 메일링 리스트인 <pgsql-docs@lists.postgresql.org>
로 제출한다. 문서의 어느 부분에 문제가 있는지 구체적으로 설명한다.
지원되지 않는 플랫폼에서의 이식성 문제는 <pgsql-hackers@lists.postgresql.org>
로 보낸다. 이를 통해 개발자들과 함께 해당 플랫폼에 PostgreSQL을 이식하는 작업을 진행할 수 있다.
스팸 메일을 방지하기 위해 구독하지 않은 사용자가 보내는 모든 메일은 검토 과정을 거친다. 따라서 메일 전달에 약간의 지연이 발생할 수 있다. 메일링 리스트를 구독하려면 PostgreSQL 공식 메일링 리스트에서 안내하는 절차를 따르면 된다.