# 如何使用 mysqldump 迁移 MySQL 表 OceanBase

mysqldump 是 MySQL 提供的用于导出 MySQL 数据库对象和数据的工具，非常方便。

使用帮助详情可以通过 参数 `-h` 查看，功能非常丰富，这里就不再赘述。
这里主要把 `mysqldump` 常用的场景命令参数搭配列举一下。

## 导出指定数据库的表结构（不包括数据）

```bash
mysqldump -h 127.1 -uroot -P3306 -p123456  -d TPCH --compact > tpch_ddl.sql
```

这个导出来的脚本有几个特征：

+ 视图的定义也会在里面，但是会以注释 /*!*/ 。视图我们不关注，这部分内容可以删除。
+ 会有一些特别的语法 OceanBase MYSQL 会不支持，但是不影响，需要替换掉其中部分。

下面这个示例就是到处的脚本里有一个 `MAX_ROWS=` 的设置，这个是 MySQL 特有的，OceanBase MySQL 没有这个问题，也不需要这个设置，不支持这个语法，会报错。

```sql
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `NATION` (
  `N_NATIONKEY` int(11) NOT NULL,
  `N_NAME` char(25) COLLATE utf8_unicode_ci NOT NULL,
  `N_REGIONKEY` int(11) NOT NULL,
  `N_COMMENT` varchar(152) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`N_NATIONKEY`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci MAX_ROWS=4294967295;
```

需要把所有 `MAX_ROWS=` 以及后面部分注释掉。使用批量替换技术。如在 `vim` 中使用 `:%s/MAX_ROWS=/; -- MAX_ROWS=/g` 。

注意：上面导出的 SQL 中表名是大写，说明源端 MySQL 里设置表名默认很可能是大小写敏感。因此目标 OceanBase MySQL 租户也要设置。

在导出的表结构语句里，可能包含外键。在导入 OceanBase MySQL 里时，如果外键依赖的表没有创建时，导入脚本会报错。因此导入之前需要将外键检查约束先禁用掉。

```sql
MySQL [oceanbase]> set global foreign_key_checks=off;
Query OK, 0 rows affected (0.01 sec)

MySQL [oceanbase]> show global variables like '%foreign%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| foreign_key_checks | OFF   |
+--------------------+-------+
1 row in set (0.00 sec)
```

修改后，退出会话，重新登录。
在 obclient 客户端里通过 `source` 命令可以执行外部 SQL 脚本文件。

## 导出指定数据库的表数据（不包括结构）

```bash
mysqldump -h 127.1 -uroot -P3306 -p123456 -t TPCH  > tpch_data.sql

```

mysqldump 导出的数据初始化 SQL 里会首先将表 LOCK 住，禁止其他会话写。然后使用 `insert` 写入数据。每个 `insert` 后面的 `value` 里会有很多值。这是批量 `insert` 。

```sql
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
INSERT INTO `t1` VALUES ('a'),('中');
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
```

可能还存在其他导致报错的语句这里没有提到，欢迎到 OceanBase 社区版官网问答区反馈 。反馈地址：`https://open.oceanbase.com/answer/`(<https://open.oceanbase.com/answer>) 。
