{"id":87954,"date":"2020-07-12T01:42:48","date_gmt":"2020-07-11T23:42:48","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian"},"modified":"2020-07-12T01:42:48","modified_gmt":"2020-07-11T23:42:48","slug":"unlocking-the-postgres-lock-manager-bryus-momzhian","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian","title":{"rendered":"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Descriptivo do relat\u00f3rio de 2020 de Bruce Momjian \"Unlocking the Postgres Lock Manager\".<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/1f75fbb0cb41c306c33c823ef55f7238.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>(Nota: Todos os comandos SQL dos slides podem ser obtidos atrav\u00e9s deste link: <noindex><a rel=\"nofollow\" href=\"http:\/\/momjian.us\/main\/writings\/pgsql\/locking.sql\">http:\/\/momjian.us\/main\/writings\/pgsql\/locking.sql<\/a><\/noindex>)<\/p>\n<p><\/p>\n<p>Ol\u00e1! \u00c9 maravilhoso estar aqui novamente na R\u00fassia. Pe\u00e7o desculpas por n\u00e3o ter conseguido vir no ano passado, mas este ano Ivan e eu temos grandes planos. Espero estar aqui com muito mais frequ\u00eancia. Adoro visitar a R\u00fassia. Estarei passando por Tyumen e Tver. Estou muito empolgado por poder conhecer essas cidades. <\/p>\n<p><\/p>\n<p>Meu nome \u00e9 Bruce Momjian. Eu trabalho na EnterpriseDB e estou com Postgres h\u00e1 mais de 23 anos. Moro na Filad\u00e9lfia, EUA. Viajo cerca de 90 dias por ano e participo de aproximadamente 40 confer\u00eancias. Meu <noindex><a rel=\"nofollow\" href=\"https:\/\/momjian.us\/\">site<\/a><\/noindex>, que cont\u00e9m os slides que vou apresentar a voc\u00eas agora. Portanto, ap\u00f3s a confer\u00eancia, voc\u00eas podem baix\u00e1-los do meu site pessoal. H\u00e1 tamb\u00e9m cerca de 30 apresenta\u00e7\u00f5es dispon\u00edveis. Al\u00e9m disso, existem v\u00eddeos e uma grande quantidade de postagens no blog, mais de 500 no total. \u00c9 um recurso bastante completo. E se voc\u00ea estiver interessado neste material, convido voc\u00ea a aproveit\u00e1-lo. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Fui professor, docente, antes de come\u00e7ar a trabalhar com Postgres. E estou muito feliz por agora poder compartilhar com voc\u00eas o que estou prestes a apresentar. Esta \u00e9 uma das minhas apresenta\u00e7\u00f5es mais interessantes. E esta apresenta\u00e7\u00e3o cont\u00e9m 110 slides. Come\u00e7aremos com coisas simples, mas ao final, a apresenta\u00e7\u00e3o se tornar\u00e1 progressivamente mais complexa.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/9c2e95851f3d8dc92d2ca40b5f29cd52.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Esta \u00e9 uma conversa bastante inc\u00f4moda. A quest\u00e3o da bloqueio n\u00e3o \u00e9 o t\u00f3pico mais popular. Queremos que ela desapare\u00e7a. \u00c9 como ir ao dentista. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/bbb2bf8495d458c5bc4a162880a807bb.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ol>\n<li>O bloqueio \u00e9 um problema para muitas pessoas que trabalham com bancos de dados e t\u00eam v\u00e1rios processos em execu\u00e7\u00e3o ao mesmo tempo. Eles precisam de bloqueios. Ou seja, hoje eu vou fornecer a voc\u00eas conhecimentos b\u00e1sicos sobre bloqueios. <\/li>\n<li>Identificadores de transa\u00e7\u00f5es. Esta \u00e9 uma parte bastante chata da apresenta\u00e7\u00e3o, mas \u00e9 essencial entend\u00ea-la.<\/li>\n<li>Em seguida, vamos discutir os tipos de bloqueio. Esta \u00e9 uma parte bastante mec\u00e2nica. <\/li>\n<li>E em seguida, vamos dar alguns exemplos de bloqueios. E isso vai ser bastante desafiador de entender. <\/li>\n<\/ol>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7261d9ed162b7f582ec91d6aa98fac01.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vamos falar sobre bloqueios.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/13664632ed5ce42ea3ae20830117931e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A terminologia que usamos \u00e9 bastante complexa. Quantos de voc\u00eas sabem de onde vem este trecho? Duas pessoas. \u00c9 de um jogo chamado \"Aventura Colossal na Caverna\". Era um jogo de computador baseado em texto dos anos 80, pelo que me lembro. Voc\u00ea tinha que entrar na caverna, em um labirinto, e o texto mudava, mas o conte\u00fado era mais ou menos o mesmo a cada vez. \u00c9 assim que eu me lembro desse jogo. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/8e8b88cb4d3fabc9d60bacb771a6ea38.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E aqui vemos os nomes dos bloqueios que vieram at\u00e9 n\u00f3s da Oracle. N\u00f3s os usamos. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/37941629c5bde0c387fcd34565e99a9e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aqui vemos termos que me confundem. Por exemplo, SHARE UPDATE EXCLUSIVE. Em seguida, SHARE RAW EXCLUSIVE. Honestamente, esses nomes n\u00e3o s\u00e3o muito claros. Tentaremos analis\u00e1-los com mais profundidade. Alguns cont\u00eam a palavra \"share\", que significa \u2013 separar. Alguns cont\u00eam a palavra \"exclusive\" \u2013 exclusivo. Em alguns, essas duas palavras est\u00e3o presentes. Eu gostaria de come\u00e7ar com como esses bloqueios funcionam. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/dffa5b94dc39bd00b5abc1ef1db9c334.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E tamb\u00e9m \u00e9 muito importante a palavra \"acesso\" \u2014 access. E a palavra \"row\" \u2014 linha. Ou seja, distribui\u00e7\u00e3o de acesso, distribui\u00e7\u00e3o de linhas. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/1caf91a69510d21c74700bfdcf6f7f46.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Outro problema que precisamos entender no Postgres, infelizmente n\u00e3o poderei abordar em minha apresenta\u00e7\u00e3o, \u00e9 o MVCC. Tenho uma apresenta\u00e7\u00e3o separada sobre esse tema em meu site. E se voc\u00ea achar que esta apresenta\u00e7\u00e3o \u00e9 complexa, o MVCC \u00e9 provavelmente a mais complicada que tenho. E se voc\u00ea estiver interessado, pode assisti-la no site. Voc\u00ea pode ver o v\u00eddeo. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/cbaecfa1a74340ad497b080dfc577eb2.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Outro ponto que precisamos entender \u00e9 sobre identificadores de transa\u00e7\u00e3o. Muitas transa\u00e7\u00f5es n\u00e3o podem funcionar sem identificadores \u00fanicos. E aqui temos uma explica\u00e7\u00e3o do que \u00e9 uma transa\u00e7\u00e3o. No Postgres, existem dois sistemas de numera\u00e7\u00e3o de transa\u00e7\u00f5es. Eu sei, n\u00e3o \u00e9 uma solu\u00e7\u00e3o muito bonita. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/52d603a076ce0e74f39c00bdf6b06ef5.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Al\u00e9m disso, tenha em mente que os slides ser\u00e3o bastante complexos de entender, portanto, preste aten\u00e7\u00e3o ao que est\u00e1 destacado em vermelho, \u00e9 nisso que voc\u00ea deve focar.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/df937b924ec12772447269e01cdf7cf9.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/momjian.us\/main\/writings\/pgsql\/locking.sql\">http:\/\/momjian.us\/main\/writings\/pgsql\/locking.sql<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Vamos ver. O n\u00famero da transa\u00e7\u00e3o est\u00e1 destacado em vermelho. Aqui est\u00e1 mostrada a fun\u00e7\u00e3o SELECT pg_back. Ela retorna a minha transa\u00e7\u00e3o e o ID dessa transa\u00e7\u00e3o. <\/p>\n<p><\/p>\n<p>Mais um ponto, se voc\u00ea gostou desta apresenta\u00e7\u00e3o e deseja execut\u00e1-la em seu banco de dados, pode seguir este link destacado em rosa e baixar o SQL para esta apresenta\u00e7\u00e3o. E voc\u00ea pode simplesmente execut\u00e1-la no seu PSQL e toda a apresenta\u00e7\u00e3o aparecer\u00e1 na tela imediatamente. Ela n\u00e3o conter\u00e1 cores, mas pelo menos poderemos v\u00ea-la.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/aeaeecc16029e5fa54583223069578d1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Neste caso, vemos o ID da transa\u00e7\u00e3o. Este \u00e9 o n\u00famero que atribu\u00edmos a ela. E h\u00e1 outro tipo de ID de transa\u00e7\u00e3o no Postgres, que \u00e9 chamado de ID de transa\u00e7\u00e3o virtual.<\/p>\n<p><\/p>\n<p>E precisamos entender isso. \u00c9 muito importante, caso contr\u00e1rio n\u00e3o conseguiremos compreender o bloqueio no Postgres.<\/p>\n<p><\/p>\n<p>O ID de transa\u00e7\u00e3o virtual \u00e9 um ID de transa\u00e7\u00e3o que n\u00e3o cont\u00e9m valores permanentes. Por exemplo, se eu executar um comando SELECT, provavelmente n\u00e3o vou mudar o banco de dados, n\u00e3o vou bloquear nada. Portanto, quando executamos um simples SELECT, n\u00e3o atribu\u00edmos um ID permanente a essa transa\u00e7\u00e3o. Damos apenas um ID virtual.<\/p>\n<p><\/p>\n<p>E isso aumenta o desempenho do Postgres, melhora as capacidades de limpeza, por isso o ID da transa\u00e7\u00e3o virtual consiste em dois n\u00fameros. O primeiro n\u00famero antes da barra \u00e9 o ID do backend. E \u00e0 direita vemos apenas um contador.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/8813ab1f15f71ce4fbb5448bde2cfba6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Portanto, se eu executar uma consulta, ela diz que o ID do backend \u00e9 2. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/b6f4e3a2ad8d6801af2716b0bd3bf75a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se eu executar uma s\u00e9rie dessas transa\u00e7\u00f5es, veremos que o contador aumenta a cada vez que eu executo uma consulta. Por exemplo, quando eu executo a consulta 2\/10, 2\/11, 2\/12, etc. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/0b5fbb897233ff3dd07b807af4d4e0d7.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tenha em mente que aqui existem duas colunas. \u00c0 esquerda, vemos o ID virtual da transa\u00e7\u00e3o \u2013 2\/12. E \u00e0 direita, temos o ID permanente da transa\u00e7\u00e3o. E este campo est\u00e1 vazio. E essa transa\u00e7\u00e3o n\u00e3o modifica o banco de dados. Portanto, n\u00e3o atribuo a ela um ID permanente de transa\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/e8ab3dc34ce6036eedfb87e56f41d01a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Assim que eu executo o comando analisar (ANALYZE), a mesma consulta me d\u00e1 um ID permanente de transa\u00e7\u00e3o. Veja como isso mudou. Antes eu n\u00e3o tinha esse ID, agora ele apareceu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ca546a3006bfc0881ef1c7e7fe878c7a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ent\u00e3o, aqui est\u00e1 mais uma consulta, mais uma transa\u00e7\u00e3o. O n\u00famero virtual da transa\u00e7\u00e3o \u00e9 2\/13. E se eu solicitar o ID permanente da transa\u00e7\u00e3o, quando eu executar a consulta, eu o obterei. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/69bf4082be1832504a823f6420d62609.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ent\u00e3o, mais uma vez. Temos o ID virtual da transa\u00e7\u00e3o e o ID permanente da transa\u00e7\u00e3o. Apenas entenda este ponto para compreender o comportamento do Postgres.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ecc70c44ceee36dab9c98bcfcebf4c8f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Estamos indo para a terceira se\u00e7\u00e3o. Aqui, vamos passar rapidamente por diferentes tipos de bloqueios no Postgres. Isso n\u00e3o \u00e9 muito interessante. A \u00faltima se\u00e7\u00e3o ser\u00e1 muito mais interessante. Mas devemos considerar as coisas b\u00e1sicas, porque sen\u00e3o n\u00e3o entenderemos o que vir\u00e1 a seguir. <\/p>\n<p><\/p>\n<p>Vamos passar por esta se\u00e7\u00e3o, onde analisaremos cada tipo de bloqueio. E eu vou te mostrar exemplos de como eles s\u00e3o definidos, como funcionam, e vou mostrar algumas consultas que voc\u00ea pode usar para ver como os bloqueios operam no Postgres.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/2074b6c82ff77525090c868d0c9f09f5.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Para criar uma consulta e ver o que est\u00e1 acontecendo no Postgres, precisamos executar uma consulta na visualiza\u00e7\u00e3o do sistema. Neste caso, temos o pg_lock destacado em vermelho. Pg_lock \u00e9 uma tabela do sistema que nos informa quais bloqueios est\u00e3o atualmente em uso no Postgres.<\/p>\n<p><\/p>\n<p>No entanto, \u00e9 muito dif\u00edcil para mim mostrar o pg_lock por si s\u00f3, porque \u00e9 bastante complicado. Por isso, criei uma visualiza\u00e7\u00e3o que mostra o pg_locks. E ela tamb\u00e9m realiza um trabalho para mim, o que me permite entender melhor. Ou seja, ela exclui meus bloqueios, minha pr\u00f3pria sess\u00e3o, etc. \u00c9 apenas SQL padr\u00e3o e me permite mostrar melhor o que est\u00e1 acontecendo. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/8372fff8ded76ace47591850b74db860.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Outro problema \u00e9 que essa visualiza\u00e7\u00e3o \u00e9 muito ampla, ent\u00e3o eu preciso criar uma segunda \u2013 lockview2.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/559745d390f99d7d28199be76d3abc18.png\" style=\"display:block;margin: 0 auto;\" \/> E ela me mostra mais colunas da tabela. E outra, que me mostra as outras colunas. \u00c9 bastante complicado, ent\u00e3o eu procurei apresent\u00e1-lo da forma mais simples poss\u00edvel. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/48d69895241e1f58ac5ef0e385a67644.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ent\u00e3o, criamos uma tabela chamada Lockdemo. E criamos uma linha nela. Esta \u00e9 a nossa tabela de exemplo. E n\u00f3s vamos criar se\u00e7\u00f5es apenas para te mostrar exemplos de bloqueios. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/2c5a64d5488c1eef7def91a5e0657519.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ent\u00e3o, uma linha, uma coluna. O primeiro tipo de bloqueio \u00e9 chamado de ACCESS SHARE. Este \u00e9 o bloqueio menos restritivo. Isso significa que ele praticamente n\u00e3o entra em conflito com os outros bloqueios.<\/p>\n<p><\/p>\n<p>E se quisermos definir explicitamente o bloqueio, executamos o comando \"lock table\". E ele bloquear\u00e1 explicitamente, ou seja, em modo ACCESS SHARE, executamos lock table. E se eu rodar o PSQL em segundo plano, dessa forma, eu estou iniciando uma segunda sess\u00e3o da minha primeira sess\u00e3o. Ou seja, o que eu farei aqui? Eu mudo para outra sess\u00e3o e digo a ela \"mostre-me o lockview para esta consulta\". E aqui eu tenho AccessShareLock nesta tabela. \u00c9 exatamente isso que eu pedi. E ele diz que o bloqueio foi concedido. Muito simples. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/458adfcb7fb0de3f4b23bc703a78534e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Em seguida, se olharmos para a segunda coluna, n\u00e3o h\u00e1 nada l\u00e1. Elas est\u00e3o vazias. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/f3b848f3c9bfaf1a41273effeb0965e1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se eu executar o comando \"SELECT\", \u00e9 uma forma impl\u00edcita (expl\u00edcita) de solicitar AccessShareLock. Portanto, eu libero minha tabela e executo a consulta, e a consulta retorna v\u00e1rias linhas. E em uma das linhas, vemos AccessShareLock. Portanto, SELECT chama AccessShareLock na tabela. E ele praticamente n\u00e3o entra em conflito com nada, porque \u00e9 um bloqueio de baixo n\u00edvel. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/0d9526dbea91b5e5f4e0e05a20b16d38.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se eu executar SELECT e tiver tr\u00eas tabelas diferentes? Anteriormente eu executava apenas uma tabela, agora estou gerando tr\u00eas: pg_class, pg_namespace e pg_attribute.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/415be5bb7cb7cbbe6bbfd0ab1b9b2d3e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E agora, quando olho para a consulta, vejo 9 AccessShareLocks nas tr\u00eas tabelas. Por qu\u00ea? Em azul est\u00e3o destacadas as tr\u00eas tabelas: pg_attribute, pg_class, pg_namespace. Mas voc\u00ea tamb\u00e9m pode ver que todos os \u00edndices definidos nessas tabelas tamb\u00e9m t\u00eam AccessShareLock.<\/p>\n<p><\/p>\n<p>E esse \u00e9 um bloqueio que praticamente n\u00e3o conflita com os outros. E tudo o que ele faz \u00e9 simplesmente n\u00e3o nos permitir liberar a tabela enquanto estamos a selecionando. Isso faz sentido. Ou seja, se estamos selecionando uma tabela, ela naquele momento desaparece, isso \u00e9 incorreto, portanto <strong>AccessShare \u00e9 um bloqueio de baixo n\u00edvel que nos diz \"n\u00e3o exclua esta tabela enquanto eu estiver trabalhando\".<\/strong>. Essencialmente, \u00e9 tudo o que ele faz. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/99c896a5a57f7d64077fad9368f9b41a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>ROW SHARE \u00e9 um bloqueio um pouco diferente. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/bbd833128a83fba3b7271f89e6115425.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vamos pegar um exemplo. <strong>SELECT ROW SHARE \u00e9 uma forma de bloquear cada linha individualmente.<\/strong>. Assim, ningu\u00e9m pode exclu\u00ed-las ou alter\u00e1-las enquanto as estamos visualizando. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7f7384d5c4c04ffc771192359d785c43.png\" style=\"display:block;margin: 0 auto;\" \/>Ent\u00e3o, o que faz o SHARE LOCK? Vemos que o ID da transa\u00e7\u00e3o \u00e9 681 para o SELECT. E isso \u00e9 interessante. O que aconteceu aqui? Pela primeira vez, vemos um n\u00famero no campo \"Lock\". Pegamos o ID da transa\u00e7\u00e3o, e ele diz que bloqueia-a em modo exclusivo. Tudo o que ele faz \u00e9 afirmar que h\u00e1 uma linha que est\u00e1 tecnicamente bloqueada em algum lugar da tabela. Mas n\u00e3o diz onde exatamente. Mais adiante, veremos isso com mais detalhes.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/284a303fd34c167d453facb46e207067.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aqui, estamos dizendo que o bloqueio \u00e9 usado por n\u00f3s.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/12a2be61a2f406fc125dcab11983e9c6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Portanto, o bloqueio exclusivo diz explicitamente que \u00e9 exclusivo. E tamb\u00e9m, se voc\u00ea excluir uma linha nessa tabela, isso realmente acontecer\u00e1, como voc\u00ea pode ver. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/23ed127ff4a033a6f51c0b5566fd6a7c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>SHARE EXCLUSIVE \u2013 esse \u00e9 um bloqueio mais longo.<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/12e6b0217c528ef5034eb328553fefe9.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Este (ANALYZE) \u00e9 um comando do analisador que ser\u00e1 utilizado.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/d11480b90b74c8165a60bd73cf24a683.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>SHARE LOCK \u2013 voc\u00ea pode explicitamente bloquear em modo share.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ee2a5ad8d0da5fb94865abe3cfa70fa7.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Voc\u00ea tamb\u00e9m pode criar um \u00edndice \u00fanico. E l\u00e1 voc\u00ea pode ver o SHARE LOCK, que faz parte dele. E ele bloqueia a tabela e aplica um bloqueio SHARE LOCK sobre ela.<\/p>\n<p><\/p>\n<p><strong>Por padr\u00e3o, o SHARE LOCK na tabela significa que outras pessoas podem ler a tabela, mas ningu\u00e9m pode modific\u00e1-la. E \u00e9 isso que acontece quando voc\u00ea cria um \u00edndice \u00fanico.<\/strong><\/p>\n<p><\/p>\n<p>Se eu criar um \u00edndice \u00fanico concurrently, ent\u00e3o terei um tipo diferente de bloqueio, porque, como voc\u00ea lembra, o uso de \u00edndices concurrently reduz a necessidade de bloqueio. E se eu usar um bloqueio normal, um \u00edndice normal, ent\u00e3o assim impedirei a grava\u00e7\u00e3o no \u00edndice da tabela durante sua cria\u00e7\u00e3o. Se eu usar um \u00edndice concurrently, preciso usar um tipo diferente de bloqueio. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5952ba48cda26f907d0d9265a933e880.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>SHARE ROW EXCLUSIVE \u2013 novamente, pode ser definido explicitamente.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5d780961d3a2e6aa0f82287fb4822782.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ou podemos criar uma regra, ou seja, pegar algum caso espec\u00edfico em que ele ser\u00e1 utilizado.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7b0f44c4b44426a8dd7999387b245783.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>O bloqueio EXCLUSIVE significa que ningu\u00e9m mais poder\u00e1 alterar a tabela. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/0b59c38455eb973a10be32c2cae0d2aa.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aqui vemos diferentes tipos de bloqueios. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5ec2fc9ae765dfa28285b9f025212056.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>ACCESS EXCLUSIVE, por exemplo, \u00e9 um comando de bloqueio. Por exemplo, se voc\u00ea fizer <code>CLUSTER table<\/code>, isso significar\u00e1 que ningu\u00e9m poder\u00e1 gravar l\u00e1. E ele bloqueia n\u00e3o apenas a pr\u00f3pria tabela, mas tamb\u00e9m os \u00edndices.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/9290594355c0b8cef5a07be3a94f6c24.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Esta \u00e9 a segunda p\u00e1gina do bloqueio ACCESS EXCLUSIVE, onde vemos especificamente o que ele bloqueia na tabela. Ele bloqueia linhas individuais da tabela, o que \u00e9 bastante interessante.<\/p>\n<p><\/p>\n<p>Esta \u00e9 toda a informa\u00e7\u00e3o b\u00e1sica que eu queria fornecer. Falamos sobre bloqueios, sobre IDs de transa\u00e7\u00e3o, discutimos IDs virtuais de transa\u00e7\u00e3o, e IDs permanentes de transa\u00e7\u00e3o. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/b9bc44aa88e6760c11a7d0fe247b4b33.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Agora vamos passar para exemplos de bloqueios. Esta \u00e9 a parte mais interessante. Vamos ver casos muito interessantes. E meu objetivo nesta apresenta\u00e7\u00e3o \u00e9 dar a voc\u00eas uma melhor compreens\u00e3o do que o Postgres realmente faz quando tenta bloquear certas coisas. Acredito que ele \u00e9 muito eficiente em bloquear partes espec\u00edficas. <\/p>\n<p><\/p>\n<p>Vamos considerar alguns exemplos espec\u00edficos.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/566ecc5ef289e8fdfa5a96bd8b3daa80.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Come\u00e7aremos com tabelas e com uma linha na tabela. Quando eu insiro algo, ele mostra ExclusiveLock, o ID da transa\u00e7\u00e3o e o ExclusiveLock na tabela. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/840b23a8b942211c93e233006fd3fe4b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E o que acontece se eu inserir mais duas linhas? Agora temos tr\u00eas linhas na nossa tabela. Eu inseri uma linha e obtive isso como sa\u00edda. E se eu inserir mais duas linhas, o que h\u00e1 de estranho aqui? A estranheza est\u00e1 em que eu adicionei tr\u00eas linhas a esta tabela, mas ainda tenho duas linhas na tabela de bloqueios. E isso \u00e9, essencialmente, o comportamento fundamental do Postgres.<\/p>\n<p><\/p>\n<p>Muitos pensam que se bloquearem 100 linhas em um banco de dados, precisar\u00e3o criar 100 entradas de bloqueio. Se eu bloquear 1.000 linhas de uma s\u00f3 vez, ent\u00e3o precisarei de 1.000 dessas solicita\u00e7\u00f5es. E se eu precisar bloquear um milh\u00e3o ou um bilh\u00e3o. Mas se for assim que fizermos, n\u00e3o funcionar\u00e1 muito bem. Se voc\u00ea usou um sistema que cria entradas de bloqueio para cada linha individual, ver\u00e1 que isso \u00e9 complicado. Porque voc\u00ea precisa definir a tabela de bloqueio imediatamente, que pode se sobrecarregar, mas o Postgres n\u00e3o faz dessa forma. <\/p>\n<p><\/p>\n<p>E neste slide \u00e9 muito importante que aqui est\u00e1 claramente demonstrado que existe outro sistema que opera dentro do MVCC, que bloqueia linhas individuais. Portanto, quando voc\u00ea bloqueia bilh\u00f5es de linhas, o Postgres n\u00e3o cria bilh\u00f5es de comandos de bloqueio individuais. E isso tem um efeito muito positivo no desempenho. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/09ee01fffbb9bd00c84f2ebce51458cc.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E quanto \u00e0 atualiza\u00e7\u00e3o? Estou atualizando uma linha agora, e voc\u00ea pode notar que ele imediatamente executou duas opera\u00e7\u00f5es diferentes. Ele bloqueou a tabela ao mesmo tempo, mas tamb\u00e9m bloqueou o \u00edndice. E ele precisava bloquear o \u00edndice porque h\u00e1 restri\u00e7\u00f5es \u00fanicas nessa tabela. Queremos garantir que ningu\u00e9m a modifique, ent\u00e3o a bloqueamos.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/3e72d68af2d5ae3cc062b6e8b6da343b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se eu quiser atualizar duas linhas? E vemos que ele se comporta da mesma forma. Estamos realizando o dobro de atualiza\u00e7\u00f5es, mas exatamente a mesma quantidade de linhas bloqueadas. <\/p>\n<p><\/p>\n<p>Se voc\u00ea est\u00e1 curioso sobre como o Postgres faz isso, voc\u00ea precisa ouvir minhas palestras sobre MVCC para entender como o Postgres marca internamente essas linhas que ele modifica. E o Postgres tem uma maneira de fazer isso, mas n\u00e3o o faz no n\u00edvel de bloqueio de tabelas; ele faz em um n\u00edvel mais baixo e mais eficiente.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7e119822b0fb7c5aa3c4a463841bc8e1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se eu quiser remover algo? Se eu remover, por exemplo, uma linha e ainda tiver meus dois pontos de entrada de bloqueio, mesmo que eu queira remov\u00ea-los todos, eles ainda estar\u00e3o presentes.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/c329f9fbc478a25396ea04102715973e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E, por exemplo, se eu quiser inserir 1.000 linhas e depois ou remover ou adicionar 1.000 linhas, ent\u00e3o as linhas individuais que estou adicionando ou modificando n\u00e3o s\u00e3o registradas aqui. Elas s\u00e3o registradas em um n\u00edvel mais baixo dentro da pr\u00f3pria linha. E durante a palestra sobre MVCC eu falei sobre isso em detalhes. Mas \u00e9 muito importante, ao analisar bloqueios, garantir que voc\u00ea tenha um bloqueio no n\u00edvel da tabela e que aqui voc\u00ea n\u00e3o veja como as grava\u00e7\u00f5es de linhas individuais est\u00e3o sendo feitas. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5683ca83f5c17da7928fae96c307c2d6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E quanto ao bloqueio expl\u00edcito?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/a1746f121884c898c91e3b5d2ef517b8.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Se eu clicar em \"atualizar\", tenho duas linhas bloqueadas. E se eu selecion\u00e1-las todas e clicar em \"atualizar tudo\", ainda assim restar\u00e3o duas grava\u00e7\u00f5es de bloqueio. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5d5388e5d0aff39042a9cd69edc91eea.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>N\u00e3o criamos registros separados para cada linha individual. Porque ent\u00e3o a performance despenca, pode haver muitos deles. E podemos nos encontrar em uma situa\u00e7\u00e3o complicada. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/54e88ed51e705701a8b3ddaa4a784d75.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E o mesmo ocorre se fizermos shared; podemos fazer isso para as 30 vezes. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ab9c26e9be090d85b09070ec5ba0d64d.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Estamos restaurando nossa tabela, removendo tudo e depois inserindo novamente uma linha.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/2d0a5b75f5cd08dca97b61bbae6a6cbd.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Outro tipo de comportamento que voc\u00ea v\u00ea no Postgres \u00e9 um comportamento muito bem conhecido e desejado - voc\u00ea pode realizar updates ou selects. E voc\u00ea pode fazer isso simultaneamente. E os selects n\u00e3o bloqueiam os updates e vice-versa. Estamos dizendo ao leitor para n\u00e3o bloquear quem escreve, e quem escreve n\u00e3o bloquear o leitor. <\/p>\n<p><\/p>\n<p>Vou lhe mostrar um exemplo disso. Vou fazer uma sele\u00e7\u00e3o agora. Depois faremos um INSERT. E voc\u00ea poder\u00e1 ver - 694. Voc\u00ea ver\u00e1 o ID da transa\u00e7\u00e3o que fez essa inser\u00e7\u00e3o. E \u00e9 assim que funciona. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/f80f3b68ef43a75a9590ff200741ce83.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se agora eu olhar para o meu ID de backend, ele mudou para - 695. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/65bc487bbfd7b325aa5cffa7373a40a4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E posso ver que 695 aparece na minha tabela. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/6ac586641f978615db4d021e85ef702a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se eu realizar uma atualiza\u00e7\u00e3o aqui assim, ent\u00e3o eu obtenho outro caso. Nesse caso, 695 \u00e9 um bloqueio exclusivo, e o update tem um comportamento semelhante, mas n\u00e3o h\u00e1 conflito entre eles, o que \u00e9 bastante incomum. <\/p>\n<p><\/p>\n<p>E voc\u00ea pode notar que na parte de cima est\u00e1 o ShareLock, e na parte de baixo est\u00e1 o ExclusiveLock. E ambas as transa\u00e7\u00f5es foram conclu\u00eddas.<\/p>\n<p><\/p>\n<p>E voc\u00ea precisa ouvir minha apresenta\u00e7\u00e3o sobre MVCC para entender como isso acontece. Mas essa \u00e9 uma ilustra\u00e7\u00e3o do que voc\u00ea pode fazer ao mesmo tempo, ou seja, fazer SELECT e UPDATE simultaneamente.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/3bcf43cdb9ee72ea75e17c3bf71f3407.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vamos reiniciar e fazer mais uma opera\u00e7\u00e3o. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/fdae265dbebb0fae66e47cd4eb4b1bd6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Se voc\u00ea tentar executar simultaneamente dois updates na mesma linha, ocorrer\u00e1 um bloqueio. E lembre-se, eu disse que o leitor n\u00e3o bloqueia o escritor, e o escritor bloqueia o leitor, mas um escritor bloqueia outro escritor. Ou seja, n\u00e3o podemos permitir que duas pessoas atualizem a mesma linha ao mesmo tempo. \u00c9 necess\u00e1rio esperar que um deles termine. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ef9adfe81107468dfea1c5a837b28aaa.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E para ilustrar isso, vou olhar para a tabela Lockdemo. E vamos ver uma linha. Na transa\u00e7\u00e3o 698.<\/p>\n<p><\/p>\n<p>N\u00f3s a atualizamos para 2. 699 \u00e9 a primeira atualiza\u00e7\u00e3o. E ela foi bem-sucedida ou est\u00e1 em uma transa\u00e7\u00e3o pendente, aguardando que confirmemos ou cancelamos. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/9794811cdc204141a74f67ee98fca1f6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mas olhem para o outro \u2013 2\/51 \u2013 esta \u00e9 nossa primeira transa\u00e7\u00e3o, nossa primeira sess\u00e3o. 3\/112 \u2013 esta \u00e9 a segunda solicita\u00e7\u00e3o que apareceu por cima e que mudou esse valor para 3. E se voc\u00ea notar, o primeiro bloqueou a si mesmo, que \u00e9 699. Mas 3\/112 n\u00e3o forneceu bloqueio. Na coluna Lock_mode, est\u00e1 escrito que ele est\u00e1 aguardando. Ele est\u00e1 aguardando 699. E se voc\u00ea olhar onde est\u00e1 699, est\u00e1 acima. E o que a primeira sess\u00e3o fez? Criou um bloqueio exclusivo em seu pr\u00f3prio ID de transa\u00e7\u00e3o. \u00c9 assim que o Postgres faz. Ele bloqueia seu pr\u00f3prio ID de transa\u00e7\u00e3o. E se voc\u00ea quiser esperar at\u00e9 que algu\u00e9m confirme ou cancele, voc\u00ea precisa esperar at\u00e9 que haja uma transa\u00e7\u00e3o em espera. E por isso podemos ver uma linha estranha. <\/p>\n<p><\/p>\n<p>Vamos dar mais uma olhada. \u00c0 esquerda, vemos nosso ID de processamento. Na segunda coluna, vemos nosso ID de transa\u00e7\u00e3o virtual, e na terceira vemos o lock_type. O que isso significa? Essencialmente, ele diz que bloqueia o ID de transa\u00e7\u00e3o. Mas observe que em todas as linhas abaixo est\u00e1 escrito relation. E por isso voc\u00ea tem dois tipos de bloqueio na tabela. H\u00e1 o bloqueio relation. E tamb\u00e9m h\u00e1 o bloqueio transactionid, onde voc\u00ea bloqueia a si mesmo, \u00e9 exatamente isso que acontece na primeira linha ou na parte inferior, onde transationid, onde estamos aguardando que 699 finalize sua opera\u00e7\u00e3o. <\/p>\n<p><\/p>\n<p>Estou observando o que est\u00e1 acontecendo aqui. E aqui ocorrem duas coisas ao mesmo tempo. Voc\u00ea est\u00e1 olhando para o bloqueio pelo ID de transa\u00e7\u00e3o na primeira linha, que se bloqueia. E ele se bloqueia para fazer as pessoas aguardarem. <\/p>\n<p><\/p>\n<p>Se voc\u00ea olhar a 6\u00aa linha, ver\u00e1 que o mesmo registro da primeira. E por isso a transa\u00e7\u00e3o 699 est\u00e1 bloqueada. 700 tamb\u00e9m se bloqueia. E depois na linha inferior voc\u00ea ver\u00e1 que estamos esperando que 699 finalize sua opera\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/e712a48cdb9ddc496e4e196eb3bb97c3.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E no lock_type, tuple voc\u00ea v\u00ea os n\u00fameros. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/575245898d8455f00583659264b96ce9.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Voc\u00ea pode ver que \u00e9 0\/10. E este \u00e9 o n\u00famero da p\u00e1gina, e tamb\u00e9m o offset dessa linha espec\u00edfica. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7059c7661fc81a7101b2d92d38b6f64c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E voc\u00ea v\u00ea que se torna 0\/11 quando atualizamos. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/4572ef7afc0ba8c8bbf5706ce9415d65.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mas na verdade \u2013 \u00e9 0\/10, porque ocorre a espera dessa opera\u00e7\u00e3o. Temos a oportunidade de ver que esta \u00e9 a linha que estou aguardando para confirmar. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/9dc6fb0e3dee8c0b1ccbb724d0bb6c75.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Assim que o confirmamos e pressionamos 'commit', e quando a atualiza\u00e7\u00e3o terminou, isso \u00e9 o que recebemos novamente. A transa\u00e7\u00e3o 700 \u00e9 o \u00fanico bloqueio, n\u00e3o est\u00e1 esperando mais ningu\u00e9m, pois foi comitada. Ela apenas aguarda a conclus\u00e3o da transa\u00e7\u00e3o. Assim que a 699 termina, n\u00e3o esperamos mais nada. E agora a transa\u00e7\u00e3o 700 diz que est\u00e1 tudo bem, que todos os bloqueios necess\u00e1rios est\u00e3o em todas as tabelas permitidas. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/42bc10a0c5bbda9bcf3a40f0dd87bc6b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E para complicar ainda mais, criamos outra view, que desta vez nos fornecer\u00e1 uma hierarquia. N\u00e3o espero que voc\u00ea entenda essa consulta. Mas isso nos dar\u00e1 uma vis\u00e3o mais clara do que est\u00e1 acontecendo. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/855f6dd22cba114b051e4eaac106c0ea.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Esta \u00e9 uma view recursiva, que tamb\u00e9m tem outra se\u00e7\u00e3o. E depois, isso retorna tudo junto. Vamos usar isso. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/fdb54fae54fb87131c13d67a2f66fae2.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se fizermos tr\u00eas atualiza\u00e7\u00f5es simult\u00e2neas e dissermos que a fila agora \u00e9 igual a tr\u00eas. E mudarmos 3 para 4. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/f28e0d58e223ef9ccca9ba0acab5b0ce.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E aqui vemos 4. E o ID da transa\u00e7\u00e3o 702. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/49553b4dc4bb4c07db099fd26a6da22c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E ent\u00e3o eu mudo 4 para 5. E 5 para 6, e 6 para 7. E eu coloco em fila as pessoas que estar\u00e3o esperando que essa \u00fanica transa\u00e7\u00e3o termine.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7f4a4fef1745ad9cdcd602aa0474f6ec.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E tudo se torna claro. Qual \u00e9 a primeira fila? \u00c9 702. Este \u00e9 o ID da transa\u00e7\u00e3o que inicialmente definiu esse valor. E o que est\u00e1 escrito na coluna Granted? Eu tenho marca\u00e7\u00f5es <code>f<\/code>. Essas s\u00e3o minhas atualiza\u00e7\u00f5es, que (5, 6, 7) n\u00e3o podem ser aprovadas, porque estamos esperando que a transa\u00e7\u00e3o ID 702 termine. Temos um bloqueio do ID da transa\u00e7\u00e3o. E resulta em 5 bloqueios de transa\u00e7\u00e3o ID.<\/p>\n<p><\/p>\n<p>E se voc\u00ea olhar para 704, para 705, ainda n\u00e3o foi escrito nada, porque eles ainda n\u00e3o sabem o que est\u00e1 acontecendo. Eles apenas escrevem que n\u00e3o t\u00eam ideia do que est\u00e1 acontecendo. E eles simplesmente entrar\u00e3o em modo de espera, porque est\u00e3o esperando que algu\u00e9m termine e os acorde quando houver a oportunidade de mudar a fila. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/af97313e395a47e43d5ca9e6c78271af.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00c9 assim que parece. Fica claro que todos est\u00e3o esperando pela 12\u00aa linha. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/611f2d09dfbf78abe6659f794d4ad4f6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00c9 isso que vimos aqui. Aqui est\u00e1 0\/12. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/738d1d9b272c6ef2f6e8dffd9cd9c061.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ent\u00e3o, assim que a primeira transa\u00e7\u00e3o \u00e9 aprovada, voc\u00ea pode ver aqui como a hierarquia funciona. E agora tudo se torna claro. Eles todos ficam livres. E na verdade, ainda est\u00e3o esperando. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7f53df10dd5de8776a07094e68acd195.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aqui est\u00e1 o que acontece. O 702 faz o commit. E agora o 703 recebe esse bloqueio da linha, e ent\u00e3o o 704 come\u00e7a a esperar que o 703 fa\u00e7a o commit. E o 705 tamb\u00e9m est\u00e1 esperando por isso. E quando tudo isso termina, eles se limpam. E eu gostaria de apontar que todos se alineam em uma fila. E isso \u00e9 muito parecido com uma situa\u00e7\u00e3o de engarrafamento, onde todos est\u00e3o esperando o primeiro carro. O primeiro carro parou, e todos se alinham em uma longa linha. Ent\u00e3o ele se move, depois o pr\u00f3ximo carro pode passar \u00e0 frente e receber seu bloqueio e assim por diante. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/44d6e80e90fbaa3c726bec204ee10f1b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se voc\u00ea achar que isso \u00e9 complicado o suficiente, agora vamos falar sobre deadlocks. Eu n\u00e3o sei quem de voc\u00eas j\u00e1 se deparou com isso. \u00c9 um problema bastante comum em sistemas de banco de dados. Mas deadlocks s\u00e3o aqueles casos em que uma sess\u00e3o espera que outra sess\u00e3o execute algo. E, nesse momento, a outra sess\u00e3o espera que a primeira sess\u00e3o execute alguma coisa. <\/p>\n<p><\/p>\n<p>E, por exemplo, se Ivan diz: \"Me d\u00e1 algo\", e eu digo: \"N\u00e3o, eu te dou isso apenas se voc\u00ea me der outra coisa\". E ele diz: \"N\u00e3o, eu n\u00e3o vou te dar isso se voc\u00ea n\u00e3o me der\". E n\u00f3s acabamos em uma situa\u00e7\u00e3o de deadlock. Eu tenho certeza de que Ivan n\u00e3o faria isso, mas voc\u00ea entende o sentido, que temos duas pessoas querendo algo e n\u00e3o est\u00e3o dispostas a dar isso at\u00e9 que a outra pessoa lhes d\u00ea o que querem. E n\u00e3o h\u00e1 solu\u00e7\u00e3o aqui. <\/p>\n<p><\/p>\n<p>E, essencialmente, seu banco de dados precisa identificar isso. E ent\u00e3o \u00e9 necess\u00e1rio eliminar ou encerrar uma das sess\u00f5es, porque caso contr\u00e1rio, elas permanecer\u00e3o l\u00e1 para sempre. E vemos isso em bancos de dados, vemos isso em sistemas operacionais. E em todos os lugares onde temos processos paralelos, isso pode acontecer. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/6acee6bc304593cdd9e411882b5e3406.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E agora vamos definir dois deadlocks. Vamos colocar 50 e 80. Na primeira linha, farei uma atualiza\u00e7\u00e3o de 50 para 50. Vou receber o n\u00famero da transa\u00e7\u00e3o 710. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/28a2a7fb4f91b8f8c6c78affb32d249c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E ent\u00e3o eu mudarei 80 para 81, e 50 para 51. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/f6653c36f5a09934035f4838ff0fa380.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E \u00e9 assim que isso vai parecer. Por isso, o 710 tem um bloqueio de linha, e o 711 aguarda a confirma\u00e7\u00e3o. Vimos isso quando atualizamos. O 710 \u00e9 o propriet\u00e1rio da nossa linha. E o 711 espera que o 710 conclua a transa\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/99718717ffb2024f4cb92509c2f2b878.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E est\u00e1 at\u00e9 escrito em qual linha estamos tendo deadlocks. E \u00e9 aqui que isso come\u00e7a a ficar estranho.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/423fc8973c29be1504d5bf8828beaa71.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Agora estamos atualizando 80 para 80. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/3a4b24e58f96205dbdfa8480fac2262a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E \u00e9 aqui que os deadlocks come\u00e7am. 710 est\u00e1 aguardando uma resposta de 711, enquanto 711 est\u00e1 aguardando 710. E isso n\u00e3o vai terminar bem. N\u00e3o h\u00e1 sa\u00edda para isso. Eles ficar\u00e3o aguardando a resposta um do outro. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/19394fa0b4a19991a4a4cc1e181c47e8.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E isso simplesmente come\u00e7ar\u00e1 a causar atrasos. E n\u00f3s n\u00e3o queremos isso. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/94c86723b8b42861d682c75f0c54b552.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E no Postgres existem formas de detectar quando isso acontece. E quando isso ocorre, voc\u00ea recebe um erro como este. E fica claro que um determinado processo est\u00e1 aguardando um SHARE LOCK de outro processo, ou seja, que est\u00e1 bloqueado pelo processo 711. E esse processo estava aguardando que um SHARE LOCK fosse concedido a um determinado ID de transa\u00e7\u00e3o e estava bloqueado por um determinado processo. Portanto, esta \u00e9 uma situa\u00e7\u00e3o de deadlock.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/88a499d8f03be3c9f5bc6c93aa39c9a6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E h\u00e1 deadlocks de tr\u00eas vias? Isso \u00e9 poss\u00edvel? Sim. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/20fae4c504b794b678d265a0b1e9e33d.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Inserimos esses n\u00fameros na tabela. Alteramos 40 para 40, fazemos o bloqueio. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/67b7302545781681b182d4f6ddc93d9f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Alteramos 60 para 61, 80 para 81. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/87aa9680b0160be0d798b2697a0f425d.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E ent\u00e3o mudamos 80, e ent\u00e3o \u2013 boom! <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/dc6179e048dfb42e1e11b75f956182c1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E 714 agora aguarda 715. O 716 aguarda o 715. E n\u00e3o h\u00e1 nada que se possa fazer com isso.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/e5e190437f420783f4fca26f4f04ecd3.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aqui n\u00e3o s\u00e3o apenas duas pessoas, s\u00e3o tr\u00eas. Eu quero algo de voc\u00ea, este quer algo do terceiro, e o terceiro quer algo de mim. E entramos em uma espera m\u00fatua, porque todos estamos esperando que a outra pessoa termine o que deve fazer. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/fde8e3cb14dc05c520693ca2a99cf5f1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E o Postgres sabe em qual linha isso acontece. E por isso, ele fornecer\u00e1 a voc\u00ea a seguinte mensagem, que mostra que voc\u00ea tem um problema onde tr\u00eas entradas est\u00e3o bloqueando umas \u00e0s outras. E aqui n\u00e3o h\u00e1 restri\u00e7\u00f5es. Isso pode ocorrer em uma situa\u00e7\u00e3o onde 20 registros est\u00e3o se bloqueando mutuamente. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/a3dde7b6092b3d2e93c4927b6b42d795.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>O pr\u00f3ximo problema \u00e9 o serializable. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/9bff965bafaa03a160c0787bfa8606fb.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Se houver um bloqueio serializable especial.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/db310da4461e647ed498e58b1e878fda.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E voltamos ao 719. Ele tem uma sa\u00edda perfeitamente normal. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/e7eca0a2191a62014ad949583a45bf2f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E voc\u00ea pode clicar para fazer a transa\u00e7\u00e3o a partir de serializable.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/4aa78f3e4d07b8ca48d860e8df2dacda.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E voc\u00ea percebe que agora tem outro tipo de bloqueio SA \u2013 isso significa serializable. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/f9e79b9b6b1cc581b2178b0285bd3213.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/603dc15cdda0a128c82e87275ca8ba85.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E por isso temos um novo tipo de bloqueio chamado SARieadLock, que \u00e9 um bloqueio serial e permite a inser\u00e7\u00e3o de serializa\u00e7\u00f5es.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ce2644b0e8d8b71035044c56a94621f4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E voc\u00ea tamb\u00e9m pode inserir \u00edndices \u00fanicos. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/053a37128688fe22040a2c5a3d5ad477.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nesta tabela, temos \u00edndices \u00fanicos.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/284e50ea2b0b64a9efda8b9224f466ae.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Portanto, se eu inserir o n\u00famero 2 aqui, eu terei 2. Mas na parte superior, insiro outro 2. E voc\u00ea pode ver que o 721 tem um bloqueio exclusivo. Mas agora 722 est\u00e1 aguardando que 721 conclua sua opera\u00e7\u00e3o, porque n\u00e3o pode inserir 2 at\u00e9 saber o que acontecer\u00e1 com 721. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ee01a45e1e16fe0ab10f5d172048f35f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se fizermos uma subtransa\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/58a67f29a50c5e90d3770492eb7a8fc4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aqui temos 723.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/6684b92639d48e62b6abf55bea86a951.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E se mantivermos o ponto e depois o atualizarmos, teremos um novo ID de transa\u00e7\u00e3o. Esse \u00e9 mais um comportamento que voc\u00ea precisa conhecer. Se retornarmos isso, o ID da transa\u00e7\u00e3o desaparece. 724 desaparece. Mas agora temos 725. <\/p>\n<p><\/p>\n<p>E o que estou tentando fazer aqui? Estou tentando mostrar exemplos de bloqueios incomuns que voc\u00ea pode encontrar: sejam bloqueios serializ\u00e1veis ou SAVEPOINT \u2013 s\u00e3o diferentes tipos de bloqueios que aparecer\u00e3o na tabela de bloqueios. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/3e0b5d4b4e84ca18e0e33cb46013cd70.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Isso \u00e9 a cria\u00e7\u00e3o de bloqueios expl\u00edcitos, onde temos pg_advisory_lock. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/2ce5ecd96cec5bcf0f757eb0093759c3.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E voc\u00ea v\u00ea que o tipo de bloqueio \u00e9 listado aqui como advisory. E est\u00e1 escrito em vermelho \"advisory\". E voc\u00ea pode bloquear simultaneamente com pg_advisory_unlock.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5b5ae66d50ce9aaa779bbf47de00b1d7.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E para finalizar, gostaria de mostrar mais uma coisa impressionante. Vou criar outro tipo. Mas vou unir a tabela pg_locks com a tabela pg_stat_activity. E por que quero fazer isso? Porque isso me permitir\u00e1 ver todas as sess\u00f5es atuais e quais bloqueios elas est\u00e3o esperando. E isso \u00e9 bastante interessante quando reunimos a tabela de bloqueios e a tabela de consultas. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/3949e48d9626a7a030b033dd05e7f042.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E aqui estamos criando pg_stat_view. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/2b3b7b34bb35f5a67ac5d4ed1328a910.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E estamos atualizando a linha em um. E aqui vemos 724. E ent\u00e3o atualizamos nossa linha para tr\u00eas. E o que voc\u00ea v\u00ea agora? S\u00e3o as consultas, ou seja, voc\u00ea v\u00ea toda a lista de consultas que est\u00e3o listadas na coluna da esquerda. E ent\u00e3o, no lado direito, voc\u00ea pode ver os bloqueios e o que eles criam. E isso pode ser mais claro para voc\u00ea, para que voc\u00ea n\u00e3o precise voltar a cada sess\u00e3o e ver se precisa se juntar ou n\u00e3o. Isso \u00e9 feito por n\u00f3s. <\/p>\n<p><\/p>\n<p>Outra fun\u00e7\u00e3o que \u00e9 muito \u00fatil \u00e9 <code>pg_blocking_pids<\/code>Voc\u00ea provavelmente nunca ouviu falar disso. O que ela faz? Ela nos permite dizer que, para esta sess\u00e3o 11740, quais IDs de processos ela est\u00e1 esperando. E voc\u00ea pode ver que 11740 est\u00e1 esperando 724. E 724 est\u00e1 no topo. E 11306 \u00e9 o seu ID de processo. Essencialmente, essa fun\u00e7\u00e3o percorre sua tabela de bloqueios. E eu sei que isso \u00e9 um pouco complicado, mas voc\u00ea consegue entender. Basicamente, essa fun\u00e7\u00e3o passa por essa tabela de bloqueios e tenta encontrar onde est\u00e1 esse ID de processo, considerando os bloqueios que ela est\u00e1 esperando. E tamb\u00e9m tenta calcular qual \u00e9 o ID do processo que est\u00e1 aguardando os bloqueios. Portanto, voc\u00ea pode executar essa fun\u00e7\u00e3o. <code>pg_blocking_pids<\/code>.<\/p>\n<p><\/p>\n<p>E isso pode ser muito \u00fatil. N\u00f3s adicionamos isso apenas na vers\u00e3o 9.6, ent\u00e3o essa fun\u00e7\u00e3o tem apenas 5 anos, mas \u00e9 muito e muito \u00fatil. E o mesmo se aplica \u00e0 segunda consulta. Ela mostra exatamente o que precisamos ver. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/d1975be02ba0cf516ba7bce400228e08.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00c9 sobre isso que eu queria conversar com voc\u00ea. E como eu esperava, usamos todo nosso tempo, porque havia uma grande quantidade de slides. E os slides est\u00e3o dispon\u00edveis para download. Eu gostaria de agradecer a voc\u00ea por estar aqui. Estou certo de que voc\u00ea vai gostar do restante da confer\u00eancia, muito obrigado!<\/p>\n<p><\/p>\n<p>Perguntas:<\/p>\n<p><\/p>\n<p><em>Por exemplo, se estou tentando atualizar linhas, e a segunda sess\u00e3o est\u00e1 tentando excluir toda a tabela. Pelo que eu entendo, deve haver algo como um intent lock. Existe isso no Postgres?<\/em><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ffe86d27f8bc467aeb3884320258d032.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Voltando ao come\u00e7o. Talvez voc\u00ea se lembre que quando voc\u00ea faz qualquer coisa, como um SELECT, emitimos um AccessShareLock. E isso impede a exclus\u00e3o da tabela. Portanto, se voc\u00ea, por exemplo, deseja atualizar uma linha na tabela ou excluir uma linha, algu\u00e9m n\u00e3o poder\u00e1 excluir toda a tabela ao mesmo tempo, porque voc\u00ea mant\u00e9m esse AccessShareLock sobre toda a tabela e sobre a linha. E assim que voc\u00ea terminar, eles podem exclu\u00ed-la. Mas enquanto voc\u00ea est\u00e1 mudando algo, n\u00e3o poder\u00e3o fazer isso.<\/p>\n<p><\/p>\n<p>Vamos l\u00e1 novamente. Vamos passar para o exemplo da exclus\u00e3o. E voc\u00ea v\u00ea como h\u00e1 um bloqueio exclusivo sobre toda a tabela na linha. <\/p>\n<p><\/p>\n<p><em>Isso parecer\u00e1 como um lock exclusive, certo?<\/em><\/p>\n<p><\/p>\n<p>Sim, isso parece com isso. Eu entendo do que voc\u00ea est\u00e1 falando. Voc\u00ea diz que, se eu executar um SELECT, terei um ShareExclusive, e depois eu o translado para um estado Row Exclusive, isso se torna um problema? Mas surpreendentemente, isso n\u00e3o gera problema. Isso parece um aumento no n\u00edvel de bloqueio, mas, essencialmente, eu tenho um lock que impede a exclus\u00e3o. E agora, quando eu torno esse lock mais forte, ele ainda impede a exclus\u00e3o. Portanto, n\u00e3o se trata de eu estar subindo. Ou seja, ele impedia isso mesmo quando estava em um n\u00edvel mais baixo, ent\u00e3o, quando aumento seu n\u00edvel, ele ainda impede a exclus\u00e3o da tabela. <\/p>\n<p><\/p>\n<p>Eu entendo do que voc\u00ea est\u00e1 falando. N\u00e3o h\u00e1 um caso de aumento no n\u00edvel de bloqueio aqui, onde voc\u00ea est\u00e1 tentando liberar um bloqueio para introduzir um mais forte. Aqui, \u00e9 apenas um aumento geral dessa preven\u00e7\u00e3o, portanto, isso n\u00e3o gera nenhum conflito. Mas \u00e9 uma boa pergunta. Muito obrigado por t\u00ea-la feito!<\/p>\n<p><\/p>\n<p><em>O que precisamos fazer para evitar a situa\u00e7\u00e3o de deadlock quando temos muitas sess\u00f5es, um grande n\u00famero de usu\u00e1rios?<\/em><\/p>\n<p><\/p>\n<p>O Postgres detecta automaticamente situa\u00e7\u00f5es de deadlock. E vai remover uma das sess\u00f5es automaticamente. A \u00fanica maneira de evitar a situa\u00e7\u00e3o de deadlocks \u00e9 bloquear as pessoas na mesma ordem. Portanto, quando voc\u00ea olhar para o seu aplicativo, muitas vezes a raz\u00e3o para deadlocks... Vamos imaginar que eu quero bloquear duas coisas diferentes. Um aplicativo bloqueia a tabela 1, e outro aplicativo bloqueia a tabela 2, e depois a tabela 1. E a maneira mais simples de evitar deadlocks \u00e9 olhar para o seu aplicativo e tentar garantir que o bloqueio ocorra na mesma ordem em todos os aplicativos. E isso geralmente elimina 80% dos problemas, porque v\u00e1rias pessoas diferentes escrevem esses aplicativos. E se voc\u00ea bloque\u00e1-los na mesma ordem, ent\u00e3o voc\u00ea n\u00e3o enfrenta a situa\u00e7\u00e3o de deadlock.<\/p>\n<p><\/p>\n<p><em>Muito obrigado pela sua apresenta\u00e7\u00e3o! Voc\u00ea falou sobre vacuum full e, se eu entendi corretamente, o vacuum full modifica a ordem dos registros em armazenamento separado, portanto, mant\u00e9m os registros atuais inalterados. E por que o vacuum full precisa de acesso exclusivo ao bloqueio e por que ele conflita com opera\u00e7\u00f5es de grava\u00e7\u00e3o?<\/em><\/p>\n<p><\/p>\n<p>Essa \u00e9 uma boa pergunta. A raz\u00e3o \u00e9 que o vacuum full pega a tabela. E n\u00f3s, na verdade, estamos criando uma nova vers\u00e3o da tabela. E a tabela ser\u00e1 nova. Ent\u00e3o, na verdade, ser\u00e1 uma vers\u00e3o completamente nova da tabela. E o problema \u00e9 que, quando fazemos isso, n\u00e3o queremos que as pessoas leiam isso, porque precisamos que elas vejam a nova tabela. E por isso se conecta com a pergunta anterior. Se pud\u00e9ssemos ler ao mesmo tempo, n\u00e3o conseguir\u00edamos mov\u00ea-la e direcionar as pessoas para a nova tabela. Ter\u00edamos que esperar que todos terminassem de ler esta tabela, e assim, na verdade, \u00e9 uma situa\u00e7\u00e3o de bloqueio exclusivo.<br \/>\nEstamos simplesmente dizendo que bloqueamos desde o in\u00edcio, porque sabemos que no final precisaremos de um bloqueio exclusivo para mover todos para a nova c\u00f3pia. Portanto, potencialmente podemos liberar isso. E fazemos isso com a indexa\u00e7\u00e3o simult\u00e2nea. Mas \u00e9 muito mais complicado de fazer. E isso est\u00e1 muito relacionado \u00e0 sua pergunta anterior sobre bloqueio exclusivo.<\/p>\n<p><\/p>\n<p><em>\u00c9 poss\u00edvel adicionar um tempo limite de bloqueio no Postgres? No Oracle, posso, por exemplo, escrever 'selecionar para atualizar' e esperar 50 segundos at\u00e9 a atualiza\u00e7\u00e3o. Isso era bom para o aplicativo. Mas no Postgres, ou eu fa\u00e7o isso imediatamente e n\u00e3o espero, ou espero at\u00e9 um certo tempo.<\/em> <\/p>\n<p><\/p>\n<p>Sim, voc\u00ea pode escolher o tempo limite para seus bloqueios. Voc\u00ea tamb\u00e9m pode emitir um comando sem forma, que ser\u00e1..., se n\u00e3o conseguir obter o bloqueio imediatamente. Ent\u00e3o, ou tempo limite de bloqueio, ou outra coisa que permita fazer isso. Isso n\u00e3o \u00e9 feito em n\u00edvel de sintaxe. \u00c9 feito como uma vari\u00e1vel no servidor. \u00c0s vezes, n\u00e3o \u00e9 poss\u00edvel us\u00e1-lo.<\/p>\n<p><\/p>\n<p><em>Voc\u00ea pode abrir o slide 75?<\/em> <\/p>\n<p><\/p>\n<p>Sim.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Desbloqueando o Gerenciador de Locks do Postgres. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5f0f3ee9ba29e0c231dd6e0eb66b4f6c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><em>E minha pergunta \u00e9 a seguinte. Por que ambos os processos de atualiza\u00e7\u00e3o est\u00e3o aguardando 703?<\/em><\/p>\n<p><\/p>\n<p>E essa \u00e9 uma \u00f3tima pergunta. N\u00e3o entendo, a prop\u00f3sito, por que o Postgres faz isso. Mas quando 703 foi criado, ele esperava 702. E quando 704 e 705 aparecem, parece que eles n\u00e3o sabem o que est\u00e3o esperando, porque ainda n\u00e3o h\u00e1 nada. E o Postgres faz assim: quando voc\u00ea n\u00e3o consegue obter um bloqueio, ele pensa: 'Qual \u00e9 o sentido de process\u00e1-lo?', porque voc\u00ea j\u00e1 est\u00e1 esperando algu\u00e9m. Ent\u00e3o, apenas deixamos na espera, ele nem atualiza isso. Mas o que aconteceu aqui? Assim que 702 terminou o processo e 703 obteve seu bloqueio, o sistema voltou. E disse que agora temos duas pessoas esperando. E ent\u00e3o vamos atualiz\u00e1-las juntas. E vamos indicar que ambas est\u00e3o esperando. <\/p>\n<p><\/p>\n<p>N\u00e3o sei por que o Postgres faz isso. Mas existe um problema chamado f\u2026. Acho que esse n\u00e3o \u00e9 um termo em portugu\u00eas. \u00c9 quando todos est\u00e3o esperando por um bloqueio, mesmo que haja 20 inst\u00e2ncias esperando por um bloqueio. E de repente todos despertam ao mesmo tempo. E todos come\u00e7am a tentar reagir. Mas o sistema faz com que todos esperem 703. Porque todos est\u00e3o aguardando, e os organizamos imediatamente em fila. E se qualquer outro novo pedido aparecer, que foi formado depois disso, por exemplo, 707, haver\u00e1 novamente um vazio. <\/p>\n<p><\/p>\n<p>E parece que isso \u00e9 feito para que possamos dizer que neste est\u00e1gio 702 est\u00e1 esperando 703, e todos aqueles que chegarem depois disso n\u00e3o ter\u00e3o nenhum registro nesse campo. Mas assim que o primeiro aguardando sai, todos aqueles que estavam aguardando nesse momento at\u00e9 a atualiza\u00e7\u00e3o recebem o mesmo marcador. E por isso, parece que isso foi feito para que pud\u00e9ssemos processar na ordem, para que eles fossem devidamente organizados. <\/p>\n<p><\/p>\n<p>Sempre encarei isso como um fen\u00f4meno bastante estranho. Porque aqui, por exemplo, n\u00e3o os listamos de maneira alguma. Mas, parece que toda vez que damos um novo bloqueio, olhamos para todos aqueles que est\u00e3o no processo de espera. Ent\u00e3o os organizamos em fila. E qualquer novo que chega s\u00f3 entra na fila quando a pr\u00f3xima pessoa terminou de ser processada. Uma pergunta muito boa. Muito obrigado pela pergunta!<\/p>\n<p><\/p>\n<p><em>Parece-me muito mais l\u00f3gico quando 705 espera 704.<\/em> <\/p>\n<p><\/p>\n<p>Mas o problema \u00e9 o seguinte. Tecnicamente, voc\u00ea pode ativar um ou outro. Portanto, ativaremos um ou outro. Mas o que acontece no funcionamento do sistema? Voc\u00ea v\u00ea que 703 no topo bloqueou seu pr\u00f3prio ID de transa\u00e7\u00e3o. \u00c9 assim que o Postgres funciona. E 703 \u00e9 bloqueado pelo seu pr\u00f3prio ID de transa\u00e7\u00e3o, ent\u00e3o, se algu\u00e9m quiser esperar, ele ficar\u00e1 esperando por 703. E, essencialmente, 703 \u00e9 que termina. E s\u00f3 ap\u00f3s sua finaliza\u00e7\u00e3o, algum dos processos \u00e9 ativado. E n\u00e3o sabemos exatamente qual processo vai ser. Ent\u00e3o, gradualmente, processamos tudo. Mas n\u00e3o est\u00e1 claro qual processo ser\u00e1 ativado primeiro, porque pode ser qualquer um desses processos. Basicamente, t\u00ednhamos um agendador que dizia que agora poder\u00edamos ativar qualquer um desses processos. Apenas escolhemos um aleatoriamente. Por isso, ambos precisam ser marcados, porque podemos ativar qualquer um deles. <\/p>\n<p><\/p>\n<p>E o problema \u00e9 que temos CP-infinito. Ent\u00e3o, \u00e9 bastante prov\u00e1vel que possamos ativar o mais recente. E se, por exemplo, formos ativar o mais recente, ent\u00e3o estaremos esperando por aquele que acabou de receber um bloqueio, portanto n\u00e3o determinamos quem exatamente ser\u00e1 ativado primeiro. Criamos apenas uma situa\u00e7\u00e3o assim, e o sistema os ativar\u00e1 em ordem aleat\u00f3ria. <\/p>\n<p><\/p>\n<p><em>H\u00e1 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/erogov\/posts\/\">artigos sobre locks de Egor Rogov<\/a><\/noindex>. Veja, eles tamb\u00e9m s\u00e3o interessantes e \u00fateis. O tema, \u00e9 claro, \u00e9 extremamente complexo. Muito obrigado, Bruce!<\/em><\/p>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/510322\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 2020 \u0433\u043e\u0434\u0430 \u0411\u0440\u044e\u0441\u0430 \u041c\u043e\u043c\u0436\u0438\u0430\u043d\u0430 &quot;Unlocking the Postgres Lock Manager&quot;. (\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0412\u0441\u0435 SQL \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438\u0437 \u0441\u043b\u0430\u0439\u0434\u043e\u0432 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435: http:\/\/momjian.us\/main\/writings\/pgsql\/locking.sql) \u041f\u0440\u0438\u0432\u0435\u0442! \u0417\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043d\u043e\u0432\u0430 \u0431\u044b\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u0432 \u0420\u043e\u0441\u0441\u0438\u0438. \u042f \u043f\u0440\u043e\u0448\u0443 \u043f\u0440\u043e\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u044f \u043d\u0435 \u0441\u043c\u043e\u0433 \u043f\u0440\u0438\u0435\u0445\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0433\u043e\u0434\u0443, \u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u0433\u043e\u0434\u0443 \u0443 \u0418\u0432\u0430\u043d\u0430 \u0438 \u0443 \u043c\u0435\u043d\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043f\u043b\u0430\u043d\u044b. \u042f, \u043d\u0430\u0434\u0435\u044e\u0441\u044c, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":87955,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-87954","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 2020 \u0433\u043e\u0434\u0430 \u0411\u0440\u044e\u0441\u0430 \u041c\u043e\u043c\u0436\u0438\u0430\u043d\u0430 &quot;Unlocking the Postgres Lock Manager&quot;.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Unlocking the Postgres Lock Manager. \u0411\u0440\u044e\u0441 \u041c\u043e\u043c\u0436\u0438\u0430\u043d | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 2020 \u0433\u043e\u0434\u0430 \u0411\u0440\u044e\u0441\u0430 \u041c\u043e\u043c\u0436\u0438\u0430\u043d\u0430 &quot;Unlocking the Postgres Lock Manager&quot;.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-07-11T23:42:48+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-11T23:42:48+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Desbloqueando o Gerenciador de Bloqueio do Postgres. Bruce Momjian | ProHoster","description":"Desmistificando a apresenta\u00e7\u00e3o de Bruce Momjian de 2020 \"Desbloqueando o Gerenciador de Locks do Postgres\".","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Unlocking the Postgres Lock Manager. \u0411\u0440\u044e\u0441 \u041c\u043e\u043c\u0436\u0438\u0430\u043d | ProHoster","og:description":"\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 2020 \u0433\u043e\u0434\u0430 \u0411\u0440\u044e\u0441\u0430 \u041c\u043e\u043c\u0436\u0438\u0430\u043d\u0430 &quot;Unlocking the Postgres Lock Manager&quot;.","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-07-11T23:42:48+00:00","article:modified_time":"2020-07-11T23:42:48+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"87954","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:40:34","updated":"2022-09-27 23:56:25","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/87954","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=87954"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/87954\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/87955"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=87954"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=87954"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=87954"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}