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 Backupów i plików – RMAN

Brutalne, niebezpieczne ale czasem konieczne – usuwanie kopii zapasowych.
Pierwszy nasz wpis od dawna i pierwszy na temat czarodziejskiego RMAN’a.

Pierwsze polecenie powoduje trwałe usunięcie wszystkich kopii z dysku(katalogu)
RMAN> DELETE BACKUP;

 

Powyższe polecenie zapyta czy na pewno chcemy usunąć wszystkie backupy bazy. Jeśli jesteśmy z góry pewni i lubimy ryzyko możemy pominąć potwierdzenie wpisując polecenie:
RMAN> DELETE NOPROMPT BACKUP;

 

Możemy też usunąć wszystkie kopie obrazu:
RMAN> DELETE DATAFILECOPY ALL;

 

Lub wybrane kopie obrazu, podając numer lub nazwę pliku:
RMAN> DELETE DATAFILECOPY 17;
RMAN> DELETE DATAFILECOPY '/u01/app/oracle/fra/test01.dbf’;

 

Bezpieczniejszą metodą zanim usuniemy wszystkie kopie będzie sprawdzenie i usunięcie tych, powiedzmy ‘przeterminowanych’ po wcześniejszym użyciu polecenia CROSSCHECK:
RMAN> DELETE EXPIRED BACKUP;

 

Warto również usunąć wszystkie ‘przeterminowane’ archive logi:
RMAN> DELETE EXPIRED ARCHIVELOG ALL;

 

Jest jeszcze polecenie z klauzulą OBSSOLATE które usunie wszystkie kopie które są zbyt stare zgodnie z polityką retencji:
RMAN> DELETE OBSOLETE;

 

Oczywiście nie są to wszystkie metody usuwania dlatego zapraszamy do dodawania komentarzy

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.

Upgrade bazy do 12.2.0.1

Dzisiaj dla naszego Klienta będziemy robić pierwszy testowy Upgrade bazy danych do wersji 12.2.0.1.
Klient mniejszy co nie oznacza że wszystko pójdzie szybko.

Wsparcie na ten produkt rozpocznie się według tabeli Oracle dopiero w ostatnim kwartale 2017 więc będziemy 'trochę’ pionierami 🙂

support_date

Hasło wygasło

Poniedziałek rano w pracy to zazwyczaj nie jest dobra pora na awarię. Niestety awarie nie wybierają a niektórym udałoby się zapobiec gdyby nie … inne awarie J
Pracownicy nie mogą pracować więc pewnie coś poważnego musiało się stać.
Zalogowałem się do klienta i podczas próby zalogowania na właściciela schematu zobaczyłem dość przyjemny jak na ‘awarię’ komunikat:

ORA-28001: the password has expired

Sprawdziłem więc jaki profil ma przypisany nieszczęsny użytkownik i kiedy wygasło konto
001_expiry_passwd

Na zrzucie powyżej widać że dla użytkownika nie ma stworzonej specjalnej grupy a więc można przyjąć że jego hasło wygasa co 180 dni jeśli nikt wcześniej nie zmieniał nic w profilu Default. Ale sprawdzić można to poniższym zapytaniem
002_expiry_passwd

Jeśli istnieje taka konieczność to należy zmienić parametr password_life_time choć należy pamiętać że nie jest to zalecane ze względów bezpieczeństwa
003_expiry_passwd

I jeszcze raz wykonujemy zapytanie czy przy parametrze jest wartość unlimited.

Dobry zwyczaj:
Dobrą praktyką jest stworzenie dedykowanego profilu na potrzeby działania systemu a nie korzystanie z default’owego. Są użytkownicy których zmiana hasła nie jest pożądana ponieważ korzystają z niego aplikacje zewnętrzne i przy każdym zmianie hasła konieczna byłaby ich zmiana. Natomiast dla operatorów korzystających z aplikacji zmiana hasła co 180 dni jest jak najbardziej wskazana.
Oczywiście powyższej sytuacji można było uniknąć.

Użyte skrypty:

SELECT S.PROFILE, S.EXPIRY_DATE
FROM DBA_USERS S 
WHERE S.USERNAME = 'NAZWA_UŻYTKOWNIKA’;

SELECT RESOURCE_NAME, LIMIT
FROM DBA_PROFILES
WHERE PROFILE = 'DEFAULT’;

alter profile DEFAULT LIMIT password_life_time UNLIMITED;

 

Szybkie ładowanie danych do tabeli

Czasem mamy bardzo mało czasu na załadowanie danych do tabeli. Nie robi się wtedy ważne miejsce na dysku tylko szybkość wykonania. Ostatnio spotkałem się z takim problemem stąd też ten wpis.

Tworzymy sobie dowolną tabelkę. Posłużymy się najlepiej jakąś istniejącą z większą liczbą rekordów. Na jej podstawie stworzymy tabelkę do naszego tematu

01

Czytaj dalej

Walidacja obiektów

Niekiedy a nawet dość często kiedy musimy dodać do wybranego schematu jakiś pakiet, procedurę lub funkcje okazuje się że inne obiekty schematu zostały rozkompilowane. Oczywiście w miarę używania kolejnych obiektów będą one kompilowane przez samą bazę jeśli nie mają w sobie błędów ale może to trwać bardzo długo. Warto po modyfikacjach sprawdzić więc czy na naszej bazie są jakieś obiekty które do prawidłowego działania będą potrzebne zwalidowane.

Sprawdzamy więc listę rozwalidowanych obiektów na naszej bazie

sprawdzenie obiektów

Czytaj dalej

Zmiana katalogu DATA_PUMP_DIR

Czasem mamy potrzebę aby załadować pliki dmp które ktoś nam wcześniej wyeksportował.
Powiedzmy że ktoś skopiował te pliki na dysk usb a my możemy taki dysk podłączyć do naszego serwera.

Nie musimy w tym momencie kopiować plików z dysku usb na serwer i oszczędzamy miejsce na serwerze gdy nie mamy go wystarczająco dużo na pliki dmp oraz pliki danych.

Piszemy zapytanie pod jaką lokalizacją został stworzony plik DATA_PUMP_DIR.

01

Czytaj dalej

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