精华内容
下载资源
问答
  • 数据库历史回顾和趋势:云化,融合是方向 数据库技术是信息技术领域的核心技术之一,几乎所有的信息系统都需要使用数据库系统来组织、存储、操纵和管理业务数据。数据库领域也是现代计算机学科的重要分支和研究方向...

    一、数据库历史回顾和趋势:云化,融合是方向

    数据库技术是信息技术领域的核心技术之一,几乎所有的信息系统都需要使用数据库系统来组织、存储、操纵和管理业务数据。数据库领域也是现代计算机学科的重要分支和研究方向。数据库技术于60年代诞生,70年代兴起关系型数据库和SQL语言,80年代发展SQL事实标准化,也是I&O的黄金岁月。90年代转型使得互联网数据爆发,2000年代新玩家 4V • NoSQL流行,当前Scale-Out也成为主流,相信将来会有更多的创新和发展。

    基于华为累积多年的数据库研发、搭建和维护经验,结合数据库云化改造技术,大幅优化传统数据库,为您打造更高可用、更高可靠、更高安全、更高性能、即开即用、便捷运维、弹性伸缩的数据库服务,拥有容灾、备份、恢复、安防、监控、迁移等全面的解决方案。

    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055

     不同类型的数据库基于不同的理论基础,满足不同的数据管理、处理需求

    不同类型的数据库基于不同的理论基础,满足不同的数据管理、处理需求
      关系型数据库 Oracle/MySQL

    键值数据库

    Redis

    宽列数据库 Cassandra 文档数据库 MongoDB

    图数据库

    Neo4J

    ML数据解决方案

    Spark/Tensorflow

    数据湖解决方案

    融合数据分析

    应用场景 事务处理 储存用户信息等 日志等
    Web应用等
    图分析、搜索
    数据分析、特征抽取
    全场景
    数据模型 关系表 K-V键值对 以列簇式存储
    KV键值对,V结构化
    图模型
    稀疏矩阵
    关联数组
    数学基础 关系代数,集合论 hash table
    KV二维数组
    嵌套KV
    图论
    线性代数
    关联代数

    二、当前主流的关系型数据库系统架构对比

      单元 Shared-Disk Shared-Virtual-Disk (分布式架构) Shared-Nothing (分布式架构)
    代表 PG、MySQL RAC/pureScale Aurora/PolarDB/Taurus Spanner/OceanBase/GaussDB
    特点

    1、单机主备架构

    2、扩展能力不足

    1、多写、多读

    2、Scale-up性能较高;

    3、Scale-out扩展性不足

    1、一写、多读;计算、存储分离;多副本读提 升性能,写性能受单Primary节点限制 。

    2、支持paxos/raft多AZ高可用

    1、sharding多写、多读;读写性能均可Scale-out, 不受限于单节点处理能力。

    2、支持paxos/raft多AZ高可用

     

    国产自研(达梦、金仓、南 大、神舟)的关系型数据库 都为单机架构

     

    三、华为云数据库服务全景概况

    SQL数据库:面向传统 OLTP 数据库业务

    NoSQL数据库 :面向海量扩展业务

    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055

    1、数据库RDS 服务的架构和关键功能

    关键功能特性及说明

    • SLA:99.95%,服务中断时间不超过5分钟/月,1小时/年
    • 安全:多种安全策略保护数据库和用户隐私,例如:VPC、子网、安全组、 SSL;搭配数据库安全服务DBSS提供事前、中、后安全防护,数据脱敏及审 计服务。
    • 数据迁移:提供从自建库或者其它云离线和在线迁移能力
    • 高可用:主备双机热备,一旦主数据库实例发生故障导致不可用,即可在很 短时间内切换到备用数据库实例上
    • 监控:实时监控数据库实例及引擎的关键性能指标,包括计算/内存/存储容量 使用率、I/O 活动、数据库连接数、QPS/TPS、缓冲池、读/写活动等
    • 弹性伸缩: 水平伸缩:增删只读实例(Proxy 读写分离即将上线),搭配 DDM 实现分库分表 水平扩容,垂直伸缩:CPU/内存变更、存储在线分钟级扩容
    • 备份与恢复: 备份:支持自动备份(长达732天)、手动数据备份
    • 恢复:支持PITR恢复,表级对象恢复
    • 日志管理:查询数据库错误日志和慢 SQL 日志及 binlog 日志下载
    • 参数配置:管理页面在线修改生效配置参数和参数组配置管理功能
    • 云DBA 智能运维:赋予用户对实例进行全面分析的能力,一键诊断问题 SQL ,实时诊断分析 RDS 的运行状态及提交诊断报告;应急救护快速解决故 障。
    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055

     2、云数据库 MySQL 功能特性

    GTID 约束放开

    • 支持 create table…select…
    • 支持显示事务 create temporary table…
    • 5.5 到 5.6 平滑迁移

    线程池(thread pool)

    • 基于 CPU 规格,创建有限的线程,作为常驻线程池 组 ,减少线程切换和内存消耗
    • Connection 按优先级调度,尽可能让一个事务快速 结束,而不是让众多的事务同时展开,缓慢执行

    多线程复制(MTS)

    • 在5.6中引入 MTS,基于逻辑时钟多线程复 制,降低复制延迟,减少 RTO。

    MyISAM 透明转换

    • 透明转换成 InnoDB,解决 MyISAM 中的问题
    • 无需应用改造
    • 提供自由开关

    权限控制

    • 限制 reset master; reset slave;
    • 限制 SET PASSWORD 修改内置账号
    • 限制 kill 内部线程
    • 限制 drop, alter, update 系统库表

    备份锁

    • 内核支持 backup lock 锁
    • 提供 have_backup_locks 参数
    • 长事务不会阻塞备份

    性能相关

    • SQL aggregate 下推
    • double-write buffers 并行化
    • 增强 adaptive data page flushing 算法
    • page cleaners 并行化增强

    运维相关

    • root 账号 kill 其他账号的线程
    • 查看单个线程的 CPU、内存占用情况
    • 查看表、索引的统计信息  
    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055

    3、云数据库 PostgreSQL 介绍

    • 多样化的数据类型

    不仅支持常见的字符、数字类型,还 包括数组、空间数据类型,网络数据 类型等,另外支持自定义数据类型 

    • 编程接口和语言

    ODBC / JDBC / Libpq PL / Perl、plPHP、PL/Python、PL/Ruby、 PL/Tcl 等

    • 高安全性

    字段加密 基于 DB / Schema / 表/列的权限控制

    • NoSQL 兼容

    基于 SQL 支持 JSON、XML 等非结 构化数据类型

    • 强大的并发控制

    4种标准的事务隔离等级 B-tree/GiST/GIN/SP-GiST 索引 表级锁/行级锁/建议锁

    • 使用 PG 数据库的企业

    平安科技 / 去哪儿 / Instagram / 金山 / 百度

    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055
    • 云数据库 PostgreSQL 增强版
    1. 高度兼容 Oracle语法:高度兼容 Oracle、超低数据库及业务改造成本,数据类型、内置函数、全面 SQL 语法、存储过 程、匿名块、高级包、系统视图、完整支持分区 表、存储过程事务管理、表空间等 200+项。
    2. 成本低:超高性价比,无需 License 费用成本节约 70%+
    3. 安全合规:国产化安全认证加密算法增强( SHA-256)、插件权限优化、用 户组权限管理规则优化
    4. 易用性提升:一键式 Oracle 模式切 换、数据订阅、动态修 改端口
    5. 更强性能:并行查询提速、支持基于 LLVM 的 JIT 编译加速
    6. 可靠性增强:按时间点恢复、高智能 HA、数据迁移数据校验

    4、企业级高扩展海量存储分布式数据库: Taurus 

    计算存储分离、云化架构的企业级云数据库

    基于V6CPU+Optane DC SSD+RDMA网络行业领先硬件组合
    • Taurus 数据库核心优势

    超高性能 :写300 KQPS 、读1000 KQPS

    高扩展性:15只读副 本,100T 存储

    高可靠性:跨AZ部 署,数据 三副本, 99.99%可 用性

    高兼容性:MySQL 兼容,结 合 DRS 从MySQL 在线迁移

    超低成本:1/10的 RDS MySQL 成本

    • 应用场景

    金融、娱乐:高吞吐量、大数 据量处理

    手游、电商:高可用、弹性 伸缩能力

    电信、互联网:高可靠、异地 容灾

    • 客户价值

    100T 存储、免分库分表,解决海量数据问题

    完全兼容 MySQL,无需应用改造

    15个只读副本,读写分离,解决性能扩展问题

    跨AZ部署,异地容灾,解决高可靠性问题

    标题

    5、高斯数据库-分布式企业级数据库

    • 高性能

    OLTP:单机百万TPMC,性能超越业界标杆对标产品 30%,超越开源mysql数据库5-8倍;

    OLAP:全并行架构及列存向量化引擎,实现万亿数据 关联分析秒级响应。

    • 高扩展

    OLTP:分布式线性扩展能力,TPC-C(10%分布式事 务)扩展比大于0.8;

    OLAP:开放架构,按需水平扩展,可扩展到2048节点;

    • 易使用

    易开发:兼容标准ANSI SQL2003,业务开发简单;

    易迁移:自研数据库迁移工具,支持核心数据库平滑迁 移;

    易使用:数据库一体机软硬结合,深度调优,开箱即用;

    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055

    6、文档数据库DDS服务:存储计算分离的文档数据库服务

    • 架构演进
    标题
    •  架构优势
    标题
    • 文档数据库DDS服务:优势场景
      游戏 物联网/车联网 互联网
    文档数据库应用 存储游用户信息,装备、积分等直接以内 嵌文档形式存储。方便查询、更新; 用于存储所有接入的智能设备信息,以及 设备汇报的日志信息; 存储电商平台的订单信息,订单状态可以 随派送过程不断更新;
    关键竞标项/ 行业刚需
    • 快速回档能力:补救快速迭代带来的线上 问题。要求至少能回溯一周内的数据;
    • 低成本诉求:做游戏如同赌注,客户对每 款游戏的投入成本极其敏感;
    • 百 TB 存储需求:车联网行业,国家要求 存储 1-2 年的车辆数据;
    • 灾备/迁移要求:跨 region 数据容灾;云 下到云上,异构云迁移;
    • 弹性伸缩需求:微博/直播/电商/打车等 应用,有典型的业务高低谷;
    • 高并发需求:考勤打卡等业务要求高并发 能力;
    • 数据复制服务 DRS - 迁移过程业务无中断

    导航式数据迁移, 客户易操作

    标题

    公有云项目拓展关键场景--数据库迁移

    支持各种数据库来源

    • 友商云(三A云,T云)
    • 本地IDC
    • 云内ECS自建数据库
    • 云内RDS

    支持各种网路方式

    • 公网
    • VPN
    • 专线
    • 云内VPC 

     支持各种数据库

    • MySQL
    • SQL Server
    • PostgreSQL
    • MongoDB

    支持各种云形态

    • 公有云
    • 公有专属云
    • 公有全栈云

    数据自由流动

    • 入云
    • 出云

     DRS为在线迁移场景量身打造,确保业务平滑上云

    业务零中断

    • 在线迁移技术
    • 数据实时同步
    • 迁移中业务无需中断

    数据零丢失

    • 断点续传,故障重试
    • 迁移数据和索引等
    • 迁移后对象、数据对比

    低门槛

    • 引导式流程,跟着指引操作
    • 详细、友好的信息提示
    • 预检查让迁移成功有保障

    低风险

    • 预检查让问题提前识别
    • 迁移过程时间预估
    • 关键数据库参数迁移

    四、数据库迁移解决方案-为客户数据上云保驾护航

    1、背景

    • 客户业务7*24在线
    • 访问量大和数据量大,以**科技为例,单库数据量近2TB,压 力1000TPS,完成30套核心数据库在线迁移。
    • 业务流量和压力大,可能在集中的时间段出现高于日常流量 数倍的业务高峰 

    2、客户痛点

    • 数据迁移实施过程中业务不能中断;
    • 割接时数据不能出问题;

    3、解决方案

    • 迁移业务场景调研,数据库信息收集;
    • 评估数据在线迁移方案、测试验证和方案确定;
    • 迁移实施、数据校验和割接;

    4、数据库迁移流程

    标题

     

    5、数据迁移方案和基线 

    结合客户项目经验, 形成评估模型和算法,指导评估迁移项目

    表数据量总和 最大表数据量 索引数据量总和 导出时长 导入时长 索引创建时长

    增量迁移追平时长

    数据校验时长 数据 迁移时长
    100GB 2093MB 6500MB 18min 39min 22min 13min 96min 92min
    500GB 2143MB 32500MB 91min 248min 131min 83min 4070min 553min
    1TB 2143MB 65000MB 183min 493min 247min 195min 65min 1144min

    五、华为云数据库行业解决方案

    1、金融行业:金融版+容灾+数据库安全防护能力

    客户痛点

    • 业务需要使用金融专属区,实现资源隔离
    • 需要实现异地灾备,保障可用性,满足监管要求
    • 需要满足数据存储高可用一致性,保证数据0丢失
    • 海量影像、文件等非结构化数据存储需求,需要轻松实现弹性扩展
    • 对数据安全性要求极高,需要随时保障数据资产安全。

    华为云数据库的解决方案

    • 北上深打造金融专区,满足两地三中心架构
    • 提供跨region数据安全灾备,满足金融合规监管要求
    • MySQL金融版采用Paxos协议实现数据强一致性,保证数据0丢失
    • DDS增强版存储计算分离,可轻松实现海量存储,可提供秒级弹性扩容
    • DBSS提供数据脱敏、数据库审计、防拖库和防注入功能,保障云上数据库安全
    • 上线Proxy中间件,实现弹性读写分离
    • 上线分布式数据库Taurus,满足企业分布式高性能需求
    • DRS提供异构数据迁移能力,方便企业快速上云

    典型构架

    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055

    2、汽车行业:业务复杂,数据种类多样,多数据库协同 

    行业背景和业务特征

    • 高吞吐高并发:数据采集维度多,采集走起短。车辆轨迹、状态等数据需要实时 上报,数据量的增长与汽车数量成指数式增长。
    • 业务流量变化大:数据并发写入量和车辆的在线数量紧密相关,
    • 数据种类杂:车联网需求复杂,所产生的数据种类也比较多,无一种数据库能满 足所有需求,需要多种数据库协同配合,如何使用好数据库将是业务成败关键。 

    客户痛点

    • 数据类型多样,需要自己维护多种数据库系统,维护成本高;
    • 传统数据库部署存在安全隐患,数据泄露或被窜改风险极大;
    • 车联网数据增量快,写入并发高,扩容成本与实施难度巨大。以北汽100W 辆车为例,每日新增数据2.8TB,半年数据存量0.5PB;
    • 故障数据结构不固定,写入并发大,业务查询场景复杂;

    华为云数据库的解决方案

    • DBSS+DDM+RDS——业务场景:用户数据、车辆数据,配置数据等关系型数据。 竞争力:企业级数据库安全服务DBSS,提供关键数据审计和防SQL注入。 DDM+RDS架构动态弹性业务能
    • 增强版DDS MongoDB——业务场景:LBS地理位置数据,日志数据、车辆故障告警等非结构化数据。 竞争力:DDS增强版本Mongo在和友商PK测试中表现优异,性能数倍于友商。
    • 时序数据库-规划中——业务场景:轨迹数据、电池数据,监控数据等需要车载设备上报的数据。

     典型构架:

    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055

    3、互联网行业:分布式架构,读写分离

     行业背景

    • 并发量大和数据量大,以热门产品为例,微博、知乎、头条、抖音等产品用户 数上亿,秒拍和映客在巅峰时期也曾达到上亿,XX科技业务并发连接数上万, 访问流量1GB/s以上,单库数据量近2TB,高规格数据库实例数上百
    • 业务流量变化大,可能在集中的时间段出现高于日常流量数倍的业务高峰,典 型场景包括:明星热点、火爆头条、开服、秒杀、双11

    客户痛点

    • 请求量大和数据量大,单机部署的数据库事务处理能力无法满足要求
    • 无法预测用户流量以及产生的数据量,业务高峰时客户体验会受到影响,甚至 要停服扩容,对资源弹性扩展能力要求高
    • DBA人力短缺,需要管理、维护数百个数据库实例

    解决方案

    • 对于中型互联网客户业务,通过在数据库层开启读写分离的Proxy机制,动态 添加只读实例,并搭配DCS缓存服务,分担数据库访问压力,满足数据库资源 处理能力弹性扩展的要求
    • 对于大型互联网客户业务, 通过采用DDM分布式数据库中间件,水平弹性扩 展,分散数据库单点访问压力,满足客户大数据量和高并发访问的要求;过 CloudDBA进行数据库性能诊断、异常跟踪、SQL自动审核,并提供索引推荐和 数据库优化建议,将数据库管理和运维操作简单化。 

    典型部署构架

    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055

     

     中型互联网数据库解决方案

    • 小规模(<500QPS或100TPS,读用户<100,写用户<10):在单库中通过读写 分离Proxy提升并发读的性能
    • 中规格(<5000QPS或1000TPS, 读用户<5000,写用户<100):垂直分库,将 不同的业务分布到不同的数据库
    • 搭配DCS缓存服务,分担数据库访问压力
    标题

    大型互联网数据库解决方案

    • 大规模以上(10K+QPS,10K+TPS 读用户10K+,写用户1K+):数据分片,将数 据表分到不同的数据库中
    • DDM协议兼容MySQL,水平弹性扩展,分散数据库单点访问压力 3. 方便的弹性和规格扩容,轻松应对业务规模扩大
    标题

    规划解决方案

    • 提供Scale-Out、分布式、多租户,共享存储的关系型数据库架构
    • 可靠性超越PolarDB,持平Aurora:跨AZ部署,99.99%可用性
    • 扩展性超越Aurora,持平PolarDB:15只读副本,100T存储

    Proxy和DDM适用性评估

    适用维度 Proxy DDM
    数据同步实时性要求
    查询复杂度适用性
    读写比例侧重点 读占比高于80% 写占比高于30%
    数据总量和增量 2TB以内 大于2TB
    事务一致性

    4、游戏行业:业务弹性扩展,同时关注DDS服务机会点

    客户痛点(私有云部署)

    • 资源的弹性伸缩,需要停服手工操作,不但需要停服,而 且风险极高。
    • 没有数据库的故障自动切换机制或能力不足,主实例故障, 修改应用配置,停服时间长。
    • 很少设置专职DBA岗位,遇见数据库回档场景,很难满足 运营的诉求。

    游戏行业华为云数据库的解决方案

    • 高性能 RDS MySQL性能超越阿里云;DDS增强版性能是友商的3倍以上。
    • 弹性伸缩 RDS和DDS支持磁盘的弹性扩容,对业务无影响。
    • 一键回档 (游戏业务数据诉求) RDS支持表级和实例别任意时间点的回档。
    • 快读开服 RDS和DDS,可使用快照备份创建新实例,实现快速开服。
    • 故障切换 RDS主备故障秒级别切换,对业务透明,应用配置无需改动。 

    典型游戏架构

    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055

     

    游戏行业业务和数据特点

    • 用户信息和交易数据存储在MySQL中。
    • 角色装备数据及游戏的过程日志存储在DDS中。
    • 游戏业务变化频繁,对于数据表需要做结果变更。DDS修改表结构对业务无影响。  

    六、 华为云数据库业务最佳实践

    华为云数据库服务解决方案、云南企业上云数据库迁移服务 云南天成科技 吴经理:13698746778 QQ:463592055
    展开全文
  • 三种常见的数据库备份、备份策略的制定、查找备份链、数据库的三种恢复模式与备份之间的关系、利用文件组实现冷热数据隔离备份方案、如何监控备份还原进度、阿里云RDS SQL自动化迁移上云的一种解决方案以及上个月...

    摘要: 摘要 到目前,我们完成了SQL Server备份还原专题系列八篇月报分享:三种常见的数据库备份、备份策略的制定、查找备份链、数据库的三种恢复模式与备份之间的关系、利用文件组实现冷热数据隔离备份方案、如何监控备份还原进度、阿里云RDS SQL自动化迁移上云的一种解决方案以及上个月分享的RDS SDK实现数据库迁移上阿里云,本期我们分享如何将用户线下或者ECS上自建实例级别数据库一键迁移上阿里云RDS SQL Server。

    摘要

    到目前,我们完成了SQL Server备份还原专题系列八篇月报分享:三种常见的数据库备份、备份策略的制定、查找备份链、数据库的三种恢复模式与备份之间的关系、利用文件组实现冷热数据隔离备份方案、如何监控备份还原进度、阿里云RDS SQL自动化迁移上云的一种解决方案以及上个月分享的RDS SDK实现数据库迁移上阿里云,本期我们分享如何将用户线下或者ECS上自建实例级别数据库一键迁移上阿里云RDS SQL Server。

    适用场景

    在我们上一个月分享的RDS SDK实现数据库迁移上阿里云RDS SQL Server方案中,我们实现了如何将用户线下或者ECS上自建的SQL Server实例中的一个用户数据库自动化迁移上云到RDS SQL Server,话句话说,它实现的是数据库级别的迁移上云方案,即每次迁移上云用户线下一个数据库。

    但是,有的用户可能会遇到这样的场景,我的线下有几十上百SQL Server实例,每个实例又有几十上百个数据库,总共就有成千上万个数据库迁移上云。如果是数据库级别的迁移上云方案显得力不从心,效率低下。为了解决用户大批量数据库迁移上云RDS for SQL Server,简化上云操作步骤,提高上云效率,实例级别数据库上云RDS SQL Server是我们迫切需要解决场景。

    实现分析

    由于在前一个月分享的RDS SDK实现数据库迁移上阿里云RDS SQL Server中,我们已经实现了单个数据库迁移上云方法,因此实现实例级别的迁移上云我们可以采用如下方案:

    将用户线下实例上所有的数据库全量备份文件上传到OSS的一个文件夹中

    遍历OSS上该文件夹所有的数据库备份文件

    每一个备份文件生成一个迁移上云任务

    输入参数

    基于以上的分析,我们的实现方法需要包含如下六个输入参数,以及这六个输入参数的解析参见下表:

    access_key_id		:   阿里云用户 access key id
    access_key_secret	:   阿里云用户access key secret
    rds_instance_id	:   RDS SQL实例ID
    oss_endpoint		:   OSS Endpoint地址
    oss_bucket 		:   OSS Bucket名
    directory		    :   用户数据库备份文件在OSS上文件夹路径,如果是根目录,请传入“/”
    

    具体实现

    准备工作

    参见上一个月的月报分享MSSQL · 最佳实践 · RDS SDK实现数据库迁移上阿里云RDS SQL Server中的准备工作部分。

    代码实现

    在本文,我们使用python版RDS SDK实现数据库迁移上云RDS SQL Server,当然你也可以使用C#版、Java版等其他版本,详细的代码实现如下:

    #!/usr/bin/python
    
    # -*- coding: utf-8 -*-
    
    """***************************************************************************************
    # Script name	: RDSSQLCreateMigrateTasksBatchly.py
    # Author		: jianming.wjm@alibaba-inc.com
    # Create Date   : 2018-05-17 19:27
    # Language 		: Python 2.7.10
    # Run platform  : Mac OS X 10.12.6
    
    # Purpose		: 
    					This script is for batchly Migration user offline SQL Server databases to alibaba cloud RDS SQL Server.
    					Users' FULL backup files are located on theirselves' OSS Bucket folder already.
    					This script helps users to do migration all offline databases backed-up under the OSS Bucket folder to RDS SQL.
    					We achieve those accomplishments by call alibaba cloud RDS OPENAPI.
    
    # Limitation	:
    	RDS Edition : Support RDS edition listed below
    					'2012','2012_web','2012_std', '2012_ent', '2012_std_ha', '2012_ent_ha',
       					'2014_web','2014_std', '2014_ent', '2014_std_ha', '2014_ent_ha',
       					'2016_web','2016_std', '2016_ent', '2016_std_ha', '2016_ent_ha'
    
    # Preparation	:
    				  1. python 2.7.x installing (I'm using 2.7.10)
    				  2. pip install aliyun-python-sdk-rds
    				  3. pip install oss2
    
    # Usage 		:
    	Help 		: python RDSSQLCreateMigrateTasksBatchly.py -h
    	Example 	: 
    					python ~/Downloads/RDSSQLCreateMigrateTasksBatchly.py -k <access_key_id> -s <access_key_secret> -i <rds_instance_id> -e <oss_endpoint> -b <oss_bucket> -d <directory>
    					
    					variables description
    					access_key_id		:	alibaba cloud user access key id, fg: LTAIKeRvKPRwkaU3
    					access_key_secret	:	alibaba cloud user access key secret, fg: BbZ7xhrertQ0dfgMqfAZPByhnp4G2k
    					rds_instance_id		:   RDS SQL instance ID, fg: rm-2zesz4564ud8s7123
    					oss_endpoint		:   OSS Endpoint address, fg: oss-cn-beijing.aliyuncs.com
    					oss_bucket 			:   OSS Bucket name, fg: atp-test-on-ecs
    					directory 			:   Sub folder name under OSS Bucket, fg: Migration/OPENAPIDemo
    
    
    # Output 		: There two sesction output, one is the input variables and the other is the migration requests and response.
    *********************Input variables*************************************
    
    ************************************************************************
    
    *********************Migration requests**********************************
    
    ************************************************************************
    
    
    # Modify Author : jianming.wjm@alibaba-inc.com
    # Modify Date   : 2018-05-19 21:43
    # Function:
    #**************************************************************************************
    """
    
    import json
    import os
    import sys, getopt
    import re
    import oss2
    import time
    
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkrds.request.v20140815 import DescribeMigrateTasksForSQLServerRequest
    from aliyunsdkrds.request.v20140815 import CreateMigrateTaskRequest
    from aliyunsdkrds.request.v20140815 import DescribeDBInstanceAttributeRequest
    
    
    def main(argv):
    	access_key_id =  access_key_secret =  rds_instance_id =  oss_endpoint =  oss_bucket =  directory = ''
    
    	# usage help
    	try:
    		opts, args = getopt.getopt(argv,"hk:s:i:e:b:d:",["access_key_id=", "access_key_secret=", "rds_instance_id=", "oss_endpoint=", "oss_bucket=", "directory="])
    	except getopt.GetoptError:
    		print ('%s -k <access_key_id> -s <access_key_secret> -i <rds_instance_id> -e <oss_endpoint> -b <oss_bucket> -d <directory>' % (sys.argv[0]))
    		sys.exit(2)
    
    	for opt, arg in opts:
    		if opt == '-h':
    			print ('%s -k <access_key_id> -s <access_key_secret> -i <rds_instance_id> -e <oss_endpoint> -b <oss_bucket> -d <directory>' % (sys.argv[0]))
    			sys.exit()
    		elif opt in ("-k", "-K", "--access_key_id"):
    			access_key_id = arg
    		elif opt in ("-s", "-S", "--access_key_secret"):
    			access_key_secret = arg
    		elif opt in ("-i", "-I", "--rds_instance_id"):
    			rds_instance_id = arg
    		elif opt in ("-e", "-E", "--oss_endpoint"):
    			oss_endpoint = arg
    		elif opt in ("-b", "-B", "--oss_bucket"):
    			oss_bucket = arg
    		elif opt in ("-d", "-D", "--directory"):
    			if arg.endswith("/"):
    				directory = arg
    			else:
    				directory = str("%s/" % arg)
    
    	# show the input parameters
       	print ("\n*********************Input variables*************************************\n" \
       		"access_key_id = %s\naccess_key_secret = %s\nrds_instance_id = %s\noss_endpoint = %s\noss_bucket = %s\ndirectory = %s\n" \
       		"************************************************************************"
       		% (access_key_id, access_key_secret, rds_instance_id, oss_endpoint, oss_bucket, directory))
    
    
       	# check RDS & OSS region to make sure they are located in the same region.
       	success, rds_details = rds_instnace_details(access_key_id, access_key_secret, rds_instance_id)
       	if not success:
       		print ("%s" % rds_details)
       		sys.exit()
    
       	rds_db_version, rds_engine, rds_region = rds_details["EngineVersion"], rds_details["Engine"], rds_details["RegionId"]
    
       	success, oss_details = oss_bucket_details(access_key_id, access_key_secret, oss_endpoint, oss_bucket)
       	if not success:
       		print ("%s" % oss_details)
       		sys.exit()
    
       	oss_region = oss_details.location
       	# support db version checking.
    
    
       	if rds_engine != 'SQLServer' \
       		or rds_db_version not in [	'2008r2', '2012','2012_web','2012_std', '2012_ent', '2012_std_ha', '2012_ent_ha',
       									'2014_web','2014_std', '2014_ent', '2014_std_ha', '2014_ent_ha',
       									'2016_web','2016_std', '2016_ent', '2016_std_ha', '2016_ent_ha']:
       		print("RDS engine doesn't support, this is only for RDS SQL Server engine.")
       		sys.exit()
    
       	# RDS & OSS Bucket are not under the same region.
       	if not oss_region.endswith(rds_region):
       		print("RDS & OSS Bucket are not located in the same region.")
       		sys.exit()
    
       	# RDS & OSS Bucket are in the same region.
       	print ("\n*********************Migration requests**********************************")
       	full_migrate(access_key_id, access_key_secret, rds_instance_id, oss_endpoint, oss_bucket, directory, rds_db_version)
       	print ("************************************************************************")
    
    
    def rds_instnace_details(access_key_id, access_key_secret, rds_instance_id):
    	request = DescribeDBInstanceAttributeRequest.DescribeDBInstanceAttributeRequest()
    	request.set_DBInstanceId(rds_instance_id)
    	success, response = _send_request(access_key_id, access_key_secret, request)
    
    	if success:
    		if response["Items"]["DBInstanceAttribute"]:
    			# print response["Items"]["DBInstanceAttribute"][0]["EngineVersion"]
    			# print response["Items"]["DBInstanceAttribute"][0]["RegionId"]
    			return True, response["Items"]["DBInstanceAttribute"][0]
    		else:
    			return False, "Couldn't find specify RDS [%s]." % rds_instance_id
    	
    	
    	return False, response
    
    
    def full_migrate(access_key_id, access_key_secret, rds_instance_id, oss_endpoint, oss_bucket, directory, rds_db_version):
    	"""
    	this supoort full backup files migration.
    	"""
    
    	# get all backup objects under sub_folder
    	key_parts_list, do = oss_list_objects(access_key_id, access_key_secret, oss_endpoint, oss_bucket, directory), 0
    
    	# foreach object
    	for key_parts in key_parts_list:
    		print ("\n--%s. [%s] migrate to your RDS: [%s] and the database name will be: [%s]." % (do, key_parts.file_key, rds_instance_id, key_parts.db_name))
    		do += 1
    
    		# print ("%s" % key_parts.sign_url)
    
    		request = CreateMigrateTaskRequest.CreateMigrateTaskRequest()
    		request.set_DBInstanceId(rds_instance_id)
    		request.set_DBName(key_parts.db_name)
    		request.set_BackupMode("FULL")
    		request.set_IsOnlineDB(True)
    		if rds_db_version == '2008r2':
    			request.set_DBName(key_parts.db_name.lower())
    			request.set_OSSUrls(key_parts.sign_url)
    		else:
    			request.set_OSSUrls("")
    			request.set_OssObjectPositions("%s:%s:%s" % (oss_endpoint, oss_bucket, key_parts.file_key)) # OSSEndpoint:OSSBucket:OSSFileKey
    			request.set_CheckDBMode("SyncExecuteDBCheck")
    
    		success, response = _send_request(access_key_id, access_key_secret, request)
    
    		if success:
    			print response
    
    			print ("--I'm sleeping for 2 seconds....")
    			time.sleep(2)
    		else:
    			print ("OPENAPI Response Error !!!!! : %s" % response)
    
    """
    send request to OPENAPI
    and get the response details
    """
    def _send_request(access_key_id, access_key_secret, request, region='cn-hangzhou'):
        request.set_accept_format('json')
        try:
        	# clt = AcsClient(access_key_id, access_key_secret, 'cn-hangzhou')
        	clt = AcsClient(access_key_id, access_key_secret, region)
            response_str = clt.do_action_with_exception(request)
            response_detail = json.loads(response_str)
            return True, response_detail
        except Exception as e:
            return False, e
    
    
    class oss_key_parts(object):
        """
        if the whole object file key looks like blow:
        Migration/OPENAPIDemo/TestMigration_FULL_20180518153544.bak
    	
    	then
    
    	: param str file_key: OSS object file key.
    	: param str sub_folder: OSS sub folder name, such as Migration/OPENAPIDemo
    	: param str file_name: OSS object file name, such as TestMigration_FULL_20180518153544.bak
        : param str db_name: database name, such as 'TestMigration'
        : param str bak_type: backup type , such as 'FULL'
        : param str date: backup date time, such as '20180518153544'
        : param str ext: backup file extendsion, such as 'bak'
    
        """
        def __init__(self):
        	self.file_key = ''
        	self.sub_folder = ''
        	self.file_name = ''
            self.db_name = ''
            self.bak_type = ''
            self.date = ''
            self.ext = ''
            self.sign_url = ''
    
    """
    parse the OSS file key string into oss key parts
    and return oss_key_parts object.
    """
    def oss_key_parse(file_key):
    
        key_parts = oss_key_parts()
        try:
            if file_key.find('/') >= 0:
                file_key_parts = file_key.rsplit('/', 1)
            else:
                file_key_parts = file_key
                file_key_parts = ['/', file_key]
    
            key_parts.file_key = file_key
            key_parts.sub_folder = file_key_parts[0]
            key_parts.file_name = file_key_parts[1]
    
            key_list = file_key_parts[1].rsplit('_', 2)
    
            key_parts.db_name, \
            key_parts.bak_type, \
            key_parts.date, \
            key_parts.ext = key_list[0], \
                            key_list[1], \
                            key_list[2].rsplit('.', 1)[0], \
                            key_list[2].rsplit('.', 1)[1]
        except Exception, e:
            pass
    
        return key_parts
    
    def oss_list_objects(access_key_id, access_key_secret, oss_endpoint, oss_bucket, directory):
    	"""
    	list all OSS objects under the specified sub folder
    	and return the objects list.
    	"""
    	bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), oss_endpoint, oss_bucket)
    	key_parts_list = []
    
    	# OSS Bucket Root
    	if directory == '/':
    		for object_info in oss2.ObjectIterator(bucket, delimiter='/'):
    			if not object_info.is_prefix():
    				key_part = oss_key_parse(object_info.key)
    
    				# get object sign_url
    				key_part.sign_url = bucket.sign_url('GET', object_info.key, 24 * 3600)
    
    				if key_part.ext in['bak', 'trn', 'log', 'diff']:
    					key_parts_list.append(key_part)
    				else:
    					print ("Warning!!!!!, [%s] is not backup file, filtered." % (key_part.file_key))
    	else:
    		for i, object_info in enumerate(oss2.ObjectIterator(bucket, prefix=directory)):
    			# have to the backup files, not folder
    			if not object_info.is_prefix():
    				if object_info.key.startswith(directory) and object_info.key != directory:
    					# print ("%s" % (object_info.key))
    					key_part = oss_key_parse(object_info.key)
    					
    					# get object sign_url
    					key_part.sign_url = bucket.sign_url('GET', object_info.key, 24 * 3600)
    
    					if key_part.ext in['bak', 'trn', 'log', 'diff']:
    						key_parts_list.append(key_part)
    					else:
    						print ("Warning!!!!!, [%s] is not a vaild backup file, filtered." % (key_part.file_key))
    
    	if not key_parts_list:
    		print("There is no backup file on OSS Bucket [%s] under [%s] folder, check please." % (oss_bucket, directory))
    
    	return key_parts_list
    
    
    def oss_bucket_details(access_key_id, access_key_secret, oss_endpoint, oss_bucket):
    	try:
    		bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), oss_endpoint, oss_bucket)
    		bucket_info = bucket.get_bucket_info()
    		# print ("bucket name:%s, region: %s" % (bucket_info.name, bucket_info.location))
    		return True, bucket_info
    	except Exception as e:
    		return False, e
    
    if __name__ == '__main__':
        main(sys.argv[1:])
    

    当然,以上代码,你也可以去下载以上python脚本。

    使用方法

    我们从以下三个方面简要介绍下如何使用实例级别一键迁移上云:

    查看Help

    一个例子

    输出结果

    查看Help

    你只需要使用-h来查看脚本的使用方法:

    python ~/Downloads/RDSSQLCreateMigrateTasksBatchly.py -h
    ~/Downloads/RDSSQLCreateMigrateTasksBatchly.py -k <access_key_id> -s <access_key_secret> -i <rds_instance_id> -e <oss_endpoint> -b <oss_bucket> -d <directory>
    

    一个例子

    以下是一个具体的例子:

    python ~/Downloads/RDSSQLCreateMigrateTasksBatchly.py -k LTAIQazXKPRwwErT -s BMkIUhroubQOLpOMqfA09IKlqp4G2k -i rm-2zesz5774ud8s71i5 -e oss-cn-beijing.aliyuncs.com -b atp-test-on-ecs -d Migration/OPENAPIDemo
    

    输出结果

    执行以上命令以后的结果输出,分为两个部分:

    第一部分输入参数:展示所有你的输入参数,以便查询输入错误

    第二部分提示信息:告诉你,哪一个备份文件会被迁移到哪个实例的哪一个数据库 如下的一个实例的输出信息:

    *********************Input variables*************************************
    access_key_id = LTAIQazXKPRwwErT
    access_key_secret = BMkIUhroubQOLpOMqfA09IKlqp4G2k
    rds_instance_id = rm-2zesz5774ud8s71i5
    oss_endpoint = oss-cn-beijing.aliyuncs.com
    oss_bucket = atp-test-on-ecs
    directory = Migration/OPENAPIDemo/
    ************************************************************************
    
    *********************Migration requests**********************************
    
    --0. [Migration/OPENAPIDemo/TestCollation_FULL_20180523225534.bak] migrate to your RDS: [rm-2zesz5774ud8s71i5] and the database name will be: [TestCollation].
    {u'DBInstanceId': u'rm-2zesz5774ud8s71i5', u'BackupMode': u'FULL', u'MigrateTaskId': u'106121', u'RequestId': u'67E0DD7F-7219-4F67-AAE7-B27273921303', u'TaskId': u'68244691', u'DBName': u'TestCollation'}
    --I'm sleeping for 2 seconds....
    
    --1. [Migration/OPENAPIDemo/TestMigration_FULL_20180523225534.bak] migrate to your RDS: [rm-2zesz5774ud8s71i5] and the database name will be: [TestMigration].
    {u'DBInstanceId': u'rm-2zesz5774ud8s71i5', u'BackupMode': u'FULL', u'MigrateTaskId': u'106122', u'RequestId': u'0916CD14-861B-4BF7-A68A-409E3996B0D3', u'TaskId': u'68244695', u'DBName': u'TestMigration'}
    --I'm sleeping for 2 seconds....
    
    --2. [Migration/OPENAPIDemo/testdb_FULL_20180523225534.bak] migrate to your RDS: [rm-2zesz5774ud8s71i5] and the database name will be: [testdb].
    {u'DBInstanceId': u'rm-2zesz5774ud8s71i5', u'BackupMode': u'FULL', u'MigrateTaskId': u'106123', u'RequestId': u'5835B154-2EE3-4059-BFC4-6F798CDCE546', u'TaskId': u'68244699', u'DBName': u'testdb'}
    --I'm sleeping for 2 seconds....
    ************************************************************************
    

    最后总结

    利用本篇文章,我们可以轻松实现用户线下或者ECS自建的SQL Server实例级别数据库一键迁移上云,以此来极大的提高迁移上云效率,简化操作,大大提升了用户迁移上云体验。

    原文链接

    本文为云栖社区原创内容,未经允许不得转载。

     

    展开全文
  • 三种常见的数据库备份、备份策略的制定、查找备份链、数据库的三种恢复模式与备份之间的关系、利用文件组实现冷热数据隔离备份方案、如何监控备份还原进度、阿里云RDS SQL自动化迁移上云的一种解决方案以及上个月...

    摘要

    到目前,我们完成了SQL Server备份还原专题系列八篇月报分享:三种常见的数据库备份、备份策略的制定、查找备份链、数据库的三种恢复模式与备份之间的关系、利用文件组实现冷热数据隔离备份方案、如何监控备份还原进度、阿里云RDS SQL自动化迁移上云的一种解决方案以及上个月分享的RDS SDK实现数据库迁移上阿里云,本期我们分享如何将用户线下或者ECS上自建实例级别数据库一键迁移上阿里云RDS SQL Server。

    适用场景

    在我们上一个月分享的RDS SDK实现数据库迁移上阿里云RDS SQL Server方案中,我们实现了如何将用户线下或者ECS上自建的SQL Server实例中的一个用户数据库自动化迁移上云到RDS SQL Server,话句话说,它实现的是数据库级别的迁移上云方案,即每次迁移上云用户线下一个数据库。

    但是,有的用户可能会遇到这样的场景,我的线下有几十上百SQL Server实例,每个实例又有几十上百个数据库,总共就有成千上万个数据库迁移上云。如果是数据库级别的迁移上云方案显得力不从心,效率低下。为了解决用户大批量数据库迁移上云RDS for SQL Server,简化上云操作步骤,提高上云效率,实例级别数据库上云RDS SQL Server是我们迫切需要解决场景。

    实现分析

    由于在前一个月分享的RDS SDK实现数据库迁移上阿里云RDS SQL Server中,我们已经实现了单个数据库迁移上云方法,因此实现实例级别的迁移上云我们可以采用如下方案:

    将用户线下实例上所有的数据库全量备份文件上传到OSS的一个文件夹中

    遍历OSS上该文件夹所有的数据库备份文件

    每一个备份文件生成一个迁移上云任务

    输入参数

    基于以上的分析,我们的实现方法需要包含如下六个输入参数,以及这六个输入参数的解析参见下表:

    access_key_id		:   阿里云用户 access key id
    access_key_secret	:   阿里云用户access key secret
    rds_instance_id	:   RDS SQL实例ID
    oss_endpoint		:   OSS Endpoint地址
    oss_bucket 		:   OSS Bucket名
    directory		    :   用户数据库备份文件在OSS上文件夹路径,如果是根目录,请传入“/”
    

    具体实现

    准备工作

    参见上一个月的月报分享MSSQL · 最佳实践 · RDS SDK实现数据库迁移上阿里云RDS SQL Server中的准备工作部分。

    代码实现

    在本文,我们使用python版RDS SDK实现数据库迁移上云RDS SQL Server,当然你也可以使用C#版、Java版等其他版本,详细的代码实现如下:

    #!/usr/bin/python
    
    # -*- coding: utf-8 -*-
    
    """***************************************************************************************
    # Script name	: RDSSQLCreateMigrateTasksBatchly.py
    # Author		: jianming.wjm@alibaba-inc.com
    # Create Date   : 2018-05-17 19:27
    # Language 		: Python 2.7.10
    # Run platform  : Mac OS X 10.12.6
    
    # Purpose		: 
    					This script is for batchly Migration user offline SQL Server databases to alibaba cloud RDS SQL Server.
    					Users' FULL backup files are located on theirselves' OSS Bucket folder already.
    					This script helps users to do migration all offline databases backed-up under the OSS Bucket folder to RDS SQL.
    					We achieve those accomplishments by call alibaba cloud RDS OPENAPI.
    
    # Limitation	:
    	RDS Edition : Support RDS edition listed below
    					'2012','2012_web','2012_std', '2012_ent', '2012_std_ha', '2012_ent_ha',
       					'2014_web','2014_std', '2014_ent', '2014_std_ha', '2014_ent_ha',
       					'2016_web','2016_std', '2016_ent', '2016_std_ha', '2016_ent_ha'
    
    # Preparation	:
    				  1. python 2.7.x installing (I'm using 2.7.10)
    				  2. pip install aliyun-python-sdk-rds
    				  3. pip install oss2
    
    # Usage 		:
    	Help 		: python RDSSQLCreateMigrateTasksBatchly.py -h
    	Example 	: 
    					python ~/Downloads/RDSSQLCreateMigrateTasksBatchly.py -k <access_key_id> -s <access_key_secret> -i <rds_instance_id> -e <oss_endpoint> -b <oss_bucket> -d <directory>
    					
    					variables description
    					access_key_id		:	alibaba cloud user access key id, fg: LTAIKeRvKPRwkaU3
    					access_key_secret	:	alibaba cloud user access key secret, fg: BbZ7xhrertQ0dfgMqfAZPByhnp4G2k
    					rds_instance_id		:   RDS SQL instance ID, fg: rm-2zesz4564ud8s7123
    					oss_endpoint		:   OSS Endpoint address, fg: oss-cn-beijing.aliyuncs.com
    					oss_bucket 			:   OSS Bucket name, fg: atp-test-on-ecs
    					directory 			:   Sub folder name under OSS Bucket, fg: Migration/OPENAPIDemo
    
    
    # Output 		: There two sesction output, one is the input variables and the other is the migration requests and response.
    *********************Input variables*************************************
    
    ************************************************************************
    
    *********************Migration requests**********************************
    
    ************************************************************************
    
    
    # Modify Author : jianming.wjm@alibaba-inc.com
    # Modify Date   : 2018-05-19 21:43
    # Function:
    #**************************************************************************************
    """
    
    import json
    import os
    import sys, getopt
    import re
    import oss2
    import time
    
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkrds.request.v20140815 import DescribeMigrateTasksForSQLServerRequest
    from aliyunsdkrds.request.v20140815 import CreateMigrateTaskRequest
    from aliyunsdkrds.request.v20140815 import DescribeDBInstanceAttributeRequest
    
    
    def main(argv):
    	access_key_id =  access_key_secret =  rds_instance_id =  oss_endpoint =  oss_bucket =  directory = ''
    
    	# usage help
    	try:
    		opts, args = getopt.getopt(argv,"hk:s:i:e:b:d:",["access_key_id=", "access_key_secret=", "rds_instance_id=", "oss_endpoint=", "oss_bucket=", "directory="])
    	except getopt.GetoptError:
    		print ('%s -k <access_key_id> -s <access_key_secret> -i <rds_instance_id> -e <oss_endpoint> -b <oss_bucket> -d <directory>' % (sys.argv[0]))
    		sys.exit(2)
    
    	for opt, arg in opts:
    		if opt == '-h':
    			print ('%s -k <access_key_id> -s <access_key_secret> -i <rds_instance_id> -e <oss_endpoint> -b <oss_bucket> -d <directory>' % (sys.argv[0]))
    			sys.exit()
    		elif opt in ("-k", "-K", "--access_key_id"):
    			access_key_id = arg
    		elif opt in ("-s", "-S", "--access_key_secret"):
    			access_key_secret = arg
    		elif opt in ("-i", "-I", "--rds_instance_id"):
    			rds_instance_id = arg
    		elif opt in ("-e", "-E", "--oss_endpoint"):
    			oss_endpoint = arg
    		elif opt in ("-b", "-B", "--oss_bucket"):
    			oss_bucket = arg
    		elif opt in ("-d", "-D", "--directory"):
    			if arg.endswith("/"):
    				directory = arg
    			else:
    				directory = str("%s/" % arg)
    
    	# show the input parameters
       	print ("\n*********************Input variables*************************************\n" \
       		"access_key_id = %s\naccess_key_secret = %s\nrds_instance_id = %s\noss_endpoint = %s\noss_bucket = %s\ndirectory = %s\n" \
       		"************************************************************************"
       		% (access_key_id, access_key_secret, rds_instance_id, oss_endpoint, oss_bucket, directory))
    
    
       	# check RDS & OSS region to make sure they are located in the same region.
       	success, rds_details = rds_instnace_details(access_key_id, access_key_secret, rds_instance_id)
       	if not success:
       		print ("%s" % rds_details)
       		sys.exit()
    
       	rds_db_version, rds_engine, rds_region = rds_details["EngineVersion"], rds_details["Engine"], rds_details["RegionId"]
    
       	success, oss_details = oss_bucket_details(access_key_id, access_key_secret, oss_endpoint, oss_bucket)
       	if not success:
       		print ("%s" % oss_details)
       		sys.exit()
    
       	oss_region = oss_details.location
       	# support db version checking.
    
    
       	if rds_engine != 'SQLServer' \
       		or rds_db_version not in [	'2008r2', '2012','2012_web','2012_std', '2012_ent', '2012_std_ha', '2012_ent_ha',
       									'2014_web','2014_std', '2014_ent', '2014_std_ha', '2014_ent_ha',
       									'2016_web','2016_std', '2016_ent', '2016_std_ha', '2016_ent_ha']:
       		print("RDS engine doesn't support, this is only for RDS SQL Server engine.")
       		sys.exit()
    
       	# RDS & OSS Bucket are not under the same region.
       	if not oss_region.endswith(rds_region):
       		print("RDS & OSS Bucket are not located in the same region.")
       		sys.exit()
    
       	# RDS & OSS Bucket are in the same region.
       	print ("\n*********************Migration requests**********************************")
       	full_migrate(access_key_id, access_key_secret, rds_instance_id, oss_endpoint, oss_bucket, directory, rds_db_version)
       	print ("************************************************************************")
    
    
    def rds_instnace_details(access_key_id, access_key_secret, rds_instance_id):
    	request = DescribeDBInstanceAttributeRequest.DescribeDBInstanceAttributeRequest()
    	request.set_DBInstanceId(rds_instance_id)
    	success, response = _send_request(access_key_id, access_key_secret, request)
    
    	if success:
    		if response["Items"]["DBInstanceAttribute"]:
    			# print response["Items"]["DBInstanceAttribute"][0]["EngineVersion"]
    			# print response["Items"]["DBInstanceAttribute"][0]["RegionId"]
    			return True, response["Items"]["DBInstanceAttribute"][0]
    		else:
    			return False, "Couldn't find specify RDS [%s]." % rds_instance_id
    	
    	
    	return False, response
    
    
    def full_migrate(access_key_id, access_key_secret, rds_instance_id, oss_endpoint, oss_bucket, directory, rds_db_version):
    	"""
    	this supoort full backup files migration.
    	"""
    
    	# get all backup objects under sub_folder
    	key_parts_list, do = oss_list_objects(access_key_id, access_key_secret, oss_endpoint, oss_bucket, directory), 0
    
    	# foreach object
    	for key_parts in key_parts_list:
    		print ("\n--%s. [%s] migrate to your RDS: [%s] and the database name will be: [%s]." % (do, key_parts.file_key, rds_instance_id, key_parts.db_name))
    		do += 1
    
    		# print ("%s" % key_parts.sign_url)
    
    		request = CreateMigrateTaskRequest.CreateMigrateTaskRequest()
    		request.set_DBInstanceId(rds_instance_id)
    		request.set_DBName(key_parts.db_name)
    		request.set_BackupMode("FULL")
    		request.set_IsOnlineDB(True)
    		if rds_db_version == '2008r2':
    			request.set_DBName(key_parts.db_name.lower())
    			request.set_OSSUrls(key_parts.sign_url)
    		else:
    			request.set_OSSUrls("")
    			request.set_OssObjectPositions("%s:%s:%s" % (oss_endpoint, oss_bucket, key_parts.file_key)) # OSSEndpoint:OSSBucket:OSSFileKey
    			request.set_CheckDBMode("SyncExecuteDBCheck")
    
    		success, response = _send_request(access_key_id, access_key_secret, request)
    
    		if success:
    			print response
    
    			print ("--I'm sleeping for 2 seconds....")
    			time.sleep(2)
    		else:
    			print ("OPENAPI Response Error !!!!! : %s" % response)
    
    """
    send request to OPENAPI
    and get the response details
    """
    def _send_request(access_key_id, access_key_secret, request, region='cn-hangzhou'):
        request.set_accept_format('json')
        try:
        	# clt = AcsClient(access_key_id, access_key_secret, 'cn-hangzhou')
        	clt = AcsClient(access_key_id, access_key_secret, region)
            response_str = clt.do_action_with_exception(request)
            response_detail = json.loads(response_str)
            return True, response_detail
        except Exception as e:
            return False, e
    
    
    class oss_key_parts(object):
        """
        if the whole object file key looks like blow:
        Migration/OPENAPIDemo/TestMigration_FULL_20180518153544.bak
    	
    	then
    
    	: param str file_key: OSS object file key.
    	: param str sub_folder: OSS sub folder name, such as Migration/OPENAPIDemo
    	: param str file_name: OSS object file name, such as TestMigration_FULL_20180518153544.bak
        : param str db_name: database name, such as 'TestMigration'
        : param str bak_type: backup type , such as 'FULL'
        : param str date: backup date time, such as '20180518153544'
        : param str ext: backup file extendsion, such as 'bak'
    
        """
        def __init__(self):
        	self.file_key = ''
        	self.sub_folder = ''
        	self.file_name = ''
            self.db_name = ''
            self.bak_type = ''
            self.date = ''
            self.ext = ''
            self.sign_url = ''
    
    """
    parse the OSS file key string into oss key parts
    and return oss_key_parts object.
    """
    def oss_key_parse(file_key):
    
        key_parts = oss_key_parts()
        try:
            if file_key.find('/') >= 0:
                file_key_parts = file_key.rsplit('/', 1)
            else:
                file_key_parts = file_key
                file_key_parts = ['/', file_key]
    
            key_parts.file_key = file_key
            key_parts.sub_folder = file_key_parts[0]
            key_parts.file_name = file_key_parts[1]
    
            key_list = file_key_parts[1].rsplit('_', 2)
    
            key_parts.db_name, \
            key_parts.bak_type, \
            key_parts.date, \
            key_parts.ext = key_list[0], \
                            key_list[1], \
                            key_list[2].rsplit('.', 1)[0], \
                            key_list[2].rsplit('.', 1)[1]
        except Exception, e:
            pass
    
        return key_parts
    
    def oss_list_objects(access_key_id, access_key_secret, oss_endpoint, oss_bucket, directory):
    	"""
    	list all OSS objects under the specified sub folder
    	and return the objects list.
    	"""
    	bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), oss_endpoint, oss_bucket)
    	key_parts_list = []
    
    	# OSS Bucket Root
    	if directory == '/':
    		for object_info in oss2.ObjectIterator(bucket, delimiter='/'):
    			if not object_info.is_prefix():
    				key_part = oss_key_parse(object_info.key)
    
    				# get object sign_url
    				key_part.sign_url = bucket.sign_url('GET', object_info.key, 24 * 3600)
    
    				if key_part.ext in['bak', 'trn', 'log', 'diff']:
    					key_parts_list.append(key_part)
    				else:
    					print ("Warning!!!!!, [%s] is not backup file, filtered." % (key_part.file_key))
    	else:
    		for i, object_info in enumerate(oss2.ObjectIterator(bucket, prefix=directory)):
    			# have to the backup files, not folder
    			if not object_info.is_prefix():
    				if object_info.key.startswith(directory) and object_info.key != directory:
    					# print ("%s" % (object_info.key))
    					key_part = oss_key_parse(object_info.key)
    					
    					# get object sign_url
    					key_part.sign_url = bucket.sign_url('GET', object_info.key, 24 * 3600)
    
    					if key_part.ext in['bak', 'trn', 'log', 'diff']:
    						key_parts_list.append(key_part)
    					else:
    						print ("Warning!!!!!, [%s] is not a vaild backup file, filtered." % (key_part.file_key))
    
    	if not key_parts_list:
    		print("There is no backup file on OSS Bucket [%s] under [%s] folder, check please." % (oss_bucket, directory))
    
    	return key_parts_list
    
    
    def oss_bucket_details(access_key_id, access_key_secret, oss_endpoint, oss_bucket):
    	try:
    		bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), oss_endpoint, oss_bucket)
    		bucket_info = bucket.get_bucket_info()
    		# print ("bucket name:%s, region: %s" % (bucket_info.name, bucket_info.location))
    		return True, bucket_info
    	except Exception as e:
    		return False, e
    
    if __name__ == '__main__':
        main(sys.argv[1:])
    

    当然,以上代码,你也可以去下载以上python脚本。

    使用方法

    我们从以下三个方面简要介绍下如何使用实例级别一键迁移上云:

    查看Help

    一个例子

    输出结果

    查看Help

    你只需要使用-h来查看脚本的使用方法:

    python ~/Downloads/RDSSQLCreateMigrateTasksBatchly.py -h
    ~/Downloads/RDSSQLCreateMigrateTasksBatchly.py -k <access_key_id> -s <access_key_secret> -i <rds_instance_id> -e <oss_endpoint> -b <oss_bucket> -d <directory>
    

    一个例子

    以下是一个具体的例子:

    python ~/Downloads/RDSSQLCreateMigrateTasksBatchly.py -k LTAIQazXKPRwwErT -s BMkIUhroubQOLpOMqfA09IKlqp4G2k -i rm-2zesz5774ud8s71i5 -e oss-cn-beijing.aliyuncs.com -b atp-test-on-ecs -d Migration/OPENAPIDemo
    

    输出结果

    执行以上命令以后的结果输出,分为两个部分:

    第一部分输入参数:展示所有你的输入参数,以便查询输入错误

    第二部分提示信息:告诉你,哪一个备份文件会被迁移到哪个实例的哪一个数据库 如下的一个实例的输出信息:

    *********************Input variables*************************************
    access_key_id = LTAIQazXKPRwwErT
    access_key_secret = BMkIUhroubQOLpOMqfA09IKlqp4G2k
    rds_instance_id = rm-2zesz5774ud8s71i5
    oss_endpoint = oss-cn-beijing.aliyuncs.com
    oss_bucket = atp-test-on-ecs
    directory = Migration/OPENAPIDemo/
    ************************************************************************
    
    *********************Migration requests**********************************
    
    --0. [Migration/OPENAPIDemo/TestCollation_FULL_20180523225534.bak] migrate to your RDS: [rm-2zesz5774ud8s71i5] and the database name will be: [TestCollation].
    {u'DBInstanceId': u'rm-2zesz5774ud8s71i5', u'BackupMode': u'FULL', u'MigrateTaskId': u'106121', u'RequestId': u'67E0DD7F-7219-4F67-AAE7-B27273921303', u'TaskId': u'68244691', u'DBName': u'TestCollation'}
    --I'm sleeping for 2 seconds....
    
    --1. [Migration/OPENAPIDemo/TestMigration_FULL_20180523225534.bak] migrate to your RDS: [rm-2zesz5774ud8s71i5] and the database name will be: [TestMigration].
    {u'DBInstanceId': u'rm-2zesz5774ud8s71i5', u'BackupMode': u'FULL', u'MigrateTaskId': u'106122', u'RequestId': u'0916CD14-861B-4BF7-A68A-409E3996B0D3', u'TaskId': u'68244695', u'DBName': u'TestMigration'}
    --I'm sleeping for 2 seconds....
    
    --2. [Migration/OPENAPIDemo/testdb_FULL_20180523225534.bak] migrate to your RDS: [rm-2zesz5774ud8s71i5] and the database name will be: [testdb].
    {u'DBInstanceId': u'rm-2zesz5774ud8s71i5', u'BackupMode': u'FULL', u'MigrateTaskId': u'106123', u'RequestId': u'5835B154-2EE3-4059-BFC4-6F798CDCE546', u'TaskId': u'68244699', u'DBName': u'testdb'}
    --I'm sleeping for 2 seconds....
    ************************************************************************
    

    最后总结

    利用本篇文章,我们可以轻松实现用户线下或者ECS自建的SQL Server实例级别数据库一键迁移上云,以此来极大的提高迁移上云效率,简化操作,大大提升了用户迁移上云体验。

    参考链接

    SQL Server实例级别数据库上云

    展开全文
  • 现在上云是很普遍的了,Gartner也说数据库的未来就是云。 2020年年初我们迎来了肺炎疫情,各大网络平台都承受了比以往多N倍...数据库要怎么上云,可以看这篇 数据迁移/同步方案概览里面的自建数据库迁移上云部分。 ...

    现在上云是很普遍的了,Gartner也说数据库的未来就是云。
    2020年年初我们迎来了肺炎疫情,各大网络平台都承受了比以往多N倍的压力,面对如此突如其来的压力,平台的扩容变得非常重要,而云数据库的弹性扩缩容很好地支持了这一需求。
    数据库要怎么上云,可以看这篇 数据迁移/同步方案概览里面的自建数据库迁移上云部分。
    参考:

    展开全文
  • 以前,经常接触的政企云项目,一般由服务商配合客户完成迁移方案的拟定,服务商将云资源分配好,由客户自身的厂商完成应用、数据库的迁移。厂商一般进行应用、数据库的重新部署,虽然这种方法较繁杂,但也是最稳妥的...
  • 小明最近挺忙,刚刚在外地找了个新工作,正在忙着...上班第二天,上司就交代了一项任务:公司打算将本地部署的SQL Server数据库迁移到Azure,并让小明出一份方案,必须将本地数据库内的数据尽快迁移上云,同时这一过...
  • 云数据库是高速增长的百亿级市场数据库上云是必然趋势选择迁移目标数据库解决方案对比首先考虑云数据库华为云数据库服务SQL数据库——面向传统OLTP数据库业务NoSQL数据库——面向海量扩展业务数据库生态——构建完整...
  • 迁移上云方案.pptx

    2020-04-30 17:55:03
    从线上迁移上阿里云分为网络搭建、环境准备、系统迁移、数据迁移、测试割接几个阶段,迁移的内容包括系统、数据库、海量数据。分别从以上几个方面介绍迁移方法&工具以及迁移的流程,最后介绍通常的实时周期
  • 【TechWeb】6月12日,微软SQLServer2008在...面对日益增多的勒索病毒攻击,企业是升级数据库,还是将数据库迁移至云端增强数据保护,微软都提供了解决方案。 作为微软智能云助力客户数据库迁移上云的重要举措,微软...
  • 迁云背景介绍、云上典型架构设计、迁云基本方案、应用迁移上云(云服务器ECS)、存储类数据迁移上云数据库迁移上云和迁云案例分享
  • 数据迁移功能帮助您实现同构或异构数据源之间的数据迁移,适用于数据上云迁移、阿里云内部跨实例数据迁移、数据库拆分扩容等业务场景。本文将介绍数据迁移功能支持的数据库、版本和迁移类型。 各类场景的迁移方案请...
  • 2018云栖大会南京峰会飞天技术汇专场上,阿里云高级产品专家萧少聪从准备、迁移效率和迁移后效果三个方面分享了传统数据库迁移到阿里云数据库及后续使用情况的全链路解决方案,针对主流数据库迁移到阿里云数据库的...
  • 由于云的便利性及高可靠等特性,越来越多的企业客户选择上云。大家上云遇到的第一个问题就是如何...停服迁移 — 传统数据库迁移方案 为满足不同的用户场景,市面上涌现出多种多样的数据库引擎。为了解决用户数据导...
  • 随之而来的数据上云、数据安全、数据库升级等问题也被企业提上讨论日程。在新硬件、新架构层出不穷的今天,企业如何抓住机遇踏浪前行? 传统数据迁移的“罪与罚” 数据库在企业应用和业务中的重要性,决定了其迁移...
  • 三种常见的数据库备份、备份策略的制定、查找备份链、数据库的三种恢复模式与备份之间的关系、利用文件组实现冷热数据隔离备份方案以及如何监控备份还原进度,本期我们分享阿里云是如何基于SQL Server备份还原理论来...
  • ORACLE数据库上云选择 云数据库PPAS(高度兼容Oracle) 云数据库PPAS - 提高Oracle迁移上云成功率 云数据库PPAS - Oracle兼容的数据类型 云数据库PPAS - Oracle兼容的DDL 云数据库PPAS - Oracle兼容的DML 云数据库PPAS...
  • 摘要:2018第九届中国数据库技术大会,阿里云...本文提出了Oracle 到云数据库PPAS迁移的方案,这种迁移方案为什么比Oracle到 MySQL系列的迁移容易推动呢?答案即将揭晓。Oracle数据库迁移方案数据业务架构中都会有服...
  • 三种常见的数据库备份、备份策略的制定、查找备份链、数据库的三种恢复模式与备份之间的关系、利用文件组实现冷热数据隔离备份方案以及如何监控备份还原进度,本期我们分享阿里云是如何基于SQL Server备份还原理论来...
  • 摘要: 2018第九届中国数据库技术大会,阿里云数据库产品专家萧少聪带来以阿里云如何打破Oracle迁移上云...本文提出了Oracle 到云数据库PPAS迁移的方案,这种迁移方案为什么比Oracle到 MySQL系列的迁移容易推动呢?...
  • 方案中会概述网络规划、服务器、数据库、存储数据、 Kafka和镜像数据的迁移方案描述。同时在实践环节,增加服务器和RDS的迁移操作演练和验证。 解决问题 提供服务器、数据库等关键环节的平滑迁移方案 提供云上高...

空空如也

空空如也

1 2 3
收藏数 57
精华内容 22
关键字:

数据库上云迁移方案