news 2026/9/30 6:08:48

Linux交换空间深度解析:从swap原理到配置调优与故障排查

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux交换空间深度解析:从swap原理到配置调优与故障排查

作为一个常年和Linux服务器打交道的人,我几乎每周都会遇到和swap(交换空间)相关的“事故现场”。要么是内存告警,要么是某台新上线的云主机因为没配swap,一到高峰期就频繁OOM(内存耗尽)杀进程。说实话,swap这个机制在Linux里往往是被轻视的模块,很多初学者把它当成“内存的垃圾桶”,而一些老手遇到性能问题又习惯性先骂swap,这些都是走极端的理解。

这篇我来系统聊聊Linux的交换空间,从它到底在解决什么问题、内核是怎么管理它的,到具体怎么配置、怎么监控、出了问题怎么排查,一次性讲透。内容覆盖日常运维、服务器部署、性能调优这些场景,适合刚接触Linux的开发者,也适合正在被线上内存问题折磨的运维朋友。我会把很多手册里“一句话带过”的细节展开讲清楚,比如swappiness到底调多少、swap文件为什么比swap分区更灵活、以及什么时候你其实应该关掉swap。

1. 交换空间到底在解决什么问题

1.1 内存不够用时,系统发生了什么

先不谈原理,从一个真实场景说起。我给一台云服务器装了某个开源监控系统,顺手启动了多个Java微服务,2G内存瞬间被吃光。这时候你打开SSH,发现敲命令很久才有反应,free -h一看,内存用满,这时候系统开始出现一个非常典型的现象:某个进程会突然消失,dmesg日志里出现“Out of memory: Kill process ...”。这个“突然消失”,就是内核的OOM Killer(内存耗尽杀手)干的。它像一个机场地勤,当登机口(物理内存)完全塞满,且没有备用候机区时,只能强行把一些乘客(进程)拖出航站楼。

而swap就是那个备用候机区。它的本质是一块磁盘空间,被内核拿来当作内存的延伸。当物理内存不够用的时候,内核会把一部分暂时用不到的内存数据,从RAM里搬出去,写到磁盘的swap区域里,腾出宝贵的物理内存给正在活跃运行的进程。这个动作叫swap out(换出);当进程需要访问的数据已经在swap里时,内核再把数据从磁盘读回内存,叫swap in(换入)。这个过程你不需要感知,但理解它,是你之后看懂内存和性能指标的基础。

这里有一个容易忽略的关键点:swap区域的读写是磁盘级别的,速度比内存慢几个数量级。内存是纳秒级别,即便是NVM Express固态硬盘,随机读写也在几十到几百微秒,算上PCIe总线延迟,整体大约比内存慢百倍以上。所以,swap的正确用途是“兜底”和“腾挪”,不是用来持续承受大量数据读写的。如果系统长时间、高频率地做swap in/swap out,那性能会变得非常差,表现在外部就是你敲一个命令都要等好久。

1.2 内核的换页机制与“冷热数据”

swap的具体实现机制,是Linux内核的内存管理模块中最复杂的一层之一。这里我不会搬源码,但你要建立一个非常关键的认知:内核并不等到内存完全耗尽才开始用swap,它有一套自己的换页(paging)策略。

Linux把物理内存分成一页一页(page)来管理,通常是4KB。进程访问数据时,如果数据不在物理内存里,就会触发缺页异常,内核负责把数据从磁盘的页缓存(Page Cache)或swap区域加载进来。内存里的页面可以被标记为“活跃”或“不活跃”。内核有一个后台进程(比如kswapd)会定期检查内存水位,它会尽力保证系统有一部分空闲物理内存。它怎么保证呢?扫描这些内存页面,把“不活跃”的、长时间没被访问的页面换出去,放到swap里。

这个机制带来一个很多人没意识到的事实:即使你的物理内存还够用,系统也可能已经写了一些数据到swap里。这不算bug,这是Linux主动把“冷数据”(很久没用到的内存页)挪出去,给“热数据”腾地方。理解这点,你就知道为什么有时候看到swap used不为零就开始紧张,其实是没必要的。

Page Cache在这里扮演的角色也要简单提一下。当你读取一个文件,内核会把磁盘里的内容缓存到内存的Page Cache里,下次再读就直接从内存返回,快很多。当内存压力大,内核优先回收的往往是干净Page Cache(数据已经在磁盘上,无需再写回),而不是马上把进程的匿名内存页丢到swap。这也是为什么Linux服务器的可用内存看起来那么少——实际上大部分内存都贡献给了Cache,真正“空闲”的反而很少。这个设计初衷是好的,但也导致很多新手误会“内存用了96%是不是快挂了”,其实不是。

1.3 为什么有些场景必须开swap,有些场景又必须关

基于上面这些原理,你就会明白swap在不同场景下的角色完全不同。

对桌面系统来说,swap几乎是必需品。你可能开着几十个浏览器标签页、一堆编辑器窗口,后台还有全家桶软件在更新。物理内存瞬间吃紧,如果你没开swap,系统流行做法是直接随机杀进程,网页和文档丢失,体验极差。开了swap,最多卡一点,至少应用还在,你有机会保存手头的工作。

对部分服务器场景,比如数据库服务器,尤其是Redis这类要求低延迟的内存数据库,情况是反过来的。数据库通常自己在内存里维护一套缓存和淘汰策略,它比内核更清楚哪些数据是真正重要的,所以它不希望内核“自作主张”把某些冷数据换到swap里。一旦访问到被换出的数据,得从硬盘拉回来,延迟从微秒级飙升到毫秒级,这可能会导致高并发的线上故障。所以很多数据库运维会建议设置非常低的swappiness,甚至关掉swap,就是为了避免“意外换页”导致的性能毛刺。

那到底要不要开swap,取决于你对系统延迟的容忍度、以及你对物理内存枯竭时的应对策略。我个人的习惯是,绝大多数通用服务器上配置一个小容量的swap文件,比如2GB或4GB,作为兜底,但配合调低swappiness;而在极端的延迟敏感型服务上,单独评估是否禁用。

2. swappiness参数:调整换页策略的旋钮

2.1 swappiness到底数值代表什么

Linux内核通过/proc/sys/vm/swappiness这个参数,控制“内核在多倾向于把匿名内存页(匿名页,比如进程的堆和栈)换出到swap”。它的取值范围是0到100。

先说结论,再解释原理:

  • swappiness=0:尽可能避免换出匿名页,不到万不得已不使用swap。
  • swappiness=100:内核非常积极地把匿名页换出,来给Page Cache腾空间。
  • 默认值是60,意思是内核在内存压力下,会相对积极地换出匿名页,但也保持一定平衡。

很多文章把swappiness解释成“swap使用的百分比”,这是不对的。它其实是内核扫描匿名页与文件缓存页时的权重参考。内核在回收内存时,要决定先回收哪一种页面,swappiness数值越高,匿名页在回收时的“优先被牺牲程度”就越高。换句话说,这个值是控制系统在回收内存时,更倾向于回收文件映射页面、还是更倾向于交换出匿名内存页的比例。

小提示:swappiness=0并不代表“系统永远不用swap”,它只是让内核在判断时极度不倾向于换出匿名页。如果内存压力极大,内核依然会强行换出。这个细节经常被误解。

你可以直接查看当前系统的值:

cat /proc/sys/vm/swappiness

如果想临时修改,直接写:

sudo sysctl vm.swappiness=10

这个修改立即生效,但重启后失效。要永久生效,在/etc/sysctl.conf或/etc/sysctl.d/下新增配置文件,比如99-swappiness.conf,内容写:

vm.swappiness = 10

然后执行sudo sysctl -p让配置生效。

2.2 不同场景下的推荐配置

这里我给一份我长期实践下来的参考值,但你必须明白,它不是绝对的,因为不同的业务负载、不同的存储介质、不同的内核版本,表现都可能不同。

场景建议swappiness理由
通用桌面Linux60(默认)或40保证应用不崩溃,同时有一定响应速度
云服务器/通用后端10 ~ 20尽量用物理内存,避免频繁磁盘换页
MySQL、PostgreSQL等数据库0 ~ 10让数据库自己管理缓存,减少延迟毛刺
Redis缓存服务0 或关swap完全拒绝内核换页干扰
Kubernetes节点通常关闭swap容器内存管理独立,swap可能导致QoS指标错乱
内存非常小(1GB以下)的老机器60以上必须依赖swap才能跑起来

这些数值不是拍脑袋定的,背后有实际考量。数据库场景设成0~10,是让内核在回收内存时优先丢弃那些干净的Page Cache(文件缓存),而不是把SQL执行引擎的堆栈换出去。Kubernetes场景关闭swap,是因为swap会让kubelet对Pod内存实际使用量的统计失真,可能导致OOM调度的判断不准确。

有一点要特别提醒:如果你的系统磁盘是传统的机械硬盘(HDD),swap对性能的拖累会非常明显,因为随机读写机械硬盘那点IOPS完全扛不住高频换页。这种情况要么加大物理内存,要么把swap文件放在SSD盘上,否则不如不开swap。

3. 实战:在Linux上配置交换空间

3.1 用swap分区还是swap文件

Linux支持两种常见的swap实现方式:swap分区(swap partition)和swap文件(swap file)。另外还有zram/zswap这类基于压缩内存的交换设备,后面我会单独提。

swap分区是传统做法,用fdisk或者gdisk把一块独立分区标记为Linux swap类型,然后格式化并启用。它的优点是连续且稳定,性能上几乎没额外损耗;缺点是因为它占用了独立分区,后期调整容量非常痛苦。比如你的安装脚本里已经给swap分了固定大小4G,想改成8G,就得重新分区、移动数据,这在生产环境里基本等于停机维护。

swap文件是更现代化的做法。它不是一个独立分区,而是一个普通文件,你可以随时创建、删掉、扩容,不需要重新分区。现代Linux内核和文件系统(ext4、xfs)对swap文件支持得很好,只要文件具有连续的磁盘块(mkswap会确认这一点),性能就很接近swap分区。我个人的建议是:新部署的系统,只要不是极老的发行版,一律用swap文件。云主机尤其适合这种方式,因为可以在不重建云盘的前提下动态调整。

3.2 从头创建一个swap文件并启用

接下来我们做一次完整的实操:在一台CentOS风格的Linux服务器上,创建一个4GB的swap文件并开机自动挂载。

第一步,确定磁盘剩余空间足够。用df -h /查看根分区的可用空间,留出比你想创建的swap稍大一点的空间,别把根分区塞满了。然后使用fallocate命令快速创建文件:

sudo fallocate -l 4G /swapfile

fallocate的好处是瞬间分配空间,不需要逐个写零。但某些文件系统(比如传统xfs在某些内核版本下)可能出现swapon: swapon failed: Invalid argument,原因是文件不是连续存放的。如果遇到这种情况,就用dd命令老老实实创建:

sudo dd if=/dev/zero of=/swapfile bs=1M count=4096

bs=1M count=4096意思是每次写1MB,一共写4096次,最终得到4GB文件。这一步在SSD上很快,机械硬盘可能要几十秒甚至几分钟,耐心等待。

第二步,把文件权限改成600。这一步很重要的原因是,swap文件里存的是物理内存中的敏感数据,如果权限是644,其他用户就能读取,这等于把内核内存直接暴露给低权限用户,存在严重的信息泄露风险。

sudo chmod 600 /swapfile

第三步,用mkswap命令将文件格式化成swap文件系统:

sudo mkswap /swapfile

输出大概长这样:“Setting up swapspace version 1, size = 4 GiB ...”

第四步,启用它:

sudo swapon /swapfile

然后验证:

free -h

可以看到Swap这一行的used和free发生了变化,有空间了。再用swapon --show确认:

swapon --show

输出会列出设备路径、类型(file)、大小等信息。

第五步也是最容易忘的一步:写入/etc/fstab实现开机自动挂载。用编辑器打开/etc/fstab,在末尾追加一行:

/swapfile none swap sw 0 0

这里有四个字段:第一个是设备路径(文件路径),第二个是挂载点(swap不需要挂载点,所以是none),第三个是文件系统类型(swap),第四个是挂载参数(sw就够用,有些教程写defaults也可以,但不推荐),最后两个0分别是dump和fsck选项,对swap来说都填0。

如果不放心,可以重启前先手动检测一遍fstab是否写错。用:

sudo mount -a

它不会报swap相关错误,但至少能确认fstab语法没有导致系统启动失败。更稳妥的做法是重启一次看看。

3.3 调整、移除swap的完整流程

当你需要缩小或删除swap文件时,顺序和创建是反过来的。假设你要把4GB的swap砍到2GB,不能直接删除文件,因为内核还在使用它。正确步骤是:

先关闭swap:

sudo swapoff /swapfile

如果系统当前内存压力很大,这个操作可能会失败或导致部分进程被OOM杀掉。原因是swap一旦关闭,原本被换出的数据必须全部塞回物理内存,如果物理内存剩余不够,内核只能动杀手。所以生产环境执行swapoff前,一定要先看free -h,确认物理内存有足够的空闲,或者先把不必要的服务停掉。

关闭后,删除旧文件:

sudo rm /swapfile

然后从/etc/fstab里删掉那一行,再创建一个新的2GB文件,流程跟上文一样,重新mkswap、swapon。

扩容时更简单,不需要swapoff,直接创建一个更大的新swap文件,启用它,再把旧的swapoff并删除即可。比如你把4GB扩展到8GB:

sudo fallocate -l 8G /swapfile2 sudo chmod 600 /swapfile2 sudo mkswap /swapfile2 sudo swapon /swapfile2 sudo swapoff /swapfile sudo rm /swapfile

这样就能在不中断服务的情况下完成swap扩容,整个过程对运行中的业务影响非常小,这也是swap文件方案比swap分区强太多的地方。

4. 监控与调优:让swap不拖慢应用

4.1 查看swap使用量的几种方式

日常监控,free -h是最直观的,但信息量有限。推荐组合使用下面几个命令。

swapon --show可以看到swap设备/文件、类型、大小,以及优先级。如果有多个swap区域,可以给它们设置priority,让内核优先使用某个区域。例如:

sudo swapon --priority=10 /fast_swapfile

/proc/meminfo里有很多内核内存管理的精确指标,比如SwapTotal、SwapFree、Dirty、Writeback等,适合脚本采集做长期监控。

最需要重点关注的,其实是si(swap in)和so(swap out)两个指标。可以用vmstat看:

vmstat 1

每秒钟打印一次系统状态。si和so的单位是KB/s。正常情况下,这两个值应该是0或者非常低的个位数。如果你看到si或so持续几十MB每秒,甚至几百MB每秒,说明系统正在严重依赖swap承载数据访问,这时候应用层表现大概率是延迟飙升,你需要立刻排查是内存不足还是swap配置不合理。

top或htop里也可以看到各个进程的RES(常驻物理内存)、VIRT(虚拟内存总量)等指标,配合判断是哪个进程在大量吃内存,从而导致内存压力传导到swap。要更细致地定位某个进程的swap占用,可以查看:

for file in /proc/[0-9]*/status; do grep -H VmSwap "$file" 2>/dev/null; done | sort -k2 -nr | head -10

这个命令会遍历所有进程的status文件,提取VmSwap字段并按值排序,找出占用swap最多的前10个进程。这招在排查“swap被谁吃掉了”的时候很管用。

4.2 swap与OOM Killer的关系

很多服务器故障都绕不开OOM。我需要把swap和OOM之间的因果关系讲清楚,这事关你的系统会不会被“连锁杀死”。

OOM Killer触发的前提是:内核在试图分配内存时,发现物理内存加swap都无法满足,于是启用杀手逻辑,选择一些进程杀掉来释放内存。也就是说,swap的容量实际上是物理内存的“扩容区”,它的大小直接影响系统能扛住的内存压力。

举个例子:一台物理内存4GB、无swap的服务器,跑一个需要5GB内存的应用,系统会很快走到OOM,直接杀进程。但如果配了4GB swap,应用会进入swap颠簸(thrashing)状态——进程可以用,但是极慢,因为大量内存页在swap和RAM之间来回倒腾。这种情况下的表现是,你可能连SSH都进不去,因为它也在这个“泥潭”里挣扎。有时候OOM把关键服务杀了,反而比一直颠簸更“好”一点,至少系统能恢复响应。

所以,不要以为swap越大越好。swap太大,会让系统长期处于“还能跑但是很卡”的状态,而不会及时触发OOM,这可能导致故障持续更久。swap太小,又可能过早触发OOM。合理的做法是,把swap当作“保险丝”,容量刚好够你应付内存突刺,但又不至于让系统在极度内存压力下“苟延残喘”太久。

还有一个实用技巧:在关键服务上通过oom_score_adj调整OOM被选中的概率。你可以给数据库、Nginx这些核心服务设置一个很小的值,比如-500,让OOM Killer优先去杀那些不重要的进程,而不是核心服务。写入方法很简单:

sudo echo -500 > /proc/$(pgrep mysqld)/oom_score_adj

但要注意,这个设置重启后失效,如果你要长期生效,需要借助systemd的服务单位文件里的OOMScoreAdjust字段,或者写个systemd service来配置。

4.3 内存压力大时,主动回收与手动swapoff

有时候你会遇到swap占用居高不下,但物理内存其实已经释放了的情况。例如,某个大应用运行了几个小时后退出,swap里留下了大量数据,并且永远不会再被访问。这些数据会占据swap空间,影响后续其他任务使用swap的容量。

这时候可以主动回收。Linux内核提供了一个接口,允许你主动触发内存回收:

sudo sysctl vm.drop_caches=3

这个操作会把Page Cache、inode和dentry缓存清掉,释放出大量物理内存。但要说明,drop_caches不会清swap,它清的是文件缓存,被清出来的物理内存可以用来吸收新的内存压力,从而避免内核再次读取swap。

如果想要彻底清空swap(把swap里的所有数据搬回物理内存),操作是:

sudo swapoff -a sudo swapon -a

注意:这个操作一定要慎用。如果物理内存不足以容纳swap里的全部数据,系统会立刻OOM,甚至可能直接宕机。我在某台只有6G内存、开了10G swap的机器上试过一次,执行swapoff -a之后系统像死了一样卡了十分钟,最后只能硬重启。实际工作中,除非内存非常充裕、且确实需要把swap空间腾出来给新任务,否则不建议主动清swap。

提到zram/zswap,这里简单补充。zram是把一块内存当作swap设备,但会先做压缩再存,所以实际能“存”的数据量比物理内存大不少,适合内存小、CPU富裕的嵌入式设备或低端笔记本。zswap则是介于swap和Page Cache之间的一个压缩缓存层。这两者能显著降低真实磁盘的换页次数,但会增加CPU开销。有兴趣的可以之后单独研究,日常服务器上通常用不上。

5. 常见问题与排查技巧实录

5.1 开机swap不生效

典型现象:手动执行sudo swapon /swapfile,一切正常,但重启后free -h显示swap还是0。这十有八九是你在/etc/fstab里写的那一行有问题,但系统没有报错,因为swap配置错误不会阻止系统启动(除非你在fstab里加了一个不存在的设备且标注了nofail或_netdev),它只是静默跳过。

排查步骤:先检查fstab内容,确认路径写对,文件存在,权限正确。然后用sudo findmnt --verify检查fstab的格式是否正确?其实findmnt不验证swap,更直接的办法是重启后看dmesg日志里有没有swapon相关报错。

一个很容易踩的坑是:fstab里的字段顺序写错。很多人会把/swapfile swap swap sw 0 0写成了/swapfile swap swap defaults 0 0,这不算错,但有些文档里的defaults会导致挂载参数不兼容?其实swap行用sw就够了,defaults也能用,这里不深究。更常见的错误是文件系统类型写错,有人写成了swapfile,正确的是swap。

我在用fstab配swap时还遇到过另一种情况:按教程写的/swapfile none swap sw 0 0,重启后不生效。后来发现是UEFI启动后根分区的挂载顺序和fstab解析顺序问题,导致开机时swap还没挂载根分区、文件还不存在。这种一般不会发生,因为系统启动时会先挂载根文件系统。所以碰到了多数还是拼写错误。

5.2 创建swap文件时报Invalid argument

mkswap成功后,swapon /swapfile却报swapon failed: Invalid argument,这个非常经典。

原因通常是文件系统不支持稀疏文件或文件块不连续。fallocate在某些文件系统上(比如老版本的XFS)分配的文件看似连续,实际上有空洞,swapon检查发现块不连续,直接拒绝。解决方案很简单,改用dd创建,或者加--fixpgsz?不,swapon没有这个参数。正确做法是删除文件后用dd重新创建一个实打实写满零的文件:

sudo rm /swapfile sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile

5.3 swap占用过高,怎么定位占用者

有一类问题是“swap使用率长期很高,但我看不出哪个进程在占用它”。这种时候,我推荐直接用上面提到的/proc/[pid]/status里的VmSwap字段来排查,或者用工具smem:

sudo smem -rs swap | head

smem能按swap占用从大到小排序,非常直观。如果没有smem,apt或yum装一个就行。

在嵌入式Linux场景下,还会遇到另一种诡异情况:某些进程(比如动态库的代码段)被回收到了swap,但你在进程列表里根本找不到一个“吃swap的进程”——因为它是被所有进程共享的库内存或文件缓存页,不属于任何一个单独进程。这是内核“按需换出”的正常结果,不算故障。除非swap占满且si/so很高,否则不需要担心。

5.4 SSD与HDD上的swap性能差异

最后说一个决策层面的问题:swap到底放哪个盘。如果是传统机械硬盘(HDD),随机读写性能只有每秒一二百次IOPS,swap一旦开启,高频换页会导致整机IO堵塞,CPU等待磁盘,系统像卡死一样。这种情况下,我会优先考虑不开swap,而是靠加大物理内存来扛。

如果机器装的是NVMe SSD,swap性能相对改善很多,但依然无法和内存相比。这里推荐一个思路:在SSD上开swap,主要是为了“极端的兜底”,最好再配合vm.swappiness=10这类低值,让swap只作为最后一道防线,而不是常规使用。

如果你有多块磁盘,尽量把swap文件放在读写快的盘上。如果系统盘是HDD、数据盘是SSD,一定要让swap落在SSD上,方法很简单:在SSD挂载点下建swap文件就行。

5.5 swap在容器和虚拟化环境中的特殊问题

容器时代,swap的玩法又变了。Docker容器默认没有swap限制,但宿主机一旦有swap,容器里的应用可能无意中大量使用swap,导致指标失真。Kubernetes对节点有个硬性要求:默认情况下,节点上如果启用了swap,kubelet会拒绝启动(除非配置--fail-swap-on=false)。原因在于Kubernetes的驱逐机制依赖cgroup的内存统计,swap的存在会让Pod实际内存使用量超出limit,但cgroup判断不出来,进而破坏QoS稳定性。

如果你在自己的虚拟机里学习Kubernetes,并且就想开swap做实验,那么需要关闭节点级swap或者调整kubelet参数。但从生产角度讲,容器平台节点建议关swap,这是我前文提过的。

针对虚拟机,有个值得吐槽的点:很多人装了Ubuntu Server的云镜像,默认是没有swap的,因为云厂商的镜像模板一般会禁用swap,以便使用cloud-init动态管理。所以你在云服务器上执行free -h,swap一栏基本都是0,这时候你需要按照第3节的方法自己创建。别怀疑是不是系统坏了,大概率只是默认没配。

6. 最后的经验心得

写到这里,关于swap的实践已经覆盖得比较全面了。最后分享一点个人心得。

我自己的标准模板,是针对大多数通用Linux服务器,会创建一个与物理内存大小相关的swap文件。具体来说,如果内存是2GB,我会配4GB swap;如果是4GB,配2GB swap;如果内存已经到8GB以上,就配1~2GB的swap作为兜底即可。这个比例不来自教科书,而是我根据“云服务器按量计费内存便宜、但业务突发流量不可预估”的现实情况总结出来的。

you的服务器如果完全关闭swap,一定要有完善的监控报警,否则当内存耗尽到触发OOM灭进程的那个瞬间,你大概率是在凌晨被报警电话叫醒的。反过来,如果swap开得太大,又容易让系统陷入长时间的性能泥潭。

总之,swap不是洪水猛兽,也不是灵丹妙药。它只是内核内存管理众多工具中的一个。理解它的运行规律,用合理的配置把它放在合适的位置,比单纯“开或关”要高明得多。希望这篇文章能帮你把swap这块短板补上,至少在下次服务器内存告警的时候,你能第一个想到:swap在干嘛?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 6:08:47

帆软看板 - 问题收集

1、直连模式下,ORDER BY不生效在添加 SQL 数据集时,如果 SQL 语句中用到了 ORDER BY 语句,则该 SQL 数据集的计算模式必须选择「抽取数据」来保存。在直连模式下,FineBI 会忽略 SQL 中的 ORDER BY 子句。直连模式的机制&#xff1…

作者头像 李华
网站建设 2026/9/30 6:07:26

嵌入式固件升级核心机制:Bootloader、IAP与OTA全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 6:06:20

海光C86架构入局嵌入式:边缘AI场景下的国产芯片选型与生态评估

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 6:06:04

V1项目封装实战:从请求层到组件的收拢与复盘

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 6:06:01

FPGA功耗优化五大实战技巧:从时钟门控到IO管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 6:05:59

操作系统接口的本质:从系统调用到驱动,手搓最小内核骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华