بررسی PLUGGABLE DATABASE در اوراکل 12cR1

می دانیم که قبل از اوراکل 12c، این امکان وجود داشت تا اطلاعات هر کاربر به صورت فیزیکی مستقل از دیگر کاربران ذخیره شده و نیز از نظر امنیتی این اطلاعات دور از دسترس دیگر کاربران قرار بگیرد و در صورت لزوم این قابلیت وجود داشت تا اطلاعات کاربر به بانک اطلاعاتی دیگری منتقل شود و از بانک جاری حذف شود به طور مثال ممکن بود از طریق Transportable Tablespace ، tablespace مربوط به کاربر را در صورت عدم وابستگی به دیگر tablespaceها، به بانک دیگری منتقل کرد ولی در عین حال ساختار موجود در نسخه های قبلی بسیار مستعد اختلاط بود و همه کاربران به یک data dictionary واحد وابسته بودند و همچنین انتقال بخشی از اطلاعات به بانک دیگر، با محدودیتهایی مواجه بود.

حال در اوراکل 12c، ویژگی جدیدی ارائه شد که نه تنها مشکلات مذکور را مرتفع می کند بلکه قابلیتهای جدیدی را هم به همراه دارد این ویژگی (pluggable database(PDB نام دارد.

معماری این ویژگی به این صورت است که در ابتدا container ای با عنوان root container ایجاد می شود که وجود آن برای ادامه حیات بانک اطلاعاتی ضروری می باشد و اشیاها و متاداده های مربوط به اوراکل در این container نگهداری می شوند همچنین داده های کاربری در این Container ذخیره نمی شوند سپس container یا container های دیگری از نوع PDB ایجاد می شوندکه قرار است اطلاعات کاربر در درون آن قرار بگیرد حال متناسب با نیاز، می توان pdbهای دیگری را هم به بانک اضافه کرد تعداد PDBها حداکثر می تواند به 253 برسد.

البته pdb به دو نوع application PDB و seed PDB قابل تقسیم است که application PDB حاوی اطلاعات کاربری می باشد و به ازای هر برنامه کاربردی، می توان از یک PDB مجزا استفاده کرد به طوری که هر کدام از این PDBها ساختار مستقلی از دیگری داشته باشند همچنین seed PDB یک template آماده می باشد که برای ساخت سریع PDB application به کار می رود.
نکته حائز اهمیت در این معماری، عدم امکان جابجایی برای ROOT container و قابلیت جابجایی پذیری برای PDB می باشد.

هر container دارایtablespace  system مخصوص به خود می باشد یعنیdata dictionaryای که اطلاعات و ساختار کلی بانک را نگهداری می کند از دیتا دیکشنری مربوط به اطلاعات کاربران مجزا می باشد. البته کاربران موجود در PDBها، قابلیت رویت متاداده غیرکاربری مربوط به خود را دارا می باشند به طور مثال، کاربر usef در PDB1، تنها می تواند اطلاعات datafile مربوط به pdb خود را در ویوی v$datafile ببیند(البته در صورت داشتن دسترسی) ولی امکان مشاهده اطلاعات دیگر containerها را به این شیوه نخواهد داشت.

SQL> select name from v$datafile;
+DATA01/USEF/DATAFILE/undotbs1.259.916159325
+DATA01/USEF/36A71C1B64C22204E055000000000001/DATAFILE/system.269.916159755
+DATA01/USEF/36A71C1B64C22204E055000000000001/DATAFILE/sysaux.270.916159755
+DATA01/USEF/36A71C1B64C22204E055000000000001/DATAFILE/users.272.916159853

در یک دسته بندی کلی می توان گفت:

redo log و control file بین همه containerها مشترک می باشند و به container خاصی اختصاص ندارند.
root container حاوی TEMP tablespaceپیش فرض و UNDO می باشد(نسخه 12cR1).
هر یک از PDBها می توانند tempfile مختص به خود را داشته باشند که در زمان انجام عملیات unplug، باید حفظ شود.
Application tablespaceها در درون PDBها موجود هستند.

انتقال و دسترسی اطلاعات بین pdbهای مختلف از طریق db-link قابل انجام خواهد بود.

برای گرفتن اطلاعات در مورد اشیاهای مختلف موجود در بانک، می توان از ویوهای دیتا دیکشنری در سطوح مختلف استفاده کرد که جامع ترین آمارها توسط ویوهایی ارائه می شود که با _cdb شروع می شوند.

برای مثال؛ جهت مشاهده همه ی اشیای کاربری متعلق به pdb1(از طریق container root)، می توان از دستور زیر استفاده کرد:

select owner,object_name from cdb_objects l where l.ORACLE_MAINTAINED=’N’ and l.SHARING=’NONE’ and l.CON_ID in (select CON_ID from cdb_pdbs ll where ll.PDB_NAME=’PDB1′) ;

حال اگر به یکی از pdbها وصل شده باشیم می توانیم از ویوهای _dba_، all و یا در نهایت _user استفاده کنیم. فیلدی که در بیشتر ویوها اضافه شده است، CON_ID می باشد.

نکته 1: زمانی که pdbها در حالت close قرار دارند، _cdb اطلاعاتی در مورد اشیاهای آنها نشان نخواهد داد.
نکته 2: از مزایای pluggable database می توان انتقال راحت داده ها، کاهش هزینه از بعد سخت افزاری، بهبود زمان ارتقا، مجزاسازی و … اشاره کرد.

مدیریت pluggable database

در این قسمت از متن، به شیوه اتصال به pdb و همچنین نحوه باز و بسته کردن و تغییر نام ان خواهیم پرداخت.

در زمان ایجاد هر کدام از PDBها، service_nameای هم با آن نام ایجاد می شود که برای اتصال به pdb می توان از آن استفاده کرد. برای مشاهده سرویسهای موجود در بانک اطلاعاتی، می توان از دستور زیر استفاده کرد:

SQL>select name,pdb from v$services order by 2;

همچنین می توان در صورت لزوم، به pdb مورد نظر متصل شده و سرویس جدیدی را برای آن pdb ایجاد کرد:

sqlplus “sys/sys@salak_pdb as sysdba”
SQL>EXEC DBMS_SERVICE.CREATE_SERVICE(‘PDB1′,’PDB1’)
SQL>EXEC DBMS_SERVICE.START_SERVICE(‘PDB1’)

برای اتصال به یک pdb روشهای مختلفی قابل استفاده می باشد از جمله این روشها، می توان به موارد زیر اشاره کرد:

–روش اتصال آسان(easy connect):
شکل کلی:

SQL>CONNECT username/password@net_service_name

مثالها:

sqlplus “sys/sys@192.168.232.10:1521/pdb1 as sysdba”
SQL>connect sys/sys@192.168.232.10:1521/pdb1 as sysdba;

–روش net service name:

PDB1 =
(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.232.10)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(service_name = pdb1) ) )

sqlplus “sys/sys@pdb1 as sysdba”

–تغییر container در سطح session:

SQL>alter session set container=pdb1;

بعد از انکه با یکی از روشهای مذکور، به pdb مورد نظر متصل شدیم، می توانیم با کمک دستور زیر، تعیین کنیم که در کدام container قرار داریم:

SQL>show pdbs
SQL>show con_name

همچنین در صورتی که از sqlplus برای اتصال به بانک استفاده می شود، می توان فایل glogin.sql مربوط به Sqlplus  را طوری تنظیم کرد تا همیشه نام pdb مورد نظر در خط فرمان ظاهر شود:

vi $ORACLE_HOME/sqlplus/admin/glogin.sql
define gname=idle
column global_name new_value gname
set heading off
set termout off
col global_name noprint
select upper(sys_context (‘userenv’, ‘con_name’) || ‘@’ || sys_context(‘userenv’, ‘db_name’)) global_name from dual;
set sqlprompt ‘&gname> ‘
set heading on
set termout on

با این تغییر، در صورت ورود به sqlplus، خط فرمان به صورت زیر نمایش داده می شود:

sqlplus “sys/sys@USEF_PDB as sysdba”
PDB1@dbname>

به طور پیش فرض در هر زمانی که بانک اطلاعاتی restart می شود(در نسخه 12.1.0.1)، هیچ کدام از pdbها در حالت open قرار نمی گیرند و برای تغییر حالت آنها از mount به open، می توان از دستور زیر استفاده کرد:

SQL>alter pluggable database all open;
SQL>alter pluggable database pdb1,pdb2 open;

همچنین برای close کردن آنها، از دستور زیر استفاده می شود:

SQL>alter pluggable database all close;

برای انکه PDBها به صورت خودکار در حالت open قرار بگیرند، می توان از تریگر هم بهره گرفت:

CREATE OR REPLACE TRIGGER open_pdb
AFTER STARTUP ON DATABASE
BEGIN
EXECUTE IMMEDIATE ‘ALTER PLUGGABLE DATABASE ALL OPEN’;
END open_pdb;
/

دستور زیر pdb را در حالت فقط خواندنی قرار می دهد:

SQL>ALTER PLUGGABLE DATABASE pdb1 OPEN READ ONLY;

دستور زیر همه pdbها را در حالت خواندنی/نوشتنی باز می کند:

SQL>ALTER PLUGGABLE DATABASE ALL OPEN READ WRITE FORCE;

برای بستن همه PDBها به جز pdb1,pdb2 به صورت immediate از دستور زیر استفاده می شود:

SQL>ALTER PLUGGABLE DATABASE ALL EXCEPT pfb1,pdb2 CLOSE IMMEDIATE;

نام یک PDB را به روش زیر می توان تغییر داد:

sqlplus “sys/sys@USEF_PDB as sysdba”
SQL> alter pluggable database close immediate;
SQL> alter pluggable database open restricted;
SQL> alter pluggable database rename global_name to new_pdb1;
SQL> startup force;

حذف و ایجاد یک PDB:
ایجاد pdb به طروق مختلفی قابل انجام است که در این متن، دو شیوه آن را توضیح خواهیم داد.

روش اول: با اتصال به CDB$ROOT و وارد کردن دستور زیر، می توانیم PDB جدیدی با نام pdb_usef را ایجاد کنیم:

CREATE PLUGGABLE DATABASE pdb_usef ADMIN USER usef IDENTIFIED BY a;

در این روش از PDB$SEED برای ایجاد PDB جدید استفاده می شود.

روش دوم: تکثیر(clone) از طریق یکی از pdbهای موجود، روش دیگری برای افزودن pdb جدید به بانک اطلاعاتی می باشد که در ادامه مراحل انجام آن آورده شده است:

ابتدا به PDB مورد نظر متصل شده و وضیعت  آن را در حالت read only قرار می دهیم:

sqlplus “sys/sys@pdb1 as sysdba”
SQL>  alter pluggable database PDB1  open read only force;
Pluggable database altered.

برای نمایش فایلهایی که قرار است تکثیر شوند، از دستور زیر استفاده می کنیم:

SQL> select name from v$datafile;
NAME
——————————————————————————–
/u01/oracle/oradata/USEF_CDB/datafile/o1_mf_undotbs1_c87f0hmn_.dbf
/u01/oracle/oradata/USEF_CDB/pdb1/datafile/system01.dbf
/u01/oracle/oradata/USEF_CDB/pdb1/datafile/sysaux01.dbf
/u01/oracle/oradata/USEF_CDB/pdb1/datafile/users01.dbf

در نهایت به ROOT container متصل شده تا کلونینگ یا تکثیر را انجام دهیم:

SQL> create pluggable database pdb_clone from PDB1 file_name_convert=(‘/u01/oracle/oradata/USEF_CDB/pdb1/datafile’,’/u01/oracle/oradata/USEF_CDB/pdb_clone/datafile’);

با اجرای این دستور، PDB جدیدی را در لیست PDBها خواهیم دید:

SQL> show pdbs;     
CON_ID CON_NAME                       OPEN MODE  RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED                       READ ONLY  NO
3 USEF_CDB1                      MOUNTED
4 PDB1                           READ ONLY  NO
         5 PDB_CLONE                      MOUNTED

PDB_CLONE را با دستور زیر باز می کنیم:

SQL> alter pluggable database PDB_CLONE open;

Pluggable database altered.

همچنین برای حذف یک pluggable database، می توان از دستور زیر استفاده کرد:

SQL> alter pluggable database pdb1 close;
SQL> drop pluggable database pdb1 including datafiles;

عبارت INCLUDING DATAFILES سبب حذف دیتافایلهای مربوط به PDB خواهد شد در صورتی که عبارت KEEP DATAFILES از حذف شدن این فایلها، ممانعت خواهد کرد.

مدیریت کاربران در PDB:

در محیط multitenant، می توان دو نوع user ایجاد کرد :

کاربر محلی(local user):تنها در یک PDB ایجاد می شود(در ROOT container قابل ایجاد نیست) و در PDBهای دیگر اعتباری ندارد همچنین هر کاربر محلی تنها می تواند اطلاعات PDB مربوط به خودش را ببیند(با توجه به میزان دسترسی کاربر) که این موضوع از لحاظ امنیتی، یک امتیاز محسوب می شود.

ایجاد کاربر محلی:

sqlplus “sys/sys@pdb1 as sysdba”
SQL> create user usef2 identified by usef2;
User created.

اعطای مجوز به کاربر محلی:

SQL> grant connect to usef2 ;
Grant succeeded.

کاربر عمومی(common user): در سطح ROOT container شناخته می شود و می توان با استفاده از آن، pdbها را مدیریت کرد اسامی این نوع از کاربرها، به صورت پیش فرض، با عبارت ##C شروع می شوند. برای انجام کارهای مدیریتی از قبیل plug/unplug، باز و بسته کردن PDB و … باید از کاربر عمومی استفاده کرد.

ایجاد کاربر عمومی:

SQL> create user c##usef identified by usef;
User created.

اعطای مجوز به کاربر عمومی:

SQL> grant connect to c##usef container=all;
Grant succeeded.

عبارت CONTAINER=ALL سبب می شود تا این کاربر بتواند به همه pdbها دسترسی داشته باشد.

نمایش لیست کاربران عمومی:

SQL>  col USERNAME format a30;
SQL> select con_id,username,common from cdb_users where username like’C##%’;
CON_ID USERNAME                       COM
———- —————————— —
1 C##usef                        YES
4 C##usef                        YES

طریقه حذف این دو نوع کاربران، با هم تفاوتی ندارد:

SQL>drop user  c##usef;
SQL>drop user usef2;

نکته: تقسیم بندی مربوط به انواع کاربران، در مورد roleها هم صدق می کند یعنی دو نوع role به اسامی محلی و عمومی وجود دارد که role محلی در سطح PDB تعریف می شود و خارج از آن PDB تعریف نشده خواهد بود و roleهای عمومی در سطح همه containerها شناخته شده هستند و تنها توسط کاربران عمومی در root container قابل تعریف هستند.
دستورات ایجاد role:

SQL>create role c##glob_usef;
SQL>create role loc_usef;

اعطای مجوز به roleها:

–in CDB$ROOT:
SQL>grant connect to  c##glob_usef;
–in CDB$ROOT:

SQL>grant connect to  loc_usef;
–OR
SQL>grant c##glob_usef to loc_usef;

مدیریت tablespace در PDB

همانطور که قبلا بیان شد، هر pdb به صورت اختصاصی tablespaceهایی دارد که قرار است اطلاعات اصلی سازمانها در ان قرار بگیرند. بعضی از دستورات مدیریت tablespaceها و دیتافایلها در این محیط، با شکل ان در محیط non-CDB تفاوتهایی دارد که در ادامه به بعضی از انها اشاره خواهیم کرد:

ایجاد tablespace در یک pdb:

SQL>create tablespace usef_tbs1 datafile ‘+DATA01’ size 100m;

تغییر tablespace پیش فرض یک pdb:

SQL>ALTER PLUGGABLE DATABASE DEFAULT TABLESPACE octbs;

تعیین حجم حداکثری برای همه tablespaceهای یک pdb:

SQL>ALTER PLUGGABLE DATABASE STORAGE (MAXSIZE 4G);

لغو محدودیت قبلی:

SQL>ALTER PLUGGABLE DATABASE STORAGE (MAXSIZE unlimited);

البته این کار برای temp هم امکان پذیر است برای مثال، حداکثر میزان فضایی که هر PDB می تواند از shared temporary tablespace استفاده کند، با دستور زیر قابل تعیین است:

SQL>ALTER PLUGGABLE DATABASE STORAGE (MAX_SHARED_TEMP_SIZE 50M);

تغییر اندازه یک datafile:

SQL>ALTER PLUGGABLE DATABASE PDB_USEF datafile  12 resize 500m;

offline کردن یک datafile:

SQL>ALTER PLUGGABLE DATABASE PDB_USEF datafile  15 offline ;

ایجاد یک temporary tablespace جدید برای یک PDB:

SQL>create TEMPORARY TABLESPACE ttt tempfile ‘+DATA01’ size 100m;

تغییر temp tablespace پیش فرض:

SQL>ALTER PLUGGABLE DATABASE DEFAULT TEMPORARY TABLESPACE ttt;

نکته: هر کدام از PDBها را می توان به صورت مجزا در حالت begin backup قرار داد:

SQL>ALTER PLUGGABLE DATABASE PDB_USEF  begin backup;

پارامترها در CDB

در محیط Multitenant می توان مقادیر بعضی از پارامترها را در سطح یک pdb تغییر مقدار داد که با دستور زیر، می توان لیستی کاملی از این پارامترها را مشاهده کرد:

SQL>select  * from v$parameter where  ispdb_modifiable=‘TRUE’

برای مثال می توان مقدار پارامتر open_cursors را در سطح یک pdb تغییر داد:

SQL>alter system set open_cursors=5000;

این تغییر در data dictionary باقی مانده و با راه اندازی مجدد(restart) بانک، از بین نمی رود.

با دستور زیر می توان مقدار این پارامتر را در سطوح مختلف ملاحظه کرد:

SQL>select VALUE, ISPDB_MODIFIABLE, CON_ID from V$SYSTEM_PARAMETER where name =’open_cursors’;
1000       TRUE       0
5000       TRUE       3

همچنین جدولی با اسم $PDB_SPFILE هم وجود دارد که مقادیر مربوط به پارامترهای مرتبط با pdbهای مختلف را نشان می دهد:

SQL>select container.name container_name, par.name PARAMETER, par.value$ from pdb_spfile$ par, v$containers container where par.pdb_uid = container.con_uid and par.name = ‘open_cursors’;
CONTAINER_ PARAMETER            VALUE$
———- ——————– ————
PDB_USEF   open_cursors         5000

روش دیگر برای مشاهده مقدار فعلی یک پارامتر در یک pdb، اتصال به آن pdb و اجرای دستور زیر می باشد:

SQL>show parameter open_cursors

unplug/plug کردن pdb:

یکی از مزیتهای استفاده از pluggable databaseها، راحتی در plug/unplug کردن آنها می باشد که در ادامه، شیوه انجام آن، بیان خواهد شد.

برای unplug کردن یک pdb، ابتدا باید آن pdb را در حالت close قرار داد:

SQL>show pdbs
SQL>alter pluggable database PDB1  close instances=all;

سپس دستور زیر را اجرا می کنیم که با استفاده از این دستور، فایل xmlای که حاوی اطلاعات متاداده می باشد، ساخته خواهد شد و می توان با استفاده از آن، دوباره این PDB را plug کرد.

SQL>alter pluggable database pdb1 unplug into ‘/u01/oracle/oradata/USEF_CDB/pdb1/datafile/pdb1.xml‘;
Pluggable database altered.

دو حالت برای plug کردن pdb منفصل شده قابل تصور است: plug به همان بانک قبلی و یا به یک بانک جدید.

شیوه plug کردن یک pdb را در قسمت زیر مشاهده می کنید:

SQL> Create pluggable database pdb1 using ‘/u01/oracle/oradata/USEF_CDB/pdb1/datafile/pdb1.xml’ nocopy;
Pluggable database created.

SQL>  alter pluggable database pdb1 open;
Pluggable database altered.

SQL> select count(*) from usef.tbl1;
200000

انتقال از non-cdb به cdb:

برای انتقال بانک از حالت non-cdb به حالت cdb، روشهای مختلفی وجود دارد از قبیل:

expdp/impdp، TTS، استفاده از پکیج DBMS_PDB و replication

آسان ترین روش انجام این کار، استفاده از پکیج DBMS_PDB می باشد و استفاده از Replication هم پیچیدگی کار را بیشتر خواهد کرد. در ادامه نحوه انجام انتقال از non-cdb به cdb با کمک بسته DBMS_PDB توضیح داده شده است.

 

DBMS_PDB

در این روش با استفاده از پروسیجر describe، یک فایل XML ایجاد می شود و در نهایت از طریق این فایل، می توان بانک اطلاعاتی را به صورت یک pdb به یک CDB متصل نمود. مراحل انجام این کار، به صورت زیر می باشد:

توجه!!! برای استفاده از این پکیج، بانک اطلاعاتی باید در نسخه 12c قرار داشته باشد.

ابتدا بانک non-cdb را در حالت فقط خواندنی قرار می دهیم تا کسی نتواند تغییرات جدیدی در بانک ایجاد کند.

–non-cdb

SQL> SHUTDOWN IMMEDIATE;
SQL>STARTUP OPEN READ ONLY;

متاداده مربوط به بانک را در یک فایل xml ذخیره می کنیم تا با کمک آن، pdb جدیدی را در بانک CDB ایجاد کنیم. این فایل شامل مشخصات دیتافایلها می باشد:

BEGIN
DBMS_PDB.DESCRIBE(
pdb_descr_file => ‘/u01/oracle/oradata/USEF_NONCDB/datafile/non-cdb.xml’);
END;
/

بعد از ایجاد فایل xml، بانک را shutdown می کنیم:

SQL>SHUTDOWN IMMEDIATE;

ادامه مراحل را در بانک cdb پی می گیریم:

به بانک cdb متصل شده و pdbای را با استفاده از فایل xml ایجاد می کنیم.

SQL>create pluggable database non_cdb as clone USING  ‘/u01/oracle/oradata/USEF_NONCDB/datafile/non-cdb.xml’ NOCOPY TEMPFILE REUSE;

همانطور که در قسمت زیر می بینید، بانک non-cdb به یکی از pdbهای بانک cdb تبدیل شده است.

SQL> show pdbs
CON_ID CON_NAME                       OPEN MODE  RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED                       READ ONLY  NO
3 USEF_CDB1                      READ WRITE NO
4 NON_CDB                        MOUNTED

برای اتصال به این pdb، فایل tnsnames.ora را تنظیم می کنیم.

NON_CDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhosts)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = NON_CDB)  ) )

زمانی که یک بانک non-cdb را به محیط CDB منتقل می کنیم، باید اطلاعاتی که در این محیط کاربردی ندارند را حذف کنیم و تغییراتی را در این pdb جدید اعمال کنیم، این کار با اجرای اسکریپت زیر، قابل انجام است:

SQL>alter session set container=NON_CDB;
SQL>@$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql

حال pdb را در حالت open قرار می دهیم.

SQL> alter pluggable database non_cdb open;
Pluggable database altered.

SQL> show pdbs
CON_ID CON_NAME                       OPEN MODE  RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED                       READ ONLY  NO
3 USEF_CDB1                      READ WRITE NO
4 NON_CDB                        READ WRITE NO

PDB و rman

بکاپ گیری از یک pdb به صورت مستقل از pdbهای دیگر، قابل انجام است و همچنین می توان در سطح یک pdb عملیات restore را انجام داد منتها باید قبل از انجام عملیات restore، کانتیر ROOT را هم بازیابی کرده باشیم.

عملیات بکاپ/ریکاوری از طریق اتصال به CDB$ROOT و یا با اتصال به یک PDB خاص قابل انجام است و همچنین دستورات مورد استفاده در نسخه های قبلی اوراکل، اعم از  BACKUP DATABASE،  RESTORE DATABASE، RECOVER DATABASE در این محیط هم قابل استفاده می باشند و متناسب با نحوه ورود به RMAN، عملکرد خواهند داشت به طور مثال، اگر با دستور زیر به محیط RMAN لاگین گنیم، تنها برای PDB1 بکاپ و ریکاوری قابل انجام خواهد بود.

rman target “sys/sys@pdb1”

در صورت ورود با دستور زیر، دامنه کاری RMAN برابر با کل CDB خواهد شد:

rman target /

برای انکه از همه pdbها به همرا ROOT container بکاپ گرفته شود، می توان از دستور زیر استفاده کرد:

rman target /
RMAN> BACKUP DATABASE;

در ادامه با دستورهای اختصاصی rman در محیط Multitenant آشنا خواهیم شد.

–تهیه بکاپ از ROOT conatiner به تنهایی:

rman target /
RMAN> BACKUP PLUGGABLE DATABASE “CDB$ROOT”;

–بکاپ گیری از ROOT container بعلاوه یک PDB خاص:

rman target /
RMAN> BACKUP PLUGGABLE DATABASE “CDB$ROOT”, pdb1;

–تهیه بکاپ در سطح چند pdb:

rman target /
RMAN> BACKUP PLUGGABLE DATABASE usef_pdb,pdb1;

–بکاپ گیری از یک tablespace مربوط به PDB1:

RMAN> BACKUP TABLESPACE pdb1:users,pdb_usef:tbs1;

سناریوی زیر روال کاملتری از بکاپ گیری و بازیابی یک pdb را نشان می دهد.

SQL> show pdbs
CON_ID CON_NAME                       OPEN MODE  RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED                       READ ONLY  NO
4 PDB1                                MOUNTED

rman target “sys/sys@pdb1”
RMAN> backup database format ‘/u01/oracle/usef_backup/%U.bkp’;

Starting backup at 31-DEC-15
input datafile file number=00012 name=/u01/oracle/oradata/USEF_CDB/pdb1/datafile/sysaux01.dbf
channel ORA_DISK_1: starting piece 1 at 31-DEC-15
input datafile file number=00011 name=/u01/oracle/oradata/USEF_CDB/pdb1/datafile/system01.dbf
channel ORA_DISK_2: starting piece 1 at 31-DEC-15
input datafile file number=00013 name=/u01/oracle/oradata/USEF_CDB/pdb1/datafile/users01.dbf
piece handle=/u01/oracle/usef_backup/0nqq7k9r_1_1.bkp tag=TAG20151231T200619 comment=NONE
channel ORA_DISK_3: backup set complete, elapsed time: 00:00:01
channel ORA_DISK_1: finished piece 1 at 31-DEC-15
piece handle=/u01/oracle/usef_backup/0lqq7k9r_1_1.bkp tag=TAG20151231T200619 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:15
channel ORA_DISK_2: finished piece 1 at 31-DEC-15
piece handle=/u01/oracle/usef_backup/0mqq7k9r_1_1.bkp tag=TAG20151231T200619 comment=NONE
channel ORA_DISK_2: backup set complete, elapsed time: 00:00:15
Finished backup at 31-DEC-15
Starting Control File and SPFILE Autobackup at 31-DEC-15
piece handle=/u01/oracle/fast_recovery_area/USEF_NEW/autobackup/2015_12_31/o1_mf_s_899928394_c8bpdmob_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 31-DEC-15

در اینجا برای انجام تست ریکاوری، تمامی datafileهای مربوط به pdb1 را حذف می کنیم.

rm -rf /u01/oracle/oradata/USEF_CDB/pdb1/datafile/*

در ادامه pdb1 را بازیابی می کنیم.

SQL>shutdown abort
SQL>startup mount
rman target /
RMAN>run{
restore pluggable database PDB1;
recover pluggable database PDB1;
}
Starting restore at 31-DEC-15
channel ORA_DISK_1: restoring datafile 00013 to /u01/oracle/oradata/USEF_CDB/pdb1/datafile/users01.dbf
channel ORA_DISK_1: reading from backup piece /u01/oracle/usef_backup/0nqq7k9r_1_1.bkp
/u01/oracle/oradata/USEF_CDB/pdb1/datafile/system01.dbf
channel ORA_DISK_2: reading from backup piece /u01/oracle/usef_backup/0mqq7k9r_1_1.bkp
channel ORA_DISK_3: restoring datafile 00012 to /u01/oracle/oradata/USEF_CDB/pdb1/datafile/sysaux01.dbf
channel ORA_DISK_3: reading from backup piece /u01/oracle/usef_backup/0lqq7k9r_1_1.bkp
channel ORA_DISK_1: piece handle=/u01/oracle/usef_backup/0nqq7k9r_1_1.bkp tag=TAG20151231T200619
channel ORA_DISK_2: piece handle=/u01/oracle/usef_backup/0mqq7k9r_1_1.bkp tag=TAG20151231T200619
channel ORA_DISK_3: piece handle=/u01/oracle/usef_backup/0lqq7k9r_1_1.bkp tag=TAG20151231T200619
Finished restore at 31-DEC-15
starting media recovery
media recovery complete, elapsed time: 00:00:00

همانطور که می بینید، pdb1 به راحتی بازیابی شد و حال با دستور زیر، pdb1 را در حالت read write قرار می دهیم:

SQL>alter database open;
SQL>alter pluggable database PDB1 open;
SQL> show pdbs
CON_ID CON_NAME                       OPEN MODE  RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED                       READ ONLY  NO
4 PDB1                           READ WRITE NO

نکته 1: برای انتقال فایل به صورت سازگار، در سطح PDB هم می توان از begin backup استفاده کرد:

sqlplus “sys/sys@pdb_usef as sysdba”
SQL>alter pluggable database pdb_usef begin backup;
SQL>alter pluggable database pdb_usef end backup;

نکته 2: instance recovery در سطح CDB انجام می شود و در سطح PDB بی معناست.

SQL>shut abort
Tue Nov 15 11:15:37 2016
ALTER PLUGGABLE DATABASE CLOSE ABORT
Tue Nov 15 11:15:37 2016
Immediate Kill Session#: 305, Serial#: 27992
Immediate Kill Session: sess: 0x11a897930  OS pid: 23293
Immediate Kill Session#: 366, Serial#: 53643
Immediate Kill Session: sess: 0x11b76fed0  OS pid: 23278
ALTER SYSTEM: Flushing buffer cache inst=0 container=4 local
Pluggable database PDB_USEF closed
Completed: ALTER PLUGGABLE DATABASE CLOSE ABORT
SQL>startup
Tue Nov 15 11:16:04 2016
ALTER PLUGGABLE DATABASE  OPEN
Database Characterset for PDB_USEF is AR8MSWIN1256
Opening pdb PDB_USEF (4) with no Resource Manager plan active
Tue Nov 15 11:16:09 2016
Pluggable database PDB_USEF opened read write
Completed: ALTER PLUGGABLE DATABASE  OPEN

سناریوهای بازیابی در صورت خرابی فایلها:

Temp File: از دست رفتن temp datafile در سطح CDB و PDB مسئله مهمی نخواهد بود و با راه اندازی مجدد instance، دوباره ایجاد می شود همچنین می توان آن را به صورت دستی ایجاد کرد.

SQL>create TEMPORARY TABLESPACE fff tempfile ‘/u01/oracle/temp01.dbf’ size 100m;
SQL>ALTER PLUGGABLE DATABASE DEFAULT TEMPORARY TABLESPACE fff;
SQL>rm -rf /u01/oracle/temp01.dbf
SQL>select * from source$ f,source$ g order by 1,2,3;
ERROR at line 1:
ORA-01116: error in opening database file 206
ORA-01110: data file 206: ‘/u01/oracle/temp01.dbf’
ORA-27041: unable to open file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3
startup force   èPDB_USEF
diag_adl:Re-creating tempfile /u01/oracle/temp01.dbf

Control File: سناریوی بازیابی کنترل فایل در این محیط شبیه به محیط non-CDB می باشد و pdb در این مورد نقشی ندارد:

RMAN> backup as copy current controlfile format ‘/u01/oracle/cont.ctl’;
rm -rf Current.260.916159377
rman target /
RMAN> STARTUP NOMOUNT;
RMAN> restore controlfile to  ‘+DATA01/USEF/CONTROLFILE/current.260.916159377’  from ‘/u01/oracle/cont.ctl’;
channel ORA_DISK_1: copied control file copy
Finished restore at 15-NOV-16
RMAN> RECOVER DATABASE;
RMAN> ALTER DATABASE OPEN RESETLOGS;

Redo Log File: سناریوی بازیابی redo log در این محیط شبیه به محیط non-CDB می باشد.
Root SYSTEM : سناریوی بازیابی شبیه به بانک non-CDB می باشد و pdb در این مورد موثر نیست. در اینجا نیاز به down time در حد کل بانک الزامی می باشد.

rm -rf +DATA01/USEF/DATAFILE/system.257.916159259
RMAN> STARTUP MOUNT;
RMAN> RESTORE datafile 1;
Full restore complete of datafile 1 +DATA01/USEF/DATAFILE/system.257.927981743.  Elapsed time: 0:00:11
checkpoint is 10326682
last deallocation scn is 2858459
Undo Optimization current scn is 368200
RMAN> recover datafile 1;
alter database open;
ALTER PLUGGABLE DATABASE ALL OPEN;

Root SYSAUX: در این صورت تنها downtime در سطح sysaux tablespace خواهیم داشت:

rm -rf +DATA01/USEF/DATAFILE/sysaux.256.916159217
startup mount
alter database datafile 3 offline;
ALTER TABLESPACE sysaux OFFLINE IMMEDIATE;
RMAN> RESTORE TABLESPACE sysaux;
Full restore complete of datafile 3 +DATA01/USEF/DATAFILE/sysaux.256.927983875.  Elapsed time: 0:00:34
checkpoint is 10528705
last deallocation scn is 10321079
RMAN> RECOVER TABLESPACE sysaux;
ALTER TABLESPACE sysaux ONLINE;

PDB SYSTEM: با از دست دادن دیتافایل system یکی از pdbها، CDB باز می شود و تنها pdb مربوطه در حالت mount باقی خواهد ماند:

rm -rf +DATA01/USEF/376BF99919E53E22E055000000000001/DATAFILE/system.277.917005283
startup force;
alter pluggable database all open;
SQL> show pdbs
CON_ID CON_NAME                       OPEN MODE  RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED                       READ ONLY  NO
3 PDB1                           READ WRITE NO
4 PDB_USEF                       MOUNTED

برای رفع مشکل باید:

rman target sys/sys@pdb_usef
RMAN> RESTORE datafile 12;
RMAN> recover database;
alter database open;

PDB Non-SYSTEM: سناریوی بازیابی شبیه به بانک non-CDB می باشد.

 

flashback و PDB

 

در نسخه 12cR1، عملیات flashback در سطح کل بانک اعمال می شود و فعال/غیرفعال کردن ان در سطح pdb امکان پذیر نمی باشد. برای فعال کردن flashback database در سطح CDB، می توان مشابه نسخه های قبلی دستورات زیر را وارد کرد:

SQL>SHUTDOWN IMMEDIATE
SQL>STARTUP MOUNT
SQL>alter system set db_recovery_file_dest_size=5g ;
SQL>alter system set db_recovery_file_dest=’/u01/oracle/flash’;
SQL>ALTER SYSTEM SET  DB_FLASHBACK_RETENTION_TARGET=555;
SQL>ALTER DATABASE FLASHBACK ON;
SQL>ALTER DATABASE OPEN;

توجه:با ارائه قابلیت local undo tablespace در نسخه 12cR2، می توان flashback را در سطح یک pdb هم اجرا کرد.

مثال زیر را ببینید.
ابتدا جدولی ایجاد می کنیم:

sqlplus “usef/abc@pdb_usef”
SQL>create table new as select name from v$datafile;

برای انجام تست، نیاز است تا مقدار جاری scn را مشخص کنیم:

SQL>select l.current_scn from v$database l;
10838992

جدول ایجاد شده را حذف می کنیم:

SQL>drop table new;

عملیات flashback را در سطح بانک اطلاعاتی انجام می دهیم:

SQL>STARTUP MOUNT force;
SQL>FLASHBACK DATABASE TO SCN 10838992;

برای اطمینان از صحت کار، بانک را با دستور زیر باز می کنیم:

SQL>ALTER DATABASE OPEN READ ONLY;
SQL>ALTER PLUGGABLE DATABASE ALL OPEN READ ONLY;

بعد از حصول اطمینان، در نهایت بانک اطلاعاتی را برای اعمال تغییرات باز می کنیم:

SQL>alter database open resetlogs;
SQL>ALTER PLUGGABLE DATABASE ALL OPEN;

سرانجام بررسی می کنیم جدول محذوف بازیابی شده است یا خیر؟

SQL>select * from new;
+DATA01/USEF/DATAFILE/undotbs1.259.916159325
+DATA01/USEF/376BF99919E53E22E055000000000001/DATAFILE/system.277.927989403
+DATA01/USEF/376BF99919E53E22E055000000000001/DATAFILE/sysaux.279.917005289
+DATA01/USEF/376BF99919E53E22E055000000000001/DATAFILE/usef_tbs1.282.927896327

CDB و data guard

طریقه راه اندازی data gurad در محیط CDB همانند محیط non-CDB می باشد یعنی به همان شیوه سابق می توان از طریق duplicate برای کل بانک اطلاعاتی data guard پیاده سازی کرد. نمونه ای از logهای مربوط به ایجاد data guard را در ادامه خواهیم دید:

channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00001 to +DATA02
channel ORA_AUX_DISK_2: starting datafile backup set restore
channel ORA_AUX_DISK_2: using network backup set from service usef
channel ORA_AUX_DISK_2: specifying datafile(s) to restore from backup set
…..
channel ORA_AUX_DISK_2: restore complete, elapsed time: 00:00:40
…..
datafile 1 switched to datafile copy
input datafile copy RECID=13 STAMP=928145087 file name=+DATA02/SS/DATAFILE/system.260.928145019

در صورتی که در بانک اطلاعاتی pdb جدیدی ساخته شود، به صورت خودکار این pdb درactive data guard هم ایجاد می شود. فرض کنید در محیط primary با دستور زیر pdb جدیدی را ایجاد کردیم:

SQL>CREATE PLUGGABLE DATABASE pdb_usef ADMIN USER us IDENTIFIED BY usef;

حال با رجوع به alert log مربوط به data guard، نحوه ایجاد این pdb در محیط data guard را خواهیم دید:

Recovery created pluggable database PDB_USEF
Recovery copied files for tablespace SYSTEM
Recovery successfully copied file +DATA02/SS/417EF3C2D7971FC7E053049B200A354A/DATAFILE/system.289.928148081 from +DATA02/SS/4168D3E589657BC7E053049B200A4A00/DATAFILE/system.261.928145031
Successfully added datafile 12 to media recovery
Datafile #12: ‘+DATA02/SS/417EF3C2D7971FC7E053049B200A354A/DATAFILE/system.289.928148081’
Thu Nov 17 10:55:02 2016
Recovery copied files for tablespace SYSAUX
Recovery successfully copied file +DATA02/SS/417EF3C2D7971FC7E053049B200A354A/DATAFILE/sysaux.290.928148087 from +DATA02/SS/4168D3E589657BC7E053049B200A4A00/DATAFILE/sysaux.265.928145035
Thu Nov 17 10:55:02 2016
Successfully added datafile 13 to media recovery
Datafile #13: ‘+DATA02/SS/417EF3C2D7971FC7E053049B200A354A/DATAFILE/sysaux.290.928148087’
Media Recovery Waiting for thread 1 sequence 40 (in transit)

دستور زیر نشان می دهد که این pdb در محیط data guard هم اعمال شده است:

SQL> show pdbs
CON_ID CON_NAME                       OPEN MODE  RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED                       READ ONLY  NO
3 USEF_PDB                       READ ONLY  NO
4 PDB_USEF                       MOUNTED

برای مطالعه بیشتر در این زمینه، می توانید مطلب چالشهای دیتاگارد در محیط Multitenant را مطالعه بفرمایید.

CDB و RAC

وضیعت هر یک از pdbها متناسب  با هر instance می تواند متفاوت باشد به طور مثال pdb1 می تواند در instance 1 در حالت open قرار بگیرد و در instance 2 در حالت mount قرار داشته باشد. برای دیدن وضیعت هر pdb در instanceهای مختلف، می توانیم از ویوی gv$pdbs استفاده کنیم:

SQL> select inst_id,name,open_mode from gv$pdbs where name =’USEF_PDB’;
INST_ID NAME                           OPEN_MODE
———- —————————— ———-
1 pdb1                       MOUNTED
2 pdb1                       READ WRITE

در زیر تعدادی از دستور مدیریت pdbها را در محیط rac مشاهده می کنید:

–باز کردن pdb1 در instance شماره یک:

SQL> ALTER PLUGGABLE DATABASE usef_pdb OPEN READ WRITE INSTANCES =(‘node1’);

–باز کردن pdb در همه instanceها:

SQL> alter pluggable database all open  instances=all;

–افزودن سرویس برای یک pdb خاص:

SQL> srvctl add service -d usef -pdb pdb1 -s p_srv -r node1 -a node2-P BASIC

Comments (3)

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.