PostgreSQL · 源码分析 · 回放分析(一)
在数据库运行中,源码可能遇到非预期问题,分析如断电、源码崩溃。分析这些情况可能导致数据异常或丢失,源码影响业务。分析照片墙源码大全为了在数据库重启时恢复到崩溃前状态,源码确保数据一致性和完整性,分析我们引入了WAL(Write-Ahead Logging)机制。源码WAL记录数据库事务执行过程,分析当数据库崩溃时,源码利用这些记录恢复至崩溃前状态。分析
WAL通过REDO和UNDO日志实现崩溃恢复。源码REDO允许对数据进行修改,分析UNDO则撤销修改。源码REDO/UNDO日志结合了这两种功能。除了WAL,还有Shadow Pagging、WBL等技术,但WAL是主要方法。
数据库内部,日志管理器记录事务操作,缓冲区管理器负责数据存储。当崩溃发生,恢复管理器读取事务状态,回放已提交数据,回滚中断事务,恢复数据库一致性。ARIES算法是日志记录和恢复处理的重要方法。
长时间运行后崩溃,可能需要数小时甚至数天进行恢复。检查点技术在此帮助,同城麻将源码将脏数据刷入磁盘,记录检查点位置,确保恢复从相对较新状态开始,同时清理旧日志文件。WAL不仅用于崩溃恢复,还支持复制、主备同步、时间点还原等功能。
在记录日志时,WAL只在缓冲区中记录,直到事务提交时等待磁盘写入。LSN(日志序列号)用于管理,只在共享缓冲区中检查。XLog是事务日志,WAL是持久化日志。
崩溃恢复中,checkpointer持续做检查点,加快数据页面更新,提高重启恢复速度。在回放时,数据页面不断向前更新,直至达到特定LSN。
了解WAL格式和包含信息有助于理解日志内容。PG社区正在实现Zheap特性,改进日志格式。WAL文件存储在pg_wal目录下,大小为1GB,与时间线和LSN紧密关联。事务日志与WAL段文件相关联,根据特定LSN可识别文件名和位置。
使用pg_waldump工具可以查看日志内容,ceres源码分析理解一次操作记录。日志类型包括Standby、Heap、Transaction等,对应不同资源管理器。PostgreSQL 包含种资源管理器类型,涉及堆元组、索引、序列号操作。
标准记录流程包括:读取数据页面到frame、记录WAL、进行事务提交。插入数据流程生成WAL,复杂修改如索引分裂需要记录多个WAL。
崩溃恢复流程从控制文件中获取检查点位置,严格串行回放至崩溃前状态。redo回放流程与记录代码高度一致。在部分写问题上,FullPageWrite(FPW)策略记录完整数据页面,防止损坏。WAL错误导致部分丢失不影响恢复,数据库会告知失败。磁盘静默错误和内存错误需通过冗余校验解决。
本文总结了数据库崩溃恢复原理,以及PostgreSQL日志记录和崩溃恢复实现。深入理解原理可提高数据库管理效率。下文将详细描述热备恢复和按时间点还原(PITR)方法。
Java问题解决录: 运行时抛出NoSuchMethodError / NoSuchFieldError异常
现象描述
在IDE中编译运行程序无异常,但在打包成可运行的jar包(如Spring Boot jar包)后,程序运行时会抛出NoSuchMethodError或NoSuchFieldError异常。
问题定位步骤
通过增加JVM参数如-verbose:class、通讯协议源码-XX:+TraceClassLoading或-Xlog:class+load=debug来查看类的加载情况。使用Arthas工具的jad命令可以查看已加载类的源码,从而查看类的加载路径、jar包版本号及使用的类加载器。
问题分类
问题可能源自三个主要方面:
1. **重复类定义**:在同包中或不同jar包中定义了同名类,导致类加载器加载了错误的类。这类问题通常发生在第三方jar包与项目自身的jar包中。
2. **依赖版本冲突**:maven的传递依赖特性可能导致多个版本的类被加载,最终生效的版本可能导致NoSuchMethodError或NoSuchFieldError异常。根据maven的广度优先遍历算法,高版本或低版本的类可能覆盖了其他版本的类。
3. **反射机制错误**:使用反射时,如果类定义错误或传递参数错误,也可能导致运行时异常。目前尚无自动检测这类错误的工具。
编译期发现方法
对于使用maven的项目,可以配置额外的enforcer-rules(如Ban Duplicate Classes规则)来在编译期间强制发现重复类定义的问题。对于使用Android Studio(Gradle工具)的项目,这类编译错误提示较为常见。
总结
通过增加JVM参数、使用Arthas工具、分析maven依赖树和代码中的反射使用情况,可以有效地定位和解决NoSuchMethodError或NoSuchFieldError异常。确保类定义的唯一性、避免依赖版本冲突以及正确使用反射机制是预防此类异常的关键。
微信xlog文件怎么打开?
微信xlog文件可以使用记事本或文本编辑器打开。详细解释如下:
一、微信xlog文件简述
微信xlog文件是微信应用产生的日志文件,记录了应用的使用情况和某些操作细节。这些文件一般以文本形式存储,包含了用户在微信上的点红人源码活动信息。
二、使用文本编辑器打开xlog文件
由于xlog文件通常为文本格式,我们可以使用任何文本编辑器来打开它。比如Notepad++、Sublime Text、Atom等文本编辑器都是不错的选择。打开文本编辑器后,通过“打开”功能,定位到xlog文件所在位置,选择文件后打开即可。
三、使用记事本打开xlog文件
除了文本编辑器,Windows系统自带的记事本程序也可以打开xlog文件。与打开其他文本文件一样,右击xlog文件,选择“打开方式”,然后选择“记事本”,即可打开并查看文件内容。
四、文件内容解读
打开xlog文件后,你会看到大量的文本信息。这些信息可能包括日期、时间、操作记录等。由于这是日志文件,如果你不是专业人士,可能不容易理解所有内容。但基本的文件结构和信息应该能够反映出微信的使用情况。
请注意,处理日志文件时要小心,确保不会修改或删除其中的内容,因为这些文件对于理解应用行为和解决可能出现的问题非常重要。如果不确定如何处理这些文件,建议保留原样,不要随意更改。
解析XLog:使用python通过外部解析XLog
初衷就是想深入xlog内部,想具体看一看wal内部到底存储着什么内容,为什么可以通过wal日志恢复所有的数据信息,包括为什么他可以实现主从复制等一系列操作
最终目的:拆解wal日志
我们可以使用pg_waldump查看wal信息
初始化XLOG的函数入口为BootStrapXLOG
这个函数只会在初始化的时候调用一次,用来创建控制文件和初始化XLOG segment。
我们先看看第一个XLOG文件名称生成:
所以最大的XLOG文件名称为:FFFFFFFFFF,而不是理论上的FFFFFFFFFFFFFFFF,因为uint % 最大是FF。
初始化第一个timelineID = 1
还是在xlog.c这个文件中说明创建这个文件之间会先创建一个临时文件,
pg_wal/xlogtemp.xxxxxxx("xlogtemp."加个当前进程PID),避免其他process来搞事情,然后循环写入每次写入XLOG_BLOCKSZ个字节
写完后文件大小为M
刚才创建的文件其实是一个空文件,随后通过durable_link_or_rename进行rename。
到这里,XLOG就创建完成了,不过这个文件还是空空如也
首先写入的是XLOG的头(XLogPageHeader)。
这个page_magic也可以用来验证是否是 一个page的开头
每个XLogSegment的第一个page头会写入XLogLongPageHeaderData,结构体如下:
结果如下:
这个page的前个字节就是XLogLongPageHeaderData。写入完之后整个的XLOG_SEGMENT的结构如下图所示:
但是 有一个问题 就是为什么是B?这里先按下不表,后面解析的时候会遇到问题。
日志之间有链接关系,xl_prev指向上一条日志的起始位置,下一条日志的位置用xl_tot_len可以找到,日志之间形成“双向链表”。
typedef struct XLogRecord{
日记长度
uintxl_tot_len;/* total len of entire record */
事务ID
TransactionId xl_xid;/* xact id */
上一条日志的LSN
XLogRecPtrxl_prev;/* ptr to previous record in log */
产生这个记录的动作
uint8xl_info;/* flag bits, see below */
日志记录对应的资源管理器
RmgrIdxl_rmid;/* resource manager for this record */
/* 2 bytes of padding here, initialize to zero */
pg_crccxl_crc;/* CRC for this record */
/* XLogRecordBlockHeaders and XLogRecordDataHeader follow, no padding */
日志的数据信息} XLogRecord;
xl_info低4位保存flag信息,高4位保存日志动作信息。
资源管理器的定义如下所示:
typedef struct RmgrData {
const char *rm_name; // 资源名称
void(*rm_redo) (XLogReaderState *record); // 重做函数
void(*rm_desc) (StringInfo buf, XLogReaderState *record); // 负责解析对应资源事务日志
const char *(*rm_identify) (uint8 info); // 解析xlog记录中的Info字段
void(*rm_startup) (void); // 启动时的初始化工作
void(*rm_cleanup) (void); // 结束时的清理工作
void(*rm_mask) (char *pagedata, BlockNumber blkno); // 在对页面做一致性检查前,是否需要对页面的某些部分做掩码} RmgrData;
据xlog中的xl_rmid调用资源管理器中不同资源的rm_redo回放函数进行回放。
在 PostgreSQL 内核中,rmgrlist.h 文件定义了各种类型的 rmgr(record manager),每个 rmgr 对应一个不同的数据库操作。这些 rmgr 在事务日志(XLog)中起着重要作用,用于记录不同类型的数据库操作,以便在之后的恢复过程中重做(redo)或撤销(undo)这些操作。
heap_mask 函数是 PostgreSQL 内核中用于在执行一致性检查之前对堆页(heap page)进行掩码处理的函数。在执行恢复操作时,数据库会读取 XLog 记录中的内容,并应用到对应的数据页上。为了保证恢复的正确性,必须对数据页进行一致性检查,而 heap_mask 就是用于在执行这些检查之前,对数据页进行掩码处理,从而屏蔽掉不应该参与一致性检查的部分。
以下是 heap_mask 函数的主要功能:
在实现WAL一致性检查功能时,只有涉及数据表的RMGR才需要使用Mask Function,而对于其他类型的RMGR,由于其重做操作本身已经保证了数据的正确性,因此不需要添加Mask Function。
通过区分需要Mask的RMGR和不需要Mask的RMGR,可以在WAL一致性检查过程中准确地找出可能导致数据不一致的地方,并对数据库的一致性进行严格的验证。这样,复制过程中出现的潜在问题可以及早被检测出来,并及时处理,保障数据库系统的可靠性和稳定性。
结果展示
解析wal日志
为什么XLogLongPageHeaderData 一搜都是B? 仔细阅读源码,发现问题
在XLogPageHeaderData底下出现了这个定义
这一块定义了XLogPageHeaderData的长度
分析一下 MAXALIGN---其实读英文名就可以知道 他的意思是对齐 最大
这个上面的内容就是 PG内部做了一个对齐宏,类似于 只要是PG内部的东西 基本上就按照这个对齐宏走
其中 MAXIMUM_ALIGNOF 这个是获得当前编译器中占最大位的基本类型,比如long long类型
取得的long long类型的大小为8BYTE,所以在这个宏定义当中,MAXIMUM_ALIGNOF=8
MAXALIGN 的作用其实就是为了使sizeof( struct )向上对齐,成为8的倍数的大小
思考为什么会有rem等问题,如果这个操作的tuple内容很多怎么办,或者当前record没有填满怎么办
他会根据逻辑地址算出物理插入地址,也就是说,物理地址并不会像逻辑地址那样整齐排列。
拿到对应的info后,应该怎么判断它属于什么操作,增删改查?
读取wal
openGauss数据库源码解析系列文章——事务机制源码解析(一)
事务是数据库操作的核心单位,必须满足原子性、一致性、隔离性、持久性(ACID)四大属性,确保数据操作的可靠性与一致性。以下是openGauss数据库中事务机制的详细解析:
### 事务整体架构与代码概览
在openGauss中,事务的实现与存储引擎紧密关联,主要集中在源代码的`gausskernel/storage/access/transam`与`gausskernel/storage/lmgr`目录下。事务系统包含关键组件:
1. **事务管理器**:事务系统的中枢,基于有限循环状态机,接收外部命令并根据当前事务状态决定下一步执行。
2. **日志管理器**:记录事务执行状态及数据变化过程,包括事务提交日志(CLOG)、事务提交序列日志(CSNLOG)与事务日志(XLOG)。
3. **线程管理机制**:通过内存区域记录所有线程的事务信息,支持跨线程事务状态查询。
4. **MVCC机制**:采用多版本并发控制(MVCC)实现读写隔离,结合事务提交的CSN序列号,确保数据读取的正确性。
5. **锁管理器**:实现写并发控制,通过锁机制保证事务执行的隔离性。
### 事务并发控制
事务并发控制机制保障并发执行下的数据库ACID属性,主要由以下部分构成:
- **事务状态机**:分上层与底层两个层次,上层状态机通过分层设计,支持灵活处理客户端事务执行语句(BEGIN/START TRANSACTION/COMMIT/ROLLBACK/END),底层状态机记录事务具体状态,包括事务的开启、执行、结束等状态变化。
#### 事务状态机分解
- **事务块状态**:支持多条查询语句的事务块,包含默认、已开始、事务开始、运行中、结束状态。
- **底层事务状态**:状态包括TRANS_DEFAULT、TRANS_START、TRANS_INPROGRESS、TRANS_COMMIT、TRANS_ABORT、TRANS_DEFAULT,分别对应事务的初始、开启、运行、提交、回滚及结束状态。
#### 事务状态转换与实例
通过状态机实例展示事务执行流程,包括BEGIN、SELECT、END语句的执行过程,以及相应的状态转换。
- **BEGIN**:开始一个事务,状态从默认转为已开始,之后根据语句执行逻辑状态转换。
- **SELECT**:查询语句执行,状态保持为已开始或运行中,事务状态不发生变化。
- **END**:结束事务,状态从运行中或已开始转换为默认状态。
#### 事务ID分配与日志
事务ID(xid)以uint单调递增序列分配,用于标识每个事务,CLOG与CSNLOG分别记录事务的提交状态与序列号,采用SLRU机制管理日志,确保资源高效利用。
### 总结
事务机制在openGauss数据库中起着核心作用,通过详细的架构设计与状态管理,确保了数据操作的ACID属性,支持高并发环境下的高效、一致的数据处理。MVCC与事务ID的合理使用,进一步提升了数据库的性能与数据一致性。未来,将深入探讨事务并发控制的MVCC可见性判断机制与进程内的多线程管理机制,敬请期待。
èè微信 Xlog
åæ¥å°å
æ¬æä»ç» MARS xlog 使ç¨ä»¥å使ç¨è¿ç¨ä¸è¸©è¿çå
xlog æ¯å¾®ä¿¡å¼æºæ¡æ¶ MARS çä¸é¨å, å¤çåºç¨æ¥å¿
微信ç对 xlog çä»ç»ææ¡£--ã 微信ç»ç«¯è·¨å¹³å°ç»ä»¶ mars ç³»åï¼ä¸ï¼ - é«æ§è½æ¥å¿æ¨¡åxlog) ã
æ»ç»åºæ¥å°±æ¯
MARS ç GitHub ä¸ä»ç»æ¯è¾è¯¦ç»,
å è·èµ·æ¥ä¸ä¸ª Demo ä¹å, éè¦æ·±å ¥äºè§£ä¸ä¸
mmap æ¯ä¸ç§å åæ å°æ件çæ¹æ³ï¼å³å°ä¸ä¸ªæ件æè å ¶å®å¯¹è±¡æ å°å°è¿ç¨çå°å空é´ï¼å®ç°æ件ç£çå°ååè¿ç¨èæå°å空é´ä¸ä¸æ®µèæå°åçä¸ä¸å¯¹æ å ³ç³»ãå®ç°è¿æ ·çæ å°å ³ç³»åï¼è¿ç¨å°±å¯ä»¥éç¨æéçæ¹å¼è¯»åæä½è¿ä¸æ®µå åï¼èç³»ç»ä¼èªå¨ååè页é¢å°å¯¹åºçæ件ç£çä¸ï¼å³å®æäºå¯¹æ件çæä½èä¸å¿ åè°ç¨read,writeçç³»ç»è°ç¨å½æ°ãç¸åï¼å æ ¸ç©ºé´å¯¹è¿æ®µåºåçä¿®æ¹ä¹ç´æ¥åæ ç¨æ·ç©ºé´ï¼ä»èå¯ä»¥å®ç°ä¸åè¿ç¨é´çæä»¶å ±äº«ã
æ£å¦å¾®ä¿¡çä»ç»æç« ä¸æ说ç:
mmap æ¯ä½¿ç¨é»è¾å å对ç£çæ件è¿è¡æ å°ï¼ä¸é´åªæ¯è¿è¡æ å°æ²¡æä»»ä½æ·è´æä½ï¼é¿å äºåæ件çæ°æ®æ·è´ãæä½å åå°±ç¸å½äºå¨æä½æ件ï¼é¿å äºå æ ¸ç©ºé´åç¨æ·ç©ºé´çé¢ç¹åæ¢ã
mmapå ä¹åç´æ¥åå åä¸æ ·çæ§è½ï¼èä¸ mmap æ¢ä¸ä¼ä¸¢æ¥å¿ï¼ååæ¶æºå¯¹æ们æ¥è¯´ååºæ¬å¯æ§ã
ä¸æä¸æå ³äºè¯¥æ¹æ³çæºç åæ, æ»ç»æ¥è¯´
å 为 Android ææº CPU æ¶æçå·®å¼, å¯è½ä¼æå¾å¤çæ¬ç so æ件, å¦æä½ æ¯ä½¿ç¨æ¬å°ç¼è¯ xlog ç, ä½ åºè¯¥æ³¨æ对åºä¸å CPU æ¶æç¼è¯ä¸åç so æ件
æ¬å°ç¼è¯ç so æ件æ¾å¨ src/jniLibs ç®å½ä¸, AS å¯ä»¥èªå¨ç¼è¯å° apk ä¸
æçå主è¦æ¯å 为 xposed çåå , åå¼å§ Demo å¾é¡ºå©, æ¥å ¥å°é¡¹ç®ä¸é®é¢å°±ä¸ä¸ªä¸ªç
ä¸æ以åæå°ä¼å¨åªéå è½½ so æ件, ä½æ¯ç±äº xposed çåå , Classloader æåçæ件为 /data/app/io.communet.ichater-2/base.apk , ä¸è½æ¾å°æå®ç so æ件, æ以éè¦æå®ç»å¯¹è·¯å¾
解å³:
微信ææå°å ³äºæ¥å¿åæ¥åå¼æ¥ä¸¤ç§åå ¥æ¹å¼ä»¥åæ¥å¿æ件çåå¨ä½ç½®
å®é è¿è¡ä¸åç°, å½åæ¥åå ¥æ¶, æ¥å¿æ件å¼å§ä¼è¢«åæ¾å¨ cacheDir, ä¸æ®µæ¶é´å, ä¼è¢«æ¾å° logDir, ä½æ¯å¼æ¥æ¨¡å¼ä¸, æ件ä¸ç´æ¾å¨ cacheDir, å³ä¾¿è°ç¨ appenderFlush æ¹æ³, æ¥å¿ä¼ä» mmap ä¸åå ¥æ件, ä½æ¯æ件çä½ç½®è¿æ¯å¨ cacheDir, å½ç¶, åºç¨æ读å SDCard çæé
解å³:
该é®é¢è¿æªæ¥æåå , ç®åç解å³æ¹æ³æ¯ä¸ç» cacheDir, æ件ä¼è¢«ç´æ¥æ¾å° logDir, ä½æ¯, å®æ¹è¯´å¦æä¸ç» cacheDir, å¯è½åºç° SIGBUS, åè§ issue#
/4/æ´æ°: 解å³äº, 说起æ¥é½ææ§, è¿æä¸ä¸ªåæ°
å°è¯¥å¼è®¾ç½®ä¸º 0 å³å¯, ä¹å以为è¿ä¸ªå¼è¡¨ç¤ºçæ¯ç¼åæ¥å¿ä¿åç天æ°, è®¾ç½®äº 7, å®é ä¸ä¿çç¼åæ¥å¿ç天æ°é»è®¤ 天, æ¸ çé»è¾å¦ä¸
注æåä¸æä¸çé£ä¸ª BUG åºå, è¿éæ¯å ä¸ºç¨ ä½ç so ä»£æ¿ ä½ç so 导è´ç
解å³:
jniLibs ä¸é¢ä¸è¦æ¾ ä½ç, åªæ¾ ç, å¯ä»¥å ¼å®¹
è¿æåçè¯ç»§ç»æ´æ°
2024-12-01 00:22
2024-11-30 23:08
2024-11-30 22:10
2024-11-30 22:05
2024-11-30 21:55