Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Cândva, în viitorul îndepărtat, eliminarea automată a datelor inutile va fi una dintre sarcinile importante ale SGBD [1]. Între timp, noi înșine trebuie să ne ocupăm de ștergerea sau mutarea datelor inutile în sisteme de stocare mai puțin costisitoare. Să presupunem că decideți să ștergeți câteva milioane de rânduri. O sarcină destul de simplă, mai ales dacă afecțiunea este cunoscută și există un indice adecvat. „ȘTERGERE DIN tabelul 1 WHERE col1 = :valoare” - ce ar putea fi mai simplu, nu?

video:

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

  • Sunt în comitetul programului Highload din primul an, adică din 2007.

  • Și sunt cu Postgres din 2005. L-a folosit în multe proiecte.

  • Grup cu RuPostges tot din 2007.

  • Am ajuns la peste 2100 de participanți la Meetup. Este al doilea în lume după New York, depășit multă vreme de San Francisco.

  • Locuiesc de câțiva ani în California. Am de-a face mai mult cu companii americane, inclusiv cu cele mari. Sunt utilizatori activi ai Postgres. Și sunt tot felul de lucruri interesante.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

https://postgres.ai/ este compania mea. Ne ocupăm de automatizarea sarcinilor care elimină încetinirile dezvoltării.

Dacă faci ceva, atunci uneori există un fel de prize în jurul Postgres. Să presupunem că trebuie să așteptați ca administratorul să instaleze un stand de testare pentru dvs. sau trebuie să așteptați ca DBA să vă răspundă. Și găsim astfel de blocaje în procesul de dezvoltare, testare și administrare și încercăm să le eliminăm cu ajutorul automatizării și al noilor abordări.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

https://www.seagate.com/files/www-content/our-story/trends/files/idc-seagate-dataage-whitepaper.pdf

Am fost recent la VLDB din Los Angeles. Aceasta este cea mai mare conferință despre baze de date. Și a existat un raport că în viitor DBMS nu numai că va stoca, ci și va șterge automat datele. Acesta este un subiect nou.

Există din ce în ce mai multe date în lumea zettabytes - adică 1 de petabytes. Și acum se estimează deja că avem peste 000 de zettabytes de date stocați în lume. Și sunt din ce în ce mai mulți.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

https://vldb2019.github.io/files/VLDB19-keynote-2-slides.pdf

Și ce să faci cu ea? Evident că trebuie îndepărtat. Iată un link către acest raport interesant. Dar până acum acest lucru nu a fost implementat în DBMS.

Cei care pot număra bani vor două lucruri. Ei vor să ștergem, așa că din punct de vedere tehnic ar trebui să putem face acest lucru.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Ceea ce voi spune în continuare este o situație abstractă care include o grămadă de situații reale, adică un fel de compilare a ceea ce mi s-a întâmplat de fapt cu mine și cu bazele de date din jur de multe ori, mulți ani. Greblele sunt peste tot și toată lumea le calcă tot timpul.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Să presupunem că avem o bază sau mai multe baze care cresc. Și unele înregistrări sunt, evident, un gunoi. De exemplu, utilizatorul a început să facă ceva acolo, dar nu l-a terminat. Și după ceva timp știm că acest neterminat nu mai poate fi păstrat. Adică am dori să curățăm niște lucruri de gunoi pentru a economisi spațiu, a îmbunătăți performanța etc.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

În general, sarcina este de a automatiza eliminarea unor lucruri specifice, linii specifice dintr-un tabel.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Și avem o astfel de cerere, despre care vom vorbi astăzi, adică despre eliminarea gunoiului.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Am cerut unui dezvoltator experimentat să o facă. A acceptat această solicitare, a verificat-o singur - totul funcționează. Testat pe scenă - totul este în regulă. Lansat - totul funcționează. O dată pe zi îl rulăm - totul este bine.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Baza de date crește și crește. ȘTERGEREA zilnică începe să funcționeze puțin mai încet.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Atunci înțelegem că acum avem o companie de marketing și traficul va fi de câteva ori mai mare, așa că decidem să punem temporar în pauză lucrurile inutile. Și uită să te întorci.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Câteva luni mai târziu și-au amintit. Și acel dezvoltator a renunțat sau este ocupat cu altceva, a instruit pe altul să-l returneze.

A verificat pe dev, pe scenă - totul este OK. Desigur, mai trebuie să curățați ceea ce s-a acumulat. A verificat că totul funcționează.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Ce se întâmplă mai departe? Atunci totul se destramă pentru noi. Scade astfel încât la un moment dat totul cade jos. Toată lumea este în stare de șoc, nimeni nu înțelege ce se întâmplă. Și apoi se dovedește că problema era în acest DELETE.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Ceva n-a mers bine? Iată o listă cu ceea ce ar fi putut merge prost. Care dintre acestea este cea mai importantă?

  • De exemplu, nu a existat nicio revizuire, adică expertul DBA nu a analizat-o. Ar găsi imediat problema cu un ochi experimentat și, în plus, are acces la prod, unde s-au acumulat câteva milioane de linii.

  • Poate au verificat ceva greșit.

  • Poate că hardware-ul este depășit și trebuie să actualizați această bază.

  • Sau ceva nu este în regulă cu baza de date în sine și trebuie să trecem de la Postgres la MySQL.

  • Sau poate e ceva în neregulă cu operația.

  • Poate că există unele greșeli în organizarea muncii și trebuie să concediezi pe cineva și să angajezi cei mai buni oameni?

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Nu a existat nicio verificare DBA. Dacă ar exista un DBA, ar vedea aceste câteva milioane de rânduri și chiar și fără experimente ar spune: „Ei nu fac asta”. Să presupunem că dacă acest cod ar fi în GitLab, GitHub și ar exista un proces de revizuire a codului și nu ar exista așa ceva încât fără aprobarea DBA această operațiune să aibă loc pe prod, atunci evident DBA ar spune: „Acest lucru nu se poate face. .”

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Și ar spune că vei avea probleme cu discul IO și toate procesele vor înnebuni, pot fi blocări și, de asemenea, vei bloca autovacuum pentru câteva minute, așa că nu este bine.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

http://bit.ly/nancy-hl2018-2

A doua greșeală - au verificat în locul greșit. Am văzut după faptul că multe date nedorite s-au acumulat pe prod, dar dezvoltatorul nu avea date acumulate în această bază de date și nimeni nu a creat acest junk în timpul staging-ului. În consecință, au fost 1 de linii care au funcționat rapid.

Înțelegem că testele noastre sunt slabe, adică procesul care este construit nu prinde probleme. Nu a fost efectuat un experiment DB adecvat.

Un experiment ideal se efectuează de preferință pe același echipament. Nu este întotdeauna posibil să faceți acest lucru pe același echipament, dar este foarte important ca aceasta să fie o copie la dimensiune completă a bazei de date. Aceasta este ceea ce predic de câțiva ani. Și acum un an am vorbit despre asta, le puteți urmări pe YouTube.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Poate că echipamentul nostru este prost? Dacă te uiți, atunci latența a sărit. Am văzut că utilizarea este de 100%. Desigur, dacă acestea ar fi unități NVMe moderne, atunci probabil că ne-ar fi mult mai ușor. Și poate că nu ne-am culca din asta.

Dacă aveți nori, atunci upgrade-ul se face cu ușurință acolo. S-au ridicat replici noi pe noul hardware. schimba. Și totul este bine. Destul de ușor.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Este posibil să atingem cumva discurile mai mici? Și aici, doar cu ajutorul DBA, ne scufundăm într-un anumit subiect numit reglarea punctelor de control. Se pare că nu am avut reglajul punctului de control.

Ce este punctul de control? Este în orice SGBD. Când aveți date în memorie care se modifică, acestea nu sunt scrise imediat pe disc. Informațiile că datele s-au schimbat sunt scrise mai întâi în jurnalul de scriere anticipată. Și la un moment dat, DBMS decide că este timpul să aruncăm paginile reale pe disc, astfel încât dacă avem un eșec, să putem face mai puțin REDO. Este ca o jucărie. Dacă suntem uciși, vom începe jocul de la ultimul punct de control. Și toate SGBD-ul îl implementează.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Setările din Postgres au rămas în urmă. Sunt concepute pentru volume de date și tranzacții vechi de 10-15 ani. Și punctul de control nu face excepție.

Iată informațiile din raportul nostru de verificare Postgres, adică verificarea automată a stării de sănătate. Și aici este o bază de date de câțiva terabytes. Și se vede bine că punctele de control forțate în aproape 90% din cazuri.

Ce înseamnă? Există două setări acolo. Punctul de control poate veni prin timeout, de exemplu, în 10 minute. Sau poate veni atunci când au fost completate destul de multe date.

Și implicit, max_wal_saze este setat la 1 gigaoctet. De fapt, acest lucru se întâmplă de fapt în Postgres după 300-400 de megaocteți. Ai schimbat atât de multe date și ai un punct de control.

Și dacă nimeni nu l-a reglat, iar serviciul a crescut, iar compania câștigă mulți bani, are o mulțime de tranzacții, atunci punctul de control vine o dată pe minut, uneori la fiecare 30 de secunde și uneori chiar se suprapun. Acest lucru este destul de rău.

Și trebuie să ne asigurăm că vine mai rar. Adică, putem crește max_wal_size. Și va veni mai rar.

Dar am dezvoltat o întreagă metodologie pentru cum să o facem mai corect, adică cum să luăm o decizie cu privire la alegerea setărilor, în mod clar bazată pe date specifice.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

În consecință, facem două serii de experimente pe baze de date.

Prima serie - schimbăm max_wal_size. Și facem o operațiune masivă. În primul rând, o facem cu setarea implicită de 1 gigaoctet. Și facem o ștergere masivă a multor milioane de linii.

Puteți vedea cât de greu ne este. Vedem că IO-ul discului este foarte rău. Ne uităm la câte WAL-uri am generat, pentru că acest lucru este foarte important. Să vedem de câte ori s-a întâmplat punctul de control. Și vedem că nu este bine.

Apoi creștem max_wal_size. Repetăm. Creștem, repetăm. Și de atâtea ori. În principiu, 10 puncte sunt bune, unde 1, 2, 4, 8 gigaocteți. Și ne uităm la comportamentul unui anumit sistem. Este clar că aici echipamentul ar trebui să fie ca pe prod. Trebuie să aveți aceleași discuri, aceeași cantitate de memorie și aceleași setări Postgres.

Și în acest fel ne vom schimba sistemul și știm cum se va comporta DBMS-ul în cazul unei ȘTERGERE greșite în masă, cum va fi punctul de control.

Punctele de control în rusă sunt puncte de control.

Exemplu: ȘTERGEȚI câteva milioane de rânduri după index, rândurile sunt „împrăștiate” pe pagini.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Iată un exemplu. Aceasta este o bază. Și cu setarea implicită de 1 gigabyte pentru max_wal_size, este foarte clar că discurile noastre merg la raft pentru înregistrare. Această imagine este un simptom tipic al unui pacient foarte bolnav, adică s-a simțit foarte rău. Și a existat o singură operație, a fost doar o ștergere de câteva milioane de linii.

Dacă o astfel de operație este permisă în prod, atunci ne vom întinde doar, pentru că este clar că un DELETE ne omoară în raft.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

În plus, unde 16 gigaocteți, este clar că dinții au trecut deja. Dintii sunt deja mai buni, adica batem in tavan, dar nu chiar asa rau. Acolo era ceva libertate. În dreapta este înregistrarea. Și numărul de operații - al doilea grafic. Și este clar că deja respirăm puțin mai ușor când avem 16 gigaocteți.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Și unde 64 de gigaocteți se poate vedea că a devenit complet mai bun. Deja dinții sunt pronunțați, există mai multe oportunități de a supraviețui altor operații și de a face ceva cu discul.

De ce așa?

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Mă voi scufunda puțin în detalii, dar acest subiect, cum se efectuează reglarea punctului de control, poate duce la un raport întreg, așa că nu voi încărca prea mult, dar voi sublinia puțin ce dificultăți există.

Dacă punctul de control se întâmplă prea des și ne actualizăm liniile nu secvențial, dar găsim după index, ceea ce este bine, pentru că nu ștergem întregul tabel, atunci se poate întâmpla ca la început să atingem prima pagină, apoi a miilea, iar apoi a revenit la primul . Și dacă între aceste vizite la prima pagină, punctul de control a salvat-o deja pe disc, atunci o va salva din nou, pentru că l-am murdarit a doua oară.

Și vom forța punctul de control să-l salveze de multe ori. Cum ar fi operațiuni redundante pentru el.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Dar asta nu este tot. Paginile au 8 kilobytes în Postgres și 4 kilobytes în Linux. Și există o setare full_page_writes. Este activat implicit. Și acest lucru este corect, pentru că dacă îl oprim, atunci există pericolul ca doar jumătate din pagină să fie salvată dacă se blochează.

Comportamentul scrierii în WAL al jurnalului de transmitere este de așa natură încât, atunci când avem un punct de control și schimbăm pagina pentru prima dată, întreaga pagină, adică toți cei 8 kiloocteți, intră în jurnalul de avans, deși am schimbat doar linie, care cântărește 100 de octeți. Și trebuie să scriem întreaga pagină.

În modificările ulterioare va exista doar un anumit tuplu, dar pentru prima dată notăm totul.

Și, în consecință, dacă punctul de control s-a întâmplat din nou, atunci trebuie să începem totul de la zero din nou și să împingem întreaga pagină. Cu puncte de control frecvente, când parcurgem aceleași pagini, full_page_writes = on va fi mai mult decât ar putea fi, adică generăm mai mult WAL. Mai mult este trimis la replici, la arhivă, pe disc.

Și, în consecință, avem două concedieri.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Dacă creștem max_wal_size, se dovedește că o facem mai ușoară atât pentru punctul de control, cât și pentru wal writer. Și asta e grozav.

Să punem un terabyte și să trăim cu el. Ce e rău în asta? Acest lucru este rău, pentru că în caz de eșec, vom urca ore în șir, pentru că punctul de control era demult și deja s-au schimbat multe. Și trebuie să facem toate acestea REDO. Și așa facem a doua serie de experimente.

Facem o operațiune și vedem când punctul de control este pe cale să se finalizeze, ucidem -9 Postgres intenționat.

Și după aceea îl pornim din nou, și vedem cât timp se va ridica pe acest echipament, adică cât de mult se va REFACE în această situație proastă.

Voi observa de două ori că situația este proastă. În primul rând, ne-am prăbușit chiar înainte ca punctul de control să se încheie, așa că avem multe de pierdut. Și în al doilea rând, am avut o operație masivă. Și dacă punctele de control ar fi expirat, atunci, cel mai probabil, ar fi generat mai puțin WAL de la ultimul punct de control. Adică este un învins dublu.

Măsurăm o astfel de situație pentru diferite dimensiuni max_wal_size și înțelegem că dacă max_wal_size este de 64 de gigaocteți, atunci în cel mai rău caz dublu vom urca timp de 10 minute. Și ne gândim dacă ne convine sau nu. Aceasta este o întrebare de afaceri. Trebuie să arătăm această imagine celor responsabili cu deciziile de afaceri și să întrebăm: „Cât timp ne putem întinde cel mult în cazul unei probleme? Ne putem întinde 3-5 minute în cea mai proastă situație? Și iei o decizie.

Și aici este un punct interesant. Avem câteva rapoarte despre Patroni la conferință. Și poate îl folosești. Acesta este un autofailover pentru Postgres. GitLab și Data Egret au vorbit despre asta.

Și dacă aveți un autofailover care vine în 30 de secunde, atunci poate ne putem întinde 10 minute? Pentru că până în acest moment vom trece la replică și totul va fi bine. Acesta este un punct discutabil. Nu stiu un raspuns clar. Simt doar că acest subiect nu se referă doar la recuperarea în caz de accident.

Dacă avem o recuperare lungă după un eșec, atunci ne vom simți incomozi în multe alte situații. De exemplu, în aceleași experimente, când facem ceva și uneori trebuie să așteptăm 10 minute.

Tot nu aș merge prea departe, chiar dacă avem un autofailover. De regulă, valori precum 64, 100 de gigaocteți sunt valori bune. Uneori chiar merită să alegi mai puțin. În general, aceasta este o știință subtilă.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Pentru a face iterații, de exemplu, max_wal_size =1, 8, trebuie să repetați operația de masă de mai multe ori. Ai făcut. Și pe aceeași bază vrei să o faci din nou, dar deja ai șters totul. Ce să fac?

Voi vorbi mai târziu despre soluția noastră, ce facem pentru a repeta în astfel de situații. Și aceasta este cea mai corectă abordare.

Dar în acest caz, am fost norocoși. Dacă, așa cum scrie aici „BEGIN, DELETE, ROLLBACK”, atunci putem repeta DELETE. Adică, dacă l-am anulat singuri, atunci îl putem repeta. Și din punct de vedere fizic, datele vor fi în același loc. Nici măcar nu te umflă. Puteți repeta peste astfel de ștergeri.

Acest DELETE cu ROLLBACK este ideal pentru reglarea punctelor de control, chiar dacă nu aveți o bază de date implementată corespunzător.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Am făcut o farfurie cu o coloană „i”. Postgres are coloane utilitare. Sunt invizibile dacă nu sunt cerute în mod expres. Acestea sunt: ​​ctid, xmid, xmax.

Ctid este o adresă fizică. Pagina zero, primul tuplu din pagină.

Se vede ca dupa ROOLBACK tuplu a ramas in acelasi loc. Adică putem încerca din nou, se va comporta la fel. Acesta este principalul lucru.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Xmax este momentul morții tuplului. A fost ștampilat, dar Postgres știe că tranzacția a fost anulată, deci nu contează dacă este 0 sau este o tranzacție anulată. Acest lucru sugerează că este posibil să iterați peste DELETE și să verificați operațiunile în bloc ale comportamentului sistemului. Puteți face laboratoare de baze de date pentru cei săraci.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Este vorba despre programatori. Și despre DBA, ei îi mustră mereu pe programatori pentru asta: „De ce faci operațiuni atât de lungi și dificile?”. Acesta este un subiect perpendicular complet diferit. A fost administrație, iar acum va fi dezvoltare.

Evident, nu ne-am rupt în bucăți. Este clar. Este imposibil să nu spargeți astfel de DELETE pentru o grămadă de milioane de linii în părți. Se va face timp de 20 de minute și totul se va întinde. Dar, din păcate, chiar și dezvoltatorii experimentați fac greșeli, chiar și în companii foarte mari.

De ce este important să spargi?

  • Dacă vedem că discul este dur, atunci hai să-l încetinim. Și dacă suntem rupti, atunci putem adăuga pauze, putem încetini accelerarea.

  • Și nu îi vom bloca pe alții mult timp. În unele cazuri, nu contează, dacă ștergeți gunoiul real la care nimeni nu lucrează, atunci cel mai probabil nu veți bloca pe nimeni, în afară de munca de autovacuum, pentru că va aștepta finalizarea tranzacției. Dar dacă eliminați ceva ce poate solicita altcineva, atunci va fi blocat, va exista un fel de reacție în lanț. Tranzacțiile lungi trebuie evitate pe site-uri web și aplicații mobile.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

https://postgres.ai/products/joe/

Acest lucru este interesant. Văd adesea că dezvoltatorii întreabă: „Ce dimensiune de pachet ar trebui să aleg?”.

Este clar că, cu cât dimensiunea pachetului este mai mare, cu atât costul general al tranzacției este mai mic, adică costul general suplimentar din tranzacții. Dar, în același timp, timpul crește pentru această tranzacție.

Am o regulă foarte simplă: luați cât de mult puteți, dar nu treceți peste executabile pe secundă.

De ce o secundă? Explicația este foarte simplă și de înțeles pentru toată lumea, chiar și pentru persoanele netehnice. Vedem o reacție. Să luăm 50 de milisecunde. Dacă ceva s-a schimbat, atunci ochiul nostru va reacționa. Dacă mai puțin, atunci mai dificil. Dacă ceva răspunde după 100 de milisecunde, de exemplu, ai făcut clic pe mouse și ți-a răspuns după 100 de milisecunde, simți deja această ușoară întârziere. O secundă este deja percepută ca frâne.

În consecință, dacă ne împărțim operațiunile în masă în rafale de 10 secunde, atunci avem riscul să blocăm pe cineva. Și va funcționa pentru câteva secunde, iar oamenii o vor observa deja. Prin urmare, prefer să nu fac mai mult de o secundă. Dar, în același timp, nu o despărțiți foarte fin, deoarece cheltuielile generale ale tranzacției vor fi vizibile. Baza va fi mai dură și pot apărea alte probleme diferite.

Alegem dimensiunea pachetului. În fiecare caz, o putem face diferit. Poate fi automatizat. Și suntem convinși de eficiența procesării unui pachet. Adică ștergem un pachet sau ACTUALIZAM.

Apropo, tot ce vorbesc nu este doar despre DELETE. După cum ați ghicit, acestea sunt operațiuni în bloc asupra datelor.

Și vedem că planul este excelent. Puteți vedea scanarea indexului, scanarea numai cu index este și mai bună. Și avem o cantitate mică de date implicate. Și mai puțin de o secundă se împlinește. Super.

Și încă trebuie să ne asigurăm că nu există degradare. Se întâmplă ca primele pachete să funcționeze repede, iar apoi se înrăutățește din ce în ce mai rău. Procesul este de așa natură încât trebuie să testați multe. Exact pentru asta sunt laboratoarele de baze de date.

Și mai trebuie să pregătim ceva astfel încât să ne permită să urmărim corect acest lucru în producție. De exemplu, putem scrie ora în jurnal, putem scrie unde suntem acum și pe cine am șters acum. Și asta ne va permite să înțelegem ce se întâmplă mai târziu. Și în cazul în care ceva nu merge bine, găsiți rapid problema.

Dacă trebuie să verificăm eficiența solicitărilor și trebuie să repetăm ​​de mai multe ori, atunci există un fel de bot. El este deja gata. Este folosit zilnic de zeci de dezvoltatori. Și știe cum să ofere o bază de date uriașă terabyte la cerere în 30 de secunde, propria ta copie. Și puteți șterge ceva acolo și spuneți RESET și ștergeți-l din nou. Puteți experimenta cu el în acest fel. Văd un viitor pentru chestia asta. Și deja o facem.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

https://docs.gitlab.com/ee/development/background_migrations.html

Care sunt strategiile de partiţionare? Văd 3 strategii de partiționare diferite pe care le folosesc dezvoltatorii de pe pachet.

Primul este foarte simplu. Avem un ID numeric. Și să o împărțim în diferite intervale și să lucrăm cu asta. Dezavantajul este clar. În primul segment, s-ar putea să avem 100 de linii de gunoi real, în al doilea 5 rânduri sau deloc, sau toate cele 1 de linii se vor dovedi a fi gunoi. Lucrare foarte neuniformă, dar se rupe ușor. Au luat ID-ul maxim și l-au spart. Aceasta este o abordare naivă.

A doua strategie este o abordare echilibrată. Este folosit în Gitlab. Au luat și au scanat masa. Am găsit limitele pachetelor de identificare, astfel încât fiecare pachet să aibă exact 10 de înregistrări. Și pune-le la coadă. Și apoi procesăm. Puteți face acest lucru în mai multe fire.

Și în prima strategie, apropo, poți face asta în mai multe fire. Nu e greu.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

https://medium.com/@samokhvalov/how-partial-indexes-affect-update-performance-in-postgres-d05e0052abc

Dar există o abordare mai rece și mai bună. Aceasta este a treia strategie. Și atunci când este posibil, este mai bine să o alegeți. Facem acest lucru pe baza unui index special. În acest caz, cel mai probabil va fi un index în funcție de starea noastră de gunoi și ID. Vom include ID-ul, astfel încât să fie doar o scanare index, astfel încât să nu mergem la heap.

În general, scanarea numai index este mai rapidă decât scanarea indexului.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Și găsim rapid ID-urile noastre pe care vrem să le ștergem. BATCH_SIZE selectăm în avans. Și nu doar le obținem, ci le obținem într-un mod special și le piratam imediat. Dar blocăm astfel încât dacă sunt deja blocate, nu le blocăm, ci mergem mai departe și le luăm pe următoarele. Aceasta este pentru actualizare sărită blocată. Această super caracteristică a Postgres ne permite să lucrăm în mai multe fire dacă vrem. Este posibil într-un singur flux. Și aici există un CTE - aceasta este o cerere. Și avem o ștergere reală în curs de la etajul doi al acestui CTE - returning *. Puteți returna id-ul, dar este mai bine *dacă nu aveți multe date pe fiecare linie.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

De ce avem nevoie de ea? Acesta este ceea ce trebuie să raportăm. De fapt, acum am șters atât de multe rânduri. Și avem margini după ID sau prin created_at ca acesta. Puteți face min, max. Se mai poate face ceva. Poți să faci multe lucruri aici. Și este foarte convenabil pentru monitorizare.

Mai este o notă despre index. Dacă decidem că avem nevoie de un index special pentru această sarcină, atunci trebuie să ne asigurăm că nu strica actualizările heap only tuples. Adică Postgres are astfel de statistici. Acest lucru poate fi văzut în pg_stat_user_tables pentru tabelul dvs. Puteți vedea dacă sunt utilizate actualizări fierbinți sau nu.

Există situații în care noul tău index le poate tăia pur și simplu. Și aveți toate celelalte actualizări care funcționează deja, încetinește. Nu doar pentru că a apărut indexul (fiecare index încetinește puțin actualizările, dar puțin), dar aici tot îl strică. Și este imposibil să faci o optimizare specială pentru acest tabel. Asta se întâmplă uneori. Aceasta este o subtilitate pe care puțini oameni își amintesc. Și această greblă este ușor de călcat. Uneori se întâmplă că trebuie să găsiți o abordare din cealaltă parte și să vă faceți în continuare fără acest nou index sau să faceți un alt index sau, într-un alt mod, de exemplu, puteți utiliza a doua metodă.

Dar aceasta este cea mai optimă strategie, cum să împărțiți în loturi și să trageți la loturi cu o singură solicitare, să ștergeți puțin etc.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Tranzacții lungi https://gitlab.com/snippets/1890447

Autovacuum blocat - https://gitlab.com/snippets/1889668

problema de blocare - https://gitlab.com/snippets/1890428

Greșeala #5 este una mare. Nikolai de la Okmeter a vorbit despre monitorizarea Postgres. Monitorizarea ideală Postgres, din păcate, nu există. Unele sunt mai aproape, altele sunt mai departe. Okmeter este suficient de aproape de a fi perfect, dar lipsesc multe și trebuie adăugate. Trebuie să fii pregătit pentru asta.

De exemplu, tuplurile moarte sunt cel mai bine monitorizate. Dacă aveți o mulțime de lucruri moarte în tabel, atunci ceva nu este în regulă. Este mai bine să reacționăm acum, altfel poate fi degradare și ne putem întinde. S-a întâmplat.

Dacă există un IO mare, atunci este clar că acest lucru nu este bine.

Tranzacții lungi, de asemenea. Tranzacțiile lungi nu ar trebui să fie permise pe OLTP. Și aici este un link către un fragment care vă permite să luați acest fragment și să faceți deja o anumită urmărire a tranzacțiilor lungi.

De ce sunt proaste tranzacțiile lungi? Pentru că toate încuietorile vor fi eliberate abia la sfârșit. Și îi dă jos pe toată lumea. În plus, blocăm autovacuum pentru toate mesele. Nu e bine deloc. Chiar dacă ai activat modul de așteptare la cald pe replică, tot e rău. În general, nicăieri nu este mai bine să eviți tranzacțiile lungi.

Dacă avem multe mese care nu sunt aspirate, atunci trebuie să avem o alertă. Aici este posibilă o astfel de situație. Putem afecta indirect funcționarea autovacuumului. Acesta este un fragment de la Avito, pe care l-am îmbunătățit ușor. Și s-a dovedit a fi un instrument interesant pentru a vedea ce avem cu autovacuum. De exemplu, unele mese așteaptă acolo și nu își vor aștepta rândul. De asemenea, trebuie să îl puneți în monitorizare și să aveți o alertă.

Și emite blocuri. Pădurea de copaci blocuri. Îmi place să iau ceva de la cineva și să-l îmbunătățesc. Aici am luat un CTE recursiv cool de la Data Egret care arată o pădure de copaci de ecluză. Acesta este un instrument bun de diagnosticare. Și pe baza ei, puteți construi și monitorizare. Dar acest lucru trebuie făcut cu atenție. Trebuie să faci un mic statement_timeout pentru tine. Și lock_timeout este de dorit.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Uneori, toate aceste erori apar în sumă.

În opinia mea, principala greșeală aici este organizatorică. Este organizatorică, pentru că tehnica nu trage. Acesta este numărul 2 - au verificat în locul greșit.

Am verificat în locul greșit, pentru că nu aveam o clonă de producție, ceea ce este ușor de verificat. Este posibil ca un dezvoltator să nu aibă deloc acces la producție.

Și nu am verificat acolo. Dacă am fi verificat acolo, am fi văzut-o singuri. Dezvoltatorul a văzut totul chiar și fără DBA dacă a verificat-o într-un mediu bun, unde există aceeași cantitate de date și o locație identică. Ar fi văzut toată această degradare și i-ar fi rușine.

Mai multe despre autovacuum. După ce am făcut o matură masivă de câteva milioane de linii, mai trebuie să facem REPACK. Acest lucru este deosebit de important pentru indici. Se vor simți prost după ce vom curăța totul acolo.

Iar dacă vrei să readuci munca zilnică de curățenie, atunci aș sugera să o faci mai des, dar mai mic. Poate fi o dată pe minut sau chiar mai des puțin. Și trebuie să monitorizați două lucruri: că acest lucru nu are erori și că nu rămâne în urmă. Trucul pe care l-am arătat va rezolva doar asta.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Ceea ce facem este open source. Este postat pe GitLab. Și facem astfel încât oamenii să poată verifica chiar și fără un DBA. Facem un laborator de baze de date, adică numim componenta de bază la care lucrează Joe în prezent. Și puteți lua o copie a producției. Acum există o implementare a lui Joe for slack, puteți spune acolo: „explicați o astfel de solicitare” și obțineți imediat rezultatul pentru copia dumneavoastră a bazei de date. Puteți chiar ȘTERGE acolo și nimeni nu va observa acest lucru.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Să presupunem că aveți 10 teraocteți, noi facem laboratorul de baze de date și 10 teraocteți. Și cu baze de date simultane de 10 teraocteți, 10 dezvoltatori pot lucra simultan. Fiecare poate face ce vrea. Poate șterge, arunca, etc. Asta e o fantezie. Despre asta vom vorbi mâine.

Dragă DELETE. Nikolay Samokhvalov (Postgres.ai)

Aceasta se numește thin provisioning. Aceasta este aprovizionare subtilă. Acesta este un fel de fantezie care înlătură foarte mult întârzierile în dezvoltare, în testare și face lumea un loc mai bun în acest sens. Adică, vă permite doar să evitați problemele cu operațiunile în vrac.

Exemplu: bază de date de 5 terabyți, obținerea unei copii în mai puțin de 30 de secunde. Și nici măcar nu depinde de dimensiune, adică nu contează câți terabytes.

Astăzi poți merge la postgres.ai și săpa în instrumentele noastre. Vă puteți înregistra pentru a vedea ce este acolo. Puteți instala acest bot. Este gratis. Scrie.

întrebări

Foarte des, în situații reale, se dovedește că datele care ar trebui să rămână în tabel sunt mult mai puține decât cele care trebuie șterse. Adică, într-o astfel de situație, este adesea mai ușor să implementați o astfel de abordare, atunci când este mai ușor să creați un nou obiect, să copiați acolo doar datele necesare și să trunchiați tabelul vechi. Este clar că este nevoie de o abordare programatică pentru acest moment, în timp ce vei trece. Cum este această abordare?

Aceasta este o abordare foarte bună și o sarcină foarte bună. Este foarte asemănător cu ceea ce face pg_repack, este foarte asemănător cu ceea ce trebuie să faci când faci ID-uri de 4 octeți. Multe cadre au făcut asta acum câțiva ani și doar plăcile au crescut și trebuie convertite la 8 octeți.

Această sarcină este destul de dificilă. Am reusit. Și trebuie să fii foarte atent. Există încuietori etc. Dar se face. Adică, abordarea standard este să mergi cu pg_repack. Declari o astfel de etichetă. Și înainte de a începe să încărcați date instantanee în el, declarați și o placă care urmărește toate modificările. Există un truc prin care este posibil să nu urmăriți nici măcar unele modificări. Există subtilități. Și apoi comutați prin schimburi. Va fi o scurtă pauză când vom opri toată lumea, dar în general acest lucru se face.

Dacă te uiți la pg_repack pe GitHub, atunci când a existat o sarcină de a converti un ID de la int 4 la int 8, atunci a fost o idee să folosești pg_repack în sine. Este posibil și acest lucru, dar este puțin hack, dar va funcționa și pentru asta. Puteți interveni în declanșatorul pe care pg_repack îl folosește și spune acolo: „Nu avem nevoie de aceste date”, adică transferăm doar ceea ce avem nevoie. Și apoi pur și simplu schimbă și atât.

Cu această abordare, obținem în continuare o a doua copie a tabelului, în care datele sunt deja indexate și stivuite foarte uniform cu indici frumoși.

Balonarea nu este prezentă, este o abordare bună. Dar știu că există încercări de a dezvolta o automatizare pentru asta, adică de a face o soluție universală. Vă pot pune în legătură cu această automatizare. Este scris în Python, ceea ce este un lucru bun.

Sunt doar puțin din lumea MySQL, așa că am venit să ascult. Și folosim această abordare.

Dar este doar dacă avem 90%. Dacă avem 5%, atunci nu este foarte bine să-l folosim.

Multumesc pentru raport! Dacă nu există resurse pentru a face o copie completă a produsului, există vreun algoritm sau formulă pentru a calcula încărcarea sau dimensiunea?

Buna intrebare. Până acum, suntem capabili să găsim baze de date de mai mulți terabyte. Chiar dacă hardware-ul de acolo nu este același, de exemplu, mai puțină memorie, mai puțin procesor și discuri nu sunt exact la fel, dar totuși o facem. Dacă nu există absolut nicăieri, atunci trebuie să te gândești. Lasă-mă să mă gândesc până mâine, ai venit, vorbim, aceasta este o întrebare bună.

Multumesc pentru raport! Ai început mai întâi despre faptul că există un Postgres grozav, care are astfel de limitări, dar se dezvoltă. Și totul este o cârjă în general. Nu este totul în conflict cu dezvoltarea Postgres în sine, în care va apărea un deferent DELETE sau altceva care ar trebui să mențină la un nivel scăzut ceea ce încercăm să ungem cu unele dintre mijloacele noastre ciudate de aici?

Dacă am spus în SQL să ștergem sau să actualizăm multe înregistrări într-o singură tranzacție, atunci cum le poate distribui Postgres acolo? Suntem limitați fizic în operațiuni. O vom face încă mult timp. Și vom închide în acest moment etc.

Gata cu indici.

Pot presupune că aceeași reglare a punctului de control ar putea fi automatizat. Într-o zi ar putea fi. Dar atunci nu prea înțeleg întrebarea.

Întrebarea este, există un astfel de vector de dezvoltare care merge ici și colo, iar aici al tău merge paralel? Acestea. Nu s-au gândit încă la asta?

Am vorbit despre principiile care pot fi folosite acum. Există un alt bot Nancy, cu aceasta puteți face reglarea automată a punctelor de control. Va fi cândva în Postgres? Nu știu, nici măcar nu s-a discutat încă. Suntem încă departe de asta. Dar există oameni de știință care creează sisteme noi. Și ne împing în indexuri automate. Există evoluții. De exemplu, vă puteți uita la reglarea automată. Selectează automat parametrii. Dar încă nu va face reglajul punctului de control pentru tine. Adică, va crește pentru performanță, tampon de shell etc.

Și pentru reglarea punctelor de control, puteți face acest lucru: dacă aveți o mie de clustere și hardware diferit, diferite mașini virtuale în cloud, puteți utiliza botul nostru Nancy face automatizare. Și max_wal_size va fi selectat automat în funcție de setările dvs. țintă. Dar până acum acest lucru nu este nici măcar aproape în miez, din păcate.

Bună ziua Ai vorbit despre pericolele tranzacțiilor lungi. Ai spus că autovacuum este blocat în caz de ștergere. Cum altfel ne face rău? Pentru că vorbim mai mult despre eliberarea spațiului și posibilitatea de a-l folosi. Ce altceva ne lipsește?

Aspiratorul automat nu este poate cea mai mare problemă aici. Și faptul că o tranzacție lungă poate bloca alte tranzacții, această posibilitate este mai periculoasă. Se poate întâlni sau nu. Dacă s-a întâlnit, atunci poate fi foarte rău. Și cu autovacuum - și aceasta este o problemă. Există două probleme cu tranzacțiile lungi în OLTP: încuietori și autovacuum. Și dacă aveți feedback-ul de așteptare la cald activat pe replică, atunci veți primi în continuare o blocare cu vid automat pe master, acesta va sosi de la replică. Dar cel puțin nu vor exista încuietori. Și va fi lok. Vorbim despre modificările datelor, așa că încuietorile sunt un punct important aici. Și dacă toate acestea sunt pentru mult, mult timp, atunci tot mai multe tranzacții sunt blocate. Îi pot fura pe alții. Și apar arbori lok. Am oferit un link către fragment. Și această problemă devine mai vizibilă mai repede decât problema cu autovacuum-ul, care se poate acumula doar.

Multumesc pentru raport! Ai început raportul spunând că ai testat incorect. Ne-am continuat ideea că trebuie să luăm același echipament, cu baza în același mod. Să presupunem că i-am oferit dezvoltatorului o bază. Și a dat curs cererii. Și pare să fie bine. Dar nu verifică pentru live, ci pentru live, de exemplu, avem o încărcătură de 60-70%. Și chiar dacă folosim acest tuning, nu funcționează foarte bine.

Este important să ai un expert în echipă și să folosești experți DBA care pot prezice ce se va întâmpla cu o încărcare reală de fundal. Când tocmai am condus schimbările noastre curate, vedem imaginea. Dar o abordare mai avansată, când am făcut din nou același lucru, dar cu o sarcină simulată cu producția. E destul de misto. Până atunci, trebuie să crești. E ca un adult. Ne-am uitat doar la ceea ce avem și, de asemenea, ne-am uitat dacă avem suficiente resurse. Asta e o intrebare buna.

Când facem deja un garbage select și avem, de exemplu, un steag șters

Aceasta este ceea ce face automat autovacuum în Postgres.

Oh, o face?

Autovacuum este colectorul de gunoi.

Vă mulțumim!

Multumesc pentru raport! Există o opțiune de a proiecta imediat o bază de date cu partiționare în așa fel încât tot gunoiul să se murdărească de pe tabelul principal undeva în lateral?

Desigur că au.

Este posibil atunci să ne protejăm dacă am încuiat o masă care nu ar trebui folosită?

Desigur că au. Dar este ca o întrebare despre pui și ouă. Dacă știm cu toții ce se va întâmpla în viitor, atunci, desigur, vom face totul mișto. Dar afacerea se schimbă, apar rubrici noi, solicitări noi. Și apoi – hopa, vrem să-l eliminăm. Dar această situație ideală, în viață apare, dar nu întotdeauna. Dar, per total, este o idee bună. Doar trunchiază și atât.

Sursa: www.habr.com

Adauga un comentariu