49 #ifndef UNIV_HOTBACKUP
55 # include <sys/types.h>
56 # include <sys/stat.h>
60 #if defined(LINUX_NATIVE_AIO)
71 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
80 UNIV_INTERN ibool os_do_not_call_flush_at_each_write = FALSE;
85 #ifndef UNIV_HOTBACKUP
88 #define OS_FILE_N_SEEK_MUTEXES 16
89 UNIV_INTERN
os_mutex_t os_file_seek_mutexes[OS_FILE_N_SEEK_MUTEXES];
92 #define OS_AIO_MERGE_N_CONSECUTIVE 64
153 UNIV_INTERN mysql_pfs_key_t innodb_file_data_key;
154 UNIV_INTERN mysql_pfs_key_t innodb_file_log_key;
155 UNIV_INTERN mysql_pfs_key_t innodb_file_temp_key;
192 #elif defined(LINUX_NATIVE_AIO)
239 #if defined(LINUX_NATIVE_AIO)
240 io_context_t* aio_ctx;
244 struct io_event* aio_events;
252 #if defined(LINUX_NATIVE_AIO)
254 #define OS_AIO_REAP_TIMEOUT (500000000UL)
257 #define OS_AIO_IO_SETUP_RETRY_SLEEP (500000UL)
260 #define OS_AIO_IO_SETUP_RETRY_ATTEMPTS 5
264 static os_event_t* os_aio_segment_wait_events = NULL;
276 static ulint os_aio_n_segments = ULINT_UNDEFINED;
280 static ibool os_aio_recommend_sleep_for_read_threads = FALSE;
283 UNIV_INTERN ulint os_n_file_reads = 0;
284 UNIV_INTERN ulint os_bytes_read_since_printout = 0;
285 UNIV_INTERN ulint os_n_file_writes = 0;
286 UNIV_INTERN ulint os_n_fsyncs = 0;
287 UNIV_INTERN ulint os_n_file_reads_old = 0;
288 UNIV_INTERN ulint os_n_file_writes_old = 0;
289 UNIV_INTERN ulint os_n_fsyncs_old = 0;
290 UNIV_INTERN time_t os_last_printout;
292 UNIV_INTERN ibool os_has_said_disk_full = FALSE;
294 #ifndef UNIV_HOTBACKUP
313 os_aio_validate_skip(
void)
317 # define OS_AIO_VALIDATE_SKIP 13
321 static int os_aio_validate_count = OS_AIO_VALIDATE_SKIP;
327 if (--os_aio_validate_count > 0) {
331 os_aio_validate_count = OS_AIO_VALIDATE_SKIP;
343 os_get_os_version(
void)
346 OSVERSIONINFO os_info;
348 os_info.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
350 ut_a(GetVersionEx(&os_info));
352 if (os_info.dwPlatformId == VER_PLATFORM_WIN32s) {
354 }
else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
356 }
else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
357 switch (os_info.dwMajorVersion) {
362 return (os_info.dwMinorVersion == 0) ?
OS_WIN2000
387 ibool report_all_errors)
394 err = (ulint) GetLastError();
396 if (report_all_errors
397 || (err != ERROR_DISK_FULL && err != ERROR_FILE_EXISTS)) {
401 " InnoDB: Operating system error number %lu"
402 " in a file operation.\n", (ulong) err);
404 if (err == ERROR_PATH_NOT_FOUND) {
406 "InnoDB: The error means the system"
407 " cannot find the path specified.\n");
411 "InnoDB: If you are installing InnoDB,"
412 " remember that you must create\n"
413 "InnoDB: directories yourself, InnoDB"
414 " does not create them.\n");
416 }
else if (err == ERROR_ACCESS_DENIED) {
418 "InnoDB: The error means mysqld does not have"
419 " the access rights to\n"
420 "InnoDB: the directory. It may also be"
421 " you have created a subdirectory\n"
422 "InnoDB: of the same name as a data file.\n");
423 }
else if (err == ERROR_SHARING_VIOLATION
424 || err == ERROR_LOCK_VIOLATION) {
426 "InnoDB: The error means that another program"
427 " is using InnoDB's files.\n"
428 "InnoDB: This might be a backup or antivirus"
429 " software or another instance\n"
431 " Please close it to get rid of this error.\n");
432 }
else if (err == ERROR_WORKING_SET_QUOTA
433 || err == ERROR_NO_SYSTEM_RESOURCES) {
435 "InnoDB: The error means that there are no"
436 " sufficient system resources or quota to"
437 " complete the operation.\n");
438 }
else if (err == ERROR_OPERATION_ABORTED) {
440 "InnoDB: The error means that the I/O"
441 " operation has been aborted\n"
442 "InnoDB: because of either a thread exit"
443 " or an application request.\n"
444 "InnoDB: Retry attempt is made.\n");
447 "InnoDB: Some operating system error numbers"
448 " are described at\n"
451 "operating-system-error-codes.html\n");
457 if (err == ERROR_FILE_NOT_FOUND) {
459 }
else if (err == ERROR_DISK_FULL) {
460 return(OS_FILE_DISK_FULL);
461 }
else if (err == ERROR_FILE_EXISTS) {
462 return(OS_FILE_ALREADY_EXISTS);
463 }
else if (err == ERROR_SHARING_VIOLATION
464 || err == ERROR_LOCK_VIOLATION) {
465 return(OS_FILE_SHARING_VIOLATION);
466 }
else if (err == ERROR_WORKING_SET_QUOTA
467 || err == ERROR_NO_SYSTEM_RESOURCES) {
468 return(OS_FILE_INSUFFICIENT_RESOURCE);
469 }
else if (err == ERROR_OPERATION_ABORTED) {
470 return(OS_FILE_OPERATION_ABORTED);
477 if (report_all_errors
478 || (err != ENOSPC && err != EEXIST)) {
482 " InnoDB: Operating system error number %lu"
483 " in a file operation.\n", (ulong) err);
487 "InnoDB: The error means the system"
488 " cannot find the path specified.\n");
492 "InnoDB: If you are installing InnoDB,"
493 " remember that you must create\n"
494 "InnoDB: directories yourself, InnoDB"
495 " does not create them.\n");
497 }
else if (err == EACCES) {
499 "InnoDB: The error means mysqld does not have"
500 " the access rights to\n"
501 "InnoDB: the directory.\n");
503 if (strerror((
int)err) != NULL) {
505 "InnoDB: Error number %lu"
507 err, strerror((
int)err));
511 "InnoDB: Some operating system"
512 " error numbers are described at\n"
515 "operating-system-error-codes.html\n");
523 return(OS_FILE_DISK_FULL);
527 return(OS_FILE_ALREADY_EXISTS);
531 return(OS_FILE_PATH_ERROR);
533 if (srv_use_native_aio) {
534 return(OS_FILE_AIO_RESOURCES_RESERVED);
538 if (srv_use_native_aio) {
539 return(OS_FILE_AIO_INTERRUPTED);
554 os_file_handle_error_cond_exit(
557 const char* operation,
565 if (err == OS_FILE_DISK_FULL) {
568 if (os_has_said_disk_full) {
576 " InnoDB: Encountered a problem with"
582 " InnoDB: Disk is full. Try to clean the disk"
583 " to free space.\n");
585 os_has_said_disk_full = TRUE;
590 }
else if (err == OS_FILE_AIO_RESOURCES_RESERVED) {
593 }
else if (err == OS_FILE_AIO_INTERRUPTED) {
596 }
else if (err == OS_FILE_ALREADY_EXISTS
597 || err == OS_FILE_PATH_ERROR) {
600 }
else if (err == OS_FILE_SHARING_VIOLATION) {
604 }
else if (err == OS_FILE_INSUFFICIENT_RESOURCE) {
608 }
else if (err == OS_FILE_OPERATION_ABORTED) {
614 fprintf(stderr,
"InnoDB: File name %s\n", name);
617 fprintf(stderr,
"InnoDB: File operation call: '%s'.\n",
621 fprintf(stderr,
"InnoDB: Cannot continue operation.\n");
637 os_file_handle_error(
640 const char* operation)
643 return(os_file_handle_error_cond_exit(name, operation, TRUE));
651 os_file_handle_error_no_exit(
654 const char* operation)
657 return(os_file_handle_error_cond_exit(name, operation, FALSE));
661 #define USE_FILE_LOCK
662 #if defined(UNIV_HOTBACKUP) || defined(__WIN__)
666 # undef USE_FILE_LOCK
685 lk.l_whence = SEEK_SET;
686 lk.l_start = lk.l_len = 0;
687 if (fcntl(fd, F_SETLK, &lk) == -1) {
689 "InnoDB: Unable to lock %s, error: %d\n", name, errno);
691 if (errno == EAGAIN || errno == EACCES) {
693 "InnoDB: Check that you do not already have"
694 " another drizzled process\n"
695 "InnoDB: using the same InnoDB data"
706 #ifndef UNIV_HOTBACKUP
718 for (i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) {
736 file = fdopen(fd,
"w+b");
742 " InnoDB: Error: unable to create temporary file;"
743 " errno: %d\n", errno);
765 ibool error_is_fatal)
773 LPWIN32_FIND_DATA lpFindFileData;
774 char path[OS_FILE_MAX_PATH + 3];
776 ut_a(strlen(dirname) < OS_FILE_MAX_PATH);
778 strcpy(path, dirname);
779 strcpy(path + strlen(path),
"\\*");
785 lpFindFileData =
ut_malloc(
sizeof(WIN32_FIND_DATA));
787 dir = FindFirstFile((LPCTSTR) path, lpFindFileData);
791 if (dir == INVALID_HANDLE_VALUE) {
793 if (error_is_fatal) {
794 os_file_handle_error(dirname,
"opendir");
802 dir = opendir(dirname);
804 if (dir == NULL && error_is_fatal) {
805 os_file_handle_error(dirname,
"opendir");
824 ret = FindClose(dir);
827 os_file_handle_error_no_exit(NULL,
"closedir");
839 os_file_handle_error_no_exit(NULL,
"closedir");
859 LPWIN32_FIND_DATA lpFindFileData;
862 lpFindFileData =
ut_malloc(
sizeof(WIN32_FIND_DATA));
864 ret = FindNextFile(dir, lpFindFileData);
867 ut_a(strlen((
char *) lpFindFileData->cFileName)
870 if (strcmp((
char *) lpFindFileData->cFileName,
".") == 0
871 || strcmp((
char *) lpFindFileData->cFileName,
"..") == 0) {
876 strcpy(info->
name, (
char *) lpFindFileData->cFileName);
878 info->
size = (ib_int64_t)(lpFindFileData->nFileSizeLow)
879 + (((ib_int64_t)(lpFindFileData->nFileSizeHigh))
882 if (lpFindFileData->dwFileAttributes
883 & FILE_ATTRIBUTE_REPARSE_POINT) {
889 info->
type = OS_FILE_TYPE_LINK;
890 }
else if (lpFindFileData->dwFileAttributes
891 & FILE_ATTRIBUTE_DIRECTORY) {
892 info->
type = OS_FILE_TYPE_DIR;
898 info->
type = OS_FILE_TYPE_FILE;
906 }
else if (GetLastError() == ERROR_NO_MORE_FILES) {
910 os_file_handle_error_no_exit(dirname,
911 "readdir_next_file");
918 struct stat statinfo;
919 #ifdef HAVE_READDIR_R
921 char dirent_buf[
sizeof(
struct dirent)
922 + _POSIX_PATH_MAX + 100];
927 char dirent_buf[
sizeof(
struct dirent)
937 #ifdef HAVE_READDIR_R
938 ret = readdir_r(dir, (
struct dirent*)dirent_buf, &ent);
950 "InnoDB: cannot read directory %s, error %lu\n",
951 dirname, (ulong)ret);
963 ut_a(strlen(ent->d_name) < _POSIX_PATH_MAX + 100 - 1);
965 ut_a(strlen(ent->d_name) < UCHAR_MAX + 100 - 1);
976 ut_a(strlen(ent->d_name) < OS_FILE_MAX_PATH);
978 if (strcmp(ent->d_name,
".") == 0 || strcmp(ent->d_name,
"..") == 0) {
983 strcpy(info->
name, ent->d_name);
985 full_path =
static_cast<char*
>(
ut_malloc(strlen(dirname) + strlen(ent->d_name) + 10));
987 sprintf(full_path,
"%s/%s", dirname, ent->d_name);
989 ret = stat(full_path, &statinfo);
993 if (errno == ENOENT) {
1009 os_file_handle_error_no_exit(full_path,
"stat");
1016 info->
size = (ib_int64_t)statinfo.st_size;
1018 if (S_ISDIR(statinfo.st_mode)) {
1019 info->
type = OS_FILE_TYPE_DIR;
1020 }
else if (S_ISLNK(statinfo.st_mode)) {
1021 info->
type = OS_FILE_TYPE_LINK;
1022 }
else if (S_ISREG(statinfo.st_mode)) {
1023 info->
type = OS_FILE_TYPE_FILE;
1025 info->
type = OS_FILE_TYPE_UNKNOWN;
1044 const char* pathname,
1046 ibool fail_if_exists)
1052 rcode = CreateDirectory((LPCTSTR) pathname, NULL);
1054 || (GetLastError() == ERROR_ALREADY_EXISTS
1055 && !fail_if_exists))) {
1057 os_file_handle_error(pathname,
"CreateDirectory");
1066 rcode = mkdir(pathname, 0770);
1068 if (!(rcode == 0 || (errno == EEXIST && !fail_if_exists))) {
1070 os_file_handle_error(pathname,
"mkdir");
1106 DWORD attributes = 0;
1113 create_flag = OPEN_EXISTING;
1114 }
else if (create_mode == OS_FILE_CREATE) {
1115 create_flag = CREATE_NEW;
1116 }
else if (create_mode == OS_FILE_CREATE_PATH) {
1122 create_flag = CREATE_NEW;
1123 create_mode = OS_FILE_CREATE;
1129 if (access_type == OS_FILE_READ_ONLY) {
1130 access = GENERIC_READ;
1131 }
else if (access_type == OS_FILE_READ_WRITE) {
1132 access = GENERIC_READ | GENERIC_WRITE;
1138 file = CreateFile((LPCTSTR) name,
1140 FILE_SHARE_READ | FILE_SHARE_WRITE,
1148 if (file == INVALID_HANDLE_VALUE) {
1151 retry = os_file_handle_error(name,
1171 if (access_type == OS_FILE_READ_ONLY) {
1172 create_flag = O_RDONLY;
1174 create_flag = O_RDWR;
1176 }
else if (create_mode == OS_FILE_CREATE) {
1177 create_flag = O_RDWR | O_CREAT | O_EXCL;
1178 }
else if (create_mode == OS_FILE_CREATE_PATH) {
1184 create_flag = O_RDWR | O_CREAT | O_EXCL;
1185 create_mode = OS_FILE_CREATE;
1191 if (create_mode == OS_FILE_CREATE) {
1192 file = open(name, create_flag, S_IRUSR | S_IWUSR
1193 | S_IRGRP | S_IWGRP);
1195 file = open(name, create_flag);
1201 retry = os_file_handle_error(name,
1207 #ifdef USE_FILE_LOCK
1208 }
else if (access_type == OS_FILE_READ_WRITE
1209 && os_file_lock(file, name)) {
1248 DWORD attributes = 0;
1249 DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1254 create_flag = OPEN_EXISTING;
1255 }
else if (create_mode == OS_FILE_CREATE) {
1256 create_flag = CREATE_NEW;
1262 if (access_type == OS_FILE_READ_ONLY) {
1263 access = GENERIC_READ;
1264 }
else if (access_type == OS_FILE_READ_WRITE) {
1265 access = GENERIC_READ | GENERIC_WRITE;
1266 }
else if (access_type == OS_FILE_READ_ALLOW_DELETE) {
1267 access = GENERIC_READ;
1268 share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ
1278 file = CreateFile((LPCTSTR) name,
1286 if (file == INVALID_HANDLE_VALUE) {
1300 if (access_type == OS_FILE_READ_ONLY) {
1301 create_flag = O_RDONLY;
1303 create_flag = O_RDWR;
1305 }
else if (create_mode == OS_FILE_CREATE) {
1306 create_flag = O_RDWR | O_CREAT | O_EXCL;
1312 if (create_mode == OS_FILE_CREATE) {
1313 file = open(name, create_flag, S_IRUSR | S_IWUSR
1314 | S_IRGRP | S_IWGRP);
1316 file = open(name, create_flag);
1321 #ifdef USE_FILE_LOCK
1322 }
else if (access_type == OS_FILE_READ_WRITE
1323 && os_file_lock(file, name)) {
1343 const char* file_name,
1344 const char* operation_name)
1349 #if defined(UNIV_SOLARIS) && defined(DIRECTIO_ON)
1350 if (directio(fd, DIRECTIO_ON) == -1) {
1352 errno_save = (int)errno;
1355 " InnoDB: Failed to set DIRECTIO_ON "
1356 "on file %s: %s: %s, continuing anyway\n",
1357 file_name, operation_name, strerror(errno_save));
1359 #elif defined(O_DIRECT)
1360 if (fcntl(fd, F_SETFL, O_DIRECT) == -1) {
1362 errno_save = (int)errno;
1365 " InnoDB: Failed to set O_DIRECT "
1366 "on file %s: %s: %s, continuing anyway\n",
1367 file_name, operation_name, strerror(errno_save));
1368 if (errno_save == EINVAL) {
1371 " InnoDB: O_DIRECT is known to result in "
1372 "'Invalid argument' on Linux on tmpfs, "
1373 "see MySQL Bug#26662\n");
1379 (void)operation_name;
1415 DWORD share_mode = FILE_SHARE_READ;
1422 if (create_mode == OS_FILE_OPEN_RAW) {
1423 create_flag = OPEN_EXISTING;
1424 share_mode = FILE_SHARE_WRITE;
1426 || create_mode == OS_FILE_OPEN_RETRY) {
1427 create_flag = OPEN_EXISTING;
1428 }
else if (create_mode == OS_FILE_CREATE) {
1429 create_flag = CREATE_NEW;
1430 }
else if (create_mode == OS_FILE_OVERWRITE) {
1431 create_flag = CREATE_ALWAYS;
1437 if (purpose == OS_FILE_AIO) {
1442 if (srv_use_native_aio) {
1443 attributes = attributes | FILE_FLAG_OVERLAPPED;
1446 #ifdef UNIV_NON_BUFFERED_IO
1447 # ifndef UNIV_HOTBACKUP
1448 if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
1452 }
else if (srv_win_file_flush_method
1454 attributes = attributes | FILE_FLAG_NO_BUFFERING;
1457 attributes = attributes | FILE_FLAG_NO_BUFFERING;
1460 }
else if (purpose == OS_FILE_NORMAL) {
1462 #ifdef UNIV_NON_BUFFERED_IO
1463 # ifndef UNIV_HOTBACKUP
1464 if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
1468 }
else if (srv_win_file_flush_method
1470 attributes = attributes | FILE_FLAG_NO_BUFFERING;
1473 attributes = attributes | FILE_FLAG_NO_BUFFERING;
1481 file = CreateFile((LPCTSTR) name,
1482 GENERIC_READ | GENERIC_WRITE,
1500 if (file == INVALID_HANDLE_VALUE) {
1511 retry = os_file_handle_error_no_exit(name,
1512 create_mode == OS_FILE_CREATE ?
1515 retry = os_file_handle_error(name,
1516 create_mode == OS_FILE_CREATE ?
1532 const char* mode_str = NULL;
1537 if (create_mode ==
OS_FILE_OPEN || create_mode == OS_FILE_OPEN_RAW
1538 || create_mode == OS_FILE_OPEN_RETRY) {
1541 create_flag = O_RDONLY;
1543 create_flag = O_RDWR;
1544 }
else if (create_mode == OS_FILE_CREATE) {
1545 mode_str =
"CREATE";
1546 create_flag = O_RDWR | O_CREAT | O_EXCL;
1547 }
else if (create_mode == OS_FILE_OVERWRITE) {
1548 mode_str =
"OVERWRITE";
1549 create_flag = O_RDWR | O_CREAT | O_TRUNC;
1556 ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL);
1562 if (type == OS_LOG_FILE
1566 fprintf(stderr,
"Using O_SYNC for file %s\n", name);
1569 create_flag = create_flag | O_SYNC;
1586 retry = os_file_handle_error_no_exit(name,
1587 create_mode == OS_FILE_CREATE ?
1590 retry = os_file_handle_error(name,
1591 create_mode == OS_FILE_CREATE ?
1606 if (type != OS_LOG_FILE
1617 #ifdef USE_FILE_LOCK
1618 if (create_mode != OS_FILE_OPEN_RAW && os_file_lock(file, name)) {
1620 if (create_mode == OS_FILE_OPEN_RETRY) {
1623 fputs(
" InnoDB: Retrying to lock"
1624 " the first data file\n",
1626 for (i = 0; i < 100; i++) {
1628 if (!os_file_lock(file, name)) {
1634 fputs(
" InnoDB: Unable to open the first data file\n",
1664 ret = DeleteFile((LPCTSTR)name);
1670 if (GetLastError() == ERROR_FILE_NOT_FOUND) {
1678 if (count > 100 && 0 == (count % 10)) {
1680 "InnoDB: Warning: cannot delete file %s\n"
1681 "InnoDB: Are you running ibbackup"
1682 " to back up the file?\n", name);
1700 if (ret != 0 && errno != ENOENT) {
1701 os_file_handle_error_no_exit(name,
"delete");
1726 ret = DeleteFile((LPCTSTR)name);
1732 if (GetLastError() == ERROR_FILE_NOT_FOUND) {
1741 if (count > 100 && 0 == (count % 10)) {
1743 "InnoDB: Warning: cannot delete file %s\n"
1744 "InnoDB: Are you running ibbackup"
1745 " to back up the file?\n", name);
1764 os_file_handle_error_no_exit(name,
"delete");
1782 const char* oldpath,
1784 const char* newpath)
1789 ret = MoveFile((LPCTSTR)oldpath, (LPCTSTR)newpath);
1795 os_file_handle_error_no_exit(oldpath,
"rename");
1801 ret = rename(oldpath, newpath);
1804 os_file_handle_error_no_exit(oldpath,
"rename");
1829 ret = CloseHandle(file);
1835 os_file_handle_error(NULL,
"close");
1844 os_file_handle_error(NULL,
"close");
1853 #ifdef UNIV_HOTBACKUP
1859 os_file_close_no_error_handling(
1868 ret = CloseHandle(file);
1906 low = GetFileSize(file, &high);
1908 if ((low == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) {
1919 offs = lseek(file, 0, SEEK_END);
1921 if (offs == ((off_t)-1)) {
1926 if (
sizeof(off_t) > 4) {
1927 *size = (ulint)(offs & 0xFFFFFFFFUL);
1928 *size_high = (ulint)(offs >> 32);
1930 *size = (ulint) offs;
1958 return((((ib_int64_t)size_high) << 32) + (ib_int64_t)size);
1975 ib_int64_t current_size;
1976 ib_int64_t desired_size;
1982 ut_a(size == (size & 0xFFFFFFFF));
1985 desired_size = (ib_int64_t)size + (((ib_int64_t)size_high) << 32);
1988 buf_size =
ut_min(64, (ulint) (desired_size / UNIV_PAGE_SIZE))
1990 buf2 =
static_cast<unsigned char *
>(
ut_malloc(buf_size + UNIV_PAGE_SIZE));
1993 buf =
static_cast<unsigned char *
>(
ut_align(buf2, UNIV_PAGE_SIZE));
1996 memset(buf, 0, buf_size);
1998 if (desired_size >= (ib_int64_t)(100 * 1024 * 1024)) {
2000 fprintf(stderr,
"InnoDB: Progress in MB:");
2003 while (current_size < desired_size) {
2006 if (desired_size - current_size < (ib_int64_t) buf_size) {
2007 n_bytes = (ulint) (desired_size - current_size);
2012 ret = os_file_write(name, file, buf,
2013 (ulint)(current_size & 0xFFFFFFFF),
2014 (ulint)(current_size >> 32),
2018 goto error_handling;
2022 if ((ib_int64_t) (current_size + n_bytes) / (ib_int64_t)(100 * 1024 * 1024)
2023 != current_size / (ib_int64_t)(100 * 1024 * 1024)) {
2025 fprintf(stderr,
" %lu00",
2026 (ulong) ((current_size + n_bytes)
2027 / (ib_int64_t)(100 * 1024 * 1024)));
2030 current_size += n_bytes;
2033 if (desired_size >= (ib_int64_t)(100 * 1024 * 1024)) {
2035 fprintf(stderr,
"\n");
2040 ret = os_file_flush(file);
2060 HANDLE h = (HANDLE) _get_osfhandle(fileno(file));
2061 return(SetEndOfFile(h));
2063 return(!ftruncate(fileno(file), ftell(file)));
2091 if (ret == -1 && errno == ENOLCK) {
2093 if (failures % 100 == 0) {
2097 " InnoDB: fsync(): "
2098 "No locks available; retrying\n");
2133 ret = FlushFileBuffers(file);
2144 == ERROR_INVALID_FUNCTION) {
2148 os_file_handle_error(NULL,
"flush");
2158 #if defined(HAVE_DARWIN_THREADS)
2159 # ifndef F_FULLFSYNC
2161 # define F_FULLFSYNC 51
2162 # elif F_FULLFSYNC != 51
2163 # error "F_FULLFSYNC != 51: ABI incompatibility with Mac OS X 10.3"
2170 if (!srv_have_fullfsync) {
2174 ret = os_file_fsync(file);
2176 ret = fcntl(file, F_FULLFSYNC, NULL);
2181 ret = os_file_fsync(file);
2185 ret = os_file_fsync(file);
2203 " InnoDB: Error: the OS said file flush did not succeed\n");
2205 os_file_handle_error(NULL,
"flush");
2232 #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
2236 ut_a((offset & 0xFFFFFFFFUL) == offset);
2241 if (
sizeof(off_t) > 4) {
2242 offs = (off_t)offset + (((off_t)offset_high) << 32);
2245 offs = (off_t)offset;
2247 if (offset_high > 0) {
2249 "InnoDB: Error: file read at offset > 4 GB\n");
2255 #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
2261 n_bytes = pread(file, buf, (ssize_t)n, offs);
2273 #ifndef UNIV_HOTBACKUP
2281 #ifndef UNIV_HOTBACKUP
2283 i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2288 ret_offset = lseek(file, offs, SEEK_SET);
2290 if (ret_offset < 0) {
2293 ret = read(file, buf, (ssize_t)n);
2296 #ifndef UNIV_HOTBACKUP
2327 ut_a((offset & 0xFFFFFFFFUL) == offset);
2332 if (
sizeof(off_t) > 4) {
2333 offs = (off_t)offset + (((off_t)offset_high) << 32);
2335 offs = (off_t)offset;
2337 if (offset_high > 0) {
2339 "InnoDB: Error: file write"
2340 " at offset > 4 GB\n");
2349 #if defined(HAVE_PWRITE) && !defined(HAVE_BROKEN_PREAD)
2355 ret = pwrite(file, buf, (ssize_t)n, offs);
2362 # ifdef UNIV_DO_FLUSH
2365 && !os_do_not_call_flush_at_each_write) {
2371 ut_a(TRUE == os_file_flush(file));
2379 # ifndef UNIV_HOTBACKUP
2387 # ifndef UNIV_HOTBACKUP
2389 i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2394 ret_offset = lseek(file, offs, SEEK_SET);
2396 if (ret_offset < 0) {
2402 ret = write(file, buf, (ssize_t)n);
2404 # ifdef UNIV_DO_FLUSH
2407 && !os_do_not_call_flush_at_each_write) {
2413 ut_a(TRUE == os_file_flush(file));
2418 # ifndef UNIV_HOTBACKUP
2456 #ifndef UNIV_HOTBACKUP
2462 ut_a((offset & 0xFFFFFFFFUL) == offset);
2463 ut_a((n & 0xFFFFFFFFUL) == n);
2466 os_bytes_read_since_printout += n;
2473 low = (DWORD) offset;
2474 high = (DWORD) offset_high;
2480 #ifndef UNIV_HOTBACKUP
2482 i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2487 ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2489 if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2491 #ifndef UNIV_HOTBACKUP
2499 goto error_handling;
2502 ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
2504 #ifndef UNIV_HOTBACKUP
2512 if (ret && len == n) {
2519 os_bytes_read_since_printout += n;
2522 ret = os_file_pread(file, buf, n, offset, offset_high);
2524 if ((ulint)ret == n) {
2530 "InnoDB: Error: tried to read %lu bytes at offset %lu %lu.\n"
2531 "InnoDB: Was only able to read %ld.\n",
2532 (ulong)n, (ulong)offset_high,
2533 (ulong)offset, (
long)ret);
2538 retry = os_file_handle_error(NULL,
"read");
2545 "InnoDB: Fatal error: cannot read from file."
2546 " OS error number %lu.\n",
2548 (ulong) GetLastError()
2585 #ifndef UNIV_HOTBACKUP
2591 ut_a((offset & 0xFFFFFFFFUL) == offset);
2592 ut_a((n & 0xFFFFFFFFUL) == n);
2595 os_bytes_read_since_printout += n;
2602 low = (DWORD) offset;
2603 high = (DWORD) offset_high;
2609 #ifndef UNIV_HOTBACKUP
2611 i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2616 ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2618 if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2620 #ifndef UNIV_HOTBACKUP
2628 goto error_handling;
2631 ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
2633 #ifndef UNIV_HOTBACKUP
2641 if (ret && len == n) {
2648 os_bytes_read_since_printout += n;
2651 ret = os_file_pread(file, buf, n, offset, offset_high);
2653 if ((ulint)ret == n) {
2661 retry = os_file_handle_error_no_exit(NULL,
"read");
2689 flen = fread(str, 1, size - 1, file);
2718 ulint n_retries = 0;
2720 #ifndef UNIV_HOTBACKUP
2726 ut_a((offset & 0xFFFFFFFFUL) == offset);
2727 ut_a((n & 0xFFFFFFFFUL) == n);
2738 low = (DWORD) offset;
2739 high = (DWORD) offset_high;
2745 #ifndef UNIV_HOTBACKUP
2747 i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
2752 ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
2754 if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
2756 #ifndef UNIV_HOTBACKUP
2767 " InnoDB: Error: File pointer positioning to"
2768 " file %s failed at\n"
2769 "InnoDB: offset %lu %lu. Operating system"
2770 " error number %lu.\n"
2771 "InnoDB: Some operating system error numbers"
2772 " are described at\n"
2774 REFMAN
"operating-system-error-codes.html\n",
2775 name, (ulong) offset_high, (ulong) offset,
2776 (ulong) GetLastError());
2781 ret = WriteFile(file, buf, (DWORD) n, &len, NULL);
2786 # ifdef UNIV_DO_FLUSH
2787 if (!os_do_not_call_flush_at_each_write) {
2788 ut_a(TRUE == os_file_flush(file));
2792 #ifndef UNIV_HOTBACKUP
2800 if (ret && len == n) {
2809 if (GetLastError() == ERROR_LOCK_VIOLATION && n_retries < 100) {
2818 if (!os_has_said_disk_full) {
2820 err = (ulint)GetLastError();
2825 " InnoDB: Error: Write to file %s failed"
2826 " at offset %lu %lu.\n"
2827 "InnoDB: %lu bytes should have been written,"
2828 " only %lu were written.\n"
2829 "InnoDB: Operating system error number %lu.\n"
2830 "InnoDB: Check that your OS and file system"
2831 " support files of this size.\n"
2832 "InnoDB: Check also that the disk is not full"
2833 " or a disk quota exceeded.\n",
2834 name, (ulong) offset_high, (ulong) offset,
2835 (ulong) n, (ulong) len, (ulong) err);
2837 if (strerror((
int)err) != NULL) {
2839 "InnoDB: Error number %lu means '%s'.\n",
2840 (ulong) err, strerror((
int)err));
2844 "InnoDB: Some operating system error numbers"
2845 " are described at\n"
2847 REFMAN
"operating-system-error-codes.html\n");
2849 os_has_said_disk_full = TRUE;
2856 ret = os_file_pwrite(file, buf, n, offset, offset_high);
2858 if ((ulint)ret == n) {
2863 if (!os_has_said_disk_full) {
2868 " InnoDB: Error: Write to file %s failed"
2869 " at offset %lu %lu.\n"
2870 "InnoDB: %lu bytes should have been written,"
2871 " only %ld were written.\n"
2872 "InnoDB: Operating system error number %lu.\n"
2873 "InnoDB: Check that your OS and file system"
2874 " support files of this size.\n"
2875 "InnoDB: Check also that the disk is not full"
2876 " or a disk quota exceeded.\n",
2877 name, offset_high, offset, n, (
long int)ret,
2879 if (strerror(errno) != NULL) {
2881 "InnoDB: Error number %lu means '%s'.\n",
2882 (ulint)errno, strerror(errno));
2886 "InnoDB: Some operating system error numbers"
2887 " are described at\n"
2889 REFMAN
"operating-system-error-codes.html\n");
2891 os_has_said_disk_full = TRUE;
2907 os_file_type_t* type)
2911 struct _stat statinfo;
2913 ret = _stat(path, &statinfo);
2914 if (ret && (errno == ENOENT || errno == ENOTDIR)) {
2921 os_file_handle_error_no_exit(path,
"stat");
2926 if (_S_IFDIR & statinfo.st_mode) {
2927 *type = OS_FILE_TYPE_DIR;
2928 }
else if (_S_IFREG & statinfo.st_mode) {
2929 *type = OS_FILE_TYPE_FILE;
2931 *type = OS_FILE_TYPE_UNKNOWN;
2939 struct stat statinfo;
2941 ret = stat(path, &statinfo);
2942 if (ret && (errno == ENOENT || errno == ENOTDIR)) {
2949 os_file_handle_error_no_exit(path,
"stat");
2954 if (S_ISDIR(statinfo.st_mode)) {
2955 *type = OS_FILE_TYPE_DIR;
2956 }
else if (S_ISLNK(statinfo.st_mode)) {
2957 *type = OS_FILE_TYPE_LINK;
2958 }
else if (S_ISREG(statinfo.st_mode)) {
2959 *type = OS_FILE_TYPE_FILE;
2961 *type = OS_FILE_TYPE_UNKNOWN;
2983 struct _stat statinfo;
2985 ret = _stat(path, &statinfo);
2986 if (ret && (errno == ENOENT || errno == ENOTDIR)) {
2993 os_file_handle_error_no_exit(path,
"stat");
2997 if (_S_IFDIR & statinfo.st_mode) {
2998 stat_info->
type = OS_FILE_TYPE_DIR;
2999 }
else if (_S_IFREG & statinfo.st_mode) {
3000 stat_info->
type = OS_FILE_TYPE_FILE;
3002 stat_info->
type = OS_FILE_TYPE_UNKNOWN;
3005 stat_info->
ctime = statinfo.st_ctime;
3006 stat_info->
atime = statinfo.st_atime;
3007 stat_info->
mtime = statinfo.st_mtime;
3008 stat_info->
size = statinfo.st_size;
3013 struct stat statinfo;
3015 ret = stat(path, &statinfo);
3017 if (ret && (errno == ENOENT || errno == ENOTDIR)) {
3024 os_file_handle_error_no_exit(path,
"stat");
3029 if (S_ISDIR(statinfo.st_mode)) {
3030 stat_info->
type = OS_FILE_TYPE_DIR;
3031 }
else if (S_ISLNK(statinfo.st_mode)) {
3032 stat_info->
type = OS_FILE_TYPE_LINK;
3033 }
else if (S_ISREG(statinfo.st_mode)) {
3034 stat_info->
type = OS_FILE_TYPE_FILE;
3036 stat_info->
type = OS_FILE_TYPE_UNKNOWN;
3039 stat_info->
ctime = statinfo.st_ctime;
3040 stat_info->
atime = statinfo.st_atime;
3041 stat_info->
mtime = statinfo.st_mtime;
3042 stat_info->
size = statinfo.st_size;
3050 # define OS_FILE_PATH_SEPARATOR '\\'
3052 # define OS_FILE_PATH_SEPARATOR '/'
3090 const char* last_slash = strrchr(path, OS_FILE_PATH_SEPARATOR);
3099 if (last_slash == path) {
3120 ibool success, subdir_exists;
3121 os_file_type_t type;
3124 if (strlen(subdir) == 1
3125 && (*subdir == OS_FILE_PATH_SEPARATOR || *subdir ==
'.')) {
3134 if (success && !subdir_exists) {
3150 #ifndef UNIV_HOTBACKUP
3156 os_aio_array_get_nth_slot(
3161 ut_a(index < array->n_slots);
3163 return((array->
slots) + index);
3166 #if defined(LINUX_NATIVE_AIO)
3172 os_aio_linux_create_io_ctx(
3175 io_context_t* io_ctx)
3181 memset(io_ctx, 0x0,
sizeof(*io_ctx));
3186 ret = io_setup(max_events, io_ctx);
3188 #if defined(UNIV_AIO_DEBUG)
3190 "InnoDB: Linux native AIO:"
3191 " initialized io_ctx for segment\n");
3205 " InnoDB: Warning: io_setup() failed"
3206 " with EAGAIN. Will make %d attempts"
3207 " before giving up.\n",
3208 OS_AIO_IO_SETUP_RETRY_ATTEMPTS);
3211 if (retries < OS_AIO_IO_SETUP_RETRY_ATTEMPTS) {
3214 "InnoDB: Warning: io_setup() attempt"
3224 " InnoDB: Error: io_setup() failed"
3225 " with EAGAIN after %d attempts.\n",
3226 OS_AIO_IO_SETUP_RETRY_ATTEMPTS);
3232 " InnoDB: Error: Linux Native AIO interface"
3233 " is not supported on this platform. Please"
3234 " check your OS documentation and install"
3235 " appropriate binary of InnoDB.\n");
3242 " InnoDB: Error: Linux Native AIO setup"
3243 " returned following error[%d]\n", -ret);
3248 "InnoDB: You can disable Linux Native AIO by"
3249 " setting innodb_native_aio = off in my.cnf\n");
3261 os_aio_array_create(
3273 #elif defined(LINUX_NATIVE_AIO)
3274 struct io_event* aio_event = NULL;
3277 ut_a(n_segments > 0);
3293 array->handles =
ut_malloc(n *
sizeof(HANDLE));
3296 #if defined(LINUX_NATIVE_AIO)
3297 array->aio_ctx = NULL;
3298 array->aio_events = NULL;
3302 if (!srv_use_native_aio) {
3303 goto skip_native_aio;
3309 array->aio_ctx = (io_context**)
ut_malloc(n_segments *
3310 sizeof(*array->aio_ctx));
3311 for (i = 0; i < n_segments; ++i) {
3312 if (!os_aio_linux_create_io_ctx(n/n_segments,
3313 &array->aio_ctx[i])) {
3325 aio_event = (io_event*)
ut_malloc(n *
sizeof(io_event));
3326 memset(aio_event, 0x0,
sizeof(io_event) * n);
3327 array->aio_events = aio_event;
3331 for (i = 0; i < n; i++) {
3332 slot = os_aio_array_get_nth_slot(array, i);
3337 slot->handle = CreateEvent(NULL,TRUE, FALSE, NULL);
3339 over = &(slot->control);
3341 over->hEvent = slot->handle;
3343 *((array->handles) + i) = over->hEvent;
3345 #elif defined(LINUX_NATIVE_AIO)
3347 memset(&slot->control, 0x0,
sizeof(slot->control));
3367 for (i = 0; i < array->
n_slots; i++) {
3369 CloseHandle(slot->handle);
3380 #if defined(LINUX_NATIVE_AIO)
3381 if (srv_use_native_aio) {
3410 ulint n_segments = 2 + n_read_segs + n_write_segs;
3412 ut_ad(n_segments >= 4);
3416 for (i = 0; i < n_segments; i++) {
3423 os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1);
3424 if (os_aio_ibuf_array == NULL) {
3428 srv_io_thread_function[0] =
"insert buffer thread";
3430 os_aio_log_array = os_aio_array_create(n_per_seg, 1);
3431 if (os_aio_log_array == NULL) {
3435 srv_io_thread_function[1] =
"log thread";
3437 os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg,
3439 if (os_aio_read_array == NULL) {
3443 for (i = 2; i < 2 + n_read_segs; i++) {
3444 ut_a(i < SRV_MAX_N_IO_THREADS);
3445 srv_io_thread_function[i] =
"read thread";
3448 os_aio_write_array = os_aio_array_create(n_write_segs * n_per_seg,
3450 if (os_aio_write_array == NULL) {
3454 for (i = 2 + n_read_segs; i < n_segments; i++) {
3455 ut_a(i < SRV_MAX_N_IO_THREADS);
3456 srv_io_thread_function[i] =
"write thread";
3459 os_aio_sync_array = os_aio_array_create(n_slots_sync, 1);
3460 if (os_aio_sync_array == NULL) {
3465 os_aio_n_segments = n_segments;
3469 os_aio_segment_wait_events =
static_cast<os_event_t *
>(
ut_malloc(n_segments *
sizeof(
void*)));
3471 for (i = 0; i < n_segments; i++) {
3475 os_last_printout = time(NULL);
3493 os_aio_array_free(os_aio_ibuf_array);
3494 os_aio_ibuf_array = NULL;
3495 os_aio_array_free(os_aio_log_array);
3496 os_aio_log_array = NULL;
3497 os_aio_array_free(os_aio_read_array);
3498 os_aio_read_array = NULL;
3499 os_aio_array_free(os_aio_write_array);
3500 os_aio_write_array = NULL;
3501 os_aio_array_free(os_aio_sync_array);
3502 os_aio_sync_array = NULL;
3504 for (i = 0; i < os_aio_n_segments; i++) {
3508 ut_free(os_aio_segment_wait_events);
3509 os_aio_segment_wait_events = 0;
3510 os_aio_n_segments = 0;
3519 os_aio_array_wake_win_aio_at_shutdown(
3525 for (i = 0; i < array->
n_slots; i++) {
3527 SetEvent((array->
slots + i)->handle);
3544 os_aio_array_wake_win_aio_at_shutdown(os_aio_read_array);
3545 os_aio_array_wake_win_aio_at_shutdown(os_aio_write_array);
3546 os_aio_array_wake_win_aio_at_shutdown(os_aio_ibuf_array);
3547 os_aio_array_wake_win_aio_at_shutdown(os_aio_log_array);
3549 #elif defined(LINUX_NATIVE_AIO)
3556 if (srv_use_native_aio) {
3564 for (i = 0; i < os_aio_n_segments; i++) {
3578 os_event_wait(os_aio_write_array->
is_empty);
3587 os_aio_get_segment_no_from_slot(
3595 if (array == os_aio_ibuf_array) {
3598 }
else if (array == os_aio_log_array) {
3601 }
else if (array == os_aio_read_array) {
3602 seg_len = os_aio_read_array->
n_slots
3605 segment = 2 + slot->
pos / seg_len;
3607 ut_a(array == os_aio_write_array);
3608 seg_len = os_aio_write_array->
n_slots
3612 + slot->
pos / seg_len;
3623 os_aio_get_array_and_local_segment(
3626 ulint global_segment)
3630 ut_a(global_segment < os_aio_n_segments);
3632 if (global_segment == 0) {
3633 *array = os_aio_ibuf_array;
3636 }
else if (global_segment == 1) {
3637 *array = os_aio_log_array;
3640 }
else if (global_segment < os_aio_read_array->n_segments + 2) {
3641 *array = os_aio_read_array;
3643 segment = global_segment - 2;
3645 *array = os_aio_write_array;
3647 segment = global_segment - (os_aio_read_array->
n_segments + 2);
3659 os_aio_array_reserve_slot(
3680 OVERLAPPED* control;
3682 #elif defined(LINUX_NATIVE_AIO)
3690 ulint slots_per_seg;
3694 ut_a((len & 0xFFFFFFFFUL) == len);
3703 local_seg = (offset >> (UNIV_PAGE_SIZE_SHIFT + 6))
3712 if (!srv_use_native_aio) {
3727 for (i = local_seg * slots_per_seg, counter = 0;
3728 counter < array->
n_slots; i++, counter++) {
3731 slot = os_aio_array_get_nth_slot(array, i);
3761 slot->
buf =
static_cast<unsigned char *
>(buf);
3767 control = &(slot->control);
3768 control->Offset = (DWORD)offset;
3769 control->OffsetHigh = (DWORD)offset_high;
3770 ResetEvent(slot->handle);
3772 #elif defined(LINUX_NATIVE_AIO)
3775 if (!srv_use_native_aio) {
3776 goto skip_native_aio;
3781 if (
sizeof(aio_offset) == 8) {
3782 aio_offset = offset_high;
3784 aio_offset += offset;
3786 ut_a(offset_high == 0);
3787 aio_offset = offset;
3790 iocb = &slot->control;
3793 io_prep_pread(iocb, file, buf, len, aio_offset);
3795 ut_a(type == OS_FILE_WRITE);
3796 io_prep_pwrite(iocb, file, buf, len, aio_offset);
3799 iocb->data = (
void*)slot;
3816 os_aio_array_free_slot(
3842 ResetEvent(slot->handle);
3844 #elif defined(LINUX_NATIVE_AIO)
3846 if (srv_use_native_aio) {
3847 memset(&slot->control, 0x0,
sizeof(slot->control));
3854 ut_ad(slot->n_bytes == 0);
3855 ut_ad(slot->ret == 0);
3866 os_aio_simulated_wake_handler_thread(
3868 ulint global_segment)
3877 ut_ad(!srv_use_native_aio);
3879 segment = os_aio_get_array_and_local_segment(&array, global_segment);
3887 for (i = 0; i < n; i++) {
3888 slot = os_aio_array_get_nth_slot(array, i + segment * n);
3900 os_event_set(os_aio_segment_wait_events[global_segment]);
3913 if (srv_use_native_aio) {
3919 os_aio_recommend_sleep_for_read_threads = FALSE;
3921 for (i = 0; i < os_aio_n_segments; i++) {
3922 os_aio_simulated_wake_handler_thread(i);
3945 if (srv_use_native_aio) {
3951 os_aio_recommend_sleep_for_read_threads = TRUE;
3953 for (g = 0; g < os_aio_n_segments; g++) {
3954 os_aio_get_array_and_local_segment(&array, g);
3956 if (array == os_aio_read_array) {
3964 #if defined(LINUX_NATIVE_AIO)
3970 os_aio_linux_dispatch(
3979 ut_ad(slot != NULL);
3988 iocb = &slot->control;
3991 ret = io_submit(array->aio_ctx[io_ctx_index], 1, &iocb);
3993 #if defined(UNIV_AIO_DEBUG)
3995 "io_submit[%c] ret[%d]: slot[%p] ctx[%p] seg[%lu]\n",
3996 (slot->
type == OS_FILE_WRITE) ?
'w' :
'r', ret, slot,
3997 array->aio_ctx[io_ctx_index], (ulong)io_ctx_index);
4002 if (UNIV_UNLIKELY(ret != 1)) {
4058 DWORD len = (DWORD) n;
4063 #if defined LINUX_NATIVE_AIO || defined WIN_ASYNC_IO
4073 ut_ad(os_aio_validate_skip());
4075 ut_ad((n & 0xFFFFFFFFUL) == n);
4079 mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER);
4083 && !srv_use_native_aio
4094 return(os_file_read(file, buf, offset,
4098 ut_a(type == OS_FILE_WRITE);
4100 return(os_file_write(name, file, buf, offset, offset_high, n));
4103 #if defined LINUX_NATIVE_AIO || defined WIN_ASYNC_IO
4108 array = os_aio_read_array;
4110 array = os_aio_write_array;
4119 array = os_aio_ibuf_array;
4122 array = os_aio_log_array;
4124 array = os_aio_sync_array;
4126 #if defined(LINUX_NATIVE_AIO)
4128 ut_a(!srv_use_native_aio);
4135 slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
4136 name, buf, offset, offset_high, n);
4138 if (srv_use_native_aio) {
4140 os_bytes_read_since_printout += n;
4142 ret = ReadFile(file, buf, (DWORD)n, &len,
4145 #elif defined(LINUX_NATIVE_AIO)
4146 if (!os_aio_linux_dispatch(array, slot)) {
4152 os_aio_simulated_wake_handler_thread(
4153 os_aio_get_segment_no_from_slot(
4157 }
else if (type == OS_FILE_WRITE) {
4158 if (srv_use_native_aio) {
4161 ret = WriteFile(file, buf, (DWORD)n, &len,
4164 #elif defined(LINUX_NATIVE_AIO)
4165 if (!os_aio_linux_dispatch(array, slot)) {
4171 os_aio_simulated_wake_handler_thread(
4172 os_aio_get_segment_no_from_slot(
4181 if (srv_use_native_aio) {
4182 if ((ret && len == n)
4183 || (!ret && GetLastError() == ERROR_IO_PENDING)) {
4192 retval = os_aio_windows_handle(ULINT_UNDEFINED,
4210 #if defined LINUX_NATIVE_AIO || defined WIN_ASYNC_IO
4212 os_aio_array_free_slot(array, slot);
4214 retry = os_file_handle_error(name,
4216 ?
"aio read" :
"aio write");
4237 os_aio_windows_handle(
4257 ulint orig_seg = segment;
4267 if (segment == ULINT_UNDEFINED) {
4268 array = os_aio_sync_array;
4271 segment = os_aio_get_array_and_local_segment(&array, segment);
4277 ut_ad(os_aio_validate_skip());
4278 ut_ad(segment < array->n_segments);
4282 if (array == os_aio_sync_array) {
4283 WaitForSingleObject(
4284 os_aio_array_get_nth_slot(array, pos)->
handle,
4289 i = WaitForMultipleObjects((DWORD) n,
4290 array->handles + segment * n,
4301 slot = os_aio_array_get_nth_slot(array, i + segment * n);
4305 if (orig_seg != ULINT_UNDEFINED) {
4307 "get windows aio return value");
4310 ret = GetOverlappedResult(slot->
file, &(slot->control), &len, TRUE);
4317 if (ret && len == slot->
len) {
4320 #ifdef UNIV_DO_FLUSH
4321 if (slot->
type == OS_FILE_WRITE
4322 && !os_do_not_call_flush_at_each_write) {
4323 if (!os_file_flush(slot->
file)) {
4328 }
else if (os_file_handle_error(slot->
name,
"Windows aio")) {
4346 struct PSI_file_locker* locker = NULL;
4347 register_pfs_file_io_begin(locker, slot->
file, slot->
len,
4348 (slot->
type == OS_FILE_WRITE)
4351 __FILE__, __LINE__);
4354 ut_a((slot->
len & 0xFFFFFFFFUL) == slot->
len);
4356 switch (slot->
type) {
4358 ret = WriteFile(slot->
file, slot->
buf,
4359 (DWORD) slot->
len, &len,
4364 ret = ReadFile(slot->
file, slot->
buf,
4365 (DWORD) slot->
len, &len,
4374 register_pfs_file_io_end(locker, len);
4377 if (!ret && GetLastError() == ERROR_IO_PENDING) {
4384 ret = GetOverlappedResult(slot->
file,
4389 ret_val = ret && len == slot->
len;
4392 os_aio_array_free_slot(array, slot);
4398 #if defined(LINUX_NATIVE_AIO)
4412 os_aio_linux_collect(
4422 struct timespec timeout;
4423 struct io_event* events;
4424 struct io_context* io_ctx;
4427 ut_ad(array != NULL);
4428 ut_ad(seg_size > 0);
4429 ut_ad(segment < array->n_segments);
4432 events = &array->aio_events[segment * seg_size];
4435 io_ctx = array->aio_ctx[segment];
4438 start_pos = segment * seg_size;
4441 end_pos = start_pos + seg_size;
4455 memset(events, 0,
sizeof(*events) * seg_size);
4457 timeout.tv_nsec = OS_AIO_REAP_TIMEOUT;
4459 ret = io_getevents(io_ctx, 1, seg_size, events, &timeout);
4466 if (ret == -EAGAIN) {
4474 if (ret == -EINTR) {
4484 if (UNIV_UNLIKELY(ret < 0)) {
4487 " InnoDB: unexpected ret_code[%d] from"
4488 " io_getevents()!\n", ret);
4494 for (i = 0; i < ret; i++) {
4496 struct iocb* control;
4498 control = (
struct iocb *)events[i].obj;
4499 ut_a(control != NULL);
4507 #if defined(UNIV_AIO_DEBUG)
4509 "io_getevents[%c]: slot[%p] ctx[%p]"
4511 (slot->
type == OS_FILE_WRITE) ?
'w' :
'r',
4512 slot, io_ctx, segment);
4524 slot->n_bytes = events[i].res;
4525 slot->ret = events[i].res2;
4543 os_aio_linux_handle(
4566 ut_a(global_seg != ULINT_UNDEFINED);
4569 segment = os_aio_get_array_and_local_segment(&array, global_seg);
4575 for (i = 0; i < n; ++i) {
4576 slot = os_aio_array_get_nth_slot(
4577 array, i + segment * n);
4591 "waiting for completed aio requests");
4592 os_aio_linux_collect(array, segment, n);
4601 "processing completed aio requests");
4606 ut_ad(slot != NULL);
4615 if ((slot->ret == 0) && (slot->n_bytes == (
long)slot->
len)) {
4618 #ifdef UNIV_DO_FLUSH
4619 if (slot->
type == OS_FILE_WRITE
4620 && !os_do_not_call_flush_at_each_write)
4621 && !os_file_flush(slot->
file) {
4635 os_file_handle_error(slot->
name,
"Linux aio");
4642 os_aio_array_free_slot(array, slot);
4656 ulint global_segment,
4674 ulint n_consecutive;
4677 ulint lowest_offset;
4681 byte* combined_buf2;
4687 *consecutive_ios = NULL;
4689 memset(consecutive_ios, 0,
sizeof(
os_aio_slot_t*) * OS_AIO_MERGE_N_CONSECUTIVE);
4690 segment = os_aio_get_array_and_local_segment(&array, global_segment);
4697 "looking for i/o requests (a)");
4698 ut_ad(os_aio_validate_skip());
4699 ut_ad(segment < array->n_segments);
4705 if (array == os_aio_read_array
4706 && os_aio_recommend_sleep_for_read_threads) {
4711 goto recommended_sleep;
4717 "looking for i/o requests (b)");
4722 for (i = 0; i < n; i++) {
4723 slot = os_aio_array_get_nth_slot(array, i + segment * n);
4729 "InnoDB: i/o for slot %lu"
4730 " already done, returning\n",
4747 lowest_offset = ULINT_MAX;
4749 for (i = 0; i < n; i++) {
4750 slot = os_aio_array_get_nth_slot(array, i + segment * n);
4753 age = (ulint)difftime(time(NULL),
4756 if ((age >= 2 && age > biggest_age)
4757 || (age >= 2 && age == biggest_age
4758 && slot->
offset < lowest_offset)) {
4761 consecutive_ios[0] = slot;
4766 lowest_offset = slot->
offset;
4771 if (n_consecutive == 0) {
4776 lowest_offset = ULINT_MAX;
4778 for (i = 0; i < n; i++) {
4779 slot = os_aio_array_get_nth_slot(array,
4785 consecutive_ios[0] = slot;
4789 lowest_offset = slot->
offset;
4794 if (n_consecutive == 0) {
4803 ut_ad(n_consecutive != 0);
4804 ut_ad(consecutive_ios[0] != NULL);
4806 slot = consecutive_ios[0];
4811 for (i = 0; i < n; i++) {
4812 slot2 = os_aio_array_get_nth_slot(array, i + segment * n);
4814 if (slot2->
reserved && slot2 != slot
4824 consecutive_ios[n_consecutive] = slot2;
4829 if (n_consecutive < OS_AIO_MERGE_N_CONSECUTIVE) {
4831 goto consecutive_loop;
4845 slot = consecutive_ios[0];
4847 for (i = 0; i < n_consecutive; i++) {
4848 total_len += consecutive_ios[i]->
len;
4851 if (n_consecutive == 1) {
4853 combined_buf = slot->
buf;
4854 combined_buf2 = NULL;
4856 combined_buf2 =
static_cast<unsigned char *
>(
ut_malloc(total_len + UNIV_PAGE_SIZE));
4858 ut_a(combined_buf2);
4860 combined_buf =
static_cast<unsigned char *
>(
ut_align(combined_buf2, UNIV_PAGE_SIZE));
4869 if (slot->
type == OS_FILE_WRITE && n_consecutive > 1) {
4873 for (i = 0; i < n_consecutive; i++) {
4875 ut_memcpy(combined_buf + offs, consecutive_ios[i]->buf,
4876 consecutive_ios[i]->len);
4877 offs += consecutive_ios[i]->
len;
4885 "InnoDB: doing i/o of type %lu at offset %lu %lu,"
4888 (ulong) slot->
offset, (ulong) total_len);
4892 if (slot->
type == OS_FILE_WRITE) {
4893 ret = os_file_write(slot->
name, slot->
file, combined_buf,
4897 ret = os_file_read(slot->
file, combined_buf,
4906 "aio: %lu consecutive %lu:th segment, first offs %lu blocks\n",
4907 n_consecutive, global_segment, slot->
offset / UNIV_PAGE_SIZE);
4914 for (i = 0; i < n_consecutive; i++) {
4916 ut_memcpy(consecutive_ios[i]->buf, combined_buf + offs,
4917 consecutive_ios[i]->len);
4918 offs += consecutive_ios[i]->
len;
4922 if (combined_buf2) {
4930 for (i = 0; i < n_consecutive; i++) {
4949 os_aio_array_free_slot(array, slot);
4966 os_event_wait(os_aio_segment_wait_events[global_segment]);
4970 "InnoDB: i/o handler thread for i/o"
4971 " segment %lu wakes up\n",
4972 (ulong) global_segment);
4983 os_aio_array_validate(
4988 ulint n_reserved = 0;
4998 for (i = 0; i < array->
n_slots; i++) {
4999 slot = os_aio_array_get_nth_slot(array, i);
5022 os_aio_array_validate(os_aio_read_array);
5023 os_aio_array_validate(os_aio_write_array);
5024 os_aio_array_validate(os_aio_ibuf_array);
5025 os_aio_array_validate(os_aio_log_array);
5026 os_aio_array_validate(os_aio_sync_array);
5038 os_aio_print_segment_info(
5054 fprintf(file,
" [");
5057 fprintf(file,
", ");
5060 fprintf(file,
"%lu", n_seg[i]);
5062 fprintf(file,
"] ");
5076 ulint n_res_seg[SRV_MAX_N_IO_THREADS];
5077 time_t current_time;
5078 double time_elapsed;
5079 double avg_bytes_read;
5082 for (i = 0; i < srv_n_file_io_threads; i++) {
5083 fprintf(file,
"I/O thread %lu state: %s (%s)", (ulong) i,
5084 srv_io_thread_op_info[i],
5085 srv_io_thread_function[i]);
5088 if (os_aio_segment_wait_events[i]->is_set) {
5089 fprintf(file,
" ev set");
5093 fprintf(file,
"\n");
5096 fputs(
"Pending normal aio reads:", file);
5098 array = os_aio_read_array;
5109 memset(n_res_seg, 0x0,
sizeof(n_res_seg));
5111 for (i = 0; i < array->
n_slots; i++) {
5114 slot = os_aio_array_get_nth_slot(array, i);
5119 n_res_seg[seg_no]++;
5121 fprintf(stderr,
"Reserved slot, messages %p %p\n",
5131 fprintf(file,
" %lu", (ulong) n_reserved);
5133 os_aio_print_segment_info(file, n_res_seg, array);
5137 if (array == os_aio_read_array) {
5138 fputs(
", aio writes:", file);
5140 array = os_aio_write_array;
5145 if (array == os_aio_write_array) {
5146 fputs(
",\n ibuf aio reads:", file);
5147 array = os_aio_ibuf_array;
5152 if (array == os_aio_ibuf_array) {
5153 fputs(
", log i/o's:", file);
5154 array = os_aio_log_array;
5159 if (array == os_aio_log_array) {
5160 fputs(
", sync i/o's:", file);
5161 array = os_aio_sync_array;
5167 current_time = time(NULL);
5168 time_elapsed = 0.001 + difftime(current_time, os_last_printout);
5171 "Pending flushes (fsync) log: %lu; buffer pool: %lu\n"
5172 "%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n",
5173 (ulong) fil_n_pending_log_flushes,
5174 (ulong) fil_n_pending_tablespace_flushes,
5175 (ulong) os_n_file_reads, (ulong) os_n_file_writes,
5176 (ulong) os_n_fsyncs);
5180 "%lu pending preads, %lu pending pwrites\n",
5185 if (os_n_file_reads == os_n_file_reads_old) {
5186 avg_bytes_read = 0.0;
5188 avg_bytes_read = (double) os_bytes_read_since_printout
5189 / (os_n_file_reads - os_n_file_reads_old);
5193 "%.2f reads/s, %lu avg bytes/read,"
5194 " %.2f writes/s, %.2f fsyncs/s\n",
5195 (os_n_file_reads - os_n_file_reads_old)
5197 (ulong)avg_bytes_read,
5198 (os_n_file_writes - os_n_file_writes_old)
5200 (os_n_fsyncs - os_n_fsyncs_old)
5203 os_n_file_reads_old = os_n_file_reads;
5204 os_n_file_writes_old = os_n_file_writes;
5205 os_n_fsyncs_old = os_n_fsyncs;
5206 os_bytes_read_since_printout = 0;
5208 os_last_printout = current_time;
5218 os_n_file_reads_old = os_n_file_reads;
5219 os_n_file_writes_old = os_n_file_writes;
5220 os_n_fsyncs_old = os_n_fsyncs;
5221 os_bytes_read_since_printout = 0;
5223 os_last_printout = time(NULL);
5233 os_aio_all_slots_free(
void)
5239 array = os_aio_read_array;
5247 array = os_aio_write_array;
5255 array = os_aio_ibuf_array;
5263 array = os_aio_log_array;
5271 array = os_aio_sync_array;