当前位置: 首页 > news >正文

3.00001 postgres如何初始化系统参数?

文章目录

    • 加载参数整体流程
    • 参数结构
      • 举例:ConfigureNamesBool
    • 初始化参数 InitializeGUCOptions
      • build_guc_variables
      • InitializeOneGUCOption
      • InitializeGUCOptionsFromEnvironment
    • 命令行添加
    • SelectConfigFiles配置

加载参数整体流程

我们先看下guc参数是如何管理的。
在这里插入图片描述
首先初始化GUC选项,将其设置为默认值;然后读取命令行配置,最后读取配置文件postgresql.conf中的配置项。

参数结构

有5类参数:ConfigureNamesBool、ConfigureNamesInt、ConfigureNamesReal、ConfigureNamesReal、ConfigureNamesEnum。

在guc_tables中定义了不同类型的参数清单:

struct config_bool ConfigureNamesBool[] (guc_tables.c:771)
struct config_int ConfigureNamesInt[]   (guc_tables.c:2056)
struct config_real ConfigureNamesReal[] (guc_tables.c:3678)
struct config_string ConfigureNamesString[] (guc_tables.c:3959)
struct config_enum ConfigureNamesEnum[]  (guc_tables.c:4736)

不同的参数类型结构体定义在guc_tables.h

struct config_generic (guc_tables.h:153) //被用于下面几种类型参数的成员。
struct config_bool (guc_tables.h:198)
struct config_int (guc_tables.h:212)
struct config_real (guc_tables.h:228)
struct config_string  (guc_tables.h:254)
struct config_enum (guc_tables.h:268)

在guc_tables.h中定义了参数类型如下:guc_tables.h:21

enum config_type
{PGC_BOOL,PGC_INT,PGC_REAL,PGC_STRING,PGC_ENUM,
};

在guc_tables.c中定义了参数类型对应的值如下:guc_tables.c:731

const char *const config_type_names[] =
{[PGC_BOOL] = "bool",[PGC_INT] = "integer",[PGC_REAL] = "real",[PGC_STRING] = "string",[PGC_ENUM] = "enum",
};

举例:ConfigureNamesBool

ConfigureNamesBool参数组,每一个成员都是一个结构体config_bool

struct config_bool ConfigureNamesBool[] =
{{{"backtrace_on_internal_error", PGC_SUSET, DEVELOPER_OPTIONS,gettext_noop("Log backtrace for any error with error code XX000 (internal error)."),NULL,GUC_NOT_IN_SAMPLE},&backtrace_on_internal_error,false,NULL, NULL, NULL},

结构体config_bool的定义如下:

struct config_bool
{struct config_generic gen;  //包含的config_generic结构体/* constant fields, must be set correctly in initial value: */bool	   *variable;bool		boot_val;GucBoolCheckHook check_hook;GucBoolAssignHook assign_hook;GucShowHook show_hook;/* variable fields, initialized at runtime: */bool		reset_val;void	   *reset_extra;
};

结构体config_generic的定义如下:

struct config_generic
{/* constant fields, must be set correctly in initial value: */const char *name;			/* name of variable - MUST BE FIRST */GucContext	context;		/* context required to set the variable */enum config_group group;	/* to help organize variables by function */const char *short_desc;		/* short desc. of this variable's purpose */const char *long_desc;		/* long desc. of this variable's purpose */int			flags;			/* flag bits, see guc.h *//* variable fields, initialized at runtime: */enum config_type vartype;	/* type of variable (set only at startup) */int			status;			/* status bits, see below */GucSource	source;			/* source of the current actual value */GucSource	reset_source;	/* source of the reset_value */GucContext	scontext;		/* context that set the current value */GucContext	reset_scontext; /* context that set the reset value */Oid			srole;			/* role that set the current value */Oid			reset_srole;	/* role that set the reset value */GucStack   *stack;			/* stacked prior values */void	   *extra;			/* "extra" pointer for current actual value */dlist_node	nondef_link;	/* list link for variables that have source* different from PGC_S_DEFAULT */slist_node	stack_link;		/* list link for variables that have non-NULL* stack */slist_node	report_link;	/* list link for variables that have the* GUC_NEEDS_REPORT bit set in status */char	   *last_reported;	/* if variable is GUC_REPORT, value last sent* to client (NULL if not yet sent) */char	   *sourcefile;		/* file current setting is from (NULL if not* set in config file) */int			sourceline;		/* line in source file */
};

初始化参数 InitializeGUCOptions

InitializeGUCOptionsbuild_guc_variables();InitializeOneGUCOption(guc_variables[i]);InitializeGUCOptionsFromEnvironment

build_guc_variables

完成空间申请与初始化,

  1. 会通过设定的参数组ConfigureNamesxxx中的vartype值;
  2. 将所有的参数保存在guc_hashtab全局hash桶内
  • 初始化所有的参数组的vartype为对应的config_type,
		struct config_bool *conf = &ConfigureNamesBool[i];/* Rather than requiring vartype to be filled in by hand, do this: */conf->gen.vartype = PGC_BOOL;num_vars++;
  • 创建hash结构
// (guc.c:976)
guc_hashtab = hash_create("GUC hash table",size_vars,&hash_ctl,HASH_ELEM | HASH_FUNCTION | HASH_COMPARE | HASH_CONTEXT);

其中的guc_hashtab为static的hash结构(guc.c:241):

static HTAB *guc_hashtab;		/* entries are GUCHashEntrys */...// HTAB定义如下:
/** Top control structure for a hashtable --- in a shared table, each backend* has its own copy (OK since no fields change at runtime)*/
struct HTAB
{HASHHDR    *hctl;			/* => shared control information */HASHSEGMENT *dir;			/* directory of segment starts */HashValueFunc hash;			/* hash function */HashCompareFunc match;		/* key comparison function */HashCopyFunc keycopy;		/* key copying function */HashAllocFunc alloc;		/* memory allocator */MemoryContext hcxt;			/* memory context if default allocator used */char	   *tabname;		/* table name (for error messages) */bool		isshared;		/* true if table is in shared memory */bool		isfixed;		/* if true, don't enlarge *//* freezing a shared table isn't allowed, so we can keep state here */bool		frozen;			/* true = no more inserts allowed *//* We keep local copies of these fixed values to reduce contention */Size		keysize;		/* hash key length in bytes */long		ssize;			/* segment size --- must be power of 2 */int			sshift;			/* segment shift = log2(ssize) */
};
  • 将参数加入guc_hashtable
		struct config_generic *gucvar = &ConfigureNamesBool[i].gen;//这一步会从guc_hashtab(静态结构的hash表),中查找参数名(gucvar->name),没有的话就会新建一个返回给hentryhentry = (GUCHashEntry *) hash_search(guc_hashtab,&gucvar->name,HASH_ENTER,&found);Assert(!found);//初始化添加时一定找不到参数名的,那么就会新建一个桶,同时把桶赋值gucvar即 &ConfigureNamesBool[i].gen;hentry->gucvar = gucvar;

其中,
结构体GUCHashEntry的定义链如下:

typedef struct
{const char *gucname;		/* hash key */struct config_generic *gucvar;	/* -> GUC's defining structure */
} GUCHashEntry;

hash_search(dynahash.c:955)函数定义如下,其直接套用下层hash_search_with_hash_value函数

void *
hash_search(HTAB *hashp,const void *keyPtr,HASHACTION action,bool *foundPtr)
{return hash_search_with_hash_value(hashp,keyPtr,hashp->hash(keyPtr, hashp->keysize),action,foundPtr);
}

hash_search_with_hash_value(dynahash.c:968)函数大致作用是:
在Bucket中一个个找,用currBucket判断是否为null来确认是非存在对应的桶

// 在Bucket中一个个找,用currBucket判断是否为null来确认是非存在对应的桶while (currBucket != NULL){if (currBucket->hashvalue == hashvalue &&match(ELEMENTKEY(currBucket), keyPtr, keysize) == 0)break;prevBucketPtr = &(currBucket->link);currBucket = *prevBucketPtr;
#ifdef HASH_STATISTICShash_collisions++;hctl->collisions++;
#endif}

针对不同的hashaction有不同的动作

// hashaction的定义如下(hsearch.h:110)
/* hash_search operations */
typedef enum
{HASH_FIND,HASH_ENTER,HASH_REMOVE,HASH_ENTER_NULL,
} HASHACTION;* action is one of:*		HASH_FIND: look up key in table*		HASH_ENTER: look up key in table, creating entry if not present*		HASH_ENTER_NULL: same, but return NULL if out of memory*		HASH_REMOVE: look up key in table, remove entry if present... ...
// (dynahash.c:1037)switch (action){case HASH_FIND:... case HASH_ENTER:case HASH_ENTER_NULL:/* Return existing element if found, else create one */if (currBucket != NULL)return (void *) ELEMENTKEY(currBucket);/* disallow inserts if frozen */if (hashp->frozen)elog(ERROR, "cannot insert into frozen hashtable \"%s\"",hashp->tabname);//重新申请一个hash bucketcurrBucket = get_hash_entry(hashp, freelist_idx);if (currBucket == NULL){/* out of memory */if (action == HASH_ENTER_NULL)return NULL;/* report a generic message */if (hashp->isshared)ereport(ERROR,(errcode(ERRCODE_OUT_OF_MEMORY),errmsg("out of shared memory")));elseereport(ERROR,(errcode(ERRCODE_OUT_OF_MEMORY),errmsg("out of memory")));}/* link into hashbucket chain */*prevBucketPtr = currBucket;currBucket->link = NULL;/* copy key into record */currBucket->hashvalue = hashvalue;hashp->keycopy(ELEMENTKEY(currBucket), keyPtr, keysize);/** Caller is expected to fill the data field on return.  DO NOT* insert any code that could possibly throw error here, as doing* so would leave the table entry incomplete and hence corrupt the* caller's data structure.*/return (void *) ELEMENTKEY(currBucket);}

在初始化参数是的堆栈如下:其中action是“HASH_ENTER”。

#0  hash_search_with_hash_value (hashp=0x1023f80, keyPtr=0xfb4c60 <ConfigureNamesBool>, hashvalue=1010527281, action=HASH_ENTER, foundPtr=0x7fffffffe05f) at dynahash.c:975
#1  0x0000000000bc1901 in hash_search (hashp=0x1023f80, keyPtr=0xfb4c60 <ConfigureNamesBool>, action=HASH_ENTER, foundPtr=0x7fffffffe05f) at dynahash.c:960
#2  0x0000000000bcd413 in build_guc_variables () at guc.c:985
#3  0x0000000000bce451 in InitializeGUCOptions () at guc.c:1546
#4  0x0000000000911a54 in PostmasterMain (argc=1, argv=0x1000ef0) at postmaster.c:585
#5  0x00000000007d3f97 in main (argc=1, argv=0x1000ef0) at main.c:197

如上所示,会使用get_hash_entry(dynahash.c:1256)重新创建一个bucket存储某一个参数。存储类型为GUCHashEntry。

InitializeOneGUCOption

代码栈如下:

Breakpoint 1, InitializeOneGUCOption (gconf=0xfc39c8 <ConfigureNamesString+3400>) at guc.c:1648
1648            gconf->status = 0;
(gdb) bt
#0  InitializeOneGUCOption (gconf=0xfc39c8 <ConfigureNamesString+3400>) at guc.c:1648
#1  0x0000000000bce4a4 in InitializeGUCOptions () at guc.c:1558
#2  0x0000000000911a54 in PostmasterMain (argc=3, argv=0x1000ef0) at postmaster.c:585
#3  0x00000000007d3f97 in main (argc=3, argv=0x1000ef0) at main.c:197

其中
InitializeOneGUCOption函数的入参gconf来源如下,为GUCHashEntry->config_generic:

	hash_seq_init(&status, guc_hashtab);while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL){/* Check mapping between initial and default value */Assert(check_GUC_init(hentry->gucvar));InitializeOneGUCOption(hentry->gucvar);}

即此时通过全局静态变量guc_hashtab来一个个配置参数。配置过程调用InitializeOneGUCOption函数,具体步骤如下:

  • 第一步:填充统一的默认值:
	gconf->status = 0;gconf->source = PGC_S_DEFAULT;gconf->reset_source = PGC_S_DEFAULT;gconf->scontext = PGC_INTERNAL;gconf->reset_scontext = PGC_INTERNAL;gconf->srole = BOOTSTRAP_SUPERUSERID;gconf->reset_srole = BOOTSTRAP_SUPERUSERID;gconf->stack = NULL;gconf->extra = NULL;gconf->last_reported = NULL;gconf->sourcefile = NULL;gconf->sourceline = 0;
  • 第二部,初始化参数值
switch (gconf->vartype){case PGC_BOOL:{struct config_bool *conf = (struct config_bool *) gconf;bool		newval = conf->boot_val;void	   *extra = NULL;if (!call_bool_check_hook(conf, &newval, &extra,PGC_S_DEFAULT, LOG))elog(FATAL, "failed to initialize %s to %d",conf->gen.name, (int) newval);if (conf->assign_hook)conf->assign_hook(newval, extra);*conf->variable = conf->reset_val = newval;conf->gen.extra = conf->reset_extra = extra;break;}case PGC_INT:{......

此时newval值的来源在哪里?
查看此时的conf变量,发现它的初始值中就conf->boot_val就是1!!

(gdb) p *conf
$15 = {gen = {name = 0xe2dc71 "extra_float_digits", context = PGC_USERSET, group = CLIENT_CONN_LOCALE, short_desc = 0xe2dc88 "Sets the number of digits displayed for floating-point values.", long_desc = 0xe2dcc8 "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than "..., flags = 0, vartype = PGC_INT, status = 0, source = PGC_S_DEFAULT, reset_source = PGC_S_DEFAULT, scontext = PGC_INTERNAL, reset_scontext = PGC_INTERNAL, srole = 10, reset_srole = 10, stack = 0x0, extra = 0x0, nondef_link = {prev = 0x0, next = 0x0}, stack_link = {next = 0x0}, report_link = {next = 0x0}, last_reported = 0x0, sourcefile = 0x0, sourceline = 0}, variable = 0xfb49d8 <extra_float_digits>, boot_val = 1, min = -15, max = 3, check_hook = 0x0, assign_hook = 0x0, show_hook = 0x0, reset_val = 0, reset_extra = 0x0}

然而此时的conf 来源与gconf,而gconf来源于静态变量guc_hashtab。其中保存的是struct config_int ConfigureNamesInt[]的地址。
查看config_int ConfigureNamesInt[];发现:

	{{"extra_float_digits", PGC_USERSET, CLIENT_CONN_LOCALE,gettext_noop("Sets the number of digits displayed for floating-point values."),gettext_noop("This affects real, double precision, and geometric data types. ""A zero or negative parameter value is added to the standard ""number of digits (FLT_DIG or DBL_DIG as appropriate). ""Any value greater than zero selects precise output mode.")},&extra_float_digits,1, -15, 3,NULL, NULL, NULL},

已经默认配置了初始值。见上面的“1,-15,3”分别对应指针conf的“boot_val,min,max”;
同时观察整个ConfigureNamesInt数组,发现初始值也有一些宏,如下

	{/* Can't be set in postgresql.conf */{"server_version_num", PGC_INTERNAL, PRESET_OPTIONS,gettext_noop("Shows the server version as an integer."),NULL,GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE},&server_version_num,PG_VERSION_NUM, PG_VERSION_NUM, PG_VERSION_NUM,NULL, NULL, NULL},

即通过静态参数组中的boot_val属性为每个参数赋值。

InitializeGUCOptionsFromEnvironment

堆栈如下:

Breakpoint 1, InitializeGUCOptionsFromEnvironment () at guc.c:1596
warning: Source file is more recent than executable.
1596            env = getenv("PGPORT");
(gdb) bt
#0  InitializeGUCOptionsFromEnvironment () at guc.c:1596
#1  0x0000000000bce512 in InitializeGUCOptions () at guc.c:1578
#2  0x0000000000911a54 in PostmasterMain (argc=3, argv=0x1000ef0) at postmaster.c:585
#3  0x00000000007d3f97 in main (argc=3, argv=0x1000ef0) at main.c:197

其中主要调用SetConfigOption(guc.c:4275)来配置PGPORT、PGDATESTYLE、PGCLIENTENCODING这些linuc的宏(环境变量),确认postgresql中的port、datestyle、client_encoding等参数配置,如下图:

	env = getenv("PGPORT");if (env != NULL)SetConfigOption("port", env, PGC_POSTMASTER, PGC_S_ENV_VAR);env = getenv("PGDATESTYLE");if (env != NULL)SetConfigOption("datestyle", env, PGC_POSTMASTER, PGC_S_ENV_VAR);env = getenv("PGCLIENTENCODING");if (env != NULL)SetConfigOption("client_encoding", env, PGC_POSTMASTER, PGC_S_ENV_VAR);

其中SetConfigOption(guc.c:4275)

void
SetConfigOption(const char *name, const char *value,GucContext context, GucSource source)
{(void) set_config_option(name, value, context, source,GUC_ACTION_SET, true, 0, false);
}

SetConfigOption嵌套set_config_option(guc.c:3333)函数如下:

int
set_config_option(const char *name, const char *value,GucContext context, GucSource source,GucAction action, bool changeVal, int elevel,bool is_reload)
{// bt如下
#0  set_config_with_handle (name=0xe2460e "transaction_isolation", handle=0x0, value=0xe245ff "read committed", context=PGC_POSTMASTER, source=PGC_S_OVERRIDE, srole=10, action=GUC_ACTION_SET, changeVal=true, elevel=0, is_reload=false) at guc.c:3401
#1  0x0000000000bd16fe in set_config_option (name=0xe2460e "transaction_isolation", value=0xe245ff "read committed", context=PGC_POSTMASTER, source=PGC_S_OVERRIDE, action=GUC_ACTION_SET, changeVal=true, elevel=0, is_reload=false) at guc.c:3351
#2  0x0000000000bd33a0 in SetConfigOption (name=0xe2460e "transaction_isolation", value=0xe245ff "read committed", context=PGC_POSTMASTER, source=PGC_S_OVERRIDE) at guc.c:4278
#3  0x0000000000bce4db in InitializeGUCOptions () at guc.c:1567
#4  0x0000000000911a54 in PostmasterMain (argc=3, argv=0x1000ef0) at postmaster.c:585
#5  0x00000000007d3f97 in main (argc=3, argv=0x1000ef0) at main.c:197

其也是通过将guc_hashtab全局hash表内的值拿出来,经过一系列对比之后进行赋值。

命令行添加

// postmaster.c:594while ((opt = getopt(argc, argv, "B:bC:c:D:d:EeFf:h:ijk:lN:OPp:r:S:sTt:W:-:")) != -1){switch (opt)case 'B':SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV);break;... ...

这里面会对不同的参数做设置:
同时也是调用的SetConfigOption(guc.c:4275)完成重写

SelectConfigFiles配置

调用堆栈如下:

(gdb) b SelectConfigFiles
Breakpoint 2 at 0xbcedd2: file guc.c, line 1795.
(gdb) r
Starting program: /home/db_postg/build/bin/postgres -D /home/db_postg/data
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".Breakpoint 2, SelectConfigFiles (userDoption=0x102bff0 "/home/db_postg/data", progname=0x10002a0 "postgres") at guc.c:1795
1795            if (userDoption)
(gdb) b read
Breakpoint 3 at 0x7ffff7d5bc10 (2 locations)
(gdb) b open
Breakpoint 4 at 0x7ffff7d5b920 (2 locations)
(gdb) c
Continuing.
Breakpoint 4, 0x00007ffff7d5b920 in open64 () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff7d5b920 in open64 () from /lib64/libc.so.6
#1  0x00007ffff7ceb956 in _IO_file_open () from /lib64/libc.so.6
#2  0x00007ffff7cebb2a in __GI__IO_file_fopen () from /lib64/libc.so.6
#3  0x00007ffff7cdf41d in __fopen_internal () from /lib64/libc.so.6
#4  0x00000000009a72b3 in AllocateFile (name=0x102c130 "/home/db_postg/data/postgresql.conf", mode=0xe264d2 "r") at fd.c:2601
#5  0x0000000000bd947e in ParseConfigFile (config_file=0x10228b8 "/home/db_postg/data/postgresql.conf", strict=true, calling_file=0x0, calling_lineno=0, depth=0, elevel=15, head_p=0x7fffffffdfb8, tail_p=0x7fffffffdfb0)at guc-file.l:238
#6  0x0000000000bcc202 in ProcessConfigFileInternal (context=PGC_POSTMASTER, applySettings=true, elevel=15) at guc.c:299
#7  0x0000000000bd926d in ProcessConfigFile (context=PGC_POSTMASTER) at guc-file.l:152
#8  0x0000000000bcef97 in SelectConfigFiles (userDoption=0x102bff0 "/home/db_postg/data", progname=0x10002a0 "postgres") at guc.c:1864
#9  0x0000000000911f78 in PostmasterMain (argc=3, argv=0x1000ef0) at postmaster.c:768
#10 0x00000000007d3f97 in main (argc=3, argv=0x1000ef0) at main.c:197
(gdb) c
Continuing.Breakpoint 3, 0x00007ffff7d5bc10 in read () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff7d5bc10 in read () from /lib64/libc.so.6
#1  0x00007ffff7ceb118 in __GI__IO_file_xsgetn () from /lib64/libc.so.6
#2  0x00007ffff7cdf983 in fread () from /lib64/libc.so.6
#3  0x0000000000bd8258 in yy_get_next_buffer () at guc-file.c:1369
#4  0x0000000000bd7d38 in GUC_yylex () at guc-file.c:1209
#5  0x0000000000bd9d22 in ParseConfigFp (fp=0x102e040, config_file=0x102c130 "/home/db_postg/data/postgresql.conf", depth=0, elevel=15, head_p=0x7fffffffdfb8, tail_p=0x7fffffffdfb0) at guc-file.l:388
#6  0x0000000000bd956e in ParseConfigFile (config_file=0x10228b8 "/home/db_postg/data/postgresql.conf", strict=true, calling_file=0x0, calling_lineno=0, depth=0, elevel=15, head_p=0x7fffffffdfb8, tail_p=0x7fffffffdfb0)at guc-file.l:262
#7  0x0000000000bcc202 in ProcessConfigFileInternal (context=PGC_POSTMASTER, applySettings=true, elevel=15) at guc.c:299
#8  0x0000000000bd926d in ProcessConfigFile (context=PGC_POSTMASTER) at guc-file.l:152
#9  0x0000000000bcef97 in SelectConfigFiles (userDoption=0x102bff0 "/home/db_postg/data", progname=0x10002a0 "postgres") at guc.c:1864
#10 0x0000000000911f78 in PostmasterMain (argc=3, argv=0x1000ef0) at postmaster.c:768
#11 0x00000000007d3f97 in main (argc=3, argv=0x1000ef0) at main.c:197

其中的主要动作有:
1、生成配置文件路径并打开:

// SelectConfigFiles at guc.c:1826...if (userDoption)configdir = make_absolute_path(userDoption);elseconfigdir = make_absolute_path(getenv("PGDATA"));/*(gdb) p configdir$5 = 0x102c010 "/home/db_postg/data"*/... else if (configdir){fname = guc_malloc(FATAL,strlen(configdir) + strlen(CONFIG_FILENAME) + 2);sprintf(fname, "%s/%s", configdir, CONFIG_FILENAME);fname_is_malloced = false;}/*(gdb) p fname$4 = 0x1022868 "/home/db_postg/data/postgresql.conf"*/

2、配置数据目录参数和配置文件参数

	SetConfigOption("config_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);... ...//第一次读取配置文件,只是为了设置data目录。ProcessConfigFile(PGC_POSTMASTER);...data_directory_rec = (struct config_string *)find_option("data_directory", false, false, PANIC);if (*data_directory_rec->variable)SetDataDir(*data_directory_rec->variable);else if (configdir)SetDataDir(configdir);... ...SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);

3、配置其余参数

ProcessConfigFile(PGC_POSTMASTER);
...
SetConfigOption("hba_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
...
SetConfigOption("ident_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);

相关文章:

3.00001 postgres如何初始化系统参数?

文章目录 加载参数整体流程参数结构举例&#xff1a;ConfigureNamesBool 初始化参数 InitializeGUCOptionsbuild_guc_variablesInitializeOneGUCOptionInitializeGUCOptionsFromEnvironment 命令行添加SelectConfigFiles配置 加载参数整体流程 我们先看下guc参数是如何管理的。…...

C# 读取 CSV 文件的方法汇总

文章目录 1. 使用System.IO命名空间中的类2. 处理标题行和指定列3. 使用CsvHelper库4. 高级功能和异常处理5. 使用 LINQ6. 总结 CSV&#xff08;Comma-Separated Values&#xff0c;逗号分隔值&#xff09;文件是一种简单的文本文件格式&#xff0c;用于存储表格数据。在C#中&a…...

element+ 引入图标报错 Failed to resolve import “@element-plus/icons-vue“ from “

element 引入图标报错 Internal server error: Failed to resolve import “element-plus/icons-vue” from “src\components\TimeLine.vue”. Does the file exist? 原因&#xff1a;element-plus需要单独引入 icons 文档 pnpm install element-plus/icons-vue之后就可以…...

Github 2024-05-25 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-25统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目3TypeScript项目3非开发语言项目1HTML项目1Rust项目1Go项目1Jupyter Notebook项目1Java项目1Angular文档:交付Web应用程序的自信之选…...

VPN的详细理解

VPN&#xff08;Virtual Private Network&#xff0c;虚拟私人网络&#xff09;是一种在公共网络上建立加密通道的技术&#xff0c;通过这种技术可以使远程用户访问公司内部网络资源时&#xff0c;实现安全的连接和数据传输。以下是对VPN的详细介绍&#xff1a; 选择代理浏览器…...

java后端轮播图的设计

对于表示轮播图位置这种有限且较小范围的数据&#xff0c;一般可以使用整数类型来表示。考虑到位置序号一般是非负整数且数量较少&#xff0c;可以选择使用小范围的整数类型&#xff0c;如下&#xff1a; 整数类型: 对于Java中&#xff0c;可以考虑使用 int 类型来表示位置序号…...

upload-labs 21关解析

目录 一、代码审计 二、实践 三、总结 一、代码审计 $is_upload false; $msg null; if(!empty($_FILES[upload_file])){//检查MIME$allow_type array(image/jpeg,image/png,image/gif);if(!in_array($_FILES[upload_file][type],$allow_type)){$msg "禁止上传该类型…...

常用汇编指令

&#xff08;arg&#xff09;argument&#xff1a;自变量&#xff0c;变元 &#xff08;reg&#xff09;register&#xff1a;寄存器 &#xff08;seg&#xff09;segment&#xff1a;段寄存器 &#xff08;mem&#xff09;memory&#xff1a;存储器&#xff08;内存单元&am…...

LabVIEW软件需求分析文档内容和编写指南

编写LabVIEW软件需求分析文档&#xff08;Software Requirements Specification, SRS&#xff09;是软件开发的关键步骤之一。以下是详细的内容结构、编写指南和注意事项&#xff1a; 内容结构 引言 项目背景&#xff1a;简要介绍项目背景和目的。 文档目的&#xff1a;说明需…...

spring cache(三)demo

目录 一、入门demo 1、pom 2、配置文件 3、config 4、controller 5、service 6、dao 7、dto与常量 8、测试&#xff1a; 8.1、无参 8.2、单参 &#xff08;1&#xff09;缓存与删除缓存 &#xff08;2&#xff09;删除缓存加入异常 二、自定义删除key 1、pom 2、…...

Android 应用开发语言选择对比

Android开发语言有多种&#xff0c;但是每种语言的各有不同的适用场景&#xff0c;对比介绍如下&#xff1a; 一.首选&#xff1a;原生应用Java&#xff0c;Kotlin 1.截至目前&#xff0c;大约有70%的Android开发者仍然使用Java语言进行开发&#xff0c;而30%的开发者则选择…...

Git 小白入门到进阶—(基本概念和常用命令)

一.了解 Git 基本概念和常用命令的作用 (理论) 基本概念 1、工作区 包含.git文件夹的目录&#xff0c;主要用存放开发的代码2、仓库 分为本地仓库和远程仓库&#xff0c;本地仓库是自己电脑上的git仓库(.git文件夹);远程仓库是在远程服务器上的git仓库git文件夹无需我们进行操…...

大数据框架总结(全)

☔️ 大数据框架总结&#xff08;全&#xff09; 关注“大数据领航员”&#xff0c;在公众号号中回复关键字【大数据面试资料】&#xff0c;即可可获取2024最新大数据面试资料的pdf文件 一. Hadoop HDFS读流程和写流程 HDFS写数据流程 &#xff08;1&#xff09;客户端通过…...

44、Flink 的 Interval Join 详解

Interval Join Interval join 组合元素的条件为&#xff1a;两个流&#xff08;暂时称为 A 和 B&#xff09;中 key 相同且 B 中元素的 timestamp 处于 A 中元素 timestamp 的一定范围内&#xff0c;即 b.timestamp ∈ [a.timestamp lowerBound; a.timestamp upperBound] 或…...

H6246 60V降压3.3V稳压芯片 60V降压5V稳压芯片IC 60V降压12V稳压芯片

H6246降压稳压芯片是一款电源管理芯片&#xff0c;为高压输入、低压输出的应用设计。以下是对该产品的详细分析&#xff1a; 一、产品优势 宽电压输入范围&#xff1a;H6246支持8V至48V的宽电压输入范围&#xff0c;使其能够适应多种不同的电源环境&#xff0c;增强了产品的通用…...

【MySQL精通之路】查询优化器的使用(8)

MySQL通过影响查询计划评估方式的系统变量、可切换优化、优化器和索引提示以及优化器成本模型提供优化器控制。 服务器在column_statistics数据字典表中维护有关列值的直方图统计信息&#xff08;请参阅第10.9.6节“Optimizer统计信息”&#xff09;。与其他数据字典表一样&am…...

Docker in Docker(DinD)原理与实践

随着云计算和容器化技术的快速发展&#xff0c;Docker作为开源的应用容器引擎&#xff0c;已经成为企业部署和管理应用程序的首选工具。然而&#xff0c;在某些场景下&#xff0c;我们可能需要在Docker容器内部再运行一个Docker环境&#xff0c;即Docker in Docker&#xff08;…...

科技前沿:IDEA插件Translation v3.6 带来革命性更新,翻译和发音更智能!

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …...

【并发小知识】

计算机五大组成部分 控制器 运算器 存储器 输入设备 输出设备 计算机的核心真正干活的是CPU&#xff08;控制器运算器中央处理器&#xff09; 程序要想计算机运行&#xff0c;它的代码必须要先由硬盘读到内存&#xff0c;之后cpu取指再执行 操作系统发展史 穿孔卡片处理…...

python将多个音频文件与一张图片合成视频

代码中m4a可以换成mp3,图片和音频放同一目录&#xff0c;图片名image.jpg&#xff0c;多线程max_workers可以根据CPU核心数量修改。 import os import subprocess import sys import concurrent.futures import ffmpeg def get_media_duration(media_path): probe ffmp…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...