View Source Pow.Store.Backend.MnesiaCache.Unsplit (Pow v1.0.38)
GenServer that handles network split recovery for
Pow.Store.Backend.MnesiaCache
.
This should be run on node(s) that has the Pow.Store.Backend.MnesiaCache
GenServer running. It'll subscribe to the Mnesia system messages, and listen
for :inconsistent_database
system events. The first node to set the global
lock will find the island with the oldest node and restore that nodes table
into all the partitioned nodes.
If a table unrelated to Pow is also affected, an error will be logged and the
network will stay partitioned. If you don't mind potential data loss for any
of your tables in Mnesia, you can set flush_tables: :all
to restore all the
affected tables from the oldest node in the cluster.
For better control, you can use
unsplit
instead of this module.
Usage
To start the GenServer, add it to your application start/2
function:
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
MyApp.Repo,
MyAppWeb.Endpoint,
{Pow.Store.Backend.MnesiaCache, extra_db_nodes: {Node, :list, []}},
Pow.Store.Backend.MnesiaCache.Unsplit
]
opts = [strategy: :one_for_one, name: MyAppWeb.Supervisor]
Supervisor.start_link(children, opts)
end
# ...
end
Auto initialize cluster
If nodes are lazily connected a race condition can occur in which the
Pow.Store.Backend.MnesiaCache
is running on each node without being
connected in a Mnesia cluster.
To ensure that cluster will automatically initialize,
Pow.Store.Backend.MnesiaCache.Unsplit
will reset the most recent node's
Mnesia schema when connecting to another node or a cluster. This will only
occur if the Mnesia node has never been connected to the other node(s) and
the other node currently runs the Mnesia cache GenServer.
The Pow.Store.Backend.MnesiaCache
GenServer will be restarted, using the same
:extra_db_nodes
configuration as when it was first initialized. Therefor
it's important that a MFA is used like {Node, :list, []}
for the auto
initialization to succeed.
Please be aware the reset of the Mnesia node will result in data loss for the node.
Strategy for multiple libraries using the Mnesia instance
It's strongly recommended to take into account any libraries that will be using Mnesia for storage before using this module.
A common example would be a job queue, where a potential solution to prevent
data loss is to simply keep the job queue table on only one server instead of
replicating it among all nodes. When a network partition occurs, it won't be
part of the affected tables so this module can self-heal without the job
queue table set in :flush_tables
.
There may still be data loss if nodes are lazily connected. Please read the "Auto initialize cluster" section above.
Initialization options
:flush_tables
- list of tables that may be flushed and restored from the oldest node in the cluster. Defaults tofalse
when only the MnesiaCache table will be flushed. Use:all
if you want to flush all affected tables. Be aware that this may cause data loss.:auto_initialize_cluster
- a boolean value to automatically initialize the Mnesia cluster by resetting the node Mnesia schema when new nodes are connected, defaults totrue
.
Summary
Functions
Returns a specification to start this module under a supervisor.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor
.
@spec start_link(Pow.Config.t()) :: GenServer.on_start()