当前位置: 代码网 > it编程>数据库>MsSqlserver > PostgreSQL慢查询日志配置与日志管理完全指南

PostgreSQL慢查询日志配置与日志管理完全指南

2026年08月24日 MsSqlserver 我要评论
纲要logging_collector:日志收集器log_destination:日志输出目标log_directory:日志目录log_filename:日志文件名格式log_rotation_ag

纲要

  • 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 控制日志输出目标,支持 stderrcsvlogjsonlogsyslog(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_connectionslog_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

autovacuum 与检查点日志

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

最常用的慢查询控制参数,设置语句执行时间阈值(毫秒),超过该阈值的语句将在执行完成后连同耗时一并记录:

log_min_duration_statement = 500  # 记录超过500ms的查询
  • 设为 0:记录所有语句及其耗时
  • 设为 -1(默认):禁用

该参数记录查询文本,适合生产环境定位慢查询。

log_duration

记录所有已完成语句的耗时,不记录查询文本

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 语句(createalterdrop 等)
  • mod:记录 ddl 及数据修改语句(insertupdatedeletetruncatecopy from
  • all:记录所有语句

log_statement 在语句被正确解析后即记录。与 log_min_duration_statement 配合使用时,已被 log_statement 记录的查询不会被重复记录。

日志采样(postgresql 14+)

高并发场景下记录所有语句会带来显著性能开销和日志量压力。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_prefixprintf 风格的字符串,用于自定义日志行前缀:

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:用 sql 查询日志

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 角色权限。

api 速览

参数类型默认值适用版本说明
logging_collectorbooleanoff全部启用日志收集器
log_destinationstringstderr全部日志输出目标
log_directorystringpg_log全部日志目录
log_filenamestringpostgresql-%y-%m-%d_%h%m%s.log全部日志文件名格式
log_rotation_ageinteger1440全部轮转时间阈值(分钟)
log_rotation_sizeinteger10240全部轮转大小阈值(kb)
log_truncate_on_rotationbooleanoff全部轮转时是否截断
log_connectionsbooleanoff全部记录连接事件
log_disconnectionsbooleanoff全部记录断开事件
log_autovacuum_min_durationinteger-1全部autovacuum 日志阈值(ms)
log_checkpointsbooleanoff全部记录检查点
log_lock_waitsbooleanoff全部记录锁等待
log_temp_filesinteger-1全部临时文件日志阈值(kb)
log_min_duration_statementinteger-1全部慢查询阈值(ms)
log_durationbooleanoff全部记录所有语句耗时
log_statementenumnone全部语句类型过滤
log_min_duration_sampleinteger-114+采样阈值(ms)
log_statement_sample_ratefloat1.014+采样率(0.0~1.0)
log_line_prefixstring‘’全部日志行前缀
log_min_messagesenumwarning全部服务器日志级别
client_min_messagesenumnotice全部客户端消息级别

demo 完整示例

以下 demo 演示如何在 node.js 应用中配置 postgresql 慢查询日志,并使用 file_fdw 查询日志进行分析。

运行说明

环境要求

  • postgresql 14+
  • node.js 16+
  • pg npm 包

步骤

  1. 配置 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 '
  1. 重启 postgresql 使配置生效:
sudo systemctl restart postgresql
# 或
pg_ctl restart -d /path/to/data
  1. 安装依赖并运行 demo:
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 视图可查看当前运行时配置

postgresql 原生指令对照

-- 查看当前慢查询阈值
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、创建测试表、插入测试数据、执行慢查询并查看日志配置。

go 示例

运行说明

环境要求

  • go 1.19+
  • postgresql 14+
  • 驱动:github.com/lib/pq

步骤

  1. 初始化模块并安装依赖:
go mod init demo
go get github.com/lib/pq
  1. 确保 postgresql.conf 已按前文配置,并重启 postgresql。
  2. 运行:
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 视图获取当前日志参数

python 示例

运行说明

环境要求

  • python 3.8+
  • postgresql 14+
  • 驱动:psycopg2-binary

步骤

  1. 安装依赖:
pip install psycopg2-binary
  1. 确保 postgresql 配置正确并重启。
  2. 运行:
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 避免显式事务
  • 游标执行 ddl 和 dml,fetchall 获取结果
  • time.time() 测量执行耗时(毫秒转换)
  • 查询 pg_settings 查看运行时配置

java 示例

运行说明

环境要求

  • jdk 11+
  • postgresql 14+
  • maven 或手动添加依赖:org.postgresql:postgresql:42.7.3

步骤

  1. 创建 maven 项目,在 pom.xml 中添加:
<dependency>
    <groupid>org.postgresql</groupid>
    <artifactid>postgresql</artifactid>
    <version>42.7.3</version>
</dependency>
  1. 编译并运行:
mvn compile
mvn exec:java -dexec.mainclass="demo"

或直接使用 javacjava(需将 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 驱动,url 格式 jdbc:postgresql://host:port/db
  • 通过 properties 传递认证信息
  • 使用 try-with-resources 自动释放资源(statementresultsetconnection
  • 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返回 errortry/excepttry/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_samplelog_statement_sample_rate 平衡性能开销与可观测性。

file_fdw 提供了用 sql 分析日志的创新途径,大幅提升日志分析的灵活性和效率。所有配置变更需通过 postgresql.confalter system 持久化,并调用 pg_reload_conf() 动态生效。

以上就是postgresql慢查询日志配置与日志管理完全指南的详细内容,更多关于postgresql慢查询日志配置与管理的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com