亚马逊AWS官方博客

举重若轻-用snowball迁移数据库上云

概述

随着企业上云渐渐形成“新常态”,越来越多的迁移方案和工具为大家所熟悉,但大部分的数据传输都是基于网络的,即使使用专线的解决方案,在海量数据迁移的场景下也依然可能力不从心。因此,AWS 针对这类场景推出了AWS Snowball 服务,客户可通过物理存储设备 (绕过 Internet) 加快将海量数据传入和传出 AWS 的速度。Snowball 会通过加密和防篡改技术,保护静态数据和物理运送中的数据。您无需担心自己的数据泄露或丢失。 当然 snowball 并不是包治百病的偏方,是否使用 snowball 需要综合地考量数据量、成本、时间等因素,如果要在本地数据中心和 Amazon S3 之间传输 10 TB 以下的数据,则 Snowball 对您来说可能不是最优的选择。 本文希望通过一个使用 snowball 将 ORACLE 数据库备份传输上 AWS,进而搭建由本地 ORACLE 数据库和云端 EC2 上运行 ORACLE 数据库组成的 data guard 环境,最终通过切换完成最小停机时间数据库迁移上云的 DEMO,让读者对 snowball 的使用有一个直观的认识,大体的步骤如下:

请注意,本文中的 ORACLE 环境和您的实际环境会有差异,DEMO 中的步骤和各种参数的配置,仅供参考,当您需要完成实际迁移项目时,请和您的 DBA 团队商讨,根据实际情况进行调整。

1 环境准备

1.1 数据库准备

1.1.1 测试环境概述

身份 操作系统 数据库版本 主机名 端口 实例名
主库 Linux 11.2.0.1.0 Primary 1521 orcl
备库 Linux 11.2.0.1.0 Standby 1521 stby

两台服务器网络已经调通,互相可以访问,并建立了 SSH 互信,具体步骤这里不展开。可以通过在主备库主机上分别执行 ssh <远程主机名> date来测试

1.1.2 日志准备

1 在主库上开启归档,用以下命令检查,如果还没有开启归档,需要启动数据库到 mount,而后用 alter database archivelog; 开启归档,开启后用 Archive log list; 查看归档设置,输出如下图所示。
2 使用命令 alter database force logging; 对主库开启 force logging ,而后用 select force_logging from v$database; 查询设置结果,输出如下图所示。

3 在主库上用以下命令创建 standby logfile

alter database drop standby logfile group 4;

alter database drop standby logfile group 5;

alter database drop standby logfile group 6;

alter database drop standby logfile group 7;

alter database add standby logfile group 4 '/u01/app/oracle/oradata/orcl/stbredo04.log' size 50m;

alter database add standby logfile group 5 '/u01/app/oracle/oradata/orcl/stbredo05.log' size 50m;

alter database add standby logfile group 6 '/u01/app/oracle/oradata/orcl/stbredo06.log' size 50m;

alter database add standby logfile group 7 '/u01/app/oracle/oradata/orcl/stbredo07.log' size 50m;

设置后用以下语句查询设置结果:

set linesize 200;

select group#,dbid,thread#,sequence#,bytes/1024/1024,archived,status from v$standby_log;  

col member  format a50;

select member,type from v$logfile;

1.1.3 参数文件修改

在主库上通过 spfile 生成 pfile,并进行编辑,添加 data guard 相关的参数,在本例中,主库 unique name 是 orcl,备库 unique name 是 stby,添加参数时注意不同角色数据库的名称,尤其是 log_file_name_convert 和 db_file_name_convert 两个参数,这两个参数用来指定数据文件和 redo 文件路径的转换,譬如源的数据文件是 /u01/app/oracle/oradata/stby/system01.dbf,我们希望将这个数据文件的路径转换到 /u01/app/oracle/oradata/orcl/,那么我们的 db_file_name_convert 就要配置为 ‘/u01/app/oracle/oradata/stby/ ‘,’/u01/app/oracle/oradata/orcl/ ‘,这两个参数十分重要且容易配错,请您务必注意。 以下的参数信息仅供参考,需要您的 DBA 按照实际情况配置。

create pfile='/u01/app/oracle/product/11.2.0/dbhome_1/dbs/initorcl.ora'  from spfile;

orcl.__db_cache_size=385875968

orcl.__java_pool_size=16777216

orcl.__large_pool_size=16777216

orcl.__oracle_base='/u01/app/oracle'#ORACLE_BASE set from environment

orcl.__pga_aggregate_target=553648128

orcl.__sga_target=1040187392

orcl.__shared_io_pool_size=0

orcl.__shared_pool_size=603979776

orcl.__streams_pool_size=0

*.audit_file_dest='/u01/app/oracle/admin/orcl/adump'

*.audit_trail='db'

*.compatible='11.2.0.0.0'

*.control_files='/u01/app/oracle/oradata/orcl/control01.ctl','/u01/app/oracle/flash_recovery_area/orcl/control02.ctl'

*.db_block_size=8192

*.db_domain=''

*.db_name='orcl'

*.db_recovery_file_dest='/u01/app/oracle/flash_recovery_area'

*.db_recovery_file_dest_size=4070572032

*.diagnostic_dest='/u01/app/oracle'

*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'

*.memory_target=1588592640

*.open_cursors=300

*.processes=150

*.remote_login_passwordfile='EXCLUSIVE'

*.undo_tablespace='UNDOTBS1'

*.db_unique_name='orcl'

*.fal_client='ORCL'

*.fal_server='STBY'

*.log_archive_config='DG_CONFIG=(orcl,stby)'

*.log_archive_dest_1='LOCATION=/u01/app/oracle/flash_recovery_area/ORCL/archivelog/ valid_for=(ALL_LOGFILES,ALL_ROLES) db_unique_name=orcl'

*.log_archive_dest_2='SERVICE=stby valid_for=(online_logfiles,primary_role) db_unique_name=stby'

*.log_archive_dest_state_2='ENABLE'

*.log_archive_max_processes=4

*.log_file_name_convert='/u01/app/oracle/oradata/stby/ ','/u01/app/oracle/oradata/orcl/ '

*.db_file_name_convert='/u01/app/oracle/oradata/stby/ ','/u01/app/oracle/oradata/orcl/ '

*.standby_file_management='AUTO'

在主库服务器上通过 scp initorcl.ora standby:$ORACLE_HOME/dbs/initstby.ora 拷贝 pfile 到备库 initorcl.ora 100% 1599 1.4MB/s 00:00 在备库上编辑 initstby.ora,需要注意以下两点,同样地,以下参数仅供参考,需要DBA按实际情况修改
1 除了主库添加的参数,备库的 audit 文件目录以及 control file 的目录会有变化
2 对于主库添加的参数,要注意备库和主库涉及路径,名称的不同

orcl.__db_cache_size=385875968

orcl.__java_pool_size=16777216

orcl.__large_pool_size=16777216

orcl.__oracle_base='/u01/app/oracle'#ORACLE_BASE set from environment

orcl.__pga_aggregate_target=553648128

orcl.__sga_target=1040187392

orcl.__shared_io_pool_size=0

orcl.__shared_pool_size=603979776

orcl.__streams_pool_size=0

*.audit_file_dest='/u01/app/oracle/admin/stby/adump'

*.audit_trail='db'

*.compatible='11.2.0.0.0'

*.control_files='/u01/app/oracle/oradata/stby/control01.ctl','/u01/app/oracle/flash_recovery_area/stby/control02.ctl'

*.db_block_size=8192

*.db_domain=''

*.db_name='orcl'

*.db_recovery_file_dest='/u01/app/oracle/flash_recovery_area'

*.db_recovery_file_dest_size=4070572032

*.diagnostic_dest='/u01/app/oracle'

*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'

*.memory_target=1588592640

*.open_cursors=300

*.processes=150

*.remote_login_passwordfile='EXCLUSIVE'

*.undo_tablespace='UNDOTBS1'

*.db_unique_name='stby'

*.fal_client='STBY'

*.fal_server='ORCL'

*.log_archive_config='DG_CONFIG=(orcl,stby)'

*.log_archive_dest_1='LOCATION=/u01/app/oracle/flash_recovery_area/STBY/archivelog/ valid_for=(ALL_LOGFILES,ALL_ROLES) db_unique_name=stby'

*.log_archive_dest_2='SERVICE=orcl valid_for=(online_logfiles,primary_role) db_unique_name=orcl'

*.log_archive_dest_state_2='ENABLE'

*.log_archive_max_processes=4

*.log_file_name_convert='/u01/app/oracle/oradata/orcl/ ','/u01/app/oracle/oradata/stby/ '

*.db_file_name_convert='/u01/app/oracle/oradata/orcl/ ','/u01/app/oracle/oradata/stby/ '

*.standby_file_management='AUTO'

1.1.4 Listener与 tnsnames 文件修改

主库上的 listener 配置文件应静态注册您的主库,可以参考以下配置

[oracle@primary dbs]$ cat $ORACLE_HOME/network/admin/listener.ora
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = primary)(PORT = 1521))
    )
  )
SID_LIST_LISTENER =
   (SID_LIST =
     (SID_DESC =
       (SID_NAME = orcl)
       (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
           (GLOBAL_DBNAME = orcl)
     )
     (SID_DESC =
       (SID_NAME = orcl)
       (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
       (GLOBAL_DBNAME = orcl_DGB)
     )
     (SID_DESC =
       (SID_NAME = orcl)
       (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
       (GLOBAL_DBNAME = orcl_DGMGRL)
     )
   )
ADR_BASE_LISTENER = /u01/app/oracle

在备库上的listener配置文件同样应静态注册您的备库,可以参考以下配置

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = standby)(PORT = 1521))
    )
  )
SID_LIST_LISTENER =
   (SID_LIST =
     (SID_DESC =
       (SID_NAME = stby)
       (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
        (GLOBAL_DBNAME = stby)
     )
     (SID_DESC =
       (SID_NAME = stby)
       (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
       (GLOBAL_DBNAME = stby_DGMGRL)
     )
     (SID_DESC =
       (SID_NAME = stby)
       (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
       (GLOBAL_DBNAME = stby_DGB)
     )
   )
ADR_BASE_LISTENER = /u01/app/oracle

此外,在主备库主机上需要编写 tnsnames 文件,可以参考以下内容

[oracle@primary dbs]$ cat $ORACLE_HOME/network/admin/tnsnames.ora
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.

ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = primary)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )
stby =
   (DESCRIPTION =
     (ADDRESS_LIST =
       (ADDRESS = (PROTOCOL = TCP)(HOST = standby)(PORT = 1521))
     )
     (CONNECT_DATA =
       (SERVICE_NAME = stby)
     )
   )

1.1.5 password文件

为了让超级用户能远程登陆,需要创建 password 文件,参考以下命令创建 password 文件,再将其从主库上远程拷贝到备库上。

orapwd file='/u01/app/oracle/product/11.2.0/dbhome_1/dbs/orapworcl' password=Oracle123 entries=10  ignorecase=y scp orapworcl standby:/u01/app/oracle/product/11.2.0/dbhome_1/dbs/orapwstby  

1.1.6 备库主机创建目录

根据上述备库参数文件中设置的数据文件,redo 文件,control 文件,aduit 文件的路径,我们需要在备库上预先创建好相应目录

mkdir -p /u01/app/oracle/admin/stby/adump
mkdir -p /u01/app/oracle/oradata/stby/
mkdir -p /u01/app/oracle/flash_recovery_area/stby
mkdir -p /u01/app/oracle/flash_recovery_area/STBY/archivelog
mkdir -p /u01/app/oracle/flash_recovery_area/STBY/onlinelog

1.2 激活 Snowball

1.2.1 申请 Snowball

首先,我们需要申请 snowball,请打开 console 进入 snowball 的服务界面

点击 create job 按钮,选择 Import into Amazon S3 任务类型,可以通过 snowball 将数据上传到 AWS,或者通过 snowball 从 AWS 下发数据,这里我们选择“导入 Amazon S3” 任务类型

点击下一步,在下一个页面提供公司名称、地址、收货人姓名、电话等信息

点击下一步,请提供 job 的名称,并从下拉菜单中选择数据导入的 S3 bucket name,我们需要预先在自己的 AWS 账号中创建 S3 bucket

点击下一步,要提供相应的权限,点击 create/select IAM role,我们可以创建一个新的 IAM role 给snowball,也可以选择已有的 IAM role。


点击下一步,这里我们可以设置 SNS topic,在您选定的 job 状态变化时通知您,譬如在向您发货或者货物到达时,给您发通知。这个页面设置好后,再点击下一步,就会进入 review 界面,显示我们之前所有的配置信息,如果一切正确,点击 create job 就可以最终创建任务,然后我们就可以等待快递公司将 snowball 送货上门了。


1.2.2 下载 snowball 客户端

在snowball传输过程中,我们可以先安装Snowball 客户端,它 是一个您在本地工作站上运行以执行数据传输的独立终端应用程序。提供您传输数据时所需的所有功能,包括处理错误以及向本地工作站写入日志,以便进行故障排除和审计。请在AWS官网snowball服务主页或者snowball用户指南文档中根据您要运行snowball客户端程序的主机OS类型选择下载相应的程序。 由于工作站通常是在 Snowball 和数据源之间传输数据的瓶颈所在,我们强烈建议您使用性能强大的计算机作为工作站,而且您的工作站必须能够满足处理、内存和网络的高要求。针对工作规格,我们的官方文档有详细建议和说明https://docs.amazonaws.cn/zh_cn/snowball/latest/ug/specifications.html#workstationspecs,在实际案例中请注意避免工作站成为性能瓶颈,从而影响传输效率。本次DEMO中我们将用我的windows笔记本安装snowball客户端。 我们通过上述网页下载windows安装程序snowball-client-win-1.0.1-281.msi,双击安装snowball agent,默认安装。 安装后进入安装目录,执行 snowball help 测试

1.2.3 连接snowball

当快递公司将snowball发送到您的公司后,您就可以将snowball连接到您刚才安装了客户端程序的工作站上, 到货时snowball的前后面板是关闭的,如下图所示

打开面板后,可以看到附带的线缆,每个 Snowball 均被设计为支持通过 RJ45、SFP+ 铜缆或 SFP+ 光纤 10 Gb 以太网传输数据。请连通电源和线缆

墨水屏会显示网络配置,这里 DHCP 已经自动分配了 IP,也可以手动完成网络配置

重要
为防止损坏您的数据,请勿在传输数据时,断开 Snowball 或更改其网络设置。


1.2.4 激活 snowball

在AWS console的snowball服务页面,选择我们之前创建的job,展开该任务的 Job status 窗格,然后选择 View job details,在显示的详细信息窗格中,展开 Credentials。请记下解锁代码 (包括连字符),因为您需要提供全部 29 个字符才能传输数据。在对话框中选择 Download manifest,然后按照说明将任务清单文件下载到您的计算机上。清单文件名包括您的 Job ID。

在安装了snowball客户端的笔记本上,进入安装目录执行以下命令激活snowball

snowball start -i [IP Address] -m [Path/to/manifest/file] -u [29 character unlock code]    

2 迁移数据库

2.1主库备份

通过CONFIGURE CONTROLFILE AUTOBACKUP ON;更改RMAN设置,使之自动备份control file

而后在主数据库进行RMAN备份,因为使用snowball迁移的数据库通常很大,所以我们可以考虑使用BACKUP AS COMPRESSED BACKUPSET对备份集进行压缩,此外,我们也可以使用多个RMAN通道,然后将数据文件分配到不同的通道,以此来调整备份的总吞吐量。以下脚本仅供参考,请读者根据实际情况进行修改。

rman target /
  run{        
  allocate channel c1 type disk;
  backup database plus archivelog tag='full';        
  release channel c1;}

通过 list backup; 列出所需的备份文件,注意会有多个备份文件需要拷贝

2.2 用 Snowball 拷贝备份文件上云

2.2.1 将备份文件拷贝到 Snowball

我们将所有需要的备份文件拷贝到安装了snowball 客户端的笔记本上的 C:\ orclbak 目录下,使用命令 snowball cp -r C:\orclbak s3://phoenixyy-test-bucket/orclbak/ 拷贝该目录下的所有备份文件到 snowball,拷贝速度和我们使用网络连接的类型以及安装 snowball 客户端的主机资源有关,我们还可以考虑多个客户端的并行复制。具体优化方式请遵循最佳实践,这里不再赘述 https://docs.amazonaws.cn/zh_cn/snowball/latest/ug/performance.html

拷贝成功后请用 snowball ls s3://phoenixyy-test-bucket/orclbak 命令验证上传结果

如果一切正确,可以用 snowball stop 停止从 当前安装 Snowball 客户端 的主机到 Snowball 的通信

2.2.2 拷贝备份文件到备库主机

接下来我们需要遵循文档https://docs.amazonaws.cn/zh_cn/snowball/latest/ug/shipping.html 将snowball寄回AWS,我们上传的数据会自动上传到我们此前创建snowball任务时指定的S3 bucket里,而后我们就可以下载备份文件到要安装备库的EC2主机上了,该EC2主机上已经安装了ORACLE软件,这里,我们跳过了安装ORACLE软件和snowball运输的环节,直接进入从S3下载的环节 首先,我们将备份文件置于与主库完全相同的路径下,故而先在备库主机上创建备份文件一致的目录

mkdir -p /u01/app/oracle/flash_recovery_area/ORCL/backupset/2018_11_27
mkdir -p /u01/app/oracle/flash_recovery_area/ORCL/autobackup/2018_11_27

而后,我们将从S3下载备份文件到备库主机相同的目录下,在这里,我们遵循文档https://docs.amazonaws.cn/cli/latest/userguide/awscli-install-linux.html 预先安装并配置了AWS Command Line Interface,我们可以用命令 aws s3 ls  s3://phoenixyy-test-bucket/orclbak列出上传的备份文件

再通过以下命令将备份文件逐一下载到备库主机,为了简化操作,保证备份文件在备库主机上所在的目录和主库主机的目录保持一致。这里的文件名称,路径以及S3 bucket名称都需要按照实际情况修改

aws s3 cp s3://phoenixyy-test-bucket/orclbak/o1_mf_annnn_FULL_fzskrbnv_.bkp /u01/app/oracle/flash_recovery_area/ORCL/backupset/2018_11_27/o1_mf_annnn_FULL_fzskrbnv_.bkp
aws s3 cp s3://phoenixyy-test-bucket/orclbak/o1_mf_nnndf_TAG20181127T042407_fzskq7js_.bkp /u01/app/oracle/flash_recovery_area/ORCL/backupset/2018_11_27/o1_mf_nnndf_TAG20181127T042407_fzskq7js_.bkp
aws s3 cp s3://phoenixyy-test-bucket/orclbak/o1_mf_s_993270283_fzskrcs1_.bkp /u01/app/oracle/flash_recovery_area/ORCL/autobackup/2018_11_27/o1_mf_s_993270283_fzskrcs1_.bkp
aws s3 cp s3://phoenixyy-test-bucket/orclbak/o1_mf_annnn_FULL_fzskq6ct_.bkp /u01/app/oracle/flash_recovery_area/ORCL/backupset/2018_11_27/o1_mf_annnn_FULL_fzskq6ct_.bkp

2.3 创建data guard环境

2.3.1 还原备库

在备库上用之前准备的pfile启动备库实例到nomount,并生成 spfile

startup nomount pfile=$ORACLE_HOME/dbs/initstby.ora
create spfile from pfile;
shutdown immediate
startup nomount 

使用 rman target sys/Oracle123@orcl auxiliary / 连接主库和备库,执行 duplicate target database for standby nofilenamecheck;  还原备库,其输出类似


2.3.2 恢复备库

用命令alter database recover managed standby database using current logfile disconnect from session;在备库上开启real-time apply redo data

用命令select process,client_process,sequence#,status from v$managed_standby; 检查备库关键进程运行情况

在主库上执行如下语句创建测试表 test 并插入一条记录

create table test(id number);
insert into test values(1);
commit;

在备库上将数据库只读打开,而后查询test验证复制成功

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
alter database open;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE  USING CURRENT LOGFILE   DISCONNECT FROM SESSION;

2.3.3 搭建DG broker环境

在主备库上修改参数dg_broker_start

alter system set dg_broker_start=true scope=both;

在主库上配置并开启 configuration

dgmgrl /
create configuration 'orcl' as primary database is 'orcl' connect identifier is orcl;
add database 'stby' as connect identifier is stby maintained as physical;
enable configuration;
show configuration verbose;


2.3.4 切换数据库

最后我们模拟一下将数据库从IDC机房切换到AWS上的过程,在备库主机上执行如下命令

dgmgrl 
connect sys/Oracle123@orcl
disable fast_start failover;
show configuration verbose;
switchover to stby;

在新备库上执行以下语句查看状态是否正确

set linesize 200
select dbid,open_mode,database_role,switchover_status,flashback_on from v$database;
select process,client_process,sequence#,status from v$managed_standby;

在原来的备库,现在的主库stby中,向test表插入一条新记录, insert into test values(2); commit; 在原来的主库现在的备库orcl中查询test表,验证数据记录复制成功

set linesize 200
select dbid,open_mode,database_role,switchover_status,flashback_on from v$database;
select * from test;

结语

希望通过本文,您能对 snowball 有所了解。以后当您面临海量数据需要迁移上云,灾备环境搭建,数据中心退役乃至内容分发的时候,尤其在网络传输成为瓶颈时,您能想到还有一个选择,可以使用 snowball 举重若轻地完成任务。

参考文档

《AWS snowball 用户指南》

本篇作者

吕琳

AWS解决方案架构师,负责基于 AWS 的云计算方案的咨询与架构设计,同时致力于数据库和大数据方面的研究和推广。在加入AWS 之前曾在Oracle担任高级讲师并在Amazon担任高级DBA,在数据库设计运维调优、DR解决方案、大数据以及企业应用等方面有丰富的经验。