Włączanie – wyłączanie Indeksu

Ostatnio na szkoleniu z Administracji na szybko zastanawialiśmy się jak można włączyć i wyłączyć indeks który już mamy na bazie.

Otóż wcale nie jest to tak intuicyjne jakby się wydawało 😉

Jeśli indeks jest oparty na funkcji czyli np.:
CREATE INDEX indeks_funk ON tabelka (UPPER(nazwa_kolumny));

Wyłączyć go możemy poleceniem:
ALTER INDEX indeks_funk DISABLE;
a włączyć:
ALTER INDEX indeks_funk ENABLE;

 

Gdy mamy natomiast indeks nie oparty na funkcji musimy go oznaczyć jako nieużywany:
ALTER INDEX indeks_funk UNUSABLE;
a jeśli chcemy włączyć musimy go po prostu przebudować:
ALTER INDEX indeks_funk REBUILD;

Indeks funkcyjny

Czy to już doping ?

Indeksy zazwyczaj przyspieszają wyszukiwanie wierszy w tabelach.

Indeksy funkcyjne pozwalają skorzystać nawet podczas stosowania różnych operacji w zapytaniach.

Indeks jest strukturą drzewiastą, można więc szybko znaleźć położenie poszukiwanych wierszy. Konsekwencja będzie dużo szybsze wyszukiwanie niż analizowanie wierszy krok po kroku.

Tworzę testową tabelkę TEST_USERS
———————————————-
CREATE TABLE test_users (
id_users    NUMBER(10)    NOT NULL,
 first_name  VARCHAR2(40)  NOT NULL,
 last_name   VARCHAR2(40)  NOT NULL,
 sex         VARCHAR2(1),
 date_reg    DATE
);

Pętla kursorem się toczy

Popełniam więc krótki skrypt który uzupełni przykładową tabelkę wirtualnymi danymi inspirując się zawodnikami ‘Kuchennej rewolucji’:
———————————
BEGIN
   FOR CUR_REC IN 1 .. 5000 LOOP
      IF MOD(CUR_REC, 2) = 0 THEN
        INSERT INTO test_users
        VALUES
                (CUR_REC, 'Rafał’ || CUR_REC, 'Majka’, 'M’, SYSDATE);
        ELSE
             INSERT INTO test_users
             VALUES
                 (CUR_REC, 'Peter’ || CUR_REC, 'Sagan’, 'F’, SYSDATE);
       END IF;
       COMMIT;
  END LOOP;
END;
/

 

Ufaj ale sprawdzaj 😉

Dla pewności sprawdzam czy tabelka została wypełniona
SELECT * FROM test_users;

 

Za mało, za dużo, Statystyka

Warto w tym momencie przeliczyć również statystyki na naszej tabeli.
EXEC DBMS_STATS.gather_table_stats(USER, 'test_users’, cascade => TRUE);

 

Inwigilacja, czyli włączam podsłuch i słucham

Włączam autotrace i sprawdzam plan zapytania (pamiętając że tabela nie ma żadnych indeksów)
SET AUTOTRACE ON
SELECT * FROM TEST_USERS WHERE UPPER(FIRST_NAME) = 'RAFAŁ2′;
01_indx_func
Zgodnie z przewidywaniami jest przeglądana cała tabela w poszukiwaniu jednego wiersza.

 

Bez analizy i przygotowania się nie da
Dla testów stworzę zwykły, najprostszy indeks na tabeli, po czym znów przeliczę statystki.
CREATE INDEX ind_first_name ON test_users (first_name);
EXEC DBMS_STATS.gather_table_stats(USER, 'test_users’, cascade => TRUE);

 

Test zwykłego indeksu

SET AUTOTRACE ON
SELECT * FROM TEST_USERS WHERE UPPER(FIRST_NAME) = 'RAFAŁ2′;
01_indx_func
niestety indeks na nic nam się zdał. Baza i tak przeglądała całą tabelę w poszukiwaniu jednego wiersza.

 

Zadanie dla inżyniera – konstruktora

Skoro używam w warunku zapytania podniesienia do wielkich liter i wiem ze takie zapytanie będzie wykonywane często to tworzę indeks funkcyjny dzięki któremu Oracle przestanie przeglądać całą tabelę w poszukiwaniu wiersza.

DROP INDEX ind_first_name;
CREATE INDEX ind_first_name ON test_users (UPPER(first_name));

 

Test prawdy

SET AUTOTRACE ON
SELECT * FROM TEST_USERS WHERE UPPER(FIRST_NAME) = 'RAFAŁ2′;

03_indx_func

 

Analiza kosztów J

W sumie nie potrzeba żadnego specjalistycznego sprzętu do analizy wyników. Widać że Oracle korzysta już z indeksu funkcyjnego i koszt zajmuje to 40 bajtów zamiast 1500 oraz koszt procesora 2 zamiast 9.

Mniejsze znaczy szybsze J

 

 

Usuwanie niepotrzebnych backupów

Administrator musi zajmować się kopiami bazy – a przynajmniej powinien coś na ten temat wiedzieć.
Poza samym wykonaniem backupu bazy powinien potrafić sprawdzić i wyczyścić przestarzałe pliki z katalogu RMAN’a.

Admin powinien to wykonać prawidłowo ponieważ przy kolejnym tworzeniu backupu dostaniemy niepotrzebne błędy i dodatkowo zajmą nam miejsce.

Pod żadnym pozorem nie usuwamy plików z poziomu systemu operacyjnego np. poleceniem rm w LINUX J

Warto więc dowiedzieć się czegoś więcej jak zdiagnozować przestarzałe kopie i jak je prawidłowo usunąć.

  1. Diagnoza polityki przechowywania backupów.
    łączymy się z RMAN i wykonujemy polecenie show all. Wyszukujemy tekst:
    CONFIGURE RETENTION POLICY TO RECOVERY…

Trzeba jednak zwrócić uwagę że jeśli nasz parametr jest ustawiony np. na 4 dni ale w tym czasie nie mamy wykonanej pełnej kopii (full backup) to czas ten będzie                   wydłużony do ostatniej takiej kopii.

Przestarzałe kopie to takie które nie są wymagane aby bez problemu odzyskać bazę danych.

Podczas wykonania DELETE OBSOLETE wykonają się następujące rzeczy:
– fizyczne pliki backupu zostaną usunięte z systemu plików,
– wpisy kopii zapasowej zostaną usunięte,
– pliki zostaną oznaczone jako usunięte w pliku kontrolnym Oracle.

2. Wyświetlamy kopie zapasowe przed usunięciem przestarzałych.
01.list_of_backup

Widzimy że mamy kopie nawet z 17 marca 2017 roku a aby spełnić warunki odzyskiwania potrzebne nam są backupy z czterech ostatnich dni. Kilkanaście plików jest              nam więc zbędnych.

3. Sprawdzimy poprawność plików BACKUPU w repozytorium RMAN’a poleceniem CROSSCHECK BACKUP.
02.crosscheck_backup

4. Usuwamy przestarzałe pliki RMAN.
Po sprawdzeniu crosscheck , usuwamy przestarzałe pliki danych przy użyciu polecenia DELETE OBSOLETE.
03.delete_obsolete

Wpisując YES rozpoczniemy proces usuwania przestarzałych plików RMAN.
Usuwane zostają również fizyczne pliki warto więc sprawdzić 2 lub nawet 3 razy co się usuwa.

Pisząc skrypt shell’owy możemy pozbyć się potwierdzenia aby nie wpisywać YES. Posłuży do tego komenda DELETE NOPROMPT OBSOLETE;

5. Sprawdzenie listy backupów znanym nam już poleceniem LIST BACKUP SUMMARY;
          Lista pokaże tylko potrzebne backupy które są wymagane do odzyskania bazy po awarii.

Wolne miejsce na TBS

IMPDP 40 GB – wczytuje się 20 godzinę i nie pokazuje żadnego błędu…
Przetwarzanie typu obiektu SCHEMA_EXPORT/TABLE/INDEX/INDEX

Ostatnio musiałem zrobić export wybranych schematów i zaimportować do innej instancji.
Zacząłem od zrobienia exportu datapumpem, następnie na drugiej instancji utworzyłem tablespace oraz użytkowników do których miał być wykonany import.
Zazwyczaj sprawdzam ile plików danych jest przydzielonych na bazie źródłowej danej przestrzeni i tworzę ich tyle samo na bazie docelowej – tym razem jednak tego nie zrobiłem.
Dla wyjaśnienia – rozmiar danych do eksportu wynosił około 40 GB więc niezbyt dużo.
Całą komendę importu uruchomiłem na serwerze w tzw. Screenie więc spokojnie mogłem zamknąć swoją stacje i wrócić do swojej sesji na serwerze za jakiś czas. Na szczęście nie było wielkiego ciśnienia więc wróciłem do tematu po około 20 godzinach a tam stoi na tym samym etapie czyli przerzucania na bazę indeksów.

Przetwarzanie typu obiektu SCHEMA_EXPORT/TABLE/INDEX/INDEX

Wtedy wróciło mi myślenie J i postanowiłem sprawdzić ile miejsca wolnego zostało na przestrzeniach które stworzyłem przed importem.
Aby dobrze to obliczyć skorzystałem z dwóch widoków systemowych dba_data_files oraz dba_free_space.
Od mojego max_size_gb (bytes – dba_data_files) odjąłem  size_gb (maxbytes – dba_data_files) a następnie dodałem zsumowaną wolną przestrzeń (sum (bytes) – dba_free_space).

001_cfs

dostaniemy wynik jak poniżej który każdy powinien potrafić odczytać ze zrozumieniem

002_cfs

 

Duplikacja bazy danych z użyciem RMAN – Windows

Czasem mamy potrzebę aby szybko na tym samym serwerze postawić/odświeżyć  środowisko testowe. Oczywiście możemy posłużyć się data pumpem ale możemy też użyć opcji duplikacji. Wcześniej musimy tylko utworzyć kilka plików dla nowej instancji.


Tworzymy nowy plik pfile dla bazy testowej np. initTEST.ora kopiując zawartość z pliku produkcyjnego pfile. Jeśli takiego pliku nie ma bo jest tylko spfile to musimy go sobie stworzyć. Logujemy się do bazy produkcyjnej na użytkownika sys i wydajemy polecenie create pfile from spfile;
Z pliku pfile testowego usuwamy parametry ukryte zaczynające się od  _ , i dopisujemy parametry zaznaczone poniżej.

01

Czytaj dalej