关于Mysql大批量插入数据报Packet for query is too large的问题

本文介绍了解决MySQL批量插入数据时出现“Packetforqueryistoolarge”错误的方法。通过调整max_allowed_packet参数或采用分批插入的方式,有效解决了因数据包过大导致的批量插入失败问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mysql大批量插入数据报Packet for query is too large




      项目中需要实时解析聚类的结果文件,然后入库,突然最近这几天系统日志经常报错:### Error updating database.  Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (49049746 > 4194304). You can change this value on the server by setting the max_allowed_packet' variable.,具体错误日志截图如下:



然后查了一下资料是MySQL的一个系统参数问题:max_allowed_packet,我这里当时设置值为4194304(4M),一般默认是1M查询:show VARIABLES like '%max_allowed_packet%';
修改此变量的值:MySQL安装目录下的my.ini文件中的[mysqld]段中的"max_allowed_packet = 1M",如更改为100M(或更大,如果没有这行内容,增加一行),保存,重起MySQL服务。现在可以load大于100M的文件了。




      还有一种方法,如果服务器配置受限,无法改成更大,那我们可以分批次来批量入库,而不是一次性入库(这样会插入不成功,报错),我们可以1000条作为一次批量插入,多插几次,这也是一种办法!代码如下:

Integer docCount = relateDocList.size();
log.info("评论观点对应的文档数量为:" + docCount);
if(docCount >= COMMENT_DOC_COUNT) {
    Integer insertTimes = (docCount % COMMENT_DOC_COUNT == 0 ? docCount / COMMENT_DOC_COUNT : docCount / COMMENT_DOC_COUNT + 1);
    for(int i = 1; i <= insertTimes; i++) {
        List<EventCommentsRelateDoc> subDocList = null;
        if(i == insertTimes) {
            subDocList = relateDocList.subList((i - 1) * COMMENT_DOC_COUNT, docCount);
        } else {
            subDocList = relateDocList.subList((i - 1) * COMMENT_DOC_COUNT, i * COMMENT_DOC_COUNT);
        }
        for(EventCommentsRelateDoc relateDoc : subDocList) {
            for(Asset asset : assetIdsList) {
                if(relateDoc.getAssetId().equals(asset.getAssetId())) {
                    relateDoc.setCreateDate(asset.getCreateDate());
                    break;
                }
            }
        }
        try {
            count = eventCommentsRelateDocMapper.addNetizenCommentRelateDoc(relateDocList);
            log.info("插入评论观点对应文档成功,文档数:" + relateDocList.size());
        } catch (Exception e) {
            log.info("插入评论观点对应文档失败...,文档数:" + relateDocList.size(), e);
        }
    }
} else {
    for(EventCommentsRelateDoc relateDoc : relateDocList) {
        for(Asset asset : assetIdsList) {
            if(relateDoc.getAssetId().equals(asset.getAssetId())) {
                relateDoc.setCreateDate(asset.getCreateDate());
                break;
            }
        }
    }
    try {
        count = eventCommentsRelateDocMapper.addNetizenCommentRelateDoc(relateDocList);
        log.info("插入评论观点对应文档成功,文档数:" + relateDocList.size());
    } catch (Exception e) {
        log.info("插入评论观点对应文档失败...,文档数:" + relateDocList.size(), e);
    }
}

如有不对的地方,还希望大神们多多指教!!!



<think>我们正在解决MySQLPacketTooBigException异常,特别是当错误信息显示为(40 > -1)时,这通常表示max_allowed_packet参数被错误地设置为-1(无效值)。根据引用[1]中的信息,我们看到max_allowed_packet的值可能被设置为1048576(即1MB),但用户的问题中显示的是32M,而错误信息中的-1表明配置可能未正确加载。以下将按照步骤详细说明如何解决此问题。</think>### 解决 MySQL PacketTooBigException (40 > -1) 异常 当 MySQL 出现 `Packet for query is too large (40 > -1)` 错误时,表示数据包大小超过服务器允许的最大值,且配置值异常(-1)。以下是完整解决方案: --- #### 步骤 1:验证当前配置 登录 MySQL 执行: ```sql SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet'; ``` 若返回值为 **-1**(异常)或小于实际数据包大小(如引用[1]中的 `1048576` = 1MB),则需调整[^1]。 --- #### 步骤 2:临时解决方案(立即生效) ```sql -- 设置为64MB(根据数据量调整) SET GLOBAL max_allowed_packet = 64*1024*1024; -- 刷新权限 FLUSH PRIVILEGES; ``` > ⚠️ 此修改在服务重启后失效,适合临时测试 --- #### 步骤 3:永久解决方案(需重启服务) 1. **修改配置文件** - Linux: `/etc/my.cnf` - Windows: `C:\ProgramData\MySQL\MySQL Server X.X\my.ini` 2. 在 `[mysqld]` 区块添加: ```ini # 推荐64MB,大数据场景可设128M max_allowed_packet = 64M ``` 3. **重启 MySQL 服务** ```bash # Linux sudo systemctl restart mysqld # Windows(管理员CMD) net stop MySQL net start MySQL ``` --- #### 步骤 4:验证配置生效 ```sql SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet'; ``` 应返回: ``` +--------------------+----------+ | Variable_name | Value | +--------------------+----------+ | max_allowed_packet | 67108864 | # 64MB的字节数 +--------------------+----------+ ``` --- ### 特殊情况处理 若仍报 `(40 > -1)`: 1. 检查配置文件路径是否正确(通过 `mysqld --help --verbose` 查看加载路径) 2. 确认修改的是 `[mysqld]` 区块(非 `[client]`) 3. 查看错误日志定位问题: ```bash # Linux tail -100 /var/log/mysqld.log # Windows C:\ProgramData\MySQL\MySQL Server X.X\Data\<hostname>.err ``` --- ### 预防措施 1. **分批处理大数据操作**(Java示例) ```java // 每500条分批插入 int batchSize = 500; for (int i = 0; i < dataList.size(); i += batchSize) { List<Data> batch = dataList.subList(i, Math.min(i+batchSize, dataList.size())); jdbcTemplate.batchUpdate("INSERT ...", batch); } ``` 2. **监控大查询** ```sql /* 检查历史大包查询 */ SELECT * FROM performance_schema.events_statements_history WHERE SQL_TEXT LIKE '%INSERT%' AND MESSAGE_TEXT LIKE '%max_allowed_packet%'; ``` > 💡 **关键原则**: > - 生产环境建议设置 `max_allowed_packet ≥ 64MB` > - 单次操作数据量超过 10MB 时应强制分批处理 > - 定期检查 `max_allowed_packet` 配置是否被意外重置
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值