1. 项目背景与整体思路
前阵子我同时处理了两件事:一是把线上MySQL从单实例改成主从复制架构,为后续高可用打底;二是在机器人导航项目里接入分层思维链H-CoT方案,也就是SG-Nav那套思路,配合在线分层3D场景图做目标导航。一个偏数据库基础设施,一个偏具身智能算法,看上去八竿子打不着,但我在实际部署时发现它们经常咬合在一起——导航实验的日志、场景图的元数据、评估结果全都要落库,而库一旦挂了,整个实验等于白跑。所以我把这两段经验整理成一篇博文,希望能给正在折腾高可用MySQL,或者正在研究机器人目标导航的同行一些参考。
这篇内容的核心落脚点有两个:第一,MySQL主从复制到底是什么、怎么搭、怎么保证高可用,我会把从原理到踩坑的完整过程写清楚;第二,SG-Nav这个导航方案里的H-CoT分层思维链、在线分层3D场景图是怎么设计的,为什么能提升目标导航效率,我也按我的理解拆开讲明白。这两部分我会尽量保持同样的风格:先说为什么,再说怎么做,最后讲遇到了哪些坑。
1.1 为什么要把两个方向放到一起写
很多人看到这个组合会觉得奇怪,但其实是一个很常见的工程现状:近几年做机器人导航、视觉语言导航这类工作,后台几乎都离不开数据库。SG-Nav在做在线建图和语义推理时,会产生海量关键帧、物体置信度、区域拓扑更新、候选目标打分这些中间数据。如果只存在内存里,进程一崩溃全丢;如果写本地文件,又很难做跨机器分析和多轮实验对比。我最后的选择是把这些结构化数据全部写进MySQL,然后为了不让这些实验日志成为单点,顺手把主从复制做了。
反过来也一样:MySQL主从复制本身不是新技术,但真正做到高可用、可维护、能排查问题,还是有不少细节。比如GTID模式怎么配、半同步复制怎么开、从库延迟飙高怎么处理,这些我不写清楚,过几个月再翻笔记也未必能想起来。所以这篇文章本质上是我的工程笔记,把“数据库底座”和“导航算法上盖”放一起,是因为我在实际项目里就是这么一起搭建的。
1.2 技术选型的关键判断
先说我为什么在数据库侧选了MySQL 8.0 + 主从复制,而不是一开始就上分布式数据库或者云数据库。原因很简单:项目数据量还没有大到需要分片的程度,核心诉求是“别因为单机宕机把数据搞丢”,以及“读流量能分流一部分”。主从复制是投入成本最低、资料最全、排查思路最成熟的高可用基础手段。等到一定规模之后,再考虑MHA、Orchestrator或者InnoDB Cluster,这些方案也全都建立在复制之上。
导航侧我为什么关注SG-Nav,是因为它解决的问题非常典型:传统目标导航agent要在一个未知环境里找到指定类别的物体,很多方法要么是端到端强化学习,泛化性差;要么只会做边界探索,不知道“牙刷更可能在浴室”这种常识。SG-Nav把在线分层3D场景图和H-CoT分层思维链结合起来,让导航决策从“像素级反应”升级成“语义级推理”,这个思路在工程上可行,也更容易调试。我的实验环境是仿真为主,后面也会实机验证,接下来详细讲。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 主从复制的底层逻辑与搭建过程
2.1 复制原理:binlog、relay log 和三个线程
主从复制这件事,理解原理比记住命令重要。MySQL把每次对数据变更的记录写到二进制日志(binlog),主库上有个log dump线程负责把binlog发给从库;从库有两个线程:IO线程负责接收主库发来的binlog并写入本地的中继日志(relay log),SQL线程负责读取relay log并逐条回放。这就是“一主两线程”的经典结构。
binlog有三种格式:STATEMENT、ROW、MIXED。STATEMENT记录的是SQL语句,优点是日志量小,缺点是有时候回放结果不一致;ROW记录的是每一行数据变更,更安全但日志量大;MIXED是混合模式。我在8.0里默认用ROW,因为高可用场景下一旦启用半同步复制或者做数据校验,ROW格式的准确度最高。GTID(全局事务标识符)是另一个关键点:每个事务在原始主库上都会分配一个全局唯一ID,从库可以通过GTID自动定位到该从哪里继续拉取,而不是靠手动记录日志文件和偏移量。所以我在配置里把gtid_mode=ON和enforce_gtid_consistency=ON都打开了,后续做主从切换会省很多事。
2.2 环境准备:两台机器加一套干净初始化
我这次用了两台Ubuntu 22.04服务器,一台做主库(192.168.1.10),一台做从库(192.168.1.11),安装的都是MySQL 8.0.36。生产环境我建议用tar包或者apt源安装,不要用那种一条命令装全家桶的方式,因为不好控制版本和配置路径。安装完成后,先别急着改配置,第一步是初始化:
bash复制mkdir -p /data/mysql
chown -R mysql:mysql /data/mysql
mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql
用--initialize-insecure可以让root用户初始为空密码,方便首次登录,但登录后立刻设置强密码。两台机器都做好这步,再分别调整配置文件。这里有个经验:尽量把datadir放到独立数据盘,不要跟系统盘混在一起,否则磁盘写满会直接把系统
