Servicii baze de date

MySql 61 Solutii

SQL Server 307 Solutii

Cum faci refresh tabelelor locale utilizând API-ul DataPump

Aveți două baze de date (una locală și una la distanță) și intenționați să reîmprospătați unele tabele locale cu date din tabele la distanță. Pentru a demonstra acest lucru este creat următorul mediu:

connect / as sysdba

— test user
create user test identified by <password> default tablespace users temporary tablespace temp;
grant connect, resource to test;

— facem obiecte in schema TEST
connect test/parola

— test tables
create table a_tab
(
id number,
text varchar2(50)
);

create table b_tab
(
id number,
text varchar2(50)
);

— populare tabele de test
insert into a_tab values (1, ‘Remote schema, table A_TAB – Row 1’);
insert into a_tab values (2, ‘Remote schema, table A_TAB – Row 2’);
insert into b_tab values (1, ‘Remote schema, table B_TAB – Row 1’);
insert into b_tab values (2, ‘Remote schema, table B_TAB – Row 2’);
commit; 

 

create table transfer_objects
(
owner varchar2(30),
table_name varchar2(30),
object_type varchar2(30)
);

—  tabele ce for fi actualizate in  baza locala 
insert into transfer_objects values (‘TEST’, ‘A_TAB’, ‘TABLE’);
insert into transfer_objects values (‘TEST’, ‘B_TAB’, ‘TABLE’);
commit;

 

Baza de date locala (target)

 

connect / as sysdba

— directorul folosit pentru logurile DataPump 
create directory refresh as ‘<PATH>’;

— test user
create user test identified by <password> default tablespace users temporary tablespace temp;
grant connect, resource, create database link to test;
grant read, write on directory refresh to test;

— creare obiecte in schema TEST
connect test/parola

–Creare database link din local in remote
create database link link_to_remote connect to test identified by <password> using ‘<TNS alias to remote>’;

create table a_tab
(
id number,
text varchar2(50)
);

create table b_tab
(
id number,
text varchar2(50)
);

— populare tabele de tes
insert into a_tab values (1, ‘Local schema, table A_TAB – Row 1’);
insert into b_tab values (1, ‘Local schema, table B_TAB – Row 1’);
commit;

Porniți următorul bloc PL/SQL care apelează API-ul DataPump în baza de date locală pentru a reîmprospăta tabelele A_TAB/B_TAB de la distanță:

set serverout on size 1000000
declare
my_handle number; — Data Pump job handle
my_db_link varchar2(30) := ‘LINK_TO_REMOTE’;
ind NUMBER; — Loop index
percent_done NUMBER; — Percentage of job complete
job_state VARCHAR2(30); — To keep track of job state
le ku$_LogEntry; — For WIP and error messages
js ku$_JobStatus; — The job status from get_status
jd ku$_JobDesc; — The job description from get_status
sts ku$_Status; — The status object returned by get_status

begin
— creare job 
my_handle := dbms_datapump.open
(
operation => ‘IMPORT’,
job_mode => ‘TABLE’,
remote_link => my_db_link
);

dbms_output.put_line (‘Opened DataPump job with handle: ‘||to_char (my_handle));dbms_datapump.set_parallel (my_handle, 1);
dbms_output.put_line (‘Added parallel’);

dbms_datapump.set_parameter
(
handle => my_handle,
name => ‘TABLE_EXISTS_ACTION’,
value => ‘REPLACE’
);
dbms_output.put_line (‘Added parameter REPLACE’);

dbms_datapump.add_file
(
handle => my_handle,
filename => ‘impdp_test.log’,
directory => ‘REFRESH’,
filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE
);
dbms_output.put_line (‘Added log file’);

dbms_datapump.metadata_filter
(
handle => my_handle,
name => ‘NAME_EXPR’,
value => ‘IN (SELECT TABLE_NAME FROM TEST.TRANSFER_OBJECTS WHERE OWNER = ”TEST” AND OBJECT_TYPE = ”TABLE”)’,
object_type => ‘TABLE’
);
dbms_output.put_line (‘Added metadata filter’);

dbms_datapump.start_job (my_handle);

percent_done := 0;
job_state := ‘UNDEFINED’;
while (job_state != ‘COMPLETED’) and (job_state != ‘STOPPED’) loop
dbms_datapump.get_status
(
my_handle,
dbms_datapump.ku$_status_job_error +
dbms_datapump.ku$_status_job_status +
dbms_datapump.ku$_status_wip, -1 , job_state, sts
);
js := sts.job_status;

if js.percent_done != percent_done then
dbms_output.put_line (‘*** Job percent done = ‘||to_char (js.percent_done));
percent_done := js.percent_done;
end if;

if (bitand (sts.mask, dbms_datapump.ku$_status_wip) != 0) then
le := sts.wip;
else
if (bitand (sts.mask, dbms_datapump.ku$_status_job_error) != 0) then
le := sts.error;
else
le := null;
end if;
end if;

if le is not null then
ind := le.FIRST;
while ind is not null loop
dbms_output.put_line (le(ind).LogText);
ind := le.NEXT(ind);
end loop;
end if;
end loop;

dbms_output.put_line (‘Job has completed’);
dbms_output.put_line (‘Final job state = ‘||job_state);
dbms_datapump.detach (my_handle);
end;
/

Outputul ar trebui sa fie ca in exemplul de mai jos:

Opened DataPump job with handle: 18
Added parallel
Added parameter REPLACE
Added log file
Added metadata filter
Starting “TEST”.”SYS_IMPORT_TABLE_01″:
Estimate in progress using BLOCKS method…
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 128 KB
. . imported “TEST”.”A_TAB” 2 rows
. . imported “TEST”.”B_TAB” 2 rows
*** Job percent done = 100
Job “TEST”.”SYS_IMPORT_TABLE_01″ successfully completed at 13:22:54
Job has completed
Final job state = COMPLETED

PL/SQL procedure successfully completed.

Conținutul tabelelor locale după importul DataPump este următorul:

SQL> select * from a_tab;

ID TEXT
————— ————————————————–
1 Remote schema, table A_TAB – Row 1
2 Remote schema, table A_TAB – Row 2

SQL> select * from b_tab;

ID TEXT
————— ————————————————–
1 Remote schema, table B_TAB – Row 1
2 Remote schema, table B_TAB – Row 2

[mai mult...]

Configure RMAN to purge archivelogs after applied on standby

To automatically purge the archivelogs from the FRA, using RMAN, once they are applied to the standby database we have to:

Configure the following parameter in RMAN (standby):

RMAN> CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY;

Starting from 11g, we have enhanced the configure archivelog deletion policy to include TO APPLIED ON [ALL] STANDBY [BACKED UP n TIMES TO DEVICE TYPE ]. This will ensure that the archivelogs is applied as well as backed up on primary before it is being purged.

The archivelog must have been applied to the standby. Run the following query to list all archivelogs applied to the standby:

select a.thread#, a.sequence#, a.applied
from v$archived_log a, v$database d
where a.activation# = d.activation#
and a.applied=’YES’
/

If there is space pressure in the FRA, the archive logs will be automaticly deleted. When an archivelog is automatically deleted from the FRA, you will see this in the database’s alert.log:

Sat Feb 04 12:16:35 2023
Deleted Oracle managed file /opt/app/oracle/FRA/<DB_NAME>/archivelog/2023_01_30/o1_mf_1_22_a12fds3a_.arc
Deleted Oracle managed file /opt/app/oracle/FRA/<DB_NAME>/archivelog/2023_01_31/o1_mf_1_22_a12fds3b_.arc

[mai mult...]

Istoric restore baza de date

Mai jos este o procedura ce primeste ca parametru numele unei baze de date microsoft sql server si returneaza, pentru acea baza de date, istoricul retorurilor efectuate pe acel server de sql, data fiecarui restore, data backup-ului folosit in restore, numele cu care a fost restaurat baza de date precum si backup-ul folosit la restaurarea respectiva.

[mai mult...]

Partial Indexes for Partitioned Tables in Oracle Database

Table: INDEXING [ON | OFF] Clause

Decizia despre ce partiții sunt indexate se ia folosind INDEXING [ON | OFF] asociată fiecărei partiții, implicit fiind INDEXING ON. Creăm un tabel partiționat cu trei partiții. Primele două partiții au indexarea activată. Una implicit și alta în mod explicit. A treia partiție are indexarea dezactivată.

— Creați și completați tabelul partiționat.

drop table t1 purge;

create table t1 (
id number,
description varchar2(50),
created_date date
)
partition by range (created_date) (
partition part_2021 values less than (date ‘2021-01-01’),
partition part_2022 values less than (date ‘2022-01-01’) indexing on,
partition part_2023 values less than (date ‘2023-01-01’) indexing off
);

insert into t1 values (1, ‘t1 one’, date ‘2021-07-01’);
insert into t1 values (2, ‘t1 two’, date ‘2023-07-01’);
insert into t1 values (3, ‘t1 three’, date ‘2023-01-01’);
commit;

Coloana INDEXING a viewului USER_TAB_PARTITIONS ne arată starea de indexare a fiecărei partiții. Doar partiția 2023 are INDEXING dezactivat.

column table_name format a20
column partition_name format a20

select table_name,
partition_name,
indexing
from user_tab_partitions
where table_name = ‘T1’
order by 1,2;

TABLE_NAME PARTITION_NAME INDE
——————– ——————– —-
T1 PART_2021 ON
T1 PART_2022 ON
T1 PART_2023 OFF

SQL>

Schimbăm clauza de indexare pentru o partiție folosind comanda ALTER TABLE … MODIFY PARTITION. Dezactivăm indexarea pentru partițiile 2021 și 2022 și activăm indexarea pentru partiția 2023.

alter table t1 modify partition part_2021 indexing off;
alter table t1 modify partition part_2022 indexing off;
alter table t1 modify partition part_2023 indexing on;

Putem vedea modificările reflectate în rezultatul din vizualizarea USER_TAB_PARTITIONS. Indexarea este dezactivată pentru partițiile 2021 și 2022. Indexarea este activată pentru partiția 2023.

select table_name,
partition_name,
indexing
from user_tab_partitions
where table_name = ‘T1’
order by 1,2;

TABLE_NAME PARTITION_NAME INDE
——————– ——————– —-
T1 PART_2021 OFF
T1 PART_2022 OFF
T1 PART_2023 ON

SQL>

Index: INDEXING [FULL | PARTIAL] Clause

Chiar și cu setările de indexare a partiției activate, în mod implicit, indecșii sunt creați ca INDEXING FULL, deci setarea partiției este ignorată.

Creăm un index local pe coloana CREATED_DATE. Dacă nu specificăm clauza INDEXING în timpul creării indexului, acțiunea implicită este INDEXING FULL.

drop index t1_local_partial_idx;

— create index t1_local_partial_idx on t1(created_date) local indexing full;
create index t1_local_partial_idx on t1(created_date) local;

Verificând coloana STATUS a viewului USER_IND_PARTITIONS, vedem că toate partițiile indexului sunt utilizabile. În mod implicit, crearea indexului ignoră setarea INDEXARE a partițiilor de tabel.

column index_name format a25

select index_name,
partition_name,
status
from user_ind_partitions
where index_name = ‘T1_LOCAL_PARTIAL_IDX’
order by 1,2;

INDEX_NAME PARTITION_NAME STATUS
————————- ——————– ——–
T1_LOCAL_PARTIAL_IDX PART_2021 USABLE
T1_LOCAL_PARTIAL_IDX PART_2022 USABLE
T1_LOCAL_PARTIAL_IDX PART_2023 USABLE

SQL>

Verificând coloana INDEXING a vizualizării USER_INDEXES, vedem că indexul este marcat ca indexare COMPLET.

column indexing format a8

select index_name,
indexing
from user_indexes
where index_name = ‘T1_LOCAL_PARTIAL_IDX’
order by 1;

INDEX_NAME INDEXING
————————- ——–
T1_LOCAL_PARTIAL_IDX FULL

SQL>

Stergem indexul și îl creăm din nou, de data aceasta folosind clauza INDEXING PARTIAL.

drop index t1_local_partial_idx;
create index t1_local_partial_idx on t1(created_date) local indexing partial;

Acum vedem că partițiile de tabel marcate ca INDEXING OFF nu sunt indexate și au partiții de index marcate ca inutilizabile. Partiția de tabel din 2023 a fost marcată ca INDEXING ON, deci este indexată și vedem o partiție de index utilizabilă.

select index_name,
partition_name,
status
from user_ind_partitions
where index_name = ‘T1_LOCAL_PARTIAL_IDX’
order by 1,2;

INDEX_NAME PARTITION_NAME STATUS
————————- ——————– ——–
T1_LOCAL_PARTIAL_IDX PART_2021 UNUSABLE
T1_LOCAL_PARTIAL_IDX PART_2022 UNUSABLE
T1_LOCAL_PARTIAL_IDX PART_2023 USABLE

SQL>

Verificând coloana INDEXING a vizualizării USER_INDEXES, vedem că indexul este marcat ca indexare PARTIAL.

column indexing format a8

select index_name,
indexing
from user_indexes
where index_name = ‘T1_LOCAL_PARTIAL_IDX’
order by 1;

INDEX_NAME INDEXING
————————- ——–
T1_LOCAL_PARTIAL_IDX PARTIAL

SQL>

Indecșii globali pot fi creați și ca indecși parțiali, doar cu partițiile marcate incluse în index.
Creăm un index global parțial. Observați utilizarea clauzei de indexare “partial”. Indexul rezultat este marcat ca INDEXING PARTIAL.

create index t1_global_partial_idx on t1(description) global indexing partial;

— Verificati statusul indexului

select index_name,
indexing
from user_indexes
where index_name like ‘T1%’
order by 1;

INDEX_NAME INDEXING
————————- ——–
T1_GLOBAL_PARTIAL_IDX PARTIAL
T1_LOCAL_PARTIAL_IDX PARTIAL

SQL>

[mai mult...]