当前位置: 首页 > news >正文

PostgreSQL pg-xact(clog)目录文件缺失处理

 一、 背景

        前些天晚上突然收到业务反馈,查询DB中的一个表报错

Could not open file "pg-xact/005E": No such file or directory.

         两眼一黑难道是文件损坏了...登录查看DB日志,还好没有其他报错,业务也反馈只有这一个表在从库查询报错,主库正常,于是开始分析处理。

二、 解决方法

根据搜索结果看,这个问题基本就两种处理方法,这里先列出来。

1. 数据库恢复

       如果数据库小,或者对数据一致性要求高,建议的方法还是进行恢复,因为方法二实际对数据一致性是有损的。

2. 新建全0文件

报错是文件没了,所以解决方法是手动建回去(记得先确认权限)

#postgres用户执行
dd if=/dev/zero of=$PGDATA/pg_xact/005E bs=256k count=1
chmod 600 $PGDATA/pg_xact/005E

风险

       clog存事务的最终状态信息,就是这个事务最终是提交了还是回滚了,建一个空的文件,相当于文件里的事务不知道它提交还是回滚了,理论上会出现数据不一致。

       为什么这里建全0文件可以修复,从源码中可以看到,CLOG的日志段创建函数如下:

/** This func must be called ONCE on system install.  It creates* the initial CLOG segment.  (The CLOG directory is assumed to* have been created by initdb, and CLOGShmemInit must have been* called already.)*/
void
BootStrapCLOG(void)
{int			slotno;LWLockAcquire(XactSLRULock, LW_EXCLUSIVE);/* Create and zero the first page of the commit log */slotno = ZeroCLOGPage(0, false);/* Make sure it's written out */SimpleLruWritePage(XactCtl, slotno);Assert(!XactCtl->shared->page_dirty[slotno]);LWLockRelease(XactSLRULock);
}

主要为两个函数:

  • ZeroCLOGPage函数:将该可用缓冲区初始化为全0
  • SimpleLruWritePage函数:会再调用SlruInternalWritePage函数将页由缓冲区写入磁盘

三、 CLOG是什么

1. 原理及作用

postgresql源码学习(51)—— 提交日志CLOG 原理 用途 管理函数-CSDN博客

2. CLOG如何删除

报错是clog没了,所以这里再学习一下CLOG的删除原理

  • TruncateCLOG函数:调用WriteTruncateXlogRec删除过期的CLOG
  • 是否过期根据当前数据库中最旧事务id oldestXact判断
/** Remove all CLOG segments before the one holding the passed transaction ID** Before removing any CLOG data, we must flush XLOG to disk, to ensure* that any recently-emitted FREEZE_PAGE records have reached disk; otherwise* a crash and restart might leave us with some unfrozen tuples referencing* removed CLOG data.  We choose to emit a special TRUNCATE XLOG record too.* Replaying the deletion from XLOG is not critical, since the files could* just as well be removed later, but doing so prevents a long-running hot* standby server from acquiring an unreasonably bloated CLOG directory.** Since CLOG segments hold a large number of transactions, the opportunity to* actually remove a segment is fairly rare, and so it seems best not to do* the XLOG flush unless we have confirmed that there is a removable segment.*/
void
TruncateCLOG(TransactionId oldestXact, Oid oldestxid_datoid)
{int			cutoffPage;/** The cutoff point is the start of the segment containing oldestXact. We* pass the *page* containing oldestXact to SimpleLruTruncate.*/cutoffPage = TransactionIdToPage(oldestXact);/* Check to see if there's any files that could be removed */if (!SlruScanDirectory(XactCtl, SlruScanDirCbReportPresence, &cutoffPage))return;					/* nothing to remove *//** Advance oldestClogXid before truncating clog, so concurrent xact status* lookups can ensure they don't attempt to access truncated-away clog.** It's only necessary to do this if we will actually truncate away clog* pages.*/AdvanceOldestClogXid(oldestXact);/** Write XLOG record and flush XLOG to disk. We record the oldest xid* we're keeping information about here so we can ensure that it's always* ahead of clog truncation in case we crash, and so a standby finds out* the new valid xid before the next checkpoint.*/WriteTruncateXlogRec(cutoffPage, oldestXact, oldestxid_datoid);/* Now we can remove the old CLOG segment(s) */SimpleLruTruncate(XactCtl, cutoffPage);
}
  • AdvanceOldestClogXid函数:对比 clog中的事务id 与 当前数据库最旧事务id oldestXact,如果clog中的更旧,将其更新为oldestXact,避免后续并发事务访问到已被清理的clog。
/** Advance the cluster-wide value for the oldest valid clog entry.** We must acquire XactTruncationLock to advance the oldestClogXid. It's not* necessary to hold the lock during the actual clog truncation, only when we* advance the limit, as code looking up arbitrary xids is required to hold* XactTruncationLock from when it tests oldestClogXid through to when it* completes the clog lookup.*/
void
AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
{LWLockAcquire(XactTruncationLock, LW_EXCLUSIVE);if (TransactionIdPrecedes(ShmemVariableCache->oldestClogXid,oldest_datfrozenxid)){ShmemVariableCache->oldestClogXid = oldest_datfrozenxid;}LWLockRelease(XactTruncationLock);
}

四、 遗留问题

这个报错为什么会突然出现,目前还没查到相关资料

1. 现场情况

  • 报错PG版本为10.5,从库查询报错,主库不报错
  • 报错中要找的clog为005E,txid为 99185979
  • 报错数据库最旧的clog为0269,并且已经是两个月前的

  • 报错数据库当前txid为 9436969370,远远大于报错的

一个小补充:为什么查出来的txid是94亿多,远远大于了42亿,实际上txid的计算有一个转换,转完之后大概是8亿多。

select (txid_current() % (2^32)::bigint)::text::xid;
  • 当时数据库中最老的表年龄大概是1.9亿,并且不是报错的这个表

2. 一些猜测

       从现场情况来看,005E文件应该是PG正常删除,而非误删或文件系统损坏导致不可访问。

       奇怪的是为什么查询该表会访问这么旧的文件,从事务年龄来看,这不应该是个正常的访问,比较怀疑还是遇到了bug。

参考

《PostgreSQL数据库内核分析》第7章

PostgresQL-丢失各种数据文件如何恢复 - binbinx - 博客园

相关文章:

PostgreSQL pg-xact(clog)目录文件缺失处理

一、 背景 前些天晚上突然收到业务反馈,查询DB中的一个表报错 Could not open file "pg-xact/005E": No such file or directory. 两眼一黑难道是文件损坏了...登录查看DB日志,还好没有其他报错,业务也反馈只有这一个表在从库查询报…...

《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明

参考 《element plus 使用 icon 图标(两种方式)》使用 icon 升级 Vue2 升级 Vue3 项目时,遇到命名时的实心与空心点差异! ElementUI: 实心是 el-icon-more空心是 el-icon-more-outline ElementPlus: 实心是 el-icon-more-fill…...

基于碎纸片的拼接复原算法及MATLAB实现

一、问题描述 破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。传统上,拼接复原工作需由人工完成,准确率较高,但效率很低。特别是当碎片数量巨大,人工拼接很难在短时间内完成任务。随着计算…...

苍穹外卖 软件开发流程

软件开发的流程: 1.需求分析 完成需求规格说明书、产品原型。 需求规格说明书:一般而言是word文档描述当前项目的各个组成部分,如:系统定义、应用环境、功能规格、性能需求等,都会在文档中描述。 …...

mysqldump导出表结构和表数据和存储过程和函数

0、查看表结构信息 (1) 只查看表结构的注释信息 select table_name,table_comment from information_schema.tables where table_schema 表所在的库 and table_name 表名 ; mysql> select table_name,table_comment from information_schema.tables where tabl…...

常见的排序算法及分类对比

虽然在竞赛和编程语言中用到的排序算法主要是时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的高效算法,但作为算法学习,我们要从简单到复杂,认识常见的排序算法,并理解其算法思想。本文列出几乎所有的排序算法并进行分类对比。 排序算法总表 以下是一个对比表格…...

多窗口切换——selenium

获取窗口句柄(以Python Selenium为例) current_window_handle方法 用于获取当前窗口的句柄。句柄是一个标识符,用于唯一标识一个窗口。示例代码: from selenium import webdriverdriver webdriver.Chrome() driver.get("…...

LFD STM32编程规范20241111

1. 源文件和头文件放同一目录bsp文件夹顺序文件注释防重复设置#include#defineenum类型声明、定义 包括struct union typedef全局变量声明文件级变量声明全局或文件级函数声明函数实现。按函数声明顺序文件尾注释。/**************END FILE**************/引用头文件不用绝对路…...

Python学习------第八天

函数 函数的传入参数 掌握函数返回值的作用 掌握函数返回值的定义语法 函数的嵌套调用: 函数的局部变量和全局变量 局部变量的作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。 money 5000000 n…...

【扩散——BFS】

题目 代码 #include <bits/stdc.h> using namespace std; const int t 2020, off 2020; #define x first #define y second typedef pair<int, int> PII; int dx[] {0, 0, 1, -1}, dy[] {-1, 1, 0, 0}; int dist[6080][6080]; // 0映射到2020&#xff0c;2020…...

C++ 编程基础(5)类与对象 | 5.5、多态

文章目录 一、多态1、概念2、多态实现方式3、动态绑定与静态绑定4、虚函数4.1、声明与定义4.2、虚函数的工作原理4.3、虚函数的优点与注意事项 5、不能声明为虚函数的函数6、纯虚函数7、抽象类8、总结 前言&#xff1a; 在C编程语言中&#xff0c;多态性&#xff08;Polymorphi…...

客户端发送http请求进行流量控制

客户端发送http请求进行流量控制 实现方式 1&#xff1a;使用 Semaphore (信号量) 控制流量 asyncio.Semaphore 是一种简单的流控方法&#xff0c;可以用来限制并发请求数量。 import asyncio import aiohttp import timeclass HttpClientWithSemaphore:def __init__(self, …...

STM32 低功耗模式详解

目录 一、什么是低功耗 二、低功耗的核心思想 三、STM32的3种低功耗模式 1、睡眠模式 (Sleep Mode) 2、停止模式 (Stop Mode) 3、 待机模式 (Standby Mode) 四、相关电源管理寄存器 1、PWR_CR (Power Control Register, 电源控制寄存器) 2、PWR_CSR (Power Control/St…...

我的第一个PyQt5程序

PyQt5的开发环境配置完成之后&#xff0c;开始编写第一个PyQt5的程序。 方法一&#xff1a;使用将.ui转换成.py文件的方法 import sys from FirstPyQt import Ui_MainWindow from PyQt5.QtWidgets import *#QtCore,QtGui,QtWidgets # from QtTest import Ui_MainWindow#导入Q…...

Unity调用Python

代码如下&#xff1a; if (useAI){/** 通过PaddlePaddle进行合成处理* */// 创建线程参数对象ThreadParameters parameters new ThreadParameters(){pythonPath "python", // 如果 Python 在系统路径中&#xff0c;可以直接使用 "python"pythonScript U…...

前端,location.reload刷新页面

location.reload() 是 JavaScript 中的一个方法&#xff0c;它用于重新加载当前页面。当你调用这个方法时&#xff0c;浏览器会重新加载当前页面的资源&#xff0c;就像用户点击了浏览器的刷新按钮一样。 基本用法 // 刷新当前页面 location.reload();带参数的用法 location…...

5G的发展演进

5G发展的驱动力 什么是5G [远程会议&#xff0c;2020年7月10日] 在来自世界各地的政府主管部门、电信制造及运营企业、研究机构约200多名会议代表和专家们的共同见证下&#xff0c;ITU-R WP 5D#35e远程会议宣布3GPP 5G技术&#xff08;含NB-IoT&#xff09;满足IMT-2020 5G技…...

数据库参数备份

MySQL #!/bin/bash # 获取当前日期和时间的时间戳 TIMESTAMP$(date "%Y%m%d-%H%M%S")# 0、创建目录 mkdir /tmp/parameter_$TIMESTAMP/# 1、获取所有命名空间 echo "1、获取所有命名空间" NAMESPACES$(kubectl get ns | grep qfusion- | grep -v qfusion-…...

PG数据库 数据库时间字段 开始时间和结束时间,判断和查询条件的开始和截止时间存在交集,SQL如何编写

PG 数据库时间字段 开始时间和结束时间&#xff0c;判断和查询条件的开始和截止时间存在交集&#xff0c;SQL如何编写&#xff1f; 在 PostgreSQL 中&#xff0c;如果你想要查询那些时间段&#xff08;由 开始时间 和 结束时间 定义&#xff09;与给定的时间段有交集的记录&am…...

k8s服务内容滚动升级以及常用命令介绍

查看K8S集群所有的节点信息 kubectl get nodes 删除K8S集群中某个特定节点 kubectl delete nodes/10.0.0.123 获取K8S集群命名空间 kubectl get namespace 获取K8S所有命名空间的那些部署 kubectl get deployment --all-namespaces 创建命名空间 web界面上看到的效果,但是…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...