~stewart/haildb/historical

« back to all changes in this revision

Viewing changes to os/os0file.c

  • Committer: Stewart Smith
  • Date: 2010-04-14 16:57:03 UTC
  • Revision ID: stewart@flamingspork.com-20100414165703-oegscdguy22kizql
innodb plugin 1.0.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
/* We do not call os_file_flush in every os_file_write. */
89
89
#endif /* UNIV_DO_FLUSH */
90
90
 
91
 
#ifndef UNIV_HOTBACKUP
 
91
#ifdef UNIV_HOTBACKUP
 
92
# define os_aio_use_native_aio  FALSE
 
93
#else /* UNIV_HOTBACKUP */
92
94
/* We use these mutexes to protect lseek + file i/o operation, if the
93
95
OS does not provide an atomic pread or pwrite, or similar */
94
96
#define OS_FILE_N_SEEK_MUTEXES  16
198
200
/** If the following is TRUE, read i/o handler threads try to
199
201
wait until a batch of new read requests have been posted */
200
202
static ibool    os_aio_recommend_sleep_for_read_threads = FALSE;
201
 
#endif /* !UNIV_HOTBACKUP */
 
203
#endif /* UNIV_HOTBACKUP */
202
204
 
203
205
UNIV_INTERN ulint       os_n_file_reads         = 0;
204
206
UNIV_INTERN ulint       os_bytes_read_since_printout = 0;
315
317
                                " software or another instance\n"
316
318
                                "InnoDB: of MySQL."
317
319
                                " Please close it to get rid of this error.\n");
 
320
                } else if (err == ERROR_WORKING_SET_QUOTA
 
321
                           || err == ERROR_NO_SYSTEM_RESOURCES) {
 
322
                        fprintf(stderr,
 
323
                                "InnoDB: The error means that there are no"
 
324
                                " sufficient system resources or quota to"
 
325
                                " complete the operation.\n");
 
326
                } else if (err == ERROR_OPERATION_ABORTED) {
 
327
                        fprintf(stderr,
 
328
                                "InnoDB: The error means that the I/O"
 
329
                                " operation has been aborted\n"
 
330
                                "InnoDB: because of either a thread exit"
 
331
                                " or an application request.\n"
 
332
                                "InnoDB: Retry attempt is made.\n");
318
333
                } else {
319
334
                        fprintf(stderr,
320
335
                                "InnoDB: Some operating system error numbers"
336
351
        } else if (err == ERROR_SHARING_VIOLATION
337
352
                   || err == ERROR_LOCK_VIOLATION) {
338
353
                return(OS_FILE_SHARING_VIOLATION);
 
354
        } else if (err == ERROR_WORKING_SET_QUOTA
 
355
                   || err == ERROR_NO_SYSTEM_RESOURCES) {
 
356
                return(OS_FILE_INSUFFICIENT_RESOURCE);
 
357
        } else if (err == ERROR_OPERATION_ABORTED) {
 
358
                return(OS_FILE_OPERATION_ABORTED);
339
359
        } else {
340
360
                return(100 + err);
341
361
        }
454
474
 
455
475
                os_thread_sleep(10000000);  /* 10 sec */
456
476
                return(TRUE);
 
477
        } else if (err == OS_FILE_INSUFFICIENT_RESOURCE) {
 
478
 
 
479
                os_thread_sleep(100000);        /* 100 ms */
 
480
                return(TRUE);
 
481
        } else if (err == OS_FILE_OPERATION_ABORTED) {
 
482
 
 
483
                os_thread_sleep(100000);        /* 100 ms */
 
484
                return(TRUE);
457
485
        } else {
458
486
                if (name) {
459
487
                        fprintf(stderr, "InnoDB: File name %s\n", name);
817
845
        ret = stat(full_path, &statinfo);
818
846
 
819
847
        if (ret) {
 
848
 
 
849
                if (errno == ENOENT) {
 
850
                        /* readdir() returned a file that does not exist,
 
851
                        it must have been deleted in the meantime. Do what
 
852
                        would have happened if the file was deleted before
 
853
                        readdir() - ignore and go to the next entry.
 
854
                        If this is the last entry then info->name will still
 
855
                        contain the name of the deleted file when this
 
856
                        function returns, but this is not an issue since the
 
857
                        caller shouldn't be looking at info when end of
 
858
                        directory is returned. */
 
859
 
 
860
                        ut_free(full_path);
 
861
 
 
862
                        goto next_file;
 
863
                }
 
864
 
820
865
                os_file_handle_error_no_exit(full_path, "stat");
821
866
 
822
867
                ut_free(full_path);
1245
1290
                }
1246
1291
#endif
1247
1292
#ifdef UNIV_NON_BUFFERED_IO
 
1293
# ifndef UNIV_HOTBACKUP
1248
1294
                if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
1249
1295
                        /* Do not use unbuffered i/o to log files because
1250
1296
                        value 2 denotes that we do not flush the log at every
1253
1299
                           == SRV_WIN_IO_UNBUFFERED) {
1254
1300
                        attributes = attributes | FILE_FLAG_NO_BUFFERING;
1255
1301
                }
1256
 
#endif
 
1302
# else /* !UNIV_HOTBACKUP */
 
1303
                attributes = attributes | FILE_FLAG_NO_BUFFERING;
 
1304
# endif /* !UNIV_HOTBACKUP */
 
1305
#endif /* UNIV_NON_BUFFERED_IO */
1257
1306
        } else if (purpose == OS_FILE_NORMAL) {
1258
1307
                attributes = 0;
1259
1308
#ifdef UNIV_NON_BUFFERED_IO
 
1309
# ifndef UNIV_HOTBACKUP
1260
1310
                if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
1261
1311
                        /* Do not use unbuffered i/o to log files because
1262
1312
                        value 2 denotes that we do not flush the log at every
1265
1315
                           == SRV_WIN_IO_UNBUFFERED) {
1266
1316
                        attributes = attributes | FILE_FLAG_NO_BUFFERING;
1267
1317
                }
1268
 
#endif
 
1318
# else /* !UNIV_HOTBACKUP */
 
1319
                attributes = attributes | FILE_FLAG_NO_BUFFERING;
 
1320
# endif /* !UNIV_HOTBACKUP */
 
1321
#endif /* UNIV_NON_BUFFERED_IO */
1269
1322
        } else {
1270
1323
                attributes = 0;
1271
1324
                ut_error;
2022
2075
                                offset */
2023
2076
{
2024
2077
        off_t   offs;
 
2078
#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
2025
2079
        ssize_t n_bytes;
 
2080
#endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
2026
2081
 
2027
2082
        ut_a((offset & 0xFFFFFFFFUL) == offset);
2028
2083
 
2061
2116
        {
2062
2117
                off_t   ret_offset;
2063
2118
                ssize_t ret;
 
2119
#ifndef UNIV_HOTBACKUP
2064
2120
                ulint   i;
 
2121
#endif /* !UNIV_HOTBACKUP */
2065
2122
 
2066
2123
                os_mutex_enter(os_file_count_mutex);
2067
2124
                os_n_pending_reads++;
2068
2125
                os_mutex_exit(os_file_count_mutex);
2069
2126
 
 
2127
#ifndef UNIV_HOTBACKUP
2070
2128
                /* Protect the seek / read operation with a mutex */
2071
2129
                i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2072
2130
 
2073
2131
                os_mutex_enter(os_file_seek_mutexes[i]);
 
2132
#endif /* !UNIV_HOTBACKUP */
2074
2133
 
2075
2134
                ret_offset = lseek(file, offs, SEEK_SET);
2076
2135
 
2080
2139
                        ret = read(file, buf, (ssize_t)n);
2081
2140
                }
2082
2141
 
 
2142
#ifndef UNIV_HOTBACKUP
2083
2143
                os_mutex_exit(os_file_seek_mutexes[i]);
 
2144
#endif /* !UNIV_HOTBACKUP */
2084
2145
 
2085
2146
                os_mutex_enter(os_file_count_mutex);
2086
2147
                os_n_pending_reads--;
2158
2219
#else
2159
2220
        {
2160
2221
                off_t   ret_offset;
 
2222
# ifndef UNIV_HOTBACKUP
2161
2223
                ulint   i;
 
2224
# endif /* !UNIV_HOTBACKUP */
2162
2225
 
2163
2226
                os_mutex_enter(os_file_count_mutex);
2164
2227
                os_n_pending_writes++;
2165
2228
                os_mutex_exit(os_file_count_mutex);
2166
2229
 
 
2230
# ifndef UNIV_HOTBACKUP
2167
2231
                /* Protect the seek / write operation with a mutex */
2168
2232
                i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2169
2233
 
2170
2234
                os_mutex_enter(os_file_seek_mutexes[i]);
 
2235
# endif /* UNIV_HOTBACKUP */
2171
2236
 
2172
2237
                ret_offset = lseek(file, offs, SEEK_SET);
2173
2238
 
2193
2258
# endif /* UNIV_DO_FLUSH */
2194
2259
 
2195
2260
func_exit:
 
2261
# ifndef UNIV_HOTBACKUP
2196
2262
                os_mutex_exit(os_file_seek_mutexes[i]);
 
2263
# endif /* !UNIV_HOTBACKUP */
2197
2264
 
2198
2265
                os_mutex_enter(os_file_count_mutex);
2199
2266
                os_n_pending_writes--;
2227
2294
        DWORD           low;
2228
2295
        DWORD           high;
2229
2296
        ibool           retry;
 
2297
#ifndef UNIV_HOTBACKUP
2230
2298
        ulint           i;
 
2299
#endif /* !UNIV_HOTBACKUP */
2231
2300
 
2232
2301
        ut_a((offset & 0xFFFFFFFFUL) == offset);
2233
2302
 
2246
2315
        os_n_pending_reads++;
2247
2316
        os_mutex_exit(os_file_count_mutex);
2248
2317
 
 
2318
#ifndef UNIV_HOTBACKUP
2249
2319
        /* Protect the seek / read operation with a mutex */
2250
2320
        i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2251
2321
 
2252
2322
        os_mutex_enter(os_file_seek_mutexes[i]);
 
2323
#endif /* !UNIV_HOTBACKUP */
2253
2324
 
2254
2325
        ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2255
2326
 
2256
2327
        if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2257
2328
 
 
2329
#ifndef UNIV_HOTBACKUP
2258
2330
                os_mutex_exit(os_file_seek_mutexes[i]);
 
2331
#endif /* !UNIV_HOTBACKUP */
2259
2332
 
2260
2333
                os_mutex_enter(os_file_count_mutex);
2261
2334
                os_n_pending_reads--;
2266
2339
 
2267
2340
        ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
2268
2341
 
 
2342
#ifndef UNIV_HOTBACKUP
2269
2343
        os_mutex_exit(os_file_seek_mutexes[i]);
 
2344
#endif /* !UNIV_HOTBACKUP */
2270
2345
 
2271
2346
        os_mutex_enter(os_file_count_mutex);
2272
2347
        os_n_pending_reads--;
2275
2350
        if (ret && len == n) {
2276
2351
                return(TRUE);
2277
2352
        }
2278
 
#else
 
2353
#else /* __WIN__ */
2279
2354
        ibool   retry;
2280
2355
        ssize_t ret;
2281
2356
 
2294
2369
                "InnoDB: Was only able to read %ld.\n",
2295
2370
                (ulong)n, (ulong)offset_high,
2296
2371
                (ulong)offset, (long)ret);
2297
 
#endif
 
2372
#endif /* __WIN__ */
2298
2373
#ifdef __WIN__
2299
2374
error_handling:
2300
2375
#endif
2343
2418
        DWORD           low;
2344
2419
        DWORD           high;
2345
2420
        ibool           retry;
 
2421
#ifndef UNIV_HOTBACKUP
2346
2422
        ulint           i;
 
2423
#endif /* !UNIV_HOTBACKUP */
2347
2424
 
2348
2425
        ut_a((offset & 0xFFFFFFFFUL) == offset);
2349
2426
 
2362
2439
        os_n_pending_reads++;
2363
2440
        os_mutex_exit(os_file_count_mutex);
2364
2441
 
 
2442
#ifndef UNIV_HOTBACKUP
2365
2443
        /* Protect the seek / read operation with a mutex */
2366
2444
        i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2367
2445
 
2368
2446
        os_mutex_enter(os_file_seek_mutexes[i]);
 
2447
#endif /* !UNIV_HOTBACKUP */
2369
2448
 
2370
2449
        ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2371
2450
 
2372
2451
        if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2373
2452
 
 
2453
#ifndef UNIV_HOTBACKUP
2374
2454
                os_mutex_exit(os_file_seek_mutexes[i]);
 
2455
#endif /* !UNIV_HOTBACKUP */
2375
2456
 
2376
2457
                os_mutex_enter(os_file_count_mutex);
2377
2458
                os_n_pending_reads--;
2382
2463
 
2383
2464
        ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
2384
2465
 
 
2466
#ifndef UNIV_HOTBACKUP
2385
2467
        os_mutex_exit(os_file_seek_mutexes[i]);
 
2468
#endif /* !UNIV_HOTBACKUP */
2386
2469
 
2387
2470
        os_mutex_enter(os_file_count_mutex);
2388
2471
        os_n_pending_reads--;
2391
2474
        if (ret && len == n) {
2392
2475
                return(TRUE);
2393
2476
        }
2394
 
#else
 
2477
#else /* __WIN__ */
2395
2478
        ibool   retry;
2396
2479
        ssize_t ret;
2397
2480
 
2404
2487
 
2405
2488
                return(TRUE);
2406
2489
        }
2407
 
#endif
 
2490
#endif /* __WIN__ */
2408
2491
#ifdef __WIN__
2409
2492
error_handling:
2410
2493
#endif
2463
2546
        DWORD           ret2;
2464
2547
        DWORD           low;
2465
2548
        DWORD           high;
2466
 
        ulint           i;
2467
2549
        ulint           n_retries       = 0;
2468
2550
        ulint           err;
 
2551
#ifndef UNIV_HOTBACKUP
 
2552
        ulint           i;
 
2553
#endif /* !UNIV_HOTBACKUP */
2469
2554
 
2470
2555
        ut_a((offset & 0xFFFFFFFF) == offset);
2471
2556
 
2482
2567
        os_n_pending_writes++;
2483
2568
        os_mutex_exit(os_file_count_mutex);
2484
2569
 
 
2570
#ifndef UNIV_HOTBACKUP
2485
2571
        /* Protect the seek / write operation with a mutex */
2486
2572
        i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2487
2573
 
2488
2574
        os_mutex_enter(os_file_seek_mutexes[i]);
 
2575
#endif /* !UNIV_HOTBACKUP */
2489
2576
 
2490
2577
        ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2491
2578
 
2492
2579
        if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2493
2580
 
 
2581
#ifndef UNIV_HOTBACKUP
2494
2582
                os_mutex_exit(os_file_seek_mutexes[i]);
 
2583
#endif /* !UNIV_HOTBACKUP */
2495
2584
 
2496
2585
                os_mutex_enter(os_file_count_mutex);
2497
2586
                os_n_pending_writes--;
2525
2614
        }
2526
2615
# endif /* UNIV_DO_FLUSH */
2527
2616
 
 
2617
#ifndef UNIV_HOTBACKUP
2528
2618
        os_mutex_exit(os_file_seek_mutexes[i]);
 
2619
#endif /* !UNIV_HOTBACKUP */
2529
2620
 
2530
2621
        os_mutex_enter(os_file_count_mutex);
2531
2622
        os_n_pending_writes--;
2951
3042
        return(array);
2952
3043
}
2953
3044
 
 
3045
/************************************************************************//**
 
3046
Frees an aio wait array. */
 
3047
static
 
3048
void
 
3049
os_aio_array_free(
 
3050
/*==============*/
 
3051
        os_aio_array_t* array)  /*!< in, own: array to free */
 
3052
{
 
3053
#ifdef WIN_ASYNC_IO
 
3054
        ulint   i;
 
3055
 
 
3056
        for (i = 0; i < array->n_slots; i++) {
 
3057
                os_aio_slot_t*  slot = os_aio_array_get_nth_slot(array, i);
 
3058
                os_event_free(slot->event);
 
3059
        }
 
3060
#endif /* WIN_ASYNC_IO */
 
3061
 
 
3062
#ifdef __WIN__
 
3063
        ut_free(array->native_events);
 
3064
#endif /* __WIN__ */
 
3065
        os_mutex_free(array->mutex);
 
3066
        os_event_free(array->not_full);
 
3067
        os_event_free(array->is_empty);
 
3068
 
 
3069
        ut_free(array->slots);
 
3070
        ut_free(array);
 
3071
}
 
3072
 
2954
3073
/***********************************************************************
2955
3074
Initializes the asynchronous io system. Creates one array each for ibuf
2956
3075
and log i/o. Also creates one array each for read and write where each
3021
3140
 
3022
3141
}
3023
3142
 
 
3143
/***********************************************************************
 
3144
Frees the asynchronous io system. */
 
3145
UNIV_INTERN
 
3146
void
 
3147
os_aio_free(void)
 
3148
/*=============*/
 
3149
{
 
3150
        ulint   i;
 
3151
 
 
3152
        os_aio_array_free(os_aio_ibuf_array);
 
3153
        os_aio_ibuf_array = NULL;
 
3154
        os_aio_array_free(os_aio_log_array);
 
3155
        os_aio_log_array = NULL;
 
3156
        os_aio_array_free(os_aio_read_array);
 
3157
        os_aio_read_array = NULL;
 
3158
        os_aio_array_free(os_aio_write_array);
 
3159
        os_aio_write_array = NULL;
 
3160
        os_aio_array_free(os_aio_sync_array);
 
3161
        os_aio_sync_array = NULL;
 
3162
 
 
3163
        for (i = 0; i < os_aio_n_segments; i++) {
 
3164
                os_event_free(os_aio_segment_wait_events[i]);
 
3165
        }
 
3166
 
 
3167
        ut_free(os_aio_segment_wait_events);
 
3168
        os_aio_segment_wait_events = 0;
 
3169
        os_aio_n_segments = 0;
 
3170
}
 
3171
 
3024
3172
#ifdef WIN_ASYNC_IO
3025
3173
/************************************************************************//**
3026
3174
Wakes up all async i/o threads in the array in Windows async i/o at
3371
3519
os_aio_simulated_put_read_threads_to_sleep(void)
3372
3520
/*============================================*/
3373
3521
{
 
3522
 
 
3523
/* The idea of putting background IO threads to sleep is only for
 
3524
Windows when using simulated AIO. Windows XP seems to schedule
 
3525
background threads too eagerly to allow for coalescing during
 
3526
readahead requests. */
 
3527
#ifdef __WIN__
3374
3528
        os_aio_array_t* array;
3375
3529
        ulint           g;
3376
3530
 
 
3531
        if (os_aio_use_native_aio) {
 
3532
                /* We do not use simulated aio: do nothing */
 
3533
 
 
3534
                return;
 
3535
        }
 
3536
 
3377
3537
        os_aio_recommend_sleep_for_read_threads = TRUE;
3378
3538
 
3379
3539
        for (g = 0; g < os_aio_n_segments; g++) {
3384
3544
                        os_event_reset(os_aio_segment_wait_events[g]);
3385
3545
                }
3386
3546
        }
 
3547
#endif /* __WIN__ */
3387
3548
}
3388
3549
 
3389
3550
/*******************************************************************//**
3618
3779
        ibool           ret_val;
3619
3780
        BOOL            ret;
3620
3781
        DWORD           len;
 
3782
        BOOL            retry           = FALSE;
3621
3783
 
3622
3784
        if (segment == ULINT_UNDEFINED) {
3623
3785
                array = os_aio_sync_array;
3671
3833
                        ut_a(TRUE == os_file_flush(slot->file));
3672
3834
                }
3673
3835
#endif /* UNIV_DO_FLUSH */
 
3836
        } else if (os_file_handle_error(slot->name, "Windows aio")) {
 
3837
 
 
3838
                retry = TRUE;
3674
3839
        } else {
3675
 
                os_file_handle_error(slot->name, "Windows aio");
3676
3840
 
3677
3841
                ret_val = FALSE;
3678
3842
        }
3679
3843
 
3680
3844
        os_mutex_exit(array->mutex);
3681
3845
 
 
3846
        if (retry) {
 
3847
                /* retry failed read/write operation synchronously.
 
3848
                No need to hold array->mutex. */
 
3849
 
 
3850
                switch (slot->type) {
 
3851
                case OS_FILE_WRITE:
 
3852
                        ret = WriteFile(slot->file, slot->buf,
 
3853
                                        slot->len, &len,
 
3854
                                        &(slot->control));
 
3855
 
 
3856
                        break;
 
3857
                case OS_FILE_READ:
 
3858
                        ret = ReadFile(slot->file, slot->buf,
 
3859
                                       slot->len, &len,
 
3860
                                       &(slot->control));
 
3861
 
 
3862
                        break;
 
3863
                default:
 
3864
                        ut_error;
 
3865
                }
 
3866
 
 
3867
                if (!ret && GetLastError() == ERROR_IO_PENDING) {
 
3868
                        /* aio was queued successfully!
 
3869
                        We want a synchronous i/o operation on a
 
3870
                        file where we also use async i/o: in Windows
 
3871
                        we must use the same wait mechanism as for
 
3872
                        async i/o */
 
3873
 
 
3874
                        ret = GetOverlappedResult(slot->file,
 
3875
                                                  &(slot->control),
 
3876
                                                  &len, TRUE);
 
3877
                }
 
3878
 
 
3879
                ret_val = ret && len == slot->len;
 
3880
        }
 
3881
 
3682
3882
        os_aio_array_free_slot(array, slot);
3683
3883
 
3684
3884
        return(ret_val);