summaryrefslogtreecommitdiff
path: root/storage/xtradb
diff options
context:
space:
mode:
authorJan Lindström <jplindst@mariadb.org>2015-02-13 11:49:31 +0200
committerJan Lindström <jplindst@mariadb.org>2015-02-13 11:49:31 +0200
commit454beee5fbd9da8e87a54b46ea716679693361bd (patch)
tree9ef1493fdb62e1526189624051b93b332ae92113 /storage/xtradb
parent356ae629f0b8ecd5e4b277bdaedf6d55ce09a603 (diff)
downloadmariadb-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.cc6
-rw-r--r--storage/xtradb/fil/fil0fil.cc8
-rw-r--r--storage/xtradb/os/os0file.cc23
-rw-r--r--storage/xtradb/row/row0merge.cc18
-rw-r--r--storage/xtradb/row/row0mysql.cc1
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 */