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

Ceph入门到精通-Linux下Ceph源码编译和GDB调试

Ceph版本:14.2.22
Linux版本:ubuntu-server 18.04

 
 

第一部分 下载Ceph源码

1.1 配置Ceph源码镜像源

Ceph源码是托管在Github上,由于某些原因,国内访问Github网站很慢,所以需要从其他途径加速获取源码。Github官方给出了几个Github的镜像网站:

  1. https://github.com.cnpmjs.org/
  2. https://hub.fastgit.org/

本地需要修改~/.gitconfig文件,才可以从上面镜像网站获取源码,相关配置如下:

#Github镜像源
[url "https://hub.fastgit.org/"]insteadOf = https://github.com/

注:国内也有Ceph源码的镜像,比如Gitee、Gitcode,但不建议从这些网站上获取。因为Ceph源码中使用了大量的第三方源码作为自己的子模块,而Gitee、Gitcode不一定将这些子模块全部同步过来。相反,上面的两个镜像网站和Github完全是同步的,所以可以放心使用。

1.2 克隆ceph源码

Ceph源码很大,可根据需要,选择性下载哪个版本或哪个分支。本案例拉取v14.2.22版本的源码。版本和分支的区别:版本的代码不会随时间改变,被定格在打标签的那一刻;分支的代码会随时间不断开发改变。

# 根据自己需要更换 v14.2.22 为自己需要的版本
git clone -b v14.2.22 --depth=1 https://github.com/ceph/ceph.git

1.3 同步子模块源码

Ceph源码中使用大量的子模块,在 ceph/.gitmodules 文件中罗列出所有的子模块。在后面执行do_cmake.sh 脚本生成 build 目录时,do_cmake.sh 首先同步子模块源码到指定目录。根据经验,在同步子模块源码时很容易出现同步不全,或同步失败,这直接会导致构建 build 目录失败。为了防止此状况发生,建议提前手动去同步子模块源码。

git submodule update --init --recursive

注:如果发现同步子模块源码失败,重复执行上面命令即可。如果中断同步子模块源码,此时必须要到相应目录下删除该子模块所有文件,尤其是 .git 文件。如果不删除 .git,重复执行上面命令时,则会直接跳过同步该子模块,导致子模块源码缺失。这个问题无法被检测到,因为执行完上面命令后,依然会显示同步成功,而不会提示哪个子模块没有被同步。
 
 

第二部分 源码编译

2.1 安装依赖

Ceph源码安装依赖很简单,直接执行源码根目录下install-deps.sh脚本,根据经验发现,该脚本存在一些问题,需要稍微修改一下。

2.1.1 修改launchpad源

脚本会安装gcc环境,安装包源url只需要保留一个即可,修改install-deps.sh脚本中的函数ensure_decent_gcc_on_ubuntu

deb [lang=none] http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu $codename main
#deb [arch=amd64 lang=none] http://mirror.cs.uchicago.edu/ubuntu-toolchain-r $codename main
#deb [arch=amd64,i386 lang=none] http://mirror.yandex.ru/mirrors/launchpad/ubuntu-toolchain-r $codename main

2.1.2 屏蔽调用安装libboost的部分

脚本会安装 libboost 库,编译源码过程会再次下载 boost 源码包,因此脚本中不应该再安装 libboost,屏蔽install-deps.sh以下2个地方

 *Bionic*)#install_boost_on_ubuntu bionic;;

2.1.3 设置pypi镜像源

脚本会安装pypi库,默认url下载很慢,需要设置pypi库镜像源。创建 ~/.pip/pip.conf 文件,并追加以下内容

[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com

2.1.4 安装其他依赖

编译源码过程中会遇到很多函数用到zstd库,默认情况下ubuntu18.04只安装了libzstd1,但没有用,需要安装 libzstd1-dev

sudo apt install libzstd1-dev

2.1.5 执行脚本

./install-deps.sh

2.2 编译Ceph源码

2.2.1 开启debug模式

如果想要调试Ceph源码,需要设置编译源码模式为debug模式,默认编译模式为release模式,该模式是不能调试源码。向 ceph/CMakeList 文件的 set(VERSION 14.2.22) 后追加以下内容

set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -Wall -g")
set(CMAKE_CXX_FLAGS "-O0 -Wall -g")
set(CMAKE_C_FLAGS "-O0 -Wall -g ")

2.2.2 构建build目录

直接执行do_cmake脚本,该脚本会进行一系列检测,包括源码是不是完整,依赖是不是都安装了等等。如果出现问题,构建出的build目录是不完整的,最直接的影响是无法生成makefile文件,导致无法编译。

./do_cmake.sh

2.2.3 下载boost源码包

在执行make编译的时候,脚本会自动下载 boost_1_72_0.tar.bz2,由于下载地址和网络问题,下载很慢,为了节省时间,提前手动下载,下载地址:https://download.ceph.com/qa/boost_1_72_0.tar.bz2,将下载的好的包放在ceph/build/boost/src即可。

2.2.4 编译

使用make编译必须要到ceph/build目录下执行,ceph源码可以单独编译某一个模块,也可以全部编译。使用make可以指定多线程编译,提高编译速度,但要合理分配线程数,建议使用4线程编译即可。

#方式1:全部编译
make all -j4
#方式2:单独编译osd某块
make ceph-osd -j4
#查看所有模块
make help

注:源码编译会生成很多库文件和二进制文件,分别放在ceph/build/lib和ceph/build/bin目录下
 
 

第三部分 部署Debug版本的集群

3.1 集群部署

Cpeh源码提供了一个部署开发集群的脚本:vstart.sh,该脚本会利用本地IP和不同端口来配置MON、MGR、OSD等。切换到切换到build目录下,执行以下命令,部署一个新的集群

MON=1 OSD=6 MDS=0 MGR=1 RGW=0 ../src/vstart.sh -d -n  -x  --without-dashboard

参数解释:

  1. MON、 OSD、 MDS、 MGR是配置相应的个数
  2. -d:debug,开启debug模式
  3. -n:new,新建一个集群
  4. -x:cephx,cephx认证
  5. --without-dashboard,mgr的一个配置,自测发现如果这个不关闭,部署会报错

3.2 查看集群状态

切换到build目录下,执行以下命令,查看集群状态

./bin/ceph -s 

结果如下

  cluster:id:     88b11a21-7dd1-49d8-bb24-c18821ff09aehealth: HEALTH_OKservices:mon: 1 daemons, quorum a (age 5m)mgr: x(active, since 5m)osd: 6 osds: 6 up (since 4m), 6 in (since 4m)data:pools:   0 pools, 0 pgsobjects: 0 objects, 0 Busage:   12 GiB used, 594 GiB / 606 GiB availpgs:   

注:ceph 14.2.22版本的vstart.sh脚本并没有将ceph可执行文件添加到系统环境变量中,所有的ceph命令都必须在build目录下执行

3.3 部署ceph分级存储结构

本案例需要调试ceph分级存储功能,因此简单的搭建一个分层存储结构。为集群分配6个OSD,创建2个pool,cache pool和ec pool,每个pool分配了3个osd。
详细部署请参考(文章还在编写中)
 
 

第四部分 代码调试

4.1 查看PG-OSD映射关系

如果仔细阅读源码,会发现ceph分级存储主要是由主OSD进程来负责。如果不是主OSD,是无法调试到代码中的。所以需要查看分级存储中缓存池的PG映射关系。

#切换到build目录下,执行以下命令
./bin/ceph pg ls-by-pool cache_poolPG  OBJECTS DEGRADED MISPLACED UNFOUND BYTES OMAP_BYTES* OMAP_KEYS* LOG STATE        SINCE VERSION REPORTED UP        ACTING    SCRUB_STAMP                DEEP_SCRUB_STAMP           
5.0       0        0         0       0     0           0          0  18 active+clean   22h  323'18   323:76 [2,4,0]p2 [2,4,0]p2 2021-09-25 16:55:28.572062 2021-09-24 11:30:14.717641 

从结果可以看到PG5.0对应的主OSD为OSD 2

4.2 查看主OSD进程

执行以下命令

ps -ef | grep ceph

结果如下

admins   10961 19680  0 15:12 pts/0    00:00:00 grep --color=auto ceph
admins   18474     1  1 Sep24 ?        01:02:09 /home/admins/code/ceph/build/bin/ceph-mon -i a -c /home/admins/code/ceph/build/ceph.conf
admins   18582     1  1 Sep24 ?        00:33:41 /home/admins/code/ceph/build/bin/ceph-mgr -i x -c /home/admins/code/ceph/build/ceph.conf
admins   18806     1  1 Sep24 ?        00:41:15 /home/admins/code/ceph/build/bin/ceph-osd -i 1 -c /home/admins/code/ceph/build/ceph.conf
admins   19096     1  1 Sep24 ?        00:41:06 /home/admins/code/ceph/build/bin/ceph-osd -i 3 -c /home/admins/code/ceph/build/ceph.conf
admins   19242     1  1 Sep24 ?        00:40:37 /home/admins/code/ceph/build/bin/ceph-osd -i 4 -c /home/admins/code/ceph/build/ceph.conf
admins   19415     1  1 Sep24 ?        00:41:00 /home/admins/code/ceph/build/bin/ceph-osd -i 5 -c /home/admins/code/ceph/build/ceph.conf
admins   20385     1  1 Sep24 ?        00:39:47 /home/admins/code/ceph/build/bin/ceph-osd -i 0 -c /home/admins/code/ceph/build/ceph.conf
admins   22235     1  1 Sep24 ?        00:40:24 /home/admins/code/ceph/build/bin/ceph-osd -i 2 -c /home/admins/code/ceph/build/ceph.conf

从结果可以看到,主OSD进程号为 22235

4.3 GDB多线程调试

关于linux gdb多线程调试具体用法这里就不多介绍,需要学习了解的,请百度。以下仅为本案例调试步骤

4.3.1 进入gdb模式

gdb调试需要以管理员权限,执行以下命令,进入gdb模式

sudo gdb

结果如下

[sudo] password for admins: 
GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) 

4.3.2 attach osd2 进程

(gdb) attach 22235
Attaching to process 22235
[New LWP 22237]
[New LWP 22238]
[New LWP 22239]
[New LWP 22248]
[New LWP 22249]
[New LWP 22250]
[New LWP 22251]
[New LWP 22254]
[New LWP 22255]
[New LWP 22256]
[New LWP 22257]
[New LWP 22258]
[New LWP 22259]
[New LWP 22260]
[New LWP 22269]
[New LWP 22270]
[New LWP 22271]
........
........
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007fd026a7dad3 in futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x55b3123d8910) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
88        ../sysdeps/unix/sysv/linux/futex-internal.h: No such file or directory.
(gdb)

4.3.3 设置断点

#本例断电设置在PrimaryLogPG::do_op函数开始
(gdb) b PrimaryLogPG.cc:1952
Breakpoint 1 at 0x55b305d28af2: file /home/admins/code/ceph/src/osd/PrimaryLogPG.cc, line 1952.#设置完断电之,执行continue
(gdb) c
Continuing.

4.3.4 测试

向存储池中写入数据,测试结果如下

[Switching to Thread 0x7fd0034cb700 (LWP 22364)]
Thread 57 "tp_osd_tp" hit Breakpoint 1, PrimaryLogPG::do_op (this=0x55b312519400, op=...) 
at /home/admins/code/ceph/src/osd/PrimaryLogPG.cc:1952
1952        {

从上面结果可以看到,当写入数据时,函数停在代码的1952行,现在就可以使用gdb命令进行代码调试,和正常调试代码一样。但需要值得注意的一点是,由于ceph osd存在心跳机制,当调试某一个osd时,如果长时间没有走完该走的流程,该osd会被标记为down,就无法再继续调试。需要重新进入gdb模式!

相关文章:

Ceph入门到精通-Linux下Ceph源码编译和GDB调试

Ceph版本&#xff1a;14.2.22 Linux版本&#xff1a;ubuntu-server 18.04 第一部分 下载Ceph源码 1.1 配置Ceph源码镜像源 Ceph源码是托管在Github上&#xff0c;由于某些原因&#xff0c;国内访问Github网站很慢&#xff0c;所以需要从其他途径加速获取源码。Github官方给出…...

【c语言】动态内存管理(超详细)

他治愈了身边所有人&#xff0c;唯独没有治愈他自己—超脱 csdn上的朋友你们好呀&#xff01;&#xff01;今天给大家分享的是动态内存管理 &#x1f440;为什么存在动态内存分配 我们定义的局部变量在栈区创建 int n 4;//在栈上开辟4个字节大小int arr[10] { 0 };//在栈上开…...

Linux/centos上如何配置管理NFS服务器?

Linux/centos上如何配置管理NFS服务器&#xff1f; 1 NFS基础了解1.1 NFS概述1.2 NFS工作流程 2 安装和启动NFS服务2.1 安装NFS服务器2.2 启动NFS服务 3 配置NFS服务器和客户端3.1 配置NFS服务器3.2 配置NFS客户端 4 实际示例4.1 基本要求4.2 案例实现 1 NFS基础了解 NFS&…...

Element组件浅尝辄止5:Empty 空状态组件

Empty空状态组件&#xff1a;空状态时的占位提示。 如第一次进入当前功能模块时&#xff0c;数据状态为空&#xff0c;则展示空状态&#xff0c;可用到Empty组件 1.How? <el-empty description"描述文字"></el-empty> 2.自定义图片 通过设置 image 属…...

【华为Datacom 综合拓扑案例—分享篇】

拓扑图 题目要求 实验要求&#xff1a; 1、PC1\PC2\PC3\PC4采用DHCP自动获取IP地址&#xff0c;SW5作为服务器&#xff0c;SW3和SW4作为中继 创建地址池ip pool huawei1和ip pool huawei2&#xff0c;租期都为2天 2、SW3与SW4做链路聚合&#xff0c;采用LACP模式。SW3作为主…...

springcloud3 使用openfegin实现getpost请求调用

一 项目介绍 1.1 工程介绍 1.consumer9008 2.provider9009 二 get请求 2.1 消费端 1.controller 2.service 2.2 提供者 1.提供者 2.3 测试请求 地址&#xff1a; http://localhost:9008/consumer/payment/nacos/2223 三 post请求 3.1 消费者 3.2 提供者 3.3 测试请求…...

【JVM】类装载的执行过程

文章目录 类装载的执行过程1.加载2.验证3.准备4.解析5.初始化6.使用7.卸载 类装载的执行过程 类装载总共分为7个过程&#xff0c;分别是 加载&#xff0c;验证&#xff0c;准备、解析、初始化、使用、卸载 1.加载 将类的字节码文件加载到内存(元空间&#xff09;中。这一步会…...

FreeRTOS(独立看门狗监测任务执行与低功耗Tickless模式)

资料来源于硬件家园&#xff1a;资料汇总 - FreeRTOS实时操作系统课程(多任务管理) 目录 一、独立看门狗介绍 二、看门狗监测多任务执行思路 1、监测目标 2、监测方案 3、应用注意事项 三、看门狗监测多任务编程 1、STM32cubeMX配置 2、代码编写 四、低功耗Tickless模…...

预训练GNN:GPT-GNN Generative Pre-Training of Graph Neural Networks

一.文章概述 本文提出了一种自监督属性图生成任务来预训练GNN&#xff0c;使得其能捕图的结构和语义属性。作者将图的生成分为两个部分&#xff1a;属性生成和边生成&#xff0c;即给定观测到的边&#xff0c;生成节点属性&#xff1b;给定观测到的边和生成的节点属性&#xf…...

Python实现透明隧道爬虫ip:不影响现有网络结构

作为一名专业爬虫程序员&#xff0c;我们常常需要使用隧道代理来保护个人隐私和访问互联网资源。本文将分享如何使用Python实现透明隧道代理&#xff0c;以便在保护隐私的同时不影响现有网络结构。通过实际操作示例和专业的解析&#xff0c;我们将带您深入了解透明隧道代理的工…...

并发编程系列-CompletableFuture

利用多线程来提升性能&#xff0c;实质上是将顺序执行的操作转化为并行执行。仔细观察后&#xff0c;你还会发现在顺序转并行的过程中&#xff0c;一定会牵扯到异步化。举个例子&#xff0c;现在下面这段示例代码是按顺序执行的&#xff0c;为了优化性能&#xff0c;我们需要将…...

锁粒度的粗细与时空损耗互换

1 空间换时间的cases 1.1 redis的用户分组限流和用户定制的限流器 Redis 用户分组限流和用户定制的限流器&#xff1a;使用 Redis 进行用户分组限流或用户定制的限流意味着你使用 Redis 数据库来维护用户的访问限制。可以通过计数器、滑动窗口或令牌桶等算法来实现限流。用户…...

[Android 11]使用Android Studio调试系统应用之Settings移植(七):演示用AS编译错误问题

文章目录 1. 篇头语2. 系列文章3. AS IDE的配置3.1 AS版本3.2 Gradle JDK 版本4. JDK的下载5. AS演示工程地址6.其他版本JDK导致的错误1. 篇头语 距离2021年开始,系列文章发表已经有近两年了,依旧有网友反馈一些gitee上演示源码编译的一些问题,这里就记录一下。 2. 系列文章…...

MyBatis面试题

MyBatis面试题&#xff1a; 1、MyBatis是什么&#xff1f; Mybatis是一个半ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它内部封装了JDBC&#xff0c;加载驱动、创建连接、创建statement等繁杂的过程&#xff0c;开发者开发时只需要关注如何编写SQL语句&#xf…...

Lorenz系统最大lyapunov exponent的求解

首先看下Lorenz混沌系统: 赋予初始值,例如: 当然,初始值可以根据需要设定。 看下他的吸引子,很美: 看下他的分叉图:...

c#实现策略模式

下面是一个使用C#实现策略模式的示例代码&#xff1a; using System;// 策略接口 public interface IStrategy {void Execute(); }// 具体策略类A public class ConcreteStrategyA : IStrategy {public void Execute(){Console.WriteLine("具体策略A的执行逻辑");} …...

家纺行业小程序商城搭建指南

家纺行业作为一个不可或缺的消费领域&#xff0c;近年来备受关注。随着互联网的发展&#xff0c;小程序商城成为家纺行业拓展市场的新利器。搭建一个家纺行业小程序商城并不是一件困难的事情&#xff0c;只需要按照以下几个步骤进行操作&#xff0c;就能轻松上手。 首先&#x…...

Python语法基础--条件选择

学习目标 使用比较运算符编写布尔表达式。使用random.randint(a,b)或者random.random()函数来生成随机数。编写布尔表达式(AdditionQuiz)。使用单向if语句实现选择控制。使用单向if语句编程。使用双向if-else语句实现选择控制。使用嵌套if和多向if-elif-else语句实现选择控制。…...

visual studio 2017 运行的程序关闭后不能再运行?(visual studio建立项目之后退出,如何再次完整打开项目?)

在你储存项目的文件夹里面应该是这样的 里面.vcxproj后缀名的就是原来创建的项目&#xff0c;直接打开这个头文件源文件就会一起出来了&#xff01; 真的管用&#xff0c;亲测有效。...

亚马逊feedback和review有什么区别

在亚马逊上&#xff0c;"Feedback"&#xff08;反馈&#xff09;和"Review"&#xff08;评论&#xff09;是两个不同的概念&#xff0c;它们在购物体验中起着不同的作用。 Feedback&#xff08;反馈&#xff09;&#xff1a; 亚马逊的"Feedback"…...

2026年项目交付排期系统选型指南:10款主流工具深度测评

一、为什么你的项目总是交付延期&#xff1f;进入2026年&#xff0c;多项目并行、跨地域协作、人力资源紧张、需求频繁变更&#xff0c;已经成为各行业项目推进的常态化现状。当下多数项目出现交付延期问题&#xff0c;核心原因往往并非团队执行效率不足&#xff0c;而是项目排…...

【安全基线】测试数据脱敏规范:喂给大模型的数据,如何确保不泄露公司机密?

一、开篇:当“喂数据”变成“泄机密” 2026年4月,一条消息震动了整个AI行业:为OpenAI、Anthropic和Meta提供训练数据的明星初创公司Mercor确认发生安全事件,黑客组织TeamPCP通过污染开源项目LiteLLM的CI/CD流水线,发布了恶意版本1.82.7和1.82.8到PyPI仓库,Mercor正是数千…...

NLP之BERT预训练模型详解

摘要&#xff1a; BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是谷歌于2018年提出的革命性自然语言处理模型&#xff0c;首次将基于Transformer的双向编码器架构成功应用于预训练语言模型&#xff0c;在多项NLP基准任务上刷新了最优…...

Gramophone安全与权限管理:Android 13+存储权限最佳实践

Gramophone安全与权限管理&#xff1a;Android 13存储权限最佳实践 【免费下载链接】Gramophone A sane music player built with media3 and material design library that is following androids standard strictly. 项目地址: https://gitcode.com/gh_mirrors/gr/Gramopho…...

AI落地实战指南:场景锚定、能力分层与人机协同五步法

1. 项目概述&#xff1a;这不是一场技术发布会&#xff0c;而是一份从业者手绘的路线图 “AI: The Journey Ahead”——这个标题乍看像某场科技峰会的宣传语&#xff0c;或是某本畅销书的副标题。但在我过去十二年跑遍制造业产线、教育机构机房、中小律所档案室、社区卫生站HIS…...

免费卸载软件再推荐!支持多款软件同时卸载、注册表清理、垃圾文件清理、空文件查找、进程管理、启动管理等等功能!强制卸载+系统清理,绝了

前言 电脑里总有那么几个“钉子户”软件&#xff01;卸载按钮灰色、控制面板里找不到、残留注册表像牛皮癣一样反复出现今天推荐的这款卸载工具,不管程序多顽固、卸载器多残废&#xff0c;都能一键连根拔起&#xff0c;顺带把垃圾文件、空文件夹、无效快捷方式打包带走&#x…...

2026年如何向 GPT-5.5 提问,拿到更高质量的技术解释和方案

摘要&#xff1a; 2026年的工具生态正在从“追大模型”转向“讲效率、讲成本、讲合规”。本文结合当前小模型高效化、国产工具崛起、多模型聚合的趋势&#xff0c;分享一套面向 GPT-5.5 的高质量提问方法&#xff0c;帮助开发者和普通用户更快拿到清晰、可执行、可落地的技术答…...

使用电脑快速测试DeviceNet设备通讯

日常对客户进行技术支持的时候&#xff0c;我们发现工厂自动化领域的不同部门不同职能的人员对于工业通讯设备都面临着一些使用的困难&#xff0c;例如设备研发人员&#xff0c;尤其是嵌入式研发部门&#xff0c;对于工厂自动化使用的工业通讯协议和自动化组态软件&#xff0c;…...

量子近似优化算法(QAOA)原理与实践指南

1. 量子近似优化算法(QAOA)基础解析 量子近似优化算法(QAOA)是近年来量子计算领域最具应用前景的混合算法之一。作为一名长期从事量子算法研究的工程师&#xff0c;我见证了QAOA从理论构想到实际应用的完整发展历程。这种算法巧妙地将经典优化技术与量子线路相结合&#xff0c;…...

从‘能看’到‘好看’:用Seaborn调色板为你的热力图注入专业感

从‘能看’到‘好看’&#xff1a;用Seaborn调色板为你的热力图注入专业感 在数据驱动的决策时代&#xff0c;可视化不仅是展示数字的工具&#xff0c;更是讲述数据故事的视觉语言。当你的热力图从"能看"升级为"好看"&#xff0c;数据洞察的传递效率可能提…...