summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2015-03-09 18:21:48 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2015-03-09 18:33:25 +0200
commita7fd11b31d52b62ef7b61783bb83a5e62271307b (patch)
tree979131c0d6ce96f32c4d56f87008d54e1bdeef42
parentec16d1b62fb08b4dd3aa415a9bf717b5039a56cc (diff)
downloadmariadb-git-a7fd11b31d52b62ef7b61783bb83a5e62271307b.tar.gz
MDEV-7685: MariaDB - server crashes when inserting more rows than
available space on disk Add error handling when disk full situation happens and intentionally bring server down with stacktrace because on all cases InnoDB can't continue anyway.
-rw-r--r--mysql-test/suite/innodb/r/innodb-alter-table-disk-full.result63
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter-table-disk-full-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter-table-disk-full.test75
-rw-r--r--storage/innobase/btr/btr0btr.cc6
-rw-r--r--storage/innobase/handler/handler0alter.cc1
-rw-r--r--storage/innobase/os/os0file.cc17
-rw-r--r--storage/xtradb/btr/btr0btr.cc6
-rw-r--r--storage/xtradb/handler/handler0alter.cc1
-rw-r--r--storage/xtradb/os/os0file.cc16
9 files changed, 28 insertions, 158 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-alter-table-disk-full.result b/mysql-test/suite/innodb/r/innodb-alter-table-disk-full.result
deleted file mode 100644
index a357fe27f37..00000000000
--- a/mysql-test/suite/innodb/r/innodb-alter-table-disk-full.result
+++ /dev/null
@@ -1,63 +0,0 @@
-call mtr.add_suppression("InnoDB: Error: row_merge_drop_indexes_dict failed with error code*");
-create table t1(a int, b int) engine=innodb;
-create procedure innodb_insert_proc (repeat_count int)
-begin
-declare current_num int;
-set current_num = 0;
-while current_num < repeat_count do
-insert into t1 values(current_num, current_num);
-set current_num = current_num + 1;
-end while;
-end//
-commit;
-set autocommit=0;
-call innodb_insert_proc(20000);
-commit;
-set autocommit=1;
-create table t2(a int) engine=innodb;
-show create table t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `a` int(11) DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-set DEBUG_DBUG='+d,ib_os_aio_func_io_failure_28';
-alter table t1 add testcol int;
-ERROR HY000: The table 't1' is full
-show create table t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` int(11) DEFAULT NULL,
- `b` int(11) DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-alter table t2 add testcol int;
-ERROR HY000: The table 't2' is full
-alter table t1 add testcol int;
-ERROR HY000: The table 't1' is full
-alter table t1 add testcol int;
-ERROR HY000: The table 't1' is full
-alter table t1 add testcol2 int;
-ERROR HY000: The table 't1' is full
-alter table t1 add testcol3 int;
-ERROR HY000: The table 't1' is full
-alter table t1 add testcol int;
-ERROR HY000: The table 't1' is full
-show create table t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` int(11) DEFAULT NULL,
- `b` int(11) DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-drop table t2;
-alter table t1 add testcol2 int;
-ERROR HY000: The table 't1' is full
-alter table t1 add testcol3 int;
-ERROR HY000: The table 't1' is full
-call innodb_insert_proc(20000);
-set autocommit=0;
-call innodb_insert_proc(20000);
-commit;
-set autocommit=1;
-set DEBUG_DBUG='';
-drop procedure innodb_insert_proc;
-drop table t1;
-drop table if exists t2;
diff --git a/mysql-test/suite/innodb/t/innodb-alter-table-disk-full-master.opt b/mysql-test/suite/innodb/t/innodb-alter-table-disk-full-master.opt
deleted file mode 100644
index 9c2ee7846b6..00000000000
--- a/mysql-test/suite/innodb/t/innodb-alter-table-disk-full-master.opt
+++ /dev/null
@@ -1 +0,0 @@
---innodb-use-native-aio=0
diff --git a/mysql-test/suite/innodb/t/innodb-alter-table-disk-full.test b/mysql-test/suite/innodb/t/innodb-alter-table-disk-full.test
deleted file mode 100644
index 8fd8e3914c4..00000000000
--- a/mysql-test/suite/innodb/t/innodb-alter-table-disk-full.test
+++ /dev/null
@@ -1,75 +0,0 @@
-# MDEV-6288: Innodb causes server crash after disk full, then can't ALTER TABLE any more
---source include/have_innodb.inc
---source include/not_windows.inc
---source include/not_valgrind.inc
---source include/not_embedded.inc
-
-# DEBUG_SYNC must be compiled in.
---source include/have_debug_sync.inc
-
-call mtr.add_suppression("InnoDB: Error: row_merge_drop_indexes_dict failed with error code*");
-
-create table t1(a int, b int) engine=innodb;
-
-delimiter //;
-create procedure innodb_insert_proc (repeat_count int)
-begin
- declare current_num int;
- set current_num = 0;
- while current_num < repeat_count do
- insert into t1 values(current_num, current_num);
- set current_num = current_num + 1;
- end while;
-end//
-delimiter ;//
-commit;
-
-set autocommit=0;
-call innodb_insert_proc(20000);
-commit;
-set autocommit=1;
-
-create table t2(a int) engine=innodb;
-show create table t2;
-
-# This caused crash earlier
-set DEBUG_DBUG='+d,ib_os_aio_func_io_failure_28';
---error 1114
-alter table t1 add testcol int;
-show create table t1;
---error 1114
-alter table t2 add testcol int;
---error 1114
-alter table t1 add testcol int;
---error 1114
-alter table t1 add testcol int;
---error 1114
-alter table t1 add testcol2 int;
---error 1114
-alter table t1 add testcol3 int;
---error 1114
-alter table t1 add testcol int;
-show create table t1;
---error 0,1051
-drop table t2;
---error 1114
-alter table t1 add testcol2 int;
---error 1114
-alter table t1 add testcol3 int;
---error 0,1114
-call innodb_insert_proc(20000);
-set autocommit=0;
---error 0,1114
-call innodb_insert_proc(20000);
-commit;
-set autocommit=1;
-
-set DEBUG_DBUG='';
-
-drop procedure innodb_insert_proc;
-drop table t1;
---disable_warnings
-drop table if exists t2;
---enable_warnings
-
-
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index 00b90120f6c..79b533481b7 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -3055,12 +3055,6 @@ 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/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index b387c217b43..76d68bb9676 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -128,6 +128,7 @@ my_error_innodb(
break;
case DB_OUT_OF_FILE_SPACE:
my_error(ER_RECORD_FILE_FULL, MYF(0), table);
+ ut_error;
break;
case DB_TEMP_FILE_WRITE_FAILURE:
my_error(ER_GET_ERRMSG, MYF(0),
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index b646b74b246..30e98c2eddd 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -617,7 +617,7 @@ os_file_handle_error_cond_exit(
os_has_said_disk_full = TRUE;
fflush(stderr);
-
+ ut_error;
return(FALSE);
case OS_FILE_AIO_RESOURCES_RESERVED:
@@ -4607,7 +4607,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; os_has_said_disk_full = TRUE;);
+ mode = OS_AIO_SYNC; os_has_said_disk_full = FALSE;);
if (mode == OS_AIO_SYNC
#ifdef WIN_ASYNC_IO
@@ -4639,7 +4639,11 @@ os_aio_func(
ret = os_file_write_func(name, file, buf, offset, n);
DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
- os_has_said_disk_full = TRUE; ret = 0; errno = 28;);
+ os_has_said_disk_full = FALSE; ret = 0; errno = 28;);
+
+ if (!ret) {
+ os_file_handle_error_cond_exit(name, "os_file_write_func", TRUE, FALSE);
+ }
}
return ret;
@@ -5463,9 +5467,14 @@ consecutive_loop:
aio_slot->offset, total_len);
DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
- os_has_said_disk_full = TRUE;
+ os_has_said_disk_full = FALSE;
ret = 0;
errno = 28;);
+
+ if (!ret) {
+ os_file_handle_error_cond_exit(aio_slot->name, "os_file_write_func", TRUE, FALSE);
+ }
+
} else {
ret = os_file_read(
aio_slot->file, combined_buf,
diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc
index 1da487f1400..d240188e772 100644
--- a/storage/xtradb/btr/btr0btr.cc
+++ b/storage/xtradb/btr/btr0btr.cc
@@ -3097,12 +3097,6 @@ 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/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 3441fe04006..bb58a92ed1a 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -128,6 +128,7 @@ my_error_innodb(
break;
case DB_OUT_OF_FILE_SPACE:
my_error(ER_RECORD_FILE_FULL, MYF(0), table);
+ ut_error;
break;
case DB_TEMP_FILE_WRITE_FAILURE:
my_error(ER_GET_ERRMSG, MYF(0),
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 112581442ab..a88c344a6ee 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -716,6 +716,7 @@ os_file_handle_error_cond_exit(
fflush(stderr);
+ ut_error;
return(FALSE);
case OS_FILE_AIO_RESOURCES_RESERVED:
@@ -4735,7 +4736,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; os_has_said_disk_full = TRUE;);
+ mode = OS_AIO_SYNC; os_has_said_disk_full = FALSE;);
if (mode == OS_AIO_SYNC) {
ibool ret;
@@ -4751,7 +4752,11 @@ os_aio_func(
ret = os_file_write(name, file, buf, offset, n);
DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
- os_has_said_disk_full = TRUE; ret = 0; errno = 28;);
+ os_has_said_disk_full = FALSE; ret = 0; errno = 28;);
+
+ if (!ret) {
+ os_file_handle_error_cond_exit(name, "os_file_write_func", TRUE, FALSE);
+ }
}
if (!ret) {
@@ -5582,7 +5587,12 @@ consecutive_loop:
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;);
+ os_has_said_disk_full = FALSE; ret = 0; errno = 28;);
+
+ if (!ret) {
+ os_file_handle_error_cond_exit(aio_slot->name, "os_file_write_func", TRUE, FALSE);
+ }
+
} else {
ret = os_file_read(
aio_slot->file, combined_buf,