linux下postgres未能正常啟動的解決過程


起因是一次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不會。

具體差別和作用,留在后續仔細研究。

 

p.s. 毫無頭緒的時候,可以先從ps命令入手,執行“ps aux | grep postgres”,看看相關的進程,再進一步分析。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM