Prev Next

Database / Mnesia intermediate to advanced Interview questions

1. What is the difference between mnesia:transaction/1 and mnesia:sync_transaction/1? 2. What is the difference between async_dirty and sync_dirty activity contexts? 3. How does mnesia:activity/4 let you customize the access context of an operation? 4. What is table fragmentation in Mnesia and why would you use it? 5. How do you configure a fragmented Mnesia table? 6. Why does fragmentation help Mnesia scale beyond what one table replica set can handle? 7. What is the difference between mnesia:match_object/1 and mnesia:select/2? 8. What is mnesia:all_keys/1 used for? 9. How do you integrate Mnesia with QLC for complex queries? 10. Why would you use qlc:q with mnesia:table/1 instead of mnesia:select/2? 11. What is a sticky lock in Mnesia and why does it improve performance? 12. When can sticky locks cause a problem in a distributed Mnesia cluster? 13. How do you dynamically add a new node to a running Mnesia cluster? 14. What is mnesia:change_config(extra_db_nodes, Nodes) used for? 15. How do you remove a table replica from a node without dropping the whole table? 16. What is mnesia:del_table_copy/2 used for? 17. How do you move a table copy from one node to another while the system stays live? 18. What is mnesia:move_table_copy/3 used for? 19. What is the {majority, true} table option and what tradeoff does it introduce? 20. Why would you enable the majority option on a table prone to network partitions? 21. What is a local_content table in Mnesia? 22. When would you use a local_content table instead of a normal replicated table? 23. What is mnesia:set_master_nodes/2 used for? 24. How does setting master nodes influence conflict resolution after a network partition? 25. What is mnesia_tm and what role does it play internally? 26. How does Mnesia's transaction manager serialize concurrent transactions touching the same records? 27. Why can a "hot" record or table become a bottleneck under heavy Mnesia write load? 28. How can you redesign a schema to reduce lock contention on a frequently-updated record? 29. What is mnesia:subscribe/1 used for? 30. How do you react to table events using Mnesia's subscription mechanism? 31. What is a nested Mnesia transaction and how does it behave differently from a top-level one? 32. Why should nested transactions generally be avoided or used carefully in Mnesia? 33. What is the dc_dump_limit configuration parameter used for? 34. Why does tuning the transaction log dump frequency matter for write-heavy Mnesia workloads? 35. How do you merge two previously-separate Mnesia clusters into one? 36. What complications arise when merging schemas from two independently-created Mnesia databases? 37. How does Mnesia decide which node's data wins during schema merge conflicts? 38. What is the difference between a global lock and a per-record lock in Mnesia transactions? 39. When would you use mnesia:read_lock_table/1 instead of relying on per-record locks? 40. How do you profile and optimize Mnesia transaction throughput in a write-heavy system? 41. Why is batching multiple related writes into a single transaction usually better than many small transactions? 42. How does Mnesia's schema interact with OTP release upgrades (appup/relup)? 43. What is the difference between mnesia:dirty_all_keys/1 and mnesia:all_keys/1? 44. Explain the internal working of how Mnesia chooses which replica to read from in a load-balanced cluster? 45. What is the where_to_read table_info item used for? 46. What is mnesia:dump_log/0 used for? 47. How do you handle a transaction that needs to retry after being aborted due to a deadlock? 48. What is the difference between mnesia:transaction/1's built-in behavior and manual retry logic you might add?

1. What is the difference between mnesia:transaction/1 and mnesia:sync_transaction/1?

Both give the same atomicity and locking guarantees, but they differ in when they return control to the caller relative to replication. mnesia:transaction/1 can return as soon as the commit is decided locally, while replication to other nodes finishes asynchronously in the background. mnesia:sync...

Read full answer

2. What is the difference between async_dirty and sync_dirty activity contexts?

Both are non-transactional access contexts you can use with mnesia:activity/2 or by directly calling dirty functions, trading Mnesia's usual locking/atomicity for speed — the difference between them is, again, about replication timing rather than locking. async_dirty sync_dirty Returns as s...

Read full answer

3. How does mnesia:activity/4 let you customize the access context of an operation?

mnesia:activity(AccessContext, Fun, Args, Module) is the general-purpose entry point underlying transaction/1 , sync_transaction/1 , and the dirty variants — those are really just convenience wrappers around activity/4 with a specific context pre-selected. mnesia:activity(transaction, fun u...

Read full answer

4. What is table fragmentation in Mnesia and why would you use it?

Fragmentation splits a single logical table into multiple physical fragments, each of which can live on a different node (or set of nodes), while application code still addresses it as one table name. It exists for tables whose size or write volume would overwhelm what a single, fully-replicated ...

Read full answer

5. How do you configure a fragmented Mnesia table?

Fragmentation is set up via the frag_properties option on mnesia:create_table/2 , specifying how many fragments to create and how to distribute them across nodes. m nes ia : crea te _ ta ble(sessio ns , [{ fra g_proper t ies , [{ n ode_pool , [ n ode 1 @hos t , n ode 2 @hos t , n ode 3 @hos t ]},...

Read full answer

6. Why does fragmentation help Mnesia scale beyond what one table replica set can handle?

A normal, fully-replicated Mnesia table means every node holding a copy stores (and, for disc_copies , durably persists) the entire dataset, and every write must be coordinated and applied across all of those full copies via two-phase commit. Both the storage requirement and the write coordinatio...

Read full answer

7. What is the difference between mnesia:match_object/1 and mnesia:select/2?

Both let you query beyond a simple primary-key lookup, but match_object/1 uses a simpler, pattern-only interface, while select/2 supports full match specifications with guard conditions. mnesia:match_object/1 mnesia:select/2 A single pattern with `'_'` wildcards; returns whole matching records. P...

Read full answer

8. What is mnesia:all_keys/1 used for?

mnesia:all_keys(Table) returns every primary key currently stored in a table, run inside a transaction (or a dirty context via mnesia:dirty_all_keys/1 ) — a quick way to enumerate a table's contents by key without writing a match specification. mnesia:transaction(fun() -> mnesia:all_keys(pe...

Read full answer

9. How do you integrate Mnesia with QLC for complex queries?

QLC (Query List Comprehension) provides a SQL-like, declarative query syntax over any "queryable" data source, and Mnesia tables can be exposed to it via mnesia:table/1 , letting you write joins, sorting, and filtering across one or more tables in a single expression. mnesia:transaction(fun() -> ...

Read full answer

10. Why would you use qlc:q with mnesia:table/1 instead of mnesia:select/2?

select/2 is a single-table, match-specification-based query — excellent for filtering one table efficiently, but it can't express a relationship spanning multiple tables in one query. QLC's comprehension syntax reads much closer to how you'd describe the query in plain language (join these ...

Read full answer

11. What is a sticky lock in Mnesia and why does it improve performance?

Acquiring a write lock on a replicated table normally requires coordinating with every node holding a copy, even if, in practice, all the writes to a particular record consistently originate from the same node. A sticky lock lets a node "claim" ownership of a table's locking for itself after its ...

Read full answer

12. When can sticky locks cause a problem in a distributed Mnesia cluster?

A sticky lock optimizes for the common case where the same node keeps writing to a table, but it means lock "ownership" has to be reclaimed if a different node suddenly needs to write — and if the node currently holding the sticky lock has become unreachable (crashed, network partition), re...

Read full answer

13. How do you dynamically add a new node to a running Mnesia cluster?

Bringing a new node into an already-running Mnesia cluster involves connecting it at the Erlang distribution level first, then explicitly telling Mnesia's schema about it via mnesia:change_config(extra_db_nodes, [NewNode]) , which merges the new node into the existing schema rather than creating ...

Read full answer

14. What is mnesia:change_config(extra_db_nodes, Nodes) used for?

This call tells the local Mnesia instance about additional nodes it should try to connect and merge schema information with — it's the mechanism behind both joining a brand-new node to an existing cluster and reconnecting a node that was started independently but should now become part of a...

Read full answer

15. How do you remove a table replica from a node without dropping the whole table?

mnesia:del_table_copy(Table, Node) removes just one node's copy of a table from the schema and frees its local storage, while the table itself keeps running normally on every other node still holding a copy — it's the inverse of add_table_copy/3 . mnesia:del_table_copy(session, 'nodeb@host'...

Read full answer

16. What is mnesia:del_table_copy/2 used for?

mnesia:del_table_copy(Table, Node) updates the schema to stop treating the given node as a replica of the specified table, and reclaims whatever storage (memory and/or disk) that copy was using on that node — a schema-level operation, run as part of deliberate cluster maintenance rather tha...

Read full answer

17. How do you move a table copy from one node to another while the system stays live?

mnesia:move_table_copy(Table, FromNode, ToNode) relocates a table's replica from one node to another without taking the table offline — useful for rebalancing load, retiring a node, or migrating data ahead of decommissioning old hardware. mnesia:move_table_copy(session, 'old_node@host', 'ne...

Read full answer

18. What is mnesia:move_table_copy/3 used for?

This function is the standard tool for live data rebalancing and node decommissioning: moving a specific table's replica to a different node without a maintenance window where the table is unavailable. mnesia:move_table_copy(person, 'nodeA@old_host', 'nodeD@new_host'). Common scenarios: migrating...

Read full answer

19. What is the {majority, true} table option and what tradeoff does it introduce?

Setting {majority, true} on a table requires that a write be acknowledged by a majority of the nodes holding a copy of that table before the transaction is allowed to commit — if a network partition leaves a node (or minority group of nodes) unable to reach a majority of replicas, writes on...

Read full answer

20. Why would you enable the majority option on a table prone to network partitions?

Without the majority option, a partition can let two isolated groups of nodes both keep accepting writes to the same replicated table independently, setting up an inconsistent-database conflict that has to be manually or programmatically resolved once the partition heals — and any conflicti...

Read full answer

21. What is a local_content table in Mnesia?

A local_content table is replicated in the sense that its schema exists on every listed node, but each node keeps its own independent data in it — writes on one node are never propagated to other nodes' copies, unlike a normal replicated table where every copy is meant to converge on the sa...

Read full answer

22. When would you use a local_content table instead of a normal replicated table?

Reach for local_content specifically when the data is conceptually per-node rather than shared — each node's copy is meant to hold genuinely different information, not a synchronized replica of the same logical dataset. A normal replicated table is the wrong fit here since it's designed aro...

Read full answer

23. What is mnesia:set_master_nodes/2 used for?

mnesia:set_master_nodes(Table, Nodes) designates specific nodes as the authoritative source for a table's data when Mnesia needs to decide which replica to trust — most notably when recovering from an inconsistent database state after a network partition, where by default Mnesia can't autom...

Read full answer

24. How does setting master nodes influence conflict resolution after a network partition?

When a partition heals and Mnesia detects that a table's replicas diverged, its default behavior is to raise an inconsistent_database_event and leave the decision of which side to trust to an operator or a configured event handler, since it has no inherent basis to prefer one side over the other....

Read full answer

25. What is mnesia_tm and what role does it play internally?

mnesia_tm is Mnesia's internal transaction manager process — the component actually responsible for coordinating a transaction's lifecycle: acquiring locks, tracking what a transaction has read/written, driving the two-phase commit exchange with other nodes for replicated tables, and decidi...

Read full answer

26. How does Mnesia's transaction manager serialize concurrent transactions touching the same records?

Mnesia uses pessimistic locking rather than optimistic concurrency control: when a transaction reads or writes a record, mnesia_tm acquires the appropriate lock (read or write) on that record before proceeding, and a conflicting lock request from another concurrent transaction simply has to wait ...

Read full answer

27. Why can a "hot" record or table become a bottleneck under heavy Mnesia write load?

Because Mnesia uses per-record (or sometimes per-table) locking inside transactions, any record that many concurrent transactions all need to write to becomes a serialization point: every transaction touching it has to wait its turn for the write lock, no matter how many CPU cores or schedulers a...

Read full answer

28. How can you redesign a schema to reduce lock contention on a frequently-updated record?

The core fix is usually to split one hot, shared record into several independent pieces that different transactions can update without contending for the same lock, then combine them only when actually reading a final value. %% instead of one shared counter record: %% #counter{name = hits, value ...

Read full answer

29. What is mnesia:subscribe/1 used for?

mnesia:subscribe/1 registers the calling process to receive events about Mnesia activity — table changes, system events like node up/down, or schema changes — delivered as ordinary messages, letting application code react to data changes without polling. mnesia:subscribe({table, perso...

Read full answer

30. How do you react to table events using Mnesia's subscription mechanism?

After subscribing, the subscribing process simply receives ordinary messages in its mailbox whenever a matching event occurs, and handles them with a normal receive clause — there's no separate callback registration mechanism the way gen_event handlers work; it's just messages. mnesia:subsc...

Read full answer

31. What is a nested Mnesia transaction and how does it behave differently from a top-level one?

Calling mnesia:transaction/1 from inside code that's already running within another transaction creates a nested transaction . Rather than being a fully independent transaction, it shares the outer transaction's locks and only really commits when the outermost transaction itself commits — a...

Read full answer

32. Why should nested transactions generally be avoided or used carefully in Mnesia?

Since a nested transaction shares the outer transaction's fate (an inner abort takes down the whole outer transaction), relying on nesting to isolate a "risky" operation from the rest doesn't actually provide the isolation you might expect from true nested/savepoint semantics in some relational d...

Read full answer

33. What is the dc_dump_limit configuration parameter used for?

Mnesia doesn't write every single transaction directly and immediately into a disc_copies table's on-disk data file — it appends to a transaction log first, periodically "dumping" that log into the actual table files. dc_dump_limit controls how large that log is allowed to grow (as a multip...

Read full answer

34. Why does tuning the transaction log dump frequency matter for write-heavy Mnesia workloads?

Every write to a disc_copies table involves appending to a log file, which is cheap, versus periodically folding that log into the actual on-disk table representation, which is comparatively expensive (it involves more disk I/O restructuring the actual data file). Dumping too frequently adds over...

Read full answer

35. How do you merge two previously-separate Mnesia clusters into one?

Mnesia doesn't provide a single built-in "merge two schemas" command — merging two independently created databases is a deliberate, mostly manual migration process, since each side already has its own complete schema and potentially overlapping table names or keys. %% t ypical approach : ex...

Read full answer

36. What complications arise when merging schemas from two independently-created Mnesia databases?

The core problem is that each database's schema and table content evolved independently, with no shared history — so there's no inherent way for Mnesia to know how to reconcile them. Concretely: Key collisions — the same primary key value may exist in both databases referring to compl...

Read full answer

37. How does Mnesia decide which node's data wins during schema merge conflicts?

Left to its own defaults, Mnesia doesn't have an inherent basis for deciding whose data "wins" — when two nodes reconnect and discover their schemas or table contents disagree, it raises an inconsistent_database_event rather than guessing. Resolution happens through one of a few explicit me...

Read full answer

38. What is the difference between a global lock and a per-record lock in Mnesia transactions?

A per-record lock (the default behavior of read/1 / write/1 inside a transaction) only blocks other transactions from touching that specific record, letting unrelated concurrent transactions on other records in the same table proceed freely. A global (table-level) lock, taken via mnesia:read_lock...

Read full answer

39. When would you use mnesia:read_lock_table/1 instead of relying on per-record locks?

Table-level locking makes sense specifically when an operation needs a consistent view of, or exclusive access to, the entire table at once — something per-record locks can't provide, since they only protect individual rows from concurrent modification while leaving the rest of the table op...

Read full answer

40. How do you profile and optimize Mnesia transaction throughput in a write-heavy system?

Profiling starts with identifying where time is actually going: lock contention on specific records/tables, replication coordination overhead across nodes, or transaction log dump frequency — each has a different fix. Check for hot records/tables via tracing or by inspecting which transacti...

Read full answer

41. Why is batching multiple related writes into a single transaction usually better than many small transactions?

Every transaction carries fixed overhead beyond the actual work it does: acquiring locks, and for replicated tables, coordinating a two-phase commit round-trip with every replica. Running ten related writes as ten separate transactions pays that coordination overhead ten times over; wrapping them...

Read full answer

42. How does Mnesia's schema interact with OTP release upgrades (appup/relup)?

A release upgrade's appup instructions describe how to hot-swap module code and transform running gen_server state via code_change/3 , but Mnesia's schema and table data live outside that per-process state entirely — changing a Mnesia record's shape isn't something code_change/3 touches, si...

Read full answer

43. What is the difference between mnesia:dirty_all_keys/1 and mnesia:all_keys/1?

Both return every primary key in a table, but they differ in the same way other dirty/transactional pairs do: mnesia:all_keys/1 must run inside a transaction (or another activity context) and takes the appropriate lock, giving you a result consistent with the rest of that transaction's view of th...

Read full answer

44. Explain the internal working of how Mnesia chooses which replica to read from in a load-balanced cluster?

For a table replicated across multiple nodes, Mnesia tracks a per-table where_to_read preference — by default, favoring reading from the local node's own copy if it holds one, since a local read avoids any network round-trip entirely. flowchart TD A[Read request for Table] --> B{Does this n...

Read full answer

45. What is the where_to_read table_info item used for?

mnesia:table_info(Table, where_to_read) returns which node the local Mnesia instance would currently read that table from — useful for diagnosing read-routing behavior directly, rather than inferring it indirectly from latency measurements. mnesia:table_info(session, where_to_read). %% -> n...

Read full answer

46. What is mnesia:dump_log/0 used for?

mnesia:dump_log/0 forces an immediate dump of the current transaction log into the actual on-disk table files, rather than waiting for the automatic threshold (governed by dc_dump_limit ) to be reached naturally. mnesia:dump_log(). %% -> dumped It's mainly useful around planned maintenance moment...

Read full answer

47. How do you handle a transaction that needs to retry after being aborted due to a deadlock?

When Mnesia detects a deadlock between two transactions, it aborts one of them automatically, but it doesn't retry it for you — the calling code gets back {aborted, Reason} and is responsible for deciding whether and how to retry. retry_transaction(Fun, Retries) when Retries > 0 -> case mne...

Read full answer

48. What is the difference between mnesia:transaction/1's built-in behavior and manual retry logic you might add?

mnesia:transaction/1 itself already retries internally in one specific, narrow case: if the transaction is aborted purely because of a lock conflict that Mnesia's own internal deadlock resolution detected as safely retryable, it can re-run the transaction function automatically without the caller...

Read full answer

«
»

Comments & Discussions