use mysqldump --opt <database> <tablename>
para criar um dump de sua tabela e alimentá-lo em seu novo servidor. Como aparentemente você tem acesso ao banco de dados remoto via TCP / IP, você simplesmente poderia usar
mysqldump --opt --user=<youruser> --password=<yourpassword> -host <yourhost> \
<yourDB> <yourtable> | mysql -u <newserveruser> -p<password>
para conectar-se ao banco de dados remoto, despejá-lo e alimentar a saída em seu novo servidor.
Se você não tivesse acesso TCP / IP direto ao banco de dados remoto, ainda assim poderia fazer o mesmo tunelando os dados por meio do SSH após configurar autenticação de chave pública :
ssh -C -l <remoteuser> <remoteserver> \
'mysqldump --opt --user=<youruser> --password=<yourpassword> <yourDB> <yourtable>' \
| mysql -u <newserveruser> -p<password>
Consulte a documentação para mysqldump
e o man page para SSH para mais detalhes.
Se você precisar de mais eficiência de largura de banda, considere criar um dump com mysqldump
, armazenando-o no servidor de origem e usando rsync
para copiar / atualizar o equivalente no servidor de destino antes de importar. Como rsync
criará somas de verificação de rolagem na origem e no arquivo de destino, provavelmente não será necessário transferir a maior parte do o conteúdo do despejo em execuções subseqüentes.
Houve um patch mysqldump que foi usado para usar tabelas temporárias ao inserir linhas e renomear a tabela para o nome da tabela original para reduzir o tempo de bloqueio, mas eu consideraria experimental, pois tem problemas não resolvidos e nunca entrou em o ramo principal. Veja esta discussão para o código de correção e detalhes.
Se você simplesmente não consegue largar a tabela no destino por qualquer motivo, você pode inserir os dados despejados em uma nova tabela (uma abordagem rápida e um pouco insegura canalizaria a saída mysqldump
para sed -e 's/mytable/newtable/g'
antes de canalizar mais para mysql
) e, em seguida, executar um ciclo UPDATE / DELETE / INSERT com um par de JOINs como este ( não testado , faça uma verificação de sanidade):
/* set write lock on the table so it cannot be read while updating */
LOCK TABLES mytable WRITE;
/* update all rows which are present in mytable and newtable */
UPDATE mytable AS M LEFT JOIN newtable AS N ON M.primarykey = N.primarykey
SET M.column1=N.column1, M.column2=N.column2 [...]
WHERE N.primarykey Is Not NULL;
/* delete all rows from mytable which are no longer present in newtable */
DELETE M FROM mytable AS M LEFT JOIN newtable AS N on M.primarykey = N.primarykey
WHERE N.primarykey Is NULL;
/* insert new rows from newtable */
INSERT INTO mytable (primarykey, column1, column2, [...])
SELECT (N.primarykey, N.column1, N.column2, [...]) FROM mytable AS M
RIGHT JOIN newtable AS N ON M.primarykey=N.primarykey WHERE M.primarykey Is NULL
/* release lock */
UNLOCK TABLES;
Nota: é claro, os dados do seu banco de dados seriam inconsistentes enquanto você estiver inserindo / atualizando seus dados, mas contanto que você não esteja usando transações (não disponível para tabelas MyISAM), isso seria o caso não importa o que você faça - derrubar e recriar a tabela criaria inconsistências temporárias, assim como fazer o ciclo de atualização / exclusão / inserção. Isso se deve à própria natureza de um design sem transações atômico do MyISAM.