博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bgwriter 的睡眠时间差异
阅读量:6387 次
发布时间:2019-06-23

本文共 7823 字,大约阅读时间需要 26 分钟。

开始

简单说就是一开始启动的很频繁(200ms 级),后来没有什么事情可做,就懒惰了。变成了 10秒级别。

实际验证如下

postgresql.conf 中和 log 相关部分:

log_line_prefix = '%m'        log_min_messages = info        logging_collector = off

对 bufmgr.c 的 BgBufferSync的调试:

bool                BgBufferSync(void)                {                                    ……                /* Execute the LRU scan */                while (num_to_scan > 0 && reusable_buffers < upcoming_alloc_est)                {                                                    //added by gaojian                                fprintf(stderr,"num_to_scan is: %d \n",num_to_scan);                                int    buffer_state = SyncOneBuffer(next_to_clean, true);                            if (++next_to_clean >= NBuffers)                {                    next_to_clean = 0;                                elog(INFO,"------------------next_passes++.\n");                next_passes++;            }                num_to_scan--;                                if (buffer_state & BUF_WRITTEN)                {                    reusable_buffers++;                if (++num_written >= bgwriter_lru_maxpages)                {                    BgWriterStats.m_maxwritten_clean++;                break;            }            }                else if (buffer_state & BUF_REUSABLE)                    reusable_buffers++;        }                                elog(INFO,".......BgBufferSync Called.");                /* Return true if OK to hibernate */                return (bufs_to_lap == 0 && recent_alloc == 0);            }

运行的结果是:

[作者:技术者高健@博客园  mail:  ]

[postgres@localhost bin]$ ./postgres -D /usr/local/pgsql/data2012-11-02 16:09:55.139 CSTLOG:  database system was shut down at 2012-11-02 16:01:26 CSTsaved_info_valid false.2012-11-02 16:09:55.199 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:09:55.199 CSTLOG:  autovacuum launcher started2012-11-02 16:09:55.201 CSTLOG:  database system is ready to accept connections2012-11-02 16:09:55.399 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:09:55.599 CSTINFO:  .......BgBufferSync Called.……2012-11-02 16:12:11.350 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:12:11.550 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:12:11.751 CSTINFO:  ------------------next_passes++.2012-11-02 16:12:11.751 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:12:11.951 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:12:12.151 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:12:22.360 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:12:32.568 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:12:42.777 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:12:52.985 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:13:03.194 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:13:13.403 CSTINFO:  .......BgBufferSync Called.2012-11-02 16:13:23.614 CSTINFO:  .......BgBufferSync Called.

bgwriter 会在循环中 睡眠-->醒来->调用BgBufferSync-->睡眠。

基本上,其睡眠应该分”浅睡眠“和”深睡眠“

再回头来看 bgwriter.c 的代码:

/*                             * GUC parameters                             */                            int            BgWriterDelay = 200;                                            /*                             * Multiplier to apply to BgWriterDelay when we decide to hibernate.                             * (Perhaps this needs to be configurable?)                             */                            #define HIBERNATE_FACTOR            50                                            ……                                                        /*                             * Main entry point for bgwriter process                             *                             * This is invoked from AuxiliaryProcessMain, which has already created the                             * basic execution environment, but not enabled signals yet.                             */                            void                            BackgroundWriterMain(void)                            {                                ……                            /*                             * Loop forever                             */                            for (;;)                            {                                ……                                                        /*                             * 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);                        }                            ……                        }                        }

可以看到,一开始是睡   BgWriterDelay 就会醒。

然后,睡了若干次再醒后,如果发现  (rc == WL_TIMEOUT && can_hibernate && prev_hibernate) 得到了满足。

那么, 就进入新的睡眠模式:

/* Sleep ... */

rc = WaitLatch(&MyProc->procLatch,
    WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
      BgWriterDelay * HIBERNATE_FACTOR);

最后一个参数变成了  BgWriterDelay * HIBERNATE_FACTOR 正好等于 10秒。

[作者:技术者高健@博客园  mail:  ]

结束

转载地址:http://lnbha.baihongyu.com/

你可能感兴趣的文章
Mqtt ----心跳机制
查看>>
180404
查看>>
远程连接身份验证错误,又找不到加密Oracle修正
查看>>
C++三种内存分配方式
查看>>
谷歌为URL缩短服务goo.gl开放API
查看>>
关于delphi 窑洞的关闭
查看>>
测试基础 – 软件测试计划
查看>>
os-cocos2d游戏开发基础-进度条-开发笔记
查看>>
[Hibernate]在VS2010中应用NHibernate 3.2与MySQL
查看>>
Velocity与JSP技术比较
查看>>
硬盘重装Ubuntu12.04的感受
查看>>
jQuery 2.0.3 源码分析 Deferred(最细的实现剖析,带图)
查看>>
Android json操作之取得一个对象
查看>>
Android的历史与花边
查看>>
myeclipse6.0下载及注冊码
查看>>
Android开发之大位图二次採样压缩处理(源码分享)
查看>>
Count Complete Tree Nodes
查看>>
Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持
查看>>
深入理解PHP内核(四)概览-PHP脚本的执行
查看>>
[RxJS] Displaying Initial Data with StartWith
查看>>