linux下postgres未能正常启动的解决过程

转载:http://www.cnblogs.com/starRebel/p/7892214.html

起因是一次linux服务器重启后,postgres没有起来,手动找原因。

1. 直接在命令行打postgresql,按tab补全。。。没反应,说明没有装入系统环境变量包含的目录(echo $PATH查看)。

2. 了解到试试service,一般系统安装软件都会在/etc/init.d/里面放一个可执行文件,输入"service postgresql"后tab补全出来,执行,发现启动失败。

3. 继续找原因。想着去哪看看日志,发现没有头绪。只好去/etc/init.d/里面试试运气,打开postgresql-9.5脚本,发现有如下配置

复制代码
# Set defaults for configuration variables
PGENGINE=/usr/pgsql-9.5/bin
PGDATA=/var/lib/pgsql/9.5/data
PGLOG=/var/lib/pgsql/9.5/pgstartup.log
# Log file for pg_upgrade
PGUPLOG=/var/lib/pgsql/$PGMAJORVERSION/pgupgrade.log

lockfile="/var/lock/subsys/${NAME}"
pidfile="/var/run/${NAME}.pid"

# Override defaults from /etc/sysconfig/pgsql if file is present
[ -f /etc/sysconfig/pgsql/${NAME} ] && . /etc/sysconfig/pgsql/${NAME}
复制代码

p.s.日志文件的路径一般通过两个方式查找:1.在脚本文件里面找。2.在配置文件里面找。

4. 接着试试/var/lib/pgsql/9.5/pgstartup.log文件,没发现什么有用的信息,日期都比较早。。。有点纳闷。

Success. You can now start the database server using:

    /usr/pgsql-9.5/bin/pg_ctl -D /var/lib/pgsql/9.5/data -l logfile start

< 2017-08-18 18:06:47.597 CST >LOG:  redirecting log output to logging collector process
< 2017-08-18 18:06:47.597 CST >HINT:  Future log output will appear in directory "pg_log".

似乎Future log output will appear in directory "pg_log".这句话有些线索。然而查看了/var/lib/pgsql/9.5/data/pg_log/目录下的日志后,并没有进展(找个日志都这么难)。

5. 从逻辑上讲,日志都是由程序写的,而程序只有一个:/etc/init.d/postgresql-9.5,所以继续回到shell脚本查找,发现新的线索:

# Override defaults from /etc/sysconfig/pgsql if file is present
[ -f /etc/sysconfig/pgsql/${NAME} ] && . /etc/sysconfig/pgsql/${NAME}

因为对shell不是很熟,所以一开始以为就是可判断语句,自动忽略了。后来google之后发现,这个'.'等同于source。于是打开/etc/sysconfig/pgsql/postgresql-9.5文件:

PGPORT=5433
PGDATA=/opt/var/lib/pgsql/data
PGLOG=/opt/var/lib/pgsql/pgstartup.log

发现新大陆!原来日志文件是在这里配置,也不知道是什么时候修改的。先打开/opt/var/lib/pgsql/pgstartup.log看看:

< 2017-11-16 18:30:30.080 CST >FATAL:  lock file "/tmp/.s.PGSQL.5433.lock" is empty
< 2017-11-16 18:30:30.080 CST >HINT:  Either another server is starting, or the lock file is the remnant of a previous server startup crash.
< 2017-11-16 18:34:36.677 CST >FATAL:  lock file "/tmp/.s.PGSQL.5433.lock" is empty
< 2017-11-16 18:34:36.677 CST >HINT:  Either another server is starting, or the lock file is the remnant of a previous server startup crash.
< 2017-11-16 18:35:09.510 CST >FATAL:  could not create lock file "/tmp/.s.PGSQL.5433.lock": Permission denied
< 2017-11-16 18:36:32.316 CST >FATAL:  could not create lock file "/tmp/.s.PGSQL.5433.lock": Permission denied

果然在这。

6. 根据任务日志,发现启动失败是因为没有权限创建文件。。但是,我是root账号来执行脚本的,应该是有权限的,继续寻找原因。

回到/etc/init.d/postgresql-9.5脚本,发现:

$SU -l postgres -c "$PGENGINE/postmaster -D '$PGDATA' ${PGOPTS} &" >> "$PGLOG" 2>&1 < /dev/null

原来是脚本会切换到postgres账户运行命令,su postgres检查之后发现,确实没有在/tmp文件夹下创建文件的权限。

7. 知道原因就好办了。简单粗暴,直接chmod o+w /tmp。再运行postgresql-9.5,正常启动。

归根结底,还是要回到脚本代码寻找信息。

 --------------------------------------------------------------------------

补充

centos7使用systemctl代替service来管理系统服务,文件和程序的目录位置和在centos6下有所不同。

在centos7上安装postgresql-9.5后,在/etc/init.d/目录下没有postgresql-9.5脚本。。。

google一番,发现systemctl命令还是很强大的,各类信息都可以查看:

systemctl list-units
systemctl list-units --type=service

这里我们想要查看脚本内容,则通过命令:

systemctl cat postgresql-9.5

会打印出脚本的内容,在首行会输出文件的路径:

复制代码
# /usr/lib/systemd/system/postgresql-9.5.service
# It's not recommended to modify this file in-place, because it will be
# overwritten during package upgrades.  If you want to customize, the
# best way is to create a file "/etc/systemd/system/postgresql-9.5.service",
# containing
#       .include /lib/systemd/system/postgresql-9.5.service
#       ...make your changes here...
# For more info about custom unit files, see
# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F
复制代码

其实是在目录/usr/lib/systemd/system/下面,另外这段信息也提醒最好另外建一个脚本文件再修改以防止升级的时候会恢复成默认值。

查看端口是不是已经开启:

lsof -i:5432

或者查看postgres正在监听哪个端口:

netstat -tunlp|grep postgres

如果外部链接不上数据库,需要修改配置文件:

复制代码
pg_hba.conf:
     # TYPE  DATABASE        USER            ADDRESS                 METHOD
     # "local" is for Unix domain socket connections only
     local   all             all                                     trust
     # IPv4 local connections:
     host    all             all             127.0.0.1/32            trust
     host    all             all             192.168.20.1/24         trust
     host    all             all             192.168.66.1/24         trust
     # IPv6 local connections:
     host    all             all             ::1/128                 trust

***需要注意的是,上面的设置都改成“trust”的话,那么外部连接到数据库是不需要密码的。
postgresql.conf: 
listen_addresses='*'

复制代码

再systemctl restart postgresql-9.5.service重启服务。

如果外部客户端还是链接不上,就考虑是不是防火墙阻止了5432端口的访问。

 --------------------------------------------------------------------------

处理完这个问题后,想到

1. 有哪些程序是可以使用service命令来快速启动的?

答案是放在/etc/init.d/目录下的脚本就可以通过service启动。这点可以通过service脚本代码观察到(which service):

SERVICEDIR="/etc/init.d"

一般的,脚本的结构需要有start|stop|restart等选项

复制代码
case "$1" in
    start)
        do start-thing;
        ;;
    stop)
        do stop-thing;
        ;;
    restart)
        do restart-thing;
        ;;
    ...
esac
复制代码

除此之外,也可以有一些特有的参数,通过“service scriptName argument”调用,当然前提是要有执行权限。

参考http://blog.csdn.net/taiyang1987912/article/details/41698817

2. 如何开机自动启动postgres?

答案是/etc/rc.d/。linux有7个运行级别(别个级别对应启动的服务有所不同),每种运行级别分别对应着/etc/rc.d/rc[0~6].d这7个目录。

这7个目录中,每个目录分别存放着对应运行级别加载时需要关闭或启动的服务,由详细信息可以知道,个脚本文件都对应着/etc/init.d/目录下具体的服务。

复制代码
lrwxrwxrwx. 1 root root 20 Jul  4  2016 K01certmonger -> ../init.d/certmonger*
lrwxrwxrwx. 1 root root 24 Jul  4  2016 K01libvirt-guests -> ../init.d/libvirt-guests*
lrwxrwxrwx. 1 root root 16 Jul  4  2016 K01smartd -> ../init.d/smartd*
lrwxrwxrwx. 1 root root 17 Jul  4  2016 K02oddjobd -> ../init.d/oddjobd*
lrwxrwxrwx. 1 root root 13 Jul  4  2016 K05atd -> ../init.d/atd*
lrwxrwxrwx. 1 root root 17 Jul  4  2016 K05wdaemon -> ../init.d/wdaemon*
lrwxrwxrwx. 1 root root 14 Jul  4  2016 K10cups -> ../init.d/cups*
lrwxrwxrwx. 1 root root 16 Jul  4  2016 K10psacct -> ../init.d/psacct*
lrwxrwxrwx. 1 root root 19 Jul  4  2016 K10saslauthd -> ../init.d/saslauthd*
lrwxrwxrwx  1 root root 22 Feb 22  2017 K14zabbix-agent -> ../init.d/zabbix-agent*
lrwxrwxrwx  1 root root 22 Jul  5  2016 K15htcacheclean -> ../init.d/htcacheclean*
lrwxrwxrwx  1 root root 15 Jul  5  2016 K15httpd -> ../init.d/httpd*
......
复制代码

K开头的脚本文件代表运行级别加载时需要关闭的,S开头的代表需要执行,数字表示执行的顺序,K01certmonger最先执行。

如果想要把自己的脚本设置成开机启动,则创建一个软连接,放到相应运行级别的目录就行。

即把script放在/etc/init.d/目录,再在/etc/rc.d/rc*.d/目录创建一个软连接:

ln -s /etc/init.d/sshd /etc/rc.d/rc3.d/S40ssh

有一个快捷的方法,通过chkconfig命令来添加启动,例如:

chkconfig --level 35 服务名 on

在3和5运行级别启动。

参考https://www.cnblogs.com/nerxious/archive/2013/01/18/2866548.html

3. 如何配置系统环境变量,如何对用户单独配置?

通过/etc/profile,/etc/bashrc,以及~/.bash_profile,~/.bashrc,~/.profile。这里还涉及到登录式、非登录式,

转述:

~/.bash_profile 是交互式、login 方式进入 bash 运行的
~/.bashrc 是交互式 non-login 方式进入 bash 运行的
通常二者设置大致相同,所以通常前者会调用后者。login shell与non-login shell的主要区别在于它们启动时会读取不同的配置文件,从而导致环境不一样。
所以一般优先把变量设置在.bashrc里面。
比如在crontab里面执行一个命令,.bashrc设置的环境变量会生效,而.bash_profile不会。

具体差别和作用,留在后续仔细研究。

原文地址:https://www.cnblogs.com/wang-yaz/p/10639268.html