Bug #121234 Util.dumpTables: Thread stack overrun when list of tables to dump is too long
Submitted: 4 Sep 19:53
Reporter: Marcos Albe (OCA) Email Updates:
Status: Open Impact on me:
None 
Category:Shell Dump & Load Severity:S3 (Non-critical)
Version:8.4.10 OS:Any
Assigned to: CPU Architecture:Any

[4 Sep 19:53] Marcos Albe
Description:
Util.dumpTables will consume all the thread's stack when the list of tables passed is too large

js> a.length;
1000
js> util.dumpTables('sbtest', a, '/tmp/bkp/');
Acquiring global read lock
Global read lock acquired
Initializing - done 
Global read lock has been released
Util.dumpTables: Thread stack overrun:  1008640 bytes used of a 1048576 byte stack, and 40000 bytes needed.  Use 'mysqld --thread_stack=#' to specify a bigger stack. (MYSQLSH 1436)

The problem is a query which uses STRCMP once per table, like:
2026-09-04T19:48:39.712946Z        51 Query     SELECT TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE,TABLE_ROWS,AVG_ROW_LENGTH,ENGINE,CREATE_OPTIONS,TABLE_COMMENT FROM information_schema.tables WHERE ((STRCMP(TABLE_SCHEMA COLLATE utf8_bin,'sbtest')=0 AND (STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest998')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest994')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest993')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest992')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest99')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest987')&STRCMP(TABLE_NAME COLLATE utf8_bin,'
sbtest985')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest984')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest980')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest979')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest976')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest974')&....&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest580')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest582')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest397')&STRCMP(TABLE_NAME COLLATE utf8_bin,'sbtest583'))=0)) AND (STRCMP(TABLE_SCHEMA COLLATE utf8_bin,'sbtest'))=0;

How to repeat:
1) Create 1000 tables; I used sysbench:

~$ mysql -uroot -pmsandbox -e "CREATE DATABASE IF NOT EXISTS sbtest";
~$ sysbench --db-driver=mysql \
--mysql-user=msandbox \
--mysql-password=msandbox \
--mysql-socket=/tmp/mysql.sock \
--mysql-db=sbtest \
--table_size=500 \
--tables=1000 \
--threads=10 \
/usr/share/sysbench/oltp_read_only.lua prepapre;

2) Get the list of tables in an array:
~$ mysqlsh --user=root --password=msandbox --js
js> var tablesList = Array()
js> session.runSql("SELECT table_name FROM information_schema.tables WHERE table_schema='sbtest'").fetchAll().forEach(row => {tablesList.push(row[0])});

3) Call dumpTables using that array

js> util.dumpTables('sbtest', tablesList, '/mnt/backups/');
Acquiring global read lock
Global read lock acquired
Initializing - done 
Global read lock has been released
Util.dumpTables: Thread stack overrun:  1008640 bytes used of a 1048576 byte stack, and 40000 bytes needed.  Use 'mysqld --thread_stack=#' to specify a bigger stack. (MYSQLSH 1436)

Suggested fix:
I guess using an IN condition, instead of bitwise-and'ing the result of 1000 STRCMP() calls?  Sadly the easy workaround requires a server restart, so actually fixing this would make a lot of sense.