PostgreSQL 2-10 function

exec_simple_query('SELECT * FROM t1 WHERE c1 > 10') pg_parse_query pg_analyze_and_rewrite parse_analyze transformStmt transformSelectStmt transformWhereClause transformExpr transformAExprOp oper oper_search # 查找操作符所有相关函数 enforce_generic_type_consistency # 根据已知数据类型,找到最符合的函数,自动调用隐式转换 make_op pg_plan_queries PortalRun ExecInterpExpr ExecEvalExprSwitchContext -- ciphera_gt / int4gt

July 1, 2026 · 1 min · 32 words · Me

海量 3 需求 pg_hba.conf加密

1 需求背景 客户使用vb什么版本? 2215 客户的要求: 2 需求分析 2.1 适配点 在使用vastbase的多个阶段,都可能涉及pg_hba.conf 编译安装 初始化 升级 配置 gs_guc修改pg_hba 手动编辑pg_hba 启动 运维 pg_backup pg_rewind vb_ctl restart 2.2 代码流程 编译 初始化 main # initdb.cpp canonicalize_path # PGDATA find_other_exec # 在gs_initdb bin目录下,查找gaussdb bin # 在$GAUSSHOME/share/postgrsql目录下,检查以下文件是否存在 check_input('postgres.bki, postgres.description, pg_hba.conf.sample, postgresql.conf.sample, ..., system_views.sql, ...') check_locale_encoding init_log gs_getenv_r('GAUSSLOG') canonicalize_path('$PGDATA/PG_VERSION') fprintf(PG_MAJORVERSION = '9.2') setup_config readfile("postgresql.conf.sample") readfile("pg_hba.sample") writefile("pg_hba.conf") bootstrap_template1 write_version_file setup_auth get_set_pwd setup_depend load_plpgsql setup_sysviews 升级 配置 启动 pg_ctl 运行 PostmasterMain # postmaster 线程 InitializeGUCOptions getopt_r load_hba # 加载hba ServerLoop ConnCreate StreamConnection BackendStartup PostgresMain # postgres 线程 InitBackendWorker InitSession CheckAuthentication PerformAuthentication port->protocol_config->fn_authenticate ClientAuthentication hba_getauthmethod check_hba g_instance.libpq_cxt_comm_parsed_hba_lines # 读取缓存的hba if init_user: get_default_auth_method else: check_hostname sendAuthRequest recv_and_check_password_packet # 接收客户端的password crypt_verify for (;;) ReadCommand exec_simple_query('SQL') SIGHUB_handler load_hba 运维 ...

April 1, 2025 · 2 min · 217 words · Me

海量 3 需求 oracle resource

| -| -| -| -| -| -| -| | 1 | FAILED_LOGIN_ATTEMPTS | [1, max] unlimited | failed_login_attempts | [1,1000] | 认证类 | 登录数据库时,如果密码错误次数超过<本参数>,则账号会被锁定,短期内无法再登录 | | 2 | PASSWORD_LOCK_TIME | [1, max] unlimited | password_lock_time | [1,525600]min | 认证类 | 如果因密码错误次数过多,导致账号被锁,将锁定<本参数>的时间 | | 3 | PASSWORD_LIFE_TIME | [1, max] unlimited | password_effect_time | [30,36500]day | 认证类 | 设置或更新用户密码时,超过<本参数>的时间,密码会过期(oracle与vastase表现不同) | | 4 | PASSWORD_GRACE_TIME | - | - | - | 认证类 | 如果密码过期,在<本参数>的时间内,密码仍可使用 | | 5 | PASSWORD_REUSE_TIME | [1, max] unlimited | password_reuse_time | [30, 90]day | 认证类 | 用户设置密码时,如果密码在过去的<本参数>的时间内别用过,则密码不能复用,opengauss [0,3650] | | 6 | PASSWORD_REUSE_MAX | - | password_reuse_max | [1,100] | 认证类 | 用户设置密码时,如果密码已被重复使用过<本参数>的次数,则密码不能复用 | | 7 | INACTIVE_ACCONT_TIME | - | - | - | 认证类 | 如果一个账号在<本参数>的时间内,未登录过,则锁定账号 | | 8 | PASSWORD_VERIFY_FUNCTION | - | - | - | 认证类 | 用户设置密码时,调用<本参数>指定的函数,检查密码是否符合要求 | | 9 | PASSWORD_ROLLOVER_TIME | - | - | - | 认证类 | 新旧密码滚动更新天数 | | 10 | SESSIONS_PER_USER | - | - | - | 资源类 | 1个用户可建立的最大连接数 | | 11 | CPU_PER_SESSION | - | - | - | 资源类 | 1个连接可使用CPU时间数 | | 12 | CPU_PER_CALL | - | - | - | 资源类 | 1个调用(比如1个SQL)可使用CPU时间数 | | 13 | CONNECT_TIME | - | - | - | 资源类 | 1个连接可持续的时间 | | 14 | IDLE_TIME | [1, max] unlimited | session_timeout | [0,86400] | 资源类 | 1个连接空闲时间限制 | | 15 | LOGICAL_READS_PER_CALL | - | - | - | 资源类 | 1次调用(比如1个SQL)允许读写的page数量 | | 16 | LOGICAL_READS_PER_SESSION | - | - | - | 资源类 | 1个连接允许读取的page数量 | | 17 | PRIVATE_SGA | - | - | - | 资源类 | 1个连接可使用的共享内存空间大小 | | 18 | CONPOSITE_LIMIT | - | - | - | 资源类 | 1个连接可可使用的总资源:按cpu时间、连接时间、page读写数等加权求和 | ...

March 24, 2025 · 2 min · 317 words · Me

数据结构与算法 3 排序

1 概述 1.1 衡量标准 1.2 分类 算法 思想 最好时间复杂度 最坏时间复杂度 时间复杂度 空间复杂度 稳定性 冒泡排序 比较、交换 O(n) O(n^2) O(n^2) O(1) 稳定,值相等不交换 插入排序 比较、移动 O(n) O(n^2) O(n^2) 选择排序 比较、交换 归并排序 快速排序 堆排序 桶排序 计数排序 基数排序 /* 冒泡排序 */ void sort_bubble(int *arr, int arrlen) { int end; int tmp; int i; end = arrlen - 1; for (end = arrlen - 1; end > 1; end--) { for (i = 0; i < end - 1; i++) { if (arr[i] < arr[i + 1]) { tmp = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = tmp; } } } }

January 21, 2025 · 1 min · 99 words · Me

PostgreSQL 3-2 Page

1 Page的概念 1.1 前置概念 首先,简单介绍一些基本概念: 关系 Relation:PostgreSQL是一款关系型数据库,在数据库中,1个表对应关系代数中的1个关系,即1个Relation。本博客中,将1个Relation指1个表 数据文件 RelFile:通过CREATE TABLE t1 (c1 INT, c2 TEXT)等语法创建1个表时,PostgreSQL会生成1个与表对应的数据文件,表中数据都将被存储至数据文件中 数据库页 Page:1个数据文件,由1个或多个大小为8192字节(即8k)的数据页组成 行 Row:在SQL语法INSERT INTO t1 VALUES (1, 'data1')中,(1, 'data1')是表中的1行数据 元组 Tuple:在PostgreSQL中,1个Tuple存储1行数据,数据越长,Tuple越长。1个Page可以存储多个Tuple 1.2 Page Page的格式如下:

January 21, 2025 · 1 min · 30 words · Me

数据库安全 0 postgresql表级透明加密

1 特性背景 2 实现方案 2.1 系统表 1. pg_key_info 密钥信息 2. pg_key_data 密钥数据 3. pg_encryption 加密对象 2.2 定义表 2.3 定义表加密 2.4 操作表 2.5 管理表加密 2.6 管理主密钥 2.7 管理数据密钥 2.8 管理加密定义 2.8 未来计划 一、功能补充 二、语法复用 3 关键设计 3.1 格式设计 3.2 流程设计 整体流程 加密粒度 加密时机 加密判断 密钥存储 解密时机 解密判断 密钥来源 3.3 其他设计 3.2 主备密钥同步 4 特性源码 4.1 功能概览 基本功能篇 高级功能篇 加强篇 4.2 新增系统表 pg_key_info 4.2 新增系统表 pg_key_data 4.3 新增语法 CREATE KEY 4.4 新增语法 CREATE TABLE .. (protect=$data_key) 4.5 对加密对象的数据进行加密 参考 1 特性背景 2 实现方案 2.1 系统表 1. pg_key_info 密钥信息 keyoid keyname type alrotithm storage access protect create_time round 1 mk_1 master_key any localkms path=./keyfile $pass1 2024/02/01 13:01:01 - 2 dk_1 date_key aes_256_cbc database m100.d100.b1.i2 mk1 2024/02/01 13:01:01 0 2. pg_key_data 密钥数据 oid keydata algorithm 3 abcd1234 aes_256 3. pg_encryption 加密对象 type name oid special protect oldest_round table t1 100 - dk_1 1 2.2 定义表 定义表 定义表的语法与非加密表一致,我们通过单独的语法定义ENCRYPTION。 ...

January 21, 2025 · 4 min · 706 words · Me

PostgreSQL 3-6 Smgr

接口 void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo); // 创建文件 void smgrdounlink(SMgrRelation reln, bool isRedo); SMgrRelation smgropen(RelFileNode rnode, BackendId backend); void smgrclose(SMgrRelation reln); void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync); void smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer); void smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync); 调用关系 // 索引模块 btbuildempty() smgrwrite(metapage) _bt_blwritepage() smgrwrite() spgbuildempty() smgrwrite() |- FlushBuffer() ... |- FlushRelationBuffers() |- LocalBufferAlloc() smgrwrite() // FlushBuffer |- BufferAlloc() // readBuffer时,申请一个buffer,可能调用页面淘汰算法 |- FlushDatabaseBuffers() |- FlushRelationBuffers() |- FlushOneBuffer() FlushBuffer() // FlushOneBuffer XLogReadBufferForRedoExtended() FlushOneBuffer() // FlushRelationBuffers |- heap_sync() |- ATExecSetTableSpace() // ALTER TABLE SET TABLESPACE FlushRelationBuffers() // heap_sync when HEAP_INSERT_SKIP_WAL |- intorel_shutdown() |- CopyFrom() |- transientrel_shutdown() |- ATRewriteTable() heap_sync() // FlushDatabaseBuffers dbase_redo() FlushDatabaseBuffers() write时机: readBuffer时,如果buffer不在内存,且共享缓冲池已满,调用页面置换算法进行刷盘 alter table set table space copy

January 21, 2025 · 1 min · 125 words · Me

PostgreSQL 3-3 Buffer

1 Buffer基本介绍 1.1 Buffer解决的问题 实际应用场景中,PostgreSQL可能需要1分钟处理数十万次事务,频繁读写Page。Buffer提供以下2个基本功能: 加载Page至内存:PostgreSQL需要读写数时,都需先从磁盘中,将指定的Page加载至内存中,再在内存中操作Page 缓存常用Page:Page被加载至内存后,还会在内存停留一段时间,降低PostgreSQL直接从磁盘读写Page的频率 1.2 Buffer的基本功能 Buffer缓存Page时,需考虑以下几个场景: 插入Page:大部分事务操作表的Page时,先从Buffer中查找Page,如果Page不在Buffer中,再从磁盘读取Page,将其放入Buffer中,再操作Buffer中的Page 查找Page:访问Page时,通过文件名和Page编号等信息可确定唯一Page 访问Page:所有事务均可访问Buffer,需考虑多事务并发读写同一Pape的场景 淘汰Page:Buffer能缓存的Page数量有限,在Page数量过多时,需淘汰一些Page 落盘Page:Buffer中通常缓存表数据文件的Page,前文提到,事务持久化的标志是WAL日志落盘,因此,Buffer中的Page无需实时落盘,仅需异步落盘即可 2 Buffer的基本原理 2.1 插入Page 插入Page主要由读Page操作触发,上层函数读取Page的主要流程如下: 上层模块统一调用ReadBuffer()接口,读取指定表的指定Page ReadBuffer()中,先从Buffer查找Page,如果找到Page,则直接返回Buffer中的Page 如果未从Buffer找到Page,现在Buffer中预留存储Page的空间 之后,调用Smgr模块,从磁盘读取指定Page,并将其放入预留的空间内,再返回Buffer中的Page 函数调用关系大概如下图所示: ReadBuffer(Relation, BlockNumber) # 1 ReadBufferExtended() ReadBuffer_common() BufferAlloc() # 2,3 查找Page,如找到,返回;如未找到,预留存储Page的空间 smgrread(.., BlockNumber) # 4 如果未找到Page,从磁盘将Page读入预留的Page空间内,返回 2.2 查找Page 上层函数读Page时,首先进入查找Page阶段。 1.1 buffer池模型 模型: 1.2 buffer池接口 缓冲区接口: /* bufmgr.h */ /* 1 buffer池管理 */ void InitBufferPool(void); void InitBufferPoolAccess(void); void InitBufferPoolBackend(void); /* 2 buffer管理 */ /* 2.1 读buffer */ Buffer ReadBuffer(Relation reln, BlockNumber blockNum); Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy); Buffer ReadBufferWithoutRelcache(RelFileNode rnode, ForkNumber forkNum, BlockNumber blockNum,ReadBufferMode mode, BufferAccessStrategy strategy); /* 2.2 清理buffer */ oid ReleaseBuffer(Buffer buffer); void UnlockReleaseBuffer(Buffer buffer); void MarkBufferDirty(Buffer buffer); void IncrBufferRefCount(Buffer buffer); Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, BlockNumber blockNum); /* 2.3 刷盘buffer */ void CheckPointBuffers(int flags); void FlushOneBuffer(Buffer buffer); void FlushRelationBuffers(Relation rel); void FlushDatabaseBuffers(Oid dbid); void BufmgrCommit(void); bool BgBufferSync(void); /* 2.4 删除关联buffer */ void DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum, BlockNumber firstDelBlock); void DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes); void DropDatabaseBuffers(Oid dbid); /* 2.5 锁buffer */ void UnlockBuffers(void); void LockBuffer(Buffer buffer, int mode); bool ConditionalLockBuffer(Buffer buffer); void LockBufferForCleanup(Buffer buffer); bool ConditionalLockBufferForCleanup(Buffer buffer); bool HoldingBufferPinThatDelaysRecovery(void); 1.3 buffer调用 插入数据 ...

January 21, 2025 · 3 min · 547 words · Me

PostgreSQL 3-7 Xlog

5 wal落盘 WalWriterMain for :: XLogBackgroundFlush LWLockAcquire(LW_EXCLUSIVE) XLogWrite LWLockRelease() CommitTransaction RecordTransactionCommit BufmgrCommit XactLogCommitRecord # xlog记录commit TransactionTreeSetCommitTsData XLogFlush(XactLastRecEnd) for :: WaitXLogInsertionsToFinish XLogWrite write ResourceOwnerRelease AtEOXact_Buffers AtEOXact_RelationCache ... 1 概述 1.1 背景 https://zhmin.github.io/posts/postgresql-wal-format/ wal机制解决的问题:持久性、原子性、性能、数据同步、恢复 持久性需求: 执行一次事务/事务块,例如INSERT语句,除了要写数据文件,还需要更新系统表、索引文件、fsm文件、vm文件、事务提交文件等 为避免故障导致数据丢失,产生的数据写入磁盘才算事务成功 应用 数据库 磁盘 | 1. INSERT (5) --> | | 2. 读取数据页 <-- | | 3. 将数据写入数据页 | 4. 存储数据页 --> | | 5. 读取索引文件 --> | | 6... | 7. 读取fsm文件 --> | | 8... | 9. 读取vm文件 --> | | 10... | 11. INSERT 成功 <-- | 原子性需求: ...

January 21, 2025 · 11 min · 2275 words · Me

PostgreSQL 3-2 Transation (v2)

概述 假如,2个会话,并发写入数据: BEGIN; INSERT INTO t1 VALUES(1, 'data1'); COMMIT; BEGIN; INSERT INTO t1 VALUES(1, 'data2'); COMMIT; 加锁逻辑: exec_simple_query pg_parse_query pg_analyze_and_rewrite pg_plan_queries PortalStart PortalRun PortalRunMulti ProcessQuery ExecutorStart standard_ExecutorStart InitPlan ExecInitNode ExecInitModifyTable ExecInitResultRelation ExecGetRangeTableRelation table_open(relation, 'RowExclusiveLock') # 8级锁,行级排他锁 relation_open LockRelationOid LockAcquire ExecutorRun standard_ExecutorRun ExecutePlan ... ExecInsert table_tuple_insert heapam_tuple_insert heap_insert RelationGetBufferForTuple LockBuffer LWLockAcquire(buffer, 'LW_EXCLUSIVE') # 读写锁 RelationPutHeapTuple log_heap_insert 锁 HWLock 8级 relation, index, buffer 死锁检测 LWLocks buffer SpinLock PresicateLock HWLock 锁 取值 操作 AccessShareLock 1 SELECT RowShareLock 2 SELECT FOR UPDATE/SHARE RowExclusiveLock 3 INSERT/UPDATE/DELETE ShareUpdateExclusiveLock 4 VACUUM/ANALYZE/CRATE INDEX CONCURRENTLY ShareLock 5 CREATE INDEX ShareRowExclusiveLock 6 row share ExclusiveLock 7 block ROW SHARE/SELECT FOR UPDATE AccessExclusiveLock 8 ALTER TABLE/DROP TABLE/VACUUM FULL LockRelationOid LockAcquireExtended hash_search 所有进程共享 ...

July 3, 2026 · 1 min · 166 words · Me
心情不好的时候可以点一下 🐱
×
🤖 Doubao AI ×
Hi! 我是你的技术助手。关于代码、架构或 Bug,随时问我!🚀