1. MySQL安装部署概述
MySQL作为全球最流行的开源关系型数据库,其安装部署是每个开发者和管理员的必备技能。无论是个人开发环境搭建,还是企业级生产部署,掌握MySQL的正确安装方法都至关重要。根据我多年在不同环境下的部署经验,MySQL的安装过程看似简单,实则暗藏许多影响后续使用的关键细节。
MySQL的安装方式主要分为三种:二进制包安装、源码编译安装和容器化部署。二进制包安装适合绝大多数场景,简单快捷;源码编译安装适合需要深度定制的情况;而容器化部署则更适合云原生环境和快速测试。在本文中,我将重点介绍最常用的二进制包安装方式,同时也会对比不同部署方式的适用场景。
提示:无论选择哪种安装方式,强烈建议使用MySQL 8.0及以上版本,因为5.7版本已在2023年10月结束生命周期,不再接收安全更新。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与依赖检查
2.1 系统环境要求
在开始安装前,必须确保系统环境满足MySQL的基本要求。对于Linux系统(以CentOS 7为例),需要至少2GB内存和5GB磁盘空间。实际生产环境中,建议配置更高的资源:
bash复制# 检查系统资源
free -h
df -h
如果是在Windows系统上安装,需要确保系统是Windows 10或更高版本,并且已安装最新的系统更新。Windows下的安装过程相对简单,主要是通过MySQL Installer完成,本文不做重点介绍。
2.2 依赖包安装
MySQL运行需要一些系统库的支持,在安装前需要确保这些依赖已经就位:
bash复制# CentOS/RHEL系统
sudo yum install -y libaio numactl openssl-devel
# Ubuntu/Debian系统
sudo apt-get install -y libaio1 libnuma1 libssl-dev
我曾经遇到过因为缺少libaio库导致MySQL无法启动的情况,所以特别强调这些依赖的重要性。安装完依赖后,建议重启系统以确保所有变更生效。
2.3 用户和目录准备
出于安全考虑,MySQL应该使用专门的系统用户运行,而不是root用户:
bash复制sudo groupadd mysql
sudo useradd -r -g mysql -s /bin/false mysql
同时,需要规划好MySQL的数据目录和日志目录。默认情况下,MySQL会使用/var/lib/mysql作为数据目录,但在生产环境中,我建议将数据目录放在独立的磁盘分区上:
bash复制sudo mkdir -p /data/mysql
sudo chown -R mysql:mysql /data/mysql
3. MySQL二进制包安装
3.1 下载MySQL社区版
推荐从MySQL官方下载站点获取最新稳定版的二进制包:
bash复制wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.33-linux-glibc2.17-x86_64-minimal.tar.xz
国内用户可能会遇到下载速度慢的问题,可以使用国内镜像源:
bash复制wget https://mirrors.aliyun.com/mysql/Downloads/MySQL-8.0/mysql-8.0.33-linux-glibc2.17-x86_64-minimal.tar.xz
注意:下载完成后务必验证文件的完整性,可以通过MD5或SHA256校验和进行验证。
3.2 解压和安装
将下载的包解压到/usr/local目录,并创建符号链接:
bash复制sudo tar xvf mysql-8.0.33-linux-glibc2.17-x86_64-minimal.tar.xz -C /usr/local
sudo ln -s /usr/local/mysql-8.0.33-linux-glibc2.17-x86_64 /usr/local/mysql
设置环境变量,方便后续操作:
bash复制echo 'export PATH=/usr/local/mysql/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
3.3 初始化MySQL
这是安装过程中最关键的一步,初始化方式在MySQL 5.7和8.0之间有显著区别:
bash复制sudo mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql
初始化完成后,会在日志中显示root用户的临时密码,务必记录下来:
code复制[Note] [MY-010454] [Server] A temporary password is generated for root@localhost: 临时密码
我曾经因为没记录这个临时密码,不得不重新初始化实例,耽误了不少时间。
3.4 配置MySQL服务
创建MySQL的配置文件my.cnf,这是性能调优和安全加固的基础:
bash复制sudo tee /etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql
socket=/tmp/mysql.sock
# 性能相关配置
innodb_buffer_pool_size=1G
innodb_log_file_size=256M
max_connections=200
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
# 安全相关配置
skip-name-resolve
local-infile=0
EOF
创建systemd服务单元文件:
bash复制sudo tee /etc/systemd/system/mysqld.service <<EOF
[Unit]
Description=MySQL Server
After=network.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE=65535
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
启动MySQL服务并设置开机自启:
bash复制sudo systemctl daemon-reload
sudo systemctl start mysqld
sudo systemctl enable mysqld
4. 初始配置与安全加固
4.1 修改root密码
使用初始化时获得的临时密码登录MySQL:
bash复制mysql -uroot -p
然后执行密码修改:
sql复制ALTER USER 'root'@'localhost' IDENTIFIED BY '你的新密码';
重要:生产环境中,密码应该包含大小写字母、数字和特殊字符,且长度不少于16位。
4.2 运行安全脚本
MySQL提供了一个安全配置向导脚本:
bash复制mysql_secure_installation
这个脚本会引导你完成以下安全设置:
- 移除匿名用户
- 禁止root远程登录
- 移除测试数据库
- 重新加载权限表
4.3 创建应用用户
生产环境中不应该使用root用户进行日常操作,应该为每个应用创建单独的用户:
sql复制CREATE USER 'appuser'@'%' IDENTIFIED BY '强密码';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'%';
FLUSH PRIVILEGES;
我曾经遇到过因为使用root用户连接应用导致的安全事故,所以特别强调最小权限原则的重要性。
5. 常见问题与解决方案
5.1 初始化失败问题
问题现象:初始化时出现"InnoDB: Operating system error number 13 in a file operation"
原因分析:通常是SELinux或目录权限问题
解决方案:
bash复制# 临时关闭SELinux
sudo setenforce 0
# 或修改SELinux策略
sudo chcon -R -t mysqld_db_t /data/mysql
5.2 启动失败问题
问题现象:服务启动失败,日志中出现"Can't create/write to file"
原因分析:通常是数据目录权限不正确
解决方案:
bash复制sudo chown -R mysql:mysql /data/mysql
sudo chmod 750 /data/mysql
5.3 连接问题
问题现象:远程客户端无法连接MySQL
原因分析:可能是防火墙或MySQL绑定地址限制
解决方案:
bash复制# 开放3306端口
sudo firewall-cmd --zone=public --add-port=3306/tcp --permanent
sudo firewall-cmd --reload
# 修改MySQL绑定地址
sudo sed -i 's/bind-address.*/bind-address = 0.0.0.0/' /etc/my.cnf
sudo systemctl restart mysqld
6. 性能优化建议
6.1 内存配置
MySQL的性能很大程度上取决于内存配置,特别是InnoDB缓冲池:
ini复制# 建议设置为系统内存的50-70%
innodb_buffer_pool_size = 4G
# 对于写密集型应用,增加日志缓冲区
innodb_log_buffer_size = 64M
6.2 存储配置
对于使用SSD存储的系统,建议启用以下参数:
ini复制innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
innodb_flush_neighbors = 0
6.3 连接管理
避免连接数过多导致系统资源耗尽:
ini复制max_connections = 300
thread_cache_size = 50
wait_timeout = 300
7. 备份与恢复
7.1 使用mysqldump
基本的全量备份命令:
bash复制mysqldump -u root -p --all-databases --single-transaction > full_backup.sql
我曾经因为没加--single-transaction参数导致备份期间锁表,影响了线上业务。
7.2 二进制日志备份
启用二进制日志可以实现时间点恢复:
ini复制[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin
expire_logs_days = 7
7.3 使用Percona XtraBackup
对于大型数据库,物理备份更高效:
bash复制sudo yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
sudo percona-release enable ps-80 release
sudo yum install percona-xtrabackup-80
# 全量备份
xtrabackup --backup --target-dir=/backups/mysql/full
8. 监控与维护
8.1 基本监控命令
sql复制-- 查看连接数
SHOW STATUS LIKE 'Threads_connected';
-- 查看查询缓存命中率
SHOW STATUS LIKE 'Qcache%';
-- 查看InnoDB状态
SHOW ENGINE INNODB STATUS;
8.2 定期维护任务
建议设置以下定期维护任务:
- 每周优化碎片化严重的表
- 每月检查并清理过期的二进制日志
- 每季度审计用户权限
8.3 使用Performance Schema
MySQL 8.0的Performance Schema提供了丰富的监控指标:
sql复制-- 启用所有监控项
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES';
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES';
9. 高可用部署方案
9.1 主从复制配置
基本的主从复制配置步骤:
- 在主服务器上:
sql复制CREATE USER 'repl'@'%' IDENTIFIED BY '密码';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
- 在从服务器上:
sql复制CHANGE MASTER TO
MASTER_HOST='主服务器IP',
MASTER_USER='repl',
MASTER_PASSWORD='密码',
MASTER_AUTO_POSITION=1;
START SLAVE;
9.2 组复制配置
MySQL Group Replication提供了更高可用性的解决方案:
ini复制[mysqld]
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "节点IP:33061"
group_replication_group_seeds= "节点1IP:33061,节点2IP:33061,节点3IP:33061"
group_replication_bootstrap_group=off
9.3 使用MySQL Router
MySQL Router可以实现自动故障转移:
bash复制sudo yum install mysql-router
sudo mysqlrouter --bootstrap root@主服务器IP:3306 --user=mysql
sudo systemctl start mysqlrouter
10. 容器化部署方案
10.1 使用Docker部署
基本Docker运行命令:
bash复制docker run --name mysql -e MYSQL_ROOT_PASSWORD=密码 -p 3306:3306 -v /data/mysql:/var/lib/mysql -d mysql:8.0
10.2 使用Docker Compose
更复杂的多容器部署:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 密码
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
volumes:
mysql_data:
10.3 Kubernetes部署
在K8s中部署MySQL StatefulSet:
yaml复制apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: "密码"
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
11. 版本升级策略
11.1 小版本升级
对于8.0.x系列的小版本升级,通常可以直接替换二进制文件:
bash复制# 停止MySQL服务
sudo systemctl stop mysqld
# 备份数据
sudo cp -r /data/mysql /data/mysql_backup
# 替换新版本
sudo tar xvf mysql-8.0.34-linux-glibc2.17-x86_64-minimal.tar.xz -C /usr/local
sudo rm /usr/local/mysql
sudo ln -s /usr/local/mysql-8.0.34-linux-glibc2.17-x86_64 /usr/local/mysql
# 启动服务
sudo systemctl start mysqld
11.2 大版本升级
从5.7升级到8.0需要更谨慎的步骤:
- 先在测试环境验证升级过程
- 使用mysql_upgrade工具
- 检查所有不兼容的特性变更
我曾经因为直接升级导致应用不兼容,不得不回退版本,所以特别强调测试的重要性。
12. 安全最佳实践
12.1 定期安全审计
建议每季度执行一次安全审计:
sql复制-- 检查空密码账户
SELECT User, Host FROM mysql.user WHERE authentication_string = '';
-- 检查匿名账户
SELECT User, Host FROM mysql.user WHERE User = '';
-- 检查权限过大的账户
SELECT * FROM mysql.user WHERE Super_priv = 'Y';
12.2 加密连接配置
强制使用SSL/TLS加密连接:
ini复制[mysqld]
require_secure_transport=ON
ssl_ca=/path/to/ca.pem
ssl_cert=/path/to/server-cert.pem
ssl_key=/path/to/server-key.pem
12.3 审计日志
启用企业版审计插件或开源的MariaDB审计插件:
ini复制[mysqld]
plugin-load=audit_log.so
audit_log_format=JSON
audit_log_policy=ALL
13. 性能调优实战
13.1 慢查询优化
启用慢查询日志并分析:
ini复制[mysqld]
slow_query_log=1
slow_query_log_file=/var/log/mysql/mysql-slow.log
long_query_time=1
log_queries_not_using_indexes=1
使用pt-query-digest分析慢查询:
bash复制pt-query-digest /var/log/mysql/mysql-slow.log > slow_report.txt
13.2 索引优化
使用EXPLAIN分析查询执行计划:
sql复制EXPLAIN SELECT * FROM users WHERE username = 'test';
添加合适的索引:
sql复制ALTER TABLE users ADD INDEX idx_username (username);
我曾经通过添加一个复合索引,将查询时间从3秒降到了0.01秒。
13.3 配置优化工具
使用MySQLTuner进行配置优化:
bash复制wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl
perl mysqltuner.pl
14. 常见错误处理
14.1 表损坏修复
当表损坏时,可以使用REPAIR TABLE:
sql复制REPAIR TABLE 表名;
对于InnoDB表,通常需要使用强制恢复模式:
ini复制[mysqld]
innodb_force_recovery=6
14.2 主从复制错误
跳过特定复制错误:
sql复制STOP SLAVE;
SET GLOBAL sql_slave_skip_counter=1;
START SLAVE;
14.3 连接池问题
调整连接池配置:
ini复制[mysqld]
thread_cache_size=50
table_open_cache=4000
15. 自动化部署方案
15.1 使用Ansible部署
基本的Ansible playbook示例:
yaml复制- hosts: db_servers
become: yes
tasks:
- name: Install MySQL
yum:
name: mysql-community-server
state: present
- name: Start MySQL service
service:
name: mysqld
state: started
enabled: yes
- name: Change root password
mysql_user:
name: root
password: "新密码"
login_unix_socket: /var/lib/mysql/mysql.sock
15.2 使用Terraform部署
在云环境中自动化部署MySQL:
hcl复制resource "aws_db_instance" "mysql" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "8.0"
instance_class = "db.t2.micro"
name = "mydb"
username = "admin"
password = "强密码"
parameter_group_name = "default.mysql8.0"
skip_final_snapshot = true
}
16. 多实例部署
16.1 单机多实例配置
在同一台服务器上运行多个MySQL实例:
ini复制# /etc/my.cnf
[mysqld@replica01]
datadir=/var/lib/mysql-replica01
socket=/var/lib/mysql-replica01/mysql.sock
port=3307
[mysqld@replica02]
datadir=/var/lib/mysql-replica02
socket=/var/lib/mysql-replica02/mysql.sock
port=3308
启动多实例:
bash复制sudo systemctl start mysqld@replica01
sudo systemctl start mysqld@replica02
16.2 资源隔离
使用cgroups限制每个实例的资源使用:
bash复制sudo yum install libcgroup-tools
sudo cgcreate -g cpu,memory:/mysql_replica01
sudo cgset -r cpu.shares=512 mysql_replica01
sudo cgset -r memory.limit_in_bytes=4G mysql_replica01
17. 备份恢复实战
17.1 时间点恢复
使用二进制日志进行时间点恢复:
bash复制mysqlbinlog --start-datetime="2023-01-01 00:00:00" --stop-datetime="2023-01-01 12:00:00" /var/log/mysql/mysql-bin.000001 | mysql -u root -p
17.2 部分恢复
只恢复特定的数据库:
bash复制mysqldump -u root -p --databases db1 db2 > partial_backup.sql
mysql -u root -p < partial_backup.sql
17.3 大表恢复技巧
对于大表恢复,可以分批导入:
bash复制split -l 10000 large_table.sql large_table_part_
for file in large_table_part_*; do
mysql -u root -p dbname < $file
done
18. 监控告警配置
18.1 Prometheus监控
使用mysqld_exporter采集MySQL指标:
bash复制docker run -d -p 9104:9104 -e DATA_SOURCE_NAME="root:密码@(localhost:3306)/" prom/mysqld-exporter
18.2 Grafana仪表板
导入MySQL监控仪表板(ID:7362):
bash复制curl -X POST -H "Content-Type: application/json" -d '{"dashboard": {"id":7362}, "overwrite": true}' http://admin:admin@grafana:3000/api/dashboards/db
18.3 告警规则配置
示例Prometheus告警规则:
yaml复制groups:
- name: mysql_alerts
rules:
- alert: HighThreadsRunning
expr: mysql_global_status_threads_running > 100
for: 5m
labels:
severity: warning
annotations:
summary: "High number of running threads on {{ $labels.instance }}"
description: "MySQL instance {{ $labels.instance }} has {{ $value }} running threads"
19. 性能测试方法
19.1 使用sysbench
基本测试命令:
bash复制# 准备测试数据
sysbench oltp_read_write --db-driver=mysql --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=密码 --mysql-db=sbtest --tables=10 --table-size=100000 prepare
# 运行测试
sysbench oltp_read_write --db-driver=mysql --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=密码 --mysql-db=sbtest --tables=10 --table-size=100000 --threads=16 --time=300 run
19.2 使用mysqlslap
内置的基准测试工具:
bash复制mysqlslap --user=root --password=密码 --concurrency=50 --iterations=10 --auto-generate-sql --auto-generate-sql-load-type=mixed --auto-generate-sql-add-autoincrement
19.3 测试结果分析
关键指标解读:
- QPS (Queries Per Second):每秒查询数,越高越好
- TPS (Transactions Per Second):每秒事务数
- 延迟:95%和99%百分位延迟
20. 云数据库迁移
20.1 迁移到AWS RDS
使用AWS Database Migration Service:
bash复制aws dms create-replication-task \
--replication-task-identifier "mysql-to-rds" \
--source-endpoint-arn "源端点ARN" \
--target-endpoint-arn "目标端点ARN" \
--replication-instance-arn "复制实例ARN" \
--migration-type "full-load-and-cdc" \
--table-mappings '{"rules":[{"rule-type":"selection","rule-id":"1","rule-name":"1","object-locator":{"schema-name":"%","table-name":"%"},"rule-action":"include"}]}'
20.2 迁移到阿里云RDS
使用DTS数据传输服务:
bash复制# 创建迁移任务
aliyun dts CreateMigrationJob \
--RegionId cn-hangzhou \
--MigrationJobClass small \
--PayType PostPaid \
--SourceEndpoint.EngineName MySQL \
--SourceEndpoint.IP 源IP \
--SourceEndpoint.Port 3306 \
--SourceEndpoint.UserName 用户名 \
--SourceEndpoint.Password 密码 \
--DestinationEndpoint.EngineName MySQL \
--DestinationEndpoint.InstanceID 目标实例ID \
--MigrationMode all
20.3 迁移到Google Cloud SQL
使用Database Migration Service:
bash复制gcloud database-migration migration-jobs create mysql-to-cloudsql \
--source=源连接配置文件 \
--destination=目标连接配置文件 \
--type=ONE_TIME \
--dump-path=gs://bucket/path
21. 数据同步方案
21.1 使用Canal同步到Elasticsearch
Canal配置示例:
properties复制canal.instance.mysql.slaveId=1234
canal.instance.master.address=127.0.0.1:3306
canal.instance.dbUsername=canal
canal.instance.dbPassword=密码
canal.instance.filter.regex=.*\\..*
21.2 使用Debezium同步到Kafka
Debezium MySQL连接器配置:
json复制{
"name": "inventory-connector",
"config": {
"connector.class": "io.debezium.connector.mysql.MySqlConnector",
"database.hostname": "mysql",
"database.port": "3306",
"database.user": "debezium",
"database.password": "密码",
"database.server.id": "184054",
"database.server.name": "dbserver1",
"database.include.list": "inventory",
"database.history.kafka.bootstrap.servers": "kafka:9092",
"database.history.kafka.topic": "schema-changes.inventory"
}
}
21.3 使用Maxwell同步到Redis
Maxwell配置示例:
properties复制producer=redis
redis_host=127.0.0.1
redis_port=6379
redis_database=0
mysql_host=127.0.0.1
mysql_user=maxwell
mysql_password=密码
22. 数据分片方案
22.1 使用MyCAT分片
MyCAT分片配置示例:
xml复制<schema name="testdb" checkSQLschema="false" sqlMaxLimit="100">
<table name="orders" primaryKey="id" dataNode="dn1,dn2" rule="mod-long" />
</schema>
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="localhost:3306" user="root" password="密码"/>
</dataHost>
22.2 使用ShardingSphere分片
ShardingSphere-JDBC配置示例:
yaml复制dataSources:
ds0:
url: jdbc:mysql://localhost:3306/db0
username: root
password: 密码
ds1:
url: jdbc:mysql://localhost:3306/db1
username: root
password: 密码
shardingRule:
tables:
orders:
actualDataNodes: ds$->{0..1}.orders_$->{0..1}
tableStrategy:
inline:
shardingColumn: user_id
algorithmExpression: orders_$->{user_id % 2}
databaseStrategy:
inline:
shardingColumn: order_id
algorithmExpression: ds$->{order_id % 2}
22.3 使用Vitess分片
Vitess分片方案:
bash复制# 创建分片
vtctlclient -server localhost:15999 CreateShard test_keyspace/0
vtctlclient -server localhost:15999 InitShardMaster -force test_keyspace/0 test-100
23. 数据加密方案
23.1 透明数据加密(TDE)
配置InnoDB表空间加密:
ini复制[mysqld]
early-plugin-load=keyring_file.so
keyring_file_data=/var/lib/mysql-keyring/keyring
加密表:
sql复制ALTER TABLE sensitive_data ENCRYPTION='Y';
23.2 列级加密
使用AES_ENCRYPT函数:
sql复制-- 加密
UPDATE users SET ssn = AES_ENCRYPT('123-45-6789', '加密密钥');
-- 解密
SELECT AES_DECRYPT(ssn, '加密密钥') FROM users;
23.3 加密连接
强制使用SSL连接:
sql复制CREATE USER 'secure_user'@'%' REQUIRE SSL;
GRANT ALL PRIVILEGES ON *.* TO 'secure_user'@'%';
24. 审计与合规
24.1 启用审计日志
使用MariaDB审计插件:
ini复制[mysqld]
plugin-load-add=server_audit.so
server_audit_logging=ON
server_audit_events=connect,query
server_audit_file_path=/var/log/mysql/audit.log
24.2 合规检查
使用mysql_upgrade检查:
bash复制mysql_upgrade -u root -p --check-version
24.3 GDPR合规
数据匿名化处理:
sql复制-- 使用伪匿名化
UPDATE customers SET email=CONCAT(LEFT(email, 1), '*****', SUBSTRING_INDEX(email, '@', -1));
25. 灾难恢复方案
25.1 备份策略设计
推荐3-2-1备份策略:
- 3份数据副本
- 2种不同介质
- 1份异地备份
25.2 恢复演练流程
定期执行恢复测试:
- 从备份恢复测试实例
- 验证数据完整性
- 测量恢复时间
25.3 自动化恢复脚本
示例恢复脚本:
bash复制#!/bin/bash
# 停止MySQL
systemctl stop mysqld
# 清理数据目录
rm -rf /var/lib/mysql/*
# 从备份恢复
xtrabackup --copy-back --target-dir=/backups/mysql/full
# 修复权限
chown -R mysql:mysql /var/lib/mysql
# 启动MySQL
systemctl start mysqld
26. 性能监控指标
26.1 关键性能指标
必须监控的核心指标:
- 查询吞吐量 (QPS/TPS)
- 连接使用率
- 缓冲池命中率
- 锁等待时间
26.2 使用Performance Schema
查询性能数据:
sql复制SELECT * FROM performance_schema.events_statements_summary_by_digest
ORDER BY sum_timer_wait DESC LIMIT 10;
26.3 自定义监控
创建自定义监控视图:
sql复制CREATE VIEW db_perf.view_mysql_status AS
SELECT
VARIABLE_NAME,
VARIABLE_VALUE,
NOW() AS collect_time
FROM performance_schema.global_status;
27. 连接池优化
27.1 HikariCP配置
Spring Boot中的HikariCP配置:
properties复制spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.connection-timeout=2000
spring.datasource.hikari.max-lifetime=1800000
27.2 Druid配置
阿里巴巴Druid连接池配置:
properties复制# 初始连接数
druid.initial-size=5
# 最大连接数
druid.max-active=20
# 获取连接等待超时时间
druid.max-wait=60000
# 间隔多久检测空闲连接
druid.time-between-eviction-runs-millis=60000
# 连接最小生存时间
druid.min-evictable-idle-time-millis=300000
27.3 连接泄漏检测
启用连接泄漏检测:
java复制// HikariCP配置
config.setLeakDetectionThreshold(30000);
// Druid配置
druidDataSource.setRemoveAbandoned(true);
druidDataSource.setRemoveAbandonedTimeout(300);
28. 查询优化技巧
28.1 EXPLAIN分析
深入解读EXPLAIN输出:
- type列:从最好到最差依次是 system > const > eq_ref > ref > range > index > ALL
- Extra列:注意Using filesort和Using temporary
28.2 索引优化策略
创建高效索引的原则:
- 为WHERE、JOIN、ORDER BY子句中的列创建索引
- 使用覆盖索引避免回表
- 注意索引选择性
28.3 分页查询优化
低效的分页:
sql复制SELECT * FROM large_table LIMIT 1000000, 10;
优化后的分页:
sql复制SELECT * FROM large_table WHERE id > 1000000 ORDER BY id LIMIT 10;
29. 存储引擎选择
29.1 InnoDB特性
InnoDB的核心特性:
- 支持ACID事务
- 行级锁定
- 外键约束
- 崩溃恢复
29.2 MyISAM适用场景
MyISAM的适用情况:
- 只读或读多写少的应用
- 不需要事务支持
- 全文索引需求
29.3 其他存储引擎
特殊用途引擎:
- MEMORY:临时表、高速缓存
- ARCHIVE:归档存储
- CSV:CSV文件处理
30. 最佳实践总结
经过多年的MySQL部署和维护,我总结了以下黄金法则:
- 规划先行:在安装前规划好数据目录、日志目录和备份策略
- 安全第一:最小权限原则,加密敏感数据,定期审计
- 监控为王:没有监控的系统就像盲人摸象
- 备份重于一切:没有备份的系统不值得运行
- 持续优化:数据库性能会随着数据增长而下降,需要定期优化
最后分享一个实用的小技巧:在my.cnf中添加以下配置可以快速查看当前配置:
ini复制[mysql]
prompt=\\u@\\h [\\d]>\\_
这样连接MySQL时会显示更详细的信息提示符,包括用户名、主机名和当前数据库,对于管理多个数据库实例特别有用。
