Fix 'new manifest created with non 0 lock' error

Fix dropping and creating the same database on dolt sql-server. We were caching doltdb's using a singleton
and at the manifest cache level which lead to problems.
This commit is contained in:
Dhruv Sringari
2022-12-13 17:24:48 -08:00
parent 24cac8c28f
commit 5ea4353b0c
8 changed files with 81 additions and 0 deletions

View File

@@ -65,6 +65,13 @@ func CloseAllLocalDatabases() (err error) {
return
}
func DeleteFromSingletonCache(path string) error {
singletonLock.Lock()
defer singletonLock.Unlock()
delete(singletons, path)
return nil
}
// PrepareDB creates the directory for the DB if it doesn't exist, and returns an error if a file or symlink is at the
// path given
func (fact FileFactory) PrepareDB(ctx context.Context, nbf *types.NomsBinFormat, u *url.URL, params map[string]interface{}) error {

View File

@@ -215,6 +215,10 @@ func (ddb *DoltDB) WriteEmptyRepoWithCommitTimeAndDefaultBranch(
return err
}
func (ddb *DoltDB) Close() error {
return ddb.db.Close()
}
func getCommitValForRefStr(ctx context.Context, db datas.Database, vrw types.ValueReadWriter, ref string) (*datas.Commit, error) {
if err := datas.ValidateDatasetId(ref); err != nil {
return nil, fmt.Errorf("invalid ref format: %s", ref)

View File

@@ -592,15 +592,29 @@ func (p DoltDatabaseProvider) DropDatabase(ctx *sql.Context, name string) error
dbKey := formatDbMapKeyName(name)
db := p.databases[dbKey]
ddb := db.(Database).ddb
err = ddb.Close()
if err != nil {
return err
}
// get location of database that's being dropped
dbLoc := p.dbLocations[dbKey]
if dbLoc == nil {
return sql.ErrDatabaseNotFound.New(db.Name())
}
dropDbLoc, err := dbLoc.Abs("")
if err != nil {
return err
}
// If this database is re-created, we don't want to return any cached results.
err = dbfactory.DeleteFromSingletonCache("file://" + dropDbLoc + "/.dolt/noms")
if err != nil {
return err
}
rootDbLoc, err := p.fs.Abs("")
if err != nil {
return err

View File

@@ -427,6 +427,11 @@ func (mm manifestManager) UpdateGCGen(ctx context.Context, lastLock addr, newCon
return
}
func (mm manifestManager) Close() error {
mm.cache.Delete(mm.Name())
return nil
}
func (mm manifestManager) Name() string {
return mm.m.Name()
}

View File

@@ -114,3 +114,17 @@ func (mc *manifestCache) Put(db string, contents manifestContents, t time.Time)
return nil
}
// Delete removes a key from the cache.
func (mc *manifestCache) Delete(db string) {
mc.mu.Lock()
defer mc.mu.Unlock()
if entry, ok := mc.entry(db); ok {
mc.totalSize -= entry.contents.size()
mc.lru.Remove(entry.lruEntry)
delete(mc.cache, db)
}
return
}

View File

@@ -128,4 +128,15 @@ func TestSizeCache(t *testing.T) {
assert.False(t, ok)
})
t.Run("Delete", func(t *testing.T) {
c := newManifestCache(1 * defSize)
err := c.Put("db", manifestContents{}, time.Now())
require.NoError(t, err)
_, _, ok := c.Get("db")
assert.True(t, ok)
c.Delete("db")
_, _, ok = c.Get("db")
assert.False(t, ok)
})
}

View File

@@ -1111,6 +1111,9 @@ func (nbs *NomsBlockStore) Close() (err error) {
if cerr := nbs.tables.close(); cerr != nil {
err = cerr
}
if cerr := nbs.mm.Close(); cerr != nil {
err = cerr
}
return
}

View File

@@ -1798,6 +1798,29 @@ s.close()
[[ ! "$output" =~ "mydb" ]] || false
}
@test "sql-server: create database, drop it, and then create it again" {
skiponwindows "Missing dependencies"
mkdir mydbs
cd mydbs
start_sql_server >> server_log.txt 2>&1
dolt sql-client -P $PORT -u dolt --use-db '' -q "CREATE DATABASE mydb1;"
[ -d mydb1 ]
run dolt sql-client -P $PORT -u dolt --use-db '' -q "DROP DATABASE mydb1;"
[ $status -eq 0 ]
[ ! -d mydb1 ]
run dolt sql-client -P $PORT -u dolt --use-db '' -q "CREATE DATABASE mydb1;"
[ $status -eq 0 ]
[ -d mydb1 ]
run dolt sql-client -P $PORT -u dolt --use-db '' -q "SHOW DATABASES;"
[ $status -eq 0 ]
[[ "$output" =~ "mydb1" ]] || false
}
@test "sql-server: dropping database with '-' in it" {
skiponwindows "Missing dependencies"