mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-05 08:10:50 +00:00
Restrict max RBF transaction size
This commit is contained in:
parent
78eb9e0711
commit
9eba299d35
3 changed files with 34 additions and 2 deletions
|
|
@ -39,6 +39,25 @@ func TestDB_Open(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDB_WAL(t *testing.T) {
|
||||
t.Run("ErrTxTooLarge", func(t *testing.T) {
|
||||
config := rbfcfg.NewDefaultConfig()
|
||||
config.MaxWALSize = 4 * rbf.PageSize
|
||||
|
||||
db := MustOpenDB(t, config)
|
||||
defer MustCloseDB(t, db)
|
||||
|
||||
tx := MustBegin(t, db, true)
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := tx.CreateBitmap("x"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if err := tx.CreateBitmap("y"); err != rbf.ErrTxTooLarge {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDB_Recovery(t *testing.T) {
|
||||
// Ensure a bitmap header written without a bitmap is truncated.
|
||||
t.Run("TruncPartialWALBitmap", func(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ var (
|
|||
ErrBitmapNameRequired = errors.New("bitmap name required")
|
||||
ErrBitmapNotFound = errors.New("bitmap not found")
|
||||
ErrBitmapExists = errors.New("bitmap already exists")
|
||||
ErrTxTooLarge = errors.New("rbf tx too large")
|
||||
)
|
||||
|
||||
// Debug is just a temporary flag used for debugging.
|
||||
|
|
|
|||
16
rbf/tx.go
16
rbf/tx.go
|
|
@ -69,7 +69,12 @@ func (tx *Tx) Writable() bool {
|
|||
|
||||
// dirty returns true if any pages have been updated in this tx.
|
||||
func (tx *Tx) dirty() bool {
|
||||
return len(tx.dirtyPages) != 0 || len(tx.dirtyBitmapPages) != 0
|
||||
return tx.dirtyN() != 0
|
||||
}
|
||||
|
||||
// dirtyN returns the number of dirty pages.
|
||||
func (tx *Tx) dirtyN() int {
|
||||
return len(tx.dirtyPages) + len(tx.dirtyBitmapPages)
|
||||
}
|
||||
|
||||
// PageN returns the number of pages in the database as seen by this transaction.
|
||||
|
|
@ -954,11 +959,18 @@ func (tx *Tx) readPage(pgno uint32) ([]byte, error) {
|
|||
|
||||
func (tx *Tx) writePage(page []byte) error {
|
||||
tx.dirtyPages[readPageNo(page)] = page
|
||||
return nil
|
||||
return tx.checkTxSize()
|
||||
}
|
||||
|
||||
func (tx *Tx) writeBitmapPage(pgno uint32, page []byte) error {
|
||||
tx.dirtyBitmapPages[pgno] = page
|
||||
return tx.checkTxSize()
|
||||
}
|
||||
|
||||
func (tx *Tx) checkTxSize() error {
|
||||
if (tx.walPageN+tx.dirtyN())*PageSize >= len(tx.db.wal) {
|
||||
return ErrTxTooLarge
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue