阿里雲 CentOS 7/8 預設倉庫僅提供 MariaDB 或舊版 MySQL。生產環境需使用 **MySQL 官方 YUM 源** 安裝最新 8.0 LTS,並完成安全初始化、參數調優、防火牆、監控整合。本文提供從零到生產就緒的完整 SOP。
# 檢查現有套件 rpm -qa | grep -i mariadb rpm -qa | grep -i mysql # 完整移除 (含資料目錄備份) systemctl stop mariadb mysqld 2>/dev/null || true yum remove -y mariadb* mysql* 2>/dev/null || true # 若需保留資料,先備份 /var/lib/mysql
# 下載並安裝 RPM 包 (含 GPG Key) rpm -Uvh https://repo.mysql.com/mysql80-community-release-el7-7.noarch.rpm # CentOS 7 # rpm -Uvh https://repo.mysql.com/mysql80-community-release-el8-7.noarch.rpm # CentOS 8/Stream # 驗證倉庫啟用 yum repolist enabled | grep mysql
yum install -y mysql-community-server mysql-community-client mysql-community-devel # 驗證版本 mysqld --version # mysql Ver 8.0.36 for Linux on x86_64 (MySQL Community Server - GPL)
systemctl enable --now mysqld # 獲取臨時 root 密碼 (8.0 首次啟動自動生成) grep 'temporary password' /var/log/mysqld.log # 例: 2024-05-20T10:30:00.123456Z 0 [Note] [MY-010454] A temporary password is generated for root@localhost: xYz7!Abc # 執行安全初始化腳本 mysql_secure_installation # 輸入臨時密碼 → 設定強密碼 → 移除匿名用戶 → 禁止 root 遠程登入 → 移除 test 資料庫 → 重新載入權限表
# /etc/my.cnf.d/custom.cnf (或 /etc/my.cnf [mysqld] 區塊) [mysqld] # 基礎 server_id=1 port=3306 datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock pid-file=/var/run/mysqld/mysqld.pid log-error=/var/log/mysqld.log # 字元集 character_set_server=utf8mb4 collation_server=utf8mb4_general_ci init_connect='SET NAMES utf8mb4' skip-character-set-client-handshake # 連線 max_connections=2000 max_user_connections=1800 max_connect_errors=100000 connect_timeout=10 wait_timeout=600 interactive_timeout=600 # InnoDB 核心 (假設 16GB 記憶體,InnoDB 佔 70% ≈ 11GB) innodb_buffer_pool_size=11G innodb_buffer_pool_instances=8 innodb_log_file_size=2G innodb_log_files_in_group=2 innodb_log_buffer_size=256M innodb_flush_log_at_trx_commit=1 innodb_flush_method=O_DIRECT innodb_file_per_table=ON innodb_autoinc_lock_mode=2 innodb_read_io_threads=8 innodb_write_io_threads=8 innodb_io_capacity=2000 innodb_io_capacity_max=4000 # Binlog / 複寫 log_bin=mysql-bin binlog_format=ROW binlog_expire_logs_seconds=604800 max_binlog_size=1G sync_binlog=1 gtid_mode=ON enforce_gtid_consistency=ON log_slave_updates=ON # 查詢快取 (8.0 已移除 query_cache,改用 ProxySQL/Redis) # 慢查詢 slow_query_log=ON slow_query_log_file=/var/log/mysql/slow.log long_query_time=1 log_queries_not_using_indexes=ON min_examined_row_limit=100 # 其他 tmp_table_size=256M max_heap_table_size=256M sort_buffer_size=4M join_buffer_size=4M read_rnd_buffer_size=4M thread_cache_size=100 table_open_cache=4000 table_definition_cache=2000 open_files_limit=65535 # 安全 local_infile=OFF skip_name_resolve=ON ssl=ON require_secure_transport=ON
# firewalld firewall-cmd --permanent --add-service=mysql firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --reload # 或 iptables iptables -A INPUT -p tcp --dport 3306 -j ACCEPT # SELinux (若啟用) setsebool -P mysql_connect_any 1 semanage port -a -t mysqld_port_t -p tcp 3306 # 非預設埠需執行
CREATE USER 'app_user'@'%' IDENTIFIED BY 'AppPassw0rd!' REQUIRE SSL; GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON app_db.* TO 'app_user'@'%'; FLUSH PRIVILEGES; -- 唯讀帳號 (報表/備份) CREATE USER 'readonly'@'%' IDENTIFIED BY 'ReadOnlyPassw0rd!' REQUIRE SSL; GRANT SELECT ON app_db.* TO 'readonly'@'%';
| 現象 | 原因 | 解決 |
|---|---|---|
Authentication plugin 'caching_sha2_password' cannot be loaded | 客戶端驅動版本過舊 (JDBC < 8.0.13、PHP mysqli < 7.4) | 升級驅動、或建立用戶指定 IDENTIFIED WITH mysql_native_password |
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements | 密碼策略 validate_password 預設 MEDIUM | 暫時降低 SET GLOBAL validate_password.policy=LOW、或用複雜密碼 |
啟動失敗 InnoDB: Cannot allocate memory for the buffer pool | innodb_buffer_pool_size 超過實體記憶體 | 調整為實體記憶體 60-70% |
主從複寫 Duplicate entry 錯誤 | GTID 模式下手動插入主鍵衝突 | 使用 SET GTID_NEXT 或停寫主庫重建從庫 |
| 磁碟空間暴增 | Binlog 未自動清理 / 慢查詢日誌未輪轉 | 設定 binlog_expire_logs_seconds、配置 logrotate |
# 1. 連線測試 mysql -uapp_user -p -h127.0.0.1 -e "SELECT VERSION(); SHOW VARIABLES LIKE 'ssl%';" # 2. 參數生效確認 mysql -uroot -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW VARIABLES LIKE 'gtid_mode';" # 3. 慢查詢測試 mysql -uapp_user -p -e "SELECT SLEEP(2);" # 應出現在 /var/log/mysql/slow.log # 4. 備份測試 mysqldump --single-transaction --routines --triggers --events -uapp_user -p app_db > /backup/test_dump.sql # 5. 監控整合 (Prometheus mysqld_exporter) # docker run -d --name mysqld_exporter -p 9104:9104 \ # -e DATA_SOURCE_NAME="exporter:Passw0rd!@(127.0.0.1:3306)/" \ # prom/mysqld-exporter:v0.14.0
結語: 阿里雲 CentOS 安裝 MySQL 8.0 關鍵在於:**官方源、安全初始化、InnoDB 參數按記憶體比例配置、GTID+ROW Binlog、SSL 強制、防火牆/SELinux 放行**。建議將上述 custom.cnf、mysql_secure_installation 回答、帳號建立腳本納入 Ansible/Terraform 自動化,實現基礎設施即代碼。