mongodb学习笔记2
1、创建用户
创建一个超级用户
use admin
db.createUser({user:"adminUserName",pwd:"adminUserPwd",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})
超级用户的role有两种,userAdmin或者userAdminAnyDatabase(比前一种多加了对所有数据库的访问)。db是指定数据库的名字,admin是管理数据库。
创建一个不受访问限制的超级用户
use admin
db.createUser(
{user:"user_root",pwd:"pwd_root",roles:["root"]
}
)
创建一般用户:
use xxlong_db
db.createUser({user:"xxlongdb_user",pwd:"xxlongdb_pwd",roles:[{role:"read",db:"xxlong_db"},{role:"read",db:"xxlong"}]});
修改密码
use admin
db.changeUserPassword(
"xxlongdb_user"
,
"xxx"
);
db.runCommand({usersInfo:
"xxlongdb_user"
};
db.runCommand(
{updateUser:"xxlongdb_user",pwd:"xxx",customData:{title:"xxx"}});
新用户登录:mongo --host 127.0.0.1:27017 -u adminUserName -p adminUserPwd --authenticationDatabase admin
mongo --host 127.0.0.1:27017
db.auth("xxlongdb_user","xxlongdb_pwd");之后才能对数据库操作
查看当前用户权限:db.runCommand({usersInfo:"adminUserName",showPrivileges:true});
删除用户:
use admin
db.system.users.remove({user:"xxlongdb_user"});
2、主从服务器
主:
新建文件夹/home/xxlong/mongodb_data/master
mongod --bind_ip=127.0.0.1 --port=8888 --dbpath=/home/xxlong/mongodb_data/master --master
从:
新建文件夹/home/xxlong/mongodb_data/slave1
mongod --bind_ip=127.0.0.1 --port=7777 --dbpath=/home/xxlong/mongodb_data/slave1 --source=127.0.0.1:8888 --slave
其它参数:
--only 从节点-->指定复制某个数据库,默认是复制全部数据库
--slavedelay 从节点-->设置主数据库同步数据的延迟(单位是秒)
--fastsync 从节点-->以主数据库的节点快照为节点启动从数据库
--autosync 从节点-->如果不同步则重新同步数据库
--oplogSize 主节点-->设置oplog的大小(主节点操作记录存储到local的oplog中)
登录主节点:
mongo 127.0.0.1:8888
登录从节点:
mongo 127.0.0.1:7777
如果show dbs 报错 解决:
rs.slaveOk()
use local
db.sources.find();
挂接主节点,操作之前只留下从数据库服务
db.sources.insert("host","127.0.0.1:8888");
删除已经挂接的主节点,操作之前只留下从数据库服务
db.sources.remove("host","127.0.0.1:8888");
这样主节点创建的数据库在从节点中也会出现
3、副本集
步骤1、创建三个文件夹/home/xxlong/mongodb_data/replSet_1111 /home/xxlong/mongodb_data/replSet_2222 /home/xxlong/mongodb_data/replSet_3333
mongod --bind_ip=127.0.0.1 --port=1111 --dbpath=/home/xxlong/mongodb_data/replSet_1111 --replSet=child/127.0.0.1:2222 #设定同伴
mongod --bind_ip=127.0.0.1 --port=2222 --dbpath=/home/xxlong/mongodb_data/replSet_2222 --replSet=child/127.0.0.1:3333
mongod --bind_ip=127.0.0.1 --port=3333 --dbpath=/home/xxlong/mongodb_data/replSet_3333 --replSet=child/127.0.0.1:1111
步骤2、初始化副本集
db.runCommand({"replSetInitiate":{"_id":'child',"members":[{"_id":1,"host":"127.0.0.1:1111"},{"_id":2,"host":"127.0.0.1:2222"},{"_id":3,"host":"127.0.0.1:3333"}]}})
按照算法选举一个活跃的数据库,另两个为备份数据库
登录mongo 127.0.0.1:1111 mongo 127.0.0.1:2222 mongo 127.0.0.1:3333
有一个是child:PRIMARY> ,另外两个是child:SECONDARY>
从节点不能执行查询操作,使用rs.slaveOk(),就可以了,rs.slaveOk()默认是true,设置rs.slaveOk(false),则从节点就不可以执行查询操作了
mongo的节点类型:
1、standard:常规节点,参与投票,有可能成为活跃节点
2、passive:副本节点,参与投票,复制节点,但是不能成为活跃节点
3、arbiter:仲裁节点,只参与投票不复制节点,也不能成为活跃节点
初始化高级参数:
config_object:
{
_id : <setname>,
members: [
{
_id : <ordinal>,
host : <hostname[:port]>
[, arbiterOnly : true]
[, buildIndexes : <bool>]
[, hidden : true]
[, priority: <priority>]
[, tags: {loc1 : desc1, loc2 : desc2, ..., locN : descN}]
[, slaveDelay : <n>]
[, votes : <n>]
}
, ...
],
[settings: {
[getLastErrorDefaults: <lasterrdefaults>]
[, getLastErrorModes : <modes>]
}]
}
_id:副本集的名字,必须和命令行的名字匹配,也就是刚才启动mongodb数据库命令行的那个名字,数字字母,不能包含"/";
members:一个数组用来表示副本集中的每个成员,这个数组必须包含_id和host这2个key。
members 数组:
_id:在副本集中的每一个成员都必须有一个_id表示,这个_id是通常是数字,从0开始增长。需要注意的是当其中一个成员退休了(指从副本集config中移除了),新加入的成员不能重新使用这个退休成员的_id;
host:ip地址和端口号;
arbiterOnly(false):如果是true,则表示这个成员为仲裁节点,不接收数据;
buildIndexes(true):如果设置为false,则会阻止在这个节点上创建第二索引,通常这个节点是作为纯粹的数据备份,从不用来被查询。不过也因为此节点没有第二索引,所以他写入的东西很少,也就需要很少的内存和磁盘。_id的索引还是会被创建的。只有当priority属性设置为0时,此项才能设置为false,一般不会用到这个选项;
hidden(false):如果此项为true,不要告诉客户端的此节点的存在,设置隐藏节点的原因是此节点的数据的使用模式和其他节点大为不同,比如:报表,统计,备份等。设置为ture时,允许你针对这个节点发送非主要查询。
priority(1.0):权重,更高的权重会被选举为主节点,0代表副本节点,1到1000是常规节点
tags({}):一个文档代表这台服务器的位置,有利于位置感知的读写。其实就是表示此节点位于哪个数据中心的,mongodb会根据tags找近的数据中心节点同步数据。
slaveDelay(0):同步数据的延迟,设置为0表示立即更新同步数据。
votes(1):此节点可以发出的投票数,一般不用修改他
settings 对象:settings对象可以在集群建立起来以后用再进行设置,通常使用默认值
有3种方式可以初始化一个副本集:
1、db.runCommand( { replSetInitiate : <config_object> } )
2、rs.initiate(<config_object>)
3、rs.initiate()//先初始化,再通过rs.add等方法修改
删除节点: rs.remove("10.1.10.30:10001")
增加节点:rs.add({_id:4,host:"10.1.10.30:10001"});
3、分片
配置服务器:mongod --bind_ip=127.0.0.1 --port=60000 --dbpath=/home/xxlong/mongodb_data/shard/config
路由服务器:mongos --bind_ip=127.0.0.1 --port=60001 --configdb=127.0.0.1:60000
分片服务器:mongod --bind_ip=127.0.0.1 --port=60002 --dbpath=/home/xxlong/mongodb_data/shard/slice_db1
mongod --bind_ip=127.0.0.1 --port=60003 --dbpath=/home/xxlong/mongodb_data/shard/slice_db2
登录路由服务器添加分片,查看:
mongo 127.0.0.1:60001
use admin
db.runCommand({addshard:"127.0.0.1:60002",allowLocal:true}); #{ "shardAdded" : "shard0000", "ok" : 1 }
db.runCommand({addshard:"127.0.0.1:60003",allowLocal:true}); #{ "shardAdded" : "shard0001", "ok" : 1 }
use config
db.shards.find(); #自动分片{ "_id" : "shard0000", "host" : "127.0.0.1:60002" } { "_id" : "shard0001", "host" : "127.0.0.1:60003" }
db.databases.find(); #{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
_id表示数据库的名字
partitioned表示数据库是否已经分区,默认是false,需要开启分区。数据库的分区是针对集合而言的,即启动分区,实际上是对数据库的集合进行分区
primary:MongoDB的分片是基于数据库的。即一个分片节点中,有些数据库开启了分片功能,而有些数据库没有开启分片。
那么没有开启分片的数据只能位于分片集群的一个分片上,
因此用户读写没有开启分片的数据库时,mongos需要通过某种机制知道,这个数据库位于哪台分片节点上。
MongoDB通过primary这个属性来记录这个信息如下所示:
比如建立一个数据库users,往里插入一条数据后,再次执行use config; db.databases.find(),结果如下,表示users数据库建立在shard0000上
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "users", "partitioned" : false, "primary" : "shard0000" }
打开数据库分片功能:
use xxlongdb
db.student.insert({"number":0,"name":"xxlong"});
use config
db.databases.find(); #{ "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "xxlongdb", "partitioned" : false, "primary" : "shard0000" }
use admin
db.runCommand({"enablesharding":"xxlongdb"});
use config
db.databases.find(); #{ "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "xxlongdb", "partitioned" : true, "primary" : "shard0000" }
对集合进行分片:
use admin
db.runCommand({"shardcollection":"xxlongdb.student","key":{"_id":1}}); #{ "collectionsharded" : "xxlongdb.student", "ok" : 1 }
分片的chunkSize设置
首先执行如下命令,查看数据库的分片信息。这是对片键uid的范围进行了定义,此时在shard0001上,uid的分片区间是负无穷到正无穷
use config
db.chunks.find();
{ "_id" : "xxlongdb.student-_id_MinKey", "lastmod" : Timestamp(1, 0), "lastmodEpoch" : ObjectId("55da9d3f1683a40c9157364d"),
"ns" : "xxlongdb.student","min" : { "_id" : { "$minKey" : 1 } }, "max" : { "_id" : { "$maxKey" : 1 } }, "shard" : "shard0000" }
查看MongoDB的默认的chunkSize,为64M
use config db.settings.find(); #{ "_id" : "chunksize", "value" : 64 }
通过如下命令将chunkSize的大小改为1M
use config
db.settings.save({_id:"chunksize",value:1})
db.settings.find(); #{ "_id" : "chunksize", "value" : 1 }
利用大数据量进行测试:
use xxlongdb
function add(){
for(var i=1;i<=600000;i++){
db.student.insert({"number":i++,"name":"xxlong"});
};
}
add()
use xxlongdb
db.student.find().count() #300000
登录分片服务器:mongo 127.0.0.1:60002
use xxlongdb
db.student.find().count(); #203876
登录分片服务器:mongo 127.0.0.1:60003
use xxlongdb
db.student.find().count(); #96125
查看配置库对于分片服务器的配置存储:
db.printShardingStatus();
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("55d98773d222b86a3013e52c")
}
shards:
{ "_id" : "shard0000", "host" : "127.0.0.1:60002" }
{ "_id" : "shard0001", "host" : "127.0.0.1:60003" }
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
5 : Success
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "xxlongdb", "partitioned" : true, "primary" : "shard0000" }
xxlongdb.student
shard key: { "_id" : 1 }
chunks:
shard0000 3
shard0001 3
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : ObjectId("55dac71e82b34018cdeafe77") } on : shard0001 Timestamp(2, 0)
{ "_id" : ObjectId("55dac71e82b34018cdeafe77") } -->> { "_id" : ObjectId("55dac74282b34018cdebec27") } on : shard0001 Timestamp(3, 0)
{ "_id" : ObjectId("55dac74282b34018cdebec27") } -->> { "_id" : ObjectId("55dac75382b34018cdec6300") } on : shard0000 Timestamp(4, 1)
{ "_id" : ObjectId("55dac75382b34018cdec6300") } -->> { "_id" : ObjectId("55daca037c517cdbbd57613f") } on : shard0000 Timestamp(3, 2)
{ "_id" : ObjectId("55daca037c517cdbbd57613f") } -->> { "_id" : ObjectId("55dacac17c517cdbbd58e238") } on : shard0000 Timestamp(3, 3)
{ "_id" : ObjectId("55dacac17c517cdbbd58e238") } -->> { "_id" : { "$maxKey" : 1 } } on : shard0001 Timestamp(4, 0)
{ "_id" : "xxlong", "partitioned" : false, "primary" : "shard0000" }
{ "_id" : "test", "partitioned" : false, "primary" : "shard0001" }
添加分片
启动一个新的MongoDB实例,这个实例中没有要分片的数据库集合,如果有的话,先删除掉
mongod --bind_ip=127.0.0.1 --port=60004 --dbpath=/home/xxlong/mongodb_data/shard/slice_db3
登录路由服务器:
mongo 127.0.0.1:60001
use admin
db.runCommand({addshard:"127.0.0.1:60004",allowLocal:true});
此后,分片Balancer开始平衡分片服务器中的文档,在上面两个分片80万个文档,添加一个分片后,
平衡后(60001:30000,60002:173451,60003:96124,60004:30426),执行命令:
use config
printShardingStatus(db.getSisterDB("config"),1);
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("55d98773d222b86a3013e52c")
}
shards:
{ "_id" : "shard0000", "host" : "127.0.0.1:60002" }
{ "_id" : "shard0001", "host" : "127.0.0.1:60003" }
{ "_id" : "shard0002", "host" : "127.0.0.1:60004" }
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
7 : Success
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "xxlongdb", "partitioned" : true, "primary" : "shard0000" }
xxlongdb.student
shard key: { "_id" : 1 }
chunks:
shard0000 2
shard0001 2
shard0002 2
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : ObjectId("55dac71e82b34018cdeafe77") } on : shard0002 Timestamp(6, 0)
{ "_id" : ObjectId("55dac71e82b34018cdeafe77") } -->> { "_id" : ObjectId("55dac74282b34018cdebec27") } on : shard0001 Timestamp(6, 1)
{ "_id" : ObjectId("55dac74282b34018cdebec27") } -->> { "_id" : ObjectId("55dac75382b34018cdec6300") } on : shard0002 Timestamp(5, 0)
{ "_id" : ObjectId("55dac75382b34018cdec6300") } -->> { "_id" : ObjectId("55daca037c517cdbbd57613f") } on : shard0000 Timestamp(5, 1)
{ "_id" : ObjectId("55daca037c517cdbbd57613f") } -->> { "_id" : ObjectId("55dacac17c517cdbbd58e238") } on : shard0000 Timestamp(3, 3)
{ "_id" : ObjectId("55dacac17c517cdbbd58e238") } -->> { "_id" : { "$maxKey" : 1 } } on : shard0001 Timestamp(4, 0)
{ "_id" : "xxlong", "partitioned" : false, "primary" : "shard0000" }
{ "_id" : "test", "partitioned" : false, "primary" : "shard0001" }
如果要添加的分片包含了分片的数据库集合,此时加入到分片集合中,会出错:
use admin
db.runCommand({addshard:"127.0.0.1:60004",allowLocal:true});
{
"ok" : 0,
"errmsg":"can't add shard 127.0.0.1:60004 because a local database'xxlongdb'exists in another shard0001:10.1.241.203:27018"
}
删除分片
登录路由服务器:
mongo 127.0.0.1:60001
use admin
db.runCommand({removeshard:"127.0.0.1:60004"});
{
"msg" : "draining started successfully",
"state" : "started",
"shard" : "shard0002",
"ok" : 1
}
use config
db.shards.find();
{ "_id" : "shard0000", "host" : "127.0.0.1:60002" }
{ "_id" : "shard0001", "host" : "127.0.0.1:60003" }
{ "_id" : "shard0002", "host" : "127.0.0.1:60004" }
printShardingStatus(db.getSisterDB("config"),1)
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("55d98773d222b86a3013e52c")
}
shards:
{ "_id" : "shard0000", "host" : "127.0.0.1:60002" }
{ "_id" : "shard0001", "host" : "127.0.0.1:60003" }
{ "_id" : "shard0002", "host" : "127.0.0.1:60004", "draining" : true }
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
9 : Success
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "xxlongdb", "partitioned" : true, "primary" : "shard0000" }
xxlongdb.student
shard key: { "_id" : 1 }
chunks:
shard0000 3
shard0001 3
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : ObjectId("55dac71e82b34018cdeafe77") } on : shard0000 Timestamp(7, 0)
{ "_id" : ObjectId("55dac71e82b34018cdeafe77") } -->> { "_id" : ObjectId("55dac74282b34018cdebec27") } on : shard0001 Timestamp(6, 1)
{ "_id" : ObjectId("55dac74282b34018cdebec27") } -->> { "_id" : ObjectId("55dac75382b34018cdec6300") } on : shard0001 Timestamp(8, 0)
{ "_id" : ObjectId("55dac75382b34018cdec6300") } -->> { "_id" : ObjectId("55daca037c517cdbbd57613f") } on : shard0000 Timestamp(5, 1)
{ "_id" : ObjectId("55daca037c517cdbbd57613f") } -->> { "_id" : ObjectId("55dacac17c517cdbbd58e238") } on : shard0000 Timestamp(3, 3)
{ "_id" : ObjectId("55dacac17c517cdbbd58e238") } -->> { "_id" : { "$maxKey" : 1 } } on : shard0001 Timestamp(4, 0)
{ "_id" : "xxlong", "partitioned" : false, "primary" : "shard0000" }
{ "_id" : "test", "partitioned" : false, "primary" : "shard0001" }
被删除的分片没有从config数据库的shards中删除,相反只是添加了一个属性draining:true
{ "_id" : "shard0001", "host" : "127.0.0.1:60003" }
{ "_id" : "shard0002", "host" : "127.0.0.1:60004", "draining" : true }
管理维护sharding
登录路由服务器:mongo 127.0.0.1:60001
use config
1、列出所有的shard server
db.runCommand({listshards:1});
2、查看sharding信息
printShardingStatus();
3、查看是否是sharding
db.runCommand({isdbgrid:1});
4、对现有表进行sharding
db.runCommand({"shardcollection":"xxlongdb.student","key":{"_id":1}});
use xxlongdb
db.student.status();
5、新增shard server
db.runCommand({addshard:"127.0.0.1:60004",allowLocal:true});
6、移除shard server
db.runCommand({removeshard:"127.0.0.1:60004"});