就像所有复杂系统一样,PostgreSQL有时候也会出点状况:查询跑得太慢,服务器压力变大,用户开始着急。日志记录就是用来观察数据库内部运行情况的方法,目的是:
- 找出慢查询 —— 就是那些拖慢应用速度的家伙。
- 优化性能 —— 通过分析查询的行为来搞定。
- 诊断错误 —— 比如约束冲突或者语法写错啥的。
- 做审计 —— 跟踪谁在服务器上做了什么操作。
日志记录的关键参数
PostgreSQL的配置文件(postgresql.conf)里有一堆和日志相关的参数。咱们来看看最重要的几个。
log_statement—— SQL查询日志记录
log_statement参数决定哪些SQL查询会被写进日志。它可以取以下值:
none—— 不记录任何查询日志。ddl—— 只记录数据定义命令(比如CREATE、ALTER、DROP)。mod—— 记录所有修改数据的命令(比如INSERT、UPDATE、DELETE)。all—— 记录所有SQL查询(包括普通的SELECT)。
举个例子:
如果你想记录所有查询,在postgresql.conf文件里设置:
log_statement = 'all'
如果你只想记录数据变更命令:
log_statement = 'mod'
改完配置后别忘了重启服务器:
sudo systemctl restart postgresql
log_duration—— 执行时间日志记录
log_duration参数可以把每个查询的执行时间写进日志。这样你就能知道哪些查询最耗时。
举个例子:
要开启查询执行时长日志,设置:
log_duration = on
如果你只想记录慢查询,可以用log_min_duration_statement参数(咱们后面会讲)。
log_min_duration_statement—— 慢查询日志记录
这个参数只会把执行时间超过指定毫秒数的查询写进日志。用来找数据库里的“慢动作”特别方便。
举个例子:
要记录执行超过1秒的查询:
log_min_duration_statement = 1000
如果你想不管多快都记录所有查询,只要把值设成0:
log_min_duration_statement = 0
设成-1就关闭按时长记录日志。
log_line_prefix—— 日志消息结构
log_line_prefix参数可以自定义日志消息的格式。这样你可以给每条日志加点上下文(比如用户名、PID、日期时间啥的)。
举个例子:
要记录用户名、数据库名、时间和进程号,用:
log_line_prefix = '%t [%p]: [%d]: [%u]: '
这里:
%t—— 查询时间。%p—— 进程PID。%d—— 数据库名。%u—— 用户名。
所有可用选项列表:PostgreSQL文档。
logging_collector—— 日志收集器
logging_collector参数用来把日志写进文件。如果关掉了,日志只会输出到标准输出(stdout),其实挺不方便的。
要启用日志收集器:
logging_collector = on
别忘了用log_directory和log_filename指定日志文件路径:
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d.log'
参数的实际用法
咱们来看看在实际场景下怎么用这些日志参数。
场景1:记录所有查询
如果你刚开始用新数据库,想看清楚所有发生的事,配置:
log_statement = 'all'
log_line_prefix = '%t [%p]: [%d]: [%u]: '
现在每个在库里执行的查询都会被写进日志文件——调试超方便!
场景2:查找慢查询
如果你发现服务器有时候“卡”,想找出问题查询,配置:
log_min_duration_statement = 500 # 记录超过500毫秒的查询
log_line_prefix = '%t [%p]: [%d]: [%u]: [%r] '
这里%r会加上客户端IP地址。这样你就能轻松找出让服务器压力山大的查询。
场景3:最小日志模式
如果你的服务器很稳定,只想保留最基本的审计日志:
log_statement = 'mod'
log_duration = off
这样只会记录数据变更(比如INSERT、UPDATE)。
日志分析
日志一多起来,学会分析就很重要啦!你可以:
用文本编辑器打开日志文件:
cat /var/log/postgresql/postgresql.log
用分析工具,比如grep,找出慢查询:
grep "duration: " /var/log/postgresql/postgresql.log
用更高级的日志分析工具,比如pgBadger。
实用建议
日志太详细会让磁盘压力变大。生产环境只开你需要的参数就行。
定期清理或归档旧日志文件,别让磁盘爆了。
日志记录要高效,参数只收集必要数据就好。比如log_min_duration_statement能帮你精准定位问题,还省资源。
怎么样?现在配置PostgreSQL日志和用它分析查询、提升性能都不在话下了。正如某位(其实不止一位)不知名但肯定很牛的开发者说过:“日志——让我们能回顾查询的过去,修正数据库的未来”。
GO TO FULL VERSION