MySQL 8.0.38/8.4.1/9.0.0 超过1万张表触发BUG,系统直接crash

下面是测试用例。

shell脚本(批量创建1万张表)

1w_bug.sh

#!/bin/bash

# MySQL connection details
MYSQL_HOST="127.0.0.1"
MYSQL_PORT="3306"
MYSQL_USER="admin"
MYSQL_PASSWORD="123456"
MYSQL_DATABASE="mysql8_bug"

# Number of tables to create
NUM_TABLES=10000
THREADS=16

# MySQL command to execute
MYSQL_CMD="/usr/local/mysql-8.0.38/bin/mysql -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PASSWORD"

# Check MySQL connection
echo "Checking MySQL connection..."
echo "SELECT 1;" | $MYSQL_CMD 2>/dev/null
if [ $? -ne 0 ]; then
    echo "Error: Unable to connect to MySQL. Please check your connection details."
    exit 1
fi

# Create database if it doesn't exist
echo "Creating database if it doesn't exist..."
echo "CREATE DATABASE IF NOT EXISTS $MYSQL_DATABASE;" | $MYSQL_CMD

# Use the created or existing database
MYSQL_CMD="$MYSQL_CMD $MYSQL_DATABASE"

# Function to create a table
create_table() {
    local table_name="table_$1"
    local sql="CREATE TABLE IF NOT EXISTS $table_name (id INT PRIMARY KEY AUTO_INCREMENT, data VARCHAR(255));"
    echo "$sql" | $MYSQL_CMD
    if [ $? -eq 0 ]; then
        echo "success"
    else
        echo "failure"
    fi
}

export -f create_table
export MYSQL_CMD

# Generate a sequence of table numbers and run the create_table function in parallel
success_count=$(seq 1 $NUM_TABLES | parallel -j $THREADS create_table | grep -c "success")

echo "Completed creating $success_count tables out of $NUM_TABLES."


BUG复现

shell> yum install parallel -y
shell> bash 1w_bug.sh

批量创建1万张后,你正常关闭mysqld进程,然后再启动mysqld进程,此时,MySQL直接crash,报错信息:

2024-07-12T00:58:29Z UTC - mysqld got signal 11 ;
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
BuildID[sha1]=6227f28e6cc1a743f6222b3a3a0c05561cc905ee
Thread pointer: 0x0
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 = 0 thread_stack 0x100000
/usr/local/mysql-8.0.38/bin/mysqld(my_print_stacktrace(unsigned char const*, unsigned long)+0x2e) [0x208916e]
/usr/local/mysql-8.0.38/bin/mysqld(print_fatal_signal(int)+0x35f) [0xfcf17f]
/usr/local/mysql-8.0.38/bin/mysqld(handle_fatal_signal+0xa5) [0xfcf235]
/lib64/libpthread.so.0(+0xf630) [0x7fdcca755630]
/usr/local/mysql-8.0.38/bin/mysqld(Validate_files::check(__gnu_cxx::__normal_iterator<dd::Tablespace const* const*, std::
vector<dd::Tablespace const*, std::allocator<dd::Tablespace const*> > > const&, __gnu_cxx::__normal_iterator<dd::Tablespace const* const*, std::vector<dd::Tablespace const*, std::allocator<dd::Tablespace const*> > > const&, unsigned long)+0x89e) [0x20d260e]/usr/local/mysql-8.0.38/bin/mysqld(std::thread::_State_impl<std::thread::_Invoker<std::tuple<Detached_thread, std::functi
on<void (__gnu_cxx::__normal_iterator<dd::Tablespace const* const*, std::vector<dd::Tablespace const*, std::allocator<dd::Tablespace const*> > > const&, __gnu_cxx::__normal_iterator<dd::Tablespace const* const*, std::vector<dd::Tablespace const*, std::allocator<dd::Tablespace const*> > > const&, unsigned long)>, __gnu_cxx::__normal_iterator<dd::Tablespace const* const*, std::vector<dd::T/usr/local/mysql-8.0.38/bin/mysqld() [0x29f8bd4]/lib64/libpthread.so.0(+0x7ea5) [0x7fdcca74dea5]
/lib64/libc.so.6(clone+0x6d) [0x7fdcc8b63b0d]
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
2024-07-12T00:58:29.761733Z mysqld_safe mysqld from pid file /data/mysql/mysql8/data/ck1.pid ended


解决方案

回退到MySQL 8.0.37版本。


参考文献:https://www.percona.com/blog/do-not-upgrade-to-any-version-of-mysql-after-8-0-37/

https://perconadev.atlassian.net/browse/PS-9306