PostgreSQL(二十二)缓冲区管理器

news2024/9/21 0:45:47

目录

一、缓冲区概述

1、缓冲区结构

2、buffer_tag结构

3、Backend进程读取操作

4、写脏块

二、缓冲区管理器结构

1、第一层:Buffer Table layer(缓冲区表层)

2、第二层:Buffer Descriptor Layer(缓冲区描述层)

3、第三层:buffer pool layer

4、数据的访问过程

三、缓冲区管理器锁(Buffer Manager Locks)

1、表层的锁

2、描述层的锁

3、spin lock--自旋锁/旋转锁

四、缓冲区管理器的工作原理

1、情况1:访问已存放在缓冲区中的数据块

2、情况2:加载数据块到空的缓冲池插槽

3、情况3:加载数据块到一个需要释放的缓冲池插槽

4、缓冲区块替换机制

五、环形缓冲区(Ring Buffer)

1、Bulk-reading

2、Bulk-writing

3、Vacuum-processing

六、共享池缓冲区参数设置

1、shared_buffers参数设置

2、wal_buffers 参数设置

3、effective_cache_size参数设置


一、缓冲区概述

1、缓冲区结构

缓冲区:存放各种类型的数据块

(1)数据文件页、表和索引块

(2)可用空间地图块(fsm)

(3)可见性地图块(_vm)

(4)缓冲区数组索引--buffer_ids

2、buffer_tag结构

(1)RelFileNode:分别为表对象oid、数据块oid、表空间oid

(2)页面的fork number(分别为0、1、2)(0=表和索引块,1=fsm,2=vm)

(3)页面number(页面属于哪个块)

示例:缓冲区标记:{(16821、16384、37721)、0、7}

(1)7=标识第7个块中的页

(2)0=fork号,0表明这是存放表数据的数据块

(3)37721=对象号(关系号,OID),表明是属于哪个对象的

(4)16384=数据库OID,说明该块的内容属于OID为16384的数据库

(5)16821=表空间OID,说明该块的内容属于OID 16821的表空间。

3、Backend进程读取操作

后台进程读取数据块到缓冲区的流程(图解)

4、写脏块

下面进程工作时会导致脏块写(将脏页刷新到存储区):

(1)checkpointer(检查点进程):

--将从上一个检查点以来到当前检查点为止,产生的脏块,全都写入磁盘。

--检査点进程将检査点记录写入WAL段文件,并在检查点启动时刷新脏页。

--ckpt的写是一个I/O密集型的写。

(2)background writer(后台写进程)

--后台写进程bgwr持续一点一点地刷新脏页,对数据库活动的影响最小。

--后台写进程的作用是可以减少检查点密集写的影响。

--后台写进程每200毫秒唤醒一次(由bgwriter_delay定义),最多刷新100页(由bgwriter_Iru_maxpages定义)(默认情况下)。

tip:类比oracle的bgwr和ckpt进程,不同的是:

在oracle中,ckpt会给bgwr一个写的信号,由bgwr完成全部的脏块写动作。

在PG中,检査点与后台写进程分离。pg的ckpt自己也会执行脏块写的动作,与bgwr一起写。

相比之下,PG后台写进程独立的方式可以减少ckpt在写时的I/O密集程度。

二、缓冲区管理器结构

Buffer manager’s three-layer structure--缓冲区管理器的三层结构(图解)

1、第一层:Buffer Table layer(缓冲区表层)

在这一层内置的hash函数将buffer_tags映射到插槽,插槽中记录了buffer_tags和描述层的buffer_id的映射关系。

2、第二层:Buffer Descriptor Layer(缓冲区描述层)

本层描述内容包含:buffer_tag与缓冲池插槽id的映射关系,访问次数统计,锁等信息

(1)tag:数据块的tag

(2)buffer_id:缓冲池ID

(3)refcount:记录块被访问的次数。

(4)usage_count:使用的次数,与refcount相关。两者配合使用。

(5)countext_lock and io_in_progress_lock:锁信息。访问内存缓冲区时,需要进行加锁保护。

(6)flags:内存块的标记

       --dirty bit:脏块

       --valid bit:有效块(脏块的内容被写到磁盘后,原本的脏块就变为有效块)

       --io_in_progress bit:正在写/处理的块

(7)freeNext

3、第三层:buffer pool layer

缓冲池是存储数据文件页(如表、索引)的简单数组。缓冲池数组的索引称为buffer_ids;

缓冲池被分割成大小为8k的插槽,等于页面大小。因此,每个槽可以存储整个页面。

4、数据的访问过程

第一次访问一个数据块(在缓冲区全为空时),缓冲区管理器是怎么做的:

(1)先请求一个缓冲区空间,再buffer table 层把描述层的buffer_id把buffer_tag进行映射;

(2)然后在描述层把buffer_tag与缓冲区id进行映射;

(3)最后把数据块读到相应的缓冲区槽。

访问数据块时,要怎么做:

(1)先通过buffer table层,获取A块的插槽id=0

(2)通过ID=0定位到Buffer Descriptor层,找到对应的插槽,在插槽中获得对应的buffer_id

(3)将获取的buffer_id告诉后端进程,然后后端进程根据这个buffer_id来直接访问缓冲区

三、缓冲区管理器锁(Buffer Manager Locks)

缓冲区管理器为许多不同的目的使用许多锁;

锁是缓冲区管理器同步机制的一部分,它们与任何SQL语句和SQL选项都不相关。

1、表层的锁

BufMappingLock保护整个缓冲表的数据完整性。它是一个轻量锁,可以在共亨和独占模式下使用。

在缓冲区表中搜索条目时,后端进程保存共亨的BufMappingLock。当插入或删除条目时,后端进程持有独占锁。

2、描述层的锁

每个缓冲区描述符使用两个轻量级锁

(1)content_lock:内容锁。典型的强制访问限制的锁。它可以用于共享和独占模式。

       当执行下列操作之一时,将获取独占内容锁:

              --dml操作

              --物理删除元组或压缩存储页上的可用空间(Vacuum操作和HOT处理)

              --冻结存储页中的元组

(2)io_in_progress_lock:用于等待缓冲区上的I/O完成(对数据块进行操作时)。

当pg进程从存储区加载/写入页面数据时,该进程在访问存储器时持有相应描述符的独占io_in_progress锁。

3、spin lock--自旋锁/旋转锁

如何固定缓冲区描述符:

(1)获取缓冲区描述符的自旋锁

(2)将其refcount和usage_count的值增加1

(3)松开旋转锁

如何将脏位设置为“1”:

(1)获取缓冲区描述符的自旋锁

(2)使用按位操作将脏位设置为“1”

(3)松开旋转锁

四、缓冲区管理器的工作原理

1、情况1:访问已存放在缓冲区中的数据块

(1)后端进程访问表层相关插槽;

(2)获取共享模式的BufMapping锁;

(3)通过表层获得对应描述层的插槽ID(id=2);

(4)在描述层通过获得的插槽id,获取缓冲区的buffer id;

(5)释放锁;

(6)后端进程依据获得的buffer id,直接访问缓冲池的内容,获得数据。

2、情况2:加载数据块到空的缓冲池插槽

(1)后台进程没有在缓冲区中发现这个数据块;

(2)从描述层中分配一个可用的插槽,返回插槽id

(3)获取独家模式的BufMapping锁;

(4)在表层绑定tag与id信息;

(5)将磁盘中的数据块内容读取到缓冲池;

(6)释放锁;

(7)后台进程利用从描述层获取的buffer id,直接访问缓冲区内容。

3、情况3:加载数据块到一个需要释放的缓冲池插槽

核心:先释放、再加载

(1)后台进程发现目标数据不在缓冲池中。

(2)在描述层寻找可用的插槽,发现目前插槽已满。

然后根据替换机制规则,判断出F是一个可以老化出去的块。然后将这个块的空间释放,用于存储现在需要查询的数据块。

(3)目前这个内存块存储的还是原本Tag_F映射的buffer id对应的磁盘内容;

(4)获取旧的独家模式的BufMapping锁;

(5)获取新的独家模式的BufMapping锁,并在表层插入一条新的条目。此时在表层就会有两个记录的tag同时指向了同一个描述层id(接下来的步骤需要给旧的删除);

(6)删除旧条目,释放旧的独家模式的BufMapping锁(删除后,映射关系失效);

(7)将当前需要查询的数据,从磁盘中读取到缓冲区中;

(8)释放之前获取的新的独家模式的BufMapping锁;

(9)后台进程根据获取的buffer id直接访问缓冲区读取数据。

4、缓冲区块替换机制

替换页面算法

8.1以前:LRU算法

        最近最少使用原则:热度高的表放到LRU的列表头部,热度低了就被放到列表末尾,老化放在末尾的表。

8.1及以后:时钟扫描算法

       缓冲区描述符显示为蓝色或青色框,框中的数字显示每个描述符的使用计数,每扫描一次则-1,缓冲区每被访问过一次则+1

当时钟扫描到refcount=0时,此块将会被老化。否则重复循环扫描,直到扫到0为止

五、环形缓冲区(Ring Buffer)

        当业务需要一个大块的缓冲池时,假如扫描了超过四分之一缓冲池空间(共享缓冲区/4)时,还没有找到足够的可用缓冲池,则会新分配一个环形缓冲区。这个新分配的环形缓冲池就被称为ring-buffer。

        这种情况一般会出现在大数据块操作时,例如:bulk-reading(大量加载)、bulk-writing(大量写)、vacuum-processing(空间整理).

        优点:不会因为某个特殊的大业务动作,来影响已经使用的数据缓冲区,起到一个保护作用,提高缓冲区重复利用率,降低磁盘I/O。

1、Bulk-reading

当大量加载业务需要大块的缓冲池切扫描了超过四分之一缓冲池还没找到,则会分配一个256KB的ring-buffer。

2、Bulk-writing

当大量写业务出现这种情况,会分配一个16MB的ring-buffer。

执行下面列出的sql命令时,会触发大量写业务:

       (1)COPY FROM command.

       (2)CREATE TABLE AS command.

       (3)CREATE MATERIALIZED VIEW    or    REFERSH MATERIALIZED VIEW command.

       (4)ALTER TABLE command.

3、Vacuum-processing

当自动真空机进行真空处理时出现这种情况,会分配一个256KB的ring-buffer。

六、共享池缓冲区参数设置

1、shared_buffers参数设置

show shared_buffers;
Alter system set shared_buffers=256M;

2、wal_buffers 参数设置

show wal_buffers;
Alter system set wal_buffers =4M

3、effective_cache_size参数设置

show effective_cache_size;

这个参数提供可用于磁盘高速缓存的内存量的估计值。它只是一个建议值,而不是确切分配的内存或缓存大小。它不会实际分配内存,而是会告知优化器内核中可用的缓存量。

这个值会影响执行SQL时是选择全表扫描还是优化器的决策。在一个索引的代价估计中,更高的数值会使得索引扫描更可能被使用,更低的数值会使得顺序扫描(全表扫描)更可能被使用。

在设置这个参数时,还应该考虑 Postgresql的共享缓冲区以及将被用于 Postgresql数据文件的内核磁盘缓冲区。

默认值是4GB。不建议修改,除非对于这个参数的理解以及数据库业务场景非常了解、笃定修改后会提高性能(大佬可以玩,菜鸡不要动)。

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

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

相关文章

Vue2-动画

1.transition过渡 | 用transition CSS做动画 Vue-transition文档:进入/离开 & 列表过渡 — Vue.js [用transition做CSS动画]Enter状态:JS Bin - Collaborative JavaScript Debugging Leave状态:JS Bin - Collaborative JavaScript Debug…

经验分享:征信查询多了会不会影响大数据综合评分?

很多人在申请贷款的时候,会有一个疑问,就是自己的征信没逾期,就是查询偏多一点,但能达到申贷要求,为什么还会被拒贷?其实就是大数据花了的原因,那征信查询多了会不会影响大数据综合评分呢?接下来本文就为…

【C++】继承最全解析(什么是继承?继承有什么用?)

目录 一、前言 二、什么是继承 ? 💢继承的概念💢 💢继承的定义💢 🥝定义格式 🍇继承权限 三、基类与派生类对象的赋值转换 四、继承的作用域 五、派生类中的默认成员函数 &#x1f4a2…

[leetcode]minimum-cost-to-reach-destination-in-time 规定时间内到达终点的最小费用

. - 力扣&#xff08;LeetCode&#xff09; class Solution { private:// 极大值static constexpr int INFTY INT_MAX / 2;public:int minCost(int maxTime, vector<vector<int>>& edges, vector<int>& passingFees) {int n passingFees.size();ve…

windows节点加入一个Linux集群组成的kubernetes集群

windows节点加入一个Linux集群组成的kubernetes集群 背景描述一.准备环境搭建二.Windows上docker安装三.配置Windows server2019方法一&#xff1a;自动配置安装方法二&#xff1a;手动配置安装失败处理过程 四.Windows的node加入Linux的kubernetes集群五.配置Linux的master 背…

在linux中查找 / 目录下的以.jar结尾的文件(find / -name *.jar)

文章目录 1、查找 / 目录下的以.jar结尾的文件 1、查找 / 目录下的以.jar结尾的文件 [rootiZuf6332h890vozldoxcprZ ~]# find / -name *.jar /etc/java/java-1.8.0-openjdk/java-1.8.0-openjdk-1.8.0.342.b07-1.el9_0.x86_64/lib/security/policy/limited/US_export_policy.ja…

初学SpringMVC之过滤器解决乱码

写个 login.jsp 页面 提交的 method 一般为 post&#xff08;写 get 不安全&#xff0c;地址栏上会显示&#xff09; action 表示提交后跳转的地址 &#xff08;不直接写控制器里的路径是因为配置 Tomcat 时设置了前缀路径&#xff0c;默认走 http://localhost:8080&#xf…

Linux ---gcc

c语言的链接类型&#xff1a; 动态链接&#xff1a; ll /lib64/libc-2.17.so 静态链接&#xff1a; ll /lib64/libc.a glibc-static安装-CSDN博客https://blog.csdn.net/itas109/article/details/104226783在Linux中下载c语言的静态库。 gcc test.c -o test.s -static 以…

代码随想录二刷7.22|977.有序数组的平方

暴力解法&#xff1a; ——如果想暴力解决这个问题的话&#xff0c;可以像题目那样&#xff0c;先将每一个元素平方&#xff0c;然后再排序 双指针&#xff1a; ——从题目中找到的信息&#xff1a;这是一个非递减顺序的整数数组&#xff0c;从例子中&#xff0c;可以容易看…

搭建NEMU与QEMU的DiffTest环境(Socket方式)

搭建NEMU与QEMU的DiffTest环境&#xff08;Socket方式&#xff09; 1 简述2 编译NEMU2.1 配置2.2 修改NEMU/scripts/build.mk2.3 修改isa_difftest_checkregs函数2.4 修改isa_pmp_check_permission函数2.5 编译 3 编译qemu-socket-difftest3.1 修改NEMU/scripts/isa.mk3.2 修改…

数据结构之单链表在不带标准头的情况下C,C#,C++分别怎么实现?

文章目录 单链表的概念单链表的操作单链表不带标准头结点示例C语言实现C#实现C实现 数据结构是计算机科学中非常重要的一部分&#xff0c;它帮助我们理解和操作数据。单链表是数据结构中的一种基本类型&#xff0c;它由一系列节点组成&#xff0c;每个节点包含数据域和指向列表…

强化学习编程实践-4-基于蒙特卡洛的方法

第3章给出了学习算法的基本思路&#xff1a;策略评估和策略改善。其中策略评估用到了以下的公式&#xff08;4.1&#xff09;&#xff1a; 策略改善则用了最简单的贪婪策略&#xff08;4.2&#xff09;&#xff1a; 为什么要用蒙特卡洛算法&#xff1f;先看公式4.1和4.2&#x…

图鸟UI框架在uni-app多端应用开发中的实践与应用

摘要&#xff1a; 随着移动互联网的蓬勃发展&#xff0c;跨平台应用开发已成为行业趋势。本文将探讨图鸟UI框架如何在uni-app开发环境下助力开发者高效构建多端应用&#xff0c;并通过具体案例展示其在实际项目中的应用效果。 一、引言 在移动应用开发领域&#xff0c;跨平台…

【错题集-编程题】栈和排序(栈 + 贪心)

牛客对于题目连接&#xff1a;栈和排序_牛客题霸_牛客网 (nowcoder.com) 一、分析题目 每次尽可能的先让当前需要的最大值弹出去。 二、代码 // 修改后的代码 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方…

百度文心4.0 Turbo开放,领跑国内AI大模型赛道!

百度文心4.0 Turbo开放&#xff0c;领跑国内AI大模型赛道&#xff01; 前言 文心一言大模型 就在7月5日&#xff0c;在2024世界人工智能大会 (WAIC) 上&#xff0c;百度副总裁谢广军宣布文心大模型4.0 Turbo正式向企业客户全面开放&#xff01;这一举动直接引发了业界的关注。那…

uniapp微信小程序 TypeError: $refs[ref].push is not a function

我的写法 this.$refs.addPopup.open();报错 打印出来是这样的 解决 参考未整理 原因 在当前页面使用的v-for循环 并且循环体内也有组件使用了ref&#xff08;而我没有把每个ref做区别命名&#xff09; 这样就导致了我有很多同名的ref&#xff0c;然后就报错了 解决办法&a…

上海-三轮摩托车—D证科目四 错题记录

目录 1.安全驾驶题 2.道路图标题 3.天气类情景题 4.事故处理类题 上海-三轮摩托车—D证科目一 错题记录: 1.安全驾驶题

阐述 C 语言中的浮点数精度问题?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; &#x1f4d9;C 语言百万年薪修炼课程 【https://dwz.mosong.cc/cyyjc】通俗易懂&#xff0c;深入浅出&#xff0c;匠心打磨&#xff0c;死磕细节&#xff0c;6年迭代&…

tableau回归分析与时间序列分析 - 17

回归分析与时间序列分析 1. 回归分析1.1 线性回归绘制1.1.1 导入数据1.1.2 基本绘制1.1.3 趋势线显示-方法一1.1.4 趋势线显示-方法二1.1.5 趋势线显示-方法三1.1.6 添加区域注释 1.2 指数回归绘制1.2.1 创建字段1.2.2 异常区分1.2.3 创建参数1.2.4 异常区分字段修改1.2.5 显示…

MySQL学习笔记 下

MySQL学习笔记&#xff08;需接上篇&#xff09; 1. 通配符 用于替换字符串中的一个或多个字符&#xff1b;通配符常与LIKE关键字一起使用&#xff0c;用于搜索字段中的指定模式&#xff1b; 2. 别名 用于为表或表中的列提供临时名称&#xff1b; 别名用于为表或表中的字段…