日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

对PostgreSQL中后台进程内存挂载的初步学习

發布時間:2023/12/10 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对PostgreSQL中后台进程内存挂载的初步学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

開始

從 CreateSharedMemoryAndSemaphores?開始:

對于 Postmaster 的各個子進程而言,內存結構在 Postmaster 中已經建立,只是需要掛到各子進程自己的本地變量上。

/* * CreateSharedMemoryAndSemaphores * Creates and initializes shared memory and semaphores. * * This is called by the postmaster or by a standalone backend. * It is also called by a backend forked from the postmaster in the * EXEC_BACKEND case. In the latter case, the shared memory segment * already exists and has been physically attached to, but we have to * initialize pointers in local memory that reference the shared structures, * because we didn't inherit the correct pointer values from the postmaster * as we do in the fork() scenario. The easiest way to do that is to run * through the same code as before. (Note that the called routines mostly * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case. * This is a bit code-wasteful and could be cleaned up.) * * If "makePrivate" is true then we only need private memory, not shared * memory. This is true for a standalone backend, false for a postmaster. */ void CreateSharedMemoryAndSemaphores(bool makePrivate, int port) { …… /* * Set up shmem.c index hashtable */ InitShmemIndex(); /* * Set up xlog, clog, and buffers */ XLOGShmemInit(); CLOGShmemInit(); SUBTRANSShmemInit(); MultiXactShmemInit(); InitBufferPool(); /* * Set up lock manager */ InitLocks(); /* * Set up predicate lock manager */ InitPredicateLocks(); /* * Set up process table */ if (!IsUnderPostmaster) InitProcGlobal(); CreateSharedProcArray(); CreateSharedBackendStatus(); TwoPhaseShmemInit(); /* * Set up shared-inval messaging */ CreateSharedInvalidationState(); /* * Set up interprocess signaling mechanisms */ PMSignalShmemInit(); ProcSignalShmemInit(); CheckpointerShmemInit(); AutoVacuumShmemInit(); WalSndShmemInit(); WalRcvShmemInit(); /* * Set up other modules that need some shared memory space */ BTreeShmemInit(); SyncScanShmemInit(); AsyncShmemInit(); #ifdef EXEC_BACKEND /* * Alloc the win32 shared backend array */ if (!IsUnderPostmaster) ShmemBackendArrayAllocation(); #endif /* * Now give loadable modules a chance to set up their shmem allocations */ if (shmem_startup_hook) shmem_startup_hook(); }

接著看?InitShmemIndex

/* * InitShmemIndex() --- set up or attach to shmem index table. */ void InitShmemIndex(void) { HASHCTL info; int hash_flags; /* * Create the shared memory shmem index. * * Since ShmemInitHash calls ShmemInitStruct, which expects the ShmemIndex * hashtable to exist already, we have a bit of a circularity problem in * initializing the ShmemIndex itself. The special "ShmemIndex" hash* table name will tell ShmemInitStruct to fake it. */ info.keysize = SHMEM_INDEX_KEYSIZE; info.entrysize = sizeof(ShmemIndexEnt); hash_flags = HASH_ELEM; ShmemIndex = ShmemInitHash("ShmemIndex", SHMEM_INDEX_SIZE, SHMEM_INDEX_SIZE,&info, hash_flags); }

然后是?ShmemInitHash,重點要關注 hash_flag 的設置

/* * ShmemInitHash -- Create and initialize, or attach to, a * shared memory hash table. * * We assume caller is doing some kind of synchronization * so that two processes don't try to create/initialize the same * table at once. (In practice, all creations are done in the postmaster * process; child processes should always be attaching to existing tables.) * * max_size is the estimated maximum number of hashtable entries. This is * not a hard limit, but the access efficiency will degrade if it is * exceeded substantially (since it's used to compute directory size and * the hash table buckets will get overfull). * * init_size is the number of hashtable entries to preallocate. For a table * whose maximum size is certain, this should be equal to max_size; that * ensures that no run-time out-of-shared-memory failures can occur. * * Note: before Postgres 9.0, this function returned NULL for some failure * cases. Now, it always throws error instead, so callers need not check * for NULL. */ HTAB * ShmemInitHash(const char *name, /* table string name for shmem index */ long init_size, /* initial table size */ long max_size, /* max size of the table */ HASHCTL *infoP, /* info about key and bucket size */ int hash_flags) /* info about infoP */ { bool found; void *location; /* * Hash tables allocated in shared memory have a fixed directory; it can't * grow or other backends wouldn't be able to find it. So, make sure we * make it big enough to start with. * * The shared memory allocator must be specified too. */ infoP->dsize = infoP->max_dsize = hash_select_dirsize(max_size); infoP->alloc = ShmemAlloc; hash_flags |= HASH_SHARED_MEM | HASH_ALLOC | HASH_DIRSIZE; /* look it up in the shmem index */ location = ShmemInitStruct(name, hash_get_shared_size(infoP, hash_flags), &found); /* * if it already exists, attach to it rather than allocate and initialize * new space */ if (found) hash_flags |= HASH_ATTACH; /* Pass location of hashtable header to hash_create */ infoP->hctl = (HASHHDR *) location; return hash_create(name, init_size, infoP, hash_flags); }

再下來:

/* * hash_create -- create a new dynamic hash table * * tabname: a name for the table (for debugging purposes) * nelem: maximum number of elements expected * *info: additional table parameters, as indicated by flags * flags: bitmask indicating which parameters to take from *info * * Note: for a shared-memory hashtable, nelem needs to be a pretty good * estimate, since we can't expand the table on the fly. But an unshared * hashtable can be expanded on-the-fly, so it's better for nelem to be * on the small side and let the table grow if it's exceeded. An overly * large nelem will penalize hash_seq_search speed without buying much. */ HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags) { …… if (flags & HASH_SHARED_MEM) { /* * ctl structure and directory are preallocated for shared memory * tables. Note that HASH_DIRSIZE and HASH_ALLOC had better be set as * well. */ hashp->hctl = info->hctl; hashp->dir = (HASHSEGMENT *) (((char *) info->hctl) + sizeof(HASHHDR)); hashp->hcxt = NULL; hashp->isshared = true; /* hash table already exists, we're just attaching to it */ if (flags & HASH_ATTACH) { /* make local copies of some heavily-used values */ hctl = hashp->hctl; hashp->keysize = hctl->keysize; hashp->ssize = hctl->ssize; hashp->sshift = hctl->sshift; return hashp; } } else { …… } …… return hashp; }

[作者:技術者高健@博客園 ?mail:?luckyjackgao@gmail.com?]

結束

轉載于:https://www.cnblogs.com/gaojian/archive/2012/11/06/2757116.html

總結

以上是生活随笔為你收集整理的对PostgreSQL中后台进程内存挂载的初步学习的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。