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/*======
5This file is part of PerconaFT.
6
7
8Copyright (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
46void 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 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
54
55typedef struct txn_manager *TXN_MANAGER;
56
57struct referenced_xid_tuple {
58 TXNID begin_id;
59 TXNID end_id;
60 uint32_t references;
61};
62
63struct 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};
78typedef struct txn_manager *TXN_MANAGER;
79
80struct 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
112struct 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
138void toku_txn_manager_init(TXN_MANAGER* txn_manager);
139void toku_txn_manager_destroy(TXN_MANAGER txn_manager);
140
141TXNID toku_txn_manager_get_oldest_living_xid(TXN_MANAGER txn_manager);
142
143TXNID toku_txn_manager_get_oldest_referenced_xid_estimate(TXN_MANAGER txn_manager);
144
145void toku_txn_manager_handle_snapshot_create_for_child_txn(
146 TOKUTXN txn,
147 TXN_MANAGER txn_manager,
148 TXN_SNAPSHOT_TYPE snapshot_type
149 );
150void 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.
158void 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
165void toku_txn_manager_start_txn_for_recovery(
166 TOKUTXN txn,
167 TXN_MANAGER txn_manager,
168 TXNID xid
169 );
170
171void toku_txn_manager_finish_txn(TXN_MANAGER txn_manager, TOKUTXN txn);
172
173void 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
180void 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.
185int toku_txn_manager_get_root_txn_from_xid (TXN_MANAGER txn_manager, TOKU_XA_XID *xid, DB_TXN **txnp);
186
187uint32_t toku_txn_manager_num_live_root_txns(TXN_MANAGER txn_manager);
188
189typedef int (*txn_mgr_iter_callback)(TOKUTXN txn, void* extra);
190
191int toku_txn_manager_iter_over_live_txns(
192 TXN_MANAGER txn_manager,
193 txn_mgr_iter_callback cb,
194 void* extra
195 );
196
197int toku_txn_manager_iter_over_live_root_txns(
198 TXN_MANAGER txn_manager,
199 txn_mgr_iter_callback cb,
200 void* extra
201 );
202
203int 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
211void toku_txn_manager_suspend(TXN_MANAGER txn_manager);
212void toku_txn_manager_resume(TXN_MANAGER txn_manager);
213
214void toku_txn_manager_set_last_xid_from_logger(TXN_MANAGER txn_manager, TXNID last_xid);
215void toku_txn_manager_set_last_xid_from_recovered_checkpoint(TXN_MANAGER txn_manager, TXNID last_xid);
216TXNID toku_txn_manager_get_last_xid(TXN_MANAGER mgr);
217
218bool toku_txn_manager_txns_exist(TXN_MANAGER mgr);
219
220// Test-only function
221void toku_txn_manager_increase_last_xid(TXN_MANAGER mgr, uint64_t increment);
222
223TXNID toku_get_youngest_live_list_txnid_for(TXNID xc, const xid_omt_t &snapshot_txnids, const rx_omt_t &referenced_xids);
224