1736
1736
return op_synced;
1739
#ifdef XT_CORRECT_TABLE_FREE_COUNT
1740
#define CORRECT_COUNT TRUE
1742
#define CORRECT_COUNT FALSE
1744
#ifdef XT_CHECK_RECORD_FREE_COUNT
1745
#define CHECK_RECS TRUE
1747
#define CHECK_RECS FALSE
1749
#if defined(XT_CHECK_RECORD_FREE_COUNT) || defined(XT_CHECK_ROW_FREE_COUNT)
1750
#define RECOVER_FREE_COUNTS
1753
#ifdef RECOVER_FREE_COUNTS
1754
/* {CORRECTED-ROW-COUNT}
1755
* This error can be repeated by crashing the server during
1756
* high activitity, after flush table writes the table header
1758
* On recovery, the free count "from the future" is used as
1759
* the starting point for subsequent allocation and frees.
1760
* The count is wrong after that point.
1762
* The recovery of the count only works correctly if a
1763
* checkpoint is complete successfully after that table
1764
* header is flushed. Basically the writing of the table
1765
* header should be synchronsized with the writing of the
1766
* end of the checkpoint.
1768
* Another solution would be to log the count, along with
1769
* the allocate and free commannds.
1771
* The 3rd solution is the one used here. The count is corrected
1774
static void xres_recover_table_free_counts(XTThreadPtr self, XTDatabaseHPtr db, XTWriterStatePtr ws)
1777
XTTableEntryPtr te_ptr;
1780
xt_enum_tables_init(&edx);
1781
while ((te_ptr = xt_enum_tables_next(self, db, &edx))) {
1782
if ((tab = te_ptr->te_table)) {
1783
if (xres_open_table(self, ws, te_ptr->te_tab_id))
1784
xt_tab_check_free_lists(self, ws->ws_ot, CHECK_RECS, CORRECT_COUNT);
1740
1791
* Operations from the log are applied in sequence order.
1741
1792
* If the operations are out of sequence, they are buffered
2567
2618
/* This is true because if no transaction was placed in RAM then
2568
2619
* the next transaction in RAM will have the next ID: */
2569
2620
db->db_xn_min_ram_id = db->db_xn_curr_id + 1;
2622
#ifdef RECOVER_FREE_COUNTS
2623
if (xres_cp_log_id != *log_id || xres_cp_log_offset != *log_offset) {
2624
/* Recovery took place, correct the row count! */
2625
xres_recover_table_free_counts(self, db, &ws);