Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Proposo llegir la transcripció de l'informe de principis de 2016 d'Andrey Salnikov "Errors típics en aplicacions que provoquen una inflació en postgresql"

En aquest informe, analitzaré els principals errors de les aplicacions que es produeixen en l'etapa de disseny i escriptura del codi de l'aplicació. I només prendré aquells errors que provoquen una inflació a Postgresql. Per regla general, aquest és el començament del final del rendiment del vostre sistema en conjunt, encara que inicialment no es va veure cap requisit previ per a això.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Un plaer rebre a tothom! Aquest informe no és tan tècnic com l'anterior del meu company. Aquesta xerrada està adreçada als desenvolupadors de sistemes back-end principalment perquè tenim un nombre força elevat de clients. I tots cometen els mateixos errors. Us parlaré d'ells. Explicaré a què són fatals i dolents aquests errors.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Per què es cometen errors? Es realitzen per dos motius: a l'atzar, potser funcionarà per desconeixement d'alguns mecanismes que es produeixen a nivell entre la base i l'aplicació, així com a la pròpia base.

Et donaré tres exemples amb imatges terribles de com les coses van anar malament. Descriuré breument el mecanisme que s'hi produeix. I com tractar-los, quan van passar i quins mètodes preventius utilitzar per evitar errors. Us parlaré de les eines auxiliars i us donaré enllaços útils.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Vaig utilitzar una base de dades de prova on tenia dues taules. Una placa amb comptes de clients, l'altra amb operacions en aquests comptes. I amb certa periodicitat, actualitzem els saldos d'aquests comptes.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Les dades inicials de la placa: és força petita, 2 MB. El temps de resposta de la base de dades i concretament de la placa també és molt bo. I una càrrega força bona: 2 operacions per segon a la placa.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

I a través d'aquest informe us mostraré gràfics perquè quedi clar què passa. Sempre hi haurà 2 diapositives amb gràfics. La primera diapositiva és el que passa en general al servidor.

I en aquesta situació, veiem que realment tenim un plat petit. L'índex és petit amb 2 MB. Aquest és el primer gràfic de l'esquerra.

El temps de resposta mitjà al servidor també és estable, petit. Aquest és el gràfic superior dret.

El gràfic inferior esquerre és les transaccions més llargues. Podem veure que les transaccions s'estan completant ràpidament. I l'aspirador automàtic encara no funciona aquí, perquè era una prova d'inici. Aleshores funcionarà i ens serà útil.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

La segona diapositiva estarà sempre dedicada a la placa de prova. En aquesta situació, actualitzem constantment els saldos del compte del client. I veiem que el temps mitjà de resposta per a l'operació d'actualització és força bo, menys d'un mil·lisegon. Veiem que els recursos del processador (aquest és el gràfic superior dret) també es consumeixen de manera uniforme i bastant petita.

El gràfic inferior dret mostra quanta memòria operativa i de disc passem a la recerca de la línia desitjada abans d'actualitzar-la. I el nombre d'operacions a la placa és de 2 per segon, com he dit al principi.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

I ara tenim una tragèdia. Per alguna raó, es produeix una transacció oblidada des de fa temps. Els motius solen ser tots banals:

  • Un dels més habituals és que vam començar a accedir a un servei extern en el codi de l'aplicació. I aquest servei no ens respon. És a dir, vam obrir una transacció, vam fer un canvi a la base de dades i vam passar de l'aplicació a llegir el correu o a un altre servei dins de la nostra infraestructura, i per alguna raó no ens respon. I la nostra sessió es va penjar en un estat: no se sap quan es resoldrà.
  • La segona situació és quan es va produir una excepció al nostre codi per algun motiu. I no vam processar el tancament de la transacció a l'excepció. I vam tenir una sessió pendent amb una transacció oberta.
  • I l'últim també és força habitual. Aquest és un codi de mala qualitat. Alguns marcs obren una transacció. Es penja i és possible que no sàpigues a l'aplicació que el tens penjat.

On porten aquestes coses?

Al fet que les nostres taules i índexs comencen a augmentar dràsticament. Aquest és exactament el mateix efecte d'inflor. Per a la base de dades, això s'expressarà en el fet que tindrem un augment molt fort del temps de resposta de la base de dades, augmentarà la càrrega al servidor de la base de dades. I com a resultat, la nostra aplicació patirà. Perquè si al vostre codi vau gastar 10 mil·lisegons en una sol·licitud a la base de dades, 10 mil·lisegons a la vostra lògica, la vostra funció va funcionar 20 mil·lisegons. I ara la teva situació serà molt trista.

I a veure què passa. El gràfic inferior esquerre mostra que tenim una transacció llarga i llarga. I si mirem el gràfic superior esquerre, veiem que la mida de la taula va saltar de dos megabytes a 300 megabytes. Al mateix temps, la quantitat de dades de la taula no ha canviat, és a dir, hi ha una quantitat força gran d'escombraries.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

La situació general pel que fa al temps mitjà de resposta del servidor també ha canviat en diversos ordres de magnitud. És a dir, totes les sol·licituds del servidor van començar a caure completament. I paral·lelament es van posar en marxa els processos interns de Postgres davant l'autobuit, que intenten fer alguna cosa i consumir recursos.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Què passa amb el nostre plat? El mateix. El temps de resposta mitjà a la tauleta va augmentar diversos ordres de magnitud. Si concretament en termes de recursos consumits, llavors veiem que la càrrega del processador ha augmentat molt. Aquest és el gràfic superior dret. I ha augmentat perquè el processador ha de passar per un munt de línies inútils a la recerca de la que necessites. Aquest és el gràfic inferior dret. I com a resultat, el nombre de trucades per segon va començar a baixar molt, perquè la base de dades no té temps per processar el mateix nombre de peticions.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Hem de tornar a la vida. Ens enfilem a Internet i descobrim que les transaccions llargues comporten un problema. Trobem i matem aquesta transacció. I tot ens va bé. Tot funciona com cal.

Ens vam calmar, però al cap d'una estona comencem a notar que l'aplicació no funciona com abans de l'emergència. Les sol·licituds es processen igualment més lentament, i molt més lentament. Una i mitja o dues vegades més lent, concretament en el meu exemple. La càrrega al servidor també és superior a la que era abans de l'accident.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

I la pregunta: "Què passa amb la base en aquest moment?". I amb base hi ha una situació següent. Al gràfic de transaccions, podeu veure que s'ha aturat i realment no hi ha transaccions a llarg termini. Però les dimensions de la placa durant l'accident van créixer fatalment. I no ha disminuït des de llavors. El temps mitjà a la base s'ha estabilitzat. I les respostes semblen anar adequadament amb una velocitat acceptable per a nosaltres. Autovacuum es va fer més actiu i va començar a fer alguna cosa amb la tauleta, perquè necessita treure més dades.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Concretament, al marcador de la prova, on canviem els saldos: el temps de resposta a la sol·licitud sembla haver tornat a la normalitat. Però de fet és una vegada i mitja més gran.

I per la càrrega del processador, veiem que la càrrega del processador no tornava al valor desitjat abans de l'accident. I les raons es troben només al gràfic inferior dret. Es pot veure que hi ha una recerca d'una certa quantitat de memòria. És a dir, per buscar la línia desitjada, gastem els recursos del servidor de bases de dades a l'hora d'ordenar dades inútils. El nombre de transaccions per segon s'ha estabilitzat.

En general, bé, però la situació és pitjor del que era. Degradació explícita de la base de dades com a conseqüència de la nostra aplicació que treballa amb aquesta base de dades.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

I per entendre què hi passa, si no estàveu a l'informe anterior, ara una mica de teoria. Teoria sobre el procés intern. Per què autoaspirar i què fa?

Literalment en poques paraules per a la comprensió. En algun moment tenim una taula. Tenim files a la taula. Aquestes línies poden ser actives, en directe, necessitem ara. Estan marcats en verd a la imatge. I hi ha línies límit que ja s'han resolt, s'han actualitzat, hi han aparegut noves entrades. I es marquen que ja no són interessants per a la base de dades. Però es troben a la taula per les peculiaritats de Postgres.

Per què necessiteu un autoaspirador? Autovacuum arriba en algun moment, truca a la base de dades i li pregunta: "Si us plau, doneu-me l'identificador de la transacció més antiga que està oberta actualment a la base de dades". La base de dades retorna aquest identificador. I l'autoaspirador, confiant-hi, passa per les línies de la taula. I si veu que algunes línies han estat modificades per transaccions molt més antigues, llavors té dret a marcar-les com a línies que podrem reutilitzar en el futur escrivint-hi dades noves. Aquest és un procés de fons.

En aquest moment, continuem treballant amb la base de dades, seguim fent alguns canvis a la taula. I en aquestes línies, que podem reutilitzar, escrivim dades noves. I d'aquesta manera aconseguim un cicle, és a dir, hi apareixen algunes línies velles mortes tot el temps, en comptes d'elles anotem línies noves que necessitem. I aquest és l'estat normal perquè PostgreSQL funcioni.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Què va passar durant l'accident? Com va tenir lloc aquest procés?

Teníem un plat en algunes condicions, alguns vius, alguns morts. Ha arribat l'autovacuum. Va preguntar a la base de dades quina és la nostra transacció més antiga, quin és el seu identificador. Tinc aquesta identificació, que pot tenir moltes hores, potser deu minuts. Depèn de la càrrega que tinguis a la base de dades. I va anar a buscar línies que pugui marcar com a reutilitzades. I no vaig trobar aquestes línies a la nostra taula.

Però en aquest moment seguim treballant amb la taula. Hi fem alguna cosa, l'actualitzem, canviem les dades. Què hauria de fer la base de dades en aquest moment? No li queda més remei que afegir noves línies al final de la taula existent. I així a nosaltres la mida de la taula comença a inflar-se.

Realment necessitem línies verdes per funcionar. Però durant aquest problema, resulta que el percentatge de línies verdes és extremadament baix en tot el volum de la taula.

I quan executem una consulta, la base de dades ha de passar per totes les línies, tant vermelles com verdes, per trobar la línia correcta. I l'efecte d'inflar la taula amb dades inútils s'anomena "inflor", que també ens consumeix espai al disc. Recordeu que eren 2 MB, ara són 300 MB? Ara canvieu els megabytes a gigabytes i perdreu tots els recursos del vostre disc força ràpidament.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Quines són les implicacions per a nosaltres?

  • En el meu exemple, la taula i l'índex han crescut 150 vegades. Alguns dels nostres clients han tingut més casos fatals quan l'espai en disc es va començar a esgotar.
  • Les taules mai s'encongiran per si soles. L'autoaspiració en alguns casos pot tallar la cua de la taula si només hi ha línies mortes. Però com que hi ha una rotació constant, una línia verda pot penjar al final i no s'actualitzarà, i tota la resta es registrarà en algun lloc del començament de la placa. Però aquest és un esdeveniment tan improbable que la vostra taula disminuirà de mida, per la qual cosa no hauríeu d'esperar-hi.
  • La base de dades ha d'ordenar tota la pila de línies inútils. I estem malgastant recursos de disc, malbaratant recursos del processador i electricitat.
  • I això afecta directament a la nostra aplicació, perquè si al principi dedicàvem 10 mil·lisegons a una sol·licitud, 10 mil·lisegons al nostre codi, aleshores durant l'error vam començar a dedicar un segon a una sol·licitud i 10 mil·lisegons al codi, és a dir, un ordre de la magnitud del rendiment de l'aplicació va disminuir. I quan es va resoldre l'accident, vam començar a gastar 20 mil·lisegons per sol·licitud, 10 mil·lisegons per codi. Això vol dir que encara ens hem enfonsat una vegada i mitja pel que fa al rendiment. I tot això és a causa d'una transacció que va penjar, i, potser, per culpa nostra.
  • I la pregunta: “Com puc recuperar-ho tot?” Perquè ens vagi tot bé i les peticions s'executin tan ràpid com abans de l'accident.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Per a això, hi ha un cert cicle de treball que s'està duent a terme.

Primer hem de trobar les taules problemàtiques que s'han inflat. Entenem que algunes taules registren de manera més activa, d'altres menys activament. I per a això fem servir l'extensió pgstattuple. En instal·lar aquesta extensió, podeu escriure consultes per ajudar-vos a trobar taules prou inflades.

Un cop hagis trobat aquestes taules, s'han de comprimir. Ja hi ha eines per a això. A la nostra empresa, utilitzem tres eines. El primer és el VACUUM FULL integrat. És cruel, dur i despietat, però de vegades és molt útil. pg_repack и pgcompactable són utilitats de tercers per comprimir taules. I tenen més cura amb la base de dades.

S'utilitzen en funció del que us convingui més. Però d'això en parlaré al final. El més important és que hi ha tres eines. Hi ha molt per triar.

Després d'haver-ho corregit tot, assegurant-nos que tot està bé, hauríem de saber com prevenir aquesta situació en el futur:

  • És bastant fàcil de prevenir. Heu de controlar la durada de les sessions al servidor mestre. Sessions especialment perilloses en estat inactiu en estat de transacció. Aquests són els que acaben d'obrir una transacció, van fer alguna cosa i van marxar, o simplement es van penjar, es van perdre al codi.
  • I per a vosaltres, com a desenvolupadors, és important provar el codi en el moment que es produeixin aquestes situacions. No és difícil de fer. Aquesta serà una comprovació útil. Evitaràs molts problemes "infantils" associats a transaccions llargues.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

En aquests gràfics, volia mostrar-vos com va canviar la taula i el comportament de la base de dades després de passar VACUUM FULL a la taula en aquest cas. Aquesta no és la meva producció.

La mida de la taula va tornar immediatament al seu estat de treball normal d'un parell de megabytes. Això no va afectar gaire el temps de resposta mitjà del servidor.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Però concretament a la nostra taula de proves, on vam actualitzar els saldos del compte, veiem que el temps mitjà de resposta a una sol·licitud per actualitzar les dades de la tauleta es va reduir als nivells previs a l'accident. Els recursos consumits pel processador per executar aquesta sol·licitud també van caure als nivells previs a l'accident. I el gràfic inferior dret mostra que ara trobem exactament la línia que necessitem immediatament, sense passar per la pila de línies mortes que hi havia abans de comprimir la taula. I el temps mitjà de consulta es va mantenir aproximadament al mateix nivell. Però aquí tinc, més aviat, l'error del meu maquinari.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Aquí és on acaba la primera història. Ella és la més comuna. I li passa a tothom, independentment de l'experiència del client, com de programadors qualificats hi hagi. Tard o d'hora passa.

La segona història, en què distribuïm la càrrega i optimitzem els recursos del servidor

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

  • Hem crescut i ens hem convertit en nois seriosos. I entenem que tenim una rèplica i ens aniria bé equilibrar la càrrega: escriure al Mestre i llegir-ne la rèplica. I normalment aquesta situació es presenta quan volem elaborar algun tipus d'informes o ETL. I les empreses estan molt contentes amb això. Realment vol una varietat d'informes amb un munt d'anàlisis complexes.
  • Els informes duren moltes hores, perquè les analítiques complexes no es poden calcular en mil·lisegons. Nosaltres, com els valents, escrivim codi. Fem en l'aplicació d'inserció que enregistrem al Master, realitzem informes sobre la rèplica.
  • Distribuïm la càrrega.
  • Tot funciona perfectament. Som genials.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

I com és aquesta situació? Concretament, en aquests gràfics, també he afegit la durada de les transaccions de la rèplica durant la durada de la transacció. La resta de gràfics només fan referència al servidor mestre.

En aquest moment, el meu tauler d'informes havia crescut. N'hi ha més. Podem veure que el temps mitjà de resposta del servidor és estable. Podem veure que tenim una transacció de llarga durada a la rèplica que s'executa durant 2 hores. Veiem el treball silenciós de l'autoaspirador, que processa les línies mortes. I tots estem bé.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Concretament, segons la tauleta de prova, continuem actualitzant els saldos dels comptes allà. I també tenim un temps de resposta estable a petició, un consum de recursos estable. Tot va bé amb nosaltres.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Tot va bé fins al moment en què aquests informes comencen a reaccionar sobre un conflicte amb la replicació. I disparen a intervals regulars.

Entrem en línia i comencem a llegir per què passa això. I trobem una solució.

La primera solució és augmentar la latència de replicació. Sabem que el nostre informe té una durada de 3 hores. Estableix el retard de replicació a 3 hores. Comencem tot, però encara seguim tenint problemes amb el fet que de vegades es disparen els informes.

Volem que tot sigui perfecte. Anem més enllà. I trobem una configuració fantàstica a Internet: hot_standby_feedback. Ho encenem. Hot_standby_feedback ens permet mantenir l'autoaspiració en funcionament al Master. Per tant, desfer-nos completament dels conflictes de replicació. I tots treballem bé amb els informes.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

I què està passant amb el servidor mestre en aquest moment? I amb el servidor Master, tenim un desastre total. Ara estem veient gràfics amb aquestes dues configuracions activades. I veiem que la sessió a la rèplica d'alguna manera va començar a influir en la situació del servidor mestre. Té un impacte perquè ha suspès l'autoaspiració que neteja les línies mortes. La mida de la nostra taula s'ha disparat de nou. El temps mitjà d'execució de consultes a tota la base de dades també es va disparar. Els autoaspiradors es van estrènyer una mica.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Concretament, al nostre plat, veiem que l'actualització de dades també va saltar al cel. De la mateixa manera, el consum de recursos del processador ha augmentat molt. Tornem a repetir un gran nombre de línies inútils mortes. I el temps de resposta en aquesta tauleta, el nombre de transaccions ha baixat.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Com serà si no sabem de què parlava abans?

  • Comencem a buscar problemes. Si hem trobat problemes a la primera part, sabem que aquest pot ser el motiu d'una transacció llarga i pugem al Màster. El problema és del Mestre. Salsitxes ell. S'està escalfant, té una mitjana de càrrega inferior a cent.
  • Les sol·licituds s'alenteixen allà, però no hi veiem cap transacció a llarg termini. I no entenem què està passant. No sabem on mirar.
  • Comprovació del maquinari del servidor. Potser la nostra incursió s'ha ensorrat. Potser hem cremat la barra de memòria. Sí, qualsevol pot ser. Però no, els servidors són nous, tot funciona bé.
  • Corre tothom: administradors, desenvolupadors i el director. Res ajuda.
  • I en algun moment, tot comença a corregir-se de sobte.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

A la rèplica, en aquell moment, la petició va funcionar i va marxar. Hem rebut un informe. El negoci encara està content. Com podeu veure, la nostra taula ha tornat a créixer i no baixarà. Al gràfic amb sessions, vaig deixar una part d'aquesta llarga transacció de la rèplica, perquè pugueu avaluar quant de temps triga fins que la situació s'estabilitzi.

La sessió ha desaparegut. I només després d'un temps el servidor entra més o menys en ordre. I el temps mitjà de resposta de les sol·licituds al servidor mestre torna a la normalitat. Perquè, finalment, l'autoaspirador va tenir l'oportunitat de netejar, marcar aquestes línies mortes. I va començar a fer la seva feina. I amb quina rapidesa ho fa, tan ràpid estarem en ordre.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

A la taula de prova, on actualitzem els saldos del compte, veiem exactament la mateixa imatge. El temps mitjà d'actualització del compte també s'està normalitzant gradualment. També es redueixen els recursos consumits pel processador. I el nombre de transaccions per segon torna a la normalitat. Però de nou, torna a la normalitat, no és el mateix que teníem abans de l'accident.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

En qualsevol cas, obtenim una baixada de rendiment, com en el primer cas, d'una vegada i mitja a dues, i de vegades fins i tot més.

Sembla que ho hem fet tot bé. Distribueix la càrrega. L'equip no està inactiu. Segons la ment, van trencar les peticions, però tot i així tot va sortir malament.

  • No actives hot_standby_feedback? Sí, no es recomana activar-lo sense motius especialment forts. Perquè aquest gir afecta directament el servidor mestre i hi suspèn el treball de l'autoaspirador. En activar-lo en alguna rèplica i oblidar-lo, podeu matar el Mestre i tenir grans problemes amb l'aplicació.
  • Augmentar max_standby_streaming_delay? Sí, per als informes ho és. Si teniu un informe de tres hores i no voleu que es bloquegi a causa de conflictes de rèplica, només heu d'augmentar el retard. Un informe llarg mai requereix dades que hagin entrat a la base de dades ara mateix. Si el teniu durant tres hores, l'està executant durant un període de dades antigues. I tu, aquestes tres hores de retard, aquestes sis hores de retard, no jugaràs cap paper, però rebràs informes de manera coherent i no coneixeràs els problemes amb la seva caiguda.
  • Naturalment, heu de controlar les sessions llargues a les rèpliques, sobretot si decidiu habilitar hot_standby_feedback en una rèplica. Perquè pot ser qualsevol cosa. Vam donar aquesta observació al desenvolupador perquè pogués provar les sol·licituds. Va escriure una petició boja. Va començar i va anar a beure te, i vam aconseguir el Mestre establert. O vam llançar l'aplicació incorrecta allà. Les situacions són variades. Les sessions sobre rèpliques s'han de controlar amb la mateixa cura que al màster.
  • I si teniu consultes ràpides i llargues sobre rèpliques, en aquest cas és millor dividir-les per distribuir la càrrega. Aquest és un enllaç a streaming_delay. Per tenir una rèplica ràpida amb un petit retard de replicació. Per a les sol·licituds d'informes de llarga durada, tingueu una rèplica que pugui quedar-se enrere 6 hores, un dia. Aquesta és una situació completament normal.

Eliminem les conseqüències de la mateixa manera:

  • Trobem taules inflades.
  • I comprimim amb l'eina més convenient que ens convingui.

La segona història acaba aquí. Passem a la tercera història.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

També força habitual per a nosaltres, en el qual fem la migració.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

  • Qualsevol producte de programari creix. Els requisits estan canviant. En qualsevol cas, volem desenvolupar-nos. I passa que hem d'actualitzar les dades de la taula, és a dir, executar l'actualització pel que fa a la nostra migració a la nova funcionalitat que estem implementant com a part del nostre desenvolupament.
  • El format de dades antic no s'adapta. Suposem que ara passem a la segona taula, on tinc operacions sobre aquests comptes. I, diguem que estaven en rubles, i vam decidir augmentar la precisió i fer-ho en copecs. I per això hem de fer una actualització: multiplicar per cent el camp amb l'import de l'operació.
  • En el món actual, utilitzem eines de control de versions de bases de dades automatitzades. Diguem Liquibase. Hi registrem la nostra migració. Ho provem a la nostra base de proves. Tot està bé. L'actualització s'està executant. Els blocs funcionen durant un temps, però obtenim dades actualitzades. I podem llançar noves funcionalitats sobre això. Tot provat i revisat. Tot confirmat.
  • Va realitzar treballs planificats, realitzat migracions.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Aquí teniu la migració amb l'actualització presentada davant vostre. Com que tinc operacions de comptes, la placa era de 15 GB. I com que estem actualitzant totes les línies, hem duplicat la placa amb l'actualització, perquè hem sobreescrit totes les línies.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Durant la migració, no hem pogut fer res amb aquesta etiqueta, perquè totes les sol·licituds d'aquesta s'han posat a la cua i s'espera que s'hagi acabat aquesta actualització. Però aquí vull cridar la vostra atenció sobre els números que hi ha a l'eix vertical. És a dir, tenim un temps mitjà de sol·licitud abans de la migració al voltant de 5 mil·lisegons i una càrrega al processador, el nombre d'operacions de bloc per llegir la memòria del disc és inferior a 7,5.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Vam migrar i vam tornar a tenir problemes.

La migració va tenir èxit, però:

  • La funcionalitat antiga va començar a funcionar més temps.
  • La taula ha tornat a créixer de mida.
  • La càrrega al servidor ha tornat a ser més del que era.
  • I, és clar, encara estem jugant amb la funcionalitat que funcionava bé, l'hem millorat una mica.

I això torna a ser inflor, que torna a espatllar les nostres vides.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Aquí demostro que la taula, com els dos casos anteriors, no tornarà a les mides anteriors. La càrrega mitjana al servidor sembla ser adequada.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

I si ens dirigim a la taula amb comptes, veurem que el temps mitjà de sol·licitud s'ha duplicat per a aquesta taula. La càrrega del processador i el nombre de línies a ordenar a la memòria van saltar per sobre de 7,5, però va ser inferior. I va saltar en el cas dels processadors en 2 vegades, en el cas de les operacions de blocs en 1,5 vegades, és a dir, vam obtenir una degradació del rendiment del servidor. I com a resultat, la degradació del rendiment de la nostra aplicació. Al mateix temps, el nombre de trucades es va mantenir aproximadament al mateix nivell.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

I aquí el més important és entendre com fer aquestes migracions correctament. I s'han de fer. Aquestes migracions les fem amb força regularitat.

  • Aquestes migracions tan grans no es fan automàticament. Sempre s'han de controlar.
  • Necessita supervisió d'una persona experta. Si teniu un DBA a l'equip, deixeu que el DBA ho faci. És la seva feina. Si no, deixa que ho faci la persona més experimentada, que sàpiga treballar amb bases de dades.
  • El nou esquema de base de dades, fins i tot si actualitzem una columna, sempre el preparem per etapes, és a dir, amb antelació abans del llançament de la nova versió de l'aplicació:
  • S'afegeixen nous camps en els quals escriurem només les dades actualitzades.
  • Transferim dades del camp antic al camp nou en petites parts. Per què estem fent això? En primer lloc, sempre controlem el procés d'aquest procés. Sabem que ja hem transferit tants lots i ens queden molts.
  • I el segon efecte positiu és que entre cada lot tanquem una transacció, n'obrim una de nova, i això fa possible que l'autoaspirador funcioni segons la placa, per marcar els límits de reutilització.
  • Per a les línies que apareixeran durant el funcionament de l'aplicació (encara tenim l'aplicació antiga), afegim un disparador que escriu nous valors als nous camps. En el nostre cas, es tracta d'una multiplicació per cent del valor antic.
  • Si som completament tossuts i volem el mateix camp, després de completar totes les migracions i abans de llançar la nova versió de l'aplicació, simplement canviem el nom dels camps. Els antics en algun nom inventat, i canviem el nom dels camps nous als antics.
  • I només després d'això llançarem una nova versió de l'aplicació.

I al mateix temps, no ens inflor i no ens enfonsarem en el rendiment.

Aquest és el final de la tercera història.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

https://github.com/dataegret/pg-utils/blob/master/sql/table_bloat.sql

https://github.com/dataegret/pg-utils/blob/master/sql/table_bloat_approx.sql

I ara una mica més sobre les eines que vaig esmentar a la primera història.

Abans de buscar inflor, heu d'instal·lar l'extensió pgstattuple.

Perquè no us inventeu peticions, ja hem escrit aquestes peticions al nostre treball. Podeu utilitzar-los. Aquí hi ha dues peticions.

  • El primer triga molt de temps, però us mostrarà els valors exactes de la inflor segons la taula.
  • El segon funciona més ràpid i és molt eficaç quan cal avaluar ràpidament si hi ha inflor o no a la taula. I també hauríeu d'entendre que sempre hi ha una inflor en una taula de Postgres. Aquesta és una característica del seu model MVCC.
  • I un 20% d'inflor està bé per a les taules en la majoria dels casos. És a dir, no us hauríeu de preocupar i comprimir aquesta taula.

Vam descobrir com identificar les taules que s'inflen amb nosaltres, a més, quan estan inflades amb dades inútils.

Ara sobre com arreglar la inflor:

  • Si tenim un plat petit i bons discs, és a dir, en un plat de fins a un gigabyte, és molt possible utilitzar VACUUM FULL. Et prendrà un pany exclusiu durant uns segons, i d'acord, però ho farà tot de manera ràpida i dura. Què fa VACUUM FULL? Es necessita un bloqueig exclusiu a la taula i reescriu les files en directe de les taules antigues a la taula nova. I al final els substitueix. Suprimeix fitxers antics, substitueix els nous per antics. Però mentre duri el seu treball, necessita un pany exclusiu a la taula. Això vol dir que no podeu fer res amb aquesta taula: ni escriure-hi, ni llegir-hi, ni modificar-la. I VACUUM FULL requereix espai addicional en disc per escriure dades.
  • Eina següent pg_repack. Pel seu principi, és molt semblant a VACUUM FULL, perquè també sobreescriu les dades dels fitxers antics als nous i els substitueix a la taula. Però, al mateix temps, no pren un bloqueig exclusiu a la taula al principi del seu treball, sinó que només l'agafa en el moment en què té dades preparades per substituir els fitxers. Té els mateixos requisits de recursos de disc que VACUUM FULL. Necessiteu espai de disc addicional, i això de vegades és fonamental si teniu taules de terabytes. I és bastant voraç amb el processador, perquè treballa activament amb E/S.
  • La tercera utilitat és pgcompactable. Té més cura dels recursos, perquè funciona amb principis una mica diferents. L'essència principal de pgcompacttable és que mou totes les files en directe al principi de la taula amb actualitzacions a la taula. I llavors comença el buit en aquesta taula, perquè sabem que tenim files vives al principi i mortes al final. I el mateix buit talla aquesta cua, és a dir, no requereix molt espai addicional al disc. I, al mateix temps, encara es pot esprémer pels recursos.

Tot amb eines.

Errors típics de l'aplicació que provoquen una inflació a postgresql. Andrei Salnikov

Si trobeu interessant el tema de la inflació pel que fa a l'excavació més endins, aquí teniu alguns enllaços útils per a vosaltres:

Aquí he intentat mostrar una història de terror per als desenvolupadors, perquè són els nostres clients directes de les bases de dades i han d'entendre a què i a què porten les accions. Espero haver aconseguit. Gràcies per la vostra atenció!

Les vostres preguntes

Gràcies pel reportatge! Vostè va parlar de com es poden identificar els problemes. Com es poden avisar? És a dir, vaig tenir una situació en què les peticions es penjaven no només perquè es dirigien a alguns serveis externs. Eren només unes unions salvatges. Hi havia unes peticions minúscules i inofensives que van quedar durant un dia i després van començar a fer una mena de ximpleries. És a dir, és molt semblant al que estàs descrivint. Com fer-ne el seguiment? Seieu i mireu constantment, quina sol·licitud està bloquejada? Com es pot prevenir això?

En aquest cas, aquesta és una tasca dels administradors de la vostra empresa, no necessàriament del DBA.

Sóc administrador.

PostgreSQL té una vista anomenada pg_stat_activity que mostra les consultes pendents. I podeu veure quant de temps hi està penjat.

He d'entrar cada 5 minuts i mira?

Configureu cron i comproveu. Si teniu una petició llarga, escriviu una carta i ja està. És a dir, no cal mirar amb els ulls, això es pot automatitzar. Rebràs una carta, la respons. O pots disparar automàticament.

Hi ha raons clares per les quals passa això?

N'he enumerat alguns. Altres exemples més complexos. I pot haver-hi una llarga conversa.

Gràcies pel reportatge! Volia aclarir sobre la utilitat pg_repack. Si no requereix un bloqueig exclusiu, aleshores...

Ella fa un pany exclusiu.

... aleshores podria perdre dades. La meva aplicació no hauria d'enregistrar res en aquest moment?

No, funciona en silenci amb la taula, és a dir, pg_repack transfereix primer totes les línies en directe que hi ha. Naturalment, hi ha algun tipus de registre a la taula. Només tira aquesta cua de cavall.

És a dir, encara ho fa al final?

Al final, cal un bloqueig exclusiu per intercanviar aquests fitxers.

Serà més ràpid que VACUUM FULL?

VACUUM FULL, tal com va començar, va prendre immediatament un pany exclusiu. I fins que no ho faci tot, no la deixarà marxar. I pg_repack només pren un bloqueig exclusiu en el moment de substituir els fitxers. En aquest punt, no s'escriu allà, però les dades no es perdran, tot estarà en ordre.

Hola! Has parlat del treball de l'autobuit. Hi havia un gràfic amb cel·les vermelles, grogues i verdes del registre. És a dir, grocs, els va marcar com a suprimits. I com a resultat, pots escriure alguna cosa nova en ells?

Sí. Postgres no elimina files. Té tanta especificitat. Si actualitzem la línia, marcarem l'antiga com a eliminada. L'identificador de transacció que ha canviat aquesta línia apareix allà dalt i escrivim una nova línia. I tenim sessions que potencialment poden llegir-les. En algun moment, es fan força vells. I l'essència de l'autoaspirador és que recorre aquestes línies i les marca com a innecessàries. I allà podeu sobreescriure les dades.

Entenc. Però la pregunta no és sobre això. No estava d'acord. Diguem que tenim una taula. Té camps de mida variable. I si intento inserir alguna cosa nova, és possible que simplement no encaixi a la cel·la antiga.

No, allà en qualsevol cas s'actualitza tota la línia. Postgres té dos models d'emmagatzematge. Selecciona entre el tipus de dades. Hi ha dades que s'emmagatzemen directament a la taula, i també hi ha dades tos. Són grans quantitats de dades: text, json. S'emmagatzemen en tauletes separades. I segons aquestes tauletes, passa la mateixa història amb inflor, és a dir, tot és igual. Només s'enumeren per separat.

Gràcies pel reportatge! Què tan acceptable és utilitzar sol·licituds de temps d'espera de les declaracions per limitar la durada?

Molt acceptable. El fem servir a tot arreu. I com que no disposem de serveis propis, oferim suport remot, hi ha una gran varietat de clients. I tothom està bastant satisfet amb això. És a dir, tenim feines a cron que controlen. És que la durada de les sessions es negocia amb el client, davant del qual no clavem. Pot ser un minut, pot ser 10 minuts. Depèn de la càrrega de la base i del seu propòsit. Però tots fem servir pg_stat_activity.

Gràcies pel reportatge! Estic intentant provar el teu informe per a les meves aplicacions. I sembla que comencem una transacció a tot arreu i la completem explícitament a tot arreu. Si hi ha alguna excepció, es produeix la mateixa recuperació. I llavors vaig pensar. Després de tot, la transacció no pot començar de manera explícita. Això és una pista per a la noia, suposo. Si només faig una actualització de registre, la transacció començarà a PostgreSQL i només finalitzarà quan es desconnecti la connexió?

Si ara parleu del nivell d'aplicació, depèn del controlador que utilitzeu, de l'ORM que s'estigui utilitzant. Hi ha moltes configuracions allà. Si teniu activada la confirmació automàtica, una transacció s'inicia allà i es tanca immediatament.

És a dir, tanca immediatament després de l'actualització?

Depèn de la configuració. Vaig anomenar una configuració. Això és una confirmació automàtica. Ella és bastant comuna. Si està habilitat, la transacció s'ha obert i tancat. A menys que hàgiu dit explícitament "iniciar la transacció" i "acabar la transacció", però simplement heu llançat una sol·licitud a la sessió.

Hola! Gràcies pel reportatge! Imagineu que tenim una base de dades que s'infla i s'infla i després el servidor es queda sense espai. Hi ha alguna eina per solucionar aquesta situació?

S'ha de supervisar el lloc al servidor d'una bona manera.

Per exemple, DBA va anar a beure te, va estar a un complex, etc.

Quan es crea un sistema de fitxers, es crea almenys una mica d'espai de reserva on no s'escriuen dades.

Què passa si és completament zero?

Allà s'anomena espai reservat, és a dir, es pot alliberar, i segons el gran que es va crear, s'obté espai lliure. Per defecte, no sé quants n'hi ha. I en un altre cas, lliurar discos perquè tinguis un lloc on realitzar una operació de recuperació. Podeu suprimir alguna taula que segur que no necessitareu.

No hi ha altres eines?

Sempre està fet a mà. I al lloc es revela què és millor fer-hi, perquè hi ha dades que són crítiques, hi ha no crítiques. I per a cada base de dades i aplicació que hi funcioni, depèn de l'empresa. Sempre es decideix al moment.

Gràcies pel reportatge! Tinc dues preguntes. Primer, vau mostrar diapositives on es mostrava que en el cas de les transaccions penjades, tant la quantitat d'espai de taula com la mida de l'índex creixen. I més enllà de l'informe hi havia un munt d'utilitats que empaqueten la tauleta. I què passa amb l'índex?

També els empaqueten.

Però el buit no afecta l'índex?

Alguns treballen amb un índex. Per exemple pg_rapack, pgcompacttable. El buit recrea els índexs, els afecta. VACUUM FULL té l'essència de sobreescriure-ho tot, és a dir, funciona amb tothom.

I la segona pregunta. No entenia per què els informes sobre rèpliques depenen tant de la pròpia rèplica. Em va semblar que els informes es llegeixen i la replicació és escriptura.

Què causa un conflicte de replicació? Tenim un Màster sobre quins processos es desenvolupen. Tenim un autoaspirador. Autoaspirat, de fet, què fa? Retalla algunes línies antigues. Si en aquest moment tenim una sol·licitud a la rèplica que llegeix aquestes línies antigues, i al Mestre hi havia una situació que l'autobuit marcava aquestes línies com a possibles per reescriure, aleshores les sobreescriurem. I hem rebut un paquet de dades, quan hem de reescriure les línies que la sol·licitud necessita a la rèplica, el procés de rèplica esperarà el temps d'espera que heu configurat. I llavors PostgreSQL decidirà què és més important per a ell. I la rèplica és més important per a ell que una sol·licitud, i dispararà la sol·licitud per fer aquests canvis a la rèplica.

Andreu, tinc una pregunta. Aquests meravellosos gràfics que vau mostrar durant la presentació, és el resultat d'algun treball de la vostra utilitat? Com es van fer els gràfics?

Aquest és un servei Okmetre.

És un producte comercial?

Sí. Aquest és un producte comercial.

Font: www.habr.com

Afegeix comentari