]> git.pld-linux.org Git - packages/mysql.git/blame_incremental - innodb_lru_dump_restore.patch
- rel 2; patches updated
[packages/mysql.git] / innodb_lru_dump_restore.patch
... / ...
CommitLineData
1# name : innodb_lru_dump_restore.patch
2# introduced : 11 or before
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8--- a/storage/innobase/buf/buf0lru.c
9+++ b/storage/innobase/buf/buf0lru.c
10@@ -2197,6 +2197,289 @@
11 memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
12 }
13
14+/********************************************************************//**
15+Dump the LRU page list to the specific file. */
16+#define LRU_DUMP_FILE "ib_lru_dump"
17+
18+UNIV_INTERN
19+ibool
20+buf_LRU_file_dump(void)
21+/*===================*/
22+{
23+ os_file_t dump_file = -1;
24+ ibool success;
25+ byte* buffer_base = NULL;
26+ byte* buffer = NULL;
27+ buf_page_t* bpage;
28+ ulint buffers;
29+ ulint offset;
30+ ibool ret = FALSE;
31+ ulint i;
32+
33+ for (i = 0; i < srv_n_data_files; i++) {
34+ if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) {
35+ fprintf(stderr,
36+ " InnoDB: The name '%s' seems to be used for"
37+ " innodb_data_file_path. For safety, dumping of the LRU list"
38+ " is not being done.\n", LRU_DUMP_FILE);
39+ goto end;
40+ }
41+ }
42+
43+ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
44+ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
45+ if (!buffer) {
46+ fprintf(stderr,
47+ " InnoDB: cannot allocate buffer.\n");
48+ goto end;
49+ }
50+
51+ dump_file = os_file_create(innodb_file_temp_key, LRU_DUMP_FILE, OS_FILE_OVERWRITE,
52+ OS_FILE_NORMAL, OS_DATA_FILE, &success);
53+ if (!success) {
54+ os_file_get_last_error(TRUE);
55+ fprintf(stderr,
56+ " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
57+ goto end;
58+ }
59+
60+ buffers = offset = 0;
61+
62+ for (i = 0; i < srv_buf_pool_instances; i++) {
63+ buf_pool_t* buf_pool;
64+
65+ buf_pool = buf_pool_from_array(i);
66+
67+ mutex_enter(&buf_pool->LRU_list_mutex);
68+ bpage = UT_LIST_GET_LAST(buf_pool->LRU);
69+
70+ while (bpage != NULL) {
71+ if (offset == 0) {
72+ memset(buffer, 0, UNIV_PAGE_SIZE);
73+ }
74+
75+ mach_write_to_4(buffer + offset * 4, bpage->space);
76+ offset++;
77+ mach_write_to_4(buffer + offset * 4, bpage->offset);
78+ offset++;
79+
80+ if (offset == UNIV_PAGE_SIZE/4) {
81+ success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
82+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
83+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
84+ UNIV_PAGE_SIZE);
85+ if (!success) {
86+ mutex_exit(&buf_pool->LRU_list_mutex);
87+ fprintf(stderr,
88+ " InnoDB: cannot write page %lu of %s\n",
89+ buffers, LRU_DUMP_FILE);
90+ goto end;
91+ }
92+ buffers++;
93+ offset = 0;
94+ }
95+
96+ bpage = UT_LIST_GET_PREV(LRU, bpage);
97+ }
98+ mutex_exit(&buf_pool->LRU_list_mutex);
99+ }
100+
101+ if (offset == 0) {
102+ memset(buffer, 0, UNIV_PAGE_SIZE);
103+ }
104+
105+ mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
106+ offset++;
107+ mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
108+ offset++;
109+
110+ success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
111+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
112+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
113+ UNIV_PAGE_SIZE);
114+ if (!success) {
115+ goto end;
116+ }
117+
118+ ret = TRUE;
119+end:
120+ if (dump_file != -1)
121+ os_file_close(dump_file);
122+ if (buffer_base)
123+ ut_free(buffer_base);
124+
125+ return(ret);
126+}
127+
128+typedef struct {
129+ ib_uint32_t space_id;
130+ ib_uint32_t page_no;
131+} dump_record_t;
132+
133+static int dump_record_cmp(const void *a, const void *b)
134+{
135+ const dump_record_t *rec1 = (dump_record_t *) a;
136+ const dump_record_t *rec2 = (dump_record_t *) b;
137+
138+ if (rec1->space_id < rec2->space_id)
139+ return -1;
140+ if (rec1->space_id > rec2->space_id)
141+ return 1;
142+ if (rec1->page_no < rec2->page_no)
143+ return -1;
144+ return rec1->page_no > rec2->page_no;
145+}
146+
147+/********************************************************************//**
148+Read the pages based on the specific file.*/
149+UNIV_INTERN
150+ibool
151+buf_LRU_file_restore(void)
152+/*======================*/
153+{
154+ os_file_t dump_file = -1;
155+ ibool success;
156+ byte* buffer_base = NULL;
157+ byte* buffer = NULL;
158+ ulint buffers;
159+ ulint offset;
160+ ulint reads = 0;
161+ ulint req = 0;
162+ ibool terminated = FALSE;
163+ ibool ret = FALSE;
164+ dump_record_t* records = NULL;
165+ ulint size;
166+ ulint size_high;
167+ ulint length;
168+
169+ dump_file = os_file_create_simple_no_error_handling(innodb_file_temp_key,
170+ LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
171+ if (!success || !os_file_get_size(dump_file, &size, &size_high)) {
172+ os_file_get_last_error(TRUE);
173+ fprintf(stderr,
174+ " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
175+ goto end;
176+ }
177+
178+ ut_print_timestamp(stderr);
179+ fprintf(stderr, " InnoDB: Restoring buffer pool pages from %s\n",
180+ LRU_DUMP_FILE);
181+
182+ if (size == 0 || size_high > 0 || size % 8) {
183+ fprintf(stderr, " InnoDB: broken LRU dump file\n");
184+ goto end;
185+ }
186+ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
187+ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
188+ records = ut_malloc(size);
189+ if (!buffer || !records) {
190+ fprintf(stderr,
191+ " InnoDB: cannot allocate buffer.\n");
192+ goto end;
193+ }
194+
195+ buffers = 0;
196+ length = 0;
197+ while (!terminated) {
198+ success = os_file_read(dump_file, buffer,
199+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
200+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
201+ UNIV_PAGE_SIZE);
202+ if (!success) {
203+ fprintf(stderr,
204+ " InnoDB: either could not read page %lu of %s,"
205+ " or terminated unexpectedly.\n",
206+ buffers, LRU_DUMP_FILE);
207+ goto end;
208+ }
209+
210+ for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
211+ ulint space_id;
212+ ulint page_no;
213+
214+ space_id = mach_read_from_4(buffer + offset * 4);
215+ page_no = mach_read_from_4(buffer + (offset + 1) * 4);
216+ if (space_id == 0xFFFFFFFFUL
217+ || page_no == 0xFFFFFFFFUL) {
218+ terminated = TRUE;
219+ break;
220+ }
221+
222+ records[length].space_id = space_id;
223+ records[length].page_no = page_no;
224+ length++;
225+ if (length * 8 >= size) {
226+ fprintf(stderr,
227+ " InnoDB: could not find the "
228+ "end-of-file marker after reading "
229+ "the expected %lu bytes from the "
230+ "LRU dump file.\n"
231+ " InnoDB: this could be caused by a "
232+ "broken or incomplete file.\n"
233+ " InnoDB: trying to process what has "
234+ "been read so far.\n",
235+ size);
236+ terminated= TRUE;
237+ break;
238+ }
239+ }
240+ buffers++;
241+ }
242+
243+ qsort(records, length, sizeof(dump_record_t), dump_record_cmp);
244+
245+ for (offset = 0; offset < length; offset++) {
246+ ulint space_id;
247+ ulint page_no;
248+ ulint zip_size;
249+ ulint err;
250+ ib_int64_t tablespace_version;
251+
252+ space_id = records[offset].space_id;
253+ page_no = records[offset].page_no;
254+
255+ if (offset % 16 == 15) {
256+ os_aio_simulated_wake_handler_threads();
257+ buf_flush_free_margins(FALSE);
258+ }
259+
260+ zip_size = fil_space_get_zip_size(space_id);
261+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
262+ continue;
263+ }
264+
265+ if (fil_is_exist(space_id, page_no)) {
266+
267+ tablespace_version = fil_space_get_version(space_id);
268+
269+ req++;
270+ reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
271+ | OS_AIO_SIMULATED_WAKE_LATER,
272+ space_id, zip_size, TRUE,
273+ tablespace_version, page_no, NULL);
274+ buf_LRU_stat_inc_io();
275+ }
276+ }
277+
278+ os_aio_simulated_wake_handler_threads();
279+ buf_flush_free_margins(FALSE);
280+
281+ ut_print_timestamp(stderr);
282+ fprintf(stderr,
283+ " InnoDB: Completed reading buffer pool pages"
284+ " (requested: %lu, read: %lu)\n", req, reads);
285+ ret = TRUE;
286+end:
287+ if (dump_file != -1)
288+ os_file_close(dump_file);
289+ if (buffer_base)
290+ ut_free(buffer_base);
291+ if (records)
292+ ut_free(records);
293+
294+ return(ret);
295+}
296+
297 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
298 /**********************************************************************//**
299 Validates the LRU list for one buffer pool instance. */
300--- a/storage/innobase/buf/buf0rea.c
301+++ b/storage/innobase/buf/buf0rea.c
302@@ -60,7 +60,7 @@
303 which case it is never read into the pool, or if the tablespace does
304 not exist or is being dropped
305 @return 1 if read request is issued. 0 if it is not */
306-static
307+UNIV_INTERN
308 ulint
309 buf_read_page_low(
310 /*==============*/
311--- a/storage/innobase/fil/fil0fil.c
312+++ b/storage/innobase/fil/fil0fil.c
313@@ -5307,6 +5307,70 @@
314 return(DB_SUCCESS);
315 }
316
317+/********************************************************************//**
318+Confirm whether the parameters are valid or not */
319+UNIV_INTERN
320+ibool
321+fil_is_exist(
322+/*==============*/
323+ ulint space_id, /*!< in: space id */
324+ ulint block_offset) /*!< in: offset in number of blocks */
325+{
326+ fil_space_t* space;
327+ fil_node_t* node;
328+
329+ /* Reserve the fil_system mutex and make sure that we can open at
330+ least one file while holding it, if the file is not already open */
331+
332+ fil_mutex_enter_and_prepare_for_io(space_id);
333+
334+ space = fil_space_get_by_id(space_id);
335+
336+ if (!space) {
337+ mutex_exit(&fil_system->mutex);
338+ return(FALSE);
339+ }
340+
341+ node = UT_LIST_GET_FIRST(space->chain);
342+
343+ for (;;) {
344+ if (UNIV_UNLIKELY(node == NULL)) {
345+ mutex_exit(&fil_system->mutex);
346+ return(FALSE);
347+ }
348+
349+ if (space->id != 0 && node->size == 0) {
350+ /* We do not know the size of a single-table tablespace
351+ before we open the file */
352+
353+ break;
354+ }
355+
356+ if (node->size > block_offset) {
357+ /* Found! */
358+ break;
359+ } else {
360+ block_offset -= node->size;
361+ node = UT_LIST_GET_NEXT(chain, node);
362+ }
363+ }
364+
365+ /* Open file if closed */
366+ fil_node_prepare_for_io(node, fil_system, space);
367+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
368+
369+ /* Check that at least the start offset is within the bounds of a
370+ single-table tablespace */
371+ if (UNIV_UNLIKELY(node->size <= block_offset)
372+ && space->id != 0 && space->purpose == FIL_TABLESPACE) {
373+ mutex_exit(&fil_system->mutex);
374+ return(FALSE);
375+ }
376+
377+ mutex_exit(&fil_system->mutex);
378+ return(TRUE);
379+}
380+
381 #ifndef UNIV_HOTBACKUP
382 /**********************************************************************//**
383 Waits for an aio operation to complete. This function is used to write the
384--- a/storage/innobase/handler/ha_innodb.cc
385+++ b/storage/innobase/handler/ha_innodb.cc
386@@ -196,6 +196,8 @@
387
388 static char* innodb_version_str = (char*) INNODB_VERSION_STR;
389
390+static my_bool innobase_blocking_lru_restore = FALSE;
391+
392 /** Possible values for system variable "innodb_stats_method". The values
393 are defined the same as its corresponding MyISAM system variable
394 "myisam_stats_method"(see "myisam_stats_method_names"), for better usability */
395@@ -2652,6 +2654,8 @@
396 srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
397 srv_use_checksums = (ibool) innobase_use_checksums;
398
399+ srv_blocking_lru_restore = (ibool) innobase_blocking_lru_restore;
400+
401 #ifdef HAVE_LARGE_PAGES
402 if ((os_use_large_pages = (ibool) my_use_large_pages))
403 os_large_page_size = (ulint) opt_large_page_size;
404@@ -11964,6 +11968,19 @@
405 "Limit the allocated memory for dictionary cache. (0: unlimited)",
406 NULL, NULL, 0, 0, LONG_MAX, 0);
407
408+static MYSQL_SYSVAR_UINT(buffer_pool_restore_at_startup, srv_auto_lru_dump,
409+ PLUGIN_VAR_RQCMDARG,
410+ "Time in seconds between automatic buffer pool dumps. "
411+ "0 (the default) disables automatic dumps.",
412+ NULL, NULL, 0, 0, UINT_MAX32, 0);
413+
414+static MYSQL_SYSVAR_BOOL(blocking_buffer_pool_restore,
415+ innobase_blocking_lru_restore,
416+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
417+ "Block XtraDB startup process until buffer pool is full restored from a "
418+ "dump file (if present). Disabled by default.",
419+ NULL, NULL, FALSE);
420+
421 static struct st_mysql_sys_var* innobase_system_variables[]= {
422 MYSQL_SYSVAR(additional_mem_pool_size),
423 MYSQL_SYSVAR(autoextend_increment),
424@@ -12048,6 +12065,8 @@
425 MYSQL_SYSVAR(random_read_ahead),
426 MYSQL_SYSVAR(read_ahead_threshold),
427 MYSQL_SYSVAR(io_capacity),
428+ MYSQL_SYSVAR(buffer_pool_restore_at_startup),
429+ MYSQL_SYSVAR(blocking_buffer_pool_restore),
430 MYSQL_SYSVAR(purge_threads),
431 MYSQL_SYSVAR(purge_batch_size),
432 MYSQL_SYSVAR(rollback_segments),
433--- a/storage/innobase/handler/i_s.cc
434+++ b/storage/innobase/handler/i_s.cc
435@@ -50,6 +50,7 @@
436 #include "trx0rseg.h" /* for trx_rseg_struct */
437 #include "trx0sys.h" /* for trx_sys */
438 #include "dict0dict.h" /* for dict_sys */
439+#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
440 }
441
442 #define OK(expr) \
443@@ -4336,6 +4337,36 @@
444 "Hello!");
445 goto end_func;
446 }
447+ else if (!strncasecmp("XTRA_LRU_DUMP", ptr, 13)) {
448+ ut_print_timestamp(stderr);
449+ fprintf(stderr, " InnoDB: Administrative command 'XTRA_LRU_DUMP'"
450+ " was detected.\n");
451+
452+ if (buf_LRU_file_dump()) {
453+ field_store_string(i_s_table->field[0],
454+ "XTRA_LRU_DUMP was succeeded.");
455+ } else {
456+ field_store_string(i_s_table->field[0],
457+ "XTRA_LRU_DUMP was failed.");
458+ }
459+
460+ goto end_func;
461+ }
462+ else if (!strncasecmp("XTRA_LRU_RESTORE", ptr, 16)) {
463+ ut_print_timestamp(stderr);
464+ fprintf(stderr, " InnoDB: Administrative command 'XTRA_LRU_RESTORE'"
465+ " was detected.\n");
466+
467+ if (buf_LRU_file_restore()) {
468+ field_store_string(i_s_table->field[0],
469+ "XTRA_LRU_RESTORE was succeeded.");
470+ } else {
471+ field_store_string(i_s_table->field[0],
472+ "XTRA_LRU_RESTORE was failed.");
473+ }
474+
475+ goto end_func;
476+ }
477
478 field_store_string(i_s_table->field[0],
479 "Undefined XTRA_* command.");
480--- a/storage/innobase/include/buf0lru.h
481+++ b/storage/innobase/include/buf0lru.h
482@@ -204,6 +204,18 @@
483 void
484 buf_LRU_stat_update(void);
485 /*=====================*/
486+/********************************************************************//**
487+Dump the LRU page list to the specific file. */
488+UNIV_INTERN
489+ibool
490+buf_LRU_file_dump(void);
491+/*===================*/
492+/********************************************************************//**
493+Read the pages based on the specific file.*/
494+UNIV_INTERN
495+ibool
496+buf_LRU_file_restore(void);
497+/*======================*/
498
499 /******************************************************************//**
500 Remove one page from LRU list and put it to free list */
501--- a/storage/innobase/include/buf0rea.h
502+++ b/storage/innobase/include/buf0rea.h
503@@ -31,6 +31,37 @@
504 #include "buf0types.h"
505
506 /********************************************************************//**
507+Low-level function which reads a page asynchronously from a file to the
508+buffer buf_pool if it is not already there, in which case does nothing.
509+Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
510+flag is cleared and the x-lock released by an i/o-handler thread.
511+@return 1 if a read request was queued, 0 if the page already resided
512+in buf_pool, or if the page is in the doublewrite buffer blocks in
513+which case it is never read into the pool, or if the tablespace does
514+not exist or is being dropped
515+@return 1 if read request is issued. 0 if it is not */
516+UNIV_INTERN
517+ulint
518+buf_read_page_low(
519+/*==============*/
520+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
521+ trying to read from a non-existent tablespace, or a
522+ tablespace which is just now being dropped */
523+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
524+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
525+ ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
526+ at read-ahead functions) */
527+ ulint space, /*!< in: space id */
528+ ulint zip_size,/*!< in: compressed page size, or 0 */
529+ ibool unzip, /*!< in: TRUE=request uncompressed page */
530+ ib_int64_t tablespace_version, /*!< in: if the space memory object has
531+ this timestamp different from what we are giving here,
532+ treat the tablespace as dropped; this is a timestamp we
533+ use to stop dangling page reads from a tablespace
534+ which we have DISCARDed + IMPORTed back */
535+ ulint offset, /*!< in: page number */
536+ trx_t* trx);
537+/********************************************************************//**
538 High-level function which reads a page asynchronously from a file to the
539 buffer buf_pool if it is not already there. Sets the io_fix flag and sets
540 an exclusive lock on the buffer frame. The flag is cleared and the x-lock
541--- a/storage/innobase/include/fil0fil.h
542+++ b/storage/innobase/include/fil0fil.h
543@@ -653,6 +653,14 @@
544 void* message, /*!< in: message for aio handler if non-sync
545 aio used, else ignored */
546 trx_t* trx);
547+/********************************************************************//**
548+Confirm whether the parameters are valid or not */
549+UNIV_INTERN
550+ibool
551+fil_is_exist(
552+/*==============*/
553+ ulint space_id, /*!< in: space id */
554+ ulint block_offset); /*!< in: offset in number of blocks */
555 /**********************************************************************//**
556 Waits for an aio operation to complete. This function is used to write the
557 handler for completed requests. The aio array of pending requests is divided
558--- a/storage/innobase/include/srv0srv.h
559+++ b/storage/innobase/include/srv0srv.h
560@@ -364,6 +364,12 @@
561 reading of a disk page */
562 extern ulint srv_buf_pool_reads;
563
564+/** Time in seconds between automatic buffer pool dumps */
565+extern uint srv_auto_lru_dump;
566+
567+/** Whether startup should be blocked until buffer pool is fully restored */
568+extern ibool srv_blocking_lru_restore;
569+
570 /** Status variables to be passed to MySQL */
571 typedef struct export_var_struct export_struc;
572
573@@ -669,6 +675,16 @@
574 /*=====================*/
575 void* arg); /*!< in: a dummy parameter required by
576 os_thread_create */
577+/*********************************************************************//**
578+A thread which restores the buffer pool from a dump file on startup and does
579+periodic buffer pool dumps.
580+@return a dummy parameter */
581+UNIV_INTERN
582+os_thread_ret_t
583+srv_LRU_dump_restore_thread(
584+/*====================*/
585+ void* arg); /*!< in: a dummy parameter required by
586+ os_thread_create */
587 /******************************************************************//**
588 Outputs to a file the output of the InnoDB Monitor.
589 @return FALSE if not all information printed
590--- a/storage/innobase/srv/srv0srv.c
591+++ b/storage/innobase/srv/srv0srv.c
592@@ -332,6 +332,12 @@
593 reading of a disk page */
594 UNIV_INTERN ulint srv_buf_pool_reads = 0;
595
596+/** Time in seconds between automatic buffer pool dumps */
597+UNIV_INTERN uint srv_auto_lru_dump = 0;
598+
599+/** Whether startup should be blocked until buffer pool is fully restored */
600+UNIV_INTERN ibool srv_blocking_lru_restore;
601+
602 /* structure to pass status variables to MySQL */
603 UNIV_INTERN export_struc export_vars;
604
605@@ -2708,6 +2714,58 @@
606 /* We count the number of threads in os_thread_exit(). A created
607 thread should always use that to exit and not use return() to exit. */
608
609+ os_thread_exit(NULL);
610+
611+ OS_THREAD_DUMMY_RETURN;
612+}
613+
614+/*********************************************************************//**
615+A thread which restores the buffer pool from a dump file on startup and does
616+periodic buffer pool dumps.
617+@return a dummy parameter */
618+UNIV_INTERN
619+os_thread_ret_t
620+srv_LRU_dump_restore_thread(
621+/*====================*/
622+ void* arg __attribute__((unused)))
623+ /*!< in: a dummy parameter required by
624+ os_thread_create */
625+{
626+ uint auto_lru_dump;
627+ time_t last_dump_time;
628+ time_t time_elapsed;
629+
630+#ifdef UNIV_DEBUG_THREAD_CREATION
631+ fprintf(stderr, "The LRU dump/restore thread has started, id %lu\n",
632+ os_thread_pf(os_thread_get_curr_id()));
633+#endif
634+
635+ /* If srv_blocking_lru_restore is TRUE, restore will be done
636+ synchronously on startup. */
637+ if (srv_auto_lru_dump && !srv_blocking_lru_restore)
638+ buf_LRU_file_restore();
639+
640+ last_dump_time = time(NULL);
641+
642+loop:
643+ os_thread_sleep(5000000);
644+
645+ if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
646+ goto exit_func;
647+ }
648+
649+ time_elapsed = time(NULL) - last_dump_time;
650+ auto_lru_dump = srv_auto_lru_dump;
651+ if (auto_lru_dump > 0 && (time_t) auto_lru_dump < time_elapsed) {
652+ last_dump_time = time(NULL);
653+ buf_LRU_file_dump();
654+ }
655+
656+ goto loop;
657+exit_func:
658+ /* We count the number of threads in os_thread_exit(). A created
659+ thread should always use that to exit and not use return() to exit. */
660+
661 os_thread_exit(NULL);
662
663 OS_THREAD_DUMMY_RETURN;
664--- a/storage/innobase/srv/srv0start.c
665+++ b/storage/innobase/srv/srv0start.c
666@@ -87,6 +87,7 @@
667 # include "btr0pcur.h"
668 # include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
669 # include "zlib.h" /* for ZLIB_VERSION */
670+# include "buf0lru.h" /* for buf_LRU_file_restore() */
671
672 /** Log sequence number immediately after startup */
673 UNIV_INTERN ib_uint64_t srv_start_lsn;
674@@ -120,9 +121,9 @@
675 static os_file_t files[1000];
676
677 /** io_handler_thread parameters for thread identification */
678-static ulint n[SRV_MAX_N_IO_THREADS + 6];
679+static ulint n[SRV_MAX_N_IO_THREADS + 7];
680 /** io_handler_thread identifiers */
681-static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6];
682+static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 7];
683
684 /** We use this mutex to test the return value of pthread_mutex_trylock
685 on successful locking. HP-UX does NOT return 0, though Linux et al do. */
686@@ -1841,6 +1842,15 @@
687 os_thread_create(&srv_monitor_thread, NULL,
688 thread_ids + 4 + SRV_MAX_N_IO_THREADS);
689
690+ /* Create the thread which automaticaly dumps/restore buffer pool */
691+ os_thread_create(&srv_LRU_dump_restore_thread, NULL,
692+ thread_ids + 5 + SRV_MAX_N_IO_THREADS);
693+
694+ /* If srv_blocking_lru_restore is TRUE, load buffer pool contents
695+ synchronously */
696+ if (srv_auto_lru_dump && srv_blocking_lru_restore)
697+ buf_LRU_file_restore();
698+
699 srv_is_being_started = FALSE;
700
701 err = dict_create_or_check_foreign_constraint_tables();
702--- /dev/null
703+++ b/mysql-test/suite/sys_vars/r/innodb_blocking_buffer_pool_restore_basic.result
704@@ -0,0 +1,3 @@
705+SELECT @@global.innodb_blocking_buffer_pool_restore;
706+@@global.innodb_blocking_buffer_pool_restore
707+0
708--- /dev/null
709+++ b/mysql-test/suite/sys_vars/t/innodb_blocking_buffer_pool_restore_basic.test
710@@ -0,0 +1 @@
711+SELECT @@global.innodb_blocking_buffer_pool_restore;
This page took 0.038222 seconds and 4 git commands to generate.