From 8e1ec8836dabc58dfc0115b36ed440b4371b70d7 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 28 Mar 2020 00:56:03 +0000 Subject: [PATCH] searchidxshard: ensure we set indexlevel on shard[0] For sharded v2 repositories with few-enough messages, it is possible for shard[0] to go unused and never trigger the ->commit_txn_lazy to set the indexlevel field in Xapian metadata. So set it immediately at initialization and avoid this case. While we're at it, avoid triggering needless pwrite syscalls from ->set_metadata by checking with ->get_metadata, first. --- lib/PublicInbox/SearchIdx.pm | 26 +++++++++++++++++--------- lib/PublicInbox/SearchIdxShard.pm | 4 +++- t/init.t | 7 ++++++- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/lib/PublicInbox/SearchIdx.pm b/lib/PublicInbox/SearchIdx.pm index 44b05813..7d089e7a 100644 --- a/lib/PublicInbox/SearchIdx.pm +++ b/lib/PublicInbox/SearchIdx.pm @@ -58,6 +58,7 @@ sub new { ibx_ver => $version, indexlevel => $indexlevel, }, $class; + $self->{-set_indexlevel_once} = 1 if $indexlevel eq 'medium'; $ibx->umask_prepare; if ($version == 1) { $self->{lock_path} = "$inboxdir/ssoma.lock"; @@ -842,20 +843,27 @@ sub begin_txn_lazy { }); } +# store 'indexlevel=medium' in v2 shard=0 and v1 (only one shard) +# This metadata is read by Admin::detect_indexlevel: +sub set_indexlevel { + my ($self) = @_; + + if (!$self->{shard} && # undef or 0, not >0 + delete($self->{-set_indexlevel_once})) { + my $xdb = $self->{xdb}; + my $level = $xdb->get_metadata('indexlevel'); + if (!$level || $level ne 'medium') { + $xdb->set_metadata('indexlevel', 'medium'); + } + } +} + sub commit_txn_lazy { my ($self) = @_; delete $self->{txn} or return; $self->{-inbox}->with_umask(sub { if (my $xdb = $self->{xdb}) { - - # store 'indexlevel=medium' in v2 shard=0 and - # v1 (only one shard) - # This metadata is read by Admin::detect_indexlevel: - if (!$self->{shard} # undef or 0, not >0 - && $self->{indexlevel} eq 'medium') { - $xdb->set_metadata('indexlevel', 'medium'); - } - + set_indexlevel($self); $xdb->commit_transaction; } $self->{over}->commit_lazy if $self->{over}; diff --git a/lib/PublicInbox/SearchIdxShard.pm b/lib/PublicInbox/SearchIdxShard.pm index 2b48b1b4..1ea01095 100644 --- a/lib/PublicInbox/SearchIdxShard.pm +++ b/lib/PublicInbox/SearchIdxShard.pm @@ -11,9 +11,11 @@ use IO::Handle (); # autoflush sub new { my ($class, $v2writable, $shard) = @_; - my $self = $class->SUPER::new($v2writable->{-inbox}, 1, $shard); + my $ibx = $v2writable->{-inbox}; + my $self = $class->SUPER::new($ibx, 1, $shard); # create the DB before forking: $self->_xdb_acquire; + $self->set_indexlevel; $self->_xdb_release; $self->spawn_worker($v2writable, $shard) if $v2writable->{parallel}; $self; diff --git a/t/init.t b/t/init.t index e20ff006..a78c2fc8 100644 --- a/t/init.t +++ b/t/init.t @@ -5,6 +5,7 @@ use warnings; use Test::More; use PublicInbox::Config; use PublicInbox::TestCommon; +use PublicInbox::Admin; use File::Basename; my ($tmpdir, $for_destroy) = tmpdir(); sub quiet_fail { @@ -72,11 +73,15 @@ SKIP: { quiet_fail($cmd, 'initializing V2 as V1 fails'); foreach my $lvl (qw(medium basic)) { + my $dir = "$tmpdir/v2$lvl"; $cmd = [ '-init', "v2$lvl", '-V2', '-L', $lvl, - "$tmpdir/v2$lvl", "http://example.com/v2$lvl", + $dir, "http://example.com/v2$lvl", "v2$lvl\@example.com" ]; ok(run_script($cmd), "-init -L $lvl"); is(read_indexlevel("v2$lvl"), $lvl, "indexlevel set to '$lvl'"); + my $ibx = PublicInbox::Inbox->new({ inboxdir => $dir }); + is(PublicInbox::Admin::detect_indexlevel($ibx), $lvl, + 'detected expected level w/o config'); } # loop for idempotency -- 2.44.0