- 浏览: 226582 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
chenxliang:
2016年10月26、27日,上海浦东,Postgres中国用 ...
PostgreSQL的用户、角色和权限管理 -
gejiod:
最近出了SQL:2011標準,希望樓主也更新下
SQL2008标准 -
lincon77:
太长了,又是E文,要是有些例子可能好理解些
SQL2003标准 -
少主丶无翼:
很谢,找了很久
SQL2003标准 -
zeeeitch:
...
PostgreSQL启动过程中的那些事七:初始化共享内存和信号二十:shmem中初始化堆同步扫描、pg子进程相关结构
话说 pg 中有个昙花一现的进程“启动进程”(“ startup progress ”),做了启动 XLOG 、验证数据库一致性、根据需要做数据库恢复和创建检查点等事情(参见《 pg 启动过程中的那些事十五 StartDataBase 梗概》),现在来讨论这个进程。
1
StartupDataBase 调用流程略图
话说 Main()->PostmasterMain()->StartupDatabase() ,启动数据库, StartupDatabase 方法其实就是 StartChildProcess 方法。还有启动后台写进程的方法 StartBackgroundWriter 、 WAL 日志写进程的方法 StartWalWriter 、 WAL 日志接受进程的方法 StartWalreceiver 都是 StartChildProcess 方法,只是入参不同,可能的入参见枚举类型 AuxProcType 。相关定义见下面。
#define StartupDataBase() StartChildProcess(StartupProcess)
#define StartBackgroundWriter() StartChildProcess(BgWriterProcess)
#define StartWalWriter() StartChildProcess(WalWriterProcess)
#define StartWalReceiver() StartChildProcess(WalReceiverProcess)
typedef enum
{
CheckerProcess ,
BootstrapProcess ,
StartupProcess ,
BgWriterProcess ,
WalWriterProcess ,
WalReceiverProcess ,
NUM_AUXPROCTYPES /* Must be last! */
} AuxProcType ;
接着 StartChildProcess()->postmaster_forkexec()->internal_forexec() ,在 StartChildProcess 方法中,组织了参数“ postgres –forkboot NULL [v_AuxProcType] ”, [v_AuxProcType] 就是枚举类型 AuxProcType 的变量。再调用 internal_forexec() ,把要传递给即将产生的新进程的参数组织到了 BackendParameters 结构里并写入到文件 pgsql_tmp/pgsql_tmp.backend_var.[pid].[tmpFileNum] 里, [pid] 是当前进程 ID , [tmpFileNum] 是一个静态递增的无符号整型变量。然后用这个文件名字代替参数串中的 NULL ,现在参数成了这样“ postgres –forkboot pgsql_tmp/pgsql_tmp.backend_var.[pid].[tmpFileNum] [v_AuxProcType] ”,然后 fork 一个进程——“启动进程”。 BackendParameters 结构的定义见下面
typedef struct
{
Port port;
InheritableSocket portsocket;
char DataDir[MAXPGPATH];
pgsocket ListenSocket[MAXLISTEN];
long MyCancelKey;
int MyPMChildSlot;
#ifndef WIN32
unsigned long UsedShmemSegID;
#else
HANDLE UsedShmemSegID;
#endif
void *UsedShmemSegAddr;
slock_t *ShmemLock;
VariableCache ShmemVariableCache;
Backend *ShmemBackendArray;
LWLock *LWLockArray;
slock_t *ProcStructLock;
PROC_HDR *ProcGlobal;
PGPROC *AuxiliaryProcs;
PMSignalData *PMSignalState;
InheritableSocket pgStatSock;
pid_t PostmasterPid;
TimestampTz PgStartTime;
TimestampTz PgReloadTime;
bool redirection_done;
#ifdef WIN32
HANDLE PostmasterHandle;
HANDLE initial_signal_pipe;
HANDLE syslogPipe[2];
#else
int syslogPipe[2];
#endif
char my_exec_path[MAXPGPATH];
char pkglib_path[MAXPGPATH];
char ExtraOptions[MAXPGPATH];
} BackendParameters;
该结构由 postmaster 用于它和前端进程交互。它包含在后台进程运行前所需要的所有状态信息。这个结构由 malloc 分配内存并且后台进程运行时它仍然是可用的,或者由 palloc 在 TopMemoryContext 中分配,因此它使 PostgresMain 执行。
typedef struct Port
{
pgsocket sock ; /* File descriptor */
bool noblock ; /* is the socket in non-blocking mode? */
ProtocolVersion proto ; /* FE/BE protocol version */
SockAddr laddr ; /* local addr (postmaster) */
SockAddr raddr ; /* remote addr (client) */
char * remote_host ; /* name (or ip addr ) of remote host */
char * remote_hostname ; /* name (not ip addr ) of remote host, if
* available */
int remote_hostname_resolv ; /* +1 = remote_hostname is known to
* resolve to client's IP address; -1
* = remote_hostname is known NOT to
* resolve to client's IP address; 0 =
* we have not done the forward DNS
* lookup yet */
char * remote_port ; /* text rep of remote port */
CAC_state canAcceptConnections ; /* postmaster connection status */
/* 需要启动包保存的 并传递进后台进程使用的信息。指向一个可替换的名字值对列表 */
char * database_name ;
char * user_name ;
char * cmdline_options ;
List * guc_options ;
/* 在认证周期期间需要持有的信息 */
HbaLine * hba ;
char md5Salt [4]; /* Password salt */
/* 没有业务的放在该结构里的信息,但是因为 elog.c 要用到, database_name 和其它成员也是同样的情况。 */
TimestampTz SessionStartTime ; /* backend start time */
/*TCP 活跃设置
如果 AF_UNIX 或者还不知道,默认值是 0 ;如果 AF_UNIX 或者使用默认值,当前值是 0 。 -1 作为默认值意味着本进程不能发现默认的。 */
int default_keepalives_idle ;
int default_keepalives_interval ;
int default_keepalives_count ;
int keepalives_idle ;
int keepalives_interval ;
int keepalives_count ;
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
/* 如果支持 GSSAPI ,存储 GSSAPI 信息。否则,物理保证在该结构里相同的偏移量而置 NULL */
pg_gssinfo *gss;
#else
void * gss ;
#endif
/* SSL 结构(放在最后以使其不影响其他字段位置) */
#ifdef USE_SSL
SSL *ssl;
X509 *peer;
char peer_dn[128 + 1];
char peer_cn[SM_USER + 1];
unsigned long count;
#endif
} Port ;
2
启动进程的调用流程略图
在启动进程里 Main()->SubPostmasterMain() ,调用了如下方法,启动 XLOG 后就结束了生命。
1 ) MemoryContextInt 方法,参见《 PostgresQL 启动过程中的那些事一》;
2 ) InitializeGUCOptions 方法,参见《 PostgresQL 启动过程中的那些事三》;
3 ) Read_backend_variablases 方法,为重组 BackendParameters 结构读取前面存储的文件 pgsql_tmp/pgsql_tmp.backend_var.[pid].[tmpFileNum] ;
4 ) PGSharedMemoryReAttach 方法, attach 进程 postmaster 里的共享内存;
5 ) read_nondefault_variables 方法,读非默认 GUC 参数,参见《 PostgresQL 中的那些事 十一:保存非默认 GUC 参数到文件 》;
6 ) ClosePostmasterPorts 方法,关闭“启动进程”不用的文件句柄,当然,在 postmaster 进程里这些文件还是打开的;
7 ) InitShmemAccess 方法,在初始化本进程共享内存全局变量:这些 shmem 头的 ShmemSegHdr 、 shmem 起始地址 ShmemBase 和 shmem 结束地址 +1 的 ShmemBase 。定义见下面。
static PGShmemHeader *ShmemSegHdr ; /* shared mem segment header */
static void *ShmemBase; /* start address of shared memory */
static void *ShmemEnd; /* end+1 address of shared memory */
8 ) InitAuxiliaryProcess 方法,初始化一个 PGPROC 结构;
9 ) CreateSharedMemoryAndSemaphores 方法,参见《 PostgresQL 中的那些事七》;
10 ) AuxiliaryProcessMain 方法,辅助进程入口函数,干一堆活;
SubPostmasterMain 的流程图见下面。根据启动进程的传入参数“ postgres –forkboot NULL [v_AuxProcType] ”走了 "--forkboot" 这个分支。还有 bgwriter 进程、 WalWriter 进程、 WalReciver 进程都走了这个分支,以后要讨论到相关进程,就直接从这个分支里开始了。还有 AutoVacuumLauncher 进程、 AutoVacuumWorker 进程、归档进程、统计进程以及为前端提供服务的 postgres 进程等在进程初始阶段,几乎没有区别的都走了 1-6 步,然后根据不同入参走了不同的分支,因此以后要讨论到这些进程,就直接从这些分支开始。
SubPostmasterMain 的流程图
第 8 步 InitAuxiliaryProcess 初始化了一个每个辅助进程都有一个的 PGPROC 结构。每一个后台进程都在共享内存里有一个 PGPROC 结构,共享内存里有一个未使用的 PGPROC 结构链表,从其中给新的后台进程分配 。参见《 PostgresQL 启动过程中的那些事七初始化 ProcGlobal 》 。
当等待锁时,这个 PGPROC 结构被链入锁的等待进程队列。回收后的 PGPROC 链入 ProcGlobal (见《 PostgresQL 启动过程中的那些事七初始化 ProcGlobal 》)的空 闲进程列表。
注意,两阶段提交会为每一个当前已准备事务设置一个假的 PGPROC 。这些 PGPROC 出现在 ProcArray 数据结构里以使已准备事务显示其还在运行并且能正确显示其持有锁。已准备事务的 PGPROC 和真实进程的 PGPROC 的区别是已准备事务的 PGPROC 的 pid 等于 0 。在已准备事务的 PGPROC 里不使用信号和锁行为,但是它的 myProcLocks[] 列表是有效的。
struct PGPROC
{
/* proc ->links 必须是结构的第一个成员 */
SHM_QUEUE links ; /* list link if process is in a list */
PGSemaphoreData sem ; /* ONE semaphore to sleep on */
int waitStatus ; /* STATUS_WAITING, STATUS_OK or STATUS_ERROR */
LocalTransactionId lxid ; /* local id of top-level transaction currently
* being executed by this proc , if running;
* else InvalidLocalTransactionId */
TransactionId xid ; /* id of top-level transaction currently being
* executed by this proc , if running and XID
* is assigned; else InvalidTransactionId */
TransactionId xmin ; /* minimal running XID as it was when we were
* starting our xact , excluding LAZY VACUUM:
* vacuum must not remove tuples deleted by
* xid >= xmin ! */
int pid ; /* Backend's process ID; 0 if prepared xact */
/* 当后台进程仍在启动时这些字段是 0: */
BackendId backendId ; /* This backend's backend ID (if assigned) */
Oid databaseId ; /* OID of database this backend is using */
Oid roleId ; /* OID of role using this backend */
bool inCommit ; /* true if within commit critical section */
uint8 vacuumFlags ; /* vacuum-related flags, see above */
/* 当是热备模式时,显示已为当前事务发出冲突信号。尽管没有要求,当持有 ProcArrayLock 锁事设置 / 消除。如果需要,没有锁可以访问。
bool recoveryConflictPending ;
/* 如果有,是进程当前正在等待的轻量锁的信息 */
bool lwWaiting ; /* true if waiting for an LW lock */
bool lwExclusive ; /* true if waiting for exclusive access */
struct PGPROC * lwWaitLink ; /* next waiter for same LW lock */
/* 如果有,进程当前正在等待的锁的信息 */
/* 如果当前没有等待的锁, waitLock 和 waitProcLock 是 NULL */
LOCK * waitLock ; /* Lock object we're sleeping on ... */
PROCLOCK * waitProcLock ; /* Per-holder info for awaited lock */
LOCKMODE waitLockMode ; /* type of lock we're waiting for */
LOCKMASK heldLocks ; /* bitmask for lock types already held on this
* lock object by this backend */
Latch procLatch ; /* generic latch for process */
/* 如果需要,是允许本进程等待同步复制的信息。如果没有等待的话 waitLSN 的值是 InvalidXLogRecPtr ;仅由用户后台进程设置。除非属主进程或 WALSender 进程可以 touch syncRepState 。仅当持有 SyncRepLock 锁时才可以用 syncRepLinks 。
*/
XLogRecPtr waitLSN ; /* waiting for this LSN or higher */
int syncRepState ; /* wait state for sync rep */
SHM_QUEUE syncRepLinks ; /* list link if process is in syncrep queue */
/* 为锁持有的所有 PROCLOCK 对象或者由该后台进程等待的 PROCLOCK 被链入这些链表中的一个,根据他们锁的分区号。
所有为持有锁或者有后台进程等待的 PROCLOCK 对象被链到这个列表,股他们锁的发布号。
*/
SHM_QUEUE myProcLocks [NUM_LOCK_PARTITIONS];
struct XidCache subxids ; /* cache for subtransaction XIDs */
};
typedef struct SHM_QUEUE
{
struct SHM_QUEUE * prev ;
struct SHM_QUEUE * next ;
} SHM_QUEUE ;
第 10 步行信息
AuxiliaryProcessMain 的流程图
在 AuxiliaryProcessMain 方法中,设置本进程运行模式为引导模式,调用 BaseInit 方法初始化了一个虚拟文件描述符结构 Vfd 的头指针 VfdCache 并注册了进程退出是清理临时文件的函数,接着初始化了存储管理器,这个另行讨论,最后初始化了本地记录每个缓存信息的数组 。然后根据情况 ProcSignalInit 为辅助进程分配 ProcSignalSlot ,调用 InitBufferPoolBackbend 方法,在其中调用 on_shmem_exit 注册共享内存退出清理缓存相关资源要调用的函数 AtProcExit_Buffers 。然后把进程设回通常模式。根据传入参数调用 StartupProcessMain ,设置合适的信号处理句柄,然后调用 StartupXLOG 方法,这个方法有约 1000 行,搞完退出,产生子进程退出信号,激活 postmaster 进程响应该信号句柄 reaper ,启动其它进程。
先到这儿把,下一篇接着讨论 StartupXLOG 方法。
------------
转载请著名出处,来自博客:
blog.csdn.net/beiigang
beigang.iteye.com
发表评论
-
PostgreSQL服务过程中的那些事三:pg服务进程中的内存上下文
2012-12-31 15:07 1995题外话:年底了,就以这篇博文结束2012 ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询六:执行器执行
2012-11-07 20:13 1782话说 查询“ select c ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询五:规划成plantree
2012-10-31 20:37 1642话说 查询“ select cname, comp ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询四:分析重写成querytree
2012-10-24 19:27 1382话说 查询“ select cname, comp ... -
postgresql 小技巧
2012-10-16 19:36 1316Note : #PostgreSQL and ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询三:获取内存快照
2012-10-16 19:31 1731话说 查询“ select cname, comp ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询二:SQL解析为parsetree
2012-10-09 19:50 1486话说 查询“ select cname, comp fr ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询一:开启事务
2012-09-25 19:55 1824在《 PostgreSQL 服务过程中的那些事二: ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程一.八:加载DB基础设施,完成服务进程初始化
2012-09-18 21:02 1737话说调用 InitPostgres ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程一.七:初始化portal管理环境
2012-09-11 19:58 1601话说调用 In ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程一.六:初始化系统表缓存catcache
2012-09-04 20:51 1809话说调用 InitPostgres ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程一.五:初始化relcache管理环境
2012-08-28 20:47 1269话说调用 InitPostgres ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程三:初始化relcache管理环境
2012-08-28 20:46 0<!-- [if gte mso 9]><x ... -
PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询梗概
2012-08-21 21:04 1213话说客户端发起请求, pg 服务器为该请求启动一个 ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程二:建立连接完成
2012-08-13 18:50 15343 这节主要讨论 pg 服务进程 pos ... -
PostgreSQL服务过程中的那些事一:启动postgres服务进程一
2012-08-08 14:42 5640到pg 服务进程了,打算搞一个完整但简单的查询例子,从 ... -
PostgreSQL启动过程中的那些事十九:walwriter进程二
2012-08-03 16:53 13403 这节主要讨论 walwrit ... -
PostgreSQL启动过程中的那些事十九:walwriter进程一
2012-08-01 17:26 1539话说 main()->Po ... -
PostgreSQL启动过程中的那些事十八:bgwriter进程二
2012-07-27 07:25 14003 这节主要讨论 bgwr ... -
PostgreSQL启动过程中的那些事十八:bgwriter进程一
2012-07-23 20:18 1563话说 main()->Postm ...
相关推荐
一、服务器进程的启动和关闭: 一、服务器进程的启动和关闭: 一、服务器进程的启动和关闭: 一、服务器进程的启动和关闭: 一、服务器进程的启动和关闭: 一、服务器进程的启动和关闭: . 50 PostgreSQL PostgreSQL...
数据库的启动与关闭
1、pg_ctl start调用start_postmaster启动PG的主进程后,每隔0.1ms检查一次postmaster.pid文件,是否已写入ready/standby 2、总共会检查600次,即从启动主进程后,最多等待60s,如果没有写入ready/standby则打印...
6. 也可以通过"systemctl status/start/stop postgresql"命令查看PostgreSQL的状态/启动/停用 7. 通过命令"sh pgsql.sh uninstall"可以卸载安装的PostgreSQL 8. 可以通过"sh pgsql.sh -h"查看帮助信息
一、服务器进程的启动和关闭: 下面是pg_ctl命令的使用方法和常用选项,需要指出的是,该命令是postgres命令的封装体,因此在使用上比直接使用postgres更加方便。 代码如下: pg_ctl init[db] [-D DATADIR] [-s]...
进程中有N个postgres.exe(此为正常,见官方文档),却有一个始终占满CPU(由于本机是双核,占用了50%的资源)。自带的pgAdmin III连接会死掉。 此问题在网上搜索没找到答案。 查看日志发现有这样一条错误信息: %t...
Pm2 //生产环境守护进程 Nginx & Apache //生产环境代理请求 */ 启动脚本 npm i //安装依赖 //*修改config 下的dbConfig.js 文件连接数据库 npm start //编译 npm run dev //启动项目 热更新 // '...
2.1 数据目录介绍 2.2 数据库文件的布局 2.3 索引与文件布局 2.4 新增表空间后的布局 2.5 物理文件整体布局 3.1 启动流程介绍 3.2 进程
如果由于意外事件或在部署过程中按比例扩大了时钟进程,这种情况会使旧版本保持运行,直到新版本响应运行状况检查,则可能会出现这种情况。 在服务器启动时运行数据库迁移。 如果您的应用程序得到扩展,则多个进程...
回归测试是一套复杂完整的测试,用来测试嵌入在PostgreSQL...串行模式顺序运行每个测试,而并行模式启动多个服务器进程,并行地运行一组测试。并行测试使我们对进程内部通讯和锁的正确工作有足够的信心。由于历史原因,
国外程序员刷题 PostGres - 启动并运行 ...一种是一组管理存储表的数据库的进程和文件。 继续我们之前的类比,数据库服务器将映射到 Google Sheets。 动词等价 (创建、读取、更新和删除) 、SQL、HTTP
国外程序员刷题PostGres - 启动并运行 ...一种是一组管理存储表的数据库的进程和文件。 继续我们之前的类比,数据库服务器将映射到 Google Sheets。 动词等价 (创建、读取、更新和删除) 、SQL、HTTP
这些过程中的方法有2个缺点:1)您必须确保只有1个进程正在运行计划,否则您可能会多次运行任务; 2)如果1个进程恰好发生故障(由于中断或停机),则有风险。部署),如果计划执行该作业,则将跳过该作业。 ...
通用调度器PostgreSQL通用SQL语句调度程序,无其他依赖项(要求9.5) 这种体系结构基于一个中央调度程序的概念,该进程在必要时启动工作进程。 这比每个数据库一个控制器进程便宜。 它可以启动并运行更多并行的相同...
另外,还有一种‘StandaloneBackend’使用的方式,虽然通过这种方式也可以启动服务器,但是一般只在数据库的初始化(PostgreSQL的cluster的初始化,相当于其他数据库的instance的初始化)、紧急维护的时候使用,所以...
Web应用程序的部署系统,最初用于托管Yesod应用程序。 Keter为您的应用程序执行以下操作: 绑定到主端口(通常是端口80),并根据虚拟主机名向...为了在开发过程中快速启动和运行Keter,请在Ubuntu系统(而不是生产服
PostgreSQL 号称“世界上最先进的开源数据库“,可以运行在多种平台下,是tb级数据库,而且性能也很好 中大型企业 oracle 甲骨文 获得最高认证级别的ISO标准安全认证,性能最高, 保持开放平台下的TPC-D和TPC-C的...
部署说明(该项目需要Node.js和PostgreSQL才能运行): 随附的批处理文件,用于在Windows上启动前端/后端进程,对于其他环境,请使用手动命令PostgreSQL用户和数据库创建在PostgreSQL中使用用户名“ challenger”和...
一台机器上的多个进程可以使用SQLite读写本地ZODB数据库,而无需启动和管理另一个进程(即ZEO)。 Blob可以存储在共享文件系统上,也可以(建议)存储在关系数据库中,并且只能本地缓存。 同一进程中的多个线程...