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

并行执行的4种类别——《OceanBase 并行执行》系列 4

OceanBase 支持多种类型语句的并行执行。在本篇博客中,我们将根据并行执行的不同类别,分别详细阐述:并行查询、并行数据操作语言(DML)、并行数据定义语言(DDL)以及并行 LOAD DATA 。

《并行执行系列》并行执行系列的内容分为七篇博客,本篇是其中的第四篇。

并行执行概念
如何手动设置并行度
并行执行线程资源管理方式
并行执行的4种类别
并行执行参数的应用技巧
如何进行并行执行的诊断与调优 
快速上手并行执行​​​​​​​

4.1 并行查询

你可以在下面几种场景里使用并行查询:

  • select 语句,以及 select 子查询
  • DML 语句(INSERT,UPDATE,DELETE)的查询部分
  • 外表查询

并行查询的决策分为两部分: 

  1. 决定走并行查询。如果查询中使用了 PARALLEL HINT,SESSION 上开启了并行查询,或TABLE 属性指定了并行,那么将会开启并行查询。
  2. 决定并行度。并行查询中,每个 DFO 的并行度可以不一样。
    • 对于基表扫描或索引扫描 DFO,其并行度由 PARALLEL HINT、SESSION 并行属性,或TABLE 属性来决定。
    • 对于基表扫描或索引扫描 DFO,如果运行时检测到它访问的数据不足一个宏块,那么它的运行时并发度会被局部自动降低。
    • 对于 JOIN 等中间节点,其 DFO 并行度继承左孩子 DFO 的并行度。
    • 部分 DFO 不允许并行执行(如计算 ROWNUM 的节点),那么他们的并行度会被强制设为 1。

4.2 并行 DML

大部分场景下,可以使用并行 DML (Parallel DML,简称 PDML)加速数据导入、更新、删除操作。

4.2.1 DML 并行度

DML 的并行度和查询部分的并行度一致。开启并行 DML 时,查询部分总是自动开启并行。读出的数据会根据待更新表的分区位置做重分布,然后由多个线程并行 DML,每个线程负责若干个分区。

并行度和目标表的分区数之间有倍数关系时,一般可以达到最佳性能。当并发度高于分区数时,会有多个线程处理同一个分区的数据;当并发度低于分区数时,单个线程可能处理多个分区的数据,并且每个线程处理的分区不重合。当并行度大于目标表分区数时,建议并行度是分区数的整数倍。

一般来说,同时向一个分区插入数据的线程数不要超过 4 个,超过这个值后扩展性并不好,日志同步会成为瓶颈,另外还有一些分区级别的锁同步开销。当并行度小于目标表分区数时,建议分区数是并行度的整数倍。这样,每个线程处理的分区数差不多,可以避免插入工作量倾斜。

4.2.2 索引表处理策略

并行 DML 支持自动维护索引表。

当索引表为本地索引时,并行 DML 在更新主表时,存储层会自动维护本地索引。

当索引表为全局索引时,并行 DML 框架会生成特定的计划来维护全局索引。假设有两个全局索引,处理流程如下:

  1. 首先,会用 DFO1 更新主表;
  2. 然后,DFO1 将全局索引1、全局索引2需要的数据发给 DFO2,用 DFO2 更新全局索引表1;
  3. 最后,DFO2 将全局索2引需要的数据发给 DFO3,用 DFO3 更新全局索引表2。

1705634034

以上策略对所有 INSERT、DELETE、UPDATE 语句有效,对于 MERGE 语句,处理方式略有不同,所有的索引维护操作会集中到一个 DFO 中处理,如下图所示:

  1. 首先,会用 DFO1 更新主表;
  2. 然后,DFO1 将全局索引1、全局索引2需要的数据发给 DFO2,DFO2 内部会逐个完成全部全局索引的维护操作。

1705634043

4.2.3 更新分区键的处理策略

对于 UPDATE 语句来说,当主表或全局索引表的分区键被更新时,需要把旧数据从旧分区中删除,然后把新数据插入到新分区中。这个过程通常被称作 row movement。

当发生 row movement 时,需要将 UPDATE 操作拆分成两步操作:先 DELETE,然后 INSERT。具体地,会将出现 row movement 的 UPDATE DFO 拆分成两个 DFO,第一个 DFO 负责 DELETE,第二个 DFO 负责 INSERT。并且,为了避免主键冲突,必须确保 DELETE DFO 完全执行完成后才能开始执行 INSERT DFO。

4.2.4 事务处理

OceanBase 并行 DML 和普通 DML 语句一样,完全支持事务处理。并行 DML 语句可以和其它查询语句一起出现在同一个事务中,执行完成并行 DML 语句后无需立即提交事务,就可以在后继的查询语句中读取到 DML 语句的结果。

在 OBServer v4.1 版本之前,当并行 DML 执行时间超长时,需要给租户配置项 undo retention 设置合适的值,否则可能发生 -4138 (OB_SNAPSHOT_DISCARDED) 错误,导致 SQL 在内部反复重试,直至超时。undo retention 字面意思是 Undo 的保留位点,即从当前时间回溯多长时间的 Undo 日志是保留下来的。对于 OceanBase 数据库来说,是将该时段的所有数据多版本保留下来。当并行 DML 执行时间超过 undo retention 设定的时间时,多版本数据可能被淘汰,当 DML 中的任何后继操作试图访问淘汰的多版本数据时,就会触发 OB_SNAPSHOT_DISCARDED 报错。undo retention 的默认值是 30 分钟,这意味着在默认情况下,如果并行 DML 语句 30 分钟内不能执行完成,无论语句的超时时间设定为多少,语句都可能执行超时并报错。一般来说,如果业务中的最长并行 DML 的执行时间为 2h 时, undo retention 可以设置为 2.5h。undo retention 不能随意设置为极大值,那会导致多版本数据无法回收,打爆磁盘。

从 OBServer v4.1 版本起,并行 DML 的执行不再依赖 undo retention 设定。多版本数据会根据事务版本号回收,只要事务还活跃,事务对应的版本号能读到的内容就不会回收。不过,数据盘满的场景是例外,此时还是会强行回收多版本数据,并行 DML 会收到 OB_SNAPSHOT_DISCARDED 报错,并自动重试整个 SQL。

4.2.5 旁路导入

当内存空间不足时,并行 DML 容易报告内存不足错误。没有走旁路导入路径的并行 DML,数据首先会写入 Memtable,然后通过转储、合并写入磁盘。因为并行 DML 写入数据到 Memtable 的速度极快,当写入速度快过转储速度时,内存就会不断增长,最终触发内存不足报错。

为了解决这个问题,OceanBase v4.1 的存储层提供了旁路导入功能。当并行 DML 使用旁路导入功能执行 INSERT 语句时,数据会绕过 Memtable 直接写入磁盘,不仅避免了内存不足的问题,而且还能提升数据导入性能。

用户通过 APPEND HINT 开启旁路导入功能。旁路导入开始前,要求提交上一个事务,并且设置 autocommit = 1。在 v4.2 版本中,旁路导入功能必须配合并行 DML 才能正常工作,如果没有通过 HINT 或 session 开启并行 DML,则旁路导入的 HINT 会被自动忽略。语法示例如下:

set autocommit = 1;
insert /*+ append enable_parallel_dml parallel(3) */ into t1 select * from t2;

预计在未来版本中,旁路导入功能会放松对事务的要求,可以出现在事务中的任意位置。

4.2.6 无法并行的 DML 操作

为了保证正确的 DML 语义,如下场景中,查询部分可以并行,但 DML 部分无法并行:

  • 如果目标表包含 local unique index,则 DML 部分不可并行,查询部分依然可以并行
  • INSERT ON DUPLICATE KEY UPDATE 语句的 DML 部分不可并行
  • 如果目标表包含 Trigger、外键,则 DML 部分不可并行
  • 如果 MERGE INTO 语句的目标表中包含 global unique index,则 DML 部分不可并行
  • 如果 DML 启用了 IGNORE 模式,则 DML 部分不可并行

如果发现 DML 没有走并行,可以通过 explain extended 来查看 Note 字段,确定未走并行的原因。

4.2.7 Row Movement 操作

当更新分区表的分区键时,可能使数据从一个分区搬迁到另一个分区。在 Oracle 模式下通过下面的命令可以禁止数据跨分区搬迁:

create table t1 (c1 int primary key, c2 int) partition by hash(c1) partitions 3;
alter table t1 disable row movement;OceanBase(TEST@TEST)>update t1 set c1 = c1 + 100000000;
ORA-14402: updating partition key column would cause a partition change

但是,并行 DML 会忽略表的 row movement 属性,总是允许更新分区键。

4.3 并行 DDL

支持并行执行的 DDL 语句包括:

  • CREATE TABLE AS SELECT
  • ALTER TABLE
  • CREATE INDEX

4.3.0 原理

所有并行 DDL 都是通过特定的 Parallel DML 完成。例如,创建索引本质是创建一个索引空表,然后并行地从主表查询出索引列数据,最后并行地插入到索引表中。

4.3.1 通过 HINT 指定并行度

目前(v4.2)仅 CREATE INDEX 语句支持通过 PARALLEL HINT 开启并行,其余 DDL 都只支持 SESSION 变量和 TABLE PARALLEL 属性来开启。

CREATE /*+ PARALLEL(3) */ INDEX IDX ON T1(C2);

4.3.2 通过 SESSION 变量指定并行度

上述所有 DDL 语句都支持通过 SESSION 变量来指定并行度。指定并行度后,该 SESSION 上的所有 DDL 都自动按照该并行度并行执行,并且查询部分和修改部分都使用相同的并行度。

SET _FORCE_PARALLEL_DDL_DOP = 3;
CREATE TABLE T1 (C1 int, C2 int, C3 int, C4 int);
CREATE INDEX IDX ON T1(C2);
-- v4.2 中,CREATE TABLE AS SELECT 开并行,
-- 用的是 “SET _FORCE_PARALLEL_DML_DOP”
-- 而不是 “SET _FORCE_PARALLEL_DDL_DOP”
-- 后继版本可能会修改成后者
SET _FORCE_PARALLEL_DML_DOP = 3;
CREATE TABLE T1 (C1 int, C2 int, C3 int, C4 int);
CREATE TABLE T2 AS SELECT * FROM T1;

4.3.3 通过表 PARALLEL 属性指定并行度

本节内容实测并没有走并行,需要跟进是否符合设计。验证方法:

select plan_operation, count(*) threads from oceanbase.gv$sql_plan_monitor where trace_id = last_trace_id() group by plan_line_id, plan_operation order by plan_line_id;

DDL 相关表上有 PARALLEL 属性时,可以使用 SET 语句设定 SESSION 变量来开启并行执行。例如:

SET _ENABLE_PARALLEL_DDL = 1;
CREATE TABLE T1 (C1 int, C2 int, C3 int, C4 int) PARALLEL = 3;
CREATE INDEX IDX ON T1(C2) PARALLEL = 2;
-- v4.2 中,CREATE TABLE AS SELECT 开并行,
-- 用的是 “SET _ENABLE_PARALLEL_DML”
-- 而不是 “SET _ENABLE_PARALLEL_DDL”
-- 后继版本可能会修改成后者
SET _ENABLE_PARALLEL_DML = 1;
CREATE TABLE T1 (C1 int, C2 int, C3 int, C4 int) PARALLEL = 3;
CREATE TABLE T2 PARALLEL 2 AS SELECT * FROM T1;

4.3.4 优先级

如果同时指定了 PARALLEL HINT、FORCE SESSION PARALLEL、表级 PARALLEL 属性中的两个或多个,那么它们的优先级如下:

PARALLEL HINT 优先级 > FORCE SESSION PARALLEL 优先级 > 表 PARALLEL 属性优先级

4.3.5 旁路导入

CREATE INDEX 语句无论是否开启并行,总是会走旁路导入(Direct Write,Bypass memtable)。

CREATE TABLE AS SELECT 语句目前(v4.2)还不支持旁路导入功能,如果数据量比较大,建议先建立空表,然后使用并行 DML 旁路导入模式并行插入。

4.4 并行 LOAD DATA

LOAD DATA 的实现不是基于并行 DML,它的实现方式是:先用多个线程并行切分 csv 文件,拼成多个 insert 语句,然后用一定的并发度分发执行这些 insert 语句。

LOAD DATA /*+ parallel(2) */ infile "test.csv" INTO TABLE t1 FIELDS TERMINATED BY ',' ENCLOSED BY '"';

上述语句中,PARALLEL 选项指定加载数据的并行度,如果没有指定 PARALLEL HINT,则默认以 PARALLEL 为 4 来并行执行 LOAD DATA。 PARALLEL 建议取值范围是 [0, 租户的最大CPU数]。

4.5 局部无法并行的场景

  • 最顶层 DFO 无需并行,它负责和客户端交互,以及执行最顶层无需并行的部分操作,如 LIMIT、PX COORDINATOR 等
  • 包含 TABLE UDF 时,含该 UDF 的 DFO 只能串行执行,其余部分依然可以并行

相关文章:

并行执行的4种类别——《OceanBase 并行执行》系列 4

OceanBase 支持多种类型语句的并行执行。在本篇博客中,我们将根据并行执行的不同类别,分别详细阐述:并行查询、并行数据操作语言(DML)、并行数据定义语言(DDL)以及并行 LOAD DATA 。 《并行执行…...

函数练习.

1.打印乘法口诀表 口诀表的行数和列数自己指定如&#xff1a;输入9&#xff0c;输出99口诀表&#xff0c;输出12&#xff0c;输出1212的乘法口诀表。 multiplication(int index) { ​if (index 9) { ​int i 0; ​for (i 1; i < 10; i) { ​int j 0; ​for (j 1; j &…...

Git 分支命令操作详解

目录 1、分支的特点 2、分支常用操作 3、分支的使用 3.1、查看分支 3.2、创建分支 3.3、修改分支 3.4、切换分支 3.5、合并分支 3.6、产生冲突 3.7、解决冲突 3.8、创建分支和切换分支说明 1、分支的特点 同时并行推进多个功能开发&#xff0c;提高开发效率。各个分…...

十二生肖Midjourney绘画大挑战:释放你的创意火花

随着AI艺术逐渐进入大众视野&#xff0c;使用Midjourney绘制十二生肖不仅能够激发我们的想象力&#xff0c;还能让我们与传统文化进行一场新式的对话。在这里&#xff0c;我们会逐一提供给你创意满满的绘画提示词&#xff0c;让你的作品别具一格。而且&#xff0c;我们还精选了…...

【C++】priority_queues(优先级队列)和反向迭代器适配器的实现

目录 一、 priority_queue1.priority_queue的介绍2.priority_queue的使用2.1、接口使用说明2.2、优先级队列的使用样例 3.priority_queue的底层实现3.1、库里面关于priority_queue的定义3.2、仿函数1.什么是仿函数&#xff1f;2.仿函数样例 3.3、实现优先级队列1. 1.0版本的实现…...

Go语言函数

在Go语言中&#xff0c;函数是一种基本的构建块&#xff0c;用于组织代码并执行特定任务。它们是可重复使用的代码段&#xff0c;可以接收输入参数&#xff0c;执行一系列操作&#xff0c;并可返回结果。以下是Go语言中函数的详细介绍及其使用方法&#xff1a; 基本语法 Go语…...

如何使用EasyExcel导入百万数据

摘要&#xff1a; 本文将详细探讨如何利用EasyExcel库&#xff0c;以及结合Java编程&#xff0c;高效地导入大规模数据至应用程序中。我们将逐步介绍导入流程、代码实现细节&#xff0c;并提供性能优化建议&#xff0c;旨在帮助读者在处理百万级别数据时&#xff0c;提高效率与…...

【解决】Unity Build 应用程序运行即崩溃问题

开发平台&#xff1a;Unity 2021.3.7f1c1   一、问题描述 编辑器 Build 工程结束&#xff0c;但控制台 未显示 Build completed with a result of Succeeded [时间长度] 信息。该情况下打包流程正常&#xff0c;但应用程序包打开即崩溃。   二、问题测试记录 测试1&#xf…...

C++数据结构——红黑树

前言&#xff1a;本篇文章我们继续来分享C中的另一个复杂数据结构——红黑树。 目录 一.红黑树概念 二.红黑树性质 三.红黑树实现 1.基本框架 2.插入 3.判断平衡 四.完整代码 总结 一.红黑树概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个…...

Java并发编程:学习路线图

文章目录 一、操作系统内核原理1、进程管理详解2、内存管理详解3、IO输入输出系统详解4、进程间通信机制详解5、网络通信原理剖析 二、Java内存模型三、并发集合1、Map&#xff08;1&#xff09;ConcurrentHashMap&#xff08;2&#xff09;ConcurrentSkipListMap 2、List&…...

算法_前缀和

DP34 【模板】前缀和 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别int n in.nextInt(),q in.ne…...

C语言(指针)7

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…...

线程纵横:C++并发编程的深度解析与实践

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的Linux高性能服务器编程系列之《线程纵横&#xff1a;C并发编程的深度解析与实践》&#xff0c;在这篇文章中&#xff0c;你将会学习到C新特性&#xff0c;并发编程&#xff0c;以及其如何带来的高性能的魅力&#xff0…...

在阿里云服务器上安装MySQL

目录 一、先卸载不需要的环境 1.关闭MySQL服务 2.查看安装包以及卸载安装包 3.依次卸载所有包 4. 获取mysql官⽅yum源 二、安装&#xff08;密钥过期解决方法&#xff09; 三、启动并进入 关于MySQL MySQL是一个广泛使用的开源关系型数据库管理系统&#xff08;RDBMS&…...

国标GB28181协议EasyCVR视频汇聚平台获取设备录像仅展示部分片段的原因排查

国标GB28181协议EasyCVR安防平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力&#xff0c;平台支持7*24小时实时高清视频监控&#xff0c;能同时播放多路监控视频流&#xf…...

Java的类和对象(一)—— 初始类和对象,this关键字,构造方法

前言 从这篇文章开始&#xff0c;我们就进入到了JavaSE的核心部分。这篇文章是Java类和对象的第一篇&#xff0c;主要介绍类和对象的概念&#xff0c;this关键字以及构造方法~~ 什么是类&#xff1f;什么是对象&#xff1f; 学过C语言的老铁们&#xff0c;可以类比struct自定义…...

富格林:曝光虚假套路规避亏损

富格林指出&#xff0c;在现货黄金市场中&#xff0c;交易时间很充足投资机会也多的是&#xff0c;但为什么还是有人亏损甚至爆仓呢&#xff1f;其实导致这种情况&#xff0c;是因为有一些投资者不知道其中的虚假套路&#xff0c;很容易就一头栽进去了。要规避虚假套路带来的亏…...

数据源网站分享

1. 国家统计局&#xff1a; http://www.stats.gov.cn/提供国家宏观经济数据 2. 工业和信息化部&#xff1a; http://www.miit.gov.cn 发布工业运行及信息化相关数据 3. 中国人民银行&#xff1a; http://www.pbc.gov.cn/ 提供金融市场政策及运行相关数据 4. 国家金融监督…...

Flutter 中的 CupertinoAlertDialog 小部件:全面指南

Flutter 中的 CupertinoAlertDialog 小部件&#xff1a;全面指南 在Flutter中&#xff0c;CupertinoAlertDialog是用于在iOS风格的应用中显示警告或提示信息的模态对话框。它以其圆角卡片和模糊背景为特点&#xff0c;为用户提供了一个简洁而直观的交互界面。CupertinoAlertDi…...

【RAG 论文】UPR:使用 LLM 来做检索后的 re-rank

论文&#xff1a;Improving Passage Retrieval with Zero-Shot Question Generation ⭐⭐⭐⭐ EMNLP 2022, arXiv:2204.07496 Code: github.com/DevSinghSachan/unsupervised-passage-reranking 论文&#xff1a;Open-source Large Language Models are Strong Zero-shot Query…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...