mongodb磁盘满故障 您所在的位置:网站首页 怎么查看mongodb空间有多少 mongodb磁盘满故障

mongodb磁盘满故障

2024-02-03 17:54| 来源: 网络整理| 查看: 265

mongodb磁盘满

cat /var/log/mongodb/mongodb.log

关键的错误日志: ERROR: Insufficient free space for journal files Please make at least 3379MB available in /var/lib/mongodb/journal or use --smallfiles exception in initAndListen: 15926 Insufficient free space for journals, terminating

查了一下 ERROR: Insufficient free space for journal files 原因是因为 mongo 的 journa 目录下空间小于3379MB。磁盘至少要保证journal目录下有3379MB空间可用。 journal 至少以2G的数量进行增长,当磁盘空间不足时,就会报该错误。 看了一下磁盘占用满了: df -h /dev/sda1        91G   83G  2.8G  97% /

首先按照错误日志中解决的办法是使用 --smallfiles参数,尝试启动数据库服务。 --smallfiles 选项会减少数据文件的初始大小,并将最大大小限制为512MB。 smallfiles也会将每个日志文件的大小从1GB减少到128MB。 如果你有大量的数据库,每个数据库都包含少量的数据,那么建议使用--smallfiles 选项。 smallfiles选项可以引导mongod实例创建大量文件,这会影响较大数据库的性能,实际使用时慎重选择。

如果 journal 目录下日志文件占用空间比较大,可以关闭journal功能、删除journal目录下的文件: vim /etc/mongodb.conf nojournal = true smallfiles = true noprealloc = true 

rm -rf /var/lib/mongodb/journal/* 

重启数据库 service mongodb start

我journal本来就占用不大,主要还是数据库占用磁盘太大。因此我直接先采用日志推荐的--smallfiles启动试试:

在mongodb.service启动参数中加 --smallfiles 参数 vim /lib/systemd/system/mongodb.service ExecStart=/usr/bin/mongod --unixSocketPrefix=${SOCKETPATH} --config ${CONF} $DAEMON_OPTS   --smallfiles 

修改服务配置文件后,重新加载一下服务配置文件 systemctl daemon-reload

重新启动mongodb服务,启动成功 service mongodb start 重启数据库服务成功,但df查看磁盘占用仍然还是很高,继续尝试解决根本的磁盘占用高的问题。

查看mongodb数据库大小的几种方法: 方法1:show databases,可查看不同数据库的大小 # mongo > show databases; admin      0.078GB db01       63.923GB local      0.078GB mytestdb  16.071GB test       0.578GB 可以看到主要db01和mytestdb数据库比较大。

查看指定数据局的详情: > use mytestdb > db.stats() {         "db" : "mytestdb",         "collections" : 34,         "objects" : 8147600,         "avgObjSize" : 261.48154941332416,         "dataSize" : 2130447072,         "storageSize" : 13551329264,         "numExtents" : 138,         "indexes" : 32,         "indexSize" : 286724144,         "fileSize" : 17239638016,         "nsSizeMB" : 16,         "dataFileVersion" : {                 "major" : 4,                 "minor" : 5         },         "extentFreeList" : {                 "num" : 3,                 "totalSize" : 761118720         },         "ok" : 1 }

方法2:db.serverStatus().mem # mongo > db.serverStatus().mem {         "bits" : 64,         "resident" : 115,         "virtual" : 165558,         "supported" : true,         "mapped" : 82666,         "mappedWithJournal" : 165332 }

mapped:映射到内存的数据大小,大小等同于数据库文件的大小 visze:占用的虚拟内存大小 res:占用的物理内存大小

方法3:mongostat # mongostat connected to: 127.0.0.1 insert  query update delete getmore command flushes mapped  vsize    res faults  locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn       time      *0     *0     *0     *0       0     1|0       0  80.7g   162g   111m      0  test:0.0%          0       0|0     0|0    62b     3k     1   20:56:29      *0     *0     *0     *0       0     1|0       0  80.7g   162g   111m      0  test:0.0%          0       0|0     0|0    62b     3k     1   20:56:30      *0     *0     *0     *0       0     1|0       0  80.7g   162g   111m      0  test:0.0%          0       0|0     0|0    62b     3k     1   20:56:31 

方法4:直接查看数据库文件路径目录文件的大小 # du -sh /var/lib/mongodb/ 81G     /var/lib/mongodb/ 主要是数据库文件较大

接下来主要考虑如何回收磁盘空间。 注意:mognodb删除数据后不会释放占用的磁盘空间给操作系统,即使 drop collection 也不行,除非drop database。 删除数据以后,dbshell 中用命令 db.serverStatus().mem 可以看到磁盘空间占用显示虽然已经释放,但df命令查看OS的空闲磁盘空间没变化,mongodb并没有释放给OS。

准备工作: 方案中可能涉及到有足够的磁盘空间来操作,可以考虑给虚机增加新的磁盘,如果没有条件,也可以考虑ssh mount远程主机磁盘到本地。 我使用ssh mount方式,sshfs安装和远程mount的详细操作方法可以参考:https://blog.csdn.net/sunny05296/article/details/77722081

安装sshfs apt-get install -y sshfs # for ubuntu, 查看是否已安装:dpkg  -l |grep wget yum install -y fuse-sshfs # for fedore yum install -y epel-release & yum -y install fuse-sshfs # for Centos

挂载远程网络硬盘 mkdir /remote_dir sshfs -o rw [email protected]:/data/  remote_dir/

如果要卸载移除网盘使用: fusermount -u /remote_dir

方案1:备份恢复(mongodump & mongorestore)【我采用了该方式】 备份 # mkdir -p /remote_dir/mongo_dump_dir # mongodump -d mytestdb -o /remote_dir/mongo_dump_dir

备份后,目录下会生成数据库文件夹mytestdb,查看一下备份后的实际文件夹大小: # cd /remote_dir/mongo_dump_dir # du -h 1.6G    ./mytestdb 源库16G备份删除碎片数据以后,空间占用缩小到1.6G,可见源库中存在大量的删除数据

删除源库 # echo 'db.dropDatabase()' | mongo mytestdb

恢复源库 # mongorestore -d  mytestdb  /remote_dir/mongo_dump_dir/mytestdb

用同样的方法,我处理完 db01 库会后,大小从 61G 减少到 19G。 如果数据量不大、dump时间不长,或者经常备份有dump文件的情况的下,这种方法很简单方便。

方案2:db.repairDatabase() 【我剩余空间太少,没有尝试该方式】

官方介绍说用:删除数据库的数据以后,需要 dbshell 进入删除了数据的 db 后,执行 db.repairDatabase() 可以回收硬盘空间。 但是要注意风险: 1.在生产上操作如果意外停止可能会造成数据无法恢复的危险。 2.如果磁盘空间不足,小于现在这个db时间占有的空间,这种情况是用不了 db.repairDatabase() 的。 需要注意,db.repairDatabase() 能否执行成功,主要处决于:释放出来的磁盘空间小于释放执行前当前OS剩余的磁盘空间,则能释放成功,否则释放失败。 而我声誉磁盘空间只有2.8G,空闲磁盘太少了, 删除数据再db.repairDatabase()的话,估计失败的概率很大。所以,我直接放弃下面的命令执行:

# mongo db01 mongo> db.repairDatabase() 或者执行 mongo> db.runCommand({ repairDatabase: 1 })  后面这种方法还支持带更多的参数,这里就先不详细介绍了。

方案3:db.copyDatabase 【由于我只有一个mongodb,所以没有采用该方式】 mongo> db.copyDatabase("db_src","db_src_copyed","127.0.0.1:27017") 如果是同一个mongodb拷贝,可以直接用:db.copyDatabase("db_src","db_src_copyed") mongo> use db_src mongo> db.dropDatabase()

完整的语法:db.copyDatabase(fromdb, todb, fromhost, username, password, mechanism) fromdb:源db名,用户必须能够对这个db进行鉴权 todb: 复制到目的mongod的名字,名字可以跟原名字不一样 fromhost: ip:port 如果是同一个mongodb拷贝,这个参数可不要 username: 用户名 password:  密码 mechanism:鉴权方式,MONGODB-CR or SCRAM-SHA-1,如果 db.isMaster().maxWireVersion >= 3,那默认就是 SCRAM-SHA-1,否则默认就是 MONGODB-CR

执行数据库拷贝,源库可能是已经删除过数据的库,由于磁盘不释放,造成磁盘空间的浪费。 通过数据库拷贝命令,拷贝到目的库,不会拷贝碎片,会生成一个最小占用的库(数据库目录下也会同步生成新库的文件)。 拷贝库成功后,就可以使用 db.dropDatabase() 删除源库了。  



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有