
数据库分布式数据库云原生后端数据存储【免费下载链接】vitessVitess is a database clustering system for horizontal scaling of MySQL.项目地址https://gitcode.com/gh_mirrors/vi/vitess点击查看免费下载本指南深入剖析 Vitess v17.0.6 引入的一项破坏性变更ExecuteFetchAsDBA以及vtctl、vtctlclient对应命令开始拒绝多语句 SQL。文章不仅解释改了什么、为什么改、怎么应对还会结合当前仓库源码还原其底层实现与调用链帮助你在升级 Vitess 或编写运维脚本时准确避开这一行为变化。变更概览一次面向安全与一致性的收紧在 Vitess v17.0.6 中vtctldclient ExecuteFetchAsDBA、vtctl与vtctlclient中的同名命令不再静默接受以分号分隔的多语句 SQL。一旦检测到输入包含多条语句命令会直接返回错误并且不会尝试执行其中的任何一条。官方变更日志changelog/17.0/17.0.6/summary.md给出的典型例子是vtctldclient ExecuteFetchAsDBA my-tablet stop replica; change replication source to auto_position1; start replica在 v17.0.6 及之后这条命令会直接报错stop replica、change replication source to ...、start replica三条语句一条都不会被执行。该修复对应的 PR 为Protect ExecuteFetchAsDBA against multi-statements, excluding a sequence of CREATE TABLE|VIEW见 changelog/17.0/17.0.6/changelog.md 中 Bug fixes / General 一节。为什么这是一项破坏性变更旧行为的三大隐患在 v17.0.6 之前ExecuteFetchAsDBA会静默接受多语句 SQL 并尝试逐一执行但存在三个被官方明确指出的问题错误被静默吞掉只有第一条语句的错误会被返回第 2 条、第 3 条……语句的错误被无声忽略。这意味着一条看似成功的命令可能只完成了一半的变更。连接池脏状态命令不会消费第 2 条及之后语句的结果集随后把连接归还到连接池。任何后续查询如果恰好从池中取到这条连接都可能读到残留的多余结果集产生难以排查的灵异行为。schema 缓存与底层库不一致当多语句用于 schema 变更时只会以第一条变更重载 schema 缓存导致 vttablet 缓存的 schema 与底层 MySQL 实际结构脱节。正是这三类问题使得接受多语句这种看似便利的行为实际上成为运维事故的温床v17.0.6 选择将其一刀切地收紧。保留的唯一例外CREATE TABLE / CREATE VIEW 序列ExecuteFetchAsDBA仍允许一种特定的多语句用法——所有语句均为CREATE TABLE或CREATE VIEW形式。这是为了继续支持一种常见的 schema 初始化模式一个 SQL 文件中包含大量建表/建视图语句一次性灌入执行。这个例外在 v17.0.6 时期即已生效并在后续版本中继续演化详见下文当前主干的进一步收紧。命令形态与参数速查ExecuteFetchAsDBA用于以 DBA 权限在指定 tablet 上直接执行 SQL是运维与故障恢复场景如修数据、调整复制、初始化 schema的常用通道。其 vtctldclient 形态定义于 go/cmd/vtctldclient/command/query.govtctldclient ExecuteFetchAsDBA [--max-rows max-rows] [--json|-j] [--disable-binlogs] [--reload-schema] tablet alias query支持的关键参数默认值与含义来自 go/cmd/vtctldclient/command/query.go参数默认值含义--max-rows10000从远端 tablet 获取的最大行数--disable-binlogsfalse执行期间禁用二进制日志内部执行SET sql_log_bin OFF结束后恢复--reload-schemafalse执行后指示 tablet 重载 schema--json/-jfalse以 JSON 而非人读表格输出结果使用提醒由于多语句被拒绝任何把多条 SQL 拼接进一条ExecuteFetchAsDBA的脚本都需要改造——要么拆成逐条调用要么改用下面介绍的ExecuteMultiFetchAsDba替代接口。源码级还原校验发生在哪一层从当前仓库源码可以完整还原这条执行链路与校验位置。整条调用链为vtctldclient→vtctldgRPC 服务go/vt/vtctl/grpcvtctldserver/server.go→Wranglergo/vt/wrangler/tablet.go→ tablet 上的TabletManagergo/vt/vttablet/tabletmanager/rpc_query.go。核心校验逻辑真正执行校验的是 rpc_query.go 中ExecuteFetchAsDba传入的validateQueries回调func(queries []string, countCreate int) error { // As of v23 we do not allow multi-statement SQL in ExecuteFetchAsDba at all, and // ExecuteMultiFetchAsDba will be the only way to execute multiple statements. if len(queries) 1 { return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, multi statement queries are not supported in ExecuteFetchAsDba) } return nil }在拼接出校验回调之前analyzeExecuteFetchAsDbaMultiQueryrpc_query.go会先通过 parser 的SplitStatementToPieces把输入 SQL 拆成独立语句并逐个解析 AST、统计CREATE TABLE/CREATE VIEW的数量。这样v17.0.6 要求的全为 CREATE TABLE/VIEW 才放行就可以在校验回调里用countCreate与语句总数对比来判断。值得注意的是对于CHANGE REPLICATION SOURCE TO ...这类当前 parser 无法解析的语句代码会保留解析失败的标记而不会直接报错rpc_query.go 中的注释明确说明了这一点。校验发生在获取连接之前从executeMultiFetchAsDba的实现rpc_query.go可以看出解析、验证与 CREATE TABLE 数量门控都发生在获取 mysqld 连接之前——代码注释特意说明这样做的目的是被拒绝的批次不会白白消耗一次连接获取也不会产生后续SET sql_log_bin、foreign_key_checks、USE等往返。之后才会执行SET sql_log_bin OFF禁用 binlog、SET SESSION foreign_key_checks OFF禁用外键检查、USE dbName等会话准备再通过ExecuteFetchMulti执行并消费所有结果集rpc_query.go。测试佐证vtctld 服务层的 gRPC 单测覆盖了该 RPC 的基本行为见 go/vt/vtctl/grpcvtctldserver/server_test.go 的TestExecuteFetchAsDBA包含成功路径与 tablet 不存在等错误路径用例。当前主干的进一步收紧与替代方案从上述源码注释可以确认v17.0.6 只是第一步到 v23 及之后的版本ExecuteFetchAsDba已完全禁止任何多语句 SQL包括 CREATE TABLE/VIEW 序列ExecuteMultiFetchAsDba成为执行多条语句的唯一方式注释中引用了 vitess issue #15505。因此如果你仍运行 v17.0.x需要遵守仅 CREATE TABLE/CREATE VIEW 序列可用的例外如果你计划升级到 v23 或更高版本请提前把依赖多语句的运维脚本迁移到ExecuteMultiFetchAsDba。ExecuteMultiFetchAsDba在 tablet 侧的实现同样位于 rpc_query.go它复用同一套executeMultiFetchAsDba基础设施但不附加多语句校验并额外支持通过请求中的SessionVariables在会话前设置自定义变量如sql_mode。wrangler 层的便捷封装见 go/vt/wrangler/tablet.go。升级与脚本迁移建议扫描存量脚本全局搜索ExecuteFetchAsDBA/ExecuteFetchAsDba调用找出所有以分号拼接多条语句的用法。逐条拆分对stop replica、start replica、单条 DML/DDL 等改为逐条ExecuteFetchAsDBA调用对不可分割的批处理如批量建表在 v17.0.x 下确认全部语句均为CREATE TABLE/CREATE VIEW后仍可整批提交在 v23 则改用ExecuteMultiFetchAsDba。注意错误可见性提升升级后原先第 2 条之后的语句失败但被静默忽略的情况将直接变成调用失败脚本的错误处理路径需要相应增强避免把报错误判为执行中断而重复执行前序已成功的语句。验证 schema 一致性若此前依赖多语句 DDL升级后可对比 vttablet 缓存 schema 与底层 MySQL确认没有因旧行为留下缓存偏差。延伸阅读发布说明全文changelog/17.0/17.0.6/release_notes.md该版本全部 PR 明细changelog/17.0/17.0.6/changelog.md核心实现go/vt/vttablet/tabletmanager/rpc_query.go客户端命令定义go/cmd/vtctldclient/command/query.go服务端 RPC 实现与单测go/vt/vtctl/grpcvtctldserver/server.go、go/vt/vtctl/grpcvtctldserver/server_test.go赞分享数据库分布式数据库云原生后端数据存储【免费下载链接】vitessVitess is a database clustering system for horizontal scaling of MySQL.项目地址https://gitcode.com/gh_mirrors/vi/vitess点击查看免费下载相关推荐Vitess v17.0.6 破坏性变更解析ExecuteFetchAsDBA 正式拒绝多语句 SQLVitess v17.0.6 破坏性变更解析ExecuteFetchAsDBA 正式拒绝多语句 SQL 本文基于官方发布说明与仓库源码系统性解读 Vites数据库分布式数据库云原生后端数据存储Vitess v18.0.3 破坏性变更解析ExecuteFetchAsDBA 正式拒绝多语句 SQLVitess v18.0.3 破坏性变更解析ExecuteFetchAsDBA 正式拒绝多语句 SQL 导读 Vitess v18.0.3 发布了一个影响运维数据库分布式数据库云原生后端数据存储Vitess v18.0.3 破坏性变更解析ExecuteFetchAsDBA 拒绝多语句 SQL 及其迁移指南Vitess v18.0.3 破坏性变更解析ExecuteFetchAsDBA 拒绝多语句 SQL 及其迁移指南 本指南以 Vitess v18.0.3 发布数据库分布式数据库云原生后端数据存储创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考