[Commits] 68f2ac5: MDEV-7685: MariaDB - server crashes when inserting more rows than

Jan Lindström jan.lindstrom at mariadb.com
Mon Mar 9 18:32:10 EET 2015


revision-id: 68f2ac55181267a4a63ca01f79da694184fffbc5
parent(s): 040027c888f9b9e1a41c82fd793e0cde289e5eb1
committer: Jan Lindström
branch nick: 10.0-git
timestamp: 2015-03-09 18:21:48 +0200
message:

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.

---
 .../innodb/r/innodb-alter-table-disk-full.result   | 63 ------------------
 .../t/innodb-alter-table-disk-full-master.opt      |  1 -
 .../innodb/t/innodb-alter-table-disk-full.test     | 75 ----------------------
 storage/innobase/btr/btr0btr.cc                    |  6 --
 storage/innobase/handler/handler0alter.cc          |  1 +
 storage/innobase/os/os0file.cc                     | 17 +++--
 storage/xtradb/btr/btr0btr.cc                      |  6 --
 storage/xtradb/handler/handler0alter.cc            |  1 +
 storage/xtradb/os/os0file.cc                       | 16 ++++-
 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 a357fe2..0000000
--- 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 9c2ee78..0000000
--- 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 8fd8e39..0000000
--- 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 00b9012..79b5334 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -3055,12 +3055,6 @@ btr_page_split_and_insert(
 	/* 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 b387c21..76d68bb 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 b646b74..30e98c2 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 @@ os_aio_simulated_handle(
 			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 1da487f..d240188 100644
--- a/storage/xtradb/btr/btr0btr.cc
+++ b/storage/xtradb/btr/btr0btr.cc
@@ -3097,12 +3097,6 @@ btr_page_split_and_insert(
 	/* 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 3441fe0..bb58a92 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 1125814..a88c344 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 @@ os_aio_simulated_handle(
 			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,


More information about the commits mailing list