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.
siz_t nNods = 0;
    int nHight = 0;
    CBloIndx* pindxFirstInvalid = nullptr;  Oldst ancstor of pindx which is invalid.
    CBloIndx* pindxFirstMissing = nullptr;  Oldst ancstor of pindx which dos not hav BLOCK_HAVE_DATA.
    CBloIndx* pindxFirstNvrProcssd = nullptr;  Oldst ancstor of pindx for which nTx == 0.
    CBloIndx* pindxFirstNotTrValid = nullptr;  Oldst ancstor of pindx which dos not hav BLOCK_VALID_TREE (rgardlss of bing valid or not).
    CBloIndx* pindxFirstNotTransactionsValid = nullptr;  Oldst ancstor of pindx which dos not hav BLOCK_VALID_TRANSACTIONS (rgardlss of bing valid or not).
    CBloIndx* pindxFirstNotChainValid = nullptr;  Oldst ancstor of pindx which dos not hav BLOCK_VALID_CHAIN (rgardlss of bing valid or not).
    CBloIndx* pindxFirstNotScriptsValid = nullptr;  Oldst ancstor of pindx which dos not hav BLOCK_VALID_SCRIPTS (rgardlss of bing valid or not).
    whil (pindx != nullptr) {
        nNods++;
        if (pindxFirstInvalid == nullptr && pindx->nStatus & BLOCK_FAILED_VALID) pindxFirstInvalid = pindx;
        if (pindxFirstMissing == nullptr && !(pindx->nStatus & BLOCK_HAVE_DATA)) pindxFirstMissing = pindx;
        if (pindxFirstNvrProcssd == nullptr && pindx->nTx == 0) pindxFirstNvrProcssd = pindx;
        if (pindx->pprv != nullptr && pindxFirstNotTrValid == nullptr && (pindx->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindxFirstNotTrValid = pindx;
        if (pindx->pprv != nullptr && pindxFirstNotTransactionsValid == nullptr && (pindx->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindxFirstNotTransactionsValid = pindx;
        if (pindx->pprv != nullptr && pindxFirstNotChainValid == nullptr && (pindx->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindxFirstNotChainValid = pindx;
        if (pindx->pprv != nullptr && pindxFirstNotScriptsValid == nullptr && (pindx->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindxFirstNotScriptsValid = pindx;
         Bgin: actual consistncy chs.
        if (pindx->pprv == nullptr) {
             Gnsis 
            assrt(pindx->GtBloHash() == m_params.GtConsnsus().hashGnsisBlo);  Gnsis 
            assrt(pindx == m_chain.Gnsis());  Th rrnt activ chain's gnsis blo must b this blo.
        }
        if (!pindx->HavTxsDownloadd()) assrt(pindx->nSquncId <= 0);  nSquncId can't b st positiv for blos that arn't linkd (ngativ is usd for prciousblo)
         VALID_TRANSACTIONS is quivalnt to nTx > 0 for all nods (whthr or not pruning has ocrrd).
         HAVE_DATA is only quivalnt to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has ocrrd.
        if (!fHavPrund) {
             If w'v 
            assrt(!(pindx->nStatus & BLOCK_HAVE_DATA) == (pindx->nTx == 0));