外观
MySQL 数据库安装规范
系统要求
硬件要求
| 配置类型 | CPU | 内存 | 磁盘 | 网络 |
|---|---|---|---|---|
| 开发环境 | 2核 | 4GB | 50GB | 1Gbps |
| 测试环境 | 4核 | 8GB | 100GB | 1Gbps |
| 生产环境 | 8核+ | 16GB+ | 200GB+ SSD | 10Gbps |
软件要求
| 软件类型 | 版本要求 | 备注 |
|---|---|---|
| 操作系统 | CentOS 7.6+ / Ubuntu 18.04+ / RHEL 7.6+ | 推荐使用LTS版本 |
| 文件系统 | XFS / EXT4 | 推荐使用XFS |
| 数据库版本 | MySQL 8.0+ | 推荐使用官方最新稳定版 |
| 依赖库 | libaio, libnuma, libstdc++ | 安装前需确保已安装 |
安装前准备
1. 操作系统优化
关闭SELinux
bash
# 临时关闭
setenforce 0
# 永久关闭
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config关闭防火墙(可选)
bash
# CentOS/RHEL
systemctl stop firewalld
systemctl disable firewalld
# Ubuntu
systemctl stop ufw
systemctl disable ufw配置内核参数
编辑 /etc/sysctl.conf 文件,添加以下参数:
txt
# MySQL 性能优化
fs.file-max = 65535
fs.aio-max-nr = 1048576
# 网络优化
net.core.netdev_max_backlog = 4096
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_fin_timeout = 30
# 内存管理
vm.swappiness = 1
vm.overcommit_memory = 1
# 关闭透明大页
vm.nr_hugepages = 0应用内核参数:
bash
sysctl -p关闭透明大页
bash
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 永久关闭,添加到/etc/rc.d/rc.local
cat << EOF >> /etc/rc.d/rc.local
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
EOF
chmod +x /etc/rc.d/rc.local配置文件描述符限制
编辑 /etc/security/limits.conf 文件,添加以下内容:
txt
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 655352. 磁盘分区规划
| 挂载点 | 大小 | 文件系统 | 用途 |
|---|---|---|---|
| / | 50GB | XFS | 系统分区 |
| /var/lib/mysql | 100GB+ | XFS | 数据分区 |
| /var/log/mysql | 50GB | XFS | 日志分区 |
| swap | 8GB | - | 交换分区 |
3. 创建MySQL用户和组
bash
# 创建mysql组
groupadd mysql
# 创建mysql用户并加入组
useradd -r -g mysql -s /bin/false mysql安装步骤
1. 下载MySQL安装包
bash
# 下载MySQL 8.0.30 RPM包(CentOS/RHEL)
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
# 安装YUM源
sudo rpm -ivh mysql80-community-release-el7-3.noarch.rpm2. 安装MySQL
CentOS/RHEL
bash
# 安装MySQL服务器
sudo yum install mysql-community-serverUbuntu
bash
# 更新软件包列表
sudo apt update
# 安装MySQL服务器
sudo apt install mysql-server3. 启动MySQL服务
bash
# 启动MySQL服务
sudo systemctl start mysqld
# 设置开机自启
sudo systemctl enable mysqld
# 查看MySQL服务状态
sudo systemctl status mysqld4. 初始化MySQL
获取初始密码
bash
# CentOS/RHEL
sudo grep 'temporary password' /var/log/mysqld.log
# Ubuntu
sudo grep 'password' /var/log/mysql/error.log安全初始化
bash
# 运行安全初始化脚本
mysql_secure_installation按照提示完成以下操作:
- 输入初始密码
- 设置新的root密码
- 删除匿名用户
- 禁止root远程登录
- 删除test数据库
- 刷新权限表
配置优化
1. 基础配置
编辑MySQL配置文件 /etc/my.cnf(CentOS/RHEL)或 /etc/mysql/mysql.conf.d/mysqld.cnf(Ubuntu),添加以下配置:
ini
# 基本配置
[mysqld]
user = mysql
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
pid-file = /var/run/mysqld/mysqld.pid
# 端口配置
port = 3306
# 字符集配置
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 日志配置
log-error = /var/log/mysql/error.log
log-bin = /var/log/mysql/mysql-bin
binlog_format = ROW
expire_logs_days = 7
# 性能配置
max_connections = 2000
max_connect_errors = 10000
open_files_limit = 65535
table_open_cache = 2048
table_definition_cache = 1024
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 4M
join_buffer_size = 4M
# InnoDB配置
innodb_buffer_pool_size = 8G
innodb_buffer_pool_instances = 8
innodb_log_file_size = 2G
innodb_log_buffer_size = 16M
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table = 1
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
innodb_flush_method = O_DIRECT
innodb_large_prefix = ON
innodb_thread_concurrency = 02. GTID配置
ini
# GTID配置
gtid_mode = ON
enforce_gtid_consistency = ON3. 复制配置
ini
# 复制配置
master-info-repository = TABLE
relay-log-info-repository = TABLE
relay-log-recovery = ON
slave-preserve-commit-order = ON
slave-parallel-type = LOGICAL_CLOCK
slave-parallel-workers = 44. 重启MySQL服务
bash
sudo systemctl restart mysqld安全设置
1. 创建普通用户
sql
# 登录MySQL
mysql -u root -p
# 创建普通用户
CREATE USER 'admin'@'%' IDENTIFIED BY 'AdminPass123!';
# 授予权限
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;
# 刷新权限
FLUSH PRIVILEGES;2. 配置防火墙
bash
# 允许MySQL端口
# CentOS/RHEL 7
sudo firewall-cmd --permanent --add-port=3306/tcp
sudo firewall-cmd --reload
# Ubuntu
sudo ufw allow 3306/tcp
sudo ufw reload3. 启用SSL连接
sql
# 登录MySQL
mysql -u root -p
# 生成SSL证书
INSTALL COMPONENT 'file://component_ssl';
# 查看SSL状态
SHOW VARIABLES LIKE '%ssl%';4. 定期备份
创建备份脚本 backup_mysql.sh:
bash
#!/bin/bash
# 备份目录
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
# 创建备份目录
mkdir -p $BACKUP_DIR
# 备份所有数据库
mysqldump -u root -p"password" --all-databases --single-transaction --routines --triggers --events > $BACKUP_DIR/all_databases_$DATE.sql
# 压缩备份文件
gzip $BACKUP_DIR/all_databases_$DATE.sql
# 删除7天前的备份文件
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete添加到crontab:
bash
# 每天凌晨2点执行备份
0 2 * * * /path/to/backup_mysql.sh验证安装
1. 验证MySQL服务状态
bash
sudo systemctl status mysqld2. 验证MySQL版本
bash
mysql --version3. 验证MySQL连接
bash
# 本地连接
mysql -u root -p
# 远程连接
mysql -u admin -p -h 192.168.1.1004. 验证数据库状态
sql
# 登录MySQL后执行
SHOW GLOBAL STATUS LIKE 'Uptime';
SHOW DATABASES;版本差异
MySQL 5.7 vs MySQL 8.0
默认字符集:
- MySQL 5.7:默认字符集为latin1
- MySQL 8.0:默认字符集为utf8mb4
密码验证:
- MySQL 5.7:使用validate_password插件
- MySQL 8.0:使用validate_password组件,增强了密码强度验证
GTID:
- MySQL 5.7:支持GTID,但默认未启用
- MySQL 8.0:默认启用GTID
JSON支持:
- MySQL 5.7:基本JSON支持
- MySQL 8.0:增强的JSON支持,包括JSON路径表达式和JSON聚合函数
窗口函数:
- MySQL 5.7:不支持窗口函数
- MySQL 8.0:支持窗口函数
CTE:
- MySQL 5.7:不支持CTE
- MySQL 8.0:支持CTE
常见问题与解决方案
1. 忘记root密码
解决方案:
bash
# 停止MySQL服务
sudo systemctl stop mysqld
# 以跳过授权表模式启动MySQL
sudo mysqld_safe --skip-grant-tables --skip-networking &
# 登录MySQL
mysql -u root
# 重置密码
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPass123!';
# 退出MySQL
exit
# 停止MySQL安全模式进程
sudo pkill mysqld
# 启动MySQL服务
sudo systemctl start mysqld2. MySQL服务启动失败
解决方案:
bash
# 查看错误日志
# CentOS/RHEL
tail -n 100 /var/log/mysqld.log
# Ubuntu
tail -n 100 /var/log/mysql/error.log根据错误日志提示进行相应的修复,常见问题包括:
- 权限问题:确保MySQL数据目录权限正确
- 配置错误:检查配置文件中的语法错误
- 磁盘空间不足:确保磁盘有足够的空间
3. 无法远程连接MySQL
解决方案:
- 检查防火墙是否开放3306端口
- 检查MySQL用户是否允许远程连接
- 检查MySQL配置是否绑定了正确的IP地址
sql
# 允许用户远程连接
CREATE USER 'user'@'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'user'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;4. 数据库连接数过多
解决方案:
- 增加max_connections参数
- 检查应用程序是否存在连接泄漏
- 考虑使用连接池
ini
# 在my.cnf中增加
max_connections = 2000生产环境最佳实践
1. 硬件选择
- 使用高性能SSD磁盘,提高I/O性能
- 配置足够的内存,建议将70-80%的内存分配给InnoDB缓冲池
- 选择多核CPU,提高并发处理能力
- 使用10Gbps网络,确保数据传输速度
2. 配置管理
- 使用配置管理工具(如Ansible、Puppet)管理MySQL配置
- 定期备份配置文件
- 记录配置变更历史
3. 监控与告警
- 监控MySQL服务状态、连接数、查询性能等指标
- 设置告警规则,当指标超过阈值时及时通知
- 使用专业的监控工具,如Prometheus+Grafana、Zabbix等
4. 定期维护
- 定期优化表结构
- 定期更新统计信息
- 定期检查和修复表
- 定期清理日志和临时文件
5. 安全管理
- 定期更新MySQL版本,修复安全漏洞
- 使用强密码策略
- 限制用户权限,遵循最小权限原则
- 定期进行安全审计
常见问题(FAQ)
Q1: MySQL安装时遇到依赖问题怎么办?
A1: 可以使用以下命令安装缺失的依赖:
bash
# CentOS/RHEL
yum install -y libaio libnuma libstdc++
# Ubuntu
apt install -y libaio1 libnuma1 libstdc++6Q2: 如何修改MySQL数据目录?
A2: 按照以下步骤修改MySQL数据目录:
- 停止MySQL服务
- 复制数据目录到新位置
- 修改配置文件中的datadir参数
- 修改目录权限
- 启动MySQL服务
Q3: 如何查看MySQL当前配置?
A3: 可以使用以下命令查看MySQL当前配置:
sql
# 查看所有配置变量
SHOW VARIABLES;
# 查看特定配置变量
SHOW VARIABLES LIKE 'max_connections';Q4: 如何优化MySQL查询性能?
A4: 可以从以下几个方面优化MySQL查询性能:
- 为查询字段创建合适的索引
- 优化SQL语句,避免全表扫描
- 调整MySQL配置参数
- 考虑使用缓存
- 垂直或水平拆分表
Q5: 如何升级MySQL版本?
A5: 推荐使用滚动升级方式:
- 备份数据
- 安装新版本MySQL
- 测试新版本功能
- 逐步迁移数据
- 切换到新版本
Q6: 如何监控MySQL复制状态?
A6: 可以使用以下命令监控MySQL复制状态:
sql
# 主库查看二进制日志状态
SHOW MASTER STATUS;
# 从库查看复制状态
SHOW SLAVE STATUS\G;
# 查看复制延迟
SHOW GLOBAL STATUS LIKE 'Seconds_Behind_Master';Q7: 如何处理MySQL死锁?
A7: 可以使用以下命令查看和处理死锁:
sql
# 查看当前进程
SHOW PROCESSLIST;
# 查看InnoDB状态,包含死锁信息
SHOW ENGINE INNODB STATUS\G;
# 杀死死锁进程
KILL process_id;Q8: 如何优化InnoDB缓冲池大小?
A8: 建议将InnoDB缓冲池大小设置为系统内存的70-80%:
ini
# 在my.cnf中设置
innodb_buffer_pool_size = 12GQ9: 如何清理MySQL二进制日志?
A9: 可以使用以下命令清理MySQL二进制日志:
sql
# 清理指定日期之前的日志
PURGE BINARY LOGS BEFORE '2023-01-01 00:00:00';
# 只保留最近7天的日志
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);Q10: 如何查看MySQL表大小?
A10: 可以使用以下命令查看MySQL表大小:
sql
SELECT
table_schema AS '数据库',
table_name AS '表名',
ROUND(data_length / 1024 / 1024, 2) AS '数据大小(MB)',
ROUND(index_length / 1024 / 1024, 2) AS '索引大小(MB)',
ROUND((data_length + index_length) / 1024 / 1024, 2) AS '总大小(MB)'
FROM information_schema.TABLES
WHERE table_schema = '数据库名' AND table_name = '表名';