Problemas com Migrate_from_s3

When migrating from S3 to local storage, we see a number of issues.

The main issue is that the migrate_from_s3 rake task is not taking the Uploads table as a starting point, but the posts. This causes it to skip a lot of uploads which are being left on S3.

  • uploads used as logo’s because they are not referenced in a post
  • uploads for avatars because they are not referenced in a post
  • uploads that are (for some reason) referenced by their CDN URL in raw because they do not match the regex that is being used to identify the uploads
  • uploads that are on non-AWS S3 storage because they do not match the regex because it requires amazonaws in the URL
  • uploads that for some reason do not match the second, different regex (we’re seeing this with non-image uploads like mp3 files, not sure why this is happening)
2 curtidas

We’re working on improving the way we associate uploads to posts (by using the upload:// scheme) that will make these storage migrations much more bulletproof. There’s little point to fixing these rake tasks before that’s done.

7 curtidas

Recentemente, abri um novo PR para permitir migrar menos posts de cada vez (como testar um por vez) e adicionei testes para a tarefa.

Parece fazer sentido começar pelos posts, já que você precisa reassar os posts para alterar a URL no conteúdo assado após cada migração; migrar todos os uploads e depois iniciar os reassamentos deixaria o site muito quebrado por um tempo potencialmente longo em um site grande (preciso migrar cerca de 100 GB do S3 para local, então isso é importante para mim). Mas o que escrevi pode ajudar a começar a criar uma tarefa migrate_uploads_from_s3 que seria executada após migrate_from_s3 para limpar uploads que não faziam parte de posts.

@zogstrip Qual é o status atual de “Estamos trabalhando em…” — isso ainda está em fluxo ou essa migração já vale a pena ser observada?

5 curtidas

Temos feito muito trabalho na frente de uploads para garantir que tenhamos associações melhores entre posts e uploads.

Essas tarefas de migração podem ser melhoradas à vontade :+1:

2 curtidas

Descobrirei se vale a pena meu tempo investigar postagens fora do fluxo normal assim que conseguir usar os uploads em lote para migrar meu site fora do horário comercial! :smiling_face: Obrigado pela revisão do PR!

1 curtida

Tenho dois pontos a abordar a seguir: o primeiro é que o limite é útil, mas atua apenas como um limite no espaço de busca; em seguida, quero poder especificar um número máximo de posts a modificar. Portanto, pretendo adicionar um número máximo de posts a modificar, além de um limite para a consulta.

Além disso, ao especificar max, faz sentido ser explícito sobre o que está sendo processado para fins de depuração. Assim, gostaria de tornar a saída verbosa se max não for nil — isso permitirá que as pessoas validem o processo antes de continuar, já que esse é o caso de uso principal deste trabalho.

Acho que vou definir max como o primeiro argumento e um limite opcional como o segundo, porque, na verdade, o max é o mais importante; o limite serve apenas para tornar o “um ping apenas” mais barato.

O segundo ponto é: não-upload, ou seja, uploads. Há pouco mais de um ano, tentei fazer upload de um vídeo no site Discourse ao qual estava me juntando, enquanto lutava para descobrir como escrever a migração do Google+ para o Discourse, e vi que o que foi escrito era https://#{SiteSettings.absolute_base_url}/original/3X/b/a/ba9e06ebc2f4397f26793bb5cd4e169308dd371d.mp4.

Hoje, ao fazer upload de um vídeo, obtenho algo como ![file_example_MP4_480_1_5MG|video](upload://caJ9ykkpshw3PFK4464VUIPWJ4l.mp4).

Pelo menos no meu teste mais recente, migrate_from_s3 estragou completamente essas URLs, fazendo com que nem sequer fossem mais URLs, o que definitivamente precisa ser corrigido. Depois, acho que, na prática, é improvável que essa tarefa encontre ![texto](url-não-upload-para-migrar). Portanto, como primeira abordagem, gostaria apenas de adicionar a sintaxe de link Markdown ao redor do protocolo mágico upload, em vez de fazer a expressão regular lidar com ambos os casos e, como resultado, ficar ainda mais difícil de ler. Mas posso mudar de ideia sobre isso.

Parece que a tag video ou audio é adicionada em JavaScript por meio de correspondência com expressão regular, então terei que copiar as expressões regulares de app/assets/javascripts/discourse/app/lib/uploads.js para a tarefa para identificá-las corretamente. Vou incluir a origem das expressões regulares para que a próxima pessoa que as encontrar saiba de onde atualizá-las. :stuck_out_tongue:

Esta noite, reservei um tempo para trabalhar nisso e já tenho um PR (Pull Request) em andamento. Ele não está concluído; sei que ainda há bugs nele. Não acho que tenha alterado qualquer comportamento para URLs do pseudo-protocolo upload: (normais para imagens) até agora, embora tenha adicionado uma verificação de sanidade.

Com as alterações neste PR, migrei com sucesso tanto uploads normais do pseudo-protocolo upload: quanto vídeos que atualmente são referenciados explicitamente por referência ao S3 (bem, no meu caso, espaços do Digital Ocean). Estou usando isso para modificar apenas um post por vez com este comando:

bin/rake uploads:batch_migrate_from_s3[1,1000]

Observe que isso não irá além dos primeiros 1000 posts retornados de forma um pouco aleatória pela consulta ao banco de dados; o limite baixo é apenas para agilizar a consulta enquanto migra apenas um post por vez, revisa esse post para garantir o comportamento correto e depois recomeça para encontrar outro. Este comando funciona dessa maneira apenas com o PR em que estou trabalhando atualmente!

Continuo a adicionar saída de diagnóstico enquanto trabalho nisso e estou começando a pensar que isso é importante além do desenvolvimento. Estou vendo muitas falhas de download transitórias nos espaços do Digital Ocean, onde alguns, mas não todos, os downloads em um post são migrados, o que, no original, apenas imprimiria um . e continuaria, dizendo Done no final, mas, na verdade, a tarefa não estaria concluída. Tive que fazer algo como cinco ou seis passes em um único post antes que todos os arquivos fossem migrados. (Não estava contando porque achei que estava depurando um bug local no início.) Estou esperando ter que executar essa migração repetidamente com o mesmo limite até que os diagnósticos estejam limpos. Portanto, estou fazendo a impressão de progresso verbosa apenas se max estiver definido, mas imprimindo mensagens de aviso úteis em qualquer caso.

No momento, estou usando a seguinte solução alternativa para os downloads intermitentemente falhos do Discourse Spaces, o que, na prática, tem melhorado tremendamente minha taxa de sucesso (3 tentativas têm sido totalmente suficientes em centenas de posts migrados até agora).

https://github.com/johnsonm/discourse/commit/7dfac12a2ea6ec04ba4e0616b4e0dbd1d806cff7

Também descobri que, de alguma forma, acabamos com vídeos maiores do que o limite que configurei quando importei do Google+ — tive que aumentar temporariamente tanto SiteSettings.max_image_size_kb quanto SiteSettings.max_attachment_size_kb enquanto fazia migrações pontuais de alguns vídeos grandes, dos quais não tenho certeza de como eles acabaram no site, mas não quero quebrá-los agora… Não faço ideia se o bug que permitia uploads grandes estava no meu script de importação, no Discourse ou apenas na minha memória sobre quais alterações fiz nas configurações ao longo do tempo. :wink:

Como grande parte do que estou migrando foi uma importação do G+, alguns dos meus posts acabaram falhando nas validações atuais. Recebi alguns erros como Unhandled failure: Validation failed: Sorry, new users can only put one image in a post e inicialmente não entendi por que eles não se repetiam. Acontece que os uploads foram movidos com sucesso para o local e todos usavam o pseudo-protocolo upload:, então o conteúdo bruto não mudou. No entanto, post.save! ainda falhou com esse erro nas validações, o que impediu que post.rebake! fosse acionado. Assim, tenho alguns posts entre 30 mil com imagens que precisam ser rebaked; infelizmente, não tenho registro de quais posts são esses. Agora mudei para post.save!(validate: false) como outra correção, então esse problema específico não deve mais ocorrer. Estou muito feliz por ter feito a migração começar a abortar em erros não tratados; caso contrário, isso potencialmente causaria muito mais danos do que apenas alguns posts.

Para manter meu site utilizável, incluindo o envio de notificações, enquanto executo a migração, não quero sobrecarregar as filas do Sidekiq. Sei que nomear coisas é um dos dois problemas mais difíceis da ciência da computação, junto com a invalidação de cache e erros de off-by-one, mas estou propondo DISCOURSE_MIGRATION_MAX_ENQUEUED como uma variável de ambiente para definir quantos slots de fila no total (não slots de job) podem ser preenchidos ao prosseguir para migrar outro item após um rebake durante uma migração, evitando sobrecarregar as filas, para que o site continue funcionando. Tenho um patch que adiciona isso, com valor padrão zero, para todo o rebake por post em lib/tasks/uploads.rake. Estou usando isso na minha migração de produção.

https://github.com/discourse/discourse/blob/59a761851b9c8786d3a9692f8c595372b0534f77/lib/tasks/uploads.rake

4 curtidas

@zogstrip Você se importa de revisar este PR, já que você tem o contexto da revisão recente do meu último PR nesta área? FIX: Make migrations from S3 more robust; fix bare URL migration by johnsonm · Pull Request #10093 · discourse/discourse · GitHub

Incluí nele as correções que tenho feito enquanto executo essa migração relativamente grande. Não tentei adicionar testes para cada correção; não tenho certeza de como injetar cada tipo de erro. Mas, pelo menos, a nova funcionalidade está testada.

@RGJ Acredito que meu PR, no estado atual, pode resolver todos os seus pontos, exceto os dois primeiros, embora eu não tenha certeza sobre o CDN. Meu site usava CDN e migrou vídeos que tinham URLs de CDN, mas isso pode ter sido um efeito colateral da nomenclatura com os Discourse Spaces. Se você tiver casos adicionais, espero que meu PR forneça uma estrutura fácil para adicionar ao regex e criar casos de teste para as variações adicionais.

Acho que está correto migrar primeiro por post, pois após migrar os uploads em um post, o post precisa ser rebaked para que o post cozido tenha as URLs corretas. Após terminar de migrar meus posts (o que pode levar menos de duas semanas agora que mudei minha limitação de taxa para verificar o comprimento da fila diretamente), vou analisar qualquer trabalho restante para fazer a limpeza.

Como vários posts podem compartilhar referências ao mesmo conteúdo se mais de uma pessoa fizer upload do mesmo arquivo, é necessário uma segunda passagem que verifique os dados cozidos em busca de URLs antigas e rebake esses posts para pegar a nova localização. Pode usar a mesma limitação de taxa para evitar sobrecarregar as filas.

Provavelmente não verei nenhum logotipo quebrado no makerforums, pois ajustamos a marcação depois de parar de colocar novo conteúdo no “s3” (para nós, DigitalOcean Spaces), mas provavelmente verei vários uploads ainda no S3, pelo menos para avatares. A migração de uploads não associados a um post deve ser iniciada apenas após todos os posts terem sido migrados, e provavelmente terei que documentar isso após terminar de migrar os uploads nos posts.

@pfaffman Vi Bizarre Problems with migrate_from_s3 - #5, que descreve erros que não se repetiram. Sem minhas correções no PR atual, os erros são silenciosamente ignorados, incluindo falhas de validação. Acredito que o trabalho aqui resolverá pelo menos alguns dos problemas que você viu naquela época.

@hosna Os problemas que você levantou em https://meta.discourse.org/t/what-does-rake-uploads-migrate-from-s3-exactly-do/97285 estão parcialmente ou completamente resolvidos até agora neste PR. Se não estiverem completamente resolvidos, adicionei testes que facilitarão a adição de novos testes para validar correções adicionais.

@sam, já que você colocou a etiqueta 2.6 no PR, estou assumindo que ele não será mesclado por pelo menos alguns dias; devo trazer meu trabalho de recurso de limitação de taxa para o PR junto com as correções? Ou você prefere manter correções e trabalho de recurso em PRs separados? Posso fazer de qualquer forma. O recurso de limitação de taxa está funcionando muito bem; estou migrando cerca de três vezes mais rápido, sem impacto na disponibilidade do site, agora que estou aguardando a fila do Sidekiq esvaziar, então faz sentido trazê-lo, acho, se for algo normalmente aceito em PRs. Caso contrário, precisarei aguardar o PR para mesclar o trabalho em que ele se baseia, então, de qualquer forma, seria bom ouvir sua opinião.

..

Refatorei meu patch de limitação de taxa de migração e o incluí no PR. Está funcionando na prática, e o sar indica que estou vendo quase zero tempo ocioso continuamente, enquanto o site continua funcionando, durante a migração ao vivo. Uma vantagem do modo em lote é que posso verificar novas versões do Discourse após cada lote completo de migrações; atualizei meu site para a 2.6.0beta1 na primeira oportunidade após o corte e tenho executado as migrações com sucesso na 2.6.0beta1 com meu PR de migração por cima desde a atualização.

Acredito que o PR está pronto para revisão agora; planejo enviar outro PR para as últimas etapas, mas colocar isso em prática melhorará a experiência geral de migração para todos, mesmo antes de eu terminar as últimas partes.

5 curtidas

Bem, isso foi há muito tempo…

Estou ansioso para ver isso resolvido. No momento, tenho vários sites em multisite que precisam buscar imagens do S3 (no momento, acho que algumas imagens estão locais e outras estão no S3) e depois enviar para o S3.

1 curtida

@pfaffman Provavelmente é uma boa coisa que, quando comecei meu projeto de migração, eu não soubesse o que hoje acredito ter descoberto. Parece que, se eu tivesse usado o minio client para copiar todo o bucket S3 para a pasta local de uploads, modificado todos os Upload.url para nil no console do Rails e rebaked o site, tudo teria sido migrado em horas, sem precisar regenerar todas as imagens. (Em vez disso, estou limitado pela taxa de execução, pois estou convertendo todas as imagens novamente, como se a CPU local fosse mais barata do que apenas copiar todas as imagens processadas do S3.)

E então, se tivesse sido tão fácil, eu não teria feito nenhum desse trabalho para tornar as migrações mais confiáveis em geral, e ninguém mais teria se beneficiado. :smiling_face:

4 curtidas

Ah. Isso parece ser o que eu queria saber. Talvez eu tente isso.

1 curtida

Eu… definitivamente faria um backup antes de tentar esse caminho, já que estou apenas especulando. Não quero te induzir ao erro.

Ah, e mais uma coisa: isso teria falhado completamente para uploads de áudio e vídeo, e eu não teria percebido até mais tarde, e então teria tentado entender o problema e escrever código personalizado. Então, se você tem uploads de áudio e vídeo, com certeza deve começar por aí, e não funcionará corretamente sem o PR que está aberto e só será mesclado após o lançamento da versão 2.5, já que @sam o marcou como 2.6.

2 curtidas

Peço desculpas por me juntar à conversa tão tarde. Acabei de ver seu PR e estou me perguntando por que você está recriando o modelo Upload em vez de apenas alterar suas URLs? E por que não apenas iterar sobre os OptimizedImages e fazer o mesmo?

2 curtidas

@RGJ Eu não mudei isso em nada; recriar o Upload foi uma correção de bug feita por @zogstrip em Cannot execute the rake uploads:migrate_from_s3 - #11

Estou apenas tentando fazer funcionar o código que já existia, e não conheço bem os detalhes internos do Discourse; tenho estado às cegas por bastante tempo. Minha única experiência com Ruby são os poucos PRs que fiz para o Discourse. Seguir o padrão do código existente parece não ser a rota mais eficiente (veja minha conversa com @pfaffman acima sobre curto-circuitar), concordo totalmente. Como você pode notar pelo fato de que, mais cedo hoje, eu nem percebi que OptimizedImages.url também precisaria ser modificado para um caminho /uploads e que o etag precisaria ser definido como nil (e não sei mais o quê), ainda estou voando às cegas.

Ainda preciso iterar sobre as postagens primeiro, pelo menos para corrigir URLs literais antigas nas postagens. Ainda preciso de algumas das outras correções, como não revalidar postagens e não engolir erros silenciosamente. Ainda acho que preciso implementar limitação de taxa, para limitar o impacto em sites em produção.

Quanto às suas duas primeiras preocupações envolvendo atualizações de não-postagens, aqui está meu trabalho em andamento, ainda não testado em um site em produção (commit) que pode ajudar, mas que só vou testar no meu site em produção quando toda a migração de uploads de postagens estiver concluída.

Ajustar algo que já funcionava era tudo o que eu tinha disposição para fazer. Se você quiser fazer uma migração mais rápida, eu sou totalmente a favor; pode fazer sentido mesclar meu trabalho mais lento, mas pelo menos melhor, como uma melhoria de Pareto, e então você poderia substituí-lo completamente por algo muito melhor, e eu seria o primeiro a celebrar, mesmo que eu não esteja mais em posição de usá-lo naquele momento.

1 curtida

@mcdanlj Obrigado pela sua explicação. Eu estava fazendo uma pergunta de verdade, não querendo sugerir que há algum problema agora. Não sei se a maneira que sugeri é de alguma forma “melhor” — talvez introduzisse muitos novos problemas. Acredito que o código, como está hoje, não importa quem o escreveu, existe por um motivo.

3 curtidas

@RGJ da mesma forma, sou sincero ao dizer que, se alguém souber com certeza como evitar o imbróglio de reconstruir todas as imagens, estou totalmente a favor. E se eu fosse um desenvolvedor experiente do Discourse e soubesse como fazer isso facilmente, provavelmente teria feito isso desde o início.

Minha suposição é que migrar do S3 não é um caso comum para quem tem muitas imagens, então dificilmente vale a pena o tempo gasto, em comparação com adicionar recursos mais geralmente úteis ao Discourse. Eu tinha aproximadamente 100 GB de uploads importados do Google+ para o MakerForums e escolhemos o S3 com a ideia de que muitas pessoas poderiam migrar dessas comunidades para o MakerForums. No entanto, no final, apenas algumas comunidades migraram ativamente, e o crescimento contínuo não justificou permanecer no S3. Acredito que esse seja um caso bastante extremo, e o reprocessamento das imagens é um custo único.

Por fim, sou muito grato por você ter aberto esse tópico desde o início, pois, caso contrário, eu poderia facilmente ter perdido os uploads não relacionados a posts.

@RGJ Você está claramente certo de que destruir e recriar não é uma boa solução. Adicionei uma verificação: raise "Erro: URL do upload #{url} mudou para #{new_upload.short_url}, deveria permanecer inalterada." if url != new_upload.short_url, que pelo menos relata problemas com fontes corrompidas. A interrupção dos Digital Ocean Spaces de hoje enviou-me dados corrompidos, o que acionou esse erro para muitos uploads — não sei quantos. Mas, como já havia destruído o upload antigo, agora tenho algumas páginas corrompidas, e só percebi depois de perder o histórico de logs que indicava quais páginas estavam corrompidas. Assim, nem mesmo consigo corrigi-las manualmente a partir de um backup.

Portanto, embora meu trabalho seja uma melhoria em relação à maneira antiga, pois pelo menos relata alguns erros, seria muito melhor baixar os arquivos, verificar os SHA1 dos arquivos baixados e escrevê-los em arquivos locais. Enquanto isso, modifiquei meu PR para interromper a migração em qualquer erro não tratado, pelo menos para limitar a perda de dados.

Ainda acho que meu trabalho deve ser mesclado como uma melhoria de Pareto, já que não piora nada e, de fato, melhora a situação. No entanto, seria ainda melhor fazer da maneira correta. Acredito que isso envolveria criar lib/file_store/from_s3_migration.rb em paralelo a lib/file_store/to_s3_migration.rb, mas não estou à altura disso.

Como meu PR ainda não foi revisado, adicionei mais coisas a ele. Criei uma tarefa uploads:report_missing_uploads que percorre o campo raw procurando instâncias de upload://... onde o objeto de upload não está presente. Pelo menos no meu caso, com backups, poderei examinar meus backups, encontrar os arquivos órfãos e restaurá-los no site, depois recriar esses posts para restaurar as imagens que desapareceram. Encontrei 678 deles para buscar nos backups, dos quais já localizei todos, exceto 10, então estou feliz por ter escrito o teste! Preciso lidar com isso antes de avançar para a fase em que recriarei os posts restantes.

Concluí minha primeira fase de migração, sem incluir a recriação de posts afetados com uploads compartilhados e sem incluir uploads não relacionados a posts. Após concluir outro backup remoto, planejo testar esses recursos também e adicioná-los ao meu PR.

Agora comecei a testar as próximas fases da migração: recriação de posts e migração de uploads não relacionados a posts. Minha primeira lição foi que a recriação como próxima etapa falha devido a avatares de uploads não relacionados a posts em posts citados, então a recriação de posts precisa ser a última etapa.

Próxima descoberta: Obrigado, restrições de chave estrangeira! Ao migrar uploads não relacionados a posts, descobri que preciso migrar pelo menos os perfis antes de migrar os uploads não relacionados a posts de forma geral.

ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR:  update or delete on table "uploads" violates foreign key constraint "fk_rails_1d362f2e97" on table "user_profiles"

A migração de perfis foi complicada, pois precisei migrar dois uploads anexados ao perfil, mas, em alguns casos, as pessoas usavam a mesma imagem para ambos, então precisei fazer esse trabalho em três etapas. Migrei com sucesso todos os perfis do meu site com URLs do S3.

Migrei todos os meus uploads não relacionados a posts e não relacionados a perfis. @RGJ, se quiser testar a branch que publiquei, ela está atualizada com meu trabalho. Tudo nela já foi usado para uma migração completa do site.

@cvx Não sei quando você terá a chance de revisar, mas sem meu PR, migrate_from_s3 definitivamente está cheio de bugs de destruição silenciosa de dados. O que fiz não é perfeito, mas protege contra muitos bugs que encontrei na prática.

Fiz todo o trabalho que pretendo fazer aqui por enquanto. Migrei meu site, o que significa que nem mesmo consigo avaliar efetivamente quaisquer alterações solicitadas. Se você rejeitar este PR, sugiro fortemente que, em vez disso, exclua a migração existente, pois ela destruirá dados silenciosamente para os usuários.

Em relação ao PR, às vezes obtenho falhas de teste no CI (na versão atual), algo assim:

7867 exemplos, 0 falhas, 11 pendentes, 1 erro ocorreu fora dos exemplos

##[error]Process completed with exit code 1.

Isso não se reproduz localmente (até agora) e não vejo nenhuma informação nos logs do CI que indique o que está errado no CI, então não vou perder mais tempo tentando explorar a saída do CI em busca de informações ocultas.

Uma última observação: Após concluir a migração, descobrimos que as fotos de perfil de alguns usuários foram perdidas durante a migração, e eles estão restaurando-as manualmente. Acredito que seria necessário código adicional para ter sucesso nisso, mas como só percebi isso tarde demais, não tenho um caso de teste para validar. Portanto, esse é um bug remanescente que pode causar problemas em algumas configurações, mas não estou mais em condições de escrever essa correção adicional.

5 curtidas

Como meu PR corrigindo a corrupção silenciosa de dados que é migrate_from_s3 nem sequer foi analisado, pelo menos migrate_to_s3 pode ser documentado como uma via de mão única?

No momento, francamente, é uma armadilha para iniciantes.

@cvx @zogstrip Qual é a preferência de vocês? Analisar o PR ou simplesmente remover migrate_from_s3 inteiramente e ser honesto sobre o fato de que é uma via de mão única?

5 curtidas

Desculpe, a culpa é minha. Vou revisar o PR esta semana.

7 curtidas

O conteúdo da revisão foi basicamente que a abordagem atual está tão completamente errada que precisa ser reconstruída do zero e de forma diferente; que a tentativa de corrigi-la da maneira como foi escrita anteriormente não é aceitável. Eu não estou disposto a isso, então realmente acho que migrate_from_s3 deve ser removido completamente e migrate_to_s3 deve ser marcado como uma porta de mão única da qual você realmente deve querer se comprometer para sempre. No momento, ter migrate_from_s3 no código-fonte é uma falha de integridade de dados no Discourse.

Não recebi uma revisão oportuna enquanto trabalhava no processo de migração, e agora que já migrei há muito tempo (com alguns resultados quebrados, como alguns avatares defeituosos), estou sem um ambiente de teste significativo. Não tenho nenhuma confiança de que faria isso corretamente, então desisti dessa luta. Cabe ao próximo coitado que achou que seria uma boa ideia colocar imagens em algum serviço de armazenamento de objetos semelhante ao S3 para resolver o problema. Desculpe!

2 curtidas

@CxV Como você rejeitou a migração anterior por ter sido feita completamente de forma incorreta e precisar ser refeita do zero, por favor, revise e faça o merge desta correção do bug de corrupção de dados:

2 curtidas

Como já foi observado, encontrei alguns problemas com a migração que fiz. Isso corrobora o ponto de @cvx de que escrevi a migração completamente errada e, até que alguém a faça corretamente, a remoção da migração existente, cheia de corrupção silenciosa de dados, realmente deveria ser mesclada. (É um patch muito simples, a revisão deve ser trivial. Quanto antes for mesclado, menos provável será que alguém destrua seu site tentando voltar por uma porta de mão única. Não sei como pedir mais enfaticamente uma mesclagem; se soubesse, faria. Edição: Obrigado, @cvx, pela aprovação, mesclagem e acompanhamento para garantir que a migração em massa seja marcada como irreversível.)

Aqui estão os problemas conhecidos que encontrei:

  • Pelo menos o avatar do discobot não apareceu; toda a participação do discobot mostrou o avatar genérico de pessoa (cabeça e ombros em cinza claro sobre fundo branco).
  • Alguns outros avatares de pessoas não foram migrados corretamente. Muitos foram corrigidos manualmente.
  • Quando o site estava sendo configurado, o administrador original experimentou alterações na configuração do “S3” (no nosso caso, Digital Ocean Spaces, com e sem CDN), o que levou a algumas imagens otimizadas órfãs que não foram corrigidas na migração.

Para quem tentou usar minha branch e teve algumas imagens desaparecendo assim, executei uma “gambiarra” no console do Rails e isso corrigiu algumas coisas. Esta não é a maneira correta de fazer isso; eu simplesmente não conheço o modelo o suficiente para fazer do jeito certo. Meu conhecimento em Ruby é muito fraco; não toco em Ruby fora das minhas pequenas contribuições para o Discourse.

Mas, como está, essa terrível gambiarra corrigiu imagens quebradas (de erros iniciais de configuração) e pelo menos trouxe de volta o avatar do discobot (e possivelmente outros, mas todos aqueles dos quais eu já tinha conhecimento já haviam sido reparados).

O que não aparece aqui é tudo o que fiz entre os passos, analisando cada conjunto conforme avançava. Isso fez parte de uma sessão de “explorar o que existe no console do Rails” e não é realmente um script que escrevi e executei. Isso não tem tratamento de erros, e fiz um backup completo do site antes de começar qualquer um desses trabalhos.

Não sei como dizer com mais ênfase que este código não é a maneira idiomática do Ruby on Rails de fazer essa reparação. Eu apenas quis compartilhar como consertei pelo menos parte do dano que causei a mim mesmo em minha tentativa anterior de migrar meu site do Digital Ocean Spaces.

require 'set'

uploadids = Set.new
optimizedimages = Set.new
OptimizedImage.where("url like '%UNIQUEPARTOFS3URL%'").each do |oi|
  uploadids.add(oi.upload_id)
  optimizedimages.add(oi)
end

postids = Set.new
uploadids.each do |u|
  PostUpload.where(upload_id: u).each do |pu|
    postids.add(pu.post_id)
  end
end

optimizedimages.each do |oi|
  oi.delete
end

postids.each do |pid|
  Post.where(id: pid).each do |p|
    p.rebake!
  end
end
2 curtidas