readme
来自「postgresql8.3.4源码,开源数据库」· 代码 · 共 224 行
TXT
224 行
$PostgreSQL: pgsql/src/backend/utils/misc/README,v 1.8 2007/12/28 00:23:23 tgl Exp $GUC IMPLEMENTATION NOTESThe GUC (Grand Unified Configuration) module implements configurationvariables of multiple types (currently boolean, int, float, and string).Variable settings can come from various places, with a priority orderingdetermining which setting is used.PER-VARIABLE HOOKSEach variable known to GUC can optionally have an assign_hook and/ora show_hook to provide customized behavior. Assign hooks are used toperform validity checking on variable values (above and beyond whatGUC can do). They are also used to update any derived state that needsto change when a GUC variable is set. Show hooks are used to modifythe default SHOW display for a variable.If an assign_hook is provided, it points to a function of the signature bool assign_hook(newvalue, bool doit, GucSource source)where the type of "newvalue" matches the kind of variable. This functionis called immediately before actually setting the variable's value (so itcan look at the actual variable to determine the old value). If thefunction returns "true" then the assignment is completed; if it returns"false" then newvalue is considered invalid and the assignment is notperformed. If "doit" is false then the function should simply checkvalidity of newvalue and not change any derived state. The "source" parameterindicates where the new value came from. If it is >= PGC_S_INTERACTIVE,then we are performing an interactive assignment (e.g., a SET command), andereport(ERROR) is safe to do. But when source < PGC_S_INTERACTIVE, we arereading a non-interactive option source, such as postgresql.conf. In thiscase the assign_hook should *not* ereport but should just return false if itdoesn't like the newvalue.If an assign_hook returns false then guc.c will report a generic "invalidvalue for option FOO" error message. If you feel the need to provide a morespecific error message, ereport() it using "GUC_complaint_elevel(source)"as the error level. Note that this might return either ERROR or a lower levelsuch as LOG, so the ereport call might or might not return. If it doesreturn, return false out of the assign_hook.For string variables, the signature for assign hooks is a bit different: const char *assign_hook(const char *newvalue, bool doit, GucSource source)The meanings of the parameters are the same as for the other types of GUCvariables, but the return value is handled differently: NULL --- assignment fails (like returning false for other datatypes) newvalue --- assignment succeeds, assign the newvalue as-is malloc'd (not palloc'd!!!) string --- assign that value insteadThe third choice is allowed in case the assign_hook wants to return a"canonical" version of the new value. For example, the assign_hook fordatestyle always returns a string that includes both output and inputdatestyle options, although the input might have specified only one.Note that a string variable's assign_hook will NEVER be called with a NULLvalue for newvalue, since there would be no way to distinguish successand failure returns. If the boot_val or reset_val for a string variableis NULL, it will just be assigned without calling the assign_hook.Therefore, a NULL boot_val should never be used in combination with anassign_hook that has side-effects, as the side-effects wouldn't happenduring a RESET that re-institutes the boot-time setting.If a show_hook is provided, it points to a function of the signature const char *show_hook(void)This hook allows variable-specific computation of the value displayedby SHOW.SAVING/RESTORING GUC VARIABLE VALUESPrior values of configuration variables must be remembered in order to dealwith several special cases: RESET (a/k/a SET TO DEFAULT), rollback of SETon transaction abort, rollback of SET LOCAL at transaction end (eithercommit or abort), and save/restore around a function that has a SET option.RESET is defined as selecting the value that would be effective had therenever been any SET commands in the current session.To handle these cases we must keep track of many distinct values for eachvariable. The primary values are:* actual variable contents always the current effective value* reset_val the value to use for RESET(Each GUC entry also has a boot_val which is the wired-in default value.This is assigned to the reset_val and the actual variable duringInitializeGUCOptions(). The boot_val is also consulted to restore thecorrect reset_val if SIGHUP processing discovers that a variable formerlyspecified in postgresql.conf is no longer set there.)In addition to the primary values, there is a stack of former effectivevalues that might need to be restored in future. Stacking and unstackingis controlled by the GUC "nest level", which is zero when outside anytransaction, one at top transaction level, and incremented for eachopen subtransaction or function call with a SET option. A stack entryis made whenever a GUC variable is first modified at a given nesting level.(Note: the reset_val need not be stacked because it is only changed bynon-transactional operations.)A stack entry has a state, a prior value of the GUC variable, a rememberedsource of that prior value, and depending on the state may also have a"masked" value. The masked value is needed when SET followed by SET LOCALoccur at the same nest level: the SET's value is masked but must beremembered to restore after transaction commit.During initialization we set the actual value and reset_val based onwhichever non-interactive source has the highest priority. They willhave the same value.The possible transactional operations on a GUC value are:Entry to a function with a SET option: Push a stack entry with the prior variable value and state SAVE, then set the variable.Plain SET command: If no stack entry of current level: Push new stack entry w/prior value and state SET else if stack entry's state is SAVE, SET, or LOCAL: change stack state to SET, don't change saved value (here we are forgetting effects of prior set action) else (entry must have state SET+LOCAL): discard its masked value, change state to SET (here we are forgetting effects of prior SET and SET LOCAL) Now set new value.SET LOCAL command: If no stack entry of current level: Push new stack entry w/prior value and state LOCAL else if stack entry's state is SAVE or LOCAL or SET+LOCAL: no change to stack entry (in SAVE case, SET LOCAL will be forgotten at func exit) else (entry must have state SET): put current active into its masked slot, set state SET+LOCAL Now set new value.Transaction or subtransaction abort: Pop stack entries, restoring prior value, until top < subxact depthTransaction or subtransaction commit (incl. successful function exit): While stack entry level >= subxact depth if entry's state is SAVE: pop, restoring prior value else if level is 1 and entry's state is SET+LOCAL: pop, restoring *masked* value else if level is 1 and entry's state is SET: pop, discarding old value else if level is 1 and entry's state is LOCAL: pop, restoring prior value else if there is no entry of exactly level N-1: decrement entry's level, no other state change else merge entries of level N-1 and N as specified belowThe merged entry will have level N-1 and prior = older prior, so easiestto keep older entry and free newer. There are 12 possibilities sincewe already handled level N state = SAVE:N-1 NSAVE SET discard top prior, set state SETSAVE LOCAL discard top prior, no change to stack entrySAVE SET+LOCAL discard top prior, copy masked, state S+LSET SET discard top prior, no change to stack entrySET LOCAL copy top prior to masked, state S+LSET SET+LOCAL discard top prior, copy masked, state S+LLOCAL SET discard top prior, set state SETLOCAL LOCAL discard top prior, no change to stack entryLOCAL SET+LOCAL discard top prior, copy masked, state S+LSET+LOCAL SET discard top prior and second masked, state SETSET+LOCAL LOCAL discard top prior, no change to stack entrySET+LOCAL SET+LOCAL discard top prior, copy masked, state S+LRESET is executed like a SET, but using the reset_val as the desired newvalue. (We do not provide a RESET LOCAL command, but SET LOCAL TO DEFAULThas the same behavior that RESET LOCAL would.) The source associated withthe reset_val also becomes associated with the actual value.If SIGHUP is received, the GUC code rereads the postgresql.confconfiguration file (this does not happen in the signal handler, but atnext return to main loop; note that it can be executed while within atransaction). New values from postgresql.conf are assigned to actualvariable, reset_val, and stacked actual values, but only if each ofthese has a current source priority <= PGC_S_FILE. (It is thus possiblefor reset_val to track the config-file setting even if there iscurrently a different interactive value of the actual variable.)The assign_hook and show_hook routines work only with the actual variable,and are not directly aware of the additional values maintained by GUC.This is not a problem for normal usage, since we can assign first to theactual variable and then (if that succeeds) to the additional values asneeded. However, for SIGHUP rereads we may not want to assign to theactual variable. Our procedure in that case is to call the assign_hookwith doit = false so that the value is validated, but no derived state ischanged.STRING MEMORY HANDLINGString option values are allocated with strdup, not with thepstrdup/palloc mechanisms. We would need to keep them in a permanentcontext anyway, and strdup gives us more control over handlingout-of-memory failures.We allow a string variable's actual value, reset_val, boot_val, and stackedvalues to point at the same storage. This makes it slightly harder to freespace (we must test whether a value to be freed isn't equal to any of theother pointers in the GUC entry or associated stack items). The mainadvantage is that we never need to strdup during transaction commit/abort,so cannot cause an out-of-memory failure there.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?