2110
2110
memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
2113
/********************************************************************//**
2114
Dump the LRU page list to the specific file. */
2115
#define LRU_DUMP_FILE "ib_lru_dump"
2119
buf_LRU_file_dump(void)
2120
/*===================*/
2122
os_file_t dump_file = -1;
2124
byte* buffer_base = NULL;
2125
byte* buffer = NULL;
2132
for (i = 0; i < srv_n_data_files; i++) {
2133
if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) {
2135
" InnoDB: The name '%s' seems to be used for"
2136
" innodb_data_file_path. For safety, dumping of the LRU list"
2137
" is not being done.\n", LRU_DUMP_FILE);
2142
buffer_base = static_cast<byte *>(ut_malloc(2 * UNIV_PAGE_SIZE));
2143
buffer = static_cast<byte *>(ut_align(buffer_base, UNIV_PAGE_SIZE));
2144
if (buffer == NULL) {
2146
" InnoDB: cannot allocate buffer.\n");
2150
dump_file = os_file_create(innodb_file_temp_key, LRU_DUMP_FILE, OS_FILE_OVERWRITE,
2151
OS_FILE_NORMAL, OS_DATA_FILE, &success);
2152
if (success == FALSE) {
2153
os_file_get_last_error(TRUE);
2155
" InnoDB: cannot open %s\n", LRU_DUMP_FILE);
2159
buffers = offset = 0;
2161
for (i = 0; i < srv_buf_pool_instances; i++) {
2162
buf_pool_t* buf_pool;
2164
buf_pool = buf_pool_from_array(i);
2166
buf_pool_mutex_enter(buf_pool);
2167
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2169
while (bpage != NULL) {
2171
memset(buffer, 0, UNIV_PAGE_SIZE);
2174
mach_write_to_4(buffer + offset * 4, bpage->space);
2176
mach_write_to_4(buffer + offset * 4, bpage->offset);
2179
if (offset == UNIV_PAGE_SIZE/4) {
2180
success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
2181
(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
2182
(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
2184
if (success == FALSE) {
2185
buf_pool_mutex_exit(buf_pool);
2187
" InnoDB: cannot write page %lu of %s\n",
2188
buffers, LRU_DUMP_FILE);
2195
bpage = UT_LIST_GET_PREV(LRU, bpage);
2197
buf_pool_mutex_exit(buf_pool);
2201
memset(buffer, 0, UNIV_PAGE_SIZE);
2204
mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
2206
mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
2209
success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
2210
(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
2211
(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
2213
if (success == FALSE) {
2219
if (dump_file != -1)
2220
os_file_close(dump_file);
2222
ut_free(buffer_base);
2228
ib_uint32_t space_id;
2229
ib_uint32_t page_no;
2232
static int dump_record_cmp(const void *a, const void *b)
2234
const dump_record_t *rec1 = (dump_record_t *) a;
2235
const dump_record_t *rec2 = (dump_record_t *) b;
2237
if (rec1->space_id < rec2->space_id)
2239
if (rec1->space_id > rec2->space_id)
2241
if (rec1->page_no < rec2->page_no)
2243
return rec1->page_no > rec2->page_no;
2246
/********************************************************************//**
2247
Read the pages based on the specific file.*/
2250
buf_LRU_file_restore(void)
2251
/*======================*/
2253
os_file_t dump_file = -1;
2255
byte* buffer_base = NULL;
2256
byte* buffer = NULL;
2261
bool terminated = false;
2263
dump_record_t* records = NULL;
2268
dump_file = os_file_create_simple_no_error_handling(innodb_file_temp_key,
2269
LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
2270
if (success == FALSE || !os_file_get_size(dump_file, &size, &size_high)) {
2271
os_file_get_last_error(TRUE);
2273
" InnoDB: cannot open %s\n", LRU_DUMP_FILE);
2276
if (size == 0 || size_high > 0 || size % 8) {
2277
fprintf(stderr, " InnoDB: broken LRU dump file\n");
2280
buffer_base = static_cast<byte *>(ut_malloc(2 * UNIV_PAGE_SIZE));
2281
buffer = static_cast<byte *>(ut_align(buffer_base, UNIV_PAGE_SIZE));
2282
records = static_cast<dump_record_t *>(ut_malloc(size));
2283
if (buffer == NULL || records == NULL) {
2285
" InnoDB: cannot allocate buffer.\n");
2291
while (!terminated) {
2292
success = os_file_read(dump_file, buffer,
2293
(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
2294
(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
2296
if (success == FALSE) {
2298
" InnoDB: either could not read page %lu of %s,"
2299
" or terminated unexpectedly.\n",
2300
buffers, LRU_DUMP_FILE);
2304
for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
2308
space_id = mach_read_from_4(buffer + offset * 4);
2309
page_no = mach_read_from_4(buffer + (offset + 1) * 4);
2310
if (space_id == 0xFFFFFFFFUL
2311
|| page_no == 0xFFFFFFFFUL) {
2316
records[length].space_id = space_id;
2317
records[length].page_no = page_no;
2319
if (length * 8 >= size) {
2321
" InnoDB: could not find the "
2322
"end-of-file marker after reading "
2323
"the expected %lu bytes from the "
2325
" InnoDB: this could be caused by a "
2326
"broken or incomplete file.\n"
2327
" InnoDB: trying to process what has "
2328
"been read so far.\n",
2337
qsort(records, length, sizeof(dump_record_t), dump_record_cmp);
2339
for (offset = 0; offset < length; offset++) {
2344
int64_t tablespace_version;
2346
space_id = records[offset].space_id;
2347
page_no = records[offset].page_no;
2349
if (offset % 16 == 15) {
2350
os_aio_simulated_wake_handler_threads();
2351
buf_flush_free_margins();
2354
zip_size = fil_space_get_zip_size(space_id);
2355
if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
2359
if (fil_is_exist(space_id, page_no)) {
2361
tablespace_version = fil_space_get_version(space_id);
2364
reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
2365
| OS_AIO_SIMULATED_WAKE_LATER,
2366
space_id, zip_size, TRUE,
2367
tablespace_version, page_no);
2368
buf_LRU_stat_inc_io();
2372
os_aio_simulated_wake_handler_threads();
2373
buf_flush_free_margins();
2375
ut_print_timestamp(stderr);
2377
" InnoDB: reading pages based on the dumped LRU list was done."
2378
" (requested: %lu, read: %lu)\n", req, reads);
2381
if (dump_file != -1)
2382
os_file_close(dump_file);
2384
ut_free(buffer_base);
2113
2391
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
2114
2392
/**********************************************************************//**
2115
2393
Validates the LRU list for one buffer pool instance. */