]> git.pld-linux.org Git - packages/mysql.git/blob - innodb_lru_dump_restore.patch
small reorganize, move slave related options together
[packages/mysql.git] / innodb_lru_dump_restore.patch
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.088732 seconds and 3 git commands to generate.