|
| 1 | +# MySQL 握手错误修复说明 |
| 2 | + |
| 3 | +## 问题描述 |
| 4 | +使用 MySQL Connector/J 8.2.0 连接时出现 `[08S01][1043] Bad handshake.` 错误。 |
| 5 | + |
| 6 | +## 修复内容 |
| 7 | + |
| 8 | +### 1. 更新 CAPABILITIES 标志 |
| 9 | +- **修改文件**: `app/Protocol/MySql/Handshake.php` |
| 10 | +- **旧值**: `0x000880df` |
| 11 | +- **新值**: `0x00aff7df` |
| 12 | +- **原因**: MySQL Connector/J 8.2.0 期望服务器支持更多能力标志,包括: |
| 13 | + - `CLIENT_PROTOCOL_41` (0x00000200) |
| 14 | + - `CLIENT_MULTI_STATEMENTS` (0x00010000) |
| 15 | + - `CLIENT_MULTI_RESULTS` (0x00020000) |
| 16 | + - `CLIENT_PLUGIN_AUTH` (0x00080000) |
| 17 | + - `CLIENT_CONNECT_ATTRS` (0x00100000) |
| 18 | + - 等等 |
| 19 | + |
| 20 | +### 2. 增加详细日志 |
| 21 | +- **修改文件**: `app/Service/ProxyService.php` |
| 22 | +- **新增内容**: |
| 23 | + - 握手包详细信息日志(包括十六进制和 ASCII 表示) |
| 24 | + - 客户端数据详细日志 |
| 25 | + - 客户端认证响应解析日志(包括 capabilities 详细信息) |
| 26 | + - 连接关闭详情日志 |
| 27 | + - 新增 `toAscii()` 辅助方法用于日志输出 |
| 28 | + |
| 29 | +### 3. 更新服务器版本号 |
| 30 | +- **修改文件**: `app/Protocol/MySql/Handshake.php` |
| 31 | +- **旧值**: `5.7.0-sqlLogProxy` |
| 32 | +- **新值**: `5.7.44-sqlLogProxy` |
| 33 | +- **原因**: 匹配实际的 MySQL 版本,减少客户端疑虑 |
| 34 | + |
| 35 | + |
| 36 | +### 2. 查看日志 |
| 37 | +```bash |
| 38 | +# 查看连接日志 |
| 39 | +tail -f runtime/logs/connection.log |
| 40 | + |
| 41 | +# 查看默认日志 |
| 42 | +tail -f runtime/logs/hyperf.log |
| 43 | + |
| 44 | +# 查看SQL日志 |
| 45 | +tail -f runtime/logs/sql.log |
| 46 | +``` |
| 47 | + |
| 48 | +### 3. 使用 MySQL Connector/J 8.2.0 测试连接 |
| 49 | +确保使用以下连接字符串: |
| 50 | +``` |
| 51 | +jdbc:mysql://localhost:3317/your_database?useSSL=false |
| 52 | +``` |
| 53 | + |
| 54 | +## 预期结果 |
| 55 | + |
| 56 | +### 成功连接时,日志应该显示: |
| 57 | +1. **握手包发送**: |
| 58 | + ``` |
| 59 | + [info] 握手包发送结果 {"client_id":"1","handshake_length":xx,...} |
| 60 | + ``` |
| 61 | + |
| 62 | +2. **收到客户端认证响应**: |
| 63 | + ``` |
| 64 | + [info] 检测到客户端认证响应,准备连接目标MySQL {...} |
| 65 | + [info] 解析客户端认证信息成功 {"username":"root","database":"test",...} |
| 66 | + ``` |
| 67 | + |
| 68 | +3. **成功连接到目标MySQL**: |
| 69 | + ``` |
| 70 | + [info] MySQL连接建立成功 {"host":"mysql57.common-all","port":3306,...} |
| 71 | + ``` |
| 72 | + |
| 73 | +### 如果仍然失败,检查: |
| 74 | +1. 客户端的 capabilities 是否与服务器匹配 |
| 75 | +2. 认证插件名称是否正确(`mysql_native_password`) |
| 76 | +3. 字符集设置是否正确 |
| 77 | +4. 目标 MySQL 服务器是否正常运行 |
| 78 | + |
| 79 | +## 关键改进点 |
| 80 | + |
| 81 | +### CAPABILITIES 标志详解 |
| 82 | +``` |
| 83 | +0x00aff7df 的组成部分: |
| 84 | +- 0x00000001: CLIENT_LONG_PASSWORD |
| 85 | +- 0x00000002: CLIENT_FOUND_ROWS |
| 86 | +- 0x00000004: CLIENT_LONG_FLAG |
| 87 | +- 0x00000008: CLIENT_CONNECT_WITH_DB |
| 88 | +- 0x00000010: CLIENT_NO_SCHEMA |
| 89 | +- 0x00000020: CLIENT_COMPRESS |
| 90 | +- 0x00000040: CLIENT_ODBC |
| 91 | +- 0x00000080: CLIENT_LOCAL_FILES |
| 92 | +- 0x00000100: CLIENT_IGNORE_SPACE |
| 93 | +- 0x00000200: CLIENT_PROTOCOL_41 (重要) |
| 94 | +- 0x00000400: CLIENT_INTERACTIVE |
| 95 | +- 0x00000800: CLIENT_SSL |
| 96 | +- 0x00001000: CLIENT_IGNORE_SIGPIPE |
| 97 | +- 0x00002000: CLIENT_TRANSACTIONS |
| 98 | +- 0x00004000: CLIENT_RESERVED |
| 99 | +- 0x00008000: CLIENT_SECURE_CONNECTION |
| 100 | +- 0x00010000: CLIENT_MULTI_STATEMENTS (重要) |
| 101 | +- 0x00020000: CLIENT_MULTI_RESULTS (重要) |
| 102 | +- 0x00040000: CLIENT_PS_MULTI_RESULTS |
| 103 | +- 0x00080000: CLIENT_PLUGIN_AUTH |
| 104 | +- 0x00100000: CLIENT_CONNECT_ATTRS |
| 105 | +- 0x00200000: CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA |
| 106 | +``` |
| 107 | + |
| 108 | +## 注意事项 |
| 109 | + |
| 110 | +1. **CAPABILITIES 必须同步更新**: |
| 111 | + - `Handshake::CAPABILITIES` |
| 112 | + - `Auth::CAPABILITIES` |
| 113 | + |
| 114 | +2. **日志级别**: |
| 115 | + - 使用 `debug` 级别记录详细信息 |
| 116 | + - 使用 `info` 级别记录关键事件 |
| 117 | + - 使用 `warning` 记录异常情况 |
| 118 | + - 使用 `error` 记录错误 |
| 119 | + |
| 120 | +3. **性能考虑**: |
| 121 | + - 生产环境可以适当降低日志级别 |
| 122 | + - 使用日志轮转避免日志文件过大 |
0 commit comments