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 {
81     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 
93     ~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 {
113     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,
builder() -> Builder194     void* extra
195     );
196 
197 int toku_txn_manager_iter_over_live_root_txns(
198     TXN_MANAGER txn_manager,
from_parts(src: Parts) -> Result<Uri, InvalidUriParts>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