f99010fae1
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Linux) (push) Has been cancelled
Desktop Artifacts / Desktop Build (Windows) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Has been cancelled
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Has been cancelled
57 lines
1.3 KiB
Go
57 lines
1.3 KiB
Go
package duckdb
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
)
|
|
|
|
const duckCheckpointMinFreeBytes int64 = 16 << 20
|
|
|
|
type duckDBMaintenance interface {
|
|
checkpointAfterPush(context.Context, *sql.DB) error
|
|
}
|
|
|
|
type duckDBCheckpointMaintenance struct{}
|
|
|
|
type duckDBSize struct {
|
|
blockSize int64
|
|
freeBlocks int64
|
|
}
|
|
|
|
func (duckDBCheckpointMaintenance) checkpointAfterPush(
|
|
ctx context.Context, duck *sql.DB,
|
|
) error {
|
|
size, err := readDuckDBSize(ctx, duck)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !shouldCheckpointDuckDB(size) {
|
|
return nil
|
|
}
|
|
if _, err := duck.ExecContext(ctx, `CHECKPOINT`); err != nil {
|
|
return fmt.Errorf("checkpointing duckdb mirror: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func readDuckDBSize(ctx context.Context, duck *sql.DB) (duckDBSize, error) {
|
|
var size duckDBSize
|
|
if err := duck.QueryRowContext(ctx, `
|
|
SELECT block_size, free_blocks
|
|
FROM pragma_database_size()
|
|
WHERE database_name = current_database()
|
|
`).Scan(&size.blockSize, &size.freeBlocks); err != nil {
|
|
return duckDBSize{}, fmt.Errorf("reading duckdb database size: %w", err)
|
|
}
|
|
return size, nil
|
|
}
|
|
|
|
func shouldCheckpointDuckDB(size duckDBSize) bool {
|
|
if size.blockSize <= 0 || size.freeBlocks <= 0 {
|
|
return false
|
|
}
|
|
blocksNeeded := (duckCheckpointMinFreeBytes + size.blockSize - 1) / size.blockSize
|
|
return size.freeBlocks >= blocksNeeded
|
|
}
|