Mnesia memory, size and effects of table copy types

Matthew Sackman <>
Thu Jul 2 12:39:20 CEST 2009


I'm doing some manual memory management and when memory gets tight, I'm
converting some mnesia tables from disc_copies to disc_only_copies. But
I have a few questions because what I'm seeing reported through table_info
seems odd.

ets and mnesia claim to report memory size in words. But dets reports in
bytes. When a table is put in disc_only_copies, can someone confirm it's
still words I'm getting back, and not bytes? Because the following looks
very very fishy

> mnesia:create_table(mytable, [{disc_copies, [node()]}]).
{atomic,ok}
> mnesia:table_info(mytable, size).
0
> mnesia:table_info(mytable, memory).
299

Ok, so presumeably, that's the number of words in RAM. Maybe. Docs don't
actually say - it could very well be the sum of bytes on disk and words
in ram, but let's assume it's not double counting.

> mnesia:change_table_copy_type(mytable, node(), disc_only_copies).
{atomic,ok}
> mnesia:table_info(mytable, size).                                
0
> mnesia:table_info(mytable, memory).                              
5752

Um. Ok, so maybe that's just some RAM based overhead or something. But
it's gone up quite a long way... far enough that I'm not convinced
that's words and not bytes.

> mnesia:change_table_copy_type(mytable, node(), ram_copies).      
{atomic,ok}
> mnesia:table_info(mytable, size).                          
0
> mnesia:table_info(mytable, memory).                        
299

Oh well, at least we're back. Now, let's fill the table up:

> [ mnesia:dirty_write(mytable, {mytable, N, <<0:8192>>}) || N <- lists:seq(1, 1000000) ].
[ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,ok,
 ok,ok,ok,ok,ok,ok,ok,ok,ok,ok|...]
> mnesia:table_info(mytable, size).                                                       
1000000
> mnesia:table_info(mytable, memory).                                                     
17144943

> mnesia:change_table_copy_type(mytable, node(), disc_copies).                            
{atomic,ok}
> mnesia:table_info(mytable, size).                                                       
1000000
> mnesia:table_info(mytable, memory).                         
17144943

Still good... but then:

> mnesia:change_table_copy_type(mytable, node(), disc_only_copies).
{atomic,ok}
> mnesia:table_info(mytable, size).                                
1000000
> mnesia:table_info(mytable, memory).                              
1929666056

Oh goodie. 1929666056 / 17144943 = 112.6. So going to disk has made it
MUCH bigger. I am less than convinced by these numbers.

> size(term_to_binary({mytable, 1000000, <<0:8192>>})) * 1000000.
1047000000

So, given that's at least in the same magnitude, I'm really suspecting
the number returned by table_info when in disc_only_copies is in
*bytes*, not words.

> round ((size(term_to_binary({mytable, 1000000, <<0:8192>>})) * 1000000) / erlang:system_info(wordsize)).
130875000

The minimum number of words is some 7 times bigger than the amount of
memory reported when using ets. However, I can well believe this
assuming we don't really have 1e6 copies of that binary.

So, from this, I deduce that calling table_info(Tab, memory) reports:
a) if ets is being used, the number of words of RAM used by the table
b) if ets isn't being used, the number of bytes of the table on disk

Is this right?

Cheers,

Matthew


More information about the erlang-questions mailing list