online move lob partition
SQL> alter table TEST.MESSAGE move partition MESG01 online lob (content) store as (tablespace TEST_TBS) update indexes ;
SQL> alter table TEST.MESSAGE move partition MESG01 online lob (content) store as (tablespace TEST_TBS) update indexes ;
اگر بیشتر فضای 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 منابع
SQL> alter database move datafile
'+DATA/FBPPRD/5E0295675F4B5286E0534911140A1EE8/DATAFILE/test_sdat.302.993730507'
to
'+SDATA';
select to_char((from_tz(cast(sysdate as timestamp), 'UTC') at time zone
'ASIA/Tehran'),
'yyyy-mm-dd hh24:mi:ss')
from dual;
یک سری جداول وجود دارند که لازم است پارتیشن های آنها به صورت دوره ای پاک شوند. مثلا یک 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های معین شده حذف نماییم.
نکته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 خاص را با استفاده از بکاپی که از آنها داریم بازیابی کنیم. مثلا 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
در موارد مختلفی شاید نیاز داشته باشیم که یک PDB را از یک root container جدا و آن را به یک root container دیگر متصل کنیم.
اگر بخواهیم یک اسکریپت خاص را در چند اسکیما اجرا کنیم ، راه حل های زیر وجود دارد ( البته به جز این موارد ممکن است راه حل های دیگری هم وجود داشته باشد ) :
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;');