ذخیره AWR snapshot خارج از SYSAUX

همانطور که می دانید AWR snapshotها در SYSAUX tablespace ذخیره می شوند و تا نسخه 19c نمی توان آنها را در tablespace مجزایی ذخیره کرد. این امکان در نسخه 19c با اضافه شدن پارامتر TABLESPACE_NAME به پروسیجر dbms_workload_repository.modify_snapshot_settings به وجود آمد.

Connected to Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 
SQL> desc dbms_workload_repository.modify_snapshot_settings
Parameter       Type     Mode Default? 
--------------- -------- ---- -------- 
RETENTION       NUMBER   IN   Y        
INTERVAL        NUMBER   IN   Y        
TOPNSQL         NUMBER   IN   Y        
DBID            NUMBER   IN   Y        
TABLESPACE_NAME VARCHAR2 IN   Y        
RETENTION       NUMBER   IN   Y        
INTERVAL        NUMBER   IN   Y        
TOPNSQL         VARCHAR2 IN            
DBID            NUMBER   IN   Y        
TABLESPACE_NAME VARCHAR2 IN   Y      

همچنین اوراکل در نسخه 21c ستون TABLESPACE_NAME را به ویوی awr_cdb_wr_control اضافه کرده است که از طریق آن می توانیم tablespace جاری AWR  را مشخص کنیم:

(بیشتر…)

اوراکل 23ai – ایجاد خودکار AWR Snapshot در سطح PDB

در زمان ارائه قابلیت Pluggable Database در نسخه 12cR1،ء AWR snapshotها صرفا در سطح CDB ایجاد می شدند و امکان ایجاد snapshot در سطح PDB وجود نداشت. در نسخه 12cR2 پارامتری به نام awr_pdb_autoflush_enabled اضافه شد که با تنظیم آن به مقدار TRUE، به صورت خودکار در سطح PDB هم AWR snapshot ایجاد می شود اما مقدار پیش فرض این پارامتر تا قبل از نسخه 23ai برابر با FALSE بوده و در نسخه 23ai به صورت پیش فرض فعال می باشد:

SQL*Plus: Release 23.0.0.0.0 - Developer-Release on Thu Sep 7 10:57:00 2023
SQL> show parameter awr_pdb_autoflush_enabled
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
awr_pdb_autoflush_enabled            boolean     TRUE

با این تغییر در صورتی که اسکریپت awrrpt.sql را در هر کدام از PDBها اجرا کنیم، گزینه AWR_PDB مقدار پیش فرض خواهد بود:

Specify the location of AWR Data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AWR PDB reports can be generated using data stored in this PDB or ROOT.
Please enter the desired location at the prompt. Default value is 'AWR_PDB'.
    AWR_PDB  - Use AWR data from PDB
    AWR_ROOT - Use AWR data from ROOT
Enter value for awr_location: AWR_PDB
Location of AWR Data Specified: AWR_PDB

اما در نسخه های قبلی، گزینه AWR_ROOT مقدار پیش فرض بوده است:

Specify the location of AWR Data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AWR_ROOT - Use AWR data from root (default)
AWR_PDB - Use AWR data from PDB
Enter value for awr_location:

برای دیتابیسی با تعداد PDB زیاد و workload بسیار بالا، بهتر است پارامتر awr_snapshot_time_offset را هم در کنار پارامتر awr_pdb_autoflush_enabled تنظیم کنیم تا AWR snapshotها برای همه PDBها به صورت همزمان ایجاد نشوند و با ایجاد وقفه ای هر چند مختصر، از سکته دیتابیس جلوگیری شود.

اوراکل 23ai- شناسایی علت تغییر رفتار Optimizer با استفاده از ویوی DBA_HIST_OPTIMIZER_ENV_DETAILS

تغییر Execution Plan یک کوئری می تواند به دلایل ساده ای مثل حذف و اضافه کردن ایندکس، پارتیشن بندی جدول، پارتیشن بندی ایندکس اتفاق بیفتد اما شناسایی علت تغییر رفتار Optimizer همیشه ساده نیست چرا که در بعضی از موارد تغییر در Optimizer Environment منجر به ایجاد Execution Plan جدید می شود.

برای مثال در sessionای پارامتر OPTIMIZER_INDEX_COST_ADJ که میزان گرایش Optimizer به استفاده از ایندکس را تعیین می کند، به عدد 1 و در session دیگر این پارامتر به مقدار 1000! تنظیم شده است بدون تردید این تفاوت ها در Optimizer Environment، می تواند Execution Plan بعضی از کوئری ها را تغییر دهد.

موضوع این مستند در مورد آن است که چگونه می توانیم تشخیص دهیم تغییر Execution Plan یک کوئری به دلیل تغییر در Optimizer Environment است؟ و به طور دقیق تر، کدام پارامترها و عوامل محیطی منجر به ایجاد Execution Plan جدید شده اند. این کار را با قابلیت جدیدی که اوراکل در نسخه 23c ارائه کرده است، انجام خواهیم داد.

(بیشتر…)

حذف محدودیتهای Parallel DML در اوراکل نسخه 23ai

در نسخه 21c اگر در تراکنشی از Parallel DML استفاده کنیم، امکان گرفتن query و یا اجرای دستورات DML و یا Parallel DML بر روی همان جدول و در همان تراکنش از ما گرفته خواهد شد:

SQL> alter session enable parallel dml;
Session altered.

SQL> insert /*+parallel(10)*/ into tbl1 select * from v$datafile;
1536 rows created.

Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.8.0.0.0

SQL> select count(*) from tbl1;
'ORA-12838: cannot read/modify an object after modifying it in parallel'
SQL> delete tbl1;
'ORA-12838: cannot read/modify an object after modifying it in parallel'

با خاتمه دادن به تراکنش شاهد این خطا نخواهیم بود:

SQL> commit;
Commit complete.

SQL> select count(*) from tbl1;
  COUNT(*)
----------
      6144

SQL> delete tbl1;
6144 rows deleted.

در نسخه 23c این محدودیت برداشته شده و بدون بستن تراکنش می توانیم دستور فوق را اجرا کنیم:

Oracle Database 23c Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.3.0.23.09

SQL> alter session enable parallel dml;
Session altered.

SQL> insert /*+parallel(10)*/ into tbl1 select * from v$datafile;
14 rows created.

SQL> select count(*) from tbl1;
  COUNT(*)
----------
        28

SQL> delete tbl1;
28 rows deleted.

اوراکل 23ai– پشتیبانی Fast Ingest از Partitioning، Compression و LOB

Memoptimized Rowstore Fast Ingest یکی از قابلیتهای جدید اوراکل در نسخه 19c است که می تواند در زمینه IOT بسیار کاربردی باشد قبلا در مطلبی تحت عنوان “Memoptimized Fast Ingest در اوراکل 19c“، سعی کردیم به طور مفصل این قابلیت را شرح دهیم. اوراکل در نسخه 23c بهبودهایی را در این زمینه ایجاد کرده است که موضوع این مستند خواهد بود.

پشتیبانی از Partitioning

در نسخه 19c و 21c امکان تنظیم MEMOPTIMIZE FOR WRITE برای جداول پارتیشن شده وجود نداشت:

Connected to Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 
SQL> create table TBL1
  2  (
  3    id   NUMBER not null,
  4    text VARCHAR2(3000),
  5    mydate date
  6  )
  7  SEGMENT CREATION IMMEDIATE
  8  partition by range ( mydate )
  9  interval ( numtoyminterval(1,'MONTH'))
 10  (
 11   PARTITION p1 VALUES LESS THAN (TO_DATE('1-1-2015', 'DD-MM-YYYY'))
 12  );
Table created
SQL> ALTER TABLE tbl1 MEMOPTIMIZE FOR WRITE;
ORA-62165: MEMOPTIMIZE FOR WRITE cannot be enabled on table with specified partitioning type.

این قابلیت در نسخه 23c اضافه شد:

(بیشتر…)

قابلیت Materialized View Concurrent Refresh در اوراکل 23ai

بروز شدن همزمان Materialized Viewهای on-commit refresh از طریق sessionهای مختلف می تواند سبب رخ دادن eventای به نام enq: JI – contention شود چرا که این نوع از MVها به طور پیش فرض به صورت سریالی بروز می شوند و امکان بروزرسانی Concurrent را ندارند.

در قسمت زیر، از طریق دو session به طور همزمان دیتایی را در جدول مرجع MV درج کرده ایم که این  مسئله سبب شد تعداد زیادی از eventهای enq: JI – contention را شاهد باشیم:

SQL> create materialized view auther_contry_mv
refresh fast on commit
as
select country,count(*) from author_tbl group by country;
Materialized view created.
Session 1:
SQL>  begin
for i in  10000 ..19999 loop
insert into author_tbl values(i,'Rahmat Rabbani','m','Oracle DBA','IRAN');
commit;
end loop;
end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:03:00.18
Session 2:
begin
for i in 1 ..9999 loop
insert into author_tbl values(i,'Rahmat Rabbani','m','Oracle DBA','IRAN');
commit;
end loop;
end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:03:00.25

در نسخه 23c اوراکل از طریق قابلیت Materialized View Concurrent Refresh این محدودیت از بین برده است و با استفاده از این قابلیت می توان به صورت Concurrent این نوع از MVها را بروزرسانی کرد.

(بیشتر…)

اوراکل 23ai- امکان استفاده از قابلیت Memoptimized Rowstore بدون تنظیم Hint

برای استفاده از قابلیت Memoptimized Rowstore در نسخه های 19c و 21c، ابتدا می بایست این قابلیت را در سطح جدول فعال می کردیم و بعد از آن، در زمان درج دیتا، Hintای را به دستور insert اضافه می کردیم با توجه به آنکه ممکن است application از قبل نوشته شده باشد، اضافه کردن Hint به دستور insert می تواند مانعی برای استفاده از قابلیت Memoptimized Rowstore شود.

SQL> ALTER TABLE tbl1 MEMOPTIMIZE FOR WRITE;
Table altered

SQL> INSERT /*+ MEMOPTIMIZE_WRITE */ INTO tbl1 VALUES (1,'usefzadeh.com');

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

در نسخه 21c اوراکل پارامتری به نام MEMOPTIMIZE_WRITES را اضافه کرده است که از طریق آن می توان بدون تنظیم این Hint، از این قابلیت بهرمند شد:

SQL> show parameter memoptimize_writes
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
memoptimize_writes                   string      HINT

(بیشتر…)

نکاتی در مورد Materialized View و NoLogging

بروزرسانی Materialized Viewهای حجیم آن هم به صورت complete می تواند DBA را در جنبه های مختلفی به چالش بکشاند به ویژه آنکه دیتابیس در مود آرشیو قرار داشته باشد چرا که در این صورت، بروزرسانی MV منجر به ایجاد حجم زیادی از آرشیولاگ خواهد شد. البته اثرات منفی این مسئله، صرفا به فضای مصرفی redoها خلاصه نمی شود و از لحاظ پرفورمنسی هم می تواند بر روی عملکرد دیتابیس اثر منفی بگذارد.

در این متن بررسی می کنیم که غیرفعال کردن Logging در سطوح object، tablespace و database چه اثراتی را بر روی عملیات ساخت و بروزرسانی Materialized Viewها به همراه خواهد داشت(مطالعه مطلب “تاثیر عملیات NOLOGGING در دیتاگارد”  پیشنهاد می شود).

(بیشتر…)

اوراکل 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';

غیرفعال کردن Auto Indexing برای ad hoc query

اوراکل در نسخه 21c با ارائه پارامتر OPTIMIZER_SESSION_TYPE امکان غیرفعال کردن automatic indexing را در سطح session فراهم کرده است. مقدار پیش فرض این پارامتر برابر با NORMAL است و با تنظیم این پارامتر به مقدار ADHOC، همه QUERYهایی که در session جاری اجرا می شوند، از دید Auto Indexing نادیده گرفته خواهند شد.

SQL> alter session set optimizer_session_type=ADHOC;
Session altered.

البته در نسخه 19c می توانستیم بعضی از schemaها را از دید Auto Indexing پنهان کنیم برای مثال با اجرای دستور زیر، اسکیمای ALI در exclusion list قرار خواهد گرفت:

SQL> EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SCHEMA', 'ALI', FALSE);