事务
文章平均质量分 90
Hehuyi_In
这个作者很懒,什么都没留下…
展开
-
postgresql 手动清理wal日志的101个坑
新年的第一天,总结下去年遇到的关于WAL日志清理的101个坑,以及如何相对安全地进行清理。前面是关于WAL日志堆积的原因分析,清理相关可以直接看第三部分。原创 2024-02-10 23:12:42 · 3735 阅读 · 2 评论 -
postgresql源码学习(58)—— 删除or重命名WAL日志?这是一个问题
最近因为WAL日志重命名踩到大坑,一直很纠结WAL日志在什么情况下会被删除,什么情况下会被重命名,钻研一下这个部分。首先无用WAL日志的清理发生检查点执行时,检查点执行核心函数为CreateCheckPoint。其中核心调用栈为CreateCheckPoint函数很复杂,从外往里看会很容易晕,所以我们倒过来,先从最内层的RemoveXlogFile开始研究。因为debug跑了很多次,后文各日志段号等不会完全一致,但本质是相同的。注意这个跟踪属于高危操作,db进程有可能挂掉,千万别在生产环境随便执行。原创 2023-07-22 23:20:08 · 2565 阅读 · 0 评论 -
postgresql源码学习(53)—— vacuum②-lazy vacuum之heap_vacuum_rel函数
lazy vacuum之table_relation_vacuum函数与heap_vacuum_rel函数原创 2023-01-23 21:54:17 · 1747 阅读 · 0 评论 -
postgresql源码学习(52)—— vacuum①-准备工作与主要流程
关于vacuum的基础知识,参考,本篇从源码层继续学习vacuum相关操作在vacuum.c中,当手动执行vacuum及analyze命令,其主入口为ExecVacuum()函数——主要负责为真正执行操作的vacuum()函数做一系列准备工作(语句解析、选项设置与检查、测试设置等),核心是调用vacuum()函数。原创 2023-01-22 17:26:47 · 2635 阅读 · 0 评论 -
postgresql源码学习(51)—— 提交日志CLOG 原理 用途 管理函数
提交日志CLOG 原理 用途 管理函数原创 2022-11-30 15:11:19 · 1679 阅读 · 0 评论 -
postgresql源码学习(49)—— MVCC⑤-cmin与cmax 同事务内的可见性判断
cmin与cmax 同事务内的可见性判断原创 2022-11-20 23:02:23 · 1379 阅读 · 0 评论 -
postgresql源码学习(十九)—— MVCC④-可见性判断 HeapTupleSatisfiesMVCC函数
回顾一下前面提到的SNAPSHOT_MVCC类型快照的可见性判断条件:原创 2022-10-16 11:08:06 · 1784 阅读 · 3 评论 -
PostgreSQL回滚TRUNCATE操作的原理
下午大家在讨论pg可以回滚truncate操作,好奇原理是怎么样的,搜到的大部分文章只提到了“事务DDL”的概念,没有详细介绍。后来找到了这篇文章,翻译时有删改,原文参考一、 回滚原理与 Oracle 和 MySQL 等 RDB 不同,PostgreSQL 采用追记型架构(追記型アーキテクチャ)。简单来说,当更新行数据时,不会更新原始数据,而是将原始数据标记为已删除,并插入更新的数据。即使10列中只有1列要更新,也会插入10列数据。虽然可能会带来更新的性能问题,但它也更容易实现读一致性。.........原创 2022-08-31 22:31:53 · 5192 阅读 · 2 评论 -
postgresql源码学习(35)—— 检查点⑤-检查点中的XLog清理机制
前篇我们提到,检查点的工作之一是删除无用的日志文件,本篇我们来看看其中具体的计算和删除函数。前文中相关代码如下(在6. 删除无用的日志文件):postgresql源码学习(32)—— 检查点④-核心函数CreateCheckPoint_Hehuyi_In的博客-CSDN博客主要函数和宏定义如下 估算两次checkpoint之间产生的xlog量,主要用于后面XLOGfileslop函数的日志预分配。 如果上次估算量比这次实际产生的要小,则将估算值更新为这次产生的量。否则,按照原创 2022-08-07 12:30:47 · 2661 阅读 · 2 评论 -
postgresql源码学习(33)—— 事务日志⑨ - 从insert记录看日志写入整体流程
前面我们分开看了每一个步骤的具体函数,这里再通过一个简单insert语句的跟踪,来看看整体的流程。目前只看WAL相关的部分,因为insert整体涉及到非常多东西,有些是还没学习到的。原创 2022-07-30 15:06:33 · 1847 阅读 · 0 评论 -
postgresql源码学习(32)—— 检查点④-核心函数CreateCheckPoint
检查点④-核心函数CreateCheckPoint原创 2022-07-23 21:35:09 · 1987 阅读 · 0 评论 -
postgresql源码学习(28)—— 事务日志⑧ - 日志真正落盘函数 XLogWrite
XLogWrite是XLOG落盘的最底层函数,负责将XLOG真正写入磁盘。参数1表示请求写入的起点LSN,参数2表示是否灵活写入(If flexible == true, we don't have to write as far as WriteRqst)这个函数的细节较多,我们来慢慢分析,首先回顾几个概念 当一个物理文件写满之后,会写下一个。在实际落盘时,是以页面为单位进行落盘,所以在落盘前需要找到每个页面的起始位置,然后将整个页面进行落盘。综上所述,XLOG的落盘流程如下:原创 2022-07-09 21:47:00 · 2453 阅读 · 0 评论 -
postgresql源码学习(27)—— 事务日志⑦-日志落盘上层函数 XLogFlush
这两个结构体定义代码在xlog.c,它们在日志落盘过程中非常重要,会反反复复出现。Write与Flush的区别源码中关于这两个结构体的注释很长,值得关注的是: XLogFlush函数用于将record之前的所有XLog全部落盘,它是XLogWrite的上层函数,XLogWrite是真正的落盘函数,下一篇我们会讨论。 在上面三种情况中,最简单也是最可控的就是commit之前的XLOG落盘,为了方便调试排除其他干扰因素,我们需要首先将后台落盘的进程walwriter挂起,以免在c原创 2022-07-09 17:55:14 · 2412 阅读 · 0 评论 -
postgresql源码学习(25)—— 事务日志⑥-等待日志完成WAL Buffer写入
前篇我们留下了两个问题:第一个问题很直观,主要是第二个。首先我们回顾一下日志写入的两个核心流程:来考虑这样一种场景:时间点事务A事务B1预留空间,获取EndPos_A 2 预留空间,获取EndPos_B3 将数据全部复制入WAL Buffer4 执行commit 此时应该将EndPos_B之前的日志全部刷盘5将数据全部复制入WAL Buffer 所以,在调用XLogWrite进行XLOG刷盘之前,都需要调用WaitXLogInsertionsToFinish。那它怎么样判断指定位置之前是否还有XLOG原创 2022-06-27 14:13:17 · 1990 阅读 · 0 评论 -
postgresql源码学习(24)—— 事务日志⑤-日志写入WAL Buffer
日志写入WAL Buffer的过程分为两步:你可能会疑惑:为什么数据复制的并发度只设为8?如果设大会有什么问题吗? 这个问题的答案在WaitXLogInsertionsToFinish函数(除此之外它还要解决另一个非常重要的问题),我们后面会学习它。 简单来说,每次WAL刷入磁盘,都会调用这个函数,而这个函数需要遍历所有WALInsertLocks,所以NUM_XLOGINSERT_LOCKS不宜过大,目前代码中写死为8。 如前所述,这个代码最重要就干两件事:原创 2022-06-24 16:37:21 · 2299 阅读 · 0 评论 -
postgresql源码学习(23)—— 事务日志④-日志组装
前篇最后提到,日志注册之后XLOG填充进度为(红色暂无数据、绿色已有数据):XLogRecord+XLogRecordBlockHeader+RelFileNode+BlockNumber + mainrdata_len(XLogRecordDataHeaderShort 或 XLogRecordDataHeaderLong) +xl_heap_header(block data) + 实际元组数据 + xl_heap_insert(main data) 日志组装函数XLogRecordAss原创 2022-06-23 17:50:57 · 2073 阅读 · 0 评论 -
postgresql源码学习(22)—— 事务日志③-日志的注册
从功能上看从对应函数来看本节主要介绍日志注册(蓝色)部分。 这俩名字很像,registered_buffers是一个数组,其中的每个元素由registered_buffer结构体组成。该数组用于注册被修改的页面信息,XLogRegisterBuffer函数每注册一个页面时,会在其中占用一个槽位。 rdatas是一个数组,其中的每个元素由XLogRecData结构体组成。事务日志并不直接写入WAL Buffer,而是先将XLogRecData组成链表,然后将此链表转为一条事务日志。原创 2022-06-04 12:59:18 · 2237 阅读 · 0 评论 -
postgresql源码学习(21)—— 事务日志②-日志初始化
我们知道,WAL日志并不是实时刷盘的,pg在共享内存中分配了XLOG BUFFER缓存日志页。当要写入日志记录时,会先写入XLOG BUFFER,而在这之前,首先要干的是先为事务日志申请共享内存,以及一些重要结构体的初始化。本节主要内容如下: 用户可以通过wal_buffers参数来指定XLOG BUFFER中缓存页面的数量。wal_buffers默认值为-1,表示pg通过启发式算法(XLOGChooseNumBuffers函数)计算出需要缓存页面的数量。 除了XLOG BUFFER原创 2022-06-04 12:47:18 · 2360 阅读 · 0 评论 -
postgresql源码学习(二十)—— 事务日志①-日志格式
关于WAL日志的一些基础知识,可以参考之前的文章,本篇侧重于源码部分。pg 崩溃恢复篇(一)—— WAL的作用与全页写机制_Hehuyi_In的博客-CSDN博客_pg walpg 崩溃恢复篇(二)—— WAL文件结构及管理_Hehuyi_In的博客-CSDN博客_wal文件 来看这个图层次比较多,具体来看以下按照代码中出现的先后顺序排列 日志段其他页的Header信息(除第一个页外每个日志页都有一个,图中浅蓝色部分),存放事务日志对应的版本、时间线等信息。跨页访问类似于再原创 2022-06-04 11:55:45 · 2894 阅读 · 0 评论 -
postgresql源码学习(十八)—— MVCC③-创建(获取)快照
一、 GetTransactionSnapshot函数 GetTransactionSnapshot函数中,通过FirstSnapshotSet标志来判断当前要获得的是不是事务的第一个快照。如果是,则通过GetSnapshotData获得快照并将快照缓存。在已提交读隔离级别下,直接返回获得的快照;在可重复读及串行化隔离级别下,返回缓存的快照(就是前一篇介绍的源码实现方法)。函数主要流程图如下:SnapshotGetTransactionSnapshot(void){ ...原创 2022-05-28 21:59:45 · 2579 阅读 · 0 评论 -
postgresql源码学习(十七)—— MVCC②-快照与隔离级别简介
一、 快照简介 快照是记录数据库当前瞬时状态的一个数据结构。pg的快照主要保存:当前所有活跃事务的最小、最大事务ID、当前活跃事务列表、commandID等。 快照可以分为多种类型,每种快照类型都对应了一种判断元组可见性的方法。二、 快照结构体1. 结构体定义typedef struct SnapshotData *Snapshot;typedef struct SnapshotData{ SnapshotType snapshot_type;...原创 2022-05-25 23:16:44 · 2781 阅读 · 0 评论 -
postgresql源码学习(十六)—— MVCC①-元组上的版本信息
关于元组的基础知识,曾经在 pg事务篇(一)—— 事务与多版本并发控制MVCC_Hehuyi_In的博客-CSDN博客_pg 事务 中介绍过,本篇主要侧重于源码和实验部分。一、 页与元组的组织结构1. 页的组织结构 pg数据库采用页面存储的方式,每个表都会有多个页面,每页大小是8K。 页从前往后保存头信息(Header Info,绿色部分)、元组偏移量(红色部分);从后往前存放元组信息(灰色的tuple);中间为页面空闲空间(Free Space...原创 2022-05-21 23:05:58 · 2238 阅读 · 0 评论 -
postgresql源码学习(六)—— 回滚(中止)与清理事务
一、 AbortTransaction1. gdb测试会话1会话22. 具体代码与跟踪调用栈如下static voidAbortTransaction(void){ TransactionState s = CurrentTransactionState; TransactionId latestXid; bool is_parallel_worker; /* Prevent cancel/die interrupt while cleani原创 2022-05-09 23:40:04 · 3215 阅读 · 2 评论 -
postgresql源码学习(五)—— 提交事务
结束事务分为两类:提交:CommitTransaction 回滚:AbortTransaction一、 CommitTransaction1. 流程图2. 提交和刷盘步骤 上面流程图里最重要的是事务日志写回磁盘部分:RecordTransactionCommit(),保证已提交数据不会丢失。if ((wrote_xlog && markXidCommitted && synchronous_commit > SYN...原创 2022-05-07 23:13:31 · 4065 阅读 · 0 评论 -
postgresql源码学习(四)—— 启动事务
一、 虚拟事务 前篇我们说到,执行dml操作时,才会为事务分配事务id。不过,即使没有事务id,事务也会用一个虚拟事务id来代表自己。 虚拟事务id由两部分组成:backendId(后台进程id,会话独有)+ localTransactionId(进程维护的本地事务id),以下结构体代码在 lock.htypedef struct{ BackendId backendId; /* backendId from PGPROC */ LocalTransaction...原创 2022-05-07 18:53:51 · 3610 阅读 · 0 评论 -
postgresql源码学习(三)—— 事务ID分配
一、 事务状态与事务栈1.事务状态注意区分pg中事务块和事务的概念pg中事务块:DB理论中的事务 pg中事务:事务块中sql语句因此这里说的事务状态是指,底层事务(事务块中sql语句)真正的状态typedef enum TransState{ TRANS_DEFAULT, /* idle */ TRANS_START, /* transaction starting */ TRANS_INPROGRESS,...原创 2022-05-07 18:38:59 · 3309 阅读 · 4 评论 -
postgresql源码学习(二)—— 事务块状态转换
一、 简单介绍事务块:begin标志事务块开始,commit(end)、rollback(abort) 等标志事务块结束事务块的各种状态定义在xact.c文件typedef enum TBlockState 部分,注意事务块的状态和事务的状态是不一样的(后篇会学习事务的状态)typedef enum TBlockState{ /* not-in-transaction-block states */ TBLOCK_DEFAULT, /* idle */ TBLOCK_STARTED,原创 2022-05-01 11:27:06 · 3195 阅读 · 0 评论 -
pg事务篇(三)—— 事务状态与Hint Bits(t_infomask)
一、 引入背景前篇(https://blog.csdn.net/Hehuyi_In/article/details/102868231)提到,clog日志记录了事务的四种状态。当需要获取事务状态时,pg可以通过调用三个内部函数——TransactionIdIsInProcess、TransactionIdDidCommit和TransactionIdDidAbort,读取CLOG返回所请求...原创 2019-11-10 18:27:16 · 2930 阅读 · 0 评论 -
Oracle 嵌套事务 VS 自治事务
一、概念嵌套事务(Nested Transaction):指在主事务(MT)中嵌套的一个或多个子事务,并且子事务与主事务相互影响。自治事务(Autonomous Transaction):由主事务调用但又独立于主事务,子事务对commit和rollback进行自治管理,不影响主事务执行效果。常用于写入LOG或TRACE信息便于查找错误。二、嵌套事务1.预备Create TablecreatetableTEST_POLICY(POLICY_CODE...原创 2020-09-25 00:05:17 · 2152 阅读 · 0 评论 -
MySQL InnoDB锁类型小结
(一)先说明一下定义:1. 读现象(Read phenomena):SQL 92标准规定了3种不同的读现象。脏读、不可重复读和幻读。分别解释一下。1.1 脏读:A dirty read (aka uncommitted dependency) occurs when a transaction is allowed to read data from a row that has be...原创 2020-04-07 01:10:40 · 1590 阅读 · 0 评论 -
sqlserver 为什么事务失败没有回滚
初学数据库便知道,事务应该有原子性:要求事务要么全部完成,要么全部不完成,不能停滞在某个中间状态。然而,在下面的例子中事务却没有完全“回滚”,导致了异常数据的发生,为什么?一、 问题复现CREATE TABLE [dbo].[test1]([id] [int] NOT NULL,[testname] [varchar](10) NULL) ON [PRIMARY]现在执行一个事...转载 2020-01-17 16:40:58 · 3542 阅读 · 1 评论 -
pg 崩溃恢复篇(一)—— WAL的作用与全页写机制
WAL(Write Ahead Log)机制最初在7.1版中实现,以减轻服务器崩溃的影响。它也是基于时间点恢复(PITR)和流复制(SR)实现的基础。WAL机制非常复杂,在第一篇中,我们只看看为什么需要WAL,它有什么作用,又会有什么不足。一、没有WAL的插入操作要看为什么需要有WAL,那就先看看如果没有会怎么样。假设我们TABLE_A中插入一些数据,这些数据没有使用WAL功能...原创 2019-11-12 15:21:44 · 4542 阅读 · 0 评论 -
pg事务篇(二)—— 事务ID回卷与事务冻结(freeze)
一、 什么是事务ID回卷前篇文章留下了一个问题,旧事务不应看见新事务修改结果,txid通过比较大小来判断是否可见,任何事务只可见txid<其自身txid的事务修改结果。但txid是无符号的32位整型,它并不是无限的,当42亿数据用尽之后又应该如何判断可见性?https://blog.csdn.net/Hehuyi_In/article/details/102868231pg将txid空...原创 2019-11-02 16:12:16 · 9089 阅读 · 3 评论 -
pg事务篇(一)—— 事务与多版本并发控制MVCC
一、 MVCC常用实现方法一般MVCC有2种实现方法:写新数据时,把旧数据快照存入其他位置(如oracle的回滚段、sqlserver的tempdb)。当读数据时,读的是快照的旧数据。 写新数据时,旧数据不删除,直接插入新数据。PostgreSQL就是使用的这种实现方法。1. PostgreSQL的MVCC实现方式优缺点优点无论事务进行了多少操作,事务回滚可以立即完成 数据可...原创 2019-11-02 11:13:38 · 5771 阅读 · 0 评论