diff options
author | Jan Lindström <jplindst@mariadb.org> | 2015-02-13 11:49:31 +0200 |
---|---|---|
committer | Jan Lindström <jplindst@mariadb.org> | 2015-02-13 11:49:31 +0200 |
commit | 454beee5fbd9da8e87a54b46ea716679693361bd (patch) | |
tree | 9ef1493fdb62e1526189624051b93b332ae92113 /storage/xtradb | |
parent | 356ae629f0b8ecd5e4b277bdaedf6d55ce09a603 (diff) | |
download | mariadb-git-454beee5fbd9da8e87a54b46ea716679693361bd.tar.gz |
MDEV-6288 :Innodb causes server crash after disk full, then can't ALTER TABLE any more
Fix try to avoid unnecessary crashes when disk full situation is reached
on alter table.
Diffstat (limited to 'storage/xtradb')
-rw-r--r-- | storage/xtradb/btr/btr0btr.cc | 6 | ||||
-rw-r--r-- | storage/xtradb/fil/fil0fil.cc | 8 | ||||
-rw-r--r-- | storage/xtradb/os/os0file.cc | 23 | ||||
-rw-r--r-- | storage/xtradb/row/row0merge.cc | 18 | ||||
-rw-r--r-- | storage/xtradb/row/row0mysql.cc | 1 |
5 files changed, 41 insertions, 15 deletions
diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc index d240188e772..1da487f1400 100644 --- a/storage/xtradb/btr/btr0btr.cc +++ b/storage/xtradb/btr/btr0btr.cc @@ -3097,6 +3097,12 @@ func_start: /* 2. Allocate a new page to the index */ new_block = btr_page_alloc(cursor->index, hint_page_no, direction, btr_page_get_level(page, mtr), mtr, mtr); + + /* Play safe, if new page is not allocated */ + if (!new_block) { + return(rec); + } + new_page = buf_block_get_frame(new_block); new_page_zip = buf_block_get_page_zip(new_block); btr_page_create(new_block, new_page_zip, cursor->index, diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 5d547edaaf9..da61d29f6f8 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -4982,7 +4982,11 @@ retry: success = TRUE; } + DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", + success = FALSE; errno = 28;os_has_said_disk_full = TRUE;); + mutex_enter(&fil_system->mutex); + if (success) { node->size += n_pages; space->size += n_pages; @@ -5023,6 +5027,10 @@ retry: offset, page_size * n_pages, NULL, NULL, space_id, NULL); #endif /* UNIV_HOTBACKUP */ + + DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", + success = FALSE; errno = 28; os_has_said_disk_full = TRUE;); + if (success) { os_has_said_disk_full = FALSE; } else { diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 691054a7e47..112581442ab 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -4735,7 +4735,7 @@ os_aio_func( mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER); DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", - mode = OS_AIO_SYNC;); + mode = OS_AIO_SYNC; os_has_said_disk_full = TRUE;); if (mode == OS_AIO_SYNC) { ibool ret; @@ -4744,20 +4744,15 @@ os_aio_func( if (type == OS_FILE_READ) { ret = os_file_read_func(file, buf, offset, n, trx); - } - else { + } else { ut_ad(!srv_read_only_mode); ut_a(type == OS_FILE_WRITE); ret = os_file_write(name, file, buf, offset, n); - } - DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", - os_has_said_disk_full = FALSE;); - DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", - ret = 0;); - DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", - errno = 28;); + DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", + os_has_said_disk_full = TRUE; ret = 0; errno = 28;); + } if (!ret) { fprintf(stderr, "FAIL"); @@ -5585,17 +5580,15 @@ consecutive_loop: ret = os_file_write( aio_slot->name, aio_slot->file, combined_buf, aio_slot->offset, total_len); + + DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", + os_has_said_disk_full = TRUE; ret = 0; errno = 28;); } else { ret = os_file_read( aio_slot->file, combined_buf, aio_slot->offset, total_len); } - if (aio_slot->type == OS_FILE_WRITE) { - DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28_2", - os_has_said_disk_full = FALSE; ret = 0; errno = 28;); - } - srv_set_io_thread_op_info(global_segment, "file i/o done"); if (aio_slot->type == OS_FILE_READ && n_consecutive > 1) { diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index 5d88d750478..1d66707736d 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -2401,6 +2401,24 @@ row_merge_insert_index_tuples( #endif /* UNIV_DEBUG */ ulint* ins_offsets = NULL; + /* First reserve enough free space for the file segments + of the index tree, so that the insert will not fail because + of lack of space */ + + { + ulint n_extents = cursor.tree_height / 16 + 3; + ibool success; + ulint n_reserved = 0; + + success = fsp_reserve_free_extents(&n_reserved, index->space, + n_extents, FSP_NORMAL, &mtr); + + if (!success) { + error = DB_OUT_OF_FILE_SPACE; + goto err_exit; + } + } + error = btr_cur_optimistic_insert( BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG | BTR_KEEP_SYS_FLAG | BTR_CREATE_FLAG, diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 854ebd6f8cc..ec4f865c6b3 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -4387,6 +4387,7 @@ row_drop_table_for_mysql( case DB_OUT_OF_FILE_SPACE: err = DB_MUST_GET_MORE_FILE_SPACE; + trx->error_state = err; row_mysql_handle_errors(&err, trx, NULL, NULL); /* raise error */ |