mongodb --nssize
默认情况下,MongoDB(MMAP)的每个数据库的命名空间保存在一个 16MB 的 .ns 文件中,平均每个命名占用约 628 字节,也即整个数据库的命名空间的上限约为 24000。
每一个集合、索引都将占用一个命名。所以,如果每个集合有一个索引(比如默认的 _id 索引),那么最多可以创建 12000 个集合。如果索引数更多,则可创建的集合数就更少了。同时,如果集合数太多,一些操作也会变慢。
不过,如果真的需要建立更多的集合的话,MongoDB 也是支持的,只需要在启动时加上“–nssize”参数,这样对应数据库的命名空间文件就可以变得更大以便保存更多的命名。这个命名空间文件(.ns 文件)最大可以为 2G,也就是说最大可以支持约 340 万个命名,如果每个集合有一个索引的话,最多可创建约 170 万个集合。
还需要注意,–nssize 只设置新创建的 .ns 文件的大小,如果想改变已经存在的数据库的命名空间,在使用这个参数启动后,还需要运行 db.repairDatabase() 命令来调整尺寸。
这个参数是限制mmap,wired tiger没这个限制
profile 分析器 分析慢查询
数据类型code
Object ID :Documents 自生成的 _id
String: 字符串,必须是utf-8
Boolean:布尔值,true 或者false (这里有坑哦~在我们大Python中 True False 首字母大写)
Integer:整数 (Int32 Int64 你们就知道有个Int就行了,一般我们用Int32)
Double:浮点数 (没有float类型,所有小数都是Double)
Arrays:数组或者列表,多个值存储到一个键 (list哦,大Python中的List哦)
Object:如果你学过Python的话,那么这个概念特别好理解,就是Python中的字典,这个数据类型就是字典
Null:空数据类型 , 一个特殊的概念,None Null
Timestamp:时间戳
Date:存储当前日期或时间unix时间格式 (我们一般不用这个Date类型,时间戳可以秒杀一切时间类型)
看着挺多的,但是真要是用的话,没那么复杂,很简单的哦
mongodb复制释放是异步的?是异步
mongodb 集群的算法是什么?raft
更新操作立刻fsync到磁盘?
不会,磁盘写操作默认是延迟执行的。写操作可能在两三秒(默认在60秒内)后到达磁盘。例如,如果一秒内数据库收到一千个对一个对象递增的操作,仅刷新磁盘一次。
。
没有参数控制?持久化只是依赖check point机制?如何配置check point的频率?
触发checkpoint执行,通常有如下几种情况:
按一定时间周期:默认60s,执行一次checkpoint;
按一定日志文件大小:当Journal日志文件大小达到2GB(如果已开启),执行一次checkpoint;
任何打开的数据文件被修改,关闭时将自动执行一次checkpoint。
看来是没有参数能控制check point的执行时机
数据安全问题,getLastError 作用?确保数据安全问题的要设置
-----begin-----------
By default:
Collection data (including oplog) is fsynced to disk every 60 seconds.
Write operations are fsynced to journal file every 100 milliseconds.
Note, oplog is available right away in memory for slaves to read. Oplog is a capped collection
so a new oplog is never created, old data just rolls off.
GetLastError with params:
(no params) = return after data updated in memory.
fsync: true:
with --journal = wait for next fsync to journal file (up to 100 milliseconds);
without --journal = force fsync of collection data to disk then return.
w: 2 = wait for data to be updated in memory on at least two replicas.
########
可以看到:
1、如果打开journal,那么即使断电也只会丢失100ms的数据,这对大多数应用来说都可以容忍了。从1.9.2+,mongodb都会默认打开journal功能,以确保数据安全。而且journal的刷新时间是可以改变的,2-300ms的范围,使用 --journalCommitInterval 命令。
2、Oplog和数据刷新到磁盘的时间是60s,对于复制来说,不用等到oplog刷新磁盘,在内存中就可以直接复制到Sencondary节点。
GetLastError Command
getLastError 是Mongodb的一个命令,从名字上看,它好像是取得最后一个error,但其实它是Mongodb的一种客户端阻塞方式。用这个命令来获得写操作是否成功的信息。
getlastError有几个参数:j,w,fsync。在大多数的语言驱动中,这个命令是被包装成writeConcern类,比如java。
在write concer中可以指定,w: 向几个节点写入后才向客户端确认,j: 写入操作的journal持久化后才向客户端确认
通过上面的2个参数设置可以设置成几乎跟mysql一样的半同步的方式。
不清楚w的写入是否是指刷盘了,mysql是想从库推送binlog mongo是拉去oplog
-------end-----------
mongodb空间预分配
分片键的选择
更新分片键
我可以把moveChunk目录里的旧文件删除吗?
没问题,这些文件是在分片(shard)进行均衡操作(balancing)的时候产生的临时文件。一旦这些操作已经完成,相关的临时文件也应该被删除掉。但目前清理工作是需要手动的,所以请小心地考虑再释放这些文件的空间。
查看正在使用的连接
db._adminCommand(“connPoolStats”);
journaling作用配置,与oplog的区别?
oplog 相当于binlog
journaling相当于redo,刷新的间隔间隔见上面的描述
mongodb中的特殊对象
GridFS是一种将大型文件存储在MongoDB中的文件规范。使用GridFS可以将大文件分隔成多个小文档存放,这样我们能够有效的保存大文档,而且解决了BSON对象有限制的问题。
capped集合
过期索引:过期索引,指的是一段时间后会过期的索引,在索引过期后,相应的数据会被删除
文档设置过期
mongodb 的存储结构是什么?
wired tiger 数据的存储也是b+tree 索引是btree?
为神马mongodb要使用btree?
wiretiger是使用的btree,
为神马用btree,不是b+tree?
copy on write的概念?
跳转列表的数据结构?
mongodb适合少量大表还是大量小表的存放?
并发锁
WiredTiger使用文档级并发控制进行写操作。因此,多个客户端可以并发同时修改集合的不同文档。
对于大多数读写操作,WiredTiger使用乐观并发控制模式。WiredTiger仅在全局、数据库和集合级别使用意向锁。当存储引擎检测到两个操作之间存在冲突时,将引发写冲突,从而导致MongoDB自动重试该操作。
一些全局操作(通常是涉及多个数据库的短暂操作)仍然需要全局“实例范围级别的”锁。其他一些操作(例如删除集合)仍然需要独占数据库锁。
compact 一个集合,会加集合所在DB的互斥写锁,会导致该DB上所有的读写请求都阻塞;因为 compact 执行的时间可能很长,跟集合的数据量相关,所以强烈建议在业务低峰期执行,避免影响业务。compact会阻塞库的写入
,那就是需要警惕一些数据库操作潜在的锁问题了,比如:
创建索引(默认Foreground模式),会对数据库产生写锁(X),所以一定要用Background模式
删除集合,dropCollection,会对数据库产生写锁(X),谨慎!
MapReduce操作,会对数据库产生读锁(S)和写锁(X),谨慎!
连接鉴权,db.auth(),会对admin库产生读锁,而admin是库级锁。
检查点与快照
WiredTiger使用MultiVersion并发控制(MVCC)方式。在操作开始时,WiredTiger为操作提供数据的时间点快照。快照提供了内存数据的一致视图。
写入磁盘时,WiredTiger将所有数据文件中的快照中的所有数据以一致的方式写入磁盘。现在持久的数据充当数据文件中的检查点。该检查点可确保数据文件直到最后一个检查点(包括最后一个检查点)都保持一致;即检查点可以充当恢复点。
从3.6版本开始,MongoDB配置WiredTiger以60秒的间隔创建检查点(即将快照数据写入磁盘)。在早期版本中,MongoDB将检查点设置为在WiredTiger中以60秒的间隔或在写入2GB日志数据时对用户数据进行检查,以先到者为准。
在写入新检查点期间,先前的检查点仍然有效。这样,即使MongoDB在写入新检查点时终止或遇到错误,重启后,MongoDB仍可从上一个有效检查点恢复。
当WiredTiger的元数据表被原子更新以引用新的检查点时,新的检查点将变为可访问且永久的。一旦可以访问新的检查点,WiredTiger就会从旧的检查点释放页面。
使用WiredTiger,即使没有日志,MongoDB也可以从最后一个检查点恢复;但是,要恢复上一个检查点之后所做的更改,请运行日志功能。
敲黑板!!!
从MongoDB 4.0开始,您不能指定–nojournal选项或storage.journal.enabled:使用WiredTiger存储引擎的副本集成员为false。
那么wt的mvcc是用什么方式实现的?mysql,oracle是undo, pg是在表上保留历史数据变更。
日志
WiredTiger将预写日志(即日志)与检查点结合使用以确保数据持久性。
WiredTiger日志保留检查点之间的所有数据修改。如果MongoDB在检查点之间退出,它将使用日志重播自上一个检查点以来修改的所有数据。有关MongoDB将日志数据写入磁盘的频率的信息,具体请参阅日志处理。
WiredTiger日志使用快速压缩库进行压缩。要指定其他压缩算法或不进行压缩,请使用storage.wiredTiger.engineConfig.journalCompressor设置参数。有关更改日志压缩器的详细信息,请参阅“更改WiredTiger日志压缩器”文档。
敲黑板!!!
如果日志记录小于或等于128字节(WiredTiger的最小日志记录大小),则WiredTiger不会压缩该记录。
您可以通过将storage.journal.enabled设置为false来禁用独立实例的日志记录,这可以减少维护日志记录的开销。对于独立实例,不使用日志意味着MongoDB意外退出时,您将丢失最后一个检查点之前的所有数据修改信息。
再次敲黑板!!!
从MongoDB 4.0开始,您不能指定–nojournal选项或storage.journal.enabled:使用WiredTiger存储引擎的副本集成员为false。
您也可以参考:使用WiredTiger日志。
那么控制日志写入频率的参数有哪些?
read concern ,write concern有哪些相关配置,作用分别是什么?
写操作可以指定write concern。当一个命令包含write concern时,该操作所在的线程会一直阻塞,直到操作产生的oplogEntries被write concern指定的节点复制。主节点需要跟踪从节点的最新状态(Oplog复制延时情况)来明确该命令何时返回。write concern可以指定要等待的节点数或多数节点(majority)。如果指定了majority,则写操作还将等待该操作已经包含在已提交的快照(committed snapshot)中,以便可以通过readConcern: { level: majority } 读取。
mongodb $lookup 使用
副本集标签怎么用?
mongodb mtools 使用
mongodb 事务隔离级别有哪些?
通过什么指标去查看数据都是在内存中操作的,也就是缓存命中率怎么计算?
mongodb更改同步源的几种情况:
OplogFetcher会由于各种原因而关闭。当每一批次数据成功地处理之后,OplogFetcher会决定是否继续从当前同步源进行同步数据。如果OplogFetcher决定继续,它将等待下一批次到达并重复操作。否则,OplogFetcher将终止,这将导致BackgroundSync选择新的同步源。更改同步源的原因包括:
1)本节点不再处于副本集中。
2)同步源节点不再处于副本集中。
3)用户使用了replSetSyncFrom命令来更改同步源。
4)链式复制选项(chainingAllowed)被关闭,该节点当前从主节点同步数据,与原同步源的链路被禁用。
5)同步源不是主节点,并且没有自己的同步源,这也就意味着同步源节点将不会及时获取新的日志条目,最终会导致从该同步源同步数据的节点滞后。
6)同步源节点最新的OpTime比另一个成员最新的OpTime 落后30秒(maxSyncSourceLagSecs)。这说明同步源已经滞后了,此时改变同步源可以减少同步源的读IO压力,使得同步源和其他节点尽量不要相差太远。
7)该节点发现了一个网络延时(ping值)更小的同步源。该节点到新的同步源的ping比到当前同步源至少小一个changeSyncSourceThresholdMillis时间, changeSyncSourceThresholdMillis也是一个服务器参数,默认值是5ms。
链式复制选项是什么概念?
oplog 的应用过程
OplogApplier负责应用oplog的具体工作。它运行在一个while循环中,每次循环做以下事情:
获取下一批Oplog
加PBWM(Parallel Batch Writer Mode)锁。
将oplogTruncateAfterPoint设置为节点上一次应用的optime(在此批次之前),以帮助节点在oplog写入的过程中异常关闭时恢复启动。
将这批oplog写入local.oplog.rs。
清除oplogTruncateAfterPoint并将minValid设置为这批oplog中最后一条oplog的optime。在应用到minValid optime之前,数据库的状态相对于oplog是不一致的。
多个线程并行应用oplog, 这意味着同一批oplog不会被顺序执行。
每个批次中的操作会由不同的写线程执行,同一个线程中的操作串行执行。
同一个collection的oplog一定会被同一个线程处理。
不同collection的oplog可能会被分配到不同的线程处理。
每个线程会将相邻的insert操作合并为一个bulk执行以提高性能,其他操作单独执行。
存储引擎(wiredTiger/rocksDB) Flush WAL。
持久化”applied through” optime(一批oplog中的最后一条oplog的optime)。由于这批oplog已经应用完了,oplog和数据库数据保持一致了,因此此时可以更新minValid记录了。
通知存储引擎(mongo-wiredTiger/mongoRocks)更新oplog可见性。由于oplog是并行应用的,因此只有在完整应用完一批oplog之后,更新oplog可见性才是安全的,否则会有oplog 空洞出现。
析构这批oplog,并推进全局时间戳(和节点的lastAppliedOpTime)。
mongodb 中的reconcile 具体做了什么?
wt的btree相较于InnoDB有些不一样的地方(详细结构见https://github.com/wiredtiger/wiredtiger/wiki/Reconciliation-overview),InnoDB的内存中的page结构和磁盘上的page结构是一样的,都是紧凑的binary,修改产生的脏页会in place的更新到原有磁盘的page上, 这样的好处是刷盘时,直接把16k的page,按字节数组的方式一次性刷下去即可。
WiredTiger将磁盘上的page读上来之后,会在内存中构建成另外一种复杂结构,这个结构较binary结构好处就是可以重新组织或嵌入具有更高并发性的结构,比如wt使用的HazardPointer,对page刷盘时,其实就是对该页的HazardPointer的’写获取’操作,并且在刷盘时保持 原有磁盘上的page不变,直接找一个新的page空间,把内存里page的修改(保存在page的modify_list中)变成磁盘page的结构写入 ,这个page刷盘的过程称为reconcile(wt里很多生僻的名词)。这样的好处是对不修改原有page,就能更好的并发,并且不像InnoDB一样,需要一个DoubleWriteBuffer保证非disk block 512B写时对原有页可能发生conrrupt。(这里有个小问题,如果是更新都写入新page,如果每次都只是更新page中很小的数据,数据的空间占用会比较大,待验证?!)
这样实现的mvcc?保存之前的page,这样并发高的情况下,会产生很多的block,磁盘文件应该会占用的很大,另外生成一个新的block就能避免断页的产生?
如何手工限制主库的写入速度?
启用流控制后,当延迟快接近flowControlTargetLagSeconds参数指定的秒数时,主节点上的写操作必须首先获得许可单(tickets)才可以获取写锁。通过限制每秒发出的许可单的数量,流控制机制可以将延迟保持在目标数值之下。
mysql的三个列表结构:
1 free list
2 flush list
3 lru list,还实现了冷热区域
mongo中是扫所有的block,然后放入队列,worker开始清理队列
read concern 和read preference的区别:
https://mongoing.com/archives/3403
一个是控制可见度一个是控制在哪里读。