postgresql的buffer descriptor

postgresql的buffer descriptor,第1张

概述本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/15195807   在Oracle里,曾经被itpub吵得沸沸扬扬的buffer,buffer handle概念已经逐渐冷淡下来。当年的热闹也仅仅停留在官方文档,以及一些猜测层面。 现在Oracle在互联网公司(主要是阿里巴巴)已经被逐渐铲除。开源技术攻

本文原创为freas_1990,转载请标明出处:http://www.jb51.cc/article/p-zzldlbjr-yu.html

在Oracle里,曾经被itpub吵得沸沸扬扬的buffer,buffer handle概念已经逐渐冷淡下来。当年的热闹也仅仅停留在官方文档,以及一些猜测层面。

现在Oracle在互联网公司(主要是阿里巴巴)已经被逐渐铲除。开源技术攻城略地之势越见明显。

为了纪念曾经的热闹,我们从开源的postgresql层面来看一下buffer descriptor是什么概念吧。

基于原代码分析,不贴文档,不掉书袋,直接贴源代码。

/* *  struct sbufdesc -- shared buffer cache Metadata for a single *		       shared buffer descriptor. * *	We keep the name of the database and relation in which this *	buffer appears in order to avoID a catalog lookup on cache *	flush if we don't have the reldesc in the cache.  It is also *	possible that the relation to which this buffer belongs is *	not visible to all backends at the time that it gets flushed. *	Dbname,relname,dbID,and relID are enough to determine where *	to put the buffer,for all storage managers. */struct sbufdesc {    Buffer		freeNext;	/* link for freeList chain */    Buffer		freePrev;    SHMEM_OFFSET	data;		/* pointer to data in buf pool */    /* tag and ID must be together for table lookup to work */    BufferTag		tag;		/* file/block IDentifIEr */    int			buf_ID;		/* maps global desc to local desc */    BufFlags		flags;    	/* described below */    int16		bufsmgr;	/* storage manager ID for buffer */    unsigned		refcount;	/* # of times buffer is pinned */    char sb_dbname[nameDATALEN+1];	/* name of db in which buf belongs */    char sb_relname[nameDATALEN+1];	/* name of reln */#ifdef HAS_TEST_AND_SET    /* can afford a dedicated lock if test-and-set locks are available */    slock_t	io_in_progress_lock;#endif /* HAS_TEST_AND_SET */    /*     * I padded this structure to a power of 2 (128 bytes on a MIPS) because     * BufferDescriptorGetBuffer is called a billion times and it does an     * C pointer subtraction (i.e.,"x - y" -> array index of x relative     * to y,which is calculated using division by struct size).  Integer     * ".div" hits you for 35 cycles,as opposed to a 1-cycle "sra" ...     * this Hack cut 10% off of the time to create the Wisconsin database!     * It eats up more shared memory,of course,but we're (allegedly)     * going to make some of these types bigger soon anyway... -pma 1/2/93     *//* NO spinlock */#if defined(PORTname_ultrix4)    char		sb_pad[60];	/* no slock_t */#endif /* mips *//* HAS_TEST_AND_SET -- platform dependent size */#if defined(PORTname_aix)    char		sb_pad[44];	/* typedef unsigned int slock_t; */#endif /* aix */#if defined(PORTname_Alpha)    char		sb_pad[40];	/* typedef msemaphore slock_t; */#endif /* Alpha */#if defined(PORTname_hpux)    char		sb_pad[44];	/* typedef struct { int sem[4]; } slock_t; */#endif /* hpux */#if defined(PORTname_irix5)    char		sb_pad[44];	/* typedef abilock_t slock_t; */#endif /* irix5 */#if defined(PORTname_next)    char		sb_pad[56];	/* typedef struct mutex slock_t; */#endif /* next *//* HAS_TEST_AND_SET -- default 1 byte spinlock */#if defined(PORTname_BSD44_derived) || \    defined(PORTname_bsdi) || \    defined(PORTname_bsdi_2_1) || \    defined(PORTname_i386_solaris) || \    defined(PORTname_linux) || \    defined(PORTname_sparc) || \    defined(PORTname_sparc_solaris)    char		sb_pad[56];	/* has slock_t */#endif /* 1 byte slock_t */};


开头的两个域:freeNext,freePrev是典型的双向链表知识,不多做阐述。

SHMEM_OFFSET data;定义了当前buffer的内存地址。由于buffer是在共享内存内,这个地址其实是一个“unsigned long”类型(参考postgresql共享内存之——分片(slice))。

refcount这个域是一个老概念了,在redis源代码解析系列里曾经提到过,也就是这个buffer(或者内存对象)被引用的次数。postgresql(或者Oracle)里的buffer pin即起源于这里。

当refcount非0时,说明当前buffer正在被使用,此时,应该被pin住。

/* HAS_TEST_AND_SET -- default 1 byte spinlock */#if defined(PORTname_BSD44_derived) || \    defined(PORTname_bsdi) || \    defined(PORTname_bsdi_2_1) || \    defined(PORTname_i386_solaris) || \    defined(PORTname_linux) || \    defined(PORTname_sparc) || \    defined(PORTname_sparc_solaris)    char		sb_pad[56];	/* has slock_t */#endif /* 1 byte slock_t */

这里为每个平台预留了1 byte的空间用做“自旋锁”。

顺便提一下。Oracle 10g里采用了mutex机制,并与之前的latch机制做了比较。窃以为,没有读到源代码,光看一些官方宣传文档,对mutex和latch机制做出评价都是在瞎扯淡。

总结

以上是内存溢出为你收集整理的postgresql的buffer descriptor全部内容,希望文章能够帮你解决postgresql的buffer descriptor所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1177664.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存