更多"C/C++、PostgreSQL、编译原理、计算机原理、TCP/IP、数据结构&算法、Linux编程”等技术文章更新于公众号: 君子黎
1. PostgreSQL日志管理
使用pg_ctl命令启动PostgreSQL服务,默认情况下,PostgreSQL是不会将系统日志信息输入到设备文件中的。因此,这无疑对PostgreSQL服务的管理和状态监测、性能排查等维护带来了巨大的问题与考验,特别是对于一个现场使用中的数据库而言,若出现了问题,而没有日志记录,那将是多么棘手的一件事。因此,本文将着重介绍如何开启PostgreSQL服务的运行日志方案。
1.1 开启PostgreSQL服务日志两种方式
1.1.1 pg_ctl的可选参数-l指定日志文件
对于PostgreSQL数据库,可以有两种方式来进行日志配置和打印。第一种是使用pg_ctl启动数据库服务时候,通过使用可选参数-l来配置PostgreSQL将日志信息打印到对应目录,如下图为pg_ctl的参数信息。
可通过--log=/home/xx/xx/1.log 来指定将日志打印到/home/xx/xx/目录下的1.log文件中,注意,这里1.log文件已存在该目录,并且且文件权限用户需要是:postgres,如果是root,则会失败,比如
此时的1.log还是root用户,如下图所示:
修改为postgres用户权限后,再次重新启动服务,则成功。
现在1.log文件中已经有PostgreSQL日志信息。如下:
[root@Thor LOG_SELF]# tail -f 1.log 2021-02-24 19:39:08.697 CST [17377] LOG: starting PostgreSQL 13.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit 2021-02-24 19:39:08.698 CST [17377] LOG: listening on IPv6 address "::1", port 5566 2021-02-24 19:39:08.698 CST [17377] LOG: listening on IPv4 address "127.0.0.1", port 5566 2021-02-24 19:39:08.720 CST [17377] LOG: listening on Unix socket "/tmp/.s.PGSQL.5566" 2021-02-24 19:39:08.744 CST [17378] LOG: database system was interrupted; last known up at 2021-02-24 19:36:30 CST 2021-02-24 19:39:08.801 CST [17378] LOG: database system was not properly shut down; automatic recovery in progress 2021-02-24 19:39:08.813 CST [17378] LOG: redo starts at 0/160E738 2021-02-24 19:39:08.813 CST [17378] LOG: invalid record length at 0/160E770: wanted 24, got 0 2021-02-24 19:39:08.813 CST [17378] LOG: redo done at 0/160E738 2021-02-24 19:39:08.878 CST [17377] LOG: database system is ready to accept connections
1.1.2 通过postgresql.conf配置文件来指定log日志目录
当使用initdb命令初始化数据库蔟之后,会在指定的目录下生成一个postgresql.conf配置文件,里面是该数据库服务对应的所有完整配置信息,包括辅助进程:logger(系统日志进程)、background writer(后台写进程)、walwriter(预写式日志写进程)、autovacuum launcher(系统自动清理进程)、archiver(日志归档进程)。因此我们在postgresql.conf配置文件中通过修改有关log日志相关的选项,即可达到记录PostgreSQL服务的日志信息目的。
在 【PostgreSQL教程】· postgresql.conf配置文件详解 一文中,详细地对postgresql.conf配置文件中的各参数选项作了较为详细的描述说明。现在我们直接看和log日志相关的部分选项参数,如下:
#------------------------------------------------------------------------------ # REPORTING AND LOGGING #------------------------------------------------------------------------------ # - Where to Log - # 配置日志输出目录,类unix默认是stderr。根据平台不同,有效值是stderr、csvlog、syslog和eventlog的组合, # cslog要求logging_collector是on状态。 当log日志输出到stderr时使用。 #log_destination = 'stderr' # 日志收集器(off不开启,on开启)。 当开启(on)后,将系统产生的日志信息输出到指定的目录下。 #logging_collector = off # 配置log日志输出目录 #log_directory = '/home/ssd/psql13_2/LOG_SELF/' # 配置log日志文件名称的命名规则,如果修改或打开,则使用默认规则 #log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log文件权限 #log_file_mode = 0600 # 如果启用,则与新日志文件同名的现有日志文件将被截断,而不是附加到新日志文件。默认值为off,表示在所有情况下都附加到现有文件。 #log_truncate_on_rotation = off # 保留单个文件的最长时间,默认是1d,也可以是1min,1s。 0-则禁用此功能 #log_rotation_age = 1d # 保留单个文件的最大字节,默认是10MB #log_rotation_size = 10MB //省略若干,详情参看 - 【PostgreSQL教程】· postgresql.conf配置文件详解 . . . . . . log_timezone = 'Asia/Shanghai'
备注:log_rotation_size是配置日志文件大小,当日志文件达到这个大小时候,会被关闭掉,然后重新创建一个新的log文件。
1.2 logging_collector配置决定是否开启logger辅助进程
对于PostgreSQL数据库的配置文件postgresql.conf中,logging_collector(日志收集器辅助进程)选项的默认值是off,即关闭的。这时候,当开启(su postgres -c '/usr/local/postgresql13_2/bin/pg_ctl -D /home/ssd/psql13_2/ -m fast start')PostgreSQL服务时候,是看不到logger守护进程的。如下图所示:
现在修改logging_collector的值为on,重启服务,再次查看(ps -eLf|grep postgres),则可看到次数的logger日志搜集辅助进程已经开启,如下图所示:
结论:为了让PostgreSQL数据库记录任何的日志记录消息,必须将loggin_collector参数置为on。当修改次参数时候,必须重新启动PostgreSQL数据库服务。
1.3 postgresql.conf文件中与log相关配置的建议
· log_min_duration_statement(通常建议禁用)
用于设置时间阈值:凡是运行时间超过此阈值的查询均应该记录下来(作为“慢速查询”)。设为0:将记录数据库中的运行的每个语句,而设置为-1将禁用日志记录。该参数可以为min、s、ms、h等,比如:1h、1min、1s、1ms。修改此参数不需要重新启动PostgreSQL服务器。eg: log_min_duration_statement = 3s
, 则表示记录每个运行超过3s或大于3s的语句。
· log_line_prefix
自定义PostgreSQL数据库日志文件中的每个日志行的格式规则。默认日志行打印规则是:
日期 时区 行号 打印级别 函数名 .... 等等 2021-02-25 14:15:59.221 CST [1340] DEBUG: pg_amproc: vac: 0 (threshold 147), ins: 0 (threshold 1097), anl: 0 (threshold 98)
可以根据自己的需求爱好进行修改,由于该选项参数众多,因此,阅读 PostgreSQL日志文档 以进行定制。
· log_duration(建议禁用, off)
该参数默认off的,若打开此参数选项,则会记录PostgreSQL日志中每个已完成语句的持续时间,与log_min_duration_statement无关。启用该参数可能会增加日志文件的使用率,并且增加对服务器性能的影响。
· log_rotation_size
单个日志文件的大小限制,默认是10MB,当log文件超过这个限制后, 将重新创建一个log文件。
· log_rotation_age
控制log文件的寿命,默认是1天。 一旦log文件的时间达到这个阈值,则将强行进行轮换(即新建一个log文件),通常单位可以是:h、d、min,最小粒度是一分钟。当然,若log_rotation_size先达到,则无论时间是否达到,都将创建一个新的log文件。
比如:log_rotation_age = 5min;log_rotation_size = 1MB,在5min时间后,若单个log文件没有到达1MB,则也会重新创建一个新的log文件。如下所示:
· log_statement
控制记录什么类型的SQL操作,通常SQL语言包括4中类型的的语言类别语句:DDL(数据定义语言)、DML(数据操作语言)、DCL(数据控制语言)和TCL(事务控制语言)。常见的DDL包括:创建数据库、创建表、修改表、删除表、创建查询命令、修改查询命令和删除数据表等。推荐的设置是DDL,它将记录所有已执行的DDL。其他可能值:none、mod(包括DDL和DML)以及all。
· log_temp_files
记录与临时表有关的日志信息。
更多关于PostgreSQL数据库错误报告和日志的配置信息请阅读 PostgreSQL错误报告和日志 。
2. logger日志辅助进程的原理
2.1 PostgreSQL V8.0引入logger系统日志记录器
syslogger系统日志记录器是在PostgreSQL V8.0版本中引入的。它通过重定向到管道来捕获来自postmaster、backends和其他子进程的所有stderr输出,并将其写入一组日志文件。可以在配置文件(postgresql.conf)中的设置日志文件的大小和保留时间限制。如果达到或是超过了这些限制,则关闭掉当前的日志文件,并且创建一个新的日志文件。这些日志文件存储在一个子目录中(根据postgresql.conf中的log_directory选项)。同时用户可以设置自己的日志文件命名规则方案(即log_filename),如果默认,则log文件名为:'postgresql-%Y-%m-%d_%H%M%S.log', 比如:
[root@Thor LOG_SELF]# ll total 4 -rw-r--r-- 1 postgres postgres 968 Feb 24 19:39 1.log -rw------- 1 postgres postgres 0 Feb 25 11:55 postgresql-2021-02-25_115551.log
在V9.6之前,默认情况下,PostgreSQL是将所有日志文件存储于pg_log目录(PostgreSQL数据库蔟目录,log_directory = 'pg_log')中,从PostgreSQL 10开始,pg_log已经重命名为简单日志。
比如对于9.6.7版本的PostgreSQL,当使用initdb命令初始化数据库蔟之后(目录:/home/ssd/pgsql/data),会在该目录下默认创建一个名为:pg_log 的目录文件。
该pg_log目录下是所有与PostgreSQL相关的日志文件信息。
log文件其命名规则默认是13.2的log文件命令规则相同,如下:
但是PostgreSQL13.2版本安装的数据库蔟下面已经没有了pg_log目录。当然可以通过修改参数log_directory将log文件存储到指定的目录位置。
2.2 logger日志记录器的原理
对于SysLogger系统日志收集器的工作原理请阅读 【PostgreSQL教程】· PostgreSQL系统日志收集器SysLogger工作原理(一) 。