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

2023-11-08 monetdb-事务-只有RR隔离级别-原因分析

摘要:

monetdb的事务隔离级别只有RR, 和mysql/innodb的具有RR和RC两个隔离级别不同.

本文分析monetdb的RR隔离级别的实现方式, 以及分析这种隔离级别方式如何导致只有RR隔离级别.

测试流程:

测试方式:

  1. 分别开两个mclient终端, 连接同一个mserver实例
  2. 两个client终端分别叫做客户端A和客户端B
  3. 客户端A开启auto commit, 执行的sql为插入一条数据
    1. insert into t1 values(3);
  4. 客户端B开启start transaction, 之心的sql为统计数据的数量
    1. start transaction;
    2. select count(1) from t1;
  5. 客户端A插入一条数据后, 在客户端B执行select count(1) 查看数据的数量

测试结果:

  1. 无论客户端A插入多少条数据
  2. 客户端B执行了start transaction后,通过select count(1)查询出的数据的数量永远不变
  3. 也就是说客户端B只能读到start transaction执行之前的数据
  4. 客户端B的隔离级别为可重复读,read repeated, 即RR

RR的隔离级别的原因定位方式:

  1. 客户端A是auto commit的方式, 每插入一条数据就会自动提交事务
  2. 对客户端B而言, 数据的可见性来说,A插入的数据, 都是已经提交的 
  3. 但是B看不到A插入的数据, 那么对来说, 必然是存在某种规则对数据进行了过滤
  4. 要排查的话, 应该从B的角度, 追查为什么无法拿到A插入的数据

排查过程:

一. 通过日志分析select count的执行的核心函数:

日志:

2023-11-08 08:42:24    M_DEBUG ALGO     client3              monetdb5/mal/mal_interpreter.c:716             runMALsequence       calling querylog.define
2023-11-08 08:42:24    M_DEBUG ALGO     client3              monetdb5/mal/mal_interpreter.c:687             runMALsequence       calling sql.count
2023-11-08 08:45:56    M_DEBUG ALGO     client3              monetdb5/mal/mal_interpreter.c:687             runMALsequence       calling sql.resultSet
2023-11-08 08:45:56    M_DEBUG ALGO     client3              gdk/gdk_bat.c:292                              COLnew2              -> tmp_647#0@0[lng]TSRN
2023-11-08 08:45:56    M_DEBUG ALGO     client3              gdk/gdk_bat.c:1039                             BUNappendmulti       tmp_647#0@0[lng]TSRN appending 1 values
2023-11-08 08:45:56    M_DEBUG ALGO     client3              gdk/gdk_bat.c:292                              COLnew2              -> tmp_725#0@0[oid]TSRN
2023-11-08 08:45:56    M_DEBUG ALGO     client3              gdk/gdk_batop.c:2846                           BATconstant          -> tmp_725#1@0[oid]TSRKN 23usec

核心函数:

calling sql.count

二. 分析 sql.count的执行细节:

调用堆栈:

#0  segs_end (segs=0x1952b230, tr=0x7f9fb0104450, table=0x1952aa60) at /root/work/monetdb-dev/trunk/monetdb/sql/storage/bat/bat_storage.c:457
#1  0x00007fa055d07ad1 in count_col (tr=0x7f9fb0104450, c=0x1952b2d0, access=10) at /root/work/monetdb-dev/trunk/monetdb/sql/storage/bat/bat_storage.c:773
#2  0x00007fa055c85186 in SQLbasecount (cntxt=0x13b4580, mb=0x7f9fb0135570, stk=0x7f9fb013c3e0, pci=0x7f9fb0144400) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_rank.c:1289
#3  0x00007fa069395007 in runMALsequence (cntxt=0x13b4580, mb=0x7f9fb0135570, startpc=1, stoppc=0, stk=0x7f9fb013c3e0, env=0x0, pcicaller=0x0)at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_interpreter.c:688
#4  0x00007fa06939377e in runMAL (cntxt=0x13b4580, mb=0x7f9fb0135570, mbcaller=0x0, env=0x0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_interpreter.c:357
#5  0x00007fa055bb85eb in SQLrun (c=0x13b4580, m=0x7f9fb01167e0) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_execute.c:259
#6  0x00007fa055bb9ee7 in SQLengineIntern (c=0x13b4580, be=0x7f9fb0136060) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_execute.c:709
#7  0x00007fa055bb74b5 in SQLengine (c=0x13b4580) at /root/work/monetdb-dev/trunk/monetdb/sql/backends/monet5/sql_scenario.c:1358
#8  0x00007fa0693b4862 in runPhase (c=0x13b4580, phase=4) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:453
#9  0x00007fa0693b49cc in runScenarioBody (c=0x13b4580, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:479
#10 0x00007fa0693b4bd8 in runScenario (c=0x13b4580, once=0) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_scenario.c:510
#11 0x00007fa0693b6fea in MSserveClient (c=0x13b4580) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:589
#12 0x00007fa0693b6863 in MSscheduleClient (command=0x7f9fb0000b70 '\333' <repeats 199 times>, <incomplete sequence \333>..., challenge=0x7f9ff7bfcce3 "gWPRtbcO", fin=0x7f9fb0002b90, fout=0x7f9fc4009630, protocol=PROTOCOL_9, blocksize=8190) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/mal/mal_session.c:445
#13 0x00007fa06947c1d4 in doChallenge (data=0x7f9fc4006790) at /root/work/monetdb-dev/trunk/monetdb/monetdb5/modules/mal/mal_mapi.c:222
#14 0x00007fa068d2e729 in THRstarter (a=0x7f9fc400bb20) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_utils.c:1668
#15 0x00007fa068dabb23 in thread_starter (arg=0x7f9fc400bb90) at /root/work/monetdb-dev/trunk/monetdb/gdk/gdk_system.c:862
#16 0x00007fa0682ec1ca in start_thread () from /lib64/libpthread.so.0
#17 0x00007fa067f58e73 in clone () from /lib64/libc.so.6

核心函数:

segs_end

static size_t
segs_end( segments *segs, sql_trans *tr, sql_table *table)
{size_t cnt = 0;lock_table(tr->store, table->base.id);segment *s = segs->h, *l = NULL;if (segs->t && SEG_IS_VALID(segs->t, tr))l = s = segs->t;for(;s; s = s->next) {if (SEG_IS_VALID(s, tr))l = s;}if (l)cnt = l->end;unlock_table(tr->store, table->base.id);return cnt;
}

SEG_IS_VALID

/* A segment is part of the current transaction is someway or is deleted by some other transaction but use to be valid */
#define SEG_IS_VALID(seg, tr) \((!seg->deleted && VALID_4_READ(seg->ts, tr)) || \(seg->deleted && OLD_VALID_4_READ(seg->ts, seg->oldts, tr)))

VALID_4_READ

/* valid* !deleted && VALID_4_READ(TS, tr)				existing or newly created segment*  deleted && TS > tr->ts && OLDTS < tr->ts		deleted after current transaction*/#define VALID_4_READ(TS,tr) \(TS == tr->tid || (tr->parent && tr_version_of_parent(tr, TS)) || TS < tr->ts)

核心数据:

拿到的segment: 

(gdb) p l[0]
$47 = {start = 0, end = 25, deleted = false, ts = 1, oldts = 0, next = 0x7f9fbc027ed0, prev = 0x0
}

未拿到的segment:

(gdb) p segs->t[0]
$46 = {start = 25, end = 26, deleted = false, ts = 1875, oldts = 0, next = 0x0, prev = 0x0
}

三. 分析过滤segment的代码逻辑:

核心处理:

/* valid* !deleted && VALID_4_READ(TS, tr)				existing or newly created segment*  deleted && TS > tr->ts && OLDTS < tr->ts		deleted after current transaction*/#define VALID_4_READ(TS,tr) \(TS == tr->tid || (tr->parent && tr_version_of_parent(tr, TS)) || TS < tr->ts)

核心数据结构:

sql_trans 

typedef struct sql_trans {char *name;ulng ts;			/* transaction start timestamp */ulng tid;			/* transaction id */sql_store store;	/* keep link into the global store */MT_Lock lock;		/* lock protecting concurrent writes to the changes list */list *changes;		/* list of changes */list *dropped;  	/* protection against recursive cascade action*/list *predicates;	/* list of read predicates logged during update transactions */list *dependencies;	/* list of dependencies created (list of sqlids from the objects) */list *depchanges;	/* list of dependencies changed (it would be tested for conflicts at the end of the transaction) */lng logchanges;		/* count number of changes to be applied to the wal */int active;			/* is active transaction */int status;			/* status of the last query */sql_catalog *cat;sql_schema *tmp;	/* each session has its own tmp schema */changeset localtmps;sql_allocator *sa;	/* transaction allocator */struct sql_trans *parent;	/* multilevel transaction support */
} sql_trans;

segment 

typedef struct segment {BUN start;BUN end;bool deleted;	/* we need to keep a dense segment set, 0 - end of last segemnt,some segments maybe deleted */ulng ts;		/* timestamp on this segment, ie tid of some active transaction or commit time of append/delete orrollback time, ie ready for reuse */ulng oldts;		/* keep previous ts, for rollbacks */struct segment *next;	/* usualy one should be enough */struct segment *prev;	/* used in destruction list */
} segment;

核心判断逻辑:

1. (TS == tr->tid)

  1. TS 是 seg->ts
  2. tid是transaction id, 也就是事务id  /* transaction id */
  3. tr->ts 是 /* transaction start timestamp */
  4. seg->ts 和 tr->tid 进行比较,其实使用了一些hack技巧和成员复用

2. (TS < tr->ts)

  1. 重点是这个逻辑
  2. tr->ts 是这个事务开始的时间
  3. TS 是 seg->ts, 是这个数据段被提交的时间
  4. 所以这个判断的逻辑, 就是tr这个事务, 只能看到这个开始之前被记录的数据段里的数据
  5. 也就说, 从tr这个事务开始后, 再被提交的事务, 都无法被看到
  6. 从调用方的角度, 就是 read repeated 的隔离级别

如何扩充新的隔离级别呢?

  1. 注意我说的是扩充新的隔离级别,而不是修改已有的隔离级别
  2. RR的隔离级别需要被保留
  3. 使用mysql的隔离级别的参数来控制
  4. 新增RC的隔离级别
  5. RC的隔离级别, 可以看到已经提交的事务的数据, 而不仅仅是 TS < tr->ts 的

相关文章:

2023-11-08 monetdb-事务-只有RR隔离级别-原因分析

摘要: monetdb的事务隔离级别只有RR, 和mysql/innodb的具有RR和RC两个隔离级别不同. 本文分析monetdb的RR隔离级别的实现方式, 以及分析这种隔离级别方式如何导致只有RR隔离级别. 测试流程: 测试方式: 分别开两个mclient终端, 连接同一个mserver实例两个client终端分别叫做客…...

微信小程序:怎么在一个js中修改另一个js的数据(这里通过缓存进行实现)

实例&#xff1a;现有两个页面index.js和category.js,我现在想在index.js中修改category.js的数据 初始数据 category [{name: 物流配送,list: [{id: 1,job: 外卖骑手,checked: true}, {id: 2,job: 快递员,checked: false}, {id: 3,job: 司机,checked: false}, {id: 4,job: …...

01-基于IDEA,Spring官网,阿里云官网,手动四种方式创建SpringBoot工程

快速上手SpringBoot SpringBoot技术由Pivotal团队研发制作&#xff0c;功能的话简单概括就是加速Spring程序初始搭建过程和Spring程序的开发过程的开发 最基本的Spring程序至少有一个配置文件或配置类用来描述Spring的配置信息现在企业级开发使用Spring大部分情况下是做web开…...

map相关题目

KY264 单词识别 题目描述&#xff1a; 输入一个英文句子&#xff0c;把句子中的单词(不区分大小写)按出现次数按从多到少把单词和次数在屏幕上输出来&#xff0c;次数一样的按照单词小写的字典序排序输出&#xff0c;要求能识别英文单词和句号。 输入描述&#xff1a; 输入…...

JAVA 版小程序商城免费搭建 多商家入驻 直播带货 商城系统 B2B2C 商城源码之 B2B2C产品概述

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…...

moc_ XX.cpp 中的函数没有定义

解决办法&#xff1a; 直接将 moc_OnlyTest.cpp 文件&#xff0c;添加到工程目录下&#xff0c;解决。...

11.8代码

利用gpiod子系统实现开发板六盏灯&#xff0c;安装驱动点亮&#xff0c;卸载驱动熄灭 #include <linux/init.h> #include <linux/module.h> #include <linux/of.h> #include <linux/gpio/consumer.h> /*myleds{core-leds{leds <&gpioz 5 0>…...

常用的表单校验规则——邮箱/QQ/身份证号码/微信/电话/数字字母/整数/文本/密码等

1.邮箱校验规则 //邮箱校验 export const validateEmail async (RuleObject, value) > {// const reg new RegExp(/^[A-Za-z0-9\u4e00-\u9fa5][a-zA-Z0-9_-]$/)const reg new RegExp(/^[a-zA-Z0-9_-]([a-zA-Z0-9]\.)(com|cn|net|org)$/)if (value) {if (!reg.test(value…...

Mysql数据库 11.SQL语言 储存过程 下 储存过程管理和游标

一、存储过程管理 1.查询存储过程 查询所有储存过程 语法 show procedure status; 代码实现 #查询存储过程 show procedure status; 运行结果 加入条件查询储存过程 语法 show procedure status where db储存过程名; 代码实现 #查询带有条件的储存过程 查询名字为pro…...

如何在Visual Studio上创建项目并运行【超级详细】

工欲善其事&#xff0c;必先利其器。想要学好编程&#xff0c;首先要把手中的工具利用好&#xff0c;今天小编教一下大家如何在史上最强大的编译器--Visual Studio上创建项目。&#x1f357; 一.打开编译器&#x1f357; 双击你电脑上的vs&#xff0c;(2012,2019,2022)都行。&…...

《C++ Primer》第7章 类(二)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 7.4 类的作用域&#xff08;P253&#xff09; 每个类都有自己的作用域&#xff0c;在类的作用域之外&#xff0c;普通的数据和函数成员只能由对象、引用或指针使用成员访问运算符访问&#xff0c;类型成员则…...

git仓库代码克隆

说明&#xff1a; 由于服务项目的厂商不同且需求不断变化且交付周期临近&#xff0c;所以想把之前一个仓库的代码弄到一个新的仓库&#xff0c;待交付完毕后再进行代码整合。 第一步 先创建一个远程仓库用来放你要克隆的代码。 第二步 克隆一份裸版本代码库 git clone --ba…...

AM@向量代数@向量基本概念和向量线性运算

文章目录 abstract向量的基本概念向量向量的坐标分解式和坐标&#x1f47a;向量的模向量的长度(大小)&#x1f47a;零向量单位向量&#x1f47a;方向向量非零向量的单位向量正规化向量夹角&#x1f47a; 向量方向角和向量间夹角投影几何描述向量的线性运算向量的加减运算向量的…...

2023-11-08 LeetCode每日一题(最长平衡子字符串)

2023-11-08每日一题 一、题目编号 2609. 最长平衡子字符串二、题目链接 点击跳转到题目位置 三、题目描述 给你一个仅由 0 和 1 组成的二进制字符串 s 。 如果子字符串中 所有的 0 都在 1 之前 且其中 0 的数量等于 1 的数量&#xff0c;则认为 s 的这个子字符串是平衡子…...

Web3.0的测试题

任务&#xff1a; 在前端开发一个查询UI&#xff0c;查询当前用户账户的ETH余额和指定ERC20合约中的余额 目标&#xff1a; UI框架指定使用 MUI (https://mui.com)需要查询到当前账户的ETH余额并展示在UI界面上需要输入ERC20合约地址后&#xff0c;查询到到当前账户在此ERC20…...

Javascript知识点详解:对象的继承、原型对象、原型链

目录 对象的继承 原型对象概述 构造函数的缺点 prototype 属性的作用 原型链 constructor 属性 instanceof 运算符 构造函数的继承 多重继承 对象的继承 面向对象编程很重要的一个方面&#xff0c;就是对象的继承。A 对象通过继承 B 对象&#xff0c;就能直接拥有 B …...

学之思开源考试系统部署至Centos7

学之思开源考试系统部署至Centos7 1、下载源码 源码下载&#xff1a; https://gitee.com/mindskip/xzs-mysql 数据库脚本下载&#xff1a; https://www.mindskip.net:999/ 2、项目打包 分别在\source\vue\xzs-student目录和source\vue\xzs-admin目录&#xff0c;执行前端打…...

如何利用浏览器的可见性API优化网站性能

最近在使用微软AI聊天工具Bing时&#xff0c;发现一个有趣的东西。我向它提问后&#xff0c;它在持续输出的过程中&#xff0c;如果我离开了当前它的浏览器会话&#xff0c;比如切屏&#xff0c;看当前浏览器的其它标签页&#xff0c;它会默认停止它的输出&#xff0c;等我回来…...

还不知道IP地址不够用是怎么被大牛们解决的?(NAT/NAPT, IPv6, DHCP)

文章目录 前言1. DHCP网络管理协议什么是 DHCPDHCP 两种分配机制 2. NAT网络地址转换协议什么是 NATNAT 技术使用NAT网络设备间如何通信两个内网设备相互通信不同内网中的设备相互通信NAT IP转换过程 NAPT 技术NAT 技术的缺陷 3. IPv6 协议什么是 IPv6 总结 前言 在之前的文章…...

使用决策树预测隐形眼镜类型

任务描述 本关任务&#xff1a;编写一个例子讲解决策树如何预测患者需要佩戴的隐形眼镜类型。使用小数据集&#xff0c;我们就可以利用决策树学到很多知识&#xff1a;眼科医生是如何判断患者需要佩戴的镜片类型&#xff0c;一旦理解了决策树的工作原理&#xff0c;我们甚至也…...

DeerFlow效果展示:自动生成的深度研究报告与播客内容惊艳分享

DeerFlow效果展示&#xff1a;自动生成的深度研究报告与播客内容惊艳分享 1. DeerFlow核心能力概览 DeerFlow作为一款深度研究智能助手&#xff0c;整合了语言模型、网络搜索和代码执行能力&#xff0c;能够自动完成从信息收集到内容生成的全流程工作。其核心功能亮点包括&am…...

SpringBoot 3.2.0 项目里,如何优雅地引入 Flowable 7.1.0 工作流引擎?

SpringBoot 3.2.0 项目优雅集成 Flowable 7.1.0 工作流引擎实战指南 在微服务架构中引入工作流引擎&#xff0c;往往意味着需要在不破坏现有架构的前提下实现业务流程的自动化管理。本文将深入探讨如何在已具备MyBatis-Plus、Spring Cloud Alibaba等技术栈的SpringBoot 3.2.0项…...

矩阵分解(1)-- 从高斯消元到对称正定:LU、LDLT与Cholesky分解的算法演进与应用场景

1. 矩阵分解&#xff1a;为什么我们需要它&#xff1f; 想象一下你面前有一堆积木&#xff0c;乱七八糟地堆在一起。如果你想快速找到其中某一块积木&#xff0c;可能需要翻找很久。但如果有人帮你把这些积木按照颜色、形状分类摆放整齐&#xff0c;找起来就会容易得多。矩阵分…...

【Agents】自定义子代理进阶:后台执行

基础篇&#xff1a;【Agents】Claude Code 多 Agent 入门&#xff1a;从一问一答到并行协作实践篇1:【Agents】Claude Code 自定义子代理&#xff1a;内置的不够用&#xff0c;就自己造实践篇2:【Agents】自定义子代理进阶&#xff1a;沙盒隔离 ​ 上一篇用 isolation: worktre…...

大数据在电力行业应用案例解析 -【电力技术】(25)RPA 在电力业扩报装中的自动化应用与实现

目录 一、引言:业扩报装的效率瓶颈 二、RPA 技术特点与电力适用性 三、RPA 在业扩报装中的四大核心应用场景 3.1 预受理自动审核 3.2 批量用户信息自动导入 3.3 勘查工单自动派工 3.4 流程自动流转与归档 四、RPA 实施流程(标准化) 五、典型应用成效 六、完整可运行…...

实时行情系统设计:从协议选择到高可用架构,再到数据源选型

一、核心问题及解决方案&#xff08;按踩坑频率排序&#xff09; 问题 1&#xff1a;误删他人持有锁——最基础也最易犯的漏洞 成因&#xff1a;释放锁时未做身份校验&#xff0c;直接执行 DEL 命令删除键。典型场景&#xff1a;服务 A 持有锁后&#xff0c;业务逻辑耗时超过锁…...

Qwen3-14B开源大模型实战:WebUI界面定制+API接口二次开发教程

Qwen3-14B开源大模型实战&#xff1a;WebUI界面定制API接口二次开发教程 1. 开箱即用的私有部署方案 Qwen3-14B作为通义千问最新开源的大语言模型&#xff0c;在14B参数规模下展现出惊人的多任务处理能力。但很多开发者在本地部署时常常遇到环境配置复杂、显存不足、推理速度…...

新手福音:无需github,在快马平台轻松入门第一个web应用

最近在学前端开发时&#xff0c;发现很多教程都推荐从GitHub克隆项目来练习&#xff0c;但GitHub经常访问不稳定&#xff0c;对新手特别不友好。好在发现了InsCode(快马)平台&#xff0c;不用折腾GitHub就能直接上手写代码&#xff0c;特别适合我这种刚入门的小白。今天就用它做…...

如何快速解锁AMD 780M APU的完整AI性能?终极优化指南

如何快速解锁AMD 780M APU的完整AI性能&#xff1f;终极优化指南 【免费下载链接】ROCmLibs-for-gfx1103-AMD780M-APU ROCm Library Files for gfx1103 and update with others arches based on AMD GPUs for use in Windows. 项目地址: https://gitcode.com/gh_mirrors/ro/…...

“人工智能+”政策下,企业AI转型的机遇与路径

在“人工智能”政策的大力推动下&#xff0c;企业引入AI项目与产品正成为提升竞争力、实现转型提效的关键举措。对于山东地区&#xff0c;尤其是威海地区的企业而言&#xff0c;把握这一趋势&#xff0c;积极探索AI技术的应用&#xff0c;无疑是顺应时代发展的明智选择。企业引…...