[MDEV-25099] Inconsistent error upon updating read-only table with ROW_FORMAT=COMPRESSED Created: 2021-03-09  Updated: 2022-06-06

Status: Open
Project: MariaDB Server
Component/s: Data Manipulation - Insert, Storage Engine - InnoDB
Affects Version/s: 10.6
Fix Version/s: 10.6

Type: Bug Priority: Trivial
Reporter: Elena Stepanova Assignee: Rucha Deodhar
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-23497 make ROW_FORMAT=COMPRESSED read-only ... Closed

 Description   

MTR test is at the end of the description.

Command-line client version

set global innodb_read_only_compressed= off;
create table t (a int) row_format=compressed;
insert into t values (1),(2),(3);
set global innodb_read_only_compressed= on;
 
insert into t values (4);
show warnings;
delete from t where a = 2;
show warnings;
 
drop table t;

10.6 d317350a76

MariaDB [db]> insert into t values (4);
ERROR 4047 (HY000): InnoDB refuses to write tables with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE.
 
MariaDB [db]> show warnings;
+-------+------+------------------------------------------------------------------------------+
| Level | Code | Message                                                                      |
+-------+------+------------------------------------------------------------------------------+
| Error | 4047 | InnoDB refuses to write tables with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE. |
| Error | 1036 | Table 't' is read only                                                       |
+-------+------+------------------------------------------------------------------------------+
2 rows in set (0.000 sec)

MariaDB [db]> delete from t where a = 2;
ERROR 1036 (HY000): Table 't' is read only
 
MariaDB [db]> show warnings;
+---------+------+------------------------------------------------------------------------------+
| Level   | Code | Message                                                                      |
+---------+------+------------------------------------------------------------------------------+
| Warning | 4047 | InnoDB refuses to write tables with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE. |
| Error   | 1036 | Table 't' is read only                                                       |
+---------+------+------------------------------------------------------------------------------+
2 rows in set (0.000 sec)

Note that for INSERT 4047 is an error, while for DELETE it's a warning.

MTR version

--source include/have_innodb.inc
 
set global innodb_read_only_compressed= off;
create table t (a int) engine=InnoDB row_format=compressed;
insert into t values (1),(2),(3);
set global innodb_read_only_compressed= on;
 
--error ER_UNSUPPORTED_COMPRESSED_TABLE
insert into t values (4);
show warnings;
 
--error ER_UNSUPPORTED_COMPRESSED_TABLE
delete from t where a = 2;
show warnings;
 
# Cleanup 
drop table t;



 Comments   
Comment by Marko Mäkelä [ 2021-07-23 ]

InnoDB is issuing the error code ER_UNSUPPORTED_COMPRESSED_TABLE using my_error() on DDL, and everywhere else via the following:

ib_senderrf(m_user_thd, IB_LOG_LEVEL_WARN, ER_UNSUPPORTED_COMPRESSED_TABLE);

Also, every DML member function of ha_innobase is returning the same value:

	if (is_read_only()) {
		DBUG_RETURN(HA_ERR_TABLE_READONLY);
	}

The error/warning mismatch between INSERT and DELETE ought to be due to something outside InnoDB.

Comment by Norio Akagi [ 2022-06-06 ]

I have debugged this issue and summarizing the observation so far:

The difference between INSERT and DELETE is caused by this line
https://github.com/MariaDB/server/blob/10.6/sql/sql_class.cc#L1093
MariaDB overwrites the level with ERROR because the method really_abort_on_warning() return TRUE only for the insert case but not for the delete case. It looks thd->abort_on_warning == TRUE on insert but FALSE on delete.

Here is my assumption and to be validated, but only in sql_insert.cc we have this code and this would be TRUE in the test case.
thd->abort_on_warning= !ignore && thd->is_strict_mode();

Can anyone from MariaDB help me to suggest a proper way to fix this ? The line above has the comment

    /*
      FIXME:
      push_warning and strict SQL_MODE case.
    */

which makes me think that we don't want to specifically overwrite with ERROR in this test case. Is my understanding correct ?

Generated at Thu Feb 08 09:35:08 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.