0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

MongoDB 实例 Crash 的故障现象问题

OSC开源社区 来源:OSC开源社区 2023-06-29 11:24 次阅读

1故障现象

近日,朋友遇到一个 MongoDB 实例 Crash 的问题,找到我帮忙一起分析原因,事情经过以及分析过程如下,可供学习。

操作过程

运维人员在优化慢查询时针对性创建了一个索引,语句如下:

db.c1.createIndex('name':1,background:true)

随后又将表上一个没能用上的索引删除,语句如下:

db.c1.dropIndex('idx_age')

在主节点上很顺利的就完成了,但是不久后就发现从节点发生了 Crash,日志中包含下列崩溃信息

2023-04-13T0750.752+0000ESTORAGE[conn3569849]WiredTigererror(-31802)[1681369250:752455][9937:0x7fe740144700],WT_CONNECTION.open_session:__open_session,2058:outofsessions,configuredfor20030(includinginternalsessions):WT_ERROR:non-specificWiredTigererrorRaw:[1681369250:752455][9937:0x7fe740144700],WT_CONNECTION.open_session:__open_session,2058:outofsessions,configuredfor20030(includinginternalsessions):WT_ERROR:non-specificWiredTigererror
2023-04-13T0750.752+0000INETWORK[listener]connectionacceptedfromxxx.xxx.xxx.xxx#3570023(20576connectionsnowopen)
2023-04-13T0750.753+0000F-[conn3569849]Invariantfailure:conn->open_session(conn,NULL,"isolation=snapshot",&_session)resultedinstatusUnknownError:-31802:WT_ERROR:non-specificWiredTigererroratsrc/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp111

其它信息

变更表是一张几千万的大表;

数据库架构为 MongoDB 4.0.14 的 PSA 架构;

应用开启了读写分离,从节点也存在大量只读请求。

2问题分析

根据日志信息,初步怀疑是连接打满了,检查最大连接数配置。

初步排查

shard1:PRIMARY>db.serverStatus().connections;
{"current":7,"available":29993,"totalCreated":7,"active":2}

最大连接数是由 maxIncomingConnections 参数和 ulimit 决定的。

net:
maxIncomingConnections:30000

在测试环境模拟连接数打满的情况,发现在连接数满了的情况下实例只会拒绝新的连接,而非直接 Crash。

connectingto:mongodb://10.186.64.88:27017/admin?gssapiServiceName=mongodb
2023-04-19T1326.578+0000INETWORK[js]DBClientConnectionfailedtoreceivemessagefromxxx.xxx.xxx.xxx-HostUnreachable:Connectionclosedbypeer
2023-04-19T1326.579+0000EQUERY[js]Error:networkerrorwhileattemptingtoruncommand'isMaster'onhost'10.186.64.88:27017':
connect@src/mongo/shell/mongo.js17
@(connect)6
exception:connectfailed

根据 SERVER-30462 描述怀疑是 WT_SESSION[1] 打满的情况。

WT_SESSION 是 MongoDB Server 和 WiredTiger[2] 存储引擎内部交互使用的会话,几乎所有操作都是在 WT_SESSION 的上下文中执行的。因此 WT_SESSION 在超过限制后将会触发较为严重的情况。

f6b17b4a-15a0-11ee-962d-dac502259ad0.png

源码分析

在源码 mongo/wiredtiger_kv_engine.cpp[3] 中可以看到 WT_SESSION 硬编码指定为 20000。

std::stringstreamss;
ss<< "create,";
    ss << "cache_size=" << cacheSizeMB << "M,";
    ss << "cache_overflow=(file_max=" << maxCacheOverflowFileSizeMB << "M),";
    ss << "session_max=20000,";
    ss << "eviction=(threads_min=4,threads_max=4),";
    ss << "config_base=false,";
    ss << "statistics=(fast),";

这一点也能在启动日志中进一步得到验证。

f6fd0a1a-15a0-11ee-962d-dac502259ad0.png

如果 WT_SESSION 数量超过 20000,将会触发 out of sessions 的报错。

/*Findthefirstinactivesessionslot.*/
for(session_ret=conn->sessions,i=0;i< conn->session_size;++session_ret,++i)
if(!session_ret->active)
break;
if(i==conn->session_size)
WT_ERR_MSG(session,WT_ERROR,"outofsessions,configuredfor%"PRIu32
"(including"
"internalsessions)",
conn->session_size);

提出疑问

分析到这开始疑惑 WT_SESSION 打满与索引操作存在什么样的关系?为什么相同的操作在主节点可以正常完成,而从节点会发生 Crash?

在创建索引时指定 background:true 可以在后台构建索引,不会加锁阻塞集合上的其它操作,这也是我们日常添加索引常用的方式。

但在删除索引时,我们有一点需要注意,但又常常被忽略,在主节点删除索引后同步到从节点回放时,如果从节点正在跑同一个集合上后台创建索引的操作,那么删除索引的操作将会被阻塞,更严重的是这时候实例上所有 namespace 的访问都将会阻塞。针对这一现象在官网 dropIndex[4] 文档中有提及:

Avoid dropping an index on a collection while any index is being replicated on a secondary. If you attempt to drop an index from a collection on a primary while the collection has a background index building on a secondary, reads will be halted across all namespaces and replication will halt until the background index build completes.

当任何创建索引操作复制到 Secondary 时,应避免在集合上删除索引。如果你试图在 Primary 上删除一个索引,而该集合在 Secondary 上有一个索引正在后台创建,那么所有 namespace 的访问将被停止,复制也会停止,直到后台索引建立完成。

回到错误日志中查找更多内容,就能发现从节点在后台创建索引时,又执行了同一个集合上的删除索引操作。

2023-04-13T0527.002+0000I-[replindexbuilder178]IndexBuild(background):122873800/64001875719%
2023-04-13T0530.002+0000I-[replindexbuilder178]IndexBuild(background):122976300/64001876919%
2023-04-13T0530.434+0000ICOMMAND[replwriterworker11]CMD:dropIndexestest.c1

初步结论

到此,我们得出初步结论。事情起因是主节点在同一个集合上执行创建索引和删除索引后,在从节点回放时出现了很严重的阻塞,大量的只读请求开始不断积压,最后导致 WT_SESSION 消耗殆尽,Server 无法与 WiredTiger 进行内部通信,最终导致实例 Crash。

3问题复现

下面的案例在测试环境复现 WT_SESSION 超过限制的情况,dropIndex 导致从节点锁阻塞的问题有兴趣可自己测试复现,这里就不做演示了。

WT_SESSION 上限是由 wiredtiger_open 配置中的 session_max 决定的,但 MongoDB 并未直接暴露 session_max的配置方式,只能通过下列方式进行覆盖设置。

mongod-f/etc/mongod.conf--wiredTigerEngineConfigString="session_max=5"
f7134e92-15a0-11ee-962d-dac502259ad0.png

然后在数据库内部发起一个全局排它锁。

mongo>db.fsyncLock()

编写下列 Python 脚本模拟并发线程。

#!/usr/bin/python
#-*-coding:UTF-8-*-
importmultiprocessing
importpymongo

deffind():
cnx_args=dict(username='root',password='abcd123#',host='127.0.0.1',port=27018,authSource='admin')
client=pymongo.MongoClient(**cnx_args)
db=client['test']
results=db.tab100.insert_one({"name":"jack"})
if__name__=="__main__":
x=1
whilex<350:
        p=multiprocessing.Process(target=find)
        p.start()
        print("start thread:",x)
        x+=1
    p.join()

这时 MongoDB 实例还在正常运行,因为我们的请求还没有真正的进入到 WiredTiger 引擎层,但一旦我们手动释放排它锁,所有请求都会在短时间内进入 WiredTiger 引擎,WT_SESSION 瞬间超过限制,实例紧接着发生 Crash。

mongo>db.fsyncUnlock()

错误日志如下,与生产日志相同。

f72c85d8-15a0-11ee-962d-dac502259ad0.png

4总结

net.maxIncomingConnections 设置应小于 WT_SESSION;

可以根据实际需求调整游标超时时间,避免出现大面积积压的情况;

避免创建索引和删除索引先后执行,特别是先执行后台创建索引的情况下;

4.2 版本中废弃了 background 选项,对索引创建过程进行了优化,只会在索引创建的开始和结束时持有 exclusive lock;并且 4.0 版本官方已经停止提供服务了,建议尽快升级。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 存储
    +关注

    关注

    12

    文章

    3859

    浏览量

    84670
  • 数据库
    +关注

    关注

    7

    文章

    3591

    浏览量

    63373
  • mongodb
    +关注

    关注

    0

    文章

    22

    浏览量

    332

原文标题:故障分析 | MongoDB索引操作导致Crash

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    MySQL和MongoDB的对比

    MySQL和MongoDB的对比http://bbs.edu118.com/forum.php?mod=viewthread&tid=212&fromuid=231(出处: 信盈达
    发表于 08-28 14:51

    MongoDB 4.0 RC 版本强势登陆

    摘要: MongoDB 因其灵活的文档模型、可扩展分布式设计广受开发者喜爱,在此基础上,MongoDB 4.0 推出了更强大的功能支持,目前4.0第一个RC版本已经发布,本文将介绍 MongoDB
    发表于 06-11 19:42

     华为云MongoDB弹性伸缩能力提升100倍

    弹性伸缩能力提升。此外DDS还容忍任意N-1个节点故障,支持单节点扩容步长。系统解决开源MongoDB使用过程中遇到的一系列问题。   华为云DDS与开源MongoDB性能对比图   事实上,DDS
    发表于 08-03 13:00

    MongoDB的安装教程

    MongoDB安装教程
    发表于 05-29 15:06

    电源常见故障现象

    的基本原则和方法,掌握故障判断的一般步骤。学会常用典型故障的判断和处理,根据故障现象,分析故障原因,判断
    发表于 09-08 06:07

    TCL彩电故障维修实例大全

    TCL彩电故障维修实例大全   例1.故障现象:TCL王牌
    发表于 01-15 17:56 2.4w次阅读

    熊猫彩电维修故障实例大全

    熊猫彩电维修故障实例大全 例1.故障现象:画面上有不规则的淡黑色阴影在走动,严重时亮度信号丢失,图像仅见暗暗的彩色。  原因及部位:勾边电
    发表于 01-15 18:02 1.5w次阅读

    现象到本质:网络设备故障诊断经典实例

    现象到本质:网络设备故障诊断经典实例    路由器、交换机在局域网中使用的范围越来越广。在此笔者就对局域网中与此类
    发表于 08-01 11:28 718次阅读

    关系型数据库到MongoDB的战略迁移实例分析

    CSDN:请先和大家介绍下自己和您目前所从事的工作,以及关注哪些技术领域? 唐建法:我目前在MongoDB官方担任的是负责MongoDB相关解决方案架构师。关注的领域是新一代数据处理的相关技术以及
    发表于 09-30 14:24 0次下载
    关系型数据库到<b class='flag-5'>MongoDB</b>的战略迁移<b class='flag-5'>实例</b>分析

    四通阀故障现象

    本视频首先介绍了四通阀故障现象,其次介绍了四通阀故障判断方法,最后介绍了四通阀故障检查步骤。
    的头像 发表于 10-27 11:33 2.5w次阅读

    使用MongoDB和NodeJS设计物联网系统的详细资料说明

    目标 基于阿里云服务快速构建物联网系统 准备工作 ECS MongoDB EMR Alinode 中间件代码 注意事项:ECS,MongoDB 可以选择按量计费的服务。 实例申请 Step1 拿到
    发表于 10-18 14:51 1次下载
    使用<b class='flag-5'>MongoDB</b>和NodeJS设计物联网系统的详细资料说明

    MongoDB索引操作导致Crash的问题及其解决办法

    近日,朋友遇到一个 MongoDB 实例 Crash 的问题,找到我帮忙一起分析原因,事情经过以及分析过程如下,可供学习。
    的头像 发表于 06-20 09:51 411次阅读
    <b class='flag-5'>MongoDB</b>索引操作导致<b class='flag-5'>Crash</b>的问题及其解决办法

    PetaExpress云数据库 MongoDB(mongodb数据库)优势

    MongoDB的数据模型是针对文档的。所谓文档是一种类似JSON的结构。可以简单理解,MongoDB存储在数据库中的各种JSON,在MongoDB中称为“BSON”。 PetaExpress云数据库
    的头像 发表于 07-14 10:06 334次阅读

    如何实现不同MongoDB实例间的数据复制?

    NineData提供了高效、安全、准确的MongoDB迁移方案。与传统的迁移工具相比,NineData实现了业务不停服的全量数据迁移和增量数据的采集复制能力,解决了停机时间长、可靠性低、数据准确性
    的头像 发表于 09-13 14:44 277次阅读
    如何实现不同<b class='flag-5'>MongoDB</b><b class='flag-5'>实例</b>间的数据复制?

    MongoDB数据恢复—MongoDB数据库文件损坏的数据恢复案例

    服务器数据恢复环境: 一台Windows Server操作系统服务器,服务器上部署MongoDB数据库。 MongoDB数据库故障&检测: 工作人员在未关闭MongoDB数据
    的头像 发表于 04-23 14:48 79次阅读
    <b class='flag-5'>MongoDB</b>数据恢复—<b class='flag-5'>MongoDB</b>数据库文件损坏的数据恢复案例