连接后 mongobee 在 Atlas 集群上读取 DBname.system.indexes 失败

Posted

技术标签:

【中文标题】连接后 mongobee 在 Atlas 集群上读取 DBname.system.indexes 失败【英文标题】:Reading of DBname.system.indexes failed on Atlas cluster by mongobee after getting connected 【发布时间】:2018-10-03 02:47:17 【问题描述】:

我有一个 Jhipster Spring 启动项目。最近我从 mlabs 独立沙箱转移到 Atlas 集群沙箱 M0 免费层副本集。它甚至可以工作,我对它进行了一些数据库操作。但是现在由于某种原因出现了读取权限错误

Error creating bean with name 'mongobee' defined in class path resource [DatabaseConfiguration.class]: Invocation of init method failed; nested exception is com.mongodb.MongoQueryException: Query failed with error code 8000 and error message 'user is not allowed to do action [find] on [test.system.indexes]' on server ********-shard-00-01-mfwhq.mongodb.net:27017

你可以在这里看到完整的堆栈https://pastebin.com/kaxcr7VS

我搜索了高低,我只能找到 M0 层用户没有权限覆盖我没有做的管理数据库。

即使现在连接到 Mlabs DB 也可以正常工作,但在 Atlas DB M0 层上存在此问题。

Mongo DB 版本:3.4

罐子和它的版本 名称:'mongobee',版本:'0.10' 名称:'mongo-java-driver',版本:'3.4.2'

@尼尔·伦恩 我用来连接的 userId 是管理员的,连接读写通过 shell 或 Robo3T(mongo 客户端)工作

【问题讨论】:

来自堆栈跟踪'user is not allowed to do action [find] on [test.system.indexes]' 这意味着您要连接的用户在当前数据库上没有执行此操作的权限。您在用户的错误数据库名称空间中,或者您为用户分配了错误的权限。对于大多数应用程序使用而言,readWrite 角色应该是一个合理的启动器。 【参考方案1】:

在与 MongoDB 支持团队讨论后,MongoDB 3.0 弃用了对 system.indexes 集合的直接访问,该集合以前用于列出数据库中的所有索引。应用程序应改为使用db.<COLLECTION>.getIndexes()

从MongoDB Atlas docs可以看出,他们可能会禁止调用system.集合:

(可选)对于 read 和 readWrite 角色,您还可以指定一个集合。如果不指定 read 和 readWrite 的集合,则该角色适用于数据库中的所有集合(不包括某些 system.collection)。

从堆栈跟踪可以看出 MongoBee 正在尝试进行此调用,因此现在是库问题,应该更新它。

更新: 为了在MongoBee 发布新版本之前解决问题:

    获取MongoBeegit clone git@github.com:mongobee/mongobee.gitcd mongobee的最新资源 获取拉取请求git fetch origin pull/87/head:mongobee-atlas 结帐git checkout mongobee-atlas 安装MongoBee jar mvn clean install/target文件夹或本地/.m2获取编译jar 将 jar 用作项目的依赖项

【讨论】:

即使使用 0.13 的最新 mongobee jar,它也会抛出相同的错误。我们如何解决这个问题,以便我可以连接到 Atlas 集群?任何建议表示赞赏 @Artist 我已经向 MongoBee 库提交了一个拉取请求来解决这个问题。我希望他们能合并它并尽快发布。 github.com/mongobee/mongobee/pull/87 这很有帮助。您是否建议重写 jar 类来解决此问题? @Artist 我宁愿用上面的拉取请求编译另一个jar,保留在 repo 中并使用它直到新的库版本发布。 @Artist 我已经添加了有关操作的详细步骤,如果适合您,请检查并接受答案。【参考方案2】:

今天早上遇到了这个问题。这是解决问题的快速而肮脏的猴子补丁:

package com.github.mongobee.dao;

import com.github.mongobee.changeset.ChangeEntry;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;

import java.util.List;

import static com.github.mongobee.changeset.ChangeEntry.CHANGELOG_COLLECTION;

public class ChangeEntryIndexDao 

    public void createRequiredUniqueIndex(DBCollection collection) 
        collection.createIndex(new BasicDBObject()
                        .append(ChangeEntry.KEY_CHANGEID, 1)
                        .append(ChangeEntry.KEY_AUTHOR, 1),
                new BasicDBObject().append("unique", true));
    

    public DBObject findRequiredChangeAndAuthorIndex(DB db) 
        DBCollection changelogCollection = db.getCollection(CHANGELOG_COLLECTION);
        List<DBObject> indexes = changelogCollection.getIndexInfo();
        if (indexes == null) return null;
        for (DBObject index : indexes) 
            BasicDBObject indexKeys = ((BasicDBObject) index.get("key"));
            if (indexKeys != null && (indexKeys.get(ChangeEntry.KEY_CHANGEID) != null && indexKeys.get(ChangeEntry.KEY_AUTHOR) != null)) 
                return index;
            
        
        return null;
    

    public boolean isUnique(DBObject index) 
        Object unique = index.get("unique");
        if (unique != null && unique instanceof Boolean) 
            return (Boolean) unique;
         else 
            return false;
        
    

    public void dropIndex(DBCollection collection, DBObject index) 
        collection.dropIndex(index.get("name").toString());
    


【讨论】:

我怎么能使用上面的代码,因为它是一个罐子 如果你把它放在你自己的 src/main/java 文件夹下匹配的包名 com.gitgub.mongobee.dao 它将覆盖 jar ;) 因此它应该被考虑一个临时解决方案!我将提交给 mongobee 以供将来考虑 不用担心,如果这对您有用,请考虑将其标记为已回答。 :) 这是一个不错的 hack,但覆盖 jar 类并不是我想要的。如果没有更多答案,我会将其标记为答案 对于更多搜索者,如果两次加载此类(lib 和类路径)时出现任何错误,您可能需要从加载的 mongobee 中排除该类。【参考方案3】:
Caused by: java.lang.NoSuchMethodError: com.github.mongobee.dao.ChangeEntryIndexDao.<init>(Ljava/lang/String;)V
    at com.github.mongobee.dao.ChangeEntryDao.<init>(ChangeEntryDao.java:34)
    at com.github.mongobee.Mongobee.<init>(Mongobee.java:87)
    at com.xxx.proj.config.DatabaseConfiguration.mongobee(DatabaseConfiguration.java:62)
    at com.xxx.proj.config.DatabaseConfiguration$$EnhancerBySpringCGLIB$$4ae465a5.CGLIB$mongobee$1(<generated>)
    at com.xxx.proj.config.DatabaseConfiguration$$EnhancerBySpringCGLIB$$4ae465a5$$FastClassBySpringCGLIB$$f202afb.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
    at com.xxx.proj.config.DatabaseConfiguration$$EnhancerBySpringCGLIB$$4ae465a5.mongobee(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 22 common frames omitted

jhipster 5 必须使用不同的版本,因为我在实现上述代码时得到了这一点。看起来它期待一个不同的版本。

【讨论】:

【参考方案4】:

system.indexes 的访问是mongobee 中的open issue。该问题已在项目中修复,但在修复发布之前该项目已被放弃。

由于这个项目的放弃,两个后续库已经从 mongobee 分叉出来,它们已经解决了这个问题:Mongock 和 mongobeeJ。

将应用程序的依赖项从 mongobee 库切换到这些后续库之一将允许您在 Atlas 上运行 mongobee 数据库迁移。

总结这些库:

Mongock - 2018 年从 mongobee 分叉。积极维护。与原始版本相比有了显着发展,包括对 Spring、Spring Boot 以及 Mongo Java 驱动程序的 3 和 4 版本的内置支持。 mongobeeJ - 2018 年从 mongobee 分叉。已经发布了五个更新版本。从原始 mongobee 的最小进化。 Mongo Java Driver 4 支持已于 2020 年 8 月实施。该项目已于 2020 年 8 月弃用,其创建者建议改用 Mongock 等库。

【讨论】:

以上是关于连接后 mongobee 在 Atlas 集群上读取 DBname.system.indexes 失败的主要内容,如果未能解决你的问题,请参考以下文章

如何将atlas mongodb与集群连接

无法使用 MEAN 堆栈连接到 Mongodb.atlas 集群

安装atlas后执行hive命令报错

MySQL——Atlas代理MySQL集群实现读写分离

数据库应用——Atlas代理MySQL集群实现读写分离

如何通过 Java 驱动程序正确连接到 Atlas M0(免费层)集群?