跳转至

MySQL 连接器

MySQL 走 MySQL 线协议,底层用 mysql crate。语句刻意走文本协议——同一个适配器还服务 TiDBStarRocksDoris,那几个引擎对预处理语句的支持并不完整——结果统一归一成共享的 ResultSet 结构。

连接走池化(默认 8 条),按需建立。由 exec-mysql feature 控制。

连接配置

datasources:
  mysql_prod:
    type: mysql
    host: ${MYSQL_HOST}
    port: 3306
    username: dosi
    password: ${MYSQL_PASSWORD}
    database: analytics

也可以写成一整串 DSN:

datasources:
  mysql_prod:
    type: mysql
    uri: mysql://dosi:${MYSQL_PASSWORD}@mysql.internal:3306/analytics

参数

类型 必填 默认 说明
type string mysql
host string 是* *除非给了 uri:
port int 3306
username string
password string 尽量用 ${VAR};明文会在 stderr 上告警。
database string 编译出的表名在这个库里解析。
uri string 完整的 mysql:// DSN。它会取代离散键:写了 uri: 之后,hostportusernamepassworddatabase 都不再生效。
default bool false 连接配置

本连接器解析但不使用的键: sslmodesslrootcert(这个适配器完全没有 TLS 处理)、schemacatalogarrow_flight_portaccountrolewarehousecompat_mode

有两个驱动行为是写死的,不对外暴露:关闭 Unix socket 优先(所以 host: localhost 确实走 TCP),以及清空客户端连接属性——有些代理和分支实现会拒绝带属性的握手。

已知限制

  • 没有 FULL OUTER JOIN——但这不构成查询限制。多分支合并(多个不同粒度的指标)会改用可移植的 UNION 键 CTE + LEFT JOIN 形态下推,和 Postgres 家族用的是同一套。模型不用改。
  • 没有三参数 DATEDIFF MySQL 的 DATEDIFF 只接受两个日期;写成单位在前的三参数形式,在这个方言下会在编译期被拒。
  • 没有 CORR / COVAR_* MySQL 根本没有这两个函数,所以相关性窗口会被直接拒绝,而不是用近似值糊过去。
  • 没有 TLS。 配置里的 sslmode/sslrootcert 在这里不生效;把连接放在可信网络里,或者前面挂一个负责 TLS 终结的代理。

本地验证连接

$ dosi query --model model.yaml \
    --metrics revenue --group-by orders.status --execute --connection mysql_prod

排错

报错 原因与处理
connection "x": bad url: <e> uri: 不是合法的 mysql:// DSN。
cannot reach server: <io error> 主机、端口或网络——根本没人应答。
带着服务端原文的 auth 错误(1045、1044 或 1698) 凭据不对、在这个库上没权限,或者账号要求的认证插件不匹配(auth_socket 账号无法走 TCP)。
server rejected SQL (<code>): <message> MySQL 拒了编译出的语句;错误码和文字都是 MySQL 的。
this build has no mysql executor (feature "exec-mysql" not enabled) 官方二进制自带;自己编译的要加 --features exec-mysql

参考链接