我已经安装了MongoDB v4.0
,因为它有一个最棒的特性,就是可以在Nodejs中使用mongodb
3.1驱动的事务(Transaction)。
当我尝试使用事务会话时,遇到了以下错误:
MongoError: Transaction numbers are only allowed on a replica set member or mongos.
那是什么,我该如何去除它?
我已经安装了MongoDB v4.0
,因为它有一个最棒的特性,就是可以在Nodejs中使用mongodb
3.1驱动的事务(Transaction)。
当我尝试使用事务会话时,遇到了以下错误:
MongoError: Transaction numbers are only allowed on a replica set member or mongos.
那是什么,我该如何去除它?
MongoDB 4.0
最令人兴奋的新功能无疑是事务。但是,遗憾的是,大多数安装和运行MongoDB的工具都启动了一个单独的服务器而不是副本集。如果您尝试在独立服务器上启动会话,您将收到此错误。
要使用事务,您需要一个MongoDB副本集,并且为开发启动副本集是一项复杂的过程。新的run-rs npm模块
使启动副本集变得容易。只需运行run-rs即可启动副本集,run-rs甚至会为您安装正确版本的MongoDB。
除了Node.js和npm之外,run-rs没有任何外部依赖项。您不需要安装Docker、homebrew、APT、Python或者MongoDB。
使用npm的-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
。
你可以在这里找到更多相关细节。
我找到了解决方案,只需要在MongoDB配置文件中进行三行配置。
从MongoDB Atlas切换到安装在CentOS 7 VPS上的MongoDB v4.4.0后,我也遇到了这个问题。
run-rs
解决方案对我不起作用,但是我成功地在不使用任何第三方工具的情况下解决了这个问题,按照以下步骤操作:
mongod
。最有效的方法是使用命令 mongo
进入MongoDB shell,然后执行下列步骤:
db.shutdownServer()
您将无法使用MongoDB服务器。 对于我来说,关闭过程太长了,然后我用以下命令杀死了该进程:
systemctl stop -f mongod
如果您杀死了mongod
进程,那么您可能需要运行mongod --dbpath /var/db --repair
var/db
应该指向您的数据库目录。
有关副本集设置步骤,请查看/etc/mongod.conf
文件,
查找replication
值行,并将以下行添加如下:
replication:
oplogSizeMB: <int>
replSetName: <string>
enableMajorityReadConcern: <boolean>
使用replSetName
值进行下一步操作。
这些设置的示例: oplogSizeMB: 2000
replSetName: rs0
enableMajorityReadConcern: false
将replSetName的值添加到连接URL中&replicaSet=--YourReplicationSetName--
如果您使用了我们示例中的名称rs0
,那么您应该在DB连接URL查询中添加replicaSet = rs0
输入命令:systemctl start mongod
使用命令mongo
进入MongoDB shell,输入命令rs.initiate()
现在您应该在副本集数据库中。
/etc/mongod.conf
文件中排除enableMajorityReadConcern: true
行。使用mongo --version
检查您的Mongo安装版本。 - Looiversion: '3.8'
services:
mongodb:
image: mongo:5
command: --replSet rs0
ports:
- "28017:27017"
environment:
MONGO_INITDB_DATABASE: attachment-api-local-dev
healthcheck:
# use 'mongo' instead of 'mongosh' if MongoDB version is lower than 5
test: mongosh --eval 'db.runCommand("ping").ok' localhost:27017/test --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" }
]
})
'
services:
mongodb:
image: bitnami/mongodb:5.0
ports:
- "27017:27017"
environment:
MONGODB_REPLICA_SET_MODE: primary
ALLOW_EMPTY_PASSWORD: 'yes'
MONGODB_REPLICA_SET_KEY
环境变量也是必需的。如果没有它,Mongo 进程将拒绝在容器中启动,并显示该变量是强制性的错误。我只需将其设置为类似 MONGODB_REPLICA_SET_KEY: 123456
的内容即可。 - BoazFROM 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
mongo
,也没有打印错误,只有在将mongo
替换为mongosh
时才能看到)。除此之外,您还需要CMD ["--replSet", "rs", "--keyFile", "/etc/mongodb.key"]
。 - Dmitry MugtasimovRUN echo 'rs.initiate();' > /docker-entrypoint-initdb.d/replica-init.script
RUN echo 'mongosh -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" < /docker-entrypoint-initdb.d/replica-init.script' > /docker-entrypoint-initdb.d/replica-init.sh
我们还是会出现“MongoServerError:This node was not started with the replSet option”错误。这只是因为docker-entrypoint.sh
未设计用于运行副本。 实际上,它似乎是设计成不运行副本的。请参见源代码中的#remove“--auth”和“--replSet”以进行我们的初始启动
。 - Dmitry Mugtasimov/usr/lib/mongod.service or /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
$ mongosh
$ rs.initiate()
run-rs npm模块
。零配置MongoDB运行程序。它启动一个没有非Node依赖项的副本集,甚至没有MongoDB。MongoDB Atlas
中创建一个帐户,这将为您提供有限的资源MongoDB集群,因此您可以运行/测试应用程序。
MongoDB Atlas
适用于 mongo:5.0.5-focal
镜像。
Dockerfile:
FROM mongo:5.0.5-focal AS rs-mongo
# Make MongoDB a replica set to support transactions. Based on https://dev59.com/B1UK5IYBdhLWcg3wqRhn#68621185
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"]
scripts/docker-entrypoint.sh.patch:
--- 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日
出现错误是因为您正在使用MongoDB会话,但它未在您的系统上配置。
运行以下命令以安装run-rs:
npm install run-rs -g
运行:
run-rs -v 4.0.0 --shell
您应该看到以下输出。请耐心等待,因为MongoDB 4.0.0大约有70MB。
$ run-rs -v 4.0.0 --shell
Downloading MongoDB 4.0.0
Copied MongoDB 4.0.0 to '/home/node/lib/node_modules/run-rs/4.0.0'
Purging database...
Running '/home/node/lib/node_modules/run-rs/4.0.0/mongod'
Starting replica set...
Started replica set on "mongodb://localhost:27017,localhost:27018,localhost:27019"
Running mongo shell: /home/node/lib/node_modules/run-rs/4.0.0/mongo
rs:PRIMARY>
你现在本地运行着 MongoDB 4.0.0 副本集。运行 rs.status() 来验证副本集是否在运行。
注意:- 你的 nodejs 版本应该是 $gte v3.1.0
mongod
实例: https://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set/ - Marcel Falliere