برگرداندن بکاپ PDB در یک CDB جدید!

مطابق با داکیومنتهای اوراکل در زمینه Backup/Recovery، برای برگرداندن یک PDB ابتدا باید بکاپ CDB مربوط به آن PDB را برگرداند در غیر این صورت امکان برگرداندن PDB وجود ندارد! اما در این متن با روش جدیدی آشنا خواهیم شد که امکان برگرداندن بکاپ PDB را در یک CDB جدید فراهم می کند. البته این روش همیشه جواب نمی دهد و بهتر است که در سناریو بکاپ و ریکاوری این موضوع را در نظر داشته باشیم.

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

بکاپ از RmanPDB:

Connected to:
Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
SQL> show pdbs
    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         5 PDB1                           READ WRITE NO
         4 RMANPDB                        READ WRITE NO
RMAN> backup pluggable database RmanPDB format '/oracle21c/bkp_pdb/%U' current controlfile  format '/oracle21c/bkp_pdb/control0000.bkp';
Starting backup at 16-OCT-21
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=266 device type=DISK
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00068 name=/oracle21c/base/oradata/DB21C/CE75C2880CCD2A3FE0530488200A29C8/datafile/o1_mf_sysaux_jpo62lhz_.dbf
input datafile file number=00067 name=/oracle21c/base/oradata/DB21C/CE75C2880CCD2A3FE0530488200A29C8/datafile/o1_mf_system_jpo62lhv_.dbf
input datafile file number=00069 name=/oracle21c/base/oradata/DB21C/CE75C2880CCD2A3FE0530488200A29C8/datafile/o1_mf_undotbs1_jpo62lj1_.dbf
input datafile file number=00070 name=/oracle21c/base/oradata/DB21C/CE75C2880CCD2A3FE0530488200A29C8/datafile/o1_mf_tbs01_jpo66vjx_.dbf
channel ORA_DISK_1: starting piece 1 at 16-OCT-21
channel ORA_DISK_1: finished piece 1 at 16-OCT-21
piece handle=/oracle21c/bkp_pdb/4p0bo4mu_153_1_1 tag=TAG20211016T052342 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
including current control file in backup set
channel ORA_DISK_1: starting piece 1 at 16-OCT-21
channel ORA_DISK_1: finished piece 1 at 16-OCT-21
piece handle=/oracle21c/bkp_pdb/control0000.bkp tag=TAG20211016T052342 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 16-OCT-21

(بیشتر…)

JSON Multivalue index در اوراکل 21c

در متن “JSON و دیتابیس اوراکل” توضیح دادیم که چگونه اوراکل در نسخه 12c امکان ذخیره و کنترل اطلاعات JSON را در قالب دیتاتایپ CLOB، varchar و … فراهم کرده است و همچنین مطالبی را در مورد نحوه ایندکس گذاری کلیدهای JSON ارائه کرده ایم(برای مطالعه). در نسخه 21c بهبودهای دیگری نظیر نوع داده JSON، تابع JSON_TRANSFORM و … هم به این مجموعه قابلیتها اضافه شد که قبلا بعضی از آنها را مستند کرده ایم و در این متن قصد داریم در مورد یکی دیگر از این قابلیتها که JSON Multi value index است، نکاتی را بنویسیم.

می دانیم که قرار نیست ما به ازای هر کلید در JSON، صرفا یک مقدار ذخیره شود و در مواردی ممکن است مقدار یک کلید، یک آرایه(یا همان لیست) باشد. در این شرایط استفاده از روشهای قبلی ایندکس گذاری برای جستجو چندان کارآمد نخواهند بود و باید به دنبال روش جدیدی برای این حالت باشیم. در ادامه با ارائه مثالی، بیشتر این موضوع را توضیح خواهیم داد.

(بیشتر…)

تابع checksum در اوراکل 21c

در نسخه 12c، اوراکل با ارائه تابع STANDARD_HASH، امکان محاسبه hash value را برای یک فیلد و یا عبارت فراهم کرده است:

SQL> select id,salary,substr(STANDARD_HASH(id||salary),1,20) hash_id_sal from tbl1;
        ID     SALARY HASH_ID_SAL
---------- ---------- ----------------------
         1         10 5E796E48332AF4142B10
         2         12 E2154FEA5DA2DD0D1732
         3         17 F44A286F486D11990238
         4         18 93AC1946CB917ABC4735

با این روش می توانیم از تغییر مقدار سطرهای جدول باخبر شویم. البته در نسخه های قبل از 12c هم می توانستیم از توابع دیگری نظیر ora_hash بدین منظور استفاده کنیم:

SQL> select id,salary,ora_hash(id||salary)  hash_id_sal from tbl1;

        ID     SALARY HASH_ID_SAL
---------- ---------- -----------
         1         10  3316966336
         2         12  1402677848
         3         17  3795753203
         4         18   936769390

در نسخه 21c هم قابلیت جدیدی در این زمینه ارائه شد و اوراکل با معرفی تابع checksum، امکان شناسایی تغییر دیتا را در سطح ستون فراهم کرده است.

(بیشتر…)

اوراکل 21c – پشتیبانی از شرط نامساوی در Automatic Indexing

قابلیت auto indexing در اوراکل نسخه 19c شرط عدم تساوی را پشتیبانی نمی کند که قبلا در این مورد مطلبی را ارائه کرده ایم. نسخه 21c این قابلیت را فراهم کرده است که در ادامه این مسئله را می بینید.

برای نمایش این محدودیت، جدولی را همراه با حجم قابل توجهی از اطلاعات ایجاد می کنیم:

SQL> create table tb(id number,name varchar2(100),date_time date,c1 varchar2(4000),c2 varchar2(4000));
Table created
SQL> insert into tb select rownum,'test'||’’||rownum,sysdate - rownum,rpad('test',400,'c1'),rpad('test',400,'c2') from dual connect by level <=666444;
666444 rows inserted
SQL> commit;
Commit complete
SQL> exec dbms_stats.gather_table_stats(ownname => user,tabname => 'TB');
PL/SQL procedure successfully completed

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

Select count(*) from tb where id between 1 and 10;

همچنین با اجرای بلاک plsql زیر، سعی در مجاب کردن اوراکل برای بررسی این پرس و جو داریم:

declare
  temp number;
begin
  for a in 1 .. 1000 loop
    select count(*) into temp from tb where id between 1 and 10;
  end loop;
end;

پس از گذشت interval پانزده دقیقه ای، گزارشی از آخرین اجرا را می بینیم:

select DBMS_AUTO_INDEX.REPORT_ACTIVITY(SYSTIMESTAMP-1,SYSTIMESTAMP,'HTML','ALL','ALL') from dual;

با اجرای دستور زیر خواهیم دید که بر روی ستون id ایندکسی ایجاد شده است:

select owner,index_name,table_name,auto from dba_indexes where AUTO='YES';

قابلیتهای جدید اوراکل 21c در زمینه عملگرهای مجموعه ای

تا قبل از نسخه 21c، صرفا می توانستیم از سه عملگر مجموعه ای INTERSECT، MINUS و UNION [ALL] در اوراکل استفاده کنیم اما در نسخه 21c دو عملگر جدید EXCEPT و EXCEPT ALL به این مجموعه اضافه شدند که این دو عملگر معادل عملگرهای MINUS و MINUS ALL هستند و صرفا به دلیل استفاده از عبارتهای EXCEPT و EXCEPT ALL در دیتابیسهای دیگر، اوراکل هم این دو عملگر را به مجموعه عملگرهای خود اضافه کرده است.

مجددا تاکید می شود که در عمل تفاوتی بین EXCEPT و MINUS وجود ندارد و حتی در صورت استفاده از عملگر EXCEPT، اوراکل در زمان اجرای پرس و جو، در مرحله Query Transformation، عملگر EXCEPT را به MINUS تبدیل می کند.

با این توضیحات، در شرایط زیر، برای برگرداندن رکوردهایی که در t1.c1 وجود دارند اما در t2.c1 وجود ندارد(با حذف رکوردهای تکراری!!) دو انتخاب داریم، عملگرEXCEPT و عملگر MINUS:

select t1.c1 from t1
MINUS
select t2.c1 from t2;
D
Z
select t1.c1 from t1
EXCEPT
select t2.c1 from t2;
D
Z

(بیشتر…)

اوراکل 21c – بازگرداندن دیتابیس به هر زمانی در گذشته

اوراکل در نسخه 19c اجازه نمی دهد که یک pdb را به زمانی از یک ORPHAN incarnation برگردانیم:

SQL*Plus: Release 19.0.0.0.0 - Production on Thu Apr 21 08:28:57 2022
Version 19.3.0.0.0
SQL>  SELECT con_id, status, pdb_incarnation# inc#, begin_resetlogs_scn, end_resetlogs_scn FROM v$pdb_incarnation ORDER BY 3;
    CON_ID STATUS        INC# BEGIN_RESETLOGS_SCN END_RESETLOGS_SCN
---------- ------- ---------- ------------------- -----------------
         3 PARENT           0             1920977           1920977
         3 ORPHAN           1             1963437           1963437
         3 CURRENT          2             1964176           1964176
SQL>  alter pluggable database pdb1401 close;
Pluggable database altered.
SQL> flashback pluggable database to scn 1962565;
ORA-39889: Specified System Change Number (SCN) or timestamp is in the middle of a previous PDB RESETLOGS operation.
SQL> flashback pluggable database PDB1401  to scn 1963437;
ORA-39889: Specified System Change Number (SCN) or timestamp is in the middle of a previous PDB RESETLOGS operation.
[oracle@stb ~]$ rman target sys/sys@192.168.1.20:1521/pdb1401
RMAN> reset pluggable database pdb1401  to incarnation 1;
'RMAN-07536: command not allowed when connected to a Pluggable Database'

اما در نسخه 21c این قابلیت به وجود آمد تا بتوان یک PDB را به هر زمانی در گذشته برگرداند(البته گذشته نزدیک). در ادامه با سناریوی زیر و با ایجاد یک ORPHAN incarnation بیشتر با این فیچر را آشنا خواهیم شد.

(بیشتر…)

اوراکل 21c – انجام auditing بر اساس current user

ستونهای DBUSERNAME و CURRENT_USER در ویوی unified_audit_trail شباهت زیادی به هم دارند و در بسیاری از مواقع، این دو ستون حاوی اطلاعات یکسانی هستند. معمولا در این ستونها نام کاربری که به دیتابیس لاگین کرده و دستور را اجرا نموده است ، ذخیره می شود.

مگر آنکه کاربر متصل به دیتابیس با حقوق definer(یا همان definer right)، دستوری را اجرا کند، که در این صورت، نام کاربر متصل به دیتابیس در ستون DBUSERNAME ثبت می شود و نام کاربر definer که مجری واقعی دستور بوده در ستون CURRENT_USER ذخیره می شود.

*برای آشنایی بیشتر با مفهوم definer right و  invoker right پیشنهاد می شود مطلب بررسی Invoker’s Rights و Definer’s Rights را مطالعه کنید.

برای مثال، کاربر A پروسیجر زیر را به صورت definer right تعریف کرده است:

create or replace procedure prc1 authid definer as
  id_var number;
begin
  select object_id into id_var from usef.tbl1 where object_name = ‘TB’;
end;
/

(بیشتر…)

بهبودهای حلقه تکرار FOR در اوراکل 21c

با فرمت حلقه FOR آشنا هستید:

FOR loop_counter IN [REVERSE] lowest_number..highest_number
LOOP
   {...statements...}
END LOOP;

مطابق این syntax، قرار است شمارنده(loop_counter) به صورت ترتیبی(با گام یک) از نقطه lowest_number به نقطه highest_number برسد. برای مثال، با اجرای قطعه کد زیر، اعداد 4 تا 8 نمایش داده می شوند:

SQL> set serveroutput on
begin
  for i in 4 .. 8 loop
    dbms_output.put_line(i);
  end loop;
end;
/
4
5
6
7
8
PL/SQL procedure successfully completed.


(بیشتر…)

تابع ANY_VALUE در اوراکل 21c

ANY_VALUE تابع جدیدی است که در اوراکل 21c معرفی شده و البته در Release Updateهای انتهایی اوراکل نسخه 19c(یعنی از 19.8 به بالا) هم قابل استفاده است. در متن پیش رو با این تابع آشنا خواهیم شد.

*پرس و جوی زیر در pdb1 اجرا می شود و قرار است مشخص کند هر tablespace چند دیتافایل دارد:

select t.ts#, t.name, count(*) "Tedad_DataFile"
  from v$datafile d, v$tablespace t
 where t.ts# = d.ts#
 group by t.ts#, t.name;

همانطور که مشاهده می کنید، در پرس و جوی فوق هر دو ستون ts# و name در قسمت group by قید شده اند در صورتی که عدم درج ستون name در قسمت group by، تغییری در خروجی ایجاد نمی کند اما اوراکل اجازه این کار را به ما نمی دهد:

ORA-00979: not a GROUP BY expression

(بیشتر…)

اوراکل 21c – بهبودهای ابزار AutoUpgrade در زمینه RAC

در نسخه 21c، اوراکل قابلیتهای جدیدی را در زمینه ابزار Autoupgrade ارائه کرده است که قبلا در مورد بعضی از آنها مطالبی را نوشته ایم. یکی دیگر از بهبودهای(البته جزئی) ابزار AutoUpgrade در نسخه 21c، خودکارسازی بعضی از مراحل ارتقا دیتابیس RAC است.

در نسخه های قبل از اوراکل 21c، برای ارتقا دیتابیس RAC، می بایست مراحل زیر به صورت دستی انجام شود:

1.تنظیم پارامتر CLUSTER_DATABASE به مقدار FALSE

2.متوقف کردن instanceهای حاضر در کلاستر

3.استارت یکی از instanceها برای شروع عملیات ارتقا

4. تنظیم مجدد پارامتر CLUSTER_DATABASE به مقدار TRUE بعد از اتمام ارتقا

5.استارت همه instanceها

5.رجیستر کردن نسخه جدید در کلاستر

این عملیات در نسخه 21c به صورت خودکار توسط ابزار AutoUpgrade مدیریت می شود(البته این قابلیت بعدا در اوراکل نسخه 19.8 به بالا هم اضافه شد).

(بیشتر…)