Comment 2 for bug 1552673

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Tentative 5.7 fix

diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index b76607d..db63ccb 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -608,6 +608,7 @@ rescan:
       bpage != NULL;
       bpage = prev) {

+ ut_ad(!must_restart);
   ut_a(buf_page_in_file(bpage));

   /* Save the previous link because once we free the
@@ -628,9 +629,6 @@ rescan:

    /* Remove was unsuccessful, we have to try again
    by scanning the entire list from the end.
- This also means that we never released the
- flust list mutex. Therefore we can trust the prev
- pointer.
    buf_flush_or_remove_page() released the
    flush list mutex but not the LRU list mutex.
    Therefore it is possible that a new page was
@@ -647,6 +645,12 @@ rescan:
    iteration. */

    all_freed = false;
+
+ if (UNIV_UNLIKELY(must_restart)) {
+
+ /* cannot trust the prev pointer */
+ break;
+ }
   } else if (flush) {

    /* The processing was successful. And during the
@@ -654,10 +658,6 @@ rescan:
    when calling buf_page_flush(). We cannot trust
    prev pointer. */
    goto rescan;
- } else if (UNIV_UNLIKELY(must_restart)) {
-
- ut_ad(!all_freed);
- break;
   }

   ++processed;
@@ -670,6 +670,11 @@ rescan:
    /* Reset the batch size counter if we had to yield. */

    processed = 0;
+ } else if (UNIV_UNLIKELY(must_restart)) {
+
+ /* Cannot trust prev pointer now */
+ all_freed = false;
+ break;
   }

 #ifdef DBUG_OFF