MySQL8.0全栈初始化脚本集

我来为您提供 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. 使用说明

  1. 给脚本添加执行权限​:
bash 复制代码
chmod +x *.sh
  1. 执行顺序​:
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
  1. 重要安全提示​:

    • 生产环境务必修改默认密码

    • 限制数据库访问IP

    • 定期备份重要数据

    • 启用SSL连接(生产环境)

    • 配置适当的防火墙规则

这些脚本涵盖了 MySQL 8.0 初始化的主要环节,包括安装、配置、数据库初始化、用户管理和备份策略。

相关推荐
六月闻君4 小时前
MySQL8主从数据库复制故障
数据库·mysql
洲覆4 小时前
缓存异常:缓存穿透、缓存击穿、缓存雪崩
开发语言·数据库·mysql·缓存
xcLeigh5 小时前
KingbaseES数据库:本地连接全攻略!从环境检查到问题排查,新手也能轻松上手
数据库
rexling15 小时前
【玩转全栈】----Django基本配置和介绍
数据库·django·sqlite
Deamon Tree5 小时前
如何保证缓存与数据库更新时候的一致性
java·数据库·缓存
大G的笔记本5 小时前
MySQL 中的 行锁(Record Lock) 和 间隙锁(Gap Lock)
java·数据库·mysql
洲覆5 小时前
go-mysql-transfer 伪装从库实现 MySQL 到 Redis 数据同步(完整配置)
数据库·redis·mysql·golang
谅望者6 小时前
SQL 自连接详解:当数据表需要与自己对话(组织层级实战)
数据库·sql·mysql·oracle·database
姚远Oracle ACE6 小时前
解读 “SQL ordered by Physical Reads (UnOptimized)“
数据库·sql·oracle