diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-04-28 11:46:29 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-04-28 11:46:29 +0300 |
commit | cce1b6e245a7ee30e6ebfcd45556e8caa6e754c2 (patch) | |
tree | b57792c870c55ce6084e4588bd6a146c8abdc91d | |
parent | cf64d27badc5c90ae72c590c9043a0e3ed837fc1 (diff) | |
download | mariadb-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.cc | 15 |
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); |