همانطور که می دانید برای مدیریت فایلهای موجود در محیط asm، نمی توان از دستورات سیستم عاملی استفاده کرد(البته در محیط acfs که بر روی asm پیاده می شود، این نقصان برطرف شده است).
برای مثال نمی توان با دستوراتی چون cp ،mv و… در سطح لینوکس، بر روی فایلهای موجود در فضای asm اعمال مدیریت کرد در صورتی که ممکن است برای یک مدیر بانک اطلاعاتی، انجام چنین کاری بسیار ضروری باشد(انتقال فایل به محیط بیرون، اصلاح و ….).
یکی از این عملیاتهای پرکاربرد، انتقال فایل بین دو محیط سیستم عامل و asm می باشد که در ادامه با ارائه سه روش، به شیوه انجام آن خواهیم پرداخت.
1.دستور cp
با کمک دستور cp در محیط asmcmd، امکان انتقال(کپی) فایل به محیط سیستم عامل امکان پذیر خواهد شد.
برای مثال، با دستور زیر، آرشیولاگی با نام thread_2_seq_9.303.958298363 که در محیط ASM قرار دارد، به مسیر grid/non_asm/ کپی خواهد شد:
[+DATA/usefdb/ARCHIVELOG/2017_10_25] >cp thread_2_seq_9.303.958298363 /grid/non_asm
copying +DATA/usefdb/ARCHIVELOG/2017_10_25/thread_2_seq_9.303.958298363 -> /grid/non_asm/thread_2_seq_9.303.958298363
همچنین برای کپی کردن یک فایل از محیط non-asm به محیط asm هم می توان از این دستور استفاده کرد:
ASMCMD [+] > cp /grid/non_asm/thread_2_seq_9.303.958298363 +DATA\usefdb\arc_2_seq_9.arc
copying /grid/non_asm/thread_2_seq_9.303.958298363 -> +DATA/usefdb/arc_2_seq_9.arc
برای انتقال دسته ای از فایلها از محیط asm به محیط non-asm می توان از قطعه کد زیر استفاده کرد:
[grid@rac1 ~]$ for i in $(asmcmd ls +DATA/usefdb/ARCHIVELOG/2017_10_25); do asmcmd cp +DATA/usefdb/ARCHIVELOG/2017_10_25/$i /grid/non_asm/; done
copying +DATA/usefdb/ARCHIVELOG/2017_10_25/thread_1_seq_10.301.958298357 -> /grid/non_asm//thread_1_seq_10.301.958298357
copying +DATA/usefdb/ARCHIVELOG/2017_10_25/thread_1_seq_11.302.958298361 -> /grid/non_asm//thread_1_seq_11.302.958298361
copying +DATA/usefdb/ARCHIVELOG/2017_10_25/thread_2_seq_9.303.958298363 -> /grid/non_asm//thread_2_seq_9.303.958298363
البته برای اینکه تنها از آرشیوهای روز جاری کپی تهیه شود، می توان از متغیر هم استفاده کرد که در این صورت، کد بالا به صورت زیر تغییر خواهد کرد:
export today=`date +%Y_%m_%d`
for i in $(asmcmd ls +DATA/usefdb/ARCHIVELOG/$today); do asmcmd cp +DATA/usefdb/ARCHIVELOG/2017_10_25/$i /grid/non_asm/; done
همچنین به طریق زیر، می توان آرشیوهای مربوط به چند روز را در یک زمان کپی کرد:
for i in $(asmcmd ls DATA/LIN/ARCHIVELOG/2017_1*); do asmcmd cp +DATA/LIN/ARCHIVELOG/*/$i /grid/non_asm/; done
برای انتقال فایل از یک سرور به سرور دیگر هم می توان از این دستور استفاده کرد که syntax ان به صورت زیر می باشد:
asmcmd cp <SOURCE_FILE_NAME> USERNAME/PASSWORD@TARGET_SERVER_IP: <TARGET_ASM_INSTANCE> :<TARGET_FILE_LOCATION>
2.ابزار RMAN
از دیگر ابزارهای قابل استفاده در این زمینه، RMAN می باشد با این مزیت که می توان به صورت سازگار دیتافایلها را در عین انلاین بودنشان، به محیط بیرون از ASM منتقل کرد.
در مثال زیر، دیتافایل شماره دو به محیط non-asm منتقل خواهد شد:
rman target /
Recovery Manager: Release 12.2.0.1.0 – Production on Wed Oct 25 10:38:23 2017
Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved.
connected to target database: USEFDB (DBID=829771136)
RMAN> copy datafile 2 to ‘/oracle/oradata/usefdb/tbs1.dbf’;
Starting backup at 25-OCT-2017 10:41:08
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile copy
input datafile file number=00002 name=+DATA/USEFDB/DATAFILE/tbs1.307.958300573
output file name=/oracle/oradata/usefdb/tbs1.dbf tag=TAG20171025T104108 RECID=1 STAMP=958300869
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:03
Finished backup at 25-OCT-2017 10:41:11
همچنین می توان از دستور زیر برای انتقال ارشیولاگ استفاده کرد:
RMAN> LIST ARCHIVELOG ALL;
RMAN> copy archivelog ‘+DATA/USEFDB/ARCHIVELOG/2017_10_28/thread_2_seq_23.329.958542319’ to‘/oracle/non-asm/thread_2_seq_23.329.958542319’;
Starting backup at 28-OCT-2017 10:05:25
using channel ORA_DISK_1
channel ORA_DISK_1: starting archived log copy
input archived log thread=2 sequence=23 RECID=35 STAMP=958542319
output file name=/oracle/non-asm/thread_2_seq_23.329.958542319 RECID=37 STAMP=958557927
channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:03
Finished backup at 28-OCT-2017 10:05:28
در صورتی که قصد داشته باشیم دسته ای از آرشیولاگها را به محیط non-asm منتقل کنیم، باید از دستور دیگری کمک بگیریم:
rman target /
Recovery Manager: Release 12.2.0.1.0 – Production on Wed Oct 25 10:38:23 2017
Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved.
connected to target database: USEFDB (DBID=829771136)
RMAN> backup as copy archivelog from logseq=11 until logseq=15 thread=2 format ‘/oracle/oradata/usefdb/arc%U’;
Starting backup at 25-OCT-2017 11:07:07
using channel ORA_DISK_1
archived log /oracle/oradata/usefdb/arc95830188795804979451 not found or out of sync with catalog
trying alternate file for archived log of thread 2 with sequence 11
channel ORA_DISK_1: starting archived log copy
input archived log thread=2 sequence=12 RECID=15 STAMP=958301939
output file name=/oracle/oradata/usefdb/arcarch_D-USEFDB_id-829771136_S-12_T-2_A-829767805_0hsht26s RECID=25 STAMP=958302428
channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting archived log copy
input archived log thread=2 sequence=13 RECID=16 STAMP=958301941
output file name=/oracle/oradata/usefdb/arcarch_D-USEFDB_id-829771136_S-13_T-2_A-829767805_0isht26t RECID=26 STAMP=958302429
channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting archived log copy
input archived log thread=2 sequence=11 RECID=12 STAMP=958301741
output file name=/oracle/oradata/usefdb/arcarch_D-USEFDB_id-829771136_S-11_T-2_A-829767805_0jsht26u RECID=27 STAMP=958302430
channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting archived log copy
input archived log thread=2 sequence=14 RECID=17 STAMP=958301942
output file name=/oracle/oradata/usefdb/arcarch_D-USEFDB_id-829771136_S-14_T-2_A-829767805_0ksht26v RECID=28 STAMP=958302431
channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting archived log copy
input archived log thread=2 sequence=15 RECID=19 STAMP=958301943
output file name=/oracle/oradata/usefdb/arcarch_D-USEFDB_id-829771136_S-15_T-2_A-829767805_0lsht270 RECID=29 STAMP=958302432
channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:01
Finished backup at 25-OCT-2017 11:07:13
3.بسته DBMS_FILE_TRANSFER
با استفاده از این بسته هم می توان فایلها را از محیط asm به محیط non-asm منتقل کرد. برای انجام این کار باید ابتدا مبدا و مقصد را با ایجاد یک دایرکتوری تعیین کرد:
CREATE DIRECTORY asmarc AS ‘+DATA/usefdb/ARCHIVELOG/2017_10_25’;
CREATE DIRECTORY nonasm AS ‘/oracle/oradata/usefdb’;
سپس با کمک پروسیجر COPY_FILE، فایل مورد نظر را کپی نمود:
BEGIN
dbms_file_transfer.copy_file(
source_directory_object =>’asmarc’,
source_file_name => ‘thread_2_seq_19.324.958301957’,
destination_directory_object => ‘nonasm’,
destination_file_name => ‘thread_2_seq_19.324.958301957’);
END;
همچنین با کمک این بسته، می توان به صورت دسته ای فایلها را کپی نمود که در قطعه کد زیر، این کار انجام شده است:
DECLARE
asmdir_var VARCHAR2(4000) := ‘asmarc’;
nonasmdir_var VARCHAR2(4000) := ‘nonasm’;
v_asm_logname VARCHAR2(4000);
v_unix_logname VARCHAR2(4000);
v_first_log_seq NUMBER := 10;
v_last_log_seq NUMBER := 15;
v_log_seq VARCHAR2(4000);
CURSOR c_logs IS
SELECT name,thread#
FROM v$archived_log
WHERE sequence# BETWEEN v_first_log_seq AND v_last_log_seq and name like ‘%+DATA%’ and thread#=2
ORDER BY sequence#;
BEGIN
FOR i IN c_logs LOOP
v_asm_logname := SUBSTR(i.name, 36);
v_log_seq := SUBSTR(v_asm_logname,1,15);
v_unix_logname := ‘arc_’ ||v_log_seq||’.log’;
DBMS_FILE_TRANSFER.COPY_FILE(asmdir_var,
v_asm_logname,
nonasmdir_var,
v_unix_logname);
DBMS_OUTPUT.PUT_LINE(v_asm_logname||’ transfer to ‘||v_unix_logname||’.’);
END LOOP;
END;
/
علاوه بر پروسیجر copy_file، دو پروسیجر دیگر هم با نامهای put_file و get_file در این زمینه وجود دارند که می توان با کمک انها فایلهایی را با کمک database link به بانک و یا سرور دیگر منتقل کرد.
تفاوت این دو پروسیجر در ان است که put_file باید در سرور مالک اصلی فایل اجرا شود(سرور مبدا) و get_file هم باید در سرور مقصد به عبارتی دیگر، همان سروری که قرار است فایل به ان ارسال شود، اجرا گردد.
مثال: ارسال فایل با کمک پروسیجر put_file و get_file:
ابتدا در بانک مقصد یک دایرکتوری ایجاد می کنیم:
SQL>CREATE OR REPLACE DIRECTORY destination_dir as ‘/oracle/non-asm’;
همچنین علاوه بر دایرکتوری، dblinkای را برای برقراری ارتباط با بانک مقصد، در بانک مبدا ایجاد می کنیم:
SQL> CREATE OR REPLACE DIRECTORY source_dir as ‘+DATA/DB12C/DATAFILE’;
SQL> CREATE DATABASE LINK remote CONNECT TO usef IDENTIFIED BY a USING ‘rac12cr2’;
حال با اتصال به بانک مبدا، فایلی را به بانک مقصد ارسال می کنیم:
BEGIN
DBMS_FILE_TRANSFER.put_file(
source_directory_object => ‘source_dir’,
source_file_name => ‘UNDOTBS1.260.957634085’,
destination_directory_object => ‘destination_dir’,
destination_file_name => ‘UNDOTBS1.260.957634085’,
destination_database => ‘REMOTE’);
END;
/
البته باید توجه داشت که قبل از ارسال دیتافایل، باید ان دیتافایل را در وضیعت فقط خواندنی قرار داد تا به صورت سازگار منتقل شود.
حال برای انجام این کار به وسیله پروسیجر get_file باید به بانک مقصد(سروری که قرار است فایل به ان منتقل شود) وصل شد و سپس پروسیجر را اجرا کرد البته قبل از ان باید dblinkای را بر روی این بانک ایجاد کرد:
SQL> CREATE DATABASE LINK remote CONNECT TO usef IDENTIFIED BY abc USING ’12cr1′;
BEGIN
DBMS_FILE_TRANSFER.get_file(
source_directory_object => ‘source_dir’,
source_file_name => ‘UNDOTBS1.260.957634085’,
source_database => ‘REMOTE’,
destination_directory_object => ‘destination_dir’,
destination_file_name => ‘UNDOTBS1.260.957634085’);
END;
/