PostgreSQL7.0手冊-管理員手冊-32. 蛻變測試
2019-09-08 23:33:51
供稿:網友
第三十二章. 錯誤分析
內容
Postmaster 啟動失敗
客貨端聯接問題
調試信息
Postmaster 啟動失敗
有幾個常見的原因會導致 postmaster 啟動失敗。檢查 postmaster 的日志文件,或者手工啟動它(不把標準輸出或標準錯誤重定向)看看出現什么樣的抱怨信息。有些可能的錯誤信息可以自解釋,但是有些不能:
FATAL: StreamServerPort: bind() failed: Address already in use
Is another postmaster already running on that port?
這里通常意味著它實際推測的:你不小心在同樣的端口上啟動了第二個 postmaster,而這時已經有一個在運行了。不過,如果核心錯誤信息不是"Address already in use"(地址已被使用)或者其他類似的意思的信息,那就有可能是一個不同的問題。例如,試著在一個保留的端口上運行 postmaster 可能出現象下面這樣的信息:
$ postmaster -i -p 666
FATAL: StreamServerPort: bind() failed: Permission denied
Is another postmaster already running on that port?
IpcMemoryCreate: shmget failed (Invalid argument) key=5440001, size=83918612, permission=600
FATAL 1: ShmemCreate: cannot create region
這樣的信息可能意味著你的核心對的共享內存區大小的限制小于 Postgres 試著創建的緩沖區大小。(或者也可能是你根本沒有在核心里配置支持 SysV 風格的共享內存。)作為一個臨時解決辦法,你可以試著用一個小于正常數量的緩沖區數目(-B開關)啟動。不過,最終你還是會希望重新配置你的核心以增加可用共享內存的大小。如果試圖在同一臺機器上啟動多個 postmaster,而他們對空間的總需求超過了核心的限制,你也可能看到這條信息。
IpcSemaphoreCreate: semget failed (No space left on device) key=5440026, num=16, permission=600
一條這樣的信息并不意味著你缺乏磁盤空間;它意味著你的核心對 SysV 信號燈的限制比 Postgres 想創建的少。如上所述,你可以通過減少信號燈數目啟動 postmaster 來繞開這個問題(-N 開關),但是最終你還是會希望提高核心的限制。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
客戶端聯接問題
一旦你有了一個正在運行的 postmaster,用客戶端應用試著聯接它失敗的原因可能有很多種。這里顯示的樣例錯誤信息是以最近版本的 libpq 為基礎的,以其他接口庫為基礎的客戶端可能生成其它的或多或少的信息。
connectDB() -- connect() failed: Connection refused
Is the postmaster running (with -i) at 'server.joe.com' and accepting connections on TCP/IP port '5432'?
這是常見的"我找不到一個可交談的 postmaster "錯誤。當試圖用 TCP/IP 通訊時看起來想上面那樣,或者用 Unix 套接字與本地 postmaster 通訊時象下面這樣:
connectDB() -- connect() failed: No such file or directory
Is the postmaster running at 'localhost' and accepting connections on Unix socket '5432'?
最后一行對校驗客戶端應該向哪里聯接很有幫助。如果實際上沒有 postmaster 在運行,核心錯誤信息很可能會是 "Connection refused" 或者 "No such file or directory",就象上面描述的那樣。(在這里,理解在這個環境里 "Connection refused" 并不意味著 postmaster 收到你的聯接請求然后拒絕了它 --- 那種情況會產生一條不同的信息,下面會介紹。)其他錯誤信息,如 "Connection timed out"可能表示更基本的問題,好象缺乏網絡聯接等。
No pg_hba.conf entry for host 123.123.123.123, user joeblow, database testdb
這樣的信息最有可能出現在你成功地與 postmaster 進行了聯接,但是人家不愿意理你。如該信息推測的那樣,postmaster 因為在它的 pg_hba.conf 配置文件里找不到認證信息而拒絕聯接請求。
Password authentication failed for user 'joeblow'
這樣的信息表明你與 postmaster 聯接上了,并且她愿意理你,但是你必須先通過在 pg_hba.conf 文件里聲明的認證方法。檢查你提供的口令,或者檢查你的 Kerberos 或 IDENT 軟件 --- 如果抱怨信息提到了那些認證類型之一。
FATAL 1: SetUserId: user 'joeblow' is not in 'pg_shadow'
這是認證失敗的另一個變種:對給出的用戶名沒有執行一條 Postgres create_user 命令。
FATAL 1: Database testdb does not exist in pg_database
在這個 postmaster 控制范圍內沒有叫這個名字的數據庫。要注意如果你不聲明數據庫名,缺省是你的 Postgres 用戶名,有可能不是正確的(數據庫)名稱。
NOTICE: Unrecognized variable client_encoding
這不是個錯誤,實際上它相當無害.如果你使用一個編譯時帶 MULTIBYTE (多字節編碼)支持的客戶端與一個編譯時沒有這個支持的服務器聯接,就會看到這條信息.(客戶端嘗試告訴服務器它需要的字符集編碼,但是服務器不知道該說些什么好.)如果這條信息讓你覺得煩,那就用帶著與服務器一樣的選項編譯的客戶端.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
調試信息
postmaster 時不時地打印一些對錯誤分析很有幫助的信息。如果你想查看來自postmaster 的調試信息,你可以帶 -d 選項運行它然后把輸出重定向到日志文件:
% postmaster -d > pm.log 2>&1 &
如果你不想看到這些信息,你可以鍵入
% postmaster -S
然后 postmaster 就會安靜下來("S"ilent)。注意上面這個例子沒有與號("&"),所以 postmaster 會運行在前臺。
pg_options
注意:由 Massimo Dal Zotto 提供
參數文件 data/pg_options 包含被后端用于控制跟蹤信息和其他可調節參數的運行時選項.令我們對這個文件感興趣的是,當后端收到一個 SIGHUP 信號后會重新讀取這個文件的信息.這就讓我們可以更改 Postgres 的運行時參數而不需要重新啟動它.在這個文件中聲明的選項可能是被追蹤包使用的調試標志(backend/utils/misc/trace.c)或者是后端用于控制其特性的一些數字參數.新的選項和參數必須在backend/utils/misc/trace.c和backend/include/utils/trace.h 里定義.
pg_options 同樣可以使用 Postgres 的 -T 開關來聲明:
postgres options -T "verbose=2,query,hostlookup-"
這樣,用于打印錯誤和調試信息的函數就可以利用 syslog(2) 功能了.向標準輸出(stdout)或標準錯誤(stderr)打印的信息是帶有時標和后端進程號前綴的字串:
#timestamp #pid #message
980127.17:52:14.173 [29271] StartTransactionCommand
980127.17:52:14.174 [29271] ProcessUtility: drop table t;
980127.17:52:14.186 [29271] SIIncNumEntries: table is 70% full
980127.17:52:14.186 [29286] Async_NotifyHandler
980127.17:52:14.186 [29286] Waking up sleeping backend process
980127.19:52:14.292 [29286] Async_NotifyFrontEnd
980127.19:52:14.413 [29286] Async_NotifyFrontEnd done
980127.19:52:14.466 [29286] Async_NotifyHandler done
這種格式改善了日志的可讀性并且讓人們可以弄明白某后端何時在做何事.同樣這也讓我們很容易寫出簡單的監控日志的 awk 或 perl 腳本來跟蹤數據庫錯誤或問題,或者計算交易時間統計數據.
向 syslog (系統日志)打印的信息使用了日志工具 LOG_LOCAL0.syslog的使用可以由 syslog 的 pg_option 控制.不幸的是,許多函數調用直接用 printf() 把它們的信息輸出到標準輸出(stdout)或標準錯誤(stderr)中去了,這樣的輸出不能重定向到 syslog 而且也不會有時標.我們的建議是所有對printf的調用都用宏 PRINTF 代替,所有向標準錯誤(stderr)的輸出都用 EPRINTF 替換,這樣我們就可以將所有輸出都控制在統一的方法下.
pg_options 文件的格式如下:
# comment
option=integer_value # set value for option
option # set option = 1
option+ # set option = 1
option- # set option = 0
注意 keyword 可以是定義在 backend/utils/misc/trace.c 里的選項名的縮寫.
參考 使用 pg_options 獲取選項關鍵字和可能的取值的完整的列表。
--------------------------------------------------------------------------------