Secondary节点为何阻塞请求近一个小时?

简介: 看到Secondary节点上的日志,我的内心的崩溃的,鉴权请求居然耗时2977790ms(约50分钟),经详细统计,这个Secondary节点上,所有16:54之后发起的用户请求,都阻塞到17:54左右才返回,处理时间最长的请求约1个小时。 2016-06-17T17:54:57.575+0800

看到Secondary节点上的日志,我的内心的崩溃的,鉴权请求居然耗时2977790ms(约50分钟),经详细统计,这个Secondary节点上,所有16:54之后发起的用户请求,都阻塞到17:54左右才返回,处理时间最长的请求约1个小时。

2016-06-17T17:54:57.575+0800 I COMMAND  [conn2581] command admin.system.users command: saslStart { saslStart: 1, mechanism: "SCRAM-SHA-1", payload: "xxx" } keyUpdates:0 writeConflicts:0 numYields:0 reslen:171 locks:{ Global: { acquireCount: { r: 2 } }, Database: { acquireCount: { r: 1 } }, Collection: { acquireCount: { r: 1 } } } protocol:op_query 2977790ms
2016-06-17T17:54:57.575+0800 I COMMAND  [conn2740] command admin.system.users command: saslStart { saslStart: 1, mechanism: "SCRAM-SHA-1", payload: "xxx" } keyUpdates:0 writeConflicts:0 numYields:0 reslen:171 locks:{ Global: { acquireCount: { r: 2 } }, Database: { acquireCount: { r: 1 } }, Collection: { acquireCount: { r: 1 } } } protocol:op_query 2416390ms

经过调查,引发备节点阻塞近1个小时主要是对一个很大的集合『后台建立索引 + 删除索引』2个动作导致。

背景知识

  1. Secondary从Primary拉取到一批oplog后,重放oplog的过程会加一把特殊的锁,这个锁会阻塞所有的reader,这么做的原因我个人理解是避免让reader看到中间状态,只有等一批oplog全部应用成功才让客户端可读,避免出现脏读的问题。
  2. 建索引有前台(foreground)和后台(background)2种模式,前台建索引会加在整个过程中对DB加互斥写锁,同一个DB下的读写操作均会阻塞至索引建立结束;后台建索引只会对DB加意向写锁,对DB下的读写无影响。
  3. Secondary重放建立索引的命令时,如果是前台模式,则整个重放建索引的过程都会阻塞所有的reader;如果是后台模式,重放时建索引的动作会放到后台线程里做,只会阻塞reader很短的时间。

为了尽量避免建索引影响业务,通常

  1. 在集合创建的时候,就建立好索引,此时因为集合为空,建索引的开销很小。(以后每次写入,同时会更新索引)
  2. 如果建索引时,集合内已经写入了很多文档,尽量使用后台模式,避免『主节点上影响某个DB的所有读写』以及『备节点上影响所有的读』。

问题分析

在我们遇到的问题里,创建索引使用的后台模式,最终仍然导致Secondary阻塞读reader近1个小时,接下来分析下问题产生的原因,主要事件的过程如下所示。

| time | Primary | Secondary |
| --- | --- | --- |
| 15:07:00| db.coll 开始后台创建索引 |
| 16:32:35 | db.coll 创建索引结束| 从oplog拉取到createIndex的操作,并开始重放|
| 16:54:53 | 删除db数据库下某个索引 | 从oplog拉取到dropIndex的请求并开始重放,此时所有的请求开始阻塞 |
| 17:54:53 | | 重放createIndex结束,开始应答阻塞的请求|

  1. 15:07:00 Primary上发起后台建索引,创建索引的过程耗费近1.5小时
  2. 16:32:25 创建索引完成,Primary上记录oplog,Secondary拉取到oplog并重放该动作,由于是后台建索引,Secondary会启动一个单独的线程来建索引,建索引的过程会对DB加意向锁,所以重放动作只会阻塞reader很短的时间(毫秒级别)。
  3. 16:54:53 用户在同一个DB下发起了一个删除索引的动作,删除动作在主上很快结束,备拉取到oplog开始重放,删除索引的动作需要对DB加互斥锁,而此时Secondary后台建索引还在进行中,已经对DB加了意向锁,导致这个互斥锁需要等待后台建索引结束,而重放oplog时,Secondary占用的特殊锁会阻塞所有的reader,所以从这个时间点开始,所有的reader都阻塞等待了。
  4. 17:54:53 Secondary后台建索引结束,删除索引获得互斥锁并完成删除动作,重放结束,阻塞的reader加锁成功并得到处理。

总结

上述问题主要因为MongoDB的设计机制导致,Secondary节点重放oplog时的锁粒度太大,会阻塞所有的读请求;但如果降低锁粒度,就可能会出现脏读的问题,这对于某些业务场景是不可接受的。目前来说,只要不把『耗时长并且需要同步到备节点』的操作放到业务逻辑里,影响是完全可以忽略的,如果实在无法避免,最终出现了Secondary长时间阻塞的情况,就直接使用默认的readPreference,只从Primary上读数据。

参考资料

相关文章
|
SQL NoSQL AliSQL
MySQL RENAME hang问题分析与修复
问题现象:alter 过程 rename 文件一直失败,导致 crash。[Warning] InnoDB: Cannot rename file ./tradesupplymember/memberpropertyinfo_0024.ibd (space id 78102), retried 1000 times. There are either pending IOs or flushes 
780 0
MySQL RENAME hang问题分析与修复
|
NoSQL MongoDB
MongoDB compact 命令详解
为什么需要 compact 一图胜千言 remove 与 drop 的区别 MongoDB 里删除一个集合里所有文档,有两种方式 db.collection.remove({}, {multi: true}),逐个文档从 btree 里删除,最后所有文档被删除,但文件物理空间不会被回收 db.
|
监控 NoSQL 数据库
云数据库MongoDB监控指标解读与关注
为方便开发者的使用,云数据库MongoDB提供了许多查看其运行状态指标的命令。如何分析这些繁多的数据指标?又如何使用这些数据指标解决我们业务中出现的问题呢?本文将带大家了解查看这些监控指标的命令并为大家逐一解读其中一些重要的指标。
11310 0
|
7月前
|
存储 关系型数据库 MySQL
【赵渝强老师】OceanBase数据库从零开始:MySQL模式
《OceanBase数据库从零开始:MySQL模式》是一门包含11章的课程,涵盖OceanBase分布式数据库的核心内容。从体系架构、安装部署到租户管理、用户安全,再到数据库对象操作、事务与锁机制,以及应用程序开发、备份恢复、数据迁移等方面进行详细讲解。此外,还涉及连接路由管理和监控诊断等高级主题,帮助学员全面掌握OceanBase数据库的使用与管理。
390 5
|
存储 NoSQL 物联网
这些案例展示了MongoDB在不同行业中的广泛应用
这些案例展示了MongoDB在不同行业中的广泛应用
670 4
|
存储 关系型数据库 MySQL
RR隔离mysql如何实现?什么情况RR不能解决幻读?
【10月更文挑战第9天】在数据库事务中,隔离级别是一个重要的概念,它定义了事务在并发环境下如何相互隔离。MySQL支持四种隔离级别:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。其中,REPEATABLE READ(简称RR)是MySQL的默认隔离级别,它旨在解决脏读、不可重复读和幻读问题。
444 2
|
存储 监控 NoSQL
【MongoDB 专栏】MongoDB 分片策略与最佳实践
【5月更文挑战第10天】MongoDB 分片是应对大数据量的扩展策略,涉及哈希和范围分片两种策略。分片架构包含分片服务器、配置服务器和路由服务器。最佳实践包括选择合适分片键、监控调整、避免热点数据等。注意数据分布不均和跨分片查询的挑战。通过实例展示了如何在电商场景中应用分片。文章旨在帮助理解并优化 MongoDB 分片使用。
619 3
【MongoDB 专栏】MongoDB 分片策略与最佳实践
|
存储 关系型数据库 MySQL
MySQL 索引优化:深入探索自适应哈希索引的奥秘
MySQL 索引优化:深入探索自适应哈希索引的奥秘
|
存储 NoSQL MongoDB
MongoDB 助力移动式汽车保养运营模式优化,将开发请求减少 90%
MongoDB针对初级,中级及熟练的技术开发人员推出系列技术文章与行业案例。深入浅出地剖析MongoDB产品基础原理,使用技巧,典型行业场景及应用,还有Code Demo及线上线下活动推荐!
4972 1
MongoDB 助力移动式汽车保养运营模式优化,将开发请求减少 90%
|
存储 人工智能 NoSQL
多维数据实时分析,MongoDB给零售企业提供快速高效的数据洞察力
客户行为正在迅速演变,供应链正在重组,员工也正在以新的方式工作。企业需要提供更加个性化的客户体验,对市场趋势做出更快速的反应,监测和预防潜在问题。
多维数据实时分析,MongoDB给零售企业提供快速高效的数据洞察力