From cce1b6e245a7ee30e6ebfcd45556e8caa6e754c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 28 Apr 2020 11:46:29 +0300 Subject: 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 --- storage/innobase/handler/ha_innodb.cc | 15 ++++++++------- 1 file 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); -- cgit v1.2.1