分类
MongoDB

一定不要用默认的设置运行MongoDB数据库,我的一次被黑经历

近几年,MongoDB应用越来越多,MongoDB也越来越火。

从2015年开始,MongoDB被一些「非 法 组 织/黑 客」盯上了。他们的做法也很简单,连到你的数据库上,把你的数据拿走,然后把你的库清空,留一个消息给你,索要比-特-币。

跟最近流行的勒赎病毒一个套路。

我在某个云上有一台服务器,主要用来做各种研究和测试,随时可以格了重装的那种。上面跑着一个MongoDB,是用默认的参数简单启动的一个单实例。

早上起来,跑程序测试时,程序直接报错。

跟踪代码,发现是头天写进去的数据不见了。

进到数据库,发现数据库都在,但里面的表全被清空了,多了一个Readme的表。查看这个表的内容:

> db.Readme.find().pretty()
{
        "_id" : "5c18d077fd42b92d8f6271c3",
        "BitCoin" : "3639hBBC8M7bwqWKj297Jc61pk9cUSKH5N",
        "eMail" : "[email protected]",
        "Exchange" : "https://localbitcoins.com",
        "Solution" : "Your database is downloaded and backed up on our secured servers. To recover your lost data: Send 0.2 BTC to our BitCoin address and Contact us by eMail with your server IP address and a proof of Payment. Any eMail without your IP address and a proof of Payment will be ignored. Your are welcome!"
}

简单来说,这是一个通知:你的数据被我们绑架了,想要赎回去,需要0.2个比-特-币。

一身冷汗。如果这是一个生产环境,如果这是一个系统的运营数据,后果不堪设想。

究其原因,这个数据库在启动时,用了默认的参数,未加任何防护。

所以,一定不要用默认的设置运行MongoDB数据库!一定不要用默认的设置运行MongoDB数据库!一定不要用默认的设置运行MongoDB数据库!

二、安全实践

1. 修改端口

MongoDB启动时,使用了几个默认的端口:

27017: 用于一般的单实例(mongod),或者集群中路由服务器(mongos)

27018: 用于集群中的分片服务器

27019: 用于集群中的配置服务器

实际布署时可以把默认端口换成别的端口。

命令行:

nbsp;./mongod --port port_number

配置文件:

port=port_number

2. 绑定IP

这个要区分一下MongoDB的版本。

查询MongoDB版本的命令:

nbsp;./mongod --version

在MongoDB Version 3.6之前,MongoDB启动时默认绑定到服务器的所有IP上。换句话说,通过所有的IP都可以访问数据库,这儿的安全隐患在于外网IP。

在3.6之后,MongoDB启动默认绑定127.0.0.1,从外网无法访问,去掉了这个隐患。

设置绑定IP,命令行:

nbsp;./mongod --bind_ip your_ip #单IP绑定
或
nbsp;./mongod --bind_ip your_ip1,your_ip2 #多IP绑定

配置文件:

bind_ip=your_ip #单IP绑定
或
bind_ip=your_ip1,your_ip2 #多IP绑定

MongoDB还提供了一个一次绑定所有IP的参数。命令行:

nbsp;./mongod --bind_ip_all

配置文件:

bind_ip_all=true

?

另外,绑定时,your_ip也可以换成域名your_host,效果是一样的。

在生产环境中,出于安全的需要,通常可以设置数据库绑定到服务器的内网IP,供数据层操作数据库就好。如果有特殊需要,可以临时绑定到外网IP,操作完成后再去掉。

数据库切换绑定IP和端口,对数据库本身没有任何影响。

3. 数据库服务器内部身份认证

数据库服务器的内部身份认证,是更高一个层次的安全策略,用于保证主从/复制集/集群中各个数据库服务器的安全合法接入。

内部身份认证,首先需要有一个数字密钥。

数字密钥可以使用机构签发的证书来生成,也可以使用自生成的密钥。

当然在低安全级别的情况下,你也可以随手写一个密钥来使用。

自生成密钥的生成命令:

nbsp;openssl rand -base64 756 > path_to_keyfile

然后设置密钥文件的读写权限:

nbsp;chmod 400 path_to_keyfile

看一下密钥文件:

nbsp;ls -l
-rw-r--r--  1 test  test  1024  5 10 17:51 test.key

下面,为数据库启用密钥文件。命令行:

nbsp;./mongod --keyFile path_to_keyfile

配置文件:

keyFile=path_to_keyfile

注意:

  • 内部认证用在多于一个服务器的情况,例如:主从/复制集/集群上,做服务器之间的互相认证。单个服务器可做可不做,实际上无效。
  • 内部认证要求认证的服务器使用相同的密钥文件。也就是说,所有的服务器使用同一个密钥文件。
  • 密钥文件有安全要求,文件权限必须是400,否则数据库启动时会有报错。

4. 用户和角色鉴权

MongoDB支持为数据库创建用户和分配角色,用用户和角色来管理和使用数据库。

MongoDB创建用户操作和上面不同。上边的内容,是在数据库运行以前进行,而创建用户,是在数据库运行以后。

nbsp;./mongo your_ip:your_port
> use admin
switched to db admin
> db.createUser({"user" : "user_name", "pwd" : "user_password","roles" : [{"role" : "userAdminAnyDatabase", "db" : "admin"}]})
Successfully added user: {
    "user" : "user_name",
    "roles" : [
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}

这样我们就加入了一个用户。

MongoDB内建的角色分以下几类:

  • 超级用户:root
  • 数据库用户角色:read、readWrite
  • 数据库管理角色:dbAdmin、dbOwner、userAdmin
  • 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager
  • 可操作所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
  • 备份、恢复角色:backup、restore

角色不详细解释了,角色名称的英文写的很明白。

在实际操作中,通常会将用户建在admin中,用roles里的db来指定用户可以使用或管理的数据库名称。

通过这一通操作,我们已经在数据库中创建好了用户。下面需要服务器启用鉴权。

命令行:

./mongod --auth

配置文件:

auth=true

这个用于mongod启动的数据库。对于集群的router,即mongos,会默认启用auth,所以不需要显式启用。

当MongoDB启用鉴权后,再用mongo客户端连接数据库,就需要输入用户帐号信息了。

nbsp;./mongo -u user_name -p user_password your_ip:your_port/admin
或
nbsp;./mongo -u user_name -p your_ip:your_port/admin #提示输入密码

同样,在代码中,数据库连接串也同步变成了:

"MongoConnection": "mongodb://user_name:[email protected]:27017/admin?wtimeoutMS=2000"

三、总结

一般来说,做完上面的安全处理,就可以完全满足生产环境的安全要求了。

再高的要求,可以通过启用TLS来强化。这会是另一个文章。

作者: Tiger.Wang

来源:https://www.cnblogs.com/tiger-wang/p/12864772.html

分类
MongoDB

【Linux】MongoDB简单介绍及常用命令分享(linux操作mongodb)

MongoDB介绍

MongoDB:介于关系数据库和非关系数据库之间,C++语言编写,分布式文件存储,可扩展的高性能数据存储,是一种NoSQL的数据库。

NoSQL:非关系型的数据库,Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称,可用于超大规模数据的存储。

数据存储为一个Document,数据结构由键值(key=>value)对组成。MongoDB文档类似于JSON对象,字段值可以包含其他文档、数组及文档数组,如下图所示:

{

name:"zhagsan",

age:"25",

groups:["news","sports"]

}

特点

面向文档存储,操作简单容易;

设置索引,实现快速排序;

本地或者网络创建数据镜像,优化MongoDB扩展性;

增加负载,分片处理;

丰富的查询表达式,查询指令使用JSON形式标记,可轻易查询文档中内嵌的对象及数组;

支持服务端脚本执行;

支持多种编程语言,如Ruby、Python、Java、C++、Php、C#等;

安装简单;

不支持表连接;

不支持事务操作;

文件存储格式为 BSON;

下载地址

官网下载地址https://www.mongodb.com/download-center/community

概念解析

database:数据库

collection:数据库集合,对应关系型数据库二维表。

document:数据文档,对应关系型数据库二维表中的每一行。

field:数据字段,对应关系型数据二维表中的每一列。

index:索引

primary key:主键,自动将_id设置为主键

{

"_id":"5dce64603ec49017b30d076a",

"nickname":"zhangsan",

"city":"Shanghai",

"age":"25",

"email":"[email protected]"

}

连接Database

MongoDB版本:3.4.7

ServerAddress serverAddress = new ServerAddress("127.0.0.1", 27017);
List<ServerAddress> addrs = new ArrayList<ServerAddress>();
addrs.add(serverAddress);
MongoCredential credential = MongoCredential.createScramSha1Credential("db_username", "db_database", "db_passwod".toCharArray());
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
credentials.add(credential);
MongoClient mongoClient = new MongoClient(addrs, credentials);
MongoDatabase mongoDatabase = mongoClient.getDatabase("db_database");

查询Collection

MongoCollection<Document> collection = mongoDatabase.getCollection("collection");
//去掉游标时间,数据量太大时,易造成时间超时
FindIterable<Document> findIterable = collection.find().noCursorTimeout(true);
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
Document doc = mongoCursor.next();
String value = (String)doc.get("field");
}

常用命令

mongo备份

mongodump备份数据库

./mongodump -h 127.0.0.1:27017 -u db_username -p db_password -d db_database -o /usr/local/backup

mongoexport备份csv collection

./mongoexport -d db_database --host 127.0.0.1:27017 --authenticationDatabase=db_database -u db_username -p db_password -c collection -o /usr/local/backup/collection.csv

mongoexport备份json collection

./mongoexport -d db_database --host 127.0.0.1:27017 --authenticationDatabase=db_database -u db_username -p db_password -c collection -o /usr/local/backup/collection.json

mongo恢复备份数据

mongorestore恢复备份的数据库

./mongorestore -h 127.0.0.1:27017 -u db_username -p db_password -d db_database /usr/local/backup

mongoimport恢复备份的json collection

./mongoimport --db db_database --host 127.0.0.1:27017 --authenticationDatabase=db_database -u db_username -p db_password --file /usr/local/backup/collection.json

mongorestore恢复备份的bson collection

./mongorestore -d db_database--host 127.0.0.1:27017 --authenticationDatabase=db_database-u db_username -p db_password /usr/local/backup/collection.bson

mongo查重

查重某一个field

db.collection.aggregate([{ $group: {"_id": { "field" : "$field"},count:{$sum:1}}}, {$match:{count:{$gte:2}}}],{ allowDiskUse: true });

索引

mongo建立唯一索引

db.collection.ensureIndex({field:1},{unique:true},{backgroud:true})

mongo建立索引

db.collection.ensureIndex({field:1})

db.collection.createIndex ({field:1})

mongo查看索引

db.collection.getIndexes()

mongo删除索引

db.collection.dropIndex({"field":1})

过期时间

mongo设置过期时间

db.collection.createIndex({'time': 1}, {expireAfterSeconds: 3600})

ok,以上就是【Linux】MongoDB简单介绍及常用命令分享,看完记得转发、点赞和收藏。想了解更多内容,请关注本小编,如果有错误,欢迎批评指正,感谢支持。

(云渺书斋)

分类
MongoDB

技术干货|如何在MongoDB中轻松使用GridFS?(连接mongodb的工具)

GridFS是用于存储和检索超过16 MB大小限制的BSON文档文件的规范。

注意

GridFS 不支持多文档事务

相较于将一个文件存储在单条文档中,GridFS将文件分为多个部分或块[1],并将每个块存储为单独的文档。默认情况下,GridFS使用的块默认大小为255kB;也就是说,除最后一个块,GridFS会将文件划分为255 kB的块。最后一个块只有必要的大小。同样,最后的那个块也不会大于默认的块大小,仅使用所需的空间以及一些其他元数据。

GridFS使用两个集合来存储文件。一个集合存储文件块,另一个集合存储文件元数据。 GridFS集合一节详细介绍了每个集合。

当你从GridFS查询文件时,驱动程序将根据需要重新组装该文件所有的块。你可以对GridFS存储的文件进行范围查询。你还可以从文件的任意部分访问其信息,例如“跳到”视频或音频文件的中间。

GridFS不仅可用于存储超过16 MB的文件,而且还可用于存储您要访问的任何文件而不必将整个文件加载到内存中。另请参阅何时使用GridFS。

什么时候使用GridFS

在MongoDB中,使用GridFS存储大于16 MB的文件。

在某些情况下,在MongoDB数据库中存储大型文件可能比在系统级文件系统上存储效率更高。

  • 如果文件系统限制了目录中文件的数量,则可以使用GridFS来存储所需数量的文件。
  • 当你要访问大文件部分的信息而不必将整个文件加载到内存中时,可以使用GridFS来调用文件的某些部分,而无需将整个文件读入内存。
  • 当你希望保持文件和元数据在多个系统和设施之间自动同步和部署时,可以使用GridFS。使用地理分布的复制集时,MongoDB可以自动将文件及其元数据分发到多个mongod实例和设施。

如果您需要对整个文件的内容进行原子更新,请不要使用GridFS。或者,您可以存储每个文件的多个版本,并在元数据中指定文件的当前版本。上传文件的新版本后,您可以原子更新元数据中指示为“最新”状态的字段,然后在需要时删除以前的版本。

此外,如果文件均小于16 MB BSON文档大小限制,请考虑将每个文件存储在单个文档中,而不是使用GridFS。您可以使用BinData数据类型存储二进制数据。有关使用BinData的详细信息,请参见驱动程序文档。

使用GridFS

要使用GridFS存储和检索文件,请使用以下任一方法:

  • MongoDB驱动程序。请参阅驱动程序文档,以获取有关将GridFS与驱动程序一起使用的信息。
  • mongofiles命令行工具。有关文档,请参见mongofiles参考。

GridFS Collections

GridFS将文件存储在两个集合中:

  • 块存储二进制块。有关详细信息,请参见chunks集合。
  • 文件存储文件的元数据。有关详细信息,请参见文件集合。

GridFS通过使用存储桶名称为每个集合添加前缀,将集合放置在一个公共存储桶中。默认情况下,GridFS使用两个集合以及一个名为fs的存储桶:

  • fs.files
  • fs.chunks

您可以选择其他存储桶名称,也可以在一个数据库中创建多个存储桶。完整集合名称(包括存储桶名称)受命名空间长度限制。

块集合

块[1]集合中的每个文档都代表了GridFS中表示的文件的不同的块。此集合中的文档具有以下格式:

{

  "_id" : <ObjectId>,

  "files_id" : <ObjectId>,

  "n" : <num>,

  "data" : <binary>

}

chunks集合中的文档包含以下字段:

  • chunks._id
  • 块的唯一ObjectId。
  • chunks.files_id
  • 在files集合中指定的“父”文档的_id。
  • chunks.n
  • 块的序列号。GridFS从0开始对所有块进行编号。
  • chunks.data
  • 块BSON二进制类型的荷载。

文件集合

文件集合中的每个文档代表GridFS中的一个文件。

{

  "_id" : <ObjectId>,

  "length" : <num>,

  "chunkSize" : <num>,

  "uploadDate" : <timestamp>,

  "md5" : <hash>,

  "filename" : <string>,

  "contentType" : <string>,

  "aliases" : <string array>,

  "metadata" : <any>,

}

files集合中的文档包含以下一些或全部字段:

  • files._id

该文档的唯一标识符。 _id是您为原始文档选择的数据类型。MongoDB文档的默认类型是BSON ObjectId。

  • files.length

文档的大小(以字节为单位)。

  • files.chunkSize

每个块的大小(以字节为单位)。GridFS将文档分为大小为chunkSize的块,最后一个除外,后者仅根据需要而变大。默认大小为255 KB。

  • files.uploadDate

GridFS首次存储这个文档的日期。此值为有日期类型。

  • files.md5

过期

FIPS 140-2禁止使用MD5算法。MongoDB驱动程序已弃用MD5支持,并将在未来版本中删除MD5的生成。需要文件摘要的应用程序应在GridFS外部实现它,并将其存储在files.metadata中。

filemd5命令返回的完整文件的MD5哈希。此值为字符串类型。

  • files.filename

可选的。GridFS文件的可读名称。

  • files.contentType

过期

可选的。GridFS文件的有效MIME类型。仅应用程序用。

使用files.metadata来存储与GridFS文件的MIME类型有关的信息。

  • files.aliases

过期

可选的。别名字符串数组。仅用于应用程序

使用files.metadata来存储与GridFS文件的MIME类型有关的信息。

  • files.metadata

可选的。元数据字段可以是任何数据类型,并且可以保存您要存储的任何其他信息。如果希望将其他任意字段添加到文件集合中的文档,请将其添加到元数据字段中的对象。

GridFS索引

GridFS使用每个块和文件集合上的索引来提高效率。为了方便起见,符合GridFS规范的驱动程序会自动创建这些索引。您还可以根据需要创建任何其他索引,以满足您的应用程序需求。

chunks索引

GridFS使用files_id和n字段在chunks集合上使用唯一的复合索引。可以有效地检索块,如以下示例所示:

db.fs.chunks.find( { files_id: myFileID } ).sort( { n: 1 } )

符合GridFS规范的驱动程序将在读取和写入操作之前自动确保此索引存在。有关GridFS应用程序的特定行为,请参阅相关的驱动程序文档。

如果该索引不存在,则可以执行以下操作以使用mongo shell创建它:

db.fs.chunks.createIndex( { files_id: 1, n: 1 }, { unique: true } );

files索引

GridFS在files集合上的filename和uploadDate字段上使用索引。该索引允许高效地检索文件,如本示例所示:

db.fs.files.find( { filename: myFileName } ).sort( { uploadDate: 1 } )

符合GridFS规范的驱动程序将在读取和写入操作之前自动确保此索引存在。有关GridFS应用程序的特定行为,请参阅相关的驱动程序文档。

如果该索引不存在,则可以执行以下操作以使用mongo shell创建它:

db.fs.files.createIndex( { filename: 1, uploadDate: 1 } );

[1]

(1, 2) 在GridFS上下文中使用术语块与在分片上下文中使用术语块无关。

分片GridFS

GridFS考虑两个集合-files和chunks。

chunks集合

要分片chunks集合,请使用{ files_id : 1, n : 1 } 或{ files_id : 1 } 作为分片键索引。files_id是一个ObjectId,并且单调更改。

对于不运行filemd5来验证成功上传的MongoDB驱动程序(例如,支持MongoDB 4.0或更高版本的MongoDB驱动程序),可以将哈希分片用于chunks集合。

如果MongoDB驱动程序运行filemd5,则不能使用Hashed Sharding。有关详细信息,请参阅SERVER-9888。

files集合

files集合很小,仅包含元数据。GridFS所需的所有密钥都不适合在分片环境中进行平均分配。保留未分片的files允许所有文件元数据文档保留在主分片上。

如果必须分片files集合,请使用_id字段,可能与应用程序字段结合使用。

原文链接:

https://github.com/mongodb-china/MongoDB-CN-Manual/blob/master/cun-chu/gridfs.md

关于作者:张琦

Java 开发工程师,陕西西安。

分类
MongoDB

MongoDB运维相关命令介绍(mongodb运维实战)

1、在线释放内存

use admin

db.runCommand({closeAllDatabases:1})

注:3.2 版本 已经去掉了这个命令了

2.rs.status()

查询复制集状态

3.db.stats()

查询指定库的状态(包含内存和磁盘的使用情况统计)

4.db.collectionsname.stats()

查询指定集合的具体信息

5.db.version()

查看当前实例的版本

6.db.getCollectionNames();

获取当前数据库下所有集合的名称

7.集合数据的导出/导入

mongoexport / mongoimport

8.数据库的备份与还原

mongodump 和 mongorestore

9.db.serverStatus()

服务器统计信息

10.db.currentOp()

统计当前运行的操作

db.currentOp(‘ture’)

包含空闲的操作

11.mongostat

诊断工具,用来统计全局系统信息

定时轮询并显示统计从每秒插入的数量到内存的使用量,再到B-树叶缺失的频率等信息。

登入当时,在bin文档下执行

1

./mongostat -h 主机IP:端口 -u用户名 –authenticationDatabase 登入验证的数据库

12.mongotop

mongotop是top命令的外部包装工具,其运行方式与mongostat 一样。

分类
MongoDB

Linux Centos 7安装MongoDB(简单!详细!)(Ubuntu安装mongodb)

Yum源

使用 概括几个常用的:

// 1 安装 
yum install package  // 安装指定的安装包package 

// 2 更新和升级 
yum update  // 全部更新 
yum update package  // 更新指定程序包package
yum check-update  // 检查可更新的程序 
yum upgrade package  // 升级指定程序包package 

// 3 查找和显示 
yum info // 列出所有可以安装或更新的包的信息
yum info package //显示安装包信息package 
yum list // 显示所有已经安装和可以安装的程序包 
yum list package  // 显示指定程序包安装情况package
yum search package // 搜索匹配特定字符的package的详细信息

// 4 删除程序 
yum remove | erase package  // 删除程序包package
yum deplist package  // 查看程序package依赖情况

// 5 清除缓存 
yum clean packages  // 清除缓存目录下的软件包 
yum clean headers // 清除缓存目录下的 headers 
yum clean oldheaders // 清除缓存目录下旧的 headers 
yum clean, yum clean all  // (= yum clean packages; yum clean oldheaders) 清除缓存目录下的软件包及旧的headers

安装Mongodb

配置系统yum源

1. 创建.repo文件,生成mongodb的源

vi /etc/yum.repos.d/mongodb-org-4.0.repo

2. 添加以下配置信息:

[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/#releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc

详解:

name         # 名称
baseurl      # 获得下载的路径
gpkcheck=1   # 表示对从这个源下载的rpm包进行校验;
enable=1     # 表示启用这个源。
gpgkey       # gpg验证

3. 保存退出

wq # 退出保存

使用yum安装MongoDB

1. 安装MongoDB

sudo yum install -y mongodb-org

2. 验证安装结果 rpm -qa |grep mongodb 复制代码 rpm -ql mongodb-org-server 复制代码

3. 启动MongoDB

启动MongoDB服务

systemctl start mongod.service

MongoDB默认端口是27017,查看是否开启

netstat -natp | grep 27017

检查数据库是否安装成功

ps -aux | grep mongod    # 查看数据库的进程是否存在

4. 验证服务开启 mongo 复制代码

常用命令清单

// 1、开启MongoDB
sudo service mongod start  或者 systemctl start mongod.service  # 开启MongoDB
sudo chkconfig mongod on  # 加入开机启动
sudo service mongod restart # 重启MongoDB

// 2、关闭MongoDB
sudo service mongod stop  # 关闭防火墙

// 3、卸载MongoDB
sudo yum erase $(rpm -qa | grep mongodb-org)    # 卸载MongoDB
sudo rm -r /var/log/mongodb  # 删除日志文件
sudo rm -r /var/lib/mongo    # 删除数据文件

远程连接Mongodb

1. 修改配置文件mongodb.conf

vi /etc/mongod.conf

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.

修改绑定ip默认127.0.0.1只允许本地连接, 所以修改为bindIp:0.0.0.0, 退出保存

2. 重启mongodb服务

sudo service mongod restart 

3. 开放对外端口

方法一

systemctl status firewalld  # 查看防火墙状态
firewall-cmd --zone=public --add-port=27017/tcp --permanent # mongodb默认端口号
firewall-cmd --reload  # 重新加载防火墙

firewall-cmd --zone=public --query-port=27017/tcp # 查看端口号是否开放成功,输出yes开放成功,no则失败

方法二

iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 27017 -j ACCEPT

4. 远程连接

默认连接

mongo 10.128.218.14:27017
复制代码

连接到自定义的用户

  1. 创建用户,设置账号,密码,权限 // admin数据库 use admin switched to db admin db.createUser({ user:"root", pwd:"123456", roles:["root"] }) Successfully added user: { "user" : "root", "roles" : [ "root" ] } // 其他数据库 use test switched to db test db.createUser({ user:"admin", pwd:"123456", roles:["readWrite", "dbAdmin"] }) Successfully added user: { "user" : "root", "roles" : [ "root" ] } 复制代码
  2. 修改mongodb.conf文件,启用身份验证 vi /etc/mongod.conf security: authorization: "enabled" # disable or enabled 复制代码
  3. 重启MongoDB sudo service mongod restart 复制代码
  4. 用户认证 use admin switched to db admin db.auth("root", "123456") 1 // 授权成功 复制代码 // 其他常用命令 db.updateUser(user, writeConcern) # 更新用户 db.dropUser('test') # 删除用户 复制代码
  5. 远程连接 // 终端连接 mongo 10.128.218.14:27017/database -u username -p password // mongoose方式连接 mongoose.connect('mongodb://username:[email protected]:port/database?options…', {useNewUrlParser: true}); // 通过客户端连接 复制代码

用户权限角色说明

规则

说明

root

只在admin数据库中可用。超级账号,超级权限

Read

允许用户读取指定数据库

readWrite

允许用户读写指定数据库

dbAdmin

允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile

userAdmin

允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户

clusterAdmin

只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限

readAnyDatabase

只在admin数据库中可用,赋予用户所有数据库的读权限

readWriteAnyDatabase

只在admin数据库中可用,赋予用户所有数据库的读写权限

userAdminAnyDatabase

只在admin数据库中可用,赋予用户所有数据库的userAdmin权限

dbAdminAnyDatabase

只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限

https://juejin.cn/post/6844903828811153421

分类
MongoDB

MongoDB安装(mongodb安装失败如何彻底删除)

时光闹钟app开发者,请关注我,后续分享更精彩!

坚持原创,共同进步!

概述

MongoDB是一个可扩展,高性能,开源,面向文档的,基于键/值类型的数据库。非常适合保存大对象及json格式的数据。本文将介绍MongoDB的单机和集群副本安装,记录下来以备后用。希望对有需要的朋友有所帮助和参考。

下载地址

# 历史产品和版本选择
https://www.mongodb.com/docs/legacy/

# 3.6版本文档地址
https://www.mongodb.com/docs/v3.6/

安装方式

  • StandAlone:单机环境,一般开发测试的时候用。
  • Replication:主从结构,一个Primary,多个Secondary,可能会有Arbitry。
- Primary挂掉之后,会选举出一个Secondary作为Primary,与zookeeper类似。
- Arbitry(仲裁节点)上面不存数据,只是为了凑数。选举算法要求节点数必须是奇数个,如果Primary+Secondary不是奇数个,就要用Arbitry凑数。
- 写数据只能在Primary,读数据默认也在Primary,可以配置成从Secondary读,可以选最近的节点。
- 数据在Primary上写成功之后,会将操作记录在oplog中,Secondary将oplog拷贝过去,然后照着操作一遍,就有数据了。
- Primary和Secondary上面的数据保证最终一致性,可以为写操作配置write concern,有几个级别:在Primary上写完就认为写成功;写到oplog后认为写成功;写到一个/多个/某个/某几个Secondary之后认为写成功,等等。
  • Sharding:share nothing的结构,每台机器只存一部分数据。mongod服务器存数据,mongos服务器负责路由读写请求,元数据存在config数据库中。

安装&准备

centos 系统 yum源创建

cat >/etc/yum.repos.d/mongodb-org-3.6.repo<<eof
[mongodb-org-3.6]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/6Server/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc
eof

根据具体情况,选择版本安装

# 安装最近版本
# sudo yum install -y mongodb-org

# 安装指定版本
sudo yum install --disablerepo=kubernetes -y mongodb-org-3.6.8 mongodb-org-server-3.6.8 mongodb-org-shell-3.6.8 mongodb-org-mongos-3.6.8 mongodb-org-tools-3.6.8

StandAlone安装配置

默认配置文件/etc/mongod.conf

- storage.dbPath 数据存储目录
- systemLog.path 系统日志目录
- net.bindIp 访问ip绑定,默认127.0.0.1。需要外部机器连接时,需调整成新人的访问源ip,或者测试所有ip放开0.0.0.0

启动MongoDB

sudo systemctl start mongod
# 如果启动报如下报错
# Failed to start mongod.service: Unit mongod.service not found.
# 启动以下命令
# sudo systemctl daemon-reload

查看MongoDB状态

sudo systemctl status mongod
# 如果想要重启系统MongoDB服务自动启动,可设置以下命令
# sudo systemctl enable mongod

停止MongoDB

sudo systemctl stop mongod

重启MongoDB

sudo systemctl restart mongod

连接MongoDB

mongo --host 127.0.0.1:27017

Replication安装

参考文档

官方文档:https://www.mongodb.com/docs/v3.6/administration/replica-set-deployment/

环境

3个节点分别安装MongoDB实例

修改/etc/mongod.conf以下配置项:

#replica set的名字
replication:
   replSetName: "rs0"
   
#client访问ip绑定,开发测试0.0.0.0所有ip   
net:
   bindIp: localhost,<ip address>  

分别在3个节点上启动MongoDB服务

sudo systemctl start mongod
# 如果启动报如下报错
# Failed to start mongod.service: Unit mongod.service not found.
# 启动以下命令
# sudo systemctl daemon-reload

Initiate the replica set(初始化副本集)

任意一个节点控制台登录MongoDB

[[email protected] ~]# mongo
MongoDB shell version v3.6.8
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.8
Server has startup warnings:
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten]
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten]
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten]
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten]
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten]
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 4096 processes, 64000 files. Number of processes should be at least 32000 : 0.5 times number of files.
2022-05-11T09:36:02.035+0800 I CONTROL  [initandlisten]
>

初始化副本集。 注:只需在集群一台机器上执行初始化命令。

rs.initiate( {
   _id : "rs0",
   members: [
      { _id: 0, host: "dev2:27017" },
      { _id: 1, host: "dev3:27017" },
      { _id: 2, host: "dev4:27017" }
   ]
})

执行结果如下:

> rs.initiate( {
...    _id : "rs0",
...    members: [
...       { _id: 0, host: "dev2:27017" },
...       { _id: 1, host: "dev3:27017" },
...       { _id: 2, host: "dev4:27017" }
...    ]
... })
{
        "ok" : 1,
        "operationTime" : Timestamp(1653010782, 1),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1653010782, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

查看配置结果:控制台执行以下指令

rs.conf()

附录

# 历史产品和版本选择
https://www.mongodb.com/docs/legacy/

# 3.6版本文档地址
https://www.mongodb.com/docs/v3.6/

#官方文档:
https://www.mongodb.com/docs/v3.6/administration/replica-set-deployment/

# 3.6社区版centos安装文档
https://www.mongodb.com/docs/v3.6/tutorial/install-mongodb-on-red-hat/

# MongoDB集群安装
https://www.cnblogs.com/seasonzone/p/3820762.html

分类
MongoDB

mongodb添加用户、用户授权和安全设置

先给个mongodb的下载地址,你可以先下载然后看下面的故事,如果你已经下载请忽略。下载地址:https://www.mongodb.com/download-center#community 之所以给出这个地址,主要是因为我个人也不能一下子就找到它,Google 搜索 mongodb 点进去后并没有社区版的下载地址。

我第一次接触mongodb是15年,在此之前使用的基本是mysql和sqlite,而平时的工作中关系型数据结构很多,文档型数据库显得力不从心,而我对mysql的性能优化理解的非常有限,所以果断跑去用mariadb 了。说得简单点,我是为了联合查询才用了mysql,但是,在之后的工作中,我不止一次发现mysql性能低下,即使是使用了mariadb 性能也不见得好多少,现在,我非常不建议你使用联合查询,因为联合查询会导致缓存没用,比如我现在的 别样网 首页有很多图片和作者信息,这个数据结构很简单,一张用户表,一张作品表,一张作品子项表,用户没登录则3张表联合查询,用户登录了则再查询下用户是否已经收藏,即4张表联合查询。说了这么多,打个广告,别样网是免费无版权高清图片共享平台。当有4张表联合查询的时候,sql语句不变的可能性很低,所以mysql的缓存基本是用不上,而如果分4次查询,至少每次查询的sql语句一样,会用到缓存,尤其是我们日活6000-7000呢,这样子的优化表现的非常明显。另外,我重构了架构,统一用户管理,那么别样网的数据库里其实是没有用户信息的,简单的说做了垂直分库,联合查询没鸟用。所以,我建议你将联合查询分离,扯淡结束,接入主题。

我下载的是3.6.3版本,并解压到了/opt/mongodb 然后在 /etc/profile 里加入了

export PATH=$PATH:/opt/mongodb/mongodb-3.6.3/bin

安装完毕,现在启动并添加用户: mongod –dbpath /opt/mongodb/data 这将启动数据库并将数据存储在/opt/mongodb/data目录里,请确保这个目录存在。接着输入 mongo,然后输入 use admin,一下是一些命令:

查看已有用户:db.system.users.find()

删除一个用户:db.system.users.remove({user:”test”})

添加管理员:db.createUser({user:”root”,pwd:”root”,roles:[{role:”readWrite”,db:”admin”}]})

修改密码:db.changeUserPassword(“username”, “xxx”)

添加一个普通用户,先use test 然后

db.createUser({user:”root”,pwd:”root”,roles:[{role:”readWrite”,db:”test”}]}) 创建普通用户你需要先切换到他的数据库,然后创建,而创建超级管理员,你需要切换到admin,安全方面,我只提几点。

首先,必须使用 auth ,如果用 mongod –dbpath /opt/mongodb/data 命令启动,那么是不需要授权的,这很危险,可以通过 mongod –dbpath /opt/mongodb/data –auth 的方式启动。

接着不要监听所有 0.0.0.0 监听来自127.0.0.1 的连接即可,其次使用ssl,避免中间人攻击,最后一点给用户仅仅必要的权限,而不是所有权限。

如果你觉得有用记得收藏哦,也可以转发让更多的人看到,ps,可以点击 左下角 了解更多 阅读优化排版的版本。您的支持,是我持续创作的动力。

分类
MongoDB

技术干货|MongoDB时间序列集合

名词解释

Glossary

bucket:带有相同的元数据且在一段有限制的间 隔区间内的测量值组。

bucket collection :用于存储时序型集合的底层的分组桶的系统集合。复制、分片和索引都是在桶级别上完成的。

measurement:带有特定时间序列的K-V集合。

meta-data:时序序列里很少随时间变化的K-V对,同时可以用于识别整个时序序列。

time-series:一段间隔内的一系列测量值。

time-series collection:一种表示可写的非物化的视图的集合类型,它允许存储和查询多个时间序列,每个序列可以有不同的元数据。

MongoDB 在5.0中支持了新的timeseries collection类型的选项,该类型用于存储时序型数据。timeseries collection提供了一组用于插入和查询测量值的简单接口,同时底层实际的数据是存储在以bucket形式的集合中。

在创建timeseries collection时,timeField字段是最小必备的配置项。metaField是另一个可选的、可被指定的元数据字段,它是用于在bucket中对测量值分组的依据。MongoDB通过提供expireAfterSeconds字段选项,也支持了对测量值的过期机制。

mydb数据库中有个以mytscoll 命名的timeseries collection,该集合在MongoDB内部的catelog(用于存储集合或视图的信息)里是由一个视图和一个系统集合组成的。

  • mydb.mytscoll 是个视图,它在MongoDB底层是用bucket collection作为包含特定属性的原始集合实现的:
    • 该视图就是通过aggregation里的$_internalUnpackBucket来实现展开bucket里数据的。
    • 该视图是可写的(仅支持插入)。同时每个被插入的文档必须包含时间字段。
    • 在查询视图时,它会隐式地展开底层在bucket collection中存储的数据,然后返回原始的非bucket形式的文档数据。
  • 该系统集合的命名空间是mydb.system.buckets.mytscoll,它是用来存储实际数据的。
    • 每一个在bucket collection里的文档,都表示了一组区间间隔的时序型数据。
    • 如果在创建timeseries collection时,定义了metaField元数据字段,那么所有在bucket里的测量值都会有这个通用的元数据字段。
    • 除了时间范围,bucket还限制了每个文档数据的总条数以及测量值的大小。

Bucket Collection Schema

{
    _id: <Object ID with time component equal to control.min.<time field>>,
    control: {
        // <Some statistics on the measurements such min/max values of data fields>
        version: 1,  // Version of bucket schema. Currently fixed at 1 since this is the
                     // first iteration of time-series collections.
        min: {
            <time field>: <time of first measurement in this bucket, rounded down based on granularity>,
            <field0>: <minimum value of 'field0' across all measurements>,
            <field1>: <maximum value of 'field1' across all measurements>,
            ...
        },
        max: {
            <time field>: <time of last measurement in this bucket>,
            <field0>: <maximum value of 'field0' across all measurements>,
            <field1>: <maximum value of 'field1' across all measurements>,
            ...
        },
        closed: <bool> // Optional, signals the database that this document will not receive any
                       // additional measurements.
    },
    meta: <meta-data field (if specified at creation) value common to all measurements in this bucket>,
    data: {
        <time field>: {
            '0', <time of first measurement>,
            '1', <time of second measurement>,
            ...
            '<n-1>': <time of n-th measurement>,
        },
        <field0>: {
            '0', <value of 'field0' in first measurement>,
            '1', <value of 'field0' in first measurement>,
            ...
        },
        <field1>: {
            '0', <value of 'field1' in first measurement>,
            '1', <value of 'field1' in first measurement>,
            ...
        },
        ...
    }
}

索引

indexes

为了保证timeseries collection的查询可以受益于索引扫描而不是全表扫描,timeseries collection允许索引可以被创建在时间上,元数据上以及元数据的子属性上。从MongoDB5.2开始,在timeseries collection也允许索引被创建在测量值上。用户使用createIndex命令提供的索引规范被转换为底层buckets collection的模式。

  • timeseries collection与底层的buckets collection之间的索引映射转换关系细节,你可以参考timeseries_index_schema_conversion_functions.h.
  • 在v5.2及以上版本的最新支持的索引类型,timeseries collection会存储用户原始的索引定义到变换后的索引定义上。当从底层的bucket collection的索引映射到timeseries collections的索引时,会返回用户原始的索引定义。

当索引被创建后,可以通过listIndexes命令或$indexStats聚合计划来检查。listIndexes$indexStats是作用于timeseries collections的,执行时,它们会在内部将底层的bucket collection的索引转化成timeseries格式的索引,并返回。比如,当我们在元数据字段中定义有mmtimeseries collection上执行listIndexes命令时,底层的bucket collection{meta:1}索引,将会以{mm:1}格式返回。

dropIndexcollMod (hidden: <bool>, expireAfterSeconds: <num>) 也同样支持在timeseries collection上。

时间字段上支持的索引类型:

  • 单字段索引
  • 组合索引
  • 哈希索引
  • 通配符索引
  • 稀疏索引
  • 多键索引
  • 带排序的索引

元数据字段和元数据子字段支持的索引类型:

  • 支持所有时间字段上支持的索引类型
  • v5.2及以上版本支持2d 索引
  • v5.2及以上版本支持2dsphere 索引
  • v5.2及以上版本支持 Partial索引

仅在v5.2及以上版本,测量值字段支持的索引类型:

  • 单字段索引
  • 组合索引
  • 2dsphere
  • 部分条件索引

`timeseries collections 上不支持的索引类型,包括 唯一索引以及文本索引。

桶目录

Catalog

为了保证高效地桶(分组)操作,我们在BucketCatalog里维护了一组开启的桶,你可以在bucket_catalog.h找到。在更高的级别,我们尝试着把并发写程序的写操作分组合并为可以一起提交地批处理,以减少对底层文档的写次数。写程序会插入它的输入批处理里的每一个文档到BucketCatalog,然后BucketCatalog会返回一个BucketCatalog::WriteBatch的处理器。一旦完成上面那些插入操作后,写程序就会检查每个写批处理。如果没有其他的写程序已经对批处理声明提交的权利,那么它会声明权利,并会提交它的批处理。否则,写程序将会稍后再提交处理。当它检查完所有的批处理,写程序将会等待其他的写程序提交每个剩下的批处理。

在内部,BucketCatalog维护一组对每个bucket 文档的更新操作。当批处理被提交时,它会将这些插入转换到成buckets的列格式,并确保任何control字段的更新(例如control.mincontrol.max)。

bucket文档在没有通过BucketCatalog的情况下被更新时,写程序就需要为有问题的文档或命名空间去调用BucketCatalog::clear ,这样它就可以更新它的内部状态,避免写入任何可能破坏bucket 格式的数据。这通常由OP观察者处理,但可能需要通过其他地方去调用。

bucket既可以通过手动设置选项control.closed 标识来关闭,也可以在许多场景下通过 BucketCatalog 自动关闭。如果BucketCatalog使用了超出给定的阈值(可通过服务器参数timeseriesIdleBucketExpiryMemoryUsageThreshold控制)的更多内存,此时它将会开始去关闭空闲的bucket。如果bucket是开启的且它没有任何未处于等待中未提交的测量值时,那么它就会被视为空闲的bucket。在下面这些场下 BucketCatalog 也会关闭bucket: 如果它拥有超过最大阈值(timeseriesBucketMaxCount)的测量值数据的数量;如果它拥有过大的数据量大小(timeseriesBucketMaxSize);又或者一个新的测量值数据是否是会导致bucket在其最旧的时间戳和最新的时间戳之间跨度比允许的间隔更长的时间(当前硬编码为一小时)。如果传入的测量值在原理上与已经到达给定bucket的度量不兼容,该bucket将被关闭,同时可以使用numBucketsClosedDueToSchemaChange度量进行跟踪。

在第一次提交给定bucket的写批处理时,就会生成新的完整的文档。后续的批处理提交中,我们只执行更新操作,不再生成新的完整的文档(因此称为‘经典’更新),是直接创建DocDiff(“delta”或者v2的更新)。

粒度

Granularity

timeseries collectiongranularity 选项在集合创建的时候,可以被设置成secondsminutes或者hours。后期可通过colMod操作来修改这个选项从secondsminutes或者从minuteshours,除此之外的转化修改目前都是不支持的。该参数想要表示在已给定的时序型测量数据之间的粗略的时间间隔,同时也用于调节其他内部参数对分组的影响。

单个bucket被允许的最大时间跨度,是由granularity选项控制,对于seconds,最大的时间跨度被设置成1小时,对于minutes就是24小时,对于hours就是30天。

当通过BucketCatalog开启新的bucket时,_id里的时间戳就是等同于control.min.<time field>的值,该值是从第一个插入bucket的测量数据中根据granularity选项来向下近似舍入而得到的。对于seconds,它将向下舍入到最接近的分钟,对于minutes,将向下舍入到最接近的小时,对于hours,它将向下舍入到最接近的日期。在闰秒和日历中的其他不规则情况下,这种舍入可能并不完美,并且通常通过对自纪元以来的秒数进行基本模运算来完成,假设每分钟 60 秒,每小时 60 分钟,以及每天 24 小时。

更新和删除

timeseries collection 支持符合以下限制的删除语句:

  • 仅支持metaField的属性的查询语句
  • 支持批量操作

同时更新满足上面同样的条件,另外遵循:

  • 仅支持metaField对应的属性值
  • 更新操作指定一个带有更新运算符表达式的更新文档(而不是替换文档或者更新的pipeline操作)
  • 不支持upsert:true 操作

这些更新与删除的执行都会被转换成相对应的底层的bucket collection的更新或删除操作。特别是,对于查询和更新文档,我们会使用真正的字段meta 替换集合的metaField。(参见 Bucket 集合规范)

例如,对于一个使用 metaField: "tag"创建的timeseries集合db.ts,考虑一个对这个集合的更新操作,其查询语句是{"tag.tag.a": "a"} ,同时更新文档语句是 {$set: {"tag.tag.a": "A"}, $rename: {"tag.tag.b": "tag.tag.c"}}。这个更新操作在 db.system.buckets.ts上会被转换成,查询语句是{"meta.tag.a": "a"},更新语句是 {$set: {"meta.tag.a": "A"}, $rename: {"meta.tag.b": "meta.tag.c"}}。然后这个转换后的更新语句就可以像普通的更新操作一样执行。上面这些转换流程也适用于删除操作。

参考文献

References

MongoDB Blog: Time Series Data and MongoDB: Part 2 – Schema Design Best Practices

关于作者:黄璜

目前就职于上海DerbySoft,主要从事基础架构中业务流程设计及研发的工作,平时工作中MongoDB使用的较多。
在提升自己外文的能力的同时,也希望为社区做出微小的贡献。

社区招募为了让社区组委会成员和志愿者朋友们灵活参与,同时我们为想要深度参与社区建设的伙伴们开设了“招募通道”,如果您想要在社区里面结交志同道合的技术伙伴,想要通过在社区沉淀有价值的干货内容,想要一个展示自己的舞台,提升自身的技术影响力,即刻加入社区贡献队伍~ 点击链接提交申请:http://mongoingmongoing.mikecrm.com/CPDCj1B

分类
MongoDB

建议收藏!Linux运维必备之nginx、mysql、es、mongodb实用笔记

nginx{

        yum install -y make gcc  openssl-devel pcre-devel  bzip2-devel libxml2 libxml2-devel curl-devel libmcrypt-devel libjpeg libjpeg-devel libpng libpng-devel openssl

        groupadd nginx
        useradd nginx -g nginx -M -s /sbin/nologin

        mkdir -p /opt/nginx-tmp

        wget http://labs.frickle.com/files/ngx_cache_purge-1.6.tar.gz
        tar fxz ngx_cache_purge-1.6.tar.gz
        # ngx_cache_purge 清除指定url缓存
        # 假设一个URL为 http://192.168.12.133/test.txt
        # 通过访问      http://192.168.12.133/purge/test.txt  就可以清除该URL的缓存。

        tar zxvpf nginx-1.4.4.tar.gz
        cd nginx-1.4.4

        # ./configure --help
        # --with                 # 默认不加载 需指定编译此参数才使用
        # --without              # 默认加载,可用此参数禁用
        # --add-module=path      # 添加模块的路径
        # --add-module=/opt/ngx_module_upstream_check \         # nginx 代理状态页面
        # ngx_module_upstream_check  编译前需要打对应版本补丁 patch -p1 < /opt/nginx_upstream_check_module/check_1.2.6+.patch
        # --add-module=/opt/ngx_module_memc \                   # 将请求页面数据存放在 memcached中
        # --add-module=/opt/ngx_module_lua \                    # 支持lua脚本 yum install lua-devel lua

        ./configure \
        --user=nginx \
        --group=nginx \
        --prefix=/usr/local/nginx \
        --with-http_ssl_module \
        --with-http_realip_module \
        --with-http_gzip_static_module \
        --with-http_stub_status_module \
        --add-module=/opt/ngx_cache_purge-1.6 \
        --http-client-body-temp-path=/opt/nginx-tmp/client \
        --http-proxy-temp-path=/opt/nginx-tmp/proxy \
        --http-fastcgi-temp-path=/opt/nginx-tmp/fastcgi \
        --http-uwsgi-temp-path=/opt/nginx-tmp/uwsgi \
        --http-scgi-temp-path=/opt/nginx-tmp/scgi

        make && make install

        /usr/local/nginx/sbin/nginx –t             # 检查Nginx配置文件 但并不执行
        /usr/local/nginx/sbin/nginx -t -c /opt/nginx/conf/nginx.conf  # 检查Nginx配置文件
        /usr/local/nginx/sbin/nginx                # 启动nginx
        /usr/local/nginx/sbin/nginx -s reload      # 重载配置
        /usr/local/nginx/sbin/nginx -s stop        # 关闭nginx服务

    }


    elasticsearch{

        vim /etc/sysctl.conf
        vm.max_map_count = 262144

        vim /etc/security/limits.conf
        * soft memlock unlimited
        * hard memlock unlimited
        sysctl -p

        curl 'localhost:9200/_cat/health?v'                    # 健康检查
        curl 'localhost:9200/_cat/nodes?v'                     # 获取集群的节点列表
        curl 'localhost:9200/_cat/indices?v'                   # 列出所有索引
        curl 127.0.0.1:9200/indexname -XDELETE                 # 删除索引
        curl -XGET http://localhost:9200/_cat/shards           # 查看分片
        curl '127.0.0.1:9200/_cat/indices'                     # 查分片同步  unassigned_shards  # 没同步完成

    }


    mysql常用命令{

        # mysql 可视化工具 MySQL Workbench

        mysqlcheck -uroot -p -S mysql.sock --optimize --databases account       # 检查、修复、优化MyISAM表
        mysqlbinlog slave-relay-bin.000001              # 查看二进制日志
        mysqladmin -h myhost -u root -p create dbname   # 创建数据库

        flush privileges;             # 刷新
        show databases;               # 显示所有数据库
        use dbname;                   # 打开数据库
        show tables;                  # 显示选中数据库中所有的表
        desc tables;                  # 查看表结构
        drop database name;           # 删除数据库
        drop table name;              # 删除表
        create database name;         # 创建数据库
        select column from table;     # 查询
        show processlist;             # 查看mysql进程
        show full processlist;        # 显示进程全的语句
        select user();                # 查看所有用户
        show slave status\G;          # 查看主从状态
        show variables;               # 查看所有参数变量
        show status;                  # 运行状态
        show table status             # 查看表的引擎状态
        show grants for [email protected]'%'                                    # 查看用户权限
        drop table if exists user                                   # 表存在就删除
        create table if not exists user                             # 表不存在就创建
        select host,user,password from user;                        # 查询用户权限 先use mysql
        create table ka(ka_id varchar(6),qianshu int);              # 创建表
        show variables like 'character_set_%';                      # 查看系统的字符集和排序方式的设定
        show variables like '%timeout%';                            # 查看超时相关参数
        delete from user where user='';                             # 删除空用户
        delete from user where user='sss' and host='localhost' ;    # 删除用户
        drop user 'sss'@'localhost';                                # 使用此方法删除用户更为靠谱
        ALTER TABLE mytable ENGINE = MyISAM ;                       # 改变现有的表使用的存储引擎
        SHOW TABLE STATUS from  dbname  where Name='tablename';     # 查询表引擎
        mysql -uroot -p -A -ss -h10.10.10.5 -e "show databases;"    # shell中获取数据不带表格 -ss参数
        CREATE TABLE innodb (id int, title char(20)) ENGINE = INNODB                     # 创建表指定存储引擎的类型(MyISAM或INNODB)
        grant replication slave on *.* to 'user'@'%' identified by 'pwd';                # 创建主从复制用户
        ALTER TABLE player ADD INDEX weekcredit_faction_index (weekcredit, faction);     # 添加索引
        alter table name add column accountid(column)  int(11) NOT NULL(column);         # 插入字段
        update host set monitor_state='Y',hostname='xuesong' where ip='192.168.1.1';     # 更新数据
        select * from information_schema.processlist where command!='sleep';             # 查看当前进程
        select * from atable where name='on' AND t<15 AND host LIKE '10%' limit 1,10;    # 多条件查询
        show create database ops_deploy;                                                 # 查看数据库编码
        show create table updatelog;                                                     # 查看数据库表编码
        alter database ops_deploy CHARACTER SET utf8;                                    # 修改数据库编码
        alter table `updatelog` default character set utf8;                              # 修改表编码
        alter table `updatelog` convert to character set utf8;                           # 修改一张表的所有字段的编码格式

        自增表{

            create table xuesong  (id INTEGER  PRIMARY KEY AUTO_INCREMENT, name CHAR(30) NOT NULL, age integer , sex CHAR(15) );  # 创建自增表
            insert into xuesong(name,age,sex) values(%s,%s,%s)  # 自增插入数据

        }

        登录mysql的命令{

            # 格式: mysql -h 主机地址 -u 用户名 -p 用户密码
            mysql -h110.110.110.110 -P3306 -uroot -p
            mysql -uroot -p -S /data1/mysql5/data/mysql.sock -A  --default-character-set=GBK

        }

        shell执行mysql命令{

            mysql -u root -p'123' xuesong < file.sql   # 针对指定库执行sql文件中的语句,好处不需要转义特殊符号,一条语句可以换行.不指定库执行时语句中需要先use
            mysql -u$username -p$passwd -h$dbhost -P$dbport -A -e "
            use $dbname;
            delete from data where date=('$date1');
            "    # 执行多条mysql命令
            mysql -uroot -p -S mysql.sock -e "use db;alter table gift add column accountid  int(11) NOT NULL;flush privileges;"  2>&1 |grep -v Warning    # 不登陆mysql插入字段

        }


        mysql字符集相关{

            show variables like '%character%';      # 查看数据库中设置字符集的参数
            # character_set_client、character_set_connection 以及 character_set_results 这几个参数都是客户端的设置
            # character_set_system、character_set_server 以及 character_set_database 是指服务器端的设置。
            # 而对于这三个服务器端的参数来说的优先级是:
            # 列级字符集 > 表级字符集 > character_set_database > character_set_server > character_set_system

            show global variables like '%char%';                                 #查看RDS实例字符集相关参数设置
            show global variables like 'coll%';                                  #查看当前会话字符序相关参数设置
            show character set;                                                  #查看实例支持的字符集
            show collation;                                                      #查看实例支持的字符序
            show create table table_name \G                                      #查看表字符集设置
            show create database database_name \G                                #查看数据库字符集设置
            show create procedure procedure_name \G                              #查看存储过程字符集设置
            show procedure status \G                                             #查看存储过程字符集设置
            alter database db_name default charset utf8;                         #修改数据库的字符集 
            create database db_name character set utf8;                          #创建数据库时指定字符集
            alter table tab_name default charset utf8 collate utf8_general_ci;   #修改表字符集和字符序

            # 下面三条sql 分别将库 dbsdq , 表 tt2 , 表 tt2 中的 c2 列修改为utf8mb4 字符集
            alter database dbsdq character set utf8mb4 collate utf8mb4_unicode_ci;
            use dbsdq;
            alter table tt2 character set utf8mb4 collate utf8mb4_unicode_ci;
            alter table tt2 modify c2  varchar(10) character set utf8mb4;
            # 修改列时,当前列中的所有行都会立即转化为新的字符集;
            # alter table 会对表加元数据锁

        }

        备份数据库{

            mysqldump -h host -u root -p --default-character-set=utf8 dbname >dbname_backup.sql               # 不包括库名,还原需先创建库,在use
            mysqldump -h host -u root -p --database --default-character-set=utf8 dbname >dbname_backup.sql    # 包括库名,还原不需要创建库
            /bin/mysqlhotcopy -u root -p    # mysqlhotcopy只能备份MyISAM引擎
            mysqldump -u root -p -S mysql.sock --default-character-set=utf8 dbname table1 table2  > /data/db.sql    # 备份表
            mysqldump -uroot -p123  -d database > database.sql    # 备份数据库结构

            # 最小权限备份
            grant select on db_name.* to [email protected]"localhost" Identified by "passwd";
            # --single-transaction  InnoDB有时间戳 只备份开始那一刻的数据,备份过程中的数据不会备份
            mysqldump -hlocalhost -P 3306 -u dbbackup --single-transaction  -p"passwd" --database dbname >dbname.sql

            # xtrabackup备份需单独安装软件 优点: 速度快,压力小,可直接恢复主从复制
            innobackupex --user=root --password="" --defaults-file=/data/mysql5/data/my_3306.cnf --socket=/data/mysql5/data/mysql.sock --slave-info --stream=tar --tmpdir=/data/dbbackup/temp /data/dbbackup/ 2>/data/dbbackup/dbbackup.log | gzip 1>/data/dbbackup/db50.tar.gz

        }

        还原数据库{

            mysql -h host -u root -p dbname < dbname_backup.sql
            source 路径.sql   # 登陆mysql后还原sql文件

        }

        赋权限{

            # 指定IP: $IP  本机: localhost   所有IP地址: %   # 通常指定多条
            grant all on zabbix.* to [email protected]"$IP";             # 对现有账号赋予权限
            grant select on database.* to [email protected]"%" Identified by "passwd";     # 赋予查询权限(没有用户,直接创建)
            grant all privileges on database.* to [email protected]"$IP" identified by 'passwd';         # 赋予指定IP指定用户所有权限(不允许对当前库给其他用户赋权限)
            grant all privileges on database.* to [email protected]"localhost" identified by 'passwd' with grant option;   # 赋予本机指定用户所有权限(允许对当前库给其他用户赋权限)
            grant select, insert, update, delete on database.* to [email protected]'ip'identified by "passwd";   # 开放管理操作指令
            revoke all on *.* from [email protected];     # 回收权限
            GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, EXECUTE, CREATE ROUTINE, ALTER ROUTINE ON `storemisc_dev`.* TO 'user'@'192.168.%'

        }

        更改密码{

            update user set password=password('passwd') where user='root'
            mysqladmin -u root password 'xuesong'

        }

        mysql忘记密码后重置{

            cd /data/mysql5
            /data/mysql5/bin/mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
            use mysql;
            update user set password=password('123123') where user='root';

        }

        mysql主从复制失败恢复{

            slave stop;
            reset slave;
            change master to master_host='10.10.10.110',master_port=3306,master_user='repl',master_password='repl',master_log_file='master-bin.000010',master_log_pos=107,master_connect_retry=60;
            slave start;

        }

        sql语句使用变量{

            use xuesong;
            set @a=concat('my',weekday(curdate()));    # 组合时间变量
            set @sql := concat('CREATE TABLE IF NOT EXISTS ',@a,'( id INT(11) NOT NULL )');   # 组合sql语句
            select @sql;                    # 查看语句
            prepare create_tb from @sql;    # 准备
            execute create_tb;              # 执行

        }

        检测mysql主从复制延迟{

            1、在从库定时执行更新主库中的一个timeout数值
            2、同时取出从库中的timeout值对比判断从库与主库的延迟

        }

        死锁{

            show OPEN TABLES where In_use > 0;                  # 查看当前锁信息
            show variables like 'innodb_print_all_deadlocks';   # 查看当前死锁参数
            set global innodb_print_all_deadlocks = 1;          # 设置死锁信息保存到错误日志
            innodb_print_all_deadlocks = 1                      # conf配置

        }

        mysql慢查询{

            select * from information_schema.processlist where command in ('Query') and time >5\G      # 查询操作大于5S的进程

            开启慢查询日志{

                # 配置文件 /etc/my.conf
                [mysqld]
                log-slow-queries=/var/lib/mysql/slowquery.log         # 指定日志文件存放位置,可以为空,系统会给一个缺省的文件host_name-slow.log
                long_query_time=5                                     # 记录超过的时间,默认为10s 建议0.5S
                log-queries-not-using-indexes                         # log下来没有使用索引的query,可以根据情况决定是否开启  可不加
                log-long-format                                       # 如果设置了,所有没有使用索引的查询也将被记录    可不加
                # 直接修改生效
                show variables like "%slow%";                         # 查看慢查询状态
                set global slow_query_log='ON';                       # 开启慢查询日志 变量可能不同,看上句查询出来的变量

            }

            mysqldumpslow慢查询日志查看{

                -s  # 是order的顺序,包括看了代码,主要有 c,t,l,r和ac,at,al,ar,分别是按照query次数,时间,lock的时间和返回的记录数来排序,前面加了a的时倒序
                -t  # 是top n的意思,即为返回前面多少条的数据
                -g  # 后边可以写一个正则匹配模式,大小写不敏感的

                mysqldumpslow -s c -t 20 host-slow.log                # 访问次数最多的20个sql语句
                mysqldumpslow -s r -t 20 host-slow.log                # 返回记录集最多的20个sql
                mysqldumpslow -t 10 -s t -g "left join" host-slow.log # 按照时间返回前10条里面含有左连接的sql语句

                show global status like '%slow%';                     # 查看现在这个session有多少个慢查询
                show variables like '%slow%';                         # 查看慢查询日志是否开启,如果slow_query_log和log_slow_queries显示为on,说明服务器的慢查询日志已经开启
                show variables like '%long%';                         # 查看超时阀值
                desc select * from wei where text='xishizhaohua'\G;   # 扫描整张表 tepe:ALL  没有使用索引 key:NULL
                create index text_index on wei(text);                 # 创建索引

            }

            Percona Toolkit 慢日志分析工具

        }

        mysql操作次数查询{

            select * from information_schema.global_status;

            com_select
            com_delete
            com_insert
            com_update

        }

    }

    mongodb{

        # mongo可视管理工具 studio 3t  

        一、启动{

            # 不启动认证
            ./mongod --port 27017 --fork --logpath=/opt/mongodb/mongodb.log --logappend --dbpath=/opt/mongodb/data/
            # 启动认证
            ./mongod --port 27017 --fork --logpath=/opt/mongodb/mongodb.log --logappend --dbpath=/opt/mongodb/data/ --auth

            # 配置文件方式启动
            cat /opt/mongodb/mongodb.conf
              port=27017                       # 端口号
              fork=true                        # 以守护进程的方式运行,创建服务器进程
              auth=true                        # 开启用户认证
              logappend=true                   # 日志采用追加方式
              logpath=/opt/mongodb/mongodb.log # 日志输出文件路径
              dbpath=/opt/mongodb/data/        # 数据库路径
              shardsvr=true                    # 设置是否分片
              maxConns=600                     # 数据库的最大连接数
            ./mongod -f /opt/mongodb/mongodb.conf

            # 其他参数
            bind_ip         # 绑定IP  使用mongo登录需要指定对应IP
            journal         # 开启日志功能,降低单机故障的恢复时间,取代dur参数
            syncdelay       # 系统同步刷新磁盘的时间,默认60秒
            directoryperdb  # 每个db单独存放目录,建议设置.与mysql独立表空间类似
            repairpath      # 执行repair时的临时目录.如果没开启journal,出现异常重启,必须执行repair操作
            # mongodb没有参数设置内存大小.使用os mmap机制缓存数据文件,在数据量不超过内存的情况下,效率非常高.数据量超过系统可用内存会影响写入性能

        }

        二、关闭{

            # 方法一:登录mongodb
            ./mongo
            use admin
            db.shutdownServer()

            # 方法:kill传递信号  两种皆可
            kill -2 pid
            kill -15 pid

        }

        三、开启认证与用户管理{

            ./mongo                      # 先登录
            use admin                    # 切换到admin库
            db.addUser("root","123456")                     # 创建用户
            db.addUser('zhansan','pass',true)               # 如果用户的readOnly为true那么这个用户只能读取数据,添加一个readOnly用户zhansan
            ./mongo 127.0.0.1:27017/mydb -uroot -p123456    # 再次登录,只能针对用户所在库登录
            #虽然是超级管理员,但是admin不能直接登录其他数据库,否则报错
            #Fri Nov 22 15:03:21.886 Error: 18 { code: 18, ok: 0.0, errmsg: "auth fails" } at src/mongo/shell/db.js:228
            show collections                                # 查看链接状态 再次登录使用如下命令,显示错误未经授权
            db.system.users.find();                         # 查看创建用户信息
            db.system.users.remove({user:"zhansan"})        # 删除用户

            #恢复密码只需要重启mongodb 不加--auth参数

        }

        四、登录{

            192.168.1.5:28017      # http登录后可查看状态
            mongo                  # 默认登录后打开 test 库
            mongo 192.168.1.5:27017/databaseName      # 直接连接某个库 不存在则创建  启动认证需要指定对应库才可登录

        }

        五、查看状态{

            #登录后执行命令查看状态
            db.runCommand({"serverStatus":1})
                globalLock         # 表示全局写入锁占用了服务器多少时间(微秒)
                mem                # 包含服务器内存映射了多少数据,服务器进程的虚拟内存和常驻内存的占用情况(MB)
                indexCounters      # 表示B树在磁盘检索(misses)和内存检索(hits)的次数.如果这两个比值开始上升,就要考虑添加内存了
                backgroudFlushing  # 表示后台做了多少次fsync以及用了多少时间
                opcounters         # 包含每种主要擦撞的次数
                asserts            # 统计了断言的次数

            #状态信息从服务器启动开始计算,如果过大就会复位,发送复位,所有计数都会复位,asserts中的roolovers值增加

            #mongodb自带的命令
            ./mongostat
                insert     #每秒插入量
                query      #每秒查询量
                update     #每秒更新量
                delete     #每秒删除量
                locked     #锁定量
                qr|qw      #客户端查询排队长度(读|写)
                ar|aw      #活跃客户端量(读|写)
                conn       #连接数
                time       #当前时间

            mongostat -h 127.0.0.1 --port 27047 --authenticationDatabase admin -u zadmin -p Keaphh9e    # 查看mongo状态
            mongotop  -h 127.0.0.1 --port 27047 --authenticationDatabase admin -u zadmin -p Keaphh9e    # 查看mongo集合的统计数据

        }

        六、常用命令{

            db.listCommands()     # 当前MongoDB支持的所有命令(同样可通过运行命令db.runCommand({"listCommands" : `1})来查询所有命令)

            db.runCommand({"buildInfo" : 1})                                  # 返回MongoDB服务器的版本号和服务器OS的相关信息
            db.runCommand({"collStats" : tablename})                          # 返回该集合的统计信息,包括数据大小,已分配存储空间大小,索引的大小等
            db.runCommand({"dropDatabase" : 1})                               # 清空当前数据库的信息,包括删除所有的集合和索引
            db.runCommand({"isMaster" : 1})                                   # 检查本服务器是主服务器还是从服务器
            db.runCommand({"ping" : 1})                                       # 检查服务器链接是否正常。即便服务器上锁,该命令也会立即返回
            db.runCommand({"repaireDatabase" : 1})                            # 对当前数据库进行修复并压缩,如果数据库特别大,这个命令会非常耗时
            db.runCommand({"serverStatus" : 1})                               # 查看这台服务器的管理统计信息
            # 某些命令必须在admin数据库下运行,如下两个命令:
            db.runCommand({"renameCollection" : 集合名, "to":集合名})          # 对集合重命名,注意两个集合名都要是完整的集合命名空间,如foo.bar, 表示数据库foo下的集合bar。
            db.runCommand({"listDatabases" : 1})                              # 列出服务器上所有的数据库

            mongo  172.20.20.1:27072/mdb --eval "db.tb.count();"              # shell执行mongo语句
            mongo --host  172.20.20.1 --port 27049

            rs.config();                                                      # 查看集群配置
            rs.status();                                                      # 查看集群节点的状态
            db.currentOp()                                                    # 获取当前正在执行的操作,可对应命令链接到ip:port
            db.runCommand( { logRotate : 1 } )                                # 日志轮转
            rs.slaveOk()                                                      # 设置从库shell可读
            rs.addArb("172.16.10.199:27020");                                 # 添加仲裁节点
            rs.add({host: "10.2.2.2:27047", priority: 0, hidden: true})       # 添加从节点 hidden true隐藏节点[priority必须为0]  false不隐藏
            rs.remove("172.20.80.216:27047");                                 # 删除节点
            rs.stepDown(120)                                                  # 主库上执行切换为从,120秒后切换回主
            show dbs                                                          # 查询db
            use post                                                          # 选择db
            show tables                                                       # 查看文档列表
            db.tb.drop()                                                      # 删除集合 需要权限
            db.tb.remove({})                                                  # 删除所有数据
            db.tb.count()                                                     # 查询文档条数
            db.tb.find()                                                      # 查看文档内容
            db.tb.find({_id:37530555})                                        # 查询指定id
            db.tb.find().sort({_id:-1}).limit(1)                              # 查询文档最后一条
            db.tb.find({"processed" : {"$ne" : true}}).limit(1);              # 字段不为 true
            db.tb.find({"processed" : {"$eq" : true}}).limit(1);              # 字段为 true
            db.tb.find({"processed" : {"$exists" : false}}).limit(1);         # 字段不存在

            db.tb.ensureIndex({"status":1}, {background:true})                # 后台加索引
            db.tb.getIndexes()                                                # 查看索引
            db.tb.ensureIndex({"c_type":1},{backgrounnd:true})                # 后台添加索引  1正向  -1反向
            db.tb.dropIndex({"c_type":1});                                    # 删除索引

        }

        七、进程控制{

            db.currentOp()                  # 查看活动进程
            db.$cmd.sys.inprog.findOne()    # 查看活动进程 与上面一样
                opid      # 操作进程号
                op        # 操作类型(查询\更新)
                ns        # 命名空间,指操作的是哪个对象
                query     # 如果操作类型是查询,这里将显示具体的查询内容
                lockType  # 锁的类型,指明是读锁还是写锁

            db.killOp(opid值)                         # 结束进程
            db.$cmd.sys.killop.findOne({op:opid值})   # 结束进程

        }

        八、备份还原{
            # mongodump 虽然能不停机备份,但是为了获取实时数据视图的能力,使用fsync命令能在运行时复制数据目录并且不会损坏数据
            # fsync会强制服务器将所有缓冲区的数据写入磁盘.配合lock还阻止对数据库的进一步写入,知道释放锁为止
            db.runCommand({"fsync":1,"lock":1})   # 执行强制更新与写入锁
            db.$cmd.sys.unlock.findOne()          # 解锁
            db.currentOp()                        # 查看解锁是否正常

            mongoexport -d test -c t1 -o t1.dat                 # 导出JSON格式
                -c         # 指明导出集合
                -d         # 使用库
            mongoexport -d test -c t1 -csv -f num -o t1.dat     # 导出csv格式
                -csv       # 指明导出csv格式
                -f         # 指明需要导出那些例

            mongoimport -d test -c t1 -file t1.dat                           # mongoimport还原JSON格式
            mongoimport -d test -c t1 -type csv --headerline -file t1.dat    # mongoimport还原csv格式数据
                --headerline                # 指明不导入第一行 因为第一行是列名

            mongodump -d test -o /bak/mongodump                # mongodump数据备份
            mongorestore -d test --drop /bak/mongodump/*       # mongorestore恢复
                --drop      # 恢复前先删除
                --gzip      # 压缩

            # 备份一个表
            # --excludeCollection string # 排除指定的集合 要排除多个,使用多个
            mongodump --host 127.0.0.1:27080 -d dbname  -c tablename  -o /data/reports/
            mongodump --host 127.0.0.1:27080 -d dbname  -c tablename  -o /data/reports/reports  -u root -p tAvaa5yNUE --authenticationDatabase admin

            # 恢复一个表
            mongorestore --host 127.0.0.1:27080 -d dbname  -c tablename --drop --dir=/data/reports/tablename.bson

            # 在线拷贝一个库
            db.copyDatabase(fromdb, todb, fromhost, username, password, mechanism)
            db.copyDatabase('mate','mate', '172.16.255.176:27047')

        }

        九、修复{

            # 当停电或其他故障引起不正常关闭时,会造成部分数据损坏丢失
            mongod --repair      # 修复操作:启动时候加上 --repair
            # 修复过程:将所有文档导出,然后马上导入,忽略无效文档.完成后重建索引。时间较长,会丢弃损坏文档
            # 修复数据还能起到压缩数据库的作用
            db.repairDatabase()    # 运行中的mongodb可使用 repairDatabase 修复当前使用的数据库
            {"repairDatabase":1}   # 通过驱动程序

        }

        十、python使用mongodb{


            easy_install pymongo      # python2.7+
            import pymongo
            connection=pymongo.Connection('localhost',27017)   # 创建连接
            db = connection.test_database                      # 切换数据库
            collection = db.test_collection                    # 获取collection
            # db和collection都是延时创建的,在添加Document时才真正创建

            文档添加, _id自动创建
                import datetime
                post = {"author": "Mike",
                    "text": "My first blog post!",
                    "tags": ["mongodb", "python", "pymongo"],
                    "date": datetime.datetime.utcnow()}
                posts = db.posts
                posts.insert(post)
                ObjectId('...')

            批量插入
                new_posts = [{"author": "Mike",
                    "text": "Another post!",
                    "tags": ["bulk", "insert"],
                    "date": datetime.datetime(2009, 11, 12, 11, 14)},
                    {"author": "Eliot",
                    "title": "MongoDB is fun",
                    "text": "and pretty easy too!",
                    "date": datetime.datetime(2009, 11, 10, 10, 45)}]
                posts.insert(new_posts)
                [ObjectId('...'), ObjectId('...')]

            获取所有collection
                db.collection_names()    # 相当于SQL的show tables

            获取单个文档
                posts.find_one()

            查询多个文档
                for post in posts.find():
                    post

            加条件的查询
                posts.find_one({"author": "Mike"})

            高级查询
                posts.find({"date": {"$lt": "d"}}).sort("author")

            统计数量
                posts.count()

            加索引
                from pymongo import ASCENDING, DESCENDING
                posts.create_index([("date", DESCENDING), ("author", ASCENDING)])

            查看查询语句的性能
                posts.find({"date": {"$lt": "d"}}).sort("author").explain()["cursor"]
                posts.find({"date": {"$lt": "d"}}).sort("author").explain()["nscanned"]

        }

    }