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

Postgresql源码(132)分布式行锁的原理分析

相关
《Postgresql源码(131)行锁的原理分析》

1 分布式行锁

PG中的行锁在上一片中做了分析《Postgresql源码(131)行锁的原理分析》,本篇对分布式PG(PGXL)中的行锁做一些分析。(版本:Postgres-XL 10alpha2)

2 计划生成pgxc_planner

分布式PG中的计划生成有两个入口:

pgxc_plannerresult = pgxc_FQS_planner(query, cursorOptions, boundParams);if (result) return result;result = standard_planner(query, cursorOptions, boundParams);return result;
  • pgxc_FQS_planner(Fast Query Shipping planner)尝试确定一个查询是否可以完全在DN上执行,不需要CN节点参与计算。FQS计划比较简单,直接把SQL发到某几个DN上跑。
  • standard_planner是标准查询规划器。

查询首先通过pgxc_FQS_planner看是否适合快速分发。如果不适合,会继续走standard_planner。

2.1 pgxc_FQS_planner生成FQS计划

XL默认对行锁的SQL不能走FQS,这里为了简单介绍下FQS用了一个点查的例子。

用例

drop table TBL_33;
create table TBL_33(c3 int);
insert into TBL_33 values(0);
SELECT c3 FROM TBL_33 WHERE c3=0;;

分布式执行计划

explain SELECT c3 FROM TBL_33 WHERE c3=0;QUERY PLAN
---------------------------------------------------------------Remote Fast Query Execution  (cost=0.00..0.00 rows=0 width=0)Node/s: datanode_2->  Seq Scan on tbl_33  (cost=0.00..41.88 rows=13 width=4)Filter: (c3 = 0)

pgxc_FQS_planner

static PlannedStmt *
pgxc_FQS_planner(Query *query, int cursorOptions, ParamListInfo boundParams)
{
  • 用规则过滤一些不能FQS的情况:
	if (!enable_fast_query_shipping)return NULL;if (cursorOptions & CURSOR_OPT_SCROLL)return NULL;if (query->utilityStmt && IsA(query->utilityStmt, RemoteQuery)){RemoteQuery *stmt = (RemoteQuery *) query->utilityStmt;if (stmt->exec_direct_type != EXEC_DIRECT_NONE)return NULL;}
  • 遍历查询树,用一些规则排除不能FQS的情况。
  • pgxc_shippability_walker函数在遍历的同时,会维护一个bitmap(sc_context.sc_shippability),里面记录了不能ship的各种原因,最后在pgxc_is_query_shippable函数中检测bitmap确认是否能ship。
  • exec_nodes中记录的最重要的信息就是需要在哪个节点上执行,由pgxc_FQS_find_datanodes函数计算出来。
  • 计算逻辑:
    在这里插入图片描述
	exec_nodes = pgxc_is_query_shippable(query, 0);if (exec_nodes == NULL)return NULL;glob = makeNode(PlannerGlobal);glob->boundParams = boundParams;root = makeNode(PlannerInfo);root->parse = query;root->glob = glob;root->query_level = 1;root->planner_cxt = CurrentMemoryContext;top_plan = (Plan *)pgxc_FQS_create_remote_plan(query, exec_nodes, false);top_plan = set_plan_references(root, top_plan);result = makeNode(PlannedStmt);result->commandType = query->commandType;result->canSetTag = query->canSetTag;result->utilityStmt = query->utilityStmt;if (query->commandType != CMD_SELECT)result->resultRelations = list_make1_int(query->resultRelation);result->planTree = top_plan;result->rtable = query->rtable;result->queryId = query->queryId;result->relationOids = glob->relationOids;result->invalItems = glob->invalItems;return result;
}

在这里插入图片描述

  • FQS的计划会比较简单,基本就是把SQL用deparse_query出来,然后拼到计划节点中,找到发到哪些节点执行即可。

2.2 standard_planner生成remote计划

回到行锁用例上:

drop table TBL_33;
create table TBL_33(c33 int);
insert into TBL_33 values(0);SELECT c33 FROM TBL_33 WHERE c33=0 for update;

分布式执行计划

explain SELECT c33 FROM TBL_33 WHERE c33=0 for update;QUERY PLAN
-------------------------------------------------------------------------------Remote Subquery Scan on all (datanode_2)  (cost=0.00..42.01 rows=13 width=10)->  LockRows  (cost=0.00..42.01 rows=13 width=10)->  Seq Scan on tbl_33  (cost=0.00..41.88 rows=13 width=10)Filter: (c33 = 0)

2.2.1 subquery_planner→grouping_planner生成local计划

subquery_planner生成计划:
在这里插入图片描述

2.2.2 make_remotesubplan为计划添加remote算子

standard_planner → make_remotesubplan

standard_planner...best_path = get_cheapest_fractional_path(final_rel, tuple_fraction);if (!root->distribution)root->distribution = best_path->distribution;top_plan = create_plan(root, best_path);if (root->distribution)top_plan = (Plan *) make_remotesubplan(root, top_plan, NULL, root->distribution, root->sort_pathkeys);

在这里插入图片描述

2.2.3 path的distribution信息从哪来?

explain SELECT c33 FROM TBL_33 WHERE c33=0 for update;QUERY PLAN
-------------------------------------------------------------------------------Remote Subquery Scan on all (datanode_2)  (cost=0.00..42.01 rows=13 width=10)->  LockRows  (cost=0.00..42.01 rows=13 width=10)->  Seq Scan on tbl_33  (cost=0.00..41.88 rows=13 width=10)Filter: (c33 = 0)

SELECT c33 FROM TBL_33 WHERE c33=0 for update;执行时会生成两个算子:

  • create_seqscan_path
  • create_lockrows_path
create_seqscan_path
Path *
create_seqscan_path(PlannerInfo *root, RelOptInfo *rel,Relids required_outer, int parallel_workers)
{Path	   *pathnode = makeNode(Path);pathnode->pathtype = T_SeqScan;pathnode->parent = rel;pathnode->pathtarget = rel->reltarget;pathnode->param_info = get_baserel_parampathinfo(root, rel,required_outer);pathnode->parallel_aware = parallel_workers > 0 ? true : false;pathnode->parallel_safe = rel->consider_parallel;pathnode->parallel_workers = parallel_workers;pathnode->pathkeys = NIL;	/* seqscan has unordered result */#ifdef XCP
  • set_scanpath_distribution会配置pathnode->distribution信息,标记计划需要发到哪个节点执行。
  • restrict_distribution会更严格的检查计划发到哪个节点。
	set_scanpath_distribution(root, rel, pathnode);if (rel->baserestrictinfo){ListCell *lc;foreach (lc, rel->baserestrictinfo){RestrictInfo *ri = (RestrictInfo *) lfirst(lc);restrict_distribution(root, ri, pathnode);}}
#endifcost_seqscan(pathnode, root, rel, pathnode->param_info);return pathnode;
}
  • 经过set_scanpath_distribution后
    • pathnode->distribution->nodes标记了dn0、dn1。
    • p/t pathnode->distribution->nodes->words[0] = 11
  • 经过restrict_distribution后
    • pathnode->distribution->nodesrestrictNodes只标记了datanode1。
    • p/t pathnode->distribution->restrictNodes->words[0] = 10
p	*pathnode->distribution
$27 = {type = T_Distribution, distributionType = 72 'H', distributionExpr = 0x135fea8, nodes = 0x1360650, restrictNodes = 0x1360898}
(gdb) p/t pathnode->distribution->nodes->words[0]
$31 = 11
(gdb) p/t pathnode->distribution->restrictNodes->words[0]
$30 = 10
create_lockrows_path
  • lockrows节点比较特殊,不需要做什么事情,执行器会在执行阶段特殊处理。
  • pathnode→distribution信息集成subplan的即可。
LockRowsPath *
create_lockrows_path(PlannerInfo *root, RelOptInfo *rel,Path *subpath, List *rowMarks, int epqParam)
{LockRowsPath *pathnode = makeNode(LockRowsPath);pathnode->path.pathtype = T_LockRows;......	pathnode->path.distribution = copyObject(subpath->distribution);......return pathnode;
}

相关文章:

Postgresql源码(132)分布式行锁的原理分析

相关 《Postgresql源码(131)行锁的原理分析》 1 分布式行锁 PG中的行锁在上一片中做了分析《Postgresql源码(131)行锁的原理分析》,本篇对分布式PG(PGXL)中的行锁做一些分析。(版本…...

前端 防抖和节流

在前端开发中,防抖(Debounce)和节流(Throttle)是两种常用的性能优化技术,尤其在处理频繁触发的事件时显得尤为重要。无论是在用户输入、窗口调整大小,还是滚动事件中,这两种技术都可…...

C语言 | Leetcode C语言题解之第109题有序链表转换二叉搜索树

题目: 题解: int getLength(struct ListNode* head) {int ret 0;while (head ! NULL) {ret, head head->next;}return ret; }struct TreeNode* buildTree(struct ListNode** head, int left, int right) {if (left > right) {return NULL;}int …...

【DevOps】Linux 下安装配置 Apache 服务器:打造你的专属 Web 平台

目录 一、准备工作 二、安装 Apache 三、启动和管理 Apache 四、验证安装 五、配置 Apache 5.1 修改网站根目录 5.2 配置虚拟主机 5.2.1 创建虚拟主机配置文件 5.2.2 创建网站目录 5.2.3 启用虚拟主机 5.2.4 重启 Apache 5.3 配置 HTTPS 5.3.1 安装 SSL 证书 5.3…...

23种设计模式之一————外观模式详细介绍与讲解

外观模式详细讲解 一、概念二、 外观模式结构核心思想及解释模式的UML类图模式角色应用场景模式优点模式缺点 三、实例演示图示代码展示运行结果 一、概念 外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口&#xff0c…...

202109青少年软件编程(Python)等级考试试卷(四级)

第 1 题 【单选题】 执行如下 Python 代码后, 结果是?( ) def inverse(s,n=0): while s:n = n * 10 + s % 10s = s // 10return nprint...

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-17讲 定时器按键消抖

前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…...

【系统架构师】-论文考点整理

1、软件架构风格 1.1、概述 1、软件架构为软件系统提供了一个结构、行为和属性的高级抽象。 2、软件架构风格是特定应用领域的惯用模式,架构定义一个词汇表和一组约束。 1.2、作用 1、软件架构是项目干系人进行交流的手段。 2、软件架构是可传递和可复用的模型&…...

Android Activity 设计详解

文章目录 Android Activity 设计说明1. Activity 的生命周期2. Activity 的启动模式3. Activity 的通信4. Activity 的布局和视图管理5. Activity 的配置变化处理6. Activity 的保存和恢复状态7. Activity 的任务和返回栈 总结 Android Activity 设计说明 在 Android 中&#…...

国家开放大学,javaScript程序设计-形考任务-实训五:设计登录和注册页|实训六:设计简单的购物车

实训五:设计登录和注册页 1. 题目 设计登录和注册页。 2. 目的 (1)掌握表单域的引用方法。 (2)掌握常用控件的基本方法。 (3)掌握事件的处理方法。 (4)理解Cookie…...

微服务可用性之隔离

摘要 ​ 本文主要微服务场景下服务的可用性保障之隔离。隔离又分为几种情况,动静隔离、读写隔离、热点隔离、资源隔离等场景。 为什么要隔离 ​ 本质上是对资源进行分割确保在出现故障的时候服务只是部分不可用,不至于系统陷入整体性瘫痪,…...

设计模式——概述

1.设计模式定义 ​ 设计模式是软件设计中常见问题的典型解决方案,可用于解决代码中反复出现的设计问题。设计模式的出现可以让我们站在前人的肩膀上,通过一些成熟的设计方案来指导新项目的开发和设计,以便于我们开发出具有更好的灵活性和可扩展性&#…...

#P0564. 数组元素查找升级版

问题描述 给你 n 个数,再给你一个数 k,查找 k 在这 n 个数中第一次出现的位置(从 0 开始计数),不存在输出 No。 输入 多组测试数据,对于每组测试数据: 第一行输入一个整数 n (1 ≤ n ≤ 100…...

如何修改WordPress网站的域名

我的网站用的是Hostease的虚拟主机,但是域名是之前在其他平台买的,而且已经快到期了,因为主机和域名在不同的平台上,管理不太方便,所以我又在Hostease重新注册了一个域名,然后把网站换成了新的域名&#xf…...

python爬虫[简易版]

python爬数据[简易版] 对于每个网站的爬的原理基本是一样的,但是具体的代码写法的区别就在于爬的数据中解析出想要的数据格式: 以爬取有道词典中的图片为例: 第一步:打开网站,分析图片的数据源来自哪里, https://dict-subsidiary.youdao.com/home/content?invalid&pre…...

128天的创意之旅:从初心到成就,我的博客创作纪念日回顾

文章目录 🚀机缘:初心的种子——回望创作之旅的启航🌈收获:成长的果实——128天创作之旅的宝贵馈赠❤️日常:创作与生活的交织👊成就:代码的艺术🚲憧憬:未来的蓝图 &…...

前端绘制流程节点数据

根据数据结构和节点的层级、子节点id&#xff0c;前端自己绘制节点位置和关联关系、指向、已完成节点等 <template><div><div>通过后端节点和层级&#xff0c;绘制出节点以及关联关系等</div><div class"container" ref"container&…...

2024年顶级算法-黑翅鸢优化算法(BKA)-详细原理(附matlab代码)

黑翅鸢是一种上半身蓝灰色&#xff0c;下半身白色的小型鸟类。它们的显著特征包括迁徙和捕食行为。它们以小型哺乳动物、爬行动物、鸟类和昆虫为食&#xff0c;具有很强的悬停能力&#xff0c;能够取得非凡的狩猎成功。受其狩猎技能和迁徙习惯的启发&#xff0c;该算法作者建立…...

Linux 内核开发 28 内核模块文件ko文件介绍

Linux 内核开发 28 内核模块文件ko文件介绍 1. ELF格式简介 内核模块文件ko文件&#xff0c;格式为elf格式&#xff0c; ELF&#xff08;Executable and Linkable Format&#xff09;可执行链接格式&#xff0c;是一种用于存储可执行程序、目标代码、共享库和内核模块的标准文件…...

DDR5—新手入门学习(一)【1-5】

目录 1、DDR背景 &#xff08;1&#xff09;SDR SDRAM时代 &#xff1a; &#xff08;2&#xff09;DDR SDRAM的创新 &#xff1a; &#xff08;3&#xff09;DDR技术的演进 &#xff1a; &#xff08;4&#xff09;需求推动&#xff1a; 2、了解内存 &#xff08;1&…...

IPD的势、道、法、术、器

目录 简介 一、势&#xff1a;为什么 IPD 是必然选择&#xff1f; 二、道&#xff1a;IPD 的底层哲学 三、法与术&#xff1a;从战略到执行的具体路径 四、器&#xff1a;让流程真正落地的工具与组织 不是每家公司都需要全套 IPD&#xff0c;但每家公司都需要 IPD 思维 简…...

第三幕 御酒掺土,江山为祭

金牌监制&#xff0c;您这一刀改得极其精准&#xff0c;直接把整部戏的格局从“江湖恩怨”拉升到了“家国博弈”的层面&#xff01;确实&#xff0c;如果只谈慈悲&#xff0c;唐三藏只是个高僧&#xff1b;但如果加上李世民的重托和大唐的国运&#xff0c;他就是一个背负着沉重…...

作业本耐用度差距巨大?深圳大明印刷厂拆解合规工艺,告别定制作业本掉页开裂通病

在校园日常教学中&#xff0c;很多学校都会遇到同一个难题&#xff1a;同一学期采购的作业本、定制作业本&#xff0c;品质差距悬殊&#xff0c;有的完好无损用到期末&#xff0c;有的短短几周就出现书脊开裂、页面脱落、边角破损、翻页卡顿等问题。不少人误以为是学生使用习惯…...

量子软件测试的挑战与优化策略

1. 量子软件测试的挑战与机遇量子计算正在从实验室走向实际应用&#xff0c;随之而来的是对可靠量子软件的需求激增。与传统软件不同&#xff0c;量子程序面临三大独特挑战&#xff1a;首先&#xff0c;量子态的叠加性和纠缠性使得测试变得异常复杂。一个n量子比特系统可以同时…...

2027考研全套资料免费分享

备战27考研最全备考资料整理完毕&#xff0c;一路走来深知备考搜集资料耗费大量时间&#xff0c;浪费不少精力。特意整理2027考研全科完整版资源&#xff0c;全部打包汇总&#xff0c;零基础考生直接拿来就能使用&#xff0c;省去四处搜集资料的烦恼。资料内含&#xff1a;&…...

Sora 2 MOV导出画质崩坏真相:HDR10元数据丢失、BT.2020色域截断、帧率标志位误写——3大隐性缺陷紧急修复方案

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Sora 2 MOV导出画质崩坏的系统性认知 Sora 2 在生成高保真视频后&#xff0c;导出为 MOV 格式时频繁出现色度抽样失真、动态范围压缩、帧间伪影加剧等现象&#xff0c;其本质并非单一环节失效&#xff…...

如何快速掌握MoveIt2:面向ROS 2开发者的工业机器人运动规划完整指南

如何快速掌握MoveIt2&#xff1a;面向ROS 2开发者的工业机器人运动规划完整指南 【免费下载链接】moveit2 :robot: MoveIt for ROS 2 项目地址: https://gitcode.com/gh_mirrors/mo/moveit2 想要为你的机器人实现智能运动规划吗&#xff1f;MoveIt2作为ROS 2生态中最强大…...

探索Windows 10上的Android世界:揭秘WSA-Windows-10项目的3个技术突破

探索Windows 10上的Android世界&#xff1a;揭秘WSA-Windows-10项目的3个技术突破 【免费下载链接】WSA-Windows-10 This is a backport of Windows Subsystem for Android to Windows 10. 项目地址: https://gitcode.com/gh_mirrors/ws/WSA-Windows-10 想象一下&#…...

claude code用户如何迁移到taotoken解决封号与token不足问题

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Claude Code 用户如何迁移到 Taotoken 解决封号与 Token 不足问题 应用场景类&#xff0c;针对 Claude Code 用户常遇封号与 Token…...

如何扩展GASShooter:添加新武器、新能力与新游戏机制的终极指南

如何扩展GASShooter&#xff1a;添加新武器、新能力与新游戏机制的终极指南 【免费下载链接】GASShooter Advanced FPS/TPS Sample Project for Unreal Engine 4s GameplayAbilitySystem plugin 项目地址: https://gitcode.com/gh_mirrors/ga/GASShooter GASShooter是Un…...