原始碼編譯安裝 MySQL 可針對硬體架構深度優化 (CPU 指令集、記憶體分配器、鎖機制),獲得 10-30% 效能提升。但編譯過程涉及大量依賴庫、CMake 參數、權限配置,易遇阻礙。本文提供 CentOS 7/8、Ubuntu 20.04/22.04 雙平台完整流程,涵蓋依賴安裝、CMake 關鍵參數、編譯優化旗標、安裝後初始化、systemd 服務配置、常見錯誤對照表。
# 1. 開發工具鏈
dnf groupinstall -y "Development Tools" # 或 yum groupinstall
dnf install -y gcc gcc-c++ make cmake3 # CMake 3.15+ (MySQL 8.0 需求)
# 2. 核心依賴庫
dnf install -y \
ncurses-devel \ # 終端介面庫 (配置介面需求)
openssl-devel \ # SSL/TLS 支援
libaio-devel \ # 非同步 IO (InnoDB 原生 AIO)
libtirpc-devel \ # RPC (NFS/遠端備份)
rpcgen \ # RPC 代碼生成器
zlib-devel \ # 壓縮
bzip2-devel \ # 壓縮
lz4-devel \ # LZ4 壓縮 (Binlog/傳輸)
zstd-devel \ # ZSTD 壓縮 (8.0.20+)
readline-devel \ # 命令列編輯 (mysql client)
libedit-devel \ # 替代 readline
libevent-devel \ # 事件通知 (Group Replication)
json-c-devel \ # JSON 解析
protobuf-devel \ # Protobuf (X Plugin)
rapidjson-devel \ # RapidJSON (8.0.13+)
tbb-devel \ # Intel TBB 並行演算法 (8.0.16+)
libicu-devel \ # ICU 國際化 (正則/排序規則)
numactl-devel # NUMA 感知分配
# 3. 可選:Jemalloc / TCMalloc (替代 glibc malloc,減少碎片)
dnf install -y jemalloc-devel # 或 gperftools-devel (tcmalloc)
apt update
apt install -y \
build-essential cmake \
libncurses5-dev libssl-dev libaio-dev libtirpc-dev \
zlib1g-dev libbz2-dev liblz4-dev libzstd-dev \
libreadline-dev libedit-dev libevent-dev \
libjson-c-dev libprotobuf-dev protobuf-compiler \
rapidjson-dev libtbb-dev libicu-dev libnuma-dev \
libjemalloc-dev # 或 libgoogle-perftools-dev
# 官方下載頁: https://dev.mysql.com/downloads/mysql/
# 範例:MySQL 8.0.36 (LTS)
wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.36.tar.gz
wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.36.tar.gz.asc
# GPG 簽名驗證 (確保原始碼未被竄改)
gpg --keyserver keyserver.ubuntu.com --recv-keys 5072E1F5
gpg --verify mysql-8.0.36.tar.gz.asc mysql-8.0.36.tar.gz
# 解壓
tar xzf mysql-8.0.36.tar.gz
cd mysql-8.0.36
# 用戶與群組
groupadd -r mysql
useradd -r -g mysql -s /sbin/nologin -M mysql
# 目錄規劃 (遵循 FHS / 最佳實踐)
mkdir -p /usr/local/mysql # 安裝根目錄 (basedir)
mkdir -p /data/mysql/data # 資料目錄 (datadir)
mkdir -p /data/mysql/binlog # Binlog 目錄
mkdir -p /data/mysql/redolog # Redo Log 目錄 (可選獨立磁碟)
mkdir -p /data/mysql/undolog # Undo Log 目錄 (8.0+ 可獨立)
mkdir -p /var/log/mysql # 錯誤/慢查詢日誌
mkdir -p /var/run/mysqld # Socket/PID
mkdir -p /etc/mysql # 配置檔
# 權限
chown -R mysql:mysql /usr/local/mysql
chown -R mysql:mysql /data/mysql
chown -R mysql:mysql /var/log/mysql
chown -R mysql:mysql /var/run/mysqld
# 建立建構目錄 (out-of-source build,便於清理重建)
mkdir build && cd build
# 核心 CMake 命令 (MySQL 8.0.36 範例)
cmake .. \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/data/mysql/data \
-DSYSCONFDIR=/etc/mysql \
-DMYSQL_TCP_PORT=3306 \
-DMYSQL_UNIX_ADDR=/var/run/mysqld/mysql.sock \
\
# === 儲存引擎 ===
-DWITH_INNODB=ON \
-DWITH_PARTITION_STORAGE_ENGINE=ON \
-DWITH_FEDERATED_STORAGE_ENGINE=OFF \
-DWITH_BLACKHOLE_STORAGE_ENGINE=OFF \
-DWITH_ARCHIVE_STORAGE_ENGINE=ON \
-DWITH_CSV_STORAGE_ENGINE=ON \
-DWITHOUT_EXAMPLE_STORAGE_ENGINE=ON \
\
# === 功能特性 ===
-DENABLED_LOCAL_INFILE=ON \
-DENABLED_PROFILING=ON \
-DWITH_SSL=system \
-DWITH_ZLIB=system \
-DWITH_LZ4=system \
-DWITH_ZSTD=system \
-DWITH_ICU=system \
-DWITH_PROTOBUF=system \
-DWITH_RAPIDJSON=system \
-DWITH_TBB=system \
-DWITH_JEMALLOC=ON \ # 或 -DWITH_TCMALLOC=ON
-DWITH_NUMA=ON \
-DWITH_VALGRIND=OFF \
-DWITH_DEBUG=OFF \
\
# === 字符集與排序規則 ===
-DDEFAULT_CHARSET=utf8mb4 \
-DDEFAULT_COLLATION=utf8mb4_unicode_ci \
-DWITH_EXTRA_CHARSETS=all \
\
# === 編譯優化旗標 (關鍵效能提升) ===
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_C_FLAGS_RELWITHDEBINFO="-O3 -march=native -mtune=native -fomit-frame-pointer -pipe" \
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O3 -march=native -mtune=native -fomit-frame-pointer -pipe -funroll-loops" \
\
# === 其他 ===
-DINSTALL_LAYOUT=STANDALONE \
-DINSTALL_MYSQLKEYRINGDIR=/usr/local/mysql/keyring \
-DINSTALL_MYSQLSHAREDIR=share \
-DINSTALL_DOCDIR=docs \
-DINSTALL_MANDIR=man \
-DINSTALL_PLUGINDIR=lib/plugin \
-DINSTALL_SCRIPTDIR=bin \
-DINSTALL_SQLBENCHDIR=sql-bench \
-DINSTALL_SUPPORTFILESDIR=support-files
關鍵優化旗標解析:警告:若目標部署機器 CPU 架構不同 (如編譯機 Intel、部署機 AMD),**必須移除 -march=native,改用通用旗標** (如
-march=native -mtune=native:啟用當前 CPU 所有指令集 (AVX2, SSE4.2, AES-NI 等),**僅限當前機器運行**,不可跨機器部署。-O3:最高優化等級,含向量化、循環展開、函數內聯。-fomit-frame-pointer:省略幀指標,釋放一個暫存器,加速函數調用。-funroll-loops(C++):循環展開,減少分支預測失敗。-pipe:編譯階段用管道而非臨時檔,加速編譯。-march=x86-64-v3或-march=nehalem)。
# 編譯 (並行加速,-j 核心數)
make -j$(nproc)
# 安裝
make install
# 驗證安裝
/usr/local/mysql/bin/mysqld --version
/usr/local/mysql/bin/mysql --version
# 1. 初始化資料目錄 (生成隨機 root 密碼,輸出至 stderr)
/usr/local/mysql/bin/mysqld \
--initialize \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/data/mysql/data \
--log-error=/var/log/mysql/error.log
# 記錄輸出中的臨時密碼:[Note] [MY-010454] A temporary password is generated for root@localhost: xxxx
# 2. 建立 SSL/RSA 憑證 (加密連線用)
/usr/local/mysql/bin/mysql_ssl_rsa_setup \
--datadir=/data/mysql/data \
--uid=mysql
# 3. 複製配置檔範本
cp /usr/local/mysql/support-files/my-default.cnf /etc/mysql/my.cnf
# 或直接建立生產配置 (見下節)
# 建立服務單元檔
cat > /etc/systemd/system/mysqld.service <<'EOF'
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
After=network.target syslog.target
[Service]
Type=notify
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/mysql/my.cnf
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=process
LimitNOFILE=65535
LimitNPROC=65535
LimitCORE=infinity
TimeoutSec=600
Restart=on-failure
RestartSec=5
PrivateTmp=false
# 安全強化 (可選)
# ProtectSystem=full
# ProtectHome=true
# NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
EOF
# 重載 systemd、啟用開機自啟、啟動
systemctl daemon-reload
systemctl enable mysqld
systemctl start mysqld
# 查看狀態
systemctl status mysqld
journalctl -u mysqld -f
[mysqld]
# === 基礎路徑 ===
basedir = /usr/local/mysql
datadir = /data/mysql/data
socket = /var/run/mysqld/mysql.sock
pid-file = /var/run/mysqld/mysqld.pid
log-error = /var/log/mysql/error.log
tmpdir = /tmp
# === 網路與連線 ===
bind-address = 0.0.0.0
port = 3306
max_connections = 2000
max_connect_errors = 100000
skip_name_resolve = ON
skip_host_cache = ON
# === InnoDB 核心 (依記憶體調整) ===
innodb_buffer_pool_size = 4G # 實體記憶體 50-70%
innodb_buffer_pool_instances = 4
innodb_log_file_size = 1G
innodb_log_files_in_group = 2
innodb_log_buffer_size = 64M
innodb_flush_log_at_trx_commit = 1
innodb_flush_method = O_DIRECT
innodb_file_per_table = ON
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
# === 字符集 ===
character_set_server = utf8mb4
collation_server = utf8mb4_unicode_ci
# === 日誌 ===
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = ON
log_bin = /data/mysql/binlog/mysql-bin
binlog_format = ROW
binlog_expire_logs_seconds = 604800
sync_binlog = 1
gtid_mode = ON
enforce_gtid_consistency = ON
# === 安全 ===
local_infile = OFF
default_authentication_plugin = mysql_native_password
# === 緩衝區 (保守) ===
table_open_cache = 4000
table_definition_cache = 2000
thread_cache_size = 100
sort_buffer_size = 2M
read_buffer_size = 1M
join_buffer_size = 256K
# 1. 使用臨時密碼登入
/usr/local/mysql/bin/mysql -uroot -p'臨時密碼' --socket=/var/run/mysqld/mysql.sock
# 2. 修改 root 密碼 (8.0 語法)
ALTER USER 'root'@'localhost' IDENTIFIED BY 'StrongRootPass123!';
# 3. 建立遠端管理帳號 (僅限管理網段)
CREATE USER 'dba'@'10.0.0.%' IDENTIFIED BY 'StrongDbaPass456!';
GRANT ALL PRIVILEGES ON *.* TO 'dba'@'10.0.0.%' WITH GRANT OPTION;
# 4. 移除匿名用戶、測試庫 (mysql_secure_installation 邏輯)
DELETE FROM mysql.user WHERE User='';
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%';
FLUSH PRIVILEGES;
| 錯誤訊息 | 原因 | 解決方案 |
|---|---|---|
CMake Error: CMAKE_C_COMPILER not set | 缺少 gcc | dnf install gcc gcc-c++ / apt install build-essential |
Could NOT find Curses / No curses/termcap library found | 缺少 ncurses-devel | dnf install ncurses-devel / apt install libncurses5-dev |
Could NOT find OpenSSL | 缺少 openssl-devel | dnf install openssl-devel / apt install libssl-dev |
Could NOT find ZSTD | 缺少 zstd-devel (8.0.20+) | dnf install zstd-devel / apt install libzstd-dev |
Could NOT find Protobuf | 缺少 protobuf-devel | dnf install protobuf-devel / apt install libprotobuf-dev protobuf-compiler |
Could NOT find ICU | 缺少 libicu-devel | dnf install libicu-devel / apt install libicu-dev |
Could NOT find TBB | 缺少 tbb-devel (8.0.16+) | dnf install tbb-devel / apt install libtbb-dev |
exec: g++: not found / g++: command not found | 缺少 gcc-c++ | dnf install gcc-c++ / apt install g++ |
ld: cannot find -laio | 缺少 libaio-devel | dnf install libaio-devel / apt install libaio-dev |
InnoDB: Operating system error number 13 (Permission denied) | 資料目錄權限錯誤 | chown -R mysql:mysql /data/mysql |
Can't create test file /data/mysql/data/hostname.lower-test | basedir/datadir 配置不匹配或權限 | 檢查 my.cnf basedir/datadir、目錄擁有者 |
Address already in use (port 3306) | 殘留進程或多實例衝突 | ss -tlnp | grep 3306、殺掉殘留進程、修改 port |
Plugin 'caching_sha2_password' cannot be loaded | 客戶端版本過舊不支援 8.0 預設認證 | 用戶改用 mysql_native_password 或升級客戶端/驅動 |
systemctl restart mysqld → mysql_upgrade (8.0.16+ 自動)。OPTIMIZE TABLE 或 ALTER TABLE ... ENGINE=InnoDB (線上工具 pt-osc/gh-ost)。