Prezentacja dla KS-ZSA Spis treści Prezentacja dla KS-ZSA...1 1.Oracle...2 1.1.Statystyki schematów, tabel, indeksów...2 1.1.1.Schematy...2 1.1.2.Tabele...3 1.1.3.Indeksy...3 1.2.Zarządzanie plikami danych / przestrzeniami tabel...4 1.2.1.Powiększanie przestrzeni tabel...4 1.2.2.Pomniejszanie plików danych...5 1.3.Zarządzanie przestrzenią UNDO - snapshot too old...7 1.4.Tuning...9 1.4.1.Newralgiczne parametry...9 1.4.2.Zapytajmy bazy czego chce...9 1.5.Kosz...12 1.6.Specyfika Oracla XE...13 2.Bde i klient Oracle kilka problemów...16 2.1.Borland Database Engine...16 2.2.Klient Oracle...18 Aktualna wersja dokumentacji (w tym instrukcja) znajduje się na serwerze FTP firmy Kamsoft: ftp://ftp.kamsoft.pl/pub/ks-fn/ks-zsa/dokumentacja/ Katowice 2008-06-09
1.Oracle 1.1.Statystyki schematów, tabel, indeksów 1.1.1.Schematy Wymuszanie przeliczenia statystyk na wybranym schemacie przybliŝone (szybsze, mniej dokładne) begin dbms_utility.analyze_schema('nazwa_schematu','estimate'); end; / dokładne (działa dłuŝej, bo analizuje wszystkie rekordy) begin dbms_utility.analyze_schema('nazwa_schematu','compute'); end; / Usunięcie statystyk begin dbms_utility.analyze_schema('nazwa_schematu','delete'); end; / Sprawdzenie kiedy ostatnio były aktualizowane statystyki select table_name,last_analyzed from dba_tables where owner='nazwa_schematu' and last_analyzed is not null Wyłączanie zbierania statystyk na całej bazie begin dbms_scheduler.disable('gather_stats_job'); end; /
1.1.2.Tabele Przeliczenie statystyk dla tabeli nazwa_tabeli analyze table nazwa_tabeli compute statistics; Skasowanie statystyk dla tabeli nazwa_tabeli analyze table nazwa_tabeli delete statistics; Przeliczenie statystyk dla tabeli nazwa_tabeli, na podstawie 20% rekordów analyze table nazwa_tabeli estimate statistics sample 20 percent; Przeliczenie statystyk dla tabeli nazwa_tabeli na podstawie 100 wierszy analyze table nazwa_tabeli estimate statistics sample 100 rows; Przeliczenie statystyk dla tabeli nazwa_tabeli dla wszystkich kolumn z indeksami analyze table nazwa_tabeli compute statistics for all indexed columns; Przeliczenie statystyk dla tabeli nazwa_tabeli dla wszystkich kolumn analyze table nazwa_tabeli compute statistics for all columns; 1.1.3.Indeksy Przeliczenie statystyk dla indeksu nazwa_indeksu analyze index nazwa_indeksu compute statistics; Skasowanie statystyk dla indeksu nazwa_indeksu analyze index nazwa_indeksu delete statistics;
1.2.Zarządzanie plikami danych / przestrzeniami tabel 1.2.1.Powiększanie przestrzeni tabel JeŜeli dostajemy błąd Oracle który mówi, Ŝe brakło miejsca w przestrzeni tabel, to oznacza, Ŝe mamy do czynienia z jedną z trzech sytuacji: nie ustawiliśmy automatycznego rozszerzania plików w przestrzeni tabel plik danych osiągnął maksymalną wielkość (przy opcji smallfile - domyślnej - maksymalną wielkością pliku jest 32GB) brakło miejsca na dysku Generalnie polecenie zmieniające wielkość pliku danych ma postać: ALTER DATABASE DATAFILE '<data_file_name data_file_number>' RESIZE <n> K M G T P E; Wydając to polecenie moŝemy zwiększyć (lub zmniejszyć) rozmiar pliku danych. MoŜe być tak, Ŝe z róŝnych względów nie chcemy zwiększać wielkości danego pliku (lub nie moŝemy), wtedy w celu rozszerzenia miejsca dla przestrzeni tabel, nalezy dodać do niej następny plik danych. Składnia polecenia dodającego plik danych do przestrzeni tabel jest następująca: ALTER TABLESPACE <tablespace_name> ADD DATAFILE '<path_and_file_name>' SIZE <n>k M G T P E; Uwaga!! Maksymalna liczba plików danych wykorzystywanych przez baze Oracle (w wersji 9i i 10g) to 65536. Maksymalna wielkość pojedynczego pliku danych w bazie Oracle 10g moŝe być obliczona ze wzoru maksymalna wielkość pliku = db_block_size * maksymalna liczba bloków w pliku Analogicznie maksymalna wielkość bazy danych maksymalna wielkość bazy = maksymalna wielkość pliku * maksymalna liczba plików w bazie dla wersji 10g Wielkość bloku Maksymalna wielkość pliku Maksymalna wielkość bazy 32 K 131,072 GB 8,589,934,592 GB 16 K 65,536 GB 4,294,967,296 GB 8 K 32,768 GB 2,147,483,648 GB 4 K 16,384 GB 1,073,741,824 GB 2 K 8,192 GB 536,870,912 GB dla wersji 9i Wielkość bloku Maksymalna wielkość pliku Maksymalna wielkość bazy 32 K 128 GB 8,388,608 GB 16 K 64 GB 4,194,304 GB 8 K 32 GB 2,097,152 GB 4 K 16 GB 1,048,579 GB 2 K 8 GB 524,288 GB Wielkości plików danych i ich zajetość moŝna odczytać wykonując zapytanie:
select FILE_NAME, d.tablespace_name, d.bytes datafile_size, nvl(sum(e.bytes),0) bytes_used, round(nvl(sum(e.bytes),0) / (d.bytes), 4) * 100 percent_used, d.bytes - nvl(sum(e.bytes),0) bytes_free from DBA_EXTENTS e, DBA_DATA_FILES d where d.file_id = e.file_id (+) group by FILE_NAME,d.TABLESPACE_NAME, d.file_id, d.bytes, STATUS order by d.tablespace_name,d.file_id Przykładowy wynik FILE_NAME TABLESPACE_NAME DATAFILE_SIZE BYTES_USED PERCENT_USED /database/dbname/apw_data.dbf BYTES_FREE APWDATA 272629760 267845632 98.25 4784128 1.2.2.Pomniejszanie plików danych ZałóŜmy sobie hipotetyczną sytuację: Mamy plik danych, wciągamy do niego dwie tabele, kaŝda ma po 50MB. W tabelach mamy rekordy które zajmują po 2kb, w pliku mamy bloki o wielkości 8kb. Po wykonaniu Update kasuje nam się z kaŝdej tabeli po 30MB, zostaje po 20MB. plik danych ma dalej 100MB i nie da sie go zmniejszyć, bo sa dane pod koniec pliku. dane w pliku zajmują 60MB, chociaŝ w rzeczywistości zajmują 40MB, stało się tak, poniewaŝ skasowaliśmy pojedyncze rekordy i poszczególne bloki nie sa zapełnione juŝ całkowicie, a tylko częściowo, więc w sumie zajmują więcej. W związku z powyŝszym musimy wykonać kilka czynności:
1.Włączyć na tabelach opcję Row Movement. alter table nazwa_tabeli enable row movement; MoŜna sprawdzić czy tabela ma włączona opcje row movement wykonując zapytanie: select table_name, tablespace_name, blocks, row_movement from dba_tables where tablespace_name like '%LAB%' order by blocks; W wyniku którego otrzymamy przykładowo: OPCJAR LAB 880 DISABLED MISC LAB 942 ENABLED LBUB LAB 3462 DISABLED ZLEC LAB 3652 DISABLED BPRK LAB 6486 DISABLED 2. Zdefragmentować tabelę, czyli poprzekładać rekordy tak, aby zajmowały pojedyncze bloki w jak najwiekszym stopniu alter table nazwa_tabeli shrink space cascade; Przykładowo przed shrinkiem na ZLEC Tablespace %Free %Used Mb Free Mb Used LAB 22 78 106 383 po shrinku na ZLEC Tablespace %Free %Used Mb Free Mb Used LAB 25 75 121 367 3.Przenieść poszczególne bloki na początek pliku. alter table <table_name> move; 4.Ewentualnie przebudować indeksy alter index <index_name> rebuild; Uwaga: JeŜeli podczas włączania opcji row movement otrzymamy komunikat ORA-10662: Segment has long columns to niestety moŝemy sobie podarować powyŝszą procedurę i zostaje tylko export/import.
1.3.Zarządzanie przestrzenią UNDO - snapshot too old W bazie Oracle funkcjonuje mechanizm nazwany zachowywaniem spójności danych. Polega on generalnie na tym, Ŝe wydając zapytanie do bazy, otrzymamy w odpowiedzi dane dokładnie z chwili wydania zapytania. Przykładowo puszczamy jakieś długie zapytanie które odczytuje dane z tabeli w tym samym czasie ktoś inny puszcza update na tej tabeli dostaniemy w odpowiedzi na nasze zapytanie dane sprzed update Do tego, Ŝeby otrzymać dane z chwili wydania zapytania Oracle korzysta z danych przechowywanych w przestrzeni UNDO. KaŜda zmiana danych (wogóle kaŝda operacja) powoduje skopiowanie do przestrzeni UNDO danych sprzed zmiany. JeŜeli Oracle podczas wykonywania zapytania dotrze do danych, które w międzyczasie zostały zmienione, to odczyta je z historii przechowywanej w przestrzeni UNDO. Problem jaki się pojawia, to zbyt duŝa ilość zmian / zbyt mała wielkość przestrzeni UNDO, a co za tym idzie niemoŝność odczytania przez Oracle danych historycznych (w przestrzeni UNDO jest przechowywana określona ilość danych, które w przypadku braku miejsca zostaną nadpisane). O takim właśnie przypadku mówi komunikat Snapshot too old. Jak widać moŝemy właściwie zrobić w tym przypadku trzy rzeczy: zmiana parametrów dotyczących operacji undo przekonać uŝytkowników, zeby nie korzystali z aplikacji w momencie wykonywania zapytania (ewentualnie, jeŝeli moŝna, to zdefiniowanie takiego zapytania do wykonania w czasie mniejszego obciąŝenia) zmienić zapytanie, Ŝeby nie musiało korzystać z danych historycznych / z takiej ilości danych (o ile jest to zapytanie napisane przez nas samych) Generalnie za politykę operacji undo odpowiada parametr undo_retention, który domyślnie jest ustawiony na 900 (co oznacza przechowywanie historii z 900 ostatnich sekund, czyli 15 minut), lub wielkość przestrzeni tabel (jeŝeli jest ustawiona stała wielkość, to parametr undo_retention jest ignorowany). śeby w miarę optymalnie ustawić zarządzanie undo, moŝemy wykonac kilka zapytań i wyliczyć wielkość dla parametru undo_retention Aktualna_wielkość_undo Undo_retention = ------------------------------------------------------------------------ (Ilość_bloków_na_sec * Wielkość_bloków_danych) Aktualna wielkość przetsrzeni UNDO SELECT SUM(a.bytes) "SIZE" FROM v$datafile a, v$tablespace b, dba_tablespaces c WHERE c.contents = 'UNDO' AND c.status = 'ONLINE' AND b.name = c.tablespace_name AND a.ts# = b.ts#;
Wynik: SIZE 382730240 Ilość uŝytych bloków undo / sekundę SELECT MAX(undoblks/((end_time-begin_time)*3600*24)) op/sec FROM v$undostat; Wynik: op/sec ---------- 3.62 Wielkość bloków danych SELECT TO_NUMBER(value) "DB_BLOCK_SIZE [KByte]" FROM v$parameter WHERE name = 'db_block_size'; Wynik DB_BLOCK_SIZE [Byte] -------------------- 8192 Optymalnie w związku z tym powinno być: undo_retention = 382730240 / (3.62 * 8192) = 12906 sekund MoŜna równieŝ do tematu podejść z drugiej strony: chcemy, aby była trzymana historia z ostatnich 30 minut (1800 sekund), więc obliczamy według wzoru: Wielkość_przestrzeni_undo = undo_retention * wielkość_bloku_danych * Ilość_operacji_undo_na_sec więc w naszym przykładzie Wielkość_przestrzeni_undo = 1800 * 8192 * 3.62 = 53379072 (czyli 55MB) Wcześniej wielkość przestrzeni UNDO była 382MB, wiec widać, Ŝe moŝemy zmniejszyć wielkość przestrzeni, bo trzymana jest historia dłuŝsza niŝ potrzebujemy.
1.4.Tuning 1.4.1.Newralgiczne parametry Parametrami które mają wpływ na wydajność bazy najczęściej zmienianymi są: sga_max_size, sga_target wielkość pamięci SGA DB_CACHE_SIZE, JAVA_POOL_SIZE, LARGE_POOL_SIZE, SHARED_POOL_SIZE, LOG_BUFFER obszary w SGA pga_aggregate_target wielkość pamięci PGA SORT_AREA_SIZE, HASH_AREA_SIZE, BITMAP_MERGE_AREA_SIZE, CREATE_BITMAP_AREA_SIZE obszary PGA Dodatkowo z punktu widzenia aplikacji Kamsoft i ogólnie pracy bazy Oracle, naleŝy zwrócić uwagę na parametry: OPEN_CURSORS OPEN_LINKS PROCESSES SESSIONS UWAGA!! Parametrem którego nie naleŝy zmieniać (chociaŝ Oracle moŝe podpowiadać, Ŝe tak byłoby lepiej) jest parametr CURSOR_SHARING. Najprawdopodobniej jest to związane z BDE - zmiana tego parametru (na jakąkolwiek inną wartość niŝ domyślna - EXACT ) powoduje, Ŝe w niektórych oknach aplikacji nie wyświetlają się nam dane (dokładniej to wyświetlają się śmieci, które są odfiltrowane). 1.4.2.Zapytajmy bazy czego chce JeŜeli chcemy spróbować zwiększyć wydajność pracy bazy Oracle, najlepiej ją odpytać i na podstawie odpowiedzi podejmować decyzje co ewentualnie moŝna zmienić. Jednym z pierwszych zapytań, które powinniśmy wykonać, jest sprawdzenie: jakie zdarzenia zajmują najwięcej czasu pracy bazy. W tym celu naleŝy wykonac poniŝsze zapytanie: select EVENT, from order TOTAL_WAITS, TOTAL_TIMEOUTS, TIME_WAITED, round(average_wait,2) "Average Wait" v$system_event by TIME_WAITED asc W ten sposób na samym dole otrzymamy zdarzenie które mogą mieć wpływ na wydajność pracy bazy danych. Niekoniecznie wszystkie zdarzenia będą miały wpływ na pracę, zdarzenia typu SQL*Net message from client lub rdbms ipc message oznaczaja tylko oczekiwanie przez bazę na następne zapytanie od uŝytkownika, więc w praktyce oznaczają Ŝe najwięcej czasu baza stoi i nic nie robi
(tu moŝemy zwiększyć wydajność, definiując zadania tak, aby wykonywały się w czasie kiedy baza jest słabo obciąŝona). Są jednak zdarzenia które oznaczają róŝnego rodzaju problemy i miejsca którym naleŝałoby się przyjrzeć. log file parallel write - oczekiwanie na zapisanie pliku redo db file parallel read i db file parallel write - oczekiwanie na zapis/odczyt danych z pliku db file scattered read - oczekiwanie na odczytanie wielu danych z pliku (np. podczas wykorzystywania indeksów) Wszystkie powyŝsze zdarzenia oznaczają długie korzystanie z dysków, ale pierwszy z nich niekoniecznie musi być spowodowany prędkością działania dysku. Generalnie pliki redo logów są dość duŝym obciąŝeniem dla systemu I/O i naleŝy rozwaŝnie podchodzić do ich obsługi. Są to pliki dość istotne dla pracy bazy, więc mirrorowanie tych plików z jednej strony ma sens, jednakŝe do tych plików jest najwięcej zapisów (tam leci cała historia zmian w bazie) i widziałem juŝ przypadki, kiedy te pliki były zapisywane 4 w ciągu minuty ( w tamtej konfiguracji oznaczało to zapisywanie 200MB na minutę) jeŝeli stworzymy mirrory do tych plików (czyli dodamy drugie pliki w poszczególnych grupach redo) to obciąŝenie wzrasta nam dwukrotnie (czyli 400MB na minutę) to naprawde potrafi bardzo zauwaŝalnie spowolnić prace serwera. Jeśli chodzi o podział pamieci to moŝna zadać kilka innych zapytań: DB Buffer Cache Hit Ratio SELECT 'DB Buffer cache Hit ratio ' "Ratio", round((1 - ((SELECT sum(value) FROM v$sysstat WHERE name = 'physical reads') / ((SELECT sum(value) FROM v$sysstat WHERE name = 'db block gets') + (SELECT sum(value) FROM v$sysstat WHERE name = 'consistent gets')))) * 100) '%' "Percentage" FROM dual; Dictionary Cache Hit Ratio select a.name "Pool", a.physical_reads, a.db_block_gets, a.consistent_gets, (select round((1 - (physical_reads/(db_block_gets + consistent_gets)))*100) from v$buffer_pool_statistics where db_block_gets + consistent_gets!= 0 and name = a.name) "ratio"
from v$buffer_pool_statistics a; Library Cache Hit Ratio select sum(pins) Executions, sum(reloads) cache_misses, sum(reloads) / sum(pins) miss_ratio from v$librarycache SQL Cache Hit Ratio select sum(pins) Pins, sum(reloads) Reloads, round((sum(pins) - sum(reloads)) / sum(pins) * 100,2) Hit_Ratio from v$librarycache Statystyki sortowań select NAME, VALUE from v$sysstat where NAME like 'sort%' Hit Ratio dla poszczególnych uŝytkowników select USERNAME, CONSISTENT_GETS, BLOCK_GETS, PHYSICAL_READS, ((CONSISTENT_GETS+BLOCK_GETS-PHYSICAL_READS) / (CONSISTENT_GETS+BLOCK_GETS)) Ratio from v$session, v$sess_io where v$session.sid = v$sess_io.sid and (CONSISTENT_GETS+BLOCK_GETS) > 0 and USERNAME is not null order by ((CONSISTENT_GETS+BLOCK_GETS-PHYSICAL_READS) / (CONSISTENT_GETS+BLOCK_GETS)) Wyświetlenie aktualnych sesji wraz z zajetością CPU select nvl(ss.username,'oracle PROC') username, se.sid, ss.machine, value cpu_usage from v$session ss, v$sesstat se, v$statname sn where se.statistic# = sn.statistic# and and NAME like '%CPU used by this session%' se.sid = ss.sid
order by VALUE asc;
1.5.Kosz W bazie Oracle 10g wprowadzony został kosz. Wszystkie obiekty które są kasowane, domyślnie w tym koszu ladują. Co za tym idzie nie zwalniają miejsca w bazie. Obiekty te są kasowane dopiero po wydaniu polecenia purge recyclebin; lub z poziomu uŝytkownika z prawami administratora purge dba_recyclebin; czysci śmieci z koszów wszystkich uŝytkowników. MoŜemy równeiŝ wyłączyc kosz na stałe w bazie, ustawiając parametr inicjalizacyjny recyclebin = off
1.6.Specyfika Oracla XE Oracle XE ma kilka ograniczeń, jednym z najistotniejszych jest obsługa bazy danych nie większej niŝ 4GB, pozostałe to: obsługa 1 procesora, obsługa do 1GB pamięci SGA, brak obsługi Javy na serwerze i tylko jedna moŝliwa instancja na serwerze. Są to ograniczenia nie do obejscia, i nie są tylko papierowymi. Przykładowo: Przekroczenie wielkosci bazy poza 4GB (bez systemu) ORA-12952: The request exceeds the maximum allowed database size of 4 GB ustawienie pamięci powyŝej 1GB ORA-44412: XE edition memory parameter invalid or not specified Drugim problemem który napotykamy juŝ na poczatku jest domyślna instalacja bazy XE z obsługą kodowania WE8MSWIN1252 a aplikacje Kamsoft korzystają z EE8MSWIN1250. Procedura zmiany kodowania na EE8MSWIN1250 logujemy się sqlplusem, czyli będąc zalogowanym na serwerze jako uŝytkownik naleŝący do grupy ora_dba sqlplus / as sysdba i wydajemy polecenia shutdown immediate; startup mount; alter system enable restricted session; alter system set job_queue_processes=0; alter system set aq_tm_processes=0; alter database open; alter database character set internal_use EE8MSWIN1250; shutdown immediate; startup open; exit (Istotna informacja: Instalator KS-ZSA sam wykonuje powyŝsze operacje, więc naleŝy je wykonywać tylko w przypadku ręcznego instalowania sobie bazy Oracle XE).
MoŜna to sprawdzić ze strony administracyjnej bazy Oracle XE Zwracam równieŝ uwagę, Ŝe domyślna instalacja bazy XE ma poustawiane parametry niŝej niŝ w wersji Standard, np: ograniczenie liczby procesów do 40 sesji do 49.
2.Bde i klient Oracle kilka problemów 2.1.Borland Database Engine Błąd tak naprawdę związany z brakiem pliku sqlora8.dll w scieŝce z której korzysta BDE. ŚcieŜkę moŝna sobie sprawdzić w rejestrze: HKLM\Software\Borland\Database Engine wartość: DLLPATH Domyślnie ustawiona na: C:\Program Files\Borland\Common Files\BDE
Błąd podobny do powyŝszego została ustalona ścieŝka do pliku pdoxusrs.net do której nie mamy dostępu do zapisu (bardzo często spotykane na MS Windows Vista. Ustawienia tej ścieŝki jest pobierane z BDE To ustawienie jest brane z pliku konfiguracyjnego BDE, czyli domyślnie c:\program Files\Borland\Common Files\BDE\IDEAPI32.CFG Ewentualnie mozemy sprawdzić jaki jest plik z ustawieniami na belce tytułowej BDEAdministratora albo znowu w rejestrze HKLM\Software\Borland\Database Engine wartość: CONFIGFILE01
2.2.Klient Oracle Próba uruchomienia aplikacji na uŝytkowniku który nie jest administratorem wywołuje błąd przy próbie zalogowania: Unable to allocate memory... Generalnie uŝytkownik musi mieć pełne uprawnienia do katalogu z klientem oracle i bde. Co istotne, ustawienie uprawnień na c:\oracle mimo włączonego przenoszenia uprawnień na podkatalogi, nie ustawia tych praw do podkatalogów oracore i w nim zoneinfo. A jest to wymagane do pracy aplikacji. Błąd jak wyŝej, ale dodatkowo:
Próba uruchomienia sqlplusa i zalogowania się na tym samym uzytkowniku SP2-1503: Unable to initialize Oracle call interface SP2-0152: ORACLE may not be functioning properly Rozwiązaniem jest Wejście w Start -> Panel sterowania -> Narzędzia administracyjne -> Zasady zabezpieczeń lokalnych W lewej części: Zasady lokalne -> Przypisywanie praw uŝytkownika W prawej części: Tworzenie obiektów globalnych -> dodajemy do tego tych uŝytkowników/grupy które mają prawo uruchamiać aplikacje Po przelogowaniu uŝytkownika będzie działać