1
1
/*****************************************************************************
3
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
4
Copyright (c) 2009, Percona Inc.
6
Portions of this file contain modifications contributed and copyrighted
7
by Percona Inc.. Those modifications are
8
gratefully acknowledged and are described briefly in the InnoDB
9
documentation. The contributions by Percona Inc. are incorporated with
10
their permission, and subject to the conditions contained in the file
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
13
5
This program is free software; you can redistribute it and/or modify it under
14
6
the terms of the GNU General Public License as published by the Free Software
19
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
21
13
You should have received a copy of the GNU General Public License along with
22
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
23
St, Fifth Floor, Boston, MA 02110-1301 USA
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
25
17
*****************************************************************************/
18
/***********************************************************************
20
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
21
Copyright (c) 2009, Percona Inc.
23
Portions of this file contain modifications contributed and copyrighted
24
by Percona Inc.. Those modifications are
25
gratefully acknowledged and are described briefly in the InnoDB
26
documentation. The contributions by Percona Inc. are incorporated with
27
their permission, and subject to the conditions contained in the file
30
This program is free software; you can redistribute it and/or modify it
31
under the terms of the GNU General Public License as published by the
32
Free Software Foundation; version 2 of the License.
34
This program is distributed in the hope that it will be useful, but
35
WITHOUT ANY WARRANTY; without even the implied warranty of
36
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
37
Public License for more details.
39
You should have received a copy of the GNU General Public License along
40
with this program; if not, write to the Free Software Foundation, Inc.,
41
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
43
***********************************************************************/
27
45
/**************************************************//**
73
91
/* We do not call os_file_flush in every os_file_write. */
74
92
#endif /* UNIV_DO_FLUSH */
77
# define os_aio_use_native_aio FALSE
78
#else /* UNIV_HOTBACKUP */
94
#ifndef UNIV_HOTBACKUP
79
95
/* We use these mutexes to protect lseek + file i/o operation, if the
80
96
OS does not provide an atomic pread or pwrite, or similar */
81
97
#define OS_FILE_N_SEEK_MUTEXES 16
185
201
/** If the following is TRUE, read i/o handler threads try to
186
202
wait until a batch of new read requests have been posted */
187
203
static ibool os_aio_recommend_sleep_for_read_threads = FALSE;
188
#endif /* UNIV_HOTBACKUP */
204
#endif /* !UNIV_HOTBACKUP */
190
206
UNIV_INTERN ulint os_n_file_reads = 0;
191
207
UNIV_INTERN ulint os_bytes_read_since_printout = 0;
302
318
" software or another instance\n"
303
319
"InnoDB: of MySQL."
304
320
" Please close it to get rid of this error.\n");
305
} else if (err == ERROR_WORKING_SET_QUOTA
306
|| err == ERROR_NO_SYSTEM_RESOURCES) {
308
"InnoDB: The error means that there are no"
309
" sufficient system resources or quota to"
310
" complete the operation.\n");
311
} else if (err == ERROR_OPERATION_ABORTED) {
313
"InnoDB: The error means that the I/O"
314
" operation has been aborted\n"
315
"InnoDB: because of either a thread exit"
316
" or an application request.\n"
317
"InnoDB: Retry attempt is made.\n");
320
323
"InnoDB: Some operating system error numbers"
336
339
} else if (err == ERROR_SHARING_VIOLATION
337
340
|| err == ERROR_LOCK_VIOLATION) {
338
341
return(OS_FILE_SHARING_VIOLATION);
339
} else if (err == ERROR_WORKING_SET_QUOTA
340
|| err == ERROR_NO_SYSTEM_RESOURCES) {
341
return(OS_FILE_INSUFFICIENT_RESOURCE);
342
} else if (err == ERROR_OPERATION_ABORTED) {
343
return(OS_FILE_OPERATION_ABORTED);
345
343
return(100 + err);
460
458
os_thread_sleep(10000000); /* 10 sec */
462
} else if (err == OS_FILE_INSUFFICIENT_RESOURCE) {
464
os_thread_sleep(100000); /* 100 ms */
466
} else if (err == OS_FILE_OPERATION_ABORTED) {
468
os_thread_sleep(100000); /* 100 ms */
472
462
fprintf(stderr, "InnoDB: File name %s\n", name);
791
781
#ifdef HAVE_READDIR_R
792
782
ret = readdir_r(dir, (struct dirent*)dirent_buf, &ent);
796
/* On AIX, only if we got non-NULL 'ent' (result) value and
797
a non-zero 'ret' (return) value, it indicates a failed
798
readdir_r() call. An NULL 'ent' with an non-zero 'ret'
799
would indicate the "end of the directory" is reached. */
804
786
"InnoDB: cannot read directory %s, error %lu\n",
805
787
dirname, (ulong)ret);
838
820
ret = stat(full_path, &statinfo);
842
if (errno == ENOENT) {
843
/* readdir() returned a file that does not exist,
844
it must have been deleted in the meantime. Do what
845
would have happened if the file was deleted before
846
readdir() - ignore and go to the next entry.
847
If this is the last entry then info->name will still
848
contain the name of the deleted file when this
849
function returns, but this is not an issue since the
850
caller shouldn't be looking at info when end of
851
directory is returned. */
858
823
os_file_handle_error_no_exit(full_path, "stat");
860
825
ut_free(full_path);
1296
1260
== SRV_WIN_IO_UNBUFFERED) {
1297
1261
attributes = attributes | FILE_FLAG_NO_BUFFERING;
1299
# else /* !UNIV_HOTBACKUP */
1300
attributes = attributes | FILE_FLAG_NO_BUFFERING;
1301
# endif /* !UNIV_HOTBACKUP */
1302
#endif /* UNIV_NON_BUFFERED_IO */
1303
1264
} else if (purpose == OS_FILE_NORMAL) {
1304
1265
attributes = 0;
1305
1266
#ifdef UNIV_NON_BUFFERED_IO
1306
# ifndef UNIV_HOTBACKUP
1307
1267
if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
1308
1268
/* Do not use unbuffered i/o to log files because
1309
1269
value 2 denotes that we do not flush the log at every
1312
1272
== SRV_WIN_IO_UNBUFFERED) {
1313
1273
attributes = attributes | FILE_FLAG_NO_BUFFERING;
1315
# else /* !UNIV_HOTBACKUP */
1316
attributes = attributes | FILE_FLAG_NO_BUFFERING;
1317
# endif /* !UNIV_HOTBACKUP */
1318
#endif /* UNIV_NON_BUFFERED_IO */
1320
1277
attributes = 0;
2114
2069
off_t ret_offset;
2116
#ifndef UNIV_HOTBACKUP
2118
#endif /* !UNIV_HOTBACKUP */
2120
2073
os_mutex_enter(os_file_count_mutex);
2121
2074
os_n_pending_reads++;
2122
2075
os_mutex_exit(os_file_count_mutex);
2124
#ifndef UNIV_HOTBACKUP
2125
2077
/* Protect the seek / read operation with a mutex */
2126
2078
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2128
2080
os_mutex_enter(os_file_seek_mutexes[i]);
2129
#endif /* !UNIV_HOTBACKUP */
2131
2082
ret_offset = lseek(file, offs, SEEK_SET);
2136
2087
ret = read(file, buf, (ssize_t)n);
2139
#ifndef UNIV_HOTBACKUP
2140
2090
os_mutex_exit(os_file_seek_mutexes[i]);
2141
#endif /* !UNIV_HOTBACKUP */
2143
2092
os_mutex_enter(os_file_count_mutex);
2144
2093
os_n_pending_reads--;
2218
2167
off_t ret_offset;
2219
# ifndef UNIV_HOTBACKUP
2221
# endif /* !UNIV_HOTBACKUP */
2223
2170
os_mutex_enter(os_file_count_mutex);
2224
2171
os_n_pending_writes++;
2225
2172
os_mutex_exit(os_file_count_mutex);
2227
# ifndef UNIV_HOTBACKUP
2228
2174
/* Protect the seek / write operation with a mutex */
2229
2175
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2231
2177
os_mutex_enter(os_file_seek_mutexes[i]);
2232
# endif /* UNIV_HOTBACKUP */
2234
2179
ret_offset = lseek(file, offs, SEEK_SET);
2312
2253
os_n_pending_reads++;
2313
2254
os_mutex_exit(os_file_count_mutex);
2315
#ifndef UNIV_HOTBACKUP
2316
2256
/* Protect the seek / read operation with a mutex */
2317
2257
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2319
2259
os_mutex_enter(os_file_seek_mutexes[i]);
2320
#endif /* !UNIV_HOTBACKUP */
2322
2261
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2324
2263
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2326
#ifndef UNIV_HOTBACKUP
2327
2265
os_mutex_exit(os_file_seek_mutexes[i]);
2328
#endif /* !UNIV_HOTBACKUP */
2330
2267
os_mutex_enter(os_file_count_mutex);
2331
2268
os_n_pending_reads--;
2337
2274
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
2339
#ifndef UNIV_HOTBACKUP
2340
2276
os_mutex_exit(os_file_seek_mutexes[i]);
2341
#endif /* !UNIV_HOTBACKUP */
2343
2278
os_mutex_enter(os_file_count_mutex);
2344
2279
os_n_pending_reads--;
2366
2301
"InnoDB: Was only able to read %ld.\n",
2367
2302
(ulong)n, (ulong)offset_high,
2368
2303
(ulong)offset, (long)ret);
2369
#endif /* __WIN__ */
2371
2306
error_handling:
2436
2369
os_n_pending_reads++;
2437
2370
os_mutex_exit(os_file_count_mutex);
2439
#ifndef UNIV_HOTBACKUP
2440
2372
/* Protect the seek / read operation with a mutex */
2441
2373
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2443
2375
os_mutex_enter(os_file_seek_mutexes[i]);
2444
#endif /* !UNIV_HOTBACKUP */
2446
2377
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2448
2379
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2450
#ifndef UNIV_HOTBACKUP
2451
2381
os_mutex_exit(os_file_seek_mutexes[i]);
2452
#endif /* !UNIV_HOTBACKUP */
2454
2383
os_mutex_enter(os_file_count_mutex);
2455
2384
os_n_pending_reads--;
2461
2390
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
2463
#ifndef UNIV_HOTBACKUP
2464
2392
os_mutex_exit(os_file_seek_mutexes[i]);
2465
#endif /* !UNIV_HOTBACKUP */
2467
2394
os_mutex_enter(os_file_count_mutex);
2468
2395
os_n_pending_reads--;
2564
2489
os_n_pending_writes++;
2565
2490
os_mutex_exit(os_file_count_mutex);
2567
#ifndef UNIV_HOTBACKUP
2568
2492
/* Protect the seek / write operation with a mutex */
2569
2493
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2571
2495
os_mutex_enter(os_file_seek_mutexes[i]);
2572
#endif /* !UNIV_HOTBACKUP */
2574
2497
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2576
2499
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2578
#ifndef UNIV_HOTBACKUP
2579
2501
os_mutex_exit(os_file_seek_mutexes[i]);
2580
#endif /* !UNIV_HOTBACKUP */
2582
2503
os_mutex_enter(os_file_count_mutex);
2583
2504
os_n_pending_writes--;
3042
/************************************************************************//**
3043
Frees an aio wait array. */
3048
os_aio_array_t* array) /*!< in, own: array to free */
3053
for (i = 0; i < array->n_slots; i++) {
3054
os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i);
3055
os_event_free(slot->event);
3057
#endif /* WIN_ASYNC_IO */
3060
ut_free(array->native_events);
3061
#endif /* __WIN__ */
3062
os_mutex_free(array->mutex);
3063
os_event_free(array->not_full);
3064
os_event_free(array->is_empty);
3066
ut_free(array->slots);
3070
2961
/***********************************************************************
3071
2962
Initializes the asynchronous io system. Creates one array each for ibuf
3072
2963
and log i/o. Also creates one array each for read and write where each
3140
/***********************************************************************
3141
Frees the asynchronous io system. */
3149
os_aio_array_free(os_aio_ibuf_array);
3150
os_aio_ibuf_array = NULL;
3151
os_aio_array_free(os_aio_log_array);
3152
os_aio_log_array = NULL;
3153
os_aio_array_free(os_aio_read_array);
3154
os_aio_read_array = NULL;
3155
os_aio_array_free(os_aio_write_array);
3156
os_aio_write_array = NULL;
3157
os_aio_array_free(os_aio_sync_array);
3158
os_aio_sync_array = NULL;
3160
for (i = 0; i < os_aio_n_segments; i++) {
3161
os_event_free(os_aio_segment_wait_events[i]);
3164
ut_free(os_aio_segment_wait_events);
3165
os_aio_segment_wait_events = 0;
3166
os_aio_n_segments = 0;
3169
3031
#ifdef WIN_ASYNC_IO
3170
3032
/************************************************************************//**
3171
3033
Wakes up all async i/o threads in the array in Windows async i/o at
3516
3378
os_aio_simulated_put_read_threads_to_sleep(void)
3517
3379
/*============================================*/
3520
/* The idea of putting background IO threads to sleep is only for
3521
Windows when using simulated AIO. Windows XP seems to schedule
3522
background threads too eagerly to allow for coalescing during
3523
readahead requests. */
3525
3381
os_aio_array_t* array;
3528
if (os_aio_use_native_aio) {
3529
/* We do not use simulated aio: do nothing */
3534
3384
os_aio_recommend_sleep_for_read_threads = TRUE;
3536
3386
for (g = 0; g < os_aio_n_segments; g++) {
3830
3678
ut_a(TRUE == os_file_flush(slot->file));
3832
3680
#endif /* UNIV_DO_FLUSH */
3833
} else if (os_file_handle_error(slot->name, "Windows aio")) {
3682
os_file_handle_error(slot->name, "Windows aio");
3838
3684
ret_val = FALSE;
3841
3687
os_mutex_exit(array->mutex);
3844
/* retry failed read/write operation synchronously.
3845
No need to hold array->mutex. */
3847
switch (slot->type) {
3849
ret = WriteFile(slot->file, slot->buf,
3855
ret = ReadFile(slot->file, slot->buf,
3864
if (!ret && GetLastError() == ERROR_IO_PENDING) {
3865
/* aio was queued successfully!
3866
We want a synchronous i/o operation on a
3867
file where we also use async i/o: in Windows
3868
we must use the same wait mechanism as for
3871
ret = GetOverlappedResult(slot->file,
3876
ret_val = ret && len == slot->len;
3879
3689
os_aio_array_free_slot(array, slot);
3881
3691
return(ret_val);