Bug #102477 When one row of result exceeded 4GB, the server does not response appropriately

Submitted: 4 Feb 2021 10:54 Modified: 4 Feb 2021 14:44
Reporter: Qilu Wei Email Updates:
Status: Unsupported Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version: OS:Linux
Assigned to: CPU Architecture:Any

[4 Feb 2021 10:54] Qilu Wei
Description:
create table t1 (a longblob);
insert into t1 values (load_file("../../mysql64_linux.tar.gz"));
-- make sure the length of one row of result exceeded 4GB.
select a,a,a,a,a,a,a,a,a,a,a from t1;

1. When the server is compiled as debug, the server failed for DBUG_ASSERT:

virtual bool Sql_cmd_dml::execute(THD*): Assertion `thd->is_error() || thd->killed' failed.
06:31:03 UTC - mysqld got signal 6 ;
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
Thread pointer: 0x4ea0e800
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 7fb49c7abba8 thread_stack 0x46000
/home/wqldb_8018/bin/mysqld(my_print_stacktrace(unsigned char const*, unsigned long)+0x43) [0x4c35aa4]
/home/wqldb_8018/bin/mysqld(handle_fatal_signal+0x2bf) [0x38e6be6]
/usr/lib64/libpthread.so.0(+0xf5e0) [0x7fb49c0d25e0]
/usr/lib64/libc.so.6(gsignal+0x37) [0x7fb49a21e1f7]
/usr/lib64/libc.so.6(abort+0x148) [0x7fb49a21f8e8]
/usr/lib64/libc.so.6(+0x2e266) [0x7fb49a217266]
/usr/lib64/libc.so.6(+0x2e312) [0x7fb49a217312]
/home/wqldb_8018/bin/mysqld(Sql_cmd_dml::execute(THD*)+0x699) [0x372dc39]
/home/wqldb_8018/bin/mysqld(mysql_execute_command(THD*, bool)+0x5c69) [0x36c9833]
/home/wqldb_8018/bin/mysqld(mysql_parse(THD*, Parser_state*)+0x798) [0x36cca0b]
/home/wqldb_8018/bin/mysqld(dispatch_command(THD*, COM_DATA const*, enum_server_command)+0x1609) [0x36c0768]
/home/wqldb_8018/bin/mysqld(do_command(THD*)+0x47d) [0x36bda37]
/home/wqldb_8018/bin/mysqld(threadpool_process_request(THD*, int*)+0x19e) [0x3856e61]
/home/wqldb_8018/bin/mysqld() [0x38ad285]
/home/wqldb_8018/bin/mysqld() [0x38ad41b]
/home/wqldb_8018/bin/mysqld() [0x540999e]
/usr/lib64/libpthread.so.0(+0x7e25) [0x7fb49c0cae25]
/usr/lib64/libc.so.6(clone+0x6d) [0x7fb49a2e134d]

2. When the server is compiled as release, the client returns a error message:

ERROR 2027 (HY000) at line 1: Malformed packet

3. The two expressions are both caused by the failure of memory realloc in String class:
bool String::mem_realloc(size_t alloc_length, bool force_on_heap) {
...
    // Signal an error if len exceeds uint32 max on 64-bit word platform.
#if defined(__WORDSIZE) && (__WORDSIZE == 64)
    if (len > std::numeric_limits<uint32>::max()) return true;
#endif
...
}
Please notice that no error message is pushed on the error stack when len exceeds uint32 max.

Go on the process of failure:
bool Sql_cmd_dml::execute(THD *thd) {
...
  // Perform statement-specific execution
  res = execute_inner(thd); // res = true here
...
  if (res) goto err; 
...
err:
  DBUG_ASSERT(thd->is_error() || thd->killed); // debug builds failed here, no error in error stack, thd->is_error() = false
..
  return thd->is_error(); // return false but in fact there is error and no record is send
}

Then, since Sql_cmd_dml::execute returns true, the server sends the OK packet and the client receives it but parses it as a data packet and fails as "ERROR 2027 (HY000) at line 1: Malformed packet".

In conclusion, error message should push to error stack in String::mem_realloc.

How to repeat:
As above.
[4 Feb 2021 14:44] MySQL Verification Team
Hi Mr. Wei,

Thank you for your bug report.

However, this is not a bug.

The maximum, hard set size of the row is 4 Gb and you have hit it.

Try using prepared statements with chunks.

Not a bug.
[7 Feb 2021 3:37] Satya Bodapati
But you could throw a better error message "The row exceeded the max allowed packet size: 4GB" instead of "malformed packet" ?

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.050 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.