/* * 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.h * Data stucture for instance level global variables. * * Instance level variables can be accessed by all threads in gaussdb. * Thread competition must be considered at the first place. If it can * be changed by every thread in this process, then we must use lock or * atomic operation to prevent competition. * * IDENTIFICATION * src/include/knl/knl_instance.h * * --------------------------------------------------------------------------------------- */ #ifndef SRC_INCLUDE_KNL_KNL_INSTANCE_H_ #define SRC_INCLUDE_KNL_KNL_INSTANCE_H_ #include #include #include "c.h" #include "datatype/timestamp.h" #include "gs_thread.h" #include "knl/knl_guc.h" #include "lib/circularqueue.h" #include "nodes/pg_list.h" #include "storage/lock/s_lock.h" #include "access/double_write_basic.h" #include "utils/knl_globalsysdbcache.h" #include "utils/palloc.h" #include "replication/replicainternal.h" #include "storage/latch.h" #include "libcomm/libcomm.h" #include "knl/knl_session.h" #include "hotpatch/hotpatch.h" #include "hotpatch/hotpatch_backend.h" #include "utils/atomic.h" #include "postmaster/bgwriter.h" #include "postmaster/pagewriter.h" #include "replication/heartbeat.h" #include "access/multi_redo_settings.h" #include "access/redo_statistic_msg.h" #include "portability/instr_time.h" #include "streaming/init.h" #include "replication/rto_statistic.h" #ifdef ENABLE_MULTIPLE_NODES #include "tsdb/utils/constant_def.h" #endif #include "streaming/init.h" #include "storage/lock/lwlock.h" #include "utils/memgroup.h" #include "instruments/gs_stack.h" #include "replication/walprotocol.h" #include "instruments/instr_mfchain.h" #ifdef ENABLE_MOT #include "storage/mot/jit_def.h" #endif #include "postmaster/barrier_creator.h" #include "pgxc/barrier.h" #include "ddes/dms/ss_dms_recovery.h" #include "ddes/dms/ss_xmin.h" #include "ddes/dms/ss_dms_callback.h" const int NUM_PERCENTILE_COUNT = 2; const int INIT_NUMA_ALLOC_COUNT = 32; const int HOTKEY_ABANDON_LENGTH = 100; const int MAX_GLOBAL_CACHEMEM_NUM = 128; const int MAX_GLOBAL_PRC_NUM = 32; const int MAX_AUDIT_NUM = 48; /* Maximum number of max parallel decode threads */ #define MAX_PARALLEL_DECODE_NUM 20 /* Maximum number of max replication slots */ #define MAX_REPLICATION_SLOT_NUM 100 #ifndef ENABLE_MULTIPLE_NODES const int DB_CMPT_MAX = 4; #endif enum knl_virtual_role { VUNKNOWN = 0, VCOORDINATOR = 1, VDATANODE = 2, VSINGLENODE = 3, }; /* * start process: set to REDO_INIT * parallel redo begin:set to REDO_STARTING_BEGIN, wait for redo worker thread to start * all redo workers are started or waiting timeout: set to REDO_STARTING_END, * if redo worker starts at this stage, the redo worker has to exit */ enum knl_parallel_redo_state { REDO_INIT = 0, REDO_STARTING_BEGIN, REDO_STARTING_END, REDO_IN_PROGRESS, REDO_DONE, }; /* all process level attribute which expose to user */ typedef struct knl_instance_attr { knl_instance_attr_sql attr_sql; knl_instance_attr_storage attr_storage; knl_instance_attr_security attr_security; knl_instance_attr_network attr_network; knl_instance_attr_memory attr_memory; knl_instance_attr_resource attr_resource; knl_instance_attr_common attr_common; } knl_instance_attr_t; typedef struct knl_g_cache_context { MemoryContext global_cache_mem; MemoryContext global_plancache_mem[MAX_GLOBAL_CACHEMEM_NUM]; MemoryContext global_prc_mem[MAX_GLOBAL_PRC_NUM]; } knl_g_cache_context; typedef struct knl_g_cost_context { double cpu_hash_cost; double send_kdata_cost; double receive_kdata_cost; Cost disable_cost; Cost disable_cost_enlarge_factor; pg_atomic_uint64 sql_patch_sequence_id; /* self-incremental sequence id for sql patch */ } knl_g_cost_context; enum plugin_vecfunc_type { DOLPHIN_VEC = 0, WHALE_VEC, /* * This is the number of vecfunc hash tables. * If you are adding a new plugin hash table, do not place an enumeration after it. */ PLUGIN_VEC_FUNC_HATB_COUNT, }; typedef struct knl_g_plugin_vec_func_context { struct HTAB* vec_func_plugin[PLUGIN_VEC_FUNC_HATB_COUNT]; } knl_g_plugin_vec_func_context; typedef struct knl_g_pid_context { ThreadId StartupPID; ThreadId TwoPhaseCleanerPID; ThreadId FaultMonitorPID; ThreadId BgWriterPID; ThreadId SpBgWriterPID; ThreadId* PageWriterPID; ThreadId PageRepairPID; ThreadId CheckpointerPID; ThreadId WalWriterPID; ThreadId WalWriterAuxiliaryPID; ThreadId WalReceiverPID; ThreadId WalRcvWriterPID; ThreadId DataReceiverPID; ThreadId DataRcvWriterPID; ThreadId AutoVacPID; ThreadId PgJobSchdPID; ThreadId PgArchPID; ThreadId PgStatPID; ThreadId PercentilePID; ThreadId *PgAuditPID; ThreadId SysLoggerPID; ThreadId CatchupPID; ThreadId WLMCollectPID; ThreadId WLMCalSpaceInfoPID; ThreadId WLMMonitorPID; ThreadId WLMArbiterPID; ThreadId CPMonitorPID; ThreadId AlarmCheckerPID; ThreadId CBMWriterPID; ThreadId AioCompleterStarted; ThreadId HeartbeatPID; ThreadId CsnminSyncPID; ThreadId BarrierCreatorPID; volatile ThreadId ReaperBackendPID; ThreadId TxnSnapCapturerPID; volatile ThreadId RbCleanrPID; volatile ThreadId SnapshotPID; ThreadId AshPID; ThreadId StatementPID; ThreadId CommSenderFlowPID; ThreadId CommReceiverFlowPID; ThreadId CommAuxiliaryPID; ThreadId CommPoolerCleanPID; ThreadId UndoLauncherPID; ThreadId GlobalStatsPID; ThreadId* CommReceiverPIDS; ThreadId UndoRecyclerPID; ThreadId TsCompactionPID; ThreadId TsCompactionAuxiliaryPID; ThreadId sharedStorageXlogCopyThreadPID; ThreadId LogicalReadWorkerPID; ThreadId LogicalDecoderWorkerPID; ThreadId BarrierPreParsePID; ThreadId exrto_recycler_pid; ThreadId ApplyLauncerPID; ThreadId StackPerfPID; ThreadId CfsShrinkerPID; ThreadId DmsAuxiliaryPID; } knl_g_pid_context; typedef struct { int lockId; MemoryContext context; HTAB* hashTbl; } GWCHashCtl; typedef struct knl_g_advisor_conntext { uint32 isOnlineRunning; /* This flag is used to avoid early clean. */ uint32 isUsingGWC; int maxMemory; int maxsqlCount; Oid currentUser; Oid currentDB; GWCHashCtl* GWCArray; MemoryContext SQLAdvisorContext; } knl_g_advisor_conntext; typedef struct knl_g_stat_context { /* Every cell is a array size of 128 and the list stores all users` sql count results */ struct List* WaitCountStatusList; /* Shared hashtable used to mapping user and g_instance.stat.WaitCountStatusList index for QPS */ struct HTAB* WaitCountHashTbl; pgsocket pgStatSock; Latch pgStatLatch; time_t last_pgstat_start_time; /* Last time the collector successfully wrote the stats file */ TimestampTz last_statwrite; /* Latest statistics request time from backends */ TimestampTz last_statrequest; volatile bool got_SIGHUP; /* unique sql */ MemoryContext UniqueSqlContext; HTAB* volatile UniqueSQLHashtbl; /* standby statement history */ MemFileChain* stbyStmtHistSlow; MemFileChain* stbyStmtHistFast; /* user logon/logout stat */ MemoryContext InstrUserContext; HTAB* InstrUserHTAB; /* workload trx stat */ HTAB* workload_info_hashtbl; /* percentile stat */ volatile bool force_process; int64 RTPERCENTILE[NUM_PERCENTILE_COUNT]; struct SqlRTInfoArray* sql_rt_info_array; MemoryContext InstrPercentileContext; /* Set at the following cases: 1. the cluster occures ha action 2. user perform reset action 3. the node startup 4. ... */ volatile TimestampTz NodeStatResetTime; int64* gInstanceTimeInfo; /* snapshot thread status counter, will +1 when "each" startup */ volatile uint32 snapshot_thread_counter; /* Record the sum of file io stat */ struct FileIOStat* fileIOStat; /* Active session history */ MemoryContext AshContext; struct ActiveSessHistArrary *active_sess_hist_arrary; char *ash_appname; char *ash_clienthostname; bool instr_stmt_is_cleaning; char *ashRelname; HTAB* ASHUniqueSQLHashtbl; /* used for capture view to json file */ HTAB* capture_view_file_hashtbl; /* dynamic function control manager */ HTAB* stmt_track_control_hashtbl; /* used for track memory alloc info */ MemoryContext track_context; HTAB* track_context_hash; HTAB* track_memory_info_hash; bool track_memory_inited; struct UHeapPruneStat* tableStat; char* memory_log_directory; #ifndef WIN32 pthread_rwlock_t track_memory_lock; /* A g_instance lock-free queue to collect keys */ CircularQueue* hotkeysCollectList; /* memorycontext for managing hotkeys */ MemoryContext hotkeysCxt; MemoryContext GsStackContext; HTAB* GsStackHashTbl; bool stack_perf_start; BACKTRACE_INFO_t backtrace_info; struct LRUCache* lru; List* fifo; volatile sig_atomic_t switchover_timeout; volatile sig_atomic_t print_stack_flag; #endif } knl_g_stat_context; /* *quota related */ typedef struct knl_g_quota_context { /* quota for each stream */ unsigned long g_quota; /* quota ratio for dynamic quota changing, but no use now */ unsigned long g_quotanofify_ratio; /* using quota or not */ bool g_having_quota; /* for notifying bufCAP of stream is changed */ struct binary_semaphore* g_quota_changing; } knl_g_quota_context; typedef enum { POLLING_CONNECTION = 0, SPECIFY_CONNECTION = 1, PROHIBIT_CONNECTION = 2 } CONN_MODE; typedef struct knl_g_disconn_node_context_data { CONN_MODE conn_mode; char disable_conn_node_host[NAMEDATALEN]; int disable_conn_node_port; } knl_g_disconn_node_context_data; typedef struct knl_g_disconn_node_context { knl_g_disconn_node_context_data disable_conn_node_data; slock_t info_lck; /* locks shared variables shown above */ } knl_g_disconn_node_context; /* *local basic connection info */ typedef struct knl_g_localinfo_context { char* g_local_host; char* g_self_nodename; int g_local_ctrl_tcp_sock; int sock_to_server_loop; /* The start time of receiving the ready message */ uint64 g_r_first_recv_time; /* record CPU utilization, gs_receivers_flow_controller ,gs_sender_flow_controller, gs_reveiver_loop, postmaster */ int *g_libcomm_used_rate; /* GSS kerberos authentication */ char* gs_krb_keyfile; #ifndef WIN32 volatile uint32 term_from_file = 1; volatile uint32 term_from_xlog = 1; bool set_term = true; knl_g_disconn_node_context disable_conn_node; volatile uint32 is_finish_redo = 0; volatile uint32 need_disable_connection_node = false; #else volatile uint32 term_from_file; volatile uint32 term_from_xlog; bool set_term; knl_g_disconn_node_context disable_conn_node; volatile uint32 is_finish_redo; volatile uint32 need_disable_connection_node; #endif } knl_g_localinfo_context; typedef struct knl_g_counters_context { /* connection number, equal to real node number (dn + cn) */ int g_cur_node_num; /* * expected node number, if g_expect_node_num != g_cur_node_num, * we will use online capacity change. */ int g_expect_node_num; /* stream number of each logic connection */ int g_max_stream_num; /* the number of receiver thread */ int g_recv_num; int g_comm_send_timeout; } knl_g_counters_context; typedef struct knl_g_tests_context { int libcomm_test_current_thread; int* libcomm_test_thread_arg; bool libcomm_stop_flag; int libcomm_test_thread_num; int libcomm_test_msg_len; int libcomm_test_send_sleep; int libcomm_test_send_once; int libcomm_test_recv_sleep; int libcomm_test_recv_once; } knl_g_tests_context; /* the epoll cabinets for receiving control messages and data */ typedef struct knl_g_pollers_context { /* data receiver epoll cabinet */ class mc_poller_hndl_list* g_libcomm_receiver_poller_list; pthread_mutex_t* g_r_libcomm_poller_list_lock; /* the epoll cabinet for receiving control messages at receiver */ class mc_poller_hndl_list* g_r_poller_list; pthread_mutex_t* g_r_poller_list_lock; /* the epoll cabinet for receiving control messages at sender */ class mc_poller_hndl_list* g_s_poller_list; pthread_mutex_t* g_s_poller_list_lock; } knl_g_pollers_context; /* request checking variable */ typedef struct knl_g_reqcheck_context { volatile bool g_shutdown_requested; volatile ThreadId g_cancel_requested; volatile bool g_close_poll_requested; } knl_g_reqcheck_context; typedef struct knl_g_mctcp_context { int mc_tcp_keepalive_idle; int mc_tcp_keepalive_interval; int mc_tcp_keepalive_count; int mc_tcp_user_timeout; int mc_tcp_connect_timeout; int mc_tcp_send_timeout; } knl_g_mctcp_context; typedef struct knl_g_commutil_context { volatile bool g_debug_mode; volatile bool g_timer_mode; volatile bool g_stat_mode; volatile bool g_no_delay; int g_comm_sender_buffer_size; long g_total_usable_memory; long g_memory_pool_size; bool ut_libcomm_test; } knl_g_commutil_context; typedef struct ckpt_view_struct { int64 ckpt_clog_flush_num; int64 ckpt_csnlog_flush_num; int64 ckpt_multixact_flush_num; int64 ckpt_predicate_flush_num; int64 ckpt_twophase_flush_num; volatile XLogRecPtr ckpt_current_redo_point; } ckpt_view_struct; const int TWO_UINT64_SLOT = 2; typedef struct knl_g_audit_context { MemoryContext global_audit_context; volatile uint32 audit_init_done; /* audit pipes */ int *sys_audit_pipes; /* audit logs */ char index_file_path[MAXPGPATH]; LWLock *index_file_lock; struct AuditIndexTableNew* audit_indextbl; struct AuditIndexTable* audit_indextbl_old; uint64 pgaudit_totalspace; /* audit thread */ volatile uint32 current_audit_index; volatile int thread_num; volatile uint32 audit_coru_fnum[MAX_AUDIT_NUM]; } knl_g_audit_context; /* incremental checkpoint */ typedef struct knl_g_ckpt_context { uint64 dirty_page_queue_reclsn; uint64 dirty_page_queue_tail; /* dirty pages applied to flush */ volatile uint32 prepared; pg_atomic_uint32 CkptBufferIdsTail; pg_atomic_uint32 CkptBufferIdsCompletedPages; volatile uint32 CkptBufferIdsFlushPages; CkptSortItem* CkptBufferIds; /* lock used by snapshot function to block page flush */ struct LWLock *snapshotBlockLock; volatile bool io_blocked_for_snapshot; /* dirty_page_queue store dirty buffer, buf_id + 1, 0 is invalid */ DirtyPageQueueSlot* dirty_page_queue; uint64 dirty_page_queue_size; pg_atomic_uint64 dirty_page_queue_head; pg_atomic_uint32 actual_dirty_page_num; slock_t queue_lock; struct LWLock* prune_queue_lock; /* pagewriter thread */ volatile uint32 current_page_writer_count; PageWriterProcs pgwr_procs; volatile uint32 page_writer_last_flush; volatile uint32 page_writer_last_queue_flush; Buffer *candidate_buffers; bool *candidate_free_map; volatile LWLock *backend_wait_lock; /* full checkpoint infomation */ volatile bool flush_all_dirty_page; volatile uint64 full_ckpt_expected_flush_loc; volatile uint64 full_ckpt_redo_ptr; /* Pagewriter thread need wait shutdown checkpoint finish */ volatile bool page_writer_can_exit; volatile bool page_writer_sub_can_exit; volatile bool is_standby_mode; /* pagewriter thread view information */ uint64 page_writer_actual_flush; volatile uint64 get_buf_num_candidate_list; volatile uint64 nvm_get_buf_num_candidate_list; volatile uint64 seg_get_buf_num_candidate_list; volatile uint64 get_buf_num_clock_sweep; volatile uint64 nvm_get_buf_num_clock_sweep; volatile uint64 seg_get_buf_num_clock_sweep; /* checkpoint view information */ ckpt_view_struct ckpt_view; RecoveryQueueState ckpt_redo_state; #ifdef ENABLE_MOT struct CheckpointCallbackItem* ckptCallback; #endif struct IncreCkptSyncShmemStruct* incre_ckpt_sync_shmem; uint64 pad[TWO_UINT64_SLOT]; } knl_g_ckpt_context; typedef struct recovery_dw_buf { char* unaligned_buf; char* buf; dw_file_head_t* file_head; volatile uint16 write_pos; bool *single_flush_state; } recovery_dw_buf; typedef struct dw_batch_file_context{ int id; volatile int fd; uint16 flush_page; /* total number of flushed pages before truncate or reset */ char* unaligned_buf; char* buf; struct LWLock* flush_lock; dw_file_head_t* file_head; volatile uint32 write_pos; /* the copied pages in buffer, updated when mark page */ uint64 file_size; dw_stat_info_batch batch_stat_info; char file_name[PATH_MAX]; }dw_batch_file_context; typedef struct knl_g_dw_context { volatile int fd; volatile uint32 closed; volatile bool old_batch_version; volatile int recovery_dw_file_num; volatile int recovery_dw_file_size; dw_batch_meta_file batch_meta_file; dw_batch_file_context *batch_file_cxts; MemoryContext mem_cxt; volatile uint32 dw_version; uint16 flush_page; char* unaligned_buf; char* buf; struct LWLock* flush_lock; dw_file_head_t* file_head; volatile uint32 write_pos; /* second version flush, only single flush */ struct LWLock* second_flush_lock; /* single flush: second version pos lock */ struct LWLock* second_buftag_lock; /* single flush: second version bufferTag page lock */ dw_file_head_t* second_file_head; volatile uint32 second_write_pos; bool is_new_relfilenode; /* RelFileNode or RelFileNodeOld */ /* single flush dw extras information */ bool *single_flush_state; /* dw single flush slot state */ /* dw recovery buf */ recovery_dw_buf recovery_buf; /* recovery the c20 version dw file */ /* dw view information */ dw_stat_info_single single_stat_info; } knl_g_dw_context; typedef struct knl_g_bgwriter_context { HTAB *unlink_rel_hashtbl; LWLock *rel_hashtbl_lock; HTAB *unlink_rel_fork_hashtbl; /* delete one fork relation file */ LWLock *rel_one_fork_hashtbl_lock; Latch *invalid_buf_proc_latch; }knl_g_bgwriter_context; typedef struct knl_g_repair_context { ThreadId startup_tid; Latch *repair_proc_latch; HTAB *page_repair_hashtbl; /* standby store page repair info */ LWLock *page_repair_hashtbl_lock; HTAB *file_repair_hashtbl; /* standby store file repair info */ LWLock *file_repair_hashtbl_lock; HTAB *global_repair_bad_block_stat; /* local_bad_block_info use this */ bool support_repair; } knl_g_repair_context; typedef struct { ThreadId threadId; uint32 threadState; } PageRedoWorkerStatus; typedef struct { uint64 preEndPtr; instr_time preTime; XLogRecPtr redo_start_ptr; int64 redo_start_time; int64 redo_done_time; int64 current_time; XLogRecPtr min_recovery_point; XLogRecPtr read_ptr; XLogRecPtr last_replayed_end_ptr; XLogRecPtr recovery_done_ptr; XLogRecPtr primary_flush_ptr; RedoWaitInfo wait_info[WAIT_REDO_NUM]; uint32 speed_according_seg; XLogRecPtr local_max_lsn; uint64 oldest_segment; } RedoPerf; typedef enum{ DEFAULT_REDO, PARALLEL_REDO, EXTREME_REDO, }RedoType; enum knl_parallel_decode_state { DECODE_INIT = 0, DECODE_STARTING_BEGIN, DECODE_STARTING_END, DECODE_IN_PROGRESS, DECODE_DONE, }; enum knl_parallel_decode_worker_state { PARALLEL_DECODE_WORKER_INVALID = 0, PARALLEL_DECODE_WORKER_INIT, PARALLEL_DECODE_WORKER_START, PARALLEL_DECODE_WORKER_RUN, PARALLEL_DECODE_WORKER_EXIT }; typedef struct { ThreadId threadId; int threadState; } ParallelDecodeWorkerStatus; typedef struct { ThreadId threadId; int threadState; } ParallelReaderWorkerStatusTye; typedef struct knl_g_parallel_decode_context { MemoryContext parallelDecodeCtx; MemoryContext logicalLogCtx; int state; slock_t rwlock; char* dbUser; char* dbName; int totalNum; volatile ParallelDecodeWorkerStatus ParallelDecodeWorkerStatusList[MAX_PARALLEL_DECODE_NUM]; volatile ParallelReaderWorkerStatusTye ParallelReaderWorkerStatus; gs_thread_t tid[MAX_PARALLEL_DECODE_NUM]; Oid relationOid; ErrorData *edata; } knl_g_parallel_decode_context; typedef struct _ExrtoSnapshotData* ExrtoSnapshot; typedef struct _StandbyReadDelayDdlState { uint64 next_index_need_unlink; uint64 next_index_can_insert; uint32 delete_stat; uint32 insert_stat; } StandbyReadDelayDdlState; typedef struct knl_g_parallel_redo_context { RedoType redoType; volatile knl_parallel_redo_state state; slock_t rwlock; /* redo worker starting lock */ MemoryContext parallelRedoCtx; uint32 totalNum; volatile PageRedoWorkerStatus pageRedoThreadStatusList[MAX_RECOVERY_THREAD_NUM]; RedoPerf redoPf; /* redo Performance statistics */ pg_atomic_uint32 isRedoFinish; int pre_enable_switch; slock_t destroy_lock; /* redo worker destroy lock */ pg_atomic_uint64 max_page_flush_lsn[NUM_MAX_PAGE_FLUSH_LSN_PARTITIONS]; pg_atomic_uint64 last_replayed_conflict_csn; pg_atomic_uint32 permitFinishRedo; pg_atomic_uint32 hotStdby; volatile XLogRecPtr newestCheckpointLoc; volatile CheckPoint newestCheckpoint; char* unali_buf; /* unaligned_buf */ char* ali_buf; XLogRedoNumStatics xlogStatics[RM_NEXT_ID][MAX_XLOG_INFO_NUM]; RedoCpuBindControl redoCpuBindcontrl; ondemand_htab_ctrl_t **redoItemHashCtrl; /* RedoItem hashmap linked list of each pipeline, used in ondemand extreme RTO */ /* extreme-rto standby read */ TransactionId exrto_recyle_xmin; XLogRecPtr global_recycle_lsn; ExrtoSnapshot exrto_snapshot; TimestampTz exrto_send_lsn_forworder_time; StandbyReadDelayDdlState standby_read_delay_ddl_stat; uint64 max_clog_pageno; int *buffer_pin_wait_buf_ids; int buffer_pin_wait_buf_len; } knl_g_parallel_redo_context; typedef struct knl_g_heartbeat_context { volatile bool heartbeat_running; } knl_g_heartbeat_context; typedef struct knl_g_csnminsync_context { bool stop; bool is_fcn_ccn; /* whether this instance is center cn or the first cn while without ccn */ } knl_g_csnminsync_context; typedef struct knl_g_barrier_creator_context { bool stop; bool is_barrier_creator; } knl_g_barrier_creator_context; typedef struct knl_g_csn_barrier_context { struct HTAB* barrier_hash_table; LWLock* barrier_hashtbl_lock; char stopBarrierId[MAX_BARRIER_ID_LENGTH]; bool pre_parse_started; int max_run_time; MemoryContext barrier_context; bool startBarrierPreParse; XLogRecPtr preparseStartLocation; XLogRecPtr preparseEndLocation; XLogRecPtr latest_valid_record; pg_crc32 latest_record_crc; uint32 latest_record_len; } knl_g_csn_barrier_context; typedef struct knl_g_comm_context { /* function point, for wake up consumer in executor */ wakeup_hook_type gs_wakeup_consumer; /* connection handles at receivers, for listening and receiving data through logic connection */ struct local_receivers* g_receivers; /* connection handles at senders, for sending data through logic connection */ struct local_senders* g_senders; bool g_delay_survey_switch; uint64 g_delay_survey_start_time; /* the unix path to send startuppacket to postmaster */ char* g_unix_path; HaShmemData* g_ha_shm_data; /* * filo queue, for keeping the usable stream indexes of each node * we pop up a stream index for communication and push back after * the stream is closed */ struct mc_queue* g_usable_streamid; /* * sockets (control tcp & sctp sockets) of receiver and sender, for socket management and avaliable checking * the indexes of the items in the array is the node indexes for each datanode, * e.g. g_r_node_sock[1] is using to keep socket information of Datanode 1 at receiver in this datanode, maybe * Datanode 2 or others */ struct node_sock* g_r_node_sock; struct node_sock* g_s_node_sock; struct libcomm_delay_info* g_delay_info; /* * two-dimension array to maintain the information of streams associated to Consumer and Producer, each element * represent a stream. the first dimension represent node and the second is stream. we call it mailbox, and the node * index and stream index is the address, e.g. we can get information of a stream at receiver by g_c_mailbox[node * id][stream id]. */ /* Consumer mailboxes at receiver */ struct c_mailbox** g_c_mailbox; /* Producer mailboxes at sender */ struct p_mailbox** g_p_mailbox; struct pg_tz* libcomm_log_timezone; bool g_use_workload_manager; knl_g_quota_context quota_cxt; knl_g_localinfo_context localinfo_cxt; knl_g_counters_context counters_cxt; knl_g_tests_context tests_cxt; knl_g_pollers_context pollers_cxt; knl_g_parallel_decode_context pdecode_cxt[MAX_REPLICATION_SLOT_NUM]; knl_g_reqcheck_context reqcheck_cxt; knl_g_mctcp_context mctcp_cxt; knl_g_commutil_context commutil_cxt; knl_g_parallel_redo_context predo_cxt; /* parallel redo context */ MemoryContext comm_global_mem_cxt; bool force_cal_space_info; bool cal_all_space_info_in_progress; HTAB* usedDnSpace; uint32 current_gsrewind_count; bool request_disaster_cluster; bool isNeedChangeRole; long lastArchiveRcvTime; void* pLogCtl; bool rejectRequest; MemoryContext redoItemCtx; #ifdef USE_SSL libcomm_sslinfo* libcomm_data_port_list; libcomm_sslinfo* libcomm_ctrl_port_list; #endif } knl_g_comm_context; class FdCollection; typedef struct knl_g_comm_logic_context { MemoryContext comm_logic_mem_cxt; FdCollection *comm_fd_collection; } knl_g_comm_logic_context; /* g_instance struct for "Pooler" */ typedef struct knl_g_pooler_context { /* Record global connection status for function 'comm_check_connection_status' */ struct GlobalConnStatus* globalConnStatus; } knl_g_pooler_context; typedef struct knl_g_libpq_context { /* Workaround for Solaris 2.6 brokenness */ char* pam_passwd; /* Workaround for passing "Port *port" into pam_passwd_conv_proc */ struct Port* pam_port_cludge; #ifdef KRB5 /* * Various krb5 state which is not connection specific, and a flag to * indicate whether we have initialised it yet. */ int pg_krb5_initialised; krb5_context pg_krb5_context; krb5_keytab pg_krb5_keytab; krb5_principal pg_krb5_server; #endif /* check internal IP, to avoid port injection*/ List* comm_parsed_hba_lines; MemoryContext parsed_hba_context; } knl_g_libpq_context; #define MIN_CONNECTIONS 1024 typedef struct knl_g_shmem_context { int MaxConnections; int MaxBackends; int MaxReserveBackendId; int ThreadPoolGroupNum; int numaNodeNum; } knl_g_shmem_context; typedef struct knl_g_executor_context { HTAB* function_id_hashtbl; #ifndef ENABLE_MULTIPLE_NODES char* nodeName; char* global_application_name; #endif } knl_g_executor_context; typedef struct knl_g_xlog_context { int num_locks_in_group; #ifdef ENABLE_MOT struct RedoCommitCallbackItem* redoCommitCallback; #endif pthread_mutex_t remain_segs_lock; ShareStorageXLogCtl *shareStorageXLogCtl; void *shareStorageXLogCtlOrigin; ShareStorageOperateCtl shareStorageopCtl; int shareStorageLockFd; ShareStorageXLogCtl *ssReplicationXLogCtl; bool need_clean_slot; /* standby node will check cascade standby slot */ } knl_g_xlog_context; typedef struct knl_g_undo_context { void **uZones; uint32 undoTotalSize; uint32 undoMetaSize; volatile uint32 uZoneCount; Bitmapset *uZoneBitmap[UNDO_PERSISTENCE_LEVELS]; MemoryContext undoContext; int64 undoChainTotalSize; int64 maxChainSize; uint32 undo_chain_visited_count; uint32 undoCountThreshold; pg_atomic_uint64 globalFrozenXid; /* Oldest transaction id which is having undo. */ pg_atomic_uint64 globalRecycleXid; pg_atomic_uint64 hotStandbyRecycleXid; bool is_exrto_residual_undo_file_recycled; } knl_g_undo_context; typedef struct knl_g_flashback_context { TransactionId oldestXminInFlashback; TransactionId globalOldestXminInFlashback; } knl_g_flashback_context; struct NumaMemAllocInfo { void* numaAddr; /* Start address returned from numa_alloc_xxx */ size_t length; }; typedef struct knl_g_numa_context { bool inheritThreadPool; // Inherit NUMA node No. from thread pool module NumaMemAllocInfo* numaAllocInfos; size_t maxLength; size_t allocIndex; } knl_g_numa_context; typedef struct knl_g_ts_compaction_context { #ifdef ENABLE_MULTIPLE_NODES volatile Compaction::knl_compaction_state state; volatile TsCompactionWorkerStatus compaction_worker_status_list[Compaction::MAX_TSCOMPATION_NUM]; #endif int totalNum; int* origin_id; volatile uint32 drop_db_count; volatile bool compaction_rest; Oid dropdb_id; MemoryContext compaction_instance_cxt; } knl_g_ts_compaction_context; typedef struct knl_g_security_policy_context { MemoryContext policy_instance_cxt; HTAB* account_table; LWLock* account_table_lock; } knl_g_security_policy_context; typedef uint64 XLogSegNo; /* XLogSegNo - physical log file sequence number */ typedef struct WalInsertStatusEntry WALInsertStatusEntry; typedef struct WALFlushWaitLockPadded WALFlushWaitLockPadded; typedef struct WALBufferInitWaitLockPadded WALBufferInitWaitLockPadded; typedef struct WALInitSegLockPadded WALInitSegLockPadded; typedef struct XlogFlushStats XlogFlushStatistics; typedef struct WALSyncRepWaitLockPadded WALSyncRepWaitLockPadded; typedef struct WalSenderStat { uint64 sendTimes; TimestampTz firstSendTime; TimestampTz lastSendTime; struct WalSnd* walsnd; } WalSenderStat; typedef struct WalSenderStats { bool isEnableStat; TimestampTz lastResetTime; slock_t mutex; WalSenderStat** stats; } WalSenderStats; typedef struct WalReceiverStats { volatile bool isEnableStat; uint64 bufferFullTimes; uint64 wakeWriterTimes; TimestampTz firstWakeTime; TimestampTz lastWakeTime; TimestampTz lastResetTime; void* walRcvCtlBlock; slock_t mutex; } WalReceiverStats; typedef struct WalRecvWriterStats { volatile bool isEnableStat; uint64 totalWriteBytes; uint64 writeTimes; uint64 totalWriteTime; uint64 totalSyncBytes; uint64 syncTimes; uint64 totalSyncTime; uint64 currentXlogSegno; TimestampTz lastResetTime; slock_t mutex; } WalRecvWriterStats; typedef struct knl_g_conn_context { volatile int CurConnCount; volatile int CurCMAConnCount; /* Connection count of cm_agent after initialize, using for connection limit */ volatile uint32 CurCMAProcCount; /* Proc count of cm_agent connections, indicate proc unsing condition */ slock_t ConnCountLock; } knl_g_conn_context; typedef struct knl_g_wal_context { /* Start address of WAL insert status table that contains WAL_INSERT_STATUS_ENTRIES entries */ WALInsertStatusEntry* walInsertStatusTable; WALFlushWaitLockPadded* walFlushWaitLock; WALBufferInitWaitLockPadded* walBufferInitWaitLock; WALInitSegLockPadded* walInitSegLock; volatile bool isWalWriterUp; XLogRecPtr flushResult; XLogRecPtr sentResult; pthread_mutex_t flushResultMutex; pthread_cond_t flushResultCV; int XLogFlusherCPU; volatile bool isWalWriterSleeping; pthread_mutex_t criticalEntryMutex; pthread_cond_t criticalEntryCV; pthread_condattr_t criticalEntryAtt; volatile uint32 walWaitFlushCount; /* only for xlog statistics use */ volatile XLogSegNo globalEndPosSegNo; /* Global variable for init xlog segment files. */ int lastWalStatusEntryFlushed; volatile int lastLRCScanned; volatile int lastLRCFlushed; int num_locks_in_group; DemoteMode upgradeSwitchMode; uint64 totalXlogIterBytes; uint64 totalXlogIterTimes; XlogFlushStatistics* xlogFlushStats; WalSenderStats* walSenderStats; WalReceiverStats* walReceiverStats; WalRecvWriterStats* walRecvWriterStats; char* ssZeroBuffer; /* an all-zero buffer used to write zero when initing xlog file */ WALSyncRepWaitLockPadded* walSyncRepWaitLock; } knl_g_wal_context; typedef struct GlobalSeqInfoHashBucket { DList* shb_list; int lock_id; } GlobalSeqInfoHashBucket; typedef struct knl_g_archive_context { XLogRecPtr barrierLsn; char barrierName[MAX_BARRIER_ID_LENGTH]; slock_t mutex; volatile int archive_slot_num; volatile int archive_recovery_slot_num; int slot_tline; struct ArchiveSlotConfig *archive_config; struct ArchiveTaskStatus *archive_status; struct ArchiveBarrierLsnInfo *barrier_lsn_info; slock_t barrier_lock; int max_node_cnt; int chosen_walsender_index; bool in_switchover; bool in_service_truncate; } knl_g_archive_context; #ifdef ENABLE_MOT typedef struct knl_g_mot_context { struct VariableCacheData* shmemVariableCache; } knl_g_mot_context; #endif typedef struct knl_g_hypo_context { MemoryContext HypopgContext; List* hypo_index_list; } knl_g_hypo_context; typedef struct knl_sigbus_context { void* sigbus_addr; int sigbus_code; } knl_sigbus_context; typedef struct knl_g_segment_context { uint32 segment_drop_timeline; } knl_g_segment_context; typedef struct knl_g_roleid_context { struct HTAB* roleid_table; } knl_g_roleid_context; #define PG_MAX_DEBUG_CONN 100 /* PlDebuggerComm should be reseted by server session */ typedef struct PlDebuggerComm { volatile bool hasUsed; /* only change when get PldebugLock */ pthread_cond_t cond; /* wake up when all valid msg saved into buffer */ pthread_mutex_t mutex; /* check flag for cond wake up */ volatile bool hasServerFlushed; /* true mean still has valid msg in buffer, false means no valid msg */ volatile bool hasClientFlushed; /* true mean still has valid msg in buffer, false means no valid msg */ /* is waiting for cond wake up in loop */ volatile bool IsClientWaited; volatile bool IsServerWaited; /* set true when server ereport, wake up client to ereport reset when client complete handled error */ volatile bool hasServerErrorOccured; /* set true when client ereport, wake up server to ereport reset when server complete handled error */ volatile bool hasClientErrorOccured; /* true during debug procedure is running */ volatile bool isProcdeureRunning; volatile uint32 lock; /* 1 means locked, 0 means unlock */ volatile uint64 serverId; volatile uint64 clientId; int bufLen; /* length of valid buffer msg */ int bufSize; /* memory size of buffer */ char* buffer; inline bool Used() { pg_memory_barrier(); return hasUsed; } inline bool hasClient() { pg_memory_barrier(); return hasUsed && clientId != 0; } inline bool isRunning() { pg_memory_barrier(); return isProcdeureRunning; } } PlDebuggerComm; typedef struct knl_g_pldebug_context { MemoryContext PldebuggerCxt; /* global memcxt for pldebugger */ PlDebuggerComm debug_comm[PG_MAX_DEBUG_CONN]; /* length is PG_MAX_DEBUG_CONN, use with lwlock HypoIndexLock */ } knl_g_pldebug_context; typedef struct _SPI_plan* SPIPlanPtr; typedef struct { char* ident; int nplans; SPIPlanPtr* splan; } EPlanRefInt; typedef struct knl_g_spi_plan_context { MemoryContext global_spi_plan_context; EPlanRefInt* FPlans; int nFPlans; EPlanRefInt* PPlans; int nPPlans; } knl_g_spi_plan_context; typedef struct knl_g_archive_thread_info { ThreadId* obsArchPID; ThreadId* obsBarrierArchPID; char** slotName; } knl_g_archive_thread_info; typedef struct knl_g_roach_context { bool isRoachRestore; char* targetTimeInPITR; char* globalBarrierRecordForPITR; bool isXLogForceRecycled; bool forceAdvanceSlotTigger; bool isGtmFreeCsn; char* targetRestoreTimeFromMedia; } knl_g_roach_context; /* Added for streaming disaster recovery */ typedef struct knl_g_streaming_dr_context { bool isInSwitchover; bool isInteractionCompleted; int hadrWalSndNum; /* Used for switchover. */ int interactionCompletedNum; /* Used for switchover. */ XLogRecPtr switchoverBarrierLsn; int64 rpoSleepTime; int64 rpoBalanceSleepTime; char currentBarrierId[MAX_BARRIER_ID_LENGTH]; char targetBarrierId[MAX_BARRIER_ID_LENGTH]; slock_t mutex; /* locks shared variables shown above */ } knl_g_streaming_dr_context; typedef struct knl_g_listen_context { #define MAXLISTEN 64 #define IP_LEN 64 /* The socket(s) we're listening to. */ pgsocket ListenSocket[MAXLISTEN]; int listen_sock_type[MAXLISTEN]; /* ori type: enum ListenSocketType */ bool reload_fds; /* use for reload listen_addresses */ char all_listen_addr_list[MAXLISTEN][IP_LEN]; int all_listen_port_list[MAXLISTEN]; int listen_chanel_type[MAXLISTEN]; /* ori type: enum ListenChanelType */ volatile uint32 is_reloading_listen_socket; /* mark PM is reloading listen_addresses */ } knl_g_listen_context; typedef struct knl_g_startup_context { uint32 remoteReadPageNum; HTAB *badPageHashTbl; char page[BLCKSZ]; XLogReaderState *current_record; volatile uint32 BadFileNum; ThreadId startup_tid; XLogRecPtr suspend_lsn; }knl_g_startup_context; typedef struct knl_g_abo_context { MemoryContext abo_model_manager_mcxt; LRUCache *lru_cache; HTAB *models; } knl_g_abo_context; typedef struct knl_g_dwsubdatadir_context { /* share and cluster one copy */ char dwOldPath[MAXPGPATH]; char dwPathPrefix[MAXPGPATH]; char dwSinglePath[MAXPGPATH]; char dwBuildPath[MAXPGPATH]; char dwUpgradePath[MAXPGPATH]; char dwBatchUpgradeMetaPath[MAXPGPATH]; char dwBatchUpgradeFilePath[MAXPGPATH]; char dwMetaPath[MAXPGPATH]; char dwExtChunkPath[MAXPGPATH]; uint8 dwStorageType; } knl_g_dwsubdatadir_context; typedef struct knl_g_datadir_context { char baseDir[MAXPGPATH]; char globalDir[MAXPGPATH]; char clogDir[MAXPGPATH]; char csnlogDir[MAXPGPATH]; char locationDir[MAXPGPATH]; char notifyDir[MAXPGPATH]; char serialDir[MAXPGPATH]; char snapshotsDir[MAXPGPATH]; char tblspcDir[MAXPGPATH]; char twophaseDir[MAXPGPATH]; char multixactDir[MAXPGPATH]; char xlogDir[MAXPGPATH]; char archiveDir[MAXPGPATH]; char controlPath[MAXPGPATH]; char controlBakPath[MAXPGPATH]; char controlInfoPath[MAXPGPATH]; knl_g_dwsubdatadir_context dw_subdir_cxt; } knl_g_datadir_context; typedef struct knl_g_dms_context { uint32 dmsProcSid; uint64 xminAck; dms_status_t dms_status; ClusterNodeState SSClusterState; ss_reformer_ctrl_t SSReformerControl; // saved in disk; saved by primary ss_reform_info_t SSReformInfo; ss_recovery_info_t SSRecoveryInfo; pg_tz* log_timezone; pg_atomic_uint32 inDmsThreShmemInitCnt; // the count of threads in DmsCallbackThreadShmemInit pg_atomic_uint32 inProcExitCnt; // Post Main in proc_exit function bool dmsInited; XLogRecPtr ckptRedo; bool resetSyscache; bool dw_init; uint64 latest_snapshot_xmin; uint64 latest_snapshot_xmax; uint64 latest_snapshot_csn; slock_t set_snapshot_mutex; char dmsInstAddr[MAX_REPLNODE_NUM][DMS_MAX_IP_LEN]; char conninfo[MAXPGPATH]; ss_dfx_stats_t SSDFxStats; ss_xmin_info_t SSXminInfo; ss_fake_seesion_context_t SSFakeSessionCxt; } knl_g_dms_context; #ifdef USE_SPQ typedef struct knl_g_spq_context { pthread_rwlock_t adp_connects_lock; struct HTAB* adp_connects; } knl_g_spq_context; #endif typedef struct knl_instance_context { knl_virtual_role role; volatile int status; DemoteMode demotion; bool fatal_error; bool WalSegmentArchSucceed; /* * request to flush buffer log data * 1. syslogger thread will read this var. if it's true, * flush all buffered log data and reset this flag. * 2. the other worker threads will set this flag be true if needed. * needn't use THR_LOCAL modifier. */ volatile sig_atomic_t flush_buf_requested; /* True if WAL recovery failed */ bool recover_error; pthread_mutex_t gpc_reset_lock; struct Dllist* backend_list; struct Backend* backend_array; void* t_thrd; char* prog_name; int64 start_time; bool binaryupgrade; bool dummy_standby; struct GlobalSeqInfoHashBucket global_seq[NUM_GS_PARTITIONS]; struct GlobalPlanCache* plan_cache; void* bgw_base; pthread_mutex_t bgw_base_lock; struct PROC_HDR* proc_base; pthread_mutex_t proc_base_mutex_lock; struct PGPROC** proc_base_all_procs; struct PGXACT* proc_base_all_xacts; struct PGPROC** proc_aux_base; struct PGPROC** proc_preparexact_base; struct ProcArrayStruct* proc_array_idx; struct HTAB* ProcXactTable; struct GsSignalBase* signal_base; struct DistributeTestParam* distribute_test_param_instance; struct SegmentTestParam* segment_test_param_instance; struct WhiteboxTestParam* whitebox_test_param_instance; /* Set by the -o option */ char ExtraOptions[MAXPGPATH]; /* load ir file count for each session */ long codegen_IRload_process_count; uint64 global_session_seq; struct HTAB* vec_func_hash; knl_g_plugin_vec_func_context plugin_vec_func_cxt; MemoryContext instance_context; MemoryContext error_context; MemoryContext signal_context; MemoryContext increCheckPoint_context; MemoryContext wal_context; MemoryContext account_context; MemoryContext builtin_proc_context; MemoryContextGroup* mcxt_group; knl_g_advisor_conntext adv_cxt; knl_instance_attr_t attr; knl_g_stat_context stat_cxt; knl_g_pid_context pid_cxt; knl_g_cache_context cache_cxt; knl_g_cost_context cost_cxt; knl_g_comm_context comm_cxt; knl_g_comm_logic_context comm_logic_cxt; knl_g_pooler_context pooler_cxt; knl_g_conn_context conn_cxt; knl_g_libpq_context libpq_cxt; struct knl_g_wlm_context* wlm_cxt; knl_g_ckpt_context ckpt_cxt; knl_g_ckpt_context* ckpt_cxt_ctl; knl_g_bgwriter_context bgwriter_cxt; knl_g_repair_context repair_cxt; struct knl_g_dw_context dw_batch_cxt; struct knl_g_dw_context dw_single_cxt; knl_g_shmem_context shmem_cxt; knl_g_wal_context wal_cxt; knl_g_executor_context exec_cxt; knl_g_heartbeat_context heartbeat_cxt; knl_g_rto_context rto_cxt; knl_g_xlog_context xlog_cxt; knl_g_numa_context numa_cxt; knl_g_undo_context undo_cxt; knl_g_flashback_context flashback_cxt; #ifdef ENABLE_MOT knl_g_mot_context mot_cxt; #endif knl_g_ts_compaction_context ts_compaction_cxt; knl_g_security_policy_context policy_cxt; knl_g_streaming_context streaming_cxt; knl_g_csnminsync_context csnminsync_cxt; knl_g_barrier_creator_context barrier_creator_cxt; knl_g_csn_barrier_context csn_barrier_cxt; GlobalSysDBCache global_sysdbcache; knl_g_archive_context archive_obs_cxt; knl_g_archive_thread_info archive_thread_info; struct HTAB* ngroup_hash_table; struct HTAB* mmapCache; struct HTAB* tmpTab; knl_g_hypo_context hypo_cxt; knl_g_segment_context segment_cxt; knl_g_pldebug_context pldebug_cxt; knl_g_spi_plan_context spi_plan_cxt; knl_g_roleid_context roleid_cxt; knl_g_roach_context roach_cxt; knl_g_streaming_dr_context streaming_dr_cxt; struct PLGlobalPackageRuntimeCache* global_session_pkg; knl_g_startup_context startup_cxt; #ifndef ENABLE_MULTIPLE_NODES void *raw_parser_hook[DB_CMPT_MAX]; char *llvmIrFilePath[DB_CMPT_MAX]; pthread_mutex_t loadPluginLock[DB_CMPT_MAX]; List* needCheckConflictSubIds; pthread_mutex_t subIdsLock; #endif uint32 noNeedWaitForCatchup; pg_atomic_uint32 extensionNum; knl_g_audit_context audit_cxt; knl_g_abo_context abo_cxt; knl_g_listen_context listen_cxt; knl_g_datadir_context datadir_cxt; knl_g_dms_context dms_cxt; bool pq_inited; #ifdef USE_SPQ knl_g_spq_context spq_cxt; #endif #ifdef USE_ASSERT_CHECKING void *shared_fi_ctx; std::atomic fi_ctx_inited; bool fi_ctx_init_finished; #endif } knl_instance_context; extern long random(); extern void knl_instance_init(); extern void knl_g_set_redo_finish_status(uint32 status); extern void knl_g_clear_local_redo_finish_status(); extern bool knl_g_get_local_redo_finish_status(); extern bool knl_g_get_redo_finish_status(); extern void knl_g_cachemem_create(); extern knl_instance_context g_instance; extern void add_numa_alloc_info(void* numaAddr, size_t length); #define GTM_FREE_MODE (g_instance.attr.attr_storage.enable_gtm_free || \ g_instance.attr.attr_storage.gtm_option == GTMOPTION_GTMFREE) #define GTM_MODE (false) #define GTM_LITE_MODE (!(GTM_FREE_MODE)) #define REDO_FINISH_STATUS_LOCAL 0x00000001 #define REDO_FINISH_STATUS_CM 0x00000002 #define ATOMIC_TRUE 1 #define ATOMIC_FALSE 0 #define GLOBAL_PLANCACHE_MEMCONTEXT \ (g_instance.cache_cxt.global_plancache_mem[u_sess->session_id % MAX_GLOBAL_CACHEMEM_NUM]) #define GLOBAL_PRC_MEMCONTEXT \ (g_instance.cache_cxt.global_prc_mem[u_sess->session_id % MAX_GLOBAL_PRC_NUM]) #define DISABLE_MULTI_NODES_GPI (u_sess->attr.attr_storage.default_index_kind == DEFAULT_INDEX_KIND_NONE) #define DEFAULT_CREATE_LOCAL_INDEX (u_sess->attr.attr_storage.default_index_kind == DEFAULT_INDEX_KIND_LOCAL) #define DEFAULT_CREATE_GLOBAL_INDEX (u_sess->attr.attr_storage.default_index_kind == DEFAULT_INDEX_KIND_GLOBAL) #endif /* SRC_INCLUDE_KNL_KNL_INSTANCE_H_ */