我来为您提供 MySQL 8.0 的完整初始化脚本集。
1. 环境检查脚本
创建 check_mysql_environment.sh:
bash
#!/bin/bash
# MySQL 8.0 环境检查脚本
echo "=== MySQL 8.0 环境检查 ==="
# 检查系统版本
echo "1. 检查系统版本..."
cat /etc/os-release
# 检查当前 MySQL 进程
echo "2. 检查 MySQL 进程..."
ps -ef | grep mysql | grep -v grep
# 检查端口占用
echo "3. 检查 3306 端口占用..."
netstat -tlnp | grep 3306 || echo "3306 端口未被占用"
# 检查磁盘空间
echo "4. 检查磁盘空间..."
df -h
# 检查内存
echo "5. 检查内存..."
free -h
# 检查 SELinux 状态
echo "6. 检查 SELinux 状态..."
sestatus 2>/dev/null || echo "SELinux 未安装"
# 检查防火墙
echo "7. 检查防火墙状态..."
systemctl status firewalld 2>/dev/null || ufw status 2>/dev/null || echo "防火墙检查跳过"
echo "=== 环境检查完成 ==="
2. MySQL 安装脚本
创建 install_mysql8.sh:
bash
#!/bin/bash
# MySQL 8.0 安装脚本(CentOS/RHEL)
MYSQL_VERSION="8.0"
MYSQL_ROOT_PASSWORD="MyNewPass123!"
DATA_DIR="/var/lib/mysql"
CONF_DIR="/etc/my.cnf.d"
echo "=== 开始安装 MySQL 8.0 ==="
# 添加 MySQL YUM 仓库
echo "1. 添加 MySQL YUM 仓库..."
rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm
# 安装 MySQL 服务器
echo "2. 安装 MySQL 服务器..."
yum install -y mysql-community-server
# 启动 MySQL 服务
echo "3. 启动 MySQL 服务..."
systemctl start mysqld
systemctl enable mysqld
# 获取临时 root 密码
TEMP_PASSWORD=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
echo "临时密码: $TEMP_PASSWORD"
# 安全配置
echo "4. 运行安全配置..."
mysql_secure_installation <<EOF
$TEMP_PASSWORD
y
$MYSQL_ROOT_PASSWORD
$MYSQL_ROOT_PASSWORD
y
y
y
y
y
EOF
echo "=== MySQL 8.0 安装完成 ==="
3. MySQL 配置文件模板
创建 my.cnf配置文件:
bash
[mysqld]
# 基础设置
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
# 网络设置
port=3306
bind-address=0.0.0.0
# 字符集设置
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
# 存储引擎
default-storage-engine=InnoDB
# 连接设置
max_connections=1000
max_connect_errors=10000
wait_timeout=28800
interactive_timeout=28800
# 缓冲区设置
key_buffer_size=256M
innodb_buffer_pool_size=2G
innodb_log_file_size=512M
innodb_log_buffer_size=64M
# 日志设置
slow_query_log=1
slow_query_log_file=/var/log/mysql-slow.log
long_query_time=2
log_queries_not_using_indexes=1
# 二进制日志
server-id=1
log-bin=mysql-bin
binlog_format=ROW
expire_logs_days=7
max_binlog_size=100M
# 安全设置
default_authentication_plugin=mysql_native_password
validate_password.policy=MEDIUM
# 其他优化
transaction_isolation=READ-COMMITTED
innodb_flush_log_at_trx_commit=1
sync_binlog=1
[mysql]
default-character-set=utf8mb4
[client]
default-character-set=utf8mb4
socket=/var/lib/mysql/mysql.sock
4. 数据库初始化脚本
创建 init_database.sql:
bash
-- MySQL 8.0 数据库初始化脚本
-- 设置全局参数
SET GLOBAL validate_password.policy = MEDIUM;
SET GLOBAL log_bin_trust_function_creators = 1;
-- 创建业务数据库
CREATE DATABASE IF NOT EXISTS `app_db` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE IF NOT EXISTS `log_db` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE IF NOT EXISTS `report_db` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建用户
CREATE USER IF NOT EXISTS 'app_user'@'%' IDENTIFIED BY 'AppUser123!';
CREATE USER IF NOT EXISTS 'read_user'@'%' IDENTIFIED BY 'ReadUser123!';
CREATE USER IF NOT EXISTS 'backup_user'@'localhost' IDENTIFIED BY 'BackupUser123!';
-- 应用数据库初始化
USE `app_db`;
-- 创建用户表
CREATE TABLE IF NOT EXISTS `users` (
`user_id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(50) UNIQUE NOT NULL,
`email` VARCHAR(100) UNIQUE NOT NULL,
`password_hash` VARCHAR(255) NOT NULL,
`first_name` VARCHAR(50),
`last_name` VARCHAR(50),
`phone` VARCHAR(20),
`status` ENUM('active', 'inactive', 'suspended') DEFAULT 'active',
`last_login` DATETIME NULL,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_username` (`username`),
INDEX `idx_email` (`email`),
INDEX `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 创建订单表
CREATE TABLE IF NOT EXISTS `orders` (
`order_id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`user_id` BIGINT UNSIGNED NOT NULL,
`order_number` VARCHAR(50) UNIQUE NOT NULL,
`total_amount` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
`status` ENUM('pending', 'paid', 'shipped', 'delivered', 'cancelled') DEFAULT 'pending',
`order_date` DATETIME DEFAULT CURRENT_TIMESTAMP,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (`user_id`) REFERENCES `users`(`user_id`) ON DELETE CASCADE,
INDEX `idx_order_number` (`order_number`),
INDEX `idx_user_id` (`user_id`),
INDEX `idx_status` (`status`),
INDEX `idx_order_date` (`order_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 创建订单详情表
CREATE TABLE IF NOT EXISTS `order_items` (
`item_id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`order_id` BIGINT UNSIGNED NOT NULL,
`product_id` BIGINT UNSIGNED NOT NULL,
`product_name` VARCHAR(255) NOT NULL,
`quantity` INT NOT NULL DEFAULT 1,
`unit_price` DECIMAL(10,2) NOT NULL,
`total_price` DECIMAL(12,2) NOT NULL,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`order_id`) REFERENCES `orders`(`order_id`) ON DELETE CASCADE,
INDEX `idx_order_id` (`order_id`),
INDEX `idx_product_id` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 创建日志数据库表
USE `log_db`;
CREATE TABLE IF NOT EXISTS `system_logs` (
`log_id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`level` ENUM('DEBUG', 'INFO', 'WARN', 'ERROR') DEFAULT 'INFO',
`module` VARCHAR(100) NOT NULL,
`message` TEXT NOT NULL,
`user_id` BIGINT UNSIGNED NULL,
`ip_address` VARCHAR(45),
`user_agent` TEXT,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_level` (`level`),
INDEX `idx_module` (`module`),
INDEX `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 创建审计日志表
CREATE TABLE IF NOT EXISTS `audit_logs` (
`audit_id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`table_name` VARCHAR(100) NOT NULL,
`record_id` BIGINT UNSIGNED NOT NULL,
`action` ENUM('INSERT', 'UPDATE', 'DELETE') NOT NULL,
`old_values` JSON,
`new_values` JSON,
`user_id` BIGINT UNSIGNED NULL,
`ip_address` VARCHAR(45),
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_table_record` (`table_name`, `record_id`),
INDEX `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 创建视图
USE `app_db`;
CREATE OR REPLACE VIEW `user_order_summary` AS
SELECT
u.user_id,
u.username,
u.email,
COUNT(o.order_id) as total_orders,
SUM(o.total_amount) as total_spent,
MAX(o.order_date) as last_order_date
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id
GROUP BY u.user_id, u.username, u.email;
-- 创建存储过程
DELIMITER //
CREATE PROCEDURE `GetUserOrders`(IN user_id BIGINT)
BEGIN
SELECT
o.order_id,
o.order_number,
o.total_amount,
o.status,
o.order_date,
COUNT(oi.item_id) as item_count
FROM orders o
LEFT JOIN order_items oi ON o.order_id = oi.order_id
WHERE o.user_id = user_id
GROUP BY o.order_id
ORDER BY o.order_date DESC;
END //
CREATE PROCEDURE `CleanOldLogs`(IN days_old INT)
BEGIN
DELETE FROM log_db.system_logs
WHERE created_at < DATE_SUB(NOW(), INTERVAL days_old DAY);
DELETE FROM log_db.audit_logs
WHERE created_at < DATE_SUB(NOW(), INTERVAL days_old DAY);
END //
DELIMITER ;
-- 创建触发器
USE `app_db`;
DELIMITER //
CREATE TRIGGER `users_before_update`
BEFORE UPDATE ON `users`
FOR EACH ROW
BEGIN
SET NEW.updated_at = CURRENT_TIMESTAMP;
END //
CREATE TRIGGER `audit_user_changes`
AFTER UPDATE ON `users`
FOR EACH ROW
BEGIN
INSERT INTO log_db.audit_logs
(table_name, record_id, action, old_values, new_values)
VALUES
('users', OLD.user_id, 'UPDATE',
JSON_OBJECT('username', OLD.username, 'email', OLD.email, 'status', OLD.status),
JSON_OBJECT('username', NEW.username, 'email', NEW.email, 'status', NEW.status));
END //
DELIMITER ;
-- 授权
GRANT SELECT, INSERT, UPDATE, DELETE ON `app_db`.* TO 'app_user'@'%';
GRANT SELECT ON `app_db`.* TO 'read_user'@'%';
GRANT SELECT ON `log_db`.* TO 'read_user'@'%';
GRANT SELECT, INSERT ON `log_db`.* TO 'app_user'@'%';
GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup_user'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;
-- 显示创建的表和用户
SHOW DATABASES;
SELECT user, host FROM mysql.user;
SHOW TABLES FROM app_db;
SHOW TABLES FROM log_db;
5. 用户管理和权限脚本
创建 user_management.sql:
bash
-- MySQL 用户管理和权限脚本
-- 创建不同权限级别的用户
CREATE USER IF NOT EXISTS 'dev_user'@'%' IDENTIFIED BY 'DevUser123!';
CREATE USER IF NOT EXISTS 'report_user'@'%' IDENTIFIED BY 'ReportUser123!';
CREATE USER IF NOT EXISTS 'api_user'@'10.0.0.%' IDENTIFIED BY 'ApiUser123!';
-- 开发用户权限(完整权限但限制IP)
GRANT ALL PRIVILEGES ON `app_db`.* TO 'dev_user'@'%';
GRANT ALL PRIVILEGES ON `test_db`.* TO 'dev_user'@'%';
-- 报表用户权限(只读权限)
GRANT SELECT ON `report_db`.* TO 'report_user'@'%';
GRANT SELECT ON `app_db`.`user_order_summary` TO 'report_user'@'%';
-- API 用户权限(限制IP段)
GRANT SELECT, INSERT, UPDATE ON `app_db`.`users` TO 'api_user'@'10.0.0.%';
GRANT SELECT, INSERT, UPDATE ON `app_db`.`orders` TO 'api_user'@'10.0.0.%';
GRANT SELECT, INSERT ON `app_db`.`order_items` TO 'api_user'@'10.0.0.%';
-- 创建角色(MySQL 8.0 新特性)
CREATE ROLE IF NOT EXISTS 'app_developer', 'app_reader', 'log_viewer';
-- 为角色授权
GRANT ALL PRIVILEGES ON `app_db`.* TO 'app_developer';
GRANT SELECT ON `app_db`.* TO 'app_reader';
GRANT SELECT ON `log_db`.* TO 'log_viewer';
-- 将角色授予用户
GRANT 'app_developer' TO 'dev_user'@'%';
GRANT 'app_reader', 'log_viewer' TO 'report_user'@'%';
-- 设置默认角色
SET DEFAULT ROLE 'app_developer' TO 'dev_user'@'%';
SET DEFAULT ROLE 'app_reader' TO 'report_user'@'%';
-- 密码策略管理
SET GLOBAL validate_password.policy = MEDIUM;
SET GLOBAL validate_password.length = 8;
SET GLOBAL validate_password.number_count = 1;
SET GLOBAL validate_password.mixed_case_count = 1;
SET GLOBAL validate_password.special_char_count = 1;
-- 查看用户权限
SELECT user, host, authentication_string FROM mysql.user;
SHOW GRANTS FOR 'dev_user'@'%';
SHOW GRANTS FOR 'report_user'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
6. 备份和恢复脚本
创建 mysql_backup.sh:
bash
#!/bin/bash
# MySQL 备份脚本
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
MYSQL_USER="backup_user"
MYSQL_PASSWORD="BackupUser123!"
MYSQL_HOST="localhost"
echo "=== MySQL 备份开始: $(date) ==="
# 创建备份目录
mkdir -p $BACKUP_DIR/$DATE
# 全量备份所有数据库
echo "执行全量备份..."
mysqldump -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD \
--single-transaction \
--routines \
--events \
--triggers \
--all-databases | gzip > $BACKUP_DIR/$DATE/full_backup.sql.gz
# 备份单独的重要数据库
DATABASES=("app_db" "log_db" "report_db")
for DB in "${DATABASES[@]}"; do
echo "备份数据库: $DB"
mysqldump -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD \
--single-transaction \
--routines \
--events \
--triggers \
$DB | gzip > $BACKUP_DIR/$DATE/${DB}_backup.sql.gz
done
# 备份用户和权限
echo "备份用户和权限..."
mysqldump -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD \
--no-data \
mysql user db tables_priv columns_priv procs_priv > $BACKUP_DIR/$DATE/mysql_grants.sql
# 清理旧备份
echo "清理超过 $RETENTION_DAYS 天的旧备份..."
find $BACKUP_DIR -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
# 检查备份文件
echo "备份文件列表:"
ls -lh $BACKUP_DIR/$DATE/
echo "=== MySQL 备份完成: $(date) ==="
7. 健康检查脚本
创建 mysql_health_check.sh:
bash
#!/bin/bash
# MySQL 健康检查脚本
MYSQL_USER="root"
MYSQL_PASSWORD="MyNewPass123!"
MYSQL_HOST="localhost"
echo "=== MySQL 健康检查: $(date) ==="
# 检查 MySQL 服务状态
echo "1. 检查 MySQL 服务状态..."
systemctl status mysqld --no-pager
# 检查 MySQL 连接
echo "2. 检查 MySQL 连接..."
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD -e "SELECT 1 AS connection_test;" 2>/dev/null && echo "✓ 连接正常" || echo "✗ 连接失败"
# 检查数据库状态
echo "3. 检查数据库状态..."
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD -e "
SHOW GLOBAL STATUS LIKE 'Uptime';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
SHOW GLOBAL STATUS LIKE 'Aborted_connects';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';
SHOW GLOBAL STATUS LIKE 'Slow_queries';
"
# 检查复制状态(如果有)
echo "4. 检查复制状态..."
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD -e "SHOW SLAVE STATUS\G" | grep -E "Slave_IO_State|Master_Host|Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master"
# 检查表状态
echo "5. 检查表状态..."
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD -e "
SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE, TABLE_ROWS, DATA_LENGTH, INDEX_LENGTH
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys')
ORDER BY DATA_LENGTH DESC LIMIT 10;
"
# 检查锁等待
echo "6. 检查锁等待..."
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD -e "
SELECT * FROM information_schema.INNODB_LOCKS;
SELECT * FROM information_schema.INNODB_LOCK_WAITS;
"
echo "=== 健康检查完成 ==="
8. 使用说明
- 给脚本添加执行权限:
bash
chmod +x *.sh
- 执行顺序:
bash
# 1. 环境检查
./check_mysql_environment.sh
# 2. 安装 MySQL
./install_mysql8.sh
# 3. 应用配置文件
cp my.cnf /etc/my.cnf
systemctl restart mysqld
# 4. 初始化数据库
mysql -u root -p < init_database.sql
# 5. 用户管理
mysql -u root -p < user_management.sql
# 6. 健康检查
./mysql_health_check.sh
-
重要安全提示:
-
生产环境务必修改默认密码
-
限制数据库访问IP
-
定期备份重要数据
-
启用SSL连接(生产环境)
-
配置适当的防火墙规则
-
这些脚本涵盖了 MySQL 8.0 初始化的主要环节,包括安装、配置、数据库初始化、用户管理和备份策略。