Core Concepts: The Start
and Stop
Lifecycle
Understanding what happens when you call Start()
and Stop()
is key to using embedded-postgres
effectively, especially for managing data and running tests in parallel.
The Start()
Lifecycle
When postgres.Start()
is called, it performs a sequence of operations to ensure a clean, isolated PostgreSQL instance is ready for use.
-
Port Availability Check: It first checks if the configured port (e.g.,
5432
) is available. If another process is listening on that port,Start()
will fail immediately. -
Path Management: The library uses several key directories:
CachePath
: Where downloaded binary archives (.txz
files) are stored. Defaults to~/.embedded-postgres-go
. This path is persistent across runs.RuntimePath
: A temporary directory for the extracted binaries and other runtime files. By default, this directory is deleted and recreated on everyStart()
call to ensure a clean slate.DataPath
: The PostgreSQL data directory (PGDATA
). By default, it's a subdirectory ofRuntimePath
, meaning it is also deleted on every start. To persist data between runs, you must configureDataPath
to a location outside ofRuntimePath
.
-
Binary Acquisition: It ensures the PostgreSQL binaries are available. This is covered in detail in the Binary Management guide.
-
Database Initialization (
initdb
): It checks if theDataPath
is a valid, initialized PostgreSQL data directory.- If
DataPath
is empty or contains data for an incompatible PostgreSQL version, it is wiped, and theinitdb
command is run to create a new database cluster. - If
DataPath
contains a valid, version-compatible cluster, it is reused. This is how data persistence is achieved.
- If
-
Start PostgreSQL Process: It executes
pg_ctl start
, pointing it to the preparedDataPath
and passing any customStartParameters
. -
Create Initial Database: If the configured database name is not the default
postgres
, it connects to the server and runsCREATE DATABASE ...
. -
Health Check: It repeatedly tries to connect to the new PostgreSQL instance.
Start()
only returns successfully once a connection is established and a simple query (SELECT 1
) succeeds. If it cannot connect within theStartTimeout
period, it returns an error.
The Stop()
Lifecycle
Calling postgres.Stop()
performs a graceful shutdown of the PostgreSQL process.
- Execute
pg_ctl stop
: It runs thepg_ctl stop -w
command, which waits for the server to shut down cleanly. - Process Cleanup: This ensures no orphaned PostgreSQL processes are left running after your application or test suite finishes.
It is crucial to call Stop()
to release resources and ensure a clean exit. A common pattern is to use defer
:
postgres := embeddedpostgres.NewDatabase()
if err := postgres.Start(); err != nil {
// handle error
}
defer postgres.Stop()
// ... your test or application logic