Currently it is possible to stupidly lose mempool data by calling the rpc "savemempool" before the previous stored mempool has been read and processed to the memory mempool.

I haven't looked at the code yet, but at minimum one ugly solution would be to have a global g_is_mempool_read_finished (or something of the short) that starts false and gets sets to true once the reading is reading processing of mempool.dat is successfully finished. The rpc savemempool checks this global on the start and returns a an error while it remains false.

* Note that we guarantee that either the proof-of-work is valid on pblock, or
 * (and possibly also) BlockChecked will have been called.
 * 
 * Call without cs_main held.
 *
 * @param[in]   pblock  The block we want to process.
 * @param[in]   fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
 * @param[out]  fNewBlock A boolean which is set to indicate if the block was first received via this call
 * @return True if state.IsValid()
 */
bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool* fNewBlock);
/**
 * Process incoming block headers.
 *
 * Call without cs_main held.
 *
 * @param[in]  block The block headers themselves
 * @param[out] state This may be set to an Error state if any error occurred processing them
 * @param[in]  chainparams The params for the chain we want to connect to
 * @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers
 * @param[out] first_invalid First header that fails validation, if one exists
 */
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, CValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex=nullptr, CBlockHeader *first_invalid=nullptr);
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0, bool blocks_dir = false);
FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly = false);
fs::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix);
bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp = nullptr);
bool LoadGenesisBlock(const CChainParams& chainparams);
/** Load the block tree and coins database from disk,
 * initializing state if we're running with -reindex. */