diff options
author | Jan Lindström <jplindst@mariadb.org> | 2013-08-23 09:03:57 +0300 |
---|---|---|
committer | Jan Lindström <jplindst@mariadb.org> | 2013-08-23 09:03:57 +0300 |
commit | c8b87ca16f05826c6801c70fb20a88a61959264e (patch) | |
tree | 81b72b932743b2fa91b3097be8eff43270ddac67 | |
parent | 9adb6e991ec87b65d04929f115d9d0c899e4ab19 (diff) | |
download | mariadb-git-c8b87ca16f05826c6801c70fb20a88a61959264e.tar.gz |
MDEV-4133: Review InnoDB tablespace allocation patch by Toshikuni Fukaya. If innodb_use_posix_fallocate is set we use posix_fallocate call to extent tablespace allocation instead of pwrite.
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 24 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 23 | ||||
-rw-r--r-- | storage/innobase/os/os0file.cc | 17 | ||||
-rw-r--r-- | storage/innobase/row/row0log.cc | 14 | ||||
-rw-r--r-- | storage/xtradb/fil/fil0fil.c | 5 |
5 files changed, 73 insertions, 10 deletions
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index a89875352c6..1779ae86c46 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -4782,6 +4782,23 @@ retry: start_page_no = space->size; file_start_page_no = space->size - node->size; +#ifdef HAVE_POSIX_FALLOCATE + if (srv_use_posix_fallocate) { + ulint n_pages = size_after_extend - start_page_no; + + success = os_file_set_size(node->name, node->handle, + n_pages * page_size); + + mutex_enter(&fil_system->mutex); + if (success) { + node->size += n_pages; + space->size += n_pages; + os_has_said_disk_full = FALSE; + } + goto complete_io; + } +#endif + /* Extend at most 64 pages at a time */ buf_size = ut_min(64, size_after_extend - start_page_no) * page_size; buf2 = static_cast<byte*>(mem_alloc(buf_size + page_size)); @@ -4835,10 +4852,15 @@ retry: space->size += pages_added; node->size += pages_added; - node->being_extended = FALSE; +#ifdef HAVE_POSIX_FALLOCATE +complete_io: + fil_node_complete_io(node, fil_system, OS_FILE_READ); +#else fil_node_complete_io(node, fil_system, OS_FILE_WRITE); +#endif + node->being_extended = FALSE; *actual_size = space->size; #ifndef UNIV_HOTBACKUP diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 17f63f19ce0..f4a7a60ca52 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3197,6 +3197,7 @@ innobase_change_buffering_inited_ok: srv_use_posix_fallocate = (ibool) innobase_use_fallocate; #endif srv_use_atomic_writes = (ibool) innobase_use_atomic_writes; + if (innobase_use_atomic_writes) { fprintf(stderr, "InnoDB: using atomic writes.\n"); @@ -3211,13 +3212,13 @@ innobase_change_buffering_inited_ok: #ifndef _WIN32 if(!innobase_file_flush_method || !strstr(innobase_file_flush_method, "O_DIRECT")) { - innobase_file_flush_method = + innobase_file_flush_method = srv_file_flush_method_str = (char*)"O_DIRECT"; fprintf(stderr, "InnoDB: using O_DIRECT due to atomic writes.\n"); } #endif #ifdef HAVE_POSIX_FALLOCATE - /* Due to a bug in directFS, using atomics needs + /* Due to a bug in directFS, using atomics needs * posix_fallocate to extend the file * pwrite() past end of the file won't work */ @@ -16892,7 +16893,11 @@ ib_senderrf( str[size - 1] = 0x0; vsnprintf(str, size, format, args); #elif HAVE_VASPRINTF - (void) vasprintf(&str, format, args); + if (vasprintf(&str, format, args) == -1) { + /* In case of failure use a fixed length string */ + str = static_cast<char*>(malloc(BUFSIZ)); + my_vsnprintf(str, BUFSIZ, format, args); + } #else /* Use a fixed length string. */ str = static_cast<char*>(malloc(BUFSIZ)); @@ -16968,7 +16973,11 @@ ib_errf( str[size - 1] = 0x0; vsnprintf(str, size, format, args); #elif HAVE_VASPRINTF - (void) vasprintf(&str, format, args); + if (vasprintf(&str, format, args) == -1) { + /* In case of failure use a fixed length string */ + str = static_cast<char*>(malloc(BUFSIZ)); + my_vsnprintf(str, BUFSIZ, format, args); + } #else /* Use a fixed length string. */ str = static_cast<char*>(malloc(BUFSIZ)); @@ -17002,7 +17011,11 @@ ib_logf( str[size - 1] = 0x0; vsnprintf(str, size, format, args); #elif HAVE_VASPRINTF - (void) vasprintf(&str, format, args); + if (vasprintf(&str, format, args) == -1) { + /* In case of failure use a fixed length string */ + str = static_cast<char*>(malloc(BUFSIZ)); + my_vsnprintf(str, BUFSIZ, format, args); + } #else /* Use a fixed length string. */ str = static_cast<char*>(malloc(BUFSIZ)); diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index b4e4f52a0f7..d1b2b12bf59 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -2099,6 +2099,23 @@ os_file_set_size( current_size = 0; +#ifdef HAVE_POSIX_FALLOCATE + if (srv_use_posix_fallocate) { + + if (posix_fallocate(file, current_size, size) == -1) { + + fprintf(stderr, "InnoDB: Error: preallocating file " + "space for file \'%s\' failed. Current size " + "%lu, desired size %lu\n", + name, current_size, size); + os_file_handle_error_no_exit(name, "posix_fallocate", FALSE); + return(FALSE); + } + return(TRUE); + } +#endif + + /* Write up to 1 megabyte at a time. */ buf_size = ut_min(64, (ulint) (size / UNIV_PAGE_SIZE)) * UNIV_PAGE_SIZE; diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index b373b70ab7a..eec5dded7cd 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -2136,7 +2136,12 @@ corruption: if (index->online_log->head.blocks) { #ifdef HAVE_FTRUNCATE /* Truncate the file in order to save space. */ - ftruncate(index->online_log->fd, 0); + if (ftruncate(index->online_log->fd, 0) == -1) { + fprintf(stderr, "InnoDB: Error: Truncate of file " + "\'%s\' failed with error %d:%s\n", + index->name + 1, errno, strerror(errno)); + goto corruption; + } #endif /* HAVE_FTRUNCATE */ index->online_log->head.blocks = index->online_log->tail.blocks = 0; @@ -2922,7 +2927,12 @@ corruption: if (index->online_log->head.blocks) { #ifdef HAVE_FTRUNCATE /* Truncate the file in order to save space. */ - ftruncate(index->online_log->fd, 0); + if (ftruncate(index->online_log->fd, 0) == -1) { + fprintf(stderr, "InnoDB: Error: Truncate of file " + "\'%s\' failed with error %d:%s\n", + index->name + 1, errno, strerror(errno)); + goto corruption; + } #endif /* HAVE_FTRUNCATE */ index->online_log->head.blocks = index->online_log->tail.blocks = 0; diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c index 48f3c43cdc0..b775df05c11 100644 --- a/storage/xtradb/fil/fil0fil.c +++ b/storage/xtradb/fil/fil0fil.c @@ -4938,10 +4938,11 @@ fil_extend_space_to_desired_size( mem_free(buf2); - fil_node_complete_io(node, fil_system, OS_FILE_WRITE); - #ifdef HAVE_POSIX_FALLOCATE complete_io: + fil_node_complete_io(node, fil_system, OS_FILE_READ); +#else + fil_node_complete_io(node, fil_system, OS_FILE_WRITE); #endif *actual_size = space->size; |