Cannot create namespace centrum.policy in multi-document transaction.

Cannot create namespace centrum.policy in multi-document transaction.

Cannot create namespace xxx.xxx in multi-document transaction.

问题

看报错信息,就是说不能在 mongo 事务中创建表。

解决否

已解决

方案

这是说: 不能在事务中创建 collection 。但你一看 sql,没有创建表语句啊。

mongo 中,如果你操作的 collection 不存在是会自动创建的。但有个例外就是事务。

在事务中是无法创建表结构的。

所以,解决这个问题,就是在执行 mongo sql 前,先创建好要操作的 collection

参考

  • https://stackoverflow.com/questions/52585715/cannot-create-namespace-in-multi-document-transactionmongodb-4-0-spring-data-2

Mongo 副本集 选择副本后 连不上 server selection error

failed: server selection error: context deadline exceeded, current topology: { Type: ReplicaSetNoPrimary, Servers: [{ Addr: 127.0.0.1:27017, Type: Unknown, Last error: connection() error occurred during connection handshake: dial tcp 127.0.0.1:27017: connect: connection refused

Mongo 副本集 选主错误 server selection error

问题

failed: server selection error: context deadline exceeded, current topology: { Type: ReplicaSetNoPrimary, Servers: [{ Addr: 127.0.0.1:27017, Type: Unknown, Last error: connection() error occurred during connection handshake: dial tcp 127.0.0.1:27017: connect: connection refused

解决否

已解决

方案

登陆 mongo server 输入命令

rs.status()

rs.status

这里看图片里,name是: mongolab:27021, 那么应用也会用这个地址去连 mongodb,如果 dns 里没有 mongolab,那么应用是连不上这个 mongo 的,最终报错就是链接超时。

查看一下Mongo集群之间的通讯 IP,或者地址是怎么配置,是否配置的IP的应用端能访问的IP段。

例如,三个 mongo 集群配置在同一网段内—— 192.168.1.0 ,如果你也按照这个 IP 来配置副本集,那么 mongo 之间通信是没问题的,但如果应用端可能读取 replica 信息后,会那副本集配置的 IP 信息去访问其他节点,这个时候应用会拿着 192.168.1.0 这个网断的 IP 去访问 mongo,如果 mongo 和应用不在一个网段,就会导致如上问题。所以,mongoreplica 配置的IP也需是应用可访问的 IP

这也是,往往运维部署,发现,mongo 互通 OK,运维溜了。等应用来连,却连不上问题。

参考

  • https://www.mongodb.com/docs/manual/replication/
  • https://www.mongodb.com/docs/manual/reference/method/rs.initiate/

Ubuntu 安装 MongoDB

Ubuntu 下如何用 apt-get 安装最新的 MongoDB

Ubuntu 安装 MongoDB

官网:https://www.mongodb.com/

社区版下载地址: https://www.mongodb.com/try/download/community

安装命令

## 安装依赖
curl -fsSL https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -

## 查看添加成功没
apt-key list

echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list

## 更新 apt
sudo apt update

## 安装 mongo
sudo apt install mongodb-org

## 启动服务
sudo systemctl start mongod.service

## 查看服务状态
sudo systemctl status mongod

## 启用状态
sudo systemctl enable mongod

## 停用状态
sudo systemctl stop mongod

初始化配置

vim /etc/mongod.conf
# network interfaces
net:
  port: 27017
#  bindIp: 127.0.0.1
  bindIp: 0.0.0.0

编辑了用户记得重启

sudo systemctl restart mongod

登陆 mongo

在安装了mongod的服务本机,mongo是无密码的,可输入如下命令直接登陆

$ mongo

远端通过如下命令登陆,未设置密码情况下,绑定了外网地址情况下,也能登陆

$ mongo "mongodb://192.168.0.x:27017"

创建用户

  • 产看所用用户
> use admin
switched to db admin
> db.system.users.find().pretty()

注意:用户相关的操作都需要 在admin db下操作!

创建 root 用户

> db.createUser(
    {
        user:"root",
        pwd:"pwd",
        roles:["root"]
    }
)

注意: 密码最好不要使用 & ? # : $ ; / . @ 等符号,因为 mongo DSN 格式是个 url,url 相关的关键词都不要用哦!

创建 admin 用户

> db.createUser(  
  { user: "admin",  
    customData:{description:"superuser"},
    pwd: "admin",  
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]  
  }  
)  

创建业务用户

> db.createUser({
    user:"user001",
    pwd:"123456",
    customData:{
        name:'jim',
        email:'jim@qq.com',
        age:18,
    },
    roles:[
        {role:"readWrite",db:"db001"},
        {role:"readWrite",db:"db002"},
        'read'// 对其他数据库有只读权限,对db001、db002是读写权限
    ]
})

用户管理

  • 改密码
use admin
db.changeUserPassword("username", "xxx")
  • 为用户追加权限
db.grantRolesToUser( "<username>", [ <roles> ], { <writeConcern> } )
  • 删除用户
use admin
db.dropUser('user001')

安全设置

访问mongo认证配置

在无密码的mongo上配置好用户后,就可以启用安全认证了。

vim /etc/mongod.conf
#security:

修改为:

security:
  authorization: enabled

如果是 mongo 低于 2.6 那么在配置文件最后一行加上:

auth = true

参考

  • https://www.digitalocean.com/community/tutorials/how-to-install-mongodb-on-ubuntu-20-04
  • https://segmentfault.com/a/1190000015603831
  • https://stackoverflow.com/questions/25325142/how-to-set-authorization-in-mongodb-config-file

float64 can only be truncated to an integer type when truncation is enabled

使用 mongo-go-dirver 反序列化到 float32 报错

error decoding key weight: float64 can only be truncated to an integer type when truncation is enabled

问题描述

通过 mongo-go-dirver findOne 查数据并反序列化到 结构体时,有个字段:

type User struct {
    Name      string    `bson:"name"`
    Age       uint32    `bson:"age"`
    Weight    float32   `bson:"weight"`
    Studying  bool      `bson:"studying"`
    Tag       []string  `bson:"tag"`
    CreatedAt time.Time `bson:"created_at"`
}

weight 字段类型为 float32,就提示:

float64 类型的值只能在启用截断时截断为整数类型

问题如何产生的

存入数据时,手写 68.1,在 Golang 中手写的 float 值默认为 float64, 所以就当 float64 存入mongo了,待你想反序列化到 float32的值时,就报错了。

在 mgo 中,程序会自动帮你截断转换了,但是在 mongo-go-driver 中需要手动处理,或者显示得配置解决方案,不然会导致报错,不输出数据!

解决否

已解决

方案

问题原因时 浮点数 decode时,超出了精度,mongo-go-driver就把这个问题抛了个error出来。那么针对这个报错,我们可以从两方面去解决。要么提高精度,要么高速golang,多的截断,咋不要了。

  1. 把float32改为 float64
  2. 在bson tag 追加 ,truncate
    Weight    float32   `bson:"weight,truncate"`

参考

  • https://segmentfault.com/a/1190000038451313