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 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;

 

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

 

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