pg_upgrade 명령을 사용할 때 기억해야 할 것들

http://postgresql.kr/blog/pg_upgrade.html
PostgreSQL 메이져 버전 업그레이드를 해야 할 경우 그 작업 방법은 현재로써는 두 가지 방법 뿐입니다.

하나는 pg_dumpall 명령과 pg_dump 명령을 이용해서 기존 데이터베이스 내용을 모두 SQL 구문으로 덤프 받아서 새 데이터베이스에서 그 덤프한 SQL 구문을 다시 실행하는 방법과,

또 다른 하나는 pg_upgrade 명령을 이용하는 것입니다.
pg_upgrade --help 명령을 이용하면 사용법이 나옵니다.
비교적 간단합니다. 또한 -k 옵션을 사용하면 덤프 & 복원 작업보다는 디스크 공간을 적게 사용합니다. 또한 엄청 빠릅니다. 그래서, pg_upgrade 명령을 사용해서, 메이져 버전 업그레이드 작업을 하는 것이 추세입니다.

하지만, 숨은 문제들이 제법있습니다.
pg_upgrade -c 옵션을 이용해서 업그레이드에 필요한 모든 사항을 확인 했다 하더라도, pg_upgrade 작업이 정상적으로 완료되지 않을 수 있습니다.
특히나 -k 옵션을 사용해서 하드링크 방식으로 업그레이드를 하는 경우라면, 중간에 작업을 실패하는 경우 난감합니다.

먼저 -c 옵션으로 미리 작업 타당성을 확인하는 작업에 가장 흔하게 나타나는 오류는 사용자 정의 확장 모듈입니다. pgxn 사이트나 github 같은 곳에서 소스를 직접 받아 설치한 확장 모듈은 새 버전에 당연히 그 확장모듈과 관련된 파일이 없습니다. 즉, 그 모듈을 일일히 확인해서 새 버전용으로 다시 만들고 설치해 주어야 합니다.

다음 9.6 업그레이드에서는 textsearch 부가 파일들 검사를 -c 옵션으로 미리 할 수 없습니다. 즉, -c 옵션으로 검사해서 업그레이드 할 준비가 다 되었다고 해서 업그레이드 작업을 진행했는데, 진행 도중 오류를 냅니다. share/tsearch_data 디렉터리 안에 필요한 파일이 없다는 오류입니다.

이 경우는 기존 데이터베이스 엔진 디렉터리에서 복사해와야 합니다.

그리고 다시 업그레이드 작업을 진행하면, initdb 작업을 한 새 데이터베이스 클러스트가 비어있지 않다면서 오류를 냅니다.
즉, 실재 업그레이드 작업이 진행되다가 실패한 경우라면, initdb 작업부터 다시 진행해야 합니다.

여기서 하나 기억해야 할 사실은 만일 새 데이터베이스 클러스트 디렉터리 밖에 있는 사용자 정의 테이블스페이스가 있다면, 여기서 문제가 생길 수 있습니다. 새로 initdb 작업을 한다고 해서, 사용자 정의 테이블스페이스까지 초기화 하지는 않기 때문입니다.

그래서, pg_upgrade 재 실행 전에 사용자 정의 테이블스페이스 디렉터러 안에 있는 이전 pg_upgrade 작업으로 생긴 파일들을 지워주어야 합니다.

이 사이트용 디비 서버의 pg_upgrade 작업은 이정도 시행착오로 잘 업그레이드 되었습니다.

하지만 여기서 끝이 아닙니다.

기존 postgresql.conf , pg_hba.conf , ssl 설정을 위해 사용되었던 서버 인증서, 서버 개인 키 등 이 정보들의 파일 복사, 파일 내용 병합 작업은 pg_upgrade -c 작업으로 확인할 수 없습니다. 이런 자질구레한 작업들을 작업전에 미리 계획에 넣어 두지 않으면, 그 만큼 업그레이드 작업 시간이 길어지게 됩니다.

이렇게 여러 작업 끝에 새 버전으로 잘 실행되었다 하더라도 아직 작업이 더 남아 있습니다.

하나는 기존 옛 버전에서 사용했던 데이터클러스터와 테이블스페이스 정리 작업을 해야 하고,
다른 하나는 새 데이터베이스가 처음 실행 되었기 때문에, 해당 데이터베이스의 빈공간  정리 작업과 자료 통계 정보 수집 작업이 필요합니다.

해당 데이터베이스에서 DML 작업이 아주 빈번하게 일어난다면, 바로 응용 프로그램 사용을 허용하게 되면, 빈번한 DML 작업이 일어날 것이고, 얼마 가지 않아, 트랜잭션 ID 겹침 방지를 위한 데이터베이스 보호 모드로 전환될 가능성이 큽니다.

왜냐하면, pg_upgrade 후 해당 데이터베이스는 급격하게 늙어버렸고, 그것에 대한 트랜잭션 ID 겹침 방지 작업을 autovacuum 작업으로 감당이 안되는 상황이 발생할 수 있기 때문입니다.
그래서, DML 작업이 빈번한 서버라면, pg_upgrade 작업 뒤 반드시 응용프로그램이 해당 데이터베이스를 사용하기 전에, vacuumdb -F -z -a 같은 명령으로 데이터베이스 클러스터를 정리해 줄 필요가 있습니다.

까먹기 전에 남겨 놓으려고 막 적었습니다. 문서가 많이 지저분하지만 알아서 잘 읽으세요.

추가.
역시 이렇게 정리를 해도 빼먹은 것이 있네요. 확장 모듈 버전이 올라간 경우, 기존 데이터베이스에서 사용했던 그 확장 모듈은 pg_update 작업으로 자동으로 그 확장 모듈의 버전까지 올리는 작업을 하지는 않습니다.  psql 접속 뒤 \dx 명령으로 사용하고 있는 확장 모듈을 찾아서,
alter extension 모듈이름 update;
명령으로 모든 확장 모듈을 업그레이드 해주어야 합니다.
물론 이 작업은 해당 서버에 있는 모든 데이터베이스에 해당됩니다.