Deploy MySQL 8.4 from Source with a Single Script Across Major Linux Distributions
This guide provides a comprehensive, step‑by‑step shell script that automates the installation, configuration, and service setup of MySQL 8.4 from source on a wide range of Linux distributions, including Rocky, AlmaLinux, CentOS, openEuler, Anolis, OpenCloudOS, Kylin, UOS, openSUSE, Ubuntu, and Debian.
2.4.2.5 Prepare environment variables
echo 'PATH=/apps/mysql/bin:$PATH' > /etc/profile.d/mysql.sh
. /etc/profile.d/mysql.sh
chown -R mysql:mysql /apps/mysql/2.4.2.6 Generate database files
# /data/mysql will be created automatically, but /data must exist
# --initialize generates an initial password, --initialize-insecure generates an empty password
# Generate initial password
mysqld --initialize --user=mysql --datadir=/data/mysql
# Example log output (truncated)
2025-04-30T14:21:27.126347Z 0 [System] [MY-015017] [Server] MySQL Server Initialization - start.
2025-04-30T14:21:27.130746Z 0 [System] [MY-013169] [Server] /apps/mysql/bin/mysqld (mysqld 8.4.5) initializing of server progress as process 45248
2025-04-30T14:21:27.133400Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4.
2025-04-30T14:21:27.133406Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8mb3_general_ci' is a collation of the deprecated character set UTF8MB3. Please consider using UTF8MB4 with an appropriate collation instead.
2025-04-30T14:21:28.313966Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: q&VUtowtA6!.
# Generate empty‑password root user
mysqld --initialize-insecure --user=mysql --basedir=/apps/mysql --datadir=/data/mysql
2025-04-30T16:03:40.486647Z 0 [System] [MY-015017] [Server] MySQL Server Initialization - start.
2025-04-30T16:03:40.494615Z 0 [System] [MY-013169] [Server] /apps/mysql/bin/mysqld (mysqld 8.4.5) initializing of server progress as process 46287
2025-04-30T16:03:40.501884Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4.
2025-04-30T16:03:40.501891Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8mb3_general_ci' is a collation of the deprecated character set UTF8MB3. Please consider using UTF8MB4 with an appropriate collation instead.
2025-04-30T16:03:41.857055Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password! Please consider switching off the --initialize-insecure option.2.4.2.7 Prepare configuration file
cat > /etc/my.cnf <<EOF
[mysqld]
user=mysql
basedir=/apps/mysql/
datadir=/data/mysql
port=3306
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql.log
pid-file=/data/mysql/mysql.pid
[client]
port=3306
socket=/data/mysql/mysql.sock
EOF2.4.2.8 Prepare startup script and start service
# Copy the appropriate systemd service file depending on the OS
# Rocky, AlmaLinux, CentOS, openEuler, Anolis, OpenCloudOS, Kylin, UOS, openSUSE
cp /apps/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
# Ubuntu Server 24.04 LTS
cp /apps/mysql/usr/lib/systemd/system/mysqld.service /lib/systemd/system/
# For Ubuntu 18.04/20.04/22.04 LTS and Debian 11/12 without a provided service file
cat > /lib/systemd/system/mysqld.service <<EOF
[Unit]
Description=MySQL Server
After=network.target
[Service]
User=mysql
Group=mysql
ExecStart=/apps/mysql/bin/mysqld --defaults-file=/etc/my.cnf
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable --now mysqld2.4.2.9 Modify password
# If an empty password was generated, this step can be skipped
mysqladmin -u root -p'q&VUtowtA6!.' password 1234562.4.2.10 Login test
mysql
mysql> status;
+-----------------------+
| Variable_name |
+-----------------------+
| ... (output truncated) |
+-----------------------+
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+2.4.2.11 One‑click MySQL 8.4 source installation script
#!/bin/bash
# ------------------------------------------------------------
# Author: Raymond
# Description: Install MySQL 8.4 from source on many Linux OSes
# ------------------------------------------------------------
COLOR="echo -e \033[01;31m"
END='\033[0m'
# Detect OS name and version
os() {
. /etc/os-release
MAIN_NAME=$(sed -rn '/^NAME=/s@.*="([[:alpha:]]+).*"$@\1@p' /etc/os-release)
if [[ $MAIN_NAME == "Kylin" ]]; then
MAIN_VERSION_ID=$(sed -rn '/^VERSION_ID=/s@.*="([[:alpha:]]+)(.*)"$@\2@p' /etc/os-release)
else
MAIN_VERSION_ID=$(sed -rn '/^VERSION_ID=/s@.*="?([0-9]+)\.?*"?$@\1@p' /etc/os-release)
fi
if [[ $MAIN_NAME == "Ubuntu" || $MAIN_NAME == "Debian" ]]; then
FULL_NAME="$PRETTY_NAME"
elif [[ $MAIN_NAME == "UOS" ]]; then
FULL_NAME="$NAME"
else
FULL_NAME="$NAME$VERSION_ID"
fi
}
os
SRC_DIR=/usr/local/src
INSTALL_DIR=/apps/mysql
DATA_DIR=/data/mysql
MYSQL_URL='https://cdn.mysql.com//Downloads/MySQL-8.4/'
MYSQL_FILE='mysql-8.4.5.tar.gz'
CMAKE_URL='https://cmake.org/files/v3.31/'
CMAKE_FILE='cmake-3.31.7-linux-x86_64.tar.gz'
# ... (other URLs and file names omitted for brevity) ...
check_mysql_file() {
if [[ $MAIN_NAME == "Rocky" || $MAIN_NAME == "AlmaLinux" || $MAIN_NAME == "CentOS" || $MAIN_NAME == "Anolis" || $MAIN_NAME == "OpenCloudOS" || $MAIN_NAME == "Kylin" ]]; then
rpm -q wget &>/dev/null || { $COLOR "Installing wget..."; $END; yum -y install wget &>/dev/null; }
fi
if [[ ! -e $MYSQL_FILE ]]; then
$COLOR "Downloading MySQL source package..."; $END
wget ${MYSQL_URL}${MYSQL_FILE} || { $COLOR "MySQL source download failed!"; $END; exit 1; }
else
$COLOR "MySQL source package already present."; $END
fi
}
# Similar functions for CMake, GCC, etc. are defined here (omitted for brevity)
install_mysql() {
if [[ -d $INSTALL_DIR ]]; then
$COLOR "MySQL already installed, aborting."; $END; exit 1;
fi
$COLOR "Starting MySQL installation..."; $END
# Create mysql user/group
id mysql &>/dev/null || { groupadd -r mysql; useradd -s /sbin/nologin -d $DATA_DIR -r -g mysql mysql; $COLOR "Created mysql user."; $END; }
mkdir -p $DATA_DIR && chown -R mysql:mysql $DATA_DIR
# Install dependencies based on OS (logic omitted for brevity)
# Extract source and compile
tar xf $MYSQL_FILE
MYSQL_DIR=$(echo $MYSQL_FILE | sed -nr 's/^(.*[0-9]).*/\1/p')
cd $MYSQL_DIR
cmake \
-DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \
-DMYSQL_UNIX_ADDR=$DATA_DIR/mysql.sock \
-DSYSCONFDIR=/etc \
-DSYSTEMD_PID_DIR=$INSTALL_DIR \
-DDEFAULT_CHARSET=utf8mb4 \
-DDEFAULT_COLLATION=utf8mb4_general_ci \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DMYSQL_DATADIR=$DATA_DIR \
-DFORCE_INSOURCE_BUILD=1 \
-DWITH_SYSTEMD=1
make -j $(nproc) && make install
if [[ $? -eq 0 ]]; then
$COLOR "MySQL compiled and installed successfully!"; $END
else
$COLOR "MySQL compilation failed, exiting!"; $END; exit 1;
fi
echo "PATH=$INSTALL_DIR/bin:\$PATH" > /etc/profile.d/mysql.sh
. /etc/profile.d/mysql.sh
chown -R mysql:mysql $INSTALL_DIR
mysqld --initialize-insecure --user=mysql --basedir=$INSTALL_DIR --datadir=$DATA_DIR
cat > /etc/my.cnf <<EOF
[mysqld]
user=mysql
basedir=$INSTALL_DIR
datadir=$DATA_DIR
port=3306
socket=$DATA_DIR/mysql.sock
log-error=$DATA_DIR/mysql.log
pid-file=$DATA_DIR/mysql.pid
[client]
port=3306
socket=$DATA_DIR/mysql.sock
EOF
# Copy appropriate systemd service file
if [[ $MAIN_NAME == "Rocky" || $MAIN_NAME == "AlmaLinux" || $MAIN_NAME == "CentOS" || $MAIN_NAME == "openEuler" || $MAIN_NAME == "Anolis" || $MAIN_NAME == "OpenCloudOS" || $MAIN_NAME == "Kylin" || $MAIN_NAME == "UOS" || $MAIN_NAME == "openSUSE" ]]; then
cp $INSTALL_DIR/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
elif [[ $MAIN_NAME == "Ubuntu" ]]; then
cp $INSTALL_DIR/usr/lib/systemd/system/mysqld.service /lib/systemd/system/
elif [[ $MAIN_NAME == "Debian" ]]; then
cat > /lib/systemd/system/mysqld.service <<EOF
[Unit]
Description=MySQL Server
After=network.target
[Service]
User=mysql
Group=mysql
ExecStart=$INSTALL_DIR/bin/mysqld --defaults-file=/etc/my.cnf
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
fi
systemctl daemon-reload && systemctl enable --now mysqld
if [[ $? -ne 0 ]]; then
$COLOR "Failed to start MySQL service, exiting!"; $END; exit 1;
fi
$COLOR "$FULL_NAME OS, MySQL installation completed!"; $END
}
main() {
check_mysql_file
# Additional checks for CMake, GCC, etc. would be called here
install_mysql
}
# Dispatch based on detected OS and version
if [[ $MAIN_NAME == "Rocky" && $MAIN_VERSION_ID =~ ^(8|9|10)$ ]]; then
main
elif [[ $MAIN_NAME == "AlmaLinux" && $MAIN_VERSION_ID =~ ^(8|9|10)$ ]]; then
main
elif [[ $MAIN_NAME == "CentOS" && $MAIN_VERSION_ID =~ ^(7|8|9|10)$ ]]; then
main
elif [[ $MAIN_NAME == "openEuler" && $MAIN_VERSION_ID =~ ^(22|24)$ ]]; then
main
elif [[ $MAIN_NAME == "Anolis" && $MAIN_VERSION_ID =~ ^(8|23)$ ]]; then
main
elif [[ $MAIN_NAME == "OpenCloudOS" && $MAIN_VERSION_ID =~ ^(8|9)$ ]]; then
main
elif [[ $MAIN_NAME == "Kylin" && $MAIN_VERSION_ID == 10 ]]; then
main
elif [[ $MAIN_NAME == "UOS" && $MAIN_VERSION_ID == 20 ]]; then
main
elif [[ $MAIN_NAME == "openSUSE" && $MAIN_VERSION_ID == 15 ]]; then
main
elif [[ $MAIN_NAME == "Ubuntu" && $MAIN_VERSION_ID =~ ^(18|20|22|24)$ ]]; then
main
elif [[ $MAIN_NAME == "Debian" && $MAIN_VERSION_ID =~ ^(11|12|13)$ ]]; then
main
else
$COLOR "This script does not support $FULL_NAME OS!"; $END
fiSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
