Zero  0.1.0
xct_logger.h
Go to the documentation of this file.
1 #ifndef __XCT_LOGGER_H
2 #define __XCT_LOGGER_H
3 
4 #include "sm.h"
5 #include "xct.h"
6 #include "btree_page_h.h"
7 #include "logdef_gen.h"
8 #include "log_core.h"
9 
10 class XctLogger {
11 public:
12 
13  /*
14  * This method replaces the old log "stubs" that were generated by a Perl
15  * script logdef.pl. Two overloads are required because of the cumbersome
16  * way in which PageLSNs are managed in Zero (see xct_t::give_logbuf).
17  */
18  // CS TODO we need a new page-lsn update mechanism!
19  template<class Logrec, class... Args>
20  static lsn_t log(const Args& ... args) {
21  xct_t* xd = smthread_t::xct();
22  bool should_log = smlevel_0::log && smlevel_0::logging_enabled && xd;
23  if (!should_log) {
24  return lsn_t::null;
25  }
26 
27  logrec_t* logrec = _get_logbuf(xd);
28  new(logrec) Logrec;
29  logrec->init_header(Logrec::TYPE);
30  logrec->init_xct_info();
31  reinterpret_cast<Logrec*>(logrec)->construct(args...);
32  w_assert1(logrec->valid_header());
33 
34  // REDO log records always pertain to a page and must therefore use log_p
35  w_assert1(!logrec->is_redo());
36 
37  // If it's a log for piggy-backed SSX, we call log->insert without updating _last_log
38  // because this is a single log independent from other logs in outer transaction.
39  if (xd->is_piggy_backed_single_log_sys_xct()) {
40  w_assert1(logrec->is_single_sys_xct());
41  lsn_t lsn;
42  W_COERCE(ss_m::log->insert(*logrec, &lsn));
43  w_assert1(lsn != lsn_t::null);
44  DBGOUT3(<< " SSX logged: " << logrec->type() << "\n new_lsn= " << lsn);
45  return lsn;
46  }
47 
48  lsn_t lsn;
49  logrec->set_xid_prev(xd->tid(), xd->last_lsn());
50  W_COERCE(ss_m::log->insert(*logrec, &lsn));
51  W_COERCE(xd->update_last_logrec(logrec, lsn));
52 
53  return lsn;
54  }
55 
56  template<class Logrec, class PagePtr, class... Args>
57  static lsn_t log_p(PagePtr p, const Args& ... args) {
58  xct_t* xd = smthread_t::xct();
59  bool should_log = smlevel_0::log && smlevel_0::logging_enabled && xd;
60  if (!should_log) {
61  return lsn_t::null;
62  }
63 
64  if (_should_apply_img_compression(Logrec::TYPE, p)) {
65  // log this page image as an SX to keep it out of the xct undo chain
66  sys_xct_section_t sx{false};
67  log_p<page_img_format_log>(p);
68  sx.end_sys_xct(RCOK);
69 
70  // Keep track of additional space created by page images on log
71  auto extra_space = p->get_log_volume();
72  w_assert3(extra_space > 0);
73  ADD_TSTAT(log_img_format_bytes, extra_space);
74  p->reset_log_volume();
75  }
76 
77  logrec_t* logrec = _get_logbuf(xd);
78 
79  new(logrec) Logrec;
80  logrec->init_header(Logrec::TYPE);
81  logrec->init_xct_info();
82  logrec->init_page_info(p);
83  reinterpret_cast<Logrec*>(logrec)->construct(p, args...);
84  w_assert1(logrec->valid_header());
85 
86  if (p->tag() != t_btree_p || p->root() == p->pid()) {
87  logrec->set_root_page();
88  }
89 
90  // set page LSN chain
91  logrec->set_page_prev_lsn(p->get_page_lsn());
92 
93  // If it's a log for piggy-backed SSX, we call log->insert without updating _last_log
94  // because this is a single log independent from other logs in outer transaction.
95  if (xd->is_piggy_backed_single_log_sys_xct()) {
96  w_assert1(logrec->is_single_sys_xct());
97  lsn_t lsn;
98  W_COERCE(ss_m::log->insert(*logrec, &lsn));
99  w_assert1(lsn != lsn_t::null);
100  _update_page_lsns(p, lsn, logrec->length());
101  DBGOUT3(<< " SSX logged: " << logrec->type() << "\n new_lsn= " << lsn);
102  return lsn;
103  }
104 
105  lsn_t lsn;
106  logrec->set_xid_prev(xd->tid(), xd->last_lsn());
107  W_COERCE(ss_m::log->insert(*logrec, &lsn));
108  W_COERCE(xd->update_last_logrec(logrec, lsn));
109  _update_page_lsns(p, lsn, logrec->length());
110 
111  return lsn;
112  }
113 
114  template<class Logrec, class PagePtr, class... Args>
115  static lsn_t log_p(PagePtr p, PagePtr p2, const Args& ... args) {
116  xct_t* xd = smthread_t::xct();
117  bool should_log = smlevel_0::log && smlevel_0::logging_enabled && xd;
118  if (!should_log) {
119  return lsn_t::null;
120  }
121 
122  logrec_t* logrec = _get_logbuf(xd);
123  new(logrec) Logrec;
124  logrec->init_header(Logrec::TYPE);
125  logrec->init_xct_info();
126  logrec->init_page_info(p);
127  reinterpret_cast<Logrec*>(logrec)->construct(p, p2, args...);
128  w_assert1(logrec->valid_header());
129 
130  if (p->tag() != t_btree_p || p->root() == p->pid()) {
131  logrec->set_root_page();
132  }
133  if (p2->tag() != t_btree_p || p2->root() == p2->pid()) {
134  logrec->set_root_page();
135  }
136 
137  // set page LSN chain
138  logrec->set_page_prev_lsn(p->get_page_lsn());
139  // For multi-page log, also set LSN chain with a branch.
140  w_assert1(logrec->is_multi_page());
141  w_assert1(logrec->is_single_sys_xct());
142  multi_page_log_t* multi = logrec->data_ssx_multi();
143  w_assert1(multi->_page2_pid != 0);
144  multi->_page2_prv = p2->get_page_lsn();
145 
146  // If it's a log for piggy-backed SSX, we call log->insert without updating _last_log
147  // because this is a single log independent from other logs in outer transaction.
148  if (xd->is_piggy_backed_single_log_sys_xct()) {
149  w_assert1(logrec->is_single_sys_xct());
150  lsn_t lsn;
151  W_COERCE(ss_m::log->insert(*logrec, &lsn));
152  w_assert1(lsn != lsn_t::null);
153  _update_page_lsns(p, lsn, logrec->length());
154  _update_page_lsns(p2, lsn, logrec->length());
155  DBGOUT3(<< " SSX logged: " << logrec->type() << "\n new_lsn= " << lsn);
156  return lsn;
157  }
158 
159  lsn_t lsn;
160  logrec->set_xid_prev(xd->tid(), xd->last_lsn());
161  W_COERCE(ss_m::log->insert(*logrec, &lsn));
162  W_COERCE(xd->update_last_logrec(logrec, lsn));
163  _update_page_lsns(p, lsn, logrec->length());
164  _update_page_lsns(p2, lsn, logrec->length());
165 
166  return lsn;
167  }
168 
169  /*
170  * log_sys is used for system log records (e.g., checkpoints, clock
171  * ticks, reads & writes, recovery events, debug stuff, stats, etc.)
172  *
173  * The difference to the other logging methods is that no xct or page
174  * is involved and the logrec buffer is obtained with the 'new' operator.
175  */
176  template<class Logrec, class... Args>
177  static lsn_t log_sys(const Args& ... args) {
178  // this should use TLS allocator, so it's fast
179  // (see macro DEFINE_SM_ALLOC in allocator.h and logrec.cpp)
180  logrec_t* logrec = new logrec_t;
181 
182  new(logrec) Logrec;
183  logrec->init_header(Logrec::TYPE);
184  logrec->init_xct_info();
185  reinterpret_cast<Logrec*>(logrec)->construct(args...);
186  w_assert1(logrec->valid_header());
188 
189  lsn_t lsn;
190  W_COERCE(ss_m::log->insert(*logrec, &lsn));
191 
192  delete logrec;
193  return lsn;
194  }
195 
196  template<class PagePtr>
197  static void _update_page_lsns(PagePtr page, lsn_t new_lsn, uint32_t size) {
198  page->update_page_lsn(new_lsn);
199  page->increment_log_volume(size);
200  }
201 
202  template<class PagePtr>
203  static bool _should_apply_img_compression(logrec_t::kind_t type, PagePtr page) {
204  if (type == logrec_t::t_page_img_format) {
205  return false;
206  }
207 
208  auto comp = ss_m::log->get_page_img_compression();
209  if (comp == 0) {
210  return false;
211  }
212  auto vol = page->get_log_volume();
213  if (vol >= comp) {
214  page->reset_log_volume();
215  return true;
216  }
217  return false;
218  }
219 
220  static logrec_t* _get_logbuf(xct_t* xd) {
222  return smthread_t::get_logbuf2();
223  }
224  return smthread_t::get_logbuf();
225  }
226 };
227 
228 // CS TODO this is a temporary alias -- at some point the SM should have its
229 // own generic Logger template argument
231 
232 #endif // __XCT_LOGGER_H
bool is_multi_page() const
Definition: logrec.h:634
multi_page_log_t * data_ssx_multi()
Definition: logrec.h:676
static xct_t * xct()
return xct this thread is running
Definition: smthread.h:364
static logrec_t * get_logbuf()
Definition: smthread.h:355
const w_rc_t RCOK
Definition: w_rc.h:239
#define w_assert1(x)
Level 1 should not add significant extra time.
Definition: w_base.h:198
Definition: logrec.h:375
void init_xct_info()
Definition: logrec.cpp:224
rc_t end_sys_xct(rc_t result)
Definition: xct.cpp:1711
A transaction. Internal to the storage manager.This class may be used in a limited way for the handli...
Definition: xct.h:185
Definition: logrec.h:179
static void _update_page_lsns(PagePtr page, lsn_t new_lsn, uint32_t size)
Definition: xct_logger.h:197
#define w_assert3(x)
Level 3 definitely adds significant time.
Definition: w_base.h:214
void init_header(kind_t)
Definition: logrec.cpp:201
static lsn_t log_sys(const Args &... args)
Definition: xct_logger.h:177
void set_page_prev_lsn(const lsn_t &lsn)
Definition: logrec.h:573
Base struct for log records that touch multi-pages.
Definition: logrec.h:463
static const lsn_t null
Definition: lsn.h:371
bool is_redo() const
Definition: logrec.h:630
static lsn_t log(const Args &... args)
Definition: xct_logger.h:20
Used to automatically begin/commit/abort a system transaction.
Definition: xct.h:1204
bool valid_header(const lsn_t &lsn_ck=lsn_t::null) const
Definition: logrec.cpp:247
#define DBGOUT3(a)
Definition: w_debug.h:212
Represents a transactional log record.
Definition: logrec.h:143
bool is_piggy_backed_single_log_sys_xct() const
Definition: xct.h:579
void set_xid_prev(tid_t tid, lsn_t last)
Definition: logrec.cpp:232
static lsn_t log_p(PagePtr p, const Args &... args)
Definition: xct_logger.h:57
Log Sequence Number. See Log Sequence Numbers (LSN).
Definition: lsn.h:243
btree page
Definition: generic_page.h:90
void init_page_info(const PagePtr p)
Definition: logrec.h:241
static constexpr u_char get_logrec_cat(kind_t type)
Definition: logrec.h:686
bool is_single_sys_xct() const
Definition: logrec.h:672
Definition: xct_logger.h:10
static bool _should_apply_img_compression(logrec_t::kind_t type, PagePtr page)
Definition: xct_logger.h:203
#define W_COERCE(x)
Call a function or method x, fail catastrophically if error is returned.
Definition: w_rc.h:349
kind_t type() const
Definition: logrec.h:598
static lsn_t log_p(PagePtr p, PagePtr p2, const Args &... args)
Definition: xct_logger.h:115
void set_root_page()
Definition: logrec.h:620
smsize_t length() const
Definition: logrec.h:545
#define ADD_TSTAT(x, y)
Increment statistic named x by y.
Definition: smthread.h:397
kind_t
Definition: logrec.h:149
static logrec_t * _get_logbuf(xct_t *xd)
Definition: xct_logger.h:220
static logrec_t * get_logbuf2()
Definition: smthread.h:359