BackgroundWriterMain代码
来源:互联网 发布:投针法计算圆周率c语言 编辑:程序博客网 时间:2024/05/16 15:09
提示:
由于工作原因文章还没有弄完,请跳过,弄完后,会删除此提示
基础流程:
BackgroundWriterMainBgBuffferSync->SyncOneBuffer-> FlushBuffer()-> smgrwrite()
逻辑部分
首先代码定义一些基础类型和变量,例如:信号的处理,bgwrite的内存上下文,错误处理机制等。 然后,进入后台写进程,后台写进程是一个死循环进程,启动后,如果没有一些特殊情况(如:master死亡,关机等信号)就会一直运行。 此函数主要做一些简单的工作,如,监听信号(重新加载、关机等信号)确定是否退出或者重载。 调用落盘函数接口(BgBufferSync),将落盘动作返回的统计动作发送给stat统计表。 做一些简单的判断判断是否要进入一个长时间的睡眠(如果超过WL_TIMEOUT,并且连续两次没有落盘动作,就会进入一个长时间的睡眠)。 如果睡眠时间到,或者睡眠期间有内存的分配操作,就会醒来。然后再次循环。
代码部分
voidBackgroundWriterMain(void){ sigjmp_buf local_sigjmp_buf; //解析:定义错误恢复变量,保存错误后信号 MemoryContext bgwriter_context; //解析:定义内存上下文 bool prev_hibernate; //解析:定义预先睡眠,后面用来确定是否进入一个深度睡眠 WritebackContext wb_context; //解析:定义后台写进程上下文 //内存上下文解析: //1.pg是基于进程的,每个进程拥有一块内存,分配内存上下文为了方便内存的处理。 //2.方便错误处理,自己进行内存的管理,方便错误发生时进行恢复操作。 pqsignal(SIGHUP, BgSigHupHandler); /* set flag to read config file */ pqsignal(SIGINT, SIG_IGN); pqsignal(SIGTERM, ReqShutdownHandler); /* shutdown */ pqsignal(SIGQUIT, bg_quickdie); /* hard crash time */ pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, bgwriter_sigusr1_handler); pqsignal(SIGUSR2, SIG_IGN); /* * Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); pqsignal(SIGTTIN, SIG_DFL); pqsignal(SIGTTOU, SIG_DFL); pqsignal(SIGCONT, SIG_DFL); pqsignal(SIGWINCH, SIG_DFL); /* We allow SIGQUIT (quickdie) at all times */ sigdelset(&BlockSig, SIGQUIT); //上面是对一些信号的注册 CurrentResourceOwner = ResourceOwnerCreate(NULL, "Background Writer"); //创建一个资源所有者来与我们的资源保持联系 /* * We just started, assume there has been either a shutdown or end-of-recovery 快照. */ last_snapshot_ts = GetCurrentTimestamp(); bgwriter_context = AllocSetContextCreate(TopMemoryContext, "Background Writer", ALLOCSET_DEFAULT_MINSIZE,ALLOCSET_DEFAULT_INITSIZE,ALLOCSET_DEFAULT_MAXSIZE); //创建一个内存上下文,内存上下文的作用见:内存上下文篇 MemoryContextSwitchTo(bgwriter_context); //切换内存上下文 WritebackContextInit(&wb_context, &bgwriter_flush_after); //下面是做错误恢复和检查用的,后期做整理 if (sigsetjmp(local_sigjmp_buf, 1) != 0) { /* Since not using PG_TRY, must reset error stack by hand */ error_context_stack = NULL; /* Prevent interrupts while cleaning up */ HOLD_INTERRUPTS(); /* Report the error to the server log */ EmitErrorReport(); /* * These operations are really just a minimal subset of AbortTransaction(). * We don't have very many resources to worry about in bgwriter, but we do have LWLocks, buffers, and temp files. */ LWLockReleaseAll(); AbortBufferIO(); UnlockBuffers(); /*释放 buffer pins : */ ResourceOwnerRelease(CurrentResourceOwner, RESOURCE_RELEASE_BEFORE_LOCKS, false, true); /* we needn't bother with the other ResourceOwnerRelease phases */ AtEOXact_Buffers(false); AtEOXact_SMgr(); AtEOXact_Files(); AtEOXact_HashTables(false); /* * Now return to normal top-level context and clear ErrorContext for * next time. */ MemoryContextSwitchTo(bgwriter_context); FlushErrorState(); /* Flush any leaked data in the top-level context */ MemoryContextResetAndDeleteChildren(bgwriter_context); /* re-initilialize to avoid repeated errors causing problems */ WritebackContextInit(&wb_context, &bgwriter_flush_after); /* Now we can allow interrupts again */ RESUME_INTERRUPTS(); /* * Sleep at least 1 second after any error. * A write error is likely to be repeated, and we don't want to be filling the error logs as fast as we can. */ pg_usleep(1000000L); /* * Close all open files after any error. This is helpful on Windows, * where holding deleted files open causes various strange errors. * It's not clear we need it elsewhere, but shouldn't hurt. */ smgrcloseall(); /* Report wait end here, when there is no further possibility of wait */ pgstat_report_wait_end(); } /* We can now handle ereport(ERROR) */ PG_exception_stack = &local_sigjmp_buf; /* * Unblock signals (they were blocked when the postmaster forked us) */ PG_SETMASK(&UnBlockSig); /* * Reset hibernation state after any error. */ prev_hibernate = false; //开始进入后台写进程的流程 for (;;) { bool can_hibernate; //定义bool变量确定是否进入长时间的睡眠,可以认为是一个开关变量 int rc; /* Clear any already-pending wakeups */ ResetLatch(MyLatch); //判断是否接受到SIGHUP信号,接收到后重新加载配置文件 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 */ } // 重中之重,进行一次脏数据的落盘操作,根据落盘状况重置开关变量can_hibernate,确定是否需要进入一次长时间睡眠。 can_hibernate = BgBufferSync(&wb_context); //将统计数据发送到stats collector pgstat_send_bgwriter(); //判断是否是checkpoint后的第一次操作 if (FirstCallSinceLastCheckpoint()) { /* * After any checkpoint, close all smgr files. * This is so we won't hang onto smgr * references to deleted files indefinitely. * */ smgrcloseall(); } //判断Log记录level 并且系统没有在recovery。 if (XLogStandbyInfoActive() && !RecoveryInProgress()) { TimestampTz timeout = 0; TimestampTz now = GetCurrentTimestamp(); timeout =TimestampTzPlusMilliseconds(last_snapshot_ts, LOG_SNAPSHOT_INTERVAL_MS); /* * only log if enough time has passed and some xlog record has been inserted. * 只有xlog已经落盘足够时间 */ if (now >= timeout &&last_snapshot_lsn != GetXLogInsertRecPtr()) { last_snapshot_lsn = LogStandbySnapshot(); last_snapshot_ts = now; } } //判断WaitLatch是由于哪种原因造成的返回 rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, BgWriterDelay /* ms */ ); //如果没有latch 事件,并且BgBufferSync没有落盘脏数据,函数就会睡眠一个比较长的时间。一旦有内存的分配,它就会被唤醒. if (rc == WL_TIMEOUT && can_hibernate && prev_hibernate) { /* Ask for notification at next buffer allocation */ StrategyNotifyBgWriter(MyProc->pgprocno); /* Sleep ... */ rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, BgWriterDelay * HIBERNATE_FACTOR); /* Reset the notification request in case we timed out */ StrategyNotifyBgWriter(-1); } //如果是由于master进程死亡造成的返回,进程退出,否则的话 if (rc & WL_POSTMASTER_DEATH) exit(1); prev_hibernate = can_hibernate; }
1 0
- BackgroundWriterMain代码
- 代码
- 代码!
- 代码
- 代码
- 代码
- 代码
- 代码
- 代码
- 代码
- 代码
- 代码
- 代码
- 代码
- 代码
- 代码
- 代码
- 代码
- js实现冒泡排序
- win7 32位系统下安装paddle
- .gitignore简介
- bzoj1600(排列组合)
- 接口--制作接口
- BackgroundWriterMain代码
- Microsoft SQL Server,错误2
- 计算机图像处理领域重要期刊汇总
- 最终排名
- java/android 使用swig编译c/c++ 代码类型转换
- Git中三种文件状态及其转换
- LINUX下Oracle数据库用户创建方法详解
- 朴素贝叶斯算法的参数的最大似然估计
- 多态理解