# myonlineddl
**Repository Path**: mysql3306/myonlineddl
## Basic Information
- **Project Name**: myonlineddl
- **Description**: 安全高效的改表平台,非常适用于搭建平台化改表系统。
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 5
- **Created**: 2021-08-06
- **Last Updated**: 2021-11-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# myonlineddl
### 一、介绍
- 安全高效的改表平台,非常适用于搭建平台化改表系统。
- 支持建表/改表/删表/truncate等操作。
- 仅实现了后台逻辑,于前端无关,可以给前端提供api调用。
### 软件架构
流程图如下

#### 简单介绍
- 1、格式化SQL,需要将业务SQL做统一格式化处理,方便后面做SQL解析。
- 2、第一次SQL解析。根据用户提交的DDL做预定义用法判断,检查所有操作是否是满足预定义的。这块逻辑就是把控工单的操作,做到所有操作都可控。啥能做,啥不能做。
- 3、第二次SQL解析。判断单条DDL是否满足【Only Modifies Metadata】如果满足就直接OnlineDDL了,如果不满足就使用ghost/ptosc工具。选择工具的时候会针对上述的优缺点问题做各自的判断,然后优先选择ghost。说白了就是工单自适应,可根据当前操作,及不同环境做出判断,并调整相应配置生成一个安全合理又高效的执行计划。
- 4、提供DDL审核功能,并不是说业务提交什么就都能通过。比如说,是否允许null值,是否要求有注释,是否要求规范索引名等等。都可以通过规则开关进行审核。(这点跟上述得预定义用法判断有区别,一个是限制操作,一个是控制操作是否规范合理)
- 5、加上监控,和对异常处理。比如对mdl的监控,连接数,活跃连接数,磁盘空间等等,触发告警会有邮件提示。
- 6、尽可能的保证每个工单的原子性。就是尽可能的保证每个工单里的每条DDL都成功。要么就都不做,要做就都要成功,需要注意,这里说的是尽可能,有点耐人寻味。
- 7、通过API去实现动态配置改表工单,比如正在执行的改表需要暂停,恢复,终止,又或者需要获取改表进度。
- 8、扫尾工作。这点没什么好说的,擦干屁股很重要,避免下次踩坑。
#### 如何实现
要实现上述功能,最大的难度就是如何对业务的DDL操作进行解析。只有实现了SQL解析,才能消除上痛点实现功能。大家也可以想想怎么实现SQL解析这个功能。现在提几个我在实现的时候遇到问题,供大家思考:
- 1、SQL格式化的时候,注释会对你的实现会产生很大的阻碍,那么该如何处理注释的呢。( “/* */ comment '' # --”等等这些注释 )
- 2、SQL解析的时候要考虑【Only Modifies Metadata】分change、modify,varchar扩长度(又有局限性)等场景。如何鉴定这些是否满足【OMM】,如果是modify的组合模式(modify varchar and not varchar)又该怎么鉴定。
- 3、如何鉴定是否满足8.0的快速加列。
- 4、SQL审核的功能,如何把控DDL操作是合理的。
- 5、保留字问题怎么处理呢?不处理,直接返回错误?那用户体验太差了。有些人可能就会说,用反引号引起来就好了,那么问题来了,用户不知道这是关键字,他写的SQL没有用反引号,那需要工单系统二次处理给加上,那应该怎么加呢?哪些需要加呢?
以上几点,大家可以想想怎么实现,可能用脑子一过觉得难度好像不大,但是真正落实到代码,应该还是有些难度的。毕竟ALTER TABLE语法千变万化,组合十分复杂,关于我是如何实现的,有兴趣的小伙伴可以看一下代码,欢迎吐槽改进。
### 二、安装教程
#### 1、获取项目
```
git clone https://gitee.com/mo-shan/myonlineddl.git
```
> 建议放在/data/git/下面, 后面配置起来比较方便,就不用修改main.sh里面的work_dir变量了
- 目录结构如下:
```
centos1 root /data/git/myonlineddl >> ls -l
total 5100
drwxr-xr-x 2 root root 4096 Mar 14 21:19 bin
drwxr-xr-x 2 root root 4096 Jun 15 2021 conf
drwxr-xr-x 12 root root 4096 Mar 14 18:31 function
drwxr-xr-x 2 root root 4096 Jun 8 2021 html
drwxr-xr-x 2 root root 4096 Mar 14 21:54 init
drwxr-xr-x 2 root root 4096 Mar 14 21:58 logs
-rw-r--r-- 1 root root 21275 Mar 14 20:06 main.sh
-rw-r--r-- 1 root root 5168793 Mar 14 09:27 myonlineddlApi.tar.gz
drwxr-xr-x 2 root root 4096 Mar 14 21:40 tmp
centos1 root /data/git/myonlineddl >>
centos1 root /data/git/myonlineddl >> tree -L 3
.
├── bin
│ ├── gh-ost
│ ├── msrt
│ ├── pt-duplicate-key-checker
│ ├── pt-online-schema-change
│ ├── send_mail.py
│ ├── socat
│ └── timeout
├── conf
│ └── myonlineddl.conf
├── function
│ ├── analysis
│ │ ├── f_delete_for_string.sh
│ │ ├── f_get_alter_sql.sh
│ │ ├── f_get_create_sql.sh
│ │ ├── f_get_sql_file.sh
│ │ └── f_return_alter_sql.sh
│ ├── check
│ │ ├── f_check_mode_opt.sh
│ │ ├── f_check_net_delay.sh
│ │ ├── f_check_osc_or_alter.sh
│ │ ├── f_check_ssh_auth.sh
│ │ └── f_check_work_is_run.sh
│ ├── clean
│ │ └── f_exit.sh
│ ├── dbadb
│ │ ├── f_check_diy_info.sh
│ │ ├── f_get_diy_info.sh
│ │ ├── f_print_progress_info.sh
│ │ ├── f_record_info_to_dbadb.sh
│ │ └── f_update_status_for_task.sh
│ ├── log
│ │ ├── f_archive_log.sh
│ │ ├── f_logging.sh
│ │ └── f_usage.sh
│ ├── mail
│ │ ├── f_check_mdl_and_send_mail.sh
│ │ └── f_send_mail_for_alter_table_schedule.sh
│ ├── monitor
│ │ ├── f_check_connect.sh
│ │ ├── f_check_daemonize.sh
│ │ ├── f_check_disk_space.sh
│ │ ├── f_check_mdl_lock_daemonize.sh
│ │ └── f_check_mdl_lock.sh
│ ├── mysql
│ │ ├── f_check_mysql_info.sh
│ │ ├── f_check_slave_status.sh
│ │ ├── f_check_table_after_ddl.sh
│ │ ├── f_check_table_and_disk_size.sh
│ │ ├── f_clear_table.sh
│ │ ├── f_create_test_env.sh
│ │ ├── f_delete_tmp_table.sh
│ │ ├── f_exe_alter_sql.sh
│ │ ├── f_exe_osc_comm.sh
│ │ ├── f_exe_sql_in_mysql.sh
│ │ ├── f_get_mysql_node_info.sh
│ │ └── f_support_onlineddl.sh
│ ├── osctool
│ │ ├── f_init_osc_opt.sh
│ │ └── f_kill_process.sh
│ └── prepare
│ ├── f_init_dir.sh
│ └── f_init_tmpvar.sh
├── html
├── init
│ ├── env56.sql
│ ├── env80.sql
│ ├── myonlineddl.sql
│ ├── test56.sql
│ └── test80.sql
├── logs
│ └── main.log
├── main.sh
├── myonlineddlApi.tar.gz
└── tmp
├── alter_table.mstest.3307.123456
└── alter_table.mstest.3308.123456
17 directories, 60 files
centos1 root /data/git/myonlineddl >>
```
- bin 可执行文件
- conf 配置文件
- function 函数文件
> - 每个目录里面的函数功能,大概跟文件名沾边
> - mysql 目录下面的文件,基本都是处理mysql相关的
> - check 目录就是检查相关的
> - monitor 就是监控相关的
> - analysis 就是sql解析相关
- html html文件,发邮件的时候会先生成html文件
- img 图片
- init 初始化sql
- logs 日志文件
> - execute 表示在线上执行的任务的日志,日志命名规范是[pt-osc-sql文件名.log,gh-ost-sql文件名.log]
> - test是测试环境输出的日志,日志命名规范是,同execute;
> - script是脚本日志,日志命名规范是[sql文件名.log]
- main.sh 主程序
- myonlineddlApi.tar.gz 项目
- tmp 临时目录,我一般会把本地的sql文件放在这里
#### 2、安装pt所需perl环境
```
yum -y install perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL perl-CPAN perl-Digest-MD5
```
#### 3、准备测试环境
- 需要MySQL测试环境,原则上线上有几个版本就需要有几个测试环境,按照版本对应,比如需要改8.0的表,就需要在8.0的测试环境预执行。
> 如果没有找到对应的测试环境,改表会报错并终止。
> 另外需要给测试环境的用户所有权限, 因为改表过程中需要建库,建表,删库,删表。
> 权限请参考init/test56.sql等文件
```
centos1 root /data/git/myonlineddl >> ll init/
total 32
-rw-r--r-- 1 root root 564 Jun 15 2021 env56.sql
-rw-r--r-- 1 root root 752 Jun 15 2021 env80.sql
-rw-r--r-- 1 root root 12568 Mar 14 18:34 myonlineddl.sql
-rw-r--r-- 1 root root 91 Jun 15 2021 test56.sql
-rw-r--r-- 1 root root 278 Jun 15 2021 test80.sql
centos1 root /data/git/myonlineddl >> cat init/test56.sql
grant all on *.* to myonlineddl@'192.168.%' identified by 'myonlineddlpassword'; -- 授权
centos1 root /data/git/myonlineddl >> cat init/test80.sql
create user if not exists myonlineddl@'192.168.%' identified by 'myonlineddlpassword'; -- 创建用户8.0
grant all on *.* to myonlineddl@'192.168.%'; -- 授权
centos1 root /data/git/myonlineddl >>
```
#### 4、准备mysql环境
- 安装的机器要有mysql环境,很多命令依赖于mysql客户端工具。
#### 5、准备msrt环境
- 如果没有ssh环境需要部署这个工具,用于代替ssh,主要是采集mysql节点的磁盘监控。
- 如果没有ssh免密环境又没有部署这个工具,则不会监控磁盘空间,建议部署。
- 到目标节点运行如下命令即可,注意需要给每个mysql节点部署。
> - 这里的pass选项需要对应后面的配置文件中的密码,否则将通讯失败
> - 该工具可以自行修改,修改完直接make重新编译即可 https://gitee.com/mo-shan/msrt.git
#### 6、python 2.7环境
- api依赖于2.7环境,读者也可以根据自己实际情况开发api环境,将view拷贝过去即可。
> 下面介绍api环境的部署
- 随包有个myonlineddlApi.tar.gz,解压到/data/git
- 进入目录解压py27env.tar.gz虚拟环境即可,也可自己搭建虚拟环境然后pip install -r requirements.txt
- 修改配置
```
centos1 root /data/git/myonlineddl/myonlineddlApi >> cat conf/config.ini
[MySQL]
mysql_host = 192.168.1.10
mysql_port = 3306
mysql_user = myonlineddl
mysql_pass = myonlineddlpassword
mysql_db = myonlineddl
mysql_table = "dbadb_alter_table_repl_time"
centos1 root /data/git/myonlineddl/myonlineddlApi >>
```
> 请根据实际情况进行修改dbadb环境的连接信息
- 使用虚拟环境运行app.py即可。
> 可以通过如下方式去访问接口,然后进行改表状态的控制
> 这里是因为当前这个工单没有该表任务,所以提示这个。
#### 7、检查socat环境
- 动态调整改表状态需要这个工具。
```
centos1 root /data/git/myonlineddl >> ./bin/socat --help
./bin/socat: error while loading shared libraries: libreadline.so.5: cannot open shared object file: No such file or directory
centos1 root /data/git/myonlineddl >>
```
> 如果报错请参考下面的操作进行安装配置
```
centos1 root /data/git/myonlineddl >> yum -y install readline-devel readline
centos1 root /data/git/myonlineddl >> cd /lib64
centos1 root /lib64 >> ll *libreadline*
lrwxrwxrwx. 1 root root 18 Aug 22 2020 libreadline.so.6 -> libreadline.so.6.0
-rwxr-xr-x 1 root root 272008 Jun 21 2012 libreadline.so.6.0
centos1 root /lib64 >> ln -s /lib64/libreadline.so.6 /lib64/libreadline.so.5
centos1 root /lib64 >> ll *libreadline*
lrwxrwxrwx 1 root root 23 Mar 14 00:18 libreadline.so.5 -> /lib64/libreadline.so.6
lrwxrwxrwx. 1 root root 18 Aug 22 2020 libreadline.so.6 -> libreadline.so.6.0
-rwxr-xr-x 1 root root 272008 Jun 21 2012 libreadline.so.6.0
centos1 root /lib64 >>
```
#### 8、编辑配置文件
- conf/myonlineddl.conf
> - 请读者根据实际情况更新该文件
> - 改表用户要求有管理员权限,即 *.* 权限。也就是对应到配置文件中的【mysql_user】
> - 如果软件存放的目录不是/data/git/myonlineddl, 则需要改一下main.sh第一行代码的work_dir变量
#### 9、搭建dbadb环境
- dbadb环境可以理解为是改表需要保存元数据的地方,里面会有一些表,建议是独立的库。
> 对这些表中的两个做一些介绍,其余表可以自行查看建表语句,都有注释
> - dbadb_alter_table_repl_time 改表状态表,需要根据这个表去动态调整改表的状态,比如暂停,恢复,终止,改表任务开始后会在这个表写一行记录,api就是通过更新这行记录,然后程序实施监控这行记录是否被变更。
> - dbadb_drop_table_state_info 删表工单记录表,每个删表工单需要执行的sql都会保存到这里,延迟删除的话,crontab 也是读这个表的记录。
> - mysql_ins_rs mysql集群信息表,这个表记录了所有master - slave 信息,改表程序会根据用户传的端口去读这个表然后才知道去哪改表,所以要求每个集群端口唯一。 mysql_ins_rs
> - 可以看到我这个环境有两套集群 3307 3308
> 另外,需要注意的是用户需要传递一个sql文件,文件保存的是ddl操作,文件名要求分几个段【alter_table.testdb.3306.1234456】,并且按照小数点分割:
> - 1、动作,表示需要做啥操作,目前支持的是create_table 和alter_table
> - 2、db名称, 需要告诉程序要改那个db的
> - 3、mysql端口, 通过这个端口去dbadb库里查 mysql_ins_rs 表, 获取到master及slave的相关信息。
> - 4、第四个段目前没有用,建议是时间戳,也可以随便什么字符,通过后面的测试也能看出来规则
#### 10、配置邮件服务
触发告警后是通过邮件发送告知,如果没有邮件服务器环境可以使用bin目录下的 send_mail.py脚本进行发送
> 建议使用163邮箱
> 这里只需要将实际的用户密码配上就行, 但是需要注意的是这个密码不是邮箱的登录密码,而是【客户端授权密码】,如果没有设置过需要开启一下,请参照如下图
#### 11、配置crontab(可选)
> 如果有延迟删除,延迟truncate等需求,需要配上crontab,要不然延迟操作将失效。
```
#crontab里面添加如下规则,请根据实际情况配置
0 5 * * * bash /data/git/myonlineddl/main.sh -a crontab_drop -u 1005155691@qq.com #添加者:moshan,每天凌晨5点会读dbadb_drop_table_state_info 表,将符合条件的端口做删除操作
```
### 三、使用介绍
#### 1、使用帮助
> 通过上述几个步骤操作完成后可以通过查看一下参数介绍:

> 功能介绍

##### (1)改表操作介绍
```
bash main.sh -h localhost -f tmp/alter_table.mstest.3308.123456 -u 1005155691@qq.com -O $(date +%s)
```
> - -h 必选。-h 的作用是可以从源端传sql文件,比如通过api调用的时候,通过rsync拉sql文件
> - -f 必选。如果-h是源端(非localhost),就会通过rsync拉取以if这个文件为名的文件。如果-h是localhost的时候-f指定的文件必须存在,否则会报错。
> - -u是用户的邮箱地址
> - -O是工单号, 建议使用时间戳
> - -e 可选0|1 默认是1,表示在线上执行,如果是0表示对这个操作进行check。不会到线上执行。
##### (2)建表操作介绍
```
bash main.sh -h localhost -f tmp/create_table.mstest.3308.123456 -u 1005155691@qq.com -O $(date +%s)
```
> 请参照改表参数介绍
##### (3)删表操作介绍
```
bash main.sh -a drop_table -D mstest -T "mstest,mstest1,mstest2,mstest3,mstest4,mstest5,mstest6" -O $(date +%s) -u 1005155691@qq.com -P 3307
```
> - -a 必选 表示操作drop_table|truncate_table|later_drop_table|later_truncate_table
> - -D dbname
> - -T table list 逗号隔开
> - -O 工单号
> - -u 用户邮箱地址
> - -P 端口号
> - truncate_table|later_drop_table|later_truncate_table等操作,参数一样。带later标识表示延迟操作,会先rename成待删除表,然后三天后删除
> - 需要说明一下,延迟删除是通过crontab去实现的,所以需要部署一个crontab任务,如下
```
centos1 root /data/git/myonlineddl >> crontab -l
0 5 * * * bash /data/git/myonlineddl/main.sh -a crontab_drop
centos1 root /data/git/myonlineddl >>
centos1 root /data/git/myonlineddl >> bash /data/git/myonlineddl/main.sh -a crontab_drop
[ 2021-03-14 23:04:10 ] [ 提示 ] [ 192.168.1.10 ] [ f_main ] [ 开始执行 : 'main.sh -a crontab_drop' ]
[ 2021-03-14 23:04:10 ] [ 警告 ] [ 192.168.1.10 ] [ f_check_mode_opt ] [ 本次操作是处理延迟删除遗留的待删除的任务 ]
[ 2021-03-14 23:04:10 ] [ 提示 ] [ 192.168.1.10 ] [ f_check_mode_opt ] [ 开始执行 : 'main.sh ' ] [ 本次操作日志, 详情请看 : /data/git/myonlineddl/logs/script/.log ]
[ 2021-03-14 23:04:17 ] [ 提示 ] [ 192.168.1.10 ] [ /data/git/myonlineddl/main.sh ] [ 执行结束 : -a crontab_drop ]
centos1 root /data/git/myonlineddl >>
```
#### 2、用例介绍
- (1)测试用例1 - 8.0
> 改表前的表结构
```
mysql> show create table mstest9\G
*************************** 1. row ***************************
Table: mstest9
Create Table: CREATE TABLE `mstest9` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`name1` char(50) DEFAULT NULL,
`name2` varchar(50) DEFAULT NULL,
`name3` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql>
```
> 出主键外,所有字段的长度都是50,但是name1是char类型,其余是varchar
> 改表语句
```
centos1 root /data/git/myonlineddl >> cat tmp/alter_table.mstest.3307.123456
alter table mstest9
modify name varchar(55) DEFAULT NULL,
modify name1 varchar(55) DEFAULT NULL,
modify name2 varchar(55) DEFAULT NULL,
modify name3 varchar(55) DEFAULT NULL;
centos1 root /data/git/myonlineddl >>
```
> varchar字段都扩了5个字符长度变成55,按照预期,不满足OMM,所以会选择ghost工具

> 可以看到日志中红色箭头部分,检测到name1 是char 到varchar类型的修改,不满足OMM操作, 所以需要用工具进行操作。
- (2)测试用例2 - 8.0
> 改表前的表结构
```
mysql> show create table mstest9\G
*************************** 1. row ***************************
Table: mstest9
Create Table: CREATE TABLE `mstest9` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(55) DEFAULT NULL,
`name1` varchar(55) DEFAULT NULL,
`name2` varchar(55) DEFAULT NULL,
`name3` varchar(55) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql>
```
> 现在把改表sql改成如下
```
centos1 root /data/git/myonlineddl >>
centos1 root /data/git/myonlineddl >> cat tmp/alter_table.mstest.3307.123456
alter table mstest9
modify name varchar(60) DEFAULT NULL,
modify name1 varchar(60) DEFAULT NULL,
modify name2 varchar(60) DEFAULT NULL,
modify name3 varchar(60) DEFAULT NULL;
centos1 root /data/git/myonlineddl >>
```
> 上一个测试用例都将字段长度改成55了,而且将name1从char变成varchar,本次测试将所有字段又扩5个字符长度变成60。按照预期,满足OMM,所以会直接进行alter table操作

> 可以看到和预期一样。使用啦alter table操作
- (3)测试用例3 - 5.6
> 改表前的表结构
```
mysql> show create table mstest\G
*************************** 1. row ***************************
Table: mstest
Create Table: CREATE TABLE `mstest` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(12) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql>
```
> 现在把改表sql改成如下
```
centos1 root /data/git/myonlineddl >> cat tmp/alter_table.mstest.3308.123456
alter table mstest modify name varchar(15);
centos1 root /data/git/myonlineddl >>
```
> - 计划将varchar 从12扩到15
> - 并且将msrt停掉, 来看看效果

> - 可以看到因为版本的问题熬制没有满足OMM,所以还是会用工具进行操作,且因为msrt没有运行,则不会监控磁盘空间。
> - 这时候在执行一次刚才的ddl语句会发生什么呢,请看下图

> 这是因为第二次再执行就满足OMM了,所以会使用alter table直接进行操作
#### 3、api介绍
> api工作原理就是去修改 dbadb.dbadb_alter_table_repl_time表,实现获取改表进度,控制工单状态(暂停,继续,终止)或者修改其他配置项。
```
mysql> show create table dbadb_alter_table_repl_time\G
*************************** 1. row ***************************
Table: dbadb_alter_table_repl_time
Create Table: CREATE TABLE `dbadb_alter_table_repl_time` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'pk',
`order_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '对应改表工单号',
`user_mail` varchar(50) DEFAULT '' COMMENT '工单申请人的邮箱地址',
`port` int(11) NOT NULL DEFAULT '0' COMMENT 'mysql端口, 表示该端口需要定制化延迟时间, 且检查所有从库',
`chunk_size` int(11) DEFAULT '3000' COMMENT '对应ghost命令的--chunk-size=xxx',
`run_state` int(11) DEFAULT '0' COMMENT '0正常改表, 1暂停改表, -1终止改表. 改成1, 可以暂停改表, 改成0又可以继续改表. 改成-1终止该工单改表(注意需要修改dbadb工单号对应的那行, 否则不会生效. chunk_size,run_state,repl_time是基于工单号的)',
`repl_time` int(11) NOT NULL DEFAULT '60' COMMENT '最大允许多少秒的延迟',
`big_table` tinyint(4) DEFAULT '0' COMMENT '是否支持大表改表, 如果表大小超过500g, 需要将这个字段改成1. 修改后仅单次生效',
`disk_space` tinyint(4) DEFAULT '0' COMMENT '如果主库磁盘空间不足表大小的两倍不允许改表, 如果需要继续改表需要将这个字段改成1,表示允许【磁盘空间大小=表大小+50G】. 修改后仅单次生效',
`osc_tool` tinyint(4) DEFAULT '0' COMMENT '0表示只能选择改表工具, 优先选ghost, 如果置为1. 表示强制使用pt-osc进行改表, 适用于ghost不能用的场景. 修改后仅单次生效',
`progress` varchar(50) NOT NULL DEFAULT '0%' COMMENT '改表进度值',
`max_connect` int(11) DEFAULT '2500' COMMENT '改表过程中, 连接数超过这个值就会kill掉空连接',
`unique_key` tinyint(4) DEFAULT '0' COMMENT '是否支持添加唯一索引, 添加唯一索引有丢数据得风险(目标唯一索引的列存在重复值的话就会丢数据) 1表示允许, 默认是0',
`remarks` varchar(200) NOT NULL DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`),
UNIQUE KEY `ixk_order_id` (`order_id`),
KEY `ixk_port` (`port`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='改表配置表,通过操作这个表动态调整改表状态,以及改表工具的参数'
1 row in set (0.00 sec)
mysql>
```
##### (1)用法介绍
> 总共就四个参数,curl命令的apiurl关键字 需要改成api 的url
- key
> 操作动作,可选操作有如下几个动作。需要注意:基于工单的是需要一个工单号,基于端口的是要一个端口。
> - stop_task 终止改表,基于工单的
> - pause_task 暂停改表,基于工单
> - start_task 继续改表,基于工单
> - get_progress 获取改表进度,基于工单
> - big_table 允许超过500g的大表进行改表操作,基于端口
> - disk_space 主库磁盘空间不足表大小的两倍不允许改表,设置这个参数可以允许,基于端口
> - repl_time 从库允许的最大延迟秒数,默认60s,基于工单
> - chunk_size 这个可以忽略,基于工单
- value
> 指定一个值,整数。只有当key=repl_time | chunk_size 才有效,其他清空使用这个选项不生效。
- mail
> 一个邮箱地址。主要是用于记录操作日志,操作人的邮箱。
- OrderId
> 工单号
##### (2)简单用例
###### 以下基于工单号操作 - API
> 获取某工单的改表进度
> - key=get_progress
> - mail=1005155691@qq.com
> - OrderId=4900579887
```
#操作命令
curl 'apiurl?key=pause_task&mail=1005155691@qq.com&OrderId=4900579887'
```
> 暂停某工单的改表任务
> - key=pause_task
> - mail=1005155691@qq.com
> - OrderId=4900579887
> stop_task start_task同这个操作流程
```
#操作命令
curl 'http://apiurl?key=get_progress&mail=1005155691@qq.com&OrderId=4900579887'
```
> 修改延迟时间
> - key=repl_time 【修改chunk_size同理】
> - value=30
> - mail=1005155691@qq.com
> - OrderId=4900579887
```
#操作命令
curl 'http://apiurl?key=repl_time&value=30&mail=1005155691@qq.com&OrderId=4900649172'
```
###### 以下基于端口号操作 - API
> 允许大表改表
> - key=big_table 【修改disk_space同理】
> - mail=1005155691@qq.com
> - port=20948
> 注意:除big_table,disk_space,需要修改不存在的行,不能通过api修改 ,需要通过脚本,后文有介绍。
```
#操作命令
curl 'http://apiurl?key=big_table&mail=1005155691@qq.com&port=20948'
```
###### 以下基于脚本操作
> 修改chunk_size
> - -a chunk_size 【修改chunk_size】
> - -N 100 【修改后的值】
> - -P 20002 【mysql端口,大写P】
> - -u 1005155691@qq.com 【用户邮箱地址,建议写】
```
#操作命令
bash main.sh -a chunk_size -N 100 -P 20002
```
> 修改延迟时间
> - -a repl_time 【修改repl_time】
> - -N 1 【修改后的值,秒数】
> - -P 20001 【mysql端口,大写P】
> - -u 1005155691@qq.com 【用户邮箱地址,建议写】
```
#操作命令
bash main.sh -a repl_time -N 10 -P 20001
```
> 不支持添加唯一索引问题处理
> - key=unique_key
> - mail=1005155691@qq.com
> - port=3306
> 注意:仅单次生效,变更后,只要该端口有改表工单执行了,这个配置就失效了

> 对于上述这种情况,可以跟业务沟通后,如果能承担丢数据的风险就可以放开该端口的添加唯一索引的限制,但是放开动作仅单次生效,即放开动作操作以后仅有一个工单生效,不管这个工单是否成功,放开动作都将失效。
> 放开添加唯一索引的限制操作流程。
```
#操作命令
bash main.sh -a unique_key -N 1 -P 3306 -u 1005155691@qq.com
```

##### (3)总结
- 操作分两类:基于工单,基于端口。开启工单前都通过端口,开启工单后都通过工单号。
- 以上列举的用例可能并不全面,读者可以举一反三,照葫芦画瓢按需进行操作。
- 通过api操作。除了big_table|disk_space,其余操作只能通过工单号去操作,后续会找时间完善。
- 通过api操作的动作都可以通过脚本实现,反之不行。
- repl_time|chunk_size需要通过端口号操作的话(就是说改表前需要进行配置)就需要使用脚本操作。
- 这个骚操作可能有点绕,可以多看两遍。有需要的可以联系笔者进行咨询。
### 四、写在最后
- 日拱一卒,终有一日成车,就是干!
> 感谢阅读!