sql >> Databáze >  >> RDS >> PostgreSQL

PostgreSQL běží pomalu? Tipy a triky, jak se dostat ke zdroji

Jako správce databáze PostgreSQL se každý den očekává, že bude kontrolovat zálohy, aplikovat změny DDL, ujistit se, že protokoly neobsahují žádné chyby, které by mohly narušit hru, a odpovídat na panická volání od vývojářů, jejichž zprávy běží dvakrát déle než normálně. mít schůzku za deset minut.

I když dobře rozumíte stavu spravovaných databází, vždy se budou objevovat nové případy a nové problémy související s výkonem a tím, jak se databáze „cítí“. Ať už se jedná o zpanikařený e-mail nebo otevřený lístek pro „databáze je pomalá“, tento běžný úkol lze obecně sledovat pomocí několika kroků ke kontrole, zda je či není problém s PostgreSQL a jaký může být.

V žádném případě se nejedná o vyčerpávající návod a kroky není třeba provádět v žádném konkrétním pořadí. Ale je to spíše soubor počátečních kroků, které lze podniknout, aby pomohly rychle najít běžné pachatele a také získat nový pohled na to, v čem může být problém. Vývojář může vědět, jak se aplikace chová a jak reaguje, ale správce databáze ví, jak se databáze chová a reaguje na aplikaci, a společně lze problém najít.

POZNÁMKA: Dotazy, které mají být provedeny, by měly být provedeny jako superuživatel, jako je „postgres“ nebo jakýkoli uživatel databáze, kterému byla udělena oprávnění superuživatele. Omezeným uživatelům bude buď odepřeno, nebo budou data vynechána.

Krok 0 – Shromažďování informací

Získejte co nejvíce informací od toho, kdo říká, že se databáze zdá pomalá; konkrétní dotazy, připojené aplikace, časové rámce zpomalení výkonu atd. Čím více informací poskytnou, tím snáze bude problém najít.

Krok 1 – Zkontrolujte pg_stat_activity

Požadavek může mít mnoho různých forem, ale pokud je „pomalost“ obecným problémem, kontrola pg_stat_activity je prvním krokem k pochopení toho, co se děje. Pohled pg_stat_activity (dokumentaci pro každý sloupec v tomto pohledu lze nalézt zde) obsahuje řádek pro každý proces serveru / připojení k databázi z klienta. V tomto zobrazení je několik užitečných informací, které vám mohou pomoci.

POZNÁMKA: Je známo, že pg_stat_activity v průběhu času mění strukturu a zpřesňuje data, která prezentuje. Pochopení samotných sloupců pomůže v budoucnu dynamicky vytvářet dotazy podle potřeby.

Pozoruhodné sloupce v pg_stat_activity jsou:

  1. dotaz:textový sloupec zobrazující dotaz, který se právě provádí, čeká na provedení nebo byl naposledy proveden (v závislosti na stavu). To může pomoci určit, které dotazy/dotazy, které může vývojář hlásit, běží pomalu.
  2. client_addr:IP adresa, ze které pochází toto připojení a dotaz. Pokud je prázdný (nebo Null), pochází z localhost.
  3. backend_start, xact_start, query_start:Tyto tři poskytují časové razítko, kdy každý začal. Backend_start představuje, kdy bylo navázáno připojení k databázi, xact_start je začátek aktuální transakce a query_start je začátek aktuálního (nebo posledního) dotazu.
  4. stav:Stav připojení k databázi. Aktivní znamená, že právě provádí dotaz, „nečinný“ znamená, že čeká na další vstup od klienta, „nečinný v transakci“ znamená, že čeká na další vstup od klienta, zatímco drží otevřenou transakci. (Existují další, ale jejich pravděpodobnost je vzácná, další informace najdete v dokumentaci).
  5. datname:Název databáze, ke které je připojení aktuálně připojeno. Ve více databázových clusterech to může pomoci izolovat problematická připojení.
  6. wait_event_type a wait_event:Tyto sloupce budou mít hodnotu null, když dotaz nečeká, ale pokud čeká, budou obsahovat informace o tom, proč dotaz čeká, a prozkoumání pg_locks může určit, na co čeká. (PostgreSQL 9.5 a starší má pouze booleovský sloupec nazvaný ‚čekání‘, pravda, pokud čekáte, nepravda, pokud ne.

1.1. Čeká dotaz/blokován?

Pokud existuje konkrétní dotaz nebo dotazy, které jsou „pomalé“ nebo „nezaseknuté“, zkontrolujte, zda nečekají na dokončení dalšího dotazu. Kvůli uzamčení vztahu mohou jiné dotazy uzamknout tabulku a nedovolit jiným dotazům přistupovat k datům nebo je měnit, dokud nebude tento dotaz nebo transakce dokončena.

PostgreSQL 9.5 a starší:

SELECT * FROM pg_stat_activity WHERE waiting = TRUE;

PostgreSQL 9.6:

SELECT * FROM pg_stat_activity WHERE wait_event IS NOT NULL;

PostgreSQL 10 a novější (?):

SELECT * FROM pg_stat_activity WHERE wait_event IS NOT NULL AND backend_type = 'client backend';

Výsledky tohoto dotazu ukáží všechna připojení, která aktuálně čekají na jiné připojení, aby uvolnily zámky u vztahu, který je potřeba.

Pokud je dotaz blokován jiným připojením, existuje několik způsobů, jak zjistit, co to je. V PostgreSQL 9.6 a novějších umožňuje funkce pg_blocking_pids() zadat ID procesu, který je blokován, a vrátí pole ID procesů, které jsou zodpovědné za jeho blokování.

PostgreSQL 9.6 a novější:

SELECT * FROM pg_stat_activity 
WHERE pid IN (SELECT pg_blocking_pids(<pid of blocked query>));

PostgreSQL 9.5 a starší:

SELECT blocked_locks.pid     AS blocked_pid,
         blocked_activity.usename  AS blocked_user,
         blocking_locks.pid     AS blocking_pid,
         blocking_activity.usename AS blocking_user,
         blocked_activity.query    AS blocked_statement,
         blocking_activity.query   AS current_statement_in_blocking_process
   FROM  pg_catalog.pg_locks         blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity  ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks         blocking_locks 
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
   WHERE NOT blocked_locks.GRANTED;

(Dostupné z PostgreSQL Wiki).

Tyto dotazy budou ukazovat na cokoli, co blokuje konkrétní poskytnuté PID. Díky tomu lze rozhodnout o ukončení blokovacího dotazu nebo připojení, nebo jej nechat běžet.

Krok 2 – Pokud dotazy běží, proč tak dlouho trvají?

2.1. Spouští plánovač dotazy efektivně?

Pokud má dotaz (nebo sada dotazů) stav „aktivní“, pak je ve skutečnosti spuštěn. Pokud celý dotaz není dostupný v pg_stat_activity, získejte jej od vývojářů nebo z protokolu postgresql a začněte prozkoumávat plánovač dotazů.

EXPLAIN SELECT * FROM postgres_stats.table_stats t JOIN hosts h ON (t.host_id = h.host_id) WHERE logged_date >= '2018-02-01' AND logged_date < '2018-02-04' AND t.india_romeo = 569;
Nested Loop  (cost=0.280..1328182.030 rows=2127135 width=335)
  ->  Index Scan using six on victor_oscar echo  (cost=0.280..8.290 rows=1 width=71)
          Index Cond: (india_romeo = 569)
  ->  Append  (cost=0.000..1306902.390 rows=2127135 width=264)
        ->  Seq Scan on india_echo romeo  (cost=0.000..0.000 rows=1 width=264)
                Filter: ((logged_date >= '2018-02-01'::timestamp with time zone) AND (logged_date < '2018-02-04'::timestamp with time zone) AND (india_romeo = 569))
        ->  Seq Scan on juliet victor_echo  (cost=0.000..437153.700 rows=711789 width=264)
                Filter: ((logged_date >= '2018-02-01'::timestamp with time zone) AND (logged_date < '2018-02-04'::timestamp with time zone) AND (india_romeo = 569))
        ->  Seq Scan on india_papa quebec_bravo  (cost=0.000..434936.960 rows=700197 width=264)
                Filter: ((logged_date >= '2018-02-01'::timestamp with time zone) AND (logged_date < '2018-02-04'::timestamp with time zone) AND (india_romeo = 569))
        ->  Seq Scan on two oscar  (cost=0.000..434811.720 rows=715148 width=264)
                Filter: ((logged_date >= '2018-02-01'::timestamp with time zone) AND (logged_date < '2018-02-04'::timestamp with time zone) AND (india_romeo = 569))

Tento příklad ukazuje plán dotazů pro spojení dvou tabulek, které také zasáhne rozdělenou tabulku. Hledáme cokoli, co může způsobit zpomalení dotazu, a v tomto případě plánovač provádí několik sekvenčních skenů na oddíly, což naznačuje, že jim chybí indexy. Přidání indexů do těchto tabulek pro sloupec „india_romeo“ tento dotaz okamžitě zlepší.

Věci, které je třeba hledat, jsou sekvenční skenování, vnořené smyčky, drahé třídění atd. Porozumění plánovači dotazů je zásadní pro zajištění toho, aby dotazy fungovaly co nejlépe, oficiální dokumentaci si můžete přečíst zde.

2.2. Jsou zapojené stoly nafouklé?

Pokud jsou dotazy stále pomalé, aniž by plánovač dotazů ukazoval na něco zřejmého, je čas zkontrolovat stav příslušných tabulek. Jsou příliš velké? Jsou nafouklí?

SELECT n_live_tup, n_dead_tup from pg_stat_user_tables where relname = ‘mytable’;
n_live_tup  | n_dead_tup
------------+------------
      15677 |    8275431
(1 row)

Zde vidíme, že existuje mnohonásobně více mrtvých řádků než živých řádků, což znamená, že k nalezení správných řádků musí motor prosít data, která ani nejsou relevantní, aby našel skutečná data. Vakuum / vakuum plné na tomto stole výrazně zvýší výkon.

Krok 3 – Kontrola protokolů

Pokud problém stále nelze najít, zkontrolujte protokoly, zda nejsou nějaké stopy.

FATAL / ERROR zprávy:

Hledejte zprávy, které mohou způsobovat problémy, jako jsou uváznutí nebo dlouhé čekací doby na získání zámku.

Kontrolní body

Doufejme, že log_checkpoints je nastaveno na on, což bude zapisovat informace o kontrolních bodech do protokolů. Existují dva typy kontrolních bodů, časované a vyžádané (vynucené). Pokud jsou kontrolní body vynuceny, pak je třeba před zpracováním dalších dotazů zapsat špinavé vyrovnávací paměti v paměti na disk, což může dát databázovému systému celkový pocit „pomalosti“. Zvýšení checkpoint_segments nebo max_wal_size (v závislosti na verzi databáze) poskytne kontrolnímu ukazateli více prostoru pro práci a také pomůže editoru na pozadí převzít část zátěže při psaní.

Krok 4 – Jaký je stav hostitelského systému?

Pokud v samotné databázi nejsou žádné stopy, možná je samotný hostitel přetížený nebo má problémy. Cokoli od přetíženého IO kanálu po disk, přetečení paměti za účelem swapu nebo dokonce selhávající disk, žádný z těchto problémů by nebyl zjevný s ničím, na co jsme se podívali dříve. Za předpokladu, že databáze běží na operačním systému založeném na *nix, zde je několik věcí, které mohou pomoci.

4.1. Zatížení systému

Pomocí „top“ se podívejte na průměrnou zátěž hostitele. Pokud se počet blíží nebo překračuje počet jader v systému, mohlo by to být jednoduše příliš mnoho souběžných připojení, které zasáhlo databázi a přivedlo ji k procházení, aby je dohnala.

load average: 3.43, 5.25, 4.85

4.2. Systémová paměť a SWAP

Pomocí „zdarma“ zkontrolujte, zda byl SWAP vůbec použit. Přetečení paměti do SWAP v databázovém prostředí PostgreSQL je extrémně špatné pro výkon a mnoho DBA dokonce odstraní SWAP z databázových hostitelů, protože chyba „nedostatek paměti“ je pro mnohé výhodnější než pomalý systém.

Pokud se používá SWAP, restart systému jej vyčistí a může být potřeba zvýšit celkovou systémovou paměť nebo překonfigurovat využití paměti pro PostgreSQL (jako je snížení shared_buffers nebo work_mem).

[[email protected] ~]$ free -m
              total        used        free      shared  buff/cache   available
Mem:           7986         225        1297          12        6462        7473
Swap:          7987        2048        5939

4.3. Přístup k disku

PostgreSQL se pokouší udělat hodně své práce v paměti a rozložit zápis na disk, aby se minimalizovala úzká hrdla, ale na přetíženém systému s těžkým zápisem je snadno možné vidět, že těžké čtení a zápisy způsobí zpomalení celého systému, když dohání. na požadavcích. Rychlejší disky, více disků a IO kanály jsou některé způsoby, jak zvýšit množství práce, kterou lze provést.

Nástroje jako „iostat“ nebo „iotop“ mohou pomoci určit, zda existuje úzké hrdlo disku a odkud může pocházet.

4.4. Zkontrolujte protokoly

Pokud vše ostatní selže, nebo i když ne, měli byste vždy zkontrolovat protokoly, abyste zjistili, zda systém nehlásí něco, co není v pořádku. Již jsme diskutovali o kontrole postgresql.logs, ale systémové protokoly mohou poskytnout informace o problémech, jako jsou selhání disků, selhání paměti, problémy se sítí atd. Každý z těchto problémů může způsobit, že databáze bude fungovat pomalu a nepředvídatelně, takže dobré pochopení dokonalého zdraví může pomoci najít tyto problémy.

Stáhněte si Whitepaper Today Správa a automatizace PostgreSQL s ClusterControlZjistěte, co potřebujete vědět k nasazení, monitorování, správě a škálování PostgreSQLStáhněte si Whitepaper

Krok 5 – Něco stále nedává smysl?

I ti nejzkušenější správci narazí na něco nového, co nedává smysl. Zde může pomoci globální komunita PostgreSQL. Podobně jako v kroku č. 0 platí, že čím jasnější informace jsou komunitě poskytnuty, tím snadněji mohou pomoci.

5.1. PostgreSQL e-mailové konference

Vzhledem k tomu, že PostgreSQL je vyvíjen a spravován komunitou s otevřeným zdrojovým kódem, existují tisíce lidí, kteří prostřednictvím e-mailových konferencí diskutují o nesčetných tématech včetně funkcí, chyb a problémů s výkonem. E-mailové konference lze nalézt zde, přičemž pgsql-admin a pgsql-performance jsou nejdůležitější pro hledání pomoci s problémy s výkonem.

5.2. IRC

Freenode hostí několik PostgreSQL kanálů s vývojáři a správci po celém světě a není těžké najít užitečnou osobu, která by vystopovala, odkud mohou pocházet problémy. Více informací lze nalézt na IRC stránce PostgreSQL.


  1. Správnost a omezení

  2. Jak formátovat záporné hodnoty pomocí závorek na serveru SQL Server (T-SQL)

  3. Rails:Postgres oprávnění k vytvoření databáze na rake db:create:all odepřeno

  4. CHYBA:sloupec vztahu neexistuje PostgreSQL ,Nelze spustit dotaz na vložení