PostgreSQL •••

http://postgresql.kr/blog/postgresql_guide.html

0. 들어가며

이 내용은 지난 MySQL Power Group 카페 주관 2016년 2차 기술 세미나에서 발표한 내용을 정리한 것입니다.

엔지니어 - 개발자, 관리자 - 들을 위한 PostgreSQL의 좋은 점(•), 나쁜 점(•), 이상한 점(•)을 소개합니다.

1. 좋은 점

1.1. BSD 라이선스

PostgreSQL의 사용 허가서 즉 라이선스는 버클리 표준 배포 라이선스에 기초합니다.  이 라이선스의 가장 큰 특징은 소스를 변경하고 그 소스를 숨긴 채 재배포 해도 법적으로 문제가 없다는 점입니다. 이 점에서 자유 소프트웨어 재단(FSF)의 GNU 공중 라이선스(GPL)와 가장 큰 차이점이 있습니다.   이 두 라이선스의 대표적인 소프트웨어는 FreeBSD와, Linux(리눅스 커널과 많은 GNU 소프트웨어들) 입니다.  관계형 데이터베이스로는 PostgreSQL과 MySQL, MariaDB가 대표적인 각각 해당 라이선스를 채택하고 있습니다.

BSD 라이선스의 소스 수정 재배포의 자유로움 때문에, PostgreSQL은 주로 자사 솔루션과 함께 포함되는 무료 데이터베이스로 주로 사용되고, MySQL은 주로 웹 서비스에서 사용되고 있습니다.

오픈 소스 프로젝트에 BSD 형식의 라이선스를 사용해야 하는 이유라는 FreeBSD 측의 문서는 이 라이선스 문제를 아주 잘 설명하고 있습니다. 참고하세요.

1.2. 20년 전통의 역사

올해로 PostgreSQL 이라는 발음하기 힘든 이 이름이 등장한 지 20년 되었습니다.  이 데이터베이스의 시작은 이보다 훨씬 오래되었지만, 20년이라는 기간도 결코 적은 기간은 아니죠.  이렇게 오랫동안 계속 이 프로젝트가 유지되어 온 것은 개발 그룹의 헌신적인 노력도 있었겠지만,  BSD 라이선스라는 기업 독점이 힘든 라이선스 색깔과 FreeBSD 개발 & 배포 방법을 그대로 따르고 있는 아주 보수적인 절차들이 한 몫을 했습니다.

PostgreSQL의 기능 개발은 다른 오픈소스 프로젝트에 비해 많이 느립니다.  한 예로 9.3 버전에 처음 등장한 백그라운드 워커 인터페이스가 올 해 가을이나, 겨울에 나올 9.6의 병렬 쿼리 기능의 기반이 되었습니다.  즉 쿼리의 병렬 처리를 구현 하기 위해서 동적 백그라운드 워커 프로세스 처리 인터페이스를 만들고, 하나씩 필요한 기능을 차근히 진행해 무려 4년만에 겨우 병렬 쿼리를 구현했습니다.  스트리밍 복제 기능도 마찬가지였습니다.  왜 이렇게 답답하게 진행되는가는 첫번째는 사용자 층이 MySQL에 비해 많지 않기 때문에, 충분한 테스트를 거치는데 시간이 더 올래 걸리는 것도 있지만, 커밋페스트라는 전통적인 민주적 절차를 최대한 지켜려고 노력하기 때문입니다.  이렇게 해야 특정 기업의 기업 논리에 휘둘리지 않기 때문입니다. (민주주의는 느리다)


1.3. 비용절감

오픈 소스를 사용하면 비용절감이 된다고 많이들 이야기합니다.  또한 기업을 운영하는 입장에 이 이 이야기는 꽤나 솔깃합니다. 

PostgreSQL을 사용하면 관계형 데이터베이스를 이용하는데 어떤 비용도 들지 않습니다.

이 말은 거짓말입니다. 많은 비용이 들어갑니다.  - 기존 시스템을 PostgreSQL로 옮기겠다면,  개발자, 운영자의 재교육비가 들고, 전환 비용이 들고, 새 시스템의 하드웨어 비용이 듭니다.   또한 그렇게 옮겨온, 새로 구축한 시스템의 개발, 운영 관계자가 퇴사를 해 버리면, 그 대체 인력을 수급하기 위한 비용도 듭니다.  또 해당 서비스가 장사가 잘 되면,  서버 스케일업 비용 (CPU도 바꾸고, 메모리도 늘리고, 트랜잭션 로그 처리를 위한 빠른 SSD로 교체하는 비용), 백업 저장소 비용등 하드웨어 비용도 추가로 듭니다.

절대로 공짜가 아닙니다.  도입 의사 결정권자는 반드시 이런 모든 비용을 함께 계산해 보아야 할 것입니다.

그럼에도 불구하고, 단지 소프트웨어 구매비용만 생각한다면, 당연히 그 비용절감의 유혹은 참지 못할 유혹임은 분명합니다.


1.4. 확장성

PostgreSQL을 만져본 뭔가 만들기 좋아하는 개발자들 가운데 꽤 많은 분들이 PostgreSQL은 관계형 데이터베이스 관리 시스템이 아니라, 또 다른 데이터베이스 관리 시스템을 만들기위한 플랫폼이다고 찬사(?)를 보냅니다.

PostgreSQL 9.5 기준으로 CREATE 구문은 마흔개 정도가 됩니다. 즉, 웬만한 데이터베이스 객체들은 대부분 사용자가 원하는 대로 만들 수 있다는 말입니다.

pgxn.org 사이트를 중심으로 계속 자료가 쌓여가는 확장 기능들과, 상상력에 감탄하는 깜찍한 집계함수들, 타 데이터베이스 전환을 쉽게하는 자료형, 연산자의 사용자 정의화 등 뭔가 만들기를 좋기하는 개발자가 이 데이터베이스를 만지면, 한참을 신나게 만지고도 더 만질게 많다는 점에 놀라는 데이터베이스입니다.


1.5. 진보

PostgreSQL은 그 공식 사이트에서 '세상에 있는 오픈 소스 데이터베이스 가운데 가장 진보한 데이터베이스' 라는 슬로건으로 제품을 소개하고 있습니다.

그 개발과 배포는 참 엄격하고, 보수적이면서도 데이터베이스 자체의 색깔은 가장 진보적이다는 말을 사용합니다.  이렇게 진보적일 수 있는 이유는, BSD 라이선스 정책에 따라 보다 안정적이고, 기업 친화적인 제품을 원한다면, 그것을 원하는 기업이, 개발자가 직접 그런 것을 만들어서 장사를 하면 된다는 시장 경제 관점에서 좀 더 자유로운 위치에 있고 싶어하기 때문인 듯 합니다.

이렇게 PostgreSQL을 가지고 장사를 하고 있는 대표적인 기업들을 소개하면,

EnterpriseDB사의 Postgres Advenced Server 가 있고, 이 제품은 Oracle 호환성을 영업전략으로 사용하고 있습니다.  후지쯔사의 Enterprise Postgres, Greenplum 등 그 외 수 많은 제품들이 만들어졌다 사라지고 했습니다. 

하지만, 이렇게 격변하는 IT 시장에서 PostgreSQL은 한 발짝 뒤에 물러서 계속 진보를 추구하겠다는 점은 PostgreSQL만의 꽤 큰 좋은 점일 것입니다. (물론 이게 장점만 될 수는 없지만)


2. 나쁜 점

2.1. 의아한 오류 문

데이터베이스 인코딩이 euc_kr로 되어 있는데, '케잌'이 입력되면 오류를 냅니다. '2016-06-31'일을 입력해도,  숫자를 0으로 나누려고 해도 오류를 냅니다.  단순히 개발자 입장이라면 지극히 당연한 오류라고 생각이 들겠지만, 기업 환경 데이터베이스를 자주 썼던 분들에게는 이런 오류가 낯설기만 합니다.   왜냐하면, 기업 환경에서는 융통성이 필요하거든요.  PostgreSQL은 융통성인 그리 많지 않습니다.  limit, offset 구문이 그 대표적인 예입니다. ANSI SQL에서 limit offset 구문이 등장하면서 PostgreSQL의 구문을 ANSI 기준으로 바꿔버립니다.  데이터베이스 업그레이드 이후 코드 수정은 사용자 너네들 몫이니, 우리는 표준을 따르겠다는 식입니다.


2.2. 장애분석 보고서를 위해

PostgreSQL 기술문서는 한국어로 된 것이 많이 없습니다. 결국 장애 원인을 분석해야 한다면, 영문 설명서를 읽고, 구글에서 찾아보고, 번역기를 돌리고, 심지어 소스까지 열어보고, 더 정확한 원인을 찾기 위해, 개발 장비에 디버그 코드를 심어 컴파일하고, gdb 를 실행하는 일까지 하는 경우도 종종 생깁니다.  업무 분장이 잘 되어있는 기업 환경에서 이런 일을 해당 데이터베이스 관리자가 해야 한다는 것은 엄청난 부담입니다.

하지만, Do It Yourself! 라는 오픈소스의 오래된 슬로건을 기억한다면 위와 같은 작업은 오픈소스를 쓰는 쪽에서 기꺼이 짊어지고 가야 할 짐이겠지요.


2.3. 학습 비용

PostgreSQL의 공식 사용 설명서를 인쇄하면 A4 용지 총 3천 쪽 분량입니다.  이는 성경책보다 1천쪽이 더 많습니다.   그것도 아직까지 한글로 전체 번역되지 못 한 실정입니다.  PostgreSQL을 배워야하는 입장에서는 당연히 큰 부담입니다.  국내 사용자 층이 넓어 누구나 쉽게 배울 수 있는 것도 아니고,  전문적으로 컨설팅, 교육을 맡고 있는 기업도 없어 순전히 그 학습자의 의지에 달려있습니다.  얼마나 부지런히 찾아보고, 정리하고, 테스트 해봐야하는가에 따라 그 학습자의 역량 차이가 날 수 밖에 없는 환경입니다.

당장에, select 구문을 살펴보아도 MySQL의 그것과 차이가 확연합니다.  문서를 읽다가 지칩니다.

결국 PostgreSQL 도입을 염두해 둔다면, 이것을 사용하는 개발자, 운영자의 교육을 어떻게 유연하게 할 것인가를 고민해야 합니다.


2.4. TLDP를 넘어서는 독해력

앞의 이야기와 이어서, PostgreSQL의 문서 시스템은 리눅스 도큐먼트 프로젝트(TLDP)를 처음 접하는 이들의 당혹감과 비슷한 인상을 줍니다. 

그림은 하나도 없고, 오직 글들만 빽빽하게 있으며,  설명서를 읽다가 보면, 데이터베이스 내용 보다 천문학을, 유전공학을 이해해야하는 것은 아닌지하는 의심이 들 정도로, (메일링 리스트를 읽고 있으면 이들은 법조인이 아닐까? 하는 생각까지 들 정도로) 그 내용이 아주 산만합니다.   물론 요즘은 기업들이 많이 참여해서 좀 다듬어지기는 했지만, PostgreSQL 특유의 산만함은 여전합니다.

독해력이 좋아야 합니다.늘상 코드로 이야기하는 개발자 입장에 PostgreSQL을 사용하면 많이 갑갑합니다.  대표적인 예가 explain 출력 결과일 것입니다.  아마 관계형 데이터베이스 실행계획 출력 결과 가운데, PostgreSQL이 제일 읽기 힘들 것입니다. 

또한 릴레이션, 튜플, 어트리뷰트 같은 요즘은 관계형 데이터베이스 실무에서는 잘 쓰지 않는 용어들이 아직도 그대로 사용하고 있어, 처음 접하는 사람들에게는 많이 낯설 수 밖에 없습니다.


2.4. 진보를 표방한 비주류

PostgreSQL은 관계형 데이터베이스 내에서 주류가 아닙니다. 전세계에서 사용되고 있는 관계형 데이터베이스는 Oracle, MSSQL, MySQL이 대부분입니다.  메모리 캐시, NoSQL, 그래프 데이터베이스 등 수 많은 다양한 데이터베이스들이 점점 많이 사용되어지는 가운데, 관계형 데이터베이스는 점점 그 입지가 좁아지고 있습니다. 게다가 오픈소스 데이터베이스만 고려했을 때도, 이제는 MySQL과 그 관심도 격차가 많이 좁혀지기는 했지만, 아직까지도 PostgreSQL의 전세계 관심도는 MySQL에 많이 못 미칩니다.  IT 전체적인 시각에서 본다면, 정말 거대한 바다의 한 방울의 물일 뿐입니다.  주류로 편승하려면, 좀 더 기업 친화적인 성격을 가져야 할 텐데, 그렇지도 않습니다.  앞에서 이야기 했듯이 기업  친화적인 솔루션은 그걸 원하는 업체가 하면 될 것이다고 생각합니다.


3. 이상한 점

3.1 그들만의 글자들

PostgreSQL에서는 참 다양한 자료형과, 그 자료형에서 사용할 수 있는 연산자를 제공합니다.  PostgreSQL 기능을 참 잘 쓰는 이가 작성한 쿼리를 처음 보는 사람이 접하면, 마치 외계어 SQL을 보는 듯 할 것입니다.   ANSI 표준을 잘 지키겠다고 하면서, 새로운 기능이 필요하다고 느끼면, 그 기능에 맞는 자료형을 만들고, 그 연산자를 만듭니다.  이는 개발을 좀더 진보적으로 할 수 있는 길을 제공하기도 하지만, 기존 개발자들에게 또 새로운 학습 대상이 되어버립니다.  가장 대표적인 예가 range 자료형입니다.  기간을 저장할 수 있는 자료형인데, 특정 기간을 이 자료형으로 처리하면, 개발과 성능을 극대화 할 수 있습니다.  (한 번 사용해 보면 그 매력에 쉽게 벗어나질 못합니다.  기업 내 전사 데이터 거버넌스 부서의 제재를 받지 않는다면 말이죠)


3.2. 헷갈리는 해석

사용자 층이 얕은 탓에 어떤 견해가 중론으로 되지 못하고, 다양한 의견들이 존재합니다.  이것을 단점으로 볼 수도 있겠으나, 획일성보다는 다양성을 추구하는 입장에서는 좋은 점일 것이고, 사용자 입장에서는 취사 선택만 잘 하면 될 문제이기 때문에,  이상한 점으로 분류했습니다.

대표적인 예가 공유 버퍼 크기입니다.  어떤 이들은 너무 크게 잡으면 안된다고 하고, 어떤 이는 메모리가 수용하는 한 크게 잡는 것이 좋다고 합니다.  답은 원래의 공유 버퍼가 만들어진 의도 대로 쓰는 것이 답이죠.  공유 버퍼란 디스크 읽기 쓰기를 최소화 하기 위해서 사용되는 자료 페이지를 메모리에 보관하는 것이니, 성능 튜닝의 핵심은 얼마만큼의 공유 버퍼 크기가 디스크 읽기 쓰기에서 가장 효율적인가? 입니다.   어떤 서비스에서는 아주 적어도 되고, 어떤 서비스에서는 아주 큰 것이 더 효율적일 수 있겠죠.  이런 식입니다.  그런데, 이 문제는 모든 관계형 데이터베이스가 다 그렇지 않나싶네요.

autovacuum 설정도 마찬가지입니다. 어떤 이들은 효율적인 서비스를 위해서 autovacuum 기능을 끄는 것이 좋다고 하고, 어떤 이들은 보다 더 적극적으로 autovacuum 기능을 이용해야 한다고 합니다.   이 문제도 답은 autovacuum 원래의  의도를  잘 파악해서 잘 쓰면 된다는 아주 두리뭉실한 답이 전부인 것 같네요.   아직까지 PostgreSQL의 autovacuum 기능은 데이터베이스 관리자가 개입 해야 하는 상황이 발생하기는 합니다.  트랜잭션이 아주 빈번하거나, 자료량이 아주 많은 경우입니다.  그 외 경우는 관리자가 개입하지 않아도 자료를 잘 관리해서 항상 최적의 성능을 내도록 하는 원래의 기능이 잘 작동합니다.


3.3. 부모가 여럿

PostgreSQL의 독특한 점 가운데 대표적인 것이 테이블 상속입니다.  객체지향 언어처럼 상위 객체가 있고, (인터페이스 형태일 수도 있고) 그것의 속성을 상속해서 하위 객체를 만드는 것처럼 테이블을 그런 식으로 만들 수 있습니다.  처음 설계 당시에는 아주 혁신적인 기능이었지만, 전통적인 모델링 영역에서는 절대로 수용될 수 없었던, 그래서, 지금은 모두에게 외면 받는 기능 가운데 하나입니다.

이 기능이 아직도 아직까지 유효한 이유는 PostgreSQL에서는 테이블 파티션 기능을 이 상속 개념으로 구현합니다.  많이 낯설죠. (현재 개발 그룹에서는 새로운 테이블 파티션을 열심히 논의 중이기는 합니다.  언젠가는 바뀌겠지요.)

잘 쓰면 정말 멋진 기능인데, 표준이 되지 못하고, 그저 PostgreSQL의 독특한 점으로만 남아있는게 많이 아쉬운 부분입니다.


3.4. 그들만의 규칙

PostgreSQL은 룰(규칙)이라는 독특한 객체를 제공합니다. 해당 테이블을 조회하라는 요청이 오면, 조회 하지 말고, 다른 테이블을 조회해서 클라이언트에게 보내라는 식의 규칙입니다.  이 객체가 만들어진 이유는 이 규칙으로 관계형 데이터베이스 표준에서 이야기하고 있는 뷰와 트리거를 구현할 수 있다고 생각했기 때문입니다.  물론 어느 정도는 성공했습니다.  이 규칙 객체를 잘 쓰면 개발, 운영에서 꽤 많은 문제들을 쉽게 해결 할 수 있습니다.  문제는 이것이 ANSI SQL이 아니라는 점.

또 한 예로 'a' 문자열과 'a    ' 문자열이 같은가를 비교하는 부분에 있어 ANSI SQL 스펙 해석에 있어 견해 차이가 있습니다.  PostgreSQL에서는 varchar 자료형인 경우 이 둘은 다르다고 판단합니다.

트랜잭션 격리 수준에 대한 기본값도 Read Committed 입니다. Repeatable Read가 기본값인 데이터베이스를 사용했던 사용자라면 많이 의아스러운 부분입니다.


4. 마치며, 우버의 MySQL win back 이야기

마지막으로 최근 공개되어 많이 이야기 되었던 우버의 기술 문서에 대한 저의 개인적인 견해를 이야기하고자 합니다.

  • PostgreSQL의 다중키 인덱스 사용시 Heap Only Tuple 업데이트를 사용할 수 없어 성능이 저하된다 - 사실입니다. 하지만 해당 문서를 읽어보면, MySQL로 옮겨가면서 모델링을 key-value 방식으로 바꿨다고 합니다.  key-value 방식으로 간다면, 이 HOT  기능이 잘 쓸 수 있었을 것이고, 게다가 jsonb 형태로 자료형을 저장한다면, 추가로 gist 인덱스를 쓸 수 있어 보다 유연한 서비스를 구현할 수 있었을 것입니다.
  • 쿼리 기반 복제가 불가능하여 다양한 설계가 힘들다 - 사실입니다. 하지만, 2년전에 논리 디코딩 인터페이스가 구현되었습니다.  우버 개발자 정도면 이 기능을 이용해서 충분히 자체적으로 문제를 풀 수 있었을 것이라고 믿습니다. 단지 문제가 있었다면, 아래 데이터베이스 메이져 업그레이드의 단점이 발목을 잡았을 수는 있었겠지만, 그렇다고 하더라도, 충분히 기술적 한계를 극복할 수 있음에도 불구하고, 마냥 문제가 많았다고 하는 것은 좀 낯 부끄러운 부분인듯합니다.
  • 메이져 버전 업그레이드의 비용이 너무 많이 든다. - 이 부분도 사실입니다. pg_upgrade 명령으로 많은 부분이 개선되기는 했지만, PostgreSQL 특유의 하위호환성이 다른 기업 친화적인 데이터베이스보다 높지 않은 것은 사실입니다.  하지만, 이 부분은 진보를 표방하는 데이터베이스의 숙명이 아닐까합니다.  이런 데이터베이스를 쓰겠다는 것은 그만큼 실험적인 도전을 열심히 하겠다는 것이고, 우버 정도면 충분히 나설 수 있었을 것인데, 아쉽다는 생각을 합니다.

여기까지는 저의 개인적인 견해이며, PostgreSQL 개발자 그룹 내에서도 이 문제에 대해서 열심히 논의 하면서, 보다 더 각 영역의 코어 개발 역량이 필요하다는 이야기와 함께, 새 버전의 병렬 쿼리 처리 문제와 스토리지 플러그인, 좀 더 기업 친화적인 정책들 등 이런 저런 이야기들을 많이 하고 있더군요.

PostgreSQL이 과연 어떤 모습으로 변해 가는지 지켜보는 재미도 솔솔 할 것입니다.

참 매력적인 데이터베이스이죠?