diff --git a/src/gausskernel/security/gs_ledger/ledger_check.cpp b/src/gausskernel/security/gs_ledger/ledger_check.cpp index c64a351b4..92b2562e0 100644 --- a/src/gausskernel/security/gs_ledger/ledger_check.cpp +++ b/src/gausskernel/security/gs_ledger/ledger_check.cpp @@ -53,34 +53,34 @@ */ static uint64 gen_usertable_hash_sum(Relation rel) { - uint64 rel_hash = 0; - bool is_null = false; - int hash_natt = user_hash_attrno(rel->rd_att); + uint64 rel_hash = 0;//初始化关系哈希和为零 + bool is_null = false;//初始化标志位为假 + int hash_natt = user_hash_attrno(rel->rd_att);//获取用户关系的哈希属性编号 Assert(hash_natt >= 0); - HeapTuple tuple; - TupleDesc desc = rel->rd_att; - Snapshot snapshot = GetActiveSnapshot(); - TableScanDesc scan; - if (RELATION_CREATE_BUCKET(rel)) { - Relation bucket_rel = NULL; - oidvector *bucket_list = searchHashBucketByOid(rel->rd_bucketoid); - for (int i = 0; i < bucket_list->dim1; i++) { - bucket_rel = bucketGetRelation(rel, NULL, bucket_list->values[i]); - scan = heap_beginscan(bucket_rel, snapshot, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { + HeapTuple tuple;//用于存储关系的元组 + TupleDesc desc = rel->rd_att;//获取关系的元组描述 + Snapshot snapshot = GetActiveSnapshot();//活动快照 + TableScanDesc scan;//表扫描器 + if (RELATION_CREATE_BUCKET(rel)) {//如果关系是哈希分区表啊 + Relation bucket_rel = NULL;//初始化分区关系 + oidvector *bucket_list = searchHashBucketByOid(rel->rd_bucketoid);//获取哈希分区列表 + for (int i = 0; i < bucket_list->dim1; i++) {//遍历哈希分区列表 + bucket_rel = bucketGetRelation(rel, NULL, bucket_list->values[i]);//获取哈希分区关系 + scan = heap_beginscan(bucket_rel, snapshot, 0, NULL);//开始扫描分区表 + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) {//遍历分区表中的元组 rel_hash += DatumGetUInt64(heap_getattr(tuple, hash_natt + 1, desc, &is_null)); - } - heap_endscan(scan); + }//获取哈希值累加到关系哈希和中 + heap_endscan(scan);//结束扫描 bucketCloseRelation(bucket_rel); } - } else { - scan = heap_beginscan(rel, snapshot, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { + } else {//如果关系不是哈希分区表 + scan = heap_beginscan(rel, snapshot, 0, NULL);//开始扫描关系 + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) {//遍历关系中的元组 rel_hash += DatumGetUInt64(heap_getattr(tuple, hash_natt + 1, desc, &is_null)); } - heap_endscan(scan); + heap_endscan(scan);//结束扫描 } - return rel_hash; + return rel_hash;//返回关系哈希和 } /* @@ -92,27 +92,27 @@ static uint64 gen_usertable_hash_sum(Relation rel) */ static uint64 get_usertable_hash_sum(Oid relid) { - uint64 rel_hash = 0; + uint64 rel_hash = 0;//初始化关系哈希和为零 Relation rel = NULL; - rel = heap_open(relid, AccessShareLock); - if (!RelationIsPartitioned(rel)) { - rel_hash = gen_usertable_hash_sum(rel); - } else { - List *partition_list = NIL; + rel = heap_open(relid, AccessShareLock);//打开用户表关系并获取共享锁 + if (!RelationIsPartitioned(rel)) {//如果用户表不是分区表 + rel_hash = gen_usertable_hash_sum(rel);//调用函数 + } else {//如果是分区表 + List *partition_list = NIL;//初始化 ListCell *lc = NULL; - Partition part; - Relation fake_rel; - partition_list = relationGetPartitionList(rel, AccessShareLock); - foreach (lc, partition_list) { - part = (Partition)lfirst(lc); + Partition part;//分区 + Relation fake_rel;//假分区关系 + partition_list = relationGetPartitionList(rel, AccessShareLock);//获取分区列表 + foreach (lc, partition_list) {//遍历分区列表 + part = (Partition)lfirst(lc);//获取分区 fake_rel = partitionGetRelation(rel, part); - rel_hash += gen_usertable_hash_sum(fake_rel); - releaseDummyRelation(&fake_rel); + rel_hash += gen_usertable_hash_sum(fake_rel);//调用函数计算分区关系哈希和并累加 + releaseDummyRelation(&fake_rel);//释放分区关系 } - releasePartitionList(rel, &partition_list, AccessShareLock); + releasePartitionList(rel, &partition_list, AccessShareLock);// 释放分区列表 } - heap_close(rel, AccessShareLock); - return rel_hash; + heap_close(rel, AccessShareLock);// 关闭用户表关系并释放共享锁 + return rel_hash;// 返回关系哈希和 } /* @@ -122,28 +122,28 @@ static uint64 get_usertable_hash_sum(Oid relid) */ static uint64 get_histtable_hash_sum(Oid hist_oid) { - uint64 rel_hash = 0; - bool is_null = false; - Relation hist_rel; + uint64 rel_hash = 0;// 初始化哈希差值为零 + bool is_null = false;// 初始化标志位为假 + Relation hist_rel;// 初始化历史表关系 TableScanDesc scan; - HeapTuple tuple; + HeapTuple tuple; // 用于存储历史表中的元组 Snapshot snapshot = GetActiveSnapshot(); - hist_rel = heap_open(hist_oid, AccessShareLock); - scan = heap_beginscan(hist_rel, snapshot, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { + hist_rel = heap_open(hist_oid, AccessShareLock);// 打开历史表关系并获取共享锁 + scan = heap_beginscan(hist_rel, snapshot, 0, NULL); // 开始扫描历史表 + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { // 遍历历史表中的元组 Datum value = heap_getattr(tuple, USERCHAIN_COLUMN_HASH_INS + 1, hist_rel->rd_att, &is_null); - if (!is_null) { - rel_hash += DatumGetUInt64(value); + if (!is_null) {// 如果不是空值 + rel_hash += DatumGetUInt64(value);// 累加到哈希差值中 } value = heap_getattr(tuple, USERCHAIN_COLUMN_HASH_DEL + 1, hist_rel->rd_att, &is_null); - if (!is_null) { - rel_hash -= DatumGetUInt64(value); + if (!is_null) {// 如果不是空值 + rel_hash -= DatumGetUInt64(value); // 从哈希差值中减去 } } - heap_endscan(scan); - heap_close(hist_rel, AccessShareLock); + heap_endscan(scan);// 结束历史表扫描 + heap_close(hist_rel, AccessShareLock); // 关闭历史表关系并释放共享锁 return rel_hash; } @@ -171,23 +171,23 @@ static bool has_ledger_consistent_privilege(Oid relid, Oid namespaceId) */ bool is_hist_hash_identity(Oid relid, uint64 *res_hash) { - uint64 user_hash_sum; - uint64 hist_hash_sum; + uint64 user_hash_sum;// 用户表的哈希和 + uint64 hist_hash_sum;// 历史表的哈希和 char hist_name[NAMEDATALEN]; - char *rel_name = get_rel_name(relid); - if (!get_hist_name(relid, rel_name, hist_name)) { - ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("get hist table name failed."))); + char *rel_name = get_rel_name(relid);// 获取用户表的名称 + if (!get_hist_name(relid, rel_name, hist_name)) {// 获取历史表的名称 + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("get hist table name failed."))); // 如果获取失败,则���错 } - Oid histoid = get_relname_relid(hist_name, PG_BLOCKCHAIN_NAMESPACE); - if (!OidIsValid(histoid)) { - ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("could not find hist table of \"%s\".", rel_name))); + Oid histoid = get_relname_relid(hist_name, PG_BLOCKCHAIN_NAMESPACE);// 获取历史表的 OID + if (!OidIsValid(histoid)) { // 如果 OID 无效 + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("could not find hist table of \"%s\".", rel_name)));// 报错,找不到历史表 } - user_hash_sum = get_usertable_hash_sum(relid); - hist_hash_sum = get_histtable_hash_sum(histoid); + user_hash_sum = get_usertable_hash_sum(relid); // 获取用户表的哈希总和 + hist_hash_sum = get_histtable_hash_sum(histoid); // 获取历史表的哈希总和 - *res_hash = hist_hash_sum; - return user_hash_sum == hist_hash_sum; + *res_hash = hist_hash_sum; // 返回历史表的哈希和 + return user_hash_sum == hist_hash_sum; // 返回用户表哈希和和历史表哈希和是否相等的比较结果 } #ifdef ENABLE_MULTIPLE_NODES @@ -201,28 +201,28 @@ bool is_hist_hash_identity(Oid relid, uint64 *res_hash) */ static void StrategyFuncAnd(ParallelFunctionState* state) { - TupleTableSlot* slot = NULL; - bool result = true; + TupleTableSlot* slot = NULL;// 创建 TupleTableSlot 用于存储结果 + bool result = true;// 初始化结果为true - Assert(state); - Assert(state->tupstore); - Assert(state->tupdesc); - slot = MakeSingleTupleTableSlot(state->tupdesc); + Assert(state); // 断言 state 不为空 + Assert(state->tupstore);// 断言 tupstore 不为空 + Assert(state->tupdesc);// 断言 tupdesc 不为空 + slot = MakeSingleTupleTableSlot(state->tupdesc);// 创建单个 TupleTableSlot 用于存储数据 while (true) { bool isnull = false; - if (!tuplestore_gettupleslot(state->tupstore, true, false, slot)) + if (!tuplestore_gettupleslot(state->tupstore, true, false, slot)) // 从 tupstore 获取下一个结果,如果没有更多结果则退出循环 break; - if (!DatumGetBool(tableam_tslot_getattr(slot, 1, &isnull))) { + if (!DatumGetBool(tableam_tslot_getattr(slot, 1, &isnull))) {// 从 TupleTableSlot 中获取属性值,如果为 false 则将结果设置为 false 并退出循环 result = false; break; } - (void)ExecClearTuple(slot); + (void)ExecClearTuple(slot); // 清空 TupleTableSlot } - state->result = result; + state->result = result;// 将结果存储在并行函数状态中 } /* @@ -235,31 +235,30 @@ static void StrategyFuncAnd(ParallelFunctionState* state) */ static void StrategyFuncUInt64Sum(ParallelFunctionState* state) { - TupleTableSlot* slot = NULL; - int64 result = 0; + TupleTableSlot* slot = NULL;// 创建 TupleTableSlot 用于存储结果 + int64 result = 0;// 初始化结果为 0 - Assert(state && state->tupstore && state->tupdesc); - slot = MakeSingleTupleTableSlot(state->tupdesc); + Assert(state && state->tupstore && state->tupdesc);// 断言 state、tupstore 和 tupdesc 不为空 + slot = MakeSingleTupleTableSlot(state->tupdesc);// 创建单个 TupleTableSlot 用于存储数据 while (true) { bool isnull = false; - if (!tuplestore_gettupleslot(state->tupstore, true, false, slot)) + if (!tuplestore_gettupleslot(state->tupstore, true, false, slot))// 从 tupstore 获取下一个结果,如果没有更多结果则退出循环 break; - result += DatumGetUInt64(tableam_tslot_getattr(slot, 1, &isnull)); - ExecClearTuple(slot); + result += DatumGetUInt64(tableam_tslot_getattr(slot, 1, &isnull));// 从 TupleTableSlot 中获取属性值并累加到结果中 + ExecClearTuple(slot);// 清空 TupleTableSlot } - state->result = result; + state->result = result;// 将结果存储在并行函数状态中 } #endif - /* - * ledger_hist_check -- check whether user table hash and history table hash are equal + * ledger_hist_check -- 检查用户表哈希和历史表哈希是否相等 * - * parameter1: user table name [type: text] - * parameter2: namespace of user table [type: text] + * parameter1: 用户表名 [类型: text] + * parameter2: 用户表的命名空间 [类型: text] */ Datum ledger_hist_check(PG_FUNCTION_ARGS) { @@ -269,30 +268,32 @@ Datum ledger_hist_check(PG_FUNCTION_ARGS) bool res = false; char *table_name; char *table_nsp; - text *rel_nsp = PG_GETARG_TEXT_PP(0); - text *rel_name = PG_GETARG_TEXT_PP(1); + text *rel_nsp = PG_GETARG_TEXT_PP(0); // 获取第一个参数,用户表的命名空间 + text *rel_name = PG_GETARG_TEXT_PP(1); // 获取第二个参数,用户表名 - table_nsp = text_to_cstring(rel_nsp); - table_name = text_to_cstring(rel_name); - nsp_oid = get_namespace_oid(table_nsp, false); - relid = get_relname_relid(table_name, nsp_oid); - ledger_usertable_check(relid, nsp_oid, table_name, table_nsp); - if (!has_ledger_consistent_privilege(relid, nsp_oid)) { + + table_nsp = text_to_cstring(rel_nsp);// 将文本参数转换为 C 字符串 + table_name = text_to_cstring(rel_name);// 将文本参数转换为 C 字符串 + nsp_oid = get_namespace_oid(table_nsp, false);// 获取命名空间的 OID + relid = get_relname_relid(table_name, nsp_oid);// 获取用户表的 OID + ledger_usertable_check(relid, nsp_oid, table_name, table_nsp);// 检查用户表是否存在 + + if (!has_ledger_consistent_privilege(relid, nsp_oid)) { // 检查权限 ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Permission denied."))); } - res = is_hist_hash_identity(relid, &res_hash); + res = is_hist_hash_identity(relid, &res_hash);// 检查用户表哈希和历史表哈希是否相等 #ifdef ENABLE_MULTIPLE_NODES - if (!IsConnFromCoord()) { - StringInfoData buf; - ParallelFunctionState* state = NULL; - initStringInfo(&buf); + if (!IsConnFromCoord()) {// 如果不是从协调器节点调用 + StringInfoData buf;// 创建一个字符串缓冲区 + ParallelFunctionState* state = NULL;// 创建并行函数状态 + initStringInfo(&buf);// 初始化字符串缓冲区 appendStringInfo(&buf, "SELECT pg_catalog.ledger_hist_check('%s', '%s')", table_nsp, table_name); /* Get all hash diffs from DNs in distribute scenairo. */ state = RemoteFunctionResultHandler(buf.data, NULL, StrategyFuncAnd); - res &= state->result; - FreeParallelFunctionState(state); + res &= state->result;// 更新结果 + FreeParallelFunctionState(state);// 释放并行函数状态 } #endif return BoolGetDatum(res); @@ -309,19 +310,19 @@ static uint64 get_gchain_relhash_sum(Oid relid) HeapTuple tuple = NULL; /* scan the gs_global_chain catalog by relid */ - Relation gchain_rel = heap_open(GsGlobalChainRelationId, AccessShareLock); + Relation gchain_rel = heap_open(GsGlobalChainRelationId, AccessShareLock);// 打开 gs_global_chain 关系 Form_gs_global_chain rdata = NULL; - TableScanDesc scan = heap_beginscan(gchain_rel, SnapshotNow, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { - rdata = (Form_gs_global_chain)GETSTRUCT(tuple); - if (rdata == NULL || rdata->relid != relid) { + TableScanDesc scan = heap_beginscan(gchain_rel, SnapshotNow, 0, NULL);// 创建表扫描描述符 + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) {// 循环遍历结果集 + rdata = (Form_gs_global_chain)GETSTRUCT(tuple);// 获取结果的数据结构 + if (rdata == NULL || rdata->relid != relid) {// 如果数据为空或者 OID 不匹配,则继续下一轮循环 continue; } - relhash += rdata->relhash; + relhash += rdata->relhash;// 累加关系哈希值 } - heap_endscan(scan); - heap_close(gchain_rel, AccessShareLock); - return relhash; + heap_endscan(scan);// 结束扫描 + heap_close(gchain_rel, AccessShareLock);// 关闭关系 + return relhash;// 返回关系哈希和 } /* @@ -336,39 +337,39 @@ static uint64 get_gchain_relhash_sum(Oid relid) Datum get_dn_hist_relhash(PG_FUNCTION_ARGS) { #ifndef ENABLE_MULTIPLE_NODES - DISTRIBUTED_FEATURE_NOT_SUPPORTED(); + DISTRIBUTED_FEATURE_NOT_SUPPORTED(); // 不支持分布式特性 return UInt64GetDatum(0); #else - if (!IsConnFromCoord()) { + if (!IsConnFromCoord()) {// 如果不是从协调器节点调用 ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Permission denied."))); return UInt64GetDatum(0); } Oid user_relid; Oid nsp_oid; uint64 res_hash; - text *rel_nsp = PG_GETARG_TEXT_PP(0); - text *rel_name = PG_GETARG_TEXT_PP(1); + text *rel_nsp = PG_GETARG_TEXT_PP(0);// 获取第一个参数,用户表的命名空间 + text *rel_name = PG_GETARG_TEXT_PP(1);// 获取第二个参数,用户表名 char *table_name; char *table_nsp; - table_nsp = text_to_cstring(rel_nsp); - table_name = text_to_cstring(rel_name); - nsp_oid = get_namespace_oid(table_nsp, false); - user_relid = get_relname_relid(table_name, nsp_oid); - ledger_usertable_check(user_relid, nsp_oid, table_name, table_nsp); + table_nsp = text_to_cstring(rel_nsp);// 将文本参数转换为 C 字符串 + table_name = text_to_cstring(rel_name);// 将文本参数转换为 C 字符串 + nsp_oid = get_namespace_oid(table_nsp, false);// 获取命名空间的 OID + user_relid = get_relname_relid(table_name, nsp_oid);// 获取用户表的 OID + ledger_usertable_check(user_relid, nsp_oid, table_name, table_nsp);// 检查用户表是否存在 if (!has_ledger_consistent_privilege(user_relid, nsp_oid)) { ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("Permission denied."))); } - if (IS_PGXC_DATANODE) { - if (!is_hist_hash_identity(user_relid, &res_hash)) { + if (IS_PGXC_DATANODE) {// 如果当前节点是数据节点 + if (!is_hist_hash_identity(user_relid, &res_hash)) {// 检查用户表哈希和历史表哈希是否相等 res_hash = 0; } - } else { + } else {// 如果当前节点是协调器节点 res_hash = get_gchain_relhash_sum(user_relid); } - return UInt64GetDatum(res_hash); + return UInt64GetDatum(res_hash);//返回结果 #endif }