大数据

使用脚本对数据库进行迁移

2019-08-13  本文已影响0人  minute_5

为什么要进行数据迁移与修复

在日常工作开发中,随着我们产品不断迭代发展,我们希望在重构功能的同时,还需要保证在版本迭代之前操作数据保留并且变更得能够适应新的功能结构,这个时候往往会存在数据表的大量修改与变动,就是我们通常所说的 平滑升级

代码中使用定时任务

  1. 在代码中使用定时任务来对数据库进行数据迁移与修复时,一般都会存在读取、更改、插入等操作,如果数据量很大,那么修复时耗会使得我们难以接受。
  2. 更糟糕的是如果我们系统使用到的是微服务架构,微服务之间的通信调用也存在着时间损耗,这里进一步使得时耗尽延长。
  3. 但如果使用的是shell脚本,速度将会大大提升,比如我们在代码中进行数据修复要花掉5分钟时间,使用脚本修复可以只需要2秒。

Mysql - 这里举例三个微服务:

需要被同步的微服务数据库 - 新表存在的服务:base_service
需要同步数据的 - 旧表存在的服务:devops_service,agile_service

如果要修复的数据在同一台服务器上,而且你只想导出部分字段到所需的表中,那么:

只需要连接上数据库,使用sql将数据查询出来再插入就可以了(这里,sql灵活多变,你可以根据自己的同步数据策略进行修改)

mysql -u$BaseDBUSER -p$BaseDBPASS -h $BaseDBHOST << EOF
use ${base_service};
insert into ${base_service}.${base_service_table_app}(id, name, code, organization_id, image_url,type) 
select id, name, code, organization_id, image_url,'custom' from ${base_service_table_project};

insert into ${base_service}.${base_service_table_app_service}(id, name, code, is_active, app_id, type,img_url) 
select id, name, code, is_active, app_id, type, img_url from ${devops_service}.${devops_service_table_das};

insert into ${base_service}.${base_service_table_app_version}(name, status, start_date, release_date, application_id,description)  
select name, status_code, start_date, release_date, project_id as application_id, description from ${agile_service}.${agile_service_table_apv};
EOF

这里再思考一个问题,修复数据是在什么时候

一般来说是用户部署我们的服务的时候,就需要对数据库进行迁移修复,那如果用户进行多次部署呢?这里mysql的话使用存储过程实现校验数据是否已经迁移修复了,如果已经迁移过就不需要再进行修复了。

如果要修复的数据在不同服务器上,那么:

我们需要将agile_service,devops_service的数据先导出,插入表与数据到base_service,然后使用sql对数据进行修复,再删除掉导入进来的旧表就好了。

# 第二种方案 - 各个微服务的数据在不同服务器上

# 同步devops_app_service数据到base_service
# 导出旧表数据及结构到需要被迁移的数据库表中
mysqldump -u$DevopsDBUSER -p$DevopsDBPASS -h $DevopsDBHOST -P$DevopsDBPORT \
${devops_service} ${devops_service_table_das} \
| mysql -u$BaseDBUSER -p$BaseDBPASS -h $BaseDBHOST -P$BaseDBPORT ${base_service}

# 同步agile_app_service数据到base_service
# 导出旧表数据及结构到需要被迁移的数据库表中
mysqldump -u$AgileDBUSER -p$AgileDBPASS -h $AgileDBHOST -P$AgileDBPORT \
${agile_service} ${agile_service_table_apv} \
| mysql -u$BaseDBUSER -p$BaseDBPASS -h $BaseDBHOST -P$BaseDBPORT ${base_service}

# 迁移数据到新表并删除旧表
mysql -u$BaseDBUSER -p$BaseDBPASS -h $BaseDBHOST -P$BaseDBPORT << EOF
use ${base_service};
drop procedure if exists sync_data;
delimiter //
create procedure sync_data()
begin
declare syncProNum int;
declare syncAppServiceNum int;
declare syncAppVersionNum int;

select count(id) into syncProNum from ${base_service_table_project} where APPLICATION_ID is NULL;
if (syncProNum != 0) then
update ${base_service_table_project} set application_id = id;
insert into ${base_service_table_app}(id, name, code, organization_id, image_url,type) select id, name, code, organization_id, image_url,'custom' from ${base_service_table_project};
end if;

select count(id) into syncAppServiceNum from ${base_service_table_app_service};
if (syncAppServiceNum = 0) then
insert into ${base_service_table_app_service}(id, name, code, is_active, app_id, type,img_url) select id, name, code, is_active, app_id, type, img_url from ${devops_service_table_das};
end if;

select count(id) into syncAppVersionNum from ${base_service_table_app_version};
if (syncAppVersionNum = 0) then
insert into ${base_service_table_app_version}(id, name, status_code, start_date, release_date, application_id,description)  select version_id as id,name, status_code, start_date, release_date, project_id as application_id, description from ${agile_service_table_apv};
end if;

end//
delimiter ;

SET @@autocommit=0;
call sync_data;
SET @@autocommit=1;
drop table ${devops_service_table_das};
drop table ${agile_service_table_apv};
drop procedure if exists sync_data;
EOF

Oracle - 使用agile与base两个微服务:

需要被同步的微服务数据库 - 新表存在的服务:base_service
需要同步数据的 - 旧表存在的服务:agile_service

同一台服务器数据迁移修复和mysql相同,使用Oracle命令连接上服务器数据库就行了
多台服务器数据迁移修 - 使用dblink
sqlplus $BaseDBUSER/$BaseDBPASS@//$BaseDBHOST:$BaseDBPORT/sid << EOF
create public database link agile_service_link
connect to system identified by password
using 'agile_service';
begin
insert into ${base_service_table_app_version}(id, name, code, organization_id, image_url,type)  
select id, name, code, organization_id, image_url,'custom' from ${agile_service_table_apv}@agile_service_link;
commit;
exception
when others
then
dbms_output.put_line('Exception happened,data was rollback');
rollback;
end;
EOF
上一篇 下一篇

猜你喜欢

热点阅读