1476 lines
44 KiB
C++
Executable File
1476 lines
44 KiB
C++
Executable File
/* --------------------------------------------------------------------
|
|
* guc_network.cpp
|
|
*
|
|
* Support for grand unified configuration schema, including SET
|
|
* command, configuration file, and command line options.
|
|
* See src/backend/utils/misc/README for more information.
|
|
*
|
|
*
|
|
* Copyright (c) 2000-2012, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 2010-2012 Postgres-XC Development Group
|
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
|
*
|
|
* IDENTIFICATION
|
|
* src/backend/utils/misc/guc/guc_network.cpp
|
|
*
|
|
* --------------------------------------------------------------------
|
|
*/
|
|
#include "postgres.h"
|
|
#include "knl/knl_variable.h"
|
|
|
|
#include <float.h>
|
|
#include <math.h>
|
|
#include <limits.h>
|
|
#include <arpa/inet.h>
|
|
#include "utils/elog.h"
|
|
|
|
#ifdef HAVE_SYSLOG
|
|
#include <syslog.h>
|
|
#endif
|
|
|
|
#include "access/cbmparsexlog.h"
|
|
#include "access/gin.h"
|
|
#include "access/gtm.h"
|
|
#include "pgxc/pgxc.h"
|
|
#include "access/transam.h"
|
|
#include "access/twophase.h"
|
|
#include "access/xact.h"
|
|
#include "access/xlog.h"
|
|
#include "gs_bbox.h"
|
|
#include "catalog/namespace.h"
|
|
#include "catalog/pgxc_group.h"
|
|
#include "catalog/storage_gtt.h"
|
|
#include "commands/async.h"
|
|
#include "commands/prepare.h"
|
|
#include "commands/vacuum.h"
|
|
#include "commands/variable.h"
|
|
#include "commands/tablespace.h"
|
|
#include "commands/trigger.h"
|
|
#include "funcapi.h"
|
|
#include "instruments/instr_statement.h"
|
|
#include "job/job_scheduler.h"
|
|
#include "libpq/auth.h"
|
|
#include "libpq/be-fsstubs.h"
|
|
#include "libpq/ip.h"
|
|
#include "libpq/libpq.h"
|
|
#include "libpq/pqformat.h"
|
|
#include "miscadmin.h"
|
|
#include "opfusion/opfusion.h"
|
|
#include "optimizer/cost.h"
|
|
#include "optimizer/geqo.h"
|
|
#include "optimizer/nodegroups.h"
|
|
#include "optimizer/paths.h"
|
|
#include "optimizer/planmain.h"
|
|
#include "optimizer/prep.h"
|
|
#include "optimizer/gtmfree.h"
|
|
#include "parser/parse_expr.h"
|
|
#include "parser/parse_oper.h"
|
|
#include "parser/parse_type.h"
|
|
#include "parser/parser.h"
|
|
#include "parser/scansup.h"
|
|
#include "pgstat.h"
|
|
#include "pgxc/route.h"
|
|
#include "workload/workload.h"
|
|
#include "pgaudit.h"
|
|
#include "instruments/instr_unique_sql.h"
|
|
#include "commands/tablecmds.h"
|
|
#include "nodes/nodes.h"
|
|
#include "optimizer/pgxcship.h"
|
|
#include "pgxc/execRemote.h"
|
|
#include "pgxc/locator.h"
|
|
#include "optimizer/pgxcplan.h"
|
|
#include "pgxc/poolmgr.h"
|
|
#include "pgxc/nodemgr.h"
|
|
#include "utils/lsyscache.h"
|
|
#include "access/multi_redo_settings.h"
|
|
#include "catalog/pg_authid.h"
|
|
#include "commands/user.h"
|
|
#include "commands/user.h"
|
|
#include "flock.h"
|
|
#include "gaussdb_version.h"
|
|
#include "libcomm/libcomm.h"
|
|
#include "libpq/libpq-be.h"
|
|
#include "libpq/md5.h"
|
|
#include "libpq/sha2.h"
|
|
#include "optimizer/planner.h"
|
|
#include "optimizer/streamplan.h"
|
|
#include "postmaster/alarmchecker.h"
|
|
#include "postmaster/autovacuum.h"
|
|
#include "postmaster/bgwriter.h"
|
|
#include "postmaster/pagewriter.h"
|
|
#include "postmaster/postmaster.h"
|
|
#include "postmaster/syslogger.h"
|
|
#include "postmaster/twophasecleaner.h"
|
|
#include "postmaster/walwriter.h"
|
|
#include "postmaster/bgworker.h"
|
|
#include "replication/dataqueue.h"
|
|
#include "replication/datareceiver.h"
|
|
#include "replication/reorderbuffer.h"
|
|
#include "replication/replicainternal.h"
|
|
#include "replication/slot.h"
|
|
#include "replication/syncrep.h"
|
|
#include "replication/walreceiver.h"
|
|
#include "replication/walsender.h"
|
|
#include "storage/buf/bufmgr.h"
|
|
#include "storage/cucache_mgr.h"
|
|
#include "storage/smgr/fd.h"
|
|
#include "storage/predicate.h"
|
|
#include "storage/procarray.h"
|
|
#include "storage/standby.h"
|
|
#include "storage/remote_adapter.h"
|
|
#include "tcop/tcopprot.h"
|
|
#include "threadpool/threadpool.h"
|
|
#include "tsearch/ts_cache.h"
|
|
#include "utils/acl.h"
|
|
#include "utils/anls_opt.h"
|
|
#include "utils/atomic.h"
|
|
#include "utils/be_module.h"
|
|
#include "utils/builtins.h"
|
|
#include "utils/bytea.h"
|
|
#include "utils/distribute_test.h"
|
|
#include "utils/segment_test.h"
|
|
#include "utils/guc_tables.h"
|
|
#include "utils/memtrack.h"
|
|
#include "utils/memutils.h"
|
|
#include "utils/pg_locale.h"
|
|
#include "utils/plancache.h"
|
|
#include "utils/portal.h"
|
|
#include "utils/ps_status.h"
|
|
#include "utils/rel_gs.h"
|
|
#include "utils/rel.h"
|
|
#include "utils/snapmgr.h"
|
|
#include "utils/syscache.h"
|
|
#include "access/heapam.h"
|
|
#include "utils/tzparser.h"
|
|
#include "utils/xml.h"
|
|
#include "workload/cpwlm.h"
|
|
#include "workload/workload.h"
|
|
#include "utils/guc_network.h"
|
|
#include "ddes/dms/ss_init.h"
|
|
|
|
static bool check_maxconnections(int* newval, void** extra, GucSource source);
|
|
static bool check_pooler_maximum_idle_time(int* newval, void** extra, GucSource source);
|
|
static bool check_sctp_support(bool* newval, void** extra, GucSource source);
|
|
static void assign_comm_debug_mode(bool newval, void* extra);
|
|
static void assign_comm_stat_mode(bool newval, void* extra);
|
|
static void assign_comm_timer_mode(bool newval, void* extra);
|
|
static void assign_comm_no_delay(bool newval, void* extra);
|
|
static void assign_comm_ackchk_time(int newval, void* extra);
|
|
static bool CheckMaxInnerToolConnections(int* newval, void** extra, GucSource source);
|
|
static bool check_ssl(bool* newval, void** extra, GucSource source);
|
|
|
|
#ifndef ENABLE_MULTIPLE_NODES
|
|
static bool check_listen_addresses(char **newval, void **extra, GucSource source);
|
|
static void assign_listen_addresses(const char *newval, void *extra);
|
|
#endif
|
|
|
|
#ifdef LIBCOMM_SPEED_TEST_ENABLE
|
|
static void assign_comm_test_thread_num(int newval, void* extra);
|
|
static void assign_comm_test_msg_len(int newval, void* extra);
|
|
static void assign_comm_test_send_sleep(int newval, void* extra);
|
|
static void assign_comm_test_send_once(int newval, void* extra);
|
|
static void assign_comm_test_recv_sleep(int newval, void* extra);
|
|
static void assign_comm_test_recv_once(int newval, void* extra);
|
|
#endif
|
|
|
|
#ifdef LIBCOMM_FAULT_INJECTION_ENABLE
|
|
static void assign_comm_fault_injection(int newval, void* extra);
|
|
#endif
|
|
|
|
static const char* show_unix_socket_permissions(void);
|
|
static bool check_max_datanode(int* newval, void** extra, GucSource source);
|
|
static void comm_change_datanode(int newval, void* extra);
|
|
static const char* show_max_datanode(void);
|
|
static bool check_max_coordnode(int* newval, void** extra, GucSource source);
|
|
static void comm_change_coordnode(int newval, void* extra);
|
|
static const char* show_max_coordnode(void);
|
|
|
|
static void InitNetworkConfigureNamesBool();
|
|
static void InitNetworkConfigureNamesInt();
|
|
static void InitNetworkConfigureNamesInt64();
|
|
static void InitNetworkConfigureNamesReal();
|
|
static void InitNetworkConfigureNamesString();
|
|
static void InitNetworkConfigureNamesEnum();
|
|
|
|
/*
|
|
* Contents of GUC tables
|
|
*
|
|
* See src/backend/utils/misc/README for design notes.
|
|
*
|
|
* TO ADD AN OPTION AS FOLLOWS.
|
|
*
|
|
* 1. Declare a global variable of type bool, int, double, or char*
|
|
* and make use of it.
|
|
*
|
|
* 2. Decide at what times it's safe to set the option. See guc.h for
|
|
* details.
|
|
*
|
|
* 3. Decide on a name, a default value, upper and lower bounds (if
|
|
* applicable), etc.
|
|
*
|
|
* 4. Add a record below.
|
|
*
|
|
* 5. Add it to src/backend/utils/misc/postgresql_single.conf.sample or
|
|
* src/backend/utils/misc/postgresql_distribute.conf.sample or both,
|
|
* if appropriate.
|
|
*
|
|
* 6. Don't forget to document the option (at least in config.sgml).
|
|
*
|
|
* 7. If it's a new GUC_LIST option you must edit pg_dumpall.c to ensure
|
|
* it is not single quoted at dump time.
|
|
*/
|
|
/* ******* option records follow ******* */
|
|
void InitNetworkConfigureNames()
|
|
{
|
|
InitNetworkConfigureNamesBool();
|
|
InitNetworkConfigureNamesInt();
|
|
InitNetworkConfigureNamesInt64();
|
|
InitNetworkConfigureNamesReal();
|
|
InitNetworkConfigureNamesString();
|
|
InitNetworkConfigureNamesEnum();
|
|
|
|
return;
|
|
}
|
|
|
|
static void InitNetworkConfigureNamesBool()
|
|
{
|
|
struct config_bool localConfigureNamesBool[] = {
|
|
{{"enable_stateless_pooler_reuse",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Pooler stateless reuse mode."),
|
|
NULL,
|
|
GUC_NOT_IN_SAMPLE},
|
|
&g_instance.attr.attr_network.PoolerStatelessReuse,
|
|
false,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
// Stream communication
|
|
{{"comm_tcp_mode",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
CLIENT_CONN,
|
|
gettext_noop("Whether use tcp commucation mode for stream"),
|
|
NULL,
|
|
},
|
|
&g_instance.attr.attr_network.comm_tcp_mode,
|
|
true,
|
|
check_sctp_support,
|
|
NULL,
|
|
NULL},
|
|
{{"comm_debug_mode",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Whether use libcomm debug mode for print debug information"),
|
|
NULL,
|
|
},
|
|
&u_sess->attr.attr_network.comm_debug_mode,
|
|
#ifdef ENABLE_LLT
|
|
true,
|
|
#else
|
|
false,
|
|
#endif
|
|
NULL,
|
|
assign_comm_debug_mode,
|
|
NULL},
|
|
{{"comm_stat_mode",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Whether use libcomm stat mode for print stat data"),
|
|
NULL,
|
|
},
|
|
&u_sess->attr.attr_network.comm_stat_mode,
|
|
#ifdef ENABLE_LLT
|
|
true,
|
|
#else
|
|
false,
|
|
#endif
|
|
NULL,
|
|
assign_comm_stat_mode,
|
|
NULL},
|
|
{{"comm_timer_mode",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Whether use libcomm timer debug mode for print timer data"),
|
|
NULL,
|
|
},
|
|
&u_sess->attr.attr_network.comm_timer_mode,
|
|
#ifdef ENABLE_LLT
|
|
true,
|
|
#else
|
|
false,
|
|
#endif
|
|
NULL,
|
|
assign_comm_timer_mode,
|
|
NULL},
|
|
{{"comm_no_delay",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Whether set NO_DELAY option for libcomm socket"),
|
|
NULL,
|
|
},
|
|
&u_sess->attr.attr_network.comm_no_delay,
|
|
false,
|
|
NULL,
|
|
assign_comm_no_delay,
|
|
NULL},
|
|
{{"enable_force_reuse_connections",
|
|
PGC_BACKEND,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Session force reuse pooler connections."),
|
|
NULL,
|
|
GUC_NOT_IN_SAMPLE},
|
|
&u_sess->attr.attr_network.PoolerForceReuse,
|
|
false,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"comm_client_bind",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Whether client use bind function"),
|
|
NULL,
|
|
},
|
|
&u_sess->attr.attr_network.comm_client_bind,
|
|
false,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"comm_ssl",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
CONN_AUTH_SECURITY,
|
|
gettext_noop("Enables libcomm SSL connections."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.comm_enable_SSL,
|
|
false,
|
|
check_ssl,
|
|
NULL,
|
|
NULL},
|
|
{{"enable_dolphin_proto",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SECURITY,
|
|
gettext_noop("Enables dolphin database protocol"),
|
|
NULL},
|
|
&g_instance.attr.attr_network.enable_dolphin_proto,
|
|
false,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
/* End-of-list marker */
|
|
{{NULL,
|
|
(GucContext)0,
|
|
(GucNodeType)0,
|
|
(config_group)0,
|
|
NULL,
|
|
NULL},
|
|
NULL,
|
|
false,
|
|
NULL,
|
|
NULL,
|
|
NULL}
|
|
};
|
|
|
|
Size bytes = sizeof(localConfigureNamesBool);
|
|
u_sess->utils_cxt.ConfigureNamesBool[GUC_ATTR_NETWORK] =
|
|
(struct config_bool*)MemoryContextAlloc(SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_CBB), bytes);
|
|
errno_t rc = memcpy_s(u_sess->utils_cxt.ConfigureNamesBool[GUC_ATTR_NETWORK], bytes,
|
|
localConfigureNamesBool, bytes);
|
|
securec_check_ss(rc, "\0", "\0");
|
|
}
|
|
|
|
static void InitNetworkConfigureNamesInt()
|
|
{
|
|
struct config_int localConfigureNamesInt[] = {
|
|
{{"max_connections",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the maximum number of concurrent connections for clients."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.MaxConnections,
|
|
200,
|
|
10,
|
|
MAX_BACKENDS,
|
|
check_maxconnections,
|
|
NULL,
|
|
NULL},
|
|
{{"max_inner_tool_connections",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the maximum number of concurrent connections for inner tools."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.maxInnerToolConnections,
|
|
50,
|
|
1,
|
|
MAX_BACKENDS,
|
|
CheckMaxInnerToolConnections,
|
|
NULL,
|
|
NULL},
|
|
{{"sysadmin_reserved_connections",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the number of connection slots reserved for system admin."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.ReservedBackends,
|
|
3,
|
|
0,
|
|
MAX_BACKENDS,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"port",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the TCP port the server listens on."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.PostPortNumber,
|
|
DEF_PGPORT,
|
|
1,
|
|
65535,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"unix_socket_permissions",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the access permissions of the Unix-domain socket."),
|
|
gettext_noop("Unix-domain sockets use the usual Unix file system "
|
|
"permission set. The parameter value is expected "
|
|
"to be a numeric mode specification in the form "
|
|
"accepted by the chmod and umask system calls. "
|
|
"(To use the customary octal format the number must "
|
|
"start with a 0 (zero).)")},
|
|
&g_instance.attr.attr_network.Unix_socket_permissions,
|
|
0700,
|
|
0000,
|
|
0777,
|
|
NULL,
|
|
NULL,
|
|
show_unix_socket_permissions},
|
|
{{"pooler_maximum_idle_time",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DATA_NODES,
|
|
gettext_noop("Maximum idle time of the pooler links."),
|
|
NULL,
|
|
GUC_UNIT_S},
|
|
&u_sess->attr.attr_network.PoolerMaxIdleTime,
|
|
600,
|
|
0,
|
|
INT_MAX,
|
|
check_pooler_maximum_idle_time,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"minimum_pool_size",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DATA_NODES,
|
|
gettext_noop("Initial pool size."),
|
|
gettext_noop("If number of active connections decreased below this value, "
|
|
"new connections are established")},
|
|
&u_sess->attr.attr_network.MinPoolSize,
|
|
50,
|
|
1,
|
|
65535,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
// Stream communication
|
|
{{"comm_sctp_port",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the STCP port the server listens on."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.comm_sctp_port,
|
|
7000,
|
|
0,
|
|
65535,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"comm_control_port",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the stream control port the server listens on."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.comm_control_port,
|
|
7001,
|
|
0,
|
|
65535,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"comm_quota_size",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the stream quota size in kB."),
|
|
NULL,
|
|
GUC_UNIT_KB},
|
|
&g_instance.attr.attr_network.comm_quota_size,
|
|
1024,
|
|
0,
|
|
2048000,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"comm_usable_memory",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the total usable memory for communication(in kB)."),
|
|
NULL,
|
|
GUC_UNIT_KB},
|
|
&g_instance.attr.attr_network.comm_usable_memory,
|
|
4000 * 1024,
|
|
100 * 1024,
|
|
INT_MAX / 2,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"comm_memory_pool",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the memory pool size for communication(in kB)."),
|
|
NULL,
|
|
GUC_UNIT_KB},
|
|
&g_instance.attr.attr_network.comm_memory_pool,
|
|
2000 * 1024,
|
|
100 * 1024,
|
|
INT_MAX / 2,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"comm_memory_pool_percent",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the percent of comm_memory_pool for dynamic workload."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.comm_memory_pool_percent,
|
|
0,
|
|
0,
|
|
100,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"comm_ackchk_time",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
QUERY_TUNING,
|
|
gettext_noop("Send ack check package to stream sender periodically."),
|
|
NULL,
|
|
GUC_UNIT_MS},
|
|
&u_sess->attr.attr_network.comm_ackchk_time,
|
|
2000,
|
|
0,
|
|
20000,
|
|
NULL,
|
|
assign_comm_ackchk_time,
|
|
NULL},
|
|
|
|
#ifdef LIBCOMM_SPEED_TEST_ENABLE
|
|
{{"comm_test_thread_num",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Libcomm performance testing framework thread number of streams."),
|
|
NULL},
|
|
&u_sess->attr.attr_network.comm_test_thread_num,
|
|
0,
|
|
0,
|
|
65535,
|
|
NULL,
|
|
assign_comm_test_thread_num,
|
|
NULL},
|
|
{{"comm_test_msg_len",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Libcomm performance testing framework message len."),
|
|
NULL},
|
|
&u_sess->attr.attr_network.comm_test_msg_len,
|
|
8192,
|
|
1,
|
|
65535,
|
|
NULL,
|
|
assign_comm_test_msg_len,
|
|
NULL},
|
|
{{"comm_test_send_sleep",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Libcomm performance testing framework producer thread sleep time."),
|
|
NULL},
|
|
&u_sess->attr.attr_network.comm_test_send_sleep,
|
|
0,
|
|
0,
|
|
INT_MAX,
|
|
NULL,
|
|
assign_comm_test_send_sleep,
|
|
NULL},
|
|
{{"comm_test_send_once",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Libcomm performance testing framework producer thread send message size once time."),
|
|
NULL},
|
|
&u_sess->attr.attr_network.comm_test_send_once,
|
|
8192,
|
|
1,
|
|
INT_MAX,
|
|
NULL,
|
|
assign_comm_test_send_once,
|
|
NULL},
|
|
{{"comm_test_recv_sleep",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Libcomm performance testing framework consumer thread sleep time."),
|
|
NULL},
|
|
&u_sess->attr.attr_network.comm_test_recv_sleep,
|
|
0,
|
|
0,
|
|
INT_MAX,
|
|
NULL,
|
|
assign_comm_test_recv_sleep,
|
|
NULL},
|
|
{{"comm_test_rcv_once",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Libcomm performance testing framework consumer thread recv message size once time."),
|
|
NULL},
|
|
&u_sess->attr.attr_network.comm_test_recv_once,
|
|
8192,
|
|
1,
|
|
INT_MAX,
|
|
NULL,
|
|
assign_comm_test_recv_once,
|
|
NULL},
|
|
#endif
|
|
|
|
#ifdef LIBCOMM_FAULT_INJECTION_ENABLE
|
|
{{"comm_fault_injection",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Libcomm fault injection framework."),
|
|
NULL},
|
|
&u_sess->attr.attr_network.comm_fault_injection,
|
|
0,
|
|
-10,
|
|
INT_MAX,
|
|
NULL,
|
|
assign_comm_fault_injection,
|
|
NULL},
|
|
#endif
|
|
{{"comm_max_receiver",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Maximum number of internal receiver threads."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.comm_max_receiver,
|
|
4,
|
|
1,
|
|
50,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"cn_send_buffer_size",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CLIENT_CONN_STATEMENT,
|
|
gettext_noop("Sets the send buffer size used in CN, unit in KB."),
|
|
NULL,
|
|
GUC_UNIT_KB},
|
|
&g_instance.attr.attr_network.cn_send_buffer_size,
|
|
8,
|
|
8,
|
|
128,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"comm_sender_buffer_size",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("The libcomm sender's buffer size in every interaction between DN and CN, "
|
|
"or DN and DN, unit(KB)"),
|
|
NULL},
|
|
&g_instance.comm_cxt.commutil_cxt.g_comm_sender_buffer_size,
|
|
8,
|
|
1,
|
|
1024,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"max_pool_size",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
DATA_NODES,
|
|
gettext_noop("Max pool size."),
|
|
gettext_noop("If number of active connections reaches this value, "
|
|
"other connection requests will be refused")},
|
|
&g_instance.attr.attr_network.MaxPoolSize,
|
|
400,
|
|
1,
|
|
65535,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"pooler_port",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
COORDINATORS,
|
|
gettext_noop("Legacy port of the Pool Manager. Now it is used for cn HA port for build and replication "
|
|
"under thread pool mode."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.PoolerPort,
|
|
6667,
|
|
1,
|
|
65535,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"pooler_timeout",
|
|
PGC_SIGHUP,
|
|
NODE_DISTRIBUTE,
|
|
DATA_NODES,
|
|
gettext_noop("Timeout of the Pool Communication with Other Nodes."),
|
|
NULL,
|
|
GUC_UNIT_S},
|
|
&u_sess->attr.attr_network.PoolerTimeout,
|
|
600,
|
|
0,
|
|
7200,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"pooler_connect_max_loops",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DATA_NODES,
|
|
gettext_noop("Max retries of the Pooler Connecting to Other Nodes."),
|
|
NULL},
|
|
&u_sess->attr.attr_network.PoolerConnectMaxLoops,
|
|
1,
|
|
0,
|
|
20,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"pooler_connect_interval_time",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DATA_NODES,
|
|
gettext_noop("Indicates the interval for each retry."),
|
|
NULL,
|
|
GUC_UNIT_S},
|
|
&u_sess->attr.attr_network.PoolerConnectIntervalTime,
|
|
15,
|
|
0,
|
|
7200,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"pooler_connect_timeout",
|
|
PGC_SIGHUP,
|
|
NODE_DISTRIBUTE,
|
|
DATA_NODES,
|
|
gettext_noop("Timeout of the Pooler Connecting to Other Nodes."),
|
|
NULL,
|
|
GUC_UNIT_S},
|
|
&u_sess->attr.attr_network.PoolerConnectTimeout,
|
|
60,
|
|
0,
|
|
7200,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{"pooler_cancel_timeout",
|
|
PGC_SIGHUP,
|
|
NODE_DISTRIBUTE,
|
|
DATA_NODES,
|
|
gettext_noop("Timeout of the Pooler Cancel Connections to Other Nodes."),
|
|
NULL,
|
|
GUC_UNIT_S},
|
|
&u_sess->attr.attr_network.PoolerCancelTimeout,
|
|
15,
|
|
0,
|
|
7200,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"max_coordinators",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
DATA_NODES,
|
|
gettext_noop("Maximum number of Coordinators in the cluster."),
|
|
gettext_noop("It is not possible to create more Coordinators in the cluster than "
|
|
"this maximum number.")},
|
|
&g_instance.attr.attr_network.MaxCoords,
|
|
1024,
|
|
2,
|
|
MAX_CN_NODE_NUM,
|
|
check_max_coordnode,
|
|
comm_change_coordnode,
|
|
show_max_coordnode},
|
|
{{"comm_max_datanode",
|
|
PGC_USERSET,
|
|
NODE_DISTRIBUTE,
|
|
DEVELOPER_OPTIONS,
|
|
gettext_noop("Currently number of Datanodes."),
|
|
NULL},
|
|
&u_sess->attr.attr_network.comm_max_datanode,
|
|
256,
|
|
1,
|
|
MAX_DN_NODE_NUM,
|
|
check_max_datanode,
|
|
comm_change_datanode,
|
|
show_max_datanode},
|
|
|
|
{{"comm_max_stream",
|
|
PGC_POSTMASTER,
|
|
NODE_DISTRIBUTE,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Maximum number of streams."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.comm_max_stream,
|
|
1024,
|
|
1,
|
|
60000,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"dolphin_server_port",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the TCP port the server listens on for dolphin client-server protocol."),
|
|
NULL},
|
|
&g_instance.attr.attr_network.dolphin_server_port,
|
|
3308,
|
|
1024,
|
|
65535,
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
/* End-of-list marker */
|
|
{{NULL,
|
|
(GucContext)0,
|
|
(GucNodeType)0,
|
|
(config_group)0,
|
|
NULL,
|
|
NULL},
|
|
NULL,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL}
|
|
};
|
|
|
|
Size bytes = sizeof(localConfigureNamesInt);
|
|
u_sess->utils_cxt.ConfigureNamesInt[GUC_ATTR_NETWORK] =
|
|
(struct config_int*)MemoryContextAlloc(SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_CBB), bytes);
|
|
errno_t rc = memcpy_s(u_sess->utils_cxt.ConfigureNamesInt[GUC_ATTR_NETWORK], bytes,
|
|
localConfigureNamesInt, bytes);
|
|
securec_check_ss(rc, "\0", "\0");
|
|
}
|
|
|
|
static void InitNetworkConfigureNamesReal()
|
|
{
|
|
struct config_real localConfigureNamesReal[] = {
|
|
|
|
/* End-of-list marker */
|
|
{{NULL,
|
|
(GucContext)0,
|
|
(GucNodeType)0,
|
|
(config_group)0,
|
|
NULL,
|
|
NULL},
|
|
NULL,
|
|
0.0,
|
|
0.0,
|
|
0.0,
|
|
NULL,
|
|
NULL,
|
|
NULL}
|
|
};
|
|
|
|
Size bytes = sizeof(localConfigureNamesReal);
|
|
u_sess->utils_cxt.ConfigureNamesReal[GUC_ATTR_NETWORK] =
|
|
(struct config_real*)MemoryContextAlloc(SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_CBB), bytes);
|
|
errno_t rc = memcpy_s(u_sess->utils_cxt.ConfigureNamesReal[GUC_ATTR_NETWORK], bytes,
|
|
localConfigureNamesReal, bytes);
|
|
securec_check_ss(rc, "\0", "\0");
|
|
}
|
|
|
|
static void InitNetworkConfigureNamesInt64()
|
|
{
|
|
struct config_int64 localConfigureNamesInt64[] = {
|
|
|
|
/* End-of-list marker */
|
|
{{NULL,
|
|
(GucContext)0,
|
|
(GucNodeType)0,
|
|
(config_group)0,
|
|
NULL,
|
|
NULL},
|
|
NULL,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL}
|
|
};
|
|
|
|
Size bytes = sizeof(localConfigureNamesInt64);
|
|
u_sess->utils_cxt.ConfigureNamesInt64[GUC_ATTR_NETWORK] =
|
|
(struct config_int64*)MemoryContextAlloc(SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_CBB), bytes);
|
|
errno_t rc = memcpy_s(u_sess->utils_cxt.ConfigureNamesInt64[GUC_ATTR_NETWORK], bytes,
|
|
localConfigureNamesInt64, bytes);
|
|
securec_check_ss(rc, "\0", "\0");
|
|
}
|
|
|
|
static void InitNetworkConfigureNamesString()
|
|
{
|
|
struct config_string localConfigureNamesString[] = {
|
|
{{"unix_socket_group",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the owning group of the Unix-domain socket."),
|
|
gettext_noop("The owning user of the socket is always the user "
|
|
"that starts the server.")},
|
|
&g_instance.attr.attr_network.Unix_socket_group,
|
|
"",
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
{{"unix_socket_directory",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the directory where the Unix-domain socket will be created."),
|
|
NULL,
|
|
GUC_SUPERUSER_ONLY},
|
|
&g_instance.attr.attr_network.UnixSocketDir,
|
|
"",
|
|
check_canonical_path,
|
|
NULL,
|
|
NULL},
|
|
|
|
#ifdef ENABLE_MULTIPLE_NODES
|
|
{{"listen_addresses",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the host name or IP address(es) to listen to."),
|
|
NULL,
|
|
GUC_LIST_INPUT},
|
|
&g_instance.attr.attr_network.ListenAddresses,
|
|
"localhost",
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
#else
|
|
{{"listen_addresses",
|
|
PGC_SIGHUP,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the host name or IP address(es) to listen to."),
|
|
NULL,
|
|
GUC_LIST_INPUT},
|
|
&u_sess->attr.attr_network.ListenAddresses,
|
|
"localhost",
|
|
check_listen_addresses,
|
|
assign_listen_addresses,
|
|
NULL},
|
|
#endif
|
|
|
|
{{"local_bind_address",
|
|
PGC_POSTMASTER,
|
|
NODE_ALL,
|
|
CONN_AUTH_SETTINGS,
|
|
gettext_noop("Sets the host name or IP address(es) to connect to for sctp."),
|
|
NULL,
|
|
GUC_LIST_INPUT},
|
|
&g_instance.attr.attr_network.tcp_link_addr,
|
|
"0.0.0.0",
|
|
NULL,
|
|
NULL,
|
|
NULL},
|
|
|
|
{{NULL,
|
|
(GucContext)0,
|
|
(GucNodeType)0,
|
|
(config_group)0,
|
|
NULL,
|
|
NULL},
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL}
|
|
};
|
|
|
|
Size bytes = sizeof(localConfigureNamesString);
|
|
u_sess->utils_cxt.ConfigureNamesString[GUC_ATTR_NETWORK] =
|
|
(struct config_string*)MemoryContextAlloc(SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_CBB), bytes);
|
|
errno_t rc = memcpy_s(u_sess->utils_cxt.ConfigureNamesString[GUC_ATTR_NETWORK], bytes,
|
|
localConfigureNamesString, bytes);
|
|
securec_check_ss(rc, "\0", "\0");
|
|
}
|
|
|
|
static void InitNetworkConfigureNamesEnum()
|
|
{
|
|
struct config_enum localConfigureNamesEnum[] = {
|
|
|
|
/* End-of-list marker */
|
|
{{NULL,
|
|
(GucContext)0,
|
|
(GucNodeType)0,
|
|
(config_group)0,
|
|
NULL,
|
|
NULL},
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL}
|
|
};
|
|
|
|
Size bytes = sizeof(localConfigureNamesEnum);
|
|
u_sess->utils_cxt.ConfigureNamesEnum[GUC_ATTR_NETWORK] =
|
|
(struct config_enum*)MemoryContextAlloc(SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_CBB), bytes);
|
|
errno_t rc = memcpy_s(u_sess->utils_cxt.ConfigureNamesEnum[GUC_ATTR_NETWORK], bytes,
|
|
localConfigureNamesEnum, bytes);
|
|
securec_check_ss(rc, "\0", "\0");
|
|
}
|
|
|
|
/* ******* end of options list ******* */
|
|
|
|
|
|
static bool check_maxconnections(int* newval, void** extra, GucSource source)
|
|
{
|
|
const int factor = 4;
|
|
const int min = 64;
|
|
const int max = 1024;
|
|
int bgworkers = *newval / factor;
|
|
|
|
/* g_max_worker_processes should be a quarter of max_connections, and between 64 and 1024 */
|
|
g_max_worker_processes = Max(bgworkers, min);
|
|
g_max_worker_processes = Min(g_max_worker_processes, max);
|
|
|
|
#ifdef PGXC
|
|
if (IS_PGXC_COORDINATOR && *newval > MAX_BACKENDS) {
|
|
GUC_check_errmsg("PGXC can't support max_connections more than %d.", MAX_BACKENDS);
|
|
return false;
|
|
}
|
|
#endif
|
|
if (*newval + g_instance.attr.attr_storage.autovacuum_max_workers + g_instance.attr.attr_sql.job_queue_processes +
|
|
AUXILIARY_BACKENDS + AV_LAUNCHER_PROCS +
|
|
g_instance.attr.attr_network.maxInnerToolConnections + g_max_worker_processes > MAX_BACKENDS) {
|
|
return false;
|
|
}
|
|
|
|
if (g_instance.attr.attr_storage.dms_attr.enable_dms && *newval > DMS_MAX_CONNECTIONS) {
|
|
GUC_check_errmsg("Shared Storage can't support max_connections more than %d.", DMS_MAX_CONNECTIONS);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Check if the kernel version greater than suse sp2 (3.0.13)
|
|
* Only a warning is printed to log.
|
|
* Returning false will cause FATAL error and it will not be good.
|
|
*/
|
|
static bool check_sctp_support(bool* newval, void** extra, GucSource source)
|
|
{
|
|
if (*newval == false) {
|
|
GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED);
|
|
GUC_check_errmsg("SET COMM_TCP_MODE TO OFF is no longer supported");
|
|
*newval = true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void assign_comm_debug_mode(bool newval, void* extra)
|
|
{
|
|
gs_set_debug_mode(newval);
|
|
return;
|
|
}
|
|
|
|
static void assign_comm_stat_mode(bool newval, void* extra)
|
|
{
|
|
gs_set_stat_mode(newval);
|
|
return;
|
|
}
|
|
|
|
static void assign_comm_timer_mode(bool newval, void* extra)
|
|
{
|
|
gs_set_timer_mode(newval);
|
|
return;
|
|
}
|
|
|
|
static void assign_comm_no_delay(bool newval, void* extra)
|
|
{
|
|
gs_set_no_delay(newval);
|
|
return;
|
|
}
|
|
|
|
static bool CheckMaxInnerToolConnections(int* newval, void** extra, GucSource source)
|
|
{
|
|
if (*newval + g_instance.attr.attr_storage.autovacuum_max_workers + g_instance.attr.attr_sql.job_queue_processes +
|
|
g_instance.attr.attr_network.MaxConnections +
|
|
AUXILIARY_BACKENDS + AV_LAUNCHER_PROCS + g_max_worker_processes > MAX_BACKENDS) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool check_ssl(bool* newval, void** extra, GucSource source)
|
|
{
|
|
#ifndef USE_SSL
|
|
|
|
if (*newval) {
|
|
GUC_check_errmsg("COMM SSL is not supported by this build");
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
static bool check_pooler_maximum_idle_time(int* newval, void** extra, GucSource source)
|
|
{
|
|
if (*newval < 0) {
|
|
GUC_check_errmsg("GaussDB can't support idle time less than 0 or more than %d seconds.", INT_MAX);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void assign_comm_ackchk_time(int newval, void* extra)
|
|
{
|
|
gs_set_ackchk_time(newval);
|
|
}
|
|
|
|
#ifndef ENABLE_MULTIPLE_NODES
|
|
static bool check_listen_addresses(char **newval, void **extra, GucSource source)
|
|
{
|
|
if (*newval == NULL || strlen(*newval) == 0) {
|
|
GUC_check_errmsg("listen_addresses can not set to empty");
|
|
return false;
|
|
}
|
|
|
|
char* rawstring = NULL;
|
|
List* elemlist = NULL;
|
|
rawstring = pstrdup(*newval);
|
|
if (!SplitIdentifierString(rawstring, ',', &elemlist)) {
|
|
/* syntax error in list */
|
|
GUC_check_errmsg("invalid list syntax for \"listen_addresses\": %s", *newval);
|
|
list_free_ext(elemlist);
|
|
pfree(rawstring);
|
|
return false;
|
|
}
|
|
list_free_ext(elemlist);
|
|
pfree(rawstring);
|
|
return true;
|
|
}
|
|
|
|
static void transform_ip_to_addr(char* host_name, unsigned short port_number)
|
|
{
|
|
char* service = NULL;
|
|
struct addrinfo* addrs = NULL;
|
|
struct addrinfo* addr = NULL;
|
|
struct addrinfo hint;
|
|
char portNumberStr[32];
|
|
int family = AF_UNSPEC;
|
|
errno_t rc = snprintf_s(portNumberStr, sizeof(portNumberStr), sizeof(portNumberStr) - 1, "%hu", port_number);
|
|
securec_check_ss(rc, "\0", "\0");
|
|
service = portNumberStr;
|
|
/* Initialize hint structure */
|
|
rc = memset_s(&hint, sizeof(hint), 0, sizeof(hint));
|
|
securec_check(rc, "\0", "\0");
|
|
hint.ai_family = family;
|
|
hint.ai_flags = AI_PASSIVE;
|
|
hint.ai_socktype = SOCK_STREAM;
|
|
|
|
int ret = pg_getaddrinfo_all(host_name, service, &hint, &addrs);
|
|
if (ret || addrs == NULL) {
|
|
if (host_name != NULL) {
|
|
ereport(LOG,
|
|
(errmsg("could not translate host name \"%s\", service \"%s\" to address: %s",
|
|
host_name,
|
|
service,
|
|
gai_strerror(ret))));
|
|
} else {
|
|
ereport(LOG,
|
|
(errmsg("could not translate service \"%s\" to address: %s", service, gai_strerror(ret))));
|
|
}
|
|
if (addrs != NULL) {
|
|
pg_freeaddrinfo_all(hint.ai_family, addrs);
|
|
}
|
|
return;
|
|
}
|
|
|
|
for (addr = addrs; addr; addr = addr->ai_next) {
|
|
if (!IS_AF_UNIX(family) && IS_AF_UNIX(addr->ai_family)) {
|
|
/*
|
|
* Only set up a unix domain socket when they really asked for it.
|
|
* The service/port is different in that case.
|
|
*/
|
|
continue;
|
|
}
|
|
struct sockaddr* sinp = NULL;
|
|
char* result = NULL;
|
|
|
|
sinp = (struct sockaddr*)(addr->ai_addr);
|
|
if (addr->ai_family == AF_INET6) {
|
|
result = inet_net_ntop(AF_INET6,
|
|
&((struct sockaddr_in6*)sinp)->sin6_addr,
|
|
128,
|
|
t_thrd.postmaster_cxt.LocalAddrList[t_thrd.postmaster_cxt.LocalIpNum],
|
|
IP_LEN);
|
|
} else if (addr->ai_family == AF_INET) {
|
|
result = inet_net_ntop(AF_INET,
|
|
&((struct sockaddr_in*)sinp)->sin_addr,
|
|
32,
|
|
t_thrd.postmaster_cxt.LocalAddrList[t_thrd.postmaster_cxt.LocalIpNum],
|
|
IP_LEN);
|
|
}
|
|
if (result == NULL) {
|
|
ereport(WARNING, (errmsg("inet_net_ntop failed, error: %d", EAFNOSUPPORT)));
|
|
} else {
|
|
ereport(DEBUG5, (errmodule(MOD_COMM_FRAMEWORK),
|
|
errmsg("[reload listen IP]set LocalIpNum[%d] %s",
|
|
t_thrd.postmaster_cxt.LocalIpNum,
|
|
t_thrd.postmaster_cxt.LocalAddrList[t_thrd.postmaster_cxt.LocalIpNum])));
|
|
t_thrd.postmaster_cxt.LocalIpNum++;
|
|
}
|
|
}
|
|
|
|
/* finally free malloc memory */
|
|
if (addrs != NULL) {
|
|
pg_freeaddrinfo_all(hint.ai_family, addrs);
|
|
}
|
|
}
|
|
|
|
static void assign_listen_addresses(const char *newval, void *extra)
|
|
{
|
|
if (t_thrd.postmaster_cxt.can_listen_addresses_reload && !IsUnderPostmaster) {
|
|
if (newval != NULL && strlen(newval) != 0 && u_sess->attr.attr_network.ListenAddresses != NULL &&
|
|
strcmp((const char *)newval, u_sess->attr.attr_network.ListenAddresses) != 0) {
|
|
ereport(WARNING,
|
|
(errmsg("Postmaster received signal to reload listen_addresses, update \"%s\" to \"%s\".",
|
|
u_sess->attr.attr_network.ListenAddresses, newval)));
|
|
t_thrd.postmaster_cxt.is_listen_addresses_reload = true;
|
|
}
|
|
}
|
|
|
|
if (IsUnderPostmaster) {
|
|
int i = 0;
|
|
errno_t rc = EOK;
|
|
char* rawstring = NULL;
|
|
List* elemlist = NULL;
|
|
rawstring = pstrdup(newval);
|
|
if (!SplitIdentifierString(rawstring, ',', &elemlist)) {
|
|
list_free_ext(elemlist);
|
|
pfree(rawstring);
|
|
return;
|
|
}
|
|
t_thrd.postmaster_cxt.LocalIpNum = 0;
|
|
for (i = 0; i < MAXLISTEN; i++) {
|
|
rc = memset_s(t_thrd.postmaster_cxt.LocalAddrList[i], IP_LEN, '\0', IP_LEN);
|
|
securec_check(rc, "", "");
|
|
}
|
|
ListCell* l = NULL;
|
|
ListCell* elem = NULL;
|
|
int checked_num = 0;
|
|
foreach(l, elemlist) {
|
|
char* curhost = (char*)lfirst(l);
|
|
|
|
/* Deduplicatd listen IP */
|
|
int check = 0;
|
|
bool has_checked = false;
|
|
foreach(elem, elemlist) {
|
|
if (check >= checked_num) {
|
|
break;
|
|
}
|
|
if (strcmp(curhost, (char*)lfirst(elem)) == 0) {
|
|
has_checked = true;
|
|
break;
|
|
}
|
|
check++;
|
|
}
|
|
checked_num++;
|
|
if (has_checked) {
|
|
has_checked = false;
|
|
continue;
|
|
}
|
|
|
|
if (strcmp(curhost, "*") == 0) {
|
|
transform_ip_to_addr(NULL, (unsigned short)g_instance.attr.attr_network.PostPortNumber);
|
|
} else {
|
|
transform_ip_to_addr(curhost, (unsigned short)g_instance.attr.attr_network.PostPortNumber);
|
|
}
|
|
}
|
|
list_free_ext(elemlist);
|
|
pfree(rawstring);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef LIBCOMM_SPEED_TEST_ENABLE
|
|
static void assign_comm_test_thread_num(int newval, void* extra)
|
|
{
|
|
gs_set_test_thread_num(newval);
|
|
return;
|
|
}
|
|
static void assign_comm_test_msg_len(int newval, void* extra)
|
|
{
|
|
gs_set_test_msg_len(newval);
|
|
return;
|
|
}
|
|
static void assign_comm_test_send_sleep(int newval, void* extra)
|
|
{
|
|
gs_set_test_send_sleep(newval);
|
|
return;
|
|
}
|
|
static void assign_comm_test_send_once(int newval, void* extra)
|
|
{
|
|
gs_set_test_send_once(newval);
|
|
return;
|
|
}
|
|
static void assign_comm_test_recv_sleep(int newval, void* extra)
|
|
{
|
|
gs_set_test_recv_sleep(newval);
|
|
return;
|
|
}
|
|
static void assign_comm_test_recv_once(int newval, void* extra)
|
|
{
|
|
gs_set_test_recv_once(newval);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
#ifdef LIBCOMM_FAULT_INJECTION_ENABLE
|
|
static void assign_comm_fault_injection(int newval, void* extra)
|
|
{
|
|
gs_set_fault_injection(newval);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
static const char* show_unix_socket_permissions(void)
|
|
{
|
|
char* buf = t_thrd.buf_cxt.show_unix_socket_permissions_buf;
|
|
int size = sizeof(t_thrd.buf_cxt.show_unix_socket_permissions_buf);
|
|
int rcs = 0;
|
|
|
|
rcs = snprintf_s(buf, size, size - 1, "%04o", g_instance.attr.attr_network.Unix_socket_permissions);
|
|
securec_check_ss(rcs, "\0", "\0");
|
|
return buf;
|
|
}
|
|
|
|
static bool check_max_datanode(int* newval, void** extra, GucSource source)
|
|
{
|
|
if (*newval + g_instance.attr.attr_network.MaxCoords > MAX_CN_DN_NODE_NUM) {
|
|
ereport(LOG,
|
|
(errmsg("PGXC can't support comm_max_datanode more than %d.",
|
|
MAX_CN_DN_NODE_NUM - g_instance.attr.attr_network.MaxCoords)));
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void comm_change_datanode(int newval, void* extra)
|
|
{
|
|
// newval is the number of DN.
|
|
// MaxCoords is CN=16.
|
|
gs_change_capacity(newval + g_instance.attr.attr_network.MaxCoords);
|
|
return;
|
|
}
|
|
|
|
static const char* show_max_datanode(void)
|
|
{
|
|
char nbuf[16];
|
|
int rcs = 0;
|
|
|
|
rcs = snprintf_s(
|
|
nbuf, sizeof(nbuf), sizeof(nbuf) - 1, "%d", gs_get_cur_node() - g_instance.attr.attr_network.MaxCoords);
|
|
securec_check_ss(rcs, "\0", "\0");
|
|
return pstrdup(nbuf);
|
|
}
|
|
|
|
static bool check_max_coordnode(int* newval, void** extra, GucSource source)
|
|
{
|
|
if (*newval + u_sess->attr.attr_network.comm_max_datanode > MAX_CN_DN_NODE_NUM) {
|
|
ereport(LOG,
|
|
(errmsg("PGXC can't support max_coordinators more than %d.",
|
|
MAX_CN_DN_NODE_NUM - u_sess->attr.attr_network.comm_max_datanode)));
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void comm_change_coordnode(int newval, void* extra)
|
|
{
|
|
// newval is the number of DN.
|
|
// MaxCoords is CN=16.
|
|
gs_change_capacity(newval + u_sess->attr.attr_network.comm_max_datanode);
|
|
return;
|
|
}
|
|
|
|
static const char* show_max_coordnode(void)
|
|
{
|
|
char nbuf[16];
|
|
int rcs = 0;
|
|
|
|
rcs = snprintf_s(nbuf, sizeof(nbuf), sizeof(nbuf) - 1, "%d", g_instance.attr.attr_network.MaxCoords);
|
|
securec_check_ss(rcs, "\0", "\0");
|
|
return pstrdup(nbuf);
|
|
}
|