Resumo
Bancos de dados tendem a manter muitos metadados, dados organizacionais, etc. Uma inserção é muito improvável que seja um simples acréscimo, como seria com um arquivo de texto. O teste do SQLite mostra que ele se comporta dessa maneira, nos modos WAL e não-WAL. Isso faz com que o rsync tenha que sincronizar muito mais dados do que você espera. Você pode reduzir um pouco essa sobrecarga usando um --block-size
baixo (ao custo de mais computação de sobrecarga e transferência de somas de verificação).
Uma abordagem melhor é provavelmente despejar novos registros como um dump SQL, compactá-lo e transferi-lo. Como alternativa, parece haver várias soluções de replicação para o SQLite, você pode usar uma delas.
roaima sugere que, no mínimo, você provavelmente poderia fazer um despejo SQL completo, compactá-lo usando gzip --rsyncable
e, em seguida, rsync isso. Vale a pena testar, suponho, para ver se é um delta pequeno o suficiente.
Detalhes
O que você está tentando deve funcionar. Eu pessoalmente adicionaria --partial
às suas opções de rsync, para o caso de de alguma forma detectar o arquivo crescente como uma transferência parcial. Você também pode obter estatísticas de transferência melhores com --stats
.
cmp -l
em duas versões - ver se há alterações em outras páginas além das finais. Lembre-se que a idéia de% " rsync
" de uma "página" / bloco é diferente da do SQLite; você pode mudar o rsync via --block-size
. Reduzir isso pode ajudar.
Edit: Eu fiz um teste rápido com o SQLite. Mesmo com 32k páginas, adicionando um monte de entradas de log rabiscadas na página every . Detalhes abaixo.
Editar 2 : Parece ser melhor no modo WAL, embora você ainda tenha uma enorme sobrecarga, provavelmente do ponto de verificação.
Editar 3 : Também é melhor quanto mais dados você adicionar por transferência, acho que provavelmente rabisca alguns blocos repetidas vezes. Então você está transferindo o mesmo conjunto de blocos, independentemente de ter escrito para eles uma ou cem vezes.
BTW: Para minimizar a transferência, você provavelmente pode fazer muito melhor que o rsync. Por exemplo, um despejo SQL de novos registros desde a última transferência executada por xz --best
(ou mesmo gzip
) provavelmente seria um pouco menor.
Teste rápido de SQLite
Esquema:
CREATE TABLE log (id integer primary key not null, ts integer not null, app text not null, message text not null);
CREATE INDEX log_ts_idx on log(ts);
CREATE INDEX log_app_idx on log(app);
Programa Perl:
use 5.022;
use DBI;
my $DBH = DBI->connect('dbi:SQLite:test.db', '', '', {RaiseError => 1, AutoCommit => 0})
or die "connect...";
my @apps = (
'[kthreadd]', '[ksoftirqd/0]',
⋮ # there were 191 of these
'[kworker/5:0H]',
);
my @messages = <DATA>;
(my $curr_time) = $DBH->selectrow_array(<<QUERY);
SELECT COALESCE(MAX(ts),978307200) FROM log
QUERY
my $n_apps = @apps;
my $n_msgs = @messages;
say "Apps: $n_apps";
say "Messages: $n_msgs";
say 'Start time: ', scalar gmtime($curr_time), ' UTC';
my $sth = $DBH->prepare(<<QUERY);
INSERT INTO log(ts, app, message) VALUES (?, ?, ?)
QUERY
for (my $i = 0; $i < 10_000; ++$i) {
$sth->execute(int($curr_time), $apps[int rand $n_apps], $messages[int rand $n_msgs]);
$curr_time += rand 0.1;
}
$DBH->commit;
__DATA__
microcode: CPU0 microcode updated early to revision 0x19, date = 2013-06-21
Linux version 4.5.0-2-amd64 ([email protected]) (gcc version 5.3.1 20160528 (Debian 5.3.1-21) ) #1 SMP Debian 4.5.5-1 (2016-05-29)
⋮
Havia muito mais mensagens de log de exemplo (2076).
Verificando quais páginas foram alteradas:
cp test.db test.db.old
perl test.pl
cmp -l test.db.old test.db | perl -n -E '/^\s*(\d+) / or die "wtf"; $bucket{int $1/32768} = 1; END { say join "\n", sort( { $a <=> $b } keys %bucket) }'