MishkaInstaller.MnesiaRepo (Mishka installer v0.1.8)

Copy Markdown View Source

Boots, supervises and dynamically clusters the Mnesia store used by MishkaInstaller.

On start it (re)configures the Mnesia directory, creates the schema, starts Mnesia, waits for the local tables, creates the essential tables, and broadcasts :synchronized on the "mnesia" PubSub channel so the event and installer layers can come online.

It also watches the BEAM cluster (:net_kernel.monitor_nodes/1) and keeps Mnesia membership in sync at runtime: a configured peer that connects after boot is joined automatically.

Configuration

Configure under the :mishka_installer application env, keyed by this module:

config :mishka_installer, MishkaInstaller.MnesiaRepo,
  mnesia_dir: "/var/lib/my_app/mnesia",
  essential: [MishkaInstaller.Event.Event, MishkaInstaller.Installer.Installer],
  cluster_nodes: :auto,
  dynamic_membership: true,
  wait_timeout: 60_000,
  wait_retries: 5
  • :mnesia_dir — where Mnesia stores its files. Defaults to ".mnesia/<env>" under the project.
  • :essential — modules whose database_config/0 defines a table to create on boot. Defaults to [MishkaInstaller.Installer.Installer, MishkaInstaller.Event.Event].
  • :cluster_nodes — the seed/existing cluster nodes this node should join. :auto (default) and [] mean standalone seed (this node owns the schema). A non-empty list makes this node a joiner: it wipes its local schema, connects to those nodes, becomes a disc_copies member and copies each essential table. Run one seed node (:auto/[]) and point the others at it (cluster_nodes: [seed]). A joiner whose seed is not reachable yet does not crash — it boots :pending (empty, no tables) and joins as soon as a configured node connects. Forming the BEAM cluster (libcluster/Node.connect) is a separate, prior step.
  • :dynamic_membership — watch :net_kernel.monitor_nodes/1 and join configured peers that connect after boot. Defaults to true, but it is only active when :cluster_nodes lists peers — a standalone/default node (:auto/[]) never watches the cluster and stays fully passive regardless of this flag. Set false to opt a clustered node out of runtime monitoring (boot-time join only).

Cluster limits

Mnesia has no automatic split-brain resolution. On a network partition both sides keep writing; on heal an inconsistent_database event is emitted (alarmed via telemetry + a critical log) and an operator must resolve it. A node going down is never auto-evicted (a transient netsplit would otherwise destroy a healthy replica) — removing a node is an explicit operator action. Recovery helpers (force_load_table/set_master_nodes) are not yet implemented.

  • :wait_timeout / :wait_retries — one wait "slice" (ms) and how many slices to wait while disc_copies tables load from disk into RAM before giving up. Raise these for large datasets.

Restart

On a restart where Mnesia is already running on the configured dir with the essential tables loaded, boot is a no-op re-announce — it does not stop/re-init Mnesia under the running event/installer processes.

Telemetry

All events use the [:mishka_installer, :mnesia, ...] prefix:

  • [:mishka_installer, :mnesia, :init, :start | :stop | :exception] — a :telemetry.span/3 around boot. :stop carries :duration; metadata: :node, :result, :tables.

  • [:mishka_installer, :mnesia, :table] — once per essential table. Metadata: :table, :status (:created | :already_exists | :already_loaded | :copied | :error).
  • [:mishka_installer, :mnesia, :synchronized] — after the boot broadcast. Metadata: :node, :tables.
  • [:mishka_installer, :mnesia, :health_check] — periodic. Measurements: :table_count, :schema_count. Metadata: :node, :healthy?, :missing.
  • [:mishka_installer, :mnesia, :inconsistent_database] — split-brain detected. Metadata: :node, :context.
  • [:mishka_installer, :mnesia, :cluster, :nodeup] — a node connected. Metadata: :node, :peer, :action (:joined | :connected | :already_member | :ignored | :pending | {:error, term}).
  • [:mishka_installer, :mnesia, :cluster, :nodedown] — a node disconnected (log + alarm only, no eviction). Metadata: :node, :peer, :db_member?.

Summary

Functions

Returns a specification to start this module under a supervisor.

Returns each local table (except :schema) with its storage type and local_content flag.

Starts the Mnesia repository process.

Returns the current repository state.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

schemas()

@spec schemas() :: [{atom(), keyword()}]

Returns each local table (except :schema) with its storage type and local_content flag.

start_link(state \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the Mnesia repository process.

state()

@spec state() :: struct()

Returns the current repository state.