MongoDB每次都要rs.slaveOk(),好烦啊~

2022-01-25 18:44:02 浏览数 (1)

MongoDB每次都要rs.slaveOk(),好烦啊~

今天来一个MongoDB实用的技巧。

01背景介绍

在MongoDB的副本集中,如果你利用mongo-shell连接一个从节点,进行查询操作,经常会遇到下面的报错:

代码语言:javascript复制
[root@ /data1]# /usr/local/bin/mongo mongodb://root:xxxxx@10.xx.xx.xx:27017/admin
MongoDB shell version v3.6.3
connecting to: mongodb://10.xx.xx.xx:27017/admin
MongoDB server version: 3.6.3
Server has startup warnings: 
2021-12-24T18:06:34.334 0800 I STORAGE  [initandlisten] 
2021-12-24T18:06:34.334 0800 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2021-12-24T18:06:34.334 0800 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2021-12-24T18:06:36.233 0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2021-12-24T18:06:36.234 0800 I CONTROL  [initandlisten] 
cluster_name:SECONDARY> show dbs;
2022-01-04T22:50:43.712 0800 E QUERY    [thread1] Error: listDatabases failed:{
        "ok" : 0,
        "errmsg" : "not master and slaveOk=false",
        "code" : 13435,
        "codeName" : "NotMasterNoSlaveOk"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:65:1
shellHelper.show@src/mongo/shell/utils.js:816:19
shellHelper@src/mongo/shell/utils.js:706:15
@(shellhelp2):1:1

错误信息中,比较明显的给出来了,就是当前连接的是一个secondary,不是primary,而且这个secondary没有开启rs.slaveOk(),也就是不允许直接读取secondary上的数据。

那么,在交互式命令行下面,怎么解决这个问题呢?

代码语言:javascript复制
cluster_name:SECONDARY> rs.slaveOk()
cluster_name:SECONDARY> show dbs;
admin         0.000GB
config        0.000GB
local        21.716GB
processlist   0.000GB
test          0.000GB

但是,这种方案只能在当前的连接中生效,下次重新连接,又需要输入一次rs.slaveOk()

这个问题,如果你写shell脚本的话,脚本里面肯定需要带上rs.slaveOk()命令,否则,你无法执行任何命令。

怎么办?

02如何配置rs.slaveOk()永久生效

官方文档有这么一句话:

When starting, mongo checks the user’s HOME directory for a JavaScript file named .mongorc.js. If found, mongo interprets the content of .mongorc.js before displaying the prompt for the first time. If you use the shell to evaluate a JavaScript file or expression, either by using the --eval option on the command line or by specifying a .js file to mongo, mongo will read the .mongorc.js file after the JavaScript has finished processing. You can prevent .mongorc.js from being loaded by using the --norc option.

翻译过来就是:当我们启动MongoDB时,MongoDB 在启动用户的 HOME 目录中检查名为 .mongorc.js 的 JavaScript 文件。如果找到,mongo 会在第一次显示返回客户请求之前应用 .mongorc.js 的内容。 我们可以使用 --norc 选项阻止加载 .mongorc.js。

我们可以将rs.slaveOk()这条命令,写入到这个.mongors.js文件中,这样,就可以让mongo-shell客户端为我们执行这个命令了。

我的MongoDB实例的启动用户是root,所以默认的js文件就在:

/root/.mongors.js 路径下。只需要向其中键入:

echo 'rs.slaveOk()' > /root/.mongors.js 即可

后续登录时候,就不需要手工输入这个rs.slaveOk()的命令了,效果如下:

代码语言:javascript复制
[root@ /data1]# cat /root/.mongorc.js 
rs.slaveOk()
[root@ /data1]# /usr/local/bin/mongo mongodb://root:xxxxxxx@10.xx.xx.xx:27017/admin 
MongoDB shell version v3.6.3
connecting to: mongodb://10.xx.xx.xx:27017/admin
MongoDB server version: 3.6.3
Server has startup warnings: 
2021-12-24T18:06:34.334 0800 I STORAGE  [initandlisten] 
2021-12-24T18:06:34.334 0800 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2021-12-24T18:06:34.334 0800 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2021-12-24T18:06:36.233 0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2021-12-24T18:06:36.234 0800 I CONTROL  [initandlisten] 
qs:SECONDARY> show dbs;
admin         0.000GB
config        0.000GB
local        21.716GB
processlist   0.000GB
test          0.000GB

当然,这个.mongors.js文件,你还可以写上其他的命令。它都可以在你登录mongodb服务的第一时间,自动帮你执行。

03关于rs.slaveOk()命令的小插曲

人种歧视话题,这两年比较敏感,尤其是漂亮国,去年闹出来了黑人被暴力执法的事件。迫于这个问题,数据库厂商在后续版本的迭代中,逐渐取消了slave、black等字眼。

例如:

MySQL低版本中,show slave status命令在8.0版本中会变成show replica status;

Redis低版本中的slaveof命令,6.0版本将会变成replicaof;

MongoDB中的rs.slaveOk()命令,在5.0版本之后,会变成rs.secondaryOk()

这些带slave的命令,将来应该都会消失。

除此之外,那些带有black,white等字眼的单词,也会变成allow、deny,例如防火墙相关的,blacklist---黑名单,whitelist---白名单,这些会逐渐变成allowlist,denylist

不得不说,技术也应该适应普遍的价值观

0 人点赞