javascript Mongodb v4.0事务,MongoError:事务号只允许在副本集成员或mongo上使用

dm7nw8vv  于 2022-12-25  发布在  Java
关注(0)|答案(9)|浏览(193)

我在Nodejs中安装了MongoDB v4.0,以获得它最令人惊叹的特性Transaction,并将mongodb 3.1作为驱动程序。
当我尝试使用事务会话时,我遇到了这个错误:

MongoError: Transaction numbers are only allowed on a replica set member or mongos.

那是什么,我怎么才能摆脱它?

0kjbasz6

0kjbasz61#

对于那些想要针对停靠的MongoDB示例进行开发的人,下面是基于官方MongoDB停靠器映像的单文件docker-compose.yaml解决方案:

version: '3.9'

services:
  mongodb:
    image: mongo:5
    command: --replSet rs0
    ports:
      - "28017:27017"
    environment:
      MONGO_INITDB_DATABASE: attachment-api-local-dev
    healthcheck:
      test: echo 'db.runCommand("ping").ok' | mongo localhost:27017/admin --quiet
      interval: 2s
      timeout: 3s
      retries: 5

  mongo-init:
    image: mongo:5
    restart: "no"
    depends_on:
      mongodb:
        condition: service_healthy
    command: >
      mongo --host mongodb:27017 --eval
      '
      rs.initiate( {
         _id : "rs0",
         members: [
            { _id: 0, host: "localhost:27017" }
         ]
      })
      '

更简单的解决方案是只使用Bitnami MongoDB image

services:
  mongodb:
    image: bitnami/mongodb:5.0
    ports:
      - "27017:27017"
    environment:
      MONGODB_REPLICA_SET_MODE: primary
      ALLOW_EMPTY_PASSWORD: 'yes'
d4so4syb

d4so4syb2#

为了使用事务,您需要一个MongoDB副本集,在本地启动副本集进行开发是一个复杂的过程。
您可以使用run-rs npm module. Zero-configMongoDB运行器,启动一个没有非节点依赖项的副本集,甚至没有MongoDB。
或者,您可以简单地在MongoDB Atlas中创建一个帐户,它为您提供了一个资源有限的MongoDB集群,以便您可以运行/测试您的应用程序。
MongoDB Atlas

pexxcrt2

pexxcrt23#

在Linux机器上运行MongoDB时,您可以通过编辑服务文件更新连接字符串来使用复制

/lib/systemd/system/mongod.service

并使用以下内容更新它

ExecStart=/usr/bin/mongod --config "/etc/mongod.conf" --replSet rs0

其中--config "/etc/mongod.conf"指向MongoDB配置文件,--replSet rs0告诉它使用名为rs0的复制
然后重新启动

sudo systemctl daemon-reload     //<--To reload service units
sudo systemctl restart mongod    //<--To Restart MongoDB Server

然后通过terminal中的mongod示例启动复制

$ mongosh
$ rs.initiate()
kr98yfug

kr98yfug4#

我已经和这个问题斗争了好几个星期了,现在我把我的结论告诉你,为了能够在分片集群上使用事务,你至少需要在集群上运行MongoDB4.2,如果集群没有分片,我使用了一个库,它有一个子依赖mongodb NodeJS驱动程序。这个来自3.3.x版本的驱动程序在4版本的分片MongoDB集群上失败了。0.4.对我来说,解决方案是将我的集群更新到4. 2版本。
源代码:https://www.bmc.com/blogs/mongodb-transactions/

ymzxtsji

ymzxtsji5#

适用于mongo:5.0.5-focal图像。
停靠文件:

FROM mongo:5.0.5-focal AS rs-mongo

# Make MongoDB a replica set to support transactions. Based on https://stackoverflow.com/a/68621185/1952977
RUN apt-get update && apt-get install patch

# How to create scripts/docker-entrypoint.sh.patch
# 1. Download the original file:
#    wget https://github.com/docker-library/mongo/raw/master/5.0/docker-entrypoint.sh
#    ( wget https://github.com/docker-library/mongo/raw/b5c0cd58cb5626fee4d963ce05ba4d9026deb265/5.0/docker-entrypoint.sh )
# 2. Make a copy of it:
#    cp docker-entrypoint.sh docker-entrypoint-patched.sh
# 3. Add required modifications to docker-entrypoint-patched.sh
# 4. Create patch:
#    diff -u docker-entrypoint.sh docker-entrypoint-patched.sh > scripts/docker-entrypoint.sh.patch
# 5. Clean up:
#    rm docker-entrypoint.sh docker-entrypoint-patched.sh
COPY scripts/docker-entrypoint.sh.patch .
RUN patch /usr/local/bin/docker-entrypoint.sh docker-entrypoint.sh.patch
RUN mkdir -p /etc/mongo-key && chown mongodb:mongodb /etc/mongo-key

CMD ["--replSet", "rs", "--keyFile", "/etc/mongo-key/mongodb.key"]

脚本/docker-entrypoint.sh。修补程序:

--- docker-entrypoint.sh    2022-01-04 15:35:19.594435819 +0300
+++ docker-entrypoint-patched.sh    2022-01-06 10:16:26.285394681 +0300
@@ -288,6 +288,10 @@
    fi

    if [ -n "$shouldPerformInitdb" ]; then
+
+     openssl rand -base64 756 > /etc/mongo-key/mongodb.key
+    chmod 400 /etc/mongo-key/mongodb.key
+
        mongodHackedArgs=( "$@" )
        if _parse_config "$@"; then
            _mongod_hack_ensure_arg_val --config "$tempConfigFile" "${mongodHackedArgs[@]}"
@@ -408,7 +412,14 @@
        set -- "$@" --bind_ip_all
    fi

-   unset "${!MONGO_INITDB_@}"
+  echo 'Initiating replica set'
+  "$@" --logpath "/proc/$$/fd/1" --fork
+  echo 'rs.initiate({"_id":"rs","members":[{"_id":0,"host":"127.0.0.1:27017"}]});' | mongosh -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD"
+  "$@" --logpath "/proc/$$/fd/1" --shutdown
+  echo 'Done initiating replica set'
+
+  unset "${!MONGO_INITDB_@}"
+
 fi

 rm -f "$jsonConfigFile" "$tempConfigFile"

docker-compose.yml:

version: '3.9'

services:
  mongo:
    image: rs-mongo:current
    restart: always
    env_file:
      - .env
    ports:
      - 127.0.0.1:27017:27017
    volumes:
      - mongo-db:/data/db
      - mongo-configdb:/data/configdb
      - mongo-key:/etc/mongo-key

volumes:
  mongo-db:
    driver: local
  mongo-configdb:
    driver: local
  mongo-key:
    driver: local
    • 更新日期:**2022年1月6日
p1tboqfb

p1tboqfb6#

Transactions无疑是MongoDB 4.0中最令人兴奋的新特性。但不幸的是,大多数安装和运行MongoDB的工具都启动独立服务器,而不是副本集。如果您试图在独立服务器上启动会话,您将收到此错误。
为了使用事务,您需要一个MongoDB副本集,并且在本地启动一个副本集以进行开发是一个复杂的过程。新的run-rs npm module使启动副本集变得简单。运行run-rs是启动副本集所需要的全部,run-rs甚至会为您安装正确版本的MongoDB
除了Node.jsnpm之外,Run-rs没有外部依赖项。您不需要安装DockerhomebrewAPTPython,甚至MongoDB
使用npm's -g标志全局安装run-rs。您也可以在package.json文件的devDependencies中列出run-rs。

npm install run-rs -g

接下来,使用--version标志运行run-rs,Run-rs将为您下载MongoDB v4.0.0,不用担心,它不会覆盖您现有的MongoDB安装。

run-rs -v 4.0.0 --shell

然后在连接字符串中使用**replicaSet=rs**。
您可以在here中找到有关它的更多详细信息。

eiee3dmh

eiee3dmh7#

我得到了解决方案,它只是MongoDB配置文件中的三行配置。
在从MongoDB atlas切换并在我的带有WHM的CentOS 7 VPS上安装MongoDB v 4. 4. 0之后,我也面临着这个问题。
run-rs解决方案对我不起作用,但我设法在没有任何第三方工具的情况下解决了这个问题,具体步骤如下:

1.关闭mongod

最有效的方法是使用命令mongo checkout方法进入MongoDBshell

db.shutdownServer()

您将无法使用MongoDB服务器。对我来说,关闭过程花费了太长时间,然后我用以下命令杀死了该进程:

systemctl stop -f mongod

如果您终止了mongod进程,则可能需要运行mongod --dbpath /var/db --repair
var/db应该指向您的数据库目录。

2.设置复制副本设置配置。

对于replicaSet设置步骤,请 checkout /etc/mongod.conf文件,查找replication值行,并且您应该添加以下行,如下所示:

replication:
   oplogSizeMB: <int>
   replSetName: <string>
   enableMajorityReadConcern: <boolean>

在下一步中使用replSetName值。
这些设置的示例:

oplogSizeMB: 2000
   replSetName: rs0
   enableMajorityReadConcern: false

3.添加您的连接字符串URL。

将replSetName的值添加到连接URL &replicaSet=--YourReplicationSetName--
如果您使用了我们示例中的名称rs0,则应该将URL查询replicaSet=rs0添加到DB连接中

4.再次打开mongod

输入以下命令:systemctl start mongod

5.访问replicaSet数据库

使用命令mongo进入MongoDB shell,然后输入命令rs.initiate(),现在您应该已进入replicaSet数据库。

lb3vh1jj

lb3vh1jj8#

使用Docker进行本地开发的可能解决方案
创建停靠文件

FROM mongo:4.4.7
RUN echo "rs.initiate();" > /docker-entrypoint-initdb.d/replica-init.js
CMD [ "--replSet", "rs" ]

构建此停靠文件

docker build ./ -t mongodb:4.7-replset

运行此创建的映像

docker run --name mongodb-replset -p 27017:27017 -d mongodb:4.7-replset

使用此URI连接到数据库

mongodb://localhost:27017/myDB
wlp8pajw

wlp8pajw9#

我最近也遇到过同样的问题,因为我连接到的远程Mongo服务器的版本与我的本地开发环境不同。
为了快速解决这个问题,我在连接字符串中添加了以下参数:
重试写入=假

相关问题