Commit 2bd90b44 authored by marko's avatar marko

branches/innodb+: When buffering an insert, notify the buffer pool

watch.  This should fix the race condition that seems to have caused
Issue #126: When another thread is buffering an insert for the record
that is being purged, it should invoke buf_pool_watch_notify(), so
that the purge will not be buffered. Otherwise, the purge would be
buffered for the wrong record (one that was inserted after the purge
determined that the record can be removed).

When deletes are not buffered, the latch on the secondary index page
would prevent the insert from occurring.  In delete buffering, the
buf_pool_watch replaces the page latch when the page is not in the
buffer pool.

buf_pool_watch_notify(): Make public.

ibuf_insert(): Invoke buf_pool_watch_notify() when buffering an
insert or a delete-mark operation.
parent 838b6909
...@@ -2506,13 +2506,13 @@ buf_page_init_low( ...@@ -2506,13 +2506,13 @@ buf_page_init_low(
} }
/************************************************************************ /************************************************************************
Set watch happened flag. */ Set watch occurred flag. */
UNIV_INLINE UNIV_INTERN
void void
buf_pool_watch_notify( buf_pool_watch_notify(
/*==================*/ /*==================*/
ulint space, /* in: space id of page read in */ ulint space, /* in: space id of page read in */
ulint offset) /* in: offset of page read in */ ulint offset) /* in: offset of page read in */
{ {
ut_ad(buf_pool_mutex_own()); ut_ad(buf_pool_mutex_own());
......
...@@ -3462,6 +3462,23 @@ ibuf_insert( ...@@ -3462,6 +3462,23 @@ ibuf_insert(
ut_a(!dict_index_is_clust(index)); ut_a(!dict_index_is_clust(index));
if (UNIV_LIKELY(op != IBUF_OP_DELETE)) {
/* If another thread buffers an insert on a page while
the purge is in progress, the purge for the same page
must not be buffered, because it could remove a record
that was re-inserted later.
We do not call this in the IBUF_OP_DELETE case,
because that would always trigger the buffer pool
watch during purge and thus prevent the buffering of
delete operations. We assume that IBUF_OP_DELETE
operations are only issued by the purge thread. */
buf_pool_mutex_enter();
buf_pool_watch_notify(space, page_no);
buf_pool_mutex_exit();
}
entry_size = rec_get_converted_size(index, entry, 0); entry_size = rec_get_converted_size(index, entry, 0);
if (entry_size >= (page_get_free_space_of_empty(comp) / 2)) { if (entry_size >= (page_get_free_space_of_empty(comp) / 2)) {
......
...@@ -981,6 +981,14 @@ UNIV_INTERN ...@@ -981,6 +981,14 @@ UNIV_INTERN
void void
buf_pool_watch_clear(void); buf_pool_watch_clear(void);
/*======================*/ /*======================*/
/************************************************************************
Set watch occurred flag. */
UNIV_INTERN
void
buf_pool_watch_notify(
/*==================*/
ulint space, /* in: space id of page read in */
ulint offset);/* in: offset of page read in */
/******************************************************************** /********************************************************************
Check if the given page is being watched and has been read to the buffer Check if the given page is being watched and has been read to the buffer
pool. */ pool. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment