-
Notifications
You must be signed in to change notification settings - Fork 17
Last writter lsn cache v2 #191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to move all this to the neon extension, out of xlog.c. But that can be done separately.
src/backend/access/transam/xlog.c
Outdated
struct LastWrittenLsnCacheEntry* next; | ||
struct LastWrittenLsnCacheEntry* prev; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the doubly-linked list macros from ilist.h
. So this would become:
dlist_node lru_node;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't heard the term "L2-List" before. It means a doubly-linked list, right?
|
||
typedef struct LastWrittenLsnCacheEntry | ||
{ | ||
BufferTag key; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, the block number in the BufferTag is the first block of the 8 MB chunk of blocks, right? Would be good to add a comment here. Or maybe at the top of the struct, to explain how the cache works in general.
src/backend/access/transam/xlog.c
Outdated
#define LAST_WRITTEN_LSN_CACHE_BUCKET 1024 /* blocks = 8Mb */ | ||
|
||
|
||
/* | ||
* Cache of last written LSN for each relation chunk (hash bucket). | ||
* Also to provide request LSN for smgrnblocks, smgrexists there is pseudokey=InvalidBlockId which stores LSN of last | ||
* relation metadata update. | ||
* Size of the cache is limited by GUC variable lastWrittenLsnCacheSize ("lsn_cache_size"), | ||
* pages are replaced using LRU algorithm, based on L2-list. | ||
* Access to this cache is protected by 'LastWrittenLsnLock'. | ||
*/ | ||
static HTAB *lastWrittenLsnCache; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move these next to LastWrittenLsnCacheEntry. It's easier to see how it works when they're all together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I do not understand what you mean. LastWrittenLsnCacheEntry
contains prev
and 'next' which you have suggested to replaces with dlist_node lru_node
. Which next
do you mean here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I meant, "let's move these close to LastWrittenLsnCacheEntry". I didn't mean the field next
.
if (lsn > entry->lsn) | ||
entry->lsn = lsn; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should always be true I think. Make it an assertion or at least log a WARNING.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at least if you make it lsn >= entry->lsn
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as ore than one page is mapped to the same chunk, it can be th two backends are setting their last written lsn
concurrently and the order in which this requests will be executed is unpredicatable.
There is no race condition, because access to lst written lsn cache is synchronized using LW-lock.
But still we need to choose maximal LSN, don't we?
Co-authored-by: Heikki Linnakangas <heikki.linnakangas@iki.fi>
14ac745
to
49fdfbc
Compare
Replaced with #200 |
Replace #167