1
diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c
2
--- a/storage/innodb_plugin/buf/buf0lru.c 2010-04-29 18:58:20.000000000 +0900
3
+++ b/storage/innodb_plugin/buf/buf0lru.c 2010-04-30 15:47:10.000000000 +0900
4
@@ -2107,6 +2107,218 @@
5
memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
8
+/********************************************************************//**
9
+Dump the LRU page list to the specific file. */
10
+#define LRU_DUMP_FILE "ib_lru_dump"
14
+buf_LRU_file_dump(void)
15
+/*===================*/
17
+ os_file_t dump_file = -1;
19
+ byte* buffer_base = NULL;
20
+ byte* buffer = NULL;
27
+ for (i = 0; i < srv_n_data_files; i++) {
28
+ if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) {
30
+ " InnoDB: The name '%s' seems to be used for"
31
+ " innodb_data_file_path. Dumping LRU list is not"
32
+ " done for safeness.\n", LRU_DUMP_FILE);
37
+ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
38
+ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
41
+ " InnoDB: cannot allocate buffer.\n");
45
+ dump_file = os_file_create(LRU_DUMP_FILE, OS_FILE_OVERWRITE,
46
+ OS_FILE_NORMAL, OS_DATA_FILE, &success);
48
+ os_file_get_last_error(TRUE);
50
+ " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
54
+ mutex_enter(&LRU_list_mutex);
55
+ bpage = UT_LIST_GET_LAST(buf_pool->LRU);
57
+ buffers = offset = 0;
58
+ while (bpage != NULL) {
60
+ memset(buffer, 0, UNIV_PAGE_SIZE);
63
+ mach_write_to_4(buffer + offset * 4, bpage->space);
65
+ mach_write_to_4(buffer + offset * 4, bpage->offset);
68
+ if (offset == UNIV_PAGE_SIZE/4) {
69
+ success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
70
+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
71
+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
74
+ mutex_exit(&LRU_list_mutex);
76
+ " InnoDB: cannot write page %lu of %s\n",
77
+ buffers, LRU_DUMP_FILE);
84
+ bpage = UT_LIST_GET_PREV(LRU, bpage);
86
+ mutex_exit(&LRU_list_mutex);
89
+ memset(buffer, 0, UNIV_PAGE_SIZE);
92
+ mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
94
+ mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
97
+ success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
98
+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
99
+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
107
+ if (dump_file != -1)
108
+ os_file_close(dump_file);
110
+ ut_free(buffer_base);
114
+/********************************************************************//**
115
+Read the pages based on the specific file.*/
118
+buf_LRU_file_restore(void)
119
+/*======================*/
121
+ os_file_t dump_file = -1;
123
+ byte* buffer_base = NULL;
124
+ byte* buffer = NULL;
129
+ ibool terminated = FALSE;
132
+ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
133
+ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
136
+ " InnoDB: cannot allocate buffer.\n");
140
+ dump_file = os_file_create_simple_no_error_handling(
141
+ LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
143
+ os_file_get_last_error(TRUE);
145
+ " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
150
+ while (!terminated) {
151
+ success = os_file_read(dump_file, buffer,
152
+ (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
153
+ (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
157
+ " InnoDB: cannot read page %lu of %s,"
158
+ " or meet unexpected terminal.",
159
+ buffers, LRU_DUMP_FILE);
163
+ for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
164
+ ulint space_id, zip_size, page_no;
166
+ ib_int64_t tablespace_version;
168
+ space_id = mach_read_from_4(buffer + offset * 4);
169
+ page_no = mach_read_from_4(buffer + (offset + 1) * 4);
170
+ if (space_id == 0xFFFFFFFFUL
171
+ || page_no == 0xFFFFFFFFUL) {
176
+ if (offset % 16 == 15) {
177
+ os_aio_simulated_wake_handler_threads();
178
+ buf_flush_free_margin(FALSE);
181
+ zip_size = fil_space_get_zip_size(space_id);
182
+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
186
+ if (fil_area_is_exist(space_id, zip_size, page_no, 0,
187
+ zip_size ? zip_size : UNIV_PAGE_SIZE)) {
189
+ tablespace_version = fil_space_get_version(space_id);
192
+ reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
193
+ | OS_AIO_SIMULATED_WAKE_LATER,
194
+ space_id, zip_size, TRUE,
195
+ tablespace_version, page_no, NULL);
196
+ buf_LRU_stat_inc_io();
203
+ os_aio_simulated_wake_handler_threads();
204
+ buf_flush_free_margin(FALSE);
206
+ ut_print_timestamp(stderr);
208
+ " InnoDB: reading pages based on the dumped LRU list was done."
209
+ " (requested: %lu, read: %lu)\n", req, reads);
212
+ if (dump_file != -1)
213
+ os_file_close(dump_file);
215
+ ut_free(buffer_base);
220
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
221
/**********************************************************************//**
222
Validates the LRU list.
223
diff -ruN a/storage/innodb_plugin/buf/buf0rea.c b/storage/innodb_plugin/buf/buf0rea.c
224
--- a/storage/innodb_plugin/buf/buf0rea.c 2010-04-30 15:01:51.000000000 +0900
225
+++ b/storage/innodb_plugin/buf/buf0rea.c 2010-04-30 15:47:10.000000000 +0900
227
which case it is never read into the pool, or if the tablespace does
228
not exist or is being dropped
229
@return 1 if read request is issued. 0 if it is not */
235
diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c
236
--- a/storage/innodb_plugin/fil/fil0fil.c 2010-04-30 15:01:51.000000000 +0900
237
+++ b/storage/innodb_plugin/fil/fil0fil.c 2010-04-30 15:47:10.000000000 +0900
238
@@ -4765,6 +4765,78 @@
242
+/********************************************************************//**
243
+Confirm whether the parameters are valid or not */
248
+ ulint space_id, /*!< in: space id */
249
+ ulint zip_size, /*!< in: compressed page size in bytes;
250
+ 0 for uncompressed pages */
251
+ ulint block_offset, /*!< in: offset in number of blocks */
252
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
253
+ aio this must be divisible by the OS block
255
+ ulint len) /*!< in: how many bytes to read or write; this
256
+ must not cross a file boundary; in aio this
257
+ must be a block size multiple */
259
+ fil_space_t* space;
262
+ /* Reserve the fil_system mutex and make sure that we can open at
263
+ least one file while holding it, if the file is not already open */
265
+ fil_mutex_enter_and_prepare_for_io(space_id);
267
+ space = fil_space_get_by_id(space_id);
270
+ mutex_exit(&fil_system->mutex);
274
+ node = UT_LIST_GET_FIRST(space->chain);
277
+ if (UNIV_UNLIKELY(node == NULL)) {
278
+ mutex_exit(&fil_system->mutex);
282
+ if (space->id != 0 && node->size == 0) {
283
+ /* We do not know the size of a single-table tablespace
284
+ before we open the file */
289
+ if (node->size > block_offset) {
293
+ block_offset -= node->size;
294
+ node = UT_LIST_GET_NEXT(chain, node);
298
+ /* Open file if closed */
299
+ fil_node_prepare_for_io(node, fil_system, space);
300
+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
302
+ /* Check that at least the start offset is within the bounds of a
303
+ single-table tablespace */
304
+ if (UNIV_UNLIKELY(node->size <= block_offset)
305
+ && space->id != 0 && space->purpose == FIL_TABLESPACE) {
306
+ mutex_exit(&fil_system->mutex);
310
+ mutex_exit(&fil_system->mutex);
314
#ifndef UNIV_HOTBACKUP
315
/**********************************************************************//**
316
Waits for an aio operation to complete. This function is used to write the
317
diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc
318
--- a/storage/innodb_plugin/handler/i_s.cc 2010-04-30 14:38:27.000000000 +0900
319
+++ b/storage/innodb_plugin/handler/i_s.cc 2010-04-30 15:47:10.000000000 +0900
321
#include "trx0rseg.h" /* for trx_rseg_struct */
322
#include "trx0sys.h" /* for trx_sys */
323
#include "dict0dict.h" /* for dict_sys */
324
+#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
326
struct buf_chunk_struct{
327
ulint mem_size; /* allocated size of the chunk */
328
@@ -3091,6 +3092,36 @@
332
+ else if (!strncasecmp("XTRA_LRU_DUMP", ptr, 13)) {
333
+ ut_print_timestamp(stderr);
334
+ fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_DUMP'"
335
+ " was detected.\n");
337
+ if (buf_LRU_file_dump()) {
338
+ field_store_string(i_s_table->field[0],
339
+ "XTRA_LRU_DUMP was succeeded.");
341
+ field_store_string(i_s_table->field[0],
342
+ "XTRA_LRU_DUMP was failed.");
347
+ else if (!strncasecmp("XTRA_LRU_RESTORE", ptr, 16)) {
348
+ ut_print_timestamp(stderr);
349
+ fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_RESTORE'"
350
+ " was detected.\n");
352
+ if (buf_LRU_file_restore()) {
353
+ field_store_string(i_s_table->field[0],
354
+ "XTRA_LRU_RESTORE was succeeded.");
356
+ field_store_string(i_s_table->field[0],
357
+ "XTRA_LRU_RESTORE was failed.");
363
field_store_string(i_s_table->field[0],
364
"Undefined XTRA_* command.");
365
diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
366
--- a/storage/innodb_plugin/handler/innodb_patch_info.h 2010-04-30 15:46:35.000000000 +0900
367
+++ b/storage/innodb_plugin/handler/innodb_patch_info.h 2010-04-30 15:47:10.000000000 +0900
369
{"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
370
{"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
371
{"innodb_relax_table_creation","Relax limitation of column size at table creation as builtin InnoDB.","","http://www.percona.com/docs/wiki/percona-xtradb"},
372
+{"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
373
{NULL, NULL, NULL, NULL}
375
diff -ruN a/storage/innodb_plugin/include/buf0lru.h b/storage/innodb_plugin/include/buf0lru.h
376
--- a/storage/innodb_plugin/include/buf0lru.h 2010-04-29 18:58:20.000000000 +0900
377
+++ b/storage/innodb_plugin/include/buf0lru.h 2010-04-30 15:47:10.000000000 +0900
380
buf_LRU_stat_update(void);
381
/*=====================*/
382
+/********************************************************************//**
383
+Dump the LRU page list to the specific file. */
386
+buf_LRU_file_dump(void);
387
+/*===================*/
388
+/********************************************************************//**
389
+Read the pages based on the specific file.*/
392
+buf_LRU_file_restore(void);
393
+/*======================*/
395
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
396
/**********************************************************************//**
397
diff -ruN a/storage/innodb_plugin/include/buf0rea.h b/storage/innodb_plugin/include/buf0rea.h
398
--- a/storage/innodb_plugin/include/buf0rea.h 2010-04-30 15:01:51.000000000 +0900
399
+++ b/storage/innodb_plugin/include/buf0rea.h 2010-04-30 15:47:10.000000000 +0900
401
#include "buf0types.h"
403
/********************************************************************//**
404
+Low-level function which reads a page asynchronously from a file to the
405
+buffer buf_pool if it is not already there, in which case does nothing.
406
+Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
407
+flag is cleared and the x-lock released by an i/o-handler thread.
408
+@return 1 if a read request was queued, 0 if the page already resided
409
+in buf_pool, or if the page is in the doublewrite buffer blocks in
410
+which case it is never read into the pool, or if the tablespace does
411
+not exist or is being dropped
412
+@return 1 if read request is issued. 0 if it is not */
417
+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
418
+ trying to read from a non-existent tablespace, or a
419
+ tablespace which is just now being dropped */
420
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
421
+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
422
+ ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
423
+ at read-ahead functions) */
424
+ ulint space, /*!< in: space id */
425
+ ulint zip_size,/*!< in: compressed page size, or 0 */
426
+ ibool unzip, /*!< in: TRUE=request uncompressed page */
427
+ ib_int64_t tablespace_version, /*!< in: if the space memory object has
428
+ this timestamp different from what we are giving here,
429
+ treat the tablespace as dropped; this is a timestamp we
430
+ use to stop dangling page reads from a tablespace
431
+ which we have DISCARDed + IMPORTed back */
432
+ ulint offset, /*!< in: page number */
434
+/********************************************************************//**
435
High-level function which reads a page asynchronously from a file to the
436
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
437
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
438
diff -ruN a/storage/innodb_plugin/include/fil0fil.h b/storage/innodb_plugin/include/fil0fil.h
439
--- a/storage/innodb_plugin/include/fil0fil.h 2010-04-30 15:01:51.000000000 +0900
440
+++ b/storage/innodb_plugin/include/fil0fil.h 2010-04-30 15:47:10.000000000 +0900
442
void* message, /*!< in: message for aio handler if non-sync
443
aio used, else ignored */
445
+/********************************************************************//**
446
+Confirm whether the parameters are valid or not */
451
+ ulint space_id, /*!< in: space id */
452
+ ulint zip_size, /*!< in: compressed page size in bytes;
453
+ 0 for uncompressed pages */
454
+ ulint block_offset, /*!< in: offset in number of blocks */
455
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
456
+ aio this must be divisible by the OS block
458
+ ulint len); /*!< in: how many bytes to read or write; this
459
+ must not cross a file boundary; in aio this
460
+ must be a block size multiple */
461
/**********************************************************************//**
462
Waits for an aio operation to complete. This function is used to write the
463
handler for completed requests. The aio array of pending requests is divided