diff --git a/src/gausskernel/storage/access/archive/nas_am.cpp b/src/gausskernel/storage/access/archive/nas_am.cpp index d69c65adc..092cd7aad 100644 --- a/src/gausskernel/storage/access/archive/nas_am.cpp +++ b/src/gausskernel/storage/access/archive/nas_am.cpp @@ -46,22 +46,22 @@ #include "postmaster/alarmchecker.h" #include "replication/walreceiver.h" -//定义文件路径的最大长度,使代码更加清晰和易于维护 +//瀹氫箟鏂囦欢璺緞鐨勬渶澶ч暱搴︼紝浣夸唬鐮佹洿鍔犳竻鏅板拰鏄撲簬缁存姢 #define MAX_PATH_LEN 1024 -//定义了一个头部长度 +//瀹氫箟浜嗕竴涓ご閮ㄩ暱搴 static int headerLen = 22; -// 定义一个函数,用于从NAS存储中读取文件数据 +// 瀹氫箟涓涓嚱鏁帮紝鐢ㄤ簬浠嶯AS瀛樺偍涓鍙栨枃浠舵暟鎹 size_t NasRead(const char* fileName, const int offset, char *buffer, const int length, ArchiveConfig *nas_config) { /* - fileName:要读取的文件名。 - offset:读取的起始偏移量。 - buffer:用于存储读取的数据的缓冲区。 - length:要读取的数据长度。 - nas_config:归档配置信息的指针,指向 ArchiveConfig 结构,包含了有关存储位置和设置的信息。 + fileName锛氳璇诲彇鐨勬枃浠跺悕銆 + offset锛氳鍙栫殑璧峰鍋忕Щ閲忋 + buffer锛氱敤浜庡瓨鍌ㄨ鍙栫殑鏁版嵁鐨勭紦鍐插尯銆 + length锛氳璇诲彇鐨勬暟鎹暱搴︺ + nas_config锛氬綊妗i厤缃俊鎭殑鎸囬拡锛屾寚鍚 ArchiveConfig 缁撴瀯锛屽寘鍚簡鏈夊叧瀛樺偍浣嶇疆鍜岃缃殑淇℃伅銆 */ - //初始化 + //鍒濆鍖 size_t readLength = 0; ArchiveConfig *archive_nas = NULL; char file_path[MAXPGPATH] = {0}; @@ -69,45 +69,45 @@ size_t NasRead(const char* fileName, const int offset, char *buffer, const int l FILE *fp = NULL; struct stat statbuf; - if ((fileName == NULL) || (buffer == NULL)) {//如果文件名和缓冲区为空会报错 + if ((fileName == NULL) || (buffer == NULL)) {//濡傛灉鏂囦欢鍚嶅拰缂撳啿鍖轰负绌轰細鎶ラ敊 ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("The parameter cannot be NULL"))); } - //获取NAS存储的配置信息 + //鑾峰彇NAS瀛樺偍鐨勯厤缃俊鎭 if (nas_config != NULL) { archive_nas = nas_config; } else { archive_nas = getArchiveConfig(); } - if (archive_nas == NULL) {//无法获取归档配置信息时报错 + if (archive_nas == NULL) {//鏃犳硶鑾峰彇褰掓。閰嶇疆淇℃伅鏃舵姤閿 ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Cannot get archive config from replication slots"))); } - if (strncmp(fileName, "global_barrier_records", headerLen) != 0) {//构建文件的完整路径 - //调用snprintf_s函数构建一个完整的文件路径,并将结果存储在 file_path 变量中 + if (strncmp(fileName, "global_barrier_records", headerLen) != 0) {//鏋勫缓鏂囦欢鐨勫畬鏁磋矾寰 + //璋冪敤snprintf_s鍑芥暟鏋勫缓涓涓畬鏁寸殑鏂囦欢璺緞锛屽苟灏嗙粨鏋滃瓨鍌ㄥ湪 file_path 鍙橀噺涓 ret = snprintf_s(file_path, MAXPGPATH, MAXPGPATH - 1, "%s/%s", archive_nas->archive_prefix, fileName); - // ret用于储存snprintf_s 函数的返回值。这个返回值表示已格式化字符串的长度。 - securec_check_ss(ret, "\0", "\0");//如果发生错误将会在 ret 中返回 '\0' ,从而帮助定位错误的位置。 - //用于检查 snprintf_s函数的返回值并进行安全性检查,以确保没有发生缓冲区溢出或格式化错误 + // ret鐢ㄤ簬鍌ㄥ瓨snprintf_s 鍑芥暟鐨勮繑鍥炲笺傝繖涓繑鍥炲艰〃绀哄凡鏍煎紡鍖栧瓧绗︿覆鐨勯暱搴︺ + securec_check_ss(ret, "\0", "\0");//濡傛灉鍙戠敓閿欒灏嗕細鍦 ret 涓繑鍥 '\0' 锛屼粠鑰屽府鍔╁畾浣嶉敊璇殑浣嶇疆銆 + //鐢ㄤ簬妫鏌 snprintf_s鍑芥暟鐨勮繑鍥炲煎苟杩涜瀹夊叏鎬ф鏌ワ紝浠ョ‘淇濇病鏈夊彂鐢熺紦鍐插尯婧㈠嚭鎴栨牸寮忓寲閿欒 } else { - char pathPrefix[MAXPGPATH] = {0};//生成一个空的char数组作为pathPrefix(用于储存归档配置的存档前缀) + char pathPrefix[MAXPGPATH] = {0};//鐢熸垚涓涓┖鐨刢har鏁扮粍浣滀负pathPrefix锛堢敤浜庡偍瀛樺綊妗i厤缃殑瀛樻。鍓嶇紑锛 ret = strcpy_s(pathPrefix, MAXPGPATH, archive_nas->archive_prefix); - //复制 archive_nas->archive_prefix 到 pathPrefix + //澶嶅埗 archive_nas->archive_prefix 鍒 pathPrefix securec_check_ss(ret, "\0", "\0"); if (!IS_PGXC_COORDINATOR) { - char *p = strrchr(pathPrefix, '/');//在pathPrefix中找到最后一个斜杠的位置 + char *p = strrchr(pathPrefix, '/');//鍦╬athPrefix涓壘鍒版渶鍚庝竴涓枩鏉犵殑浣嶇疆 if (p == NULL) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Obs path prefix is invalid"))); } - *p = '\0';//将最后一个斜杠替换为'\0' + *p = '\0';//灏嗘渶鍚庝竴涓枩鏉犳浛鎹负'\0' } ret = snprintf_s(file_path, MAXPGPATH, MAXPGPATH - 1, "%s/%s", pathPrefix, fileName); securec_check_ss(ret, "\0", "\0"); - // 构建完整路径并检查 snprintf_s 函数的返回值 + // 鏋勫缓瀹屾暣璺緞骞舵鏌 snprintf_s 鍑芥暟鐨勮繑鍥炲 } - //检查文件是否存在 + //妫鏌ユ枃浠舵槸鍚﹀瓨鍦 if (stat(file_path, &statbuf)) { if (errno != ENOENT) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat file \"%s\": %m", fileName))); @@ -115,10 +115,10 @@ size_t NasRead(const char* fileName, const int offset, char *buffer, const int l ereport(ERROR, (errcode_for_file_access(), errmsg("The file \"%s\" not exists", fileName))); return readLength; } - //打开文件并读取数据 + //鎵撳紑鏂囦欢骞惰鍙栨暟鎹 canonicalize_path(file_path); fp = fopen(file_path, "rb"); - //对于打开文件产生的错误进行处理 + //瀵逛簬鎵撳紑鏂囦欢浜х敓鐨勯敊璇繘琛屽鐞 if (fp == NULL) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", fileName))); return readLength; @@ -129,98 +129,98 @@ size_t NasRead(const char* fileName, const int offset, char *buffer, const int l return readLength; } - //读取数据到缓冲区中 + //璇诲彇鏁版嵁鍒扮紦鍐插尯涓 readLength = fread(buffer, 1, statbuf.st_size, fp); fclose(fp); return readLength; } -//该函数用于将数据写入文件,并在必要时进行备份和重命名 +//璇ュ嚱鏁扮敤浜庡皢鏁版嵁鍐欏叆鏂囦欢锛屽苟鍦ㄥ繀瑕佹椂杩涜澶囦唤鍜岄噸鍛藉悕 int NasWrite(const char* fileName, const char *buffer, const int bufferLength, ArchiveConfig *nas_config) { int ret = 0; - ArchiveConfig *archive_nas = NULL;//存储NAS配置的指针 - char file_path[MAXPGPATH] = {0};//存储构建的文件路 - char file_path_bak[MAXPGPATH] = {0};//存储备份文件路径 - char *origin_file_path = NULL;//存储规范化的文件路径的副本 - char *base_path = NULL;//存储文件的基础路径 - FILE *fp = NULL;//文件指针,用于操作文件 + ArchiveConfig *archive_nas = NULL;//瀛樺偍NAS閰嶇疆鐨勬寚閽 + char file_path[MAXPGPATH] = {0};//瀛樺偍鏋勫缓鐨勬枃浠惰矾 + char file_path_bak[MAXPGPATH] = {0};//瀛樺偍澶囦唤鏂囦欢璺緞 + char *origin_file_path = NULL;//瀛樺偍瑙勮寖鍖栫殑鏂囦欢璺緞鐨勫壇鏈 + char *base_path = NULL;//瀛樺偍鏂囦欢鐨勫熀纭璺緞 + FILE *fp = NULL;//鏂囦欢鎸囬拡锛岀敤浜庢搷浣滄枃浠 - //检查传入的参数是否为空,文件名和缓冲器为空时报错 + //妫鏌ヤ紶鍏ョ殑鍙傛暟鏄惁涓虹┖锛屾枃浠跺悕鍜岀紦鍐插櫒涓虹┖鏃舵姤閿 if ((fileName == NULL) || (buffer == NULL)) { ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("The parameter cannot be NULL"))); } - //获取归档配置信息,如果传入的归档配置参数为NULL,则尝试从默认位置获取 + //鑾峰彇褰掓。閰嶇疆淇℃伅锛屽鏋滀紶鍏ョ殑褰掓。閰嶇疆鍙傛暟涓篘ULL锛屽垯灏濊瘯浠庨粯璁や綅缃幏鍙 if (nas_config != NULL) { archive_nas = nas_config; } else { archive_nas = getArchiveConfig(); } - //检查获取到的归档配置信息是否有效,无效时报错 + //妫鏌ヨ幏鍙栧埌鐨勫綊妗i厤缃俊鎭槸鍚︽湁鏁堬紝鏃犳晥鏃舵姤閿 if (archive_nas == NULL) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Cannot get archive config from replication slots"))); } - //根据文件名构建完整的文件路径 - if (strncmp(fileName, "global_barrier_records", headerLen) != 0) {//判断文件名是否为"global_barrier_records" + //鏍规嵁鏂囦欢鍚嶆瀯寤哄畬鏁寸殑鏂囦欢璺緞 + if (strncmp(fileName, "global_barrier_records", headerLen) != 0) {//鍒ゆ柇鏂囦欢鍚嶆槸鍚︿负"global_barrier_records" ret = snprintf_s(file_path, MAXPGPATH, MAXPGPATH - 1, "%s/%s", archive_nas->archive_prefix, fileName); securec_check_ss(ret, "\0", "\0"); - //构建完整路径并检查snprintf_s函数的返回值 + //鏋勫缓瀹屾暣璺緞骞舵鏌nprintf_s鍑芥暟鐨勮繑鍥炲 } else { - char pathPrefix[MAXPGPATH] = {0};//用于存储路径前缀 - ret = strcpy_s(pathPrefix, MAXPGPATH, archive_nas->archive_prefix);//复制 archive_nas->archive_prefix 到 pathPrefix + char pathPrefix[MAXPGPATH] = {0};//鐢ㄤ簬瀛樺偍璺緞鍓嶇紑 + ret = strcpy_s(pathPrefix, MAXPGPATH, archive_nas->archive_prefix);//澶嶅埗 archive_nas->archive_prefix 鍒 pathPrefix securec_check_ss(ret, "\0", "\0"); - if (!IS_PGXC_COORDINATOR) {// 如果不是协调器节点 - char *p = strrchr(pathPrefix, '/');//在pathPrefix中查找最后一个'/' - if (p == NULL) {//没有找到'/'则会报错 + if (!IS_PGXC_COORDINATOR) {// 濡傛灉涓嶆槸鍗忚皟鍣ㄨ妭鐐 + char *p = strrchr(pathPrefix, '/');//鍦╬athPrefix涓煡鎵炬渶鍚庝竴涓'/' + if (p == NULL) {//娌℃湁鎵惧埌'/'鍒欎細鎶ラ敊 ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Obs path prefix is invalid"))); } - *p = '\0';//将最后一个斜杠替换为'\0' + *p = '\0';//灏嗘渶鍚庝竴涓枩鏉犳浛鎹负'\0' } ret = snprintf_s(file_path, MAXPGPATH, MAXPGPATH - 1, "%s/%s", pathPrefix, fileName); securec_check_ss(ret, "\0", "\0"); - // 构建完整路径并检查 snprintf_s 函数的返回值 + // 鏋勫缓瀹屾暣璺緞骞舵鏌 snprintf_s 鍑芥暟鐨勮繑鍥炲 } - canonicalize_path(file_path);//规范化文件路径,去除多余的字符,如'.'、'..'等 + canonicalize_path(file_path);//瑙勮寖鍖栨枃浠惰矾寰勶紝鍘婚櫎澶氫綑鐨勫瓧绗︼紝濡'.'銆'..'绛 - origin_file_path = pstrdup(file_path);//复制文件路径到origin_file_path - base_path = dirname(origin_file_path);//获取origin_file_path(文件的完整路径)的父级路径,即基础路径 - //检查基础路径是否存在,如果不存在则创建 + origin_file_path = pstrdup(file_path);//澶嶅埗鏂囦欢璺緞鍒皁rigin_file_path + base_path = dirname(origin_file_path);//鑾峰彇origin_file_path锛堟枃浠剁殑瀹屾暣璺緞锛夌殑鐖剁骇璺緞锛屽嵆鍩虹璺緞 + //妫鏌ュ熀纭璺緞鏄惁瀛樺湪锛屽鏋滀笉瀛樺湪鍒欏垱寤 if (!isDirExist(base_path)) { - // 调用 pg_mkdir_p 函数尝试创建目录,S_IRWXU 是指定权限参数 - if (pg_mkdir_p(base_path, S_IRWXU) != 0) {//如果返回值不为0,则说明创建目录失败 - // 如果创建目录失败,释放内存并报告错误 - pfree_ext(origin_file_path);//释放其占用的内存空间 + // 璋冪敤 pg_mkdir_p 鍑芥暟灏濊瘯鍒涘缓鐩綍锛孲_IRWXU 鏄寚瀹氭潈闄愬弬鏁 + if (pg_mkdir_p(base_path, S_IRWXU) != 0) {//濡傛灉杩斿洖鍊间笉涓0锛屽垯璇存槑鍒涘缓鐩綍澶辫触 + // 濡傛灉鍒涘缓鐩綍澶辫触锛岄噴鏀惧唴瀛樺苟鎶ュ憡閿欒 + pfree_ext(origin_file_path);//閲婃斁鍏跺崰鐢ㄧ殑鍐呭瓨绌洪棿 ereport(LOG, (errmsg("could not create path \"%s\"", base_path))); - return -1;//返回 -1 表示创建目录失败 + return -1;//杩斿洖 -1 琛ㄧず鍒涘缓鐩綍澶辫触 } } - //构建备份文件的路径,将 ".bak" 添加到 file_path + //鏋勫缓澶囦唤鏂囦欢鐨勮矾寰勶紝灏 ".bak" 娣诲姞鍒 file_path ret = snprintf_s(file_path_bak, MAXPGPATH, MAXPGPATH - 1, "%s.bak", file_path); securec_check_ss(ret, "\0", "\0"); - fp = fopen(file_path_bak, "wb");//打开备份文件,以二进制写入模式 - if (fp == NULL) {//如果打开备份文件失败,释放内存并报告错误 + fp = fopen(file_path_bak, "wb");//鎵撳紑澶囦唤鏂囦欢锛屼互浜岃繘鍒跺啓鍏ユā寮 + if (fp == NULL) {//濡傛灉鎵撳紑澶囦唤鏂囦欢澶辫触锛岄噴鏀惧唴瀛樺苟鎶ュ憡閿欒 pfree_ext(origin_file_path); ereport(LOG, (errmsg("could not create file \"%s\": %m", fileName))); return -1; } - //将数据写入备份文件 + //灏嗘暟鎹啓鍏ュ浠芥枃浠 if (fwrite(buffer, bufferLength, 1, fp) != 1) { ereport(LOG, (errmsg("could not write file \"%s\": %m", fileName))); pfree_ext(origin_file_path); fclose(fp); return -1; } - //刷新文件缓冲区,确保数据写入磁盘 + //鍒锋柊鏂囦欢缂撳啿鍖猴紝纭繚鏁版嵁鍐欏叆纾佺洏 if (fflush(fp) != 0) { ereport(LOG, (errmsg("could not fflush file \"%s\": %m", fileName))); (void)fclose(fp); pfree_ext(origin_file_path); return -1; } - //将备份文件重命名为正式文件 + //灏嗗浠芥枃浠堕噸鍛藉悕涓烘寮忔枃浠 if (rename(file_path_bak, file_path) < 0) { ereport(LOG, (errmsg("could not rename file \"%s\": %m", fileName))); (void)fclose(fp); @@ -228,8 +228,8 @@ int NasWrite(const char* fileName, const char *buffer, const int bufferLength, A return -1; } - pfree_ext(origin_file_path);//释放被占用的内存空间 - fclose(fp);//关闭文件 + pfree_ext(origin_file_path);//閲婃斁琚崰鐢ㄧ殑鍐呭瓨绌洪棿 + fclose(fp);//鍏抽棴鏂囦欢 return 0; }