요약
데이터베이스는 많은 메타 데이터, 조직 데이터 등을 유지하는 경향이 있습니다. 삽입은 텍스트 파일과 같이 단순한 추가 일 가능성이 거의 없습니다. SQLite를 테스트하면 WAL 및 비 WAL 모드에서 모두 작동합니다. 이로 인해 rsync는 예상보다 훨씬 많은 데이터를 동기화해야합니다. --block-size더 많은 오버 헤드 컴퓨팅 및 체크섬 전송 비용으로 낮은 비용을 사용하여이 오버 헤드를 다소 줄일 수 있습니다 .
더 나은 방법은 새 레코드를 SQL 덤프로 덤프하고 압축하여 전송하는 것입니다. 또는 SQLite에 대한 여러 가지 복제 솔루션이있는 것으로 보이며 그 중 하나를 사용할 수 있습니다.
roaima 는 최소한 전체 SQL 덤프를 수행하고를 사용하여 압축 gzip --rsyncable한 다음 재 동기화 할 수 있다고 제안 합니다. 그것이 델타가 충분히 작은 지 테스트 할 가치가 있다고 생각합니다.
세부
당신이 시도하는 것이 작동 해야 합니다. --partial어떻게 든 증가하는 파일을 부분 전송으로 감지하는 경우를 대비하여 개인적으로 rsync 옵션에 추가하고 싶습니다 . 로 더 나은 이전 통계를 얻을 수도 있습니다 --stats.
두 번째로 확인해야 할 것은 SQLite가 실제로 몇 페이지 만 터치하는지 여부입니다. 솔직히 파일 전체에 페이지를 작성하는 경우 놀라지 않을 것입니다. 확인하는 한 가지 빠른 방법 cmp -l은 두 가지 버전 에서 사용 하는 것입니다. 마지막 몇 페이지 이외의 페이지가 변경되었는지 확인하십시오. 기억 rsync은 "페이지"의의 생각은 / 블록 SQLite는의 다릅니다; 를 통해 rsync를 변경할 수 있습니다 --block-size. 그것을 줄이는 것이 도움이 될 수 있습니다.
편집 : SQLite로 빠른 테스트를 수행했습니다. 32k 페이지에서도 모든 페이지 에 많은 로그 항목이 추가 됩니다. 자세한 내용은 아래를 참조하십시오.
편집 2 : WAL 모드에서 더 나은 것처럼 보이지만 검사 점에서 여전히 많은 오버 헤드가 발생합니다.
편집 3 : 전송마다 추가하는 데이터가 많을수록 좋습니다. 특정 블록을 반복해서 낙서하는 것 같습니다. 따라서 블록에 한 번 또는 백 번 쓴지 여부에 관계없이 동일한 블록 세트를 전송합니다.
BTW : 전송을 최소화하기 위해 아마도 rsync보다 훨씬 더 낫습니다. 예를 들어, 마지막 전송 실행 이후 xz --best(또는 심지어 gzip) 이후에 새 레코드의 SQL 덤프는 약간 더 작을 수 있습니다.
빠른 SQLite 테스트
개요:
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);
펄 프로그램 :
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 (debian-kernel@lists.debian.org) (gcc version 5.3.1 20160528 (Debian 5.3.1-21) ) #1 SMP Debian 4.5.5-1 (2016-05-29)
⋮
더 많은 예제 로그 메시지가있었습니다 (2076).
변경된 페이지 확인 :
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) }'
but with the exception of the last 4k page (or maybe a few) the file is identical each time.실제로 확인 했습니까cmp? 아니면 더 나은가xdelta? 전송 크기를 최소화하려면 이전 버전과 새 버전을 로컬로 유지하십시오. 따라서 rsync 이외의 다른 방법으로 로컬에서 최소 이진 diff를 계산하고 계량 연결을 통해 체크섬을 보내지 않고도 보낼 수 있습니다. 이진 파일 수준 대신 데이터베이스 레코드 수준에서이 작업을 수행하는 것이 derobert가 제안한 것처럼 더 좋습니다.