多线程并发信号量控制逻辑
1 | /**/ |
1 | /**/ |
确认已安装的 MongoDB 家族版本
1 | rpm -qa | grep mongodb-org |
典型输出:
1 | mongodb-org-server-8.2.0-1.el8.x86_64 |
卸载
1 | rpm -e mongodb-org-server-8.2.0-1.el8.x86_64 |
输出
1 | Removed /etc/systemd/system/multi-user.target.wants/mongod.service. |
https://mobaxterm.mobatek.net/
ResetMasterPassword.zip
字体库缺失
如果在 Ubuntu 系统中使用 Java Web 项目导出 Excel 文件时出现异常,可能是系统缺少字体库。
可以通过以下命令安装字体库:
1 | sudo apt install fontconfig -y |
安装完成后,重启服务器
遇到 “ERROR at line 13404: Unknown command ‘’’” 错误时,这通常是由于字符集问题导致的。为了解决在 MySQL
导入数据时的问题,可以尝试以下几种方法:
指定字符集:在导入命令中添加 --default-character-set=utf8 参数,以确保字符集的一致性。例如:
1 | mysql -u root -h 127.0.0.1 -P 33067 --default-character-set=utf8 mujitokyo_dev<mujitokyo_dev.sql |
这样可以避免因字符集不匹配导致的数据导入失败
。
检查文件编码:确保 SQL 文件的编码格式与 MySQL 服务器的编码格式一致。可以使用文本编辑器或命令行工具(如 )来转换文件编码。
使用特定编码导出:在导出数据库时,就使用特定编码的形式导出。例如,如果需要导入的数据库环境编码是utf8,那么在导出时就使用utf8格式。
调整命令行客户端编码:在命令行客户端连接服务器时指定编码,例如:
1 | mysql -uroot -h192.168.0.1001 -p --default-character-set=utf8 |
这可以避免前面遇到的错误
。
max_allowed_packet 设置:如果导入的 SQL 文件较大,可能需要调整 MySQL 的 max_allowed_packet 设置,以允许更大的数据包传输你可以将 --skip-grant-tables 选项添加到 MySQL 的配置文件中,以便在每次启动时自动应用此设置。然而,需要注意的是,--skip-grant-tables 选项会跳过权限表的加载,这意味着所有用户都可以无需密码登录到 MySQL
服务器,这会带来重大的安全风险。因此,通常只在进行特定维护任务时临时使用此选项。
--skip-grant-tables 添加到配置文件找到 MySQL 配置文件: MySQL 的配置文件通常名为 my.cnf 或 my.ini,位于 /etc/mysql/、/etc/mysql/mysql.conf.d/
或 MySQL 安装目录下。
编辑配置文件: 打开配置文件,找到 [mysqld] 部分,并添加 --skip-grant-tables 选项。例如:
1 | [mysqld] |
保存并关闭文件。
重启 MySQL 服务: 重启 MySQL 服务以应用更改:
1 | sudo systemctl restart mysql |
--skip-grant-tables 的注意事项--skip-grant-tables 会跳过权限检查,任何用户都可以无需密码登录到 MySQL--skip-grant-tables--skip-grant-tables完成维护任务后,应立即从配置文件中移除 --skip-grant-tables 选项,并重启 MySQL 服务以恢复正常的权限检查:
1 | 2025-09-01T01:38:07.723468Z 0 [ERROR] InnoDB: Ignoring the redo log due to missing MLOG_CHECKPOINT between the checkpoint 1108276937 and the end 1108281882. |
从你提供的日志来看,
MySQL 在启动时遇到了与 InnoDB 存储引擎相关的问题,导致无法正常启动。
以下是日志中显示的几个关键问题及其可能的原因:
1 | 2025-09-01T01:38:07.723468Z 0 [ERROR] |
MLOG_CHECKPOINT,导致无法正确恢复数据。ibdata1 或 ib_logfile*)可能被损坏或丢失。**ib_logfile\***:这些是 InnoDB 的重做日志文件,用于恢复操作
在某些情况下,可以尝试删除一些临时文件或日志文件,但需要谨慎操作:
ib_logfile\***:如果这些文件损坏,可以尝试删除它们,然后重新启动 MySQL。MySQL 会自动重新创建这些文件。但请注意,这可能会导致一些未提交的事务丢失。\*.err**:这是 MySQL 的错误日志文件,删除它不会影响数据库的运行,但建议先备份,以便后续查看错误信息。私服客户业务量的增加,录音数据不断增加,面临着磁盘空间不足的情况,因为 MongoDB 的特性,直接删除数据占用的磁盘空间并不会释放,即使
drop collection 也不行,除非 drop database。
如果一个 db 曾经有大量的数据一段时间后又删除的话,硬盘空间就是一个问题,如何收回被 mongodb 占用的多余空间?
磁盘空间越来越大,为了避免磁盘空间超过 95%以上导致锁库,清理方案迫在眉睫。
1 | db |
解决方法选型
1 | # 格式:mongod --repair --dbpath <数据存储目录> --repairDatabase <目标数据库名> |

操作步骤:
1 | 0.连接MongoDB 节点1.use '业务DB' |
在MongoDB中,db.runCommand({compact:"collectionName",force:true})
用于压缩指定集合的数据文件,释放未使用的空间。
如果在执行该命令时出现超时问题,
可以尝试以下几种方法来处理:
MongoDB允许你设置命令的超时时间。
你可以通过maxTimeMS选项来设置命令的最大执行时间(以毫秒为单位)。
例如:
1 | db.runCommand({ |
注意点:
1 | 当然以上是我们期望的多么完美的运行过程!!! |
主要思想就是:在有新机器(磁盘)的情况下,新建一个 secondary 节点,使之与 primary 节点开始数据同步。数据的同步与直接复制数据文件不同,MongoDB
会只同步数据,因此同步完成后的数据文件是没有空集合的,以此实现了磁盘空间的回收。
上步骤:

注意点:
1 | 注意点: |
MongoDB 还支持在线复制数据:db.copyDatabase(“from”,”to”,”IP:port”),此种方法也能释放空间,因为 db.copyDatabase
复制的数据,而不是表示在磁盘中的数据文件。但是该方法在 4.0 版本起被弃用,3.x
版本还能继续使用,还可以复制远端数据库哦,方便多节点复制操作,但是需要我们备份好主库索引,手动创建索引。
主流程:
1 | 0.停掉所有业务数据读写操作1.db.copyDatabase("from","to","127.0.0.1:16161");复制出一个新的to数据库。这个已经是最小数据占用的数据。会在数据目录下产生to的相关数据文件。 |
上方法:
1 | 前提停掉所有服务0.Primary 对要迁移的db进行授权use 业务DB;db.createUser( { user: "rcrai", pwd: "xxxx", roles: [ "readWrite", "dbAdmin" ] } )db.grantRolesToUser('rcrai',[{ role: "dbAdmin", db: "业务DB" }]) 1.second机器上执行copy操作db.copyDatabase("源业务DB", "目标业务DB", "10.10.10.26:30017","rcrai","xxxx");2.等待执行完成,执行创建索引 |
注意点:
1 | 注意:second copy没执行完成和second索引没有手动创建完成前,一定不要启动业务读写,copy操作比较消耗IO,容易干挂docker的网络环境优点: 1.纯copy数据方式,速度快 2T数据耗时15小时完成 2.支持远程复制 3.second会清理掉大量的磁盘空间缺点: 1.不能自动创建索引 2.MongoDB4.0不支持,推荐方法三 3.不用于复制包含分片集合的数据库 |
原理简单粗暴,停服务,dump 出来数据,再 restore 回去。
上方法:
1 | 1.停业务服务,停止业务数据读写2.执行dump数据操作mongodump --host 10.10.12.25 --port 30017 -u rcrai -p eawmzaxtfnptvtpxefkd --authenticationDatabase admin --oplog -o /data/dumpmongo/3.执行restore恢复mongorestore --host 10.10.12.26 --port 30018 -u rcrai -p eawmzaxtfnptvtpxefkd --authenticationDatabase admin --oplogReplay /data/dumpmongo |
注意点:
1 | 优点: 1.操作简单,步骤少 2.只适用于小量数据(小于200G的场景)缺点: 1.如果数据量比较大(大于200G),mongorestore执行时间较长(3T数据恢复大于100H) |
官网该命令的定义:清理无效或损坏的数据并重建数据库索引。类似于文件系统修复命令
fsck,所以此命令主要是用于修复数据。但是需要停机业务服务,即便你不停业务服务读写的话 MongoDB 自己也会锁住直到 repair
完成。注意要有足够的磁盘空间,需要额外一倍的空间,如果 MongoDB 占用了 500G,那么 repair 时还需要额外的 500G+2G 空间。
上方法:
1 | use 业务DB;db.repairDatabase(); |
注意点:
1 | 注意: 1.db.repairDatabase()主要用于修复数据。若你拥有数据的完整副本,且有权限访问,请使用第二种方法“secondary节点同步” 2.在执行命令前请保证你有比较新的备份 3.此命令会完全阻塞数据库的读写,谨慎操作 4.此命令执行需要数据文件所在位置有等同于所有数据文件大小总和的空闲空间再加上2G 5.在使用MMAPv1存储引擎的secondary节点上执行该命令可以压缩集合数据 6.在使用WiredTiger存储引擎的MongoDB库上执行不会有压缩的效果 7.再碰到特殊情况要停止运行该命令时,可通过db.currentOp()查询进程信息,然后通过db.killOp()干掉进程优点: 1.可以追加磁盘,然后将目标目录指向新加的磁盘缺点: 1.非常消耗时间 2.在生产上操作如果意外停止可能会造成数据无法恢复的危险。 3.如果磁盘空间不足,小于现在这个db占用的空间,这种情况是用不了 |
总结
最终我们采用的是第二种和第三种方法去做的磁盘清理方案,操作客户的数据最终还是要从时效性,稳定性,以及失败的可恢复性去考虑。大家一定要注意:1.客户数据基本都在
T
级别以上,操作大规模数据属于高危操作,每一步都要慎重,且每一个环节和步骤都要在测试环节做大数据量的测试操作。2.一定要有至少一份的备份数据,且一段时间(一周)内不能被清除。3.方案不止要准备一种,私服环境多样,根据实际情况选择合适的方案。
MongoDB删除集合数据,物理磁盘空间不会直接释放,即使drop collections也无济于事。
除非drop databases。
在MongoDB4.0及以下,官网提供了一种回收MongoDB磁盘空间的方法,即 db.repairDatabase(),但该操作有一定的风险性。
注意MongoDB4.0以上版本 db.repairDatabase()方法已经被废弃。
db.repairDatabase()操作需要停业务进行,因为MongoDB会锁库直到 repair 操作完成。
另外,必须注意预留足够的磁盘空间,需要额外一倍的空间,如果MongoDB 占用数据磁盘了100G,那么 repair 时还需要额外的100G+2G 空间。
也可以追加磁盘,然后将目标目录指向新加的磁盘。
MongoDB 默认的建表方式采用 snappy 压缩算法。如果有需要,可以采用压缩率更高的 zlib 和 zstd 算法。
我曾经在某些业务中使用 zlib 算法,相比 snappy 能再节省 50% 的存储空间,仅供参考。
1 | db.runCommand({create:<collection name>, storageEngine: {wiredTiger: {configString: "block_compressor=zlib"}}}) |
可以在 mongo shell 终端执行 db.collection.stats() 查看索引大小。如果索引大小过大,需要进行优化:
通过 indexStats
命令查看索引使用情况,对于不会使用的索引,可以考虑删除。
参考:https://www.mongodb.com/docs/v6.0/reference/operator/aggregation/indexStats/
索引包含的字段应该尽量精简;
对于大 value 字段,可以在业务允许的场景下考虑使用 Hash 索引。参考下面的测试,可以将索引的大小降低 1 个数量级;
1 | 使用 YCSB 插入约 260 万条数据,对其中一个字段建索引,该字段为 100B 大小的BinData. |
MongoDB本身没有提供直接的自动清理磁盘空间的功能,但可以通过以下几种方法来实现磁盘空间的清理
:
compact命令compact命令可以对集合进行碎片整理,回收空闲的物理空间。执行该命令后,MongoDB会重新组织集合的数据文件,释放未使用的空间。例如:
1 | db.runCommand({compact: "collectionName"}); |
**1. 增加超时时间 **
MongoDB允许你设置命令的超时时间。
你可以通过maxTimeMS选项来设置命令的最大执行时间(以毫秒为单位)。
例如:
1 | db.runCommand({ |
。
repairDatabase命令repairDatabase命令可以修复数据库并回收磁盘空间。该命令会扫描数据库中的所有集合,删除无效的数据文件,并重新组织数据。执行方法如下:
1 | db.repairDatabase(); |
1 | db.runCommand({repairDatabase: 1}); |
此方法虽然有效,但可能会对数据库性能产生较大影响,且在执行过程中会锁定数据库
。
如果需要定期清理旧数据以释放磁盘空间,可以使用MongoDB的TTL(Time To Live)索引。例如,为某个集合的日期字段创建TTL索引,设置过期时间为7天:
JavaScript
复制
1 | db.collection.createIndex({createdAt: 1}, {expireAfterSeconds: 604800}); |
这样,MongoDB会自动删除createdAt字段值早于7天的文档。