Jaka jest różnica pomiędzy restore, a recovery?
Każdy pewnie wie, że backup to zapisanie kopii plików bazy danych w innej lokalizacji. Ale gdybyś chciała/chciał pogłębić swoją wiedzę to zapraszam na wideo: o tym jak to robi Oracle.
Co to jest restore też pewnie jest jasne - odtworzenie plików bazy danych z kopii w innej lokalizacji.
Najwięcej niejasności budzi proces recovery. Tłumaczenie nazwy wprost na polski to 'powrót do zdrowia'. Wg mnie najtrafniej, w kontekście baz danych, sens oddaje słowo 'uspójnianie'.
Baza danych jest spójna wtedy gdy wszystkie pliki z których baza się składa mają ostatnią zmianę wykonaną w tym samym czasie. Spójny backup można wykonać jedynie wtedy kiedy baza danych jest wyłączona. Nazywa się to zimnym backup'em - cold backup.
Co to jest ta 'spójność' (consistency) bazy danych ? W przypadku bazy danych Oracle jest to zgodność SCN (System Change Number) zapisanego w pliku kontrolnym (control file) z SCN zapisanym w nagłówkach plików bazodanowych. Gdy wartości te są nieidentyczne instancja Oracle uznaje bazę danych za niespójną i nie otworzy jej do użytku.
Backup gorący - hot backup - z założenia jest niespójny. Wykonanie backup'u trwa. W tym czasie baza jest otwarta i wykonywane są w niej zmiany. W związku z tym każdy plik skopiowany do innej lokalizacji ma inny czas ostatniej zmiany. W efekcie, po odtworzeniu, nie daje to spójnego obrazu danych w bazie danych i baza nie nadaje się do użycia. Aby backup był użyteczny - bazę danych dało się otworzyć i korzystać z niej - trzeba ją uspójnić. Niezbędne do tego są pliki logu transakcyjnego - o którym mowa w: - powstałe w czasie wykonywania backup'u bazy danych. Informacje o zmianach zawarte w logu transakcyjnym pozwalają na naniesienie zatwierdzonych transakcji i wycofanie niezatwierdzonych dzięki czemu pliki bazy danych zostaną uspójnione na ten sam punkt w czasie. Wtedy nadają się do użycia i baza danych może zostać otwarta.
Podobnie sprawa wygląda w momencie padu bazy danych - pliki bazy danych mają różne stemple w związku z tym instancja uznaje dane w bazie za niespójne. Podczas startu instancji bazy danych po awarii, następuje uspójnienie plików przy wykorzystaniu informacji z plików logu transakcyjnego.
Wydanie, instancji bazy danych Oracle, komendy 'shutdown abort
', w konsekwencjach, przypomina pad bazy. Instancja zostaje zamknięta bez uspójniania plików bazy danych.
Również naprawa pojedynczego pliku czy bloku bazodanowego wymaga jego odtworzenia z kopii zapasowej (restore). Aby następnie nadawał się do użycia przez bazę danych niezbędne jest przeprowadzenia na nim procesu uspójnienia (recovery). Czyli naniesienia na niego wszystkich zmian, które miały miejsce, od czasu wykonania kopii pliku czy bloku aż do chwili obecnej. Lub punktu w czasie innych plików bazy danych.
#database #oracle #mysql #postgresql #sqlserver #backup #restore #recovery #rdbms #dba4dev #marcinbadtke
Czym różni się proces od wątku - zilustrowane w 10 minut: https://youtu.be/bxi3tDmFZdE
Najważniejsze różnice:
Przy okazji: dlaczego na Windows koszt powstania procesu jest wyższy.
Keywords: #database #oracle #programming #sql #plsql #backend #coding #development #mysql #postgresql #sqlserver #linux #unix #windows #process #thread #dba4dev #marcinbadtke
@MuadibAtrides: Nic się nie zmieniło :-) Wg mnie najważniejszość zależy od perspektywy.
Z cyklu migracja #oracle do #postgresql
Witajcie,
Postgres jak zwykle nie przestaje mnie zadziwiać :) Pewna firma, z którą współpracowałem postanowiła przejść z oracle na postgresql. Bazę określiłbym jako "średnią w kierunku prostej" jeśli chodzi o złożoność dlatego też managerowie stwierdzili, że szkoda hajsu na oracle i przechodzimy na postgre. Większość rzeczy przeszła bez problemów i strukturę udało się przenieść ale kilka "modułów" nie działało prawidłowo. Pisząc nie działało prawidłowo mam na myśli, że baza nie rzucała wyjatkami ale dane były różne od oczekiwanych. No i po długich godzinach analizy znalazłem funkcję w oracle:
declare
vlisttype integer;
BEGIN
select distinct listtype into vlisttype from schemat.tabela where listname = :jakis_name
...xxx
EXCEPTION
WHEN TOO_MANY_ROWS THEN
begin
...zzz
end;
END;
ogólnie ten kawałek kodu w oracle powodował, że jeśli :jakis_name występował w scheat.tabela więcej niż 1 raz to odpalał się kod zzz
procedurka była na tyle sprytna, że 1 - 1 przeniosła się na postgresql bez błędów ale na postgresql zamiast odpalić się zzz odpalał się blok kodu xxx
no i doczytałem się, że postgresql nie rzuca wyjątku w takiej sytuacji ponieważ bierze PIERWSZY z brzegu rekord który mu pasuje (jeśli nie ma order by) i leci dalej.
Aby dostosować funkcję tej (i wielu innych podobnych procedur) konieczne jest dodanie słówka strict po into
declare
vlisttype integer;
BEGIN
select distinct listtype into strict vlisttype from schemat.tabela where listname = :jakis_name
...xxx
EXCEPTION
WHEN TOO_MANY_ROWS THEN
begin
...zzz
end;
END;
taka mała rzecz, a ile problemów :P
Miałam podobne problemy na poziomie migracji właśnie pomiędzy tymi dwoma bazami. Niestety trochę roboty z tym jest, czasem zastanawiasz się czemu coś działa tak a nie inaczej, ale finalnie da się to zrobić i jest to ciekawy case na lepsze poznanie mechanizmów obu tych silników.
O warto wiedzieć - właśnie jedna firma robi taką migrację i jest niestety trochę procedurek (za dużo).
Chciałbym podrzucić Wam kolejny przykład praktycznego zastosowania zapytania SQL w PostgreSQL. Zapytanie takie (lekko zmodyfikowane) wykorzystywane jest tutaj w module Kompendium do wyświetlania drzewa artykułów. Przykład kodu, który tutaj umieszczę może Wam posłużyć do wygenerowania np. struktury kategorii w sklepie internetowym.
W Kompendium każdy artykuł może być jednocześnie rodzicem dla innego artykułu. Dawno, dawno temu za czasów MySQL, używaliśmy do tego czegoś co nazywa się nested set model. Dodawanie czy przenoszenie fragmentu drzewa do innej kategori w takim modelu jest utrapieniem (do dziś mam traume jak o tym pomyślę). W #postgresql można wykonać to prościej poprzez rekurencje:
WITH RECURSIVE nodes AS (
(
SELECT 1 AS depth, ARRAY [id] AS node, id AS root_id, *
FROM categories
WHERE parent_id IS NULL
)
UNION ALL
SELECT r.depth + 1, r.node || n.id, r.root_id, n.*
FROM nodes r
JOIN categories n ON n.parent_id = r.id
)
SELECT depth,
node,
root_id,
nodes.name
FROM nodes
ORDER BY node;
Pierwsza kolumna zawiera poziom zagnieżdżenia dzięki czemu można ładnie zaprezentować strukturę drzewa. Oczywiście zamiast parent_id IS NULL
można wstawić ID kategorii macierzystej od której chcemy zacząć generowanie drzewa.
Tutaj cały kod: https://www.db-fiddle.com/f/4tasewSbBGvndYF1wnhziE/0
P.S. Jeżeli mamy dziesiątki tysięcy kategorii, możemy zbudować takie zapytanie przy użycyt materialized view
.
To jak się wszyscy tak o #postgresql rozpisują to i ja wrzucę małe co nieco.
Mamy sobie zapytanie w stylu:
create materialized view blebleble as
select
..
case
…
end as cośtam,
case
…
end as cośtacośtam
from tabelka
inner join a
inner join b
inner join c
inner join d and e
inner join f
Czyli w ogólności wiele joinów tabel zawierających dużo danych. Efektywnie musimy operować na kilkuset milionach rekordów. Wtedy postgres potrafi zgłupieć i wykonać joiny z użyciem mechanizmu neast loop
. Jak długo to będzie szło? W naszym przypadku było to kilka godzin. Ale jest na to rada. W ramach sesji, w której wykonujemy zapytanie, wystarczy dorzucić:
set enable_nestloop = off;
ZAPYTANIE
set enable_nestloop = on;
W ten magiczny sposób JOINy są wykonywane z użyciem hash join
co, pomimo że wygląda źle w planie, jest szybsze. W efekcie nasze nowe zapytanie ryło bazę przez 8 minut.
Do poczytania https://www.postgresql.org/docs/current/planner-optimizer.html
Pytanie czy macie dobrze skonfigurowane seq_page_cost
oraz random_page_cost
? Bo jeśli nie, to specjalnie się nie dziwię problemów.
Mnie uczyli, że najważniejsza różnica to, że wątki współdzielą zasoby między sobą, a procesy mają niezależny przydział - coś się zmieniło w tym temacie?