自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(32)
  • 收藏
  • 关注

原创 循环队列实现---kfifo

在优化系统性能时,我们通常需要分析一个单线程程序各模块的功能和性能,然后将这些模块拆分到多个线程中并行执行。而多个线程之间需要加入缓存以实现线程间的通信。为方便进程间通信,通常需要采用循环队列的数据结构来实现生产者-消费者模式。在图1中,对缓存1而言,线程1为生产者,将经由线程1处理后的数据写入缓存1,线程2为消费者从缓存1中读取数据进行后续处理。同理对缓存2而言,线程2为生产者而线程3为消费者。对于线程间的循环队列有如下关键的操作步骤:空间分配为队列分配一定大小的空间,在初始化时执行该操作。

2023-01-30 22:37:55 1041

原创 PostgreSQL B+树索引---页面删除之XLOG

在《PostgreSQL B+树索引—页面删除》中,我们阐述了PostgreSQL B*树索引页面删除的流程。还遗留了一个问题,在页面删除的第一阶段,我们可能会获取到一条由内部节点和叶子节点组成的链表。图1在第二阶段,PostgreSQL会从链头开始将节点从其左右兄弟中删除,直至链尾(也就是叶子节点)。在这个过程中,每次删除链头,都会修改叶子节点high key的tid让其指向当前链头的孩子,让其孩子作为新的链头。那么为什么一定要让叶子节点记录链头位置呢?

2022-08-23 14:41:53 660 2

原创 PostgreSQL B+树索引---页面删除

本文将阐述PostgreSQL B*树索引的最后一个部分,索引的页面删除。该部分内容在《PostgreSQL Blink-tree ReadMe—翻译》中其实已经涉及到了,不过Read Me的内容较多,本文将重新梳理一下B*树索引页面删除的逻辑,并从源代码的角度分析PostgreSQL如何实现页面删除。在PostgreSQL中,VACUUM操作会对B*树中的索引元组进行物理删除,当一个索引页面中的所有元组都被删除,即索引页面被删空后,VACUUM操作会将这个页面从B*树中删除。...

2022-08-18 23:46:47 2356 10

翻译 PostgreSQL Blink-tree ReadMe---翻译

src/backend/access/nbtree/READMEThis directory contains a correct implementation of Lehman and Yao’s high-concurrency B-tree management algorithm (P. Lehman and S. Yao, Efficient Locking for Concurrent Operations on B-Trees, ACM Transactions on Database Sy

2022-07-22 01:01:45 1128 4

翻译 PostgreSQL Buffer ReadMe---翻译

PostgreSQL buffer readme

2022-06-28 23:06:41 369

原创 PostgreSQL Vacuum---索引删除

PostgreSQL Vacuum—索引删除预备知识《PostgreSQL Vacuum—元组删除》《PostgreSQL B+树索引—并发控制》概述在《PostgreSQL Vacuum—元组删除》中,我们现实阐述了元组的删除过程,从中我们知道,在删除索引之前HOT链的链头元组的ItemData只能被标记为LP_DEAD来防止重用,只有当索引删除之后ItemData才能标记为LP_UNUSED以供重用。所以本章我们将来删除如何删除索引。索引的删除有如下两个场景:用户执行Vaccum命令

2021-11-15 10:09:52 4309 1

原创 PostgreSQL Vacuum---元组删除

PostgreSQL Vacuum—元组删除预备知识《PostgreSQL思考—元组何时可以被删除?》《PostgreSQL 基础模块—表和元组组织方式》《PostgreSQL 事务—MVCC》概述在《PostgreSQL思考—元组何时可以被删除?》中,我们阐述了关于元组过期的问题,在本文中我将具体阐述,对于过期元组应该如何删除。版本链与HOT机制基本概念在PostgreSQL中,MVCC并不会使用回滚区,Update的实现是先删除旧元组,再插入一条新元组。原始元组使用t_ctid指向新元

2021-11-14 16:10:26 1713 2

原创 PostgreSQL思考---元组何时可以被删除?

PostgreSQL思考—元组何时可以被删除?预备知识《PostgreSQL 事务—MVCC》概述PostgreSQL支持了MVCC,所以当执行Delete时,不会也不能彻底删除相关元组。对于Delete操作所涉及的元组,PostgreSQL只是设置其t_xmax来表示元组已经被t_xmax对应的事务删除。但此时,这条元组可能依然对某些查询事务可见,这就是元组不能直接删除的原因。那么接下来就涉及两个问题?元组何时可以被删除?元组何时被删除?关于元组何时被删除,这里直接给出答案:在用户执行V

2021-11-10 22:44:15 1229

原创 关于更新丢失的处理

关于更新丢失的处理预备知识《关于隔离性》概述在《关于隔离性》中,他们提到了更新丢失的问题。我们先来简单回顾下,如果多个用户按照如下流程并行地对数据库中的某个字段进行递增,就会出现更新丢失。-- x为程序变量begin;x = select value from test;x += 1;update test set value = x;commit;我们提到了一些数据的Repeatable Read和Serializable隔离级别可以解决更新丢失的问题。我们还提到,这样实现递增的方

2021-11-05 16:54:32 702

原创 关于隔离性

关于隔离性概述ACID是关系型数据库的重要特性,其中I表示Isolation隔离性。隔离性和操作系统的虚拟内存一样,是一种抽象,让并行执行的事务相互之间不会干扰,看起来就像一次只执行一个事务一样。也就是所谓的可串行化(Serializable),即多个并行的事务,在提交时其结果与串行执行完全相同。隔离级别的一个核心问题是:一个事务的执行过程和结果是否会影响到其他正在执行的事务。可串行化是最高级别的隔离,即事务之前互不影响。除此之外,为了并发性考虑还有几种弱一点的隔离级别,按照隔离度从低到高依次是:未提

2021-11-04 12:06:51 709

原创 不同数据库Serializable隔离级别的区别

不同数据库Serializable隔离级别的区别概述Serializable(可串行化)是数据库最高等级的隔离级别。从概念上来讲,Serializable的定义是:多个并行的事务,在提交时其结果与串行执行完全相同。当前主流数据库几乎都支持名为Serializable的隔离级别,为什么要用加上名为?因为不同数据库对于Serializable的实现方式不同,有些数据库的Serializable其实做不到真正意义的可串行化。下面,我们来分别看看MySQL、PostgreSQL、Oracle在可串行化隔离级别下

2021-11-02 15:48:43 879

原创 PostgreSQL 事务—MVCC

MVCC预备知识《PostgreSQL 流程—全表遍历》《PostgreSQL重启恢复—Checkpoint&Redo》概述在《PostgreSQL 流程—全表遍历》中我们讲解过一个函数heapgetpage,该函数用于获取页面中或有可见的元组。在全表遍历中,我们遗留了一个问题,就是如何判断元组的可见性,本文就来重点描述关于可见性的相关问题。MVCC考虑这样一个场景,当一个进程P1正在修改某元组R,进程P2希望读取R,此时应该如何处理?这是一个典型的多进程并发控制的场景。对于多进程并发

2021-10-11 20:25:08 1324 6

原创 PostgreSQL 流程---全表遍历

全表遍历预备知识《PostgreSQL 流程—查询》概述在《PostgreSQL 流程—查询》我们重点讨论了PostgreSQL的查询流程,提到全表遍历的操作主要有函数SeqNext来实现,本文将重点讨论SeqNext的流程。SeqNextSeqNext的代码比较短,我们直接来看代码:static TupleTableSlot *SeqNext(SeqScanState *node){ HeapTuple tuple; HeapScanDesc scandesc; EState

2021-10-11 16:52:36 2110

原创 PostgreSQL 流程---查询

查询概述查询是数据库中最常用也是最复杂的操作之一,关于查询涉及很多方面:SQL解析、成本评估、索引选择…等等,本文只讨论最简单的部分,即PostgreSQL如何执行全表遍历。考虑下面的SQL语句:-- 建表create table t1(id int);-- 插入insert into t1 values(1),(2),(3);-- 查询select * from t1 where id = 1;对于select语句,由于我们并没有为t1表创建索引,所以只能通过全表遍历的方式来执行查询。

2021-10-11 16:30:07 1458

原创 PostgreSQL B+树索引---并发控制

B+树索引—并发控制预备知识《B+树索引—基本结构》《B+树索引—查询》《B+树索引—插入》《B+树索引—分裂》概述最后,我们来讨论B+树的并发控制,准确来说应该是B-Link树的并发控制。并发控制是B-Link的精髓,B-Link树是在B+树的基础上进行了改造,而改造的目的就是为了提升并发性。在《B+树索引—基本结构》中,我们已经简要介绍过了B+树索引并发性的核心思想。基于这个核心思想派生出了许多精妙的实现,在本文中,我们来一一阐述。分裂锁基本首先,我们来看看并发控制中锁最多的操作:分

2021-09-28 22:00:50 1734 8

原创 PostgreSQL B+树索引---分裂持久性

B+树索引—分裂持久性预备知识《B+树索引—分裂》《基础模块—表和元组组织方式》概述在了解了B+树的分裂流程之后,我们来讨论B+树的持久性,也就是ACID的D。与B+树持久性相关有几个非常重要的问题:在B+树分裂期间,如果发生系统故障,如何确保系统重启后,B+树依然可用。B+树完成分离,并且相关事务已经提交。如果系统在B+树落盘之前发生故障,在系统重启后如何对分裂进行恢复。应对这两个问题的方案就是WAL。所以我们下面来看看在B+树发生分裂时,需要将哪些信息写入XLOG,以确保系统重启后能

2021-09-26 11:06:23 868 4

原创 PostgreSQL B+树索引---分裂

B+树索引—分裂预备知识《B+树索引—查询》《B+树索引—插入》概述现在,我们终于进入到了B+树索引最难的一个部分,节点的分裂。其实分裂本身并不难,难的主要是两个问题:分裂引起的并发控制问题。如何保证分裂的原子性,即分列时如果发生系统崩溃,如何恢复索引。在本章,主要阐述分裂基本流程及实现,分裂相关的并发控制以及原子性问题,后续由专门的文档来阐述。图解分裂在讲代码实现之前,我们先来图解以下PostgreSQL的分裂算法。图1B+树的当前状态如图1所示。关于图1,我们需要注意以下几

2021-09-23 12:42:02 3475

原创 PostgreSQL B+树索引---插入

B+树索引—插入预备知识《B+树索引—查询》概述在了解了B+树的查询逻辑之后,再来看B+树插入逻辑就比较简单了,无非就是首先定位插入位置,然后将关键字进行插入。当节点插入满后,节点会发生分裂,节点分裂是一个非常复杂的流程,后面会有专门的文章来阐述节点分裂。本文主要解决以下几个问题:插入的基本流程。索引中会插入些什么?tid是否会作为索引列?如何定位插入位置?唯一索引和主键索引如何处理?插入基本流程PostgreSQL索引插入的入口函数是btinsert,代码实现如下:boolbt

2021-09-18 11:33:29 2438 10

原创 PostgreSQL B+树索引---ScanKey

B+树索引—ScanKey预备知识《PostgreSQL B+树索引—查询》ScanKey概念对于一个给定的查询语句,我们需要做的第一件事就是从where条件中获取可以用于索引遍历的表达式,这些表达式在PostgreSQL中被称为ScanKey。下面我们先来看一个场景,首先我们创建一张带有索引的表:drop table if exists test;create table test(a int);create index idxtest on test(a);然后向表中写入数据:ins

2021-08-25 11:18:17 12971 4

原创 PostgreSQL B+树索引---查询

B+树索引—查询预备知识《B+树索引—基本结构》概述B+树索引有三个基本的操作:查询、插入、删除(更新是由删除+插入来完成)。在插入和删除之前首先需要定位插入和删除的位置,这个定位过程与查询流程基本一致,所以在讨论插入和删除之前,我们先来B+树的查询如何实现。index_getnext_tidindex_getnext_tid是索引遍历的最上层函数,index_getnext_tid每调用一次就返回一个符合索引条件的TID。TID为Tuple ID用于标识元组的位置,和Oracle中的rowid

2021-08-25 11:12:32 1817 8

原创 PostgreSQL B+树索引---基本结构

B+树索引—基本概念和特性基本概念图1PostgreSQL中使用的B+树索引结构如上图所示,其中有几个关键点需要说明。B link TreePostgreSQL B+树索引的思想来源于lehman和yao的论文《Efficient Locking for Concurrent Operations on B-Trees》,该论文介绍了B+树的一个变种,B link Tree,也叫**B***树。B*树和B+树的主要区别在于B*树的非叶子节点也用双向链表链接。B*树的主要优势在于具备更高的并发

2021-08-24 23:33:08 3893 5

原创 PostgreSQL重启恢复---Checkpoint&Redo

Checkpoint&Redo预备知识《数据库基础—重做日志》概述前面的文档中,我们讨论了很多关于XLOG问题:XLOG如何组织?如何写入log buffer?log buffer如何落盘?现在我们来阐述XLOG的用处:当数据库意外发生宕机后,如何依据XLOG来做数据恢复?在《数据库基础—重做日志》中,我们阐述过数据库几种基于日志的恢复策略,其中提到undo\redo策略是现在应用最广泛的策略。而PostgreSQL也使用的这种策略。依据undo\redo策略,我们在数据库重启恢复时,需

2021-08-01 17:11:02 3310

原创 PostgreSQL重启恢复---Log Buffer

Log Buffer预备知识《PostgreSQL重启恢复—XLOG 1.0》《PostgreSQL重启恢复—XLOG 2.0》概述在前面的文章中,我们解决了对于数据页的insert操作,需要组装一个怎样的XLOG以及XLOG写入log buffer的流程。接下来我们需要来更加深入的了解下log buffer,了解他的组织结构,了解log buffer的作用,更重要的是要了解XLOG如何落盘。还记得WAL的两大准则么:XLOG落盘之后,对应的数据才能落盘。一个事务相关的所有XLOG都落盘之后

2021-08-01 12:18:21 1408 4

原创 PostgreSQL重启恢复---XLOG 2.0

XLOG 2.0预备知识《PostgreSQL重启恢复—XLOG 1.0》概述在《PostgreSQL重启恢复—XLOG》中,我们查询的XLOG的组织结构、XLOG写入的基本流程,但是忽略了一些有意思的细节。现在我们来调试一遍全流程,在调试的过程中印证《PostgreSQL重启恢复—XLOG》中的描述,同时更加深入的分析PostgreSQL XLOG的写入。此外,本章我们还需要解决一个问题,就是PostgreSQL如何应对partial write。所以,在调试之前,我们需要先阐述什么是partia

2021-07-30 11:49:08 774

原创 PostgreSQL重启恢复---XLOG 1.0

XLOG 1.0参考资料https://zhmin.github.io/2019/11/05/postgresql-wal-format/预备知识《PostgreSQL 流程—插入》《PostgreSQL 基础模块—表和元组组织方式》概述前文说过,XLOG是PostgreSQL的重做日志,用于重启恢复时重做已提交事务中未落盘的数据。XLOG是一种物理逻辑日志,也可以称为Page-oriented Log,这类日志记录的是数据库中的页面变化。这两个概念直接讲的话可能比较抽象,所以就在XLOG流程

2021-07-30 11:28:27 1305 5

原创 内存屏障与volatile(C语言版)

内存屏障与volatile(C语言版)最有价值的写在最前面内存屏障与volatile是高并发编程中比较常用的两个技术,无锁队列的时候就会用到这两项技术。然而这两项技术设计比较广的基础知识,所以比较难以理解,也比较不容易解释清楚。关于内存屏障和volatile网上有相当多的资料,但是总感觉还是不够系统和深入。当然由于我自身水平有限,所以也不敢保证就能把这两个概念说清楚。所以在文章的开始,先列举一些我在学习过程中比较好的资料。1.基本概念https://blog.csdn.net/legend050

2021-07-11 12:58:06 3505 2

原创 PostgreSQL 流程---插入

插入预备知识《PostgreSQL 基础模块—表和元组组织方式》概述数据库的插入操作通常是由一条Insert语句实现的。Insert语句的完整执行流程比较长,包括解析SQL语句、元组组装、元组插入等一系列流程。本章只介绍元组的组装和插入部分。元组组装与插入都在ExecInsert函数中实现,代码如下:static TupleTableSlot *ExecInsert(ModifyTableState *mtstate, TupleTableSlot *slot, TupleT

2021-07-11 12:37:38 2346 2

原创 Postgresql 9.6.10在Windows下的安装和调试

相关文档https://www.postgresql.org/docs/10/install-windows-full.html 源代码编译(官方文档)https://blog.csdn.net/u012867993/article/details/102466086 源代码调试源代码版本postgresql-9.6.10.tar.gz编译环境准备1. 安装VS2017按照默认配置安装,没有特别之处。2. ActivePerl安装按照默认配置安装,选择完全安装。3. ActiveTcl

2021-07-09 17:29:21 1047

原创 PostgreSQL 基础模块---缓冲池管理

参考资料《PostgreSQL数据库内核分析》 彭智勇 彭煜玮:P99~P101概述在PostgreSQL中,任何对于表、元组、索引等操作都在缓冲池中进行,缓冲池的数据调度都以磁盘块为单位,需要访问的数据块以磁盘块为单位调用函数smgrread写入缓冲区,而smgrwrite将缓冲池数据写回磁盘。调入缓冲池中的磁盘块称为缓冲区,多个缓冲区组成的缓冲池。PostgreSQL有两种缓冲池:共享缓冲池和本地缓冲池。共享缓冲池主要作为普通表的操作场所,本地缓冲池则仅本地可见的临时表的操作场所。本文仅对共享缓

2020-10-29 18:59:44 2138

原创 PostgreSQL 基础模块---表和元组组织方式

参考资料《PostgreSQL数据库内核分析》 彭智勇 彭煜玮:P58~P60概述PostgreSQL是堆表,其中每个文件由多个块组成,块在物理磁盘中的存储形式如下图所示:块由4个部分组成:块头:PageHeaderData记录:记录由两部分组成Linp:Linp是ItemIdData类型,长度固定,在块中从前向后分配。每个ItemIdData都记录了一个偏移,用于指向Tuple。Tuple:记录的头信息,一条记录由Tuple+记录本身构成。记录本身长度不固定,在块中从后向前分配。空

2020-10-28 11:01:55 1372

原创 数据库重启恢复概述

参考资料《数据库系统设计》第二版,第6章 系统故障对策,P188~P200WALWAL(write ahead log)是基于重做日志恢复的一个先决条件。意思是,只有当相关日志落盘后,对应的数据才能落盘。比如,下面这条insert语句:begin;insert into test(id) values(1);commit;只有当insert对应的日志<T1,1,insert>落盘之后,这条insert的元组才能落盘。这是为什么?如果,insert元组先于日志落盘,假设在commi

2020-10-09 11:47:00 1500

原创 字节对齐详解

字节对齐简介1. 基本原则任何K字节的基本对象的地址必须是K的倍数。基本对象:int、double、long、short等基本数据类型,不包括struct、union、class。2. 结构体的字节对齐一个结构体,首地址必须是结构体中最大基本元素长度的整数倍。例如:struct S1 { int i; char c; int j; };设S1的首地址为xp,对于S1来说,最大的基本元素为int,所以**xp**必须是4的整数倍,称S1满足4字节对齐。解释:回顾字节对

2020-08-22 00:23:14 7980 3

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除