首页 > 数据库 > PostgreSQL > 正文

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 获取选项关键字和可能的取值的完整的列表。


--------------------------------------------------------------------------------
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选