对PostgreSQL中bgwriter的 MyProc 的理解
[作者:技术者高健@博客园 mail: luckyjackgao@gmail.com ]
在bgwriter的代码中,有这样一段,其中的MyProc显得很突兀:
/* * Loop forever */ for (;;) { bool can_hibernate; int rc; /* Clear any already-pending wakeups */ ResetLatch(&MyProc->procLatch); if (got_SIGHUP) { got_SIGHUP = false; ProcessConfigFile(PGC_SIGHUP); } if (shutdown_requested) { /* * From here on, elog(ERROR) should end with exit(1), not send * control back to the sigsetjmp block above */ ExitOnAnyError = true; /* Normal exit from the bgwriter is here */ proc_exit(0); /* done */ } /* * Do one cycle of dirty-buffer writing. */ can_hibernate = BgBufferSync(); /* * Send off activity statistics to the stats collector */ pgstat_send_bgwriter(); if (FirstCallSinceLastCheckpoint()) { /* * After any checkpoint, close all smgr files. This is so we * won't hang onto smgr references to deleted files indefinitely. */ smgrcloseall(); } /* * Sleep until we are signaled or BgWriterDelay has elapsed. * * Note: the feedback control loop in BgBufferSync() expects that we * will call it every BgWriterDelay msec. While it's not critical for * correctness that that be exact, the feedback loop might misbehave * if we stray too far from that. Hence, avoid loading this process * down with latch events that are likely to happen frequently during * normal operation. */ rc = WaitLatch(&MyProc->procLatch, WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, BgWriterDelay /* ms */ ); /* * If no latch event and BgBufferSync says nothing's happening, extend * the sleep in "hibernation" mode, where we sleep for much longer * than bgwriter_delay says. Fewer wakeups save electricity. When a * backend starts using buffers again, it will wake us up by setting * our latch. Because the extra sleep will persist only as long as no * buffer allocations happen, this should not distort the behavior of * BgBufferSync's control loop too badly; essentially, it will think * that the system-wide idle interval didn't exist. * * There is a race condition here, in that a backend might allocate a * buffer between the time BgBufferSync saw the alloc count as zero * and the time we call StrategyNotifyBgWriter. While it's not * critical that we not hibernate anyway, we try to reduce the odds of * that by only hibernating when BgBufferSync says nothing's happening * for two consecutive cycles. Also, we mitigate any possible * consequences of a missed wakeup by not hibernating forever. */ if (rc == WL_TIMEOUT && can_hibernate && prev_hibernate) { /* Ask for notification at next buffer allocation */ StrategyNotifyBgWriter(&MyProc->procLatch); /* Sleep ... */ rc = WaitLatch(&MyProc->procLatch, WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, BgWriterDelay * HIBERNATE_FACTOR); /* Reset the notification request in case we timed out */ StrategyNotifyBgWriter(NULL); } /* * Emergency bailout if postmaster has died. This is to avoid the * necessity for manual cleanup of all postmaster children. */ if (rc & WL_POSTMASTER_DEATH) exit(1); prev_hibernate = can_hibernate; }
MyProc究竟从哪里来呢?在proc.h中有说明:
/** Each backend has a PGPROC struct in shared memory. There is also a list of* currently-unused PGPROC structs that will be reallocated to new backends.** links: list link for any list the PGPROC is in. When waiting for a lock,* the PGPROC is linked into that lock's waitProcs queue. A recycled PGPROC* is linked into ProcGlobal's freeProcs list.** Note: twophase.c also sets up a dummy PGPROC struct for each currently* prepared transaction. These PGPROCs appear in the ProcArray data structure* so that the prepared transactions appear to be still running and are* correctly shown as holding locks. A prepared transaction PGPROC can be* distinguished from a real one at need by the fact that it has pid == 0.* The semaphore and lock-activity fields in a prepared-xact PGPROC are unused,* but its myProcLocks[] lists are valid.*/ struct PGPROC {/* proc->links MUST BE FIRST IN STRUCT (see ProcSleep,ProcWakeup,etc) */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 */Latch procLatch; /* generic latch for process */LocalTransactionId lxid; /* local id of top-level transaction currently* being executed by this proc, if running;* else InvalidLocalTransactionId */int pid; /* Backend's process ID; 0 if prepared xact */int pgprocno;/* These fields are zero while a backend is still starting up: */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 *//** While in hot standby mode, shows that a conflict signal has been sent* for the current transaction. Set/cleared while holding ProcArrayLock,* though not required. Accessed without lock, if needed.*/bool recoveryConflictPending;/* Info about LWLock the process is currently waiting for, if any. */bool lwWaiting; /* true if waiting for an LW lock */uint8 lwWaitMode; /* lwlock mode being waited for */struct PGPROC *lwWaitLink; /* next waiter for same LW lock *//* Info about lock the process is currently waiting for, if any. *//* waitLock and waitProcLock are NULL if not currently waiting. */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 *//** Info to allow us to wait for synchronous replication, if needed.* waitLSN is InvalidXLogRecPtr if not waiting; set only by user backend.* syncRepState must not be touched except by owning process or WALSender.* syncRepLinks used only while holding SyncRepLock.*/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 *//** All PROCLOCK objects for locks held or awaited by this backend are* linked into one of these lists, according to the partition number of* their lock.*/SHM_QUEUE myProcLocks[NUM_LOCK_PARTITIONS];struct XidCache subxids; /* cache for subtransaction XIDs *//* Per-backend LWLock. Protects fields below. */LWLockId backendLock; /* protects the fields below *//* Lock manager data, recording fast-path locks taken by this backend. */uint64 fpLockBits; /* lock modes held for each fast-path slot */Oid fpRelId[FP_LOCK_SLOTS_PER_BACKEND]; /* slots for rel oids */bool fpVXIDLock; /* are we holding a fast-path VXID lock? */LocalTransactionId fpLocalTransactionId; /* lxid for fast-path VXID* lock */ };/* NOTE: "typedef struct PGPROC PGPROC" appears in storage/lock.h. */extern PGDLLIMPORT PGPROC *MyProc; extern PGDLLIMPORT struct PGXACT *MyPgXact;
其中有一段说的:
/*
* Each backend has a PGPROC struct in shared memory. There is also a list of
* currently-unused PGPROC structs that will be reallocated to new backends.
*
也就是说,bgwriter 也好,wal writer 也罢,都有一个 类似的结构在内存中,而各个后台进程,就是靠着这个内存结构进行着一些通信。
再看这个
rc = WaitLatch(&MyProc->procLatch, WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, BgWriterDelay /* ms */ ); 看unix 平台上的 unix_latch.c 代码:
/** Wait for a given latch to be set, or for postmaster death, or until timeout* is exceeded. 'wakeEvents' is a bitmask that specifies which of those events* to wait for. If the latch is already set (and WL_LATCH_SET is given), the* function returns immediately.** The 'timeout' is given in milliseconds. It must be >= 0 if WL_TIMEOUT flag* is given. On some platforms, signals do not interrupt the wait, or even* cause the timeout to be restarted, so beware that the function can sleep* for several times longer than the requested timeout. However, this* difficulty is not so great as it seems, because the signal handlers for any* signals that the caller should respond to ought to be programmed to end the* wait by calling SetLatch. Ideally, the timeout parameter is vestigial.** The latch must be owned by the current process, ie. it must be a* backend-local latch initialized with InitLatch, or a shared latch* associated with the current process by calling OwnLatch.** Returns bit mask indicating which condition(s) caused the wake-up. Note* that if multiple wake-up conditions are true, there is no guarantee that* we return all of them in one call, but we will return at least one.*/ int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout) {return WaitLatchOrSocket(latch, wakeEvents, PGINVALID_SOCKET, timeout); }
第一个参数就是 latch了,这个是必须的。第二个就是 事件,第三个是超时参数。
[作者:技术者高健@博客园 mail: luckyjackgao@gmail.com ]
结束
对PostgreSQL中bgwriter的 MyProc 的理解相关推荐
- PostgreSQL中的io多路复用--select和epoll实现
某天和同事闲聊,同事发现一个现象,PostgreSQL在空闲状态时(没有active连接),主进程的pstack显示一直在调用/lib64/libc.so.6的__select_nocancel () ...
- PostgreSQL 中的引号与大小写
单双引号 单引号用来标识实际的值,双引号用来标识表名(table name)或列名(column name)等数据库中存在的值. select "name" from " ...
- postgresql 插入 时间戳_数据也玩躲猫猫?PostgreSQL中别人提交的数据,我为什么看不到?...
原创: Aken DB印象 文章链接:https://mp.weixin.qq.com/s/OkJaWbzcXcJtzSCOFnqeXQ 文章作为DB的学习体会,若有错误欢迎指导. 一.环境介绍 操作 ...
- Postgresql杂谈 04—Postgresql中的五种常规索引
一.索引的分类 Postgresql中索引一共分为5种,每一种都有它合适的应用场景,我们在使用时要根据不同业务的特点,选择合适的索引,这样才能加快sql语句的查询效率.下面,我们将就每种不同的索引,介 ...
- Postgresql杂谈 20—详解Postgresql中的Checkpoint、WAL日志和热备份恢复
本文中,我们共同学习下Postgresql的WAL日志.WAL,是Write Ahead Log的简称,翻译过来就是预写日志,或者叫做重做日志.相信大家对数据库事务的四大特性ACID(原子性.一致性. ...
- Postgresql中的large object
1.初识postgresql large object 一位同事在对使用pg_dump备份出来的文件(使用plain格式)进行恢复时,觉得速度非常慢,让我分析一下是什么原因. 我拿到他的.bak文件, ...
- PostgreSQL中的查询:1.查询执行阶段
PostgreSQL中的查询:1.查询执行阶段 开始关于PG内部执行机制的文章系列.这一篇侧重于查询计划和执行机制. 本系列包括: 1.查询执行阶段(本文) 2.统计数据 3.顺序扫描 4.索引扫描 ...
- PostgreSQL中的索引—6(SP-GiST)
目录 SP-GiST 架构 示例:四叉树 内部构件 示例:k维树 内部构件 示例:基数树 内部构件 属性 NULL 其他数据类型 我们已经介绍了Postgresql索引引擎.访问方法接口和三种方法:哈 ...
- pg数据库json数据类型_科学网—如何使用PostgreSQL中的JSONB数据类型(PG JSON系列2) - 孙鹏的博文...
上一篇 使用PostgreSQL中的row_to_json()直接获得JSON(PG JSON系列1)主要针对现有的非json/jsonb类型如何输出json结果,这一篇主要写一下在数据库设计中直接使 ...
最新文章
- mysql启动后在哪里编程_启动mysql后怎么连接数据库
- 从粗放到精细,如何用AI技术实现信息流广告投放的降本增效
- Python元组与字典详解
- zigbee抗干扰matlab仿真,基于Zigbee的扩频通信MATLAB仿真.doc
- UI5 xml view里control id的生成逻辑
- PWN-PRACTICE-BUUCTF-8
- 这是一个非常不错的mkv编辑制作的软件!
- react-native 第三方库
- 如何不获取root权限使用第三方主题:MIUI篇
- excel表转成PDF文档
- vscode 设置关键字高亮显示
- 第三章 集合的基本概念和运算
- 【Qt】仿QQ表情选择控件
- 【SpringBoot】SpringBoot的banner制作
- 基于Docker的frp内网穿透
- 【GTASA】如何解锁Locked的DFF模型
- 苹果CMS海螺模版V4.0修复版
- PyQt5 QtChart-曲线图
- ALtera DE2开发板学习
- 《java编程思想》第七章 复用类