54 lines
1.9 KiB
Markdown
54 lines
1.9 KiB
Markdown
# TiDB 目标库:Error 8048 isolation level 'SERIALIZABLE' is not supported
|
||
|
||
## 现象
|
||
|
||
目标库为 TiDB 时,sling 数据迁移在每个 stream 的写入阶段失败:
|
||
|
||
```
|
||
writing to target database [mode: truncate]
|
||
created table `test_demo`.`crm_orders_tmp`
|
||
execution failed
|
||
Error 8048 (HY000): The isolation level 'SERIALIZABLE' is not supported.
|
||
Set tidb_skip_isolation_level_check=1 to skip this error
|
||
```
|
||
|
||
## 原因
|
||
|
||
TiDB 不支持 `SERIALIZABLE` 隔离级别(TiDB 默认使用乐观锁/快照隔离)。sling
|
||
在目标端开启事务时请求了 `SERIALIZABLE`,TiDB 默认会直接报错拒绝。
|
||
|
||
TiDB 提供了兼容开关 `tidb_skip_isolation_level_check=1`:设置后跳过隔离级别
|
||
检查,按 TiDB 实际支持的级别执行。对"测试环境 → 本地 dev 库"的全量数据灌入
|
||
场景,这是安全的。
|
||
|
||
## 解决:连接参数
|
||
|
||
在 sling-ui 中编辑 TiDB 目标连接,在「连接参数」中加一行:
|
||
|
||
```
|
||
tidb_skip_isolation_level_check=1
|
||
```
|
||
|
||
### 工作原理
|
||
|
||
连接参数会被拼进连接 URL 的 query string,例如:
|
||
|
||
```
|
||
mysql://user:pass@tidb-host:4000/dbname?tidb_skip_isolation_level_check=1
|
||
```
|
||
|
||
sling 底层使用 go-sql-driver/mysql,会把未识别的 DSN 参数作为 session 变量
|
||
在连接建立时执行 `SET <key>=<value>`(本项目内置的 `foreign_key_checks=0`
|
||
也是同一机制)。Atlas 的连接 URL 同样会带上这些参数。
|
||
|
||
已实测验证:对普通 MySQL 设置该参数会报 `Error 1193: Unknown system
|
||
variable`,证明参数确实被 SET 为 session 变量;TiDB 上该变量存在,即达到
|
||
预期效果。
|
||
|
||
## 备注
|
||
|
||
- 该参数只对 TiDB 有效,不要给普通 MySQL/MariaDB 连接设置。
|
||
- 若希望对整个 TiDB 实例生效(所有客户端),也可以在 TiDB 上执行
|
||
`SET GLOBAL tidb_skip_isolation_level_check=1;`,但用连接参数的方式
|
||
影响面最小,推荐。
|