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

Postgresql内核源码分析-表数据膨胀是怎么回事

 74ac905cfa3740079f2f66a445a3d7c2.gif#pic_center

 

 

  • 专栏内容:postgresql内核源码分析
  • 个人主页:我的主页
  • 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

目录

前言

表数据膨胀的由来

什么时候产生膨胀

首先是update

还有delete

如何消除膨胀

结尾


前言

本文是基于postgresql 15的代码进行分析解读,演示是在centos8系统上进行。

在我们使用postgresql数据库时,总会产生一些数据膨胀,导致查询变慢,索引失效,为什么会有数据膨胀呢?产生后我们怎么做才能让数据库恢复正常呢?


 

表数据膨胀的由来

话说数据库的四大特性ACID,postgresql采用了一种MVCC(Multi Version Concurrency Control)机制来保证事务的原子性和隔离性。

 

那什么是MVCC呢,简单说就是利用事务号递增性来标识tuple的新旧版本,达到不同事务内看到的tuple隔离;下面我们用一个例子来看一下:

 

查看一张表的当前数据;

postgres=# select ctid,xmin,xmax,id from t1;

 ctid  | xmin | xmax | id

-------+------+------+----

 (0,1) | 1699 |    0 |  1

 (0,2) | 1700 |    0 |  2

(2 rows)

 

我们在一个事务中执行更新并回滚

postgres=*begin;

BEGIN

postgres=*# select txid_current();

 txid_current

--------------

         1702

(1 row)

postgres=*update t1 SET name='a' where id=1;

UPDATE 1

postgres=*rollback;

ROLLBACK

 

我们在插入数据

insert into t1(id) values(3);

insert into t1(id) values(4);

 

postgres=# select ctid,xmin,xmax,id from t1;

 ctid  | xmin | xmax | id

-------+------+------+----

 (0,1) | 1699 | 1702 |  1

 (0,2) | 1700 |    0 |  2

 (0,4) | 1703 |    0 |  3

 (0,5) | 1704 |    0 |  4

(4 rows)

发现ctid为(0,3)的位置被跳过了,因为有一个id=1的tuple版本占了,只是它可见性判断时被判定为不可见,所以我们看不到它,但确实是占用了一个位置。


什么时候产生膨胀

 

那些常见情况下为产生多版本数据呢?

 

  • 首先是update

我们来看一下update的演示:

我们update一条数据后,它的位置变到了最后,说明又一条旧版本;详细表的update代码解析详见我的专栏;

postgres=# update t1 SET name='a' where id=1;

UPDATE 1

postgres=# select ctid,xmin,xmax,id from t1;

 ctid  | xmin | xmax | id

-------+------+------+----

 (0,2) | 1700 |    0 |  2

 (0,4) | 1703 |    0 |  3

 (0,5) | 1704 |    0 |  4

 (0,6) | 1705 |    0 |  1

(4 rows)

 

  • 还有delete

这里不会产生多版本,但是delete后,tuple并不会从表里真正删掉,而是打了一个标记,这样做的目的其它和多版本是一致的,因为可能还有其它事务在引用。

下面我们看一下例子:

postgres=# delete from t1 where id = 1;

DELETE 1

postgres=# select ctid,xmin,xmax,id from t1;

 ctid  | xmin | xmax | id

-------+------+------+----

 (0,2) | 1700 |    0 |  2

 (0,4) | 1703 |    0 |  3

 (0,5) | 1704 |    0 |  4

(3 rows)

postgres=# insert into t1(id) values(5);

INSERT 0 1

postgres=# select ctid,xmin,xmax,id from t1;

 ctid  | xmin | xmax | id

-------+------+------+----

 (0,2) | 1700 |    0 |  2

 (0,4) | 1703 |    0 |  3

 (0,5) | 1704 |    0 |  4

 (0,7) | 1707 |    0 |  5

(4 rows)

我们delete后又insert,发现空闲(0,6)没有被利用,而是从(0,7)开始;

 

如何消除膨胀

postgresql在运行过程中,采用了两种方式:

一是页面裁剪;

二是autovacuum;

那它们是如何做的呢?请看本专栏内容。

 


结尾

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

 

相关文章:

Postgresql内核源码分析-表数据膨胀是怎么回事

专栏内容:postgresql内核源码分析个人主页:我的主页座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 目录 前言 表数据膨胀的由来 什么时候产生膨胀 首先是update 还有delete 如何消…...

github使用SSH进行克隆仓库

SSH 密钥拉取git 查询密钥是否存在 s -al ~/.ssh这个文件夹下 known_hosts 就是存在的密钥文件 创建密钥文件 ssh-keygen -t rsa -b 4096 -C "testtt.com"-t rsa 是 rsa 算法加密 -b 是指定密钥的长度(以位为单位)。 -C 是用于给密钥添加注…...

【Linux系统】 Linux内核与UNIX设计哲学的结合

Linux 内核虽然不是 UNIX 的直接衍生物,但它深受 UNIX 设计哲学的影响。Linux 的开发者,尤其是 Linus Torvalds,在设计和实现 Linux 时,借鉴了 UNIX 的核心思想,使 Linux 成为一个类 UNIX 系统。 以下从 UNIX 设计哲学…...

以太网PHY_RGMII通信(基于RTL8211)--FPGA学习笔记22

一、以太网基础知识 FPGA千兆网口数据传输MDIO接口——FPGA学习笔记3_yt8531sh原理图-CSDN博客 二、通信协议 1、MDIO协议格式 (1)Pre:前导码32bit全是1,同步通信 32bit (2)ST:开始字段 01 表示开始通信 2bit…...

PowerShell 脚本实战:解决 GitLab 仓库文件批量重命名难题

使用PowerShell脚本解决文件重命名问题:一次实践经验分享 在软件开发过程中,我们经常会遇到需要批量处理文件的情况。最近,我在一个项目中就遇到了这样一个需求:将GitLab仓库中所有的.ts和.py文件的扩展名修改为原扩展名加上&quo…...

数据分析及应用:滴滴出行打车日志数据分析

目录 0 日志数据集介绍 1 构建数据仓库 1.1 ods创建用户打车订单表 1.2 创建分区 1.3 上传到对应分区...

Odoo :一款免费且开源的食品生鲜领域ERP管理系统

文 / 贝思纳斯 Odoo金牌合作伙伴 引言 提供业财人资税的精益化管理,实现研产供销的融通、食品安全的追踪与溯源,达成渠道的扁平化以及直面消费者的 D2C 等数字化解决方案,以此提升运营效率与核心竞争力,支撑高质量的变速扩张。…...

请求路径中缺少必需的路径变量[xxxId]

一、请求路径中缺少了必需的路径变量 xxxId。 这通常发生在构建API请求时,未正确设置URL中的参数。以下是解决此问题的步骤: 检查API文档:确认 xxxId是否确实是请求路径中的必需参数。 构建请求URL:确保在构建请求URL时&#xff…...

【在Linux世界中追寻伟大的One Piece】HTTP cookie

目录 1 -> 引入HTTP cookie 1.1 -> 定义 1.2 -> 工作原理 1.3 -> 分类 1.4 -> 安全性 2 -> 认识cookie 2.1 -> 基本格式 2.2 -> GMT vs UTC 3 -> cookie的生命周期 3.1 -> 安全性考虑 3.2 -> 安全测试cookie 3.2.1 -> 测试co…...

COLA学习之DDD各种术语分析(一)

小伙伴们,你们好,我是老寇,前段时间,老寇刚看完张健飞老师的两本书《代码精进之路:从码农到工匠》和《程序员的底层思维》,书中的内容让我受益匪浅,因此,我把对COLA的理解做成专栏分…...

Pygments:高效的语法高亮工具

简介:Pygments 是一个强大的 Python 库,旨在为代码和文本提供优雅的语法高亮支持。无论是 Web 开发、文档生成,还是代码审阅,Pygments 都能轻松应对多种编程语言的高亮需求。其设计简洁、功能丰富,适合需要频繁进行代码…...

算法-字符串-43.字符串相乘

一、题目 二、思路解析 1.思路: 1.双重for循环,倒序依次相乘 2.在倒序处理进位问题 3.最后返回参数的类型是string,用StringBuilder拼接,再转换为字符串 2.常用方法: 1.equals,比较对象内容是否一致 "0".eq…...

linux的vdagent框架设计

1、vdagent Linux 的 spice 客户代理由两部分组成,一个系统范围的守护进程 spice-vdagentd 和一个 X11 会话代理 spice-vdagent,每个 X11 会话有一个。spice-vdagentd 通过 Sys-V initscript 或 systemd 单元启动。 如下图:spice-vdagent&a…...

CV工程师专用键盘开源项目硬件分析

1、前言 作为一个电子发烧友,你是否有遇到过这样的问题呢。当我们去查看函数定义的时候,需要敲击鼠标右键之后选择go to definition。更高级一些,我们使用键盘的快捷键来查看定义,这时候可以想象一下,你左手按下ALT&a…...

qtcanpool 知 08:Docking

文章目录 前言口味改造后语 前言 很久以前,作者用 Qt 仿照前端 UI 设计了一个 ministack(https://gitee.com/icanpool/qtcanpool/blob/release-1.x/src/libs/qcanpool/ministack.h) 控件,这个控件可以折叠。部分用户体验后&#…...

Milvus向量数据库01-基础概念

Milvus向量数据库01-基础概念 Zilliz Cloud 集群由全托管 Milvus 实例及相关计算资源构成。您可以在 Zilliz Cloud 集群中创建 Collection,然后在 Collection 中插入 Entity。Zilliz Cloud 集群中的 Collection 类似于关系型数据库中的表。Collection 中的 Entity …...

mysql备份数据库

MySQL备份/还原 的方法 mysql备份数据库 mysql备份单个数据库 #mysql备份某个库格式: mysqldump -h主机名 -P端口 -u用户名 -p"密码" --database 数据库名 > 文件名.sql#实例:mysql备份某个库: mysqldump -h10.*.*.9 -P3306 …...

NLP与LLM的工程化实践与学习思考 - 写在开头

NLP与LLM的工程化实践与学习思考[24年半年工作总结] - 写在开头 0 开头的开头 0 开头的开头 24年因为一些工作原因,短暂在NLP领域遨游了半年。这半年对我的影响蛮大,一来是因为此前从没接触过这个方向学到新东西挺开心的,二来是在工程化实践…...

LeetCode322. 零钱兑换(2024冬季每日一题 28)

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无限的。 示…...

Unix、GNU、BSD 风格中 ps 参数的区别

注:本文为“不同风格中 ps 命令参数的区别”相关文章合辑。 未去重。 BSD 风格和 UNIX 风格中 ps 参数的区别 作者:Daniel Stori 译者:LCTT Name1e5s | 2017-06-17 10:53 One Last Question ps aux 以及 ps -elf 都是查看进程的方式&…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子&#xff08…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

小木的算法日记-多叉树的递归/层序遍历

🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...

鸿蒙(HarmonyOS5)实现跳一跳小游戏

下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...

用鸿蒙HarmonyOS5实现国际象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码,使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...

python打卡day49@浙大疏锦行

知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...