mongodb生产中遇到的问题

 

Query failed with error code 17144 and error message 'Executor error: Overflow sort stage buffered data usage of 33594336 bytes exceeds internal limit of 33554432 bytes' on server ip:27017; nested exception is com.mongodb.MongoQueryException: Query failed with error code 17144 and error message 'Executor error: Overflow sort stage buffered data usage of 33594336 bytes exceeds internal limit of 33554432 bytes' on server ip:27017

 

这个问题真的是困扰我很久才找到,主要不是这个问题有多难理解,而是代码里我们针对异常都trycatch打的自己的日志,猜不透是什么原因导致的,后来网上找了个工具类,在catch里打印了堆栈异常的相关信息才发现这个mongodb的错误

 

这个错误是指,你的查询里指定了排序,mongodb排序的时候如果排序字段没有索引会把全部数据都读到内存里,默认有个32M的大小限制(为了节约内存,默认给sort操作限制了最大内存为32Mb,当数据量越来越大直到超过32Mb的时候就自然抛出异常了!)

所以有两种解决方案

解决方案:
1)修改默认内存,

db.adminCommand({setParameter:1, internalQueryExecMaxBlockingSortBytes:335544320}) //不推荐使用

2)创建索引 db.yourCollection.createIndex({<field>:<1 or -1>})
参考
原文链接:https://blog.csdn.net/u010411264/article/details/79583305

 

这里把握从网上找的打印堆栈信息的工具类贴出来,有所改动,特别是把具体错误原因输出到日志里了:

package com.taikang.obs.common.utils;

/**
 * @Author: LiuYan
 * @Description:
 * @Date: Created in 12:22 2020/1/8
 */
public class ExcpUtil {
    //打印异常堆栈信息
    public static String getStackTraceString(Throwable ex) {//(Exception ex) {
        StackTraceElement[] traceElements = ex.getStackTrace();

        StringBuilder traceBuilder = new StringBuilder();
        traceBuilder.append(ex.getMessage());
        traceBuilder.append("\n");
        if (traceElements != null && traceElements.length > 0) {
            for (StackTraceElement traceElement : traceElements) {
                traceBuilder.append(traceElement.toString());
                traceBuilder.append("\n");
            }
        }

        return traceBuilder.toString();
    }

    //构造异常堆栈信息
    public static String buildErrorMessage(Exception ex) {

        String result;
        String stackTrace = getStackTraceString(ex);
        String exceptionType = ex.toString();
        String exceptionMessage = ex.getMessage();

        result = String.format("%s : %s \r\n %s", exceptionType, exceptionMessage, stackTrace);

        return result;
    }
}

使用范例: 

public void createAutoInsReport(String nowDateString, String fileName) throws IOException {
        int count = 0;
        //文件名以当天时间为准,对应当天流水记录的报表数据
        File file = new File(path + fileName);
        FileWriter fw = null;
        BufferedWriter bw = null;
        try {
            fw = new FileWriter(file);
            bw = new BufferedWriter(fw);
            //先写当天导入的数据,全部都提交到报表中做统计
            count = writeCurrentDayInsertData(nowDateString, bw);
            log.info("报表中当天导入的数据有" + count + "条已导入");
            //再把之前导入的但是当天才处理完成的数据写入报表文件
            count = writePastDayInsertData(nowDateString, bw) + count;
        } catch (Exception e) {
            log.info("车险报表存在问题" + ExcpUtil.getStackTraceString(e));
        } finally {
            if (bw != null) bw.close();
            if (fw != null) fw.close();
        }
        log.info("今天推送了" + count + "条数据到车险报表");
        File okFile = new File(path + (fileName.replace(".txt", ".ok")));
        okFile.createNewFile();
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值