PostgreSQL
文章平均质量分 76
PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS),是以加州大学计算机系开发的POSTGRES,4.2版本为基础的对象关系型数据库管理系统。POSTGRES的许多领先概念只是在比较迟的时候才出现在商业网站数据库中。
肥叔菌
本博客主要用于记录学习过程中的笔记,每隔一段时间,博主将会将精华内容整合发到知乎、简书上。欢迎关注博主肥叔菌在其他平台上的账号,谢谢。
B站:https://space.bilibili.com/456254145
segmentfault:https://segmentfault.com/u/feishujun/articles
简书:https://www.jianshu.com/u/67bab078551a
展开
-
PostgreSQL数据库事务系统——获取virtual transaction id
如果一个事务没有进行INSERT、UPDATE、DELETE操作,那么就步会分配事务ID,但事务仍然用一个虚拟事务ID代表自己。虚拟事务ID由两部分组成,第一部分是Backend ID,另一个是每个会话自己维护的本地事务ID计数器。通过两部分组合,能保证这个虚拟事务ID的唯一性。在PostgreSQL数据库IPC——SI Message Queue中描述了Backend ID和local transaction id的产生流程。原创 2023-09-11 00:00:00 · 397 阅读 · 0 评论 -
PostgreSQL数据库IPC——SI Message Queue
SI Message Queue代码位于src/backend/storage/ipc/sinvaladt.c和src/backend/storage/ipc/sinval.c文件中,属于PostgreSQL数据库IPC进程间通信的一种方式【之前介绍过PostgreSQL数据库PMsignal——后端进程\Postmaster信号通信也是作为PostgreSQL数据库IPC进程间通信的一种方式,主要用于进程间信号通信】,主要用于POSTGRES shared cache invalidation共享缓存失效原创 2023-09-14 00:00:00 · 251 阅读 · 0 评论 -
ORCA优化器浅析——元数据交换中的MD Provider
图9显示了Orca如何与不同的后端系统交换元数据。对元数据对象的所有访问都是通过MD访问器完成的,该访问器跟踪优化会话中访问的对象,并确保在不再需要它们时释放它们。GetMDObjDXLStr函数是MD Provider中最重要的函数,为了适配不同的MD Provider,但是GetMDObjDXLStr函数需要提供对MDObj的统一封装,因此ORCA给的方法是将MDObj中的信息序列化为DXLStr(其实就是xml)并返回CWStringBase,这样就无需返回统一的MDObj基类。原创 2023-07-20 00:00:00 · 146 阅读 · 0 评论 -
PostgreSQL查询引擎——上拉子链接SubLink
子查询是查询语句中经常出现的一种类型,是比较耗时的操作。优化子查询对查询效率的提升有直接的影响。从子查询出现在SQL语句的位置看,它可以出现在目标列、FROM子句、WHERE子句、JOIN/ON子句、GROUPBY子句、HAVING子句、ORDERBY子句等位置。PostgreSQL数据库将上述子查询概念进行了分类:子查询通常以范围表的方式存在(子链接以表达式的方式存在()【在实际应用中,可以通过子句所在位置来区分子链接和子查询,出现在是子查询;出现在或中的子句是子链接】。原创 2023-07-10 00:00:00 · 353 阅读 · 0 评论 -
Greenplum数据库优化器——Join类型
PG语法FULL OUTER_P/FULL,PG内部类型JOIN_FULL,USING clause | ON clause–全外连接(full join / full outer join):满足on条件表达式,返回两个表符合条件的所有行,a表没有匹配的则a表的列返回null,b表没有匹配的则b表的列返回null,即返回的是左连接和右连接的并集。反连接 ANTI JOIN 与半连接 SEMI JOIN 相反,是指在两表关联时,当第二个表中不存在匹配记录时,返回第一个表的记录。原创 2023-07-07 00:00:00 · 259 阅读 · 0 评论 -
ORCA优化器浅析——GP数据库调用优化器流程
首先我们需要看CGPOptimizer类(src/include/gpopt/CGPOptimizer.h)为Greenplum数据库提供ORCA优化器export出来的函数的封装。Greenplum数据库主流程调用extern "C"中提供的函数,比如初始化ORCA优化器的函数InitGPOPT,优化查询树的函数GPOPTOptimizedPlan,explain流程中调用的SerializeDXLPlan函数。原创 2023-06-24 00:00:00 · 520 阅读 · 0 评论 -
PostgreSQL数据库分区裁剪——predicate_refuted_by_recurse
我们假设已经应用了eval_const_expression(),因此不存在未展开的and或or(例如,在and中没有立即的and,包括顶级List结构下方的and)。如果这不是真的,我们可能无法证明一个有效的暗示,但不会产生更糟糕的后果。可以refute推导两个表达式树的叶子节点之间的是否排斥(atom A R=> atom B iff: predicate_refuted_by_simple_clause says so),然后叠加上父节点的AND或OR关系,确定两个表达式树在该中继节点上是否排斥。原创 2023-06-15 00:00:00 · 322 阅读 · 0 评论 -
PostgreSQL数据库分区裁剪——enable_partition_pruning
在PostgreSQL 10版本之前,PostgreSQL数据库实际上是没有单独的创建分区表的DDL语句,都是通过表继承的原理来创建分区表,这样使得在PostgreSQL中使用分区表不是很方便,到PostgreSQL 10之后,PostgreSQL扩展了创建表的DDL语句,可以用这个DDL语句来创建分区表,原先使用继承的方式还是可以创建分区表,但这两种分区表是不能混用的。原创 2023-06-10 00:00:00 · 1185 阅读 · 1 评论 -
PostgreSQL数据库分区裁剪——constraint exclusion
是枚举类型(RELOPT_BASEREL, RELOPT_JOINREL, RELOPT_OTHER_MEMBER_REL, RELOPT_OTHER_JOINREL, RELOPT_UPPER_REL, RELOPT_OTHER_UPPER_REL, RELOPT_DEADREL),目前仅在其为RELOPT_BASEREL或RELOPT_OTHER_MEMBER_REL才可执行relation_excluded_by_constraints函数。控制查询优化器使用表约束以优化查询。原创 2023-06-08 00:00:00 · 564 阅读 · 0 评论 -
PostgreSQL数据库查询执行——算子间数据包裹TupleTableSlot
TupleTableSlot定义在src/include/executor/tuptable.h文件中,为何称其为算子间数据包裹,因为头文件中的注释,也就是说该结构体在执行器中用于存放元组;以ExecSeqScan函数(顺序扫描表,返回下一个合适的元组)为例,其就向上层算子提供了数据包裹TupleTableSlot。有各种不同类型的元组表槽TupleTableSlot,每个槽都能够存储不同类型的元组。可以在不修改核心代码的情况下添加其他类型的插槽。槽的类型由传递给槽创建例程的。原创 2023-05-16 00:00:00 · 638 阅读 · 0 评论 -
PostgreSQL类型系统——Data Types
PostgreSQL has a rich set of native data types available to users. Users can add new types to PostgreSQL using the CREATE TYPE command. PostgreSQL有一组丰富的本地数据类型可供用户使用。。原创 2023-05-08 01:00:00 · 1724 阅读 · 0 评论 -
PostgreSQL查询引擎——SELECT STATEMENTS SelectStmt
该规则返回单个SelectStmt节点或它们的树,表示集合操作树(set-operation tree)。The rule returns either a single SelectStmt node or a tree of them, representing a set-operation tree. 当sub-SELECT位于a_expr内并且有多余的括号时,会出现歧义:括号是属于子SELECT还是属于周围的a_exp?我们不在乎,但bison想知道。原创 2023-02-17 00:00:00 · 1069 阅读 · 0 评论 -
PostgreSQL查询引擎——General Expressions Grammar之restricted expression
General expressions语法规则定义在src/backend/parser/gram.y文件中,其是表达式语法的核心。a_expr是不受限制的类型,b_expr是必须在某些地方使用的子集,以避免移位/减少冲突。例如,我们不能将BETWEEN作为,因为AND的使用与AND作为布尔运算符冲突。因此,b_expr在BETWEEN中使用,我们从b_expr中删除布尔关键字。请注意,( a_expr )是b_expr,因此始终可以使用无限制表达式,方法是用括号将其括起来。c_expr是a_expr和。原创 2023-02-09 01:30:00 · 736 阅读 · 0 评论 -
PostgreSQL查询引擎——transform expressions之CaseExpr
定义在src/backend/parser/parser_expr.c文件中的Node *transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)函数用于分析和转换表达式,包含类型检查和类型转换的工作。原创 2023-02-06 00:00:00 · 288 阅读 · 1 评论 -
PostgreSQL查询引擎——transform expressions之columnref
定义在src/backend/parser/parser_expr.c文件中的函数用于分析和转换表达式,包含类型检查和类型转换的工作。该函数将原始语法输出转换为具有完全确定语义的表达式树(Type checking and type casting is done here. This processing converts the raw grammar output into expression trees with fully determined semantics)。原创 2023-02-09 00:00:00 · 296 阅读 · 0 评论 -
PostgreSQL查询引擎——transform expressions之const
定义在src/backend/parser/parser_expr.c文件中的函数用于分析和转换表达式,包含类型检查和类型转换的工作。该函数将原始语法输出转换为具有完全确定语义的表达式树(Type checking and type casting is done here. This processing converts the raw grammar output into expression trees with fully determined semantics)。原创 2023-02-10 00:00:00 · 387 阅读 · 0 评论 -
PostgreSQL数据库FDW——读取parquet文件用例
读取数据到column_data中:read_column同样也是使用arrow::ChunkedArray存储获取的列数据,通过allocator为每列根据数据类型分配存储空间,拷贝arrow::ChunkedArray中的列数据到新分配的存储空间中。最终将数据空间设置到this->column_data[col]中。其代码和Apache Arrow User Guide —— Reading and writing Parquet files官方历程提供的读取parquet文件的代码一致。原创 2023-01-13 16:10:08 · 738 阅读 · 0 评论 -
PostgreSQL数据库FDW——Parquet S3 MultifileMergeExecutionStateBaseS3
MultifileMergeExecutionStateBaseS3和SingleFileExecutionStateS3、MultifileExecutionStateS3类不同,reader成员被替换为ParquetReader *类型的readers vector。新增slots_initialized布尔变量指示slots成员是否已经初始化。slots成员是Heap类,,但使用STL重新实现。slots Heap中存储的是ReaderSlot元素。原创 2023-01-15 00:00:00 · 524 阅读 · 0 评论 -
PostgreSQL数据库FDW——Parquet S3 ParquetS3FdwExecutionState
create_parquet_execution_state函数根据ReaderType类型创建不同的ExecutionState子类,以实现不同的执行行为。原创 2023-01-15 00:00:00 · 316 阅读 · 0 评论 -
PostgreSQL数据库FDW——Parquet S3 CachingParquetReader
CachingParquetReader类继承自ParquetReader类,相对于DefaultParquetReader类,其新增is_active成员用于控制next函数的返回值RS_INACTIVE。新增column_data和column_nulls成员取代chuck,用于存储列数据。原创 2023-01-11 20:16:11 · 254 阅读 · 0 评论 -
PostgreSQL数据库查询执行——Parallel Query
PostgreSQL can devise query plans that can leverage multiple CPUs in order to answer queries faster. This feature is known as parallel query. Many queries cannot benefit from parallel query, either due to limitations of the current implementation or becaus翻译 2023-01-12 00:00:00 · 836 阅读 · 0 评论 -
PostgreSQL数据库FDW——Parquet S3 DefaultParquetReader类
DefaultParquetReader类继承自ParquetReader类,其包含了用于封装row group的table成员,chunk_info中包含了row group中列数据的ChunkInfo信息,chunks中包含了row group中列数据。next函数用于对外返回rowgroup提取的记录(通过read_next_rowgroup函数),并将其放置到TupleTableSlot中(通过populate_slot函数,populate_slot函数也会提取记录)。rowgroups号。原创 2023-01-13 16:07:22 · 680 阅读 · 0 评论 -
PostgreSQL数据库FDW——Parquet S3 ParallelCoordinator
ParallelCoordinator类定义在src/reader.hpp文件中,该类用于支持postgres parallel foreign scan能力。ParallelCoordinator类支持单个parquet文件扫描并行PC_SINGLE和多个parquet文件扫描并行PC_MULTI。latch提供多个进程同步的锁,用于保护data数据域,确定进程所使用的ParquetReader所扫描的parquet files和rowgroup。原创 2023-01-12 00:00:00 · 246 阅读 · 0 评论 -
PostgreSQL数据库FDW——Parquet S3 ParquetReader类
ParquetReader类定义和实现位于src/reader.cpp和src/reader.hpp下,其主要作用是首先从create_parquet_reader函数可以看出,提供两种ParquetReader:DefaultParquetReader和CachingParquetReader。这两种ParquetReader都是ParquetReader类的子类。因此首先从ParquetReader类说起。ParquetReader构造函数/析构函数ParquetReader类声明于src/rea原创 2023-01-16 00:00:00 · 860 阅读 · 0 评论 -
PostgreSQL数据库FDW——Parquet S3 Foreign Data Wrapper
and。翻译 2023-01-13 00:00:00 · 452 阅读 · 0 评论 -
PostgreSQL数据库事务系统——phenomena
The isolation level specifies the kind of phenomena that can occur during the execution of concurrent SQL-transcations. The following phenomena are possible:写写操作:如果同时存在多个写操作,写写操作直接改变了数据在同一时刻的语义,这就更不被允许,所以写写操作通常不允许被并发执行。但是,如果不做并发控制,写写并发操作也会带来数据异常现象。脏写现象:按照原创 2023-01-14 00:00:00 · 283 阅读 · 0 评论 -
PostgreSQL数据库TableAM——HeapAM synchronized scan machinery
当多个后端在同一个表上运行顺序扫描时,我们尝试使它们保持同步,以减少所需的总体I/O。目标是只将每个页面读入共享缓冲区缓存一次,并让参与共享扫描的所有后端在页面脱离缓存之前处理该页面。由于一组后端中的“领头羊”在进行seqscan时必须等待I/O,而“跟随者”则不需要,因此一旦我们可以让后端同时检查表的大致相同部分,就会产生强烈的自同步效果。因此,所有真正需要的是获得一个新的后端,开始seqscan,以接近其他后端正在读取的位置。原创 2023-01-06 00:00:00 · 1096 阅读 · 0 评论 -
Using GDB To Trace Into a Parallel Worker Spawned By Postmaster During a Large Query
返回的数据元组中有很大一部分是丢失的,因为它们被认为是不可见的,而其中的一部分仍然可见。我立刻注意到,我正在研究的新功能不能在并行工作模式下工作,不知为什么,我需要找到一种方法来调试生成的并行工作程序,以检查它是如何计算可见性的,以及内部缺少什么。技术上是的,但这个并行工作程序的生命周期可能很短,当您从ps-ef命令中看到它的PID时,该工作程序可能已经完成了它的工作并退出。在这个博客中,我想和大家分享我如何使用GDB调试和跟踪Postmaster生成的新并行工作程序,以解决可见性问题。翻译 2022-12-31 00:00:00 · 313 阅读 · 0 评论 -
PostgreSQL数据库查询执行——SeqScan节点执行
SeqScan节点代码处于src/backend/executor/nodeSeqscan.c文件中,包含了4个重要函数:ExecInitSeqScan、ExecSeqScan、ExecReScanSeqScan和 ExecEndSeqScan。原创 2022-12-28 00:00:00 · 1265 阅读 · 0 评论 -
PostgreSQL数据库TableAM——HeapAM Scans
heap_beginscan函数用于初始化HeapScanDescData结构体,ParallelTableScanDesc形参在ExecGather函数中ExecSeqScanInitializeDSM函数会调用TableAM提供的table_beginscan_parallel函数,该函数中会申请ParallelTableScanDesc内存,而串行scan时,heap_beginscan函数在SeqNext函数执行时调用,但是ParallelTableScanDesc形参为null。原创 2022-12-29 00:00:00 · 261 阅读 · 0 评论 -
PostgreSQL数据库TableAM——Table scan callbacks
在src/backend/executor/nodeSeqscan.c文件中的SeqNext函数会调用table_beginscan函数,如果scan为非并行,或计划并行实现确实顺序执行时,第一次进入该函数需要调用table_beginscan生成并初始化TableScanDesc函数。table_beginscan_bm函数用于BITMAPSCAN,table_beginscan_bm是为位图堆扫描设置TableScanDesc的另一个入口点。table_endscan函数用于结束表的扫描。原创 2022-12-26 00:00:00 · 944 阅读 · 0 评论 -
PostgreSQL数据库TableAM——HeapAM Parallel table scan
该函数的作用就是确定phs_startblock的值,也就是并行SeqScan的起始块。HeapAM对parallelscan_estimate、parallelscan_initialize和parallelscan_reinitialize三个函数指针的实现就是直接使用table_block_parallelscan_estimate、table_block_parallelscan_initialize和table_block_parallelscan_reinitialize函数。原创 2022-12-20 22:52:25 · 436 阅读 · 0 评论 -
PostgreSQL数据库可插拔存储引擎——pg_am系统表
heap_tableam_handler函数定义在src/backend/access/heap/heapam_handler.c文件中,该函数直接使用PG_RETURN_POINTER宏封装并返回了heapam_methods结构体指针。pg_am系统表定义在src/include/catalog/pg_am.h文件中,其包含的字段amname为access method name,amhandler为该am句柄函数,amtype为am的类型(i是索引、t是表)。原创 2022-12-12 00:00:00 · 1120 阅读 · 0 评论 -
PostgreSQL数据库动态共享内存管理器——dynamic shared memory segment
首先看dynamic_shared_memory_type GUC参数,该参数用于指定dynamic shared memory implementation类型(DSM_IMPL_POSIX、DSM_IMPL_SYSV、DSM_IMPL_WINDOWS、DSM_IMPL_MMAP,定义在src/include/storage/dsm_impl.h文件中)。原创 2022-11-20 19:26:49 · 1504 阅读 · 0 评论 -
PostgreSQL数据库缓冲区管理器——本地缓冲区管理
本地缓冲区管理器(local buffer manager)为temporary表(无需WAL-logged或checkpointed)进行快速缓冲区管理,API定义在src/backend/storage/buffer/localbuf.c中。原创 2022-11-22 00:00:00 · 927 阅读 · 0 评论 -
PostgreSQL数据库缓冲区管理器——Buffer Pool初始化
PostgreSQL缓冲区管理器由三层组成,即缓冲表层、缓冲区描述符层和缓冲池层。,它存储着页面的buffer_tag与描述符的buffer_id之间的映射关系;是一个由缓冲区描述符组成的数组(每个描述符与缓冲池槽一一对应,并保存着相应槽的元数据);是一个数组(每个槽都存储一个数据文件页,数组槽的索引为buffer_id)。缓冲池只是一个用于存储关系数据文件(例如表或索引)页面的简单数组。缓冲池数组的序号索引就是buffer_id。原创 2022-11-21 00:00:00 · 733 阅读 · 0 评论 -
PostgreSQL查询引擎——编译调试
创建用户:useradd postgresqlpostgresql 12.6调试环境:./configure --prefix=/home/postgresql/pg12 --with-pgport=1921 --enable-debug修改src/Makefile.global,删除-O2,添加-g260 CFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wen原创 2022-11-01 09:53:29 · 621 阅读 · 0 评论 -
PostgreSQL查询引擎——create table xxx(...)基础建表transformCreateStmt
如果形参existing_relation_id不为null,则如果查到有相同的表已经创建,则通过该参数返回该表的oid,否则返回InvalidOid。如果lockmode形参不等于NoLock,当前用户不拥有目标表,抛出一个错误,不能尝试锁定用户没有权限的表。1 首先查询需创建表所在的namespace,主要是检查该namespace的权限、加锁(防止并发drop)、检查namespace是否已经存在需要创建的表、如果namespace是temparary的,则需要更新。,作为回调函数的参数;原创 2022-10-24 00:15:00 · 647 阅读 · 0 评论 -
PostgreSQL查询引擎——create table xxx(...)基础建表流程
建表语句执行parse_analyze函数时进入传统的transform阶段时并没有执行任何trasform功能的函数,而是直接走transformStmt函数的default分支:创建Query节点,让原始语法树设置到其utilityStmt成员。执行pg_rewrite_query函数时不经过QueryRewrite函数,直接将Query节点作为querytree_list列表的元素返回。在各个点elog打印的语法树如下所示,可以说是完全一致的。原创 2022-10-24 00:00:00 · 1497 阅读 · 0 评论 -
PostgreSQL查询引擎——select * from where = transform流程
其次对targetList子句进行转换,从语法树中可以看出RESTARGET的val成员指向的是ColumnRef,且其代表的是A_START也就是“*”(所有列),因此执行ExpandColumnRefStar函数(如下图中的3),需要利用步骤2存入ParseState中的p_namespace来获取RTE。调用makeFromExpr创建FROMEXPR结构体,关联第5步transform的OPEXPR和其对用的rtindex(关联RTE),最后将其设置到查询树的jointree中去。原创 2022-10-24 00:00:00 · 549 阅读 · 0 评论