opengauss项目代码注释 #26
|
|
@ -2,20 +2,10 @@
|
|||
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
|
||||
* Portions Copyright (c) 2021, openGauss Contributors
|
||||
*
|
||||
* openGauss is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* knl_instance.cpp
|
||||
* Initial functions for instance level global variables.
|
||||
* 实例级全局变量的初始函数
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/gausskernel/process/threadpool/knl_instance.cpp
|
||||
|
|
@ -24,43 +14,46 @@
|
|||
*/
|
||||
#include <c.h>
|
||||
|
||||
#include "access/parallel_recovery/page_redo.h"
|
||||
#include "access/reloptions.h"
|
||||
#include "access/xlog.h"
|
||||
#include "commands/prepare.h"
|
||||
#include "executor/instrument.h"
|
||||
#include "gssignal/gs_signal.h"
|
||||
#include "access/parallel_recovery/page_redo.h"//用于并行恢复操作的头文件
|
||||
#include "access/reloptions.h"//处理表和索引的选项
|
||||
#include "access/xlog.h"//处理事务日志
|
||||
#include "commands/prepare.h"//用于SQL预处理
|
||||
#include "executor/instrument.h"//用于执行计划
|
||||
#include "gssignal/gs_signal.h"//处理操作系统信号
|
||||
#include "instruments/instr_waitevent.h"//用于性能监控等待事件
|
||||
#include "knl/knl_instance.h"//PostgreSQL内核实例
|
||||
#include "libcomm/libcomm.h"// 用于通信库的头文件
|
||||
#include "optimizer/cost.h"//查询优化中的成本估算
|
||||
#include "optimizer/dynsmp.h"//动态并行查询执行
|
||||
#include "optimizer/planmain.h"//查询规划主要头文件
|
||||
#include "optimizer/planner.h"//查询规划器
|
||||
#include "optimizer/streamplan.h"//流式查询计划
|
||||
#include "pgstat.h"//用于性能统计
|
||||
#include "regex/regex.h"//正则表达式
|
||||
#include "utils/memutils.h"//内存管理工具
|
||||
#include "utils/palloc.h"//内存分配
|
||||
#include "workload/workload.h"// 工作负载管理相关
|
||||
#include "instruments/instr_waitevent.h"
|
||||
#include "knl/knl_instance.h"
|
||||
#include "libcomm/libcomm.h"
|
||||
#include "optimizer/cost.h"
|
||||
#include "optimizer/dynsmp.h"
|
||||
#include "optimizer/planmain.h"
|
||||
#include "optimizer/planner.h"
|
||||
#include "optimizer/streamplan.h"
|
||||
#include "pgstat.h"
|
||||
#include "regex/regex.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/palloc.h"
|
||||
#include "workload/workload.h"
|
||||
#include "instruments/instr_waitevent.h"
|
||||
#include "access/multi_redo_api.h"
|
||||
#include "utils/hotkey.h"
|
||||
#include "lib/lrucache.h"
|
||||
#include "access/multi_redo_api.h"//多线程重做操作
|
||||
#include "utils/hotkey.h"//处理热点键
|
||||
#include "lib/lrucache.h"//LRU缓存
|
||||
|
||||
#ifdef ENABLE_WHITEBOX
|
||||
#include "access/ustore/knl_whitebox_test.h"
|
||||
#endif
|
||||
|
||||
const int SIZE_OF_TWO_UINT64 = 16;
|
||||
|
||||
//常量表示,两个64位整数的总大小为16字节
|
||||
knl_instance_context g_instance;
|
||||
|
||||
const int ALLOCSET_UNDO_MAXSIZE = 300 * UNDO_ZONE_COUNT;
|
||||
|
||||
extern void InitGlobalVecFuncMap();
|
||||
|
||||
//一个外部函数声明
|
||||
static void knl_g_cost_init(knl_g_cost_context* cost_cxt)
|
||||
{
|
||||
/*初始化一个 knl_g_cost_context 结构中的各个成员变量,
|
||||
以便后续的操作可以使用这些值来进行成本估算或其他计算*/
|
||||
cost_cxt->cpu_hash_cost = DEFAULT_CPU_HASH_COST;
|
||||
cost_cxt->send_kdata_cost = DEFAULT_SEND_KDATA_COST;
|
||||
cost_cxt->receive_kdata_cost = DEFAULT_RECEIVE_KDATA_COST;
|
||||
|
|
@ -70,54 +63,83 @@ static void knl_g_cost_init(knl_g_cost_context* cost_cxt)
|
|||
|
||||
static void knl_g_quota_init(knl_g_quota_context* quota_cxt)
|
||||
{
|
||||
//初始化一个 knl_g_quota_context 结构中的各个成员变量
|
||||
Assert(quota_cxt != NULL);
|
||||
//一个断言语句,用于确保 quota_cxt 指针不为空
|
||||
//如果为空,则会触发断言失败,表示出现了错误或非预期的情况
|
||||
quota_cxt->g_quota = 0;
|
||||
quota_cxt->g_quotanofify_ratio = 0;
|
||||
quota_cxt->g_having_quota = true;
|
||||
//当前具有资源配额
|
||||
quota_cxt->g_quota_changing = NULL;
|
||||
//当前没有正在更改的资源配额
|
||||
}
|
||||
|
||||
static void knl_g_localinfo_init(knl_g_localinfo_context* localinfo_cxt)
|
||||
{
|
||||
//初始化一个 knl_g_localinfo_context 结构中的各个成员变量
|
||||
Assert(localinfo_cxt != NULL);
|
||||
//用于确保 localinfo_cxt 指针不为空
|
||||
localinfo_cxt->g_local_host = NULL;
|
||||
//说明本地主机信息尚未设置
|
||||
localinfo_cxt->g_self_nodename = NULL;
|
||||
//说明本地节点名称尚未设置
|
||||
localinfo_cxt->g_local_ctrl_tcp_sock = -1;
|
||||
localinfo_cxt->sock_to_server_loop = -1;
|
||||
localinfo_cxt->gs_krb_keyfile = NULL;
|
||||
//说明本地控制 TCP 套接字尚未建立
|
||||
localinfo_cxt->sock_to_server_loop = -1;
|
||||
//说明与服务器的套接字通信尚未建立
|
||||
localinfo_cxt->gs_krb_keyfile = NULL;
|
||||
//说明Kerberos 密钥文件尚未设置
|
||||
}
|
||||
|
||||
static void knl_g_counters_init(knl_g_counters_context* counters_cxt)
|
||||
{
|
||||
//初始化一个 knl_g_counters_context 结构中的各个成员变量
|
||||
Assert(counters_cxt != NULL);
|
||||
//用于确保 counters_cxt 指针不为空
|
||||
counters_cxt->g_cur_node_num = 0;
|
||||
//表示当前节点数量为0
|
||||
counters_cxt->g_expect_node_num = 0;
|
||||
//表示期望的节点数量为0
|
||||
counters_cxt->g_max_stream_num = 0;
|
||||
//表示最大流的数量为0
|
||||
counters_cxt->g_recv_num = 0;
|
||||
//表示接收的数量为0
|
||||
counters_cxt->g_comm_send_timeout = 0;
|
||||
//表示通信发送超时时间为0
|
||||
}
|
||||
|
||||
static void knl_g_ckpt_init(knl_g_ckpt_context* ckpt_cxt)
|
||||
{
|
||||
//初始化一个 knl_g_ckpt_context 结构中的各个成员变量
|
||||
Assert(ckpt_cxt != NULL);
|
||||
//确保 ckpt_cxt 指针不为空
|
||||
errno_t rc = memset_s(ckpt_cxt, sizeof(knl_g_ckpt_context), 0, sizeof(knl_g_ckpt_context));
|
||||
securec_check(rc, "\0", "\0");
|
||||
//用 memset_s 函数将 knl_g_ckpt_context 结构的内存区域初始化为0
|
||||
securec_check(rc, "\0", "\0");
|
||||
//用于检查 memset_s 调用结果的安全检查,如果调试失败,会触发错误,停止运行
|
||||
SpinLockInit(&(ckpt_cxt->queue_lock));
|
||||
//初始化名为 queue_lock 的自旋锁 (自旋锁是一种用于多线程编程的同步机制,用于保护共享资源免受并发访问的干扰)
|
||||
}
|
||||
|
||||
static void knl_g_wal_init(knl_g_wal_context *const wal_cxt)
|
||||
{
|
||||
//初始化一个 knl_g_wal_context 结构,它包含了一系列成员变量的初始化操作
|
||||
int ret = 0;
|
||||
//用于存储函数返回值或错误码
|
||||
ret = pthread_condattr_init(&wal_cxt->criticalEntryAtt);
|
||||
if (ret != 0) {
|
||||
//初始化条件变量属性 criticalEntryAtt
|
||||
if (ret != 0) {
|
||||
elog(FATAL, "Fail to init conattr for walwrite");
|
||||
}
|
||||
ret = pthread_condattr_setclock(&wal_cxt->criticalEntryAtt, CLOCK_MONOTONIC);
|
||||
if (ret != 0) {
|
||||
//设置条件变量属性的时钟类型为 CLOCK_MONOTONIC
|
||||
if (ret != 0) {
|
||||
elog(FATAL, "Fail to setclock walwrite");
|
||||
}
|
||||
ret = pthread_cond_init(&wal_cxt->criticalEntryCV, &wal_cxt->criticalEntryAtt);
|
||||
if (ret != 0) {
|
||||
//初始化条件变量 criticalEntryCV,并将其关联到条件变量属性 criticalEntryAtt
|
||||
if (ret != 0) {
|
||||
elog(FATAL, "Fail to init cond for walwrite");
|
||||
}
|
||||
|
||||
|
|
@ -143,37 +165,55 @@ static void knl_g_wal_init(knl_g_wal_context *const wal_cxt)
|
|||
wal_cxt->totalXlogIterBytes = 0;
|
||||
wal_cxt->totalXlogIterTimes = 0;
|
||||
wal_cxt->xlogFlushStats = NULL;
|
||||
//初始化了结构中的各个成员变量
|
||||
//上述初始化通常用于数据库系统中与WAL相关的管理和同步
|
||||
}
|
||||
|
||||
static void knl_g_bgwriter_init(knl_g_bgwriter_context *bgwriter_cxt)
|
||||
{
|
||||
//初始化一个 knl_g_bgwriter_context 结构中的各个成员变量
|
||||
Assert(bgwriter_cxt != NULL);
|
||||
//确保 bgwriter_cxt 指针不为空
|
||||
bgwriter_cxt->unlink_rel_hashtbl = NULL;
|
||||
//表示未分配关联的哈希表
|
||||
bgwriter_cxt->rel_hashtbl_lock = NULL;
|
||||
//表示未分配关联的锁
|
||||
bgwriter_cxt->invalid_buf_proc_latch = NULL;
|
||||
bgwriter_cxt->unlink_rel_fork_hashtbl = NULL;
|
||||
bgwriter_cxt->rel_one_fork_hashtbl_lock = NULL;
|
||||
//表示未分配关联的事件触发器
|
||||
bgwriter_cxt->unlink_rel_fork_hashtbl = NULL;
|
||||
bgwriter_cxt->rel_one_fork_hashtbl_lock = NULL;
|
||||
//上述初始化通常用于数据库系统中与数据修复或一致性检查相关的数据结构和同步
|
||||
}
|
||||
|
||||
static void knl_g_repair_init(knl_g_repair_context *repair_cxt)
|
||||
{
|
||||
//初始化一个 knl_g_repair_context 结构中的各个成员变量
|
||||
Assert(repair_cxt != NULL);
|
||||
//确保 repair_cxt 指针不为空
|
||||
repair_cxt->page_repair_hashtbl = NULL;
|
||||
//表示未分配关联的哈希表
|
||||
repair_cxt->page_repair_hashtbl_lock = NULL;
|
||||
repair_cxt->repair_proc_latch = NULL;
|
||||
//表示未分配关联的锁
|
||||
repair_cxt->repair_proc_latch = NULL;
|
||||
//表示未分配关联的锁
|
||||
}
|
||||
|
||||
static void knl_g_startup_init(knl_g_startup_context *starup_cxt)
|
||||
{
|
||||
//初始化一个 knl_g_startup_context 结构中的各个成员变量
|
||||
Assert(starup_cxt != NULL);
|
||||
starup_cxt->remoteReadPageNum = 0;
|
||||
//表示远程读取的页面数量为0
|
||||
starup_cxt->badPageHashTbl = NULL;
|
||||
starup_cxt->current_record = NULL;
|
||||
//表示当前记录为空
|
||||
//上述代码通常用于数据库系统的启动阶段相关的数据结构初始化
|
||||
}
|
||||
|
||||
|
||||
static void knl_g_tests_init(knl_g_tests_context* tests_cxt)
|
||||
{
|
||||
//初始化一个 knl_g_tests_context 结构中的各个成员变量
|
||||
Assert(tests_cxt != NULL);
|
||||
tests_cxt->libcomm_test_current_thread = 0;
|
||||
tests_cxt->libcomm_test_thread_arg = NULL;
|
||||
|
|
@ -184,10 +224,12 @@ static void knl_g_tests_init(knl_g_tests_context* tests_cxt)
|
|||
tests_cxt->libcomm_test_send_once = 0;
|
||||
tests_cxt->libcomm_test_recv_sleep = 0;
|
||||
tests_cxt->libcomm_test_recv_once = 0;
|
||||
//上述多用于进行测试和调试
|
||||
}
|
||||
|
||||
static void knl_g_pollers_init(knl_g_pollers_context* pollers_cxt)
|
||||
{
|
||||
//表示尚未请求关闭轮询(poll)操作
|
||||
Assert(pollers_cxt != NULL);
|
||||
pollers_cxt->g_libcomm_receiver_poller_list = NULL;
|
||||
pollers_cxt->g_r_libcomm_poller_list_lock = NULL;
|
||||
|
|
@ -199,20 +241,30 @@ static void knl_g_pollers_init(knl_g_pollers_context* pollers_cxt)
|
|||
|
||||
static void knl_g_reqcheck_init(knl_g_reqcheck_context* reqcheck_cxt)
|
||||
{
|
||||
// 初始化一个 knl_g_reqcheck_context 结构中的各个成员变量
|
||||
Assert(reqcheck_cxt != NULL);
|
||||
reqcheck_cxt->g_shutdown_requested = false;
|
||||
//表示尚未请求关闭操作
|
||||
reqcheck_cxt->g_cancel_requested = 0;
|
||||
//表示尚未请求取消操作
|
||||
reqcheck_cxt->g_close_poll_requested = false;
|
||||
//表示尚未请求关闭轮询操作
|
||||
}
|
||||
|
||||
static void knl_g_mctcp_init(knl_g_mctcp_context* mctcp_cxt)
|
||||
{
|
||||
//初始化一个 knl_g_mctcp_context 结构中的各个成员变量
|
||||
Assert(mctcp_cxt != NULL);
|
||||
mctcp_cxt->mc_tcp_keepalive_idle = 0;
|
||||
//表示TCP连接的空闲时间(idle time)为0
|
||||
mctcp_cxt->mc_tcp_keepalive_interval = 0;
|
||||
mctcp_cxt->mc_tcp_keepalive_count = 0;
|
||||
//表示TCP保活消息发送的间隔时间为0
|
||||
mctcp_cxt->mc_tcp_keepalive_count = 0;
|
||||
//表示TCP保活消息发送的次数为0
|
||||
mctcp_cxt->mc_tcp_connect_timeout = 0;
|
||||
//表示TCP连接的超时时间为0
|
||||
mctcp_cxt->mc_tcp_send_timeout = 0;
|
||||
//表示TCP发送操作的超时时间为0
|
||||
}
|
||||
|
||||
static void knl_g_commutil_init(knl_g_commutil_context* commutil_cxt)
|
||||
|
|
@ -231,14 +283,19 @@ static void knl_g_commutil_init(knl_g_commutil_context* commutil_cxt)
|
|||
static void knl_g_parallel_redo_init(knl_g_parallel_redo_context* predo_cxt)
|
||||
{
|
||||
Assert(predo_cxt != NULL);
|
||||
//确保 predo_cxt 指针不为空
|
||||
predo_cxt->state = REDO_INIT;
|
||||
//表示并行重做的状态为初始化状态
|
||||
predo_cxt->parallelRedoCtx = NULL;
|
||||
//表示未分配关联的并行重做上下文
|
||||
for (int i = 0; i < MAX_RECOVERY_THREAD_NUM; ++i) {
|
||||
predo_cxt->pageRedoThreadStatusList[i].threadId = 0;
|
||||
predo_cxt->pageRedoThreadStatusList[i].threadState = PAGE_REDO_WORKER_INVALID;
|
||||
}
|
||||
predo_cxt->totalNum = 0;
|
||||
//表示总线程数为0
|
||||
SpinLockInit(&(predo_cxt->rwlock));
|
||||
//初始化自旋锁 rwlock
|
||||
predo_cxt->redoPf.redo_start_ptr = 0;
|
||||
predo_cxt->redoPf.redo_start_time = 0;
|
||||
predo_cxt->redoPf.redo_done_time = 0;
|
||||
|
|
@ -250,13 +307,18 @@ static void knl_g_parallel_redo_init(knl_g_parallel_redo_context* predo_cxt)
|
|||
predo_cxt->redoPf.speed_according_seg = 0;
|
||||
predo_cxt->redoPf.local_max_lsn = 0;
|
||||
predo_cxt->redoPf.oldest_segment = 1;
|
||||
//用于记录重做的进度和性能信息
|
||||
knl_g_set_redo_finish_status(0);
|
||||
//将重做完成状态设置为0
|
||||
predo_cxt->redoType = DEFAULT_REDO;
|
||||
//表示重做类型为默认类型
|
||||
predo_cxt->pre_enable_switch = 0;
|
||||
//将 pre_enable_switch 成员设置为0
|
||||
SpinLockInit(&(predo_cxt->destroy_lock));
|
||||
for (int i = 0; i < NUM_MAX_PAGE_FLUSH_LSN_PARTITIONS; ++i) {
|
||||
pg_atomic_write_u64(&(predo_cxt->max_page_flush_lsn[i]), 0);
|
||||
}
|
||||
//用于记录最大页面刷新LSN(Log Sequence Number)的值
|
||||
predo_cxt->permitFinishRedo = 0;
|
||||
predo_cxt->last_replayed_conflict_csn = 0;
|
||||
predo_cxt->hotStdby = 0;
|
||||
|
|
@ -276,27 +338,35 @@ static void knl_g_parallel_decode_init(knl_g_parallel_decode_context* pdecode_cx
|
|||
{
|
||||
Assert(pdecode_cxt != NULL);
|
||||
pdecode_cxt->state = DECODE_INIT;
|
||||
//表示并行解码的状态为初始化状态
|
||||
pdecode_cxt->parallelDecodeCtx = NULL;
|
||||
//表示未分配关联的并行解码上下文
|
||||
pdecode_cxt->ParallelReaderWorkerStatus.threadId = 0;
|
||||
pdecode_cxt->ParallelReaderWorkerStatus.threadState = PARALLEL_DECODE_WORKER_INVALID;
|
||||
for (int i = 0; i < MAX_PARALLEL_DECODE_NUM; ++i) {
|
||||
//表示并行解码工作者状态为无效
|
||||
for (int i = 0; i < MAX_PARALLEL_DECODE_NUM; ++i) {
|
||||
pdecode_cxt->ParallelDecodeWorkerStatusList[i].threadId = 0;
|
||||
pdecode_cxt->ParallelDecodeWorkerStatusList[i].threadState = PARALLEL_DECODE_WORKER_INVALID;
|
||||
}
|
||||
pdecode_cxt->totalNum = 0;
|
||||
//表示总线程数为0
|
||||
SpinLockInit(&(pdecode_cxt->rwlock));
|
||||
SpinLockInit(&(pdecode_cxt->destroy_lock));
|
||||
//初始化自旋锁 destroy_lock
|
||||
}
|
||||
|
||||
static void knl_g_cache_init(knl_g_cache_context* cache_cxt)
|
||||
{
|
||||
cache_cxt->global_cache_mem = NULL;
|
||||
//表示全局缓存内存未分配
|
||||
for (int i = 0; i < MAX_GLOBAL_CACHEMEM_NUM; ++i)
|
||||
cache_cxt->global_plancache_mem[i] = NULL;
|
||||
//通过循环遍历,对 global_plancache_mem 数组中的每个元素进行初始化
|
||||
}
|
||||
|
||||
void knl_g_cachemem_create()
|
||||
{
|
||||
//创建全局缓存内存上下文,命名为 "GlobalCacheMemory",并设置默认的内存分配参数
|
||||
g_instance.cache_cxt.global_cache_mem = AllocSetContextCreate(g_instance.instance_context,
|
||||
"GlobalCacheMemory",
|
||||
ALLOCSET_DEFAULT_MINSIZE,
|
||||
|
|
@ -305,7 +375,7 @@ void knl_g_cachemem_create()
|
|||
SHARED_CONTEXT,
|
||||
DEFAULT_MEMORY_CONTEXT_MAX_SIZE,
|
||||
false);
|
||||
|
||||
//遍历全局计划缓存内存数组,为每个元素创建内存上下文,命名为 "GlobalPlanCacheMemory",并设置默认的内存分配参数
|
||||
for (int i = 0; i < MAX_GLOBAL_CACHEMEM_NUM; ++i) {
|
||||
g_instance.cache_cxt.global_plancache_mem[i] = AllocSetContextCreate(g_instance.instance_context,
|
||||
"GlobalPlanCacheMemory",
|
||||
|
|
@ -316,6 +386,7 @@ void knl_g_cachemem_create()
|
|||
DEFAULT_MEMORY_CONTEXT_MAX_SIZE,
|
||||
false);
|
||||
}
|
||||
//遍历全局包运行时缓存内存数组,为每个元素创建内存上下文,命名为 "GlobalPackageRuntimeCacheMemory",并设置默认的内存分配参数
|
||||
for (int i = 0; i < MAX_GLOBAL_PRC_NUM; ++i) {
|
||||
g_instance.cache_cxt.global_prc_mem[i] = AllocSetContextCreate(g_instance.instance_context,
|
||||
"GlobalPackageRuntimeCacheMemory",
|
||||
|
|
@ -326,58 +397,72 @@ void knl_g_cachemem_create()
|
|||
DEFAULT_MEMORY_CONTEXT_MAX_SIZE,
|
||||
false);
|
||||
}
|
||||
//创建全局计划缓存对象
|
||||
g_instance.plan_cache = New(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_EXECUTOR)) GlobalPlanCache();
|
||||
g_instance.global_session_pkg = PLGlobalPackageRuntimeCache::Instance();
|
||||
//创建全局会话包运行时缓存对象
|
||||
g_instance.global_session_pkg = PLGlobalPackageRuntimeCache::Instance();
|
||||
}
|
||||
static void knl_g_comm_init(knl_g_comm_context* comm_cxt)
|
||||
{
|
||||
//断言确保传入的 comm_cxt 指针不为空
|
||||
Assert(comm_cxt != NULL);
|
||||
comm_cxt->gs_wakeup_consumer = NULL;
|
||||
comm_cxt->g_receivers = NULL;
|
||||
comm_cxt->g_senders = NULL;
|
||||
comm_cxt->g_delay_survey_switch = false;
|
||||
comm_cxt->g_unix_path = NULL;
|
||||
comm_cxt->g_ha_shm_data = NULL;
|
||||
comm_cxt->g_usable_streamid = NULL;
|
||||
comm_cxt->g_r_node_sock = NULL;
|
||||
comm_cxt->g_s_node_sock = NULL;
|
||||
comm_cxt->g_delay_info = NULL;
|
||||
comm_cxt->g_c_mailbox = NULL;
|
||||
comm_cxt->g_p_mailbox = NULL;
|
||||
comm_cxt->libcomm_log_timezone = NULL;
|
||||
comm_cxt->force_cal_space_info = false;
|
||||
comm_cxt->cal_all_space_info_in_progress = false;
|
||||
comm_cxt->current_gsrewind_count = 0;
|
||||
comm_cxt->isNeedChangeRole = false;
|
||||
comm_cxt->usedDnSpace = NULL;
|
||||
comm_cxt->request_disaster_cluster = true;
|
||||
comm_cxt->lastArchiveRcvTime = 0;
|
||||
|
||||
//初始化 comm_cxt 结构中的各个成员变量为默认值或 NULL
|
||||
comm_cxt->gs_wakeup_consumer = NULL; //指向唤醒消费者的指针
|
||||
comm_cxt->g_receivers = NULL; //接收者信息
|
||||
comm_cxt->g_senders = NULL; //发送者信息
|
||||
comm_cxt->g_delay_survey_switch = false; //延迟测量开关
|
||||
comm_cxt->g_unix_path = NULL; //UNIX 套接字路径
|
||||
comm_cxt->g_ha_shm_data = NULL; //HA 共享内存数据
|
||||
comm_cxt->g_usable_streamid = NULL; //可用的流 ID
|
||||
comm_cxt->g_r_node_sock = NULL; //接收节点套接字信息
|
||||
comm_cxt->g_s_node_sock = NULL; //发送节点套接字信息
|
||||
comm_cxt->g_delay_info = NULL; //延迟信息
|
||||
comm_cxt->g_c_mailbox = NULL; //CMailbox(通信邮箱)信息
|
||||
comm_cxt->g_p_mailbox = NULL; //PMailbox(通信邮箱)信息
|
||||
comm_cxt->libcomm_log_timezone = NULL; //日志时区
|
||||
comm_cxt->force_cal_space_info = false; //强制计算空间信息标志
|
||||
comm_cxt->cal_all_space_info_in_progress = false; //正在计算所有空间信息的标志
|
||||
comm_cxt->current_gsrewind_count = 0; //当前 GS_REWIND 的计数
|
||||
comm_cxt->isNeedChangeRole = false; //是否需要改变角色
|
||||
comm_cxt->usedDnSpace = NULL; //已用的数据节点空间信息
|
||||
comm_cxt->request_disaster_cluster = true; //请求灾备集群信息的标志
|
||||
comm_cxt->lastArchiveRcvTime = 0; //上次归档接收时间
|
||||
|
||||
#ifdef USE_SSL
|
||||
comm_cxt->libcomm_data_port_list = NULL;
|
||||
comm_cxt->libcomm_ctrl_port_list = NULL;
|
||||
//如果使用 SSL 加密通信,则初始化 SSL 相关的成员变量
|
||||
comm_cxt->libcomm_data_port_list = NULL; //数据端口列表
|
||||
comm_cxt->libcomm_ctrl_port_list = NULL; //控制端口列表
|
||||
#endif
|
||||
|
||||
knl_g_quota_init(&g_instance.comm_cxt.quota_cxt);
|
||||
knl_g_localinfo_init(&g_instance.comm_cxt.localinfo_cxt);
|
||||
knl_g_counters_init(&g_instance.comm_cxt.counters_cxt);
|
||||
knl_g_tests_init(&g_instance.comm_cxt.tests_cxt);
|
||||
knl_g_pollers_init(&g_instance.comm_cxt.pollers_cxt);
|
||||
knl_g_reqcheck_init(&g_instance.comm_cxt.reqcheck_cxt);
|
||||
knl_g_mctcp_init(&g_instance.comm_cxt.mctcp_cxt);
|
||||
knl_g_commutil_init(&g_instance.comm_cxt.commutil_cxt);
|
||||
knl_g_parallel_redo_init(&g_instance.comm_cxt.predo_cxt);
|
||||
//分别调用其他初始化函数来初始化 comm_cxt 中的其他成员变量
|
||||
knl_g_quota_init(&g_instance.comm_cxt.quota_cxt); //初始化配额信息
|
||||
knl_g_localinfo_init(&g_instance.comm_cxt.localinfo_cxt); //初始化本地信息
|
||||
knl_g_counters_init(&g_instance.comm_cxt.counters_cxt); //初始化计数器信息
|
||||
knl_g_tests_init(&g_instance.comm_cxt.tests_cxt); //初始化测试信息
|
||||
knl_g_pollers_init(&g_instance.comm_cxt.pollers_cxt); //初始化轮询器信息
|
||||
knl_g_reqcheck_init(&g_instance.comm_cxt.reqcheck_cxt); //初始化请求检查信息
|
||||
knl_g_mctcp_init(&g_instance.comm_cxt.mctcp_cxt); //初始化 MCTCP 信息
|
||||
knl_g_commutil_init(&g_instance.comm_cxt.commutil_cxt); //初始化通信工具信息
|
||||
knl_g_parallel_redo_init(&g_instance.comm_cxt.predo_cxt); //初始化并行重做信息
|
||||
|
||||
//遍历并初始化并行解码信息(根据最大复制槽数)
|
||||
for (int i = 0; i < g_instance.attr.attr_storage.max_replication_slots; ++i) {
|
||||
knl_g_parallel_decode_init(&g_instance.comm_cxt.pdecode_cxt[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void knl_g_conn_init(knl_g_conn_context* conn_cxt)
|
||||
{
|
||||
conn_cxt->CurConnCount = 0;
|
||||
//表示当前连接的数量为0
|
||||
conn_cxt->CurCMAConnCount = 0;
|
||||
//表示当前 CMA连接的数量为0
|
||||
conn_cxt->CurCMAProcCount = 0;
|
||||
//表示当前 CMA 进程的数量为0
|
||||
SpinLockInit(&conn_cxt->ConnCountLock);
|
||||
//用于在多线程环境下保护连接计数信息的并发访问
|
||||
}
|
||||
|
||||
static void knl_g_executor_init(knl_g_executor_context* exec_cxt)
|
||||
|
|
@ -396,29 +481,43 @@ static void knl_g_rto_init(knl_g_rto_context *rto_cxt)
|
|||
|
||||
static void knl_g_xlog_init(knl_g_xlog_context *xlog_cxt)
|
||||
{
|
||||
// 始化 xlog_cxt 结构中的成员变量为默认值或 NULL
|
||||
|
||||
//初始化 num_locks_in_group 为0,表示锁组数量为0
|
||||
xlog_cxt->num_locks_in_group = 0;
|
||||
|
||||
#ifdef ENABLE_MOT
|
||||
//如果启用了 MOT 存储引擎,则初始化 redoCommitCallback 为 NULL
|
||||
xlog_cxt->redoCommitCallback = NULL;
|
||||
#endif
|
||||
|
||||
//初始化 shareStorageXLogCtl 和 shareStorageXLogCtlOrigin 为 NULL
|
||||
xlog_cxt->shareStorageXLogCtl = NULL;
|
||||
xlog_cxt->shareStorageXLogCtlOrigin = NULL;
|
||||
//使用 memset_s 函数将 shareStorageopCtl 结构初始化为0
|
||||
errno_t rc = memset_s(&xlog_cxt->shareStorageopCtl, sizeof(ShareStorageOperateCtl), 0,
|
||||
sizeof(ShareStorageOperateCtl));
|
||||
securec_check(rc, "\0", "\0");
|
||||
//初始化 remain_segs_lock 互斥锁为 NULL
|
||||
pthread_mutex_init(&xlog_cxt->remain_segs_lock, NULL);
|
||||
//初始化 shareStorageLockFd 为 -1,表示共享存储锁的文件描述符为无效值
|
||||
xlog_cxt->shareStorageLockFd = -1;
|
||||
}
|
||||
|
||||
|
||||
static void KnlGUndoInit(knl_g_undo_context *undoCxt)
|
||||
{
|
||||
//使用 undo 命名空间
|
||||
using namespace undo;
|
||||
MemoryContext oldContext;
|
||||
|
||||
//创建 Undo 命名空间的内存上下文,并将其设置为当前上下文
|
||||
g_instance.undo_cxt.undoContext = AllocSetContextCreate(g_instance.instance_context,
|
||||
"Undo", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_UNDO_MAXSIZE, SHARED_CONTEXT);
|
||||
oldContext = MemoryContextSwitchTo(g_instance.undo_cxt.undoContext);
|
||||
/*
|
||||
* Create three bitmaps for undozone with three kinds of tables(permanent, unlogged and temp).
|
||||
* Use -1 to initialize each bit of the bitmap as 1.
|
||||
为每个持久性级别(permanent, unlogged 和 temp)创建三个位图,
|
||||
使用 -1 初始化位图的每个位(bit)为1。
|
||||
*/
|
||||
for (auto i = 0; i < UNDO_PERSISTENCE_LEVELS; i++) {
|
||||
g_instance.undo_cxt.uZoneBitmap[i] = bms_add_member(g_instance.undo_cxt.uZoneBitmap[i], PERSIST_ZONE_COUNT);
|
||||
|
|
@ -426,7 +525,9 @@ static void KnlGUndoInit(knl_g_undo_context *undoCxt)
|
|||
(g_instance.undo_cxt.uZoneBitmap[i])->nwords * sizeof(bitmapword),
|
||||
-1, (g_instance.undo_cxt.uZoneBitmap[i])->nwords * sizeof(bitmapword));
|
||||
}
|
||||
//恢复先前的内存上下文
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
//初始化 undoCxt 结构中的成员变量为默认值
|
||||
undoCxt->undoTotalSize = 0;
|
||||
undoCxt->undoMetaSize = 0;
|
||||
undoCxt->uZoneCount = 0;
|
||||
|
|
@ -443,6 +544,7 @@ static void knl_g_flashback_init(knl_g_flashback_context *flashbackCxt)
|
|||
|
||||
static void knl_g_libpq_init(knl_g_libpq_context* libpq_cxt)
|
||||
{
|
||||
//初始化libpq中各参数值
|
||||
Assert(libpq_cxt != NULL);
|
||||
libpq_cxt->pam_passwd = NULL;
|
||||
libpq_cxt->pam_port_cludge = NULL;
|
||||
|
|
@ -452,6 +554,7 @@ static void knl_g_libpq_init(knl_g_libpq_context* libpq_cxt)
|
|||
|
||||
static void InitHotkeyResources(knl_g_stat_context* stat_cxt)
|
||||
{
|
||||
//如果 hotkeysCxt 为 NULL,则创建一个新的内存上下文 hotkeysCxt
|
||||
if (stat_cxt->hotkeysCxt == NULL) {
|
||||
stat_cxt->hotkeysCxt = AllocSetContextCreate(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_OPTIMIZER),
|
||||
"HotkeysMemory",
|
||||
|
|
@ -460,48 +563,68 @@ static void InitHotkeyResources(knl_g_stat_context* stat_cxt)
|
|||
ALLOCSET_DEFAULT_MAXSIZE,
|
||||
SHARED_CONTEXT);
|
||||
}
|
||||
|
||||
//在 hotkeysCxt 内存上下文中创建 CircularQueue(循环队列)并初始化
|
||||
stat_cxt->hotkeysCollectList = New(stat_cxt->hotkeysCxt) CircularQueue(HOTKEYS_QUEUE_LENGTH, stat_cxt->hotkeysCxt);
|
||||
stat_cxt->hotkeysCollectList->Init();
|
||||
|
||||
//在 hotkeysCxt 内存上下文中创建 LRUCache(最近最少使用缓存)并初始化
|
||||
stat_cxt->lru = New(stat_cxt->hotkeysCxt) LRUCache(LRU_QUEUE_LENGTH, stat_cxt->hotkeysCxt);
|
||||
stat_cxt->lru->Init();
|
||||
|
||||
//初始化 fifo(First-In-First-Out,先进先出)队列为 NULL
|
||||
stat_cxt->fifo = NIL;
|
||||
}
|
||||
|
||||
static void knl_g_stat_init(knl_g_stat_context* stat_cxt)
|
||||
{
|
||||
//初始化等待计数哈希表为 NULL
|
||||
stat_cxt->WaitCountHashTbl = NULL;
|
||||
//初始化等待计数状态列表为 NULL
|
||||
stat_cxt->WaitCountStatusList = NULL;
|
||||
//初始化 pgStatSock 为无效的套接字
|
||||
stat_cxt->pgStatSock = PGINVALID_SOCKET;
|
||||
//初始化 got_SIGHUP 为 false
|
||||
stat_cxt->got_SIGHUP = false;
|
||||
|
||||
//初始化 UniqueSqlContext 为 NULL
|
||||
stat_cxt->UniqueSqlContext = NULL;
|
||||
//初始化 UniqueSQLHashtbl 为 NULL
|
||||
stat_cxt->UniqueSQLHashtbl = NULL;
|
||||
//初始化 InstrUserHTAB 为 NULL
|
||||
stat_cxt->InstrUserHTAB = NULL;
|
||||
//初始化 calculate_on_other_cn 为 false
|
||||
stat_cxt->calculate_on_other_cn = false;
|
||||
//初始化 force_process 为 false
|
||||
stat_cxt->force_process = false;
|
||||
//初始化 RTPERCENTILE 数组的元素为 0
|
||||
stat_cxt->RTPERCENTILE[0] = 0;
|
||||
stat_cxt->RTPERCENTILE[1] = 0;
|
||||
//初始化 NodeStatResetTime 为 0
|
||||
stat_cxt->NodeStatResetTime = 0;
|
||||
//初始化 sql_rt_info_array 为 NULL
|
||||
stat_cxt->sql_rt_info_array = NULL;
|
||||
|
||||
//初始化 gInstanceTimeInfo 数组为 0
|
||||
stat_cxt->gInstanceTimeInfo = (int64*)MemoryContextAllocZero(
|
||||
INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_DFX), TOTAL_TIME_INFO_TYPES * sizeof(int64));
|
||||
errno_t rc;
|
||||
rc = memset_s(
|
||||
stat_cxt->gInstanceTimeInfo, TOTAL_TIME_INFO_TYPES * sizeof(int64), 0, TOTAL_TIME_INFO_TYPES * sizeof(int64));
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
|
||||
//初始化 snapshot_thread_counter 为 0
|
||||
stat_cxt->snapshot_thread_counter = 0;
|
||||
|
||||
//初始化 fileIOStat 为 0
|
||||
stat_cxt->fileIOStat = (FileIOStat*)MemoryContextAllocZero(
|
||||
INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_DFX), sizeof(FileIOStat));
|
||||
rc = memset_s(stat_cxt->fileIOStat, sizeof(FileIOStat), 0, sizeof(FileIOStat));
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
//初始化 tableStat 为 0
|
||||
stat_cxt->tableStat = (UHeapPruneStat *) palloc0(sizeof(UHeapPruneStat));
|
||||
rc = memset_s(stat_cxt->tableStat, sizeof(UHeapPruneStat), 0, sizeof(UHeapPruneStat));
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
|
||||
stat_cxt->active_sess_hist_arrary = NULL;
|
||||
stat_cxt->ash_appname = NULL;
|
||||
stat_cxt->instr_stmt_is_cleaning = false;
|
||||
|
|
@ -509,11 +632,13 @@ static void knl_g_stat_init(knl_g_stat_context* stat_cxt)
|
|||
stat_cxt->ASHUniqueSQLHashtbl = NULL;
|
||||
stat_cxt->track_context_hash = NULL;
|
||||
stat_cxt->track_memory_info_hash = NULL;
|
||||
|
||||
//创建并初始化用于跟踪内存锁的 rwlock
|
||||
pthread_rwlockattr_t attr;
|
||||
/* set write-first lock for rwlock to avoid hunger of wrlock */
|
||||
(void)pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
|
||||
(void)pthread_rwlock_init(&(stat_cxt->track_memory_lock), &attr);
|
||||
|
||||
|
||||
//调用 InitHotkeyResources 函数来初始化热点数据统计资源
|
||||
InitHotkeyResources(stat_cxt);
|
||||
}
|
||||
|
||||
|
|
@ -524,17 +649,23 @@ static void knl_g_adv_init(knl_g_advisor_conntext* adv_cxt)
|
|||
adv_cxt->maxMemory = 0;
|
||||
adv_cxt->maxsqlCount = 0;
|
||||
adv_cxt->currentUser = InvalidOid;
|
||||
//表示没有有效的用户标识
|
||||
adv_cxt->currentDB = InvalidOid;
|
||||
//表示没有有效的数据库标识
|
||||
adv_cxt->GWCArray = NULL;
|
||||
|
||||
//表示没有分配内存或初始化该数组
|
||||
|
||||
adv_cxt->SQLAdvisorContext = NULL;
|
||||
//表示没有为 SQL 查询优化提供额外的上下文或资源
|
||||
}
|
||||
|
||||
static void knl_g_pid_init(knl_g_pid_context* pid_cxt)
|
||||
{
|
||||
errno_t rc;
|
||||
errno_t rc;//表示操作是否成功
|
||||
rc = memset_s(pid_cxt, sizeof(knl_g_pid_context), 0, sizeof(knl_g_pid_context));
|
||||
pid_cxt->PageWriterPID = NULL;
|
||||
/*memset_s 是一个安全版本的内存清零函数,它接受四个参数:目标内存地址,目标内存大小,
|
||||
设置的值(这里是0),以及目标内存的大小。这可以确保 pid_cxt 的所有字段都被初始化为0。*/
|
||||
pid_cxt->PageWriterPID = NULL;
|
||||
pid_cxt->CommReceiverPIDS = NULL;
|
||||
pid_cxt->PgAuditPID = NULL;
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
|
@ -542,7 +673,8 @@ static void knl_g_pid_init(knl_g_pid_context* pid_cxt)
|
|||
|
||||
static void knl_g_wlm_init(knl_g_wlm_context* wlm_cxt)
|
||||
{
|
||||
wlm_cxt->parctl_process_memory = 8; // initialize the per query memory as 8 MB
|
||||
wlm_cxt->parctl_process_memory = 8;
|
||||
//将每个查询的内存初始化为8 MB
|
||||
|
||||
wlm_cxt->cluster_state = NULL;
|
||||
wlm_cxt->dnnum_in_cluster_state = 0;
|
||||
|
|
@ -571,10 +703,15 @@ static void knl_g_compaction_init(knl_g_ts_compaction_context* tsc_cxt)
|
|||
Assert(tsc_cxt != NULL);
|
||||
tsc_cxt->totalNum = 0;
|
||||
tsc_cxt->state = Compaction::COMPACTION_INIT;
|
||||
tsc_cxt->drop_db_count = 0;
|
||||
//表示压缩状态为初始化状态
|
||||
tsc_cxt->drop_db_count = 0;
|
||||
//表示要删除的数据库数量
|
||||
tsc_cxt->origin_id = (int*)palloc0(sizeof(int) * Compaction::MAX_TSCOMPATION_NUM);
|
||||
tsc_cxt->compaction_rest = false;
|
||||
//用于跟踪数据库的原始标识
|
||||
tsc_cxt->compaction_rest = false;
|
||||
//表示没有进行压缩的休息状态
|
||||
tsc_cxt->dropdb_id = InvalidOid;
|
||||
//表示要删除的数据库的标识
|
||||
for (int i = 0; i < Compaction::MAX_TSCOMPATION_NUM; i++) {
|
||||
tsc_cxt->compaction_worker_status_list[i].thread_id = 0;
|
||||
tsc_cxt->compaction_worker_status_list[i].thread_state = Compaction::COMPACTION_WORKER_INVALID;
|
||||
|
|
@ -595,10 +732,13 @@ static void knl_g_dw_init(knl_g_dw_context *dw_cxt)
|
|||
errno_t rc = memset_s(dw_cxt, sizeof(knl_g_dw_context), 0, sizeof(knl_g_dw_context));
|
||||
securec_check(rc, "\0", "\0");
|
||||
dw_cxt->closed = 1;
|
||||
|
||||
//表示数据仓库处于关闭状态
|
||||
dw_cxt->old_batch_version = false;
|
||||
//表示使用的是旧批处理版本
|
||||
dw_cxt->recovery_dw_file_num = 0;
|
||||
//表示恢复时的数据仓库文件数量为 0
|
||||
dw_cxt->recovery_dw_file_size = 0;
|
||||
//表示恢复时的数据仓库文件大小为 0
|
||||
}
|
||||
|
||||
static void knl_g_numa_init(knl_g_numa_context* numa_cxt)
|
||||
|
|
@ -627,6 +767,7 @@ static void knl_g_archive_obs_init(knl_g_archive_context *archive_cxt)
|
|||
|
||||
static void knl_g_archive_thread_info_init(knl_g_archive_thread_info *archive_thread_info)
|
||||
{
|
||||
//用于为归档线程信息的全局结构体设置默认值和状态
|
||||
errno_t rc = memset_s(archive_thread_info, sizeof(knl_g_archive_thread_info), 0,
|
||||
sizeof(knl_g_archive_thread_info));
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
|
@ -637,6 +778,7 @@ static void knl_g_archive_thread_info_init(knl_g_archive_thread_info *archive_th
|
|||
static void knl_g_mot_init(knl_g_mot_context* mot_cxt)
|
||||
{
|
||||
mot_cxt->jitExecMode = JitExec::JIT_EXEC_MODE_INVALID;
|
||||
//这个字段用于表示 MOT 执行的 JIT(即时编译)模式,此处将其初始化为无效模式
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -672,6 +814,7 @@ static void knl_g_pldebug_init(knl_g_pldebug_context* pldebug_cxt)
|
|||
|
||||
static void knl_g_spi_plan_init(knl_g_spi_plan_context* spi_plan_cxt)
|
||||
{
|
||||
//用于在初始化 SPI 计划上下文时,将其字段初始化为默认值或空值
|
||||
spi_plan_cxt->global_spi_plan_context = NULL;
|
||||
spi_plan_cxt->FPlans = NULL;
|
||||
spi_plan_cxt->nFPlans = 0;
|
||||
|
|
@ -759,11 +902,17 @@ void knl_instance_init()
|
|||
pg_atomic_init_u32(&g_instance.extensionNum, 0);
|
||||
|
||||
/*
|
||||
* Set up the process wise memory context. The memory allocated from this
|
||||
* context will not be released untill it is called free. Meanwhile, the
|
||||
* memory context is visible to all threads but not thread safe, so only
|
||||
* postmaster thread shall use it or use it with lock protection.
|
||||
这个内存上下文是进程级别的,即每个进程都有自己独立的内存上下文,
|
||||
其中分配的内存只有在显式调用释放函数之后才会释放。此外,这个内存
|
||||
上下文对所有线程可见,但不是线程安全的,因此只有主进程(Postmaster
|
||||
线程)应该使用它,或者在使用时需要进行锁保护。
|
||||
*/
|
||||
|
||||
/*
|
||||
这种设置允许进程在运行过程中分配内存,并在需要时手动释放,而不会
|
||||
在每次分配内存时都进行自动释放。这对于需要更细粒度地控制内存管
|
||||
理的情况非常有用,但需要开发人员自行管理内存的生命周期和线程安全性。
|
||||
*/
|
||||
g_instance.instance_context = AllocSetContextCreate((MemoryContext)NULL,
|
||||
"ProcessMemory",
|
||||
ALLOCSET_DEFAULT_MINSIZE,
|
||||
|
|
@ -835,15 +984,20 @@ void knl_instance_init()
|
|||
|
||||
void add_numa_alloc_info(void* numaAddr, size_t length)
|
||||
{
|
||||
//如果已分配的 NUMA 内存信息数量超过了数组的最大长度,就要计算新的数组长度,将数组长度翻倍
|
||||
if (g_instance.numa_cxt.allocIndex >= g_instance.numa_cxt.maxLength) {
|
||||
size_t newLength = g_instance.numa_cxt.maxLength * 2;
|
||||
g_instance.numa_cxt.numaAllocInfos =
|
||||
(NumaMemAllocInfo*)repalloc(g_instance.numa_cxt.numaAllocInfos, newLength * sizeof(NumaMemAllocInfo));
|
||||
//使用repalloc函数重新分配内存,以适应新的数组长度。这将导致分配一个新的数组,同时保留以前的数据
|
||||
g_instance.numa_cxt.maxLength = newLength;
|
||||
}
|
||||
g_instance.numa_cxt.numaAllocInfos[g_instance.numa_cxt.allocIndex].numaAddr = numaAddr;
|
||||
g_instance.numa_cxt.numaAllocInfos[g_instance.numa_cxt.allocIndex].length = length;
|
||||
//将当前索引位置的 NUMA 内存地址设置为传入的 numaAddr
|
||||
g_instance.numa_cxt.numaAllocInfos[g_instance.numa_cxt.allocIndex].length = length;
|
||||
//将当前索引位置的 NUMA 内存块长度设置为传入的 length
|
||||
++g_instance.numa_cxt.allocIndex;
|
||||
//增加 NUMA 内存信息数组的索引,以便下次添加信息时使用新的位置
|
||||
}
|
||||
|
||||
void knl_g_set_redo_finish_status(uint32 status)
|
||||
|
|
@ -867,7 +1021,9 @@ bool knl_g_get_local_redo_finish_status()
|
|||
#if defined(__arm__) || defined(__arm) || defined(__aarch64__) || defined(__aarch64)
|
||||
pg_memory_barrier();
|
||||
#endif
|
||||
//使用原子读取获取 Redo 完成状态
|
||||
uint32 isRedoFinish = pg_atomic_read_u32(&(g_instance.comm_cxt.predo_cxt.isRedoFinish));
|
||||
//检查是否本地 Redo 完成(按位与操作)
|
||||
return (isRedoFinish & REDO_FINISH_STATUS_LOCAL) == REDO_FINISH_STATUS_LOCAL;
|
||||
}
|
||||
|
||||
|
|
@ -876,7 +1032,8 @@ bool knl_g_get_redo_finish_status()
|
|||
#if defined(__arm__) || defined(__arm) || defined(__aarch64__) || defined(__aarch64)
|
||||
pg_memory_barrier();
|
||||
#endif
|
||||
//使用原子读取获取 Redo 完成状态
|
||||
uint32 isRedoFinish = pg_atomic_read_u32(&(g_instance.comm_cxt.predo_cxt.isRedoFinish));
|
||||
//检查是否整体 Redo 完成(按位与操作)
|
||||
return (isRedoFinish & REDO_FINISH_STATUS_CM) == REDO_FINISH_STATUS_CM;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue