##// END OF EJS Templates
revlog: fix a bug in revlog splitting...
revlog: fix a bug in revlog splitting Specifically, if the .i.s files are not added to the transaction, then a follow-up modification of such a file records it into transaction as non-empty, which is incorrect.

File last commit:

r51535:05d429fe stable
r51535:05d429fe stable
Show More
test-transaction-rollback-on-revlog-split.t
454 lines | 12.1 KiB | text/troff | Tads3Lexer
/ tests / test-transaction-rollback-on-revlog-split.t
Joerg Sonnenberger
revlog: fix index computation during inline->non-inline transition...
r48064 Test correctness of revlog inline -> non-inline transition
----------------------------------------------------------
backup: fix issue when the backup end up in a different directory...
r51348 We test various file length and naming pattern as this created issue in the
past.
revlog: update the split + transaction test...
r51237 Helper extension to intercept renames and kill process
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065
revlog: update the split + transaction test...
r51237 $ cat > $TESTTMP/intercept_before_rename.py << EOF
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 > import os
revlog: update the split + transaction test...
r51237 > import signal
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 > from mercurial import extensions, util
>
> def extsetup(ui):
revlog: improve the robustness of the splitting process...
r51242 > def rename(orig, src, dest, *args, **kwargs):
> path = util.normpath(dest)
> if path.endswith(b'data/file.i'):
revlog: update the split + transaction test...
r51237 > os.kill(os.getpid(), signal.SIGKILL)
revlog: improve the robustness of the splitting process...
r51242 > return orig(src, dest, *args, **kwargs)
> extensions.wrapfunction(util, 'rename', rename)
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 > EOF
revlog: add a failing variant of the the split + transaction test...
r51238 $ cat > $TESTTMP/intercept_after_rename.py << EOF
> import os
> import signal
> from mercurial import extensions, util
>
> def extsetup(ui):
> def close(orig, *args, **kwargs):
> path = util.normpath(args[0]._atomictempfile__name)
> r = orig(*args, **kwargs)
> if path.endswith(b'/.hg/store/data/file.i'):
> os.kill(os.getpid(), signal.SIGKILL)
> return r
> extensions.wrapfunction(util.atomictempfile, 'close', close)
revlog: improve the robustness of the splitting process...
r51242 > def extsetup(ui):
> def rename(orig, src, dest, *args, **kwargs):
> path = util.normpath(dest)
> r = orig(src, dest, *args, **kwargs)
> if path.endswith(b'data/file.i'):
> os.kill(os.getpid(), signal.SIGKILL)
> return r
> extensions.wrapfunction(util, 'rename', rename)
revlog: add a failing variant of the the split + transaction test...
r51238 > EOF
revlog: update the split + transaction test...
r51237 $ cat > $TESTTMP/killme.py << EOF
> import os
> import signal
>
> def killme(ui, repo, hooktype, **kwargs):
> os.kill(os.getpid(), signal.SIGKILL)
> EOF
revlog: test possible read race condition with splitting...
r51239 $ cat > $TESTTMP/reader_wait_split.py << EOF
> import os
> import signal
> from mercurial import extensions, revlog, testing
> def _wait_post_load(orig, self, *args, **kwargs):
> wait = b'data/file' in self.radix
> if wait:
> testing.wait_file(b"$TESTTMP/writer-revlog-split")
> r = orig(self, *args, **kwargs)
> if wait:
> testing.write_file(b"$TESTTMP/reader-index-read")
> testing.wait_file(b"$TESTTMP/writer-revlog-unsplit")
> return r
>
> def extsetup(ui):
> extensions.wrapfunction(revlog.revlog, '_loadindex', _wait_post_load)
> EOF
revlog: update the split + transaction test...
r51237 setup a repository for tests
----------------------------
$ cat >> $HGRCPATH << EOF
> [format]
> revlog-compression=none
> EOF
$ hg init troffset-computation
$ cd troffset-computation
revlog: test more complex file pattern for revlog split...
r51346 $ files="
> file
> Directory_With,Special%Char/Complex_File.babar
> foo/bar/babar_celeste/foo
backup: fix issue when the backup end up in a different directory...
r51348 > 1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/1234567890/f
revlog: test more complex file pattern for revlog split...
r51346 > "
$ for f in $files; do
> mkdir -p `dirname $f`
> done
$ for f in $files; do
> printf '%20d' '1' > $f
> done
revlog: update the split + transaction test...
r51237 $ hg commit -Aqma
revlog: test more complex file pattern for revlog split...
r51346 $ for f in $files; do
> printf '%1024d' '1' > $f
> done
revlog: update the split + transaction test...
r51237 $ hg commit -Aqmb
revlog: test more complex file pattern for revlog split...
r51346 $ for f in $files; do
> printf '%20d' '1' > $f
> done
revlog: update the split + transaction test...
r51237 $ hg commit -Aqmc
revlog: test more complex file pattern for revlog split...
r51346 $ for f in $files; do
> dd if=/dev/zero of=$f bs=1k count=128 > /dev/null 2>&1
> done
revlog: improve the robustness of the splitting process...
r51242 $ hg commit -AqmD --traceback
Arseniy Alekseyev
revlog: fix a bug in revlog splitting...
r51535 $ for f in $files; do
> dd if=/dev/zero of=$f bs=1k count=132 > /dev/null 2>&1
> done
$ hg commit -AqmD --traceback
revlog: update the split + transaction test...
r51237
Reference size:
$ f -s file
Arseniy Alekseyev
revlog: fix a bug in revlog splitting...
r51535 file: size=135168
revlog: update the split + transaction test...
r51237 $ f -s .hg/store/data/file*
Arseniy Alekseyev
revlog: fix a bug in revlog splitting...
r51535 .hg/store/data/file.d: size=267307
.hg/store/data/file.i: size=320
revlog: update the split + transaction test...
r51237
$ cd ..
Test a hard crash after the file was split but before the transaction was committed
===================================================================================
Arseniy Alekseyev
revlog: demonstrate a bug where transaction can be aborted partially...
r49422 Test offset computation to correctly factor in the index entries themselves.
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 Also test that the new data size has the correct size if the transaction is aborted
after the index has been replaced.
Arseniy Alekseyev
revlog: demonstrate a bug where transaction can be aborted partially...
r49422 Test repo has commits a, b, c, D, where D is large (grows the revlog enough that it
transitions to non-inline storage). The clone initially has changes a, b
and will transition to non-inline storage when adding c, D.
If the transaction adding c, D is rolled back, then we don't undo the revlog split,
but truncate the index and the data to remove both c and D.
Joerg Sonnenberger
revlog: fix index computation during inline->non-inline transition...
r48064
Arseniy Alekseyev
revlog: demonstrate a bug where transaction can be aborted partially...
r49422
revlog: update the split + transaction test...
r51237 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy
Joerg Sonnenberger
revlog: fix index computation during inline->non-inline transition...
r48064 $ cd troffset-computation-copy
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065
Reference size:
revlog: update the split + transaction test...
r51237 $ f -s file
file: size=1024
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 $ f -s .hg/store/data/file*
.hg/store/data/file.i: size=1174
Joerg Sonnenberger
revlog: fix index computation during inline->non-inline transition...
r48064 $ cat > .hg/hgrc <<EOF
> [hooks]
revlog: update the split + transaction test...
r51237 > pretxnchangegroup = python:$TESTTMP/killme.py:killme
Joerg Sonnenberger
revlog: fix index computation during inline->non-inline transition...
r48064 > EOF
#if chg
$ hg pull ../troffset-computation
pulling from ../troffset-computation
[255]
#else
$ hg pull ../troffset-computation
pulling from ../troffset-computation
pacien
test-tx-rollback: more lenient glob for kill status (issue6807)...
r51277 *Killed* (glob)
revlog: update the split + transaction test...
r51237 [137]
Joerg Sonnenberger
revlog: fix index computation during inline->non-inline transition...
r48064 #endif
revlog: update the split + transaction test...
r51237
revlog: improve the robustness of the splitting process...
r51242 The inline revlog still exist, but a split version exist next to it
revlog: update the split + transaction test...
r51237
Arseniy Alekseyev
revlog: fix a bug in revlog splitting...
r51535 $ cat .hg/store/journal | tr '\0' ' ' | grep '\.s'
[1]
revlog: update the split + transaction test...
r51237 $ f -s .hg/store/data/file*
Arseniy Alekseyev
revlog: fix a bug in revlog splitting...
r51535 .hg/store/data/file.d: size=267307
revlog: improve the robustness of the splitting process...
r51242 .hg/store/data/file.i: size=132395
Arseniy Alekseyev
revlog: fix a bug in revlog splitting...
r51535 .hg/store/data/file.i.s: size=320
revlog: update the split + transaction test...
r51237
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065
Arseniy Alekseyev
revlog: demonstrate a bug where transaction can be aborted partially...
r49422 The first file.i entry should match the "Reference size" above.
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 The first file.d entry is the temporary record during the split,
revlog: update the split + transaction test...
r51237
revlog: improve the robustness of the splitting process...
r51242 A "temporary file" entry exist for the split index.
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065
$ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
data/file.i 1174
data/file.d 0
revlog: improve the robustness of the splitting process...
r51242 $ cat .hg/store/journal.backupfiles | tr -s '\000' ' ' | tr -s '\00' ' '| grep data/file
data/file.i data/journal.backup.file.i 0
data/file.i.s 0
recover is rolling the split back, the fncache is still valid
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066 $ hg recover
rolling back interrupted transaction
(verify step skipped, run `hg verify` to check your repository content)
$ f -s .hg/store/data/file*
revlog: improve the robustness of the splitting process...
r51242 .hg/store/data/file.i: size=1174
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066 $ hg tip
backup: fix issue when the backup end up in a different directory...
r51348 changeset: 1:cc8dfb126534
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066 tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
Arseniy Alekseyev
revlog: demonstrate a bug where transaction can be aborted partially...
r49422 summary: b
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066
Valentin Gatien-Baron
test: reduce noise, so the important bits stand out...
r48688 $ hg verify -q
Valentin Gatien-Baron
debugrebuildfncache: add a cheaper option to rebuild the fncache...
r48689 $ hg debugrebuildfncache --only-data
revlog: improve the robustness of the splitting process...
r51242 fncache already up to date
Valentin Gatien-Baron
debugrebuildfncache: add a cheaper option to rebuild the fncache...
r48689 $ hg verify -q
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 $ cd ..
revlog: update the split + transaction test...
r51237 Test a hard crash right before the index is move into place
===========================================================
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066
Now retry the procedure but intercept the rename of the index and check that
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 the journal does not contain the new index size. This demonstrates the edge case
where the data file is left as garbage.
revlog: update the split + transaction test...
r51237 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy2
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 $ cd troffset-computation-copy2
revlog: update the split + transaction test...
r51237
Reference size:
$ f -s file
file: size=1024
$ f -s .hg/store/data/file*
.hg/store/data/file.i: size=1174
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 $ cat > .hg/hgrc <<EOF
> [extensions]
revlog: update the split + transaction test...
r51237 > intercept_rename = $TESTTMP/intercept_before_rename.py
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 > EOF
#if chg
$ hg pull ../troffset-computation
pulling from ../troffset-computation
revlog: improve the robustness of the splitting process...
r51242 searching for changes
adding changesets
adding manifests
adding file changes
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 [255]
#else
$ hg pull ../troffset-computation
pulling from ../troffset-computation
revlog: improve the robustness of the splitting process...
r51242 searching for changes
adding changesets
adding manifests
adding file changes
pacien
test-tx-rollback: more lenient glob for kill status (issue6807)...
r51277 *Killed* (glob)
revlog: update the split + transaction test...
r51237 [137]
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 #endif
revlog: update the split + transaction test...
r51237
revlog: improve the robustness of the splitting process...
r51242 The inline revlog still exist, but a split version exist next to it
revlog: update the split + transaction test...
r51237
$ f -s .hg/store/data/file*
Arseniy Alekseyev
revlog: fix a bug in revlog splitting...
r51535 .hg/store/data/file.d: size=267307
revlog: update the split + transaction test...
r51237 .hg/store/data/file.i: size=132395
Arseniy Alekseyev
revlog: fix a bug in revlog splitting...
r51535 .hg/store/data/file.i.s: size=320
revlog: update the split + transaction test...
r51237
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
data/file.i 1174
data/file.d 0
revlog: improve the robustness of the splitting process...
r51242
recover is rolling the split back, the fncache is still valid
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066
$ hg recover
rolling back interrupted transaction
(verify step skipped, run `hg verify` to check your repository content)
$ f -s .hg/store/data/file*
.hg/store/data/file.i: size=1174
$ hg tip
backup: fix issue when the backup end up in a different directory...
r51348 changeset: 1:cc8dfb126534
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066 tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
Arseniy Alekseyev
revlog: demonstrate a bug where transaction can be aborted partially...
r49422 summary: b
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066
Valentin Gatien-Baron
test: reduce noise, so the important bits stand out...
r48688 $ hg verify -q
Joerg Sonnenberger
revlog: update data file record before index rename...
r48065 $ cd ..
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066
revlog: add a failing variant of the the split + transaction test...
r51238 Test a hard crash right after the index is move into place
===========================================================
Now retry the procedure but intercept the rename of the index.
$ hg clone --quiet --rev 1 troffset-computation troffset-computation-crash-after-rename
$ cd troffset-computation-crash-after-rename
Reference size:
$ f -s file
file: size=1024
$ f -s .hg/store/data/file*
.hg/store/data/file.i: size=1174
$ cat > .hg/hgrc <<EOF
> [extensions]
> intercept_rename = $TESTTMP/intercept_after_rename.py
> EOF
#if chg
$ hg pull ../troffset-computation
pulling from ../troffset-computation
revlog: improve the robustness of the splitting process...
r51242 searching for changes
adding changesets
adding manifests
adding file changes
revlog: add a failing variant of the the split + transaction test...
r51238 [255]
#else
$ hg pull ../troffset-computation
pulling from ../troffset-computation
revlog: improve the robustness of the splitting process...
r51242 searching for changes
adding changesets
adding manifests
adding file changes
pacien
test-tx-rollback: more lenient glob for kill status (issue6807)...
r51277 *Killed* (glob)
revlog: add a failing variant of the the split + transaction test...
r51238 [137]
#endif
revlog: improve the robustness of the splitting process...
r51242 The inline revlog was over written on disk
revlog: add a failing variant of the the split + transaction test...
r51238
$ f -s .hg/store/data/file*
Arseniy Alekseyev
revlog: fix a bug in revlog splitting...
r51535 .hg/store/data/file.d: size=267307
.hg/store/data/file.i: size=320
revlog: add a failing variant of the the split + transaction test...
r51238
$ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
data/file.i 1174
data/file.d 0
revlog: improve the robustness of the splitting process...
r51242
recover is rolling the split back, the fncache is still valid
revlog: add a failing variant of the the split + transaction test...
r51238
$ hg recover
rolling back interrupted transaction
revlog: improve the robustness of the splitting process...
r51242 (verify step skipped, run `hg verify` to check your repository content)
revlog: add a failing variant of the the split + transaction test...
r51238 $ f -s .hg/store/data/file*
revlog: improve the robustness of the splitting process...
r51242 .hg/store/data/file.i: size=1174
revlog: add a failing variant of the the split + transaction test...
r51238 $ hg tip
backup: fix issue when the backup end up in a different directory...
r51348 changeset: 1:cc8dfb126534
revlog: add a failing variant of the the split + transaction test...
r51238 tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: b
$ hg verify -q
$ cd ..
revlog: update the split + transaction test...
r51237 Have the transaction rollback itself without any hard crash
===========================================================
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066
Repeat the original test but let hg rollback the transaction.
revlog: update the split + transaction test...
r51237 $ hg clone --quiet --rev 1 troffset-computation troffset-computation-copy-rb
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066 $ cd troffset-computation-copy-rb
$ cat > .hg/hgrc <<EOF
> [hooks]
> pretxnchangegroup = false
> EOF
$ hg pull ../troffset-computation
pulling from ../troffset-computation
searching for changes
adding changesets
adding manifests
adding file changes
transaction abort!
rollback completed
abort: pretxnchangegroup hook exited with status 1
[40]
revlog: update the split + transaction test...
r51237
revlog: improve the robustness of the splitting process...
r51242 The split was rollback
revlog: update the split + transaction test...
r51237
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066 $ f -s .hg/store/data/file*
revlog: improve the robustness of the splitting process...
r51242 .hg/store/data/file.d: size=0
.hg/store/data/file.i: size=1174
revlog: update the split + transaction test...
r51237
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066 $ hg tip
backup: fix issue when the backup end up in a different directory...
r51348 changeset: 1:cc8dfb126534
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066 tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
Arseniy Alekseyev
revlog: demonstrate a bug where transaction can be aborted partially...
r49422 summary: b
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066
Valentin Gatien-Baron
test: reduce noise, so the important bits stand out...
r48688 $ hg verify -q
Joerg Sonnenberger
recover: only apply last journal record per file (issue6423)...
r48066 $ cd ..
revlog: test possible read race condition with splitting...
r51239 Read race
=========
We check that a client that started reading a revlog (its index) after the
split and end reading (the data) after the rollback should be fine
$ hg clone --quiet --rev 1 troffset-computation troffset-computation-race
$ cd troffset-computation-race
$ cat > .hg/hgrc <<EOF
> [hooks]
> pretxnchangegroup=$RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/reader-index-read $TESTTMP/writer-revlog-split
> pretxnclose = false
> EOF
start a reader
$ hg cat --rev 0 file \
> --config "extensions.wait_read=$TESTTMP/reader_wait_split.py" \
> 2> $TESTTMP/reader.stderr \
> > $TESTTMP/reader.stdout &
Do a failed pull in //
$ hg pull ../troffset-computation
pulling from ../troffset-computation
searching for changes
adding changesets
adding manifests
adding file changes
transaction abort!
rollback completed
abort: pretxnclose hook exited with status 1
[40]
$ touch $TESTTMP/writer-revlog-unsplit
$ wait
The reader should be fine
$ cat $TESTTMP/reader.stderr
$ cat $TESTTMP/reader.stdout
1 (no-eol)
$ cd ..
revlog: test that pending hooks properly see the repository on split...
r51240
pending hooks
=============
We checks that hooks properly see the inside of the transaction, while other process don't.
$ hg clone --quiet --rev 1 troffset-computation troffset-computation-hooks
$ cd troffset-computation-hooks
$ cat > .hg/hgrc <<EOF
> [hooks]
> pretxnclose.01-echo = hg cat -r 'max(all())' file | f --size
> pretxnclose.02-echo = $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/hook-done $TESTTMP/hook-tr-ready
> pretxnclose.03-abort = false
> EOF
$ (
> $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/hook-tr-ready;\
> hg cat -r 'max(all())' file | f --size;\
> touch $TESTTMP/hook-done
> ) >stdout 2>stderr &
$ hg pull ../troffset-computation
pulling from ../troffset-computation
searching for changes
adding changesets
adding manifests
adding file changes
Arseniy Alekseyev
revlog: fix a bug in revlog splitting...
r51535 size=135168
revlog: test that pending hooks properly see the repository on split...
r51240 transaction abort!
rollback completed
abort: pretxnclose.03-abort hook exited with status 1
[40]
$ cat stdout
size=1024
$ cat stderr
$ cd ..