1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: 3 #ident "$Id$" 4 /*====== 5 This file is part of PerconaFT. 6 7 8 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. 9 10 PerconaFT is free software: you can redistribute it and/or modify 11 it under the terms of the GNU General Public License, version 2, 12 as published by the Free Software Foundation. 13 14 PerconaFT is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. 21 22 ---------------------------------------- 23 24 PerconaFT is free software: you can redistribute it and/or modify 25 it under the terms of the GNU Affero General Public License, version 3, 26 as published by the Free Software Foundation. 27 28 PerconaFT is distributed in the hope that it will be useful, 29 but WITHOUT ANY WARRANTY; without even the implied warranty of 30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31 GNU Affero General Public License for more details. 32 33 You should have received a copy of the GNU Affero General Public License 34 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. 35 ======= */ 36 37 #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." 38 39 #pragma once 40 41 #include "portability/toku_portability.h" 42 #include "portability/toku_pthread.h" 43 44 #include "ft/txn/txn.h" 45 46 void set_test_txn_sync_callback(void (*) (pthread_t, void*), void*); 47 #define toku_test_txn_sync_callback(a) ((test_txn_sync_callback)? test_txn_sync_callback( a,test_txn_sync_callback_extra) : (void) 0) 48 49 #if defined(TOKU_DEBUG_TXN_SYNC) 50 #define toku_debug_txn_sync(a) toku_test_txn_sync_callback(a) 51 #else 52 #define toku_debug_txn_sync(a) ((void) 0) 53 #endif // defined(TOKU_DEBUG_TXN_SYNC) 54 55 typedef struct txn_manager *TXN_MANAGER; 56 57 struct referenced_xid_tuple { 58 TXNID begin_id; 59 TXNID end_id; 60 uint32_t references; 61 }; 62 63 struct txn_manager { 64 toku_mutex_t txn_manager_lock; // a lock protecting this object 65 txn_omt_t live_root_txns; // a sorted tree. 66 xid_omt_t live_root_ids; //contains TXNID x | x is snapshot txn 67 TOKUTXN snapshot_head; 68 TOKUTXN snapshot_tail; 69 uint32_t num_snapshots; 70 // Contains 3-tuples: (TXNID begin_id, TXNID end_id, uint64_t num_live_list_references) 71 // for committed root transaction ids that are still referenced by a live list. 72 rx_omt_t referenced_xids; 73 74 TXNID last_xid; 75 TXNID last_xid_seen_for_recover; 76 TXNID last_calculated_oldest_referenced_xid; 77 }; 78 typedef struct txn_manager *TXN_MANAGER; 79 80 struct txn_manager_state { txn_manager_statetxn_manager_state81 txn_manager_state(TXN_MANAGER mgr) : 82 txn_manager(mgr), 83 initialized(false) { 84 snapshot_xids.create_no_array(); 85 referenced_xids.create_no_array(); 86 live_root_txns.create_no_array(); 87 } 88 89 // should not copy construct 90 txn_manager_state &operator=(txn_manager_state &rhs) = delete; 91 txn_manager_state(txn_manager_state &rhs) = delete; 92 ~txn_manager_statetxn_manager_state93 ~txn_manager_state() { 94 snapshot_xids.destroy(); 95 referenced_xids.destroy(); 96 live_root_txns.destroy(); 97 } 98 99 void init(); 100 101 TXN_MANAGER txn_manager; 102 bool initialized; 103 104 // a snapshot of the txn manager's mvcc state 105 // only valid if initialized = true 106 xid_omt_t snapshot_xids; 107 rx_omt_t referenced_xids; 108 xid_omt_t live_root_txns; 109 }; 110 111 // represents all of the information needed to run garbage collection 112 struct txn_gc_info { txn_gc_infotxn_gc_info113 txn_gc_info(txn_manager_state *st, TXNID xid_sgc, TXNID xid_ip, bool mvcc) 114 : txn_state_for_gc(st), 115 oldest_referenced_xid_for_simple_gc(xid_sgc), 116 oldest_referenced_xid_for_implicit_promotion(xid_ip), 117 mvcc_needed(mvcc) { 118 } 119 120 // a snapshot of the transcation system. may be null. 121 txn_manager_state *txn_state_for_gc; 122 123 // the oldest xid in any live list 124 // 125 // suitible for simple garbage collection that cleans up multiple committed 126 // transaction records into one. not suitible for implicit promotions, which 127 // must be correct in the face of abort messages - see ftnode->oldest_referenced_xid 128 TXNID oldest_referenced_xid_for_simple_gc; 129 130 // lower bound on the oldest xid in any live when the messages to be cleaned 131 // had no messages above them. suitable for implicitly promoting a provisonal uxr. 132 TXNID oldest_referenced_xid_for_implicit_promotion; 133 134 // whether or not mvcc is actually needed - false during recovery and non-transactional systems 135 const bool mvcc_needed; 136 }; 137 138 void toku_txn_manager_init(TXN_MANAGER* txn_manager); 139 void toku_txn_manager_destroy(TXN_MANAGER txn_manager); 140 141 TXNID toku_txn_manager_get_oldest_living_xid(TXN_MANAGER txn_manager); 142 143 TXNID toku_txn_manager_get_oldest_referenced_xid_estimate(TXN_MANAGER txn_manager); 144 145 void toku_txn_manager_handle_snapshot_create_for_child_txn( 146 TOKUTXN txn, 147 TXN_MANAGER txn_manager, 148 TXN_SNAPSHOT_TYPE snapshot_type 149 ); 150 void toku_txn_manager_handle_snapshot_destroy_for_child_txn( 151 TOKUTXN txn, 152 TXN_MANAGER txn_manager, 153 TXN_SNAPSHOT_TYPE snapshot_type 154 ); 155 156 157 // Assign a txnid. Log the txn begin in the recovery log. Initialize the txn live lists. 158 void toku_txn_manager_start_txn( 159 TOKUTXN txn, 160 TXN_MANAGER txn_manager, 161 TXN_SNAPSHOT_TYPE snapshot_type, 162 bool read_only 163 ); 164 165 void toku_txn_manager_start_txn_for_recovery( 166 TOKUTXN txn, 167 TXN_MANAGER txn_manager, 168 TXNID xid 169 ); 170 171 void toku_txn_manager_finish_txn(TXN_MANAGER txn_manager, TOKUTXN txn); 172 173 void toku_txn_manager_clone_state_for_gc( 174 TXN_MANAGER txn_manager, 175 xid_omt_t* snapshot_xids, 176 rx_omt_t* referenced_xids, 177 xid_omt_t* live_root_txns 178 ); 179 180 void toku_txn_manager_id2txn_unlocked(TXN_MANAGER txn_manager, TXNID_PAIR txnid, TOKUTXN *result); 181 182 // Returns a root txn associated with xid. The system as a whole 183 // assumes that only root txns get prepared, adn therefore only 184 // root txns will have XIDs associated with them. 185 int toku_txn_manager_get_root_txn_from_xid (TXN_MANAGER txn_manager, TOKU_XA_XID *xid, DB_TXN **txnp); 186 187 uint32_t toku_txn_manager_num_live_root_txns(TXN_MANAGER txn_manager); 188 189 typedef int (*txn_mgr_iter_callback)(TOKUTXN txn, void* extra); 190 191 int toku_txn_manager_iter_over_live_txns( 192 TXN_MANAGER txn_manager, 193 txn_mgr_iter_callback cb, 194 void* extra 195 ); 196 197 int toku_txn_manager_iter_over_live_root_txns( 198 TXN_MANAGER txn_manager, 199 txn_mgr_iter_callback cb, 200 void* extra 201 ); 202 203 int toku_txn_manager_recover_root_txn( 204 TXN_MANAGER txn_manager, 205 struct tokulogger_preplist preplist[/*count*/], 206 long count, 207 long *retp, /*out*/ 208 uint32_t flags 209 ); 210 211 void toku_txn_manager_suspend(TXN_MANAGER txn_manager); 212 void toku_txn_manager_resume(TXN_MANAGER txn_manager); 213 214 void toku_txn_manager_set_last_xid_from_logger(TXN_MANAGER txn_manager, TXNID last_xid); 215 void toku_txn_manager_set_last_xid_from_recovered_checkpoint(TXN_MANAGER txn_manager, TXNID last_xid); 216 TXNID toku_txn_manager_get_last_xid(TXN_MANAGER mgr); 217 218 bool toku_txn_manager_txns_exist(TXN_MANAGER mgr); 219 220 // Test-only function 221 void toku_txn_manager_increase_last_xid(TXN_MANAGER mgr, uint64_t increment); 222 223 TXNID toku_get_youngest_live_list_txnid_for(TXNID xc, const xid_omt_t &snapshot_txnids, const rx_omt_t &referenced_xids); 224