The txindex was moved to its own database in #13033. As part of that change, data migration functionality was added, allowing the txindex to be maintained across upgrade without having to rebuild the entire index from scratch:

https://github.com/bitcoin/bitcoin/blob/5cf28d5203a6203355283ea59f071af6a468d239/src/index/txindex.cpp#L75-L90

13033 was included in v0.17, released in October 2018 and EOL in August 2020. Anyone who hasn't upgraded at this point is running unsupported code, and shouldn't have expectations around upgrading their node without having to rebuild the index. We should simplify the code by removing the `MigrateData()` functionality.
INIT_REINDEX,
    INIT_DOWNLOAD,
    POST_INIT
};
extern RecursiveMutex cs_main;
typedef std::unordered_map<uint256, CBlockIndex*, BlockHasher> BlockMap;
extern Mutex g_best_block_mutex;
extern std::condition_variable g_best_block_cv;
extern uint256 g_best_block;
/** Whether there are dedicated script-checking threads running.
 * False indicates all script checking is done on the main threadMessageHandler thread.
 */
extern bool g_parallel_script_checks;
extern bool fRequireStandard;
extern bool fCheckBlockIndex;
extern bool fCheckpointsEnabled;
extern CFeeRate minRelayTxFee;
extern int64_t nMaxTipAge;
extern uint256 hashAssumeValid;
extern arith_uint256 nMinimumChainWork;
extern CBlockIndex *pindexBestHeader;
extern const std::vector<std::string> CHECKLEVEL_DOC;
void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman);
void StartScriptCheckWorkerThreads(int threads_num);
void StopScriptCheckWorkerThreads();
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
bool AbortNode(BlockValidationState& state, const std::string& strMessage, const bilingual_str& userMessage = bilingual_str{});
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex* pindex);
void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeight);