summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-04-28 11:46:29 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-04-28 11:46:29 +0300
commitcce1b6e245a7ee30e6ebfcd45556e8caa6e754c2 (patch)
treeb57792c870c55ce6084e4588bd6a146c8abdc91d
parentcf64d27badc5c90ae72c590c9043a0e3ed837fc1 (diff)
downloadmariadb-git-cce1b6e245a7ee30e6ebfcd45556e8caa6e754c2.tar.gz
MDEV-22392 Race condition on SET GLOBAL innodb_buffer_pool_evict='uncompressed'
innodb_buffer_pool_evict_uncompressed(): Restart the loop when prev_block might not enjoy mutex protection. This is based on mysql/mysql-server@eccaecac070b6747ecf14d6b9150791f8c3e8f6d
-rw-r--r--storage/innobase/handler/ha_innodb.cc15
1 files changed, 8 insertions, 7 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index f9bad3a128c..a1505eecd29 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2000, 2019, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2000, 2020, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
@@ -17850,10 +17850,7 @@ static char* srv_buffer_pool_evict;
Evict all uncompressed pages of compressed tables from the buffer pool.
Keep the compressed pages in the buffer pool.
@return whether all uncompressed pages were evicted */
-static MY_ATTRIBUTE((warn_unused_result))
-bool
-innodb_buffer_pool_evict_uncompressed(void)
-/*=======================================*/
+static bool innodb_buffer_pool_evict_uncompressed()
{
bool all_evicted = true;
@@ -17874,9 +17871,13 @@ innodb_buffer_pool_evict_uncompressed(void)
if (!buf_LRU_free_page(&block->page, false)) {
all_evicted = false;
+ block = prev_block;
+ } else {
+ /* Because buf_LRU_free_page() may release
+ and reacquire buf_pool_t::mutex, prev_block
+ may be invalid. */
+ block = UT_LIST_GET_LAST(buf_pool->unzip_LRU);
}
-
- block = prev_block;
}
buf_pool_mutex_exit(buf_pool);