2026-04-09 01:28:15 +08:00

1130 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MySQL 实战指南
> 最流行的开源关系型数据库。
---
## 1. 关系型数据库基础
### 1.1 数据库类型
| 类型 | 说明 | 代表产品 |
|------|------|---------|
| 关系型数据库RDBMS | 基于关系模型,表与表之间有关联 | MySQL、PostgreSQL、Oracle |
| 非关系型数据库NoSQL | 非关系模型,文档/键值/列式 | MongoDB、Redis、HBase |
| NewSQL | 分布式关系型数据库 | TiDB、CockroachDB |
### 1.2 关系型数据库核心概念
```
Table→ 行Row→ 记录
→ 列Column→ 字段
→ 主键Primary Key→ 唯一标识
→ 外键Foreign Key→ 表间关联
→ 索引Index→ 加速查询
```
### 1.3 范式
| 范式 | 要求 |
|------|------|
| 1NF | 字段原子性,不可再分 |
| 2NF | 消除部分依赖,非主键字段完全依赖于主键 |
| 3NF | 消除传递依赖,非主键字段不依赖于其他非主键字段 |
### 1.4 SQL 分类
| 分类 | 命令 | 说明 |
|------|------|------|
| DDL | CREATE/ALTER/DROP | 定义数据结构 |
| DML | INSERT/UPDATE/DELETE | 操作数据 |
| DQL | SELECT | 查询数据 |
| DCL | GRANT/REVOKE | 权限控制 |
| TCL | COMMIT/ROLLBACK | 事务控制 |
---
## 2. 安装 MySQL
### 2.1 YUM/RPM 安装CentOS/RHEL
```bash
# 1. 下载 Yum Repository
wget https://repo.mysql.com/mysql80-community-release-el8-4.noarch.rpm
# 2. 安装 Repository
rpm -Uvh mysql80-community-release-el8-4.noarch.rpm
# 3. 安装 MySQL Server
yum install -y mysql-community-server
# 4. 启动服务
systemctl start mysqld
systemctl enable mysqld
# 5. 获取临时密码
grep 'temporary password' /var/log/mysqld.log
# 6. 安全初始化
mysql_secure_installation
```
### 2.2 Dockerfile 安装
```dockerfile
FROM mysql:8.0
ENV MYSQL_ROOT_PASSWORD=your_password
VOLUME /var/lib/mysql
EXPOSE 3306
```
### 2.3 二进制安装
```bash
# 1. 下载二进制包
wget https://downloads.mysql.com/archives/get/mysql-8.0.35-linux-glibc2.17-x86_64.tar.gz
# 2. 解压并创建用户
tar xf mysql-8.0.35-linux-glibc2.17-x86_64.tar.gz -C /usr/local/
ln -s /usr/local/mysql-8.0.35-linux-glibc2.17-x86_64 /usr/local/mysql
useradd -r -s /sbin/nologin mysql
# 3. 初始化
cd /usr/local/mysql
mysqld --initialize-insecure --user=mysql
# 4. 启动
mysqld_safe --user=mysql &
```
### 2.4 常见安装问题
```bash
# 解决依赖
yum install -y libaio numactl
# 解决 SSL 问题
yum update openssl -y
```
---
## 3. 管理数据库和表
### 3.1 数据库操作
```sql
-- 创建数据库
CREATE DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 查看数据库
SHOW DATABASES;
SHOW CREATE DATABASE db_name;
-- 删除数据库
DROP DATABASE db_name;
-- 使用数据库
USE db_name;
```
### 3.2 表操作
```sql
-- 创建表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE,
password VARCHAR(255) NOT NULL,
status TINYINT DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 查看表
SHOW TABLES;
DESC users;
SHOW CREATE TABLE users;
-- 修改表结构
-- 添加列
ALTER TABLE users ADD COLUMN phone VARCHAR(20) AFTER email;
-- 修改列
ALTER TABLE users MODIFY COLUMN name VARCHAR(100);
-- 删除列
ALTER TABLE users DROP COLUMN phone;
-- 重命名表
RENAME TABLE users TO app_users;
-- 删除表
DROP TABLE users;
```
### 3.3 数据操作
```sql
-- 插入数据
INSERT INTO users (name, email, password) VALUES ('张三', 'zhangsan@example.com', 'pass123');
-- 批量插入
INSERT INTO users (name, email, password) VALUES
('李四', 'lisi@example.com', 'pass123'),
('王五', 'wangwu@example.com', 'pass123');
-- 更新数据
UPDATE users SET name = '新名字' WHERE id = 1;
-- 删除数据
DELETE FROM users WHERE id = 1;
-- 条件插入或更新
INSERT INTO users (id, name) VALUES (1, '张三') ON DUPLICATE KEY UPDATE name = '张三';
-- 替换
REPLACE INTO users (id, name) VALUES (1, '张三');
```
### 3.4 查询
```sql
-- 基础查询
SELECT * FROM users;
SELECT id, name FROM users WHERE status = 1;
-- 排序
SELECT * FROM users ORDER BY created_at DESC;
-- 分页
SELECT * FROM users LIMIT 10 OFFSET 20;
-- 聚合
SELECT COUNT(*) FROM users;
SELECT SUM(amount) FROM orders;
SELECT AVG(age) FROM users;
SELECT MAX(score) FROM users;
-- 分组
SELECT status, COUNT(*) FROM users GROUP BY status;
-- HAVING
SELECT status, COUNT(*) as cnt FROM users GROUP BY status HAVING cnt > 10;
-- 多表查询
-- 内连接
SELECT u.name, o.order_no FROM users u INNER JOIN orders o ON u.id = o.user_id;
-- 左连接
SELECT u.name, o.order_no FROM users u LEFT JOIN orders o ON u.id = o.user_id;
-- 子查询
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);
-- 联合查询
SELECT name FROM users WHERE status = 1 UNION ALL SELECT name FROM admins;
```
---
## 4. 用户和权限管理
### 4.1 用户操作
```sql
-- 创建用户
CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
CREATE USER 'username'@'%' IDENTIFIED BY 'password';
-- 查看用户
SELECT user, host FROM mysql.user;
-- 重命名用户
RENAME USER 'old'@'localhost' TO 'new'@'localhost';
-- 删除用户
DROP USER 'username'@'localhost';
```
### 4.2 权限管理
```sql
-- 授予权限
GRANT SELECT, INSERT ON db_name.* TO 'username'@'localhost';
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%';
-- 撤销权限
REVOKE INSERT ON db_name.* FROM 'username'@'localhost';
-- 查看权限
SHOW GRANTS FOR 'username'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;
```
### 4.3 角色管理MySQL 8.0
```sql
-- 创建角色
CREATE ROLE app_read, app_write;
-- 授予角色权限
GRANT SELECT ON db_name.* TO app_read;
GRANT SELECT, INSERT, UPDATE, DELETE ON db_name.* TO app_write;
-- 授予用户角色
GRANT app_read TO 'username'@'localhost';
-- 查看角色
SELECT * FROM mysql.user WHERE account_type = 'role';
```
### 4.4 密码策略MySQL 8.0
```sql
-- 查看密码策略
SHOW VARIABLES LIKE 'validate_password%';
-- 设置密码策略
SET GLOBAL validate_password.policy = 'LOW';
SET GLOBAL validate_password.length = 8;
-- 锁定账户
ALTER USER 'username'@'localhost' ACCOUNT LOCK;
ALTER USER 'username'@'localhost' ACCOUNT UNLOCK;
```
---
## 5. 函数、存储过程、触发器和事件
### 5.1 内置函数
```sql
-- 字符串函数
SELECT CONCAT('Hello', ' ', 'World');
SELECT UPPER(name), LOWER(email);
SELECT SUBSTRING('Hello', 1, 3);
SELECT TRIM(' abc ');
SELECT LPAD('5', 5, '0');
-- 数值函数
SELECT ABS(-5);
SELECT ROUND(3.14159, 2);
SELECT CEIL(3.1), FLOOR(3.9);
SELECT MOD(10, 3);
-- 日期函数
SELECT NOW(), CURDATE(), CURTIME();
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');
SELECT DATE_ADD(NOW(), INTERVAL 1 DAY);
SELECT DATEDIFF('2024-01-01', '2023-01-01');
-- 条件函数
SELECT IF(status = 1, '启用', '禁用');
SELECT CASE status WHEN 1 THEN '启用' ELSE '禁用' END;
SELECT COALESCE(NULL, 'default');
```
### 5.2 自定义函数
```sql
-- 创建函数
DELIMITER //
CREATE FUNCTION get_user_name(uid INT)
RETURNS VARCHAR(100)
DETERMINISTIC
BEGIN
DECLARE result VARCHAR(100);
SELECT name INTO result FROM users WHERE id = uid;
RETURN result;
END //
DELIMITER ;
-- 调用函数
SELECT get_user_name(1);
-- 删除函数
DROP FUNCTION get_user_name;
```
### 5.3 存储过程
```sql
-- 创建存储过程
DELIMITER //
CREATE PROCEDURE get_user_by_id(IN uid INT)
BEGIN
SELECT * FROM users WHERE id = uid;
END //
CREATE PROCEDURE insert_user(IN name VARCHAR(50), IN email VARCHAR(100))
BEGIN
INSERT INTO users (name, email) VALUES (name, email);
SELECT LAST_INSERT_ID() AS user_id;
END //
CREATE PROCEDURE update_users_status()
BEGIN
UPDATE users SET status = 1 WHERE status = 0;
END //
DELIMITER ;
-- 调用
CALL get_user_by_id(1);
-- 查看
SHOW PROCEDURE STATUS;
-- 删除
DROP PROCEDURE update_users_status;
```
### 5.4 触发器
```sql
-- 创建触发器(插入后更新)
DELIMITER //
CREATE TRIGGER after_user_insert
AFTER INSERT ON users FOR EACH ROW
BEGIN
INSERT INTO user_logs (user_id, action) VALUES (NEW.id, 'insert');
END //
-- 删除后记录
CREATE TRIGGER after_user_delete
AFTER DELETE ON users FOR EACH ROW
BEGIN
INSERT INTO user_logs (user_id, action, created_at) VALUES (OLD.id, 'delete', NOW());
END //
-- 更新前记录
CREATE TRIGGER before_user_update
BEFORE UPDATE ON users FOR EACH ROW
BEGIN
SET NEW.updated_at = NOW();
END //
DELIMITER ;
-- 查看
SHOW TRIGGERS;
-- 删除
DROP TRIGGER after_user_insert;
```
### 5.5 事件(定时任务)
```sql
-- 开启事件调度器
SET GLOBAL event_scheduler = ON;
-- 创建事件
DELIMITER //
CREATE EVENT clean_old_logs
ON SCHEDULE EVERY 1 DAY
DO BEGIN
DELETE FROM logs WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
END //
DELIMITER ;
-- 查看
SHOW EVENTS;
SHOW EVENTS FROM db_name;
-- 开启/关闭事件
ALTER EVENT clean_old_logs ENABLE;
ALTER EVENT clean_old_logs DISABLE;
-- 删除
DROP EVENT clean_old_logs;
```
---
## 6. MySQL 架构
### 6.1 架构图
```
┌─────────────────────────────────────────┐
│ 连接层Connection Layer
│ 连接管理器 │ 认证 │ 线程池 │ 连接缓冲 │
└──────────────────┬──────────────────────┘
┌──────────────────▼──────────────────────┐
│ SQL 层SQL Layer
│ 解析器 │ 查询优化器 │ 预处理器 │ 执行器 │
└──────────────────┬──────────────────────┘
┌──────────────────▼──────────────────────┐
│ 存储引擎层Storage Engine
│ InnoDB │ MyISAM │ Memory │ CSV │
└──────────────────┬──────────────────────┘
┌──────────────────▼──────────────────────┐
│ 物理层Physical Layer
│ 数据文件 │ 索引文件 │ 日志文件 │ redo │
└─────────────────────────────────────────┘
```
### 6.2 解析流程
```
SQL 语句
词法分析(分词)→ 语法分析(解析)→ 语义分析(理解)→ 逻辑计划→ 物理执行计划→ 执行
```
### 6.3 缓冲池
| 缓冲池 | 说明 |
|--------|------|
| Buffer Pool | 缓存数据页和索引页 |
| Log Buffer | Redo 日志缓冲 |
| Change Buffer | 变更缓冲(二级索引) |
| Adaptive Hash Index | 自适应哈希索引 |
---
## 7. 存储引擎
### 7.1 引擎对比
| 引擎 | 事务 | 行锁 | 外键 | 全文索引 | 使用场景 |
|------|------|------|------|----------|----------|
| **InnoDB** | 支持 | 支持 | 支持 | 支持 | 默认,事务应用 |
| MyISAM | 不支持 | 表锁 | 不支持 | 支持 | 只读/静态表 |
| Memory | 不支持 | 表锁 | 不支持 | 不支持 | 临时表/缓存 |
| CSV | 不支持 | 表锁 | 不支持 | 不支持 | 数据交换 |
| Archive | 不支持 | 行锁 | 不支持 | 不支持 | 日志/归档 |
| Blackhole | 不支持 | 不支持 | 不支持 | 不支持 | 复制中继 |
### 7.2 InnoDB
```sql
-- 查看表引擎
SHOW CREATE TABLE users;
-- 修改表引擎
ALTER TABLE users ENGINE = InnoDB;
-- 查看 InnoDB 状态
SHOW ENGINE InnoDB STATUS;
-- InnoDB 配置
SHOW VARIABLES LIKE 'innodb_%';
```
### 7.3 表空间
```sql
-- 独立表空间
innodb_file_per_table = 1
-- 查看表空间文件
SHOW VARIABLES LIKE 'innodb_data_file_path';
```
---
## 8. 服务器选项和变量
### 8.1 重要系统变量
```sql
-- 查看
SHOW VARIABLES;
SHOW VARIABLES LIKE 'max_connections';
SHOW GLOBAL VARIABLES;
-- 永久修改(配置文件)
max_connections = 500
-- 临时修改(会话)
SET GLOBAL max_connections = 500;
SET SESSION sort_buffer_size = 256*1024;
```
### 8.2 常用配置
| 变量 | 说明 | 推荐值 |
|------|------|--------|
| max_connections | 最大连接数 | 500-1000 |
| query_cache_size | 查询缓存8.0 已移除) | - |
| innodb_buffer_pool_size | 缓冲池大小 | 70-80% 内存 |
| innodb_log_file_size | 日志文件大小 | 1-2GB |
| max_allowed_packet | 最大包大小 | 64M |
| character_set_server | 默认字符集 | utf8mb4 |
### 8.3 状态变量
```sql
-- 查看
SHOW STATUS;
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Qcache%';
-- 关键状态
Threads_connected -- 当前<E5BD93><E5898D><EFBFBD>接数
Threads_running -- 活跃连接数
Questions -- 总查询数
Slow_queries -- 慢查询数
```
### 8.4 配置文件示例
```ini
[mysqld]
port = 3306
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
user = mysql
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
max_connections = 500
innodb_buffer_pool_size = 2G
innodb_log_file_size = 1G
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
```
---
## 9. 优化查询和索引管理
### 9.1 索引类型
| 类型 | 说明 | 示例 |
|------|------|------|
| 主键索引 | 唯一,非空 | PRIMARY KEY |
| 唯一索引 | 唯一,可空 | UNIQUE |
| 普通索引 | 可重复 | INDEX |
| 全文索引 | 文本搜索 | FULLTEXT |
| 组合索引 | 多列复合 | INDEX(a, b, c) |
### 9.2 索引操作
```sql
-- 创建索引
CREATE INDEX idx_name ON users(name);
CREATE UNIQUE INDEX idx_email ON users(email);
ALTER TABLE users ADD INDEX idx_status_created(status, created_at);
-- 查看索引
SHOW INDEX FROM users;
-- 删除索引
DROP INDEX idx_name ON users;
ALTER TABLE users DROP INDEX idx_email;
```
### 9.3 慢查询分析
```sql
-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
SET GLOBAL long_query_time = 2;
-- 查看慢查询
SELECT * FROM mysql.slow_log ORDER BY start_time DESC;
-- 使用 EXPLAIN
EXPLAIN SELECT * FROM users WHERE name = '张三';
EXPLAIN ANALYZE SELECT * FROM users WHERE name = '张三';
```
### 9.4 查询优化技巧
```sql
-- 避免 SELECT *
SELECT id, name FROM users WHERE name = '张三';
-- 使用 LIMIT
SELECT * FROM users LIMIT 10;
-- 避免函数作用于索引列
-- 低效WHERE YEAR(created_at) = 2024
-- 高效WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01'
-- 使用覆盖索引
SELECT id, name FROM users WHERE name = '张三';
-- 避免隐式转换
-- 低效WHERE phone = 13800138000
-- 高效WHERE phone = '13800138000'
-- 合理使用 UNION
-- 使用 UNION ALL 避免重复检查
SELECT name FROM users WHERE status = 1
UNION ALL
SELECT name FROM admins WHERE status = 1;
```
### 9.5 索引失效场景
- 使用 `!=``<>`、NOT IN
- 使用 `IS NULL``IS NOT NULL`
- 使用函数或运算
- 类型转换
- LIKE 开头使用通配符
- 多列索引不遵循最左前缀
---
## 10. 锁和事务管理
### 10.1 事务特性ACID
| 特性 | 说明 |
|------|------|
| Atomicity原子性 | 事务要么全成功,要么全失败 |
| Consistency一致性 | 事务前后数据库状态一致 |
| Isolation隔离性 | 并发事务互不干扰 |
| Durability持久性 | 事务提交后永久保存 |
### 10.2 事务控制
```sql
-- 开启事务
START TRANSACTION;
BEGIN;
-- 提交
COMMIT;
-- 回滚
ROLLBACK;
-- 设置保存点
SAVEPOINT sp1;
-- 回滚到保存点
ROLLBACK TO SAVEPOINT sp1;
```
### 10.3 隔离级别
| 级别 | 脏读 | 不可重复读 | 幻读 |
|------|------|-----------|------|
| READ UNCOMMITTED | 可能 | 可能 | 可能 |
| READ COMMITTED | 不可能 | 可能 | 可能 |
| REPEATABLE READ | 不可能 | 不可能 | 可能InnoDB 不可能) |
| SERIALIZABLE | 不可能 | 不可能 | 不可能 |
```sql
-- 查看/设置隔离级别
SELECT @@transaction_isolation;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET GLOBAL transaction_isolation = 'READ-COMMITTED';
```
### 10.4 锁
```sql
-- 行锁
SELECT * FROM users WHERE id = 1 FOR UPDATE;
-- 读锁
SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE;
-- 表锁
LOCK TABLES users READ;
LOCK TABLES users WRITE;
UNLOCK TABLES;
-- 查看锁
SHOW ENGINE InnoDB STATUS;
SELECT * FROM information_schema. innodb_lock_waits;
```
### 10.5 死锁
```sql
-- 查看死锁信息
SHOW ENGINE InnoDB STATUS;
-- 避免死锁
-- 1. 按相同顺序操作数据
-- 2. 缩短事务时间
-- 3. 小批量更新
-- 4. 使用低隔离级别
```
---
## 11. 日志管理
### 11.1 日志类型
| 日志 | 说明 | 位置 |
|------|------|------|
| Error Log | 错误日志 | log_error |
| Slow Query Log | 慢查询日志 | slow_query_log_file |
| General Log | 通用查询日志 | general_log_file |
| Binary Log | 二进制日志(复制/恢复) | log_bin |
| Relay Log | 中继日志 | relay_log |
| Redo Log | 重做日志 | innodb_log_file |
### 11.2 二进制日志
```sql
-- 开启
log_bin = /var/log/mysql/mysql-bin
server_id = 1
expire_logs_days = 7
-- 查看
SHOW MASTER STATUS;
SHOW BINLOG EVENTS IN 'mysql-bin.000001';
-- 使用 binlog 恢复
mysqlbinlog mysql-bin.000001 | mysql -u root -p
-- 基于位置恢复
mysqlbinlog --stop-position=1234 mysql-bin.000001 | mysql
-- 基于时间恢复
mysqlbinlog --stop-datetime="2024-01-01 12:00:00" mysql-bin.000001 | mysql
```
### 11.3 慢查询日志
```sql
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
SET GLOBAL long_query_time = 2;
SET GLOBAL log_queries_not_using_indexes = 'ON';
```
### 11.4 通用查询日志
```sql
SET GLOBAL general_log = 'ON';
SET GLOBAL general_log_file = '/var/log/mysql/query.log';
```
---
## 12. 备份还原
### 12.1 逻辑备份mysqldump
```bash
# 备份单个库
mysqldump -u root -p db_name > backup.sql
# 备份所有库
mysqldump -u root -p --all-databases > backup.sql
# 备份指定表
mysqldump -u root -p db_name table1 table2 > backup.sql
# 备份结构(不备份数据)
mysqldump -u root -p -d db_name > structure.sql
# 备份数据(不备份结构)
mysqldump -u root -p -t db_name > data.sql
# 远程备份
mysqldump -h remote_host -u root -p db_name > backup.sql
# 压缩备份
mysqldump -u root -p db_name | gzip > backup.sql.gz
```
### 12.2 逻辑还原
```bash
# 还原
mysql -u root -p db_name < backup.sql
# 压缩还原
gunzip < backup.sql.gz | mysql -u root -p db_name
```
### 12.3 物理备份xtrabackup
```bash
# 安装
yum install percona-xtrabackup
# 全量备份
xtrabackup --backup --target-dir=/backup/full/
# 增量备份
xtrabackup --backup --target-dir=/backup/inc1/ --incremental-basedir=/backup/full/
# 准备还原
xtrabackup --prepare --target-dir=/backup/full/
# 还原
xtrabackup --copy-back --target-dir=/backup/full/
# 停止 MySQL
systemctl stop mysqld
# 删除数据文件
rm -rf /var/lib/mysql/*
# 复制还原
xtrabackup --copy-back --target-dir=/backup/full/
# 修改权限
chown -R mysql:mysql /var/lib/mysql
# 启动
systemctl start mysqld
```
### 12.4 定时备份脚本
```bash
#!/bin/bash
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
mysqldump -u root -p'your_password' --all-databases | gzip > $BACKUP_DIR/mysql_$DATE.sql.gz
find $BACKUP_DIR -mtime +7 -name "*.gz" -delete
```
crontab
```
0 2 * * * /path/to/backup.sh
```
---
## 13. MySQL 集群
### 13.1 主从复制
```
主库Master → 从库Slave
写入 Binary Log → 读取 Relay Log → 重放
```
**主库配置**
```ini
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin
```
**从库配置**
```ini
[mysqld]
server-id = 2
relay_log = /var/log/mysql/mysql-relay-bin
read_only = 1
```
**配置复制**
```sql
-- 主库创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'replpass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
-- 从库配置主库
CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_USER='repl',
MASTER_PASSWORD='replpass',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=1234;
-- 启动复制
START SLAVE;
-- 查看状态
SHOW SLAVE STATUS;
```
### 13.2 主主复制
```
库A ←→ 库B
```
配置双向复制即可,注意自增 ID 冲突:
```ini
auto_increment_increment = 2
auto_increment_offset = 1 # 节点1
auto_increment_offset = 2 # 节点2
```
### 13.3 读写分离ProxySQL
```bash
# 安装
yum install proxysql2
# 配置
SELECT * FROM mysql_servers;
SELECT * FROM mysql_users;
SELECT * FROM mysql_query_rules;
LOAD MYSQL SERVER TO RUNTIME;
LOAD MYSQL USER TO RUNTIME;
```
### 13.4 MySQL Router
```bash
# 安装
yum install mysql-router
# 配置
[logger]
level = INFO
[metadata_cache]
cluster_type = gr
group_replication_group_name = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
metadata_cluster = mycluster
router_uuid = cluster_router
[bind_address]
address = 0.0.0.0
force_primary_connection = true
```
---
## 14. 压力测试
### 14.1 sysbench
```bash
# 安装
yum install sysbench
# 准备测试
sysbench /usr/share/sysbench/oltp_common.lua \
--mysql-host=127.0.0.1 \
--mysql-port=3306 \
--mysql-user=root \
--mysql-password=password \
--mysql-db=test \
--tables=10 \
--table-size=100000 \
prepare
# 运行测试
sysbench /usr/share/sysbench/oltp_read_write.lua \
--mysql-host=127.0.0.1 \
--mysql-port=3306 \
--mysql-user=root \
--mysql-password=password \
--mysql-db=test \
--tables=10 \
--table-size=100000 \
--threads=100 \
--time=60 \
run
# 清理
sysbench /usr/share/sysbench/oltp_common.lua \
--mysql-db=test \
--tables=10 \
cleanup
```
### 14.2 mysqlslap
```bash
# 单轮测试
mysqlslap --create-schema=testdb --query="SELECT * FROM users" --concurrency=50 --iterations=10
# 完整测试
mysqlslap --user=root --password=password \
--create-schema=testdb \
--query="SELECT COUNT(*) FROM orders WHERE created_at > NOW()" \
--concurrency=10,50,100 \
--iterations=5 \
--no-drop
```
### 14.3 tpcc-mysql
```bash
# 安装
wget https://github.com/PerconaLab/tpcc-mysql/archive/refs/heads/master.zip
unzip master.zip
# 编译
cd tpcc-mysql-master/src
make
# 创建表
mysql -u root -p -e "CREATE DATABASE tpcc;"
mysql -u root -p tpcc < create_table.sql
mysql -u root -p tpcc < add_fkeys.sql
# 导入数据
tpcc_load -h localhost -P 3306 -d tpcc -u root -p "" -w 10
# 运行测试
tpcc_start -h localhost -P 3306 -d tpcc -u root -p "" -w 10 -c 10 -r 120 -l 1800
```
### 14.4 测试报告解读
| 指标 | 含义 | 基准 |
|------|------|------|
| TPS | 每秒事务数 | > 1000 |
| QPS | 每秒查询数 | > 5000 |
| 响应时间 | 平均延迟 | < 50ms |
| 95%延迟 | P95 延迟 | < 100ms |
| 连接数 | 并发连接 | 可用连接 80% |
---
## 15. 常用命令速查
### 15.1 连接管理
| 场景 | 命令 |
|------|------|
| 连接本地 | `mysql -u root -p` |
| 连接远程 | `mysql -h host -P 3306 -u root -p` |
| 导入 SQL | `mysql -u root -p db < file.sql` |
| 导出 SQL | `mysqldump -u root -p db > file.sql` |
### 15.2 状态查看
| 场景 | 命令 |
|------|------|
| 查看进程 | `SHOW PROCESSLIST;` |
| 查看状态 | `SHOW STATUS;` |
| 查看变量 | `SHOW VARIABLES;` |
| 查看引擎 | `SHOW ENGINES;` |
| 查看连接 | `SHOW STATUS LIKE 'Threads%';` |
### 15.3 性能分析
| 场景 | 命令 |
|------|------|
| 分析查询 | `EXPLAIN SELECT...` |
| 分析成本 | `EXPLAIN ANALYZE SELECT...` |
| 查看慢查询 | `SELECT * FROM mysql.slow_log;` |
| 查看索引 | `SHOW INDEX FROM table;` |
---
## 16. 小结
| 类别 | 关键点 |
|------|--------|
| 存储引擎 | InnoDB默认事务安全 |
| 字符集 | utf8mb4支持 emoji |
| 隔离级别 | READ COMMITTED |
| 备份 | mysqldump逻辑/xtrabackup物理 |
| 优化 | 索引 + EXPLAIN + 慢查询日志 |
| 集群 | 主从复制/读写分离 |
> 建议:生产环境使用 MySQL 8.0 + InnoDB配置主从复制定期备份。