其他分享
首页 > 其他分享> > RDS一键同步到新实例

RDS一键同步到新实例

作者:互联网

一.前情提要

因需求要将生产环境多台RDS给克隆到DEV环境,因为环境在调试,在生产变动时可能要重新同步一遍,这个调试周期要一个多月,期间主要是环境的部署配置。

阿里云RDS同区域同步使用DTS操作将很方便,配置DTS的迁移按照教程就能免费又快捷的迁移了。

但当RDS很多,又要不定时去迁移一下(同步要钱),就需要通过阿里云开放的api来进行批量操作了。

需要使用python3,安装阿里云核心库和rds库
pip3 install aliyun-python-sdk-core
pip3 install aliyun-python-sdk-rds
file

注意:
1.需要填写同步的信息,当完成前几个,后面一个失败,需要注释掉成功的实例信息
2.需要加上阿里云ak和sk
3.脚本会清空同步实例的库,不然也没法同步

二.脚本

#!/bin/python3
 
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
import ast, sys, pymysql, time, json
 
#填写信息主库和从库
#实例名,实例ID,要迁移的库,账号名,密码
rds_info = [
    [("生产会员", "rm-2zeasdasdsasd", "prod_userdb", "dtscp", "123456"),("dev会员", "rm-2asdsadd", "dev_userdb", "dtscp", "123456")],
    [("生产支付", "rm-2zfasda", "prod_paydb", "dtscp", "1233456"),("dev支付", "rm-2asdasdasd", "dev_paydb", "dtscp", "123456")],
    ]


#自动变量
dts_id = ""
dts_list = []

#资源信息
aliyun_user_ak = 'Lwewwewew'
aliyun_user_sk = 'AEwqewqrwqeq'
region_id = 'cn-beijing'
client = AcsClient(ak=aliyun_user_ak, secret=aliyun_user_sk, region_id=region_id, timeout=300)


#创建DTS
def Create_Dts(req):
    global dts_id
    global dts_list
    req.set_action_name('CreateMigrationJob')
    req.add_query_param('RegionId', "cn-hangzhou")
    req.add_query_param('Region', "cn-beijing")
    req.add_query_param('MigrationJobClass', "large")
    req.add_query_param('ClientToken', "fj2j3kk2jasjd")
 
    response = client.do_action(req)
    false = False
    true = True
    response_dict = eval(response)
    dts_id = response_dict['MigrationJobId']
    dts_list.append(dts_id)
 
    if response_dict['Success'] == True:
        print("创建任务成功,ID为: " + dts_id)
    else:
        print("创建任务失败")
        sys.exit()
 
#验证是否是空的库,0为空,1为不空
def Check_Table(cur):
    sql = "show tables;"
    cur.execute(sql)
    table_number = cur.fetchall()
    if table_number:
        return 1
    else:
        return 0
 
def Create_Link(rds_list):
    #部分拼接
    rds_dest_ip = rds_list[1][1] + ".mysql.rds.aliyuncs.com" #目标实例IP
 
    db = pymysql.connect(host=rds_dest_ip, port=3306, user=rds_list[1][3], passwd=rds_list[1][4], db=rds_list[1][2], charset='utf8')
    cursor = db.cursor() #使用cursor方法创建一个游标
 
    print("开始清理数据库" + rds_list[1][2])
    if Check_Table(cursor) == 0:
        print(rds_list[1][2] + "库已经是空的,跳过清理步骤")
        cursor.close()
        db.close()
    else:
        #这里输出drop开头的删除表命令,存到元组里
        sql = "show tables ;"
        cursor.execute(sql)
        table_bin = cursor.fetchall()
        cursor.execute('SET foreign_key_checks = 0;')
 
        #循环执行drop删除表命令
        for i in table_bin:
            sql = "drop table" + '`' + i[0] + '`'
            cursor.execute(sql)
        cursor.execute('SET foreign_key_checks = 1;')
 
        #检测是否清空了
        if Check_Table(cursor) == 1:
            print(rds_list[1][2] + "库清空失败")
        else:
            print(rds_list[1][2] + "清空成功")
 
        #提交操作并关闭链接
        db.commit()
        cursor.close()
        db.close()
 
def Conf_Dts(req,rds_list):
    #部分拼接
    rds_job_name = rds_list[0][0] + "-》" + rds_list[1][0] #rds实例名
    rds_sour_ip = rds_list[0][1] + ".mysql.rds.aliyuncs.com" #源实例IP
    rds_dest_ip = rds_list[1][1] + ".mysql.rds.aliyuncs.com" #目标实例IP
    rds_sour_dbname = '\"%s\"' %(rds_list[0][2])
    rds_dest_dbname = '\"%s\"' %(rds_list[1][2])
    global dts_id
    print("开始进行" + rds_job_name + "的DTS任务配置")
 
    req.set_action_name('ConfigureMigrationJob')
    req.add_query_param('RegionId', "cn-hangzhou")
    req.add_query_param('MigrationJobName', rds_job_name)
    req.add_query_param('SourceEndpoint.InstanceType', "RDS")
    req.add_query_param('DestinationEndpoint.InstanceType', "RDS")
    req.add_query_param('MigrationMode.StructureIntialization', "true")
    req.add_query_param('MigrationMode.DataIntialization', "true")
    req.add_query_param('MigrationMode.DataSynchronization', "false")
    req.add_query_param('MigrationObject', "[{     \"DBName\": %s,     \"NewDBName\": %s }]" %(rds_sour_dbname, rds_dest_dbname))
    req.add_query_param('MigrationJobId', dts_id)
    req.add_query_param('SourceEndpoint.InstanceID', rds_list[0][1])
    req.add_query_param('SourceEndpoint.EngineName', "Mysql")
    req.add_query_param('SourceEndpoint.Region', "cn-beijing")
    req.add_query_param('SourceEndpoint.IP', rds_sour_ip)
    req.add_query_param('SourceEndpoint.Port', "3306")
    req.add_query_param('SourceEndpoint.UserName', rds_list[0][3])
    req.add_query_param('SourceEndpoint.Password', rds_list[0][4])
    req.add_query_param('DestinationEndpoint.InstanceID', rds_list[1][1])
    req.add_query_param('DestinationEndpoint.EngineName', "Mysql")
    req.add_query_param('DestinationEndpoint.Region', "cn-beijing")
    req.add_query_param('DestinationEndpoint.IP', rds_dest_ip)
    req.add_query_param('DestinationEndpoint.Port', "3306")
    req.add_query_param('DestinationEndpoint.UserName', rds_list[1][3])
    req.add_query_param('DestinationEndpoint.Password', rds_list[1][4])
 
    response = client.do_action(req)
    print(str(response, encoding = 'utf-8'))
 
def Check_Dts(req, dts_name):
    req.set_action_name('DescribeMigrationJobStatus')
    req.add_query_param('RegionId', "cn-hangzhou")
    req.add_query_param('MigrationJobId', dts_name)
    response = client.do_action(request)
    res_dict = json.loads(response)
 
    dts_stat = {'NotStarted':'未启动',
        'Prechecking':'预检查中',
        'PrecheckFailed':'预检查失败',
        'Migrating':'迁移中',
        'Suspending':'暂停中',
        'MigrationFailed':'迁移失败',
        'Finished':'完成'}
 
    print(dts_name + "当前状态:" + dts_stat[res_dict['MigrationJobStatus']])

#开始执行
for rds_list in rds_info:
    #初始化
    request = CommonRequest()
    request.set_accept_format('json')
    request.set_domain('dts.aliyuncs.com')
    request.set_method('POST')
    request.set_protocol_type('https') # https | http
    request.set_version('2020-01-01')

    Create_Dts(request) #创建dts任务
    Create_Link(rds_list) #清理数据库
    Conf_Dts(request, rds_list) #配置DTS信息
    print("")

#循环显示状态
while True:
    for i in dts_list:
        Check_Dts(request, i)

    print("")
    time.sleep(30)

标签:RDS,rds,list,req,一键,param,add,实例,query
来源: https://www.cnblogs.com/rxysg/p/15696673.html