code: func (db *DB) Close() error {
  	if !db.setClosed() {
  		return ErrClosed
  	}
  
  	start := time.Now()
  	db.log("db@close closing")
  
  	// Clear the finalizer.
  	runtime.SetFinalizer(db, nil)
  
  	// Get compaction error.
  	var err error
  	select {
  	case err = <-db.compErrC:
  		if err == ErrReadOnly {
  			err = nil
  		}
  	default:
  	}
  
  	// Signal all goroutines.
  	close(db.closeC)
  
  	// Discard open transaction.
  	if db.tr != nil {
  		db.tr.Discard()
  	}
  
  	// Acquire writer lock.
  	db.writeLockC <- struct{}{}
  
  	// Wait for all gorotines to exit.
  	db.closeW.Wait()
  
  	// Closes journal.
  	if db.journal != nil {
  		db.journal.Close()
  		db.journalWriter.Close()
  		db.journal = nil
  		db.journalWriter = nil
  	}
  
  	if db.writeDelayN > 0 {
  		db.logf("db@write was delayed N·%d T·%v", db.writeDelayN, db.writeDelay)
  	}
  
  	// Close session.
  	db.s.close()
  	db.logf("db@close done T·%v", time.Since(start))
  	db.s.release()
  
  	if db.closer != nil {
  		if err1 := db.closer.Close(); err == nil {
  			err = err1
  		}
  		db.closer = nil
  	}
  
  	// Clear memdbs.
  	db.clearMems()
  
  	return err
  }
docs: // Close closes the DB. This will also releases any outstanding snapshot,
  // abort any in-flight compaction and discard open transaction.
  //
  // It is not safe to close a DB until all outstanding iterators are released.
  // It is valid to call Close multiple times. Other methods should not be
  // called after the DB has been closed.