PostgreSQL表扫描方法解析

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: PostgreSQL表扫描方法解析

本文介绍PostgreSQL表扫描方法原理。

全表扫描函数在heapam_handler的接口函数为heap_getnextslot函数。该函数从磁盘上读取数据页到内存并将遍历页记录,将其存放到slot中返回。这个函数一次只获取一个记录,到达上层的ExecutePlan函数中循环调用ExecProcNode再次进入到heap_getnextslot函数获取下一个记录,依次类推,直到获得所有记录。

主要流程:

1、首先将入参TableScanDesc sscan强制转换类型到HeapScanDesc scan,后续向scan中保存扫描记录及状态

2、分两种页扫描:如果sscan->rs_flags为SO_ALLOW_PAGEMODE即扫描所有满足可见性的记录,调用函数heapgettup_pagemode;否则扫描所有记录,调用函数heapgettup

3、最后调用函数ExecStoreBufferHeapTuple将scan->rs_ctup存储到slot中。

4、这里首先说函数heapgettup_pagemode。这个函数根据三个扫描方向分别处理。只针对向前扫描说明:

 1)第一次进这个函数scan->rs_inited为false:从scan->rs_startblock页开始扫描,先调用函数heapgetpage函数获取磁盘页。这个函数得到的值保存到下面scan成员变量中:

scan->rs_cbuf:当前扫描的内存块块号

scan->rs_cblock:当前扫描的文件中页号

scan->rs_vistuples[]:保存可见记录的索引号,从1开始

scan->rs_ntuples:该页中有多少可见记录

此时就需要将scan->rs_inited置为TRUE,表示已初始化,再次进来时就不需要重复读取磁盘页了。

 2)扫描后续记录,scan->rs_cindex保存当前记录的索引号,获取下个记录只需加1

3)根据记录索引号从scan->rs_vistuples数组中取出记录索引号,然后从scan->rs_cbuf中获取具体tuple值,保存到scan->rs_ctup

4)如果根据key范围扫描,则需要比较key值,相等则返回,否则需要扫描下一个记录并进行比较。

5)如果不需要key值,则保存当前扫描记录的索引号后返回。

6)退出while循环,即当前页所有记录扫描完,获取下一页继续扫描直到所有页扫描完


heapgettup函数流程:

  1)首先取出scan->rs_ctup地址到tuple,后续记录值要保存到tuple中

2)同样分三种扫描方向:这里同样只针对向前扫描进行说明。

3)scan->rs_inited作为是否已初始化的依据,第一次进来时从scan->rs_startblock开始进行扫描,调用函数heapgetpage函数获取磁盘页。这个函数得到的值保存到下面scan成员变量中:

scan->rs_cbuf:当前扫描的内存块块号

scan->rs_cblock:当前扫描的文件中页号

scan->rs_vistuples[]:保存可见记录的索引号,从1开始[后面没有用这个]

scan->rs_ntuples:该页中有多少可见记录

从第一个记录开始扫描即lineoff=1,然后scan->rs_inited为TRUE,表示已初始化了

4)后续进来,扫描后续记录时,lineoff为当前记录的下一个索引号

5)需要对scan->rs_cbuf描述符的content_lock加BUFFER_LOCK_SHARE,后续扫描动作都在这个锁内执行

6)获取scan->rs_cbuf页内的对应记录的索引号lpp

7)该记录正常的话,获取记录值保存到tuple中;并且判断可见性,若可见则释放锁后返回;若通过key值扫描,则需比较。相等且可见时返回。

8)记录不可见或者key值不等,需要扫描下一个记录

9)while循环退出后,即该页的记录都扫描完,将scan->rs_cbuf的描述符的content_lock释放。

10)取下一页读入scan->rs_cbuf,并加锁,继续扫描这一页记录。

11)扫描完表的所有页,则for循环退出并返回

12)和heapgettup_pagemode区别是:都通过heapgetpage函数将页读到scan->rs_cbuf,并扫描其记录将可见的记录索引号保存到scan->rs_vistuples[]数组;不同在于,他后续锁内操作,遍历页内所有记录,不通过scan->rs_vistuples数组读取记录,然后再进行可见性判断及比较。MVCC情况下调用的函数是heapgettup_pagemode函数。


相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
3月前
|
人工智能
歌词结构的巧妙安排:写歌词的方法与技巧解析,妙笔生词AI智能写歌词软件
歌词创作是一门艺术,关键在于巧妙的结构安排。开头需迅速吸引听众,主体部分要坚实且富有逻辑,结尾则应留下深刻印象。《妙笔生词智能写歌词软件》提供多种 AI 功能,帮助创作者找到灵感,优化歌词结构,写出打动人心的作品。
|
3月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
69 3
|
30天前
|
安全 Ubuntu Shell
深入解析 vsftpd 2.3.4 的笑脸漏洞及其检测方法
本文详细解析了 vsftpd 2.3.4 版本中的“笑脸漏洞”,该漏洞允许攻击者通过特定用户名和密码触发后门,获取远程代码执行权限。文章提供了漏洞概述、影响范围及一个 Python 脚本,用于检测目标服务器是否受此漏洞影响。通过连接至目标服务器并尝试登录特定用户名,脚本能够判断服务器是否存在该漏洞,并给出相应的警告信息。
160 84
|
3月前
|
人工智能
写歌词的技巧和方法全解析:开启你的音乐创作之旅,妙笔生词智能写歌词软件
怀揣音乐梦想,渴望用歌词抒发情感?掌握关键技巧,你也能踏上创作之旅。灵感来自生活点滴,主题明确,语言简洁,韵律和谐。借助“妙笔生词智能写歌词软件”,AI辅助创作,轻松写出动人歌词,实现音乐梦想。
|
10天前
|
数据可视化 项目管理
个人和团队都好用的年度复盘工具:看板与KPT方法解析
本文带你了解高效方法KPT复盘法(Keep、Problem、Try),结合看板工具,帮助你理清头绪,快速完成年度复盘。
56 7
个人和团队都好用的年度复盘工具:看板与KPT方法解析
|
28天前
|
存储 Java 开发者
浅析JVM方法解析、创建和链接
上一篇文章《你知道Java类是如何被加载的吗?》分析了HotSpot是如何加载Java类的,本文再来分析下Hotspot又是如何解析、创建和链接类方法的。
|
1月前
|
负载均衡 网络协议 算法
Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式
本文探讨了Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式,以及软件负载均衡器、云服务负载均衡、容器编排工具等实现手段,强调两者结合的重要性及面临挑战的应对措施。
88 3
|
2月前
|
JSON PHP 数据格式
PHP解析配置文件的常用方法
INI文件是最常见的配置文件格式之一。
58 12
|
2月前
|
机器学习/深度学习 人工智能 安全
TPAMI:安全强化学习方法、理论与应用综述,慕工大、同济、伯克利等深度解析
【10月更文挑战第27天】强化学习(RL)在实际应用中展现出巨大潜力,但其安全性问题日益凸显。为此,安全强化学习(SRL)应运而生。近日,来自慕尼黑工业大学、同济大学和加州大学伯克利分校的研究人员在《IEEE模式分析与机器智能汇刊》上发表了一篇综述论文,系统介绍了SRL的方法、理论和应用。SRL主要面临安全性定义模糊、探索与利用平衡以及鲁棒性与可靠性等挑战。研究人员提出了基于约束、基于风险和基于监督学习等多种方法来应对这些挑战。
81 2
|
3月前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
28 1

推荐镜像

更多