From baa79962891ff3a597d8d9dfdf465faf46e095d6 Mon Sep 17 00:00:00 2001 From: Serge Tupchii Date: Tue, 18 Jun 2024 17:24:53 +0300 Subject: [PATCH] fix(data_backup): allow exporting `ram_copies` Mnesia tables Currently, ram tables can be used for message retainer. --- .../src/emqx_mgmt_data_backup.erl | 10 +++++-- .../test/emqx_mgmt_data_backup_SUITE.erl | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/apps/emqx_management/src/emqx_mgmt_data_backup.erl b/apps/emqx_management/src/emqx_mgmt_data_backup.erl index ab0deaa87..50ddc33ca 100644 --- a/apps/emqx_management/src/emqx_mgmt_data_backup.erl +++ b/apps/emqx_management/src/emqx_mgmt_data_backup.erl @@ -408,9 +408,13 @@ export_mnesia_tab(TarDescriptor, TabName, BackupName, BackupBaseName, Opts) -> do_export_mnesia_tab(TabName, BackupName) -> Node = node(), try - {ok, TabName, [Node]} = mnesia:activate_checkpoint( - [{name, TabName}, {min, [TabName]}, {allow_remote, false}] - ), + Opts0 = [{name, TabName}, {min, [TabName]}, {allow_remote, false}], + Opts = + case mnesia:table_info(TabName, storage_type) of + ram_copies -> [{ram_overrides_dump, true} | Opts0]; + _ -> Opts0 + end, + {ok, TabName, [Node]} = mnesia:activate_checkpoint(Opts), MnesiaBackupName = mnesia_backup_name(BackupName, TabName), ok = filelib:ensure_dir(MnesiaBackupName), ok = mnesia:backup_checkpoint(TabName, MnesiaBackupName), diff --git a/apps/emqx_management/test/emqx_mgmt_data_backup_SUITE.erl b/apps/emqx_management/test/emqx_mgmt_data_backup_SUITE.erl index fb5d5988c..4e584824d 100644 --- a/apps/emqx_management/test/emqx_mgmt_data_backup_SUITE.erl +++ b/apps/emqx_management/test/emqx_mgmt_data_backup_SUITE.erl @@ -19,6 +19,7 @@ -compile(nowarn_export_all). -include_lib("emqx_utils/include/emqx_message.hrl"). +-include_lib("emqx/include/emqx_mqtt.hrl"). -include_lib("eunit/include/eunit.hrl"). -include_lib("common_test/include/ct.hrl"). -include_lib("snabbkaffe/include/snabbkaffe.hrl"). @@ -144,6 +145,34 @@ t_import_retained_messages(Config) -> {ok, #{filename := FileName}} = emqx_mgmt_data_backup:export(), ?assertEqual(Exp, emqx_mgmt_data_backup:import(FileName)). +t_export_ram_retained_messages(_Config) -> + {ok, _} = emqx_retainer:update_config( + #{ + <<"enable">> => true, + <<"backend">> => #{<<"storage_type">> => <<"ram">>} + } + ), + ?assertEqual(ram_copies, mnesia:table_info(emqx_retainer_message, storage_type)), + Topic = <<"t/backup_test_export_retained_ram/1">>, + Payload = <<"backup_test_retained_ram">>, + Msg = emqx_message:make( + <<"backup_test">>, + ?QOS_0, + Topic, + Payload, + #{retain => true}, + #{} + ), + _ = emqx_broker:publish(Msg), + {ok, #{filename := BackupFileName}} = emqx_mgmt_data_backup:export(), + ok = emqx_retainer:delete(Topic), + ?assertEqual({ok, []}, emqx_retainer:read_message(Topic)), + ?assertEqual( + {ok, #{db_errors => #{}, config_errors => #{}}}, + emqx_mgmt_data_backup:import(BackupFileName) + ), + ?assertMatch({ok, [#message{payload = Payload}]}, emqx_retainer:read_message(Topic)). + t_cluster_hocon_export_import(Config) -> RawConfBeforeImport = emqx:get_raw_config([]), BootstrapFile = filename:join(?config(data_dir, Config), ?BOOTSTRAP_BACKUP),