@gordon.gan/specflow 1.4.0-beta → 1.4.2-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/prompts/approval/database-guidance.md +79 -0
  4. package/prompts/approval/generate.md +600 -290
  5. package/skills/database/LICENSE +405 -0
  6. package/skills/database/ORIGIN.md +6 -0
  7. package/skills/database/README.md +30 -0
  8. package/skills/database/elasticsearch/LICENSE.txt +202 -0
  9. package/skills/database/elasticsearch/SKILL.md +199 -0
  10. package/skills/database/elasticsearch/examples/01-fulltext-search.md +215 -0
  11. package/skills/database/elasticsearch/examples/02-aggregation-report.md +206 -0
  12. package/skills/database/elasticsearch/examples/03-reindex-zero-downtime.md +200 -0
  13. package/skills/database/elasticsearch/examples/04-cluster-monitoring.md +204 -0
  14. package/skills/database/elasticsearch/references/01-query-dsl-fulltext.md +162 -0
  15. package/skills/database/elasticsearch/references/02-query-dsl-term.md +210 -0
  16. package/skills/database/elasticsearch/references/03-aggregations-metric.md +161 -0
  17. package/skills/database/elasticsearch/references/04-aggregations-bucket.md +236 -0
  18. package/skills/database/elasticsearch/references/05-mapping-types.md +134 -0
  19. package/skills/database/elasticsearch/references/06-analyzers.md +187 -0
  20. package/skills/database/elasticsearch/references/07-cluster-ops.md +225 -0
  21. package/skills/database/elasticsearch/references/08-elk-integration.md +170 -0
  22. package/skills/database/mysql/SKILL.md +195 -0
  23. package/skills/database/mysql/examples/01-connection-pool.md +75 -0
  24. package/skills/database/mysql/examples/02-slow-query-optimization.md +98 -0
  25. package/skills/database/mysql/examples/03-master-slave-setup.md +144 -0
  26. package/skills/database/mysql/examples/04-backup-strategy.md +212 -0
  27. package/skills/database/mysql/references/01-functions-string.md +103 -0
  28. package/skills/database/mysql/references/02-functions-date.md +152 -0
  29. package/skills/database/mysql/references/03-functions-aggregate-window.md +167 -0
  30. package/skills/database/mysql/references/04-functions-json.md +129 -0
  31. package/skills/database/mysql/references/05-sql-ddl-types.md +235 -0
  32. package/skills/database/mysql/references/06-index-optimization.md +232 -0
  33. package/skills/database/mysql/references/07-replication-ha.md +213 -0
  34. package/skills/database/mysql/references/08-backup-restore.md +207 -0
  35. package/skills/database/mysql/references/09-advanced-features.md +345 -0
  36. package/skills/database/oracle/LICENSE.txt +202 -0
  37. package/skills/database/oracle/SKILL.md +238 -0
  38. package/skills/database/oracle/examples/01-plsql-procedure.md +90 -0
  39. package/skills/database/oracle/examples/02-awr-analysis.md +99 -0
  40. package/skills/database/oracle/examples/03-rman-backup.md +108 -0
  41. package/skills/database/oracle/examples/04-dataguard-setup.md +146 -0
  42. package/skills/database/oracle/references/01-functions-string.md +91 -0
  43. package/skills/database/oracle/references/02-functions-date.md +71 -0
  44. package/skills/database/oracle/references/03-analytic-functions.md +103 -0
  45. package/skills/database/oracle/references/04-plsql-guide.md +303 -0
  46. package/skills/database/oracle/references/05-performance-tuning.md +164 -0
  47. package/skills/database/oracle/references/06-backup-recovery.md +115 -0
  48. package/skills/database/oracle/references/07-dataguard-rac.md +76 -0
  49. package/skills/database/oracle/references/08-security.md +170 -0
  50. package/skills/database/oracle/references/09-sql-syntax.md +152 -0
  51. package/skills/database/oracle/references/10-features.md +174 -0
  52. package/skills/database/postgresql/LICENSE.txt +202 -0
  53. package/skills/database/postgresql/SKILL.md +182 -0
  54. package/skills/database/postgresql/examples/.gitkeep +0 -0
  55. package/skills/database/postgresql/examples/01-jsonb-query.md +72 -0
  56. package/skills/database/postgresql/examples/02-cte-recursive.md +110 -0
  57. package/skills/database/postgresql/examples/03-performance-tuning.md +114 -0
  58. package/skills/database/postgresql/examples/04-streaming-replication.md +113 -0
  59. package/skills/database/postgresql/references/.gitkeep +0 -0
  60. package/skills/database/postgresql/references/01-functions-string.md +174 -0
  61. package/skills/database/postgresql/references/02-functions-datetime.md +54 -0
  62. package/skills/database/postgresql/references/03-functions-aggregate-window.md +142 -0
  63. package/skills/database/postgresql/references/04-functions-jsonb.md +117 -0
  64. package/skills/database/postgresql/references/05-fulltext-search.md +109 -0
  65. package/skills/database/postgresql/references/06-index-types.md +95 -0
  66. package/skills/database/postgresql/references/07-partition-fdw.md +133 -0
  67. package/skills/database/postgresql/references/08-replication-backup.md +215 -0
  68. package/skills/database/redis/LICENSE.txt +202 -0
  69. package/skills/database/redis/SKILL.md +922 -0
  70. package/skills/database/redis/examples/01-cache-usage.md +104 -0
  71. package/skills/database/redis/examples/02-session-storage.md +72 -0
  72. package/skills/database/redis/examples/03-leaderboard.md +63 -0
  73. package/skills/database/redis/examples/04-redis-cluster-setup.md +70 -0
  74. package/skills/database/redis/examples/05-stream-queue.md +65 -0
  75. package/skills/database/redis/references/command-quick-ref.md +180 -0
  76. package/skills/database/redis/references/commands-admin-key.md +413 -0
  77. package/skills/database/redis/references/commands-set-sorted-advanced.md +539 -0
  78. package/skills/database/redis/references/commands-string-hash-list.md +458 -0
  79. package/skills/database/redis/references/memory-optimization.md +150 -0
  80. package/skills/database/redis/references/redis-conf-production.md +139 -0
  81. package/skills/specflow-approval/SKILL.md +102 -181
  82. package/templates/approval.md +321 -221
@@ -0,0 +1,232 @@
1
+ # 索引与执行计划 (Index & Query Optimization)
2
+
3
+ ## 简介
4
+
5
+ 索引是 MySQL 性能优化的核心手段。正确的索引能大幅减少扫描行数,错误的索引设计则会导致全表扫描和性能灾难。
6
+
7
+ ## 索引类型
8
+
9
+ | 索引类型 | 底层结构 | 版本要求 | 适用场景 |
10
+ |---------|---------|---------|---------|
11
+ | **B-Tree** | B+ 树 | 全版本 | 等值/范围/排序查询(默认) |
12
+ | **Hash** | 哈希表 | MEMORY 引擎 | 等值查询(不支持范围) |
13
+ | **Fulltext** | 倒排索引 | 5.6+ | 全文搜索 (MATCH AGAINST) |
14
+ | **Spatial** | R-Tree | 5.7+ | 空间数据查询 |
15
+ | **Descending** | B+ 树降序 | 8.0+ | 混合排序方向优化 |
16
+ | **Invisible** | 同 B-Tree | 8.0+ | 测试删除影响而不实际删除 |
17
+ | **Functional Key Parts** | 表达式索引 | 8.0.13+ | 函数/表达式索引 |
18
+
19
+ ### B-Tree 索引创建
20
+
21
+ ```sql
22
+ -- 普通索引
23
+ CREATE INDEX idx_name ON user (name);
24
+
25
+ -- 唯一索引
26
+ CREATE UNIQUE INDEX uk_email ON user (email);
27
+
28
+ -- 复合索引(最左前缀原则)
29
+ CREATE INDEX idx_city_age ON user (city, age);
30
+
31
+ -- 前缀索引(字符串前 N 字符)
32
+ CREATE INDEX idx_email_prefix ON user (email(10));
33
+
34
+ -- 全文索引
35
+ CREATE FULLTEXT INDEX ftx_content ON article (title, content);
36
+
37
+ -- 降序索引 (MySQL 8.0+)
38
+ CREATE INDEX idx_created_desc ON `order` (created_at DESC);
39
+
40
+ -- 不可见索引(测试用)
41
+ CREATE INDEX idx_test ON user (name) INVISIBLE;
42
+ ALTER TABLE user ALTER INDEX idx_test VISIBLE;
43
+
44
+ -- 函数索引 (MySQL 8.0.13+)
45
+ CREATE INDEX idx_phone_last4 ON user ((RIGHT(phone, 4)));
46
+ ```
47
+
48
+ ## 复合索引最左前缀原则
49
+
50
+ 复合索引 `idx_a_b_c (a, b, c)`:
51
+
52
+ | 查询条件 | 索引使用情况 |
53
+ |---------|-------------|
54
+ | `WHERE a = 1` | ✅ 使用 a |
55
+ | `WHERE a = 1 AND b = 2` | ✅ 使用 a, b |
56
+ | `WHERE a = 1 AND b = 2 AND c = 3` | ✅ 使用 a, b, c |
57
+ | `WHERE a = 1 ORDER BY b` | ✅ 使用 a(排序) |
58
+ | `WHERE a = 1 AND c = 3` | ✅ 使用 a(c 只能过滤) |
59
+ | `WHERE a IN (1, 2) AND b = 3` | ✅ 使用 a, b |
60
+ | `WHERE b = 2` | ❌ 跳过了 a |
61
+ | `WHERE c = 3` | ❌ 跳过了 a, b |
62
+
63
+ ### 索引设计原则
64
+
65
+ 1. **区分度高的列放前面**:选择性 = `COUNT(DISTINCT col) / COUNT(*)`
66
+ 2. **等值条件列放前面**:`=` 比范围查询列放前面
67
+ 3. **覆盖索引**:查询列全在索引中(Extra 显示 `Using index`),避免回表
68
+ 4. **索引下推 (ICP)**:MySQL 5.6+,引擎层用 WHERE 条件过滤索引记录后再回表
69
+
70
+ ## EXPLAIN 执行计划分析
71
+
72
+ ### 使用 EXPLAIN
73
+
74
+ ```sql
75
+ EXPLAIN SELECT u.name, o.order_no
76
+ FROM user u
77
+ JOIN `order` o ON u.id = o.user_id
78
+ WHERE u.id = 100;
79
+ ```
80
+
81
+ ### EXPLAIN 输出列
82
+
83
+ | 列名 | 含义 | 关键值 |
84
+ |------|------|--------|
85
+ | `id` | SELECT 标识符,id 越大越先执行 | |
86
+ | `select_type` | 查询类型 | SIMPLE, PRIMARY, SUBQUERY, DERIVED, UNION |
87
+ | `table` | 表名 | |
88
+ | `partitions` | 扫描的分区 | |
89
+ | `type` | 访问类型(性能排序) | system > const > eq_ref > ref > range > index > **ALL** |
90
+ | `possible_keys` | 可能使用的索引 | |
91
+ | `key` | 实际使用的索引 | |
92
+ | `key_len` | 使用的索引字节长度 | 越大越好(匹配更多列) |
93
+ | `ref` | 索引匹配的列或常量 | |
94
+ | `rows` | 预估扫描行数 | 越小越好 |
95
+ | `filtered` | 过滤后百分比 | |
96
+ | `Extra` | 额外信息 | **🔑 重要** |
97
+
98
+ ### type 访问类型(从优到劣)
99
+
100
+ | type | 说明 | 示例 |
101
+ |------|------|------|
102
+ | **system** | 表只有一行 | 最好 |
103
+ | **const** | 主键/唯一索引等值查询 | `WHERE id = 1` |
104
+ | **eq_ref** | JOIN 主键/唯一索引关联 | `ON u.id = o.user_id` |
105
+ | **ref** | 普通索引等值查询 | `WHERE name = '张三'` |
106
+ | **range** | 索引范围扫描 | `WHERE id > 100`, `LIKE '张%'` |
107
+ | **index** | 全索引扫描 | 不推荐 |
108
+ | **ALL** | 全表扫描 | **❌ 最差** |
109
+
110
+ ### Extra 关键信息
111
+
112
+ | Extra 值 | 含义 |
113
+ |----------|------|
114
+ | **Using index** | 覆盖索引(无需回表)✅ 最佳 |
115
+ | **Using where** | 用 WHERE 过滤 |
116
+ | **Using index condition** | 索引下推 ICP ✅ |
117
+ | **Using temporary** | 使用临时表(需优化)❌ |
118
+ | **Using filesort** | 文件排序(需优化)❌ |
119
+ | **Using join buffer** | JOIN 未用索引 ❌ |
120
+ | **Using MRR** | 多范围读取优化 ✅ |
121
+
122
+ ### EXPLAIN ANALYZE (MySQL 8.0.18+)
123
+
124
+ ```sql
125
+ -- 实际执行并显示各步骤耗时和行数
126
+ EXPLAIN ANALYZE
127
+ SELECT u.name, COUNT(o.id) AS order_count
128
+ FROM user u
129
+ LEFT JOIN `order` o ON u.id = o.user_id
130
+ GROUP BY u.id
131
+ ORDER BY order_count DESC
132
+ LIMIT 10;
133
+ ```
134
+
135
+ ## SQL 优化原则
136
+
137
+ ```
138
+ ★ 核心原则:减少扫描行数,减少回表,减少排序
139
+
140
+ 1. WHERE 条件列建索引(符合最左前缀)
141
+ 2. 避免 SELECT *,仅取需要的列(利用覆盖索引)
142
+ 3. 用 EXISTS 代替 IN(大数据量下)
143
+ 4. 用 UNION ALL 代替 UNION(不需要去重时)
144
+ 5. 用 LIMIT 限制结果集大小
145
+ 6. 大表分页用游标(WHERE id > last_id)而非 OFFSET
146
+ 7. JOIN 的关联列必须有索引
147
+ 8. GROUP BY / ORDER BY 的列尽量利用索引
148
+ 9. 避免在 WHERE 条件列上使用函数或计算
149
+ 10. 拆分大查询为多次小查询(减少锁范围)
150
+ ```
151
+
152
+ ## 常见优化案例
153
+
154
+ ### 隐式类型转换(索引失效)
155
+
156
+ ```sql
157
+ -- ❌ phone 是 VARCHAR,传 INT 导致全表扫描
158
+ SELECT * FROM user WHERE phone = 13800138000;
159
+
160
+ -- ✅ 字符类型就传字符串
161
+ SELECT * FROM user WHERE phone = '13800138000';
162
+ ```
163
+
164
+ ### WHERE 条件函数操作(索引失效)
165
+
166
+ ```sql
167
+ -- ❌ DATE() 函数使索引失效
168
+ SELECT * FROM `order` WHERE DATE(created_at) = '2024-01-01';
169
+
170
+ -- ✅ 范围查询可用索引
171
+ SELECT * FROM `order` WHERE created_at >= '2024-01-01' AND created_at < '2024-01-02';
172
+ ```
173
+
174
+ ### 大分页优化
175
+
176
+ ```sql
177
+ -- ❌ OFFSET 越大越慢(先扫描再丢弃)
178
+ SELECT * FROM `order` ORDER BY id LIMIT 100000, 20;
179
+
180
+ -- ✅ 游标分页
181
+ SELECT * FROM `order` WHERE id > 100000 ORDER BY id LIMIT 20;
182
+
183
+ -- ✅ 子查询 + JOIN 方式
184
+ SELECT * FROM `order`
185
+ JOIN (SELECT id FROM `order` ORDER BY id LIMIT 100000, 20) AS tmp
186
+ ON `order`.id = tmp.id;
187
+ ```
188
+
189
+ ### OR 改为 UNION
190
+
191
+ ```sql
192
+ -- ❌ OR 可能用不到复合索引
193
+ SELECT * FROM user WHERE name = '张三' OR email = 'zhangsan@example.com';
194
+
195
+ -- ✅ UNION 分别用各自索引
196
+ SELECT * FROM user WHERE name = '张三'
197
+ UNION
198
+ SELECT * FROM user WHERE email = 'zhangsan@example.com';
199
+ ```
200
+
201
+ ## 慢查询配置
202
+
203
+ ```ini
204
+ # my.cnf
205
+ slow_query_log = ON # 开启慢查询
206
+ slow_query_log_file = /var/log/mysql/slow.log # 慢查询日志文件
207
+ long_query_time = 1 # 超过 1 秒的查询记录
208
+ log_queries_not_using_indexes = ON # 记录未使用索引的查询
209
+ min_examined_row_limit = 100 # 扫描行数超过此值才记录
210
+ ```
211
+
212
+ ### 分析慢查询
213
+
214
+ ```bash
215
+ # mysqldumpslow 排序取前10
216
+ mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
217
+
218
+ # Percona Toolkit 分析
219
+ pt-query-digest /var/log/mysql/slow.log
220
+ ```
221
+
222
+ ## 索引设计规范
223
+
224
+ 1. 每个表必须有主键(推荐 BIGINT AUTO_INCREMENT 或有序 UUID)
225
+ 2. 主键不宜过长(B+ 树二级索引过大)
226
+ 3. 每个表索引数不超过 5-8 个(过多影响写入性能)
227
+ 4. 大表(> 1000 万行)索引必须业务验证后创建
228
+ 5. 字符串区分度低或长度大时用前缀索引
229
+ 6. ORDER BY / GROUP BY / JOIN 的列考虑建索引
230
+ 7. 不建索引的列:频繁更新、区分度极低(如性别)
231
+ 8. 用 INVISIBLE 索引测试后再删除
232
+ 9. 避免冗余索引(如 idx_a_b 和 idx_a 重复)
@@ -0,0 +1,213 @@
1
+ # 主从复制与高可用 (Replication & High Availability)
2
+
3
+ ## 简介
4
+
5
+ MySQL 主从复制是生产环境中最常用的高可用和读写分离方案。主库(Master)记录二进制日志(Binlog),从库(Slave)通过网络读取并回放日志,实现数据同步。
6
+
7
+ ## 复制原理
8
+
9
+ ```
10
+ ┌─────────────┐ ┌─────────────┐
11
+ │ Master │ │ Slave │
12
+ ├─────────────┤ ├─────────────┤
13
+ │ Binlog │─────→ │ Relay Log │
14
+ │ (二进制日志) │ IO线程 │ (中继日志) │
15
+ └─────────────┘ └──────┬──────┘
16
+ │ SQL线程
17
+
18
+ ┌─────────────┐
19
+ │ Slave Data │
20
+ └─────────────┘
21
+ ```
22
+
23
+ **复制流程**:
24
+ 1. Master 提交事务时写入 Binlog
25
+ 2. Slave 的 IO 线程读取 Master 的 Binlog,写入 Relay Log
26
+ 3. Slave 的 SQL 线程回放 Relay Log,应用到自身数据
27
+
28
+ ## 主从同步配置
29
+
30
+ ### Master 配置
31
+
32
+ ```ini
33
+ # my.cnf
34
+ server-id = 1
35
+ log_bin = /var/log/mysql/mysql-bin
36
+ binlog_format = ROW # ROW 格式最安全(推荐)
37
+ binlog_expire_logs_seconds = 604800 # 保留 7 天
38
+ sync_binlog = 1 # 每次事务提交同步(最安全)
39
+ ```
40
+
41
+ ```sql
42
+ -- 创建复制用户
43
+ CREATE USER 'replicator'@'%' IDENTIFIED BY 'password';
44
+ GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';
45
+ FLUSH PRIVILEGES;
46
+
47
+ -- 查看 Master 状态
48
+ SHOW MASTER STATUS;
49
+ -- File: mysql-bin.000001, Position: 1234
50
+ ```
51
+
52
+ ### Slave 配置
53
+
54
+ ```ini
55
+ # my.cnf
56
+ server-id = 2
57
+ relay_log = /var/log/mysql/mysql-relay-bin
58
+ read_only = 1 # 只读(防止误写)
59
+ ```
60
+
61
+ ```sql
62
+ -- 设置主节点
63
+ CHANGE MASTER TO
64
+ MASTER_HOST = '192.168.1.100',
65
+ MASTER_PORT = 3306,
66
+ MASTER_USER = 'replicator',
67
+ MASTER_PASSWORD = 'password',
68
+ MASTER_LOG_FILE = 'mysql-bin.000001',
69
+ MASTER_LOG_POS = 1234;
70
+
71
+ -- 启动复制
72
+ START SLAVE;
73
+
74
+ -- 查看复制状态(关键字段)
75
+ SHOW SLAVE STATUS\G
76
+ -- Slave_IO_Running: Yes -- IO 线程正常
77
+ -- Slave_SQL_Running: Yes -- SQL 线程正常
78
+ -- Seconds_Behind_Master: 0 -- 延迟秒数(0 最佳)
79
+
80
+ -- 停止复制
81
+ STOP SLAVE;
82
+
83
+ -- 重置复制
84
+ RESET SLAVE ALL;
85
+ ```
86
+
87
+ ### 复制状态监控关键字段
88
+
89
+ | 字段 | 说明 | 正常值 |
90
+ |------|------|--------|
91
+ | `Slave_IO_Running` | IO 线程状态 | Yes |
92
+ | `Slave_SQL_Running` | SQL 线程状态 | Yes |
93
+ | `Seconds_Behind_Master` | 延迟秒数 | 0(或很小) |
94
+ | `Last_IO_Error` | IO 线程错误 | 空 |
95
+ | `Last_SQL_Error` | SQL 线程错误 | 空 |
96
+ | `Relay_Log_Space` | Relay Log 大小 | 稳定值 |
97
+ | `Exec_Master_Log_Pos` | 已执行位置 | 持续增长 |
98
+
99
+ ## 复制模式对比
100
+
101
+ | 模式 | 说明 | 一致性 | 性能 | 推荐度 |
102
+ |------|------|--------|------|--------|
103
+ | **异步 (ASYNC)** | Master 不等待 Slave 确认 | 最终一致性 | 最高 | 默认 |
104
+ | **半同步 (SEMISYNC)** | 至少一个 Slave 写入 Relay Log | 较高 | 略微降低 | ★★★★★ |
105
+ | **全同步 (Group Replication)** | 多数节点确认 | 强一致性 | 最低 | 特定场景 |
106
+
107
+ ### 半同步复制配置
108
+
109
+ ```sql
110
+ -- Master 和 Slave 都安装插件
111
+ INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
112
+ INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
113
+
114
+ -- Master 启用
115
+ SET GLOBAL rpl_semi_sync_master_enabled = 1;
116
+ SET GLOBAL rpl_semi_sync_master_timeout = 1000; -- 1s 超时降级为异步
117
+
118
+ -- Slave 启用
119
+ SET GLOBAL rpl_semi_sync_slave_enabled = 1;
120
+ ```
121
+
122
+ ## 复制延迟处理
123
+
124
+ ### 常见延迟原因
125
+
126
+ 1. Slave 硬件弱于 Master
127
+ 2. 大事务(一次 DELETE/UPDATE 百万行)
128
+ 3. Slave 上存在慢查询锁竞争
129
+ 4. 单线程 SQL 回放(MySQL 5.6+ 可开启并行复制)
130
+
131
+ ### 并行复制配置 (MySQL 5.7+)
132
+
133
+ ```ini
134
+ # my.cnf
135
+ slave_parallel_workers = 4
136
+ slave_parallel_type = LOGICAL_CLOCK
137
+ ```
138
+
139
+ ### 应用层处理延迟
140
+
141
+ ```sql
142
+ -- 关键读走主库(如支付成功后的订单查询)
143
+ -- 普通读走从库(容忍秒级延迟)
144
+
145
+ -- 判断延迟:如果从库读不到数据,降级读主库
146
+ ```
147
+
148
+ ## 高可用方案
149
+
150
+ | 方案 | 原理 | 优点 | 缺点 | 推荐场景 |
151
+ |------|------|------|------|---------|
152
+ | **主从 + 手动切换** | 手动执行 CHANGE MASTER | 简单 | 切换时间 10min+ | 非关键业务 |
153
+ | **MHA** | 自动检测 Master 故障切换 | 成熟稳定 | 需独立管理节点 | 经典方案 |
154
+ | **Orchestrator** | 自动故障检测/拓扑管理 | 自动修复 | 复杂度中等 | **推荐方案** |
155
+ | **InnoDB Cluster** | Group Replication + MySQL Router | 原生方案 | 需 8.0+ | MySQL 官方方案 |
156
+ | **ProxySQL + 读写分离** | 中间层路由 | 灵活路由 | 引入代理层 | 配合复制使用 |
157
+
158
+ ### Orchestrator 工作流程
159
+
160
+ ```
161
+ 1. 检测 Master 故障(心跳超时)
162
+ 2. 选择最优 Slave(延迟最小、数据最新)
163
+ 3. 自动提升为新 Master
164
+ 4. 重新配置其他 Slave 指向新 Master
165
+ 5. 通知应用层新 Master 地址(通过 API / Consul)
166
+ ```
167
+
168
+ ## 读写分离架构
169
+
170
+ ### 应用层实现
171
+
172
+ ```text
173
+ // 伪代码
174
+ if (sql.startsWith("SELECT")) {
175
+ connection = slavePool.getConnection();
176
+ } else {
177
+ connection = masterPool.getConnection();
178
+ }
179
+ ```
180
+
181
+ ### ProxySQL 实现
182
+
183
+ ```sql
184
+ -- ProxySQL 配置读写分离组
185
+ INSERT INTO mysql_replication_hostgroups
186
+ (writer_hostgroup, reader_hostgroup, comment)
187
+ VALUES (10, 20, '读写分离');
188
+
189
+ -- SELECT 自动路由到从节点(reader_hostgroup=20)
190
+ -- DML 自动路由到主节点(writer_hostgroup=10)
191
+ ```
192
+
193
+ ## 分库分表 (Sharding)
194
+
195
+ ### 何时需要分库分表
196
+
197
+ 单表 > 5000 万行或单实例 > 2TB 且预期继续增长。
198
+
199
+ ### 方案选择
200
+
201
+ | 方案 | 类型 | 说明 |
202
+ |------|------|------|
203
+ | ShardingSphere | 中间件 + 客户端 | Java 生态首选 |
204
+ | MyCAT | 数据库中间件 | 传统方案 |
205
+ | Vitess | 分布式方案 | YouTube 开源 |
206
+ | TiDB | 原生分布式 | 彻底解决但需切换数据库 |
207
+
208
+ ### 分库分表注意事项
209
+
210
+ 1. **分片键选择**:`user_id % shard_count` 或 `order_id % shard_count`
211
+ 2. **跨分片查询**:全局表、广播表、ER 分片
212
+ 3. **分布式 ID**:雪花算法、Leaf、Segment
213
+ 4. **分布式事务**:XA / TCC / Saga / Seata
@@ -0,0 +1,207 @@
1
+ # 备份与恢复 (Backup & Restore)
2
+
3
+ ## 简介
4
+
5
+ MySQL 备份分为逻辑备份(mysqldump)和物理备份(XtraBackup)。逻辑备份导出 SQL 语句,适合小规模和迁移场景;物理备份直接复制数据文件,适合大数据库的快速恢复。
6
+
7
+ ## mysqldump — 逻辑备份
8
+
9
+ ### 基本用法
10
+
11
+ ```bash
12
+ # 备份单个数据库(推荐使用 --single-transaction 避免锁表)
13
+ mysqldump -u root -p --single-transaction --routines --triggers --events shop > shop_backup.sql
14
+
15
+ # 备份所有数据库
16
+ mysqldump -u root -p --all-databases --single-transaction > all_db_backup.sql
17
+
18
+ # 只备份表结构
19
+ mysqldump -u root -p --no-data shop > shop_schema.sql
20
+
21
+ # 只备份数据
22
+ mysqldump -u root -p --no-create-info shop > shop_data.sql
23
+
24
+ # 压缩备份
25
+ mysqldump -u root -p shop | gzip > shop_backup.sql.gz
26
+
27
+ # 备份特定表
28
+ mysqldump -u root -p shop user order product > critical_tables.sql
29
+
30
+ # 备份到远程服务器
31
+ mysqldump -u root -p shop | ssh user@backup-server "cat > /backups/shop.sql"
32
+ ```
33
+
34
+ ### 关键参数说明
35
+
36
+ | 参数 | 说明 | 推荐 |
37
+ |------|------|------|
38
+ | `--single-transaction` | InnoDB 事务一致性备份,不锁表 | **必选**(InnoDB) |
39
+ | `--lock-tables` | MyISAM 表锁 | 仅 MyISAM 时需要 |
40
+ | `--routines` | 备份存储过程和函数 | ✅ 推荐 |
41
+ | `--triggers` | 备份触发器 | ✅ 推荐 |
42
+ | `--events` | 备份事件调度器 | ✅ 推荐 |
43
+ | `--quick` | 逐行导出(防止大表内存溢出) | ✅ 大表推荐 |
44
+ | `--opt` | 快速导出(默认开启) | 默认 |
45
+
46
+ ### 恢复
47
+
48
+ ```bash
49
+ # 基本恢复
50
+ mysql -u root -p shop < shop_backup.sql
51
+
52
+ # 恢复压缩备份
53
+ gunzip < shop_backup.sql.gz | mysql -u root -p shop
54
+
55
+ # 恢复多个数据库
56
+ mysql -u root -p < all_db_backup.sql
57
+ ```
58
+
59
+ ## XtraBackup — 物理备份
60
+
61
+ Percona XtraBackup 是 MySQL 物理备份的事实标准,支持热备份 InnoDB 表而不影响读写。
62
+
63
+ ### 安装
64
+
65
+ ```bash
66
+ # macOS
67
+ brew install percona-xtrabackup
68
+
69
+ # Ubuntu
70
+ apt install percona-xtrabackup-80
71
+
72
+ # CentOS
73
+ yum install percona-xtrabackup-80
74
+ ```
75
+
76
+ ### 全量备份与恢复
77
+
78
+ ```bash
79
+ # 全量备份
80
+ xtrabackup --backup --target-dir=/data/backup/full/ --user=root --password=xxx
81
+
82
+ # 准备恢复(应用 redo log,使数据一致)
83
+ xtrabackup --prepare --target-dir=/data/backup/full/
84
+
85
+ # 恢复到 MySQL 数据目录
86
+ xtrabackup --copy-back --target-dir=/data/backup/full/
87
+ # 或手动复制
88
+ rsync -avrP /data/backup/full/ /var/lib/mysql/
89
+ chown -R mysql:mysql /var/lib/mysql/
90
+ ```
91
+
92
+ ### 增量备份与恢复
93
+
94
+ ```bash
95
+ # 全量备份(基础)
96
+ xtrabackup --backup --target-dir=/data/backup/full/
97
+
98
+ # 增量备份(基于全量)
99
+ xtrabackup --backup --target-dir=/data/backup/inc1/ \
100
+ --incremental-basedir=/data/backup/full/
101
+
102
+ # 第二个增量备份(基于前一个增量)
103
+ xtrabackup --backup --target-dir=/data/backup/inc2/ \
104
+ --incremental-basedir=/data/backup/inc1/
105
+
106
+ # 增量恢复流程
107
+ # 1. 准备全量(应用 log 但不回滚未提交事务)
108
+ xtrabackup --prepare --apply-log-only --target-dir=/data/backup/full/
109
+
110
+ # 2. 合并增量 1
111
+ xtrabackup --prepare --apply-log-only --target-dir=/data/backup/full/ \
112
+ --incremental-dir=/data/backup/inc1/
113
+
114
+ # 3. 合并增量 2(最后一次不用 --apply-log-only)
115
+ xtrabackup --prepare --target-dir=/data/backup/full/ \
116
+ --incremental-dir=/data/backup/inc2/
117
+
118
+ # 4. copy-back 恢复
119
+ xtrabackup --copy-back --target-dir=/data/backup/full/
120
+ ```
121
+
122
+ ## 二进制日志与 PITR(时间点恢复)
123
+
124
+ PITR(Point-In-Time Recovery)允许恢复到某个精确的时间点,是应对误操作(DROP TABLE、DELETE 全表)的核心手段。
125
+
126
+ ### 启用二进制日志
127
+
128
+ ```ini
129
+ # my.cnf
130
+ log_bin = /var/log/mysql/mysql-bin
131
+ binlog_format = ROW # ROW 格式最安全
132
+ binlog_expire_logs_seconds = 604800 # 保留 7 天
133
+ ```
134
+
135
+ ### 查看二进制日志
136
+
137
+ ```sql
138
+ -- 查看 Binlog 是否开启
139
+ SHOW VARIABLES LIKE 'log_bin';
140
+
141
+ -- 列出所有 Binlog 文件
142
+ SHOW BINARY LOGS;
143
+
144
+ -- 查看 Binlog 事件
145
+ SHOW BINLOG EVENTS IN 'mysql-bin.000001' LIMIT 10;
146
+
147
+ -- 查看当前 Binlog 位置
148
+ SHOW MASTER STATUS;
149
+ ```
150
+
151
+ ### PITR 恢复流程
152
+
153
+ ```bash
154
+ # Step 1: 恢复最近的完整备份
155
+ mysql -u root -p shop < shop_backup.sql
156
+
157
+ # Step 2: 回放二进制日志到指定时间点
158
+ mysqlbinlog --stop-datetime="2024-01-15 10:00:00" \
159
+ /var/log/mysql/mysql-bin.* | mysql -u root -p
160
+
161
+ # 指定位置恢复
162
+ mysqlbinlog --stop-position=12345 \
163
+ /var/log/mysql/mysql-bin.000001 | mysql -u root -p
164
+
165
+ # 指定开始和结束范围
166
+ mysqlbinlog \
167
+ --start-datetime="2024-01-15 09:00:00" \
168
+ --stop-datetime="2024-01-15 10:00:00" \
169
+ /var/log/mysql/mysql-bin.000001 \
170
+ /var/log/mysql/mysql-bin.000002 \
171
+ | mysql -u root -p shop
172
+ ```
173
+
174
+ ## 备份策略推荐
175
+
176
+ ### 生产环境备份策略
177
+
178
+ ```
179
+ ┌──────────────────────────────────────────────┐
180
+ │ 生产环境备份策略: │
181
+ │ │
182
+ │ 每日凌晨 2:00: 全量备份 (XtraBackup 物理备份) │
183
+ │ 每 6 小时: 增量备份 (XtraBackup 增量) │
184
+ │ 实时: 二进制日志持续归档 (BINLOG) │
185
+ │ 保留周期: 最近 7 天全量 + 30 天增量 │
186
+ │ 异地备份: 备份文件同步到对象存储 (OSS/S3) │
187
+ │ 定期演练: 每月一次恢复测试 │
188
+ └──────────────────────────────────────────────┘
189
+ ```
190
+
191
+ ### 备份检查清单
192
+
193
+ - [ ] 全量备份是否成功(检查 `xtrabackup` 退出码)
194
+ - [ ] 备份文件大小是否合理(过大/过小要排查)
195
+ - [ ] 异地备份是否同步完成
196
+ - [ ] 二进制日志是否连续不中断
197
+ - [ ] 每月恢复演练验证备份可用性
198
+ - [ ] 备份保留策略是否符合合规要求
199
+
200
+ ## 注意事项
201
+
202
+ - **不要只依赖一种备份方式**:逻辑备份 + 物理备份 + Binlog 三者配合
203
+ - **测试恢复**:定期在测试环境演练恢复流程,确保备份可用
204
+ - **监控备份状态**:通过脚本监控备份成功率,发送告警
205
+ - **备份加密**:敏感数据的备份文件应加密存储
206
+ - **备份压缩**:物理备份建议用 `--compress` 参数,可节省 3-5 倍存储空间
207
+ - **mysqldump 对超大表(> 50GB)不适用**:导出和导入都极慢,建议用 XtraBackup