大云海山数据库(He3DB)源码详解:He3DB-MultiXactIdCreateFromMembers

42 阅读4分钟

大云海山数据库(He3DB)源码详解:He3DB-MultiXactIdCreateFromMembers

背景

大云He3DB 采用了先进的存储引擎和查询优化技术,能够快速处理大量数据和复杂查询。无论是 OLTP(在线事务处理)还是 OLAP(在线分析处理)场景,都能提供出色的性能表现。He3DB 具备完善的数据备份和恢复机制,能够在系统故障或数据损坏时快速恢复数据,确保业务的连续性。He3DB 支持水平扩展和垂直扩展,可以轻松应对不断增长的数据需求。He3DB 提供了严格的访问控制和数据加密功能,确保数据的安全性和隐私性。

本文基于大云He3DB,针对MultiXactIdCreateFromMembers进行源码解读分享

MultiXactIdCreateFromMembers

源码解读

MultiXactId
MultiXactIdCreateFromMembers(int nmembers, MultiXactMember *members)
{
	LOG_FUNCTION_ENTRY();
	MultiXactId multi; //用于存储新创建的 MultiXactId
	MultiXactOffset offset;//用于存储新分配的偏移量
	xl_multixact_create xlrec; //用于存储 XLOG 记录的结构体,记录多事务的创建信息

	debug_elog3(DEBUG2, "Create: %s",
				mxid_to_string(InvalidMultiXactId, nmembers, members));

	/*
如果缓存中已经存在相同的成员集合,则直接返回已存在的 MultiXactId,避免重复创建
	 */
	multi = mXactCacheGetBySet(nmembers, members);//检查本地缓存中是否已经存在相同的成员集合
	if (MultiXactIdIsValid(multi))//检查返回的 MultiXactId 是否有效
	{
		debug_elog2(DEBUG2, "Create: in cache!");
		LOG_FUNCTION_EXIT();
		return multi;
	}

	/* 确保成员中只有一个事务是更新事务(ISUPDATE_from_mxstatus 检查成员状态) */
	{
		int i = 0;
		bool		has_update = false;

		/*
		遍历所有成员,检查是否有多个更新事务。
		如果发现多个更新事务,抛出错误。
		如果只有一个更新事务,记录 has_update 为 true
		*/
		for (i = 0; i < nmembers; i++)
		{
			if (ISUPDATE_from_mxstatus(members[i].status))
			{
				if (has_update) {
					elog(ERROR,
					     "new multixact has more than one updating member: %s",
					     mxid_to_string(InvalidMultiXactId, nmembers, members));
				}
				else {
					HE3_LOG_PRINT("he3db file %s func %s line %d if statement no else",
						      __FILE__, __FUNCTION__,
						      __LINE__);
				}
				has_update = true;
			}
		}
	}

	multi = GetNewMultiXactId(nmembers, &offset); //分配一个新的 MultiXactId 和对应的偏移量范围

	/* 创建 XLOG 记录 */
	xlrec.mid = multi;
	xlrec.moff = offset;
	xlrec.nmembers = nmembers;
	XLogBeginInsert();
	XLogRegisterData((char *) (&xlrec), SizeOfMultiXactCreate);
	XLogRegisterData((char *) members, nmembers * sizeof(MultiXactMember));
	(void) XLogInsert(RM_MULTIXACT_ID, XLOG_MULTIXACT_CREATE_ID);//将 XLOG 记录写入 WAL 日志


	/* 将多事务信息写入 OFFSET 和 MEMBER 日志文件 */
	RecordNewMultiXact(multi, offset, nmembers, members);

	END_CRIT_SECTION();

	/*将新创建的多事务 ID 和成员信息存入本地缓存*/
	mXactCachePut(multi, nmembers, members);

	debug_elog2(DEBUG2, "Create: all done");

	LOG_FUNCTION_EXIT();
	return multi;//返回新创建的 MultiXactId
}

函数流程图

该函数流程图如下所示:

请添加图片描述

流程图解释

  1. 开始

    • 函数开始执行。
  2. 检查缓存

    • 尝试从本地缓存中查找是否存在相同的成员集合。
  3. 缓存中是否存在相同的成员集合?

    • 如果存在,直接返回缓存中的 MultiXactId,结束流程。
    • 如果不存在,继续执行。
  4. 验证成员

    • 检查成员集合是否合法(例如,是否只有一个更新事务)。
  5. 成员中是否只有一个更新事务?

    • 如果是,继续执行。
    • 如果不是,抛出错误,结束流程。
  6. 分配新的 MultiXactId 和偏移量

    • 生成新的 MultiXactId 和偏移量。
  7. 记录 XLOG

    • 将新的 MultiXactId 和成员信息记录到 XLOG(WAL 日志)。
  8. 记录到 OFFSETs 和 MEMBERs 日志

    • 将信息写入到 OFFSETs 和 MEMBERs 文件。
  9. 结束关键段

    • 结束关键段,确保操作的原子性。
  10. 更新本地缓存

    • 将新的 MultiXactId 和成员信息存储到本地缓存。
  11. 返回新的 MultiXactId

    • 函数返回新创建的 MultiXactId
  12. 结束

    • 函数执行完成。

函数调用栈

通过source insight可以查看函数的调用栈

source insight安装流程可以参考这篇文章:Source insight 工具安装及使用方法

总结

本文基于大云He3DB,针对MultiXactIdCreateFromMembers 进行源码解读分享。

MultiXactIdCreateFromMembers 函数的主要逻辑如下: 检查本地缓存中是否已经存在相同的成员集合,避免重复创建。 验证成员中是否只有一个更新事务,确保多事务的合法性。 分配新的 MultiXactId 和偏移量。 创建 XLOG 记录,描述新创建的多事务。 将多事务信息写入 OFFSET 和 MEMBER 日志文件。 将新创建的 MultiXactId 存入本地缓存,提高后续查找的效率。 这个函数的关键在于处理并发问题,确保多事务的创建过程是线程安全的,并通过缓存机制提高性能。

其余文章参考链接

大云海山数据库(He3DB)源码详解:He3DB-CLOG日志管理器函数之TransactionIdSetTreeStatus

大云海山数据库(He3DB)+AI(五):一种基于强化学习的数据库旋钮调优方法

大云海山数据库(He3DB)+AI(四):一种基于迁移学习的启发式数据库旋钮调优方法

大云海山数据库(He3DB)源码解读:海山PG 词法、语法分析

大云海山数据库(He3DB)源码详解:海山PG 空闲空间映射表FSM

大云海山数据库(He3DB)源码详解:主备复制SyncRepWaitForLSN

作者信息

公司职位
中移苏研助理软件研发工程师