forked from huawei/openGauss-server
Update nas_am.cpp
This commit is contained in:
parent
1dc7657220
commit
b02deb9a95
|
|
@ -46,22 +46,22 @@
|
|||
#include "postmaster/alarmchecker.h"
|
||||
#include "replication/walreceiver.h"
|
||||
|
||||
//定义文件路径的最大长度,使代码更加清晰和易于维护
|
||||
//定义文件路径的最大长度,使代码更加清晰和易于维护
|
||||
#define MAX_PATH_LEN 1024
|
||||
//定义了一个头部长度
|
||||
//定义了一个头部长度
|
||||
static int headerLen = 22;
|
||||
|
||||
// 定义一个函数,用于从NAS存储中读取文件数据
|
||||
// 定义一个函数,用于从NAS存储中读取文件数据
|
||||
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:归档配置信息的指针,指向 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};//生成一个空的char数组作为pathPrefix(用于储存归档配置的存档前缀)
|
||||
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, '/');//在pathPrefix中找到最后一个斜杠的位置
|
||||
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,则尝试从默认位置获取
|
||||
//获取归档配置信息,如果传入的归档配置参数为NULL,则尝试从默认位置获取
|
||||
if (nas_config != NULL) {
|
||||
archive_nas = nas_config;
|
||||
} else {
|
||||
archive_nas = getArchiveConfig();
|
||||
}
|
||||
//检查获取到的归档配置信息是否有效,无效时报错
|
||||
//检查获取到的归档配置信息是否有效,无效时报错
|
||||
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函数的返回值
|
||||
//构建完整路径并检查snprintf_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, '/');//在pathPrefix中查找最后一个'/'
|
||||
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);//复制文件路径到origin_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 函数尝试创建目录,S_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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue