~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/buf/buf0lru.cc

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:26:39 UTC
  • mfrom: (2157.2.2 give-in-to-pkg-config)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172639-nhy7i72sfhoq13ms
Merged in pkg-config fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
Created 11/5/1995 Heikki Tuuri
24
24
*******************************************************/
25
25
 
26
 
#include <config.h>
 
26
#include "config.h"
27
27
#include "buf0lru.h"
28
28
 
29
29
#ifdef UNIV_NONINL
2110
2110
        memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
2111
2111
}
2112
2112
 
2113
 
/********************************************************************//**
2114
 
Dump the LRU page list to the specific file. */
2115
 
#define LRU_DUMP_FILE "ib_lru_dump"
2116
 
 
2117
 
UNIV_INTERN
2118
 
bool
2119
 
buf_LRU_file_dump(void)
2120
 
/*===================*/
2121
 
{
2122
 
        os_file_t       dump_file = -1;
2123
 
        ibool           success;
2124
 
        byte*           buffer_base = NULL;
2125
 
        byte*           buffer = NULL;
2126
 
        buf_page_t*     bpage;
2127
 
        ulint           buffers;
2128
 
        ulint           offset;
2129
 
        bool            ret = false;
2130
 
        ulint           i;
2131
 
 
2132
 
        for (i = 0; i < srv_n_data_files; i++) {
2133
 
                if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) {
2134
 
                        fprintf(stderr,
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);
2138
 
                        goto end;
2139
 
                }
2140
 
        }
2141
 
 
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) {
2145
 
                fprintf(stderr,
2146
 
                        " InnoDB: cannot allocate buffer.\n");
2147
 
                goto end;
2148
 
        }
2149
 
 
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);
2154
 
                fprintf(stderr,
2155
 
                        " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
2156
 
                goto end;
2157
 
        }
2158
 
 
2159
 
        buffers = offset = 0;
2160
 
 
2161
 
        for (i = 0; i < srv_buf_pool_instances; i++) {
2162
 
                buf_pool_t*     buf_pool;
2163
 
 
2164
 
                buf_pool = buf_pool_from_array(i);
2165
 
 
2166
 
                buf_pool_mutex_enter(buf_pool);
2167
 
                bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2168
 
 
2169
 
                while (bpage != NULL) {
2170
 
                        if (offset == 0) {
2171
 
                                memset(buffer, 0, UNIV_PAGE_SIZE);
2172
 
                        }
2173
 
 
2174
 
                        mach_write_to_4(buffer + offset * 4, bpage->space);
2175
 
                        offset++;
2176
 
                        mach_write_to_4(buffer + offset * 4, bpage->offset);
2177
 
                        offset++;
2178
 
 
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)),
2183
 
                                                        UNIV_PAGE_SIZE);
2184
 
                                if (success == FALSE) {
2185
 
                                        buf_pool_mutex_exit(buf_pool);
2186
 
                                        fprintf(stderr,
2187
 
                                                " InnoDB: cannot write page %lu of %s\n",
2188
 
                                                buffers, LRU_DUMP_FILE);
2189
 
                                        goto end;
2190
 
                                }
2191
 
                                buffers++;
2192
 
                                offset = 0;
2193
 
                        }
2194
 
 
2195
 
                        bpage = UT_LIST_GET_PREV(LRU, bpage);
2196
 
                }
2197
 
                buf_pool_mutex_exit(buf_pool);
2198
 
        }
2199
 
 
2200
 
        if (offset == 0) {
2201
 
                memset(buffer, 0, UNIV_PAGE_SIZE);
2202
 
        }
2203
 
 
2204
 
        mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
2205
 
        offset++;
2206
 
        mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
2207
 
        offset++;
2208
 
 
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)),
2212
 
                                UNIV_PAGE_SIZE);
2213
 
        if (success == FALSE) {
2214
 
                goto end;
2215
 
        }
2216
 
 
2217
 
        ret = true;
2218
 
end:
2219
 
        if (dump_file != -1)
2220
 
                os_file_close(dump_file);
2221
 
        if (buffer_base)
2222
 
                ut_free(buffer_base);
2223
 
 
2224
 
        return(ret);
2225
 
}
2226
 
 
2227
 
typedef struct {
2228
 
        ib_uint32_t space_id;
2229
 
        ib_uint32_t page_no;
2230
 
} dump_record_t;
2231
 
 
2232
 
static int dump_record_cmp(const void *a, const void *b)
2233
 
{
2234
 
        const dump_record_t *rec1 = (dump_record_t *) a;
2235
 
        const dump_record_t *rec2 = (dump_record_t *) b;
2236
 
 
2237
 
        if (rec1->space_id < rec2->space_id)
2238
 
                return -1;
2239
 
        if (rec1->space_id > rec2->space_id)
2240
 
                return 1;
2241
 
        if (rec1->page_no < rec2->page_no)
2242
 
                return -1;
2243
 
        return rec1->page_no > rec2->page_no;
2244
 
}
2245
 
 
2246
 
/********************************************************************//**
2247
 
Read the pages based on the specific file.*/
2248
 
UNIV_INTERN
2249
 
bool
2250
 
buf_LRU_file_restore(void)
2251
 
/*======================*/
2252
 
{
2253
 
        os_file_t       dump_file = -1;
2254
 
        ibool           success;
2255
 
        byte*           buffer_base = NULL;
2256
 
        byte*           buffer = NULL;
2257
 
        ulint           buffers;
2258
 
        ulint           offset;
2259
 
        ulint           reads = 0;
2260
 
        ulint           req = 0;
2261
 
        bool            terminated = false;
2262
 
        bool            ret = false;
2263
 
        dump_record_t*  records = NULL;
2264
 
        ulint           size;
2265
 
        ulint           size_high;
2266
 
        ulint           length;
2267
 
 
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);
2272
 
                fprintf(stderr,
2273
 
                        " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
2274
 
                goto end;
2275
 
        }
2276
 
        if (size == 0 || size_high > 0 || size % 8) {
2277
 
                fprintf(stderr, " InnoDB: broken LRU dump file\n");
2278
 
                goto end;
2279
 
        }
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) {
2284
 
                fprintf(stderr,
2285
 
                        " InnoDB: cannot allocate buffer.\n");
2286
 
                goto end;
2287
 
        }
2288
 
 
2289
 
        buffers = 0;
2290
 
        length = 0;
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)),
2295
 
                                       UNIV_PAGE_SIZE);
2296
 
                if (success == FALSE) {
2297
 
                        fprintf(stderr,
2298
 
                                " InnoDB: either could not read page %lu of %s,"
2299
 
                                " or terminated unexpectedly.\n",
2300
 
                                buffers, LRU_DUMP_FILE);
2301
 
                        goto end;
2302
 
                }
2303
 
 
2304
 
                for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
2305
 
                        ulint   space_id;
2306
 
                        ulint   page_no;
2307
 
 
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) {
2312
 
                                terminated = true;
2313
 
                                break;
2314
 
                        }
2315
 
 
2316
 
                        records[length].space_id = space_id;
2317
 
                        records[length].page_no = page_no;
2318
 
                        length++;
2319
 
                        if (length * 8 >= size) {
2320
 
                                fprintf(stderr,
2321
 
                                        " InnoDB: could not find the "
2322
 
                                        "end-of-file marker after reading "
2323
 
                                        "the expected %lu bytes from the "
2324
 
                                        "LRU dump file.\n"
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",
2329
 
                                        size);
2330
 
                                terminated = true;
2331
 
                                break;
2332
 
                        }
2333
 
                }
2334
 
                buffers++;
2335
 
        }
2336
 
 
2337
 
        qsort(records, length, sizeof(dump_record_t), dump_record_cmp);
2338
 
 
2339
 
        for (offset = 0; offset < length; offset++) {
2340
 
                ulint   space_id;
2341
 
                ulint   page_no;
2342
 
                ulint   zip_size;
2343
 
                ulint   err;
2344
 
                int64_t tablespace_version;
2345
 
 
2346
 
                space_id = records[offset].space_id;
2347
 
                page_no = records[offset].page_no;
2348
 
 
2349
 
                if (offset % 16 == 15) {
2350
 
                        os_aio_simulated_wake_handler_threads();
2351
 
                        buf_flush_free_margins();
2352
 
                }
2353
 
 
2354
 
                zip_size = fil_space_get_zip_size(space_id);
2355
 
                if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
2356
 
                        continue;
2357
 
                }
2358
 
 
2359
 
                if (fil_is_exist(space_id, page_no)) {
2360
 
 
2361
 
                        tablespace_version = fil_space_get_version(space_id);
2362
 
 
2363
 
                        req++;
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();
2369
 
                }
2370
 
        }
2371
 
 
2372
 
        os_aio_simulated_wake_handler_threads();
2373
 
        buf_flush_free_margins();
2374
 
 
2375
 
        ut_print_timestamp(stderr);
2376
 
        fprintf(stderr,
2377
 
                " InnoDB: reading pages based on the dumped LRU list was done."
2378
 
                " (requested: %lu, read: %lu)\n", req, reads);
2379
 
        ret = true;
2380
 
end:
2381
 
        if (dump_file != -1)
2382
 
                os_file_close(dump_file);
2383
 
        if (buffer_base)
2384
 
                ut_free(buffer_base);
2385
 
        if (records)
2386
 
                ut_free(records);
2387
 
 
2388
 
        return(ret);
2389
 
}
2390
 
 
2391
2113
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
2392
2114
/**********************************************************************//**
2393
2115
Validates the LRU list for one buffer pool instance. */