Drizzled Public API Documentation

trx0sys.cc
1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2011, Innobase Oy. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8 
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15 St, Fifth Floor, Boston, MA 02110-1301 USA
16 
17 *****************************************************************************/
18 
19 /**************************************************/
26 #include "trx0sys.h"
27 
28 #ifdef UNIV_NONINL
29 #include "trx0sys.ic"
30 #endif
31 
32 #ifndef UNIV_HOTBACKUP
33 #include "fsp0fsp.h"
34 #include "mtr0log.h"
35 #include "mtr0log.h"
36 #include "trx0trx.h"
37 #include "trx0rseg.h"
38 #include "trx0undo.h"
39 #include "srv0srv.h"
40 #include "trx0purge.h"
41 #include "log0log.h"
42 #include "log0recv.h"
43 #include "os0file.h"
44 #include "read0read.h"
45 
48  ulint id;
49  const char* name;
53 };
54 
55 #include <drizzled/errmsg_print.h>
56 
58 typedef struct file_format_struct file_format_t;
59 
61 UNIV_INTERN trx_sys_t* trx_sys = NULL;
63 UNIV_INTERN trx_doublewrite_t* trx_doublewrite = NULL;
64 
67 UNIV_INTERN ibool trx_doublewrite_must_reset_space_ids = FALSE;
69 UNIV_INTERN ibool trx_doublewrite_buf_is_being_created = FALSE;
70 
74 UNIV_INTERN ibool trx_sys_multiple_tablespace_format = FALSE;
75 
78 /* @{ */
80 UNIV_INTERN char trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
84 UNIV_INTERN ib_int64_t trx_sys_mysql_master_log_pos = -1;
85 /* @} */
86 
90 /* @{ */
92 UNIV_INTERN char trx_sys_mysql_bin_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
94 UNIV_INTERN ib_int64_t trx_sys_mysql_bin_log_pos = -1;
95 
97 
98 /* @} */
99 #endif /* !UNIV_HOTBACKUP */
100 
102 static const char* file_format_name_map[] = {
103  "Antelope",
104  "Barracuda",
105  "Cheetah",
106  "Dragon",
107  "Elk",
108  "Fox",
109  "Gazelle",
110  "Hornet",
111  "Impala",
112  "Jaguar",
113  "Kangaroo",
114  "Leopard",
115  "Moose",
116  "Nautilus",
117  "Ocelot",
118  "Porpoise",
119  "Quail",
120  "Rabbit",
121  "Shark",
122  "Tiger",
123  "Urchin",
124  "Viper",
125  "Whale",
126  "Xenops",
127  "Yak",
128  "Zebra"
129 };
130 
132 static const ulint FILE_FORMAT_NAME_N
133  = sizeof(file_format_name_map) / sizeof(file_format_name_map[0]);
134 
135 #ifdef UNIV_PFS_MUTEX
136 /* Key to register the mutex with performance schema */
137 UNIV_INTERN mysql_pfs_key_t trx_doublewrite_mutex_key;
138 UNIV_INTERN mysql_pfs_key_t file_format_max_mutex_key;
139 #endif /* UNIV_PFS_MUTEX */
140 
141 #ifndef UNIV_HOTBACKUP
142 
145 static file_format_t file_format_max;
146 
147 /****************************************************************/
151 UNIV_INTERN
152 ibool
154 /*========================*/
155  ulint page_no)
156 {
157  if (trx_doublewrite == NULL) {
158 
159  return(FALSE);
160  }
161 
162  if (page_no >= trx_doublewrite->block1
163  && page_no < trx_doublewrite->block1
165  return(TRUE);
166  }
167 
168  if (page_no >= trx_doublewrite->block2
169  && page_no < trx_doublewrite->block2
171  return(TRUE);
172  }
173 
174  return(FALSE);
175 }
176 
177 /****************************************************************/
179 static
180 void
181 trx_doublewrite_init(
182 /*=================*/
183  byte* doublewrite)
185 {
186  trx_doublewrite = static_cast<trx_doublewrite_t *>(mem_alloc(sizeof(trx_doublewrite_t)));
187 
188  /* Since we now start to use the doublewrite buffer, no need to call
189  fsync() after every write to a data file */
190 #ifdef UNIV_DO_FLUSH
191  os_do_not_call_flush_at_each_write = TRUE;
192 #endif /* UNIV_DO_FLUSH */
193 
194  mutex_create(trx_doublewrite_mutex_key,
195  &trx_doublewrite->mutex, SYNC_DOUBLEWRITE);
196 
198 
200  doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK1);
202  doublewrite + TRX_SYS_DOUBLEWRITE_BLOCK2);
203  trx_doublewrite->write_buf_unaligned = static_cast<byte *>(ut_malloc(
204  (1 + 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) * UNIV_PAGE_SIZE));
205 
206  trx_doublewrite->write_buf = static_cast<byte *>(ut_align(
207  trx_doublewrite->write_buf_unaligned, UNIV_PAGE_SIZE));
208  trx_doublewrite->buf_block_arr = static_cast<buf_page_t **>(mem_alloc(
209  2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * sizeof(void*)));
210 }
211 
212 /****************************************************************/
215 UNIV_INTERN
216 void
218 /*===============================================*/
219 {
220  buf_block_t* block;
221  byte* doublewrite;
222  mtr_t mtr;
223 
224  /* We upgraded to 4.1.x and reset the space id fields in the
225  doublewrite buffer. Let us mark to the trx_sys header that the upgrade
226  has been done. */
227 
228  mtr_start(&mtr);
229 
230  block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
231  RW_X_LATCH, &mtr);
232  buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
233 
234  doublewrite = buf_block_get_frame(block) + TRX_SYS_DOUBLEWRITE;
235 
238  MLOG_4BYTES, &mtr);
239  mtr_commit(&mtr);
240 
241  /* Flush the modified pages to disk and make a checkpoint */
242  log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
243 
245 }
246 
247 /****************************************************************/
250 UNIV_INTERN
251 void
253 /*================================*/
254 {
255  buf_block_t* block;
256  buf_block_t* block2;
257 #ifdef UNIV_SYNC_DEBUG
258  buf_block_t* new_block;
259 #endif /* UNIV_SYNC_DEBUG */
260  byte* doublewrite;
261  byte* fseg_header;
262  ulint page_no;
263  ulint prev_page_no;
264  ulint i;
265  mtr_t mtr;
266 
267  if (trx_doublewrite) {
268  /* Already inited */
269 
270  return;
271  }
272 
273 start_again:
274  mtr_start(&mtr);
276 
277  block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
278  RW_X_LATCH, &mtr);
279  buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
280 
281  doublewrite = buf_block_get_frame(block) + TRX_SYS_DOUBLEWRITE;
282 
285  /* The doublewrite buffer has already been created:
286  just read in some numbers */
287 
288  trx_doublewrite_init(doublewrite);
289 
290  mtr_commit(&mtr);
292  } else {
293  fprintf(stderr,
294  "InnoDB: Doublewrite buffer not found:"
295  " creating new\n");
296 
299  + FSP_EXTENT_SIZE / 2 + 100)
300  * UNIV_PAGE_SIZE)) {
301  fprintf(stderr,
302  "InnoDB: Cannot create doublewrite buffer:"
303  " you must\n"
304  "InnoDB: increase your buffer pool size.\n"
305  "InnoDB: Cannot continue operation.\n");
306 
307  exit(1);
308  }
309 
310  block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
312  + TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
313 
314  /* fseg_create acquires a second latch on the page,
315  therefore we must declare it: */
316 
317  buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
318 
319  if (block2 == NULL) {
320  fprintf(stderr,
321  "InnoDB: Cannot create doublewrite buffer:"
322  " you must\n"
323  "InnoDB: increase your tablespace size.\n"
324  "InnoDB: Cannot continue operation.\n");
325 
326  /* We exit without committing the mtr to prevent
327  its modifications to the database getting to disk */
328 
329  exit(1);
330  }
331 
332  fseg_header = buf_block_get_frame(block)
334  prev_page_no = 0;
335 
336  for (i = 0; i < 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
337  + FSP_EXTENT_SIZE / 2; i++) {
338  page_no = fseg_alloc_free_page(fseg_header,
339  prev_page_no + 1,
340  FSP_UP, &mtr);
341  if (page_no == FIL_NULL) {
342  fprintf(stderr,
343  "InnoDB: Cannot create doublewrite"
344  " buffer: you must\n"
345  "InnoDB: increase your"
346  " tablespace size.\n"
347  "InnoDB: Cannot continue operation.\n"
348  );
349 
350  exit(1);
351  }
352 
353  /* We read the allocated pages to the buffer pool;
354  when they are written to disk in a flush, the space
355  id and page number fields are also written to the
356  pages. When we at database startup read pages
357  from the doublewrite buffer, we know that if the
358  space id and page number in them are the same as
359  the page position in the tablespace, then the page
360  has not been written to in doublewrite. */
361 
362 #ifdef UNIV_SYNC_DEBUG
363  new_block =
364 #endif /* UNIV_SYNC_DEBUG */
365  buf_page_get(TRX_SYS_SPACE, 0, page_no,
366  RW_X_LATCH, &mtr);
367  buf_block_dbg_add_level(new_block,
368  SYNC_NO_ORDER_CHECK);
369 
370  if (i == FSP_EXTENT_SIZE / 2) {
371  ut_a(page_no == FSP_EXTENT_SIZE);
372  mlog_write_ulint(doublewrite
374  page_no, MLOG_4BYTES, &mtr);
375  mlog_write_ulint(doublewrite
378  page_no, MLOG_4BYTES, &mtr);
379  } else if (i == FSP_EXTENT_SIZE / 2
381  ut_a(page_no == 2 * FSP_EXTENT_SIZE);
382  mlog_write_ulint(doublewrite
384  page_no, MLOG_4BYTES, &mtr);
385  mlog_write_ulint(doublewrite
388  page_no, MLOG_4BYTES, &mtr);
389  } else if (i > FSP_EXTENT_SIZE / 2) {
390  ut_a(page_no == prev_page_no + 1);
391  }
392 
393  prev_page_no = page_no;
394  }
395 
398  MLOG_4BYTES, &mtr);
402  MLOG_4BYTES, &mtr);
403 
404  mlog_write_ulint(doublewrite
407  MLOG_4BYTES, &mtr);
408  mtr_commit(&mtr);
409 
410  /* Flush the modified pages to disk and make a checkpoint */
411  log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
412 
413  fprintf(stderr, "InnoDB: Doublewrite buffer created\n");
414 
416 
417  goto start_again;
418  }
419 }
420 
421 /****************************************************************/
428 UNIV_INTERN
429 void
431 /*======================================*/
432  ibool restore_corrupt_pages)
433 {
434  byte* buf;
435  byte* read_buf;
436  byte* unaligned_read_buf;
437  ulint block1;
438  ulint block2;
439  ulint source_page_no;
440  byte* page;
441  byte* doublewrite;
442  ulint space_id;
443  ulint page_no;
444  ulint i;
445 
446  /* We do the file i/o past the buffer pool */
447 
448  unaligned_read_buf = static_cast<byte *>(ut_malloc(2 * UNIV_PAGE_SIZE));
449  read_buf = static_cast<byte *>(ut_align(unaligned_read_buf, UNIV_PAGE_SIZE));
450 
451  /* Read the trx sys header to check if we are using the doublewrite
452  buffer */
453 
454  fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO, 0,
455  UNIV_PAGE_SIZE, read_buf, NULL);
456  doublewrite = read_buf + TRX_SYS_DOUBLEWRITE;
457 
460  /* The doublewrite buffer has been created */
461 
462  trx_doublewrite_init(doublewrite);
463 
464  block1 = trx_doublewrite->block1;
465  block2 = trx_doublewrite->block2;
466 
467  buf = trx_doublewrite->write_buf;
468  } else {
469  goto leave_func;
470  }
471 
474 
475  /* We are upgrading from a version < 4.1.x to a version where
476  multiple tablespaces are supported. We must reset the space id
477  field in the pages in the doublewrite buffer because starting
478  from this version the space id is stored to
479  FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID. */
480 
482 
483  fprintf(stderr,
484  "InnoDB: Resetting space id's in the"
485  " doublewrite buffer\n");
486  } else {
488  }
489 
490  /* Read the pages from the doublewrite buffer to memory */
491 
492  fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, 0, block1, 0,
493  TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
494  buf, NULL);
495  fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, 0, block2, 0,
496  TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
497  buf + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
498  NULL);
499  /* Check if any of these pages is half-written in data files, in the
500  intended position */
501 
502  page = buf;
503 
504  for (i = 0; i < TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 2; i++) {
505 
506  page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
507 
509 
510  space_id = 0;
511  mach_write_to_4(page
513  /* We do not need to calculate new checksums for the
514  pages because the field .._SPACE_ID does not affect
515  them. Write the page back to where we read it from. */
516 
517  if (i < TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
518  source_page_no = block1 + i;
519  } else {
520  source_page_no = block2
522  }
523 
524  fil_io(OS_FILE_WRITE, TRUE, 0, 0, source_page_no, 0,
525  UNIV_PAGE_SIZE, page, NULL);
526  /* printf("Resetting space id in page %lu\n",
527  source_page_no); */
528  } else {
529  space_id = mach_read_from_4(
531  }
532 
533  if (!restore_corrupt_pages) {
534  /* The database was shut down gracefully: no need to
535  restore pages */
536 
537  } else if (!fil_tablespace_exists_in_mem(space_id)) {
538  /* Maybe we have dropped the single-table tablespace
539  and this page once belonged to it: do nothing */
540 
541  } else if (!fil_check_adress_in_tablespace(space_id,
542  page_no)) {
543  fprintf(stderr,
544  "InnoDB: Warning: a page in the"
545  " doublewrite buffer is not within space\n"
546  "InnoDB: bounds; space id %lu"
547  " page number %lu, page %lu in"
548  " doublewrite buf.\n",
549  (ulong) space_id, (ulong) page_no, (ulong) i);
550 
551  } else if (space_id == TRX_SYS_SPACE
552  && ((page_no >= block1
553  && page_no
554  < block1 + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
555  || (page_no >= block2
556  && page_no
557  < (block2
558  + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)))) {
559 
560  /* It is an unwritten doublewrite buffer page:
561  do nothing */
562  } else {
563  ulint zip_size = fil_space_get_zip_size(space_id);
564 
565  /* Read in the actual page from the file */
566  fil_io(OS_FILE_READ, TRUE, space_id, zip_size,
567  page_no, 0,
568  zip_size ? zip_size : UNIV_PAGE_SIZE,
569  read_buf, NULL);
570 
571  /* Check if the page is corrupt */
572 
573  if (UNIV_UNLIKELY
574  (buf_page_is_corrupted(read_buf, zip_size))) {
575 
576  fprintf(stderr,
577  "InnoDB: Warning: database page"
578  " corruption or a failed\n"
579  "InnoDB: file read of"
580  " space %lu page %lu.\n"
581  "InnoDB: Trying to recover it from"
582  " the doublewrite buffer.\n",
583  (ulong) space_id, (ulong) page_no);
584 
585  if (buf_page_is_corrupted(page, zip_size)) {
586  fprintf(stderr,
587  "InnoDB: Dump of the page:\n");
588  buf_page_print(read_buf, zip_size);
589  fprintf(stderr,
590  "InnoDB: Dump of"
591  " corresponding page"
592  " in doublewrite buffer:\n");
593  buf_page_print(page, zip_size);
594 
595  fprintf(stderr,
596  "InnoDB: Also the page in the"
597  " doublewrite buffer"
598  " is corrupt.\n"
599  "InnoDB: Cannot continue"
600  " operation.\n"
601  "InnoDB: You can try to"
602  " recover the database"
603  " with the my.cnf\n"
604  "InnoDB: option:\n"
605  "InnoDB:"
606  " innodb_force_recovery=6\n");
607  exit(1);
608  }
609 
610  /* Write the good page from the
611  doublewrite buffer to the intended
612  position */
613 
614  fil_io(OS_FILE_WRITE, TRUE, space_id,
615  zip_size, page_no, 0,
616  zip_size ? zip_size : UNIV_PAGE_SIZE,
617  page, NULL);
618  fprintf(stderr,
619  "InnoDB: Recovered the page from"
620  " the doublewrite buffer.\n");
621  }
622  }
623 
624  page += UNIV_PAGE_SIZE;
625  }
626 
628 
629 leave_func:
630  ut_free(unaligned_read_buf);
631 }
632 
633 /****************************************************************/
636 UNIV_INTERN
637 ibool
639 /*============*/
640  trx_t* in_trx)
641 {
642  trx_t* trx;
643 
644  ut_ad(mutex_own(&(kernel_mutex)));
645 
646  trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
647 
648  while (trx != NULL) {
649 
650  if (trx == in_trx) {
651 
652  return(TRUE);
653  }
654 
655  trx = UT_LIST_GET_NEXT(trx_list, trx);
656  }
657 
658  return(FALSE);
659 }
660 
661 /*****************************************************************/
663 UNIV_INTERN
664 void
665 trx_sys_flush_max_trx_id(void)
666 /*==========================*/
667 {
668  trx_sysf_t* sys_header;
669  mtr_t mtr;
670 
671  ut_ad(mutex_own(&kernel_mutex));
672 
673  mtr_start(&mtr);
674 
675  sys_header = trx_sysf_get(&mtr);
676 
678  trx_sys->max_trx_id, &mtr);
679  mtr_commit(&mtr);
680 }
681 
682 UNIV_INTERN
683 void
684 trx_sys_flush_commit_id(uint64_t commit_id, ulint field, mtr_t* mtr)
685 {
686  trx_sysf_t* sys_header;
687 
688  sys_header = trx_sysf_get(mtr);
689 
690  mlog_write_ull(sys_header + field + TRX_SYS_DRIZZLE_MAX_COMMIT_ID,
691  commit_id, mtr);
692 }
693 
694 
695 UNIV_INTERN
696 void
698 /*===================================*/
699 {
700  trx_sysf_t* sys_header;
701  mtr_t mtr;
702 
703  mtr_start(&mtr);
704 
705  sys_header = trx_sysf_get(&mtr);
706 
709 
710  mtr_commit(&mtr);
711 }
712 
713 /****************************************************************/
716 UNIV_INTERN
717 ulint
719 /*====================*/
720  mtr_t* mtr)
721 {
722  trx_sysf_t* sys_header;
723  ulint page_no;
724  ulint i;
725 
726  ut_ad(mutex_own(&(kernel_mutex)));
727 
728  sys_header = trx_sysf_get(mtr);
729 
730  for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
731 
732  page_no = trx_sysf_rseg_get_page_no(sys_header, i, mtr);
733 
734  if (page_no == FIL_NULL) {
735 
736  return(i);
737  }
738  }
739 
740  return(ULINT_UNDEFINED);
741 }
742 
743 /*****************************************************************/
746 static
747 void
748 trx_sysf_create(
749 /*============*/
750  mtr_t* mtr)
751 {
752  trx_sysf_t* sys_header;
753  ulint slot_no;
754  buf_block_t* block;
755  page_t* page;
756  ulint page_no;
757  byte* ptr;
758  ulint len;
759 
760  ut_ad(mtr);
761 
762  /* Note that below we first reserve the file space x-latch, and
763  then enter the kernel: we must do it in this order to conform
764  to the latching order rules. */
765 
766  mtr_x_lock(fil_space_get_latch(TRX_SYS_SPACE, NULL), mtr);
767  mutex_enter(&kernel_mutex);
768 
769  /* Create the trx sys file block in a new allocated file segment */
770  block = fseg_create(TRX_SYS_SPACE, 0, TRX_SYS + TRX_SYS_FSEG_HEADER,
771  mtr);
772  buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
773 
774  ut_a(buf_block_get_page_no(block) == TRX_SYS_PAGE_NO);
775 
776  page = buf_block_get_frame(block);
777 
779  MLOG_2BYTES, mtr);
780 
781  /* Reset the doublewrite buffer magic number to zero so that we
782  know that the doublewrite buffer has not yet been created (this
783  suppresses a Valgrind warning) */
784 
787 
788  sys_header = trx_sysf_get(mtr);
789 
790  /* Start counting transaction ids from number 1 up */
791  mach_write_to_8(sys_header + TRX_SYS_TRX_ID_STORE, 1);
792 
793  /* Reset the rollback segment slots. Old versions of InnoDB
794  define TRX_SYS_N_RSEGS as 256 (TRX_SYS_OLD_N_RSEGS) and expect
795  that the whole array is initialized. */
796  ptr = TRX_SYS_RSEGS + sys_header;
797  len = ut_max(TRX_SYS_OLD_N_RSEGS, TRX_SYS_N_RSEGS)
798  * TRX_SYS_RSEG_SLOT_SIZE;
799  memset(ptr, 0xff, len);
800  ptr += len;
801  ut_a(ptr <= page + (UNIV_PAGE_SIZE - FIL_PAGE_DATA_END));
802 
803  /* Initialize all of the page. This part used to be uninitialized. */
804  memset(ptr, 0, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page - ptr);
805 
806  mlog_log_string(sys_header, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END
807  + page - sys_header, mtr);
808 
809  /* Create the first rollback segment in the SYSTEM tablespace */
810  slot_no = trx_sysf_rseg_find_free(mtr);
811  page_no = trx_rseg_header_create(TRX_SYS_SPACE, 0, ULINT_MAX, slot_no,
812  mtr);
813  ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
814  ut_a(page_no == FSP_FIRST_RSEG_PAGE_NO);
815 
816  mutex_exit(&kernel_mutex);
817 }
818 
819 /*****************************************************************/
821 static
822 int
823 trx_rseg_compare_last_trx_no(
824 /*=========================*/
825  const void* p1,
826  const void* p2)
827 {
828  ib_int64_t cmp;
829 
830  const rseg_queue_t* rseg_q1 = (const rseg_queue_t*) p1;
831  const rseg_queue_t* rseg_q2 = (const rseg_queue_t*) p2;
832 
833  cmp = rseg_q1->trx_no - rseg_q2->trx_no;
834 
835  if (cmp < 0) {
836  return(-1);
837  } else if (cmp > 0) {
838  return(1);
839  }
840 
841  return(0);
842 }
843 
844 /*****************************************************************/
847 UNIV_INTERN
848 void
850 /*==========================*/
851 {
852  trx_sysf_t* sys_header;
853  ib_uint64_t rows_to_undo = 0;
854  const char* unit = "";
855  trx_t* trx;
856  mtr_t mtr;
857  ib_bh_t* ib_bh;
858 
859  mtr_start(&mtr);
860 
861  ut_ad(trx_sys == NULL);
862 
863  mutex_enter(&kernel_mutex);
864 
865  /* We create the min binary heap here and pass ownership to
866  purge when we init the purge sub-system. Purge is responsible
867  for freeing the binary heap. */
868 
869  ib_bh = ib_bh_create(
870  trx_rseg_compare_last_trx_no,
871  sizeof(rseg_queue_t), TRX_SYS_N_RSEGS);
872 
873  trx_sys = (trx_sys_t*)mem_zalloc(sizeof(*trx_sys));
874 
875  sys_header = trx_sysf_get(&mtr);
876 
877  trx_rseg_list_and_array_init(sys_header, ib_bh, &mtr);
878 
880 
881  /* VERY important: after the database is started, max_trx_id value is
882  divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the 'if' in
883  trx_sys_get_new_trx_id will evaluate to TRUE when the function
884  is first time called, and the value for trx id will be written
885  to the disk-based header! Thus trx id values will not overlap when
886  the database is repeatedly started! */
887 
892 
893  UT_LIST_INIT(trx_sys->mysql_trx_list);
896 
897  if (UT_LIST_GET_LEN(trx_sys->trx_list) > 0) {
898  trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
899 
900  for (;;) {
901 
902  if (trx->conc_state != TRX_PREPARED) {
903  rows_to_undo += trx->undo_no;
904  }
905 
906  trx = UT_LIST_GET_NEXT(trx_list, trx);
907 
908  if (!trx) {
909  break;
910  }
911  }
912 
913  if (rows_to_undo > 1000000000) {
914  unit = "M";
915  rows_to_undo = rows_to_undo / 1000000;
916  }
917 
918  fprintf(stderr,
919  "InnoDB: %lu transaction(s) which must be"
920  " rolled back or cleaned up\n"
921  "InnoDB: in total %lu%s row operations to undo\n",
922  (ulong) UT_LIST_GET_LEN(trx_sys->trx_list),
923  (ulong) rows_to_undo, unit);
924 
925  fprintf(stderr, "InnoDB: Trx id counter is " TRX_ID_FMT "\n",
927  }
928 
929  UT_LIST_INIT(trx_sys->view_list);
930 
931  /* Transfer ownership to purge. */
932  trx_purge_sys_create(ib_bh);
933 
934  mutex_exit(&kernel_mutex);
935 
936  mtr_commit(&mtr);
937 }
938 
939 /*****************************************************************/
941 UNIV_INTERN
942 void
944 /*================*/
945 {
946  mtr_t mtr;
947 
948  mtr_start(&mtr);
949 
950  trx_sysf_create(&mtr);
951 
952  mtr_commit(&mtr);
953 
955 }
956 
957 /*****************************************************************/
960 static
961 ibool
962 trx_sys_file_format_max_write(
963 /*==========================*/
964  ulint format_id,
965  const char** name)
967 {
968  mtr_t mtr;
969  byte* ptr;
970  buf_block_t* block;
971  ib_uint64_t tag_value;
972 
973  mtr_start(&mtr);
974 
975  block = buf_page_get(
976  TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO, RW_X_LATCH, &mtr);
977 
978  file_format_max.id = format_id;
979  file_format_max.name = trx_sys_file_format_id_to_name(format_id);
980 
981  ptr = buf_block_get_frame(block) + TRX_SYS_FILE_FORMAT_TAG;
982  tag_value = format_id + TRX_SYS_FILE_FORMAT_TAG_MAGIC_N;
983 
984  if (name) {
985  *name = file_format_max.name;
986  }
987 
988  mlog_write_ull(ptr, tag_value, &mtr);
989 
990  mtr_commit(&mtr);
991 
992  return(TRUE);
993 }
994 
995 /*****************************************************************/
998 static
999 ulint
1000 trx_sys_file_format_max_read(void)
1001 /*==============================*/
1002 {
1003  mtr_t mtr;
1004  const byte* ptr;
1005  const buf_block_t* block;
1006  ib_id_t file_format_id;
1007 
1008  /* Since this is called during the startup phase it's safe to
1009  read the value without a covering mutex. */
1010  mtr_start(&mtr);
1011 
1012  block = buf_page_get(
1013  TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO, RW_X_LATCH, &mtr);
1014 
1015  ptr = buf_block_get_frame(block) + TRX_SYS_FILE_FORMAT_TAG;
1016  file_format_id = mach_read_from_8(ptr);
1017 
1018  mtr_commit(&mtr);
1019 
1020  file_format_id -= TRX_SYS_FILE_FORMAT_TAG_MAGIC_N;
1021 
1022  if (file_format_id >= FILE_FORMAT_NAME_N) {
1023 
1024  /* Either it has never been tagged, or garbage in it. */
1025  return(ULINT_UNDEFINED);
1026  }
1027 
1028  return((ulint) file_format_id);
1029 }
1030 
1031 /*****************************************************************/
1034 UNIV_INTERN
1035 const char*
1037 /*===========================*/
1038  const ulint id)
1039 {
1040  ut_a(id < FILE_FORMAT_NAME_N);
1041 
1042  return(file_format_name_map[id]);
1043 }
1044 
1045 /*****************************************************************/
1049 UNIV_INTERN
1050 ulint
1052 /*==========================*/
1053  ulint max_format_id)
1054 {
1055  ulint format_id;
1056 
1057  /* Check the file format in the tablespace. Do not try to
1058  recover if the file format is not supported by the engine
1059  unless forced by the user. */
1060  format_id = trx_sys_file_format_max_read();
1061  if (format_id == ULINT_UNDEFINED) {
1062  /* Format ID was not set. Set it to minimum possible
1063  value. */
1064  format_id = DICT_TF_FORMAT_MIN;
1065  }
1066 
1067  drizzled::errmsg_printf(drizzled::error::INFO, "InnoDB: highest supported file format is %s",
1069 
1070  if (format_id > DICT_TF_FORMAT_MAX) {
1071 
1072  ut_a(format_id < FILE_FORMAT_NAME_N);
1073 
1074  drizzled::errmsg_printf(drizzled::error::ERROR,
1075  "InnoDB: %s: the system tablespace is in a file "
1076  "format that this version doesn't support - %s",
1077  ((max_format_id <= DICT_TF_FORMAT_MAX)
1078  ? "Error" : "Warning"),
1079  trx_sys_file_format_id_to_name(format_id));
1080 
1081  if (max_format_id <= DICT_TF_FORMAT_MAX) {
1082  return(DB_ERROR);
1083  }
1084  }
1085 
1086  format_id = (format_id > max_format_id) ? format_id : max_format_id;
1087 
1088  /* We don't need a mutex here, as this function should only
1089  be called once at start up. */
1090  file_format_max.id = format_id;
1091  file_format_max.name = trx_sys_file_format_id_to_name(format_id);
1092 
1093  return(DB_SUCCESS);
1094 }
1095 
1096 /*****************************************************************/
1100 UNIV_INTERN
1101 ibool
1103 /*========================*/
1104  ulint format_id,
1105  const char** name)
1107 {
1108  ibool ret = FALSE;
1109 
1110  ut_a(format_id <= DICT_TF_FORMAT_MAX);
1111 
1112  mutex_enter(&file_format_max.mutex);
1113 
1114  /* Only update if not already same value. */
1115  if (format_id != file_format_max.id) {
1116 
1117  ret = trx_sys_file_format_max_write(format_id, name);
1118  }
1119 
1120  mutex_exit(&file_format_max.mutex);
1121 
1122  return(ret);
1123 }
1124 
1125 /********************************************************************/
1130 UNIV_INTERN
1131 void
1133 /*==============================*/
1134 {
1135  ulint format_id;
1136 
1137  format_id = trx_sys_file_format_max_read();
1138 
1139  /* If format_id is not set then set it to the minimum. */
1140  if (format_id == ULINT_UNDEFINED) {
1142  }
1143 }
1144 
1145 /********************************************************************/
1149 UNIV_INTERN
1150 ibool
1152 /*============================*/
1153  const char** name,
1154  ulint format_id)
1155 {
1156  ibool ret = FALSE;
1157 
1158  ut_a(name);
1159  ut_a(file_format_max.name != NULL);
1160  ut_a(format_id <= DICT_TF_FORMAT_MAX);
1161 
1162  mutex_enter(&file_format_max.mutex);
1163 
1164  if (format_id > file_format_max.id) {
1165 
1166  ret = trx_sys_file_format_max_write(format_id, name);
1167  }
1168 
1169  mutex_exit(&file_format_max.mutex);
1170 
1171  return(ret);
1172 }
1173 
1174 /*****************************************************************/
1177 UNIV_INTERN
1178 const char*
1180 /*=============================*/
1181 {
1182  return(file_format_max.name);
1183 }
1184 
1185 /*****************************************************************/
1187 UNIV_INTERN
1188 void
1190 /*==========================*/
1191 {
1192  mutex_create(file_format_max_mutex_key,
1193  &file_format_max.mutex, SYNC_FILE_FORMAT_TAG);
1194 
1195  /* We don't need a mutex here, as this function should only
1196  be called once at start up. */
1197  file_format_max.id = DICT_TF_FORMAT_MIN;
1198 
1199  file_format_max.name = trx_sys_file_format_id_to_name(
1200  file_format_max.id);
1201 }
1202 
1203 /*****************************************************************/
1205 UNIV_INTERN
1206 void
1208 /*===========================*/
1209 {
1210  /* Does nothing at the moment */
1211 }
1212 
1213 /*********************************************************************
1214 Creates the rollback segments */
1215 UNIV_INTERN
1216 void
1218 /*=================*/
1219  ulint n_rsegs)
1220 {
1221  ulint new_rsegs = 0;
1222 
1223  /* Do not create additional rollback segments if
1224  innodb_force_recovery has been set and the database
1225  was not shutdown cleanly. */
1226  if (!srv_force_recovery && !recv_needed_recovery) {
1227  ulint i;
1228 
1229  for (i = 0; i < n_rsegs; ++i) {
1230 
1231  if (trx_rseg_create() != NULL) {
1232  ++new_rsegs;
1233  } else {
1234  break;
1235  }
1236  }
1237  }
1238 
1239  if (new_rsegs > 0) {
1240  fprintf(stderr,
1241  "InnoDB: %lu rollback segment(s) active.\n",
1242  new_rsegs);
1243  }
1244 }
1245 
1246 #else /* !UNIV_HOTBACKUP */
1247 
1248 /* THESE ARE COPIED FROM NON-HOTBACKUP PART OF THE INNODB SOURCE TREE
1249  (This code duplicaton should be fixed at some point!)
1250 */
1251 
1252 #define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
1253 /* The offset of the file format tag on the trx system header page */
1254 #define TRX_SYS_FILE_FORMAT_TAG (UNIV_PAGE_SIZE - 16)
1255 /* We use these random constants to reduce the probability of reading
1256 garbage (from previous versions) that maps to an actual format id. We
1257 use these as bit masks at the time of reading and writing from/to disk. */
1258 #define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW 3645922177UL
1259 #define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH 2745987765UL
1260 
1261 /* END OF COPIED DEFINITIONS */
1262 
1263 
1264 /*****************************************************************/
1270 UNIV_INTERN
1271 ibool
1272 trx_sys_read_file_format_id(
1273 /*========================*/
1274  const char *pathname,
1276  ulint *format_id)
1278 {
1279  os_file_t file;
1280  ibool success;
1281  byte buf[UNIV_PAGE_SIZE * 2];
1282  page_t* page = ut_align(buf, UNIV_PAGE_SIZE);
1283  const byte* ptr;
1284  ib_id_t file_format_id;
1285 
1286  *format_id = ULINT_UNDEFINED;
1287 
1288  file = os_file_create_simple_no_error_handling(
1289  innodb_file_data_key,
1290  pathname,
1291  OS_FILE_OPEN,
1292  OS_FILE_READ_ONLY,
1293  &success
1294  );
1295  if (!success) {
1296  /* The following call prints an error message */
1297  os_file_get_last_error(TRUE);
1298 
1299  ut_print_timestamp(stderr);
1300 
1301  fprintf(stderr,
1302 " ibbackup: Error: trying to read system tablespace file format,\n"
1303 " ibbackup: but could not open the tablespace file %s!\n",
1304  pathname
1305  );
1306  return(FALSE);
1307  }
1308 
1309  /* Read the page on which file format is stored */
1310 
1311  success = os_file_read_no_error_handling(
1312  file, page, TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE, 0, UNIV_PAGE_SIZE
1313  );
1314  if (!success) {
1315  /* The following call prints an error message */
1316  os_file_get_last_error(TRUE);
1317 
1318  ut_print_timestamp(stderr);
1319 
1320  fprintf(stderr,
1321 " ibbackup: Error: trying to read system table space file format,\n"
1322 " ibbackup: but failed to read the tablespace file %s!\n",
1323  pathname
1324  );
1325  os_file_close(file);
1326  return(FALSE);
1327  }
1328  os_file_close(file);
1329 
1330  /* get the file format from the page */
1331  ptr = page + TRX_SYS_FILE_FORMAT_TAG;
1332  file_format_id = mach_read_from_8(ptr);
1333  file_format_id -= TRX_SYS_FILE_FORMAT_TAG_MAGIC_N;
1334 
1335  if (file_format_id >= FILE_FORMAT_NAME_N) {
1336 
1337  /* Either it has never been tagged, or garbage in it. */
1338  return(TRUE);
1339  }
1340 
1341  *format_id = (ulint) file_format_id;
1342 
1343  return(TRUE);
1344 }
1345 
1346 
1347 /*****************************************************************/
1350 UNIV_INTERN
1351 ibool
1352 trx_sys_read_pertable_file_format_id(
1353 /*=================================*/
1354  const char *pathname,
1356  ulint *format_id)
1358 {
1359  os_file_t file;
1360  ibool success;
1361  byte buf[UNIV_PAGE_SIZE * 2];
1362  page_t* page = ut_align(buf, UNIV_PAGE_SIZE);
1363  const byte* ptr;
1364  ib_uint32_t flags;
1365 
1366  *format_id = ULINT_UNDEFINED;
1367 
1368  file = os_file_create_simple_no_error_handling(
1369  innodb_file_data_key,
1370  pathname,
1371  OS_FILE_OPEN,
1372  OS_FILE_READ_ONLY,
1373  &success
1374  );
1375  if (!success) {
1376  /* The following call prints an error message */
1377  os_file_get_last_error(TRUE);
1378 
1379  ut_print_timestamp(stderr);
1380 
1381  fprintf(stderr,
1382 " ibbackup: Error: trying to read per-table tablespace format,\n"
1383 " ibbackup: but could not open the tablespace file %s!\n",
1384  pathname
1385  );
1386  return(FALSE);
1387  }
1388 
1389  /* Read the first page of the per-table datafile */
1390 
1391  success = os_file_read_no_error_handling(
1392  file, page, 0, 0, UNIV_PAGE_SIZE
1393  );
1394  if (!success) {
1395  /* The following call prints an error message */
1396  os_file_get_last_error(TRUE);
1397 
1398  ut_print_timestamp(stderr);
1399 
1400  fprintf(stderr,
1401 " ibbackup: Error: trying to per-table data file format,\n"
1402 " ibbackup: but failed to read the tablespace file %s!\n",
1403  pathname
1404  );
1405  os_file_close(file);
1406  return(FALSE);
1407  }
1408  os_file_close(file);
1409 
1410  /* get the file format from the page */
1411  ptr = page + 54;
1412  flags = mach_read_from_4(ptr);
1413  if (flags == 0) {
1414  /* file format is Antelope */
1415  *format_id = 0;
1416  return (TRUE);
1417  } else if (flags & 1) {
1418  /* tablespace flags are ok */
1419  *format_id = (flags / 32) % 128;
1420  return (TRUE);
1421  } else {
1422  /* bad tablespace flags */
1423  return(FALSE);
1424  }
1425 }
1426 
1427 
1428 /*****************************************************************/
1431 UNIV_INTERN
1432 const char*
1434 /*===========================*/
1435  const ulint id)
1436 {
1437  if (!(id < FILE_FORMAT_NAME_N)) {
1438  /* unknown id */
1439  return ("Unknown");
1440  }
1441 
1442  return(file_format_name_map[id]);
1443 }
1444 
1445 #endif /* !UNIV_HOTBACKUP */
1446 
1447 #ifndef UNIV_HOTBACKUP
1448 /*********************************************************************
1449 Shutdown/Close the transaction system. */
1450 UNIV_INTERN
1451 void
1453 /*===============*/
1454 {
1455  trx_rseg_t* rseg;
1456  read_view_t* view;
1457 
1458  ut_ad(trx_sys != NULL);
1459 
1460  /* Check that all read views are closed except read view owned
1461  by a purge. */
1462 
1463  if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
1464  fprintf(stderr,
1465  "InnoDB: Error: all read views were not closed"
1466  " before shutdown:\n"
1467  "InnoDB: %lu read views open \n",
1468  static_cast<ulint>(UT_LIST_GET_LEN(trx_sys->view_list)) - 1);
1469  }
1470 
1472  trx_dummy_sess = NULL;
1473 
1475 
1476  mutex_enter(&kernel_mutex);
1477 
1478  /* Free the double write data structures. */
1479  ut_a(trx_doublewrite != NULL);
1482 
1485 
1486  mutex_free(&trx_doublewrite->mutex);
1488  trx_doublewrite = NULL;
1489 
1490  /* There can't be any active transactions. */
1491  rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
1492 
1493  while (rseg != NULL) {
1494  trx_rseg_t* prev_rseg = rseg;
1495 
1496  rseg = UT_LIST_GET_NEXT(rseg_list, prev_rseg);
1497  UT_LIST_REMOVE(rseg_list, trx_sys->rseg_list, prev_rseg);
1498 
1499  trx_rseg_mem_free(prev_rseg);
1500  }
1501 
1502  view = UT_LIST_GET_FIRST(trx_sys->view_list);
1503 
1504  while (view != NULL) {
1505  read_view_t* prev_view = view;
1506 
1507  view = UT_LIST_GET_NEXT(view_list, prev_view);
1508 
1509  /* Views are allocated from the trx_sys->global_read_view_heap.
1510  So, we simply remove the element here. */
1511  UT_LIST_REMOVE(view_list, trx_sys->view_list, prev_view);
1512  }
1513 
1514  if (! srv_apply_log_only) {
1515  ut_a(UT_LIST_GET_LEN(trx_sys->trx_list) == 0);
1516  ut_a(UT_LIST_GET_LEN(trx_sys->rseg_list) == 0);
1517  ut_a(UT_LIST_GET_LEN(trx_sys->view_list) == 0);
1518  ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0);
1519  }
1520 
1521  mem_free(trx_sys);
1522 
1523  trx_sys = NULL;
1524  mutex_exit(&kernel_mutex);
1525 }
1526 #endif /* !UNIV_HOTBACKUP */
#define FIL_PAGE_DATA_END
Definition: fil0fil.h:169
#define UT_LIST_GET_LEN(BASE)
Definition: ut0lst.h:217
trx_sys_t * trx_sys
Definition: trx0sys.cc:61
trx_doublewrite_t * trx_doublewrite
Definition: trx0sys.cc:63
int os_file_t
Definition: os0file.h:87
UNIV_INTERN void trx_sys_create_rsegs(ulint n_rsegs)
Definition: trx0sys.cc:1217
trx_id_t trx_no
Definition: trx0rseg.h:188
UNIV_INTERN void trx_sys_file_format_tag_init(void)
Definition: trx0sys.cc:1132
#define TRX_SYS_DOUBLEWRITE
Definition: trx0sys.h:479
#define UT_LIST_GET_NEXT(NAME, N)
Definition: ut0lst.h:201
UNIV_INTERN void trx_sys_file_format_init(void)
Definition: trx0sys.cc:1189
UNIV_INTERN ulint fil_io(ulint type, ibool sync, ulint space_id, ulint zip_size, ulint block_offset, ulint byte_offset, ulint len, void *buf, void *message)
Definition: fil0fil.cc:4287
UNIV_INLINE trx_sysf_t * trx_sysf_get(mtr_t *mtr)
#define DICT_TF_FORMAT_MIN
Definition: dict0mem.h:97
trx_id_t max_trx_id
Definition: trx0sys.h:579
UNIV_INTERN void log_make_checkpoint_at(ib_uint64_t lsn, ibool write_always)
Definition: log0log.cc:2104
UNIV_INTERN void trx_sys_doublewrite_init_or_restore_pages(ibool restore_corrupt_pages)
Definition: trx0sys.cc:430
UNIV_INLINE void mach_write_to_4(byte *b, ulint n)
UNIV_INTERN void trx_sys_file_format_close(void)
Definition: trx0sys.cc:1207
UNIV_INTERN const char * trx_sys_file_format_max_get(void)
Definition: trx0sys.cc:1179
ibool trx_sys_multiple_tablespace_format
Definition: trx0sys.cc:74
#define TRX_SYS_DOUBLEWRITE_MAGIC_N
Definition: trx0sys.h:529
UNIV_INTERN void buf_page_print(const byte *read_buf, ulint zip_size)
Definition: buf0buf.cc:601
#define mem_free(PTR)
Definition: mem0mem.h:249
UNIV_INTERN void trx_rseg_list_and_array_init(trx_sysf_t *sys_header, ib_bh_t *ib_bh, mtr_t *mtr)
Definition: trx0rseg.cc:365
#define TRX_ID_FMT
Definition: trx0types.h:33
undo_no_t undo_no
Definition: trx0trx.h:681
UNIV_INTERN void * ut_malloc(ulint n)
Definition: ut0mem.cc:235
#define FIL_PAGE_TYPE
Definition: fil0fil.h:118
UNIV_INLINE void mach_write_to_8(byte *b, ib_uint64_t n)
#define TRX_SYS_FILE_FORMAT_TAG
Definition: trx0sys.h:542
UNIV_INTERN ibool trx_sys_file_format_max_upgrade(const char **name, ulint format_id)
Definition: trx0sys.cc:1151
UNIV_INTERN void mlog_write_ulint(byte *ptr, ulint val, byte type, mtr_t *mtr)
Definition: mtr0log.cc:247
UNIV_INTERN ib_bh_t * ib_bh_create(ib_bh_cmp_t compare, ulint sizeof_elem, ulint max_elems)
Definition: ut0bh.cc:45
UNIV_INTERN void trx_lists_init_at_db_start(void)
Definition: trx0trx.cc:422
#define TRX_SYS_DRIZZLE_LOG_INFO
Definition: trx0sys.h:470
ibool trx_doublewrite_must_reset_space_ids
Definition: trx0sys.cc:67
UNIV_INTERN ibool buf_page_is_corrupted(const byte *read_buf, ulint zip_size)
Definition: buf0buf.cc:503
UNIV_INTERN void trx_sys_init_at_db_start(void)
Definition: trx0sys.cc:849
UNIV_INTERN ulint fil_space_get_zip_size(ulint id)
Definition: fil0fil.cc:1535
ulint conc_state
Definition: trx0trx.h:480
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED
Definition: trx0sys.h:525
trx_rseg_t * latest_rseg
Definition: trx0sys.h:593
UNIV_INTERN void trx_sys_mark_upgraded_to_multiple_tablespaces(void)
Definition: trx0sys.cc:217
#define TRX_SYS_DOUBLEWRITE_MAGIC
Definition: trx0sys.h:486
#define OS_FILE_READ
Definition: os0file.h:144
UNIV_INTERN void sess_close(sess_t *sess)
Definition: usr0sess.cc:61
#define FIL_PAGE_TYPE_TRX_SYS
Definition: fil0fil.h:181
UNIV_INTERN ulint fseg_alloc_free_page(fseg_header_t *seg_header, ulint hint, byte direction, mtr_t *mtr)
Definition: fsp0fsp.cc:2873
UNIV_INTERN rw_lock_t * fil_space_get_latch(ulint id, ulint *zip_size)
Definition: fil0fil.cc:515
#define FIL_TABLESPACE
Definition: fil0fil.h:190
sess_t * trx_dummy_sess
Definition: trx0trx.cc:48
UNIV_INTERN void trx_purge_sys_create(ib_bh_t *ib_bh)
Definition: trx0purge.cc:222
#define mem_zalloc(N)
Definition: mem0mem.h:225
UNIV_INTERN void trx_sys_read_commit_id(void)
Definition: trx0sys.cc:697
const char * name
Definition: trx0sys.cc:49
#define TRX_SYS_DOUBLEWRITE_REPEAT
Definition: trx0sys.h:504
UNIV_INLINE ulint buf_block_get_page_no(const buf_block_t *block) __attribute__((pure))
UNIV_INTERN void mtr_commit(mtr_t *mtr) __attribute__((nonnull))
Definition: mtr0mtr.cc:247
#define UT_LIST_REMOVE(NAME, BASE, N)
Definition: ut0lst.h:178
#define DICT_TF_FORMAT_MAX
Definition: dict0mem.h:94
UNIV_INTERN void trx_sys_flush_commit_id(uint64_t commit_id, ulint field, mtr_t *mtr)
Definition: trx0sys.cc:684
UNIV_INTERN void mlog_write_ull(byte *ptr, ib_uint64_t val, mtr_t *mtr)
Definition: mtr0log.cc:293
UNIV_INTERN ibool trx_in_trx_list(trx_t *in_trx)
Definition: trx0sys.cc:638
UNIV_INTERN ulint trx_rseg_header_create(ulint space, ulint zip_size, ulint max_size, ulint rseg_slot_no, mtr_t *mtr)
Definition: trx0rseg.cc:68
UNIV_INLINE void * ut_align(const void *ptr, ulint align_no)
#define TRX_SYS_TRX_ID_WRITE_MARGIN
Definition: trx0sys.h:611
UNIV_INLINE ib_uint64_t ut_uint64_align_up(ib_uint64_t n, ulint align_no)
ibool trx_doublewrite_buf_is_being_created
Definition: trx0sys.cc:69
#define MLOG_2BYTES
Definition: mtr0mtr.h:74
UNIV_INTERN void trx_sys_close(void)
Definition: trx0sys.cc:1452
UNIV_INLINE ulint ut_max(ulint n1, ulint n2)
#define ut_a(EXPR)
Definition: ut0dbg.h:105
UNIV_INTERN ulint trx_sys_file_format_max_check(ulint max_format_id)
Definition: trx0sys.cc:1051
ibool recv_needed_recovery
Definition: log0recv.cc:85
UNIV_INTERN ulint os_file_get_last_error(ibool report_all_errors)
Definition: os0file.cc:385
#define UT_LIST_GET_FIRST(BASE)
Definition: ut0lst.h:224
#define TRX_SYS_DOUBLEWRITE_FSEG
Definition: trx0sys.h:481
#define MLOG_4BYTES
Definition: mtr0mtr.h:75
UNIV_INTERN ulint trx_sysf_rseg_find_free(mtr_t *mtr)
Definition: trx0sys.cc:718
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N
Definition: trx0sys.h:551
UNIV_INTERN buf_block_t * fseg_create(ulint space, ulint page, ulint byte_offset, mtr_t *mtr)
Definition: fsp0fsp.cc:2351
#define ut_ad(EXPR)
Definition: ut0dbg.h:127
#define mtr_x_lock(B, MTR)
Definition: mtr0mtr.h:340
UNIV_INTERN void trx_sys_create(void)
Definition: trx0sys.cc:943
UNIV_INTERN void ut_free(void *ptr)
Definition: ut0mem.cc:294
#define UT_LIST_INIT(BASE)
Definition: ut0lst.h:84
#define TRX_SYS_DRIZZLE_MAX_COMMIT_ID
Definition: trx0sys.h:471
UNIV_INTERN sess_t * sess_open(void)
Definition: usr0sess.cc:39
#define TRX_SYS_RSEGS
Definition: trx0sys.h:441
#define FIL_NULL
Definition: fil0fil.h:48
UNIV_INLINE ulint trx_sysf_rseg_get_page_no(trx_sysf_t *sys_header, ulint i, mtr_t *mtr)
#define FIL_PAGE_OFFSET
Definition: fil0fil.h:82
buf_page_t ** buf_block_arr
Definition: trx0sys.h:572
#define TRX_SYS_TRX_ID_STORE
Definition: trx0sys.h:413
UNIV_INLINE ulint mach_read_from_4(const byte *b) __attribute__((nonnull
UNIV_INTERN void trx_sys_create_doublewrite_buf(void)
Definition: trx0sys.cc:252
UNIV_INTERN void fil_flush_file_spaces(ulint purpose)
Definition: fil0fil.cc:4749
UNIV_INTERN void ut_print_timestamp(FILE *file)
Definition: ut0ut.cc:247
UNIV_INTERN const char * trx_sys_file_format_id_to_name(const ulint id)
Definition: trx0sys.cc:1036
#define OS_FILE_OPEN
Definition: os0file.h:107
byte page_t
Definition: page0types.h:37
#define TRX_SYS_MYSQL_LOG_NAME_LEN
Definition: trx0sys.h:461
UNIV_INTERN void trx_rseg_mem_free(trx_rseg_t *rseg)
Definition: trx0rseg.cc:135
UNIV_INTERN void trx_purge_sys_close(void)
Definition: trx0purge.cc:269
drizzled::atomic< uint64_t > trx_sys_commit_id
Definition: trx0sys.cc:96
UNIV_INLINE void mtr_start(mtr_t *mtr) __attribute__((nonnull))
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N
Definition: trx0sys.h:531
#define TRX_SYS_DOUBLEWRITE_BLOCK2
Definition: trx0sys.h:498
#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID
Definition: fil0fil.h:156
#define TRX_SYS_DOUBLEWRITE_BLOCK1
Definition: trx0sys.h:491
UNIV_INTERN ibool fil_check_adress_in_tablespace(ulint id, ulint page_no)
Definition: fil0fil.cc:1557
UNIV_INLINE ib_uint64_t mach_read_from_8(const byte *b) __attribute__((nonnull
#define TRX_SYS_FSEG_HEADER
Definition: trx0sys.h:436
UNIV_INTERN void mlog_log_string(byte *ptr, ulint len, mtr_t *mtr)
Definition: mtr0log.cc:350
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
Definition: trx0sys.h:534
UNIV_INTERN ibool trx_doublewrite_page_inside(ulint page_no)
Definition: trx0sys.cc:153
UNIV_INLINE ulint buf_pool_get_curr_size(void)
UNIV_INTERN ibool trx_sys_file_format_max_set(ulint format_id, const char **name)
Definition: trx0sys.cc:1102
byte trx_sysf_t
Definition: trx0types.h:101
#define buf_page_get(SP, ZS, OF, LA, MTR)
Definition: buf0buf.h:316
UNIV_INTERN ibool fil_tablespace_exists_in_mem(ulint id)
Definition: fil0fil.cc:3685
byte * write_buf_unaligned
Definition: trx0sys.h:569