{"id":344778,"date":"2023-01-31T15:03:54","date_gmt":"2023-01-31T15:03:54","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=344778"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=344778","title":{"rendered":"<span>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 PostgreSQL. \u0427\u0430\u0441\u0442\u044c 3. \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u044d\u043a\u044d\u043d\u0434\u0430<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e!<\/p>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b PostgreSQL. \u041c\u044b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u043d\u0430\u00a0\u043c\u043e\u043c\u0435\u043d\u0442\u0435 \u043e\u0431\u0449\u0435\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Postgres\u00a0\u2014 \u0432\u0445\u043e\u0434\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0434\u043e\u00a0\u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430.<\/p>\n<p><strong>PostgresMain <\/strong>\u2014 \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0431\u044d\u043a\u044d\u043d\u0434\u0430. \u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0430 \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/tcop\/postgres.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/tcop\/postgres.c<\/a><\/p>\n<p>\u0411\u044d\u043a\u044d\u043d\u0434 \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u0430\u043a\u00a0\u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e (Standalone), \u0442\u0430\u043a \u0438 \u0432\u00a0\u043e\u0431\u044b\u0447\u043d\u043e\u043c (\u043c\u043d\u043e\u0433\u043e\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c) \u0440\u0435\u0436\u0438\u043c\u0435 (\u0438\u0437\u2011\u043f\u043e\u0434 Postmaster)<\/p>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0435\u0434\u0435\u0442\u0441\u044f \u0441\u00a0\u0443\u0447\u0435\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u00a0\u043c\u043d\u043e\u0433\u043e\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 (<em>IsUnderPostmaster<\/em>\u0440\u0430\u0432\u0435\u043d <code>true<\/code>)<\/p>\n<details class=\"spoiler\">\n<summary>\u0420\u0430\u0431\u043e\u0442\u0430 \u0432 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0430 \u0438\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e, \u0442\u043e \u043c\u043d\u043e\u0433\u0438\u0435 \u043e\u043f\u0446\u0438\u0438 \u0435\u0449\u0435 \u043d\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 GUC. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043f\u0435\u0440\u0435\u0434 \u0441\u0430\u043c\u0438\u043c \u0446\u0438\u043a\u043b\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438\u0441\u044c \u043d\u0435 \u0438\u0437-\u043f\u043e\u0434 Postmaster.\u00a0<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0435\u0441\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0440\u0430\u043d\u0435\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <em>InitializeGUCOptions<\/em>, \u043d\u043e \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439, \u0447\u0442\u043e \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438\u0441\u044c \u0438\u0437 Postmaster. \u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f IsUnderPostmaster. <\/p>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442 \u0441 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u043c<\/p>\n<pre><code class=\"cpp\">if (!IsUnderPostmaster) {   someOperation(); }<\/code><\/pre>\n<p>\u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a &#171;\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>someOperation<\/code> \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0432 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435&#187;<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430<\/p>\n<pre><code class=\"cpp\">void PostgresMain(int argc, char *argv[],  const char *dbname,  const char *username) {   intfirstchar;   StringInfoData input_message;   sigjmp_buflocal_sigjmp_buf;   volatile bool send_ready_for_query = true;   boolidle_in_transaction_timeout_enabled = false;   boolidle_session_timeout_enabled = false;    \/* Initialize startup process environment if necessary. *\/   if (!IsUnderPostmaster)       InitStandaloneProcess(argv[0]);      \/\/ ... }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<p>\u041a\u0430\u043a\u00a0\u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u00a0\u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u044d\u043a\u044d\u043d\u0434\u0430, \u0442\u043e \u0432\u0445\u043e\u0434\u0438\u043c \u0432\u00a0\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <em>InitProcessing<\/em>. <\/p>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b (<em>NormalProcessing)<\/em>\u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0431\u044d\u043a\u044d\u043d\u0434\u0430 (<em>InitPostgres<\/em>) <\/p>\n<details class=\"spoiler\">\n<summary>ProcessingMode<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e Postmaster \u0438\u043c\u0435\u0435\u0442 \u043c\u0430\u0448\u0438\u043d\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439, \u043d\u043e \u0438 \u0431\u044d\u043a\u044d\u043d\u0434. \u0415\u0433\u043e \u043c\u0430\u0448\u0438\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435\u043c <em>ProcessingMode<\/em><\/p>\n<pre><code class=\"cpp\">typedef enum ProcessingMode { BootstrapProcessing,\/* bootstrap creation of template database *\/ InitProcessing,\/* initializing system *\/ NormalProcessing\/* normal processing *\/ } ProcessingMode;<\/code><\/pre>\n<p>\u0412\u0441\u0435\u0433\u043e \u0435\u0441\u0442\u044c 3 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f:<\/p>\n<ul>\n<li>\n<p><em>BootstrapProcessing<\/em> &#8212; \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0411\u0414 \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0430<\/p>\n<\/li>\n<li>\n<p><em>InitProcessing<\/em> &#8212; \u0441\u0442\u0430\u0440\u0442 \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u044d\u043a\u044d\u043d\u0434\u0430<\/p>\n<\/li>\n<li>\n<p><em>NormalProcessing &#8212; <\/em>\u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043d\u0438\u0445 \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0441\u0432\u043e\u0438 \u043c\u0430\u043a\u0440\u043e\u0441\u044b:<\/p>\n<pre><code class=\"cpp\">extern ProcessingMode Mode;  #define IsBootstrapProcessingMode() (Mode == BootstrapProcessing) #define IsInitProcessingMode()(Mode == InitProcessing) #define IsNormalProcessingMode()(Mode == NormalProcessing)  #define GetProcessingMode() Mode  #define SetProcessingMode(mode) \\ do { \\ AssertArg((mode) == BootstrapProcessing || \\   (mode) == InitProcessing || \\   (mode) == NormalProcessing); \\ Mode = (mode); \\ } while(0)<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0438 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/miscadmin.h\" rel=\"noopener noreferrer nofollow\">src\/include\/miscadmin.h<\/a><\/p>\n<\/div>\n<\/details>\n<h2>\u0421\u0438\u0433\u043d\u0430\u043b\u044b<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0441\u0432\u043e\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>SIGHUP &#8212; \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>SIGINT &#8212; \u043e\u0442\u043c\u0435\u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (Fast shutdown);<\/p>\n<\/li>\n<li>\n<p>SIGTERM &#8212; \u043e\u0442\u043c\u0435\u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u0432\u044b\u0445\u043e\u0434 (Smart shutdown);<\/p>\n<\/li>\n<li>\n<p>SIGQUIT &#8212; \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0432\u044b\u0445\u043e\u0434 (Immediate shutdown);<\/p>\n<\/li>\n<li>\n<p>SIGPIPE &#8212; \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0442.\u043a. \u044d\u0442\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0435\u0439 \u0447\u0435\u043c \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0442\u044c \u2018who-knows-what operation\u2019, \u0430 \u0437\u0430\u043c\u0435\u0442\u0438\u043c \u043c\u044b \u044d\u0442\u043e \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0446\u0438\u043a\u043b\u0430;<\/p>\n<\/li>\n<li>\n<p>SIGUSR1 &#8212; \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0411\u0414;<\/p>\n<\/li>\n<li>\n<p>SIGUSR2 &#8212; \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f;<\/p>\n<\/li>\n<li>\n<p>SIGFPE &#8212; \u043e\u0448\u0438\u0431\u043a\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430 1 \u0441\u0438\u0433\u043d\u0430\u043b<\/summary>\n<div class=\"spoiler__content\">\n<p><em>SIGUSR1 <\/em>&#8212; \u0441\u0438\u0433\u043d\u0430\u043b \u0441\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u041d\u043e \u043a\u0430\u043a \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435?<\/p>\n<p>\u0412 Postgres \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u0449\u0430\u044f \u043f\u0430\u043c\u044f\u0442\u044c.<\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <em>ProcSignalSlot <\/em>\u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432<\/p>\n<pre><code class=\"cpp\">typedef struct { volatile pid_t pss_pid; volatile sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS]; pg_atomic_uint64 pss_barrierGeneration; pg_atomic_uint32 pss_barrierCheckMask; ConditionVariable pss_barrierCV; } ProcSignalSlot;<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0435 <em>pss_signalFlags<\/em> &#8212; \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0443\u043b\u0435\u0432\u0441\u043a\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u0434\u043b\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432.<\/p>\n<p>\u0421\u0430\u043c\u0438 \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435\u043c <em>ProcSignalReason<\/em><\/p>\n<pre><code class=\"cpp\">typedef enum { PROCSIG_CATCHUP_INTERRUPT,\/* sinval catchup interrupt *\/ PROCSIG_NOTIFY_INTERRUPT,\/* listen\/notify interrupt *\/ PROCSIG_PARALLEL_MESSAGE,\/* message from cooperating parallel backend *\/ PROCSIG_WALSND_INIT_STOPPING,\/* ask walsenders to prepare for shutdown  *\/ PROCSIG_BARRIER,\/* global barrier interrupt  *\/ PROCSIG_LOG_MEMORY_CONTEXT, \/* ask backend to log the memory contexts *\/  \/* Recovery conflict reasons *\/ PROCSIG_RECOVERY_CONFLICT_DATABASE, PROCSIG_RECOVERY_CONFLICT_TABLESPACE, PROCSIG_RECOVERY_CONFLICT_LOCK, PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,  NUM_PROCSIGNALS\/* Must be last! *\/ } ProcSignalReason;<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 <em>SIGUSR1 <\/em>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c<\/p>\n<pre><code class=\"cpp\">\/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a SIGUSR1 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 void procsignal_sigusr1_handler(SIGNAL_ARGS) { intsave_errno = errno;  if (CheckProcSignal(PROCSIG_CATCHUP_INTERRUPT)) HandleCatchupInterrupt();  if (CheckProcSignal(PROCSIG_NOTIFY_INTERRUPT)) HandleNotifyInterrupt();  if (CheckProcSignal(PROCSIG_PARALLEL_MESSAGE)) HandleParallelMessageInterrupt();  if (CheckProcSignal(PROCSIG_WALSND_INIT_STOPPING)) HandleWalSndInitStopping();  if (CheckProcSignal(PROCSIG_BARRIER)) HandleProcSignalBarrierInterrupt();  if (CheckProcSignal(PROCSIG_LOG_MEMORY_CONTEXT)) HandleLogMemoryContextInterrupt();  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_DATABASE)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_DATABASE);  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_TABLESPACE)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_TABLESPACE);  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_LOCK)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_LOCK);  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_SNAPSHOT)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_SNAPSHOT);  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK);  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);  SetLatch(MyLatch);  errno = save_errno; }  \/\/ \u0412 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u0441\u0435 SigProcReason \/\/ \u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f static bool CheckProcSignal(ProcSignalReason reason) { volatile ProcSignalSlot *slot = MyProcSignalSlot;  if (slot != NULL) { \/* Careful here --- don't clear flag if we haven't seen it set *\/ if (slot->pss_signalFlags[reason]) { slot->pss_signalFlags[reason] = false; return true; } }  return false; }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/storage\/ipc\/procsignal.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/storage\/ipc\/procsignal.c<\/a><\/p>\n<\/div>\n<\/details>\n<p>Postgres \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <em>SIGALRM<\/em>. \u0417\u0430 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043c\u043e\u0434\u0443\u043b\u044c <strong>timeout<\/strong> <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/misc\/timeout.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/misc\/timeout.c<\/a> <\/p>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c (\u0440\u0435)\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f: \u0432\u0441\u0435 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0438 \u0437\u0430\u043d\u043e\u0432\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u0430.<\/p>\n<h2>BaseInit<\/h2>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <em>BaseInit <\/em>(<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/init\/postinit.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/init\/postinit.c<\/a>) \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b. \u0415\u0435 \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 &#8212; \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u0449\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439:<\/p>\n<ul>\n<li>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041c\u043e\u0434\u0443\u043b\u044c fd<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0438\u043c\u0435\u043d\u0443\u0435\u0442\u0441\u044f <strong>fd<\/strong><\/p>\n<p>\u0422\u0438\u043f\u044b \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/storage\/fd.h\" rel=\"noopener noreferrer nofollow\">src\/include\/storage\/fd.h<\/a><\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0432\u043c\u0435\u0441\u0442\u043e &#171;\u0441\u044b\u0440\u044b\u0445&#187; \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0439 \u0442\u0438\u043f <em>File<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0438 \u0435\u0441\u0442\u044c <em>int<\/em><\/p>\n<pre><code class=\"cpp\">typedef int File;<\/code><\/pre>\n<p> \u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f\/\u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0444\u0430\u043b\u043e\u0432 <\/p>\n<pre><code class=\"cpp\">File PathNameOpenFile(const char *fileName, int fileFlags); File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode); File OpenTemporaryFile(bool interXact);<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u0430 &#8212; \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432. \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u044b \u0442\u0430\u0431\u043b\u0438\u0446, \u043d\u043e \u0438 \u0434\u043b\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/storage\/file\/fd.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/storage\/file\/fd.c<\/a><\/p>\n<p>\u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f LRU \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <em>vfd<\/em><\/p>\n<pre><code class=\"cpp\">typedef struct vfd { intfd;\/* current FD, or VFD_CLOSED if none *\/ unsigned short fdstate;\/* bitflags for VFD's state *\/ ResourceOwner resowner;\/* owner, for automatic cleanup *\/ FilenextFree;\/* link to next free VFD, if in freelist *\/ FilelruMoreRecently;\/* doubly linked recency-of-use list *\/ FilelruLessRecently; off_tfileSize;\/* current size of file (0 if not temporary) *\/ char   *fileName;\/* name of file, or NULL for unused VFD *\/ \/* NB: fileName is malloc'd, and must be free'd when closing the VFD *\/ intfileFlags;\/* open(2) flags for (re)opening the file *\/ mode_tfileMode;\/* mode to pass to open(2) *\/ } Vfd;  \/*  * Virtual File Descriptor array pointer and size.  This grows as  * needed.  'File' values are indexes into this array.  * Note that VfdCache[0] is not a usable VFD, just a list header.  *\/ static Vfd *VfdCache; static Size SizeVfdCache = 0;<\/code><\/pre>\n<p>\u0421\u0430\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0434\u0432\u0443\u0441\u0432\u044f\u0437\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a. \u041f\u0440\u0438\u0447\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441 0 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c &#8212; \u043e\u0441\u043e\u0431\u044b\u0439: \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u043e\/\u043a\u043e\u043d\u0435\u0446 \u0441\u043f\u0438\u0441\u043a\u0430 \u0438 \u0435\u0433\u043e \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0440\u0430\u0432\u0435\u043d <em>VFD_CLOSED<\/em>.<\/p>\n<p>\u041f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>InitFileAccess<\/em><\/p>\n<pre><code class=\"cpp\">\/*  * InitFileAccess --- initialize this module during backend startup  *  * This is called during either normal or standalone backend start.  * It is *not* called in the postmaster.  *\/ void InitFileAccess(void) { Assert(SizeVfdCache == 0);\/* call me only once *\/  \/* initialize cache header entry *\/ VfdCache = (Vfd *) malloc(sizeof(Vfd)); if (VfdCache == NULL) ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY),  errmsg(\"out of memory\")));  MemSet((char *) &amp;(VfdCache[0]), 0, sizeof(Vfd)); VfdCache->fd = VFD_CLOSED;  SizeVfdCache = 1;  \/* register proc-exit hook to ensure temp files are dropped at exit *\/ on_proc_exit(AtProcExit_Files, 0); }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0435\u0433\u043e \u0432 LRU<\/p>\n<pre><code class=\"cpp\">File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode) { char   *fnamecopy; Filefile; Vfd   *vfdP;    \/*  * We need a malloc'd copy of the file name; fail cleanly if no room.  *\/ fnamecopy = strdup(fileName); if (fnamecopy == NULL) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),  errmsg(\"out of memory\")));  file = AllocateVfd(); vfdP = &amp;VfdCache[file];  \/* Close excess kernel FDs. *\/ ReleaseLruFiles();  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);  if (vfdP->fd &lt; 0) { intsave_errno = errno;  FreeVfd(file); free(fnamecopy); errno = save_errno; return -1; } ++nfile;  vfdP->fileName = fnamecopy; \/* Saved flags are adjusted to be OK for re-opening file *\/ vfdP->fileFlags = fileFlags &amp; ~(O_CREAT | O_TRUNC | O_EXCL); vfdP->fileMode = fileMode; vfdP->fileSize = 0; vfdP->fdstate = 0x0; vfdP->resowner = NULL;  Insert(file);  return file; } <\/code><\/pre>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u0442\u043e \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u043e\u0431 \u044d\u0442\u043e\u043c<\/p>\n<pre><code class=\"cpp\">\/* If you've really really gotta have a plain kernel FD, use this *\/ intBasicOpenFile(const char *fileName, int fileFlags); intBasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode);  \/* Use these for other cases, and also for long-lived BasicOpenFile FDs *\/ extern bool AcquireExternalFD(void); extern void ReserveExternalFD(void); extern void ReleaseExternalFD(void);<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p>\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432\u00a0<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041c\u043e\u0434\u0443\u043b\u044c sync<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043e\u0431\u0449\u0438\u0435 \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432. \u0415\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u0444\u0430\u0439\u043b, \u0442\u043e \u043d\u0430\u0434\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0445. \u042d\u0442\u0438\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043c\u043e\u0434\u0443\u043b\u044c <strong>sync<\/strong> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/storage\/sync\/sync.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/storage\/sync\/sync.c<\/a>)<\/p>\n<p>\u041e\u043f\u043e\u043f\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ol>\n<li>\n<p>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0444\u0430\u0439\u043b\u0430\u0445<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"cpp\">bool RegisterSyncRequest(const FileTag *ftag,                           SyncRequestType type,                          bool retryOnError);<\/code><\/pre>\n<p>\u0412 \u043d\u0435\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <em>FileTag<\/em> \u0438 <em>SyncRequestType<\/em><\/p>\n<pre><code class=\"cpp\">\/\/ \u0422\u0438\u043f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 typedef enum SyncRequestType { SYNC_REQUEST,\/* schedule a call of sync function *\/ SYNC_UNLINK_REQUEST,\/* schedule a call of unlink function *\/ SYNC_FORGET_REQUEST,\/* forget all calls for a tag *\/ SYNC_FILTER_REQUEST\/* forget all calls satisfying match fn *\/ } SyncRequestType;  \/\/ \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u0438 \u043c\u0435\u0441\u0442\u0430 \u0434\u043b\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 typedef struct FileTag { int16handler;\/* SyncRequestHandler value, saving space *\/ int16forknum;\/* ForkNumber, saving space *\/ RelFileNode rnode; uint32segno; } FileTag;  \/\/ src\/include\/storage\/relfilenode.h typedef struct RelFileNode { OidspcNode;\/* tablespace *\/ OiddbNode;\/* database *\/ OidrelNode;\/* relation *\/ } RelFileNode;<\/code><\/pre>\n<p>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f Checkpointer \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430<\/p>\n<ol start=\"2\">\n<li>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0447\u0435\u043a\u043f\u043e\u0438\u043d\u0442\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"cpp\">void ProcessSyncRequests(void);<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041c\u043e\u0434\u0443\u043b\u044c smgr<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041c\u043e\u0434\u0443\u043b\u044c <strong>smgr<\/strong> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/storage\/smgr\/smgr.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/storage\/smgr\/smgr.c<\/a>) \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439.<\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0432\u0435\u0434\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <em>SMgrRelationData <\/em>(<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/storage\/smgr.h\" rel=\"noopener noreferrer nofollow\">src\/include\/storage\/smgr.h<\/a>)<\/p>\n<pre><code class=\"cpp\">typedef struct SMgrRelationData { \/* rnode is the hashtable lookup key, so it must be first! *\/ RelFileNodeBackend smgr_rnode;\/* relation physical identifier *\/  \/* pointer to owning pointer, or NULL if none *\/ struct SMgrRelationData **smgr_owner;  \/*  * The following fields are reset to InvalidBlockNumber upon a cache flush  * event, and hold the last known size for each fork.  This information is  * currently only reliable during recovery, since there is no cache  * invalidation for fork extension.  *\/ BlockNumber smgr_targblock; \/* current insertion target block *\/ BlockNumber smgr_cached_nblocks[MAX_FORKNUM + 1];\/* last known size *\/  \/* additional public fields may someday exist here *\/  \/*  * Fields below here are intended to be private to smgr.c and its  * submodules.  Do not touch them from elsewhere.  *\/ intsmgr_which;\/* storage manager selector *\/  \/*  * for md.c; per-fork arrays of the number of open segments  * (md_num_open_segs) and the segments themselves (md_seg_fds).  *\/ intmd_num_open_segs[MAX_FORKNUM + 1]; struct _MdfdVec *md_seg_fds[MAX_FORKNUM + 1];  \/* if unowned, list link in list of all unowned SMgrRelations *\/ dlist_nodenode; } SMgrRelationData;  typedef SMgrRelationData *SMgrRelation; <\/code><\/pre>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0445 \u044d\u0442\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>smgrread<\/em> <\/p>\n<pre><code class=\"cpp\">\/*  *smgrread() -- read a particular block from a relation into the supplied  *  buffer.  *  *This routine is called from the buffer manager in order to  *instantiate pages in the shared buffer cache.  All storage managers  *return pages in the format that POSTGRES expects.  *\/ void smgrread(SMgrRelation reln,           ForkNumber forknum,           BlockNumber blocknum,  char *buffer);<\/code><\/pre>\n<p>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439 &#171;\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440&#187;. \u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <em>f_smgr<\/em>, \u044f\u0432\u043b\u044f\u044e\u0449\u0438\u0439\u0441\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<pre><code class=\"cpp\">typedef struct f_smgr { void(*smgr_init) (void);\/* may be NULL *\/ void(*smgr_shutdown) (void);\/* may be NULL *\/ void(*smgr_open) (SMgrRelation reln); void(*smgr_close) (SMgrRelation reln, ForkNumber forknum); void(*smgr_create) (SMgrRelation reln, ForkNumber forknum, bool isRedo); bool(*smgr_exists) (SMgrRelation reln, ForkNumber forknum); void(*smgr_unlink) (RelFileNodeBackend rnode, ForkNumber forknum, bool isRedo); void(*smgr_extend) (SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync); bool(*smgr_prefetch) (SMgrRelation reln, ForkNumber forknum,   BlockNumber blocknum); void(*smgr_read) (SMgrRelation reln, ForkNumber forknum,   BlockNumber blocknum, char *buffer); void(*smgr_write) (SMgrRelation reln, ForkNumber forknum,    BlockNumber blocknum, char *buffer, bool skipFsync); void(*smgr_writeback) (SMgrRelation reln, ForkNumber forknum,    BlockNumber blocknum, BlockNumber nblocks); BlockNumber (*smgr_nblocks) (SMgrRelation reln, ForkNumber forknum); void(*smgr_truncate) (SMgrRelation reln, ForkNumber forknum,   BlockNumber nblocks); void(*smgr_immedsync) (SMgrRelation reln, ForkNumber forknum); } f_smgr; <\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 <em>smgrsw<\/em><\/p>\n<pre><code class=\"cpp\">static const f_smgr smgrsw[] = { \/* magnetic disk *\/     \/\/ \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e     \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u043e\u0434\u0443\u043b\u044c fd     \/\/ src\/backend\/storage\/smgr\/md.c { .smgr_init = mdinit, .smgr_shutdown = NULL, .smgr_open = mdopen, .smgr_close = mdclose, .smgr_create = mdcreate, .smgr_exists = mdexists, .smgr_unlink = mdunlink, .smgr_extend = mdextend, .smgr_prefetch = mdprefetch, .smgr_read = mdread, .smgr_write = mdwrite, .smgr_writeback = mdwriteback, .smgr_nblocks = mdnblocks, .smgr_truncate = mdtruncate, .smgr_immedsync = mdimmedsync, } };<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u044f\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ol>\n<li>\n<p>\u041f\u043e ID \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0435\u0433\u043e \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<\/ol>\n<p>\u0427\u0442\u0435\u043d\u0438\u0435 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c<\/p>\n<pre><code class=\"cpp\">void smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,  char *buffer) { smgrsw[reln->smgr_which].smgr_read(reln, forknum, blocknum, buffer); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p>\u041e\u0431\u0449\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b <\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041c\u043e\u0434\u0443\u043b\u044c bufmgr<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u0441 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043e\u0440\u043e\u0433\u0438\u043c \u0437\u0430\u043d\u044f\u0442\u0438\u0435\u043c. \u0414\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f &#8212; \u043c\u043e\u0434\u0443\u043b\u044c <strong>bufmgr<\/strong> \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438, \u0441\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0437 \u0444\u0430\u0439\u043b\u043e\u0432, \u0438 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a.<\/p>\n<p>\u0422\u0438\u043f \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/storage\/buf.h\" rel=\"noopener noreferrer nofollow\">src\/include\/storage\/buf.h<\/a><\/p>\n<pre><code class=\"cpp\">\/*  * Buffer identifiers.  *  * Zero is invalid, positive is the index of a shared buffer (1..NBuffers),  * negative is the index of a local buffer (-1 .. -NLocBuffer).  *\/ typedef int Buffer;  #define InvalidBuffer0<\/code><\/pre>\n<p>\u0421\u0430\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441 \u0431\u0443\u0444\u0435\u0440\u043e\u043c \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/storage\/bufmgr.h\" rel=\"noopener noreferrer nofollow\">src\/include\/storage\/bufmgr.h<\/a>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/p>\n<pre><code class=\"cpp\">Buffer ReadBuffer(Relation reln, BlockNumber blockNum); Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum,                           BlockNumber blockNum, ReadBufferMode mode,                           BufferAccessStrategy strategy); Buffer ReadBufferWithoutRelcache(RelFileNode rnode,                                  ForkNumber forkNum, BlockNumber blockNum,                                  ReadBufferMode mode, BufferAccessStrategy strategy);<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/storage\/buffer\/bufmgr.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/storage\/buffer\/bufmgr.c<\/a><\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043e\u0434\u043d\u0430 \u0438 \u0442\u0430 \u0436\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u0445, \u0442\u043e \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <em>PrivateRefCountEntry<\/em><\/p>\n<pre><code class=\"cpp\">typedef struct PrivateRefCountEntry { Bufferbuffer; int32refcount; } PrivateRefCountEntry;<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432 <em>PrivateRefCountArray<\/em><\/p>\n<pre><code class=\"cpp\">\/* 64 bytes, about the size of a cache line on common systems *\/ #define REFCOUNT_ARRAY_ENTRIES 8  static struct PrivateRefCountEntry    PrivateRefCountArray[REFCOUNT_ARRAY_ENTRIES];<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>InitProcess<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>InitProcess<\/em>. (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/storage\/lmgr\/proc.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/storage\/lmgr\/proc.c<\/a>)<\/p>\n<p>\u041e\u043d\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0435 \u0434\u043b\u044f \u0442\u0438\u043f\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 (AutoVacuum, BgWorker, WalSender \u0438 \u0442.\u0434.) \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<p>\u0414\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <em>PROC_HDR<\/em><\/p>\n<pre><code class=\"cpp\">typedef struct PROC_HDR {     \/\/ ...    \/* Length of allProcs array *\/ uint32allProcCount; \/* Head of list of free PGPROC structures *\/ PGPROC   *freeProcs; \/* Head of list of autovacuum's free PGPROC structures *\/ PGPROC   *autovacFreeProcs; \/* Head of list of bgworker free PGPROC structures *\/ PGPROC   *bgworkerFreeProcs; \/* Head of list of walsender free PGPROC structures *\/ PGPROC   *walsenderFreeProcs;      \/\/ ... } PROC_HDR;<\/code><\/pre>\n<p>\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043f\u0438\u0441\u043a\u0438 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u043b\u044f\u00a0\u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430<em>. <\/em>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <em>PGPROC<\/em>\u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430.<\/p>\n<p>\u041f\u0440\u0438\u00a0\u0441\u0442\u0430\u0440\u0442\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u0432\u043e\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438\u0437\u00a0\u0441\u043f\u0438\u0441\u043a\u0430 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445 \u0438 \u0438\u043d\u0438\u0446\u0438\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e\u00a0\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e (\u0434\u043b\u044f ID\u00a0\u2014 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0435, \u0434\u043b\u044f\u00a0bool\u00a0\u2014 false \u0438\u00a0\u0442.\u00a0\u0434.)<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a\u00a0\u043c\u044b \u0431\u044d\u043a\u044d\u043d\u0434, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0432\u043e\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438\u0437\u00a0\u0441\u043f\u0438\u0441\u043a\u0430 <code>freeProcs<\/code>. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b\u00a0\u2014 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u0430\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438.<\/p>\n<pre><code class=\"cpp\">SpinLockAcquire(ProcStructLock);  MyProc = *procgloballist;  if (MyProc != NULL) {     *procgloballist = (PGPROC *) MyProc->links.next;     SpinLockRelease(ProcStructLock); } else {     \/*      * If we reach here, all the PGPROCs are in use.  This is one of the      * possible places to detect \"too many backends\", so give the standard      * error message.  XXX do we need to give a different failure message      * in the autovacuum case?      *\/     SpinLockRelease(ProcStructLock);     \/\/ ... }<\/code><\/pre>\n<h2>InitPostgres<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043e\u0431\u0449\u0435\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>InitPostgres<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/init\/postinit.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/init\/postinit.c<\/a>) <\/p>\n<h4>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 Id<\/h4>\n<p>\u041d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0448\u0430\u0433\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u044d\u043a\u044d\u043d\u0434\u0430. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0435\u043c\u0443 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 ID. \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0431\u044d\u043a\u044d\u043d\u0434\u043e\u0432 \u0440\u0430\u0441\u0442\u0443\u0442 \u043b\u0438\u043d\u0435\u0439\u043d\u043e \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 <code>shmInvalBuffer<\/code><\/p>\n<pre><code class=\"cpp\">ProcState  *stateP = NULL; SISeg   *segP = shmInvalBuffer;  \/\/ ...  \/* Look for a free entry in the procState array *\/ for (int index = 0; index &lt; segP->lastBackend; index++) {     if (segP->procState[index].procPid == 0)\/* inactive slot? *\/     {         stateP = &amp;segP->procState[index];         break;     } }  \/\/ ...  MyBackendId = (stateP - &amp;segP->procState[0]) + 1;<\/code><\/pre>\n<p>\u0421\u0430\u043c \u044d\u0442\u043e\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0431\u044d\u043a\u044d\u043d\u0434\u044b \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u0434\u043b\u044f\u00a0\u0438\u043d\u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043e\u0431\u0449\u0435\u0433\u043e \u043a\u0435\u0448\u0430<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0441\u0435 \u0431\u044d\u043a\u044d\u043d\u0434\u044b \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432\u00a0\u0441\u043f\u0438\u0441\u043a\u0435 \u0434\u043b\u044f\u00a0\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043f\u0440\u0438\u00a0\u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h4>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432<\/h4>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p><em>DEADLOCK_TIMEOUT<\/em>\u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043f\u0440\u0438\u00a0\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438, \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0434\u0435\u0434\u043b\u043e\u043a;<\/p>\n<\/li>\n<li>\n<p><em>STATEMENT_TIMEOUT<\/em>\u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430\u00a0\u043a\u0430\u0436\u0434\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p><em>LOCK_TIMEOUT<\/em>\u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u00a0\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 (\u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u043b\u0438\u00a0\u043b\u044e\u0431\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0411\u0414);<\/p>\n<\/li>\n<li>\n<p><em>IDLE_SESSION_TIMEOUT<\/em>\u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u0435\u0430\u043d\u0441\u0430;<\/p>\n<\/li>\n<li>\n<p><em>IDLE_IN_TRANSACTION_SESSION_TIMEOUT<\/em>\u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u0435\u0430\u043d\u0441\u0430 \u0434\u043b\u044f\u00a0\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p><em>CLIENT_CONNECTION_TIMEOUT<\/em>\u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u0439\u043c\u0430\u0443\u0442\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <em>TimeoutId<\/em><\/p>\n<pre><code class=\"cpp\">\/*  * Identifiers for timeout reasons.  Note that in case multiple timeouts  * trigger at the same time, they are serviced in the order of this enum.  *\/ typedef enum TimeoutId { \/* Predefined timeout reasons *\/ STARTUP_PACKET_TIMEOUT, DEADLOCK_TIMEOUT, LOCK_TIMEOUT, STATEMENT_TIMEOUT, STANDBY_DEADLOCK_TIMEOUT, STANDBY_TIMEOUT, STANDBY_LOCK_TIMEOUT, IDLE_IN_TRANSACTION_SESSION_TIMEOUT, IDLE_SESSION_TIMEOUT, CLIENT_CONNECTION_CHECK_TIMEOUT, \/* First user-definable timeout reason *\/ USER_TIMEOUT, \/* Maximum number of timeout reasons *\/ MAX_TIMEOUTS = USER_TIMEOUT + 10 } TimeoutId;<\/code><\/pre>\n<p>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <em>RegisterTimeout<\/em> \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f <strong>timeout<\/strong><\/p>\n<pre><code class=\"cpp\">\/* callback function signature *\/ typedef void (*timeout_handler_proc) (void);  TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler);<\/code><\/pre>\n<h4>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u0435\u0448\u0430<\/h4>\n<p>\u0414\u043b\u044f\u00a0\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 Postgres \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u0435\u0448. \u0412\u0441\u0435\u0433\u043e \u0435\u0441\u0442\u044c 3\u00a0\u0442\u0438\u043f\u0430 \u043a\u0435\u0448\u0435\u0439:<\/p>\n<ul>\n<li>\n<p><em>\u041a\u0435\u0448 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0439 (RelationCache) <\/em>\u2014 \u043a\u0435\u0448 \u0434\u043b\u044f\u00a0\u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a\u00a0\u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0445\u0435\u0448\u2011\u0442\u0430\u0431\u043b\u0438\u0446\u0443.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 Postgres \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0432\u043e\u0439 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0434\u0430\u043d\u043d\u044b\u043c \u043f\u043e \u043a\u043b\u044e\u0447\u0443 &#8212; \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430. <\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/hash\/dynahash.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/hash\/dynahash.c<\/a> <\/p>\n<pre><code class=\"cpp\">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) *\/ boolisshared;\/* true if table is in shared memory *\/ boolisfixed;\/* if true, don't enlarge *\/  \/* freezing a shared table isn't allowed, so we can keep state here *\/ boolfrozen;\/* true = no more inserts allowed *\/  \/* We keep local copies of these fixed values to reduce contention *\/ Sizekeysize;\/* hash key length in bytes *\/ longssize;\/* segment size --- must be power of 2 *\/ intsshift;\/* segment shift = log2(ssize) *\/ };<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/utils\/hsearch.h\" rel=\"noopener noreferrer nofollow\">src\/include\/utils\/hsearch.h<\/a>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<pre><code class=\"cpp\">HTAB *hash_create(const char *tabname, long nelem,                   const HASHCTL *info, int flags);<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u0434\u0440\u0443\u0433\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f &#8212; simplehash<\/p>\n<p>\u041e\u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/lib\/simplehash.h\" rel=\"noopener noreferrer nofollow\">src\/include\/lib\/simplehash.h<\/a><\/p>\n<p>\u042d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445. \u042d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u0443\u044e \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438 \u0432\u0441\u0435 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b<\/p>\n<pre><code class=\"cpp\">#define SH_MAKE_PREFIX(a) CppConcat(a,_) #define SH_MAKE_NAME(name) SH_MAKE_NAME_(SH_MAKE_PREFIX(SH_PREFIX),name) #define SH_MAKE_NAME_(a,b) CppConcat(a,b)  #define SH_CREATE SH_MAKE_NAME(create)  #define SH_SCOPE extern  typedef struct SH_TYPE { \/*  * Size of data \/ bucket array, 64 bits to handle UINT32_MAX sized hash  * tables.  Note that the maximum number of elements is lower  * (SH_MAX_FILLFACTOR)  *\/ uint64size;  \/* how many elements have valid contents *\/ uint32members;  \/* mask for bucket and size calculations, based on size *\/ uint32sizemask;  \/* boundary after which to grow hashtable *\/ uint32grow_threshold;  \/* hash buckets *\/ SH_ELEMENT_TYPE *data;  #ifndef SH_RAW_ALLOCATOR \/* memory context to use for allocations *\/ MemoryContext ctx; #endif  \/* user defined data, useful for callbacks *\/ void   *private_data; }SH_TYPE;  #ifdef SH_RAW_ALLOCATOR \/* &lt;prefix>_hash &lt;prefix>_create(uint32 nelements, void *private_data) *\/ SH_SCOPESH_TYPE *SH_CREATE(uint32 nelements, void *private_data); #else \/*  * &lt;prefix>_hash &lt;prefix>_create(MemoryContext ctx, uint32 nelements,  * void *private_data)  *\/ SH_SCOPESH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements,    void *private_data); #endif<\/code><\/pre>\n<p>* \u0412 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f dynahash<\/p>\n<\/p>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p><em>\u0421\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u043a\u0435\u0448 (CatalogCache) <\/em>\u2014 \u043a\u0435\u0448 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u0412\u00a0\u043d\u0435\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u00a0\u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u0445: \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u044b, \u043a\u043b\u0430\u0441\u0441\u044b \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432, \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435<\/p>\n<\/li>\n<li>\n<p><em>\u041a\u0435\u0448 \u043f\u043b\u0430\u043d\u043e\u0432 (PlanCache) <\/em>\u2014 \u043a\u0435\u0448 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0442\u043e\u0438\u0442 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c, \u0447\u0442\u043e\u00a0\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u0435\u0448\u0430 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0439 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 3\u00a0\u044d\u0442\u0430\u043f\u0430:<\/p>\n<ol>\n<li>\n<p>\u0410\u043b\u043b\u043e\u043a\u0430\u0446\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 (\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043a\u0435\u0448\u0430, \u0445\u0435\u0448\u2011\u0442\u0430\u0431\u043b\u0438\u0446\u044b)<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u0435\u0448\u0430 \u043f\u043e\u0434\u00a0\u0432\u0430\u0436\u043d\u044b\u0435 \u043e\u0431\u0449\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b (pg_database, pg_authid, pg_auth_members, pg_shseclabel, pg_subscription<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446 \u0432\u00a0\u043a\u0435\u0448.<\/p>\n<\/li>\n<\/ol>\n<p>\u0424\u0430\u0437\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0435\u0448\u0430 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0439 \u00ab\u0440\u0430\u0437\u0431\u0440\u043e\u0441\u0430\u043d\u044b\u00bb \u043f\u043e\u00a0\u0432\u0441\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <em>InitPostres<\/em>, \u0442.\u043a. \u0434\u043b\u044f\u00a0\u043a\u0430\u0436\u0434\u043e\u0439 \u0444\u0430\u0437\u044b \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f\u00a0\u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, 2\u00a0\u0444\u0430\u0437\u0430 \u043f\u0440\u043e\u0433\u0440\u0435\u0432\u0430\u0435\u0442 \u043a\u0435\u0448 \u0434\u043b\u044f\u00a0\u0430\u0443\u0442\u0435\u043d\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u0430 3\u00a0\u0444\u0430\u0437\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0435 \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u00a0\u043a\u0435\u0448.<\/p>\n<h4>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u0440\u0442\u0430\u043b\u043e\u0432<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043f\u043e\u0440\u0442\u0430\u043b\u043e\u0432<\/p>\n<ul>\n<li>\n<p>\u0412\u044b\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u0430\u043c\u044f\u0442\u0438 &#8212; <em>TopPortalContext<\/em>;<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u043f\u043e \u0435\u0433\u043e \u0438\u043c\u0435\u043d\u0438. \u0425\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u0440\u0442\u0430\u043b<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u0440\u0442\u0430\u043b &#8212; \u043e\u0431\u044a\u0435\u043a\u0442, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0439\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441. \u042d\u0442\u043e\u0442 \u0442\u0438\u043f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/postgrespro.ru\/docs\/postgresql\/13\/protocol-overview#PROTOCOL-QUERY-CONCEPTS\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u043c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0435<\/a>, \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438, \u043f\u043e\u0441\u043b\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430. <\/p>\n<p>\u041f\u043e\u0440\u0442\u0430\u043b\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 (\u0438\u043c\u044f \u043a\u0443\u0440\u0441\u043e\u0440\u0430) \u0438\u043b\u0438 \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u043c\u0438 (\u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u0439 SELECT).\u00a0<\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u0440\u0442\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/utils\/portal.h\" rel=\"noopener noreferrer nofollow\">src\/include\/utils\/portal.h<\/a><\/p>\n<pre><code class=\"cpp\">typedef struct PortalData *Portal;  typedef struct PortalData { \/* Bookkeeping data *\/ const char *name;\/* portal's name *\/ const char *prepStmtName;\/* source prepared statement (NULL if none) *\/ MemoryContext portalContext;\/* subsidiary memory for portal *\/ ResourceOwner resowner;\/* resources owned by portal *\/ void(*cleanup) (Portal portal); \/* cleanup hook *\/  \/*  * State data for remembering which subtransaction(s) the portal was  * created or used in.  If the portal is held over from a previous  * transaction, both subxids are InvalidSubTransactionId.  Otherwise,  * createSubid is the creating subxact and activeSubid is the last subxact  * in which we ran the portal.  *\/ SubTransactionId createSubid;\/* the creating subxact *\/ SubTransactionId activeSubid;\/* the last subxact with activity *\/  \/* The query or queries the portal will execute *\/ const char *sourceText;\/* text of query (as of 8.4, never NULL) *\/ CommandTagcommandTag;\/* command tag for original query *\/ QueryCompletion qc;\/* command completion data for executed query *\/ List   *stmts;\/* list of PlannedStmts *\/ CachedPlan *cplan;\/* CachedPlan, if stmts are from one *\/  ParamListInfo portalParams; \/* params to pass to query *\/ QueryEnvironment *queryEnv; \/* environment for query *\/  \/* Features\/options *\/ PortalStrategy strategy;\/* see above *\/ intcursorOptions;\/* DECLARE CURSOR option bits *\/ boolrun_once;\/* portal will only be run once *\/  \/* Status data *\/ PortalStatus status;\/* see above *\/ boolportalPinned;\/* a pinned portal can't be dropped *\/ boolautoHeld;\/* was automatically converted from pinned to  * held (see HoldPinnedPortals()) *\/  \/* If not NULL, Executor is active; call ExecutorEnd eventually: *\/ QueryDesc  *queryDesc;\/* info needed for executor invocation *\/  \/* If portal returns tuples, this is their tupdesc: *\/ TupleDesctupDesc;\/* descriptor for result tuples *\/ \/* and these are the format codes to use for the columns: *\/ int16   *formats;\/* a format code for each column *\/  \/*  * Outermost ActiveSnapshot for execution of the portal's queries.  For  * all but a few utility commands, we require such a snapshot to exist.  * This ensures that TOAST references in query results can be detoasted,  * and helps to reduce thrashing of the process's exposed xmin.  *\/ SnapshotportalSnapshot; \/* active snapshot, or NULL if none *\/  \/*  * Where we store tuples for a held cursor or a PORTAL_ONE_RETURNING or  * PORTAL_UTIL_SELECT query.  (A cursor held past the end of its  * transaction no longer has any active executor state.)  *\/ Tuplestorestate *holdStore; \/* store for holdable cursors *\/ MemoryContext holdContext;\/* memory containing holdStore *\/  \/*  * Snapshot under which tuples in the holdStore were read.  We must keep a  * reference to this snapshot if there is any possibility that the tuples  * contain TOAST references, because releasing the snapshot could allow  * recently-dead rows to be vacuumed away, along with any toast data  * belonging to them.  In the case of a held cursor, we avoid needing to  * keep such a snapshot by forcibly detoasting the data.  *\/ SnapshotholdSnapshot;\/* registered snapshot, or NULL if none *\/  \/*  * atStart, atEnd and portalPos indicate the current cursor position.  * portalPos is zero before the first row, N after fetching N'th row of  * query.  After we run off the end, portalPos = # of rows in query, and  * atEnd is true.  Note that atStart implies portalPos == 0, but not the  * reverse: we might have backed up only as far as the first row, not to  * the start.  Also note that various code inspects atStart and atEnd, but  * only the portal movement routines should touch portalPos.  *\/ boolatStart; boolatEnd; uint64portalPos;  \/* Presentation data, primarily used by the pg_cursors system view *\/ TimestampTz creation_time;\/* time at which this portal was defined *\/ boolvisible;\/* include this portal in pg_cursors? *\/  \/* Stuff added at the end to avoid ABI break in stable branches: *\/ intcreateLevel;\/* creating subxact's nesting level *\/ }PortalData;<\/code><\/pre>\n<p>\u041f\u043e\u0440\u0442\u0430\u043b\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c 2 \u0432\u0438\u0434\u043e\u0432: SQL (SELECT, CURSOR) \u0438 \u043f\u043e\u0440\u0442\u0430\u043b \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430 &#8212; \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0438:<\/p>\n<ul>\n<li>\n<p>SCROLL &#8212; \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432\u043f\u0435\u0440\u0435\u0434 \u0438 \u043d\u0430\u0437\u0430\u0434<\/p>\n<\/li>\n<li>\n<p>NO SCROLL &#8212; \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e &#171;\u0432\u043f\u0435\u0440\u0435\u0434&#187;<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f SQL \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u043e\u0431\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u0430 \u043f\u043e\u0440\u0442\u0430\u043b\u044b \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e NO SCROLL.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u0436\u0435 \u0444\u0430\u0439\u043b\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u043e\u0440\u0442\u0430\u043b\u0430\u043c\u0438. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u043d\u0438 \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/mmgr\/portalmem.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/mmgr\/portalmem.c<\/a><\/p>\n<\/div>\n<\/details>\n<h4>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438<\/h4>\n<p>\u0421\u0431\u043e\u0440\u0449\u0438\u043a \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0431\u044b\u043b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u0432 Postmaster. \u041d\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u043d\u0438\u043c \u043c\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u043c.\u00a0<\/p>\n<p>\u0414\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0431\u044d\u043a\u044d\u043d\u0434\u0430 \u0435\u0441\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <em>PgBackendStatus<\/em><\/p>\n<pre><code class=\"cpp\">\/* ----------  * PgBackendStatus  *  * Each live backend maintains a PgBackendStatus struct in shared memory  * showing its current activity.  (The structs are allocated according to  * BackendId, but that is not critical.)  Note that the collector process  * has no involvement in, or even access to, these structs.  *  * Each auxiliary process also maintains a PgBackendStatus struct in shared  * memory.  * ----------  *\/ typedef struct PgBackendStatus { \/*  * To avoid locking overhead, we use the following protocol: a backend  * increments st_changecount before modifying its entry, and again after  * finishing a modification.  A would-be reader should note the value of  * st_changecount, copy the entry into private memory, then check  * st_changecount again.  If the value hasn't changed, and if it's even,  * the copy is valid; otherwise start over.  This makes updates cheap  * while reads are potentially expensive, but that's the tradeoff we want.  *  * The above protocol needs memory barriers to ensure that the apparent  * order of execution is as it desires.  Otherwise, for example, the CPU  * might rearrange the code so that st_changecount is incremented twice  * before the modification on a machine with weak memory ordering.  Hence,  * use the macros defined below for manipulating st_changecount, rather  * than touching it directly.  *\/ intst_changecount;  \/* The entry is valid iff st_procpid > 0, unused if st_procpid == 0 *\/ intst_procpid;  \/* Type of backends *\/ BackendType st_backendType;  \/* Times when current backend, transaction, and activity started *\/ TimestampTz st_proc_start_timestamp; TimestampTz st_xact_start_timestamp; TimestampTz st_activity_start_timestamp; TimestampTz st_state_start_timestamp;  \/* Database OID, owning user's OID, connection client address *\/ Oidst_databaseid; Oidst_userid; SockAddrst_clientaddr; char   *st_clienthostname;\/* MUST be null-terminated *\/  \/* Information about SSL connection *\/ boolst_ssl; PgBackendSSLStatus *st_sslstatus;  \/* Information about GSSAPI connection *\/ boolst_gss; PgBackendGSSStatus *st_gssstatus;  \/* current state *\/ BackendState st_state;  \/* application name; MUST be null-terminated *\/ char   *st_appname;  \/*  * Current command string; MUST be null-terminated. Note that this string  * possibly is truncated in the middle of a multi-byte character. As  * activity strings are stored more frequently than read, that allows to  * move the cost of correct truncation to the display side. Use  * pgstat_clip_activity() to truncate correctly.  *\/ char   *st_activity_raw;  \/*  * Command progress reporting.  Any command which wishes can advertise  * that it is running by setting st_progress_command,  * st_progress_command_target, and st_progress_param[].  * st_progress_command_target should be the OID of the relation which the  * command targets (we assume there's just one, as this is meant for  * utility commands), but the meaning of each element in the  * st_progress_param array is command-specific.  *\/ ProgressCommandType st_progress_command; Oidst_progress_command_target; int64st_progress_param[PGSTAT_NUM_PROGRESS_PARAM];  \/* query identifier, optionally computed using post_parse_analyze_hook *\/ uint64st_query_id; } PgBackendStatus;<\/code><\/pre>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0432\u043e\u044e \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440, \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438. \u0422\u0430\u043a \u043a\u0430\u043a Id \u0431\u044d\u043a\u044d\u043d\u0434\u043e\u0432 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u044e\u0442 \u043b\u0438\u043d\u0435\u0439\u043d\u043e (\u043e\u0442 1 \u0434\u043e <em>MAX_BACKENDS<\/em>), \u0442\u043e \u043d\u0430\u0448\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438\u043c\u0435\u0435\u0442 \u0438\u043d\u0434\u0435\u043a\u0441 <code>MyBackendId - 1<\/code> \u0432 \u044d\u0442\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435.<\/p>\n<pre><code class=\"cpp\">MyBEEntry = &amp;BackendStatusArray[MyBackendId - 1];<\/code><\/pre>\n<h4>\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f<\/h4>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\u00a0\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>ClientAuthentication <\/em>(<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/libpq\/auth.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/libpq\/auth.c<\/a>)<\/p>\n<pre><code class=\"cpp\">\/*  * Client authentication starts here.  If there is an error, this  * function does not return and the backend process is terminated.  *\/ void ClientAuthentication(Port *port);<\/code><\/pre>\n<p>\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c) \u0438 \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 pg_hba.conf \u0432 \u043a\u043e\u0434\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 pg_hba.conf \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/libpq\/hba.h\" rel=\"noopener noreferrer nofollow\">src\/include\/libpq\/hba.h<\/a><\/p>\n<p>\u0424\u0430\u0439\u043b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0441\u0442\u0440\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <em>HbaLine<\/em><\/p>\n<pre><code class=\"cpp\">typedef struct HbaLine { intlinenumber; char   *rawline; ConnTypeconntype; List   *databases; List   *roles; struct sockaddr_storage addr; intaddrlen;\/* zero if we don't have a valid addr *\/ struct sockaddr_storage mask; intmasklen;\/* zero if we don't have a valid mask *\/ IPCompareMethod ip_cmp_method; char   *hostname; UserAuthauth_method; char   *usermap; char   *pamservice; boolpam_use_hostname; boolldaptls; char   *ldapscheme; char   *ldapserver; intldapport; char   *ldapbinddn; char   *ldapbindpasswd; char   *ldapsearchattribute; char   *ldapsearchfilter; char   *ldapbasedn; intldapscope; char   *ldapprefix; char   *ldapsuffix; ClientCertMode clientcert; ClientCertName clientcertname; char   *krb_realm; boolinclude_realm; boolcompat_realm; boolupn_username; List   *radiusservers; char   *radiusservers_s; List   *radiussecrets; char   *radiussecrets_s; List   *radiusidentifiers; char   *radiusidentifiers_s; List   *radiusports; char   *radiusports_s; } HbaLine;<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u041e\u043d\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <em>UserAuth<\/em><\/p>\n<pre><code class=\"cpp\">\/*  * The following enum represents the authentication methods that  * are supported by PostgreSQL.  *  * Note: keep this in sync with the UserAuthName array in hba.c.  *\/ typedef enum UserAuth { uaReject, uaImplicitReject,\/* Not a user-visible option *\/ uaTrust, uaIdent, uaPassword, uaMD5, uaSCRAM, uaGSS, uaSSPI, uaPAM, uaBSD, uaLDAP, uaCert, uaRADIUS, uaPeer #define USER_AUTH_LAST uaPeer\/* Must be last value of this enum *\/ } UserAuth;<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438, \u043a\u0440\u043e\u043c\u0435 <em>ImplicitReject<\/em>. \u041e\u043d \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439\/\u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (<a href=\"https:\/\/dizballanze.com\/ru\/special-case-osobyi-sluchai\/\" rel=\"noopener noreferrer nofollow\"><em>SpecialCase<\/em><\/a>). \u0412\u0435\u0434\u0435\u0442 \u0441\u0435\u0431\u044f \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0438 <em>uaReject<\/em>.<\/p>\n<pre><code class=\"cpp\">\/\/ src\/backend\/libpq\/hba.c \/*  *Scan the pre-parsed hba file, looking for a match to the port's connection  *request.  *\/ static void check_hba(hbaPort *port) {   \/\/ ...      \/* If no matching entry was found, then implicitly reject. *\/   hba = palloc0(sizeof(HbaLine));   hba->auth_method = uaImplicitReject;   port->hba = hba; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0423\u0441\u043f\u0435\u0448\u043d\u0430\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0438\u0441\u0442\u0435\u043c\u0435. \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0439\u0442\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d \u0432\u0445\u043e\u0434;<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c\u0430;<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0411\u0414 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 (pg_upgrade), \u0434\u043e\u0441\u0442\u0443\u043f \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0443\u043f\u0435\u0440\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043c\u043e\u0433\u043b\u0430 \u0437\u0430\u043d\u044f\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043b\u043e\u0433\u0438\u043d\u0430\/\u043f\u0430\u0440\u043e\u043b\u044f. \u0417\u0430 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0411\u0414 \u043c\u043e\u0433\u043b\u0430 \u0438\u0441\u0447\u0435\u0437\u043d\u0443\u0442\u044c\/\u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041d\u0435 \u043b\u0438\u0448\u043d\u0438\u043c \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u044d\u0442\u043e.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0411\u0414. \u0415\u0441\u043b\u0438 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u0448\u0435\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043a\u0442\u043e-\u0442\u043e \u043d\u0430\u0447\u0430\u043b <code>DROP DATABASE<\/code>, \u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u044b \u043e\u0431 \u044d\u0442\u043e\u043c \u0443\u0437\u043d\u0430\u0435\u043c.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0411\u0414. \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u043e\u0439 \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u0430\u043c\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f ACL<\/p>\n<details class=\"spoiler\">\n<summary>ACL<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 Postgres \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u0432\u043e\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a <em>ACL &#8212; Access Control List<\/em>.<\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0411\u0414 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u042d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <em>AclItem<\/em> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/utils\/acl.h\" rel=\"noopener noreferrer nofollow\">src\/include\/utils\/acl.h<\/a>)<\/p>\n<pre><code class=\"cpp\">typedef struct AclItem { Oidai_grantee;\/* ID that this item grants privs to *\/ Oidai_grantor;\/* grantor of privs *\/ AclModeai_privs;\/* privilege bits *\/ } AclItem;<\/code><\/pre>\n<p>\u0422\u0438\u043f AclMode, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/nodes\/parsenodes.h\" rel=\"noopener noreferrer nofollow\">src\/include\/nodes\/parsenodes.h<\/a><\/p>\n<pre><code class=\"cpp\">typedef uint32 AclMode;\/* a bitmask of privilege bits *\/<\/code><\/pre>\n<p>\u041f\u0440\u0430\u0432\u0430 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u0431\u0438\u0442\u043e\u0432\u043e\u0439 \u043c\u0430\u0441\u043a\u0438. \u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f 32 \u0431\u0438\u0442\u043d\u044b\u0439 int. \u0412\u0435\u0440\u0445\u043d\u0438\u0435 16 \u0431\u0438\u0442 &#8212; \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f GRANT \u043e\u043f\u0446\u0438\u0439 (\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f SQL \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432), \u0430 \u043d\u0438\u0436\u043d\u0438\u0435 &#8212; \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430.<\/p>\n<p>\u0411\u0438\u0442\u044b \u043f\u0440\u0430\u0432 \u0434\u043b\u044f SQL \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u0430\u043c \u0436\u0435<\/p>\n<pre><code class=\"cpp\">#define ACL_INSERT(1&lt;&lt;0)\/* for relations *\/ #define ACL_SELECT(1&lt;&lt;1) #define ACL_UPDATE(1&lt;&lt;2) #define ACL_DELETE(1&lt;&lt;3) #define ACL_TRUNCATE(1&lt;&lt;4) #define ACL_REFERENCES(1&lt;&lt;5) #define ACL_TRIGGER(1&lt;&lt;6) #define ACL_EXECUTE(1&lt;&lt;7)\/* for functions *\/ #define ACL_USAGE(1&lt;&lt;8)\/* for languages, namespaces, FDWs, and  * servers *\/ #define ACL_CREATE(1&lt;&lt;9)\/* for namespaces and databases *\/ #define ACL_CREATE_TEMP (1&lt;&lt;10) \/* for databases *\/ #define ACL_CONNECT(1&lt;&lt;11) \/* for databases *\/ #define N_ACL_RIGHTS12\/* 1 plus the last 1&lt;&lt;x *\/ #define ACL_NO_RIGHTS0 \/* Currently, SELECT ... FOR [KEY] UPDATE\/SHARE requires UPDATE privileges *\/ #define ACL_SELECT_FOR_UPDATEACL_UPDATE<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a \u0411\u0414. \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/p>\n<pre><code class=\"cpp\">\/\/ src\/include\/utils\/acl.h \/* result codes for pg_*_aclcheck *\/ typedef enum { ACLCHECK_OK = 0, ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER } AclResult;  \/\/ src\/backend\/catalog\/aclchk.c AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode) { if (pg_database_aclmask(db_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }<\/code><\/pre>\n<p>\u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <em>aclmask <\/em>(<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/adt\/acl.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/adt\/acl.c<\/a>): \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0439 \u043c\u0430\u0441\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439.\u00a0<\/p>\n<p>\u041e\u0431\u0449\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c<\/p>\n<pre><code class=\"cpp\">AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how) { AclModeresult; AclModeremaining; AclItem    *aidat; inti, num;  \/\/ \u0420\u0430\u043d\u043d\u0438\u0439 \u0432\u044b\u0445\u043e\u0434 \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u043a \u043f\u0440\u0430\u0432\u0430\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0430 if (mask == 0) return 0;  result = 0;  \/\/ \u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u0432\u0441\u0435\u0433\u0434\u0430 \u0438\u043c\u0435\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f if ((mask &amp; ACLITEM_ALL_GOPTION_BITS) &amp;&amp; has_privs_of_role(roleid, ownerId)) { result = mask &amp; ACLITEM_ALL_GOPTION_BITS; if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0)) return result; }  num = ACL_NUM(acl); aidat = ACL_DAT(acl);  \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0440\u043e\u043b\u0438 for (i = 0; i &lt; num; i++) { AclItem    *aidata = &amp;aidat[i];  if (aidata->ai_grantee == ACL_ID_PUBLIC || aidata->ai_grantee == roleid) { result |= aidata->ai_privs &amp; mask; if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0)) return result; } }  \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u043d\u044b\u0445 \u0440\u043e\u043b\u0438 remaining = mask &amp; ~result; for (i = 0; i &lt; num; i++) { AclItem    *aidata = &amp;aidat[i];  if (aidata->ai_grantee == ACL_ID_PUBLIC || aidata->ai_grantee == roleid) continue;\/* already checked it *\/  if ((aidata->ai_privs &amp; remaining) &amp;&amp; has_privs_of_role(roleid, aidata->ai_grantee)) { result |= aidata->ai_privs &amp; mask; if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0)) return result; remaining = mask &amp; ~result; } }  return result; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h4>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 GUC<\/h4>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 GUC \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u041a\u0435\u0448 (\u043b\u043e\u043a\u0430\u043b\u044c \u0438 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430)<\/p>\n<\/li>\n<li>\n<p>\u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 <\/p>\n<\/li>\n<li>\n<p>Startup \u043f\u0430\u043a\u0435\u0442<\/p>\n<\/li>\n<\/ul>\n<h4>\u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430<\/h4>\n<p>\u0420\u0430\u043d\u044c\u0448\u0435 \u043c\u044b \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u043f\u0435\u0440\u0435\u0434 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0435\u0439 (<a href=\"https:\/\/www.postgresql.org\/docs\/14\/runtime-config-developer.html#GUC-PRE-AUTH-DELAY\" rel=\"noopener noreferrer nofollow\">pre_auth_delay<\/a>). \u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u043e \u043b\u043e\u0433\u0438\u043a\u0435, \u043d\u0430\u0434\u043e \u0437\u0430\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u0443\u0436\u0435 \u043f\u043e\u0441\u043b\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <a href=\"https:\/\/www.postgresql.org\/docs\/14\/runtime-config-developer.html#GUC-POST-AUTH-DELAY\" rel=\"noopener noreferrer nofollow\">post_auth_delay<\/a> \u0438\u0437 postgresql.conf<\/p>\n<pre><code class=\"cpp\">\/* Apply PostAuthDelay as soon as we've read all options *\/ if (PostAuthDelay > 0)     pg_usleep(PostAuthDelay * 1000000L);<\/code><\/pre>\n<h4>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0432\u043e\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0431\u044d\u043a\u044d\u043d\u0434\u0430<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u201c\u0442\u043e\u0447\u043d\u043e\u201d \u0441\u043c\u043e\u0436\u0435\u043c \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u0435\u0431\u044f \u0434\u043b\u044f \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u0440\u0443\u0433\u0438\u043c \u0431\u044d\u043a\u044d\u043d\u0434\u0430\u043c \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u0432\u043e\u0435\u0433\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u0430.<\/p>\n<p>\u0420\u0430\u043d\u0435\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u0432\u043e\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <em>PgBackendStatus<\/em>, \u043d\u043e \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u043d\u0430 \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u0430. \u041a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u0435\u0439\u0447\u0430\u0441.<\/p>\n<p>\u041e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441 \u043d\u0430\u043c\u0438 \u044d\u0442\u0443 \u0441\u0442\u0443\u043a\u0442\u0443\u0440\u0443 (\u0438 \u043c\u0430\u0441\u0441\u0438\u0432) \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0431\u044d\u043a\u044d\u043d\u0434\u044b (\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445, \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0440\u044b\u0445), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443. <\/p>\n<p>\u0414\u043b\u044f \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0443\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u043b\u043e\u043a\u0430 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430 \u0438\u0434\u0435\u0442 \u0443\u0436\u0435 \u0441\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439, \u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u044b \u043d\u0435\u043d\u0430\u0434\u043e\u043b\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043b\u043e\u043a \u0438 \u043f\u043e\u0434\u043c\u0435\u043d\u044f\u0435\u043c \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u0448\u0435\u0439.<\/p>\n<pre><code class=\"cpp\">void pgstat_bestart(void) { volatile PgBackendStatus *vbeentry = MyBEEntry; PgBackendStatus lbeentry;        \/\/ \u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e      memcpy(&amp;lbeentry,    unvolatize(PgBackendStatus *, vbeentry),    sizeof(PgBackendStatus));      \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 lbeentry.st_procpid = MyProcPid; lbeentry.st_backendType = MyBackendType; lbeentry.st_proc_start_timestamp = MyStartTimestamp; lbeentry.st_activity_start_timestamp = 0; lbeentry.st_state_start_timestamp = 0; lbeentry.st_xact_start_timestamp = 0; lbeentry.st_databaseid = MyDatabaseId;  if (lbeentry.st_backendType == B_BACKEND || lbeentry.st_backendType == B_WAL_SENDER || lbeentry.st_backendType == B_BG_WORKER) lbeentry.st_userid = GetSessionUserId(); else lbeentry.st_userid = InvalidOid;  if (MyProcPort) memcpy(&amp;lbeentry.st_clientaddr, &amp;MyProcPort->raddr,    sizeof(lbeentry.st_clientaddr)); else MemSet(&amp;lbeentry.st_clientaddr, 0, sizeof(lbeentry.st_clientaddr));  lbeentry.st_state = STATE_UNDEFINED; lbeentry.st_progress_command = PROGRESS_COMMAND_INVALID; lbeentry.st_progress_command_target = InvalidOid; lbeentry.st_query_id = UINT64CONST(0);  \/\/ \u0412\u0445\u043e\u0434\u0438\u043c \u0432 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0437\u043e\u043d\u0443 PGSTAT_BEGIN_WRITE_ACTIVITY(vbeentry);  lbeentry.st_changecount = vbeentry->st_changecount;      \/\/ \u041f\u043e\u0434\u043c\u0435\u043d\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f memcpy(unvolatize(PgBackendStatus *, vbeentry),    &amp;lbeentry,    sizeof(PgBackendStatus));      \/\/ ...        \/\/ \u0412\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0437\u043e\u043d\u044b PGSTAT_END_WRITE_ACTIVITY(vbeentry);      \/\/ ... }<\/code><\/pre>\n<h2>\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c<\/h2>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c: <\/p>\n<ul>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438: \u043b\u043e\u043a\u0430\u043b\u044c, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u0442\u044b, \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430, \u0442\u0430\u0439\u043c-\u0437\u043e\u043d\u0430 \u0438 \u0442.\u0434. <\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0449\u0438\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435: \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0440\u0443\u0442\u043e\u043c, hot standby, \u0432\u0435\u0440\u0441\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u0442.\u0434.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0441\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, <em>\u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0443<\/em>, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 GUC \u0432 \u043a\u043e\u0434\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0418\u0437 \u0432\u044b\u0448\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 &#8212; \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 key-value \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u041e\u043d\u0438 \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u044e\u0442 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 <code>int<\/code>, <code>double<\/code>, <code>bool<\/code>, <code>string<\/code>. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u0441\u0432\u043e\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430. (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/utils\/guc_tables.h\" rel=\"noopener noreferrer nofollow\">src\/include\/utils\/guc_tables.h<\/a>)<\/p>\n<pre><code class=\"cpp\">\/* GUC records for specific variable types *\/  struct config_bool { struct config_generic gen; \/* constant fields, must be set correctly in initial value: *\/ bool   *variable; boolboot_val; GucBoolCheckHook check_hook; GucBoolAssignHook assign_hook; GucShowHook show_hook; \/* variable fields, initialized at runtime: *\/ boolreset_val; void   *reset_extra; };  struct config_int { struct config_generic gen; \/* constant fields, must be set correctly in initial value: *\/ int   *variable; intboot_val; intmin; intmax; GucIntCheckHook check_hook; GucIntAssignHook assign_hook; GucShowHook show_hook; \/* variable fields, initialized at runtime: *\/ intreset_val; void   *reset_extra; };  struct config_real { struct config_generic gen; \/* constant fields, must be set correctly in initial value: *\/ double   *variable; doubleboot_val; doublemin; doublemax; GucRealCheckHook check_hook; GucRealAssignHook assign_hook; GucShowHook show_hook; \/* variable fields, initialized at runtime: *\/ doublereset_val; void   *reset_extra; };  struct config_string { struct config_generic gen; \/* constant fields, must be set correctly in initial value: *\/ char  **variable; const char *boot_val; GucStringCheckHook check_hook; GucStringAssignHook assign_hook; GucShowHook show_hook; \/* variable fields, initialized at runtime: *\/ char   *reset_val; void   *reset_extra; };  struct config_enum { struct config_generic gen; \/* constant fields, must be set correctly in initial value: *\/ int   *variable; intboot_val; const struct config_enum_entry *options; GucEnumCheckHook check_hook; GucEnumAssignHook assign_hook; GucShowHook show_hook; \/* variable fields, initialized at runtime: *\/ intreset_val; void   *reset_extra; }; <\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u043f\u043e\u043b\u0435\u043c \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <em>config_generic <\/em>&#8212; \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0434\u0430\u043d\u043d\u044b\u0435, \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430. <\/p>\n<pre><code class=\"cpp\">struct config_generic { \/* constant fields, must be set correctly in initial value: *\/ const char *name;\/* name of variable - MUST BE FIRST *\/ GucContextcontext;\/* 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 *\/ intflags;\/* flag bits, see guc.h *\/ \/* variable fields, initialized at runtime: *\/ enum config_type vartype;\/* type of variable (set only at startup) *\/ intstatus;\/* status bits, see below *\/ GucSourcesource;\/* source of the current actual value *\/ GucSourcereset_source;\/* source of the reset_value *\/ GucContextscontext;\/* context that set the current value *\/ GucContextreset_scontext; \/* context that set the reset value *\/ GucStack   *stack;\/* stacked prior values *\/ void   *extra;\/* \"extra\" pointer for current actual value *\/ 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) *\/ intsourceline;\/* line in source file *\/ };<\/code><\/pre>\n<p>\u0417\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 GUC \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043c\u043e\u0434\u0443\u043b\u044c. \u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/misc\/guc.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/misc\/guc.c<\/a><\/p>\n<p>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u0441\u0432\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432. <\/p>\n<pre><code class=\"cpp\">\/\/ src\/backend\/utils\/misc\/guc.c  static struct config_bool ConfigureNamesBool[]; static struct config_int ConfigureNamesInt[]; static struct config_real ConfigureNamesReal[]; static struct config_enum ConfigureNamesEnum[]; static struct config_string ConfigureNamesString[];<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 <em>guc_variables<\/em> \u0442\u0438\u043f\u0430 <em>config_generic<\/em>. \u042d\u0442\u043e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u0441\u0435\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445<\/p>\n<pre><code class=\"cpp\">\/\/ src\/backend\/utils\/misc\/guc.c  \/*  * Actual lookup of variables is done through this single, sorted array.  *\/ static struct config_generic **guc_variables;<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u043c <em>build_guc_variables<\/em><\/p>\n<pre><code class=\"cpp\">void build_guc_variables(void) { intsize_vars; intnum_vars = 0; struct config_generic **guc_vars; inti;  for (i = 0; ConfigureNamesBool[i].gen.name; i++) { struct config_bool *conf = &amp;ConfigureNamesBool[i];  \/* Rather than requiring vartype to be filled in by hand, do this: *\/ conf->gen.vartype = PGC_BOOL; num_vars++; }  for (i = 0; ConfigureNamesInt[i].gen.name; i++) { struct config_int *conf = &amp;ConfigureNamesInt[i];  conf->gen.vartype = PGC_INT; num_vars++; }  for (i = 0; ConfigureNamesReal[i].gen.name; i++) { struct config_real *conf = &amp;ConfigureNamesReal[i];  conf->gen.vartype = PGC_REAL; num_vars++; }  for (i = 0; ConfigureNamesString[i].gen.name; i++) { struct config_string *conf = &amp;ConfigureNamesString[i];  conf->gen.vartype = PGC_STRING; num_vars++; }  for (i = 0; ConfigureNamesEnum[i].gen.name; i++) { struct config_enum *conf = &amp;ConfigureNamesEnum[i];  conf->gen.vartype = PGC_ENUM; num_vars++; }  \/*  * Create table with 20% slack  *\/ size_vars = num_vars + num_vars \/ 4;  guc_vars = (struct config_generic **) guc_malloc(FATAL, size_vars * sizeof(struct config_generic *));  num_vars = 0;  for (i = 0; ConfigureNamesBool[i].gen.name; i++) guc_vars[num_vars++] = &amp;ConfigureNamesBool[i].gen;  for (i = 0; ConfigureNamesInt[i].gen.name; i++) guc_vars[num_vars++] = &amp;ConfigureNamesInt[i].gen;  for (i = 0; ConfigureNamesReal[i].gen.name; i++) guc_vars[num_vars++] = &amp;ConfigureNamesReal[i].gen;  for (i = 0; ConfigureNamesString[i].gen.name; i++) guc_vars[num_vars++] = &amp;ConfigureNamesString[i].gen;  for (i = 0; ConfigureNamesEnum[i].gen.name; i++) guc_vars[num_vars++] = &amp;ConfigureNamesEnum[i].gen;  if (guc_variables) free(guc_variables); guc_variables = guc_vars; num_guc_variables = num_vars; size_guc_variables = size_vars; qsort((void *) guc_variables, num_guc_variables,   sizeof(struct config_generic *), guc_var_compare); }<\/code><\/pre>\n<p>\u0412\u044b\u0448\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043e\u043f\u0446\u0438\u0438. \u0412 <em>config_generic <\/em>\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435 <em>flags<\/em> &#8212; \u0431\u0438\u0442\u043e\u0432\u0430\u044f \u043c\u0430\u0441\u043a\u0430 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u043f\u0446\u0438\u0438. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0444\u043b\u0430\u0433\u0438 \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/utils\/guc.h\" rel=\"noopener noreferrer nofollow\">src\/include\/utils\/guc.h<\/a><\/p>\n<pre><code class=\"cpp\">\/*  * bit values in \"flags\" of a GUC variable  *\/ #define GUC_LIST_INPUT0x0001\/* input can be list format *\/ #define GUC_LIST_QUOTE0x0002\/* double-quote list elements *\/ #define GUC_NO_SHOW_ALL0x0004\/* exclude from SHOW ALL *\/ #define GUC_NO_RESET_ALL0x0008\/* exclude from RESET ALL *\/ #define GUC_REPORT0x0010\/* auto-report changes to client *\/ #define GUC_NOT_IN_SAMPLE0x0020\/* not in postgresql.conf.sample *\/ #define GUC_DISALLOW_IN_FILE0x0040\/* can't set in postgresql.conf *\/ #define GUC_CUSTOM_PLACEHOLDER0x0080\/* placeholder for custom variable *\/ #define GUC_SUPERUSER_ONLY0x0100\/* show only to superusers *\/ #define GUC_IS_NAME0x0200\/* limit string to NAMEDATALEN-1 *\/ #define GUC_NOT_WHILE_SEC_REST0x0400\/* can't set if security restricted *\/ #define GUC_DISALLOW_IN_AUTO_FILE 0x0800\/* can't set in  * PG_AUTOCONF_FILENAME *\/<\/code><\/pre>\n<p>\u0417\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0444\u043b\u0430\u0433 <em>GUC_REPORT<\/em>. \u0414\u043b\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 GUC \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>BeginReportingGUCOptions,<\/em> \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0435\u0433\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442. <\/p>\n<pre><code class=\"cpp\">\/\/ src\/backend\/utils\/misc\/guc.c \/*  * Start up automatic reporting of changes to variables marked GUC_REPORT.  * This is executed at completion of backend startup.  *\/ void BeginReportingGUCOptions(void) { inti;  \/\/ ...  \/* Transmit initial values of interesting variables *\/ for (i = 0; i &lt; num_guc_variables; i++) { struct config_generic *conf = guc_variables[i];  if (conf->flags &amp; GUC_REPORT) ReportGUCOption(conf); }  \/\/ ... }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 (\u043f\u0430\u0440\u0430): ID \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0438 \u0442\u043e\u043a\u0435\u043d \u043e\u0442\u043c\u0435\u043d\u044b. \u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0430\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043e\u0442\u043c\u0435\u043d\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430.\u00a0<\/p>\n<p>\u0421 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u0436\u0434\u0435\u0442 <em>ReadyForQuery<\/em> \u043f\u0430\u043a\u0435\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0441\u043b\u0430\u043d \u0443\u0436\u0435 \u0432 \u0433\u043b\u0430\u0432\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435.<\/p>\n<h2>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<p>\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 <a href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-client.html#GUC-LOCAL-PRELOAD-LIBRARIES\" rel=\"noopener noreferrer nofollow\">local_preload_libraries<\/a>, <a href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES\" rel=\"noopener noreferrer nofollow\">shared_preload_libraries<\/a> \u0438 <a href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-client.html#GUC-SESSION-PRELOAD-LIBRARIES\" rel=\"noopener noreferrer nofollow\">session_preload_libraries<\/a> \u0432 postgresql.conf\u00a0<\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f <em>session_preload_libraries <\/em>\u0438 <em>local_preload_libraries<\/em>.\u00a0<\/p>\n<details class=\"spoiler\">\n<summary>\u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438 \u043c\u043e\u0434\u0443\u043b\u044c dfmgr<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a Postgres \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438\/\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u043e\u0434\u0443\u043b\u044c <strong>dfmgr<\/strong><\/p>\n<p>\u041e\u043d \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u043c\u0438 \u0432\u043e \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0445<\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <em>FunctionCallInfoBaseData <\/em>(<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/fmgr.h\" rel=\"noopener noreferrer nofollow\">src\/include\/fmgr.h<\/a>)<\/p>\n<pre><code class=\"cpp\">typedef struct FunctionCallInfoBaseData { FmgrInfo   *flinfo;\/* ptr to lookup info used for this call *\/ fmNodePtrcontext;\/* pass info about context of call *\/ fmNodePtrresultinfo;\/* pass or return extra info about result *\/ Oidfncollation;\/* collation for function to use *\/ #define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4 boolisnull;\/* function must set true if result is NULL *\/ shortnargs;\/* # arguments actually passed *\/ #define FIELDNO_FUNCTIONCALLINFODATA_ARGS 6 NullableDatum args[FLEXIBLE_ARRAY_MEMBER]; } FunctionCallInfoBaseData;  typedef struct FunctionCallInfoBaseData *FunctionCallInfo;<\/code><\/pre>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443<\/p>\n<pre><code class=\"cpp\">typedef Datum (*PGFunction) (FunctionCallInfo fcinfo);<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <\/p>\n<pre><code class=\"cpp\">void *load_external_function(const char *filename, const char *funcname,  bool signalNotFound, void **filehandle); void *lookup_external_function(void *filehandle, const char *funcname); void load_file(const char *filename, bool restricted); void **find_rendezvous_variable(const char *varName); Size EstimateLibraryStateSpace(void); void SerializeLibraryState(Size maxsize, char *start_address); void RestoreLibraryState(char *start_address);<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>load_file<\/em>. \u041e\u043d\u0430 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0433\u0440\u0443\u0436\u0430\u0435\u0442 (\u0435\u0441\u043b\u0438 \u0443\u0436\u0435 \u0431\u044b\u043b\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u0430), \u0430 \u0437\u0430\u0442\u0435\u043c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0444\u0430\u0439\u043b \u043e\u0431\u0440\u0430\u0442\u043d\u043e. \u0414\u043b\u044f \u0441\u0430\u043c\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>internal_load_library (<\/em><a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/fmgr\/dfmgr.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/fmgr\/dfmgr.c<\/a>)<\/p>\n<pre><code class=\"cpp\">\/*  * Load the specified dynamic-link library file, unless it already is  * loaded.  Return the pg_dl* handle for the file.  *  * Note: libname is expected to be an exact name for the library file.  *\/ void *internal_load_library(const char *libname);<\/code><\/pre>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c:<\/p>\n<ol>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0444\u0430\u0439\u043b \u043d\u0435 \u0431\u044b\u043b \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d \u0440\u0430\u043d\u0435\u0435:<\/p>\n<ol>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0431\u044b\u043b \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d, \u0442\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0445\u0440\u0430\u043d\u044f\u0449\u0443\u044e\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443.<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>\u0410\u043b\u043b\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c \u043f\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0444\u0430\u0439\u043b \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u043c \u0432\u044b\u0437\u043e\u0432\u043e\u043c <a href=\"https:\/\/man7.org\/linux\/man-pages\/man3\/dlopen.3.html\" rel=\"noopener noreferrer nofollow\">dlopen<\/a>.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c &#171;\u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e&#187;. \u041e\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>Pg_magic_struct<\/code> \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u043e \u0432\u0435\u0440\u0441\u0438\u044f\u043c.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <em>_PG_init, <\/em>\u0435\u0441\u043b\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u044d\u0442\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443.<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/details>\n<h4>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0430\u043c\u044f\u0442\u0438<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0447\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c &#8212; \u0430\u043b\u043b\u043e\u043a\u0430\u0446\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>\u041f\u0430\u043c\u044f\u0442\u044c \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 2 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445:<\/p>\n<ul>\n<li>\n<p><em>MessageContext<\/em> &#8212; \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (\u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442).<\/p>\n<\/li>\n<li>\n<p><em>row_description_context<\/em> &#8212; \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u0430\u043c\u044f\u0442\u0438, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439 \u0432 \u0441\u0435\u0431\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a \u043f\u0440\u0438 \u043e\u0442\u0432\u0435\u0442\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u043b\u0431\u0446\u0430, \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u043e\u043b\u0431\u0446\u0430 (object ID) \u0438\u043b\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0442\u0438\u043f\u0430. (\u0422\u043e\u043b\u044c\u043a\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 \u0441 \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/tcop\/postgres.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/tcop\/postgres.c<\/a>).<\/p>\n<\/li>\n<\/ul>\n<h2>\u041a\u043e\u043d\u0435\u0446<\/h2>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Postgres \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0438\u0434\u0435\u0442 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/709404\/\"> https:\/\/habr.com\/ru\/post\/709404\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e!<\/p>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b PostgreSQL. \u041c\u044b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u043d\u0430\u00a0\u043c\u043e\u043c\u0435\u043d\u0442\u0435 \u043e\u0431\u0449\u0435\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Postgres\u00a0\u2014 \u0432\u0445\u043e\u0434\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0434\u043e\u00a0\u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430.<\/p>\n<p><strong>PostgresMain <\/strong>\u2014 \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f\u00a0\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0431\u044d\u043a\u044d\u043d\u0434\u0430. \u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0430 \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/tcop\/postgres.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/tcop\/postgres.c<\/a><\/p>\n<p>\u0411\u044d\u043a\u044d\u043d\u0434 \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u0430\u043a\u00a0\u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e (Standalone), \u0442\u0430\u043a \u0438 \u0432\u00a0\u043e\u0431\u044b\u0447\u043d\u043e\u043c (\u043c\u043d\u043e\u0433\u043e\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c) \u0440\u0435\u0436\u0438\u043c\u0435 (\u0438\u0437\u2011\u043f\u043e\u0434 Postmaster)<\/p>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0435\u0434\u0435\u0442\u0441\u044f \u0441\u00a0\u0443\u0447\u0435\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u00a0\u043c\u043d\u043e\u0433\u043e\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 (<em>IsUnderPostmaster<\/em>\u0440\u0430\u0432\u0435\u043d <code>true<\/code>)<\/p>\n<details class=\"spoiler\">\n<summary>\u0420\u0430\u0431\u043e\u0442\u0430 \u0432 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0430 \u0438\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e, \u0442\u043e \u043c\u043d\u043e\u0433\u0438\u0435 \u043e\u043f\u0446\u0438\u0438 \u0435\u0449\u0435 \u043d\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 GUC. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043f\u0435\u0440\u0435\u0434 \u0441\u0430\u043c\u0438\u043c \u0446\u0438\u043a\u043b\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438\u0441\u044c \u043d\u0435 \u0438\u0437-\u043f\u043e\u0434 Postmaster.\u00a0<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0435\u0441\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0440\u0430\u043d\u0435\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <em>InitializeGUCOptions<\/em>, \u043d\u043e \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439, \u0447\u0442\u043e \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438\u0441\u044c \u0438\u0437 Postmaster. \u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f IsUnderPostmaster. <\/p>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442 \u0441 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u043c<\/p>\n<pre><code class=\"cpp\">if (!IsUnderPostmaster) {   someOperation(); }<\/code><\/pre>\n<p>\u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a &#171;\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>someOperation<\/code> \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0432 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435&#187;<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430<\/p>\n<pre><code class=\"cpp\">void PostgresMain(int argc, char *argv[],  const char *dbname,  const char *username) {   intfirstchar;   StringInfoData input_message;   sigjmp_buflocal_sigjmp_buf;   volatile bool send_ready_for_query = true;   boolidle_in_transaction_timeout_enabled = false;   boolidle_session_timeout_enabled = false;    \/* Initialize startup process environment if necessary. *\/   if (!IsUnderPostmaster)       InitStandaloneProcess(argv[0]);      \/\/ ... }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<p>\u041a\u0430\u043a\u00a0\u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u00a0\u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u044d\u043a\u044d\u043d\u0434\u0430, \u0442\u043e \u0432\u0445\u043e\u0434\u0438\u043c \u0432\u00a0\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <em>InitProcessing<\/em>. <\/p>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b (<em>NormalProcessing)<\/em>\u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0431\u044d\u043a\u044d\u043d\u0434\u0430 (<em>InitPostgres<\/em>) <\/p>\n<details class=\"spoiler\">\n<summary>ProcessingMode<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e Postmaster \u0438\u043c\u0435\u0435\u0442 \u043c\u0430\u0448\u0438\u043d\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439, \u043d\u043e \u0438 \u0431\u044d\u043a\u044d\u043d\u0434. \u0415\u0433\u043e \u043c\u0430\u0448\u0438\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435\u043c <em>ProcessingMode<\/em><\/p>\n<pre><code class=\"cpp\">typedef enum ProcessingMode { BootstrapProcessing,\/* bootstrap creation of template database *\/ InitProcessing,\/* initializing system *\/ NormalProcessing\/* normal processing *\/ } ProcessingMode;<\/code><\/pre>\n<p>\u0412\u0441\u0435\u0433\u043e \u0435\u0441\u0442\u044c 3 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f:<\/p>\n<ul>\n<li>\n<p><em>BootstrapProcessing<\/em> &#8212; \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0411\u0414 \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0430<\/p>\n<\/li>\n<li>\n<p><em>InitProcessing<\/em> &#8212; \u0441\u0442\u0430\u0440\u0442 \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u044d\u043a\u044d\u043d\u0434\u0430<\/p>\n<\/li>\n<li>\n<p><em>NormalProcessing &#8212; <\/em>\u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043d\u0438\u0445 \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0441\u0432\u043e\u0438 \u043c\u0430\u043a\u0440\u043e\u0441\u044b:<\/p>\n<pre><code class=\"cpp\">extern ProcessingMode Mode;  #define IsBootstrapProcessingMode() (Mode == BootstrapProcessing) #define IsInitProcessingMode()(Mode == InitProcessing) #define IsNormalProcessingMode()(Mode == NormalProcessing)  #define GetProcessingMode() Mode  #define SetProcessingMode(mode) \\ do { \\ AssertArg((mode) == BootstrapProcessing || \\   (mode) == InitProcessing || \\   (mode) == NormalProcessing); \\ Mode = (mode); \\ } while(0)<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0438 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/miscadmin.h\" rel=\"noopener noreferrer nofollow\">src\/include\/miscadmin.h<\/a><\/p>\n<\/div>\n<\/details>\n<h2>\u0421\u0438\u0433\u043d\u0430\u043b\u044b<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0441\u0432\u043e\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>SIGHUP &#8212; \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>SIGINT &#8212; \u043e\u0442\u043c\u0435\u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (Fast shutdown);<\/p>\n<\/li>\n<li>\n<p>SIGTERM &#8212; \u043e\u0442\u043c\u0435\u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u0432\u044b\u0445\u043e\u0434 (Smart shutdown);<\/p>\n<\/li>\n<li>\n<p>SIGQUIT &#8212; \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0432\u044b\u0445\u043e\u0434 (Immediate shutdown);<\/p>\n<\/li>\n<li>\n<p>SIGPIPE &#8212; \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0442.\u043a. \u044d\u0442\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0435\u0439 \u0447\u0435\u043c \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0442\u044c \u2018who-knows-what operation\u2019, \u0430 \u0437\u0430\u043c\u0435\u0442\u0438\u043c \u043c\u044b \u044d\u0442\u043e \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0446\u0438\u043a\u043b\u0430;<\/p>\n<\/li>\n<li>\n<p>SIGUSR1 &#8212; \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0411\u0414;<\/p>\n<\/li>\n<li>\n<p>SIGUSR2 &#8212; \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f;<\/p>\n<\/li>\n<li>\n<p>SIGFPE &#8212; \u043e\u0448\u0438\u0431\u043a\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430 1 \u0441\u0438\u0433\u043d\u0430\u043b<\/summary>\n<div class=\"spoiler__content\">\n<p><em>SIGUSR1 <\/em>&#8212; \u0441\u0438\u0433\u043d\u0430\u043b \u0441\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u041d\u043e \u043a\u0430\u043a \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435?<\/p>\n<p>\u0412 Postgres \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u0449\u0430\u044f \u043f\u0430\u043c\u044f\u0442\u044c.<\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <em>ProcSignalSlot <\/em>\u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432<\/p>\n<pre><code class=\"cpp\">typedef struct { volatile pid_t pss_pid; volatile sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS]; pg_atomic_uint64 pss_barrierGeneration; pg_atomic_uint32 pss_barrierCheckMask; ConditionVariable pss_barrierCV; } ProcSignalSlot;<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0435 <em>pss_signalFlags<\/em> &#8212; \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0443\u043b\u0435\u0432\u0441\u043a\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u0434\u043b\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432.<\/p>\n<p>\u0421\u0430\u043c\u0438 \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435\u043c <em>ProcSignalReason<\/em><\/p>\n<pre><code class=\"cpp\">typedef enum { PROCSIG_CATCHUP_INTERRUPT,\/* sinval catchup interrupt *\/ PROCSIG_NOTIFY_INTERRUPT,\/* listen\/notify interrupt *\/ PROCSIG_PARALLEL_MESSAGE,\/* message from cooperating parallel backend *\/ PROCSIG_WALSND_INIT_STOPPING,\/* ask walsenders to prepare for shutdown  *\/ PROCSIG_BARRIER,\/* global barrier interrupt  *\/ PROCSIG_LOG_MEMORY_CONTEXT, \/* ask backend to log the memory contexts *\/  \/* Recovery conflict reasons *\/ PROCSIG_RECOVERY_CONFLICT_DATABASE, PROCSIG_RECOVERY_CONFLICT_TABLESPACE, PROCSIG_RECOVERY_CONFLICT_LOCK, PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,  NUM_PROCSIGNALS\/* Must be last! *\/ } ProcSignalReason;<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 <em>SIGUSR1 <\/em>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c<\/p>\n<pre><code class=\"cpp\">\/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a SIGUSR1 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 void procsignal_sigusr1_handler(SIGNAL_ARGS) { intsave_errno = errno;  if (CheckProcSignal(PROCSIG_CATCHUP_INTERRUPT)) HandleCatchupInterrupt();  if (CheckProcSignal(PROCSIG_NOTIFY_INTERRUPT)) HandleNotifyInterrupt();  if (CheckProcSignal(PROCSIG_PARALLEL_MESSAGE)) HandleParallelMessageInterrupt();  if (CheckProcSignal(PROCSIG_WALSND_INIT_STOPPING)) HandleWalSndInitStopping();  if (CheckProcSignal(PROCSIG_BARRIER)) HandleProcSignalBarrierInterrupt();  if (CheckProcSignal(PROCSIG_LOG_MEMORY_CONTEXT)) HandleLogMemoryContextInterrupt();  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_DATABASE)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_DATABASE);  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_TABLESPACE)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_TABLESPACE);  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_LOCK)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_LOCK);  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_SNAPSHOT)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_SNAPSHOT);  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK);  if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);  SetLatch(MyLatch);  errno = save_errno; }  \/\/ \u0412 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u0441\u0435 SigProcReason \/\/ \u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f static bool CheckProcSignal(ProcSignalReason reason) { volatile ProcSignalSlot *slot = MyProcSignalSlot;  if (slot != NULL) { \/* Careful here --- don't clear flag if we haven't seen it set *\/ if (slot->pss_signalFlags[reason]) { slot->pss_signalFlags[reason] = false; return true; } }  return false; }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/storage\/ipc\/procsignal.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/storage\/ipc\/procsignal.c<\/a><\/p>\n<\/div>\n<\/details>\n<p>Postgres \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <em>SIGALRM<\/em>. \u0417\u0430 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043c\u043e\u0434\u0443\u043b\u044c <strong>timeout<\/strong> <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/misc\/timeout.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/misc\/timeout.c<\/a> <\/p>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c (\u0440\u0435)\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f: \u0432\u0441\u0435 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0438 \u0437\u0430\u043d\u043e\u0432\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u0430.<\/p>\n<h2>BaseInit<\/h2>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <em>BaseInit <\/em>(<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/utils\/init\/postinit.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/utils\/init\/postinit.c<\/a>) \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b. \u0415\u0435 \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 &#8212; \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u0449\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439:<\/p>\n<ul>\n<li>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041c\u043e\u0434\u0443\u043b\u044c fd<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0438\u043c\u0435\u043d\u0443\u0435\u0442\u0441\u044f <strong>fd<\/strong><\/p>\n<p>\u0422\u0438\u043f\u044b \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/include\/storage\/fd.h\" rel=\"noopener noreferrer nofollow\">src\/include\/storage\/fd.h<\/a><\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0432\u043c\u0435\u0441\u0442\u043e &#171;\u0441\u044b\u0440\u044b\u0445&#187; \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0439 \u0442\u0438\u043f <em>File<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0438 \u0435\u0441\u0442\u044c <em>int<\/em><\/p>\n<pre><code class=\"cpp\">typedef int File;<\/code><\/pre>\n<p> \u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f\/\u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0444\u0430\u043b\u043e\u0432 <\/p>\n<pre><code class=\"cpp\">File PathNameOpenFile(const char *fileName, int fileFlags); File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode); File OpenTemporaryFile(bool interXact);<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u0430 &#8212; \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432. \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u044b \u0442\u0430\u0431\u043b\u0438\u0446, \u043d\u043e \u0438 \u0434\u043b\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/master\/src\/backend\/storage\/file\/fd.c\" rel=\"noopener noreferrer nofollow\">src\/backend\/storage\/file\/fd.c<\/a><\/p>\n<p>\u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f LRU \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <em>vfd<\/em><\/p>\n<pre><code class=\"cpp\">typedef struct vfd { intfd;\/* current FD, or VFD_CLOSED if none *\/ unsigned short fdstate;\/* bitflags for VFD's state *\/ ResourceOwner resowner;\/* owner, for automatic cleanup *\/ FilenextFree;\/* link to next free VFD, if in freelist *\/ FilelruMoreRecently;\/* doubly linked recency-of-use list *\/ FilelruLessRecently; off_tfileSize;\/* current size of file (0 if not temporary) *\/ char   *fileName;\/* name of file, or NULL for unused VFD *\/ \/* NB: fileName is malloc'd, and must be free'd when closing the VFD *\/ intfileFlags;\/* open(2) flags for (re)opening the file *\/ mode_tfileMode;\/* mode to pass to open(2) *\/ } Vfd;  \/*  * Virtual File Descriptor array pointer and size.  This grows as  * needed.  'File' values are indexes into this array.  * Note that VfdCache[0] is not a usable VFD, just a list header.  *\/ static Vfd *VfdCache; static Size SizeVfdCache = 0;<\/code><\/pre>\n<p>\u0421\u0430\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0434\u0432\u0443\u0441\u0432\u044f\u0437\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a. \u041f\u0440\u0438\u0447\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441 0 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c &#8212; \u043e\u0441\u043e\u0431\u044b\u0439: \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u043e\/\u043a\u043e\u043d\u0435\u0446 \u0441\u043f\u0438\u0441\u043a\u0430 \u0438 \u0435\u0433\u043e \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0440\u0430\u0432\u0435\u043d <em>VFD_CLOSED<\/em>.<\/p>\n<p>\u041f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>InitFileAccess<\/em><\/p>\n<pre><code class=\"cpp\">\/*  * InitFileAccess --- initialize this module during backend startup  *  * This is called during either normal or standalone backend start.  * It is *not* called in the postmaster.  *\/ void InitFileAccess(void) { Assert(SizeVfdCache == 0);\/* call me only once *\/  \/* initialize cache header entry *\/ VfdCache = (Vfd *) malloc(sizeof(Vfd)); if (VfdCache == NULL) ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY),  errmsg(\"out of memory\")));  MemSet((char *) &amp;(VfdCache[0]), 0, sizeof(Vfd)); VfdCache->fd = VFD_CLOSED;  SizeVfdCache = 1;  \/* register proc-exit hook to ensure temp files are dropped at exit *\/ on_proc_exit(AtProcExit_Files, 0); }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0435\u0433\u043e \u0432 LRU<\/p>\n<pre><code class=\"cpp\">File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode) { char   *fnamecopy; Filefile; Vfd   *vfdP;    \/*  * We need a malloc'd copy of the file name; fail cleanly if no room.  *\/ fnamecopy = strdup(fileName); if (fnamecopy == NULL) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),  errmsg(\"out of memory\")));  file = AllocateVfd(); vfdP = &amp;VfdCache[file];  \/* Close<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-344778","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/344778","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=344778"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/344778\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=344778"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=344778"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=344778"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}