@RGJ allo stesso modo, sono sincero nel dire che se qualcuno sa con certezza come evitare la follia di ricostruire tutte le immagini, sono tutto orecchie; e se fossi uno sviluppatore Discourse esperto e sapessi come farlo facilmente, probabilmente l’avrei già fatto in un primo momento.
Immagino che la migrazione lontano da S3 non sia un caso comune per chi ha molte immagini, quindi potrebbe non valere la pena di dedicarci tempo, rispetto allo sviluppo di funzionalità più generalmente utili per Discourse. Avevo circa 100 GB di caricamenti importati da Google+ su MakerForums e abbiamo scelto S3 pensando che molte persone potessero trasferirsi da quelle community a MakerForums, ma alla fine solo poche community si sono trasferite attivamente, quindi la crescita continua non ha giustificato il permanere su S3. Mi aspetto che questo sia un caso piuttosto estremo e che la ric elaborazione delle immagini sia un costo una tantum.
Infine, sono molto grato per aver aperto questo argomento, perché altrimenti avrei potuto facilmente perdere i caricamenti non relativi ai post.
…
@RGJ hai chiaramente ragione: distruggere e ricreare non è una buona soluzione. Ho aggiunto un controllo, raise "Errore: l'URL di upload #{url} è cambiato in #{new_upload.short_url}, dovrebbe rimanere invariato." if url != new_upload.short_url, che almeno segnala problemi con sorgenti corrotte. L’incidente di oggi su Digital Ocean Spaces mi ha inviato dati corrotti, innescando questo errore per molti caricamenti — non so quanti. Ma poiché il vecchio upload era già stato distrutto, ora ho alcune pagine corrotte e non me ne sono accorto finché non ho perso lo storico dei log che indicava quali pagine erano danneggiate, quindi non posso nemmeno intervenire manualmente per correggerle da un backup.
Quindi, sebbene il mio lavoro rappresenti un miglioramento rispetto al metodo precedente perché almeno segnala alcuni errori, sarebbe molto meglio scaricare i file, verificare gli SHA1 dei file scaricati e scriverli su file locali. Nel frattempo, ho modificato la mia PR per fermare la migrazione in caso di qualsiasi errore non gestito, al fine di limitare almeno la perdita di dati.
Ritengo ancora che il mio lavoro dovrebbe essere unito al progetto principale come un miglioramento di Pareto, poiché non peggiora la situazione e anzi la migliora, ma sarebbe decisamente meglio farlo nel modo corretto. Credo che la soluzione giusta sia scrivere lib/file_store/from_s3_migration.rb in parallelo a lib/file_store/to_s3_migration.rb, ma non mi sento all’altezza del compito.
Poiché la mia PR non è ancora stata revisionata, ho aggiunto altro lavoro. Ho aggiunto un task uploads:report_missing_uploads che esamina raw per trovare istanze di upload://... in cui l’oggetto upload non è presente. Almeno nel mio caso, con i backup, potrò esaminare le mie copie di backup, trovare i file orfani e ripristinarli sul sito, quindi rigenerare i post per ripristinare le immagini mancanti. Ne ho trovati 678 da cercare nei backup, di cui finora ho recuperati tutti tranne 10, quindi sono contento di aver scritto il test! Dovrò occuparmene prima di passare alla fase di rigenerazione dei post rimanenti.
…
Ho completato la prima fase della migrazione, escludendo la rigenerazione dei post interessati con caricamenti condivisi e i caricamenti non relativi ai post. Dopo aver completato un altro backup remoto, prevedo di testare anche quelle funzionalità e aggiungerle alla mia PR.
…
Ho ora iniziato a testare le fasi successive della migrazione, ovvero la rigenerazione e la migrazione dei caricamenti non relativi ai post. La prima lezione è stata che la rigenerazione come passo successivo fallisce a causa di avatar non relativi ai post presenti in post citati, quindi la rigenerazione dei post deve essere l’ultimo passaggio.
Prossima scoperta: grazie ai vincoli di chiave esterna! Durante la migrazione dei caricamenti non relativi ai post, ho scoperto che devo migrare almeno i profili prima di migrare generalmente i caricamenti non relativi ai post.
ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: update or delete on table "uploads" violates foreign key constraint "fk_rails_1d362f2e97" on table "user_profiles"
La migrazione dei profili è stata complessa perché dovevo migrare due caricamenti associati al profilo, ma in alcuni casi le persone hanno utilizzato la stessa immagine per entrambi, quindi ho dovuto svolgere questo lavoro in tre fasi. Ho migrato con successo tutti i profili del mio sito con URL S3.
Ho migrato tutti i caricamenti non relativi ai post e non ai profili. @RGJ, se vuoi provare il ramo che ho pubblicato, è aggiornato con il mio lavoro. Tutto ciò che contiene è stato utilizzato per una migrazione completa del sito.
…
@cvx Non so quando avrai modo di revisionare, ma senza la mia PR, migrate_from_s3 è sicuramente pieno di bug di distruzione silenziosa dei dati. Quello che ho fatto non è perfetto, ma protegge contro molti bug che ho riscontrato nella pratica.
Ho completato tutto il lavoro che intendo fare qui al momento. Ho migrato il mio sito, il che significa che non posso nemmeno valutare efficacemente eventuali modifiche richieste. Se respingete questa PR, vi suggerisco vivamente di eliminare la migrazione esistente, poiché distruggerà silenziosamente i dati degli utenti.
Per quanto riguarda la PR, a volte ricevo fallimenti nei test in CI (nella versione corrente) qualcosa del genere:
7867 esempi, 0 fallimenti, 11 in sospeso, 1 errore verificatosi al di fuori degli esempi
##[error]Processo completato con codice di uscita 1.
Questo non si riproduce localmente (per quanto ne so) e non vedo informazioni nei log di CI che indichino cosa non va, quindi non voglio perdere altro tempo cercando di esplorare l’output di CI per trovare informazioni nascoste.
Un’ultima nota: dopo aver completato la migrazione, abbiamo scoperto che le immagini dei profili di alcuni utenti sono state perse durante la migrazione e le stanno ripristinando manualmente. Immagino che sarebbe stato necessario del codice aggiuntivo per riuscirci, ma poiché non l’ho scoperto fino a quando non era troppo tardi, non ho un caso di test per convalidarlo. Quindi questo è un bug residuo che potrebbe causare problemi in alcune configurazioni, ma non sono più nella posizione di scrivere la correzione aggiuntiva.