PostgreSQL Log 日志模块详解

news2024/9/28 1:22:54

本文讲的是操作日志,非 WAL 日志。

文章目录

  • 背景
  • 日志模块原理
    • Syslogger 核心模块
    • 日志消息通信
    • 日志轮转
        • 问题一
        • 问题二
        • 问题三
        • 问题四
        • 问题五
  • 存在的问题
    • 刷盘性能
    • 日志轮转
  • 参考资料

背景

PG 的日志模块是一个相对独立的模块,主要功能就是打印用户的操作日志以及一些异常报错信息。本文仅讲述 logging_collector 参数开启的情况。

日志模块原理

Syslogger 核心模块

PG 有各种各样的进程,其中 syslogger 进程专门用于打印日志信息。
而其余进程打印日志的方法如出一辙:将需要打印的信息发送给 syslogger 进程,由其统一负责打印。
在这里插入图片描述

syslogger 的大体逻辑如下图所示:
在这里插入图片描述

  1. postmaster 进程在 SysLogger_Start 函数完成部分初始化;
  2. 由 postmaster 进程 fork 出 syslogger 进程;
  3. 进入 syslogger 的主逻辑函数 SysLoggerMain 中,大循环监听其他进程发送来的日志消息,处理打印逻辑。在大循环中同时也根据时间和大小,来判断是否进行日志轮转。

日志消息通信

PG 的其余进程如果有需要打印的日志,通常会调用 elog 或者 ereport 来打印。而这两个函数会将日志消息分成若干个 chunk 发送给 syslogger 进程,每个 chunk 的结构可参考下图(源码中的 PipeProtoChunk 结构)
在这里插入图片描述

  • 开头两个 \0 ,表示是日志开头
  • length:用于记录当前 chunk 的长度
  • pid:发送该 chunk 的进程号
  • is_last:是否是本条日志消息的最后一个 chunk;
  • data:具体的日志消息。
  • chunk 大小:PIPE_CHUNK_SIZE ,源码 define 出的一个值,由 OS 的 PIPE_BUF 决定。具体细节可参考这部分定义的代码。
    注: PG 15 在 pipe 协议格式中做了一些变化,由 flags 代替 is_last 标记。

syslogger 在接收到日志消息后,将其按照 pid 进行分组,相同的 pid 说明日志消息来源于同一进程,将其组装起来,当收到包含 is_last 标记的最后一个 chunk 后,将整条日志消息打印到日志文件。

日志轮转

所谓日志轮转,指的就是不想继续写当前日志文件了,需要新找一个日志文件继续写日志。

PG 的日志轮转是一个坑非常多的地方,因为它由下面四个参数同时控制:

  • log_filename :日志文件格式,我们以其设定为 postgres_%d_%h 为例,某个月 14 号 15 点的日志文件名就是 postgres_14_15.log
  • log_rotation_age:如果距离当前日志文件已经超过设定的时间,那么就新开一个日志文件;
  • log_rotation_size:如果距离当前日志文件还没有超过 log_rotation_age 设定的时间,但是已经超过了 log_rotation_size 设定的大小,那么就新开一个日志文件;
  • log_truncate_on_rotation:是否在按时间轮转后做截断。即如果下一个日志文件的同名文件已经存在了,是否直接清空该文件并从头开始写;

这几个参数的具体使用可参考 PG 官方文档。看完上面的介绍,想必大家已经精通日志参数设置了,那么接下来做几道题检验自己的学习成果。

假如,我们按照以下值设定日志相关参数

log_filename='postgres_%d_%h.log'
log_rotation_age = 2h
log_rotation_size = 10MB
log_truncate_on_rotation = on

问题一

  • Q:此时时间刚到 14 号下午 17 点 ,日志文件为 postgres_14_16.log,且大小为 5MB,请问接下来要写的日志文件是什么?
  • A:postgres_14_16.log 。因为此时距离 15 点仅过了 1h,没有超过 log_rotation_age;大小并没有超过 log_rotation_size ,所以并不发生轮转。

问题二

  • Q:此时时间为 14 号下午 16 点 30 分 ,日志文件为 postgres_14_16.log,且大小刚刚超过 10MB 到达 10.9MB,请问接下来要写的日志文件是什么?
  • A:postgres_14_16.log 。因为 log_filename 参数的最小精度值就到小时,哪怕当前日志文件大小变成 1TB 也只会继续追加写这个文件。

问题三

  • Q:此时时间刚到 14 号下午 17 点 ,日志文件为 postgres_14_16.log,且大小刚刚超过 10MB 到达 10.9MB,请问接下来要写的日志文件是什么?
  • A:postgres_14_17.log 。因为满足 log_rotation_size 的轮转条件了。

问题四

  • Q:此时时间刚到 14 号下午 17 点 ,日志文件为 postgres_14_16.log,且大小刚刚超过 10MB 到达 10.9MB,但是名为 postgres_14_17.log 的文件已经存在了(上个月日志创建的),那么是追加写还是覆盖写该文件?
  • A:追加写,因为这是按大小轮转。

问题五

  • Q:此时时间刚到 14 号下午 18 点 ,日志文件为 postgres_14_16.log,且大小只有 0.1MB。但是名为 postgres_14_18.log 的文件已经存在了,那么是追加写还是覆盖写该文件?
  • A:覆盖写,log_rotation_age 强制触发按时间轮转逻辑。

上面问题都能搞懂,基本也没什么坑了。

存在的问题

刷盘性能

当前情况下,在 log_statement 参数设置成 all 时,性能下降会非常厉害。因为 PG 的日志在刷盘时的默认策略为:每写一行就刷盘。Linux 提供的刷盘模式可分为以下三种:

  • _IOFBF:全缓冲模式,缓冲区写满后才刷盘
  • _IOLBF:行缓冲模式,一行写满就刷盘
  • _IONBF:不缓冲,直接刷

当前 PG 采用第二种行缓冲模式,优点是日志出来的即时性更高,缺点就是对性能有不小的影响。

日志轮转

日志轮转的逻辑设计虽然勉强算是合理的(不会丢日志),但是理解成本很高,且有可能出现某个日志文件存在了非常非常久(上一节问题 4 的变种),一直没被删掉,需要依赖人工手动删除。

参考资料

[1] https://www.postgresql.org/docs/current/logfile-maintenance.html
[2] https://github.com/postgres/postgres

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/695736.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MATLAB第46期】基于MATLAB的改进模糊卷积神经网络IFCNN分类预测模型

【MATLAB第46期】基于MATLAB的改进模糊卷积神经网络IFCNN多分类预测模型 一、展示效果 二、思路 在正常CNN卷积神经网络训练阶段之后,使用进化算法(蜜蜂算法)拟合深度学习权重和偏差。 本文案例数据中, 用深度模型进行4分类预测…

vmware安装centos将home磁盘合并至root下

使用vmware安装centos后,发现分的盘60G,其中有17G分到了home盘,现在想只用一个盘进行统一管理,于是将home盘删除掉,再合并到root盘下,这里是直接删除掉home,没有备份数据,步骤如下: …

时间表R(t) 和 学习曲线learning curve

import numpy as np import matplotlib.pyplot as plt# 设置参数 a1 2 a2 0.1 a3 0.1 a4 1 T 10# 生成曲线数据 t np.linspace(0, 20, 1000) y np.exp(-a2 * t**a1) a3 * (t / T)**a4# 绘制曲线 plt.plot(t, y) plt.xlabel(t) plt.ylabel(R(t)) plt.title(Evolution of…

亚马逊云科技发起“可持续发展伙伴计划” ,实现降本增效、安全合规的上云价值

6月27日,“2023亚马逊云科技中国峰会”在上海世博中心盛大启幕! 在与全球客户的交流中,亚马逊云科技发现很多企业都在三个方面不断创建未雨绸缪:首先,降本增效;其次,保证业务安全合规&#xff…

vscode如何创建自定义快捷键模板(typescript React示例)

1.vs面板左下角设置-配置用户代码片段 2. 弹出搜索框中输入typescript会出来2个选项,选择第二个react 3.在代码片段中添加自己的快捷键设置片段(用$TM_FILENAME_BASE$1可以获取当前文件的名称) {// Place your snippets for typescriptreact…

python基础案例题(进制转换、字符串加密的实现、猜拳游戏、多种方法计算π)

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 环境使用: Python 3.8 Pycharm 专业版 1.进制转换 功能:获取十进制整数的二进制串,相当于内置函数bin。 算法分析: 对2辗转相除,直到商为0 每次所得余数逆序即可 流程图…

playerdemo开源项目win运行详细配置

playerdemo开源项目win运行详细配置 在项目同目录建立文件夹lib 一、下载ffmpeg 下载32位的ffmpeg,放在lib/ffmpeg路径下 二、下载sdl2 下载sdl2也放在 lib/sdl2路径下 三、配置 .pro文件 win32 { LIBS -L$$PWD/lib/SDL2/lib/x86 \-L$$PWD/lib/ffmpeg-4.2.…

springboot增加logback日志记录ip

1、增加logback配置文件: public class IPLogConfig extends ClassicConverter {Overridepublic String convert(ILoggingEvent event) {RequestAttributes requestAttributes RequestContextHolder.getRequestAttributes();if (requestAttributes null) {return…

could not read ok from ADB Server

ADB不能连接: D:\adb\platform-tools>adb.exe devices * daemon not running; starting now at tcp:5037 could not read ok from ADB Server * failed to start daemon adb.exe: failed to check server version: cannot connect to daemon关闭防火墙可以解决。…

星辰秘典:揭示Python项目的宇宙奥秘——宇宙星空模拟器

✨博主:命运之光 🌸专栏:Python星辰秘典 🐳专栏:web开发(html css js) ❤️专栏:Java经典程序设计 ☀️博主的其他文章:点击进入博主的主页 前言:你好&#x…

Unity | HDRP高清渲染管线学习笔记:Post-processing后处理效果

目录 一、后处理效果顺序 二、16个后处理效果 1. Tonemapping(色调映射) 2.White Balance(白平衡) 3. Bloom(泛光) 3.1 Quality 3.2 Bloom 3.2.1 Threshold(临界值) 3.2.2 I…

为什么 Java 是我心中的 TOP 1

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌ Java知识图谱点击链接:体系化学习Java(Java面试专题) 💕💕 感兴趣的同学可以收…

10张读书笔记思维导图|让你告别书荒

又到了2023年下半年了,很多朋友又开始计划新一轮的读书计划,可是不知道读什么?也不知道怎么读? 今天小P就给大家分享30张思维导图读书笔记,让你在读书之前先了解书里讲了什么?帮你快速筛选自己喜欢的且有用…

47从零开始学Java之详解final修饰符、常量、常量方法与常量类

作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 壹哥之前跟大家说过,在面向对象中,有abstract、static和final 这3个核心修饰符…

使用XLSX.utils.sheet_to_json()解析excel,给空的单元格赋值为空字符串

前言 今天用到XLSX来解析excel文件,调用XLSX.utils.sheet_to_json(worksheet),发现如果单元格为空的话,解析出来的结果,就会缺少相应的key(如图所示)。但是我想要单元格为空的话,值就默认给空字…

BUUCTF刷题之路--ez_pz_hackover_20161

检查开启的保护: 32位程序,没有开启保护。看到这大概率猜到是可以利用shellcode。接着IDA查看下逻辑: 主函数: header函数: chall函数: 大致讲解下程序逻辑。首先会要求你输入一个名字。存入s这个缓冲区中。…

Redis7【④ 事务 管道】

1. Redis事务 Redis 事务(Transaction)是一组 Redis 命令的集合,这些命令被当作一个整体,按顺序地串行化执行,而不会被其他命令插入。 Redis 事务使用 MULTI、EXEC、WATCH、DISCARD 和 UNWATCH 这些命令来实现。 1.1…

Linux系统:进程控制

文章目录 1 创建进程2 进程终止2.1 进程退出情况2.2 进程终止的常见方式2.2.1 return语句2.2.2 exit()函数2.2.3 _exit()函数 3进程等待3.1 进程等待的重要性3.2 进程等待的方法3.2.1 wait()方法3.2.2 waitpid()方法 4 进程替换4.1 替换原理4.2 替换函数 1 创建进程 fork()函数…

mediapipe 手势节点识别自动控制音量

参考:https://www.computervision.zone/topic/volumehandcontrol-py/ 主函数: VolumeHandControl.py import cv2 import time import numpy as np import HandTrackingModule as htm import math from ctypes import cast, POINTER from comtypes imp…

[问题解决] ubuntu 18.04 GPU驱动安装

删除当前显卡驱动[参考] sudo apt-get purge nvidia* 查看推荐驱动 sudo ubuntu-drivers devices 安装对应驱动 sudo apt install nvidia-driver-530 验证安装是否成功:nvidia-smi