18.7. 错误报告和日志

18.7.1. 在哪里记录日志

log_destination(string)

PostgreSQL支持多种记录服务器日志的方法, 包括stderrcsvlog, 和syslog。 在 Windows 里,还支持eventlog作为日志 系统。把这个选项设置为一个逗号分隔的日志目标的列表。缺省是只记录 到stderr。这个选项只能在服务器启动的时候 或者在postgresql.conf文件里设置。

如果csvlog包含在log_destination中, 日志条目以CSV格式输出,这样可以便于向程序中录入日志。 查询Section 18.7.4。 必须启用logging_collector,以产生CSV格式的日志输出。

Note: 在大多数Unix系统中,需要系统的syslog守护进程 的配置,从而使log_destination能够使用syslog 选项。PostgreSQL可以通过LOCAL7记录到 syslogLOCAL0(参阅syslog_facility),但在大多数平台上的缺省 syslog配置会忽略这些信息。 需要向syslog守护进程配置文件中添加如下信息来使其 运行:

local0.*    /var/log/postgresql

logging_collector(boolean)

这个选项捕捉plain和CSV格式的日志消息 发送到的stderr,并把它们重定向到日志文件。 这个方法通常比记录到syslog更有用,因为有些消息 类型不出现在syslog输出中(一个常见的例子是 动态连接失败的消息)。这个值只能在服务器启动的时候设置。

Note: 日志收录被设置为不能丢失信息。这就意味着在极高负载的情况下,日志产生速度大于 日志收录速度,此时服务进程会被锁。相比之下,syslog倾向于 删掉信息,如果它们不能写入时,这也意味着在这种情况下,syslog 不可靠,但却不会产生锁。

log_directory(string)

在打开了logging_collector的时候,这个选项判断日志 文件在哪个目录里创建。它可以声明成绝对路径,或者是与集群的数据目录 相对的路径。这个选项只能在服务器启动的时候或者在 postgresql.conf文件里设置。

log_filename(string)

在打开了logging_collector的时候,这个选项 设置所创建的日志文件的文件名。 这个数值将被当作strftime模式看待。 因此可以用%逃逸声明随时间而变的文件名。 (需要注意的是,如果存在依赖于%逃逸的时区, 那么,会计算log_timezone声明的时区) 注意,系统的strftime不会直接使用,因此 不支持特定平台(非标准)的扩展。

如果声明一个文件名不可逃逸,那么应该计划使用一个日志切换程序,以免填满磁盘。 在8.4版本之前,如果没有出现%逃逸,PostgreSQL 将自动附加日志文件打开的时间戳。

如果在log_destination中启用了CSV格式输出,在创建 CSV格式输出的文件名时,.csv会追加时间戳日志文件名来创建。 (如果log_filename.log结尾,会替换后缀) 在上面的例子中,CSV文件名是server_log.1093827753.csv

这个选项只能在服务器启动的时候或者在postgresql.conf文件里设置。

log_rotation_age(integer)

在打开了logging_collector的时候,这个选项 设置一个独立日志文件的最大生存期。在数值指定的分钟过去之后, 将创建一个新的日志文件。设置为零可以关闭以时间为基础的新日志文件 的创建。这个选项只能在服务器启动的时候或者在postgresql.conf 文件里设置。

log_rotation_size(integer)

在打开了logging_collector的时候,这个选项 设置一个独立的日志文件的最大尺寸。在数值指定的千字节写入日志文件 之后,将会创建一个新的日志文件。设置为零可以关闭以尺寸为基础的 新日志文件的创建。这个选项只能在服务器启动的时候或者在 postgresql.conf文件里设置。

log_truncate_on_rotation(boolean)

在打开了logging_collector的时候,这个选项将 导致PostgreSQL覆盖而不是附加到任何 同名的现有日志文件上。不过,覆盖只是发生在基于时间滚动而创建的 新文件上,而不是在服务器启动的时候或者以尺寸为基础的滚动上。 如果为 off ,将始终向已存在的文件结尾追加。比如,使用这个选项 和类似postgresql-%H.log这样的 log_filename设置将导致生成 24 个按小时生成的 日志文件然后在这些文件上循环。这个选项只能在服务器启动的时候或者 在postgresql.conf文件里设置。

例子:保留 7 天的日志,每天一个日志文件,叫做 server_log.Monserver_log.Tue, 等等,并且上周的日志会自动被这周的日志覆盖。把 log_filename设置为server_log.%a、 把log_truncate_on_rotation设置为on 、把log_rotation_age设置为1440.

例子:保留 24 小时的日志,每小时一个日志,但是如果日志文件尺寸 大于 1GB 也旋转日志。把log_filename设置为 server_log.%H%M, 把log_truncate_on_rotation设置为on, 把log_rotation_age设置为60, and 把log_rotation_size设置为1000000. 在log_filename里包含%M允许任何 尺寸驱动的旋转选取一个和开始的文件名同小时数但是名字不同的文件。

syslog_facility(enum)

如果向syslog进行记录,那么这个选项判断要使用 的syslog"facility"。 你可以从LOCAL0LOCAL1LOCAL2LOCAL3LOCAL4LOCAL5LOCAL6LOCAL7 中选择。又见你的系统的syslog 守护进程文档。这个选项只能在服务器启动的时候或者在 postgresql.conf文件里设置。 除非服务器编译时支持syslog,否则 该参数不可用。

syslog_ident(string)

如果向syslog进行记录,这个选项决定用于在 syslog日志中标识PostgreSQL 的程序名。缺省是postgresql.conf。这个选项只能在 服务器启动的时候或者在postgresql.conf文件里设置。 除非服务器编译时支持syslog,否则 该参数不可用。

silent_mode(boolean)

静默的运行服务。如果设置了这个参数,会后台自动运行服务,并且是脱离终端控制的。 只有在服务启动时才能设置这个参数。

Caution

当设置了这个参数后,服务的标准输出和标注错误会定向到data目录下的postmaster.log中。 该文件不能循环使用,因此这个文件会无限增长,除非设置将服务日志输出指定其他位置。 建议,当使用这个选项时,将log_destination设置为syslog, 或启用logging_collector。即使通过这些方法,之前服务启动时的错误信息会出现 在postmaster.log中,而不是指定的位置。

18.7.2. 什么时候记录日志

client_min_messages(enum)

这个选项控制哪些信息发送到客户端。有效的数值是 DEBUG5DEBUG4DEBUG3DEBUG2DEBUG1LOGNOTICEWARNINGERRORFATALPANIC。每个级别包含所有它后面的级别, 级别越靠后,发送的信息越少。缺省是NOTICE。 需要注意的是这里的LOGlog_min_messages 里的级别不同。

log_min_messages(enum)

控制写到服务器日志里的信息的详细程度。有效值是DEBUG5DEBUG4DEBUG3DEBUG2DEBUG1INFONOTICEWARNINGERRORLOGFATAL, and PANIC。每个级别都包含它后面的级别。越靠后的数值 发往服务器日志的信息越少。缺省是WARNING。需要 注意的是这里的LOGclient_min_messages 里的级别不同。只有超级用户可以修改这个设置。

log_min_error_statement(enum)

控制是否在服务器日志里输出那些导致错误条件的 SQL 语句。 所有导致一个特定级别(或者更高级别)错误的 SQL 语句都要被记录。 有效的值有DEBUG5DEBUG4DEBUG3DEBUG2DEBUG1INFONOTICEWARNINGERRORLOGFATAL, 和PANIC. 缺省是ERROR,表示所有导致错误、致命错误、 恐慌的 SQL 语句都将被记录。设置为PANIC表示 把这个特性关闭。只有超级用户可以改变这个设置。

log_min_duration_statement(integer)

如果某个语句的持续时间大于或者等于这个毫秒数,那么在日志行上 记录该语句及其持续时间。设置为零将打印所有查询和他们的持续时间。 设置为-1(缺省值)关闭这个功能。比如,如果你把它设置为 250ms,那么所有运行时间等于或者超过 250ms 的 SQL 语句都会被记录。打开这个选项可以很方便地跟踪需要优化的查询。 只有超级用户可以改变这个设置。

对于使用扩展查询协议的客户端,语法分析、邦定、执行每一步所花时间 都分别记录。

Note: 当此选项与log_statement同时使用时, 已经被log_statement记录的语句文本不会被重复记录。 如果没有使用syslog的话,推荐使用 log_line_prefix记录 PID 或会话 ID , 这样就可以使用它们将语句消息连接耗时消息。

Table 18-1解释PostgreSQL 使用的消息严重级别。如果日志信息记录在syslog或 Windows的eventlog下,那么严重级别也是记录在这个表中。

Table 18-1. 消息的严重级别

严重性使用syslogeventlog
DEBUG1..DEBUG5为开发人员的使用提供提供详细的信息DEBUGINFORMATION
INFO提供了用户隐含要求的信息,如VACUUM VERBOSE的输出INFOINFORMATION
NOTICE提供了可能对用户有用的信息NOTICEINFORMATION
WARNING提供了可能遇到的问题的信息NOTICEWARNING
ERROR报告当前命令终止的错误WARNINGERROR
LOG报告管理员感兴趣的信息,如检查点的活动状况INFOINFORMATION
FATAL报告导致数据库当前会话终止的错误ERRERROR
PANIC报告导致数据库所有会话终止的错误CRITERROR

18.7.3. 记录什么

application_name(string)

application_name可以是任意的小于NAMEDATALEN字字符 (标准编译是64字符)的字符串。它通常由一个连接服务器后的的应用程序设置。 名字会记录在pg_stat_activity和CSV日志条目中。 也可以通过log_line_prefix参数,包含在规律的日志条目中。 只有可打印的ASCII字符可以被用于application_name。 其他字符会被问号(?)替换。

debug_print_parse(boolean)
debug_print_rewritten(boolean)
debug_print_plan(boolean)

这个参数启用发出各种调试输出。当设置时,会打印生成的解析树, 查询重写输出,或执行的每个查询的执行计划。这些信息是在LOG 信息级别发出,因此默认的,它们会出现在服务器日志中,但不会发送给客户端。 可以通过 client_min_messages和/或log_min_messages 来设置。这些参数缺省是off。

debug_pretty_print(boolean)

当设置时,debug_pretty_print会缩进 debug_print_parsedebug_print_rewrittendebug_print_plan 产生的信息。这个结果更具有可读性,但是会比使用"compact"格式 的输出更长。缺省是开启。

log_checkpoints(boolean)

在服务器日志中记录检查点。每个检查点的一些统计信息也会包含在日志中, 这些信息包括写入缓冲区的数目,以及花费的时间。这个参数只能在 postgresql.conf文件或通过服务器命令来设置,缺省是off。

log_connections(boolean)

记录每一次连接服务器的请求,以及完全成功的客户端认证。 这个选项只能在服务器启动的时候或者在postgresql.conf文件里设置。缺省是关闭的。

Note: 一些客户端程序,如psql,在确定是否需要密码的 同时, 会连接两次,因此重复收到请求连接的消息不一定表示有问题。

log_disconnections(boolean)

这个选项类似log_connections,但是在会话结束 的时候在服务器日志里输出一行。缺省是关闭的。这个选项只能在服务器 启动的时候或者在postgresql.conf文件里设置。

log_duration(boolean)

记录每个已完成语句的持续时间。默认值是off。 只有超级用户可以改变这个设置。

对于使用扩展查询协议的客户端,语法分析、邦定、执行每一步所花时间 都分别记录。

Note: 设置为 0 时该选项与log_min_duration_statement的 不同之处在于log_min_duration_statement 强制记录查询文本。因此,如果log_durationon并且log_min_duration_statement 大于零将记录所有持续时间,但是仅记录那些超过阈值的语句。 这可以用于在高负载情况下搜集统计信息。

log_error_verbosity(enum)

控制每个消息记录在服务器日志中写的明细。有效值有TERSEDEFAULTVERBOSETERSE不记录 DETAILHINTQUERYCONTEXT 错误信息。VERBOSE的输出包括SQLSTATE错误代码(查询 Appendix A)和源代码文件名,函数名,以及产生错误的行号。 只有超级用户能修改这个设置。

log_hostname(boolean)

默认的,连接日志信息只会显示连接主机的IP地址。打开这个参数,也会记录主机名。 需要注意的是,根据主机名解析设置,会强加一个不可忽略的性能损失。 这个参数可以在postgresql.conf文件或通过服务器命令来设置。

log_line_prefix(string)

这是一个printf风格的字符串,在日志的每行开头输出。 %characters begin"escape sequences" 被状态信息替换,如下所述。忽略不可识别的逃逸。 其它字符都直接拷贝到日志行中有些逃逸只被会话进程识别,不能 应用于后端进程,比如主服务器进程。 这个选项只能在服务器启动的时候或者在postgresql.conf文件里设置。 缺省是空字符串。

逃逸效果仅用于会话
%a应用程序名
%u数用户名
%d数据库名
%r远程主机名或者IP地址以及远端端口
%h远程主机名或者IP地址
%p进程ID
%t时间戳(没有毫秒)
%m带毫秒的时间戳
%i命令标签。当前会话的命令类型。
%eSQLSTATE错误代码
%c会话ID,见下文
%l每个会话或进程的日志行编号,从1开始。
%s进程开始的时间戳
%v虚拟事务ID(backendID/localXID)
%x事务ID(0如果没有被分配)
%q 不生成任何输出,但是告诉非会话进程在字符串的这个位置停止。 被会话进程忽略。
%%Literal文本%

%c逃逸生成一个准唯一的会话标识符,由两个4位十六进制数字(不包含 前导零)组成,以点分开。这两个数字表示进程开始时间和进程ID。 如,为了从pg_stat_activity生成一个会话标识符,可以这样查询;

SELECT to_hex(EXTRACT(EPOCH FROM backend_start)::integer) || '.' ||
       to_hex(procpid)
FROM pg_stat_activity;

Tip: 如果log_line_prefix的值为非空,通常需要将它最后一个字符 设为一个空格,以与其余的日志行向区分。也可以用一个标点符号。

Tip: Syslog自己产生自己的时间戳和 进程ID信息,因此如果正在写入syslog时,可能不 太希望有这些信息。

log_lock_waits(boolean)

控制当一个会话等待时间超过deadlock_timeout而被锁时是否 产生一个日志信息。在判断一个锁等待是否会影响性能时是有用的, 缺省是off

log_statement(enum)

控制记录哪些 SQL 语句。有效的值是none(off), ddlmod, 和allddl记录所有数据定义命令,比如 CREATEALTER, 和DROP 语句。mod记录所有ddl语句,加上数据 修改语句INSERTUPDATEDELETETRUNCATE, andCOPY FROM。如果所包含的命令类型吻合, 那么PREPAREEXECUTE, 和 EXPLAIN ANALYZE语句也同样被记录。对于使用扩展 查询协议的客户端,记录发生在接受到扩展信息并包含邦定参数 (内置单引号要双写)的时候。

缺省是none。只有超级用户可以改变这个设置。

Note: 即使设置了log_statement=all,包含 简单语法错误的语句也不会被记录。因为仅在完成基本的语法分析并 确定了语句类型之后才记录日志。在使用扩展查询协议的情况下,在 执行阶段之前(语法分析或规划阶段)同样不会记录。将 log_min_error_statement设为ERROR 或更低才能记录这些语句。

log_temp_files(integer)

控制记录临时文件名和大小。可以创建临时文件用于排序,临时查询结果和hash。 当被删除时,会为每个临时文件增加一个日志条目。0表示记录所有临时文件信息, 而正值只记录那些大于等于指定千字节大小的文件。缺省设置是-1, 禁用日志记录。只有超级用户才能修改这个设置。

log_timezone(string)

为日志中的时间戳设置使用的时区。不同于timezone, 这个值是集群范围的,因此所有会话的时间戳是一致的。 缺省值是unknown,表示使用系统使用的时区。 参阅Section 8.5.3。 这个选项只能在服务器启动的时候或者在postgresql.conf 文件里进行设置。

18.7.4. 使用CSV格式的日志输出

包括在log_destination中的csvlog,提供了一个 便捷的方式向数据库中导入日志文件。这个选项以CSV格式发出日志行, 带有这些列: 以毫秒为单位的时间戳,用户名,数据库名,进程ID,客户端主机:端口号, 会话ID,每个会话的行号,命令标签,会话开始时间,虚拟事务ID,日常事务ID, 错误严重性,SQLSTATE代码,错误信息,错误信息的详细信息,建议, 导致错误的内部查询(如果存在),其中的错误位置的字符统计, 错误范围,导致错误的用户查询(如果存在,并且启用log_min_error_statement), 其中的错误位置的字符统计,PostgreSQL源代码中报错的位置(如果 log_error_verbosity设置为verbose)和应用程序名。 下面是一个用于存储CSV格式日志暑促的简单表定义:

CREATE TABLE postgres_log
(
  log_time timestamp(3) with time zone,
  user_name text,
  database_name text,
  process_ id integer,
  connection_from text,
  session_ id text,
  session_line_num bigint,
  command_tag text,
  session_start_time timestamp with time zone,
  virtual_transaction_ id text,
  transaction_ id bigint,
  error_severity text,
  sql_state_code text,
  message text,
  detail text,
  hint text,
  internal_query text,
  internal_query_pos integer,
  context text,
  query text,
  query_pos integer,
  location text,
  application_name text,
  PRIMARY KEY (session_ id, session_line_num)
);

使用COPY FROM命令,将一个日志文件导入到表中:

COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;

为了可以简单的导入CSV日志文件,需要做下面一些事情:

  1. 设置log_filenamelog_rotation_age ,为日志文件提供一个一致的,可预见的命名模式。这样,可以预测出文件名 会是什么,可以知道什么时候一个独立的日志文件会完成。

  2. log_rotation_size设置为0,以禁用基于大小的日志循环, 因为它使日志文件名很难预测。

  3. log_truncate_on_rotation设置为on, 因此同一个文件中,旧的日志数据不会与新的数据混合。

  4. 上面带有主键声明的表的定义。主键可以阻止在同一个列上输入相同的信息。 COPY命令提交所有的同时导入的数据,因此任何一个错误都会 导致整个导入失败。如果想要导入部分日志文件,结束之后再次导入该文件时, 会违反主键约束而产生导入错误。这条规则同样可以阻止突然的导入一条未 完全写入的部分行,当然,也会使COPY出错。