xiaohack's Blog - MySQL
type: channel
link: https://blog.xiaohack.org/tag/mysql/
items: 教程：构建基于 Coreflux MQTT 与托管数据库的IoT数据管道
items: MySQL 用好 Optimizer Trace，深刻理解 SQL 优化过程！
items: 爱奇艺基于OceanBase实现百亿级卡券业务的“单库双擎”架构升级
items: 实现设备监控与风速告警的实时化升级，山东港口科技借助时序数据库 TDengine 构建智慧港口“数据基石”
items: 主流关系型数据库系统缺陷实证研究——OceanBase 校企联合研究
items: 【文档悬赏令】第2号：数据库巡检手册征集，上传文档赢好礼！
items: 为什么 InnoDB 中的反向索引扫描更慢？
items: 内存一年疯涨 170%，云账单里的“隐性成本”该算清了
items: 【实操教程】免费外汇 API 获取实时汇率数据（Python+WebSocket 完整实现）
items: Spring Boot 3 集成 Apache Calcite：多数据源查询的终极解决方案

教程：构建基于 Coreflux MQTT 与托管数据库的IoT数据管道
type: item
date: 2026-02-03T16:06:19+08:00
description: 使用托管数据库部署 Coreflux MQTT 代理MQTT 代理 通过发布-订阅消息模式连接物联网设备和应用程序，使其成为现代 物联网 基础设施的重要组成部分。Coreflux 是一个 低代码 MQTT 代理，增加了实时数据处理和转换功能，让你可以直接与 DigitalOcean 托管数据库（包括 MongoDB、PostgreSQL、MySQL 和 OpenSearch）集成，而无需编写自定义集成代码。你将学到什么： 本教程将引导你部署一个完整的物联网数据管道——从在 DigitalOcean 上设置托管数据库集群和 Coreflux MQTT 代理，到配置安全的 VPC 网络、使用 Coreflux 的物联网语言 (LoT) 构建数据转换模型，以及自动将处理后的物联网数据存储到你选择的数据库中。最终你将获得一个可用于生产环境的设置，能够处理物联网应用的实时消息传递和持久存储。关键要点在深入了解分步部署过程之前，以下是你将学到的关键点：在 DigitalOcean 上部署托管数据库集群（PostgreSQL、MongoDB、MySQL 或 OpenSearch），用于可扩展的物联网数据存储。使用 Marketplace 镜像或 Docker 在 DigitalOcean Droplet （DigitalOcean的VPC）上设置 Coreflux MQTT 代理。创建安全的 VPC 网络以连接你的 MQTT 代理和数据库，无需公开暴露。使用 Coreflux 的物联网语言 (LoT) 构建实时数据管道，实现低代码物联网自动化。自动转换和存储物联网数据，从 MQTT 主题到数据库表、集合或索引。验证端到端数据流，从模拟传感器通过转换模型到数据库存储。本教程为需要实时消息传递结合持久数据存储以及搜索、分析或关系查询等高级功能的物联网应用提供了一个可用于生产环境的基础。你将构建什么在本教程结束时，你将得到：一个用于可扩展存储的托管数据库集群（PostgreSQL、MongoDB、MySQL 或 OpenSearch）一台运行 Coreflux MQTT 代理的 DigitalOcean Droplet一个用于安全 物联网通信的虚拟私有云 (VPC) 网络使用 LoT Notebook 扩展进行的实时数据模拟低代码数据转换模型和数据库集成路由用于 物联网自动化 的完整 数据集成与转换 管道Coreflux 与 DigitalOcean 合作Coreflux 通过物联网语言编程语言在 DigitalOcean 云平台上提供轻量级 MQTT 代理和数据管道工具，以实现高效的物联网通信。什么是 MQTT？MQTT（消息队列遥测传输）是一种轻量级的、发布-订阅网络协议，在物联网生态系统中被广泛采用。专为受限设备和低带宽、高延迟或不稳定的网络设计，MQTT 能够在带宽受限的环境中实现高效、实时的消息传递。关于 CorefluxCoreflux 提供了一个轻量级 MQTT 代理，以促进物联网设备与应用程序之间的高效、实时通信，包括每个用例所必需的实时数据转换功能。为可扩展性和可靠性而构建，Coreflux 专为低延迟和高吞吐量至关重要的环境量身定制。无论你是构建一个小型物联网项目还是部署工业监控系统，Coreflux 都能处理设备之间的消息路由和数据流。在 DigitalOcean 云平台上使用 Coreflux，你将获得：数据处理： 在你的数据所在之处集中处理你的数据处理需求，确保实时数据处理。数据集成： 轻松与其他 DigitalOcean 服务（如托管数据库 PostgreSQL、MongoDB、MySQL 或 OpenSearch）集成，确保为你的所有数据需求提供一个单一且简单的生态系统。可扩展性： 轻松处理不断增长的数据和设备数量，而不会影响性能。可靠性： 确保在所有连接的设备之间进行一致且可靠的消息传递。准备工作在开始本 MQTT 代理 部署教程之前，你需要：一个 DigitalOcean 帐户，可在DigitalOcean.com注册，支持绑定信用卡、支付宝或数字货币了解 MQTT 协议概念和 物联网 架构Visual Studio Code（用于 LoT Notebook 扩展）预计时间： 本教程大约需要 30-45 分钟完成，具体取决于数据库配置时间（通常每个数据库集群需要 1-5 分钟）。步骤 1 — 为物联网自动化创建网络基础设施为安全的 MQTT 通信创建 VPC 网络首先，你将创建一个虚拟私有云 (VPC)，以确保你的 物联网 服务和 MQTT 代理 之间的安全通信，无需公开访问。登录你的 DigitalOcean 控制面板从左侧导航栏进入 网络 → VPC点击 创建 VPC 网络为物联网自动化配置你的 VPC：名称…

MySQL 用好 Optimizer Trace，深刻理解 SQL 优化过程！
type: item
date: 2026-02-02T17:17:46+08:00
description: 前面的章节（社区专栏《SQL调优》）我们已经写了很多篇幅关于 MySQL 执行计划的解读，今天我们来继续延伸介绍执行计划的链路跟踪功能，也就是 MySQL 的 Optimizer Trace。在这之前，先来回顾下 EXPLAIN 的结果：mysql:ytt>explain select * from t1 a left join y1 b on a.id = b.id where a.r1<100 order by a.r2 desc; +----+-------------+-------+------------+--------+---------------+---------+---------+----------+--------+----------+-----------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+--------+---------------+---------+---------+----------+--------+----------+-----------------------------+ | 1 | SIMPLE | a | NULL | ALL | idx_r1 | NULL | NULL | NULL | 998222 | 50.00 | Using where; Using filesort | | 1 | SIMPLE | b | NULL | eq_ref | PRIMARY | PRIMARY | 4 | ytt.a.id | 1 | 100.00 | NULL | +----+-------------+-------+------------+--------+---------------+---------+---------+----------+--------+----------+-----------------------------+ 2 rows in set, 1 warning (0.00 sec)EXPLAIN 展示出来的核心数据有：表关联顺序优化器筛选过的索引实际使用的索引每张表依据统计信息的扫描行数Extra 额外数据提示两种执行计划（explain format=tree / explain format=json）展示出来的额外成本数据如果想快速对于 SQL 进行优化，基于以上的结果完全可以满足。但是想深入了解 MySQL 优化器为什么选择这样的执行计划，基于以上的结果就无法满足。举例说明：我想知道对于表 a 来讲，为什么有索引 idx_r1，但是实际却没有使用，而走的全表扫？两张表关联，为什么选择的顺序是表 a 驱动表 b，而不是表 b 驱动表 a？为什么字段 r2 有索引，但是依然要走排序？带着这些疑问，我们来介绍 MySQL 的 Optimizer Trace 功能。1. 什么是 Optimizer Trace？简单来讲，Optimizer Trace 是一个 SQL 执行计划的链路跟踪器，跟踪 SQL 的解析、优化、执行等过程，并且把结果记录到 MySQL 元数据表（information_schema.optimizer_trace），之后可以对这张表分析得到很多个执行计划的“为什么？”！2. 如何使用 Optimizer Trace？要使用 Optimizer Trace 功能，首先得打开控制开关。谨记：这个功能非常耗费资源，默认关闭的，可以通过调整以下变量开启：mysql:ytt>show variables like 'optimizer_trace%'; +------------------------------+----------------------------------------------------------------------------+ | Variable_name | Value | +------------------------------+----------------------------------------------------------------------------+ | optimizer_trace | enabled=off,one_line=off | | optimizer_trace_features | greedy_sear…

爱奇艺基于OceanBase实现百亿级卡券业务的“单库双擎”架构升级
type: item
date: 2026-01-30T11:44:54+08:00
description: 摘要：爱奇艺卡券业务原采用 “MySQL 分库分表 + ES 异步同步” 架构，面临 TP/AP 分离导致的架构复杂、AP 查询分钟级延迟、数据一致性隐患等问题。如今借助 OceanBase 的 HTAP 能力，将 AP、TP 业务融合到一个数据库，在架构简化、成本控制与效率提升方面均取得了突破。爱奇艺是国内知名的在线视频平台，每年都会推出上百部优质长视频内容，其中不乏如 2023 年现象级爆款《狂飙》这样的佳作。近两年，随着短视频、微剧的兴起，平台年处理视频内容数量级从上百部直接跃升至上万部。每一部内容从立项、拍摄、生产、制作到上线播出，均需经过复杂流程，并依赖上百个业务模块协同支持。卡券业务是出于整个业务生态里面的中台位置，对上提供中台能力，如为创新型业务会员、云影院提供商业化变现和用户转化营销工具。过去，卡券业务系统将 AP（分析处理）与 TP（事务处理）业务分开处理，架构复杂，需要较高的维护成本；如今，借助 OceanBase 的 HTAP 能力，将 AP、TP 业务融合到一个数据库，在架构简化、成本控制与效率提升方面均取得了突破。解构卡券业务的数据架构困境卡券是爱奇艺核心的营销与促销工具，贯穿爱奇艺的会员购买、云影院观影等商业化变现全链路。其底层数据库的性能直接关乎用户体验与业务敏捷性。例如，促销发券、会员领券等场景均需要业务系统提供高并发事务处理（TP）能力。而在运营侧，则需要实时统计和分析发券数量、会员领券等指标，以便评估活动效果、优化营销策略，这依赖于高效的数据分析（AP）能力。过去，卡券业务系统采用的是“MySQL 分库分表+ES 异步同步”的复杂架构：分库分表的 MySQL 来承载 TP 业务，以应对高并发海量请求；Elasticsearch（ES）来完成统计分析等 AP 类业务。“这个卡券业务的架构基本上能为业务需求提供足够的支撑。不过，我们并不满意，一直在寻找新的解决方案。”爱奇艺高级总监张冲表示。其最重要的原因就在于系统架构过于复杂，虽能满足业务需求，但每一个节点都需要研发投入大量精力维护，顶峰的时候研发资源占比近 80%，严重挤占了业务创新资源。具体而言，在 TP 业务方面，通过分库分表的 MySQL 集群支撑高并发交易，但实际日常资源利用率仅约 10%，资源冗余明显。在 AP 业务方面，ES 进行运营统计分析时的数据源自订阅多个 MySQL 实例的 binlog，经消息队列 RMQ 异步同步至 ES，链路冗长，存在分钟级延迟。并且 ES 的清理归档代价较高，Reindex 开销也比较大。此外，数据的一致性与准确性面临挑战，在异步同步过程中，甚至出现过 UV（访客数量）超过页面点击的异常，统计准确率难以保障。张冲坦言，对现有架构进行升级更深层的原因，源于对技术进步的持续追求。“我们希望技术上再往前走一走，要和互联网行业最先进的技术保持对齐。”从“分库分表+ES”到“单库双擎”，爱奇艺 HTAP 架构升级实践随着新技术趋势的出现，爱奇艺也开始寻找能够简化架构、支撑业务更好发展的新发展。数据库的升级是这次架构升级的关键。对于新一代数据库，爱奇艺提出了明确的要求：第一，必须是一款兼顾 TP、AP，具备 HTAP 能力的数据库产品，无需管 MQ，无需处理异构的数据，尽量减少对数据平台的依赖，以简化数据底座；第二，总体成本可控，和现有架构相比成本不能上升，符合公司降本增效的目标；第三，云中立，在遇到故障的时候可以实现云逃逸，且在不同的云上均可提供一致性的服务。根据上述三个基本要求，经过对多款主流数据库产品的调研与测试，OB Cloud 一体化云数据库凭借其卓越的性能与高度契合的需求满足度，赢得了爱奇艺的青睐，并且在高并发、高可用、安全、数据治理、低成本等方面的技术积累，都被浓缩到 OB Cloud 一体化云数据库的产品中。张冲表示：“OceanBase 不仅提供了真正的 HTAP 融合能力，其原生分布式架构还与我们的云原生战略高度契合。同时，OB Cloud 在百度云上开服也是一个重要契机，因为爱奇艺的系统平台就部署在百度云上。”完成数据库选型之后，爱奇艺迅速开始了数据和架构升级的准备工作。升级工作分为两个阶段：AP 升级：将 ES 集群中的百亿文档升级至 OB Cloud 集群。通过双写、迁移历史数据、切读、停双写等步骤，不仅完成数据升级，还从业务层面进行了逻辑去冗余和简化。最终，资源成本下降 60%，运营查询类 SQL 基本在 1 秒内返回。TP 升级：将 16 个物理机数据库从原生 MySQL 分库分表形态升级至 OB Cloud 集群。借助 OceanBase 的 OMS 同步工具，顺利完成海量数据同步与校验工作。最终，存储成本下降 80%，且系统具备弹性伸缩能力，无需为大促提前预备资源。张冲表示，为…

实现设备监控与风速告警的实时化升级，山东港口科技借助时序数据库 TDengine 构建智慧港口“数据基石”
type: item
date: 2026-01-29T18:10:07+08:00
description: 小T导读：在智慧港口的建设过程中，面对海量物联网设备产生的时序数据（如设备状态、能耗、作业效率等）的高效接入与实时分析需求，山东港口科技选择采用 TDengine TSDB 时序数据库作为核心数据底座，以应对传统关系型数据库在处理高并发、大规模时序数据时的性能瓶颈，实现设备状态的实时监控、数据压缩存储与智能分析，为智慧港口的数字化转型与智能化运营提供强有力的数据支撑。本次将就此实践进行具体分享。合作背景在“智慧港口”的宏伟蓝图下，山东港口科技集团面临着海量物联网设备数据接入、处理与分析的严峻挑战。港口作业涉及大量的桥吊、门机、集卡、传感器等终端设备，这些设备 7x24 小时不间断产生巨量的时序数据（如位置、状态、能耗、效率指标等）。传统的通用关系型数据库在处理这类高并发、海量的时序数据时，显得力不从心。为了夯实智慧港口的数据根基，经过严谨的选型，我们最终选择了 TDengine TSDB 作为核心时序数据平台，以支撑关键业务系统的数字化转型。选择 TDengine TSDB 的原因在引入 TDengine TSDB 之前，我们的业务系统主要面临以下痛点：数据膨胀与存储成本高：​ 港口设备每秒产生数以万计的数据点，若采用传统数据库存储，数据表会急剧膨胀，不仅占用大量存储空间，且备份和维护成本高昂。查询分析效率瓶颈：​ 对于实时监控、效率分析和历史数据回溯等场景，传统数据库的查询响应速度慢，无法满足业务对“实时洞察”的要求，特别是在聚合计算大量设备的历史数据时，耗时长达分钟甚至小时级。系统架构复杂：​ 为了应对不同的数据处理需求（如实时、短期、长期），往往需要组合使用多种数据库和技术栈（如 Redis、MySQL、Hadoop 等），这增加了系统架构的复杂性、开发和运维难度。TDengine TSDB 作为专为时序数据设计的数据库，其超高性能、内置缓存和流式计算功能、极简的架构以及强大的数据压缩能力​，恰好精准地解决了上述痛点，成为我们的理想选择。使用 TDengine TSDB 后的收益与业务提升部署 TDengine TSDB 后，我们在多个方面获得了显著收益：极致的性能提升：​ 对港口设备运行状态的查询响应速度从原来的“分钟级”提升到“毫秒级”，实现了真正的实时监控与告警。显著的降本增效：TDengine TSDB 高效的数据压缩技术，使得存储空间节省超过 80%，大幅降低了硬件与运维成本，简化的架构也减少了运维团队的工作负担。增强的数据驱动能力：​借助 TDengine TSDB 强大的时序数据计算能力，业务团队能够轻松进行设备效率分析、预测性维护和运营优化，为决策提供坚实的数据支持，进一步强化了“智慧港口解决方案”的核心优势。加速创新应用落地：借助 TDengine TSDB 这一稳定的高性能数据底座，我们能够快速开发和部署新的数据密集型应用，如全自动码头的智能调度系统、物流供应链的可视化平台等。核心业务场景与 TDengine TSDB 应用实例场景一：港口岸桥设备实时状态监控与效率分析业务描述：​ 实时监控码头所有岸桥（Quay Crane）的运行状态（如起升、下降、大车行走、小车行走）、能耗以及作业效率（如单箱能耗、作业周期），确保设备安全高效运行，并即时发现异常。TDengine TSDB 查询 SQL 示例：-- 1. 查询指定岸桥（Crane_ID = 'QC08') 在过去10分钟内的平均功率和总能耗 SELECT AVG(power_kw), SUM(power_kw * ts_interval / 3600) AS total_energy_kwh FROM crane_power_metrics WHERE crane_id = 'QC08' AND ts >= NOW - 10m INTERVAL(1m); -- 2. 统计过去1小时内，所有岸桥的作业箱量（基于每次吊装动作计数） SELECT crane_id, COUNT(*) AS operation_count FROM crane_operation_events WHERE ts >= NOW - 1h AND operation_type = 'lift_complete' GROUP BY crane_id;​通过 TDengine TSDB 毫秒级查询与高效聚合能力，我们实现了对数百台岸桥设备运行状态的实时监控（1 分钟粒度）与异常秒级捕捉，查询效率从分钟级提升至毫秒级，存储成本降低超 80%，极大提升了设备管理实时性与安全性。场景二：智能集卡（AGV/IGV）调度与路径优化业务描述：​ 追踪自动化码头内数百台智能导引车（AGV）的实时位置、速度、电池电量和状态，基于这些时序数据进行最优路径规划和调度，避免拥堵，提升整体物流周转效率…

主流关系型数据库系统缺陷实证研究——OceanBase 校企联合研究
type: item
date: 2026-01-29T16:34:24+08:00
description: 摘要：OceanBase联合中国人民大学数据库团队的数据库缺陷实证研究，被软件工程顶刊IEEE TSE录用。该研究首次构建了面向开源关系型数据库的细粒度缺陷分类体系，共获得12 项发现，为RDBMS系统的开发维护和测试提供了重要启示。研究发现，涉及SQL数据类型及数据库触发器、存储过程、参数设置等复杂功能的缺陷现有测试工作无法有效触发，这一发现为提升RDBMS缺陷检测能力提供了显著改进空间。日前，由 OceanBase 联合中国人民大学数据库系统研究团队（刘爽副教授）对主流关系型数据库系统缺陷开展的实证研究《A Comprehensive Study of Bugs in Relational DBMS》被软件工程领域顶级期刊 IEEE Transactions on Software Engineering(TSE) 正式录用。IEEE TSE 是 IEEE 旗下软件工程方向的权威期刊。在数据库缺陷实证研究方面，本论文首次系统分析了 MySQL 等三个开源数据库中 777 个真实缺陷，揭示了 RDBMS 的缺陷在根因、表症等方面的特点，以及现有测试工具在深层语义缺陷检测上的局限性。以下为论文介绍。简 介本研究通过“系统性实证分析”揭示主流关系型数据库在真实场景中的缺陷规律。研究覆盖 MySQL、SQLite 和 openGauss 三大系统中 777 个高质量修复缺陷，深入剖析其根本原因、症状表现、分布特征及其关联性。其核心贡献在于：首次构建了面向开源关系型数据库的细粒度缺陷分类体系，研究共获得 12 项发现，为 RDBMS 系统的开发维护和测试提供了重要启示。研究发现，涉及 SQL 数据类型及数据库触发器、存储过程、参数设置等复杂功能的缺陷现有测试工作无法有效触发，这一发现为提升 RDBMS 缺陷检测能力提供了显著改进空间。方法与分类体系表1：采集 bug 的统计信息本研究通过一套严谨的实证方法对关系型数据库中的真实缺陷进行系统性分类与归因。围绕三个核心维度展开：根因、症状和修复模块。研究团队从 MySQL、SQLite 和 openGauss 的官方仓库中收集了 2018 至 2023 年间报告的 2495 个缺陷，经过严格筛选后构建了一个高质量的 777 个缺陷数据集。在此基础上，作者提出了一套四维分析框架：根因维度识别出 12 类根本问题（如错误逻辑、API 误用、类型处理缺陷等）；症状维度归纳了包括错误结果、崩溃、死锁、性能退化等行为；模块维度定位缺陷修复位置（如解析器、优化器、执行引擎、存储层等）；关联性进一步探索三者之间的关联规律，例如“类型相关根因多导致错误结果，且集中于表达式求值模块”。为确保标注一致性，两名研究人员独立完成全部标签分配，并通过 Cohen’s Kappa 系数评估达成共识。该方法不仅保证了分析的客观性，也为后续数据库测试工具的设计提供了可操作的指导依据。结果与分析研究揭示了多项关键发现。首先，在根因分布上，“不正确的代码逻辑”占比最高达 32.3%，“类型处理缺陷”和“API 误用”分别以 9.0% 和 8.4% 的比例成为第二、第三大类根因。其次，在症状表现方面，“结果不一致”是最普遍的症状，占全部缺陷的 42.99%，且往往无崩溃、无报错，具有极强的隐蔽性。图1：按根本原因划分的缺陷分布进一步的跨系统对比显示：MySQL 与 SQLite 在缺陷模式上高度相似，而 openGauss 因架构差异与活跃开发状态，表现出显著不同的缺陷谱系。这些结果不仅刻画了数据库内核的脆弱面，也为未来高可靠数据库的设计与质量保障工作指明了方向。图2：症状与根因的关系概念验证工具 SQLT研究中观察到类型相关缺陷在数据库 bug 中占比显著，团队开发了一个概念验证工具 SQLT，用于针对性挖掘此类问题。SQLT 强化了对跨数据类型表达式、隐式类型转换以及非标准类型（如 BIT、JSON）组合的查询生成能力。该工具通过比对语义等价查询的执行结果，能够有效识别那些不触发崩溃但返回错误结果的静默逻辑缺陷。在实验中，SQLT 不仅成功复现了多个已知类型 bug，还新发现 8 个此前未被报告的问题，其 5 个已被 MySQL、SQLite 和 openGauss 官方确认并修复。表2：SQLT检测到的缺陷欢迎访问 OceanBase 官网获取更多信息：https://www.oceanbase.com/

【文档悬赏令】第2号：数据库巡检手册征集，上传文档赢好礼！
type: item
date: 2026-01-29T12:16:00+08:00
description: 墨天轮社区举办的 【文档悬赏令】系列活动，每次聚焦一个主题，征集真实、可操作的第一手文档，希望能扩充社区文档资源、为更多人提供有用的参考资料，让技术学习少走弯路！第2号悬赏令活动主题：数据库巡检方案实践数据库巡检是保障业务稳定运行的核心运维环节，更是DBA日常工作的重中之重。当前数据库类型、场景十分丰富，多数从业者需耗费大量时间整理巡检清单、调试巡检流程。墨天轮社区第二期【文档悬赏令】活动特围绕这一主题发起有奖征集活动，诚邀您上传实用、可落地的数据库巡检文档，和社区众位DBA们互帮互助，让巡检工作更高效、更标准！一、活动时间2026 年 1 月 26 日 - 3 月 28 日二、文档要求1、主题范围本次征集聚焦 “数据库巡检” 核心主题，覆盖国内外主流数据库，基础巡检、专项巡检、自动化巡检等多类实用方案等均可，具体范围如下：巡检主题细分（包含但不限于）：基础巡检：日常运维巡检表/巡检清单/巡检手册专项巡检：性能监控与优化巡检/灾备状态巡检/单机or集群巡检方式：手动巡检标准化文档/自动化巡检/脚本命令/巡检工具数据库不限：商业数据库：Oracle、SQL Server等国产数据库：达梦DM8、人大金仓KingbaseES、OceanBase等国产库开源数据库：MySQL、PostgreSQL、Redis等开源库2、合格要求与格式文档内容需明确巡检目的、适用场景、巡检流程等，包含巡检相关代码（部分敏感信息可隐去）。页数要求：≥5 页必加标签：上传时需在 “标签” 栏填写 “数据库巡检” + 数据库种类（如 Oracle、OceanBase） 两个标签支持格式：优先推荐 .doc、.pdf、.ppt、.md、.txt 格式（可支持前 5 页预览，下载率更高）；也可上传 .zip （需附内容说明）；以下文档将被判为不合格：1）主题无关：非“数据库巡检”相关主题2）内容搬运：直接上传电子书或产品官方文档、他人演讲PPT，或直接复制抄袭、全文搬运网站其他文章/文档内容（已发布的文章内容不可以同时上传成文档参与活动，但如果是您曾发在其他网站的内容则可以上传参与）3）流水账或凑字数：文档页数需≥5页，但不可通过凑字数、使用大量无关图片占篇幅等4）作者刷量：不可刷数据-我们鼓励作者自发宣传自己的文档，但不可使用人工刷量、注册小号刷量等方式提高下载量；不可将文档拆分多份上传，导致单份内容无实际意义、缺乏完整性5）重复文档：重新上传以前发布的文档系统会自动识别判定为重复仅自己可见，也不可删除旧文档后重新上传三、上传步骤登录上传：登录墨天轮账号后，点击链接直达上传页：https://www.modb.pro/docUpload，或在首页下拉框点击 “传文档”；填写信息：标题：建议明确标注 “数据库种类 + 巡检场景”（如《MySQL数据库巡检手册》《Oracle数据库常规巡检项目和命令》），帮助他人快速判断主题标签：上传时需在 “标签” 栏填写 “数据库巡检” + 数据库种类（如 Oracle、OceanBase） 两个标签墨值设置：支持免墨值 / 5 墨值 / 10 墨值 / 25 墨值 / 50 墨值 / 100 墨值，设置墨值后，他人下载时支付的墨值将实时计入您的账户（ps：一般来说墨值越低下载门槛越低，被下载可能更高）提交：确认信息无误后点击 “提交文档”即可。于 “控制台-内容管理-我的文档” 处可查看您所有文档明细，若您遇到“仅自己可见”“转换失败”等状态可询问墨天轮小助手（VX：modb666）询问具体原因。四、奖励设置本次活动奖励分为 “合格奖”“有效助人奖”“巡检先锋奖” 三类1、合格奖每位用户每日首次上传≥5 页的合格文档，可自动触发 “每日任务” 获 5 墨值。此外，本次活动奖励额外可叠加，根据用户合格文档数量发放不同等级的墨值奖励，具体如下：合格数量墨值0-3个10墨值/份3个以上15墨值/份2、有效助人奖根据单个文档下载数发放不同等级的墨值奖励，每个用户最多可有5个文档获得本项奖励：被下载数墨值30＜被下载数 ≤ 5050墨值50＜被下载数 ≤ 100100墨值100＜下载数 ≤ 150200墨值150＜下载数 ≤ 200300墨值下载数＞200500墨值3、巡检先锋奖将综合评估用户上传的合格文档的内容质量及总下载量，评选出 “既多产、又优质” 的核心贡献者，发予相应奖励：奖项等级奖励内容第 1 名1000 墨值 + 100元内数据库实体书一本第 2 名500墨值 + 爱国者U盘（128GB 双接口）第 3-5 名笔记本电脑支架（可旋转）说明：三类奖项单独评奖、每位用户可重复获得。其中新版本先锋奖数量将根据实际参与情况灵活调整，若参与情况佳则可能增设、反之亦然。五、奖励公布与发放进度公示：为了让大家更加了解自己的参与进度，…

为什么 InnoDB 中的反向索引扫描更慢？
type: item
date: 2026-01-29T10:59:00+08:00
description: 作者：马金友， 一名给 MySQL 找 bug 的初级 DBA。爱可生开源社区出品，原创内容未经授权不得随意使用，转载请联系小编并注明来源。本文约 1500 字，预计阅读需要 5 分钟。如果你注意到在 MySQL 中 ORDER BY DESC 查询比 ORDER BY ASC 稍微慢一些，不用担心 —— 这是已知且符合预期的行为。这是因为 InnoDB 的设计和优化是为了进行正向扫描，它使用单向链表结构来组织页面上的记录。因此，向前移动（ASC）的时间复杂度是 O(1)，而向后移动（DESC）的时间复杂度是 O(n)。这篇博客将从存储层面的角度演示这两种算法。1. InnoDB 页面结构1.1 单向链表InnoDB 使用单向链表来组织record。 每个页面有两个虚拟record：infimum 和 supremum，它们分别作为链表的头部和尾部。一旦数据页面包含用户记录，链表就会按逻辑顺序显示。infimum -> rec1 -> rec2 -> rec3 -> rec4 -> ... -> supremum1.2 REC_NEXT每条记录在记录头中额外占用 2 个字节(byte)来存储指向下一条记录的偏移量。constexpr uint32_t REC_NEXT = 2; constexpr uint32_t REC_NEXT_MASK = 0xFFFFUL;例如，infimum 记录的 REC_NEXT 值是 0x00, 0x0d。/** The page infimum and supremum of an empty page in ROW_FORMAT=COMPACT */ static const byte infimum_supremum_compact[] = { /* the infimum record */ 0x01 /*n_owned=1*/, 0x00, 0x02 /* heap_no=0, REC_STATUS_INFIMUM */, 0x00, 0x0d /* pointer to supremum */, 'i', 'n', 'f', 'i', 'm', 'u', 'm', 0, /* the supremum record */ 0x01 /*n_owned=1*/, 0x00, 0x0b /* heap_no=1, REC_STATUS_SUPREMUM */, 0x00, 0x00 /* end of record list */, 's', 'u', 'p', 'r', 'e', 'm', 'u', 'm'};通过 infimum 记录偏移 0x000d，可以得到 supremum 记录。In [1]: infimum_supremum_compact = [ ...: 0x01 , 0x00, 0x02 , 0x00, ...: 0x0d , 'i', 'n', 'f', 'i', 'm', 'u', 'm', 0, ...: 0x01 , 0x00, 0x0b, 0x00, ...: 0x00, 's', 'u', 'p', 'r', 'e', 'm', 'u', 'm' ...: ] ...: In [2]: infimum_supremum_compact[5] Out[2]: 'i' In [3]: infimum_supremum_compact[5+0x000d] Out[3]: 's'1.3 页面目录 (Page Directory)由于单向链表的数据结构，InnoDB 必须扫描整个链表才能找到一条 record，这效率很低。InnoDB 在每个数据页的末尾维护一个动态数组（page directory），数组中的每个元素（槽/slot）存储一条record的位置。/* We define a slot in the page directory as two bytes */ constexpr uint32_t PAGE_DIR_SLOT_SIZE = 2;它不是存储每条记录的地址，而是每个槽指向该槽所管理记录中的最后一条记录。一个槽通常管理 4 到 8 条记录。/* The maximum and minimum number of records owned by a directory slot. The number may drop below the minimum in the first and the last slot in the directory. */ constexpr uint32_t PAGE_DIR_SLOT_MAX_N_OWNED = 8; constexpr uint32_t PAGE_DIR_SLOT_MIN_N_OWNE…

内存一年疯涨 170%，云账单里的“隐性成本”该算清了
type: item
date: 2026-01-28T16:17:56+08:00
description: 2025 年下半年，存储价格又一次成为行业聚焦点。多家市场机构统计显示，2025 年三季度跟四季度，DRAM 和 NAND 价格一路攀升。根据 Tom's Hardware 披露的数据，2025 年 DRAM 合同价同比上涨幅度高达 171.8%，创下历史新高。此轮上涨跟 AI 数据中心建设拓展、服务器需求集中释放紧密相联，还直接引发企业 IT 基础设施采购成本上升。对于依赖自建数据中心或中小 IDC 的企业来说，这种变化带来的冲击尤为剧烈。硬件采购从一次性预算问题，演变为难以预测的长期成本风险。服务器、SSD 和内存条的价格不再稳定，交付周期也更不确定。企业在扩容时不得不承担高价买入、供货延迟的双重压力。因此，将硬件采购压力转化为按需付费的运营支出，把价格波动风险转移给云服务商，正在成为越来越多企业的选择。但问题并未因此结束。随着业务迁移到云端，企业发现云账单中存储与内存的占比仍在持续上升，即便算力配置并未明显升级，总体成本依旧水涨船高。部分团队开始反思：问题是否仅和数据量增多有关，还是资源使用方式本身就存在不合理的地方？目前，多数云实例依旧按固定的 CPU 与内存配比来交付，诸如 2 核 4GB、4 核 8GB 的规格。早期，这种设计可简化资源管理，推动了云计算普及，但如今业务形态有所改变，企业系统一般得同时支撑多样业务，各业务对于算力、内存的消耗不一样，固定规格愈发难以契合实际需求。这导致企业要么部分资源长期闲置，要么不得不面对业务在高峰阶段出现性能瓶颈的风险。当内存价格进入上行周期，这种规格错配带来的浪费被进一步放大：闲置的不再只是资源本身，而是越来越昂贵的成本。正是基于这样的背景，云基础设施走到新的路径分岔口：是继续就资源本身实施配置，还是转变方向围绕应用需求设计算力供给方式？在近期面向中国区合作伙伴召开的发布会上，华为云对 Flexus 云服务器系列规格及性能进行更新，并且展示了其在各种业务负载下的运行表现。该实例基于华为云首创的柔性算力技术，打破 CPU 与内存的固定绑定关系，使企业能够按真实业务需求配置资源，从源头减少内存浪费，并结合智能调度与应用级加速改善长期运行稳定性与算力资源投入产出比。本文将从行业环境变化与技术实现等层面，剖析这种模式背后的思路，以及它所代表的云服务器演进方向。云服务器，开始不太“合身”了云服务器长期采用固定 CPU 与内存的配比，是工程上的一种取舍考量。早期云平台首先得解决的是规模化交付和稳定调度的问题，采用固定规格利于资源池管理，同样便于容量规划及计费设计。当业务形态呈现相对单一阶段，这样的方式尚可接纳。但究其本质它是从平台管理成本角度设计的，并非从业务负载的角度出发。如今业务已不再是单一模式，电商、内容分发、数据库、缓存、AI 推理在一套系统中同步协同运行，对 CPU 以及内存的需求差别明显，固定规格无法精准对应实际负载，企业只能采用超出实际所需的实例型号。云服务器规格跟应用需求普遍不匹配，用户往往被迫去为用不到的算力和内存付费，引发大量资源的闲置浪费。资源浪费只不过是表象罢了，更深层的问题体现为性能优化的复杂度。现实的业务部署不仅涉及操作系统选定，还包含网络参数、系统参数以及应用配置参数。数量往往达到数千级别，缺少专家经验积累，难以达成稳定的最优配置。单是内核跟应用层的参数组合，就已超出普通团队可控范围，调优所用的周期漫长，效果也难以把控。从较长的时间阶段看，云服务器本身一直在不断演变，最初的资源虚拟化阶段，是把物理服务器标准化成可租借的实例；紧接着进入弹性规模阶段，采取自动伸缩的方式去应对流量变化，这两个阶段处理的是存不存在以及是否充足的问题，当下已经迈入第三阶段，关注焦点转向使用是否高效。过去，固定实例曾是工程优势，如今却愈发像是一件穿着不合身的衣服。柔性算力：从“卖规格”到“卖能力”怎样让资源本身更贴近应用？在 Flexus 云服务器 X 实例产品的设计里，华为云引入了柔性算力这一概念。在 Flexus X 实例里，柔性算力首先体现在规格形态的调整变化上。传统实例一般仅仅可在少量固定比例中选择 CPU 跟内存配置，而该实例支持按业务需求实施更精细的组合配置。发布会现场提到，所有 X 实例均支持多种非常规的 CPU/ 内存配比，包括 3:1、2:5、3:7 等组合。这可减少由规格不一致引起的资源闲置，让用户更接近按实际负载付费。然而规格数量增加，并非表示问题自动就解决了，其关键是系统如何判断哪种配置更合适。传统调度大多依据节点上剩余的 CPU 与内存。新方式需要领会业务负载本身，涵盖资源使用结构，以及随时间的变化趋势。Flexus X 实例本质上不再是调度 CPU，而是实际的业务场景。就工程实现而言，这种转变依赖底层架构的支撑，Flexus X 实例借助华为云自研的擎天 Qi…

【实操教程】免费外汇 API 获取实时汇率数据（Python+WebSocket 完整实现）
type: item
date: 2026-01-28T11:51:03+08:00
description: 在金融工具开发场景中，实时汇率数据是高频交易、跨境支付工具的核心依赖，但商用数据源成本高、轻量需求下接入性价比低，成了很多开发者的痛点。外汇市场日均 6 万亿美元的交易量，要求数据具备毫秒级时效性，而免费外汇 API 恰好能以零成本解决这一问题。本文从开发者视角，拆解基于免费外汇 API 的实时汇率获取方案，附可直接运行的 Python 代码，适配快速落地需求。一、免费外汇 API 的核心优势（开发者视角）对开发者而言，免费外汇 API 的价值远不止 “免费”，更在于适配开发效率：零成本试错：无需支付数据源订阅费，降低工具原型开发阶段的成本，聚焦核心业务逻辑；低集成门槛：接口设计标准化，文档清晰，无需额外适配开发，10 分钟即可完成接入；高性能传输：API 支持 WebSocket 协议，相比 REST API 的 “请求 - 响应” 模式，实现持久化数据通道，数据延迟低至毫秒级，满足实时性需求。二、实时汇率获取实操（完整代码 + 解析）以下为基于 WebSocket 的 EUR/USD 实时汇率获取代码，代码结构清晰，包含完整异常处理，可直接复用至项目中。1.完整代码实现import websocket import json # WebSocket URL，具体API地址根据你选择的API提供商来获取 url = "wss://api.alltick.co/forex/marketdata" # 假设的API URL # 定义请求的参数 params = { "pair": "EURUSD", # 你需要查询的货币对 "apikey": "YOUR_API_KEY" # 替换成你自己的API密钥 } # WebSocket消息格式 def on_open(ws): print("Connection established") # 发送请求数据 ws.send(json.dumps(params)) def on_message(ws, message): # 处理返回的数据 data = json.loads(message) if 'rate' in data: print(f"当前汇率：EUR/USD = {data['rate']}") else: print("没有获取到汇率数据") def on_error(ws, error): print(f"发生错误：{error}") def on_close(ws): print("连接关闭") # 创建WebSocket连接 ws = websocket.WebSocketApp(url, on_open=on_open, on_message=on_message, on_error=on_error, on_close=on_close) # 运行WebSocket连接 ws.run_forever()2.核心逻辑解析协议选型：采用 WebSocket 长连接，避免短连接频繁建联的性能损耗，适配实时数据持续推送的场景，这是相比传统 API 的核心优势；参数设计：仅保留pair（货币对）和apikey（密钥）两个核心参数，极简设计降低使用成本，替换参数即可适配多币种需求；回调函数：connect_open：连接建立后自动发送请求，无需手动触发；receive_message：解析返回数据，提取核心汇率字段，可直接对接业务逻辑；catch_error/close_connection：捕获连接异常、处理连接关闭，保障程序稳定性。三、扩展与优化建议多币种批量获取：构建货币对列表（如["EURUSD", "USDJPY", "GBPUSD"]），循环发起请求，实现多币种数据同步；异常重连机制：在catch_error中添加重连逻辑，避免因网络波动导致数据中断：python 运行 def catch_error(ws, error): print(f"数据连接异常：{error}") ws.close() ws.run_forever() # 自动重连数据持久化：在receive_message中接入数据库（如 MySQL、Redis），将实时汇率数据落地，用于后续分析或策略执行。总结免费外汇 API 是轻量级金融工具开发的最优选择，零成本且能满足实时性需求；WebSocket 协议是实现实时汇率获取的核心技术，相比 REST API 具备低延迟、长连接优势；代码核心在于回调函数的设计，异常处理是保障生产环境稳定运行的关键。如果在接入过程中遇到 API 密钥申请、协议适配等问题，欢迎在评论区交流，共同优化实现方案。

Spring Boot 3 集成 Apache Calcite：多数据源查询的终极解决方案
type: item
date: 2026-01-26T15:22:46+08:00
description: 熟悉 Spring Boot 3 的开发者，都知道它在简化开发流程、提高开发效率方面的出色表现吧！但是，在实际业务场景中，大家肯定都碰到过这样的棘手问题：订单数据存放在 MySQL 里，库存数据在 PostgreSQL 中，用户数据又保存在 MongoDB 中，当多种数据源同时存在时，想要实现统一查询简直比登天还难。所以呢，今天我就亮出我的“终极大招”——Apache Calcite，着重给大家讲讲它怎样与 Spring Boot 3 实现无缝集成，还会分享一些可以直接拿来使用的经典应用场景。掌握了这一招，多数据源查询的难题就能轻松解决啦！一、核心认知：Apache Calcite 为何是多数据源查询的利器？在动手集成前，咱们先把核心逻辑搞明白：为啥 Calcite 能成为多数据源查询的“万能钥匙”？它的核心优势到底在哪？1.1 不止是查询引擎：Calcite 的核心定位Apache Calcite 本质是一个动态数据管理框架，而非传统的数据库。它最核心的价值在于“解耦”——将数据存储与数据查询分离，无论数据存在哪里、是什么格式，都能通过统一的 SQL 接口进行查询。说通俗点，Calcite 就像个“超级数据翻译官”——不管数据藏在哪个数据源里、是什么格式，你只要写一套标准 SQL，它就能翻译成对应数据源能懂的指令，最后把结果整理成统一格式返回。这也是它能搞定多数据源查询的核心秘诀！1.2 Calcite 的核心能力拆解统一 SQL 接口：支持标准 SQL，无论底层是关系型数据库（MySQL、PostgreSQL）、非关系型数据库（MongoDB、Redis），还是文件（CSV、Parquet）、大数据引擎（Hive、Spark），都能通过同一套 SQL 查询。强大的查询优化：内置基于规则和成本的查询优化器，能自动优化 SQL 执行计划，提升查询效率，尤其是在复杂多表关联、跨数据源查询场景下，优化效果明显。灵活的数据源适配：通过“适配器（Adapter）”机制适配不同数据源，社区已提供大量现成适配器，也支持自定义开发，适配特殊数据源。轻量级集成：核心依赖体积小，无复杂依赖，可轻松集成到 Spring Boot、Spring Cloud 等主流 Java 开发框架中，无需单独部署独立服务（也支持独立部署）。二、重点实战：Spring Boot 3 集成 Calcite 核心步骤既然大家都熟悉 Spring Boot 3 的基础操作，我就不啰嗦项目搭建这些常规步骤了，直接聚焦 Calcite 集成的核心环节，每一步都附完整代码和避坑提醒，跟着做就能成！2.1 核心依赖引入第一步先引依赖，在 pom.xml 里加好 Calcite 核心包、对应数据源的适配器，再配上 MyBatis Plus 的核心依赖（替换掉原来的 Jdbc 依赖就行），具体如下： <dependency> <groupId>org.apache.calcite</groupId> <artifactId>calcite-core</artifactId> <version>1.36.0</version> </dependency> <dependency> <groupId>org.apache.calcite</groupId> <artifactId>calcite-mysql</artifactId> <version>1.36.0</version> </dependency> <dependency> <groupId>org.apache.calcite</groupId> <artifactId>calcite-mongodb</artifactId> <version>1.36.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.5</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.20</version> </dependency>这里有 3 个避坑点必须强调下：Calcite 所有组件版本要统一，不然容易出现类加载异常；MyBatis Plus 得选适配 Spring Boot 3 的版本（3.5.3+）；一定要加连接池依赖，不然 Calcite 数据源没法被 MyBatis Plus 正常管理。2.2 核心配置：C…