Zero  0.1.0
xct.h
Go to the documentation of this file.
1 /*
2  * (c) Copyright 2011-2014, Hewlett-Packard Development Company, LP
3  */
4 
5 /* -*- mode:C++; c-basic-offset:4 -*-
6  Shore-MT -- Multi-threaded port of the SHORE storage manager
7 
8  Copyright (c) 2007-2009
9  Data Intensive Applications and Systems Labaratory (DIAS)
10  Ecole Polytechnique Federale de Lausanne
11 
12  All Rights Reserved.
13 
14  Permission to use, copy, modify and distribute this software and
15  its documentation is hereby granted, provided that both the
16  copyright notice and this permission notice appear in all copies of
17  the software, derivative works or modified versions, and any
18  portions thereof, and that both notices appear in supporting
19  documentation.
20 
21  This code is distributed in the hope that it will be useful, but
22  WITHOUT ANY WARRANTY; without even the implied warranty of
23  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
24  DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
25  RESULTING FROM THE USE OF THIS SOFTWARE.
26 */
27 
28 /*<std-header orig-src='shore' incl-file-exclusion='XCT_H'>
29 
30  $Id: xct.h,v 1.161 2010/12/08 17:37:43 nhall Exp $
31 
32 SHORE -- Scalable Heterogeneous Object REpository
33 
34 Copyright (c) 1994-99 Computer Sciences Department, University of
35  Wisconsin -- Madison
36 All Rights Reserved.
37 
38 Permission to use, copy, modify and distribute this software and its
39 documentation is hereby granted, provided that both the copyright
40 notice and this permission notice appear in all copies of the
41 software, derivative works or modified versions, and any portions
42 thereof, and that both notices appear in supporting documentation.
43 
44 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
45 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
46 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
47 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48 
49 This software was developed with support by the Advanced Research
50 Project Agency, ARPA order number 018 (formerly 8230), monitored by
51 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
52 Further funding for this work was provided by DARPA through
53 Rome Research Laboratory Contract No. F30602-97-2-0247.
54 
55 */
56 
57 #ifndef __XCT_H
58 #define __XCT_H
59 
60 #include "w_defines.h"
61 
62 /* -- do not edit anything above this line -- </std-header>*/
63 
64 #if W_DEBUG_LEVEL > 2
65 // You can rebuild with this turned on
66 // if you want comment log records inserted into the log
67 // to help with deciphering the log when recovery bugs
68 // are nasty.
69 #define X_LOG_COMMENT_ON 1
70 #define ADD_LOG_COMMENT_SIG ,const char *debugmsg
71 #define ADD_LOG_COMMENT_USE ,debugmsg
72 #define X_LOG_COMMENT_USE(x) ,x
73 
74 #else
75 
76 #define X_LOG_COMMENT_ON 0
77 #define ADD_LOG_COMMENT_SIG
78 #define ADD_LOG_COMMENT_USE
79 #define X_LOG_COMMENT_USE(x)
80 #endif
81 
82 #include <chrono>
83 #include <set>
84 #include <atomic>
85 #include "AtomicCounter.hpp"
86 #include "w_key.h"
87 #include "lsn.h"
88 #include "allocator.h"
89 #include "latch.h"
90 
91 struct okvl_mode;
92 struct RawXct;
93 class lockid_t; // forward
94 class xct_i; // forward
95 class restart_thread_t; // forward
96 class lock_m; // forward
97 class lock_core_m; // forward
98 class lock_request_t; // forward
99 class xct_lock_info_t; // forward
100 class smthread_t; // forward
101 class lil_private_table;
102 class chkpt_t;
103 class logrec_t; // forward
104 class fixable_page_h; // forward
105 
126 public:
128  next_pid(0),
129  next_level(0) {}
130 
132  int32_t pages_checked;
133 
135  std::set<PageID> pids_inconsistent;
136 
139 
141  int16_t next_level;
142 
145 
148 };
149 
155 class stid_list_elem_t {
156 public:
157  StoreID stid;
158 
159  w_link_t _link;
160 
161  stid_list_elem_t(const StoreID& theStid)
162  : stid(theStid) {};
163 
164  ~stid_list_elem_t() {
165  if (_link.member_of() != nullptr) {
166  _link.detach();
167  }
168  }
169 
170  static uint32_t link_offset() {
171  return W_LIST_ARG(stid_list_elem_t, _link);
172  }
173 };
185 class xct_t : public smlevel_0 {
187  friend class xct_i;
188  friend class smthread_t;
189  friend class restart_thread_t;
190  friend class lock_m;
191  friend class lock_core_m;
192  friend class lock_request_t;
193 
194 public:
195  typedef xct_state_t state_t;
196 
197  /* A nearly-POD struct whose only job is to enable a N:1
198  relationship between the log streams of a transaction (xct_t)
199  and its core functionality such as locking and 2PC (xct_core).
200 
201  Any transaction state which should not eventually be replicated
202  per-thread goes here. Usually such state is protected by the
203  1-thread-xct-mutex.
204 
205  Static data members can stay in xct_t, since they're not even
206  duplicated per-xct, let alone per-thread.
207  */
208  struct xct_core {
209  xct_core(tid_t const& t, state_t s, int timeout);
210 
211  ~xct_core();
212 
213  //-- from xct.h ----------------------------------------------------
214  tid_t _tid;
215 
216  int _timeout; // default timeout value for lock reqs
217  bool _warn_on;
218 
219  xct_lock_info_t* _lock_info;
220 
221  lil_private_table* _lil_lock_info;
222 
224  RawXct* _raw_lock_xct;
225 
226  state_t _state;
227 
228  bool _read_only;
229 
230  lintel::Atomic<int> _xct_ended; // used for self-checking (assertions) only
231  bool _xct_aborting; // distinguish abort()ing xct from
232  // commit()ing xct when they are in state xct_freeing_space
233 
234  // CS: Using these instead of the old new_xct and destroy_xct methods
235  void* operator new(size_t s);
236 
237  void operator delete(void* p, size_t s);
238  };
239 
240 protected:
241  xct_core* _core;
242 
243 protected:
244  enum commit_t {
245  t_normal = 0,
246  t_lazy = 1,
247  t_chain = 2,
248  t_group = 4
249  };
250 
251  enum loser_xct_state_t {
252  loser_false = 0x0, // Not a loser transaction
253  loser_true = 0x1, // A loser transaction
254  loser_undoing = 0x2
255  }; // Loser transaction is being rolled back currently
256 
257 
261 public:
262  static rc_t group_commit(const xct_t* list[], int number);
263 
264  rc_t commit_free_locks(bool read_lock_only = false, lsn_t commit_lsn = lsn_t::null);
265 
266  rc_t early_lock_release();
267 
268  // CS: Using these instead of the old new_xct and destroy_xct methods
269  void* operator new(size_t s);
270 
271  void operator delete(void* p, size_t s);
272 
273 public:
274  xct_t(sm_stats_t* stats = nullptr,
276  bool sys_xct = false,
277  bool single_log_sys_xct = false,
278  const tid_t& tid = 0,
279  const lsn_t& last_lsn = lsn_t::null,
280  const lsn_t& undo_nxt = lsn_t::null,
281  bool loser_xct = false);
282 
283  ~xct_t();
284 
285 public:
286  friend ostream& operator<<(ostream&, const xct_t&);
287 
288  state_t state() const;
289 
290  void set_timeout(int t);
291 
292  int timeout_c() const;
293 
294  /*
295  * basic tx commands:
296  */
297 public:
298  static void dump(ostream& o);
299 
300  static void cleanup(bool shutdown_clean = true);
301 
302  bool is_instrumented() {
303  return (__stats != 0);
304  }
305 
306  void give_stats(sm_stats_t* s) {
307  w_assert1(__stats == 0);
308  __stats = s;
309  }
310 
311  void clear_stats() {
312  memset(__stats, 0, sizeof(*__stats));
313  }
314 
315  sm_stats_t* steal_stats() {
316  sm_stats_t* s = __stats;
317  __stats = 0;
318  return s;
319  }
320 
321  const sm_stats_t& const_stats_ref() {
322  return *__stats;
323  }
324 
325  rc_t commit(bool lazy = false, lsn_t* plastlsn = nullptr);
326 
327  rc_t commit_as_group_member();
328 
329  rc_t rollback(const lsn_t& save_pt);
330 
331  rc_t save_point(lsn_t& lsn);
332 
333  rc_t chain(bool lazy = false);
334 
335  rc_t abort(bool save_stats = false);
336 
337  // used by restart.cpp, some logrecs
338 protected:
339  sm_stats_t& stats_ref() {
340  return *__stats;
341  }
342 
343  rc_t dispose();
344 
345  void change_state(state_t new_state);
346 
347  void set_first_lsn(const lsn_t&);
348 
349  void set_last_lsn(const lsn_t&);
350 
351  void set_undo_nxt(const lsn_t&);
354 public:
355 
356  // used by checkpoint, restart:
357  const lsn_t& last_lsn() const;
358 
359  const lsn_t& first_lsn() const;
360 
361  const lsn_t& undo_nxt() const;
362 
363  const logrec_t* last_log() const;
364 
365  // used by restart, chkpt among others
366  static xct_t* look_up(const tid_t& tid);
367 
368  static tid_t oldest_tid(); // with min tid value
369  static tid_t youngest_tid(); // with max tid value
371  static void update_youngest_tid(const tid_t&);
374  // used by sm.cpp:
375  static uint32_t num_active_xcts();
376 
377  static size_t get_loser_count();
378 
379  static void fuzzy_checkpoint(chkpt_t& chkpt);
380 
382  // used for compensating (top-level actions)
383  const lsn_t& anchor(bool grabit = true);
384 
385  void release_anchor(bool compensate
387  );
388 
389  void compensate(const lsn_t&,
390  bool undoable
391  ADD_LOG_COMMENT_SIG
392  );
393 
394  // for recovery:
395  void compensate_undo(const lsn_t&);
398  // For handling log-space warnings
399  // If you've warned wrt a tx once, and the server doesn't
400  // choose to abort that victim, you don't want every
401  // ssm prologue to warn thereafter. This allows the
402  // callback function to turn off the warnings for the (non-)victim.
403  void log_warn_disable();
404 
405  void log_warn_resume();
406 
407  bool log_warn_is_on() const;
408 
409 public:
410  // logging functions
411  rc_t update_last_logrec(logrec_t* l, lsn_t lsn);
412 
413  //
414  // Used by I/O layer
415  //
416  void AddStoreToFree(const StoreID& stid);
417 
418  void AddLoadStore(const StoreID& stid);
419 
420  // Used by vol.cpp
421  void set_alloced() {}
422 
423 protected:
425  // the following is put here because smthread
426  // doesn't know about the structures
427  // and we have changed these to be a per-thread structures.
428  static lockid_t* new_lock_hierarchy();
429 
430 public: // not quite public thing.. but convenient for experiments
431  xct_lock_info_t* lock_info() const;
432 
433  lil_private_table* lil_lock_info() const;
434 
435  RawXct* raw_lock_xct() const;
436 
437 public:
438  // XXX this is only for chkpt::take(). This problem needs to
439  // be fixed correctly. DO NOT USE THIS. Really want a
440  // friend that is just a friend on some methods, not the entire class.
441  static w_rc_t acquire_xlist_mutex();
442 
443  static void release_xlist_mutex();
444 
445  static void assert_xlist_mutex_not_mine();
446 
447  static void assert_xlist_mutex_is_mine();
448 
449  static bool xlist_mutex_is_mine();
450 
451  /* "poisons" the transaction so cannot block on locks (or remain
452  blocked if already so), instead aborting the offending lock
453  request with eDEADLOCK. We use eDEADLOCK instead of
454  eLOCKTIMEOUT because all transactions must expect the former
455  and must abort in response; transactions which specified
456  WAIT_FOREVER won't be expecting timeouts, and the SM uses
457  timeouts (WAIT_IMMEDIATE) as internal signals which do not
458  usually trigger a transaction abort.
459 
460  chkpt::take uses this to ensure timely and deadlock-free
461  completion/termination of transactions which would prevent a
462  checkpoint from freeing up needed log space.
463  */
464  void force_nonblocking();
465 
466 
468 // DATA
470 protected:
471  // list of all transactions instances
473 
475 
476  void put_in_order();
477 
478  // CS TODO: TID assignment could be thread-local
479  static std::atomic<tid_t> _nxt_tid;// only safe for pre-emptive
480  // threads on 64-bit platforms
482 
483 private:
485 
486  sm_stats_t* __stats; // allocated by user
488 
489  // NB: must replicate because _xlist keys off it...
490  // NB: can't be const because we might chain...
492 
497  uint32_t _xct_chain_len;
498 
510  uint32_t _ssx_chain_len;
511 
514 
517 // hey, these could be one integer with OR-ed flags
518 
523 
525  bool _sys_xct;
526 
529 
535 
538 
541 
544 
547 
548  // For a loser transaction identified during Log Analysis phase in Recovery,
549  // the transaction state is 'xct_active' so the standard roll back logic can be
550  // used. In order to distingish a loser transaction and normal active
551  // transaction, check the '_loser_xct' flag, this is especially important
552  // for transaction driven UNDO logic.
553  // For on_demand UNDO, this flag also indicate if the loser transaction
554  // is currently rolling back
555  loser_xct_state_t _loser_xct;
556 
557  // Latch object mainly for checkpoint to access information in txn object
559 
560 protected:
561  rc_t _abort();
562 
563  rc_t _commit(uint32_t flags,
564  lsn_t* plastlsn = nullptr);
565 
566  // CS: decoupled from _commit to allow reuse in plog_xct_t
567  rc_t _commit_read_only(uint32_t flags, lsn_t& inherited_read_watermark);
568 
569  rc_t _pre_commit(uint32_t flags);
570 
571  rc_t _pre_abort();
572 
573 private:
574  bool one_thread_attached() const; // assertion
575  // helper function for compensate() and compensate_undo()
576  void _compensate(const lsn_t&, bool undoable = false);
577 
578 public:
580  return _piggy_backed_single_log_sys_xct;
581  }
582 
584  _piggy_backed_single_log_sys_xct = enabled;
585  }
586 
587  bool is_sys_xct() const {
588  return _sys_xct || _piggy_backed_single_log_sys_xct;
589  }
590 
591  bool is_single_log_sys_xct() const {
592  return _single_log_sys_xct || _piggy_backed_single_log_sys_xct;
593  }
594 
595  void set_inquery_verify(bool enabled) {
596  _inquery_verify = enabled;
597  }
598 
599  bool is_inquery_verify() const {
600  return _inquery_verify;
601  }
602 
603  void set_inquery_verify_keyorder(bool enabled) {
604  _inquery_verify_keyorder = enabled;
605  }
606 
608  return _inquery_verify_keyorder;
609  }
610 
611  void set_inquery_verify_space(bool enabled) {
612  _inquery_verify_space = enabled;
613  }
614 
615  bool is_inquery_verify_space() const {
616  return _inquery_verify_space;
617  }
618 
620  return _inquery_verify_context;
621  }
622 
624  return _inquery_verify_context;
625  }
626 
628  return _query_concurrency;
629  }
630 
632  _query_concurrency = mode;
633  }
634 
636  return _query_exlock_for_select;
637  }
638 
639  void set_query_exlock_for_select(bool mode) {
640  _query_exlock_for_select = mode;
641  }
642 
643  bool is_loser_xct() const {
644  if (loser_false == _loser_xct) {
645  return false; // Not a loser transaction
646  } else {
647  return true;
648  } // Loser transaction
649  }
650 
651  bool is_loser_xct_in_undo() const {
652  if (true == is_loser_xct()) {
653  if (loser_undoing == _loser_xct) {
654  return true;
655  } // Loser transaction and in the middle of undoing
656  }
657  return false;
658  }
659 
661  if (loser_false != _loser_xct) {
662  _loser_xct = loser_undoing;
663  }
664  }
665 
666  ostream& dump_locks(ostream&) const;
667 
669 private:
671  // non-const because it acquires mutex:
672  // removed, now that the lock mgrs use the const,INLINE-d form
673  // int timeout();
674 
675  static void xct_stats(
676  u_long& begins,
677  u_long& commits,
678  u_long& aborts,
679  bool reset);
680 
681  w_rc_t _sync_logbuf(bool block = true, bool signal = true);
682 
683  void _teardown(bool is_chaining);
684 
685 public:
691  enum elr_mode_t {
694 
697 
705 
714  elr_clv
715  };
716 
717 protected: // all data members protected
719 
721 
723 
734 
736 
737  // timestamp for calculating latency
738  std::chrono::high_resolution_clock::time_point _begin_tstamp;
739 
740  /*
741  * log_m related
742  */
743  // logrec_t* _last_log; // last log generated by xct
744  // logrec_t* _log_buf;
745  // /**
746  // * As SSX log must be separated from outer transaction's logs, we maintain another buffer.
747  // * This buffer is only used during one get/give_logbuf() call because it's SSX.
748  // * Also, again because it's SSX, it can contain only one log.
749  // */
750  // logrec_t* _log_buf_for_piggybacked_ssx;
751 
752  bool _rolling_back;// true if aborting OR
753 
754  bool should_consume_rollback_resv(int t) const;
755 
757  const {
758  return !should_consume_rollback_resv(t);
759  }
760 
761 private:
762  lintel::Atomic<int> _in_compensated_op; // in the midst of a compensated operation
763  // use an int because they can be nested.
764  lsn_t _anchor; // the anchor for the outermost compensated op
765 
766 public:
767  bool rolling_back() const {
768  return _rolling_back;
769  }
770 
771 #if W_DEBUG_LEVEL > 2
772  private:
773  bool _had_error;
774  public:
775  // Tells if we ever did a partial rollback.
776  // This state is only needed for certain assertions.
777  void set_error_encountered() { _had_error = true; }
778  bool error_encountered() const {
779  return _had_error; }
780 #else
781 
783 
784  bool error_encountered() const {
785  return false;
786  }
787 
788 #endif
789 
790  tid_t tid() const {
791  w_assert1(_core == nullptr || _tid == _core->_tid);
792  return _tid;
793  }
794 
795  uint32_t get_xct_chain_len() const {
796  return _xct_chain_len;
797  }
798 
799  uint32_t& ssx_chain_len() {
800  return _ssx_chain_len;
801  }
802 
803  const lsn_t& get_read_watermark() const {
804  return _read_watermark;
805  }
806 
807  void update_read_watermark(const lsn_t& tag) {
808  if (_read_watermark < tag) {
809  _read_watermark = tag;
810  }
811  }
812 
814  return _elr_mode;
815  }
816 
818  _elr_mode = mode;
819  }
820 
821  // Latch the xct object in order to access internal data
822  // it is to prevent data changing while reading them
823  // Mainly for checkpoint logging purpose
824  latch_t* latchp() const {
825  // If _core is gone (txn is being destroyed), return nullptr
826  // CS TODO: this is incorrect. Threads waiting on the latch after
827  // core is destructed will encounter a segmentation fault. The real
828  // problem here is that an object should not be destroyed while some
829  // thread may still try to access it. We need a different design or
830  // some higher form of concurrency control.
831  // if ( nullptr == _core)
832  // return (latch_t *)nullptr;
833 
834  return const_cast<latch_t*>(&(_latch));
835  }
836 
838  return *latchp();
839  }
840 };
841 
844 // Release anchor on destruction
845 class auto_release_anchor_t {
846  bool _compensate;
847 
848  xct_t* _xct;
849 
850 public:
851  auto_release_anchor_t(bool and_compensate) :
852  _compensate(and_compensate),
853  _xct(xct()) {}
854 
855  ~auto_release_anchor_t() {
856  _xct->release_anchor(_compensate X_LOG_COMMENT_USE("auto_release_anchor_t"));
857  }
858 };
859 
860 // Cause a rollback to the savepoint on destruction
861 // unless ok() is called, in which case, do not.
862 class auto_rollback_t {
863 private:
864  xct_t* _xd;
865 
866  lsn_t _save_pt;
867 
868  bool _roll;
869 
870  static int _count;
871 
872  int _test;
873 
874  int _line; // debugging
875  const char* _file; // debugging
876 public:
877  // for testing
878  // every so often we need to fake an eOUTOFLOGSPACE error.
879  w_rc_t test(int x) {
880  _test = x;
881  if (_test && (_count % _test == 0)) {
882  return RC(eOUTOFLOGSPACE);
883  } // will ignore ok()
884  return RCOK;
885  }
886 
887 #define AUTO_ROLLBACK_work auto_rollback_t work(__LINE__, __FILE__);
888 
889  auto_rollback_t(int line, const char* file)
890  : _xd(xct()),
891  _roll(true),
892  _test(0),
893  _line(line),
894  _file(file) {
895  // we don't care if this faking of error is thread-safe
896  _count++;
897  if (_xd) {
898  // there's no possible error from save_point
899  W_COERCE(_xd->save_point(_save_pt));
900  }
901  }
902 
903  void ok() {
904  _roll = false;
905  }
906 
907  ~auto_rollback_t() {
908 
909  if (_test && (_count % _test == 0)) {
910  _roll = true;
911  } // ignore ok()
912  if (_roll && _xd) {
913  _xd->set_error_encountered();
914  W_COERCE(_xd->rollback(_save_pt));
916 #if 0 && W_DEBUG_LEVEL > 0
917  cerr << "Internal rollback to " << _save_pt
918  << " from " << _line
919  << " " << _file
920  << endl;
921 #endif
922  }
923  }
924 };
925 
928 /*
929  * Use X_DO inside compensated operations
930  */
931 #if X_LOG_COMMENT_ON
932 #define X_DO1(x,anchor,line) \
933 { \
934  w_rc_t __e = (x); \
935  if (__e.is_error()) { \
936  w_assert3(xct()); \
937  W_COERCE(xct()->rollback(anchor)); \
938  xct()->release_anchor(true X_LOG_COMMENT_USE("X_DO1")); \
939  return RC_AUGMENT(__e); \
940  } \
941 }
942 #define X_to_string(x) # x
943 #define X_DO(x,anchor) X_DO1(x,anchor, X_to_string(x))
944 
945 #else
946 
947 #define X_DO(x, anchor) \
948 { \
949  w_rc_t __e = (x); \
950  if (__e.is_error()) { \
951  w_assert3(xct()); \
952  W_COERCE(xct()->rollback(anchor)); \
953  xct()->release_anchor(true X_LOG_COMMENT_USE("X_DO")); \
954  return RC_AUGMENT(__e); \
955  } \
956 }
957 #endif
958 
959 /* XXXX This is somewhat hacky becuase I am working on cleaning
960  up the xct_i xct iterator to provide various levels of consistency.
961  Until then, the "locking option" provides enough variance so
962  code need not be duplicated or have deep call graphs. */
963 
969 class xct_i {
970 public:
971  // NB: still not safe, since this does not
972  // lock down the list for the entire iteration.
973 
974  // FRJ: Making it safe -- all non-debug users lock it down
975  // manually right now anyway; the rest *should* to avoid bugs.
976 
978  bool locked_by_me() const {
980  W_IFDEBUG1(if (_may_check) {
981  w_assert1(_locked);
982  })
983  return true;
984  }
985  return false;
986  }
987 
989  void never_mind() {
990  // Be careful here: must leave in the
991  // state it was when we constructed this.
992  if (_locked && locked_by_me()) {
993  *(const_cast<bool*>(&_locked)) = false; // grot
995  }
996  }
997 
999  xct_t* curr() const {
1000  return unsafe_iterator.curr();
1001  }
1002 
1005  return unsafe_iterator.next();
1006  }
1007 
1009  // Note that this is called to INIT the attribute "locked"
1010  static bool init_locked(bool lockit) {
1011  if (lockit) {
1013  }
1014  return lockit;
1015  }
1024  xct_i(bool locked_accesses) :
1025  _locked(init_locked(locked_accesses)),
1026  _may_check(locked_accesses),
1027  unsafe_iterator(xct_t::_xlist) {
1028  w_assert1(_locked == locked_accesses);
1029  _check(_locked);
1030  }
1031 
1034  if (locked_by_me()) {
1035  _check(true);
1036  never_mind();
1037  _check(false);
1038  }
1039  }
1040 
1041 private:
1042  void _check(bool b) const {
1043  if (!_may_check) {
1044  return;
1045  }
1046  if (b) {
1048  } else {
1050  }
1051  }
1052 
1053  // FRJ: make sure init_locked runs before we actually create the iterator
1054  const bool _locked;
1055 
1056  const bool _may_check;
1057 
1059 
1060  // disabled
1061  xct_i(const xct_i&);
1062 
1063  xct_i& operator=(const xct_i&);
1064 };
1065 
1067 inline
1068 xct_t::state_t
1069 xct_t::state() const {
1070  if (nullptr == _core) {
1071  return xct_ended;
1072  }
1073  return _core->_state;
1074 }
1075 
1076 // For use in sm functions that don't allow
1077 // active xct when entered. These are functions that
1078 // apply to local volumes only.
1079 class xct_auto_abort_t : public smlevel_0 {
1080 public:
1081  xct_auto_abort_t() : _xct(new xct_t()) {}
1082 
1083  ~xct_auto_abort_t() {
1084  switch (_xct->state()) {
1085  case smlevel_0::xct_ended:
1086  // do nothing
1087  break;
1088  case smlevel_0::xct_active:
1089  case smlevel_0::xct_freeing_space: // we got an error in commit
1090  case smlevel_0::xct_committing: // we got an error in commit
1091  W_COERCE(_xct->abort());
1092  break;
1093  default:
1094  cerr << "unexpected xct state: " << _xct->state() << endl;
1095  W_FATAL(eINTERNAL);
1096  }
1097  delete _xct;
1098  }
1099 
1100  rc_t commit() {
1101  W_DO(_xct->commit());
1102  return RCOK;
1103  }
1104 
1105  rc_t abort() {
1106  W_DO(_xct->abort());
1107  return RCOK;
1108  }
1109 
1110 private:
1111  xct_t* _xct;
1112 };
1113 
1114 inline
1115 bool
1116 operator>(const xct_t& x1, const xct_t& x2) {
1117  return (x1.tid() > x2.tid());
1118 }
1119 
1120 inline
1121 const lsn_t&
1122 xct_t::last_lsn() const {
1123  return _last_lsn;
1124 }
1125 
1126 inline
1127 void
1128 xct_t::set_last_lsn(const lsn_t& l) {
1129  _last_lsn = l;
1130 }
1131 
1132 inline
1133 const lsn_t&
1134 xct_t::first_lsn() const {
1135  return _first_lsn;
1136 }
1137 
1138 inline
1139 void
1140 xct_t::set_first_lsn(const lsn_t& l) {
1141  _first_lsn = l;
1142 }
1143 
1144 inline
1145 const lsn_t&
1146 xct_t::undo_nxt() const {
1147  return _undo_nxt;
1148 }
1149 
1150 inline
1151 void
1152 xct_t::set_undo_nxt(const lsn_t& l) {
1153  _undo_nxt = l;
1154 }
1155 
1156 // inline
1157 // const logrec_t*
1158 // xct_t::last_log() const
1159 // {
1160 // return _last_log;
1161 // }
1162 
1163 
1166 // TODO. this should accept store id/volume id.
1167 // it should say 'does not need' if we have absolute locks in LIL.
1168 // same thing can be manually achieved by user code, though.
1169 inline bool
1171  xct_t* x = xct();
1172  if (x == nullptr) {
1173  return false;
1174  }
1175  if (x->is_sys_xct()) {
1176  return false;
1177  } // system transaction never needs locks
1179 }
1180 
1181 inline bool
1183  xct_t* x = xct();
1184  return x && x->get_query_exlock_for_select();
1185 }
1186 
1205 public:
1210  sys_xct_section_t(bool single_log_sys_xct = false);
1211 
1213  ~sys_xct_section_t();
1214 
1217  return _error_on_start;
1218  }
1219 
1221  rc_t end_sys_xct(rc_t result);
1222 
1223 private:
1225 
1227 };
1228 
1231 public:
1233  xct_t* x = xct();
1234  if (x) {
1235  DBGOUT3(<< "!!!! no_lock_section_t() - lock has been disabled");
1236 
1237  org_cc = x->get_query_concurrency();
1239  } else {
1240  DBGOUT3(<< "!!!! no_lock_section_t() - set original lock mode to t_cc_none");
1241 
1242  org_cc = smlevel_0::t_cc_none;
1243  }
1244  }
1245 
1247  xct_t* x = xct();
1248  if (x) {
1249  DBGOUT3(<< "!!!! ~no_lock_section_t() - restored original lock mode: " << org_cc);
1250  x->set_query_concurrency(org_cc);
1251  }
1252  }
1253 
1254 private:
1256 };
1257 
1258 // microseconds to "give up" watermark waits and flushes its own log in readonly xct
1260 
1261 const int ELR_READONLY_WAIT_USEC = 2000;
1262 
1263 
1264 /*<std-footer incl-file-exclusion='XCT_H'> -- do not edit anything below this line -- */
1265 
1266 #endif // __XCT_H /*</std-footer>*/
const inquery_verify_context_t & inquery_verify_context() const
Definition: xct.h:619
Lock Manager API.See Orthogonal Key Value Locking and Light-weight Intent Lock.
Definition: lock.h:27
w_keystr_t next_high_key
Definition: xct.h:147
static std::atomic< tid_t > _nxt_tid
Definition: xct.h:479
PageID next_pid
Definition: xct.h:138
const int ELR_READONLY_WAIT_MAX_COUNT
Definition: xct.h:1259
Lock table implementation class.
Definition: lock_core.h:31
Storage Manager thread.
Definition: smthread.h:201
void set_piggy_backed_single_log_sys_xct(bool enabled)
Definition: xct.h:583
const w_rc_t RCOK
Definition: w_rc.h:239
#define W_IFDEBUG1(x)
Definition: w_base.h:95
#define w_assert1(x)
Level 1 should not add significant extra time.
Definition: w_base.h:198
#define ADD_LOG_COMMENT_SIG
Definition: xct.h:77
sm_stats_t * __stats
Definition: xct.h:486
Definition: sm_base.h:258
bool is_inquery_verify_keyorder() const
Definition: xct.h:607
Definition: xct.h:693
no_lock_section_t()
Definition: xct.h:1232
#define W_LIST_ARG(class, member)
Macro used to name the member of the object that is the link.
Definition: w_list.h:463
const bool _locked
Definition: xct.h:1054
inquery_verify_context_t()
Definition: xct.h:127
A shadow transaction object for RAW-style lock manager.
Definition: lock_raw.h:469
#define RC(e)
Normal error-case return. Create a return code with the current file, line, and error code x...
Definition: w_rc.h:248
bool is_single_log_sys_xct() const
Definition: xct.h:591
bool _inquery_verify
Definition: xct.h:537
latch_t & latch()
Definition: xct.h:837
void never_mind()
Release transaction list mutex if this thread holds it.
Definition: xct.h:989
A transaction. Internal to the storage manager.This class may be used in a limited way for the handli...
Definition: xct.h:185
rc_t check_error_on_start() const
Definition: xct.h:1216
lsn_t _read_watermark
Definition: xct.h:733
w_keystr_t next_low_key
Definition: xct.h:144
Header file for lintel::Atomic class.
uint32_t StoreID
Definition: basics.h:47
uint32_t _ssx_chain_len
The count of consecutive SSXs conveyed by this transaction object.
Definition: xct.h:510
concurrency_t get_query_concurrency() const
Definition: xct.h:627
Key string class which can represent a few special values.
Definition: w_key.h:47
Definition: restart.h:51
Definition: chkpt.h:156
smlevel_0::concurrency_t org_cc
Definition: xct.h:1255
inquery_verify_context_t & inquery_verify_context()
Definition: xct.h:623
bool should_reserve_for_rollback(int t) const
Definition: xct.h:756
bool is_inquery_verify() const
Definition: xct.h:599
static const lsn_t null
Definition: lsn.h:371
const bool _may_check
Definition: xct.h:1056
static queue_based_lock_t _xlist_mutex
Definition: xct.h:484
Locking-related status of one transaction.
Definition: lock_x.h:127
xct_t * curr() const
Get transaction at cursor.
Definition: xct.h:999
elr_mode_t _elr_mode
Definition: xct.h:735
Used to automatically begin/commit/abort a system transaction.
Definition: xct.h:1204
w_list_i< xct_t, queue_based_lock_t > unsafe_iterator
Definition: xct.h:1058
#define DBGOUT3(a)
Definition: w_debug.h:212
int16_t next_level
Definition: xct.h:141
Represents a transactional log record.
Definition: logrec.h:143
lsn_t _anchor
Definition: xct.h:764
const lsn_t & get_read_watermark() const
Definition: xct.h:803
bool rolling_back() const
Definition: xct.h:767
bool _piggy_backed_single_log_sys_xct
Definition: xct.h:522
void set_inquery_verify_space(bool enabled)
Definition: xct.h:611
void set_error_encountered()
Definition: xct.h:782
uint32_t get_xct_chain_len() const
Definition: xct.h:795
List maintained in descending order.
Definition: w_list.h:689
bool is_piggy_backed_single_log_sys_xct() const
Definition: xct.h:579
bool g_xct_does_ex_lock_for_select()
Definition: xct.h:1182
lsn_t _first_lsn
Definition: xct.h:718
~no_lock_section_t()
Definition: xct.h:1246
uint32_t PageID
Definition: basics.h:45
w_link_t _xlink
Definition: xct.h:472
elr_mode_t get_elr_mode() const
Definition: xct.h:813
void set_alloced()
Definition: xct.h:421
void set_loser_xct_in_undo()
Definition: xct.h:660
Log Sequence Number. See Log Sequence Numbers (LSN).
Definition: lsn.h:243
A short-term hold (exclusive or shared) on a page.
Definition: latch.h:159
void set_inquery_verify(bool enabled)
Definition: xct.h:595
Iterator for a list.
Definition: w_list.h:76
latch_t * latchp() const
Definition: xct.h:824
size_t _original_xct_depth
Definition: xct.h:1226
Handle class for pages that may be fixed (i.e., paged in by the main buffer manager, zero::buffer_pool::BufferPool)
Definition: fixable_page_h.h:26
bool is_loser_xct() const
Definition: xct.h:643
bool is_sys_xct() const
Definition: xct.h:587
bool locked_by_me() const
True if this thread holds the transaction list mutex.
Definition: xct.h:978
void set_query_concurrency(concurrency_t mode)
Definition: xct.h:631
bool get_query_exlock_for_select() const
Definition: xct.h:635
void update_read_watermark(const lsn_t &tag)
Definition: xct.h:807
uint32_t _xct_chain_len
Definition: xct.h:497
xct_i(bool locked_accesses)
Constructor.
Definition: xct.h:1024
uint32_t & ssx_chain_len()
Definition: xct.h:799
void set_elr_mode(elr_mode_t mode)
Definition: xct.h:817
lsn_t _undo_nxt
Definition: xct.h:722
elr_mode_t
Definition: xct.h:691
bool _rolling_back
Definition: xct.h:752
std::array< long, enum_to_base(sm_stat_id::stat_max)> sm_stats_t
Definition: smstats.h:205
static w_rc_t acquire_xlist_mutex()
Definition: xct.cpp:135
Return code for most functions and methods.
Definition: w_rc.h:87
lsn_t _last_lsn
Definition: xct.h:720
LIL private lock table to remember all locks in xct.
Definition: lock_lil.h:227
void set_query_exlock_for_select(bool mode)
Definition: xct.h:639
Iterator over transaction list.
Definition: xct.h:969
std::ostream & operator<<(std::ostream &os, const ConfigFile &cf)
Definition: confparser.cpp:83
static tid_t _oldest_tid
Definition: xct.h:481
An MCS queuing spinlock.
Definition: mcs_lock.h:61
bool is_inquery_verify_space() const
Definition: xct.h:615
void _check(bool b) const
Definition: xct.h:1042
bool operator>(const cvec_t &v1, const cvec_t &v2)
Definition: vec_t.h:410
Represents a lock mode of one key entry in the OKVL lock manager.
Definition: w_okvl.h:95
#define W_COERCE(x)
Call a function or method x, fail catastrophically if error is returned.
Definition: w_rc.h:349
The means of identifying a desired or held lock.
Definition: lock_s.h:41
rc_t _error_on_start
Definition: xct.h:1224
static w_descend_list_t< xct_t, queue_based_lock_t, tid_t > _xlist
Definition: xct.h:474
xct_t * xct()
Definition: smthread.h:575
bool _inquery_verify_space
Definition: xct.h:543
loser_xct_state_t _loser_xct
Definition: xct.h:555
bool _single_log_sys_xct
Definition: xct.h:528
tid_t _tid
Definition: xct.h:491
bool g_xct_does_need_lock()
Definition: xct.h:1170
bool is_loser_xct_in_undo() const
Definition: xct.h:651
bool _inquery_verify_keyorder
Definition: xct.h:540
lintel::Atomic< int > _in_compensated_op
Definition: xct.h:762
static void assert_xlist_mutex_is_mine()
Definition: xct.cpp:111
~xct_i()
Desctructor. Calls never_mind() if necessary.
Definition: xct.h:1033
xct_t * next()
Advance cursor.
Definition: xct.h:1004
#define W_DO(x)
Call a method or function x. This macro is the normal idiom for calling a method or function...
Definition: w_rc.h:304
Definition: xct.h:696
static constexpr int WAIT_SPECIFIED_BY_THREAD
Definition: timeout.h:29
static void assert_xlist_mutex_not_mine()
Definition: xct.cpp:103
tid_t tid() const
Definition: xct.h:790
const lsn_t & first_lsn() const
void set_inquery_verify_keyorder(bool enabled)
Definition: xct.h:603
Definition: xct.h:125
uint64_t tid_t
Definition: tid_t.h:59
std::set< PageID > pids_inconsistent
Definition: xct.h:135
std::chrono::high_resolution_clock::time_point _begin_tstamp
Definition: xct.h:738
Definition: xct.h:704
const lsn_t & last_lsn() const
static bool xlist_mutex_is_mine()
Definition: xct.cpp:94
bool _sys_xct
Definition: xct.h:525
Definition: xct.h:1230
const int ELR_READONLY_WAIT_USEC
Definition: xct.h:1261
inquery_verify_context_t _inquery_verify_context
Definition: xct.h:546
lockid_t * __saved_lockid_t
Definition: xct.h:487
bool error_encountered() const
Definition: xct.h:784
concurrency_t _query_concurrency
Definition: xct.h:513
int32_t pages_checked
Definition: xct.h:132
#define INC_TSTAT(x)
Increment per-thread statistic named x by y.
Definition: smthread.h:392
#define X_LOG_COMMENT_USE(x)
Definition: xct.h:79
concurrency_t
Lock granularities.
Definition: sm_base.h:256
bool _deferred_ssx
Definition: xct.h:534
#define W_FATAL(e)
Croak with the error code e.
Definition: w_rc.h:378
Definition: sm_base.h:261
latch_t _latch
Definition: xct.h:558
const lsn_t & undo_nxt() const
bool _query_exlock_for_select
Definition: xct.h:516
static void release_xlist_mutex()
Definition: xct.cpp:142