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

【PostgreSQL数据库表膨胀的一些原因】

PostgreSQL表膨胀的原因主要有两个:一个是垃圾数据,即dead tuple行数太多未及时清理,导致不能及时提供能重用的空间,二是数据页之间存在空闲空间。

1.表的填充因子设置

表的填充因子是个很神奇的东西,因为设置太大或者太小,都可能因不同原因引起表膨胀。

  • 较低的填充因子(例如 70%)意味着每个数据页中会留出 30% 的空闲空间。这样可以减少页面因更新而频繁分裂的可能性。这通常会导致表的实际磁盘使用量增加,因为每个页面上的有效数据量较少。所以造成表的膨胀。
  • 而表的 fillfactor 设置也可能会影响 VACUUM 的效果。如果 fillfactor 设置得过高,会导致表在插入新行时未能有效利用空间,增加了死元组的存在。(默认100)。

PostgreSQL 的表默认填充因子为 100,这意味着默认情况下,PostgreSQL 会尽量将每个页面填满数据,不留空间给未来的数据更新。假设一张表的填充因子设定为 70%。这样在 PostgreSQL 插入数据到页面时,会故意留下 30% 的空间空着,以便未来对现有数据行的更新。当表的填充因子更高(接近 100%)时,每个数据页面的空余空间更少,这可能导致数据行更新时空间不足,需要重新分配页面。

postgres=# alter table t1 set (fillfactor = 70);
ALTER TABLEpostgres=# SELECTrelname AS table_name,reloptions
FROMpg_class
WHERErelname = 't1';
+------------+-----------------+
| table_name |   reloptions    |
+------------+-----------------+
| t1         | {fillfactor=70} |
+------------+-----------------+
(1 row)

2. VACUUM和VACUUM FULL本身机制

VACUUM有时候只是标记了空间为可用,但磁盘空间可能不会立即反映出来。

3. AUTOVACUUM参数不合理死元组不能及时清理

调整 autovacuum 配置参数,特别是 autovacuum_vacuum_scale_factor 和 autovacuum_vacuum_threshold。例如,降低 autovacuum_vacuum_scale_factor 的值,可以让 autovacuum 更频繁地运行。

4.一些原因导致vacuum后没清理死元组

主要有如下几种方式

  1. 失效复制槽
  2. 长事务导致
  3. 存在未提交的prepare事务
  4. idle in transaction状态的事务
  5. 函数等内部结构涉及到表的访问
  6. hot_standby_feedback参数问题
  7. 索引状态问题
  8. 表和索引的并发访问

可以参考这篇文章:​https://blog.csdn.net/weixin_47308871/article/details/142226606?spm=1001.2014.3001.5502​

5.表的统计信息问题

如果表的统计信息有问题,可能会影响 VACUUM 的效果。

6.maintenance_work_mem参数设置太小死元组不能及时清理

maintenance_work_mem 设置得太低可能会限制 VACUUM 的效率,因为VACUUM过程需要在maintenance_work_mem里缓存dead tuple的tupleid,如果太小则可能分多次清理,每次在maintenance_work_mem缓存满之后就会触发一次清理,除非之外还可能涉及到多次扫描索引的问题。正常情况下,每满一次,就会重新扫描一遍所有的索引。

v11-v13引入的一个GUC参数vacuum_cleanup_index_scale_factor,但是在v14取消了,对于大量insert,没有update、delete操作的表的vacuum,或者常规静态表的vacuum会快很多,因为不需要scan index了。

而v12版本也在表级别增加了vacuum_index_cleanup参数,可以在创建表的时候设置,也可以alter table设置。参数可以控制VACUUM在是否禁用索引清理的情况下运行,默认值为true。v12版本的VACUUM引入了一个新的选项INDEX_CLEANUP,可以跳过索引的垃圾回收。

除此之外PostgreSQL-17版本之前,maintenance_work_mem虽然可以设置很大,但是对于vacuum本身的使用,有一个1GB的最大值限制,也就是不管你设置的多大,最多一个vacuum能用到的最多也就1GB。这个在PostgreSQL数据库的文档里也有相应的记录。从PostgreSQL-17版本取消了这个限制。

tupleid为6字节长度。1GiB可存储1.7亿条左右dead tuple的tupleid。默认垃圾记录约等于表大小的20%时触发垃圾回收, 8.9亿条记录的表20%的垃圾即1.7亿条dead tuple,因此超过8.9亿, 该表的垃圾回收就可能要多次扫描index了。所以以这个方向来看的话,PostgreSQL单表不建议超过8.9亿条记录。

7.磁盘性能问题导致死元组不能及时清理

磁盘 I/O 性能问题或数据文件系统的配置也可能影响 VACUUM 的效果,如果磁盘性能不好,可能VACUUM的效率比较低,死元组不能及时清理。可以使用fio、iostat 或 vmstat来检查磁盘IO情况。

8.PostgreSQL 的事务 ID (XID) Wraparound

PostgreSQL 使用事务 ID (XID) 来追踪事务。长时间运行的事务或频繁的事务生成可能导致 XID Wraparound 问题,这会影响 VACUUM 的效果。如果 XID 接近其最大值,数据库会进行 VACUUM 来防止 XID Wraparound,但这个过程可能不会完全清理死元组。

9.表的特定数据类型影响VACUUM

某些数据类型(例如数组类型或自定义数据类型)可能会影响 VACUUM 的行为,尤其是在处理复杂的数据结构时。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 系统架构师考试学习笔记第五篇——架构设计补充知识(26)论文写作
  • 响应式网站真的就只是多了一个媒体查询吗?
  • 数仓建设:为什么我们的数据容易被业务方质疑?
  • 关于codesys循环结束,循环内累加值仍不停止累加问题
  • 002集—— CAD划线并模拟向命令窗口发送命令(CAD—C#二次开发入门)
  • 绿荫德清,数聚聚宝汇智—聚宝用户夏日交流会圆满落幕
  • linux 操作系统下cu命令介绍和使用案例
  • PHP悦读随行一键借阅图书小程序
  • 计算机网络:概述 - 性能指标
  • 深度学习经典模型之T5
  • matlab处理函数3
  • C++库std::clamp
  • Docker容器创建时,无法访问镜像源:Could not connect to archive.ubuntu.com:80
  • 【项目】高并发内存池
  • Rust 数据类型
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • canvas 高仿 Apple Watch 表盘
  • Electron入门介绍
  • IDEA常用插件整理
  • Java超时控制的实现
  • java多线程
  • JS题目及答案整理
  • React-Native - 收藏集 - 掘金
  • Twitter赢在开放,三年创造奇迹
  • vue中实现单选
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 前端面试之CSS3新特性
  • 深度学习在携程攻略社区的应用
  • 想写好前端,先练好内功
  • 一些关于Rust在2019年的思考
  • ‌U盘闪一下就没了?‌如何有效恢复数据
  • !!java web学习笔记(一到五)
  • #define与typedef区别
  • (007)XHTML文档之标题——h1~h6
  • (16)Reactor的测试——响应式Spring的道法术器
  • (3)llvm ir转换过程
  • (4)(4.6) Triducer
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (二)十分简易快速 自己训练样本 opencv级联lbp分类器 车牌识别
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (算法)求1到1亿间的质数或素数
  • (图文详解)小程序AppID申请以及在Hbuilderx中运行
  • (转)原始图像数据和PDF中的图像数据
  • ./和../以及/和~之间的区别
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET Core 项目指定SDK版本
  • .Net CoreRabbitMQ消息存储可靠机制