#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
---- a/storage/innobase/buf/buf0lru.c 2010-12-03 15:49:59.185023424 +0900
-+++ b/storage/innobase/buf/buf0lru.c 2010-12-04 15:33:37.626482350 +0900
-@@ -2224,6 +2224,284 @@
+--- a/storage/innobase/buf/buf0lru.c
++++ b/storage/innobase/buf/buf0lru.c
+@@ -2197,6 +2197,289 @@
memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
}
+ " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
+ goto end;
+ }
++
++ ut_print_timestamp(stderr);
++ fprintf(stderr, " InnoDB: Restoring buffer pool pages from %s\n",
++ LRU_DUMP_FILE);
++
+ if (size == 0 || size_high > 0 || size % 8) {
+ fprintf(stderr, " InnoDB: broken LRU dump file\n");
+ goto end;
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
-+ " InnoDB: reading pages based on the dumped LRU list was done."
++ " InnoDB: Completed reading buffer pool pages"
+ " (requested: %lu, read: %lu)\n", req, reads);
+ ret = TRUE;
+end:
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**********************************************************************//**
Validates the LRU list for one buffer pool instance. */
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-12-03 17:49:11.576124814 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-04 15:33:37.628480605 +0900
-@@ -58,7 +58,7 @@
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
+@@ -60,7 +60,7 @@
which case it is never read into the pool, or if the tablespace does
not exist or is being dropped
@return 1 if read request is issued. 0 if it is not */
ulint
buf_read_page_low(
/*==============*/
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2010-12-03 17:49:11.581025127 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2010-12-04 15:33:37.632482885 +0900
-@@ -4967,6 +4967,70 @@
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
+@@ -5307,6 +5307,70 @@
return(DB_SUCCESS);
}
#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:49:11.589956135 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:33:37.645555490 +0900
-@@ -11767,6 +11767,12 @@
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
+@@ -196,6 +196,8 @@
+
+ static char* innodb_version_str = (char*) INNODB_VERSION_STR;
+
++static my_bool innobase_blocking_lru_restore = FALSE;
++
+ /** Possible values for system variable "innodb_stats_method". The values
+ are defined the same as its corresponding MyISAM system variable
+ "myisam_stats_method"(see "myisam_stats_method_names"), for better usability */
+@@ -2652,6 +2654,8 @@
+ srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
+ srv_use_checksums = (ibool) innobase_use_checksums;
+
++ srv_blocking_lru_restore = (ibool) innobase_blocking_lru_restore;
++
+ #ifdef HAVE_LARGE_PAGES
+ if ((os_use_large_pages = (ibool) my_use_large_pages))
+ os_large_page_size = (ulint) opt_large_page_size;
+@@ -11964,6 +11968,19 @@
"Limit the allocated memory for dictionary cache. (0: unlimited)",
NULL, NULL, 0, 0, LONG_MAX, 0);
+ "Time in seconds between automatic buffer pool dumps. "
+ "0 (the default) disables automatic dumps.",
+ NULL, NULL, 0, 0, UINT_MAX32, 0);
++
++static MYSQL_SYSVAR_BOOL(blocking_buffer_pool_restore,
++ innobase_blocking_lru_restore,
++ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
++ "Block XtraDB startup process until buffer pool is full restored from a "
++ "dump file (if present). Disabled by default.",
++ NULL, NULL, FALSE);
+
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
-@@ -11849,6 +11855,7 @@
- #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
+@@ -12048,6 +12065,8 @@
+ MYSQL_SYSVAR(random_read_ahead),
MYSQL_SYSVAR(read_ahead_threshold),
MYSQL_SYSVAR(io_capacity),
+ MYSQL_SYSVAR(buffer_pool_restore_at_startup),
++ MYSQL_SYSVAR(blocking_buffer_pool_restore),
MYSQL_SYSVAR(purge_threads),
MYSQL_SYSVAR(purge_batch_size),
- NULL
-diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
---- a/storage/innobase/handler/i_s.cc 2010-12-03 17:34:35.286211349 +0900
-+++ b/storage/innobase/handler/i_s.cc 2010-12-04 15:33:37.677480733 +0900
+ MYSQL_SYSVAR(rollback_segments),
+--- a/storage/innobase/handler/i_s.cc
++++ b/storage/innobase/handler/i_s.cc
@@ -50,6 +50,7 @@
#include "trx0rseg.h" /* for trx_rseg_struct */
#include "trx0sys.h" /* for trx_sys */
+#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
}
- static const char plugin_author[] = "Innobase Oy";
-@@ -4254,6 +4255,36 @@
+ #define OK(expr) \
+@@ -4336,6 +4337,36 @@
"Hello!");
goto end_func;
}
field_store_string(i_s_table->field[0],
"Undefined XTRA_* command.");
-diff -ruN a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
---- a/storage/innobase/include/buf0lru.h 2010-12-03 15:49:59.223956070 +0900
-+++ b/storage/innobase/include/buf0lru.h 2010-12-04 15:33:37.681481467 +0900
-@@ -215,6 +215,18 @@
+--- a/storage/innobase/include/buf0lru.h
++++ b/storage/innobase/include/buf0lru.h
+@@ -204,6 +204,18 @@
void
buf_LRU_stat_update(void);
/*=====================*/
+buf_LRU_file_restore(void);
+/*======================*/
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- /**********************************************************************//**
-diff -ruN a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h
---- a/storage/innobase/include/buf0rea.h 2010-12-03 17:49:11.596953870 +0900
-+++ b/storage/innobase/include/buf0rea.h 2010-12-04 15:33:37.682563900 +0900
+ /******************************************************************//**
+ Remove one page from LRU list and put it to free list */
+--- a/storage/innobase/include/buf0rea.h
++++ b/storage/innobase/include/buf0rea.h
@@ -31,6 +31,37 @@
#include "buf0types.h"
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
-diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
---- a/storage/innobase/include/fil0fil.h 2010-12-03 17:49:11.597953501 +0900
-+++ b/storage/innobase/include/fil0fil.h 2010-12-04 15:33:37.684551372 +0900
-@@ -644,6 +644,14 @@
+--- a/storage/innobase/include/fil0fil.h
++++ b/storage/innobase/include/fil0fil.h
+@@ -653,6 +653,14 @@
void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
trx_t* trx);
/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
handler for completed requests. The aio array of pending requests is divided
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-03 17:49:11.603969747 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-04 15:33:37.685550816 +0900
-@@ -357,6 +357,9 @@
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
+@@ -364,6 +364,12 @@
reading of a disk page */
extern ulint srv_buf_pool_reads;
+/** Time in seconds between automatic buffer pool dumps */
+extern uint srv_auto_lru_dump;
++
++/** Whether startup should be blocked until buffer pool is fully restored */
++extern ibool srv_blocking_lru_restore;
+
/** Status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
-@@ -677,6 +680,16 @@
+@@ -669,6 +675,16 @@
/*=====================*/
void* arg); /*!< in: a dummy parameter required by
os_thread_create */
/******************************************************************//**
Outputs to a file the output of the InnoDB Monitor.
@return FALSE if not all information printed
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-03 17:49:11.620986661 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 15:33:37.708550811 +0900
-@@ -334,6 +334,9 @@
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
+@@ -332,6 +332,12 @@
reading of a disk page */
UNIV_INTERN ulint srv_buf_pool_reads = 0;
+/** Time in seconds between automatic buffer pool dumps */
+UNIV_INTERN uint srv_auto_lru_dump = 0;
++
++/** Whether startup should be blocked until buffer pool is fully restored */
++UNIV_INTERN ibool srv_blocking_lru_restore;
+
/* structure to pass status variables to MySQL */
UNIV_INTERN export_struc export_vars;
-@@ -2701,6 +2704,56 @@
+@@ -2708,6 +2714,58 @@
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
+ os_thread_pf(os_thread_get_curr_id()));
+#endif
+
-+ if (srv_auto_lru_dump)
++ /* If srv_blocking_lru_restore is TRUE, restore will be done
++ synchronously on startup. */
++ if (srv_auto_lru_dump && !srv_blocking_lru_restore)
+ buf_LRU_file_restore();
+
+ last_dump_time = time(NULL);
os_thread_exit(NULL);
OS_THREAD_DUMMY_RETURN;
-diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
---- a/storage/innobase/srv/srv0start.c 2010-12-03 15:18:48.916955609 +0900
-+++ b/storage/innobase/srv/srv0start.c 2010-12-04 15:33:37.711484798 +0900
-@@ -121,9 +121,9 @@
+--- a/storage/innobase/srv/srv0start.c
++++ b/storage/innobase/srv/srv0start.c
+@@ -87,6 +87,7 @@
+ # include "btr0pcur.h"
+ # include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
+ # include "zlib.h" /* for ZLIB_VERSION */
++# include "buf0lru.h" /* for buf_LRU_file_restore() */
+
+ /** Log sequence number immediately after startup */
+ UNIV_INTERN ib_uint64_t srv_start_lsn;
+@@ -120,9 +121,9 @@
static os_file_t files[1000];
/** io_handler_thread parameters for thread identification */
/** We use this mutex to test the return value of pthread_mutex_trylock
on successful locking. HP-UX does NOT return 0, though Linux et al do. */
-@@ -1816,6 +1816,10 @@
+@@ -1841,6 +1842,15 @@
os_thread_create(&srv_monitor_thread, NULL,
thread_ids + 4 + SRV_MAX_N_IO_THREADS);
+ /* Create the thread which automaticaly dumps/restore buffer pool */
+ os_thread_create(&srv_LRU_dump_restore_thread, NULL,
+ thread_ids + 5 + SRV_MAX_N_IO_THREADS);
++
++ /* If srv_blocking_lru_restore is TRUE, load buffer pool contents
++ synchronously */
++ if (srv_auto_lru_dump && srv_blocking_lru_restore)
++ buf_LRU_file_restore();
+
srv_is_being_started = FALSE;
err = dict_create_or_check_foreign_constraint_tables();
+--- /dev/null
++++ b/mysql-test/suite/sys_vars/r/innodb_blocking_buffer_pool_restore_basic.result
+@@ -0,0 +1,3 @@
++SELECT @@global.innodb_blocking_buffer_pool_restore;
++@@global.innodb_blocking_buffer_pool_restore
++0
+--- /dev/null
++++ b/mysql-test/suite/sys_vars/t/innodb_blocking_buffer_pool_restore_basic.test
+@@ -0,0 +1 @@
++SELECT @@global.innodb_blocking_buffer_pool_restore;