ma_loghandler.h 10.5 KB
Newer Older
unknown's avatar
unknown committed
1 2 3 4 5
// TODO copyright

#ifndef _ma_loghandler_h
#define _ma_loghandler_h

6 7 8 9 10 11
/* transaction log default cache size  (TODO: make it global variable) */
#define TRANSLOG_PAGECACHE_SIZE 1024*1024*2
/* transaction log default file size  (TODO: make it global variable) */
#define TRANSLOG_FILE_SIZE 1024*1024*1024
/* transaction log default flags (TODO: make it global variable) */
#define TRANSLOG_DEFAULT_FLAGS 0
12 13 14 15 16

/* Transaction log flags */
#define TRANSLOG_PAGE_CRC              1
#define TRANSLOG_SECTOR_PROTECTION     (1<<1)
#define TRANSLOG_RECORD_CRC            (1<<2)
unknown's avatar
unknown committed
17 18
#define TRANSLOG_FLAGS_NUM ((TRANSLOG_PAGE_CRC | TRANSLOG_SECTOR_PROTECTION | \
                           TRANSLOG_RECORD_CRC) + 1)
19

unknown's avatar
unknown committed
20 21 22 23 24
/*
  Page size in transaction log
  It should be Power of 2 and multiple of DISK_DRIVE_SECTOR_SIZE
  (DISK_DRIVE_SECTOR_SIZE * 2^N)
*/
25 26 27
#define TRANSLOG_PAGE_SIZE (8*1024)

#include "ma_loghandler_lsn.h"
unknown's avatar
unknown committed
28
#include "trnman_public.h"
29 30 31 32

/* short transaction ID type */
typedef uint16 SHORT_TRANSACTION_ID;

33 34
struct st_maria_share;

unknown's avatar
unknown committed
35 36
/* Length of CRC at end of pages */
#define CRC_LENGTH 4
37 38 39 40 41 42 43 44 45 46 47 48 49
/* Size of file id in logs */
#define FILEID_STORE_SIZE 2
/* Size of page reference in log */
#define PAGE_STORE_SIZE ROW_EXTENT_PAGE_SIZE
/* Size of page ranges in log */
#define PAGERANGE_STORE_SIZE ROW_EXTENT_COUNT_SIZE
#define DIRPOS_STORE_SIZE 1

/* Store methods to match the above sizes */
#define fileid_store(T,A) int2store(T,A)
#define page_store(T,A)   int5store(T,A)
#define dirpos_store(T,A) ((*(uchar*) (T)) = A)
#define pagerange_store(T,A) int2store(T,A)
unknown's avatar
unknown committed
50 51 52 53
#define fileid_korr(P) uint2korr(P)
#define page_korr(P)   uint5korr(P)
#define dirpos_korr(P) (P[0])
#define pagerange_korr(P) uint2korr(P)
54

unknown's avatar
unknown committed
55 56 57 58 59 60
/*
  Length of disk drive sector size (we assume that writing it
  to disk is atomic operation)
*/
#define DISK_DRIVE_SECTOR_SIZE 512

61 62 63 64 65 66 67
/*
  Number of empty entries we need to have in LEX_STRING for
  translog_write_record()
*/
#define LOG_INTERNAL_PARTS 1

/* position reserved in an array of parts of a log record */
68
#define TRANSLOG_INTERNAL_PARTS 2
69

70
/* types of records in the transaction log */
71 72
/* Todo: Set numbers for these when we have all entries figured out */

73 74 75
enum translog_record_type
{
  LOGREC_RESERVED_FOR_CHUNKS23= 0,
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
  LOGREC_REDO_INSERT_ROW_HEAD,
  LOGREC_REDO_INSERT_ROW_TAIL,
  LOGREC_REDO_INSERT_ROW_BLOB,
  LOGREC_REDO_INSERT_ROW_BLOBS,
  LOGREC_REDO_PURGE_ROW_HEAD,
  LOGREC_REDO_PURGE_ROW_TAIL,
  LOGREC_REDO_PURGE_BLOCKS,
  LOGREC_REDO_DELETE_ROW,
  LOGREC_REDO_UPDATE_ROW_HEAD,
  LOGREC_REDO_INDEX,
  LOGREC_REDO_UNDELETE_ROW,
  LOGREC_CLR_END,
  LOGREC_PURGE_END,
  LOGREC_UNDO_ROW_INSERT,
  LOGREC_UNDO_ROW_DELETE,
  LOGREC_UNDO_ROW_UPDATE,
  LOGREC_UNDO_ROW_PURGE,
  LOGREC_UNDO_KEY_INSERT,
  LOGREC_UNDO_KEY_DELETE,
  LOGREC_PREPARE,
  LOGREC_PREPARE_WITH_UNDO_PURGE,
  LOGREC_COMMIT,
  LOGREC_COMMIT_WITH_UNDO_PURGE,
99
  LOGREC_CHECKPOINT,
100 101 102
  LOGREC_REDO_CREATE_TABLE,
  LOGREC_REDO_RENAME_TABLE,
  LOGREC_REDO_DROP_TABLE,
103 104
  LOGREC_REDO_DELETE_ALL,
  LOGREC_REDO_REPAIR_TABLE,
105 106
  LOGREC_FILE_ID,
  LOGREC_LONG_TRANSACTION_ID,
107 108
  LOGREC_RESERVED_FUTURE_EXTENSION= 63
};
unknown's avatar
unknown committed
109
#define LOGREC_NUMBER_OF_TYPES 64              /* Maximum, can't be extended */
110

unknown's avatar
unknown committed
111
/* Size of log file; One log file is restricted to 4G */
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
typedef uint32 translog_size_t;

#define TRANSLOG_RECORD_HEADER_MAX_SIZE 1024

typedef struct st_translog_group_descriptor
{
  TRANSLOG_ADDRESS addr;
  uint8 num;
} TRANSLOG_GROUP;


typedef struct st_translog_header_buffer
{
  /* LSN of the read record */
  LSN lsn;
unknown's avatar
unknown committed
127 128
  /* array of groups descriptors, can be used only if groups_no > 0 */
  TRANSLOG_GROUP *groups;
129 130 131 132 133 134 135 136 137 138 139
  /* short transaction ID or 0 if it has no sense for the record */
  SHORT_TRANSACTION_ID short_trid;
  /*
     The Record length in buffer (including read header, but excluding
     hidden part of record (type, short TrID, length)
  */
  translog_size_t record_length;
  /*
     Buffer for write decoded header of the record (depend on the record
     type)
  */
unknown's avatar
unknown committed
140
  byte header[TRANSLOG_RECORD_HEADER_MAX_SIZE];
141 142 143 144
  /* number of groups listed in  */
  uint groups_no;
  /* in multi-group number of chunk0 pages (valid only if groups_no > 0) */
  uint chunk0_pages;
unknown's avatar
unknown committed
145 146
  /* type of the read record */
   enum translog_record_type type;
147 148
  /* chunk 0 data address (valid only if groups_no > 0) */
  TRANSLOG_ADDRESS chunk0_data_addr;
unknown's avatar
unknown committed
149 150 151
   /*
     Real compressed LSN(s) size economy (<number of LSN(s)>*7 - <real_size>)
  */
152
  int16 compressed_LSN_economy;
unknown's avatar
unknown committed
153 154 155 156
  /* short transaction ID or 0 if it has no sense for the record */
  uint16 non_header_data_start_offset;
  /* non read body data length in this first chunk */
  uint16 non_header_data_len;
157 158 159 160 161
  /* chunk 0 data size (valid only if groups_no > 0) */
  uint16 chunk0_data_len;
} TRANSLOG_HEADER_BUFFER;


unknown's avatar
unknown committed
162
typedef struct st_translog_scanner_data
163
{
unknown's avatar
unknown committed
164 165 166 167 168 169 170 171 172 173 174
  byte buffer[TRANSLOG_PAGE_SIZE];             /* buffer for page content */
  TRANSLOG_ADDRESS page_addr;                  /* current page address */
  /* end of the log which we saw last time */
  TRANSLOG_ADDRESS horizon;
  TRANSLOG_ADDRESS last_file_page;             /* Last page on in this file */
  byte *page;                                  /* page content pointer */
  /* offset of the chunk in the page */
  translog_size_t page_offset;
  /* set horizon only once at init */
  my_bool fixed_horizon;
} TRANSLOG_SCANNER_DATA;
175 176 177 178 179


struct st_translog_reader_data
{
  TRANSLOG_HEADER_BUFFER header;                /* Header */
unknown's avatar
unknown committed
180
  TRANSLOG_SCANNER_DATA scanner;                /* chunks scanner */
181
  translog_size_t body_offset;                  /* current chunk body offset */
unknown's avatar
unknown committed
182 183 184 185
  /* data offset from the record beginning */
  translog_size_t current_offset;
  /* number of bytes read in header */
  uint16 read_header;
186 187 188 189 190 191
  uint16 chunk_size;                            /* current chunk size */
  uint current_group;                           /* current group */
  uint current_chunk;                           /* current chunk in the group */
  my_bool eor;                                  /* end of the record */
};

192
struct st_transaction;
193
C_MODE_START
194

195 196 197 198 199 200 201 202 203 204
/* Records types for unittests */
#define LOGREC_FIXED_RECORD_0LSN_EXAMPLE 1
#define LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE 2
#define LOGREC_FIXED_RECORD_1LSN_EXAMPLE 3
#define LOGREC_VARIABLE_RECORD_1LSN_EXAMPLE 4
#define LOGREC_FIXED_RECORD_2LSN_EXAMPLE 5
#define LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE 6

extern void example_loghandler_init();

unknown's avatar
unknown committed
205 206 207 208
extern my_bool translog_init(const char *directory, uint32 log_file_max_size,
			     uint32 server_version, uint32 server_id,
			     PAGECACHE *pagecache, uint flags);

209 210 211 212 213 214
extern my_bool
translog_write_record(LSN *lsn, enum translog_record_type type,
                      struct st_transaction *trn,
                      struct st_maria_share *share,
                      translog_size_t rec_len, uint part_no,
                      LEX_STRING *parts_data, uchar *store_share_id);
unknown's avatar
unknown committed
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240

extern void translog_destroy();

extern translog_size_t translog_read_record_header(LSN lsn,
						   TRANSLOG_HEADER_BUFFER
						   *buff);

extern void translog_free_record_header(TRANSLOG_HEADER_BUFFER *buff);

extern translog_size_t translog_read_record(LSN lsn,
					    translog_size_t offset,
					    translog_size_t length,
					    byte *buffer,
					    struct st_translog_reader_data
					    *data);

extern my_bool translog_flush(LSN lsn);

extern my_bool translog_init_scanner(LSN lsn,
				     my_bool fixed_horizon,
				     struct st_translog_scanner_data *scanner);

extern translog_size_t translog_read_next_record_header(TRANSLOG_SCANNER_DATA
							*scanner,
							TRANSLOG_HEADER_BUFFER
							*buff);
unknown's avatar
unknown committed
241 242
extern my_bool translog_lock();
extern my_bool translog_unlock();
243 244 245 246 247 248
extern void translog_lock_assert_owner();
extern TRANSLOG_ADDRESS translog_get_horizon();
extern int translog_assign_id_to_share(struct st_maria_share *share,
                                       struct st_transaction *trn);
extern void translog_deassign_id_from_share(struct st_maria_share *share);
extern my_bool translog_inited;
unknown's avatar
unknown committed
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334

/*
  all the rest added because of recovery; should we make
  ma_loghandler_for_recovery.h ?
*/
extern LSN first_lsn_in_log();

/* record parts descriptor */
struct st_translog_parts
{
  /* full record length */
  translog_size_t record_length;
  /* full record length with chunk headers */
  translog_size_t total_record_length;
  /* current part index */
  uint current;
  /* total number of elements in parts */
  uint elements;
  /* array of parts (LEX_STRING) */
  LEX_STRING *parts;
};

typedef my_bool(*prewrite_rec_hook) (enum translog_record_type type,
                                     TRN *trn, struct st_maria_share *share,
                                     struct st_translog_parts *parts);

typedef my_bool(*inwrite_rec_hook) (enum translog_record_type type,
                                    TRN *trn,
                                    LSN *lsn,
                                    struct st_translog_parts *parts);

typedef uint16(*read_rec_hook) (enum translog_record_type type,
                                uint16 read_length, uchar *read_buff,
                                byte *decoded_buff);


/* record classes */
enum record_class
{
  LOGRECTYPE_NOT_ALLOWED,
  LOGRECTYPE_VARIABLE_LENGTH,
  LOGRECTYPE_PSEUDOFIXEDLENGTH,
  LOGRECTYPE_FIXEDLENGTH
};

/* C++ can't bear that a variable's name is "class" */
#ifndef __cplusplus
/*
  Descriptor of log record type
  Note: Don't reorder because of constructs later...
*/
typedef struct st_log_record_type_descriptor
{
  /* internal class of the record */
  enum record_class class;
  /*
    length for fixed-size record, pseudo-fixed record
    length with uncompressed LSNs
  */
  uint16 fixed_length;
  /* how much record body (belonged to headers too) read with headers */
  uint16 read_header_len;
  /* HOOK for writing the record called before lock */
  prewrite_rec_hook prewrite_hook;
  /* HOOK for writing the record called when LSN is known, inside lock */
  inwrite_rec_hook inwrite_hook;
  /* HOOK for reading headers */
  read_rec_hook read_hook;
  /*
     For pseudo fixed records number of compressed LSNs followed by
     system header
  */
  int16 compressed_LSN;
  /*  the rest is for maria_read_log & Recovery */
  /** @brief for debug error messages or "maria_read_log" command-line tool */
  const char *name;
  my_bool record_ends_group;
  /* a function to execute when we see the record during the REDO phase */
  int (*record_execute_in_redo_phase)(const TRANSLOG_HEADER_BUFFER *);
  /* a function to execute when we see the record during the UNDO phase */
  int (*record_execute_in_undo_phase)(const TRANSLOG_HEADER_BUFFER *);
} LOG_DESC;

extern LOG_DESC log_record_type_descriptor[LOGREC_NUMBER_OF_TYPES];
#endif

335
C_MODE_END
unknown's avatar
unknown committed
336
#endif