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