十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章主要介绍“PostgreSQL在启动时怎么分配共享缓存”,在日常操作中,相信很多人在PostgreSQL在启动时怎么分配共享缓存问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PostgreSQL在启动时怎么分配共享缓存”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
东港网站制作公司哪家好,找创新互联建站!从网页设计、网站建设、微信开发、APP开发、成都响应式网站建设等网站项目制作,到程序开发,运营维护。创新互联建站自2013年起到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联建站。
相信很多人知道 shared_buffers 这个参数,它设置共享缓存的大小,本篇简单讲一下它是怎样分配的。
1、参数设置(src/backend/utils/misc/guc.c)
/* * We sometimes multiply the number of shared buffers by two without * checking for overflow, so we mustn't allow more than INT_MAX / 2. */ { {"shared_buffers", PGC_POSTMASTER, RESOURCES_MEM, gettext_noop("Sets the number of shared memory buffers used by the server."), NULL, GUC_UNIT_BLOCKS }, &NBuffers, 1024, 16, INT_MAX / 2, NULL, NULL, NULL },
可以看到,这个参数在内核中并不是实际内存的大小,而是块数GUC_UNIT_BLOCKS(这个有兴趣可以读guc代码,看起来也有必要单独写一篇。)
假设我们设置512M,编译时选择块尺寸8k,那么应该分配块数是 51210241024/8192,总共65536个块。
2、共享内存的分配
实际上,共享缓存只是共享内存的一部分,这不是我们本篇的重点,所以只是简单一提。数据库启动时计算总共享内存的大小,然后从OS申请(src/backend/storage/buffer/buf_init.c):
Size BufferShmemSize(void) { Size size = 0; /* size of buffer descriptors */ size = add_size(size, mul_size(NBuffers, sizeof(BufferDescPadded))); /* to allow aligning buffer descriptors */ size = add_size(size, PG_CACHE_LINE_SIZE); /* size of data pages */ size = add_size(size, mul_size(NBuffers, BLCKSZ)); ... size = add_size(size, mul_size(NBuffers, sizeof(LWLockMinimallyPadded))); /* to allow aligning the above */ size = add_size(size, PG_CACHE_LINE_SIZE); /* size of checkpoint sort array in bufmgr.c */ size = add_size(size, mul_size(NBuffers, sizeof(CkptSortItem))); ...
还有块描述符、锁、检查点排序区的分配,这里有过大的改动,为了更好的利用cache line,早先版本一个单独的结构体拆成多个。
诸位有兴趣可以找以前的代码做对比,不写这篇文章我都不会看到这变化,对社区补丁关注不够。
3、共享缓存初始化
在申请OS共享内存(见PGSharedMemoryCreate,有多个平台版本)之后,再从中分配(ShmemInitStruct)出上边看到的几个部分,这些代码见src/backend/storage/buffer/buf_init.c:
BufferBlocks = (char *) ShmemInitStruct("Buffer Blocks", NBuffers * (Size) BLCKSZ, &foundBufs);
这是缓存部分的申请,可以看到,它又从共享内存中分配出512M(65536*8192)。
然后就是初始化,各种锁、状态。
4、更多考虑
从上边代码可以看出为什么PG不能动态增加共享缓存,因为它的块描述是一次性分配,然后就不能再改变。考虑下Oracle参数SGA_MAX_SIZE,允许动态分配但有这个上限,可以推断它似乎也有缓存块描述符类似的东西,一次性分配留作以后使用。PG想实现动态管理是不是就有了思路,也不是很难,这取决于共享内存的分配方式,可以阅读 PGSharedMemoryCreate 了解更多,也可以对比以前的老版本,看看分配方式实现有什么不同(记得是 9.1、9.2)。
到此,关于“PostgreSQL在启动时怎么分配共享缓存”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!