MongoDB每次都要rs.slaveOk(),好烦啊~
今天来一个MongoDB实用的技巧。
01背景介绍
在MongoDB的副本集中,如果你利用mongo-shell连接一个从节点,进行查询操作,经常会遇到下面的报错:
[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://218.206.242.148:12345/images/20_tencent/20220917/dnfkaxsgi3u 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上的数据。
那么,在交互式命令行下面,怎么解决这个问题呢?
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()永久生效
官方文档有这么一句话:
翻译过来就是:当我们启动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()的命令了,效果如下:
[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://218.206.242.148:12345/images/20_tencent/20220917/dnfkaxsgi3u 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
不得不说,技术也应该适应普遍的价值观。