1 : /* Copyright (C) 2007 Michael Widenius
2 :
3 : This program is free software; you can redistribute it and/or modify
4 : it under the terms of the GNU General Public License as published by
5 : the Free Software Foundation; version 2 of the License.
6 :
7 : This program is distributed in the hope that it will be useful,
8 : but WITHOUT ANY WARRANTY; without even the implied warranty of
9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 : GNU General Public License for more details.
11 :
12 : You should have received a copy of the GNU General Public License
13 : along with this program; if not, write to the Free Software
14 : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
15 :
16 : /*
17 : Storage of records in block
18 : */
19 :
20 : #define LSN_SIZE 7
21 : #define DIR_COUNT_SIZE 1 /* Stores number of rows on page */
22 : #define DIR_FREE_SIZE 1 /* Pointer to first free dir entry */
23 : #define EMPTY_SPACE_SIZE 2 /* Stores empty space on page */
24 : #define PAGE_TYPE_SIZE 1
25 : #define PAGE_SUFFIX_SIZE 4 /* Bytes for checksum */
26 : #define PAGE_HEADER_SIZE (LSN_SIZE + DIR_COUNT_SIZE + DIR_FREE_SIZE +\
27 : EMPTY_SPACE_SIZE + PAGE_TYPE_SIZE)
28 : #define PAGE_OVERHEAD_SIZE (PAGE_HEADER_SIZE + DIR_ENTRY_SIZE + \
29 : PAGE_SUFFIX_SIZE)
30 : #define BLOCK_RECORD_POINTER_SIZE 6
31 :
32 : #define FULL_PAGE_SIZE(block_size) ((block_size) - LSN_SIZE - \
33 : PAGE_TYPE_SIZE - PAGE_SUFFIX_SIZE)
34 :
35 : #define ROW_EXTENT_PAGE_SIZE 5
36 : #define ROW_EXTENT_COUNT_SIZE 2
37 : #define SUB_RANGE_SIZE 2
38 : #define BLOCK_FILLER_SIZE 2
39 : #define ROW_EXTENT_SIZE (ROW_EXTENT_PAGE_SIZE + ROW_EXTENT_COUNT_SIZE)
40 : #define TAIL_BIT 0x8000 /* Bit in page_count to signify tail */
41 : #define START_EXTENT_BIT 0x4000 /* Bit in page_count to signify start*/
42 : /* page_count set by bitmap code for tail pages */
43 : #define TAIL_PAGE_COUNT_MARKER 0xffff
44 : /* Number of extents reserved MARIA_BITMAP_BLOCKS to store head part */
45 : #define ELEMENTS_RESERVED_FOR_MAIN_PART 4
46 : /* This is just used to prealloc a dynamic array */
47 : #define AVERAGE_BLOB_SIZE 1024L*1024L
48 : /* Number of pages to store continuous blob parts */
49 : #define BLOB_SEGMENT_MIN_SIZE 128
50 :
51 : /* Fields before 'row->null_field_lengths' used by find_where_to_split_row */
52 : #define EXTRA_LENGTH_FIELDS 3
53 :
54 : /* Size for the different parts in the row header (and head page) */
55 : #define FLAG_SIZE 1
56 : #define VERPTR_SIZE 7
57 : #define DIR_ENTRY_SIZE 4
58 : #define FIELD_OFFSET_SIZE 2 /* size of pointers to field starts */
59 :
60 : /* Minimum header size needed for a new row */
61 : #define BASE_ROW_HEADER_SIZE FLAG_SIZE
62 : #define TRANS_ROW_EXTRA_HEADER_SIZE TRANSID_SIZE
63 :
64 : #define PAGE_TYPE_MASK 7
65 : enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_TYPE };
66 : #define PAGE_CAN_BE_COMPACTED 128 /* Bit in PAGE_TYPE */
67 :
68 : #define PAGE_TYPE_OFFSET LSN_SIZE
69 : #define DIR_COUNT_OFFSET (LSN_SIZE+PAGE_TYPE_SIZE)
70 : #define DIR_FREE_OFFSET (DIR_COUNT_OFFSET+DIR_COUNT_SIZE)
71 : #define EMPTY_SPACE_OFFSET (DIR_FREE_OFFSET+DIR_FREE_SIZE)
72 :
73 : /* Bits used for flag uchar (one byte, first in record) */
74 : #define ROW_FLAG_TRANSID 1
75 : #define ROW_FLAG_VER_PTR 2
76 : #define ROW_FLAG_DELETE_TRANSID 4
77 : #define ROW_FLAG_NULLS_EXTENDED 8
78 : #define ROW_FLAG_EXTENTS 128
79 : #define ROW_FLAG_ALL (1+2+4+8+128)
80 :
81 : /******** Variables that affects how data pages are utilized ********/
82 :
83 : /* Minium size of tail segment */
84 : #define MIN_TAIL_SIZE 32
85 :
86 : /*
87 : Fixed length part of Max possible header size; See row data structure
88 : table in ma_blockrec.c.
89 : */
90 : #define MAX_FIXED_HEADER_SIZE (FLAG_SIZE + 3 + ROW_EXTENT_SIZE + 3)
91 : #define TRANS_MAX_FIXED_HEADER_SIZE (MAX_FIXED_HEADER_SIZE + \
92 : TRANSID_SIZE + VERPTR_SIZE + \
93 : TRANSID_SIZE)
94 :
95 : /* We use 1 uchar in record header to store number of directory entries */
96 : #define MAX_ROWS_PER_PAGE 255
97 : #define END_OF_DIR_FREE_LIST ((uchar) 255)
98 :
99 : /* Bits for MARIA_BITMAP_BLOCKS->used */
100 : /* We stored data on disk in the block */
101 : #define BLOCKUSED_USED 1
102 : /* Bitmap on disk is block->org_bitmap_value ; Happens only on update */
103 : #define BLOCKUSED_USE_ORG_BITMAP 2
104 : /* We stored tail data on disk for the block */
105 : #define BLOCKUSED_TAIL 4
106 :
107 : /******* defines that affects allocation (density) of data *******/
108 :
109 : /*
110 : If the tail part (from the main block or a blob) would use more than 75 % of
111 : the size of page, store the tail on a full page instead of a shared
112 : tail page.
113 : */
114 : #define MAX_TAIL_SIZE(block_size) ((block_size) *3 / 4)
115 :
116 : /* Don't allocate memory for too many row extents on the stack */
117 : #define ROW_EXTENTS_ON_STACK 32
118 :
119 : /* Functions to convert MARIA_RECORD_POS to/from page:offset */
120 :
121 : static inline MARIA_RECORD_POS ma_recordpos(pgcache_page_no_t page,
122 : uint dir_entry)
123 1519 : {
124 1519 : DBUG_ASSERT(dir_entry <= 255);
125 1519 : DBUG_ASSERT(page > 0); /* page 0 is bitmap, not data page */
126 1519 : return (MARIA_RECORD_POS) (((ulonglong) page << 8) | dir_entry);
127 : }
128 :
129 : static inline pgcache_page_no_t ma_recordpos_to_page(MARIA_RECORD_POS record_pos)
130 2982 : {
131 2982 : return (pgcache_page_no_t) (record_pos >> 8);
132 : }
133 :
134 : static inline uint ma_recordpos_to_dir_entry(MARIA_RECORD_POS record_pos)
135 2982 : {
136 2982 : return (uint) (record_pos & 255);
137 : }
138 :
139 : static inline uchar *dir_entry_pos(uchar *buff, uint block_size, uint pos)
140 8862 : {
141 8862 : return (buff + block_size - DIR_ENTRY_SIZE * pos - PAGE_SUFFIX_SIZE -
142 : DIR_ENTRY_SIZE);
143 : }
144 :
145 : /* ma_blockrec.c */
146 : void _ma_init_block_record_data(void);
147 : my_bool _ma_once_init_block_record(MARIA_SHARE *share, File dfile);
148 : my_bool _ma_once_end_block_record(MARIA_SHARE *share);
149 : my_bool _ma_init_block_record(MARIA_HA *info);
150 : void _ma_end_block_record(MARIA_HA *info);
151 :
152 : my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS pos,
153 : const uchar *oldrec, const uchar *newrec);
154 : my_bool _ma_delete_block_record(MARIA_HA *info, const uchar *record);
155 : int _ma_read_block_record(MARIA_HA *info, uchar *record,
156 : MARIA_RECORD_POS record_pos);
157 : int _ma_read_block_record2(MARIA_HA *info, uchar *record,
158 : uchar *data, uchar *end_of_data);
159 : int _ma_scan_block_record(MARIA_HA *info, uchar *record,
160 : MARIA_RECORD_POS, my_bool);
161 : my_bool _ma_cmp_block_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
162 : const uchar *record, MARIA_RECORD_POS pos);
163 : my_bool _ma_scan_init_block_record(MARIA_HA *info);
164 : void _ma_scan_end_block_record(MARIA_HA *info);
165 : int _ma_scan_remember_block_record(MARIA_HA *info,
166 : MARIA_RECORD_POS *lastpos);
167 : void _ma_scan_restore_block_record(MARIA_HA *info,
168 : MARIA_RECORD_POS lastpos);
169 :
170 : MARIA_RECORD_POS _ma_write_init_block_record(MARIA_HA *info,
171 : const uchar *record);
172 : my_bool _ma_write_block_record(MARIA_HA *info, const uchar *record);
173 : my_bool _ma_write_abort_block_record(MARIA_HA *info);
174 : my_bool _ma_compare_block_record(register MARIA_HA *info,
175 : register const uchar *record);
176 : void _ma_compact_block_page(uchar *buff, uint block_size, uint rownr,
177 : my_bool extend_block, TrID min_read_from,
178 : uint min_row_length);
179 : TRANSLOG_ADDRESS
180 : maria_page_get_lsn(uchar *page, pgcache_page_no_t page_no, uchar* data_ptr);
181 :
182 : /* ma_bitmap.c */
183 : my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
184 : my_bool _ma_bitmap_end(MARIA_SHARE *share);
185 : my_bool _ma_bitmap_flush(MARIA_SHARE *share);
186 : my_bool _ma_bitmap_flush_all(MARIA_SHARE *share);
187 : void _ma_bitmap_reset_cache(MARIA_SHARE *share);
188 : my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
189 : MARIA_BITMAP_BLOCKS *result_blocks);
190 : my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks);
191 : my_bool _ma_bitmap_free_full_pages(MARIA_HA *info, const uchar *extents,
192 : uint count);
193 : my_bool _ma_bitmap_set(MARIA_HA *info, pgcache_page_no_t pos, my_bool head,
194 : uint empty_space);
195 : my_bool _ma_bitmap_reset_full_page_bits(MARIA_HA *info,
196 : MARIA_FILE_BITMAP *bitmap,
197 : pgcache_page_no_t page,
198 : uint page_count);
199 : my_bool _ma_bitmap_set_full_page_bits(MARIA_HA *info,
200 : MARIA_FILE_BITMAP *bitmap,
201 : pgcache_page_no_t page, uint page_count);
202 : uint _ma_free_size_to_head_pattern(MARIA_FILE_BITMAP *bitmap, uint size);
203 : my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *new_row,
204 : pgcache_page_no_t page, uint free_size,
205 : MARIA_BITMAP_BLOCKS *result_blocks);
206 : my_bool _ma_check_bitmap_data(MARIA_HA *info,
207 : enum en_page_type page_type,
208 : pgcache_page_no_t page,
209 : uint empty_space, uint *bitmap_pattern);
210 : my_bool _ma_check_if_right_bitmap_type(MARIA_HA *info,
211 : enum en_page_type page_type,
212 : pgcache_page_no_t page,
213 : uint *bitmap_pattern);
214 : uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
215 : pgcache_page_no_t page);
216 : void _ma_bitmap_delete_all(MARIA_SHARE *share);
217 : int _ma_bitmap_create_first(MARIA_SHARE *share);
218 : void _ma_bitmap_flushable(MARIA_HA *info, int non_flushable_inc);
219 : void _ma_bitmap_set_pagecache_callbacks(PAGECACHE_FILE *file,
220 : MARIA_SHARE *share);
221 : #ifndef DBUG_OFF
222 : void _ma_print_bitmap(MARIA_FILE_BITMAP *bitmap, uchar *data,
223 : pgcache_page_no_t page);
224 : #endif
225 :
226 : uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
227 : uint page_type,
228 : my_bool new_page,
229 : const uchar *header,
230 : const uchar *data,
231 : size_t data_length);
232 : uint _ma_apply_redo_purge_row_head_or_tail(MARIA_HA *info, LSN lsn,
233 : uint page_type,
234 : const uchar *header);
235 : uint _ma_apply_redo_free_blocks(MARIA_HA *info, LSN lsn,
236 : const uchar *header);
237 : uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn,
238 : const uchar *header);
239 : uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, LSN lsn,
240 : const uchar *header, LSN redo_lsn,
241 : uint * const number_of_blobs,
242 : uint * const number_of_ranges,
243 : pgcache_page_no_t * const first_page,
244 : pgcache_page_no_t * const last_page);
245 : my_bool _ma_apply_redo_bitmap_new_page(MARIA_HA *info, LSN lsn,
246 : const uchar *header);
247 : my_bool _ma_apply_undo_row_insert(MARIA_HA *info, LSN undo_lsn,
248 : const uchar *header);
249 : my_bool _ma_apply_undo_row_delete(MARIA_HA *info, LSN undo_lsn,
250 : const uchar *header, size_t length);
251 : my_bool _ma_apply_undo_row_update(MARIA_HA *info, LSN undo_lsn,
252 : const uchar *header, size_t length);
253 : my_bool _ma_apply_undo_bulk_insert(MARIA_HA *info, LSN undo_lsn);
254 :
255 : my_bool write_hook_for_redo(enum translog_record_type type,
256 : TRN *trn, MARIA_HA *tbl_info, LSN *lsn,
257 : void *hook_arg);
258 : my_bool write_hook_for_undo(enum translog_record_type type,
259 : TRN *trn, MARIA_HA *tbl_info, LSN *lsn,
260 : void *hook_arg);
261 : my_bool write_hook_for_redo_delete_all(enum translog_record_type type,
262 : TRN *trn, MARIA_HA *tbl_info,
263 : LSN *lsn, void *hook_arg);
264 : my_bool write_hook_for_undo_row_insert(enum translog_record_type type,
265 : TRN *trn, MARIA_HA *tbl_info,
266 : LSN *lsn, void *hook_arg);
267 : my_bool write_hook_for_undo_row_delete(enum translog_record_type type,
268 : TRN *trn, MARIA_HA *tbl_info,
269 : LSN *lsn, void *hook_arg);
270 : my_bool write_hook_for_undo_row_update(enum translog_record_type type,
271 : TRN *trn, MARIA_HA *tbl_info,
272 : LSN *lsn, void *hook_arg);
273 : my_bool write_hook_for_undo_bulk_insert(enum translog_record_type type,
274 : TRN *trn, MARIA_HA *tbl_info,
275 : LSN *lsn, void *hook_arg);
276 : my_bool write_hook_for_file_id(enum translog_record_type type,
277 : TRN *trn, MARIA_HA *tbl_info, LSN *lsn,
278 : void *hook_arg);
279 : my_bool write_hook_for_commit(enum translog_record_type type,
280 : TRN *trn, MARIA_HA *tbl_info, LSN *lsn,
281 : void *hook_arg);
282 : void _ma_block_get_status(void* param, my_bool concurrent_insert);
283 : void _ma_block_update_status(void *param);
284 : void _ma_block_restore_status(void *param);
285 : my_bool _ma_block_check_status(void *param);
|