当前位置: 首页 > news >正文

MongoDB 源码编译与调试:深入理解存储引擎设计

MongoDB 源码编译与调试:深入理解存储引擎设计

    • 第一章:环境准备与源码获取
      • 1.1 系统要求与依赖配置
      • 1.2 源码获取与结构分析
    • 第二章:编译系统与构建配置
      • 2.1 SCons 构建系统详解
      • 2.2 多配置构建策略
    • 第三章:存储引擎架构深度解析
      • 3.1 存储引擎接口设计
      • 3.2 WiredTiger 存储引擎深度分析
    • 第四章:调试环境配置与技巧
      • 4.1 GDB 调试配置
      • 4.2 实战调试示例
    • 第五章:核心模块源码分析
      • 5.1 查询执行引擎
      • 5.2 复制状态机
    • 第六章:性能分析与优化
      • 6.1 性能剖析工具
      • 6.2 存储引擎性能调优
    • 第七章:测试与验证
      • 7.1 单元测试与集成测试
      • 7.2 压力测试与故障注入
    • 第八章:生产环境部署建议
      • 8.1 编译优化建议
      • 8.2 监控与维护

第一章:环境准备与源码获取

1.1 系统要求与依赖配置

在进行 MongoDB 源码编译之前,需要准备合适的开发环境。以下是详细的环境要求:
操作系统要求:

  • Ubuntu 20.04/22.04 LTS(推荐)
  • CentOS 7/8 或 RHEL 7/8
  • macOS Monterey 或更高版本
  • Windows 10/11(使用 WSL2 推荐)
    硬件要求:
  • 内存:至少 8GB,推荐 16GB 以上
  • 磁盘空间:至少 50GB 可用空间
  • 处理器:多核处理器,支持 SSE4.2 指令集
    依赖安装(Ubuntu 示例):
# 安装基础开发工具
sudo apt-get update
sudo apt-get install -y git build-essential curl ccache# 安装 Python 和 pip
sudo apt-get install -y python3 python3-pip python3-venv# 安装 MongoDB 编译依赖
sudo apt-get install -y libcurl4-openssl-dev liblzma-dev libsnappy-dev \libzstd-dev libssl-dev libboost-all-dev libpcre3-dev libreadline-dev \libbz2-dev libnuma-dev libyaml-cpp-dev liblmdb-dev# 安装 Ninja 构建系统
sudo apt-get install -y ninja-build# 安装现代 C++ 编译器
sudo apt-get install -y clang-14 clang++-14 gcc-11 g++-11# 设置默认编译器
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 100
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 100
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-14 100

1.2 源码获取与结构分析

获取 MongoDB 源码:

# 克隆 MongoDB 仓库
git clone https://github.com/mongodb/mongo.git
cd mongo# 查看可用版本标签
git tag -l | grep '^r' | sort -V | tail -10# 切换到特定版本(例如 6.0.8)
git checkout r6.0.8# 初始化子模块
git submodule update --init --recursive --progress

MongoDB 源码目录结构:

mongo/
├── src/                          # 核心源码目录
│   ├── mongo/                    # MongoDB 核心代码
│   │   ├── db/                   # 数据库引擎
│   │   │   ├── commands/         # 数据库命令
│   │   │   ├── exec/             # 查询执行
│   │   │   ├── query/            # 查询处理
│   │   │   └── storage/          # 存储引擎接口
│   │   ├── embedded/             # 嵌入式版本
│   │   ├── client/               # 客户端代码
│   │   └── script/               # JavaScript引擎
├── etc/                          # 配置文件
├── modules/                      # 可选的编译模块
│   ├── enterprise/               # 企业版模块
│   └── third_party/              # 第三方依赖
└── buildscripts/                 # 构建脚本

第二章:编译系统与构建配置

2.1 SCons 构建系统详解

MongoDB 使用 SCons 作为主要的构建系统,这是一个基于 Python 的构建工具。
SCons 基本配置:

# 查看可用的构建选项
python3 buildscripts/scons.py --help# 常用的构建选项
export SCONSFLAGS="-j$(nproc)                    # 使用所有CPU核心--disable-warnings-as-errors   # 不将警告视为错误--use-system-ccache           # 使用系统ccache--use-system-snappy           # 使用系统snappy--release                     # 发布模式构建
"# 设置编译器和工具链
export CC=/usr/bin/clang-14
export CXX=/usr/bin/clang++-14
export LINK=/usr/bin/clang++-14

构建配置示例:

# 创建构建配置目录
mkdir -p build && cd build# 生成构建配置
python3 ../buildscripts/scons.py \--dbg=on                     \  # 调试模式--opt=on                     \  # 优化模式--ssl                        \  # 启用SSL--disable-warnings-as-errors \  # 禁用警告错误--use-system-zstd           \  # 使用系统zstd--use-system-snappy         \  # 使用系统snappy--use-system-icu            \  # 使用系统ICUcore                         \  # 构建核心组件install-platform               # 安装平台相关组件

2.2 多配置构建策略

调试版本构建:

# 调试版本配置
python3 buildscripts/scons.py \--dbg=on                  \--opt=off                 \--ssl                     \--disable-warnings-as-errors \--variables-files=etc/scons/mongodbtoolchain_stable_clang.vars \MONGO_VERSION=$(git describe --tags) \all

发布版本构建:

# 发布版本配置
python3 buildscripts/scons.py \--dbg=off                 \--opt=on                  \--ssl                     \--variables-files=etc/scons/mongodbtoolchain_stable_clang.vars \MONGO_VERSION=$(git describe --tags) \all

特定组件构建:

# 只构建 mongod
python3 buildscripts/scons.py \--dbg=on \mongod# 只构建 mongos
python3 buildscripts/scons.py \--dbg=on \mongos# 构建测试工具
python3 buildscripts/scons.py \--dbg=on \unittests \dbtests

第三章:存储引擎架构深度解析

3.1 存储引擎接口设计

MongoDB 的存储引擎采用插件式架构,核心接口定义在 src/mongo/db/storage 目录中。
核心接口类:

// 存储引擎基类
class StorageEngine {
public:virtual ~StorageEngine() = default;// 引擎初始化virtual void initialize(OperationContext* opCtx) = 0;// 恢复引擎状态virtual void notifyStorageStartupRecoveryComplete() = 0;// 创建集合virtual Status createCollection(OperationContext* opCtx,const NamespaceString& nss,const CollectionOptions& options) = 0;// 删除集合virtual Status dropCollection(OperationContext* opCtx,const NamespaceString& nss) = 0;// 事务管理virtual std::unique_ptr<Transaction> beginTransaction(OperationContext* opCtx,const TransactionOptions& options) = 0;// 检查点管理virtual void checkpoint() = 0;
};

WiredTiger 引擎实现:

class WiredTigerEngine : public StorageEngine {
public:explicit WiredTigerEngine(const std::string& path);// 重写基类方法void initialize(OperationContext* opCtx) override;Status createCollection(OperationContext* opCtx,const NamespaceString& nss,const CollectionOptions& options) override;// WiredTiger 特定方法WT_CONNECTION* getConnection() const { return _conn; }WT_SESSION* getSession(OperationContext* opCtx);private:WT_CONNECTION* _conn;std::string _path;std::atomic<uint64_t> _nextSessionId{0};
};

3.2 WiredTiger 存储引擎深度分析

WiredTiger 是 MongoDB 的默认存储引擎,其架构设计非常精巧。下图展示了 WiredTiger 存储引擎的核心架构和数据处理流程:

WiredTiger 存储引擎
缓存层
事务层
持久化层
数据刷写
日志持久化
查询处理层
日志管理器
预写日志WAL
检查点机制
B-Tree索引结构
数据压缩
文件系统操作
事务管理器
快照隔离
行级锁管理
页面缓存
存储引擎API
页面淘汰算法
客户端请求
持久化存储

缓存管理实现:

class WiredTigerCache {
public:// 缓存配置struct Config {size_t maxSize;          // 最大缓存大小double evictionTarget;    // 淘汰目标比例double evictionTrigger;   // 淘汰触发比例};WiredTigerCache(const Config& config);// 页面管理Status insertPage(PageId id, const uint8_t* data, size_t size);Status getPage(PageId id, uint8_t** data, size_t* size);Status evictPage(PageId id);// 内存管理size_t getCurrentSize() const;size_t getMaxSize() const;void resize(size_t newSize);private:// LRU 淘汰算法实现void performEviction();Config _config;std::unordered_map<PageId, CacheEntry> _pages;std::list<PageId> _lruList;mutable std::mutex _mutex;
};

事务管理实现:

class WiredTigerTransaction : public Transaction {
public:WiredTigerTransaction(WT_SESSION* session, const TransactionOptions& options);// 事务操作Status commit() override;Status abort() override;// 读写操作Status insert(const std::string& key, const std::string& value) override;Status update(const std::string& key, const std::string& value) override;Status remove(const std::string& key) override;Status read(const std::string& key, std::string* value) override;// 快照管理void setSnapshot(const Snapshot& snapshot) override;Snapshot getSnapshot() const override;private:WT_SESSION* _session;WT_TXN* _txn;bool _active;
};

第四章:调试环境配置与技巧

4.1 GDB 调试配置

GDB 初始化配置:

# 创建 .gdbinit 文件
cat > ~/.gdbinit << 'EOF'
set pagination off
set print pretty on
set print object on
set print static-members on
set print vtbl on
set print demangle on
set demangle-style gnu-v3
set history save on
set history filename ~/.gdb_history
EOF# 添加 MongoDB 特定调试命令
cat >> ~/.gdbinit << 'EOF'
define mongobtbtthread apply all bt
enddocument mongobtPrint backtrace for all threads
enddefine mongodbinfo threadsthread apply all where
enddocument mongodbShow all threads and their stack traces
end
EOF

调试符号构建:

# 构建带调试符号的版本
python3 buildscripts/scons.py \--dbg=on \--opt=off \--disable-warnings-as-errors \MONGO_VERSION=$(git describe --tags) \all# 安装调试符号
objcopy --only-keep-debug build/debug/mongod mongod.debug
objcopy --add-gnu-debuglink=mongod.debug build/debug/mongod

4.2 实战调试示例

启动调试会话:

# 启动 mongod 进行调试
gdb --args ./build/debug/mongod \--dbpath /data/db \--storageEngine wiredTiger \--port 27017 \--logpath /var/log/mongodb/mongod.log \--fork

常用 GDB 命令:

# 在 GDB 中设置断点
(gdb) break mongo::WiredTigerEngine::initialize
(gdb) break mongo::WiredTigerRecoveryUnit::commit
(gdb) break mongo::OperationContext::checkForInterrupt# 设置条件断点
(gdb) break mongo::WiredTigerSessionCache::releaseSession if sessionId == 0x1234# 查看线程信息
(gdb) info threads
(gdb) thread 2
(gdb) bt# 查看变量和内存
(gdb) print *opCtx
(gdb) print opCtx->getLockState()
(gdb) x/10x opCtx->getRecoveryUnit()# 监视点设置
(gdb) watch -l globalTransactionId
(gdb) watch *(uint64_t*)0x7fffffffe320# 反向调试
(gdb) record full
(gdb) reverse-step
(gdb) reverse-continue

LLDB 调试配置(macOS):

# LLDB 初始化配置
cat > ~/.lldbinit << 'EOF'
settings set target.x86-disassembly-flavor intel
settings set target.skip-prologue false
settings set stop-disassembly-display always
settings set frame-format frame: {${frame.index}}: {${frame.pc}} {${function.name}}{${function.name-offset}}{ ${function.addr-offset}} { at ${line.file.fullpath}:${line.number}}
EOF# LLDB 调试命令
lldb -- ./build/debug/mongod --dbpath /data/db
(lldb) breakpoint set -n mongo::WiredTigerEngine::createCollection
(lldb) breakpoint set -f wt_btree.c -l 1234
(lldb) run

第五章:核心模块源码分析

5.1 查询执行引擎

查询计划器实现:

class QueryPlanner {
public:static StatusWith<std::unique_ptr<PlanExecutor>> planQuery(OperationContext* opCtx,const CollectionPtr& collection,const QueryRequest& queryRequest,const QueryPlannerParams& params);private:// 生成候选计划Status _generateCandidates(const QueryRequest& queryRequest,std::vector<std::unique_ptr<QuerySolution>>* candidates);// 成本估算double _estimateCost(const QuerySolution& solution) const;// 索引选择Status _selectIndexes(const QueryRequest& queryRequest,std::vector<IndexEntry>* indexEntries);
};// 查询执行器
class PlanExecutor {
public:Status getNext(Document* obj, bool* exhausted);// 执行状态bool isEOF() const;void saveState();void restoreState();// 性能统计PlanStats getStats() const;private:std::unique_ptr<PlanStage> _root;WorkingSet _workingSet;
};

5.2 复制状态机

Oplog 应用逻辑:

class OplogApplier {
public:Status applyOplogBatch(OperationContext* opCtx,const std::vector<OplogEntry>& batch);private:// 应用单个操作Status _applyOperation(OperationContext* opCtx,const OplogEntry& entry);// 冲突检测和解决Status _handleConflict(OperationContext* opCtx,const OplogEntry& entry,const Status& conflictStatus);// 重试逻辑Status _retryApplication(OperationContext* opCtx,const OplogEntry& entry,int maxRetries);
};// 复制协调器
class ReplicationCoordinator {
public:// 状态管理ReplState getState() const;bool isMaster() const;// 选举管理Status startElection();Status stepDown(const Milliseconds& waitTime);// 数据同步Status syncDataFrom(const HostAndPort& source);
};

第六章:性能分析与优化

6.1 性能剖析工具

Linux perf 配置:

# 安装 perf
sudo apt-get install -y linux-tools-common linux-tools-generic# 允许非 root 用户使用 perf
echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid# 性能分析会话
perf record -g -- ./build/debug/mongod --dbpath /data/db
perf report -g graph --sort comm,dso

MongoDB 内置剖析:

// 启用数据库剖析
db.setProfilingLevel(2, { slowms: 100 })// 分析查询性能
db.system.profile.find().sort({ ts: -1 }).limit(10).pretty()// 使用 explain 分析查询计划
db.collection.find({ name: "test" }).explain("executionStats")

6.2 存储引擎性能调优

WiredTiger 配置优化:

# mongod.conf 性能优化配置
storage:wiredTiger:engineConfig:cacheSizeGB: 16           # 根据内存调整journalCompressor: snappy # 日志压缩算法directoryForIndexes: true # 索引单独目录collectionConfig:blockCompressor: zstd     # 集合数据压缩indexConfig:prefixCompression: true   # 索引前缀压缩# 网络和连接配置
net:maxIncomingConnections: 10000compression:compressors: snappy,zlib,zstd# 操作限制
operationProfiling:mode: slowOpslowOpThresholdMs: 100rateLimit: 100

运行时性能监控:

// 监控存储引擎状态
db.serverStatus().wiredTiger// 查看缓存统计
db.serverStatus().wiredTiger.cache// 查看连接和会话信息
db.serverStatus().wiredTiger.connection
db.serverStatus().wiredTiger.session// 查看事务统计
db.serverStatus().wiredTiger.transaction

第七章:测试与验证

7.1 单元测试与集成测试

运行测试套件:

# 运行核心单元测试
python3 buildscripts/scons.py \--dbg=on \unittests./build/debug/unittests --gtest_filter="StorageEngineTest*"# 运行数据库测试
python3 buildscripts/scons.py \--dbg=on \dbtests./build/debug/dbtests --suites=WiredTigerEngineTests# 运行性能测试
python3 buildscripts/scons.py \--dbg=on \performance_tests./build/debug/performance_tests --suites=QueryPerformance

自定义测试用例:

// 存储引擎测试用例
TEST_F(WiredTigerEngineTest, TransactionAtomicity) {auto opCtx = makeOperationContext();AutoGetCollection collection(opCtx.get(), nss, MODE_IX);// 开始事务opCtx->setInMultiDocumentTransaction();beginTransaction(opCtx.get());try {// 执行多个操作insertDocument(opCtx.get(), collection, doc1);insertDocument(opCtx.get(), collection, doc2);// 故意制造冲突forceConflict(opCtx.get());// 提交事务commitTransaction(opCtx.get());FAIL() << "Expected transaction conflict";} catch (const DBException& ex) {// 验证事务回滚ASSERT_EQ(ex.code(), ErrorCodes::WriteConflict);assertNoDocumentsInCollection(collection);}
}

7.2 压力测试与故障注入

压力测试脚本:

// JavaScript 压力测试
function runStressTest() {const duration = 3600; // 1小时const threads = 16;const batchSize = 1000;for (let i = 0; i < threads; i++) {startThread(function() {for (let j = 0; j < duration; j++) {// 混合读写操作if (Math.random() < 0.7) {bulkWrite([{ insert: { document: randomDocument() } },{ update: { filter: randomFilter(), update: randomUpdate() } },{ delete: { filter: randomFilter() } }], { ordered: false });} else {aggregate([{ $sample: { size: batchSize } }]);}// 随机事务操作if (Math.random() < 0.1) {startTransaction();try {performTransactionalOperations();commitTransaction();} catch (e) {abortTransaction();}}}});}
}

故障注入测试:

// 故障注入框架
class FaultInjector {
public:enum class FaultType {DiskFull,NetworkPartition,MemoryAllocationFailure,ClockSkew,ProcessKill};static void injectFault(FaultType type, double probability = 0.01);private:static std::atomic<bool> _faultInjectionEnabled;static std::mutex _mutex;static std::unordered_map<FaultType, double> _faultProbabilities;
};// 在关键路径注入故障
Status WiredTigerEngine::insertDocument(OperationContext* opCtx,const Document& doc) {// 随机注入磁盘满错误FaultInjector::injectFault(FaultType::DiskFull, 0.001);try {return _insertDocumentImpl(opCtx, doc);} catch (const StorageException& ex) {if (ex.code() == ErrorCodes::OutOfDiskSpace) {handleDiskFullCondition(opCtx);}throw;}
}

第八章:生产环境部署建议

8.1 编译优化建议

生产环境编译配置:

# 优化编译配置
python3 buildscripts/scons.py \--dbg=off                 \--opt=on                  \--ssl                     \--use-hardware-crc32      \  # 启用硬件CRC32--use-avx2                \  # 启用AVX2指令集--use-sse4.2              \  # 启用SSE4.2指令集--variables-files=etc/scons/mongodbtoolchain_stable_clang.vars \MONGO_VERSION=$(git describe --tags) \MONGO_DISTNAME="custom-optimized" \all

安全加固编译:

# 安全加固选项
python3 buildscripts/scons.py \--dbg=off                 \--opt=on                  \--ssl                     \--enable-warnings-as-errors \  # 将警告视为错误--fuzz-functionality      \  # 启用模糊测试功能--sanitize=address,undefined \  # 启用地址和未定义行为检测--variables-files=etc/scons/mongodbtoolchain_stable_clang.vars \all

8.2 监控与维护

运行时监控配置:

# 监控配置
monitoring:version: 1exporters:- type: prometheusport: 9216path: /metricsoptions:gatherInterval: 15stimeout: 10smetrics:wiredTiger:enabled: trueinterval: 30sinclude: [ "cache", "transaction", "session", "connection" ]operation:enabled: trueinterval: 60sinclude: [ "latency", "throughput", "error_rate" ]system:enabled: trueinterval: 30sinclude: [ "cpu", "memory", "disk", "network" ]

性能调优脚本:

#!/bin/bash
# MongoDB 性能调优脚本MONGO_URI="mongodb://localhost:27017"
CONFIG_FILE="/etc/mongod.conf"
BACKUP_DIR="/backup/mongodb/config"# 备份当前配置
backup_config() {local timestamp=$(date +%Y%m%d_%H%M%S)cp "$CONFIG_FILE" "$BACKUP_DIR/mongod.conf.$timestamp"echo "配置已备份到 $BACKUP_DIR/mongod.conf.$timestamp"
}# 调整 WiredTiger 缓存
adjust_cache_size() {local total_memory=$(grep MemTotal /proc/meminfo | awk '{print $2}')local cache_size=$((total_memory * 60 / 100 / 1024))  # 60% of memory in GBmongosh "$MONGO_URI" --eval "db.adminCommand({setParameter: 1,wiredTigerEngineRuntimeConfig: 'cache_size=${cache_size}GB'})"echo "设置 WiredTiger 缓存大小为 ${cache_size}GB"
}# 优化系统参数
optimize_system() {# 调整内核参数echo "net.core.somaxconn = 4096" >> /etc/sysctl.confecho "vm.swappiness = 1" >> /etc/sysctl.confecho "vm.dirty_ratio = 15" >> /etc/sysctl.confecho "vm.dirty_background_ratio = 5" >> /etc/sysctl.confsysctl -p# 调整磁盘IO调度for disk in /sys/block/sd*; doecho deadline > "$disk/queue/scheduler"echo 1024 > "$disk/queue/nr_requests"echo 128 > "$disk/queue/read_ahead_kb"done
}# 主函数
main() {backup_configadjust_cache_sizeoptimize_systemecho "性能调优完成"
}main "$@"

通过这个全面的指南,您应该能够深入理解 MongoDB 的存储引擎设计,掌握源码编译和调试的技巧,并能够在生产环境中进行有效的性能调优和故障排查。记住,深入理解系统内部机制是成为高级数据库工程师的关键一步。


文章转载自:

http://SAIfViwI.gwsfq.cn
http://1OXCC2xG.gwsfq.cn
http://jruXd6os.gwsfq.cn
http://3fleLWzZ.gwsfq.cn
http://A95wd6W5.gwsfq.cn
http://K9VCqzKN.gwsfq.cn
http://dvOxJ6P7.gwsfq.cn
http://soQ1Ki3K.gwsfq.cn
http://xyduUgtO.gwsfq.cn
http://bgtu6Aq5.gwsfq.cn
http://Jgt2YIUL.gwsfq.cn
http://M5qQLvbw.gwsfq.cn
http://Nq1Z4nkT.gwsfq.cn
http://yxOFa4BY.gwsfq.cn
http://xfh8BzQj.gwsfq.cn
http://S3buDIMT.gwsfq.cn
http://4MHXWQ79.gwsfq.cn
http://DhiWl3jp.gwsfq.cn
http://T6utZf0B.gwsfq.cn
http://Aw3ULrgB.gwsfq.cn
http://7Ks3nsIh.gwsfq.cn
http://vCirZXYm.gwsfq.cn
http://79ZMajoS.gwsfq.cn
http://J5W40xyk.gwsfq.cn
http://b3LqvFsL.gwsfq.cn
http://XqxeWKrK.gwsfq.cn
http://OpOXLpoE.gwsfq.cn
http://tag5XmmQ.gwsfq.cn
http://kkzEe91s.gwsfq.cn
http://8YkpNuEm.gwsfq.cn
http://www.dtcms.com/a/368333.html

相关文章:

  • TensorFlow 面试题及详细答案 120道(91-100)-- 实际应用与案例
  • CAD:修改
  • MQTT 认证与授权机制实践(二)
  • RL【3】:Bellman Optimality Equation
  • Apache Ranger 详细介绍
  • 计算机网络IP协议
  • Git rm 命令与系统 rm 命令的区别详解
  • More Effective C++ 条款30:代理类
  • 织信低代码:用更聪明的方式,把想法变成现实!
  • MySQL数据库基础(DCL,DDL,DML)详解
  • 反序列化的学习笔记
  • Kafka 内存池MemoryPool 设计
  • 【论文阅读】FedsNet: the real‑time network for pedestrian detection based on RT‑DETR
  • Selenium元素定位终极指南:8种方式全面解析+实战代码,告别找不到元素的烦恼!
  • 【MFC Picture Control 控件属性】
  • 迁移学习实战:基于 ResNet18 的食物分类
  • python用selenium怎么规避检测?
  • Rust 的生命周期与借用检查:安全性深度保障的基石
  • 面试 TOP101 贪心专题题解汇总Java版(BM95 —— BM96)
  • 软件启动时加配置文件 vs 不加配置文件
  • 工业跨网段通信解决方案:SG-NAT-410 网关,无需改参数,轻松打通异构 IP 网络
  • Elasticsearch-java 使用例子
  • 我改写的二分法XML转CSV文件程序速度追上了张泽鹏先生的
  • GPU测速方法
  • OpenCV C++ 色彩空间详解:转换、应用与 LUT 技术
  • 前端笔记2025
  • 跨境电商:如何提高电商平台数据抓取效率?
  • python + Flask模块学习 2 接收用户请求并返回json数据
  • K8S-Pod(上)
  • 【代码随想录day 23】 力扣 93.复原IP地址