一、索引增加引发的性能问题
问题描述:
在大型表上并发增加索引时,从库在索引构建过程中意外重启,导致构建到一半的索引崩溃。主节点首先查询对应表数据并构建索引,完成后即向客户端返回确认,此时从节点尚未开始索引构建。随后,主节点将创建索引的操作记录到oplog中,从节点获取并执行这些操作以构建索引。
解决方案:
- 临时移除副本集参数,以单实例模式启动并添加
noindexbuildretry
选项来构建索引。完成后,再将实例作为副本集成员重新加入集群。(注意:noindexbuildretry
在MongoDB 4.2版本中已废弃) - 重新构建从库以恢复索引构建过程。
二、Global Lock突然上升与读写TICKET减少
问题描述:
通过db.serverStatus().globalLock
观察到Global Lock突然上升,同时读写TICKET的剩余量减少。MongoDB的锁机制包括Global Lock、DB Lock和Collection Lock。在Global Lock层面,意向锁被用于区分读写操作,其中读操作为MODE_IS,写操作为MODE_IX。这两种锁模式互不竞争,使得读写请求可以在无竞争的情况下并行处理。当读写TICKET不足时,Global Lock值会上升。
解决方案:
- 优化查询语句以减少锁竞争和提高处理效率。
- 升级实例的内存和CPU资源以提升性能。
三、MongoDB聚合内存不足
问题描述:
在执行聚合操作时,MongoDB报告内存不足错误。默认情况下,聚合操作的内存限制为16MB。
解决方案:
通过在聚合管道操作中设置allowDiskUse: true
选项,允许MongoDB将部分数据溢出到磁盘以完成聚合操作。
四、MongoDB Config异常(3.2X版本)
问题描述:
在MongoDB 3.2X版本中,Config Servers作为独立节点启动。当某个Config服务发生异常时,整个Config集群可能变得不可用,导致分片分配失败。
解决方案:
- 通过执行
use config
和db.runCommand({dbHash: 1})
命令,对比不同节点的哈希值来确定正确的Config数据。 - 停止具有正确哈希值的Config服务和错误哈希值的Config服务,然后使用rsync同步数据,并重新启动服务。
- 为避免此类问题,建议升级MongoDB版本。
五、MongoDB无法写入
可能原因:
- Mongos层挂掉,导致无法处理写入请求。
- Mongos层整体堆积大量请求,导致写入延迟或失败。
- 某个分片会话堆积过多请求,导致写入受阻。
六、Too Many Open Files导致的MongoDB服务异常
问题描述:
当MongoDB打开的文件句柄数超过系统限制时,服务可能出现异常。WiredTiger存储引擎在MongoDB中为每个集合和索引创建单独的文件,因此集合数量增多会占用更多的文件句柄。
解决方案:
- 减少集合数量以降低文件句柄的使用。
- 增加Linux系统中MongoDB的文件打开数限制。
- 在MongoDB服务启动参数中添加
LimitNOFILE
和LimitNPROC
选项以提高限制。
七、Mongos所在服务器高负载
问题描述:
Mongos本身需要处理聚合计算等任务,当负载过高时可能导致性能下降。
解决方案:
扩展Mongos节点数量,将新的节点提供给研发团队使用,以分散负载并减少单个Mongos节点的资源消耗。
八、MongoDB Secondary节点长期处于Rollback状态
问题描述:
当MongoDB Secondary节点回滚的数据量超过300MB时,节点可能长时间处于Rollback状态无法完成同步。
解决方案:
在这种情况下,需要手动干预。保存、删除或移动导致回滚的数据,并重新同步Secondary节点以使其与Primary节点保持一致。最简单的方法是执行完全重新同步。
九、MongoDB Kill会话问题
问题描述:
当需要终止长时间运行的MongoDB会话时,可以使用db.currentOp()
和db.killOp()
命令。但被终止的会话会进入killpending
状态,如果堆积过多,释放过程会变得非常缓慢。
解决方案:
执行主从切换并重启从节点以释放killpending
状态的会话。但请注意,重启后从节点可能会进入Rollback状态。如果回滚的数据量过大,可能需要重新构建从节点。因此,建议在会话堆积过多之前及时终止不必要的操作。
网友评论