记一次"诡异"的mongodb进程退出事件

本文讨论了在使用Shell登录并启动MongoDB后,退出Shell导致MongoDB进程终止的问题。分析了原因在于Shell在退出时发送SIGHUP信号给所有子进程,包括MongoDB。提供了通过`--fork`参数启动MongoDB来避免此问题的方法,并强调了在后台运行程序时注意此类情况的重要性。

shell中通过mongo args &的方式启动mongo进程,退出shell重新登进之后发现mongo进程没了,查看日志发现有如下输出:

2015-06-18T18:39:58.593+0800 [signalProcessingThread] got signal 1 (Hangup), will terminate after current cmd ends
2015-06-18T18:39:58.593+0800 [signalProcessingThread] now exiting
2015-06-18T18:39:58.593+0800 [signalProcessingThread] dbexit:
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: going to close listening sockets…
2015-06-18T18:39:58.593+0800 [signalProcessingThread] closing listening socket: 8
2015-06-18T18:39:58.593+0800 [signalProcessingThread] closing listening socket: 10
2015-06-18T18:39:58.593+0800 [signalProcessingThread] removing socket file: /tmp/mongodb-27017.sock
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: going to flush diaglog…
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: going to close sockets…
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: waiting for fs preallocator…
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: lock for final commit…
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: final commit…
2015-06-18T18:39:58.603+0800 [replslave] repl: AssertionException dbclient error communicating with server: 172.19.2.176:27017
2015-06-18T18:39:58.615+0800 [signalProcessingThread] shutdown: closing all files…
2015-06-18T18:39:58.642+0800 [signalProcessingThread] closeAllFiles() finished
2015-06-18T18:39:58.642+0800 [signalProcessingThread] journalCleanup…
2015-06-18T18:39:58.642+0800 [signalProcessingThread] removeJournalFiles
2015-06-18T18:39:58.643+0800 [signalProcessingThread] shutdown: removing fs lock…
2015-06-18T18:39:58.643+0800 [signalProcessingThread] dbexit: really exiting now

可以看到有其他进程给mongo发了Hangup信息,就如同kill -1 pid,但可以确认的是没有人手动信号给mongodb进程,google之后发现这篇文章
原因大致如下:
Bash resends a SIGHUP to all jobs if it receives a SIGHUP itself; this would include mongod.
Also, if you happen to have huponexit turned on, every job will receive a SIGHUP when bash exits.
https://www.gnu.org/software/bash/manual/html_node/Signals.html

原来我用shell登进之后启动了mongo,然后退出shell使用的方式是直接关掉窗口,linux认为这是一起异常退出,这样一来这个shell进程就会收到SIGHUP信号,为了保证状态一致性,从而给它的所有子进程发送SIGHUP信号.而使用命令exit退出就不会有这种问题,因为linux会认为这是一种正常的退出
那么如何避免这种问题呢? 直接关闭窗口可能是很多人的习惯了(陋习),所以我们不能要求linux管理员总是这样做,是人就有可能会犯错,应该从根本上解决这个问题
查看mongodb官方文档会发现mongo有–fork这样的一个参数,使用该参数启动mongo时,会自动将其挂到init进程(pid为1)下启动,而不加的话ppid(父进程id)就是当前的shell进程,所以只要加上–fork问题就引刃而解了,这里需要注意的是,所有需要在后台运行的程序都需要注意该情况,务必采用像mongo –fork的方式执行
关于Linux的signal(信号)和bash更多内容请自行关注man bash

<think>首先,用户的问题是关于理解并优化命令 `sudo mkdir -p /data/db /usr/local/mongodb/log`。我需要参考提供的引用,但引用是关于MongoDB安装的,涉及mkdir命令。 关键引用: - 引用[1]:提到创建/data/db文件夹:`sudo mkdir -p /data/db`,然后启动MongoDB的命令。 - 引用[2]:类似,提到创建文件夹和权限修改:`sudo chmod 0755 /Users/macos/data`。 - 引用[3]:是关于解决dpkg问题的命令序列,不直接相关。 用户指定的命令是 `sudo mkdir -p /data/db /usr/local/mongodb/log`,所以这是创建两个目录:一个是/data/db,另一个是/usr/local/mongodb/log。 我的回答需要: - 解释这个命令。 - 讨论如何优化它。 - 结构清晰,帮助用户逐步解决问题。 - 使用中文。 - 遵循系统级指令:内联数学用$...$,独立公式用$$...$$(但这里可能不涉及数学),LaTeX语法正确。 - 生成相关问题。 - 在引用的段落末尾添加引用标识。 步骤: 1. **解释命令**: - `sudo`:以超级用户权限运行命令。 - `mkdir`:创建目录的命令。 - `-p`:选项,表示创建父目录(如果它们不存在);同时,它允许创建多个目录。 - 目录路径:`/data/db` 和 `/usr/local/mongodb/log`。所以,这个命令一次性创建这两个目录及其任何不存在的父目录。 2. **优化建议**: - **安全优化**:使用sudo创建系统目录,但要确保权限正确。引用[2]提到修改权限:`sudo chmod 0755 ...`。所以,在执行mkdir后,设置适当的权限可能是个好主意。 - **路径优化**:确保路径正确。例如,用户可能想要使用变量或脚本来避免硬编码路径。 - **避免重复**:如果目录已存在,mkdir -p不会报错;但仍然,在脚本中可以添加检查以避免不必要的操作。 - **结合其他命令**:如引用[1]和[2],创建目录后可能需要启动服务或设置权限。 - **错误处理**:在脚本中添加错误处理。 3. **生成相关问题**:我需要基于回答生成几个相关问题。参考示例,问题应相关于主题。 4. **结构化回答**: - 先解释命令。 - 然后讨论优化。 - 可能提供完整的命令序列或建议。 - 结束时添加相关问题。 5. **引用添加**:在引用的部分末尾添加引用标识。用户提供了引用[1], [2], [3],但用户说“上述引用仅供参考”,所以我应该尽可能参考它们。特别是引用[1]和[2]涉及mkdir和权限。 - 例如,当提到权限时,可以引用[2]。 - 当提到MongoDB启动时,可以引用[1]。 6. **用户上下文**:用户上一次提到优化使用sudo mkdir命令,涉及创建目录。引用是关于MongoDB的,但命令通用。 完整回答结构: - **引言**:简要说明命令的作用。 - **详细解释**: - 分解命令部分。 - 选项解释。 - **优化建议**: - 权限管理:引用[2]提到chmod,所以添加权限设置。 - 路径管理:使用变量或相对路径。 - 脚本化:创建脚本以便复用。 - **示例代码**:如果需要,提供Shell脚本示例。 - **总结**:强调最佳实践。 - **相关问题**:在最后生成。 相关问题想法: 1. 如何设置目录权限以确保安全? 2. 如何在脚本中处理目录创建错误? 3. 如何自动化MongoDB目录设置过程? 4. 什么是Linux文件权限的最佳实践? 在回答中自然地添加引用标识。例如: - "为了保证目录可访问性,建议设置合适的权限,如引用[2]所示。" - "正如引用[1]中提到的..." 确保回答真实可靠:基于标准Linux知识。 最终回答大纲: 1. **命令解释**:解释sudo mkdir -p /data/db /usr/local/mongodb/log。 2. **why优化**:解释为什么需要优化(安全、效率)。 3. **优化方法**: - 添加权限设置:使用chmod命令。 - 使用变量:如BASE_PATH="/data"。 - 错误检查:在脚本中添加检查。 - 完整命令序列示例。 4. **相关问题**:列出3-4个相关问题。 </think>### sudo mkdir -p /data/db /usr/local/mongodb/log 命令详解及优化 您的问题涉及理解并优化命令 `sudo mkdir -p /data/db /usr/local/mongodb/log`。这个命令主要用于创建 MongoDB 数据存储目录和日志目录,但可以扩展应用到其他场景。我会先解释命令的语法和作用,然后讨论优化方法,确保安全、高效和可维护。解释基于 Linux 系统标准命令,并参考了您提供的引用内容(如 MongoDB 安装示例)。 --- #### 1. **命令详解** - **命令结构**: - `sudo`: 以超级用户权限执行命令,避免普通用户无权操作系统目录的问题。这在创建系统级目录(如 `/data` 或 `/usr/local`)时必不可少。 - `mkdir`: Linux 创建目录的内置命令。 - `-p`: 选项表示 "parents",它会递归创建所有不存在的父目录。如果目录已存在,则忽略而不报错,这避免了手动逐层创建目录的麻烦。 - 目录路径:`/data/db` 和 `/usr/local/mongodb/log`。命令一次性创建这两个目录: - `/data/db`: 通常用于存储 MongoDB 的核心数据文件(如数据库文件)。 - `/usr/local/mongodb/log`: 用于存储 MongoDB 的日志文件,便于监控和调试。 命令整体效果是:如果 `/data` 或 `/usr/local/mongodb` 不存在,它会自动创建;然后在这些路径下新建 `db` 和 `log` 子目录。 - **为什么需要这个命令?** - MongoDB 等数据库服务在启动时要求指定数据目录(如 `/data/db`)和日志目录(如 `/usr/local/mongodb/log`)。如果目录缺失,服务可能无法运行。引用[1]中提到,通过 `sudo mongod --dbpath=/Users/.../data/db` 启动 MongoDB 时,必须确保 `dbpath` 目录事先存在;否则启动失败。类似地,日志目录的创建可以避免服务运行时无写入权限的错误。 - `-p` 选项的优点是高效:一条命令处理多个路径,无需多次执行 `mkdir`,这在脚本中尤其有用。 --- #### 2. **优化建议** 原始命令 `sudo mkdir -p /data/db /usr/local/mongodb/log` 虽简明,但在安全性和可维护性上有改进空间。以下是基于 Linux 最佳实践的优化方法,参考了您提供的引用内容: - **添加权限设置以提高安全性**: - **问题**:`sudo mkdir` 创建的目录默认权限可能过高(如 root 所有),导致普通用户或服务进程无法访问。引用[2]中提到,创建目录后需要 `sudo chmod` 修改权限(例如 `sudo chmod 0755 /Users/macos/data`),否则 MongoDB 可能无法写入日志或数据。 - **优化**:在 `mkdir` 后立即添加权限命令,限制目录访问。推荐使用 `chmod` 设置更安全的权限(如 `0755` 允许所有者读写执行,其他人只读执行)。示例命令序列: ```bash sudo mkdir -p /data/db /usr/local/mongodb/log sudo chmod 0755 /data/db # 设置数据目录权限 sudo chmod 0755 /usr/local/mongodb/log # 设置日志目录权限 ``` 这样确保 MongoDB 服务(或指定用户)能读写目录,同时防止未授权访问。权限值 `0755` 是常见选择,但可根据需求调整(如更严格的 `0700`)。 - **使用变量避免硬编码路径**: - **问题**:命令中的路径(如 `/data/db`)是硬编码的,容易出错或在系统变更时失效。引用[1]和[2]显示路径因用户环境不同而变化(如 `/Users/.../data`)。 - **优化**:在脚本中定义路径变量,提高可复用性。例如,创建 Shell 脚本: ```bash #!/bin/bash DATA_DIR="/data/db" # 定义数据目录变量 LOG_DIR="/usr/local/mongodb/log" # 定义日志目录变量 sudo mkdir -p "$DATA_DIR" "$LOG_DIR" # 使用变量创建目录 sudo chmod 0755 "$DATA_DIR" "$LOG_DIR" # 统一设置权限 echo "目录已创建并设置权限:$DATA_DIR 和 $LOG_DIR" ``` 优点:路径只需修改一次,脚本可重复运行;路径错误时易于调试。如果目录用于 MongoDB,可结合引用[1]的启动命令 `sudo mongod --dbpath=$DATA_DIR`。 - **添加错误检查和日志录**: - **问题**:`mkdir -p` 静默忽略已存在目录,但权限更改或路径错误可能未被捕获。引用[3]展示了通过命令序列处理错误(如 `mv` 和 `apt-get`),但优化目标是预防而非修复。 - **优化**:在脚本中加入条件检查,确保操作成功。示例: ```bash #!/bin/bash PATHS=("/data/db" "/usr/local/mongodb/log") # 路径数组 for path in "${PATHS[@]}"; do if sudo mkdir -p "$path"; then # 创建目录并检查退出状态 sudo chmod 0755 "$path" echo "成功创建并设置权限: $path" else echo "错误: 无法创建目录 $path" >&2 # 错误输出到 stderr exit 1 # 脚本终止 fi done ``` 好处:如果目录创建失败(如磁盘满或无效路径),脚本立即报错并退出避免后续问题。还可以添加日志重定向(如 `>> /var/log/setup.log`)用于审计。 - **整合到自动化部署流程**: - **问题**:手动运行命令效率低,尤其在多服务器环境中。引用[1]提到启动 MongoDB 的命令,但未自动化目录设置。 - **优化**:将目录创建嵌入到服务初始化脚本中(如 systemd 单元文件)。示例步骤: 1. 创建脚本(如 `/usr/local/bin/setup_mongo_dirs.sh`),包含上述优化内容。 2. 在 MongoDB 启动前调用脚本: ```systemd # /etc/systemd/system/mongod.service 示例片段 [Service] ExecStartPre=/usr/local/bin/setup_mongo_dirs.sh # 启动前确保目录存在 ExecStart=/usr/bin/mongod --dbpath=/data/db --logpath=/usr/local/mongodb/log/mongod.log ``` 这避免了每次启动前手动运行命令,提升可靠性。 **总结优化原则**:安全(权限控制)、可维护(变量化)、健壮(错误处理)和自动化。最终优化命令序列示例: ```bash # 安全创建目录并设置权限 sudo mkdir -p /data/db /usr/local/mongodb/log && \ sudo chmod 0755 /data/db /usr/local/mongodb/log ``` 此处 `&&` 确保权限更改仅在目录创建成功后执行。 --- #### 3. **注意事项** - **路径验证**:确保路径有效(如 `/usr/local` 通常需要 root 权限)。如果路径包含用户变量(如引用[2]中的 `/Users/macos/data`),使用 `whoami` 命令动态获取用户名。 - **安全性**:避免不必要的 sudo 使用。如果目录在用户主目录下,可省略 sudo(例如 `mkdir -p ~/data/db`)。 - **MongoDB 特定**:优化后,结合引用[1]启动命令 `sudo mongod --dbpath=/data/db` 测试目录是否工作正常。 - **跨平台兼容**:在 macOS 或 Linux 均适用,但 Windows 需调整语法(如使用 `md` 命令)。 通过以上优化,命令更可靠且易于集成到部署流程中。如果您有特定环境细节(如操作系统或用户权限),可进一步调整。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值