mdbx: исправление неверной assert-проверки и микрооптимизация.

В пути фиксации вложенных транзакций, условие в assert-проверке не было
корректным для случая, когда таблица уже существовала и её дескриптор
был открыт, использовался в завершаемой вложенной транзакции, но не
использовался в родительской.

Это исправление недочета также передаёт уже загруженное из БД кешируемое
состояние таблицы в родительскую транзакцию.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2025-04-10 11:40:17 +03:00
parent 4691c0b5c8
commit f35c1fe5bc

View File

@ -560,15 +560,16 @@ int txn_nested_join(MDBX_txn *txn, struct commit_timestamp *ts) {
/* Update parent's DBs array */ /* Update parent's DBs array */
eASSERT(env, parent->n_dbi == txn->n_dbi); eASSERT(env, parent->n_dbi == txn->n_dbi);
TXN_FOREACH_DBI_ALL(txn, dbi) { TXN_FOREACH_DBI_ALL(txn, dbi) {
if (txn->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)) { if (txn->dbi_state[dbi] != (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY))) {
eASSERT(env, (txn->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)) != 0 ||
(txn->dbi_state[dbi] | DBI_STALE) ==
(parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY)));
parent->dbs[dbi] = txn->dbs[dbi]; parent->dbs[dbi] = txn->dbs[dbi];
/* preserve parent's status */ /* preserve parent's status */
const uint8_t state = txn->dbi_state[dbi] | (parent->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)); const uint8_t state = txn->dbi_state[dbi] | (parent->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY));
DEBUG("dbi %zu dbi-state %s 0x%02x -> 0x%02x", dbi, (parent->dbi_state[dbi] != state) ? "update" : "still", DEBUG("dbi %zu dbi-state %s 0x%02x -> 0x%02x", dbi, (parent->dbi_state[dbi] != state) ? "update" : "still",
parent->dbi_state[dbi], state); parent->dbi_state[dbi], state);
parent->dbi_state[dbi] = state; parent->dbi_state[dbi] = state;
} else {
eASSERT(env, txn->dbi_state[dbi] == (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY)));
} }
} }