从存储引擎到执行计划:OceanBase高效运维的调优逻辑与工程实践

OceanBase的运维调优,容易陷入一个误区:把注意力集中在参数列表和命令语法上,却忽略了参数背后的机制耦合。一个内存参数的调整可能同时影响写入限速、合并触发和查询缓存的行为;一个索引的添加可能改善某条查询的执行计划,却给写入路径带来未被预期的合并压力。分布式架构把这种耦合放大了,因为任何一个局部的变更都会通过副本同步、共识协议和资源调度传播到整个集群。

真正有效的调优,建立在对三个层次之间关系的清晰理解之上。最底层是LSM-Tree存储引擎的写入与合并机制,它决定了数据以什么节奏从内存落到磁盘、以什么代价被查询读取。中间层是SQL优化器与执行引擎,它决定了每一条查询走哪条路径、消耗多少资源。最上层是资源调度与路由层,它决定了计算和存储在多个租户、多个副本之间如何分配。调优的动作发生在某一层,但效果的传导跨越三层。

本文沿着这条从底层机制到上层策略的路径展开。先拆解LSM-Tree架构下合并与转储的调优逻辑,再进入SQL层的执行计划稳定性与并行执行效率,然后讨论锁与等待事件的诊断方法,最后落到资源隔离、读写分离与诊断工具链的工程实践。文章的目标不是提供一份参数速查表,而是建立一套判断框架:在遇到性能异常时,知道先看哪一层,知道一个调整会在哪些地方产生副作用。

第一章 LSM-Tree的调优逻辑

1.1 基线加增量的读写分离

OceanBase的存储引擎基于LSM-Tree架构,将数据分为静态基线数据和动态增量数据两部分。SSTable是只读的,一旦生成就不再被修改,存储于磁盘;MemTable支持读写,存储于内存。DML操作首先写入MemTable,当MemTable达到一定大小后转储到磁盘成为SSTable。查询时需要分别对SSTable和MemTable进行查询,并将结果归并后返回。

这种设计的核心取舍是用写放大换取读放大。写入路径始终是顺序追加,MemTable到SSTable的转储是批量顺序写,写吞吐因此可以很高。但读取时需要合并多个版本的数据,合并的代价取决于SSTable的数量和层次。为了控制读放大,系统需要通过合并将多个SSTable归并为更少、更大的文件。

OceanBase在这个通用LSM-Tree模型上做了一个关键的差异化设计:宏块粒度的合并重用。数据文件按照2MB的基本粒度切分为宏块,每个宏块内部再拆分出变长的微块。合并时,没有更新的数据宏块不会被重新打开读取,只有发生变化的数据需要被重写。这种设计显著降低了合并期间的写放大,使OceanBase在保持LSM-Tree优点的同时,避免了传统LSM-Tree数据库合并代价过高的缺陷。

1.2 转储与合并的分工

转储和合并是两个不同粒度的操作。转储将MemTable中的数据刷写到磁盘成为增量的SSTable,它的粒度是单个租户的单个分区,资源消耗相对较小,对在线业务的影响较低。合并将增量SSTable与基线SSTable归并为新的基线,它的粒度涉及整个租户甚至整个集群的SSTable,资源消耗大,对QPS和TPS有中度影响。

转储的频率由freeze_trigger_percentage控制,它决定了租户内存使用达到什么比例时触发冻结。默认值是70,取值范围为1到99。降低这个值会让冻结更早发生,MemTable中的内存更早被释放,但转储的频率也会上升。提高这个值会减少转储次数,但MemTable可能在高写入负载下更快逼近内存上限。

合并的频率由minor_freeze_times和major_compact_trigger共同控制。minor_freeze_times设置单个租户冻结多少次后触发一次合并,默认值为5。这个参数是转储与合并之间的调节阀:值越大,转储积累的增量SSTable越多才触发合并,合并的频率降低,写入吞吐可能提升,但查询时需要合并的SSTable数量增加,读放大上升,数据时效性也可能下降。值越小,合并更频繁,读放大被控制在较低水平,但合并占用的CPU和IO资源更频繁地出现。

调优的判断依据不是寻找一个最优的默认值,而是根据业务的读写比例和延迟要求来校准。读密集且对查询延迟敏感的业务,应该让合并更频繁地发生,把读放大控制在低位。写密集且可以容忍查询路径上多一层合并的业务,可以适当放宽合并频率,把资源优先留给写入。

1.3 并行合并的边界条件

并行合并默认开启,它将一个compaction任务按照key range拆分成若干子任务并行执行。并行度与分区数的匹配关系直接影响合并效率。一般来说,并行度与分区数符合整比例关系时,比如分区数为8、并行度设为4或8,能够获得较好的性能。

并行合并有一个容易被忽视的边界:当Major SSTable的数据量很小而增量数据很多时,并行合并的range拆分可能把增量数据都划分到同一个compaction任务中,此时并行合并等价于单线程执行增量数据的合并。这意味着并行合并的收益取决于数据在key range上的分布是否均匀。如果增量数据集中在少数key range上,即使开启了并行合并,实际的有效并行度也远低于配置值。

合并线程数由merge_thread_count控制,L0层转储线程数由_mini_merge_concurrency控制。这些参数的调整需要与硬件资源匹配。合并是CPU和IO密集型操作,线程数超过CPU核心数时,线程之间的争用会抵消并行度的收益;线程数远低于核心数时,合并速度受限于单线程的处理能力,积压的增量数据会延长读放大持续的时间。

转储的并发分区数需要平衡。并发转储的分区过少,MemTable内存释放不够快,写入可能因为内存不足而受限;并发转储的分区过多,会消耗过多资源,影响在线交易的性能。

1.4 合并策略与压缩的权衡

合并过程中,数据会被重新编码和压缩。压缩算法的选择直接影响存储成本和查询延迟。更高的压缩率节约磁盘空间,但牺牲性能。ZSTD比LZ4节省更多空间,但ZSTD合并的时间更长,查询的响应时间也更大。

对于写入密集且查询以点查为主的OLTP业务,LZ4或更轻量的压缩算法更合适,因为点查的延迟对解压开销敏感。对于查询频率较低的历史数据或分析型负载,ZSTD的高压缩比带来的存储成本节约可能超过解压开销的代价。压缩策略的选择应该与数据的访问模式对齐,而不是追求单一的全局最优压缩率。

第二章 SQL层的调优

2.1 执行计划的缓存与软解析

一条SQL语句的执行经过编译和执行两个阶段。编译阶段,优化器进行词法分析、语法分析、语法优化和代码生成,生成执行计划后提交给执行器执行。这个过程称为硬解析,消耗资源并增加SQL延迟。为了避免每次请求都进行硬解析,执行计划被缓存在计划缓存中,相同类型的后续SQL语句首先在计划缓存中查找匹配的计划,找到后直接提交执行器执行,这个过程称为软解析。

计划缓存的存在意味着,一条SQL在第一次执行时生成的计划,可能在后续数千次执行中被反复复用。如果第一次生成的计划是非最优的,那么这个非最优计划的影响会被放大数千倍。优化器生成非最优计划的原因包括缺少索引、统计信息过时和账号权限限制。非最优计划的直接代价是逻辑读次数高、扫描数据量大,最终表现为延迟上升和吞吐下降。

2.2 用SQL Audit定位需要优化的语句

定位SQL层面的性能问题,起点是V$OB_SQL_AUDIT视图。通过按平均执行时间乘以执行次数降序排列,可以找出消耗租户资源最多的TopSQL语句。

一个典型的查询会聚合每个SQL_ID的平均耗时、平均排队时间、平均逻辑读、执行次数、平均CPU时间和平均等待时间,并按平均执行时间乘以执行次数排序取前十。逻辑读高的SQL是优化的重点,因为逻辑读直接反映了查询在存储层扫描的数据量,而扫描量是可以通过索引调整和SQL改写来控制的。

找到可疑SQL之后,下一步是查看它的执行计划。如果执行计划显示全表扫描、索引未命中或者连接顺序不合理,就需要判断是统计信息过时、索引缺失还是SQL写法导致优化器做出了错误的选择。

2.3 统计信息的收集时机与方式

统计信息是优化器决策的依据。OceanBase支持通过DBMS_STATS包或ANALYZE语句手动收集统计信息。V4.x版本支持主表和索引表的统计信息收集,MySQL模式下可以使用dbms_stats.gather_table_stats或dbms_stats.gather_index_stats,后者支持指定并行度。

统计信息的收集时机需要与数据变化节奏匹配。对于写入量大的表,统计信息在大量数据变更后会迅速过时,导致优化器基于旧的分布信息估算行数,进而选择错误的连接算法或索引。在批量导入、大规模数据迁移或分区变更之后,应该主动收集相关表的统计信息,而不是依赖自动收集的周期。

统计信息的收集本身也消耗资源。全表扫描和直方图计算在高并发时段执行会与业务查询争抢IO和CPU。收集动作应该安排在业务低峰期,或者针对变化显著的分区做增量收集,而不是每次都对全表做完整的收集。

2.4 Outline与计划绑定

当统计信息调整之后优化器仍然选择非最优计划,或者业务希望固定某个经过验证的最优计划时,可以使用Outline进行计划绑定。CREATE OUTLINE语句将指定的执行计划绑定到特定的SQL语句上,使该SQL的后续执行强制走绑定的计划。

Outline的使用场景需要区分清楚。如果优化器选择一个索引是因为它在当前数据分布下确实更优,那么强制绑定另一个索引可能在未来数据分布变化后变得次优。Outline适合的是那些优化器因为统计信息无法准确反映业务语义而做出错误选择的场景。例如,某条查询的业务语义决定了它总是只返回极少数行,但优化器因为统计信息中的平均值估算而认为它需要扫描大量数据,此时绑定一个索引扫描的Outline是合理的。

计划缓存的另一个问题是计划可能因为各种原因失效,比如统计信息更新、Schema变更或者内存压力导致的缓存淘汰。Outline在计划失效后仍然能够将SQL重新引导到绑定的计划上,这是它相对于单纯依赖计划缓存的价值。

2.5 并行执行的适配条件

并行执行通过将一个查询拆分为多个子任务在多核或多节点上同时执行来加速大查询,但它的收益依赖于一系列前提条件。

分区策略是第一个前提。在大表JOIN的场景中,如果参与JOIN的表使用相同的分区方式并绑定到同一个表组,可以实现partition wise join,这是性能最佳的并行JOIN形式。如果分区方式不匹配,数据需要做重分布,网络传输和内存开销会抵消并行度的收益。

并行度与分区数的比例关系是第二个前提。并行度与分区数符合整比例关系时性能较好,比如分区数为8,并行度设为4、8或16。如果并行度远高于分区数,多余的并行任务会因为无数据可处理而空转;如果并行度远低于分区数,单个并行任务需要处理多个分区的数据,并行加速比受限。

索引的合理性是第三个前提。创建合适的索引减少数据扫描量,才能让并行执行的每个子任务处理更少的数据,并行加速比才不会被单任务的IO瓶颈所限制。在并行执行中,如果某个子任务因为缺少索引而退化为全表扫描,整个查询的完成时间由最慢的子任务决定,并行度再高也无法弥补这个短板。

复制表是第四个可以借用的能力。V4.2及之后版本支持创建复制表,复制表在每个节点上都有完整的数据副本,JOIN时不需要做数据重分布,可以提升并行执行的效率。复制表适合小维表与大事实表的JOIN场景,不适合写入频繁的大表。

第三章 锁与等待事件

3.1 等待事件的分层

等待事件是分析并发性能瓶颈的核心工具。在任何时间点,OceanBase的工作线程要么在计算CPU利用率,要么在等待资源,例如IO资源、网络带宽或临界区。通过等待事件发生的位置和统计信息,可以识别系统性能瓶颈,尤其是高并发小查询的性能。

OceanBase目前支持超过200个等待事件,分为11个大类,包括网络、调度、临界区、latch、集群、事务提交、用户IO和系统IO等。用户IO等待事件由用户请求直接触发,系统IO等待事件由后台任务触发。

典型的诊断场景有三类。第一类是CPU利用率持续偏低而系统负载上升,这通常是因为并发瓶颈,例如频繁访问的临界区出现资源争用,通过定位等待时间最长的TopN等待事件可以找到争用的临界区。第二类是业务SQL的响应时间偶尔从不到1毫秒飙升到100毫秒以上,这通常是因为SQL的执行在某处被卡住,通过查看SQL执行期间记录的等待事件详情,尤其是耗时最长的等待事件的细节,可以定位卡住的位置。第三类是系统突然停止执行某条SQL,这通常是因为会话被锁竞争或未知原因的死锁阻塞,通过查看会话当前等待事件的详情可以定位原因。

3.2 行锁冲突的排查路径

行锁冲突是最常见的并发问题之一。排查的思路是把锁抽象为两个对象:行锁的持有者和行锁的等待者,两者都是事务的一部分,因此在监控活跃事务的同时监控锁的持有者和等待者,可以对锁冲突问题提供很大的帮助。

OceanBase提供了三张核心的虚拟表。__all_virtual_trans_stat用于监控活跃事务,包含事务的唯一标识、所在分区、参与者列表、创建时间、状态和锁冲突重试次数等信息。__all_virtual_trans_lock_stat记录当前集群中所有活跃事务持有行锁的信息,包括事务标识、持有锁的行的rowkey和所属会话。__all_virtual_lock_wait_stat统计当前集群中所有等待行锁的请求或语句的信息,包括等待的行的rowkey、开始等待的时间、绝对超时时间、重试加锁的次数、等待锁的会话ID和该行第一个等待事务的会话ID。

一个典型的排查场景是:一个会话中的未知长事务持有锁,阻塞了其他事务的执行,需要找到并停止这个长事务。方案是通过无法加锁的事务的session_id,在__all_virtual_lock_wait_stat中找到它等待锁的行的rowkey,然后通过rowkey在__all_virtual_trans_lock_stat中找到持有该行锁的事务和会话,最终定位到阻塞源。

3.3 锁的可观测性与死锁检测

一个更棘手的问题是,通过锁视图查到持有锁的会话ID之后,在会话列表中看到该会话处于SLEEP状态,无法判断这个会话是否可以安全终止,也无法确定它属于哪个业务请求。这种场景需要把锁信息与SQL审计关联起来。GVOBLOCKS视图可以查到持有锁的会话,GVOBL​OCKS视图可以查到持有锁的会话,GVOB_SQL_AUDIT可以查到该会话最近执行的SQL,GV$OB_TRANSACTION_PARTICIPANTS可以查到事务的参与者信息。通过事务ID把三者串联,可以从锁的持有者追溯到上锁的具体SQL和业务请求。

死锁的检测依赖于等待图。当事务持有的锁与其他事务冲突时,会形成wait-for链,系统定期检测这条链,如果检测到闭环,就判定为死锁并回滚其中一个事务。死锁检测的周期和重试次数可以在OCP层面通过deadlock_check_period和deadlock_retries参数调整。缩短检测间隔可以更快地发现和解除死锁,但增加了检测本身的开销。

第四章 资源隔离与路由策略

4.1 集群级内存的分配逻辑

内存是OceanBase调优中最关键的资源,因为内存的分配直接决定了写入缓冲、合并触发和查询缓存的可用空间。

memory_limit配置OBServer最大可使用的总内存大小,当前该值无上限,但如果设置的上限超过实际物理内存总和,会导致系统中其他按总内存计算的值偏大。memory_limit需要与memory_limit_percentage配合设置。

system_memory设置系统预留给非实体租户的内存容量,默认值为30G。这部分内存不分配给业务租户,用于系统内部的元数据管理、RootService运行和内部保留。rootservice_memory_limit设置RootService的最大内存容量限制,默认值为2G。

memstore_limit_percentage设置租户使用MemStore的内存占其总可用内存的百分比,默认值为50。这个参数决定了租户内存中用于写入缓冲的比例。写入密集的业务需要更高的MemStore比例来缓冲写入峰值,但过高的比例会挤压查询缓存和Block Cache的空间,影响读取性能。

4.2 CPU配额与并发控制

cpu_quota_concurrency设置租户的每个CPU配额所允许的最大并发数,默认值为4,取值范围为1到10。这个参数影响租户内工作线程的并发度。对于以短查询为主的高并发业务,适当的并发度可以提升CPU利用率;对于以长查询为主的业务,过高的并发度可能导致线程争用和上下文切换开销。

租户资源的定义还包括IOPS和会话数限制。在资源配置时,MAX_CPU必须大于或等于MIN_CPU,单元配置的CPU、内存和日志盘容量在修改后必须大于或等于租户已使用的容量。资源超配是租户创建失败的常见原因,CPU或内存的超额分配会导致创建过程在资源检查阶段被拒绝。

obdiag的巡检能力可以快速发现租户资源配置的问题,例如租户线程利用率超过95%、副本数不一致、宏块利用率过低等。这些指标如果不在上线前检查,可能在业务高峰期暴露为不可用或性能骤降。

4.3 读写分离与LDC路由

读写分离是通过将弱一致性读请求路由到备副本或只读副本,来分担主副本的读取压力。OceanBase的读写分离依赖于OBProxy的路由策略。

弱一致性读有两种路由策略:读写分离和LDC路由。LDC路由的优先级高于读写分离,ODP在选择副本时先检查LDC路由,再走读写分离路由。proxy_route_policy参数控制ODP的弱读请求路由策略,默认策略允许弱读请求被路由到备副本和只读副本,备副本的类型由route_target_replica_type决定。

LDC路由的核心是利用proxy_idc_name配置指定ODP在逻辑数据中心中的位置,使弱读请求只路由到特定区域的副本。这种方式适合跨地域部署的场景,可以避免弱读请求跨地域访问带来的延迟。读写分离策略则通过ob_route_policy系统变量控制,默认取值为readonly_zone_first,即优先读只读型副本。

读写分离的前提是业务能够容忍弱一致性读的数据延迟。对于需要读到最新数据的查询,比如刚写入后立即读取的场景,弱读会导致读不到刚提交的数据。这类查询应该走强一致性读,路由到主副本,而不是为了分担压力而牺牲一致性。

第五章 诊断工具链

5.1 obdiag的定位与部署

obdiag是专为OceanBase设计的黑屏诊断工具,功能覆盖对日志、SQL审计以及进程堆栈等信息的扫描、收集和分析。它的价值在于把原本分散在多个视图、日志文件和命令行工具中的诊断动作,收敛为一条命令的采集和分析。

obdiag支持独立部署和通过obd部署两种方式。独立部署时,通过yum安装oceanbase-diagnostic-tool包,执行init.sh初始化环境。部署完成后,通过obdiag config命令配置待诊断集群的连接信息。obdiag采用集中式收集,只需要部署在任意一台能连接到集群各节点的服务器上,不需要在每台OBServer节点上部署。

5.2 一键收集SQL诊断信息

慢查询诊断的核心是trace_id。可以通过GV$OB_SQL_AUDIT按query_sql模糊匹配获取近期SQL的trace_id,也可以在当前会话执行SELECT last_trace_id()获取前一条SQL的trace_id。

获取trace_id之后,执行obdiag gather plan_monitor命令,一键收集该SQL的执行计划、运行时统计、等待事件和相关日志。这个命令把原本需要手工在多个视图之间比对的信息聚合为一个结构化的诊断包,使问题定位从"凭经验猜"变成"按证据查"。

perf_sql场景是另一个针对慢查询的采集能力,通过trace_id一键采集所有相关诊断信息,适合SQL超时这类业务最常见的问题。

5.3 系统巡检与配置核查

性能问题的一个常见根源是系统配置与硬件规格不匹配,或者多个参数之间存在未被察觉的冲突。obdiag的system巡检项可以一次性检查所有关键配置,包括操作系统层面的参数和OceanBase层面的参数,找出可能导致瓶颈的配置项。

巡检的价值在于把上线前的检查从人工清单变成自动化流程。人工检查容易遗漏,尤其是在集群规模大、参数多的情况下。自动化巡检能够以一致的标准覆盖所有配置项,并在发现异常时给出具体的修改建议。租户资源配置的巡检可以检查线程利用率、副本一致性和宏块利用率等指标,这些指标如果在上线前被忽略,会在业务运行中以难以定位的性能异常形式暴露。

第六章 调优的判断框架

6.1 从症状到层次的映射

调优的起点是症状,但症状本身不指向具体的层次。同样表现为响应时间上升,可能是SQL执行计划变差,可能是合并积压导致读放大,可能是锁等待,也可能是租户内存不足导致频繁冻结。有效的诊断需要把症状映射到最可能出问题的层次。

如果延迟上升同时伴随逻辑读显著增加,优先看SQL层。逻辑读的增加通常意味着执行计划选择了扫描更多数据的路径,原因可能是统计信息过时或索引失效。

如果延迟上升伴随CPU利用率下降、IO等待上升,优先看存储层。合并积压或转储不及时会导致MemTable中的数据在查询时需要与更多的SSTable归并,读放大上升。检查freeze_trigger_percentage、minor_freeze_times和合并线程的积压情况。

如果延迟上升表现为间歇性的尖峰,且尖峰时间与某些操作的时间窗口重合,优先看并发层。锁等待或latch争用会造成间歇性的阻塞,通过等待事件的TopN视图可以定位争用的临界区。

如果延迟上升在特定租户上表现明显而其他租户正常,优先看资源层。租户的CPU配额、内存配额或连接数可能已经接近上限,检查租户的资源使用率与配额的比例。

6.2 调优动作的传导路径

任何一个调优动作都会沿着依赖链传导,在解决一个问题的同时可能引入新的问题。在调整参数之前,理解这个参数的传导路径,比参数本身更重要。

调小freeze_trigger_percentage会减少MemTable的内存占用,但转储频率上升,转储消耗的IO和CPU增加。如果系统的IO已经接近饱和,这个调整可能缓解内存压力却加剧IO争用。

调大minor_freeze_times会降低合并频率,写入吞吐可能提升,但查询时需要归并的SSTable数量增加,读放大上升。如果业务以读为主,这个调整会让查询延迟恶化。

增加并行度可以加速大查询,但如果并行度超过分区数的合理比例,或者数据分布不均匀,并行度的收益会被空转和跨节点数据传输所抵消。

增加索引可以改善特定查询的执行计划,但每个新增索引都会增加写入路径的维护开销和合并时的索引重建成本。索引的收益应该在查询性能的提升和写入路径的代价之间做权衡。

6.3 调优的验证方法

调优动作的效果需要通过数据来验证,而不是通过主观感受来判断。

SQL层的调优,验证指标是目标SQL的平均执行时间、逻辑读次数和CPU时间的变化。V$OB_SQL_AUDIT视图可以按SQL_ID做前后对比。

存储层的调优,验证指标是合并的完成时间、增量SSTable的数量、MemTable的冻结频率和查询的平均IO等待时间。如果合并的完成时间没有缩短,或者读放大没有下降,调整可能没有触及真正的瓶颈。

资源层的调优,验证指标是租户的CPU和内存使用率是否回到了配额的安全区间,以及租户内查询的排队时间是否下降。

验证的周期需要覆盖业务负载的完整波动。在低谷期表现良好的调整,可能在高峰期因为并发上升而失效。调整后的观察窗口应该至少覆盖一个完整的业务峰值。

结语

OceanBase的高效运维,本质上是在LSM-Tree的写入节奏、SQL优化器的决策质量、并发控制的争用水平和资源分配的隔离程度之间,持续寻找与业务负载匹配的平衡点。合并频率、计划稳定性、锁争用和内存配额,这四个变量相互牵制,任何一个的调整都会在另外三个上产生回响。

一个可复现的调优流程应该遵循这样的顺序:先用等待事件和SQL审计定位症状所在的层次,再理解该层次的机制与参数之间的传导关系,然后以最小的变更幅度做调整,最后用数据验证效果并观察传导路径上的副作用。这个流程不依赖于对某个特定版本默认值的记忆,而依赖于对机制的理解和对验证的坚持。

当合并节奏与写入负载匹配时,读放大被控制在可接受的范围;当执行计划在统计信息更新后保持稳定时,查询性能不会因为一次数据变化而突然劣化;当锁争用被可观测性工具定位到具体的会话和SQL时,并发问题从不可捉摸变为可处理;当资源配额与业务峰值对齐时,租户之间不会因为资源争抢而互相拖累。这些状态的达成,是调优工作真正的成果,也是运维从被动救火走向主动治理的标志。

相关推荐
运维行者_1 小时前
供应链安全成最大风险源,企业如何构建可控的运维体系?
运维·开发语言·网络·数据库·安全·云计算·流量监控
xiaoyunxuexibiji1 小时前
采购协同管理:从备货计划、进度确认到到货签收
大数据·运维·人工智能
画中有画1 小时前
在自动化脚本中调用其他脚本文件
运维·自动化
Android系统攻城狮2 小时前
Linux FFmpeg深度解析之avcodec_alloc_context3调用流程与实战(十四)
linux·运维·ffmpeg·车载音视频·音视频进阶·ffmpeg音视频进阶
老李IT笔记2 小时前
抹除之后机器上的受管应用可以留下:这一步省掉的是哪段时间
运维·服务器
李纲明2 小时前
WordPress 定时发布不准点或备份/邮件从不跑:先分清 WP-Cron 触发与 DISABLE_WP_CRON,再查回环与系统 Cron
运维·性能优化·wordpress·定时任务·devdiy·wp-cron
Decay__3 小时前
01_MySQL 体系架构全解 —— 连接层、SQL 层、存储引擎层与 InnoDB 深入
运维·数据库·sql·mysql·架构
Linux_cy3 小时前
nginx 502 排查手册:九种原因分类、定位命令与检查顺序
linux·运维·服务器·网络·数据库·nginx·ssh
椒颜皮皮虾྅3 小时前
模型部署不再卡在环境上:DeploySharp 四大推理引擎与 Windows/Linux 离线交付实战
linux·运维·开发语言·人工智能·windows·计算机视觉·cuda