当前位置: 首页 > news >正文

【 OpenGauss源码学习 —— 列存储(CStore)(六)】

列存储(CStore)(六)

  • 概述
  • CStore::GetCUDataFromRemote 函数
  • CStore::CheckConsistenceOfCUDescCtl 函数
  • CStore::CheckConsistenceOfCUDesc 函数
  • CStore::CheckConsistenceOfCUData 函数
  • 额外补充

声明:本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的知识产权和学术成果,力求遵循合理使用原则,并在适用的情况下注明引用来源。
本文主要参考了 OpenGauss1.1.0 的开源代码和《OpenGauss数据库源码解析》一书以及OpenGauss社区学习文档和一些学习资料

概述

  本章我们继续在【 OpenGauss源码学习 —— 列存储(CStore)(五)】的基础上进行进一步学习,本文将主要介绍 CStore 类中剩余的各别私有成员函数。

CStore::GetCUDataFromRemote 函数

  CStore::GetCUDataFromRemote 函数主要用于压缩列存储引擎CStore)中远程加载压缩单元CU)的数据。它通过从缓存中获取 CU 缓冲区,检查是否需要重用内存,并在获取压缩锁的情况下进行远程加载。如果 CU 缓冲区已经包含压缩数据,它将远程加载的数据进行验证,并在需要时覆盖缓冲区。最后,它启动 CU解压缩,并在发现 CRC 错误magic 错误时报告相应的错误。此函数支持并发访问,确保不同会话之间对 CU 数据的远程加载和解压缩操作的正确性。函数源码如下:(路径:src/gausskernel/storage/cstore/cstore_am.cpp

/** @Description: 仅被 CStore::GetCUData() 调用,用于远程加载 CU* @IN/OUT cuDescPtr: CU 描述符指针* @IN/OUT cuPtr: CU 指针* @IN/OUT colIdx: 列索引* @IN/OUT slotId: 插槽ID,必须被锁定* @IN/OUT valSize: 值的大小* @Return: CU 未压缩返回码* @See also: CStore::GetCUData*/
CUUncompressedRetCode CStore::GetCUDataFromRemote(CUDesc* cuDescPtr, CU* cuPtr, int colIdx, int valSize, const int& slotId)
{// 获取属性信息Form_pg_attribute* attrs = m_relation->rd_att->attrs;// 初始化返回码CUUncompressedRetCode retCode = CU_OK;/* 重用内存并检查是否有其他会话同时更新它。 */if (CUCache->ReserveCstoreDataBlockWithSlotId(slotId)) {// 获取 CU 缓冲区cuPtr = CUCache->GetCUBuf(slotId);cuPtr->m_inCUCache = true;// 设置属性信息cuPtr->SetAttInfo(valSize, attrs[colIdx]->atttypmod, attrs[colIdx]->atttypid);/** 远程加载需要 CU 压缩。(cuPtr->m_compressedLoadBuf != NULL)* 如果 CU 未压缩,表示其他线程已经远程读取了 CU 并进行了解压缩。*/CUCache->AcquireCompressLock(slotId);if (cuPtr->m_cache_compressed) {// 远程加载 CUm_cuStorage[colIdx]->RemoteLoadCU(cuPtr, cuDescPtr->cu_pointer, cuDescPtr->cu_size, g_instance.attr.attr_storage.enable_adio_function, true);// 验证 CU 是否正确if (cuPtr->IsVerified(cuDescPtr->magic))m_cuStorage[colIdx]->OverwriteCU(cuPtr->m_compressedBuf, cuDescPtr->cu_pointer, cuDescPtr->cu_size, false);}CUCache->RealeseCompressLock(slotId);// 完成数据块 IO 操作CUCache->DataBlockCompleteIO(slotId);} else {if (CUCache->DataBlockWaitIO(slotId)) {// 如果在远程读取 CU 时发生 IO 错误,报错ereport(ERROR,(errcode(ERRCODE_IO_ERROR),errmodule(MOD_CACHE),errmsg("There is an IO error when remote read CU in cu_id %u of relation %s file %s offset %lu. ""slotId %d, column \"%s\" ",cuDescPtr->cu_id,RelationGetRelationName(m_relation),relcolpath(m_cuStorage[colIdx]),cuDescPtr->cu_pointer,slotId,NameStr(m_relation->rd_att->attrs[colIdx]->attname))));}}// 开始解压缩 CUretCode = CUCache->StartUncompressCU(cuDescPtr, slotId, this->m_plan_node_id, this->m_timing_on, ALIGNOF_CUSIZE);if (retCode == CU_ERR_CRC || retCode == CU_ERR_MAGIC) {// 远程加载 CRC 错误或魔数错误,报错CUCache->TerminateCU(true);ereport(ERROR,(errcode(ERRCODE_DATA_CORRUPTED),(errmsg("invalid CU in cu_id %u of relation %s file %s offset %lu, remote read %s",cuDescPtr->cu_id,RelationGetRelationName(m_relation),relcolpath(m_cuStorage[colIdx]),cuDescPtr->cu_pointer,GetUncompressErrMsg(retCode)))));}return retCode;
}

CStore::CheckConsistenceOfCUDescCtl 函数

  CStore::CheckConsistenceOfCUDescCtl 函数的主要目的是在进行批量加载压缩单元(CU)时,检查不同列的压缩单元描述控制块LoadCUDescCtl)之间的一致性,确保它们在相同的加载批次中保持一致。函数源码如下:(路径:src/gausskernel/storage/cstore/cstore_am.cpp

/** @Description: 检查批量加载期间 CUDescCtl(压缩单元描述符控制块)的一致性。* @See also:*/
void CStore::CheckConsistenceOfCUDescCtl(void)
{// 获取第一列的 CUDescCtlLoadCUDescCtl* firstCUDescCtl = m_CUDescInfo[0];LoadCUDescCtl* checkCUdescCtl = NULL;// 遍历其他列的 CUDescCtl,并比较它们的字段以确保一致性for (int i = 1; i < m_colNum; ++i) {checkCUdescCtl = m_CUDescInfo[i];// 检查下一个 CU ID、上次加载数量和当前加载数量是否一致if (checkCUdescCtl->nextCUID == firstCUDescCtl->nextCUID &&checkCUdescCtl->lastLoadNum == firstCUDescCtl->lastLoadNum &&checkCUdescCtl->curLoadNum == firstCUDescCtl->curLoadNum) {continue;  // 此列的 CUDescCtl 一致,继续下一列}// 如果发现不一致性,生成错误报告ereport(defence_errlevel(),(errcode(ERRCODE_INTERNAL_ERROR),errmsg("批量加载期间 CUDescCtl(表列、下一个 CU ID、上次加载数量、当前加载数量)不一致。""CUDescCtl[%d] 为 (%d %u %u %u),CUDescCtl[%d] 为 (%d %u %u %u)",0,(m_colId[0] + 1),firstCUDescCtl->nextCUID,firstCUDescCtl->lastLoadNum,firstCUDescCtl->curLoadNum,i,(m_colId[i] + 1),checkCUdescCtl->nextCUID,checkCUdescCtl->lastLoadNum,checkCUdescCtl->curLoadNum),errdetail("关系信息:名称 \"%s\",命名空间 ID %u,ID %u,relfilenode %u/%u/%u",RelationGetRelationName(m_relation),RelationGetNamespace(m_relation),RelationGetRelid(m_relation),m_relation->rd_node.spcNode,m_relation->rd_node.dbNode,m_relation->rd_node.relNode)));}
}

注解:
  在这个上下文中,“一致性” 指的是不同列的压缩单元描述符控制块LoadCUDescCtl的一些关键字段具有相同的值,表明它们在相同的加载状态下。具体而言,这些字段包括:

  1. 下一个 CU IDnextCUID): 表示下一个将要加载的压缩单元的 ID
  2. 上次加载数量(lastLoadNum): 表示上一次加载的压缩单元数量。
  3. 当前加载数量(curLoadNum): 表示当前加载的压缩单元数量。

  通过检查这些字段的值,可以确保不同列的加载状态是一致的。这是因为在某些情况下,不同列可能在不同的时间加载不同数量的压缩单元。例如,如果某列的加载比其他列更快,它可能会在其他列加载完成之前加载更多的压缩单元
  举例来说,假设有两列 A 和 B,它们都有各自的 LoadCUDescCtl。在某个时间点,A 列nextCUID10lastLoadNum5curLoadNum8,而 B 列对应值是相同的,那么它们就是一致的。如果它们的这些值在某个时间点不同,那么就表示加载的状态不一致

CStore::CheckConsistenceOfCUDesc 函数

  CStore::CheckConsistenceOfCUDesc 函数用于检查不同列的压缩单元描述符(CUDesc)在给定的 CUDesc 索引cudescIdx)下的一致性。一致性主要涉及以下两个关键字段:

  1. CU ID(cu_id): 压缩单元的唯一标识符
  2. 行数(row_count): 压缩单元中的行数

  通过比较这些字段的值,可以确保不同列相同 CUDesc 索引下的加载状态是一致的
  举例来说,如果有两列 AB,在 CUDesc 索引为 3 的情况下,如果 A 列B 列CUDesccu_idrow_count 字段的值相同,那么它们就是一致的。如果这些值在某个时间点不同,就表示加载的状态不一致,可能是由于某些加载错误或者数据不一致导致的。
  CStore::CheckConsistenceOfCUDesc 函数函数源码如下:(路径:src/gausskernel/storage/cstore/cstore_am.cpp

/** @Description: 检查不同列的压缩单元描述符(CUDesc)在给定的CUDesc索引(cudescIdx)下的一致性。*                一致性主要涉及CU ID(cu_id)和行数(row_count)这两个关键字段的比较,*                确保不同列在相同CUDesc索引下的加载状态是一致的。* @Param[IN] cudescIdx: 给定的CUDesc索引* @See also:*/
void CStore::CheckConsistenceOfCUDesc(int cudescIdx) const
{CUDesc* firstCUDesc = m_CUDescInfo[0]->cuDescArray + cudescIdx;  // 获取第一列的CUDescCUDesc* checkCUDesc = NULL;  // 待检查的CUDesc// 遍历各列,比较CU ID和行数字段的值for (int col = 1; col < m_colNum; ++col) {checkCUDesc = m_CUDescInfo[col]->cuDescArray + cudescIdx;  // 获取当前列的CUDesc// 如果CU ID和行数字段的值相同,说明一致,继续下一列的检查if (checkCUDesc->cu_id == firstCUDesc->cu_id && checkCUDesc->row_count == firstCUDesc->row_count) {continue;}// 如果不一致,报告错误信息ereport(defence_errlevel(),(errcode(ERRCODE_INTERNAL_ERROR),errmsg("Inconsistent of CUDesc(table column, CUDesc index, CU id, number of rows) during batch loading, ""CUDesc[%d] (%d %d %u %d), CUDesc[%d] (%d %d %u %d)",0,(m_colId[0] + 1),cudescIdx,firstCUDesc->cu_id,firstCUDesc->row_count,col,(m_colId[col] + 1),cudescIdx,checkCUDesc->cu_id,checkCUDesc->row_count),errdetail("relation info: name \"%s\", namespace id %u, id %u, relfilenode %u/%u/%u",RelationGetRelationName(m_relation),RelationGetNamespace(m_relation),RelationGetRelid(m_relation),m_relation->rd_node.spcNode,m_relation->rd_node.dbNode,m_relation->rd_node.relNode)));}
}

CStore::CheckConsistenceOfCUData 函数

  CStore::CheckConsistenceOfCUData 函数用于检查列存储引擎中压缩单元数据CU)与相应的压缩单元描述符(CUDesc)之间的一致性。它包括检查关键字段如数据指针偏移指针magic行数数据大小等,确保在批量加载期间数据的正确性。如果发现不一致性,函数将生成错误报告,包括详细的关系信息列信息以及不匹配的字段值,帮助在数据存储访问过程中及早发现和排除问题。CStore::CheckConsistenceOfCUData 函数函数源码如下:(路径:src/gausskernel/storage/cstore/cstore_am.cpp

/** @Description: 检查压缩单元数据(CU)与相应的压缩单元描述符(CUDesc)之间的一致性,包括检查数据指针、偏移指针、魔数、行数和数据大小等关键字段。* @Param[IN] cuDescPtr: 压缩单元描述符指针* @Param[IN] cu: 压缩单元指针* @Param[IN] col: 列号* @See also: CStore::GetCUData*/
void CStore::CheckConsistenceOfCUData(CUDesc* cuDescPtr, CU* cu, AttrNumber col) const
{/** 该内存屏障防止乱序读取,可能导致使用未完成解压的CU。* 我们必须在GetCUData函数的每个分支中返回cuPtr之前添加内存屏障。*/
#ifdef __aarch64__pg_memory_barrier();
#endif/* 检查源数据指针 */if (cu->m_srcData == NULL) {ereport(defence_errlevel(),(errcode(ERRCODE_INTERNAL_ERROR),errmsg("CU的m_srcData指针在CheckConsistenceOfCUData中为NULL。"),errdetail("relation info: name \"%s\", namespace id %u, id %u, relfilenode %u/%u/%u",RelationGetRelationName(m_relation), RelationGetNamespace(m_relation), RelationGetRelid(m_relation),m_relation->rd_node.spcNode, m_relation->rd_node.dbNode, m_relation->rd_node.relNode),errdetail_internal("CU信息: 表列 %d, id %u, 偏移 %lu, 大小 %d, 行数 %d",col,cuDescPtr->cu_id, cuDescPtr->cu_pointer, cuDescPtr->cu_size, cuDescPtr->row_count)));}/* 检查偏移指针 */if ((cu->m_eachValSize < 0 && cu->m_offset == NULL) || (cu->HasNullValue() && cu->m_offset == NULL)) {ereport(defence_errlevel(),(errcode(ERRCODE_INTERNAL_ERROR),errmsg("CU的m_offset指针在CheckConsistenceOfCUData中为NULL。"),errdetail("relation info: name \"%s\", namespace id %u, id %u, relfilenode %u/%u/%u",RelationGetRelationName(m_relation), RelationGetNamespace(m_relation), RelationGetRelid(m_relation),m_relation->rd_node.spcNode, m_relation->rd_node.dbNode, m_relation->rd_node.relNode),errdetail_internal("CU信息: 表列 %d, id %u, 偏移 %lu, 大小 %d, 行数 %d",col,cuDescPtr->cu_id, cuDescPtr->cu_pointer, cuDescPtr->cu_size, cuDescPtr->row_count)));}/* 检查magic */if (cu->m_magic != cuDescPtr->magic) {ereport(defence_errlevel(),(errcode(ERRCODE_INTERNAL_ERROR),errmsg("缓存的CU数据与CUDesc之间的magic不匹配,CUDesc的magic %u,CU的magic %u",cuDescPtr->magic,cu->m_magic),errdetail("relation info: name \"%s\", namespace id %u, id %u, relfilenode %u/%u/%u",RelationGetRelationName(m_relation), RelationGetNamespace(m_relation), RelationGetRelid(m_relation),m_relation->rd_node.spcNode, m_relation->rd_node.dbNode, m_relation->rd_node.relNode),errdetail_internal("CU信息: 表列 %d, id %u, 偏移 %lu, 大小 %d, 行数 %d",col,cuDescPtr->cu_id, cuDescPtr->cu_pointer, cuDescPtr->cu_size, cuDescPtr->row_count)));}/* 检查行数 */if (cu->m_offsetSize > 0) {/* 参见CU::FormValuesOffset() */if ((cu->m_offsetSize / (int)sizeof(int32)) != (cuDescPtr->row_count + 1)) {ereport(defence_errlevel(),(errcode(ERRCODE_INTERNAL_ERROR),errmsg("缓存的CU数据与CUDesc之间的行数不匹配,CUDesc的行数 %d,CU的行数 %d",cuDescPtr->row_count,((cu->m_offsetSize / (int)sizeof(int32)) - 1)),errdetail("relation info: name \"%s\", namespace id %u, id %u, relfilenode %u/%u/%u",RelationGetRelationName(m_relation),RelationGetNamespace(m_relation),RelationGetRelid(m_relation),m_relation->rd_node.spcNode,m_relation->rd_node.dbNode,m_relation->rd_node.relNode),errdetail_internal("CU信息: 表列 %d, id %u, 偏移 %lu, 大小 %d, 魔数 %u",col,cuDescPtr->cu_id,cuDescPtr->cu_pointer,cuDescPtr->cu_size,cuDescPtr->magic)));}}/* 检查CU大小 */if (cu->m_cuSize != (uint32)cuDescPtr->cu_size) {ereport(defence_errlevel(),(errcode(ERRCODE_INTERNAL_ERROR),errmsg("缓存的CU数据与CUDesc之间的CU大小不匹配,CUDesc的CU大小 %u,CU的CU大小 %u",(uint32)cuDescPtr->cu_size,cu->m_cuSize),errdetail("relation info: name \"%s\", namespace id %u, id %u, relfilenode %u/%u/%u",RelationGetRelationName(m_relation),RelationGetNamespace(m_relation),RelationGetRelid(m_relation),m_relation->rd_node.spcNode,m_relation->rd_node.dbNode,m_relation->rd_node.relNode),errdetail_internal("CU信息: 表列 %d, id %u, 偏移 %lu, 行数 %d, 魔数 %u",col,cuDescPtr->cu_id,cuDescPtr->cu_pointer,cuDescPtr->row_count,cuDescPtr->magic)));}
}

额外补充

  到此,以上便基本介绍完了 CStore 类中的绝大多数成员函数,最后再补充一下CStore 类中的私有成员变量吧,这些成员变量用于维护和管理数据库表的状态元数据和其他相关信息。函数源码如下:(路径:src/gausskernel/storage/cstore/cstore_am.cpp

private:// 本地控制私有内存使用。// m_scanMemContext:用于整个 cstore-scan 过程中存活的对象。// m_perScanMemCnxt:用于每个堆表扫描和解压缩期间的临时空间。MemoryContext m_scanMemContext;MemoryContext m_perScanMemCnxt;// 当前要使用的快照。Snapshot m_snapshot;// 1. 已访问的用户列 ID// 2. 已访问的系统列 ID// 3. 用于延迟读取的标志// 4. 每个用户列的 CU 存储。int *m_colId;int *m_sysColId;bool *m_lateRead;CUStorage **m_cuStorage;// 1. 已访问列的 CUDesc 信息// 2. 用于系统或常量列的虚拟 CUDescLoadCUDescCtl **m_CUDescInfo;LoadCUDescCtl *m_virtualCUDescInfo;// 已访问的 CUDesc 索引数组// 在 RoughCheck 之后,将访问哪个 CUint *m_CUDescIdx;// adio 参数int m_lastNumCUDescIdx;int m_prefetch_quantity;int m_prefetch_threshold;bool m_load_finish;// 当前扫描位置在 CU 内int *m_scanPosInCU;// Rough Check 函数RoughCheckFunc *m_RCFuncs;typedef int (CStore::*m_colFillFun)(int seq, CUDesc *cuDescPtr, ScalarVector *vec);typedef struct {m_colFillFun colFillFun[2];} colFillArray;typedef void (CStore::*FillVectorByTidsFun)(_in_ int colIdx, _in_ ScalarVector *tids, _out_ ScalarVector *vec);typedef void (CStore::*FillVectorLateReadFun)(_in_ int seq, _in_ ScalarVector *tids, _in_ CUDesc *cuDescPtr,_out_ ScalarVector *vec);FillVectorByTidsFun *m_fillVectorByTids;FillVectorLateReadFun *m_fillVectorLateRead;colFillArray *m_colFillFunArrary;typedef void (CStore::*fillMinMaxFuncPtr)(CUDesc *cuDescPtr, ScalarVector *vec, int pos);fillMinMaxFuncPtr *m_fillMinMaxFunc;ScanFuncPtr m_scanFunc;  // cstore scan function ptr// 该计划的节点 IDint m_plan_node_id;// 1. 已访问的用户列数// 2. 已访问的系统列数。int m_colNum;int m_sysColNum;// 1. 加载的 CUDesc 信息或虚拟 CUDesc 信息的长度// 2. m_CUDescIdx 的长度int m_NumLoadCUDesc;int m_NumCUDescIdx;// 1. 当前删除掩码的 CU ID。// 2. m_CUDescIdx 中的当前访问游标// 3. CU 内的当前访问行游标uint32 m_delMaskCUId;int m_cursor;int m_rowCursorInCU;uint32 m_startCUID; /* 扫描开始的 CU ID。 */uint32 m_endCUID;   /* 扫描结束的 CU ID。 */unsigned char m_cuDelMask[MaxDelBitmapSize];// 是否存在死行bool m_hasDeadRow;// 是否需要进行 Rough Checkbool m_needRCheck;// 仅访问常量列bool m_onlyConstCol;bool m_timing_on; /* 记录 CStoreScan 步骤的时间 */RangeScanInRedis m_rangeScanInRedis; /* 如果在重分布时是范围扫描 */// cbtree 索引标志bool m_useBtreeIndex;// 第一列的索引,从 0 开始int m_firstColIdx;// 用于延迟读取// cuDesc 数组中的批次的 cuDesc ID。int m_cuDescIdx;// 用于延迟读取// 第一个延迟读取列的索引,其中填充了 ctid。int m_laterReadCtidColIdx;
};

相关文章:

【 OpenGauss源码学习 —— 列存储(CStore)(六)】

列存储&#xff08;CStore&#xff09;&#xff08;六&#xff09; 概述CStore::GetCUDataFromRemote 函数CStore::CheckConsistenceOfCUDescCtl 函数CStore::CheckConsistenceOfCUDesc 函数CStore::CheckConsistenceOfCUData 函数额外补充 声明&#xff1a;本文的部分内容参考…...

MUYUCMS v2.1:一款开源、轻量级的内容管理系统基于Thinkphp开发

MuYuCMS&#xff1a;一款基于Thinkphp开发的轻量级开源内容管理系统&#xff0c;为企业、个人站长提供快速建站解决方案。它具有以下的环境要求&#xff1a; 支持系统&#xff1a;Windows/Linux/Mac WEB服务器&#xff1a;Apache/Nginx/ISS PHP版本&#xff1a;php > 5.6 (…...

SDL2 显示文字

1.简介 SDL本身没有显示文字功能&#xff0c;它需要用扩展库SDL_ttf来显示文字。ttf是True Type Font的缩写&#xff0c;ttf是Windows下的缺省字体&#xff0c;它有美观&#xff0c;放大缩小不变形的优点&#xff0c;因此广泛应用很多场合。 使用ttf库的第一件事要从Windows的…...

c++ future 使用详解

c future 使用详解 std::future 头文件 #include <future>。 类模板&#xff0c;定义如下&#xff1a; template<class T> class future; template<class T> class future<T&>; template<> class future<void>;作用&#xff…...

好用的C C++ 日志宏 OutputDebugStringA 写到文件或界面

日志宏 #include <cstdio> #define OUTPUT_DEBUG_STRING(fmt, ...) do { \char szOutMsgFinal[10240] {0}; \std::snprintf(szOutMsgFinal, sizeof(szOutMsgFinal), "[%s|%d] " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); \OutputDebugString…...

如何在ModelScope社区魔搭下载所需的模型

本篇文章介绍如何在ModelScope社区下载所需的模型。 若您需要在ModelScope平台上有感兴趣的模型并希望能下载至本地&#xff0c;则ModelScope提供了多种下载模型的方式。 使用Library下载模型 若该模型已集成至ModelScope的Library中&#xff0c;则您只需要几行代码即可加载…...

NLP在网安领域中的应用(初级)

NLP在网安领域的应用 写在最前面1. 威胁情报分析1.1 社交媒体情报分析&#xff08;后面有详细叙述&#xff09;1.2 暗网监测与威胁漏洞挖掘 2. 恶意软件检测2.1 威胁预测与趋势分析 3. 漏洞管理和响应4. 社交工程攻击识别4.1 情感分析与实时监测4.2 实体识别与攻击者画像构建4.…...

03.UDP套接字与原始套接字

UDP套接字 注意在UDP套接字中,要使用recvfrom和sendto API: recvfrom: 接收数据包,并存储源地址(UDP) 函数原型: int WSAAPI recvfrom([in] SOCKET s,[out] char *buf,[in] int len,[...

「NLP+网安」相关顶级会议期刊 投稿注意事项+会议等级+DDL+提交格式

「NLP网安」相关顶级会议&期刊投稿注意事项 写在最前面一、会议ACL (The Annual Meeting of the Association for Computational Linguistics)IH&MMSec (The ACM Workshop on Information Hiding, Multimedia and Security)CCS (The ACM Conference on Computer and Co…...

Python开源项目RestoreFormer(++)——人脸重建(Face Restoration),模糊清晰、划痕修复及黑白上色的实践

有关 Python 和 Anaconda 及 RestoreFormer 运行环境的安装与设置请参阅&#xff1a; Python开源项目CodeFormer——人脸重建&#xff08;Face Restoration&#xff09;&#xff0c;模糊清晰、划痕修复及黑白上色的实践https://blog.csdn.net/beijinghorn/article/details/134…...

设计模式 -- 命令模式(Command Pattern)

命令模式&#xff1a;一种数据驱动的设计模式也属于行为型模式&#xff0c;请求以命令的形式包裹在对象中&#xff0c;并传给调用对象。调用对象寻找可以处理该命令的合适的对象&#xff0c;并把该命令传给相应的对象&#xff0c;该对象执行命令。你认为是命令的地方都可以使用…...

【数据分享】2021-2023年我国主要城市逐月轨道交通运营数据

以地铁为代表的轨道交通是大城市居民的主要交通出行方式之一&#xff0c;轨道交通的建设和运营情况也是一个城市发展水平的重要体现。本次我们为大家带来的是2021-2023年我国主要城市的逐月的轨道交通运营数据&#xff01; 数据指标包括&#xff1a;运营线路条数&#xff08;条…...

大数据-之LibrA数据库系统告警处理(ALM-12034 周期备份任务失败)

告警解释 周期备份任务执行失败&#xff0c;则上报该告警&#xff0c;如果下次备份执行成功&#xff0c;则恢复告警。 告警属性 告警ID 告警级别 可自动清除 12034 严重 是 告警参数 参数名称 参数含义 ServiceName 产生告警的服务名称。 RoleName 产生告警的角色…...

tx-前端笔试题记录

目录 目录 1.你最熟悉的前端框架是什么说说你对它的理解。 2.请简单实现一下js对象深度拷贝。 3.CSS 有几种方法实现垂直水平居中?请简要写一下。 4.这段程序执行之后控制台会打印什么内容? 5.下列程序的输出结果是多少?为什么? 6.有ABCDE 五个火车站&#xff0c;单向…...

详解Redis持久化(上篇——RDB持久化)

Redis持久化的作用和意义 Redis 持久化是一种机制&#xff0c;用于将内存中的数据写入磁盘&#xff0c;以保证数据在服务器重启时不会丢失。持久化是为了解决内存数据库&#xff08;如 Redis&#xff09;在服务器关闭后&#xff0c;数据丢失的问题。 Redis 持久化的主要作用和…...

爬虫常见风控

一.ip风控 单位时间内接口访问频率。 二.设备指纹风控 设备注册时候设备特征是否完整&#xff0c;信息主要包含硬件、网络、系统三部分。 硬件属性&#xff1a;设备品牌、型号、IMEI&#xff08;国际移动设备识别码&#xff09;、处理器、内存、分辨率、亮度、摄像头、电池、…...

华为ensp:边缘端口并启动BUDU保护

如上图前提是三个交换机都做了rstp&#xff0c;则在边缘的地方做 边缘端口并启动BUDU保护&#xff0c;也就是我用绿色圈出来的地方 边缘1 进入交换机的系统视图 interface e0/0/3 进入接口 stp edged-port enable quit 再退回系统视图 stp bpdu-protection 这样就可以了…...

分布式id生成数据库号段算法的golang实现

分布式id生成数据库号段算法的golang实现 介绍项目结构使用说明核心流程说明1. 定义id生成器结构体2. id生成器共有Monitor&#xff0c;GetOne, Close三个对外暴露的方法。3. 数据表结构 参与贡献 介绍 项目地址&#xff1a;gitee&#xff1b;github 本项目主要利用go语言(go1…...

【算法 | 模拟No.4】AcWing 756. 蛇形矩阵 AcWing 40. 顺时针打印矩阵

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【AcWing算法提高学习专栏】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&a…...

数据——最为直接的答案

身处于这样一个数字化快速发展、竞争强烈的时代&#xff0c;不管是企业还是个人&#xff0c;大家都需要及时获取前沿动态信息&#xff0c;密切关注市场的变化。但是&#xff0c;在不计其数的企业中&#xff0c;到底行业top 是哪些企业引领潮流&#xff1f; 只有数据能告诉你最…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

软件工程 期末复习

瀑布模型&#xff1a;计划 螺旋模型&#xff1a;风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合&#xff1a;模块内部功能紧密 模块之间依赖程度小 高内聚&#xff1a;指的是一个模块内部的功能应该紧密相关。换句话说&#xff0c;一个模块应当只实现单一的功能…...

Linux-进程间的通信

1、IPC&#xff1a; Inter Process Communication&#xff08;进程间通信&#xff09;&#xff1a; 由于每个进程在操作系统中有独立的地址空间&#xff0c;它们不能像线程那样直接访问彼此的内存&#xff0c;所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...

英国云服务器上安装宝塔面板(BT Panel)

在英国云服务器上安装宝塔面板&#xff08;BT Panel&#xff09; 是完全可行的&#xff0c;尤其适合需要远程管理Linux服务器、快速部署网站、数据库、FTP、SSL证书等服务的用户。宝塔面板以其可视化操作界面和强大的功能广受国内用户欢迎&#xff0c;虽然官方主要面向中国大陆…...

Docker环境下安装 Elasticsearch + IK 分词器 + Pinyin插件 + Kibana(适配7.10.1)

做RAG自己打算使用esmilvus自己开发一个&#xff0c;安装时好像网上没有比较新的安装方法&#xff0c;然后找了个旧的方法对应试试&#xff1a; &#x1f680; 本文将手把手教你在 Docker 环境中部署 Elasticsearch 7.10.1 IK分词器 拼音插件 Kibana&#xff0c;适配中文搜索…...