63人参与 • 2026-08-24 • MsSqlserver
logging_collector:日志收集器log_destination:日志输出目标log_directory:日志目录log_filename:日志文件名格式log_rotation_age:日志轮转时间阈值log_rotation_size:日志轮转大小阈值log_truncate_on_rotation:日志轮转截断策略log_connections / log_disconnections:连接日志log_autovacuum_min_duration:autovacuum 日志阈值log_checkpoints:检查点日志log_lock_waits:锁等待日志log_temp_files:临时文件日志log_min_duration_statement:慢查询阈值log_duration:查询时长日志log_statement:语句类型日志log_min_duration_sample / log_statement_sample_rate:日志采样(pg 14+)log_line_prefix:日志行前缀自定义log_min_messages / client_min_messages:消息级别控制file_fdw:文件外部数据包装器postgresql 的日志系统由 logging_collector 后台进程统一管理。该进程捕获发送到 stderr 的日志消息并将其重定向至日志文件。所有日志相关参数均在 postgresql.conf 中配置,修改后可通过 pg_reload_conf() 或 select pg_reload_conf() 动态加载(部分参数需重启)。
log_destination 控制日志输出目标,支持 stderr、csvlog、jsonlog 和 syslog(windows 额外支持 eventlog),可组合使用:
# postgresql.conf logging_collector = on log_destination = 'stderr,csvlog' log_directory = 'pg_log'
log_directory 指定日志文件目录,可为绝对路径或相对于 pgdata 的路径。
log_filename 支持 strftime 格式占位符:
log_filename = 'postgresql-%y-%m-%d_%h%m%s.log' log_rotation_age = 1d log_rotation_size = 100mb log_truncate_on_rotation = off
log_rotation_age:单个日志文件的最大生命周期(分钟),设为 0 禁用基于时间的轮转log_rotation_size:单个日志文件的最大大小(kb),设为 0 禁用基于大小的轮转log_truncate_on_rotation:轮转时是否截断(覆盖)而非追加已存在的同名文件pgdata/pg_log/ ├── postgresql-2026-08-21_000000.log ├── postgresql-2026-08-21_120000.log └── postgresql-2026-08-22_000000.log
log_connections 和 log_disconnections 控制客户端连接事件的记录,包含来源 ip、端口、应用名称等信息,对排查连接风暴和异常访问源至关重要:
log_connections = on log_disconnections = on
启用后日志示例:
log: connection received: host=192.168.1.100 port=54321 log: connection authorized: user=app_user database=app_db log: disconnection: session time: 0:00:05.123 user=app_user database=app_db host=192.168.1.100 port=54321
log_autovacuum_min_duration 设置 autovacuum 操作的日志阈值(毫秒),超过该阈值的操作将被记录:
log_autovacuum_min_duration = 1000 # 记录超过1秒的autovacuum操作
log_checkpoints 控制检查点事件的日志记录:
log_checkpoints = on
检查点日志示例包含脏页数量、写入时长和内存使用等信息,是分析 i/o 性能的重要依据。
log_lock_waits 控制在会话等待锁超过 deadlock_timeout 时是否产生日志:
log_lock_waits = on deadlock_timeout = 1s
log_temp_files 控制临时文件的日志记录。当查询的 work_mem 不足时,数据会溢出到磁盘临时文件:
log_temp_files = 0 # 记录所有临时文件
该参数值为 kb 单位,设为 0 记录所有临时文件,正数仅记录大于等于该值的文件,-1 禁用。结合临时文件日志可合理调整 work_mem。
最常用的慢查询控制参数,设置语句执行时间阈值(毫秒),超过该阈值的语句将在执行完成后连同耗时一并记录:
log_min_duration_statement = 500 # 记录超过500ms的查询
0:记录所有语句及其耗时-1(默认):禁用该参数记录查询文本,适合生产环境定位慢查询。
记录所有已完成语句的耗时,不记录查询文本:
log_duration = on
log_duration 只有 on/off,无法按阈值过滤。两者同时启用时,log_min_duration_statement 的优先级更高。
log_duration = on log_min_duration_statement = 500
– 所有语句的耗时均被记录,但仅超过 500ms 的语句包含查询文本
log_statement 控制哪些类型的 sql 语句被记录:
log_statement = 'ddl' # 默认值
可选值:
none(默认):不记录任何语句ddl:记录 ddl 语句(create、alter、drop 等)mod:记录 ddl 及数据修改语句(insert、update、delete、truncate、copy from)all:记录所有语句log_statement 在语句被正确解析后即记录。与 log_min_duration_statement 配合使用时,已被 log_statement 记录的查询不会被重复记录。
高并发场景下记录所有语句会带来显著性能开销和日志量压力。pg 14 引入采样机制:
log_min_duration_sample:采样阈值(毫秒),仅超过该阈值的语句才进入采样池log_statement_sample_rate:采样率(0.0 ~ 1.0)log_min_duration_sample = 100 log_statement_sample_rate = 0.5
记录所有执行时间超过 100ms 的语句中 50% 的样本。
与 log_min_duration_statement 配合时,后者的优先级更高:
log_min_duration_statement = 500 log_min_duration_sample = 100 log_statement_sample_rate = 0.1
– 记录所有超过 500ms 的查询;同时采样记录超过 100ms 查询中的 10%
log_line_prefix 是 printf 风格的字符串,用于自定义日志行前缀:
log_line_prefix = '%m [%p] %q%u@%d/%a '
常用转义符:
%m:带毫秒的时间戳%p:进程 id(pid)%u:用户名%d:数据库名%a:应用名称%h:客户端主机%r:客户端主机和端口%q:会话上下文分隔符log_min_messages 控制写入服务器日志的消息级别:
log_min_messages = 'warning'
client_min_messages 控制发送到客户端的消息级别:
client_min_messages = 'notice'
级别从低到高(低级别输出更详细):debug5 < debug4 < … < debug1 < log < notice < warning < error。
file_fdw 是 postgresql 官方 contrib 模块,允许将文件系统中的文件映射为外部表:
-- 创建扩展
create extension file_fdw;
-- 创建外部服务器
create server file_server foreign data wrapper file_fdw;
-- 创建外部表(以csv格式日志为例)
create foreign table pg_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
) server file_server
options (filename '/path/to/pg_log/postgresql.csv', format 'csv');
之后即可用标准 sql 查询日志:
select log_time, user_name, database_name, query from pg_log where error_severity = 'error' and log_time > current_timestamp - interval '1 hour' order by log_time desc;
使用 file_fdw 需具备 pg_read_server_files 角色权限。
| 参数 | 类型 | 默认值 | 适用版本 | 说明 |
|---|---|---|---|---|
logging_collector | boolean | off | 全部 | 启用日志收集器 |
log_destination | string | stderr | 全部 | 日志输出目标 |
log_directory | string | pg_log | 全部 | 日志目录 |
log_filename | string | postgresql-%y-%m-%d_%h%m%s.log | 全部 | 日志文件名格式 |
log_rotation_age | integer | 1440 | 全部 | 轮转时间阈值(分钟) |
log_rotation_size | integer | 10240 | 全部 | 轮转大小阈值(kb) |
log_truncate_on_rotation | boolean | off | 全部 | 轮转时是否截断 |
log_connections | boolean | off | 全部 | 记录连接事件 |
log_disconnections | boolean | off | 全部 | 记录断开事件 |
log_autovacuum_min_duration | integer | -1 | 全部 | autovacuum 日志阈值(ms) |
log_checkpoints | boolean | off | 全部 | 记录检查点 |
log_lock_waits | boolean | off | 全部 | 记录锁等待 |
log_temp_files | integer | -1 | 全部 | 临时文件日志阈值(kb) |
log_min_duration_statement | integer | -1 | 全部 | 慢查询阈值(ms) |
log_duration | boolean | off | 全部 | 记录所有语句耗时 |
log_statement | enum | none | 全部 | 语句类型过滤 |
log_min_duration_sample | integer | -1 | 14+ | 采样阈值(ms) |
log_statement_sample_rate | float | 1.0 | 14+ | 采样率(0.0~1.0) |
log_line_prefix | string | ‘’ | 全部 | 日志行前缀 |
log_min_messages | enum | warning | 全部 | 服务器日志级别 |
client_min_messages | enum | notice | 全部 | 客户端消息级别 |
以下 demo 演示如何在 node.js 应用中配置 postgresql 慢查询日志,并使用 file_fdw 查询日志进行分析。
环境要求:
pg npm 包步骤:
postgresql.conf:logging_collector = on log_destination = 'stderr,csvlog' log_directory = 'pg_log' log_filename = 'postgresql-%y-%m-%d_%h%m%s.log' log_rotation_age = 1d log_rotation_size = 100mb log_min_duration_statement = 500 log_connections = on log_disconnections = on log_lock_waits = on log_temp_files = 0 log_line_prefix = '%m [%p] %q%u@%d/%a '
sudo systemctl restart postgresql # 或 pg_ctl restart -d /path/to/data
npm init -y npm install pg node demo.js
// demo.js
const { client } = require('pg');
const pg_config = {
host: 'localhost',
port: 5432,
database: 'testdb',
user: 'testuser',
password: 'testpass'
};
// 创建带慢查询的测试数据
async function setuptestdata(client) {
await client.query(`
create table if not exists test_logging (
id serial primary key,
data text,
created_at timestamp default now()
)
`);
// 插入 10000 条测试数据
await client.query(`
insert into test_logging (data)
select md5(random()::text)
from generate_series(1, 10000)
`);
console.log('[setup] 测试数据已创建');
}
// 执行一个慢查询(模拟)
async function runslowquery(client) {
const start = date.now();
await client.query(`
select count(*), data
from test_logging
group by data
having count(*) > 1
order by count(*) desc
`);
const duration = date.now() - start;
console.log(`[query] 慢查询执行完成,耗时: ${duration}ms`);
}
// 使用 file_fdw 查询日志(需提前配置)
async function querylogswithfilefdw(client) {
// 创建 file_fdw 扩展
await client.query('create extension if not exists file_fdw');
// 创建外部服务器
await client.query(`
create server if not exists log_server
foreign data wrapper file_fdw
`);
// 创建外部表(csv格式)
await client.query(`
create foreign table if not exists pg_log_csv (
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
) server log_server
options (filename '/path/to/pg_data/pg_log/postgresql.csv', format 'csv')
`);
// 查询最近1小时的慢查询
const result = await client.query(`
select
log_time,
user_name,
database_name,
substring(query, 1, 100) as query_preview,
message
from pg_log_csv
where error_severity = 'log'
and message like '%duration%'
and log_time > now() - interval '1 hour'
order by log_time desc
limit 10
`);
console.log('[logs] 最近慢查询:');
result.rows.foreach(row => {
console.log(` ${row.log_time} | ${row.user_name} | ${row.query_preview}...`);
});
}
async function main() {
const client = new client(pg_config);
try {
await client.connect();
console.log('[demo] 已连接到 postgresql');
await setuptestdata(client);
// 执行多次慢查询以便产生日志
for (let i = 0; i < 3; i++) {
await runslowquery(client);
}
// 查询日志(需将路径替换为实际日志路径)
// await querylogswithfilefdw(client);
// 查看当前慢查询配置
const config = await client.query(`
select name, setting
from pg_settings
where name in (
'log_min_duration_statement',
'log_duration',
'log_statement',
'logging_collector'
)
`);
console.log('[config] 当前日志配置:');
config.rows.foreach(row => {
console.log(` ${row.name} = ${row.setting}`);
});
} catch (err) {
console.error('[error]', err);
} finally {
await client.end();
}
}
main();log_min_duration_statement 用于捕获超过阈值的慢查询logging_collector 是日志持久化的前提log_line_prefix 自定义日志格式便于解析file_fdw 将日志文件映射为外部表,用 sql 分析日志pg_settings 视图可查看当前运行时配置-- 查看当前慢查询阈值 show log_min_duration_statement; -- 动态修改(当前会话) set log_min_duration_statement = 1000; -- 动态修改(全局,下次连接生效) alter system set log_min_duration_statement = '1000'; select pg_reload_conf(); -- 查看日志相关所有参数 select name, setting, unit, context from pg_settings where name like 'log%' order by name;
以下分别使用 go、python 和 java 实现与 node.js 示例相同的功能:连接 postgresql、创建测试表、插入测试数据、执行慢查询并查看日志配置。
环境要求:
github.com/lib/pq步骤:
go mod init demo go get github.com/lib/pq
postgresql.conf 已按前文配置,并重启 postgresql。go run demo.go
// demo.go
package main
import (
"database/sql"
"fmt"
"log"
"time"
_ "github.com/lib/pq"
)
const (
host = "localhost"
port = 5432
user = "testuser"
password = "testpass"
dbname = "testdb"
)
func main() {
connstr := fmt.sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
db, err := sql.open("postgres", connstr)
if err != nil {
log.fatal("连接失败:", err)
}
defer db.close()
if err := db.ping(); err != nil {
log.fatal("ping失败:", err)
}
fmt.println("[demo] 已连接到 postgresql")
// 创建测试表
_, err = db.exec(`
create table if not exists test_logging (
id serial primary key,
data text,
created_at timestamp default now()
)
`)
if err != nil {
log.fatal("建表失败:", err)
}
// 插入测试数据
_, err = db.exec(`
insert into test_logging (data)
select md5(random()::text)
from generate_series(1, 10000)
`)
if err != nil {
log.fatal("插入数据失败:", err)
}
fmt.println("[setup] 测试数据已创建")
// 执行慢查询(重复3次)
for i := 0; i < 3; i++ {
start := time.now()
rows, err := db.query(`
select count(*), data
from test_logging
group by data
having count(*) > 1
order by count(*) desc
`)
if err != nil {
log.fatal("查询失败:", err)
}
rows.close()
duration := time.since(start)
fmt.printf("[query] 慢查询执行完成,耗时: %v\n", duration)
}
// 查看当前慢查询配置
var name, setting string
rowscfg, err := db.query(`
select name, setting
from pg_settings
where name in ('log_min_duration_statement', 'log_duration', 'log_statement', 'logging_collector')
`)
if err != nil {
log.fatal("查询配置失败:", err)
}
defer rowscfg.close()
fmt.println("[config] 当前日志配置:")
for rowscfg.next() {
rowscfg.scan(&name, &setting)
fmt.printf(" %s = %s\n", name, setting)
}
}lib/pq 驱动连接 postgresql,dsn 格式标准sql.open 返回连接池,ping 验证连通性generate_series 生成测试数据pg_settings 视图获取当前日志参数环境要求:
psycopg2-binary步骤:
pip install psycopg2-binary
python demo.py
# demo.py
import psycopg2
import time
pg_config = {
'host': 'localhost',
'port': 5432,
'database': 'testdb',
'user': 'testuser',
'password': 'testpass'
}
def main():
conn = psycopg2.connect(**pg_config)
conn.autocommit = true
cur = conn.cursor()
print("[demo] 已连接到 postgresql")
# 创建测试表
cur.execute("""
create table if not exists test_logging (
id serial primary key,
data text,
created_at timestamp default now()
)
""")
# 插入测试数据
cur.execute("""
insert into test_logging (data)
select md5(random()::text)
from generate_series(1, 10000)
""")
print("[setup] 测试数据已创建")
# 执行慢查询(重复3次)
for i in range(3):
start = time.time()
cur.execute("""
select count(*), data
from test_logging
group by data
having count(*) > 1
order by count(*) desc
""")
rows = cur.fetchall()
duration = (time.time() - start) * 1000
print(f"[query] 慢查询执行完成,耗时: {duration:.2f}ms")
# 查看当前慢查询配置
cur.execute("""
select name, setting
from pg_settings
where name in ('log_min_duration_statement', 'log_duration', 'log_statement', 'logging_collector')
""")
print("[config] 当前日志配置:")
for name, setting in cur.fetchall():
print(f" {name} = {setting}")
cur.close()
conn.close()
if __name__ == "__main__":
main()psycopg2 驱动,autocommit=true 避免显式事务fetchall 获取结果time.time() 测量执行耗时(毫秒转换)pg_settings 查看运行时配置环境要求:
org.postgresql:postgresql:42.7.3步骤:
pom.xml 中添加:<dependency>
<groupid>org.postgresql</groupid>
<artifactid>postgresql</artifactid>
<version>42.7.3</version>
</dependency>mvn compile mvn exec:java -dexec.mainclass="demo"
或直接使用 javac 和 java(需将 jar 加入 classpath)。
// demo.java
import java.sql.*;
import java.util.properties;
public class demo {
private static final string url = "jdbc:postgresql://localhost:5432/testdb";
private static final string user = "testuser";
private static final string password = "testpass";
public static void main(string[] args) {
properties props = new properties();
props.setproperty("user", user);
props.setproperty("password", password);
try (connection conn = drivermanager.getconnection(url, props)) {
system.out.println("[demo] 已连接到 postgresql");
// 创建测试表
try (statement stmt = conn.createstatement()) {
stmt.execute("""
create table if not exists test_logging (
id serial primary key,
data text,
created_at timestamp default now()
)
""");
// 插入测试数据
stmt.execute("""
insert into test_logging (data)
select md5(random()::text)
from generate_series(1, 10000)
""");
system.out.println("[setup] 测试数据已创建");
}
// 执行慢查询(重复3次)
for (int i = 0; i < 3; i++) {
long start = system.currenttimemillis();
try (statement stmt = conn.createstatement();
resultset rs = stmt.executequery("""
select count(*), data
from test_logging
group by data
having count(*) > 1
order by count(*) desc
""")) {
while (rs.next()) {
// 消费结果集
}
}
long duration = system.currenttimemillis() - start;
system.out.printf("[query] 慢查询执行完成,耗时: %dms%n", duration);
}
// 查看当前慢查询配置
try (statement stmt = conn.createstatement();
resultset rs = stmt.executequery("""
select name, setting
from pg_settings
where name in ('log_min_duration_statement', 'log_duration', 'log_statement', 'logging_collector')
""")) {
system.out.println("[config] 当前日志配置:");
while (rs.next()) {
system.out.printf(" %s = %s%n", rs.getstring("name"), rs.getstring("setting"));
}
}
} catch (sqlexception e) {
e.printstacktrace();
}
}
}jdbc:postgresql://host:port/dbproperties 传递认证信息statement、resultset、connection)system.currenttimemillis() 测量毫秒级耗时pg_settings 与 node.js 示例逻辑一致| 特性 | node.js (pg) | go (lib/pq) | python (psycopg2) | java (jdbc) |
|---|---|---|---|---|
| 连接方式 | new client(config) | sql.open("postgres", dsn) | psycopg2.connect(**config) | drivermanager.getconnection(url, props) |
| 连接池 | 默认支持(内置) | 默认支持(sql.db) | 需要额外配置(threadedconnectionpool) | 需要额外库(如 hikaricp) |
| 执行查询 | client.query() | db.query() | cur.execute() | stmt.executequery() |
| 参数化查询 | $1, $2 | $1, $2 | %s(或 %(name)s) | ? 或 $1(pg 驱动支持 $1) |
| 事务控制 | 默认自动提交,可手动 begin | 默认自动提交,可 db.begin() | autocommit 参数控制 | 默认自动提交,conn.setautocommit(false) |
| 错误处理 | try/catch | 返回 error | try/except | try/catch (sqlexception) |
| 资源释放 | 客户端 end() | defer rows.close() | cur.close() / conn.close() | try-with-resources 自动关闭 |
| 类型映射 | 自动映射 json/数组 | 需实现 scanner 接口 | 自动映射 python 类型 | 需通过 getxxx 获取 |
| 日志配置查看 | 查询 pg_settings | 查询 pg_settings | 查询 pg_settings | 查询 pg_settings |
| 适用场景 | 快速开发、原型 | 高并发、微服务 | 数据分析、脚本 | 企业级应用、spring 生态 |
所有示例均实现了相同的功能:连接 → 建表 → 批量插入 → 执行慢查询(重复3次)→ 读取日志配置。用户可根据自身技术栈选择对应语言,核心逻辑与 postgresql 交互方式一致,仅驱动 api 和语法风格不同。
本文系统梳理了 postgresql 日志体系的全部核心参数,涵盖日志输出与轮转、连接审计、autovacuum 与检查点监控、锁等待与临时文件诊断、慢查询捕获、语句类型过滤、高并发场景下的采样机制以及自定义日志格式等维度。
生产环境应根据负载特征合理配置 log_min_duration_statement(慢查询阈值)和 log_statement(语句类型),高并发场景可启用 pg 14+ 的采样参数 log_min_duration_sample 与 log_statement_sample_rate 平衡性能开销与可观测性。
file_fdw 提供了用 sql 分析日志的创新途径,大幅提升日志分析的灵活性和效率。所有配置变更需通过 postgresql.conf 或 alter system 持久化,并调用 pg_reload_conf() 动态生效。
以上就是postgresql慢查询日志配置与日志管理完全指南的详细内容,更多关于postgresql慢查询日志配置与管理的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论