18.3. 데이터베이스 서버 시작

18.3.1. 서버 시작 실패
18.3.2. 클라이언트 연결 문제

데이터베이스에 액세스하기 전에 데이터베이스 서버를 시작해야 한다. 데이터베이스 서버 프로그램을 postgres라고 한다.

미리 패키징된 PostgreSQL 버전을 사용한다면, 대부분 서버 실행 명령이 OS에서 서비스를 시작하는 명령으로 대체된다. 서버를 시작 작업은 그 미리 패키징된 버전을 사용하면, 수동으로 직접 서버를 실행하는 것보다 일이 적다. 자세한 설명은 패키지 사용 설명서를 참고하면 된다.

서버를 가장 저수준으로 직접 실행하는 방법은 postgres 명령을 실행하는 것이다. 이 때, 서버가 사용할 자료 파일이 있는 데이터 디렉터리를 -D 옵션으로 지정한다. 사용 예:

$ postgres -D /usr/local/pgsql/data

이렇게 하면 서버가 포그라운드에서 실행된다. 이것은 PostgreSQL 사용자 계정으로 로그인한 상태에서 해야 한다. -D가 없으면 이름이 환경 변수 PGDATA인 데이터 디렉터리를 서버가 사용하려고 한다. 해당 변수가 제공되지 않으면 실패하게 된다.

보통은 백그라운드에서 postgres를 시작하는 것이 좋다. 이것의 경우 일반적인 Unix 쉘 구문을 사용한다.

$ postgres -D /usr/local/pgsql/data >logfile 2>&1 &

위와 같이 서버의 stdoutstderr 출력을 어딘가에 저장해 놓는 것이 중요하다. 그러면 감사 및 문제 진단 시 도움이 된다(로그 파일 처리에 대한 자세한 내용은 24.3절 참조).

postgres 프로그램에는 다른 명령줄 옵션도 많이 있다. 자세한 내용은 postgres 참조 페이지 및 아래의 19장을 참조 바란다.

쉘 구문은 지루하고 따분하다. 따라서 일부 작업을 단순화할 수 있는 래퍼 프로그램 pg_ctl이 제공된다. 예:

pg_ctl start -l logfile

이것은 서버를 백그라운드에서 시작하고 출력을 지명된 로그 파일로 출력한다. -D 옵션은 postgres에서 사용된 것과 의미가 동일하다. pg_ctl으로도 서버를 중지할 수 있다.

보통은, 컴퓨터 부팅 시 데이터베이스 서버도 시작하는 것이 일반적이다. 자동 시작 스크립트는 운영 체제마다 다르다. PostgreSQL에서 배포되는 몇 가지 스크립트가 contrib/start-scripts 디렉터리에 있다. 하나를 설치하려면 루트 권한이 필요하다.

시스템이 다르면 부팅 시 데몬을 시작하기 위한 규칙(convention)도 달라진다. 다수의 시스템에 /etc/rc.local 또는 /etc/rc.d/rc.local 파일이 있다. 그 외에는 init.d 또는 rc.d 디렉터리를 사용한다. 서버는 루트 또는 다른 사용자가 아닌 PostgreSQL 사용자 계정으로 실행해야 한다. 그러므로 su postgres -c '...' 류의 명령을 사용해야 한다. 예를 들면:

su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog'

운영 체제별로 특수한 몇 가지 예시는 다음과 같다(각각의 경우 적절한 설치 디렉터리와 사용자 이름을 사용해야 하며, 여기서는 일반적인 값을 사용한다.).

서버 실행 중에 PID는 데이터 디렉터리의 postmaster.pid 파일에 저장된다. 이것은 동일한 데이터 디렉터리에서 실행되는 다중 서버 인스턴스를 방지하는 데 사용되고, 서버를 셧다운하는 데에도 사용될 수 있다.

18.3.1. 서버 시작 실패

서버 시작 실패에는 몇 가지 공통된 원인이 있다. 서버의 로그 파일을 확인하거나 직접 시작해서(표준 출력 또는 표준 에러를 리다이렉트하지 않고) 에러 메시지를 확인해야 한다. 아래는 몇 가지 공통된 에러 메시지를 자세히 설명한다.


LOG:  could not bind IPv4 address "127.0.0.1": Address already in use
HINT:  Is another postmaster already running on port 5432? If not, wait a few seconds and retry.
FATAL:  could not create any TCP/IP sockets

일반적으로 이것은 서버가 이미 실행되고 있는 포트에서 사용자가 다른 서버를 시작하려고 했음을 의미한다. 단, 커널 에러 메시지가 Address already in use가 아니거나, 이것과 약간 다른 경우 다른 문제일 가능성이 있다. 예를 들면, 예약된 포트 번호에서 서버를 시작하려고 하면 다음과 같이 할 것이다.

$ postgres -p 666

LOG:  could not bind IPv4 address "127.0.0.1": Permission denied
HINT:  Is another postmaster already running on port 666? If not, wait a few seconds and retry.
FATAL:  could not create any TCP/IP sockets

메시지는 다음과 같이 나타난다.

FATAL:  could not create shared memory segment: Invalid argument
DETAIL:  Failed system call was shmget(key=5440001, size=4011376640, 03600).

이것은 공유 메모리 크기에 대한 커널 제한이 PostgreSQL 이 생성하려고 하는 작업 영역보다 작다는 것을 의미하는 것일 수 있다(이 예시에서 4011376640바이트). 이 현상은 shared_memory_type 설정을 sysv로 했을 때만 보인다. 이 경우, 임시 해결책으로, 버퍼 수를 정상보다 작게 해서 서버 시작을 시도해볼 수 있다(shared_buffers). 또는 허용된 공유 메모리 크기를 늘리기 위해 사용자는 커널을 다시 환경 설정할 수 있다. 또한 동일한 머신에서 다중 서버를 시작하려는 경우 총 요청 공간이 커널 제한을 초과하면 이 메시지가 나타날 수도 있다.

에러가 다음과 같을 수 있다.

FATAL:  could not create semaphores: No space left on device
DETAIL:  Failed system call was semget(5440126, 17, 03600).

이것은 사용자의 디스크 공간이 소진되었음을 의미하지 않는다. 이것은 System V 세마포어에 대한 커널 수 제한이 생성하려는 PostgreSQL의 수보다 작다는 것을 의미한다. 위와 마찬가지로, 허용된 연결 수(max_connections)를 줄여서 서버를 시작함으로써 문제를 해결할 수 있지만, 결국에는 커널 제한을 늘리는 것이 좋다.

System V IPC 기능 환경 설정에 대한 자세한 내용은 18.4.1절에 나와 있다.

18.3.2. 클라이언트 연결 문제

클라이언트 측에서 가능한 에러 조건이 다양하고 애플리케이션에 의존적이지만, 그 중 몇 가지는 서버를 시작한 방법과 직접적인 관련이 있다. 아래 표시된 조건 외에 다른 것은 각각의 클라이언트 어플리케이션을 사용하여 문서화되어야 한다.

psql: could not connect to server: Connection refused
        Is the server running on host "server.joe.com" and accepting
        TCP/IP connections on port 5432?

이것은 일반적인 I couldn't find a server to talk to 실패이다. TCP/IP 통신을 시도할 때 위와 같이 보인다.흔한 실수로 TCP/IP 연결이 가능하도록 서버를 환경 설정하는 것을 잊어버리는 것이다.

그 대신, 로컬 서버에 대한 Unix 도메인 소켓 통신을 시도할 때 연결할 수도 있다.

psql: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

마지막 라인은 클라이언트가 올바른 곳으로 연결을 시도하고 있는지 확인할 때 유용하다. 사실상, 실행 중인 서버가 없는 경우 커널 에러 메시지는 설명한 대로 보통 Connection refused 또는 No such file or directory 중 하나이다(이 문맥의 Connection refused는 서버가 사용자의 연결 요청을 접수했고 거부했다는 것을 의미하지 않는다는 것을 알고 있는 것이 중요하다.해당 사례는 20.15절에 표시된 대로 다른 메시지가 나타난다.). Connection timed out 같은 다른 에러 메시지는 네트워크 연결성 부족 같은 좀 더 근본적인 문제를 나타내는 것일 수 있다.