Commit graph

238 commits

Author SHA1 Message Date
Ben Johnson
9ebf0e2119 Upgrade go.mod to featurebase/v3 2022-01-21 10:57:05 -07:00
Seebs
6fba8aba8b track field directly in view to prevent deadlocks
The central reason this exists:

**sync.RWMutex can block read locks even when no write lock is yet held.**

If a write lock is *requested*, this can block future read locks. In
particular, this means that recursive read locks are unsafe. But there's
additional problems.

The specific case that bit us involves not two, but *three* things
running at once.

Thing #1: executor doing AvailableShards. This RLocks the index, and
then each field, and then each view. To complete, it must be able to
obtain a read lock on each view in turn.

Thing #2: DeleteField. This Locks the index. Even if it is stuck
waiting for the lock (which it will be until AvailableShards completes),
it can prevent *additional* RLocks of the index.

Thing #3: CreateFragment. This Locks a view, then RLocks the index in
order to look up a field.

CreateFragment can't proceed until DeleteField completes. DeleteField
can't proceed until AvailableShards completes. And AvailableShards
can't proceed until CreateFragment completes.

Solution: Cache the *Field in the view, so we don't need a read lock
on the field or index to complete a CreateFragment.
2022-01-13 13:16:57 -06:00
reesporte
b13538e426 update doc comment 2022-01-03 11:16:14 -06:00
reesporte
72adb177ae Merge branch 'master' into percentile-timestamp-decimal 2022-01-03 11:12:23 -06:00
reesporte
99f6a1c113 change min to val
bc it could be used for things besides mins
2022-01-03 10:45:23 -06:00
Seebs
ddb5020aa6 slightly better lock protection around bitDepth in view
There's a number of deeper issues here (the fragment is conjuring
up a Tx, for instance) but this helps.

Also use field.view() to get the view rather than accessing viewMap
directly without a lock. Also change field.cacheBitDepth to ratchet
upwards -- if we have multiple shards and some shards have lower
depths than others, we should use the highest as the cached value,
not the most recent.
2021-12-20 15:09:27 -06:00
Matthew Jaffee
7935624549 implement percentiles on timestamp/decimal, still needs tests 2021-12-10 15:21:29 -06:00
Matthew Jaffee
aff3d3ddd9 do a backup in a go test for coverage purposes
also found a weird issue with schema marshalling

if you create a field thru the api w/o specifying a field type, you
get slightly different behavior than going thru the HTTP handler which
is... not ideal. I changed the marshaler to accept an empty field type.
2021-12-10 11:52:39 -06:00
reesporte
48aef0c8a4 add copyright notice back in
```bash
for file in `cat diffys`; do
   printf '%s\n%s\n' "// Copyright 2021 Molecula Corp. All rights reserved." "$(cat $file)" >$file;
done
```
2021-12-10 11:01:04 -06:00
reesporte
4c53f86e82 removed license from each go file
i used this script, a little clunky but it got the job done

```bash
for file in `find . -type f -print | grep '\.go'`; do
    sed '1,/^\/\/ limitations under the License.$/d' $file > $file.tmp;
    result=`cat $file.tmp`
    if [[ result != "" ]]; then
        gofmt $file.tmp &> /dev/null;
        if [[ $? == 0 ]]; then
            mv $file.tmp $file && gofmt -w $file;
        else
            rm $file.tmp;
        fi
    else
        rm $file.tmp;
    fi
done
```
2021-12-10 09:17:17 -06:00
Seebs
d4b06d077e Import/ImportValue API rework and improvements
Underlying goal: Don't use the http client to send messages back to the
local host. Also, when sending data to other nodes, don't collate it
from an ImportRequest into a completely different format, then immediately
collate that back into an ImportRequest. This does require changing
the logic over in ctl/import to make it create an ImportRequest.

Also, add additional testing to make sure we're actually trying anything
at all with several combinations (such as submitting import requests
which don't match the configuration of index or field), and improve
test coverage for that.

This introduces the ability to tell an http/client InternalClient about
a specific API that it should use for local queries where applicable.
That's not implemented outside of the import stuff, but should probably
be applied eventually to other things that are trying to talk to many
nodes one of which may be the local node. That behavior is contingent
on passing in a Qcx, because it is implicitly tied to an existing
execution context, and it can't assume that it can create a new one,
because that could deadlock.
2021-11-05 13:06:38 -05:00
kcrodgers24
b2c73b6a41 changes error message text for additional clarity 2021-10-08 09:47:16 -07:00
kcrodgers24
1f257aab9c adds more detail to CSV ingest error message 2021-10-08 08:27:49 -07:00
Seebs
214a1492a8 kill off a ton more fsyncs
Performance of tests on MacOS has been atrocious for a while, and
a lot of that is fsync, so we're trying to make that optional.

To test all of this, I modified RBF to panic if anything tried to
open an RBF database without disabling fsync, and ran the tests that
way, and tracked down the various places this could still happen.

There's a lot of places in our tree where we were creating
test holders which were not getting created with fsync disabled, which
results in a surprisingly large number of points at which we end
up calling fsync in tests, which makes tests much slower than they
need to be. There's also a bunch of places where the flags don't get
propagated correctly; for instance, storage.fsync didn't propagate
to the RBFConfig.

We add an "fsync enabled" flag to OpenTranslateStoreFunc, so we can
tell translation stores that we don't need syncing, so the server's
config can be passed on appropriately.

More of the test code that sets things up is correctly configuring
that flag by default.

We also change the barely-used bolt storage backend to support this as
well.

With this done, the only calls to fsync left in a run of `go test -short`
in the top-level directory are from the zap logger in etcd, and consumed
around 0.03 seconds. The overall impact is that `go test -short`
went from "takes enough more than 10 minutes that i don't know how long
it takes" to about 2.5 minutes.
2021-10-01 10:45:08 -05:00
Matthew Jaffee
3e222d8771 tweak to locking which should avoid stall/deadlock w/ mutex check
The view.go change is straightforward and fairly obviously more
correct.

The field.go change avoids holding the field read lock for the
duration of the mutex check request. The thinking was that while the
read lock was held something else was attempting to get a write lock,
which blocked all other read locks and something was getting into a
loop. Seebs might have a more detailed explanation, but that's as far
as my understanding goes at the moment. I believe this change is safe
though as we don't read/modify any field level data structures after
grabbing the standard view.
2021-09-16 14:07:31 -05:00
Seebs
26d38c0ee0 make details optional and support limits on mutex checks
We support query parameters for details (default false) which
request additional data, and for a limit (default 0/MaxInt32)
on number of results returned to limit the amount of spam
produced if there's a lot of results. The simpler default
output should reduce load and runtime significantly, and the
ability to specify limits makes it easier to get reasonably
small responses.

There's some context support here, but the underlying filters
don't take contexts or check for them, which is probably
a flaw but might be a bit large to correct for this.
Despite being large, this set of changes is actually
fairly well contained within the mutex-checking code.
2021-09-08 11:59:47 -05:00
Seebs
b391ab9153 mutex sanity-check
This implements a fairly straightforward sanity-check for mutexes,
implemented as a bitmapfilter at the fragment level, and with higher
levels combining results. There's two endpoints, an internal endpoint
which only checks the local node's shards, and an external one which
forwards requests (using the internal endpoint) to all the other nodes.

The internal endpoint does not do key translation, the external one
does.

The transmission format is a probably-inefficient JSON blob, and
returns data separated per-shard so we don't have as much merging
work to do.

This introduces a horrifying monstrosity function which tries to
sneakily corrupt mutex fields and which has to be exported (EWWWWW)
but which is only present in _test code (!??!! THIS WORKS WHY).

Also one typo fix in unrelated code caused by not wanting to keep
fighting with gofmt about this.
2021-09-07 12:41:49 -05:00
Seebs
016765d8a2 Prototype ingest API
This partially-implemented prototype of the ingest API is based on our
programmatic ingest API reference. It has noticable limitations, most
crucially that it doesn't handle multi-node clusters right now. However,
it basically implements the expected semantics.

There's some noticeable performance issues to do with the high overhead
of sorting bits in order to import them efficiently, but this is fixable.

We also add the hooks to the internal client, and make the finisher logic
a bit smarter.

Much of this code was originally by Nia Weiss, but it's been merged
and restructured a bit to get things broken into logical commits.
2021-08-19 09:50:59 -05:00
Seebs
423cddbdbb avoid allocations in viewsByTime
This is sort of horrible, but viewsByTime was about 25% of total CPU time in
the ingest path, NOT including increased GC overhead. This overoptimized
approach to letting us recycle a buffer, and use the same buffer for multiple
time views at once, reduces that to about 2.5%. Sorry for the mess.

We also streamline the process of building the per-view data sets a bit,
and streamline it a lot in the non-time-quantum case.
2021-08-18 13:45:36 -05:00
Seebs
f019cc7409 make import correctly reflect that it needs a single shard always
In fact, we have a number of things assuming that values passed to Import
always fit within a single known shard, so, drop all the extra complexity
around this, drop the computation of fancy view/shard keys, and so on.

There's a lot of room left to improve this probably but it's at least
better, I think.

Unfortunately, there's a handful of things, basically all of which are
test cases, which were relying on this, so, we also add functionality
for splitting import requests by shards. But this allows us to stop
duplicating each shard's inputs one at a time... which turns out to
mean that we now care that the import operation can write back to the
import request. This only affects test cases, so we adopt a crufty
hack involving cloning import requests in those rare cases, and also
when reusing the same column IDs to write to the existence field that
we'd be using later to write to another field.

Note that even if we weren't overwriting the column IDs with positions,
we'd be sorting the column/row ID lists by row-then-column, which means
we'd still be corrupting the column ID lists. This may want to change
at some point.

We also reuse a single Tx for all the views, because DB-per-shard
means that should work fine, and reduces the cost of doing these
updates, probably.
2021-08-18 13:45:36 -05:00
Seebs
1745a93aee allow "us" for microseconds in timestamp units
The convention of using a "u" for "micro" is pretty well-established and some
people will have trouble typing the Greek letter, accept that as a synonym.
2021-08-18 13:45:36 -05:00
Seebs
e768fc89ea stop using pointers to time.Time
We're reading timestamps as []int64, instead of allocating a time.Time
for each timestamp, just use the same logic to determine whether to use the
int64 timestamp that we would have used to decide whether to allocate it.
We still have to check the whole run, though, because we're providing a large
list of 0s instead of "no timestamps", for Reasons.
2021-08-18 13:45:36 -05:00
Mahesh Arumugam
858f889745 FeatureBase Renaming: changing go.mod module name for featurebase 2021-07-19 09:20:30 -07:00
Todd Gruben
b25ad81e67 restore without restart 2021-05-21 09:27:08 -05:00
Seebs
7c4b91eef0 simplify field ImportValue
There's only ever one view in importValue, but there's also only ever
one shard, because importValue is only called by things called from
the API after it has split everything up by shard.
2021-05-20 12:39:27 -05:00
Nia Weiss
f4ba34247f
remove attributes
Attributes are unmaintained and unused.
They have become more of a liability than a benefit.
This change eliminates them from the codebase.
The only user-visible change (assuming that attrs are not used) is that the attrs field will no longer appear in row JSON.
2021-05-14 10:28:08 -04:00
Kuba Podgórski
17f89f1bf6 flush bytes instead of roaring 2021-05-10 19:20:34 +02:00
Kuba Podgórski
252fadf6a0 Merge branch 'available-shards' of github.com:kuba--/molecula-pilosa into available-shards 2021-05-10 18:50:24 +02:00
Kuba Podgórski
6bdca67882 replace roaring.Bitmap by [][]byte 2021-05-10 18:45:23 +02:00
Nia
26b49cca21
fix remote available shard races (#3) 2021-05-10 18:36:40 +02:00
Kuba Podgórski
b36de3146a write shards per node 2021-05-10 13:54:18 +02:00
Kuba Podgórski
a79a36232f Write remote available shards to etcd, instead of local file. 2021-05-07 15:33:18 +02:00
Kuba Podgórski
74c1c8a86c
Merge branch 'master' into public-name-validator 2021-04-14 22:17:07 +02:00
Ben Johnson
ea01f7e37c Switch timestamp field to use epoch instead of min/max 2021-04-14 08:46:37 -06:00
Kuba Podgórski
ca1cbadb45 Make validateName function public, so other packages and projects (like IDK, Ingester) can re-use it 2021-04-14 13:33:26 +02:00
Alan Bernstein
285d0a0af8 Add log prefix levels 2021-04-12 20:33:39 -05:00
Ben Johnson
5defbe3ef2 Fix timestamp value import 2021-04-09 10:56:25 -06:00
Ben Johnson
d70eb737cb Fix timestamp field issues 2021-04-09 08:26:12 -06:00
Ben Johnson
cfc725e799 Add timestamp field type support 2021-04-06 10:50:10 -06:00
Travis
314cf3461d
Cache BitDepth on bsiGroup during index.Open.
Before this change, we were only caching the BitDepth on the
field.options. This was ok as long as applyOptions() was called after
that. But unfortunately, during startup, applyOptions() was called prior
to that being set. So with this commit, we explicitly set the value in
bsiGroup.BitDepth as well.
2021-03-14 22:51:24 -05:00
Nia Weiss
3fbf6993d0
defer cluster messages until startup 2021-02-25 16:01:49 -05:00
Seebs
c1c0e828cd lock read from bsig.BitDepth, not just write to it 2021-02-24 11:25:46 -06:00
Travis
912e51790f
remove Field.saveMeta(). get Feild.options.BitDepth from fragment 2021-02-23 10:09:56 -06:00
Travis
8b0f18721e
remove Field.loadMeta() 2021-02-23 10:09:55 -06:00
Travis
4e857e8de4
remove some calls to Field.saveMeta() 2021-02-23 10:09:55 -06:00
Travis
ebb340d83e
remove old BSI upgrade code 2021-02-23 10:09:54 -06:00
Travis
b5d6c632bf
stop storing a value for views in etcd 2021-02-15 14:39:52 -06:00
Seebs
0790fbe866 only persist views to etcd when they're not already known
Persisting views to etcd every time we check for them causes
what ends up being about a factor of 60 slowdown. Let's do it a little
less.
2021-02-15 10:19:03 -06:00
Travis
8f0270acda
adjust openExistenceField() to check on disk first 2021-02-12 20:35:36 -06:00
Kuba Podgórski
2f35b51db8
Fix endpoint tests + change BitDepth type to uint64 2021-02-12 20:35:36 -06:00