دیتابیس اوراکل

دیتابیس اوراکل
طبقه بندی موضوعی

online move lob partition

SQL> alter table TEST.MESSAGE move partition MESG01 online lob (content) store as (tablespace TEST_TBS) update indexes ;

Purge UNIFIED AUDIT TRAIL

اگر بیشتر فضای SYSAUX  توسط UNIFIED AUDIT TRAILها اشغال شده باشد، برای purge کردن آن میتوان به صورت زیر اقدام کرد.

 

1-      فضای SYSAUX را توسط کوئری زیر چک میکنیم.

 

,select occupant_name

         ,occupant_desc         

         ,"(round(space_usage_kbytes / (1024 * 1024) "SPACE(G         

         ,schema_name         

         move_procedure         

  from v$sysaux_occupants

; order by 3 desc

 

2-     اگر بیشتر فضای SYSAUX توسط AUDSYS گرفته شده باشد، برای purge کردن اطلاعات آن میتوان به روش زیر اقدام کرد.


;SQL> select count(*) from unified_audit_trail

 

به 2 روش میتوان اطلاعات جدول بالا را purge کرد:

- پاک کردن تمام اطلاعات جدول


Flush from memory--

;SQL> exec dbms_audit_mgmt.flush_unified_audit_trail


Execute the Purge Procedure--

begin

  dbms_audit_mgmt.clean_audit_trail

)

,audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED

                                                     ,use_last_arch_timestamp  => FALSE

                                                 container => DBMS_AUDIT_MGMT.CONTAINER_CURRENT

;(

;end

 

 

- پاک کردن اطلاعات از یک تاریخی به بعد

 

begin

  dbms_audit_mgmt.set_last_archive_timestamp

)

,audit_trail_type    =>  dbms_audit_mgmt.audit_trail_unified

('last_archive_time => to_timestamp('02-DEC-2018','DD-MON-YYYY

 ;(

;end


;SQL> select * from dba_audit_mgmt_last_arch_ts


Flush from memory--

;SQL> exec dbms_audit_mgmt.flush_unified_audit_trail


Execute the Purge Procedure-- 

begin

 dbms_audit_mgmt.clean_audit_trail

)

 ,audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED

                                    ,use_last_arch_timestamp => TRUE

                                   container => DBMS_AUDIT_MGMT.CONTAINER_CURRENT

 ;(

;end


برای اینکه اینکار به صورت اتوماتیک انجام شود، میتوانید به صورت زیر یک job تعریف کنید.

begin


  dbms_scheduler.create_job (


    job_name        => 'PURGE_UNIFIED_AUDIT_TRAILS',


    job_type        => 'PLSQL_BLOCK',


    job_action      => 'declare

                        l_days NUMBER := 10;

                        begin 


                          dbms_audit_mgmt.set_last_archive_timestamp(DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED, 

                                                                     TRUNC(SYSTIMESTAMP)-L_DAYS);

                          dbms_audit_mgmt.clean_audit_trail( audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,

                                                             use_last_arch_timestamp => TRUE ,

                                                             container => DBMS_AUDIT_MGMT.CONTAINER_CURRENT );


                        END;',


    start_date        => SYSTIMESTAMP,


    repeat_interval => 'freq=daily; byhour=2; byminute=0; bysecond=0;',


    end_date         => NULL,


    enabled           => TRUE,


    comments        => 'Automatically set audit last archive time.');


end;

 

 n منابع 


online move datafile in 12c

SQL> alter database move datafile

'+DATA/FBPPRD/5E0295675F4B5286E0534911140A1EE8/DATAFILE/test_sdat.302.993730507'

to

'+SDATA';

convert timzone

select to_char((from_tz(cast(sysdate as timestamp), 'UTC') at time zone

         'ASIA/Tehran'),

         'yyyy-mm-dd hh24:mi:ss')

  from dual;


پاک کردن N پارتیشن آخر یک جدول به صورت دوره ای

 

یک سری جداول وجود دارند که لازم است پارتیشن های آنها به صورت دوره ای پاک شوند. مثلا یک policy میگذاریم که 10 پارتیشن آخر یک جدول نگه داشته شوند و بقیه drop شود. با استفاده از مراحل زیر میتوان این کار را انجام داد:

 

1- یک جدول بنام list_drop_part ایجاد میکنیم و لیست جداولی که قرار است پارتیشن های آنها drop شود و همچنین policy که برای drop شدن پارتیشن ها وجود دارد را به آن جدول اضافه میکنیم.

create table c##usr1.list_drop_part

( tab_own  varchar2(128 byte),

 tab_name varchar2(128 byte),

 interval number) ;

 

 

برای هر جدول جدید، اگر لازم است پارتیشن های آن drop شود باید نام آن به list_drop_part اضافه شود. 

- در ستون interval تعداد پارتیشنهایی که باید نگهداری شوند را مشخص میکنیم.

 

2- یک جدول با نام result_drop_part ایجاد میکنیم که اطلاعات پارتیشن های drop شده در آن ریخته میشود.

 

create table c##usr1.result_drop_part

( tab_own    varchar2(128 byte),

  tab_name   varchar2(128 byte),

  part_name  varchar2(128 byte),

  high_value date,

  exec_date  date);

 

 

3- با استفاده از پروسیجر زیر میتوانیم پارتیشن های جداولی را که به list_drop_part اضافه شده اند ، بر اساس policyهای معین شده حذف نماییم.

 drop_partition_prc

 

نکته2) برای اجرای پکیج بالا باید grantهای زیر به کاربر c##usr1 داده شود.

 

grant drop any table to c##usr1 container=all;

grant select on dba_tab_partitions to c##usr1 container=all;

 

    4- میتوانیم یک job ایجاد کنیم که به صورت دوره ای اجرا شود و پروسیجر بالا را فراخوانی کند.

 

 

بازیابی یک PDB از RMAN backup

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

 

 

 

 

1- در ابتدا باید یک auxiliary instance ایجاد کنیم. که این کار را میتوانیم روی همان سرور یا سرور دیگری انجام دهیم.

--Create password file for auxiliary instance

 

 

$ cd $ORACLE_HOME/dbs

 

 

$ orapwd file=orapwtest password=m#12345678 entries=5

 

 

 

 

 

--Create init file for auxiliary instance

 

 

$ vi inittest.ora

 

نکته 1) برای ایجاد کردن init file میتوانید از روی spfile دیتابیس source یک  pfile ایجاد کنید و بعد از ایجاد تغییرات لازم از آن به عنوان init file برای  auxiliary instance استفاده کنید.

 

 

 

 

 

 

 

2- در مرحله بعدی باید auxiliary instance را nomount کنید.

 

 

 

$ export ORACLE_SID=TEST 

 

 

$ echo $ORACLE_SID

 

 

$ sqlplus / as sysdba

 

 

SQL> startup nomount pfile=/u01/app/oracle/product/12.2.0/db_1/dbs/inittest.ora;

 

 

 

 

 

3- در این مرحله با استفاده از دستور RMAN duplicate میتوانیم PDB مورد نظر را بازیابی نماییم.

 

 

 

 

 

$ rman auxiliary sys/m#12345678

 

 

RMAN> duplicate database to 'TEST' pluggable database PDB1

 

 

2> UNTIL TIME "TO_DATE ('15-10-2018 04:40:00','dd-mm-yyyy hh24:mi:ss')"

 

 

3> backup location '/home/oracle/back/';

 

 

 

نکته 2) باید بکاپ تمام  archiveهایی که میخواهیم recover کنیم در مسیر بکاپ ها موجود باشد.

 

 

 

 

 

4-  بعد میتوانیم با استفاده از دستورات زیر PDB1 را از root container auxiliary instance جدا کنیم و به root container که میخواهیم متصل نماییم.

 

 

 

 

 

--auxiliary instance

 

 

SQL> alter pluggable database PDB1 close immediate;

 

 

SQL> alter pluggable database PDB1 unplug into '/home/oracle/pdb1.pdb';

 

 

 

 

 

--target database

 

 

SQL> create pluggable database PDB1 as clone using '/home/oracle/pdb1.pdb';

 

 

SQL> alter pluggable database PDB1 open;

 

 
 

 

 

Attachments

 

RMAN Log Output from the DUPLICATE Process

PDB Unplug and Plugin in Oracle Database 12c

در موارد مختلفی شاید نیاز داشته باشیم که یک PDB را از یک root container جدا و آن را به یک root container دیگر متصل کنیم.

 

تغییر oem agent timezone

timezone یک agent بر اساس timezone سیستم عامل ست میشود، اگر timezone یک سیستم عامل را تغییر دهید برای تغییر agent timezone میتوانید بر اساس روش زیر عمل کنید:
emctl stop agent
emctl resetTZ agent

وقتی این دستور را اجرا میکنید خروجی آن به شکل زیر است :
Oracle Enterprise Manager Cloud Control 13c Release 2  
Copyright (c) 1996, 2016 Oracle Corporation.  All rights reserved.
Updating /u01/app/oracle/product/13.2.0/agent/agent_inst/sysman/config/emd.properties...
Successfully updated /u01/app/oracle/product/13.2.0/agent/agent_inst/sysman/config/emd.properties.
Login as the em repository user and run the  script:
exec mgmt_target.set_agent_tzrgn('tstdb-tst-loc-loc:3872','GMT')
and commit the changes
This can be done for example by logging into sqlplus and doing
SQL> exec mgmt_target.set_agent_tzrgn('tstdb-tst-loc-loc:3872','GMT')
SQL> commit

بعد باید به sysman متصل شوید و دستوراتی را که در بالا به آن اشاره شده است اجرا کنید:
sqlplus sysman/pass
SQL> exec mgmt_target.set_agent_tzrgn('tstdb-tst-loc-loc:3872','GMT');
SQL> commit;

برای اینکه از تغییر timezone مطمئن شوید ، میتوانید کوئری زیر را اجرا کنید:
SQL> select target_name, timezone_region from sysman.mgmt_targets where TARGET_NAME='tstdb-tst-loc-loc';

بعد از انجام این مراحل مجددا agent را start کنید.
emctl start agent


[ORA-00600: internal error code, arguments: [krfrFix-2

موقع mount کردن دیتابیس با خطای زیر مواجه شدم :

: Errors in file /u01/app/oracle/diag/rdbms/migdb/migdb/trace/migdb_rvwr_24962.trc
ORA-00600: internal error code, arguments: [krfrFix-2], [0], [2], [], [], [], [], [], [], [], [], []
2018-09-29T06:09:18.809390+00:00
.WARNING: Cannot open the flashback thread for this instance due to the above error

که توی documentها نوشته شده بود دیتابیس را به حالت mount ببرید و flashabck را off کنید، بعد دیتابیس را open کنید. ولی چون دیتابیس ما کلا موقع mount شدن با خطای بالا روبرو میشد. من راه حل زیر را انجام دادم:

;SQL> alter system reset db_recovery_file_dest
;SQL> alter database mount
;SQL> alter database flashback off
;'SQL> alter system set db_recovery_file_dest='/shst/rdb-tst
;SQL> alter database open
;SQL> alter database flashback on



اجرای یک اسکریپت خاص در چند اسکیمای مختلف ( DBMS_SYS_SQL )

اگر بخواهیم یک اسکریپت خاص را در چند اسکیما اجرا کنیم ، راه حل های زیر وجود دارد ( البته به جز این موارد ممکن است راه حل های دیگری هم وجود داشته باشد ) :

1- به تک تک آن اسکیماها وصل شده و اسکریپت مورد نظر را اجرا کنیم.

2- به یک اسکیمای خاص وصل شده و با دستور alter session set current_schema=X ،  اسکیمای خود را تغییر دهیم و اسکریپت مورد نظر را اجرا کنیم.

3- راه حل سوم استفاده از پکیج DBMS_SYS_SQL است. کاربرد این پکیج شبیه DBMS_SQL است با این تفاوت که یک کارکرد اضافه تر با نام "parse as user"  دارد که به شما اجازه میدهد یک SQL خاص را برای دیگر اسکیماها در دیتابیس اجرا کنید.

فقط قبل از اجرا باید به دو نکته خیلی خیلی مهم توجه کنید :

- این پکیج در اوراکل جزو undocumented packageها به حساب می آید و اوراکل به صورت internally برای سرویس های خود از آن استفاده میکند. و برای استفاده در خارج از اوراکل در نظر گرفته نشده است.

- این پکیج بسیار پکیج قدرتمندی است ، زیرا هر دستوری را با آن میتوان اجرا کرد ، به همین دلیل باید شدیدا این موضوع تحت کنترل قرار گیرد که این پکیج توسط چه user قرار است اجرا شود.

با در نظر گرفتن نکات بالا من یک مثال از نحوه استفاده از این پکیج را در زیر شرح داده ام :


1-Create User

create user TEST identified by TEST quota unlimited on USERS;

grant connect,create procedure,select on dba_users to TEST;

grant execute on sys.dbms_sys_sql to TEST;

 

create user C identified by C quota unlimited on USERS;

grant CONNECT,CREATE TABLE to C;

 

create user D identified by D quota unlimited on USERS;

grant CONNECT,CREATE TABLE to D;

 

2-Create Procedure In TEST User

create or replace procedure execute_script_prc(v_script in varchar2) as

  l_cursors dbms_sql.number_table;

  l_result  number;

begin

 for cur in (select user_id 

                from dba_users 

               where username in ('C','D')) loop

  --parse the cursor only if we haven't already

  if (not l_cursors.exists(cur.user_id)) then

    l_cursors(cur.user_id) := sys.dbms_sys_sql.open_cursor;

    --parsing anonymous pl/sql block

    sys.dbms_sys_sql.parse_as_user(

    c => l_cursors(cur.user_id), 

    statement => v_script, 

    language_flag => dbms_sql.native,

    userid => cur.user_id);

  end if;

 --execute script

 l_result := sys.dbms_sys_sql.execute(l_cursors(cur.user_id));

 end loop;

end execute_script_prc;

 

3-Execute script on C,D schemas

--Create table T1 in C,D schemas

exec test.execute_script_prc('create table T1 ( id number )');

--Insert to table T1 in C,D schemas

exec test.execute_script_prc('begin insert into T1 values(1); commit; end;');



  • منبع