Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Propoño ler a transcrición do informe de principios de 2016 de Andrey Salnikov "Erros típicos en aplicacións que levan a inchar en postgresql"

Neste informe, analizarei os principais erros nas aplicacións que se producen na fase de deseño e escritura do código da aplicación. E tomarei só aqueles erros que levan a inchar en Postgresql. Como regra xeral, este é o comezo do final do rendemento do seu sistema no seu conxunto, aínda que inicialmente non se viron requisitos previos para iso.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Encantada de recibir a todos! Este informe non é tan técnico como o anterior do meu compañeiro. Esta charla está dirixida a desenvolvedores de sistemas back-end principalmente porque temos un número bastante grande de clientes. E todos cometen os mesmos erros. Vouvos falar deles. Vou explicar a que fatal e malo levan estes erros.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Por que se cometen erros? Realízanse por dous motivos: ao chou, quizais funcione por descoñecemento dalgúns mecanismos que se producen a nivel entre a base e a aplicación, así como na propia base.

Vouche poñer tres exemplos con imaxes terribles de como as cousas se puxeron mal. Describirei brevemente o mecanismo que se produce alí. E como tratar con eles, cando sucederon e que métodos preventivos utilizar para evitar erros. Vouvos falar de ferramentas auxiliares e darvos ligazóns útiles.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Usei unha base de datos de proba onde tiña dúas táboas. Unha placa coas contas de clientes, a outra con operacións nestas contas. E con certa periodicidade, actualizamos os saldos destas contas.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Os datos iniciais da placa: é bastante pequena, 2 MB. O tempo de resposta para a base de datos e concretamente para a placa tamén é moi bo. E unha carga bastante boa: 2 operacións por segundo na placa.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

E a través deste informe vouvos mostrar gráficos para que quede claro o que está a pasar. Sempre haberá 2 diapositivas con gráficos. A primeira diapositiva é o que ocorre en xeral no servidor.

E nesta situación, vemos que realmente temos un pequeno prato. O índice é pequeno con 2 MB. Este é o primeiro gráfico da esquerda.

O tempo medio de resposta en todo o servidor tamén é estable, pequeno. Este é o gráfico superior dereito.

O gráfico inferior esquerdo é as transaccións máis longas. Podemos ver que as transaccións se están completando rapidamente. E o baleiro automático aínda non funciona aquí, porque - foi unha proba de inicio. Despois funcionará e será útil para nós.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

A segunda diapositiva estará sempre dedicada á placa de proba. Nesta situación, actualizamos constantemente os saldos da conta do cliente. E vemos que o tempo medio de resposta para a operación de actualización é bastante bo, menos dun milisegundo. Vemos que os recursos do procesador (este é o gráfico superior dereito) tamén se consumen de xeito uniforme e bastante pequeno.

O gráfico inferior dereito mostra a cantidade de memoria operativa e de disco pola que pasamos na procura da nosa liña desexada antes de actualizala. E o número de operacións na placa é de 2 por segundo, como dixen ao principio.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

E agora temos unha traxedia. Por algún motivo, prodúcese unha transacción esquecida durante moito tempo. As razóns adoitan ser todas banais:

  • Unha das máis comúns é que comezamos a acceder a un servizo externo no código da aplicación. E este servizo non nos responde. É dicir, abrimos unha transacción, fixemos un cambio na base de datos e pasamos da aplicación a ler correo ou a outro servizo dentro da nosa infraestrutura, e por algún motivo non nos responde. E a nosa sesión colgado nun estado - non se sabe cando se resolverá.
  • A segunda situación é cando se produciu unha excepción no noso código por algún motivo. E non procesamos o peche da transacción na excepción. E temos unha sesión de suspensión cunha transacción aberta.
  • E o último tamén é bastante común. Este é un código de mala calidade. Algúns marcos abren unha transacción. Cólgase, e quizais non saibas na aplicación que o tes colgado.

A onde levan tales cousas?

Ao feito de que as nosas táboas e índices comezan a aumentar drasticamente. Este é exactamente o mesmo efecto de inchazo. Para a base de datos, isto expresarase no feito de que teremos un aumento moi acusado no tempo de resposta da base de datos, a carga no servidor de base de datos aumentará. E como resultado, a nosa aplicación sufrirá. Porque se no teu código gastaches 10 milisegundos nunha solicitude á base de datos, 10 milisegundos na túa lóxica, entón a túa función funcionou en 20 milisegundos. E agora a túa situación será moi triste.

E a ver que pasa. O gráfico inferior esquerdo mostra que temos unha transacción longa e longa. E se observamos o gráfico superior esquerdo, vemos que o tamaño da táboa saltou de dous megabytes a 300 megabytes. Ao mesmo tempo, a cantidade de datos da táboa non cambiou, é dicir, hai unha cantidade bastante grande de lixo.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

A situación xeral en canto ao tempo medio de resposta do servidor tamén cambiou en varias ordes de magnitude. É dicir, todas as solicitudes do servidor comezaron a caer completamente. E ao mesmo tempo puxéronse en marcha os procesos internos de Postgres ante o autobaleiro, que tentan facer algo e consumir recursos.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Que pasa co noso prato? O mesmo. O tempo medio de resposta na tableta aumentou varias ordes de magnitude. Se concretamente en termos de recursos consumidos, entón vemos que a carga do procesador aumentou moito. Este é o gráfico superior dereito. E aumentou porque o procesador ten que pasar por un montón de liñas inútiles na procura da que necesitas. Este é o gráfico inferior dereito. E como resultado, o número de chamadas por segundo comezou a baixar moito, porque a base de datos non ten tempo para procesar o mesmo número de solicitudes.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Necesitamos volver á vida. Subimos a Internet e descubrimos que as transaccións longas levan a un problema. Atopamos e matamos esta transacción. E todo nos vai ben. Todo funciona como debería.

Calmamos, pero despois dun tempo comezamos a notar que a aplicación non funciona como antes da emerxencia. As solicitudes son igualmente procesadas máis lentamente, e moito máis lentamente. Unha e media ou dúas veces máis lento especificamente no meu exemplo. A carga no servidor tamén é maior que antes do accidente.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

E a pregunta: "Que lle pasa á base neste momento?". E con base hai unha situación seguinte. No gráfico de transaccións, podes ver que se detivo e que realmente non hai transaccións a longo prazo. Pero as dimensións da placa durante o accidente creceron fatalmente. E desde entón non diminuíu. O tempo medio na base estabilizouse. E as respostas parecen ir adecuadamente cunha velocidade aceptable para nós. Autovacuum fíxose máis activo e comezou a facer algo coa tableta, porque necesita cargar máis datos.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

En concreto, no cadro de puntuación da proba, onde cambiamos os saldos: o tempo de resposta á solicitude parece que volveu á normalidade. Pero en realidade é unha vez e media máis alto.

E pola carga do procesador, vemos que a carga do procesador non volveu ao valor desexado antes do accidente. E as razóns atópanse só no gráfico inferior dereito. Pódese ver que hai unha procura de certa cantidade de memoria. É dicir, para buscar a liña desexada, gastamos os recursos do servidor de bases de datos á hora de ordenar datos inútiles. O número de transaccións por segundo estabilizouse.

En xeral, boa, pero a situación é peor do que estaba. Degradación explícita da base de datos como consecuencia da nosa aplicación que traballa con esta base de datos.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

E para entender o que está a pasar alí, se non estabas no informe anterior, agora un pouco de teoría. Teoría sobre o proceso interno. Por que o baleiro automático e que fai?

Literalmente en poucas palabras para entender. Nalgún momento temos unha mesa. Temos filas na táboa. Estas liñas poden ser activas, en directo, precisamos agora. Están marcados en verde na imaxe. E hai liñas mortas que xa funcionaron, foron actualizadas, apareceron novas entradas nelas. E marcan que xa non son interesantes para a base de datos. Pero xacen na mesa polas peculiaridades de Postgres.

Por que necesitas unha aspiradora automática? O baleiro automático chega nalgún momento, chama á base de datos e pregúntalle: "Por favor, dáme o ID da transacción máis antiga que está aberta actualmente na base de datos". A base de datos devolve este ID. E o baleiro automático, confiando nel, pasa polas liñas da táboa. E se ve que algunhas liñas foron modificadas por transaccións moito máis antigas, entón ten dereito a marcalas como liñas que podemos reutilizar no futuro escribindo alí novos datos. Este é un proceso de fondo.

Neste momento, seguimos traballando coa base de datos, seguimos facendo algúns cambios na táboa. E nestas liñas, que podemos reutilizar, escribimos novos datos. E deste xeito obtemos un ciclo, é dicir, aparecen alí todo o tempo algunhas liñas vellas mortas, no canto delas anotamos liñas novas que necesitamos. E este é o estado normal para que PostgreSQL funcione.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Que pasou durante o accidente? Como se desenvolveu este proceso?

Tiñamos un prato nalgunha condición, algúns vivos, outros mortos. Chegou o autovacuo. Preguntoulle á base de datos cal é a nosa transacción máis antiga, cal é a súa identificación. Conseguín esta identificación, que pode ter moitas horas, quizais dez minutos. Depende da carga que teñas na base de datos. E foi buscar liñas que poida marcar como reutilizadas. E non atopei tales liñas na nosa táboa.

Pero neste momento seguimos traballando coa mesa. Facemos algo nel, actualízao, cambiamos os datos. Que debería facer a base de datos neste momento? Non lle queda outra que engadir novas liñas ao final da táboa existente. E así a nós o tamaño da mesa comeza a inflarse.

Realmente necesitamos liñas verdes para funcionar. Pero durante tal problema, resulta que a porcentaxe de liñas verdes é moi baixa en todo o volume da táboa.

E cando executamos unha consulta, a base de datos ten que pasar por todas as liñas, tanto vermellas como verdes, para atopar a liña correcta. E o efecto de inflar a táboa con datos inútiles chámase "inchazo", que tamén consume o noso espazo no disco. Lembra que eran 2 MB, agora son 300 MB? Agora cambia os megabytes a gigabytes e perderás todos os recursos do teu disco con bastante rapidez.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Cales son as implicacións para nós?

  • No meu exemplo, a táboa e o índice creceron 150 veces. Algúns dos nosos clientes tiveron máis casos mortais cando o espazo no disco comezou a esgotarse.
  • As táboas nunca se encollerán por si soas. Nalgúns casos, o baleiro automático pode cortar a cola da mesa se só hai liñas mortas. Pero dado que hai unha rotación constante, unha liña verde pode colgar ao final e non actualizarse, e rexistrarase todo o resto nalgún lugar do comezo da placa. Pero este é un evento tan improbable que a túa propia mesa diminuirá de tamaño, polo que non debes esperar.
  • A base de datos necesita ordenar toda a pila de liñas inútiles. E estamos malgastando recursos de disco, malgastando recursos do procesador e electricidade.
  • E isto afecta directamente á nosa aplicación, porque se ao principio gastamos 10 milisegundos nunha solicitude, 10 milisegundos no noso código, entón durante o fallo comezamos a gastar un segundo nunha solicitude e 10 milisegundos en código, é dicir, unha orde de o rendemento da aplicación de magnitude diminuíu. E cando se resolveu o accidente, comezamos a gastar 20 milisegundos por solicitude, 10 milisegundos por código. Isto significa que aínda nos afundimos unha vez e media en canto ao rendemento. E todo isto é por mor dunha transacción que colgou e, quizais, por culpa nosa.
  • E a pregunta: "¿Como podo recuperar todo?" Para que todo estea ben con nós e as solicitudes corran tan rápido como antes do accidente.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Para iso, hai un certo ciclo de traballo que se está a realizar.

Primeiro necesitamos atopar as táboas problemáticas que se incharon. Entendemos que algunhas táboas gravan de forma máis activa, outras menos activamente. E para iso usamos a extensión pgstattuple. Ao instalar esta extensión, podes escribir consultas para axudarche a atopar táboas que estean o suficientemente inchadas.

Unha vez atopadas estas táboas, hai que comprimilas. Xa hai ferramentas para iso. Na nosa empresa, utilizamos tres ferramentas. O primeiro é o VACUUM FULL incorporado. É cruel, duro e despiadado, pero ás veces é moi útil. pg_repack и pgcompactable son utilidades de terceiros para comprimir táboas. E teñen máis coidado coa base de datos.

Utilízanse dependendo do que che resulte máis cómodo. Pero disto falarei ao final. O principal é que hai tres ferramentas. Hai moito onde escoller.

Despois de corrixir todo, asegurándonos de que todo está ben, debemos saber como previr esta situación no futuro:

  • É bastante fácil de previr. Debe supervisar a duración das sesións no servidor mestre. Sesións particularmente perigosas no estado de inactividade en transacción. Estes son os que acaban de abrir unha transacción, facer algo e saíron, ou simplemente colgaron, perdéronse no código.
  • E para ti, como desenvolvedores, é importante probar o código no momento en que se produzan estas situacións. Non é difícil de facer. Esta será unha comprobación útil. Evitarás moitos problemas "infantiles" asociados con transaccións longas.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Nestes gráficos, quería mostrarche como cambiaron a táboa e o comportamento da base de datos despois de pasar VACUUM FULL na táboa neste caso. Esta non é a miña produción.

O tamaño da táboa volveu inmediatamente ao seu estado normal de traballo dun par de megabytes. Isto non afectou moito o tempo medio de resposta no servidor.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Pero concretamente na nosa táboa de proba, onde actualizamos os saldos das contas, vemos que o tempo medio de resposta a unha solicitude para actualizar os datos na tableta reduciuse aos niveis anteriores ao fallo. Os recursos consumidos polo procesador para executar esta solicitude tamén caeron aos niveis anteriores ao fallo. E o gráfico inferior dereito mostra que agora atopamos exactamente a liña que necesitamos inmediatamente, sen pasar pola pila de liñas mortas que había antes de que a táboa fose comprimida. E o tempo medio de consulta mantívose aproximadamente no mesmo nivel. Pero aquí teño, máis ben, o erro do meu hardware.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Aquí é onde remata a primeira historia. Ela é a máis común. E pásalle a todo o mundo, independentemente da experiencia do cliente, como programadores cualificados hai. Tarde ou cedo pasa.

A segunda historia, na que distribuímos a carga e optimizamos os recursos do servidor

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

  • Crecemos e convertémonos en rapaces serios. E entendemos que temos unha réplica e que estaría ben equilibrar a carga: escribirlle ao Mestre, e ler a réplica. E normalmente esta situación xorde cando queremos elaborar algún tipo de informes ou ETL. E os negocios están moi contentos con iso. Realmente quere unha variedade de informes cunha serie de análises complexas.
  • Os informes duran moitas horas, porque as análises complexas non se poden calcular en milisegundos. Nós, como rapaces valentes, escribimos código. Facemos na aplicación de inserción que gravamos no Master, realizamos informes sobre a réplica.
  • Repartimos a carga.
  • Todo funciona perfectamente. Somos xeniais.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

E como se ve esta situación? En concreto, nestes gráficos, tamén engadín a duración das transaccións da réplica durante a duración da transacción. Todos os demais gráficos refírense só ao servidor mestre.

Nese momento, o meu cadro de informes creceu. Hai máis deles. Podemos ver que o tempo medio de resposta do servidor é estable. Podemos ver que temos unha transacción longa na réplica que se executa durante 2 horas. Vemos o traballo silencioso do autovacuum, que procesa liñas mortas. E todos estamos ben.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

En concreto, segundo a tableta de proba, seguimos actualizando os saldos das contas alí. E tamén temos un tempo de resposta estable a petición, un consumo de recursos estable. Todo está ben con nós.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Todo está ben ata o momento en que estes informes comezan a devolvernos un conflito coa replicación. E disparan a intervalos regulares.

Entramos en liña e comezamos a ler por que sucede isto. E atopamos unha solución.

A primeira solución é aumentar a latencia de replicación. Sabemos que o noso informe dura 3 horas. Establece o atraso de replicación en 3 horas. Comezamos todo, pero aínda así seguimos tendo problemas co feito de que ás veces os informes se devolvan.

Queremos que todo sexa perfecto. Imos máis aló. E atopamos unha configuración xenial en Internet: hot_standby_feedback. Acendemos. Hot_standby_feedback permítenos manter o baleiro automático en execución no Master. Así, eliminamos completamente os conflitos de replicación. E todos traballamos ben cos informes.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

E que está a pasar co servidor Mestre neste momento? E co servidor Master, temos un desastre total. Agora estamos a ver gráficos con estas dúas opcións activadas. E vemos que a sesión na réplica dalgunha maneira comezou a influír na situación do servidor Mestre. Fai un impacto porque suspendeu o autoaspirador que limpa as liñas mortas. O tamaño da nosa mesa disparouse de novo. O tempo medio de execución de consultas en toda a base de datos tamén se disparou. Os aspiradores automáticos apretaron un pouco.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

En concreto, no noso prato, vemos que a actualización de datos sobre el tamén saltou ao ceo. O consumo de recursos do procesador tamén aumentou moito. Volvemos a repetir un gran número de liñas mortas e inútiles. E o tempo de resposta nesta tableta, o número de transaccións caeu.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Como será se non sabemos de que falaba antes?

  • Comezamos a buscar problemas. Se atopamos problemas na primeira parte, sabemos que este pode ser o motivo dunha transacción longa e subimos ao Master. O problema é do Mestre. Salchichas el. Está quentando, ten unha media de carga inferior a cen.
  • As solicitudes son máis lentos, pero non vemos transaccións a longo prazo alí. E non entendemos o que está a pasar. Non sabemos onde mirar.
  • Comprobación do hardware do servidor. Quizais a nosa incursión colapsou. Quizais queimamos a barra de memoria. Si, calquera cousa pode ser. Pero non, os servidores son novos, todo funciona ben.
  • Todos corren: administradores, desenvolvedores e director. Nada axuda.
  • E nalgún momento, todo comeza a corrixirse de súpeto.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Na réplica, nese momento, a solicitude funcionou e marchou. Recibimos un informe. O negocio segue contento. Como vedes, a nosa mesa volveu medrar e non vai diminuír. No gráfico con sesións, deixei un anaco desta longa transacción da réplica, para que poidas avaliar canto tempo leva ata que a situación se estabilice.

A sesión desapareceu. E só despois dun tempo o servidor chega máis ou menos en orde. E o tempo medio de resposta das solicitudes no servidor mestre volve á normalidade. Porque, finalmente, o autoaspirador tivo a oportunidade de limpar, marcar estas liñas mortas. E comezou a facer o seu traballo. E o rápido que o fai, tan rápido estaremos en orde.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Na táboa de proba, onde actualizamos os saldos das contas, vemos exactamente a mesma imaxe. O tempo medio de actualización da conta tamén se normaliza gradualmente. Tamén se reducen os recursos consumidos polo procesador. E o número de transaccións por segundo volve á normalidade. Pero de novo, volvemos á normalidade, non é o mesmo que tiñamos antes do accidente.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

En calquera caso, temos unha baixa no rendemento, como no primeiro caso, unha e media a dúas veces, e ás veces incluso máis.

Parece que fixemos todo ben. Distribuír a carga. O equipo non está inactivo. Segundo a mente, romperon as peticións, pero aínda así todo saíu mal.

  • Non activas o hot_standby_feedback? Si, non se recomenda acendelo sen motivos especialmente fortes. Porque este xiro afecta directamente ao servidor mestre e suspende alí o traballo do baleiro automático. Acendendo nalgunha réplica e esquecendo ela, podes matar ao Mestre e ter grandes problemas coa aplicación.
  • Queres aumentar max_standby_streaming_delay? Si, para os informes é. Se tes un informe de tres horas e non queres que falle debido a conflitos de replicación, simplemente aumenta o atraso. Un informe longo nunca precisa de datos que entraron na base de datos agora mesmo. Se o tes durante tres horas, está a executalo durante algún período de datos antigos. E ti, esas tres horas de atraso, esas seis horas de atraso, non xogarás ningún papel, pero recibirás informes de forma coherente e non coñecerás os problemas coa súa caída.
  • Por suposto, cómpre controlar as sesións longas nas réplicas, especialmente se decides activar o hot_standby_feedback nunha réplica. Porque pode ser calquera cousa. Fixémoslle esta observación ao programador para que probase as solicitudes. Escribiu unha petición tola. Comezou e foi tomar té, e conseguimos o mestre establecido. Ou lanzamos alí a aplicación incorrecta. As situacións son variadas. As sesións sobre réplicas deben controlarse con tanto coidado como no Master.
  • E se tes consultas rápidas e longas sobre as réplicas, neste caso é mellor dividilas para distribuír a carga. Esta é unha ligazón a streaming_delay. Para ter unha réplica rápida cun pequeno atraso de replicación. Para as solicitudes de informes de longa duración, ten unha réplica que poida quedar atrás 6 horas, un día. Esta é unha situación completamente normal.

Eliminamos as consecuencias do mesmo xeito:

  • Atopamos mesas inchadas.
  • E comprimimos coa ferramenta máis cómoda que nos conveña.

A segunda historia remata aquí. Pasemos á terceira historia.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Tamén bastante habitual para nós, no que facemos a migración.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

  • Calquera produto de software crece. Os requisitos están cambiando. En todo caso, queremos desenvolvernos. E ocorre que necesitamos actualizar os datos da táboa, é dicir, para executar a actualización en canto á nosa migración á nova funcionalidade que estamos implementando como parte do noso desenvolvemento.
  • O formato de datos antigo non é adecuado. Digamos que agora pasamos á segunda táboa, onde teño operacións sobre estas contas. E, digamos que estaban en rublos, e decidimos aumentar a precisión e facelo en copeques. E para iso necesitamos facer unha actualización: multiplicar por cen o campo co importe da operación.
  • No mundo actual, usamos ferramentas automatizadas de control de versións de bases de datos. Digamos Liquibase. Alí rexistramos a nosa migración. Probámolo na nosa base de probas. Todo está ben. A actualización está a executarse. Os bloques funcionan durante un tempo, pero recibimos datos actualizados. E podemos lanzar novas funcionalidades sobre isto. Todo probado e comprobado. Todo confirmado.
  • Realizou traballos planificados, realizou migracións.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Aquí está a migración coa actualización presentada diante de ti. Como teño operacións en contas, a placa era de 15 GB. E como estamos actualizando todas as liñas, duplicamos o tamaño da táboa porque sobrescribimos todas as liñas.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Durante a migración, non puidemos facer nada con esta etiqueta, porque todas as solicitudes para ela estaban en cola e agardaron a que finalizase esta actualización. Pero aquí quero chamar a súa atención sobre os números que están no eixe vertical. É dicir, temos un tempo medio de solicitude antes da migración na rexión de 5 milisegundos e unha carga no procesador, o número de operacións de bloque para ler a memoria do disco é inferior a 7,5.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Migramos e volvemos ter problemas.

A migración foi exitosa, pero:

  • A antiga funcionalidade comezou a funcionar máis tempo.
  • A mesa volveu medrar de tamaño.
  • A carga no servidor volveu ser máis do que era.
  • E, por suposto, aínda estamos xogando coa funcionalidade que funcionou ben, mellorámola un pouco.

E isto é outra vez inchazo, que volve estragar as nosas vidas.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Aquí demostro que a táboa, como os dous casos anteriores, non vai volver aos tamaños anteriores. A carga media no servidor parece ser adecuada.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

E se nos diriximos á táboa con contas, veremos que o tempo medio de solicitude duplicouse para esta táboa. A carga do procesador e o número de liñas a resolver na memoria saltou por riba de 7,5, pero foi menor. E saltou 2 veces no caso dos procesadores, no caso das operacións en bloque 1,5 veces, é dicir, obtivemos unha degradación no rendemento do servidor. E como resultado - a degradación do rendemento da nosa aplicación. Ao mesmo tempo, o número de chamadas mantívose aproximadamente no mesmo nivel.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

E aquí o principal é entender como facer tales migracións correctamente. E hai que facelos. Facemos estas migracións con bastante regularidade.

  • As migracións tan grandes non se fan automaticamente. Deben estar sempre controlados.
  • Necesita supervisión dunha persoa experta. Se tes un DBA no equipo, deixa que o faga. É o seu traballo. Se non, que o faga a persoa máis experimentada, que saiba traballar con bases de datos.
  • O novo esquema de base de datos, aínda que actualicemos unha columna, sempre preparámolo por etapas, é dicir, antes de que se lance a nova versión da aplicación:
  • Engádense novos campos nos que escribiremos só os datos actualizados.
  • Transferimos datos do campo antigo ao campo novo en pequenas partes. Por que facemos isto? En primeiro lugar, sempre controlamos o proceso deste proceso. Sabemos que xa levamos tantos lotes e nos quedan moitos.
  • E o segundo efecto positivo é que entre cada un destes lotes pechamos unha transacción, abrimos unha nova, e iso fai posible que o autovacuo funcione segundo a placa, para marcar liñas de reutilización.
  • Para as liñas que aparecerán durante o funcionamento da aplicación (aínda temos a aplicación antiga), engadimos un disparador que escribe novos valores en novos campos. No noso caso, trátase dunha multiplicación por cen do valor antigo.
  • Se somos completamente teimudos e queremos o mesmo campo, despois de completar todas as migracións e antes de lanzar a nova versión da aplicación, simplemente cambiamos o nome dos campos. Os antigos por algún nome inventado, e renomeamos os novos campos polos antigos.
  • E só despois diso lanzamos unha nova versión da aplicación.

E ao mesmo tempo, non nos incharemos nin nos cederemos no rendemento.

Este é o final da terceira historia.

Erros típicos da aplicación que provocan inchazo en 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

E agora un pouco máis sobre as ferramentas que mencionei na primeira historia.

Antes de buscar inchazo, debes instalar a extensión pgstattuple.

Para que non te inventes peticións, xa escribimos estas peticións no noso traballo. Podes usalos. Aquí hai dúas solicitudes.

  • O primeiro leva moito tempo, pero mostrarache os valores exactos de inchazo segundo a táboa.
  • O segundo funciona máis rápido e é moi eficaz cando necesitas avaliar rapidamente se hai inchazo ou non na táboa. E tamén debes entender que sempre hai un inchazo nunha táboa de Postgres. Esta é unha característica do seu modelo MVCC.
  • E un 20% de inchazo está ben para as táboas na maioría dos casos. É dicir, non debe preocuparse e comprimir esta táboa.

Descubrimos como identificar as táboas que están inchadas connosco, ademais, cando están inchadas con datos inútiles.

Agora sobre como corrixir o inchazo:

  • Se temos un prato pequeno e bos discos, é dicir, nun prato de ata un gigabyte, é moi posible usar VACUUM FULL. Vai tomar un bloqueo exclusivo de ti durante uns segundos, e está ben, pero fará todo rápido e con dureza. Que fai VACUUM FULL? Leva un bloqueo exclusivo na táboa e reescribe as filas vivas das táboas antigas á mesa nova. E ao final substitúeos. Elimina ficheiros antigos, substitúe os novos por antigos. Pero mentres dure o seu traballo, leva un bloqueo exclusivo sobre a mesa. Isto significa que non podes facer nada con esta táboa: nin escribir nela, nin lela, nin modificala. E VACUUM FULL require espazo adicional no disco para escribir datos.
  • Ferramenta seguinte pg_repack. Polo seu principio, é moi semellante a VACUUM FULL, porque tamén sobrescribe os datos dos ficheiros antigos a outros novos e substitúeos na táboa. Pero, ao mesmo tempo, non leva un bloqueo exclusivo sobre a mesa ao comezo do seu traballo, senón que o toma só no momento en que ten datos preparados para substituír os ficheiros. Ten os mesmos requisitos de recursos de disco que VACUUM FULL. Necesitas espazo extra no disco, e ás veces isto é fundamental se tes táboas de terabytes. E é bastante glotón en canto ao procesador, porque está a traballar activamente con E/S.
  • A terceira utilidade é pgcompactable. É máis coidadoso cos recursos, porque funciona con principios lixeiramente diferentes. A esencia principal de pgcompacttable é que move todas as filas activas ao principio da táboa con actualizacións na táboa. E entón comeza o baleiro nesta mesa, porque sabemos que temos filas vivas ao principio e liñas mortas ao final. E o propio baleiro corta esta cola, é dicir, non require moito espazo adicional no disco. E, ao mesmo tempo, aínda se pode espremer polos recursos.

Todo con ferramentas.

Erros típicos da aplicación que provocan inchazo en postgresql. Andrei Salnikov

Se pensas que o tema do inchazo é interesante en canto a profundizar máis cara a dentro, aquí tes algunhas ligazóns útiles:

Aquí tentei mostrar unha historia de terror para os desenvolvedores, porque son os nosos clientes directos das bases de datos e deben entender a que e a que accións levan. Espero ter éxito. Grazas pola súa atención!

preguntas

Grazas polo informe! Falou de como se poden identificar os problemas. Como se lles pode avisar? É dicir, tiven unha situación na que as solicitudes colgaban non só porque se dirixían a algúns servizos externos. Foron só algunhas unións salvaxes. Houbo algunhas peticións pequenas e inofensivas que quedaron un día e despois comezaron a facer algún tipo de tontería. É dicir, é moi semellante ao que estás describindo. Como rastrexalo? Senta e observa constantemente, que solicitude está bloqueada? Como se pode previr isto?

Neste caso, esta é unha tarefa para os administradores da túa empresa, non necesariamente para o DBA.

Son administrador.

PostgreSQL ten unha vista chamada pg_stat_activity que mostra consultas pendentes. E podes ver canto tempo garda alí.

Teño que entrar cada 5 minutos e mira?

Configura cron e verifica. Se tes unha petición longa, escribe unha carta e listo. É dicir, non é necesario mirar cos ollos, isto pódese automatizar. Recibirás unha carta, respondes a ela. Ou pode disparar automaticamente.

Hai razóns claras polas que isto ocorre?

Enumerei algúns. Outros exemplos máis complexos. E pode haber unha longa conversa.

Grazas polo informe! Quería aclarar a utilidade pg_repack. Se non é necesario un bloqueo exclusivo, entón...

Ela fai un peche exclusivo.

... entón podería perder datos. A miña aplicación non debería estar gravando nada neste momento?

Non, funciona en silencio coa táboa, é dicir, pg_repack transfire primeiro todas as liñas en directo que hai. Por suposto, hai algún tipo de rexistro na táboa. Só bota esta cola de cabalo.

É dicir, aínda o fai ao final?

Ao final, é necesario un bloqueo exclusivo para intercambiar estes ficheiros.

Será máis rápido que VACUUM FULL?

VACUUM FULL, como comezou, inmediatamente levou un bloqueo exclusivo. E ata que non o faga todo, non a deixará marchar. E pg_repack leva un bloqueo exclusivo só no momento de substituír os ficheiros. Neste punto, non escribe alí, pero os datos non se perderán, todo estará en orde.

Ola! Falabas do traballo do autovacuum. Había un gráfico con celas vermellas, amarelas e verdes do rexistro. É dicir, amarelas -marcounas como borradas. E como resultado, podes escribir algo novo neles?

Si. Postgres non elimina filas. Ten tal especificidade. Se actualizamos a liña, marcamos a antiga como eliminada. O ID de transacción que cambiou esta liña aparece aí arriba e escribimos unha nova liña. E temos sesións que potencialmente poden lelas. Nalgún momento, vólvense bastante vellos. E a esencia do autovacuo é que atravesa estas liñas e márcaas como innecesarias. E alí podes sobrescribir os datos.

Entendo. Pero a pregunta non é sobre iso. Non estaba de acordo. Digamos que temos unha mesa. Ten campos de tamaño variable. E se intento inserir algo novo, quizais simplemente non encaixe na cela antiga.

Non, alí en todo caso actualízase toda a liña. Postgres ten dous modelos de almacenamento. Selecciona entre o tipo de datos. Hai datos que se almacenan directamente na táboa, e tamén hai datos tos. Son grandes cantidades de datos: texto, json. Gárdanse en comprimidos separados. E segundo estas tabletas, ocorre a mesma historia con hinchazón, é dicir, todo é igual. Só están listados por separado.

Grazas polo informe! Que aceptable é utilizar as solicitudes de tempo de espera de declaracións para limitar a duración?

Moi aceptable. Usámolo en todas partes. E como non temos os nosos propios servizos, ofrecemos soporte remoto, hai unha gran variedade de clientes. E todo o mundo está moi satisfeito con isto. É dicir, temos traballos en cron que verifican. É que a duración das sesións se negocia co cliente, ante o que non cravamos. Pode ser un minuto, pode ser 10 minutos. Depende da carga da base e da súa finalidade. Pero todos usamos pg_stat_activity.

Grazas polo informe! Estou tentando probar o teu informe para as miñas aplicacións. E parece que comezamos unha transacción en todas partes e completámola explícitamente en todas partes. Se hai algunha excepción, entón ocorrerá a mesma recuperación. E entón pensei. Despois de todo, a transacción pode comezar non de forma explícita. Supoño que esta é unha pista para a moza. Se só fago unha actualización de rexistro, a transacción comezará en PostgreSQL e só rematará cando se desconecte a conexión?

Se estás a falar agora do nivel de aplicación, entón depende do controlador que esteas a usar, do ORM que se estea a utilizar. Hai moitos axustes alí. Se tes activada a confirmación automática, a transacción comeza alí e pecharase inmediatamente.

É dicir, pecha inmediatamente despois da actualización?

Depende da configuración. Chamei unha configuración. Esta é a confirmación automática. Ela é bastante común. Se está activado, a transacción foi aberta e pechada. A non ser que dixeses explícitamente "iniciar transacción" e "finalizar transacción", pero simplemente lanzou unha solicitude na sesión.

Ola! Grazas polo informe! Imaxina que temos unha base de datos que se incha e se incha e despois o servidor queda sen espazo. Existen ferramentas para solucionar esta situación?

O lugar no servidor de boa forma debe ser supervisado.

Por exemplo, DBA foi tomar té, estivo nun resort, etc.

Cando se crea un sistema de ficheiros, créase polo menos un espazo de reserva onde non se escriben datos.

E se é completamente cero?

Alí chámase espazo reservado, é dicir, pódese liberar, e segundo o grande que fose creado, conseguía espazo libre. Por defecto, non sei cantos hai. E noutro caso, entrega discos para que teñas un lugar onde realizar unha operación de recuperación. Podes eliminar algunha táboa que seguro non necesitarás.

Non hai outras ferramentas?

Sempre está feito a man. E no lugar revélase que é mellor facer alí, porque hai datos que son críticos, hai non críticos. E para cada base de datos e aplicación que traballa con ela, depende do negocio. Sempre se decide no lugar.

Grazas polo informe! Teño dúas preguntas. En primeiro lugar, mostraches diapositivas onde se mostraba que no caso das transaccións colgadas, tanto a cantidade de espazo na táboa como o tamaño do índice crecen. E máis aló do informe había unha morea de utilidades que empaquetan a tableta. E o índice?

Tamén os empaquetan.

Pero o baleiro non afecta o índice?

Algúns traballan cun índice. Por exemplo pg_rapack, pgcompacttable. O baleiro recrea os índices, aféctaos. VACUUM FULL ten a esencia de sobrescribir todo, é dicir, funciona con todos.

E a segunda pregunta. Non entendín por que os informes sobre réplicas dependen tanto da propia réplica. Pareceume que os informes están a ler, e a réplica é a escritura.

Que causa un conflito de replicación? Temos un Máster sobre o que se desenvolven os procesos. Temos un autoaspirador. O baleiro automático, de feito, que fai? Recorta algunhas liñas antigas. Se neste momento temos unha solicitude na réplica que le estas liñas antigas, e no Master houbo unha situación en que o baleiro automático marcaba estas liñas como posibles para reescribir, entón sobreescribímolas. E recibimos un paquete de datos, cando teñamos que reescribir as liñas que a solicitude necesita na réplica, entón o proceso de replicación agardará o tempo de espera que configuraches. E entón PostgreSQL decidirá o que é máis importante para el. E a réplica é máis importante para el que unha solicitude, e el disparará a solicitude para facer estes cambios na réplica.

Andrew, teño unha pregunta. Estes marabillosos gráficos que mostraches durante a presentación, son este o resultado dalgún traballo da túa utilidade? Como se fixeron os gráficos?

Este é un servizo Okmeter.

É este un produto comercial?

Si. Este é un produto comercial.

Fonte: www.habr.com

Engadir un comentario