# fast-import-mysql **Repository Path**: starcode000/fast-import-mysql ## Basic Information - **Project Name**: fast-import-mysql - **Description**: 高性能 MySQL 数据导入工具。通过流式解析和 INSERT 语句合并,将 120 万条单行 INSERT 优化为 30 次批量执行,10 秒完成 255MB SQL 文件导入。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-28 - **Last Updated**: 2026-03-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Fast MySQL Import 高性能 MySQL 数据导入工具,通过流式解析和 INSERT 语句合并实现快速导入。 ## 特性 - **流式处理** - 逐块读取大文件,内存占用低 - **语句合并** - 自动合并单行 INSERT 为批量语句,大幅提升性能 - **DELIMITER 支持** - 正确处理存储过程、触发器等的自定义分隔符 - **INSERT 修饰符** - 支持 IGNORE、LOW_PRIORITY、DELAYED、HIGH_PRIORITY - **动态大小限制** - 根据 MySQL 的 max_allowed_packet 动态计算安全大小 - **性能优化** - SESSION 级别优化(关闭外键检查、binlog) - **详细统计** - 按表统计执行时间、flush 原因分析、时间分解 - **取消支持** - 支持 AbortSignal 取消导入 - **mysqldump 兼容** - 支持 mysqldump 导出的 SQL 文件(包括版本注释) - **错误容错** - 支持 `--ignore-errors` 忽略错误继续执行 - **灵活模式** - 支持新建数据库或导入到现有数据库 - **实时统计** - 显示导入进度和性能分析 ## 性能 通过以下优化实现高速导入: - **INSERT 合并** - 将单条 INSERT 合并为批量语句,减少网络往返 - **GLOBAL 优化** - 调整日志刷盘策略(需要 SUPER 权限) - **SESSION 优化** - 关闭外键检查、唯一性检查、binlog 记录 - **事务控制** - 批量执行后立即提交,避免长事务风险 - **动态大小** - 根据实际 `max_allowed_packet` 动态计算安全合并大小 > **注意**: > - `sql_log_bin=0` 会导致本次导入不被 Canal 等工具捕获 > - GLOBAL 优化无权限时自动跳过,不影响导入流程 ## 安装 ```bash npm install # 或 pnpm install ``` ## 使用 ### 快速开始 ```bash # 开发模式(使用 tsx 直接运行 TS) npm start -- --database=mydb # 生产模式(编译后用 node 运行) npm run build node dist/mysql-import-optimized.js --database=mydb ``` ### 查看帮助 ```bash npm start -- --help ``` ### 命令行参数 | 参数 | 说明 | 默认值 | |------|------|--------| | `--file=PATH` | SQL 文件路径 | `temp/test-sql-files/...` | | `--database=DB` | 目标数据库名称(必需) | - | | `--host=HOST` | MySQL 主机地址 | `localhost` | | `--port=PORT` | MySQL 端口 | `3306` | | `--user=USER` | MySQL 用户名 | `root` | | `--password=PWD` | MySQL 密码 | 空 | | `--max-merge=N` | 最大合并大小(MB) | `12` | | `--ignore-errors` | 忽略错误继续执行 | - | | `--no-cleanup` | 不清理数据库(导入到现有库) | - | | `--force` | 跳过删除数据库确认提示 | - | ### 使用示例 ```bash # 导入到新数据库(自动创建) npm start -- --file=backup.sql --database=myapp_backup # 导入到现有数据库 npm start -- --file=backup.sql --database=myapp --no-cleanup # 指定 MySQL 连接参数 npm start -- --host=localhost --user=root --password=123456 --database=mydb # 调整合并大小(处理大文件) npm start -- --file=large.sql --database=test --max-merge=16 # 忽略错误继续执行 npm start -- --file=partial.sql --database=myapp --ignore-errors --no-cleanup # 导入 mysqldump 文件 node dist/mysql-import-optimized.js --file=dump.sql --database=mydb --force ``` ### 生成测试数据 使用内置脚本生成测试 SQL 文件: ```bash # 使用 npm 命令 npm run generate # 自定义各表数据量(独立设置,无关联关系) npm run generate -- --users=100000 --products=5000 --orders=300000 --order-items=900000 --logs=200000 # 批量 INSERT 模式(测试直接执行) npm run generate -- --mode=batch # 只生成结构(不生成数据) npm run generate -- --schema-only # 只生成基本语句(无触发器、事件、视图、存储过程) npm run generate -- --basic-only # 查看更多选项 npm run generate -- --help ``` **数据生成参数:** | 参数 | 说明 | 默认值 | |------|------|--------| | `--users=N` | 用户表行数 | 50000 | | `--products=N` | 产品表行数 | 1000 | | `--orders=N` | 订单表行数 | 100000 | | `--order-items=N` | 订单明细表行数 | 300000 | | `--logs=N` | 日志表行数 | 50000 | | `--mode=MODE` | INSERT模式:single/batch/mixed | single | ## 架构 ``` src/ ├── sql-parser/ # SQL 解析器 │ ├── index.ts # FastSqlSplitter - 支持 DELIMITER、注释、字符串状态机 │ └── types.ts # 解析器类型定义 │ ├── import/ # 导入模块 │ ├── constants.ts # 导入常量(SESSION 优化配置、大小限制) │ ├── optimization.ts # 动态计算安全大小限制 │ ├── insert-merger.ts # StreamingInsertMerger - 流式合并执行器 │ └── utils.ts # 工具函数(合并 INSERT) │ ├── db.ts # 数据库连接和优化配置 ├── importer.ts # 主导入入口(流式处理) ├── cli.ts # 命令行入口 └── types.ts # 类型定义 ``` ## 工作原理 1. **流式读取** - 使用 Node.js async iterator 逐块读取 SQL 文件(256KB chunks) 2. **语句分割** - FastSqlSplitter 使用字节级别解析,正确处理: - 字符串内的分号和转义字符 - 自定义 DELIMITER(存储过程、触发器) - 多种注释风格(`--`, `#`, `/* */`) - 条件注释(`/*!40101 ... */`) 3. **INSERT 合并** - StreamingInsertMerger 将相同结构的单行 INSERT 合并为批量语句 4. **即时执行** - 达到大小限制或表结构变化时立即执行并提交 5. **性能优化** - 动态读取 max_allowed_packet,应用 GLOBAL/SESSION 级别优化配置 ## 优化配置 导入时自动应用以下优化: ### GLOBAL 级别(需要 SUPER 权限,失败时跳过) ```sql SET GLOBAL innodb_flush_log_at_trx_commit = 2; -- 每秒刷盘 SET GLOBAL sync_binlog = 0; -- 禁用 binlog 同步刷盘 ``` ### SESSION 级别(安全,无需特殊权限) ```sql SET SESSION FOREIGN_KEY_CHECKS = 0; -- 关闭外键检查 SET SESSION UNIQUE_CHECKS = 0; -- 关闭唯一性检查 SET SESSION sql_log_bin = 0; -- 关闭 binlog 记录 SET SESSION AUTOCOMMIT = 0; -- 手动提交控制 ``` 导入完成后自动恢复 GLOBAL 和 SESSION 配置(恢复需要 SUPER 权限,失败时跳过)。 > **注意**: > - `sql_log_bin=0` 会导致本次导入不被 Canal 等工具捕获 > - GLOBAL 优化需要 SUPER 权限,无权限时会自动跳过并记录警告 ## 安全说明 **危险数据库名称保护** 脚本内置了危险数据库名称黑名单,拒绝删除以下数据库: - 系统数据库:`mysql`、`information_schema`、`performance_schema`、`sys` - 常见生产库名:`production`、`prod`、`live`、`main`、`master`、`primary` **确认提示** 默认情况下,删除数据库前会要求用户确认。使用 `--force` 参数可跳过确认: ```bash # 跳过确认(自动化场景) npm start -- --database=test_backup --force ``` **建议** - 生产环境使用 `--no-cleanup` 导入到现有数据库 - 使用 `--force` 前务必确认数据库名称正确 - 定期备份重要数据 - 注意 `sql_log_bin=0` 会导致本次导入不被 binlog 工具捕获 ## 可用脚本 | 命令 | 说明 | |------|------| | `npm start` | 使用 tsx 直接运行 TypeScript | | `npm run build` | 编译 TypeScript 到 dist 目录 | | `npm run generate` | 生成测试 SQL 数据 | | `node dist/...` | 运行编译后的 JavaScript | ## License MIT