Skip to content

Commit f99cc0d

Browse files
committed
Merge fixup 7c33ecb
The merge accidentally omitted the 10.4 commit 472b35c and reverted the 10.5 commit 6e3bd66.
1 parent e813549 commit f99cc0d

File tree

3 files changed

+53
-43
lines changed

3 files changed

+53
-43
lines changed

storage/innobase/buf/buf0buf.cc

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,26 +2393,24 @@ inline buf_page_t *buf_pool_t::watch_set(const page_id_t id,
23932393
w->id_= id;
23942394

23952395
*hash_lock= page_hash.lock_get(fold);
2396-
(*hash_lock)->write_lock();
2397-
mysql_mutex_unlock(&mutex);
23982396

23992397
buf_page_t *bpage= page_hash_get_low(id, fold);
24002398
if (UNIV_LIKELY_NULL(bpage))
24012399
{
2402-
(*hash_lock)->write_unlock();
2403-
mysql_mutex_lock(&mutex);
24042400
w->set_state(BUF_BLOCK_NOT_USED);
24052401
*hash_lock= page_hash.lock_get(fold);
24062402
(*hash_lock)->write_lock();
24072403
mysql_mutex_unlock(&mutex);
24082404
goto retry;
24092405
}
24102406

2407+
(*hash_lock)->write_lock();
24112408
ut_ad(!w->buf_fix_count_);
24122409
w->buf_fix_count_= 1;
24132410
ut_ad(!w->in_page_hash);
2414-
ut_d(w->in_page_hash= true); /* Not holding buf_pool.mutex here! */
2411+
ut_d(w->in_page_hash= true);
24152412
HASH_INSERT(buf_page_t, hash, &page_hash, fold, w);
2413+
mysql_mutex_unlock(&mutex);
24162414
return nullptr;
24172415
}
24182416

@@ -2421,6 +2419,48 @@ inline buf_page_t *buf_pool_t::watch_set(const page_id_t id,
24212419
return nullptr;
24222420
}
24232421

2422+
/** Stop watching whether a page has been read in.
2423+
watch_set(id) must have returned nullptr before.
2424+
@param id page identifier */
2425+
void buf_pool_t::watch_unset(const page_id_t id)
2426+
{
2427+
mysql_mutex_assert_not_owner(&mutex);
2428+
const ulint fold= id.fold();
2429+
page_hash_latch *hash_lock= page_hash.lock<true>(fold);
2430+
/* The page must exist because watch_set() increments buf_fix_count. */
2431+
buf_page_t *w= page_hash_get_low(id, fold);
2432+
const auto buf_fix_count= w->buf_fix_count();
2433+
ut_ad(buf_fix_count);
2434+
const bool must_remove= buf_fix_count == 1 && watch_is_sentinel(*w);
2435+
ut_ad(w->in_page_hash);
2436+
if (!must_remove)
2437+
w->unfix();
2438+
hash_lock->write_unlock();
2439+
2440+
if (must_remove)
2441+
{
2442+
const auto old= w;
2443+
/* The following is based on buf_pool_t::watch_remove(). */
2444+
mysql_mutex_lock(&mutex);
2445+
w= page_hash_get_low(id, fold);
2446+
page_hash_latch *hash_lock= buf_pool.page_hash.lock_get(fold);
2447+
hash_lock->write_lock();
2448+
if (w->unfix() == 0 && w == old)
2449+
{
2450+
ut_ad(w->in_page_hash);
2451+
ut_d(w->in_page_hash= false);
2452+
HASH_DELETE(buf_page_t, hash, &page_hash, fold, w);
2453+
// Now that the watch is detached from page_hash, release it to watch[].
2454+
ut_ad(w->id_ == id);
2455+
ut_ad(!w->buf_fix_count());
2456+
ut_ad(w->state() == BUF_BLOCK_ZIP_PAGE);
2457+
w->set_state(BUF_BLOCK_NOT_USED);
2458+
}
2459+
hash_lock->write_unlock();
2460+
mysql_mutex_unlock(&mutex);
2461+
}
2462+
}
2463+
24242464
/** Mark the page status as FREED for the given tablespace id and
24252465
page number. If the page is not in buffer pool then ignore it.
24262466
@param[in,out] space tablespace

storage/innobase/buf/buf0rea.cc

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ that the block has been replaced with the real block.
5353
@param watch sentinel */
5454
inline void buf_pool_t::watch_remove(buf_page_t *watch)
5555
{
56+
mysql_mutex_assert_owner(&buf_pool.mutex);
5657
ut_ad(hash_lock_get(watch->id())->is_write_locked());
5758
ut_a(watch_is_sentinel(*watch));
5859
if (watch->buf_fix_count())
@@ -123,16 +124,10 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
123124

124125
mysql_mutex_lock(&buf_pool.mutex);
125126

126-
/* We must acquire hash_lock this early to prevent
127-
a race condition with buf_pool_t::watch_remove() */
128-
page_hash_latch *hash_lock= buf_pool.page_hash.lock_get(fold);
129-
hash_lock->write_lock();
130-
131127
buf_page_t *hash_page= buf_pool.page_hash_get_low(page_id, fold);
132128
if (hash_page && !buf_pool.watch_is_sentinel(*hash_page))
133129
{
134130
/* The page is already in the buffer pool. */
135-
hash_lock->write_unlock();
136131
if (block)
137132
{
138133
rw_lock_x_unlock_gen(&block->lock, BUF_IO_READ);
@@ -146,6 +141,9 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
146141
bpage= &block->page;
147142

148143
/* Insert into the hash table of file pages */
144+
page_hash_latch *hash_lock= buf_pool.page_hash.lock_get(fold);
145+
hash_lock->write_lock();
146+
149147
if (hash_page)
150148
{
151149
/* Preserve the reference count. */
@@ -184,17 +182,13 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
184182
}
185183
else
186184
{
187-
hash_lock->write_unlock();
188-
189185
/* The compressed page must be allocated before the
190186
control block (bpage), in order to avoid the
191187
invocation of buf_buddy_relocate_block() on
192188
uninitialized data. */
193189
bool lru= false;
194190
void *data= buf_buddy_alloc(zip_size, &lru);
195191

196-
hash_lock->write_lock();
197-
198192
/* If buf_buddy_alloc() allocated storage from the LRU list,
199193
it released and reacquired buf_pool.mutex. Thus, we must
200194
check the page_hash again, as it may have been modified. */
@@ -205,7 +199,6 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
205199
if (UNIV_UNLIKELY(hash_page && !buf_pool.watch_is_sentinel(*hash_page)))
206200
{
207201
/* The block was added by some other thread. */
208-
hash_lock->write_unlock();
209202
buf_buddy_free(data, zip_size);
210203
goto func_exit;
211204
}
@@ -219,6 +212,9 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
219212

220213
bpage->init(BUF_BLOCK_ZIP_PAGE, page_id);
221214

215+
page_hash_latch *hash_lock= buf_pool.page_hash.lock_get(fold);
216+
hash_lock->write_lock();
217+
222218
if (hash_page)
223219
{
224220
/* Preserve the reference count. It can be 0 if

storage/innobase/include/buf0buf.h

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,33 +1739,7 @@ class buf_pool_t
17391739
/** Stop watching whether a page has been read in.
17401740
watch_set(id) must have returned nullptr before.
17411741
@param id page identifier */
1742-
void watch_unset(const page_id_t id)
1743-
{
1744-
const ulint fold= id.fold();
1745-
page_hash_latch *hash_lock= page_hash.lock<true>(fold);
1746-
/* The page must exist because watch_set() increments buf_fix_count. */
1747-
buf_page_t *watch= page_hash_get_low(id, fold);
1748-
if (watch->unfix() == 0 && watch_is_sentinel(*watch))
1749-
{
1750-
/* The following is based on watch_remove(). */
1751-
ut_ad(watch->in_page_hash);
1752-
ut_d(watch->in_page_hash= false);
1753-
HASH_DELETE(buf_page_t, hash, &page_hash, fold, watch);
1754-
hash_lock->write_unlock();
1755-
// Now that the watch is detached from page_hash, release it to watch[].
1756-
mysql_mutex_lock(&mutex);
1757-
/* It is possible that watch_remove() already removed the watch. */
1758-
if (watch->id_ == id)
1759-
{
1760-
ut_ad(!watch->buf_fix_count());
1761-
ut_ad(watch->state() == BUF_BLOCK_ZIP_PAGE);
1762-
watch->set_state(BUF_BLOCK_NOT_USED);
1763-
}
1764-
mysql_mutex_unlock(&mutex);
1765-
}
1766-
else
1767-
hash_lock->write_unlock();
1768-
}
1742+
void watch_unset(const page_id_t id);
17691743

17701744
/** Remove the sentinel block for the watch before replacing it with a
17711745
real block. watch_unset() or watch_occurred() will notice

0 commit comments

Comments
 (0)