Ei, estou com o phpBB desde 2004, então estou transferindo um fórum de tamanho considerável. Atualmente, estou no segundo dia: 303.139/2.167.314 (14%), com 446 por minuto. Como posso acelerar isso? Estou na Digital Ocean e estou usando apenas 4% da CPU. O Redis continua dando timeout para mim. Desativei os anexos.
Alguns detalhes úteis ajudariam a estreitar essa investigação:
- Tamanho do Droplet: RAM, quantidade de vCPU, tipo/tamanho do disco
- O comando de importação exato que você está executando
- As configurações relacionadas a recursos do seu
app.yml, com segredos removidos, especialmente:UNICORN_WORKERSdb_shared_buffersdb_work_mem
- Se a importação está sendo executada dentro do contêiner Docker padrão do Discourse
- Quaisquer mensagens de timeout do Redis ou trechos de log
- Se o banco de dados está local, no mesmo contêiner, ou externo
Um ponto a observar: UNICORN_WORKERS provavelmente não acelerará muito a importação, pois o importador do phpBB não é atendido principalmente pelos workers da web. Aumentá-lo pode apenas consumir mais RAM. As configurações de memória do PostgreSQL e a E/S do disco são mais prováveis de fazer diferença.
Como o uso da CPU é de apenas cerca de 4%, isso pode ser limitado por E/S, limitado pelo banco de dados ou por espera no Redis, e não por falta de CPU. O timeout do Redis merece investigação separada.

Meu log atualizado
script/import_scripts/phpbb3.rb:15:in ‘’
302570 / 2167314 ( 14.0%) [448 itens/min] Exceção ao criar a postagem 304683. Pulando.
Aguardado 1,0 segundo
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/buffered_io.rb:214:in ‘block in RedisClient::RubyConnection::BufferedIO#fill_buffer’
internal:kernel:168:in ‘Kernel#loop’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/buffered_io.rb:197:in ‘RedisClient::RubyConnection::BufferedIO#fill_buffer’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/buffered_io.rb:187:in ‘RedisClient::RubyConnection::BufferedIO#ensure_remaining’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/buffered_io.rb:152:in ‘RedisClient::RubyConnection::BufferedIO#getbyte’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/resp3.rb:113:in ‘RedisClient::RESP3.parse’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/resp3.rb:50:in ‘RedisClient::RESP3.load’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection.rb:97:in ‘RedisClient::RubyConnection#read’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/connection_mixin.rb:37:in ‘RedisClient::ConnectionMixin#call’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client.rb:374:in ‘block (2 levels) in RedisClient#call_v’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/middlewares.rb:16:in ‘RedisClient::BasicMiddleware#call’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client.rb:373:in ‘block in RedisClient#call_v’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client.rb:781:in ‘RedisClient#ensure_connected’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client.rb:372:in ‘RedisClient#call_v’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis/client.rb:90:in ‘Redis::Client#call_v’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/mini_profiler/profiling_methods.rb:90:in ‘block in Redis::Client#profile_method’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis.rb:152:in ‘block in Redis#send_command’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis.rb:151:in ‘Monitor#synchronize’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis.rb:151:in ‘Redis#send_command’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis/commands/scripting.rb:110:in ‘Redis::Commands::Scripting#_eval’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis/commands/scripting.rb:97:in ‘Redis::Commands::Scripting#evalsha’
/var/www/discourse/lib/discourse_redis.rb:38:in ‘Kernel#public_send’
/var/www/discourse/lib/discourse_redis.rb:38:in ‘block in DiscourseRedis#method_missing’
/var/www/discourse/lib/discourse_redis.rb:29:in ‘DiscourseRedis.ignore_readonly’
/var/www/discourse/lib/discourse_redis.rb:38:in ‘DiscourseRedis#method_missing’
/var/www/discourse/lib/discourse_redis.rb:270:in ‘DiscourseRedis::EvalHelper#eval’
/var/www/discourse/lib/distributed_mutex.rb:82:in ‘DistributedMutex#get_lock’
/var/www/discourse/lib/distributed_mutex.rb:50:in ‘block in DistributedMutex#synchronize’
/var/www/discourse/lib/distributed_mutex.rb:49:in ‘Thread::Mutex#synchronize’
/var/www/discourse/lib/distributed_mutex.rb:49:in ‘DistributedMutex#synchronize’
/var/www/discourse/lib/distributed_mutex.rb:34:in ‘DistributedMutex.synchronize’
/var/www/discourse/lib/post_creator.rb:410:in ‘PostCreator#transaction’
/var/www/discourse/lib/post_creator.rb:200:in ‘PostCreator#create’
/var/www/discourse/script/import_scripts/base.rb:611:in ‘ImportScripts::Base#create_post’
/var/www/discourse/script/import_scripts/base.rb:555:in ‘block in ImportScripts::Base#create_posts’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/mysql2/alias_method.rb:8:in ‘Mysql2::Result#each’
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/mysql2/alias_method.rb:8:in ‘Mysql2::Result#each’
/var/www/discourse/script/import_scripts/base.rb:542:in ‘ImportScripts::Base#create_posts’
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:212:in ‘block in ImportScripts::PhpBB3::Importer#import_posts’
/var/www/discourse/script/import_scripts/base.rb:943:in ‘block in ImportScripts::Base#batches’
internal:kernel:168:in ‘Kernel#loop’
/var/www/discourse/script/import_scripts/base.rb:942:in ‘ImportScripts::Base#batches’
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:293:in ‘ImportScripts::PhpBB3::Importer#batches’
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:208:in ‘ImportScripts::PhpBB3::Importer#import_posts’
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:38:in ‘ImportScripts::PhpBB3::Importer#execute’
/var/www/discourse/script/import_scripts/base.rb:47:in ‘ImportScripts::Base#perform’
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:22:in ‘ImportScripts::PhpBB3::Importer#perform’
script/import_scripts/phpbb3.rb:35:in ‘module:PhpBB3’
script/import_scripts/phpbb3.rb:16:in ‘module:ImportScripts’
script/import_scripts/phpbb3.rb:15:in ‘’
333919 / 2167314 ( 15.4%) [441 itens/min]
Parece que está funcionando, sem reclamações.
Até agora
Unicorn parado
Anexos e avatares desativados
O tamanho da droplet parece razoavelmente adequado para esse tipo de importação, então eu não esperaria que UNICORN_WORKERS fosse o principal limitador aqui.
Algumas observações:
- Parar o Unicorn provavelmente é aceitável para um container de importação ou staging, mas dificilmente acelerará significativamente o próprio importador.
- Com os anexos e avatares desabilitados, duas das etapas mais lentas devem ser removidas. Se você ainda estiver obtendo apenas ~440 posts/min, o gargalo pode estar na E/S do banco de dados, na consulta MySQL do phpBB de origem ou em esperas no Redis/PostgreSQL.
- Vale a pena observar com atenção a linha do log:
Exception while creating post 304683. Skipping.
Embora a importação continue, isso significa que pelo menos aquele post foi pulado. Se isso acontecer repetidamente, a migração final pode estar faltando posts.
A parte do Redis parece ser um timeout de 1 segundo no cliente Redis durante o bloqueio de mutex distribuído do Discourse enquanto o PostCreator está criando um post. Verifique se o Redis está realmente sobrecarregado ou se o timeout está apenas muito agressivo durante uma importação longa.
Próximas verificações úteis seriam:
free -h
df -h
iostat -xz 1
vmstat 1
redis-cli INFO memory
redis-cli INFO stats
redis-cli SLOWLOG GET 20
Além disso, o banco de dados MySQL do phpBB está local na mesma droplet ou sendo lido pela rede? Como o rastreamento de pilha está iterando pelo mysql2, um banco de dados de origem lento ou um disco lento podem manter o uso da CPU baixo enquanto o importador aguarda.
Na taxa atual, de 333919 / 2167314 a cerca de 441 itens/min, você ainda tem aproximadamente 69 horas restantes, então a importação pode terminar, mas minha principal preocupação é se essas exceções de timeout do Redis estão causando a omissão de posts.
Eu não sugeriria aumentar UNICORN_WORKERS. Em uma execução de importação exclusiva, o Unicorn é em grande parte irrelevante. O importante é que a importação está continuando, mas pulando posts, e é isso que eu destacaria.
Os importadores em massa são ordens de grandeza mais rápidos, mas mais difíceis de configurar e fazer funcionar.
Na maioria das vezes, é isso mesmo. Consegui acelerar a importação adicionando índices, criando views e ajustando as configurações do banco de dados. Sugiro que você dedique um pouco de tempo a isso, porque, se você encontrar um erro nos seus dados mais tarde e precisar executar a importação novamente… será uma dor de cabeça ![]()
A propósito, estamos trabalhando em novas ferramentas que farão as migrações rodarem muito, muito mais rápido!
Ainda seguindo em frente!
var/www/discourse/script/import_scripts/phpbb3/importer.rb:38:in 'ImportScripts::PhpBB3::Importer#execute'
/var/www/discourse/script/import_scripts/base.rb:47:in 'ImportScripts::Base#perform'
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:22:in 'ImportScripts::PhpBB3::Importer#perform'
script/import_scripts/phpbb3.rb:35:in '<module:PhpBB3>'
script/import_scripts/phpbb3.rb:16:in '<module:ImportScripts>'
script/import_scripts/phpbb3.rb:15:in ''
606484 / 2167314 ( 28.0%) \[415 itens/min\] Exceção ao criar a postagem 608597. Pulando.
Aguardado 1,0 segundo
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/buffered_io.rb:214:in 'block in RedisClient::RubyConnection::BufferedIO#fill_buffer'
<internal:kernel>:168:in 'Kernel#loop'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/buffered_io.rb:197:in 'RedisClient::RubyConnection::BufferedIO#fill_buffer'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/buffered_io.rb:187:in 'RedisClient::RubyConnection::BufferedIO#ensure_remaining'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/buffered_io.rb:152:in 'RedisClient::RubyConnection::BufferedIO#getbyte'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/resp3.rb:113:in 'RedisClient::RESP3.parse'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection/resp3.rb:50:in 'RedisClient::RESP3.load'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/ruby_connection.rb:97:in 'RedisClient::RubyConnection#read'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/connection_mixin.rb:37:in 'RedisClient::ConnectionMixin#call'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client.rb:374:in 'block (2 levels) in RedisClient#call_v'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client/middlewares.rb:16:in 'RedisClient::BasicMiddleware#call'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client.rb:373:in 'block in RedisClient#call_v'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client.rb:781:in 'RedisClient#ensure_connected'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-client-0.28.0/lib/redis_client.rb:372:in 'RedisClient#call_v'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis/client.rb:90:in 'Redis::Client#call_v'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/mini_profiler/profiling_methods.rb:90:in 'block in Redis::Client#profile_method'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis.rb:152:in 'block in Redis#send_command'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis.rb:151:in 'Monitor#synchronize'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis.rb:151:in 'Redis#send_command'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/redis-5.4.0/lib/redis/commands/server.rb:178:in 'Redis::Commands::Server#time'
/var/www/discourse/lib/discourse_redis.rb:38:in 'Kernel#public_send'
/var/www/discourse/lib/discourse_redis.rb:38:in 'block in DiscourseRedis#method_missing'
/var/www/discourse/lib/discourse_redis.rb:29:in 'DiscourseRedis.ignore_readonly'
/var/www/discourse/lib/discourse_redis.rb:38:in 'DiscourseRedis#method_missing'
/var/www/discourse/lib/distributed_mutex.rb:55:in 'block in DistributedMutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in 'Thread::Mutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in 'DistributedMutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in 'DistributedMutex.synchronize'
/var/www/discourse/lib/post_creator.rb:410:in 'PostCreator#transaction'
/var/www/discourse/lib/post_creator.rb:200:in 'PostCreator#create'
/var/www/discourse/script/import_scripts/base.rb:611:in 'ImportScripts::Base#create_post'
/var/www/discourse/script/import_scripts/base.rb:555:in 'block in ImportScripts::Base#create_posts'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/mysql2/alias_method.rb:8:in 'Mysql2::Result#each'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/mysql2/alias_method.rb:8:in 'Mysql2::Result#each'
/var/www/discourse/script/import_scripts/base.rb:542:in 'ImportScripts::Base#create_posts'
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:212:in 'block in ImportScripts::PhpBB3::Importer#import_posts'
/var/www/discourse/script/import_scripts/base.rb:943:in 'block in ImportScripts::Base#batches'
<internal:kernel>:168:in 'Kernel#loop'
/var/www/discourse/script/import_scripts/base.rb:942:in 'ImportScripts::Base#batches'
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:293:in 'ImportScripts::PhpBB3::Importer#batches'
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:208:in 'ImportScripts::PhpBB3::Importer#import_posts'
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:38:in 'ImportScripts::PhpBB3::Importer#execute'
/var/www/discourse/script/import_scripts/base.rb:47:in 'ImportScripts::Base#perform'
/var/www/discourse/script/import_scripts/phpbb3/importer.rb:22:in 'ImportScripts::PhpBB3::Importer#perform'
script/import_scripts/phpbb3.rb:35:in '<module:PhpBB3>'
script/import_scripts/phpbb3.rb:16:in '<module:ImportScripts>'
script/import_scripts/phpbb3.rb:15:in ''
615718 / 2167314 ( 28.4%) \[415 itens/min\]
\[phpbbimpo0:docker\*
1746813 / 2167314 (80,6%) [353 itens/min]
Concluiu, mas esqueci de importar as senhas, então tenho que começar tudo de novo
Desta vez, vou eliminar alguns posts. Provavelmente tenho meio milhão de posts de jello e contagem regressiva, rs. Obrigado pelo conselho.
Não importamos senhas e, por questões de segurança, sugerimos que você também não o faça.
Após uma migração, os usuários são solicitados a redefinir suas senhas por meio do botão “Esqueci minha senha”. Isso representa um passo extra para eles, mas, se você explicar com antecedência por que é necessário e como fazê-lo, não deverá haver problemas.
Se forem auto-hospedados, podem usar o plugin Suporte a hashes de senha migrados. Ele não importa as senhas, mas sim os hashes das senhas, portanto, é tão seguro quanto as senhas eram no sistema antigo.
Com todo o respeito, mas não vejo fundamento para isso. Nosso plugin migratepassword existe há mais de uma década e não houve nenhum problema de segurança.
Desde que você mantenha a configuração migratepassword_allow_insecure_passwords desativada, ela imporá as mesmas restrições de segurança de senha que o núcleo do Discourse.
Eu concordo majoritariamente com você! Desde que a comunidade que você está migrando não tenha sofrido uma violação de dados, os dados foram transferidos com segurança durante a importação e você está usando as ferramentas adequadas (como o plugin de senhas), então é possível importar as senhas. Apenas não é algo que apoiemos oficialmente com os scripts de importação atualmente disponíveis no núcleo.
Muito do meu conteúdo não foi transferido, então vou tentar novamente no futuro. Há algo em desenvolvimento para acelerar o processo e importar senhas oficialmente? Tentei usar o plugin, mas algumas senhas não funcionaram. Os endereços de e-mail estavam desatualizados, então foi um pesadelo para mim. Vou tentar novamente no futuro.