Skip to content

Commit

Permalink
Merge pull request #17874 from mheon/sqlite_fixes
Browse files Browse the repository at this point in the history
Sqlite fixes
  • Loading branch information
openshift-merge-robot authored Mar 22, 2023
2 parents 67431a7 + 3925cd6 commit 6b9f314
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 17 deletions.
45 changes: 28 additions & 17 deletions libpod/sqlite_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,30 @@ type SQLiteState struct {
runtime *Runtime
}

const (
// Deal with timezone automatically.
sqliteOptionLocation = "_loc=auto"
// Set the journal mode (https://www.sqlite.org/pragma.html#pragma_journal_mode).
sqliteOptionJournal = "&_journal=WAL"
// Force WAL mode to fsync after each transaction (https://www.sqlite.org/pragma.html#pragma_synchronous).
sqliteOptionSynchronous = "&_sync=FULL"
// Allow foreign keys (https://www.sqlite.org/pragma.html#pragma_foreign_keys).
sqliteOptionForeignKeys = "&_foreign_keys=1"
// Enable cache sharing for threads within a process
sqliteOptionSharedCache = "&cache=shared"
// Make sure that transactions happen exclusively.
sqliteOptionTXLock = "&_txlock=exclusive"

// Assembled sqlite options used when opening the database.
sqliteOptions = "db.sql?" +
sqliteOptionLocation +
sqliteOptionJournal +
sqliteOptionSynchronous +
sqliteOptionForeignKeys +
sqliteOptionSharedCache +
sqliteOptionTXLock
)

// NewSqliteState creates a new SQLite-backed state database.
func NewSqliteState(runtime *Runtime) (_ State, defErr error) {
state := new(SQLiteState)
Expand All @@ -45,7 +69,7 @@ func NewSqliteState(runtime *Runtime) (_ State, defErr error) {
return nil, fmt.Errorf("creating root directory: %w", err)
}

conn, err := sql.Open("sqlite3", filepath.Join(basePath, "db.sql?_loc=auto"))
conn, err := sql.Open("sqlite3", filepath.Join(basePath, sqliteOptions))
if err != nil {
return nil, fmt.Errorf("initializing sqlite database: %w", err)
}
Expand All @@ -63,29 +87,16 @@ func NewSqliteState(runtime *Runtime) (_ State, defErr error) {
return nil, fmt.Errorf("cannot connect to database: %w", err)
}

// Enable foreign keys constraints, which we use extensively in our
// tables.
if _, err := state.conn.Exec("PRAGMA foreign_keys = ON;"); err != nil {
return nil, fmt.Errorf("enabling foreign key support in database: %w", err)
}
// Enable WAL mode for performance - https://www.sqlite.org/wal.html
if _, err := state.conn.Exec("PRAGMA journal_mode = WAL;"); err != nil {
return nil, fmt.Errorf("switching journal to WAL mode: %w", err)
}
// Force WAL mode to fsync after every transaction, for reboot safety.
if _, err := state.conn.Exec("PRAGMA synchronous = FULL;"); err != nil {
return nil, fmt.Errorf("setting full fsync mode in db: %w", err)
// Migrate schema (if necessary)
if err := state.migrateSchemaIfNecessary(); err != nil {
return nil, err
}

// Set up tables
if err := sqliteInitTables(state.conn); err != nil {
return nil, fmt.Errorf("creating tables: %w", err)
}

if err := state.migrateSchemaIfNecessary(); err != nil {
return nil, err
}

state.valid = true
state.runtime = runtime

Expand Down
15 changes: 15 additions & 0 deletions libpod/sqlite_state_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ import (
)

func (s *SQLiteState) migrateSchemaIfNecessary() (defErr error) {
// First, check if the DBConfig table exists
checkRow := s.conn.QueryRow("SELECT 1 FROM sqlite_master WHERE type='table' AND name='DBConfig';")
var check int
if err := checkRow.Scan(&check); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil
}
return fmt.Errorf("checking if DB config table exists: %w", err)
}
if check != 1 {
// Table does not exist, fresh database, no need to migrate.
return nil
}

row := s.conn.QueryRow("SELECT SchemaVersion FROM DBConfig;")
var schemaVer int
if err := row.Scan(&schemaVer); err != nil {
Expand All @@ -24,6 +38,7 @@ func (s *SQLiteState) migrateSchemaIfNecessary() (defErr error) {
// Schema was just created, so it has to be the latest.
return nil
}
return fmt.Errorf("scanning schema version from DB config: %w", err)
}

// If the schema version 0 or less, it's invalid
Expand Down

0 comments on commit 6b9f314

Please sign in to comment.