mariadb/mysql-test/suite/innodb/r/alloc_fail.result
Thirunarayanan Balathandayuthapani 6f89e7eac7 MDEV-36017 Alter table aborts when temporary directory is full
Problem:
=======
- In 10.11, During Copy algorithm, InnoDB does use bulk insert
for row by row insert operation. When temporary directory
ran out of memory, row_mysql_handle_errors() fails to handle
DB_TEMP_FILE_WRITE_FAIL.

- During inplace algorithm, concurrent DML fails to write
the log operation into the temporary file. InnoDB fail to
mark the error for the online log.

- ddl_log_write() releases the global ddl lock prematurely before
release the log memory entry

Fix:
===
row_mysql_handle_errors(): Rollback the transaction when
InnoDB encounters DB_TEMP_FILE_WRITE_FAIL

convert_error_code_to_mysql(): Report an aborted transaction
when InnoDB encounters DB_TEMP_FILE_WRITE_FAIL during
alter table algorithm=copy or innodb bulk insert operation

row_log_online_op(): Mark the error in online log when
InnoDB ran out of temporary space

fil_space_extend_must_retry(): Mark the os_has_said_disk_full
as true if os_file_set_size() fails

ddl_log_write(): Release the global ddl lock after releasing
the log memory entry when error was encountered

btr_cur_optimistic_update(): Relax the assertion that
blob pointer can be null during rollback because InnoDB can
ran out of space while allocating the external page
2025-04-17 23:52:06 +05:30

47 lines
1.8 KiB
Text

#
# MDEV-36017 Alter table aborts when temporary
# directory is full
#
SET SESSION DEFAULT_STORAGE_ENGINE=InnoDB;
CREATE TABLE t1(f1 CHAR(100) NOT NULL, f2 CHAR(100) NOT NULL,
f3 CHAR(100) NOT NULL, f4 CHAR(100) NOT NULL,
f5 CHAR(100) NOT NULL)ENGINE=InnoDB;
INSERT INTO t1 SELECT 'a', 'b', 'c', 'd', 'e' FROM seq_1_to_65536;
SET STATEMENT DEBUG_DBUG="+d,write_to_tmp_file_fail" FOR
CREATE TABLE t2 as SELECT * FROM t1;
ERROR HY000: Got error 59 'Temp file write failure' from InnoDB
DROP TABLE t1;
CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100),
f3 CHAR(100))ENGINE=InnoDB;
INSERT INTO t1 SELECT seq, 'a', 'b' FROM seq_1_to_1024;
SET STATEMENT DEBUG_DBUG="+d,write_to_tmp_file_fail" FOR
ALTER TABLE t1 FORCE, ALGORITHM=COPY;
ERROR HY000: Got error 59 'Temp file write failure' from InnoDB
DROP TABLE t1;
CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100),
f3 CHAR(100))ENGINE=InnoDB;
INSERT INTO t1 SELECT seq, 'a', 'b' FROM seq_1_to_4096;
SET DEBUG_SYNC="inplace_after_index_build SIGNAL dml_start WAIT_FOR dml_commit";
ALTER TABLE t1 ADD KEY(f1), ADD INDEX(f3(10));
connect con1,localhost,root,,,;
SET DEBUG_SYNC="now WAIT_FOR dml_start";
BEGIN;
INSERT INTO t1 SELECT * FROM t1;
SET STATEMENT DEBUG_DBUG="+d,os_file_write_fail" FOR COMMIT;
SET DEBUG_SYNC="now SIGNAL dml_commit";
connection default;
ERROR HY000: Temporary file write failure
disconnect con1;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
SET STATEMENT DEBUG_DBUG="+d,ddl_log_write_fail" FOR
CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB;
DROP TABLE t1;
CREATE TABLE t1(f1 TEXT, index(f1(2)))ENGINE=InnoDB;
INSERT INTO t1 VALUES('a');
set statement DEBUG_DBUG="+d,btr_page_alloc_fail" for
UPDATE t1 set f1= REPEAT('b', 12000);
ERROR HY000: The table 't1' is full
DROP TABLE t1;