]> git.pld-linux.org Git - packages/percona-server.git/blame - innodb_lru_dump_restore.patch
- Try to fix lang config on upgrade.
[packages/percona-server.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
11@@ -2250,6 +2250,285 @@
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"
38+ " innodb_data_file_path. Dumping LRU list is not"
39+ " done for safeness.\n", LRU_DUMP_FILE);
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,
200+ " InnoDB: cannot read page %lu of %s,"
201+ " or meet unexpected terminal.\n",
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+
261+ if (fil_area_is_exist(space_id, zip_size, page_no, 0,
262+ zip_size ? zip_size : UNIV_PAGE_SIZE)) {
263+
264+ tablespace_version = fil_space_get_version(space_id);
265+
266+ req++;
267+ reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
268+ | OS_AIO_SIMULATED_WAKE_LATER,
269+ space_id, zip_size, TRUE,
270+ tablespace_version, page_no, NULL);
271+ buf_LRU_stat_inc_io();
272+ }
273+ }
274+
275+ os_aio_simulated_wake_handler_threads();
276+ buf_flush_free_margins(FALSE);
277+
278+ ut_print_timestamp(stderr);
279+ fprintf(stderr,
280+ " InnoDB: reading pages based on the dumped LRU list was done."
281+ " (requested: %lu, read: %lu)\n", req, reads);
282+ ret = TRUE;
283+end:
284+ if (dump_file != -1)
285+ os_file_close(dump_file);
286+ if (buffer_base)
287+ ut_free(buffer_base);
288+ if (records)
289+ ut_free(records);
290+
291+ return(ret);
292+}
293+
294 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
295 /**********************************************************************//**
296 Validates the LRU list for one buffer pool instance. */
297diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
298--- a/storage/innobase/buf/buf0rea.c 2010-12-03 17:49:11.576124814 +0900
299+++ b/storage/innobase/buf/buf0rea.c 2010-12-04 15:33:37.628480605 +0900
300@@ -58,7 +58,7 @@
301 which case it is never read into the pool, or if the tablespace does
302 not exist or is being dropped
303 @return 1 if read request is issued. 0 if it is not */
304-static
305+UNIV_INTERN
306 ulint
307 buf_read_page_low(
308 /*==============*/
309diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
310--- a/storage/innobase/fil/fil0fil.c 2010-12-03 17:49:11.581025127 +0900
311+++ b/storage/innobase/fil/fil0fil.c 2010-12-04 15:33:37.632482885 +0900
312@@ -4939,6 +4939,78 @@
313 return(DB_SUCCESS);
314 }
315
316+/********************************************************************//**
317+Confirm whether the parameters are valid or not */
318+UNIV_INTERN
319+ibool
320+fil_area_is_exist(
321+/*==============*/
322+ ulint space_id, /*!< in: space id */
323+ ulint zip_size, /*!< in: compressed page size in bytes;
324+ 0 for uncompressed pages */
325+ ulint block_offset, /*!< in: offset in number of blocks */
326+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
327+ aio this must be divisible by the OS block
328+ size */
329+ ulint len) /*!< in: how many bytes to read or write; this
330+ must not cross a file boundary; in aio this
331+ must be a block size multiple */
332+{
333+ fil_space_t* space;
334+ fil_node_t* node;
335+
336+ /* Reserve the fil_system mutex and make sure that we can open at
337+ least one file while holding it, if the file is not already open */
338+
339+ fil_mutex_enter_and_prepare_for_io(space_id);
340+
341+ space = fil_space_get_by_id(space_id);
342+
343+ if (!space) {
344+ mutex_exit(&fil_system->mutex);
345+ return(FALSE);
346+ }
347+
348+ node = UT_LIST_GET_FIRST(space->chain);
349+
350+ for (;;) {
351+ if (UNIV_UNLIKELY(node == NULL)) {
352+ mutex_exit(&fil_system->mutex);
353+ return(FALSE);
354+ }
355+
356+ if (space->id != 0 && node->size == 0) {
357+ /* We do not know the size of a single-table tablespace
358+ before we open the file */
359+
360+ break;
361+ }
362+
363+ if (node->size > block_offset) {
364+ /* Found! */
365+ break;
366+ } else {
367+ block_offset -= node->size;
368+ node = UT_LIST_GET_NEXT(chain, node);
369+ }
370+ }
371+
372+ /* Open file if closed */
373+ fil_node_prepare_for_io(node, fil_system, space);
374+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
375+
376+ /* Check that at least the start offset is within the bounds of a
377+ single-table tablespace */
378+ if (UNIV_UNLIKELY(node->size <= block_offset)
379+ && space->id != 0 && space->purpose == FIL_TABLESPACE) {
380+ mutex_exit(&fil_system->mutex);
381+ return(FALSE);
382+ }
383+
384+ mutex_exit(&fil_system->mutex);
385+ return(TRUE);
386+}
387+
388 #ifndef UNIV_HOTBACKUP
389 /**********************************************************************//**
390 Waits for an aio operation to complete. This function is used to write the
391diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
392--- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:49:11.589956135 +0900
393+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:33:37.645555490 +0900
394@@ -11708,6 +11708,12 @@
395 "Limit the allocated memory for dictionary cache. (0: unlimited)",
396 NULL, NULL, 0, 0, LONG_MAX, 0);
397
398+static MYSQL_SYSVAR_UINT(auto_lru_dump, srv_auto_lru_dump,
399+ PLUGIN_VAR_RQCMDARG,
400+ "Time in seconds between automatic buffer pool dumps. "
401+ "0 (the default) disables automatic dumps.",
402+ NULL, NULL, 0, 0, UINT_MAX32, 0);
403+
404 static struct st_mysql_sys_var* innobase_system_variables[]= {
405 MYSQL_SYSVAR(additional_mem_pool_size),
406 MYSQL_SYSVAR(autoextend_increment),
407@@ -11791,6 +11797,7 @@
408 #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
409 MYSQL_SYSVAR(read_ahead_threshold),
410 MYSQL_SYSVAR(io_capacity),
411+ MYSQL_SYSVAR(auto_lru_dump),
412 MYSQL_SYSVAR(purge_threads),
413 MYSQL_SYSVAR(purge_batch_size),
414 NULL
415diff -ruN a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
416--- a/storage/innobase/handler/i_s.cc 2010-12-03 17:34:35.286211349 +0900
417+++ b/storage/innobase/handler/i_s.cc 2010-12-04 15:33:37.677480733 +0900
418@@ -50,6 +50,7 @@
419 #include "trx0rseg.h" /* for trx_rseg_struct */
420 #include "trx0sys.h" /* for trx_sys */
421 #include "dict0dict.h" /* for dict_sys */
422+#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
423 }
424
425 static const char plugin_author[] = "Innobase Oy";
426@@ -4255,6 +4256,36 @@
427 "Hello!");
428 goto end_func;
429 }
430+ else if (!strncasecmp("XTRA_LRU_DUMP", ptr, 13)) {
431+ ut_print_timestamp(stderr);
432+ fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_DUMP'"
433+ " was detected.\n");
434+
435+ if (buf_LRU_file_dump()) {
436+ field_store_string(i_s_table->field[0],
437+ "XTRA_LRU_DUMP was succeeded.");
438+ } else {
439+ field_store_string(i_s_table->field[0],
440+ "XTRA_LRU_DUMP was failed.");
441+ }
442+
443+ goto end_func;
444+ }
445+ else if (!strncasecmp("XTRA_LRU_RESTORE", ptr, 16)) {
446+ ut_print_timestamp(stderr);
447+ fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_RESTORE'"
448+ " was detected.\n");
449+
450+ if (buf_LRU_file_restore()) {
451+ field_store_string(i_s_table->field[0],
452+ "XTRA_LRU_RESTORE was succeeded.");
453+ } else {
454+ field_store_string(i_s_table->field[0],
455+ "XTRA_LRU_RESTORE was failed.");
456+ }
457+
458+ goto end_func;
459+ }
460
461 field_store_string(i_s_table->field[0],
462 "Undefined XTRA_* command.");
463diff -ruN a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
464--- a/storage/innobase/include/buf0lru.h 2010-12-03 15:49:59.223956070 +0900
465+++ b/storage/innobase/include/buf0lru.h 2010-12-04 15:33:37.681481467 +0900
466@@ -219,6 +219,18 @@
467 void
468 buf_LRU_stat_update(void);
469 /*=====================*/
470+/********************************************************************//**
471+Dump the LRU page list to the specific file. */
472+UNIV_INTERN
473+ibool
474+buf_LRU_file_dump(void);
475+/*===================*/
476+/********************************************************************//**
477+Read the pages based on the specific file.*/
478+UNIV_INTERN
479+ibool
480+buf_LRU_file_restore(void);
481+/*======================*/
482
483 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
484 /**********************************************************************//**
485diff -ruN a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h
486--- a/storage/innobase/include/buf0rea.h 2010-12-03 17:49:11.596953870 +0900
487+++ b/storage/innobase/include/buf0rea.h 2010-12-04 15:33:37.682563900 +0900
488@@ -31,6 +31,37 @@
489 #include "buf0types.h"
490
491 /********************************************************************//**
492+Low-level function which reads a page asynchronously from a file to the
493+buffer buf_pool if it is not already there, in which case does nothing.
494+Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
495+flag is cleared and the x-lock released by an i/o-handler thread.
496+@return 1 if a read request was queued, 0 if the page already resided
497+in buf_pool, or if the page is in the doublewrite buffer blocks in
498+which case it is never read into the pool, or if the tablespace does
499+not exist or is being dropped
500+@return 1 if read request is issued. 0 if it is not */
501+UNIV_INTERN
502+ulint
503+buf_read_page_low(
504+/*==============*/
505+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
506+ trying to read from a non-existent tablespace, or a
507+ tablespace which is just now being dropped */
508+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
509+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
510+ ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
511+ at read-ahead functions) */
512+ ulint space, /*!< in: space id */
513+ ulint zip_size,/*!< in: compressed page size, or 0 */
514+ ibool unzip, /*!< in: TRUE=request uncompressed page */
515+ ib_int64_t tablespace_version, /*!< in: if the space memory object has
516+ this timestamp different from what we are giving here,
517+ treat the tablespace as dropped; this is a timestamp we
518+ use to stop dangling page reads from a tablespace
519+ which we have DISCARDed + IMPORTed back */
520+ ulint offset, /*!< in: page number */
521+ trx_t* trx);
522+/********************************************************************//**
523 High-level function which reads a page asynchronously from a file to the
524 buffer buf_pool if it is not already there. Sets the io_fix flag and sets
525 an exclusive lock on the buffer frame. The flag is cleared and the x-lock
526diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
527--- a/storage/innobase/include/fil0fil.h 2010-12-03 17:49:11.597953501 +0900
528+++ b/storage/innobase/include/fil0fil.h 2010-12-04 15:33:37.684551372 +0900
529@@ -644,6 +644,22 @@
530 void* message, /*!< in: message for aio handler if non-sync
531 aio used, else ignored */
532 trx_t* trx);
533+/********************************************************************//**
534+Confirm whether the parameters are valid or not */
535+UNIV_INTERN
536+ibool
537+fil_area_is_exist(
538+/*==============*/
539+ ulint space_id, /*!< in: space id */
540+ ulint zip_size, /*!< in: compressed page size in bytes;
541+ 0 for uncompressed pages */
542+ ulint block_offset, /*!< in: offset in number of blocks */
543+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
544+ aio this must be divisible by the OS block
545+ size */
546+ ulint len); /*!< in: how many bytes to read or write; this
547+ must not cross a file boundary; in aio this
548+ must be a block size multiple */
549 /**********************************************************************//**
550 Waits for an aio operation to complete. This function is used to write the
551 handler for completed requests. The aio array of pending requests is divided
552diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
553--- a/storage/innobase/include/srv0srv.h 2010-12-03 17:49:11.603969747 +0900
554+++ b/storage/innobase/include/srv0srv.h 2010-12-04 15:33:37.685550816 +0900
555@@ -356,6 +356,9 @@
556 reading of a disk page */
557 extern ulint srv_buf_pool_reads;
558
559+/** Time in seconds between automatic buffer pool dumps */
560+extern uint srv_auto_lru_dump;
561+
562 /** Status variables to be passed to MySQL */
563 typedef struct export_var_struct export_struc;
564
565@@ -655,6 +658,16 @@
566 /*=====================*/
567 void* arg); /*!< in: a dummy parameter required by
568 os_thread_create */
569+/*********************************************************************//**
570+A thread which restores the buffer pool from a dump file on startup and does
571+periodic buffer pool dumps.
572+@return a dummy parameter */
573+UNIV_INTERN
574+os_thread_ret_t
575+srv_LRU_dump_restore_thread(
576+/*====================*/
577+ void* arg); /*!< in: a dummy parameter required by
578+ os_thread_create */
579 /******************************************************************//**
580 Outputs to a file the output of the InnoDB Monitor.
581 @return FALSE if not all information printed
582diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
583--- a/storage/innobase/srv/srv0srv.c 2010-12-03 17:49:11.620986661 +0900
584+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 15:33:37.708550811 +0900
585@@ -327,6 +327,9 @@
586 reading of a disk page */
587 UNIV_INTERN ulint srv_buf_pool_reads = 0;
588
589+/** Time in seconds between automatic buffer pool dumps */
590+UNIV_INTERN uint srv_auto_lru_dump = 0;
591+
592 /* structure to pass status variables to MySQL */
593 UNIV_INTERN export_struc export_vars;
594
595@@ -2663,6 +2666,56 @@
596 /* We count the number of threads in os_thread_exit(). A created
597 thread should always use that to exit and not use return() to exit. */
598
599+ os_thread_exit(NULL);
600+
601+ OS_THREAD_DUMMY_RETURN;
602+}
603+
604+/*********************************************************************//**
605+A thread which restores the buffer pool from a dump file on startup and does
606+periodic buffer pool dumps.
607+@return a dummy parameter */
608+UNIV_INTERN
609+os_thread_ret_t
610+srv_LRU_dump_restore_thread(
611+/*====================*/
612+ void* arg __attribute__((unused)))
613+ /*!< in: a dummy parameter required by
614+ os_thread_create */
615+{
616+ uint auto_lru_dump;
617+ time_t last_dump_time;
618+ time_t time_elapsed;
619+
620+#ifdef UNIV_DEBUG_THREAD_CREATION
621+ fprintf(stderr, "LRU dump/restore thread starts, id %lu\n",
622+ os_thread_pf(os_thread_get_curr_id()));
623+#endif
624+
625+ if (srv_auto_lru_dump)
626+ buf_LRU_file_restore();
627+
628+ last_dump_time = time(NULL);
629+
630+loop:
631+ os_thread_sleep(5000000);
632+
633+ if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
634+ goto exit_func;
635+ }
636+
637+ time_elapsed = time(NULL) - last_dump_time;
638+ auto_lru_dump = srv_auto_lru_dump;
639+ if (auto_lru_dump > 0 && (time_t) auto_lru_dump < time_elapsed) {
640+ last_dump_time = time(NULL);
641+ buf_LRU_file_dump();
642+ }
643+
644+ goto loop;
645+exit_func:
646+ /* We count the number of threads in os_thread_exit(). A created
647+ thread should always use that to exit and not use return() to exit. */
648+
649 os_thread_exit(NULL);
650
651 OS_THREAD_DUMMY_RETURN;
652diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
653--- a/storage/innobase/srv/srv0start.c 2010-12-03 15:18:48.916955609 +0900
654+++ b/storage/innobase/srv/srv0start.c 2010-12-04 15:33:37.711484798 +0900
655@@ -121,9 +121,9 @@
656 static os_file_t files[1000];
657
658 /** io_handler_thread parameters for thread identification */
659-static ulint n[SRV_MAX_N_IO_THREADS + 6];
660+static ulint n[SRV_MAX_N_IO_THREADS + 7];
661 /** io_handler_thread identifiers */
662-static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6];
663+static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 7];
664
665 /** We use this mutex to test the return value of pthread_mutex_trylock
666 on successful locking. HP-UX does NOT return 0, though Linux et al do. */
667@@ -1737,6 +1737,10 @@
668 os_thread_create(&srv_monitor_thread, NULL,
669 thread_ids + 4 + SRV_MAX_N_IO_THREADS);
670
671+ /* Create the thread which automaticaly dumps/restore buffer pool */
672+ os_thread_create(&srv_LRU_dump_restore_thread, NULL,
673+ thread_ids + 5 + SRV_MAX_N_IO_THREADS);
674+
675 srv_is_being_started = FALSE;
676
677 err = dict_create_or_check_foreign_constraint_tables();
This page took 0.104392 seconds and 4 git commands to generate.