1 /* 2 Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2.0, 6 as published by the Free Software Foundation. 7 8 This program is also distributed with certain software (including 9 but not limited to OpenSSL) that is licensed under separate terms, 10 as designated in a particular file or component or in included license 11 documentation. The authors of MySQL hereby grant you an additional 12 permission to link the program and your derivative works with the 13 separately licensed software that they have included with MySQL. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License, version 2.0, for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 23 24 /* This file is included by all internal myisam files */ 25 26 /** 27 @file storage/myisam/myisamdef.h 28 */ 29 30 #ifndef STORAGE_MYISAM_MYISAMDEF_INCLUDED 31 #define STORAGE_MYISAM_MYISAMDEF_INCLUDED 1 32 33 #include "my_alloc.h" 34 #include "my_icp.h" 35 #include "my_pointer_arithmetic.h" 36 #include "myisam.h" /* Structs & some defines */ 37 #include "myisampack.h" /* packing of keys */ 38 #include "mysql/psi/mysql_file.h" 39 #include "mysql/psi/mysql_rwlock.h" 40 #include "mysql/psi/mysql_thread.h" 41 #include "thr_lock.h" 42 43 struct HA_KEYSEG; 44 struct KEY_CACHE; 45 struct MI_INFO; 46 struct MYSQL_FTPARSER_PARAM; 47 struct TREE; 48 struct st_keycache_thread_var; 49 50 /* undef map from my_nosys; We need test-if-disk full */ 51 #if defined(my_write) 52 #undef my_write 53 #endif 54 55 struct MI_STATUS_INFO { 56 ha_rows records; /* Rows in table */ 57 ha_rows del; /* Removed rows */ 58 my_off_t empty; /* lost space in datafile */ 59 my_off_t key_empty; /* lost space in indexfile */ 60 my_off_t key_file_length; 61 my_off_t data_file_length; 62 ha_checksum checksum; 63 bool uncacheable; /* Active concurrent insert */ 64 }; 65 66 struct MI_STATE_INFO { 67 struct { /* Fileheader */ 68 uchar file_version[4]; 69 uchar options[2]; 70 uchar header_length[2]; 71 uchar state_info_length[2]; 72 uchar base_info_length[2]; 73 uchar base_pos[2]; 74 uchar key_parts[2]; /* Key parts */ 75 uchar unique_key_parts[2]; /* Key parts + unique parts */ 76 uchar keys; /* number of keys in file */ 77 uchar uniques; /* number of UNIQUE definitions */ 78 uchar language; /* Language for indexes */ 79 uchar max_block_size_index; /* max keyblock size */ 80 uchar fulltext_keys; 81 uchar not_used; /* To align to 8 */ 82 } header; 83 84 MI_STATUS_INFO state; 85 ha_rows split; /* number of split blocks */ 86 my_off_t dellink; /* Link to next removed block */ 87 ulonglong auto_increment; 88 ulong process; /* process that updated table last */ 89 ulong unique; /* Unique number for this process */ 90 ulong update_count; /* Updated for each write lock */ 91 ulong status; 92 ulong *rec_per_key_part; 93 my_off_t *key_root; /* Start of key trees */ 94 my_off_t *key_del; /* delete links for trees */ 95 my_off_t rec_per_key_rows; /* Rows when calculating rec_per_key */ 96 97 ulong sec_index_changed; /* Updated when new sec_index */ 98 ulong sec_index_used; /* which extra index are in use */ 99 ulonglong key_map; /* Which keys are in use */ 100 ha_checksum checksum; /* Table checksum */ 101 ulong version; /* timestamp of create */ 102 time_t create_time; /* Time when created database */ 103 time_t recover_time; /* Time for last recover */ 104 time_t check_time; /* Time for last check */ 105 uint sortkey; /* sorted by this key (not used) */ 106 uint open_count; 107 uint8 changed; /* Changed since myisamchk */ 108 109 /* the following isn't saved on disk */ 110 uint state_diff_length; /* Should be 0 */ 111 uint state_length; /* Length of state header in file */ 112 ulong *key_info; 113 }; 114 115 #define MI_STATE_INFO_SIZE (24 + 14 * 8 + 7 * 4 + 2 * 2 + 8) 116 #define MI_STATE_KEY_SIZE 8 117 #define MI_STATE_KEYBLOCK_SIZE 8 118 #define MI_STATE_KEYSEG_SIZE 4 119 #define MI_STATE_EXTRA_SIZE \ 120 ((MI_MAX_KEY + MI_MAX_KEY_BLOCK_SIZE) * MI_STATE_KEY_SIZE + \ 121 MI_MAX_KEY * MI_MAX_KEY_SEG * MI_STATE_KEYSEG_SIZE) 122 #define MI_KEYDEF_SIZE (2 + 5 * 2) 123 #define MI_UNIQUEDEF_SIZE (2 + 1 + 1) 124 #define HA_KEYSEG_SIZE (6 + 2 * 2 + 4 * 2) 125 #define MI_COLUMNDEF_SIZE (2 * 3 + 1) 126 #define MI_BASE_INFO_SIZE (5 * 8 + 8 * 4 + 4 + 4 * 2 + 16) 127 #define MI_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */ 128 129 struct MI_BASE_INFO { 130 my_off_t keystart; /* Start of keys */ 131 my_off_t max_data_file_length; 132 my_off_t max_key_file_length; 133 my_off_t margin_key_file_length; 134 ha_rows records, reloc; /* Create information */ 135 ulong mean_row_length; /* Create information */ 136 ulong reclength; /* length of unpacked record */ 137 ulong pack_reclength; /* Length of full packed rec. */ 138 ulong min_pack_length; 139 ulong max_pack_length; /* Max possibly length of packed rec.*/ 140 ulong min_block_length; 141 ulong fields, /* fields in table */ 142 pack_fields; /* packed fields in table */ 143 uint rec_reflength; /* = 2-8 */ 144 uint key_reflength; /* = 2-8 */ 145 uint keys; /* same as in state.header */ 146 uint auto_key; /* Which key-1 is a auto key */ 147 uint blobs; /* Number of blobs */ 148 uint pack_bits; /* Length of packed bits */ 149 uint max_key_block_length; /* Max block length */ 150 uint max_key_length; /* Max key length */ 151 /* Extra allocation when using dynamic record format */ 152 uint extra_alloc_bytes; 153 uint extra_alloc_procent; 154 /* The following are from the header */ 155 uint key_parts, all_key_parts; 156 }; 157 158 /* Structs used intern in database */ 159 160 struct MI_BLOB /* Info of record */ 161 { 162 ulong offset; /* Offset to blob in record */ 163 uint pack_length; /* Type of packed length */ 164 ulong length; /* Calc:ed for each record */ 165 }; 166 167 struct MI_PACK { 168 ulong header_length; 169 uint ref_length; 170 uchar version; 171 }; 172 173 #define MAX_NONMAPPED_INSERTS 1000 174 175 struct MYISAM_SHARE { /* Shared between opens */ 176 MI_STATE_INFO state; 177 MI_BASE_INFO base; 178 MI_KEYDEF ft2_keyinfo; /* Second-level ft-key definition */ 179 MI_KEYDEF *keyinfo; /* Key definitions */ 180 MI_UNIQUEDEF *uniqueinfo; /* unique definitions */ 181 HA_KEYSEG *keyparts; /* key part info */ 182 MI_COLUMNDEF *rec; /* Pointer to field information */ 183 MI_PACK pack; /* Data about packed records */ 184 MI_BLOB *blobs; /* Pointer to blobs */ 185 LIST *in_use; /* List of threads using this table */ 186 char *unique_file_name; /* realpath() of index file */ 187 char *data_file_name, /* Resolved path names from symlinks */ 188 *index_file_name; 189 uchar *file_map; /* mem-map of file if possible */ 190 KEY_CACHE *key_cache; /* ref to the current key cache */ 191 MI_DECODE_TREE *decode_trees; 192 uint16 *decode_tables; 193 int (*read_record)(MI_INFO *, my_off_t, uchar *); 194 int (*write_record)(MI_INFO *, const uchar *); 195 int (*update_record)(MI_INFO *, my_off_t, const uchar *); 196 int (*delete_record)(MI_INFO *); 197 int (*read_rnd)(MI_INFO *, uchar *, my_off_t, bool); 198 int (*compare_record)(MI_INFO *, const uchar *); 199 /* Function to use for a row checksum. */ 200 ha_checksum (*calc_checksum)(MI_INFO *, const uchar *); 201 int (*compare_unique)(MI_INFO *, MI_UNIQUEDEF *, const uchar *record, 202 my_off_t pos); 203 size_t (*file_read)(MI_INFO *, uchar *, size_t, my_off_t, myf); 204 size_t (*file_write)(MI_INFO *, const uchar *, size_t, my_off_t, myf); 205 ulong this_process; /* processid */ 206 ulong last_process; /* For table-change-check */ 207 ulong last_version; /* Version on start */ 208 ulong options; /* Options used */ 209 ulong min_pack_length; /* Theese are used by packed data */ 210 ulong max_pack_length; 211 ulong state_diff_length; 212 uint rec_reflength; /* rec_reflength in use now */ 213 uint unique_name_length; 214 uint32 ftkeys; /* Number of full-text keys + 1 */ 215 File kfile; /* Shared keyfile */ 216 File data_file; /* Shared data file */ 217 int mode; /* mode of file on open */ 218 uint reopen; /* How many times reopened */ 219 uint w_locks, r_locks, tot_locks; /* Number of read/write locks */ 220 uint blocksize; /* blocksize of keyfile */ 221 myf write_flag; 222 enum data_file_type data_file_type; 223 /* Below flag is needed to make log tables work with concurrent insert */ 224 bool is_log_table; 225 226 bool changed, /* If changed since lock */ 227 global_changed, /* If changed since open */ 228 not_flushed, temporary, delay_key_write, concurrent_insert, have_rtree; 229 230 THR_LOCK lock; 231 mysql_mutex_t intern_lock; /* Locking for use with _locking */ 232 mysql_rwlock_t *key_root_lock; 233 my_off_t mmaped_length; 234 uint nonmmaped_inserts; /* counter of writing in non-mmaped 235 area */ 236 mysql_rwlock_t mmap_lock; 237 }; 238 239 typedef uint mi_bit_type; 240 241 struct MI_BIT_BUFF { /* Used for packing of record */ 242 mi_bit_type current_byte; 243 uint bits; 244 uchar *pos, *end, *blob_pos, *blob_end; 245 uint error; 246 }; 247 248 typedef ICP_RESULT (*index_cond_func_t)(void *param); 249 250 struct MI_INFO { 251 MYISAM_SHARE *s; /* Shared between open:s */ 252 MI_STATUS_INFO *state, save_state; 253 MI_BLOB *blobs; /* Pointer to blobs */ 254 MI_BIT_BUFF bit_buff; 255 /* accumulate indexfile changes between write's */ 256 TREE *bulk_insert; 257 DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */ 258 MEM_ROOT ft_memroot; /* used by the parser */ 259 MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit */ 260 LIST in_use; /* Thread using this table */ 261 char *filename; /* parameter to open filename */ 262 uchar *buff, /* Temp area for key */ 263 *lastkey, *lastkey2; /* Last used search key */ 264 265 /* Key used in mi_rnext_same and filled by mi_rkey. */ 266 uchar *rnext_same_key; 267 uchar *first_mbr_key; /* Searhed spatial key */ 268 uchar *rec_buff; /* Tempbuff for recordpack */ 269 uchar *int_keypos, /* Save position for next/previous */ 270 *int_maxpos; /* -""- */ 271 uint int_nod_flag; /* -""- */ 272 uint32 int_keytree_version; /* -""- */ 273 int (*read_record)(MI_INFO *, my_off_t, uchar *); 274 ulong this_unique; /* uniq filenumber or thread */ 275 ulong last_unique; /* last unique number */ 276 ulong this_loop; /* counter for this open */ 277 ulong last_loop; /* last used counter */ 278 my_off_t lastpos, /* Last record position */ 279 nextpos; /* Position to next record */ 280 my_off_t save_lastpos; 281 my_off_t pos; /* Intern variable */ 282 my_off_t last_keypage; /* Last key page read */ 283 my_off_t last_search_keypage; /* Last keypage when searching */ 284 my_off_t dupp_key_pos; 285 ha_checksum checksum; /* Temp storage for row checksum */ 286 /* QQ: the folloing two xxx_length fields should be removed, 287 as they are not compatible with parallel repair */ 288 ulong packed_length, blob_length; /* Length of found, packed record */ 289 int dfile; /* The datafile */ 290 uint opt_flag; /* Optim. for space/speed */ 291 uint update; /* If file changed since open */ 292 int lastinx; /* Last used index */ 293 uint lastkey_length; /* Length of key in lastkey */ 294 uint last_rkey_length; /* Last length in mi_rkey() */ 295 enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */ 296 uint save_lastkey_length; 297 uint pack_key_length; /* For MYISAMMRG */ 298 uint16 last_used_keyseg; /* For MyISAMMRG */ 299 int errkey; /* Got last error on this key */ 300 int lock_type; /* How database was locked */ 301 int tmp_lock_type; /* When locked by readinfo */ 302 uint data_changed; /* Somebody has changed data */ 303 uint save_update; /* When using KEY_READ */ 304 int save_lastinx; 305 LIST open_list; 306 IO_CACHE rec_cache; /* When cacheing records */ 307 uint preload_buff_size; /* When preloading indexes */ 308 myf lock_wait; /* is 0 or MY_DONT_WAIT */ 309 bool was_locked; /* Was locked in panic */ 310 bool append_insert_at_end; /* Set if concurrent insert */ 311 bool quick_mode; 312 bool page_changed; /* If info->buff can't be used for rnext */ 313 bool buff_used; /* If info->buff has to be reread for rnext */ 314 uint8 once_flags; /* For MYISAMMRG */ 315 316 /* Used in mi_rnext_same to fill rnext_same_key for the first time. */ 317 bool set_rnext_same_key; 318 319 index_cond_func_t index_cond_func; /* Index condition function */ 320 void *index_cond_func_arg; /* parameter for the func */ 321 #ifdef _WIN32 322 bool owned_by_merge; /* This MyISAM table is part of a merge union */ 323 #endif 324 THR_LOCK_DATA lock; 325 uchar *rtree_recursion_state; /* For RTREE */ 326 int rtree_recursion_depth; 327 }; 328 329 struct BUFFPEK { 330 my_off_t file_pos; /* Where we are in the sort file */ 331 uchar *base, *key; /* Key pointers */ 332 ha_rows count; /* Number of rows in table */ 333 ulong mem_count; /* numbers of keys in memory */ 334 ulong max_keys; /* Max keys in buffert */ 335 }; 336 337 struct MI_SORT_PARAM { 338 my_thread_handle thr; 339 IO_CACHE read_cache, tempfile, tempfile_for_exceptions; 340 DYNAMIC_ARRAY buffpek; 341 MI_BIT_BUFF bit_buff; /* For parallel repair of packrec. */ 342 343 /* 344 The next two are used to collect statistics, see update_key_parts for 345 description. 346 */ 347 ulonglong unique[MI_MAX_KEY_SEG + 1]; 348 ulonglong notnull[MI_MAX_KEY_SEG + 1]; 349 ulonglong sortbuff_size; 350 351 my_off_t pos, max_pos, filepos, start_recpos; 352 uint key, key_length, real_key_length; 353 uint maxbuffers, keys, find_length, sort_keys_length; 354 bool fix_datafile, master; 355 bool calc_checksum; /* calculate table checksum */ 356 MI_KEYDEF *keyinfo; 357 HA_KEYSEG *seg; 358 SORT_INFO *sort_info; 359 uchar **sort_keys; 360 uchar *rec_buff; 361 void *wordlist, *wordptr; 362 MEM_ROOT wordroot; 363 uchar *record; 364 MY_TMPDIR *tmpdir; 365 int (*key_cmp)(void *, uchar *, uchar *); 366 int (*key_read)(MI_SORT_PARAM *, void *); 367 int (*key_write)(MI_SORT_PARAM *, const void *); 368 int (*write_keys)(MI_SORT_PARAM *, uchar **, uint, BUFFPEK *, IO_CACHE *); 369 uint (*read_to_buffer)(IO_CACHE *, BUFFPEK *, uint); 370 int (*write_key)(MI_SORT_PARAM *, IO_CACHE *, uchar *, uint, uint); 371 }; 372 373 /* Some defines used by isam-funktions */ 374 375 #define USE_WHOLE_KEY MI_MAX_KEY_BUFF * 2 /* Use whole key in _mi_search() */ 376 #define F_EXTRA_LCK -1 377 378 /* bits in opt_flag */ 379 #define MEMMAP_USED 32 380 #define REMEMBER_OLD_POS 64 381 382 #define WRITEINFO_UPDATE_KEYFILE 1 383 #define WRITEINFO_NO_UNLOCK 2 384 385 /* once_flags */ 386 #define USE_PACKED_KEYS 1 387 #define RRND_PRESERVE_LASTINX 2 388 389 /* bits in state.changed */ 390 391 #define STATE_CHANGED 1 392 #define STATE_CRASHED 2 393 #define STATE_CRASHED_ON_REPAIR 4 394 #define STATE_NOT_ANALYZED 8 395 #define STATE_NOT_OPTIMIZED_KEYS 16 396 #define STATE_NOT_SORTED_PAGES 32 397 398 /* options to mi_read_cache */ 399 400 #define READING_NEXT 1 401 #define READING_HEADER 2 402 403 #define mi_getint(x) ((uint)mi_uint2korr(x) & 32767) 404 #define mi_putint(x, y, nod) \ 405 { \ 406 uint16 boh = (nod ? (uint16)32768 : 0) + (uint16)(y); \ 407 mi_int2store(x, boh); \ 408 } 409 #define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0) 410 #define mi_report_crashed(A, B) _mi_report_crashed((A), (B), __FILE__, __LINE__) 411 #define mi_mark_crashed(x) \ 412 do { \ 413 (x)->s->state.changed |= STATE_CRASHED; \ 414 DBUG_PRINT("error", ("Marked table crashed")); \ 415 mi_report_crashed((x), 0); \ 416 } while (0) 417 #define mi_mark_crashed_on_repair(x) \ 418 do { \ 419 (x)->s->state.changed |= STATE_CRASHED | STATE_CRASHED_ON_REPAIR; \ 420 (x)->update |= HA_STATE_CHANGED; \ 421 DBUG_PRINT("error", ("Marked table crashed")); \ 422 } while (0) 423 #define mi_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED) 424 #define mi_is_crashed_on_repair(x) \ 425 ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR) 426 #define mi_print_error(SHARE, ERRNO) \ 427 mi_report_error((ERRNO), (SHARE)->index_file_name) 428 429 /* Functions to store length of space packed keys, VARCHAR or BLOB keys */ 430 431 #define store_key_length(key, length) \ 432 { \ 433 if ((length) < 255) { \ 434 *(key) = (length); \ 435 } else { \ 436 *(key) = 255; \ 437 mi_int2store((key) + 1, (length)); \ 438 } \ 439 } 440 441 #define get_key_full_length(length, key) \ 442 { \ 443 if ((uchar) * (key) != 255) \ 444 length = ((uint)(uchar) * ((key)++)) + 1; \ 445 else { \ 446 length = mi_uint2korr((key) + 1) + 3; \ 447 (key) += 3; \ 448 } \ 449 } 450 451 #define get_key_full_length_rdonly(length, key) \ 452 { \ 453 if ((uchar) * (key) != 255) \ 454 length = ((uint)(uchar) * ((key))) + 1; \ 455 else { \ 456 length = mi_uint2korr((key) + 1) + 3; \ 457 } \ 458 } 459 460 #define get_pack_length(length) ((length) >= 255 ? 3 : 1) 461 462 #define MI_MIN_BLOCK_LENGTH 20U /* Because of delete-link */ 463 #define MI_EXTEND_BLOCK_LENGTH 20 /* Don't use to small record-blocks */ 464 #define MI_SPLIT_LENGTH ((MI_EXTEND_BLOCK_LENGTH + 4) * 2) 465 #define MI_MAX_DYN_BLOCK_HEADER 20 /* Max prefix of record-block */ 466 #define MI_BLOCK_INFO_HEADER_LENGTH 20 467 #define MI_DYN_DELETE_BLOCK_HEADER 20 /* length of delete-block-header */ 468 #define MI_DYN_MAX_BLOCK_LENGTH ((1L << 24) - 4L) 469 #define MI_DYN_MAX_ROW_LENGTH (MI_DYN_MAX_BLOCK_LENGTH - MI_SPLIT_LENGTH) 470 #define MI_DYN_ALIGN_SIZE 4 /* Align blocks on this */ 471 #define MI_MAX_DYN_HEADER_BYTE 13 /* max header byte for dynamic rows */ 472 #define MI_MAX_BLOCK_LENGTH \ 473 ((((ulong)1 << 24) - 1) & (~(ulong)(MI_DYN_ALIGN_SIZE - 1))) 474 #define MI_REC_BUFF_OFFSET \ 475 ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER + sizeof(uint32)) 476 477 #define PACK_TYPE_SELECTED 1 /* Bits in field->pack_type */ 478 #define PACK_TYPE_SPACE_FIELDS 2 479 #define PACK_TYPE_ZERO_FILL 4 480 #define MI_FOUND_WRONG_KEY 32738 /* Impossible value from ha_key_cmp */ 481 482 #define MI_MAX_KEY_BLOCK_SIZE \ 483 (MI_MAX_KEY_BLOCK_LENGTH / MI_MIN_KEY_BLOCK_LENGTH) 484 #define MI_BLOCK_SIZE(key_length, data_pointer, key_pointer, block_size) \ 485 (((((key_length) + (data_pointer) + (key_pointer)) * 4 + (key_pointer) + \ 486 2) / \ 487 (block_size) + \ 488 1) * \ 489 (block_size)) 490 #define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */ 491 #define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */ 492 493 #define MI_MIN_SIZE_BULK_INSERT_TREE 16384 /* this is per key */ 494 #define MI_MIN_ROWS_TO_USE_BULK_INSERT 100 495 #define MI_MIN_ROWS_TO_DISABLE_INDEXES 100 496 #define MI_MIN_ROWS_TO_USE_WRITE_CACHE 10 497 498 /* The UNIQUE check is done with a hashed long key */ 499 500 #define MI_UNIQUE_HASH_TYPE HA_KEYTYPE_ULONG_INT 501 #define mi_unique_store(A, B) mi_int4store((A), (B)) 502 503 extern mysql_mutex_t THR_LOCK_myisam; 504 505 #ifdef __cplusplus 506 extern "C" { 507 #endif 508 509 /* Some extern variables */ 510 511 extern LIST *myisam_open_list; 512 extern uchar myisam_file_magic[], myisam_pack_file_magic[]; 513 extern uint myisam_read_vec[], myisam_readnext_vec[]; 514 extern uint myisam_quick_table_bits; 515 extern File myisam_log_file; 516 extern ulong myisam_pid; 517 518 /* This is used by _mi_calc_xxx_key_length och _mi_store_key */ 519 520 struct MI_KEY_PARAM { 521 uint ref_length, key_length, n_ref_length, n_length, totlength, 522 part_of_prev_key, prev_length, pack_marker; 523 const uchar *key; 524 uchar *prev_key, *next_key_pos; 525 bool store_not_null; 526 }; 527 528 /* Prototypes for intern functions */ 529 530 extern int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, uchar *buf); 531 extern int _mi_write_dynamic_record(MI_INFO *, const uchar *); 532 extern int _mi_update_dynamic_record(MI_INFO *, my_off_t, const uchar *); 533 extern int _mi_delete_dynamic_record(MI_INFO *info); 534 extern int _mi_cmp_dynamic_record(MI_INFO *info, const uchar *record); 535 extern int _mi_read_rnd_dynamic_record(MI_INFO *, uchar *, my_off_t, bool); 536 extern int _mi_write_blob_record(MI_INFO *, const uchar *); 537 extern int _mi_update_blob_record(MI_INFO *, my_off_t, const uchar *); 538 extern int _mi_read_static_record(MI_INFO *info, my_off_t filepos, uchar *buf); 539 extern int _mi_write_static_record(MI_INFO *, const uchar *); 540 extern int _mi_update_static_record(MI_INFO *, my_off_t, const uchar *); 541 extern int _mi_delete_static_record(MI_INFO *info); 542 extern int _mi_cmp_static_record(MI_INFO *info, const uchar *record); 543 extern int _mi_read_rnd_static_record(MI_INFO *, uchar *, my_off_t, bool); 544 extern int _mi_ck_write(MI_INFO *info, uint keynr, uchar *key, uint length); 545 extern int _mi_ck_real_write_btree(MI_INFO *info, MI_KEYDEF *keyinfo, 546 uchar *key, uint key_length, my_off_t *root, 547 uint comp_flag); 548 extern int _mi_enlarge_root(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, 549 my_off_t *root); 550 extern int _mi_insert(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, 551 uchar *anc_buff, uchar *key_pos, uchar *key_buff, 552 uchar *father_buff, uchar *father_keypos, 553 my_off_t father_page, bool insert_last); 554 extern int _mi_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, 555 uchar *buff, uchar *key_buff, bool insert_last); 556 extern uchar *_mi_find_half_pos(uint nod_flag, MI_KEYDEF *keyinfo, uchar *page, 557 uchar *key, uint *return_key_length, 558 uchar **after_key); 559 extern int _mi_calc_static_key_length(MI_KEYDEF *keyinfo, uint nod_flag, 560 const uchar *key_pos, uchar *org_key, 561 uchar *key_buff, const uchar *key, 562 MI_KEY_PARAM *s_temp); 563 extern int _mi_calc_var_key_length(MI_KEYDEF *keyinfo, uint nod_flag, 564 const uchar *key_pos, uchar *org_key, 565 uchar *key_buff, const uchar *key, 566 MI_KEY_PARAM *s_temp); 567 extern int _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo, uint nod_flag, 568 const uchar *key_pos, uchar *org_key, 569 uchar *prev_key, const uchar *key, 570 MI_KEY_PARAM *s_temp); 571 extern int _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo, uint nod_flag, 572 const uchar *key_pos, uchar *org_key, 573 uchar *prev_key, const uchar *key, 574 MI_KEY_PARAM *s_temp); 575 void _mi_store_static_key(MI_KEYDEF *keyinfo, uchar *key_pos, 576 MI_KEY_PARAM *s_temp); 577 void _mi_store_var_pack_key(MI_KEYDEF *keyinfo, uchar *key_pos, 578 MI_KEY_PARAM *s_temp); 579 void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo, uchar *key_pos, 580 MI_KEY_PARAM *s_temp); 581 582 extern int _mi_ck_delete(MI_INFO *info, uint keynr, uchar *key, 583 uint key_length); 584 extern int _mi_readinfo(MI_INFO *info, int lock_flag, int check_keybuffer); 585 extern int _mi_writeinfo(MI_INFO *info, uint options); 586 extern int _mi_test_if_changed(MI_INFO *info); 587 extern int _mi_mark_file_changed(MI_INFO *info); 588 extern int _mi_decrement_open_count(MI_INFO *info); 589 extern int _mi_check_index(MI_INFO *info, int inx); 590 extern int _mi_search(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, 591 uint key_len, uint nextflag, my_off_t pos); 592 extern int _mi_bin_search(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, 593 uchar *key, uint key_len, uint comp_flag, 594 uchar **ret_pos, uchar *buff, bool *was_last_key); 595 extern int _mi_seq_search(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, 596 uchar *key, uint key_len, uint comp_flag, 597 uchar **ret_pos, uchar *buff, bool *was_last_key); 598 extern int _mi_prefix_search(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, 599 uchar *key, uint key_len, uint comp_flag, 600 uchar **ret_pos, uchar *buff, bool *was_last_key); 601 extern my_off_t _mi_kpos(uint nod_flag, uchar *after_key); 602 extern void _mi_kpointer(MI_INFO *info, uchar *buff, my_off_t pos); 603 extern my_off_t _mi_dpos(MI_INFO *info, uint nod_flag, const uchar *after_key); 604 extern my_off_t _mi_rec_pos(MYISAM_SHARE *info, uchar *ptr); 605 extern void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos); 606 extern uint _mi_get_static_key(MI_KEYDEF *keyinfo, uint nod_flag, uchar **page, 607 uchar *key); 608 extern uint _mi_get_pack_key(MI_KEYDEF *keyinfo, uint nod_flag, uchar **page, 609 uchar *key); 610 extern uint _mi_get_binary_pack_key(MI_KEYDEF *keyinfo, uint nod_flag, 611 uchar **page_pos, uchar *key); 612 extern uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *keypos, 613 uchar *lastkey, uchar *endpos, 614 uint *return_key_length); 615 extern uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, 616 uchar *key, uchar *keypos, uint *return_key_length); 617 extern uint _mi_keylength(MI_KEYDEF *keyinfo, const uchar *key); 618 extern uint _mi_keylength_part(MI_KEYDEF *keyinfo, const uchar *key, 619 HA_KEYSEG *end); 620 extern uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, const uchar *from); 621 extern int _mi_search_next(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, 622 uint key_length, uint nextflag, my_off_t pos); 623 extern int _mi_search_first(MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos); 624 extern int _mi_search_last(MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos); 625 extern uchar *_mi_fetch_keypage(MI_INFO *info, MI_KEYDEF *keyinfo, 626 my_off_t page, int level, uchar *buff, 627 int return_buffer); 628 extern int _mi_write_keypage(MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t page, 629 int level, uchar *buff); 630 extern int _mi_dispose(MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos, 631 int level); 632 extern my_off_t _mi_new(MI_INFO *info, MI_KEYDEF *keyinfo, int level); 633 extern uint _mi_make_key(MI_INFO *info, uint keynr, uchar *key, 634 const uchar *record, my_off_t filepos); 635 extern uint _mi_pack_key(MI_INFO *info, uint keynr, uchar *key, 636 const uchar *old, key_part_map keypart_map, 637 HA_KEYSEG **last_used_keyseg); 638 extern int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf); 639 extern int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, 640 uint length, int re_read_if_possibly); 641 extern ulonglong retrieve_auto_increment(MI_INFO *info, const uchar *record); 642 643 extern uchar *mi_alloc_rec_buff(MI_INFO *, ulong, uchar **); 644 #define mi_get_rec_buff_ptr(info, buf) \ 645 ((((info)->s->options & HA_OPTION_PACK_RECORD) && (buf)) \ 646 ? (buf)-MI_REC_BUFF_OFFSET \ 647 : (buf)) 648 #define mi_get_rec_buff_len(info, buf) \ 649 (*((uint32 *)(mi_get_rec_buff_ptr(info, buf)))) 650 651 extern ulong _mi_rec_unpack(MI_INFO *info, uchar *to, const uchar *from, 652 ulong reclength); 653 extern bool _mi_rec_check(MI_INFO *info, const uchar *record, uchar *packpos, 654 ulong packed_length, bool with_checkum); 655 extern int _mi_write_part_record(MI_INFO *info, my_off_t filepos, ulong length, 656 my_off_t next_filepos, uchar **record, 657 ulong *reclength, int *flag); 658 extern void _mi_print_key(FILE *stream, HA_KEYSEG *keyseg, const uchar *key, 659 uint length); 660 extern bool _mi_read_pack_info(MI_INFO *info, bool fix_keys); 661 extern int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, uchar *buf); 662 extern int _mi_read_rnd_pack_record(MI_INFO *, uchar *, my_off_t, bool); 663 extern int _mi_pack_rec_unpack(MI_INFO *info, MI_BIT_BUFF *bit_buff, uchar *to, 664 uchar *from, ulong reclength); 665 extern ulonglong mi_safe_mul(ulonglong a, ulonglong b); 666 extern int _mi_ft_update(MI_INFO *info, uint keynr, uchar *keybuf, 667 const uchar *oldrec, const uchar *newrec, 668 my_off_t pos); 669 670 #ifdef __cplusplus 671 } 672 #endif 673 674 struct MI_BLOCK_INFO { /* Parameter to _mi_get_block_info */ 675 uchar header[MI_BLOCK_INFO_HEADER_LENGTH]; 676 ulong rec_len; 677 ulong data_len; 678 ulong block_len; 679 ulong blob_len; 680 my_off_t filepos; 681 my_off_t next_filepos; 682 my_off_t prev_filepos; 683 uint second_read; 684 uint offset; 685 }; 686 687 /* bits in return from _mi_get_block_info */ 688 689 #define BLOCK_FIRST 1 690 #define BLOCK_LAST 2 691 #define BLOCK_DELETED 4 692 #define BLOCK_ERROR 8 /* Wrong data */ 693 #define BLOCK_SYNC_ERROR 16 /* Right data at wrong place */ 694 #define BLOCK_FATAL_ERROR 32 /* hardware-error */ 695 696 #define NEED_MEM ((uint)10 * 4 * (IO_SIZE + 32) + 32) /* Nead for recursion */ 697 #define MAXERR 20 698 #define BUFFERS_WHEN_SORTING 16 /* Alloc for sort-key-tree */ 699 #define MY_HOW_OFTEN_TO_WRITE 1000 /* How often we want info on screen */ 700 #define WRITE_COUNT MY_HOW_OFTEN_TO_WRITE 701 #define INDEX_TMP_EXT ".TMM" 702 #define DATA_TMP_EXT ".TMD" 703 704 #define UPDATE_TIME 1 705 #define UPDATE_STAT 2 706 #define UPDATE_SORT 4 707 #define UPDATE_AUTO_INC 8 708 #define UPDATE_OPEN_COUNT 16 709 710 #define USE_BUFFER_INIT (((1024L * 512L - MALLOC_OVERHEAD) / IO_SIZE) * IO_SIZE) 711 #define READ_BUFFER_INIT (1024L * 256L - MALLOC_OVERHEAD) 712 #define SORT_BUFFER_INIT (2048L * 1024L - MALLOC_OVERHEAD) 713 #define MIN_SORT_BUFFER (4096ULL - MALLOC_OVERHEAD) 714 715 enum myisam_log_commands { 716 MI_LOG_OPEN, 717 MI_LOG_WRITE, 718 MI_LOG_UPDATE, 719 MI_LOG_DELETE, 720 MI_LOG_CLOSE, 721 MI_LOG_EXTRA, 722 MI_LOG_LOCK, 723 MI_LOG_DELETE_ALL 724 }; 725 726 #define myisam_log(a, b, c, d) \ 727 if (myisam_log_file >= 0) _myisam_log(a, b, c, d) 728 #define myisam_log_command(a, b, c, d, e) \ 729 if (myisam_log_file >= 0) _myisam_log_command(a, b, c, d, e) 730 #define myisam_log_record(a, b, c, d, e) \ 731 if (myisam_log_file >= 0) _myisam_log_record(a, b, c, d, e) 732 733 #define fast_mi_writeinfo(INFO) \ 734 if (!(INFO)->s->tot_locks) (void)_mi_writeinfo((INFO), 0) 735 #define fast_mi_readinfo(INFO) \ 736 ((INFO)->lock_type == F_UNLCK) && _mi_readinfo((INFO), F_RDLCK, 1) 737 738 #ifdef __cplusplus 739 extern "C" { 740 #endif 741 742 extern uint _mi_get_block_info(MI_BLOCK_INFO *, File, my_off_t); 743 extern uint _mi_rec_pack(MI_INFO *info, uchar *to, const uchar *from); 744 extern uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff, 745 MI_BLOCK_INFO *info, uchar **rec_buff_p, 746 File file, my_off_t filepos); 747 extern void _mi_store_blob_length(uchar *pos, uint pack_length, uint length); 748 extern void _myisam_log(enum myisam_log_commands command, MI_INFO *info, 749 const uchar *buffert, uint length); 750 extern void _myisam_log_command(enum myisam_log_commands command, MI_INFO *info, 751 const uchar *buffert, uint length, int result); 752 extern void _myisam_log_record(enum myisam_log_commands command, MI_INFO *info, 753 const uchar *record, my_off_t filepos, 754 int result); 755 extern void mi_report_error(int errcode, const char *file_name); 756 extern bool _mi_memmap_file(MI_INFO *info); 757 extern void _mi_unmap_file(MI_INFO *info); 758 extern uint save_pack_length(uint version, uchar *block_buff, ulong length); 759 extern uint read_pack_length(uint version, const uchar *buf, ulong *length); 760 extern uint calc_pack_length(uint version, ulong length); 761 extern size_t mi_mmap_pread(MI_INFO *info, uchar *Buffer, size_t Count, 762 my_off_t offset, myf MyFlags); 763 extern size_t mi_mmap_pwrite(MI_INFO *info, const uchar *Buffer, size_t Count, 764 my_off_t offset, myf MyFlags); 765 extern size_t mi_nommap_pread(MI_INFO *info, uchar *Buffer, size_t Count, 766 my_off_t offset, myf MyFlags); 767 extern size_t mi_nommap_pwrite(MI_INFO *info, const uchar *Buffer, size_t Count, 768 my_off_t offset, myf MyFlags); 769 770 uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite); 771 uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state); 772 uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, bool pRead); 773 uint mi_base_info_write(File file, MI_BASE_INFO *base); 774 uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base); 775 int mi_keyseg_write(File file, const HA_KEYSEG *keyseg); 776 uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg); 777 uint mi_keydef_write(File file, MI_KEYDEF *keydef); 778 uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef); 779 uint mi_uniquedef_write(File file, MI_UNIQUEDEF *keydef); 780 uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *keydef); 781 uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo); 782 uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo); 783 extern int mi_disable_indexes(MI_INFO *info); 784 extern int mi_enable_indexes(MI_INFO *info); 785 extern int mi_indexes_are_disabled(MI_INFO *info); 786 ulong _my_calc_total_blob_length(MI_INFO *info, const uchar *record); 787 ha_checksum mi_checksum(MI_INFO *info, const uchar *buf); 788 ha_checksum mi_static_checksum(MI_INFO *info, const uchar *buf); 789 bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, uchar *record, 790 ha_checksum unique_hash, my_off_t pos); 791 ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const uchar *buf); 792 int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def, const uchar *record, 793 my_off_t pos); 794 int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def, 795 const uchar *record, my_off_t pos); 796 int mi_unique_comp(MI_UNIQUEDEF *def, const uchar *a, const uchar *b, 797 bool null_are_equal); 798 void mi_get_status(void *param, int concurrent_insert); 799 void mi_update_status(void *param); 800 void mi_restore_status(void *param); 801 void mi_copy_status(void *to, void *from); 802 bool mi_check_status(void *param); 803 804 extern MI_INFO *test_if_reopen(char *filename); 805 bool check_table_is_closed(const char *name, const char *where); 806 int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *orn_name, 807 File file_to_dup); 808 809 int mi_open_keyfile(MYISAM_SHARE *share); 810 void mi_setup_functions(MYISAM_SHARE *share); 811 bool mi_dynmap_file(MI_INFO *info, my_off_t size); 812 int mi_munmap_file(MI_INFO *info); 813 void mi_remap_file(MI_INFO *info, my_off_t size); 814 void _mi_report_crashed(MI_INFO *file, const char *message, const char *sfile, 815 uint sline); 816 817 int mi_check_index_cond(MI_INFO *info, uint keynr, uchar *record); 818 819 /* Functions needed by mi_check */ 820 volatile int *killed_ptr(MI_CHECK *param); 821 void mi_check_print_error(MI_CHECK *param, const char *fmt, ...) 822 MY_ATTRIBUTE((format(printf, 2, 3))); 823 void mi_check_print_warning(MI_CHECK *param, const char *fmt, ...) 824 MY_ATTRIBUTE((format(printf, 2, 3))); 825 void mi_check_print_info(MI_CHECK *param, const char *fmt, ...) 826 MY_ATTRIBUTE((format(printf, 2, 3))); 827 int flush_pending_blocks(MI_SORT_PARAM *param); 828 int sort_ft_buf_flush(MI_SORT_PARAM *sort_param); 829 int thr_write_keys(MI_SORT_PARAM *sort_param); 830 void *thr_find_all_keys(void *arg); 831 int flush_blocks(MI_CHECK *param, KEY_CACHE *key_cache, File file); 832 833 int sort_write_record(MI_SORT_PARAM *sort_param); 834 int _create_index_by_sort(MI_SORT_PARAM *info, bool no_messages, ulonglong); 835 836 extern void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t func, 837 void *func_arg); 838 839 #ifdef __cplusplus 840 extern thread_local st_keycache_thread_var *keycache_tls; 841 } 842 #endif 843 844 #ifdef HAVE_PSI_INTERFACE 845 extern PSI_mutex_key mi_key_mutex_MYISAM_SHARE_intern_lock, 846 mi_key_mutex_MI_SORT_INFO_mutex, mi_key_mutex_MI_CHECK_print_msg; 847 848 extern PSI_rwlock_key mi_key_rwlock_MYISAM_SHARE_key_root_lock, 849 mi_key_rwlock_MYISAM_SHARE_mmap_lock; 850 851 extern PSI_cond_key mi_key_cond_MI_SORT_INFO_cond, 852 mi_keycache_thread_var_suspend; 853 854 extern PSI_file_key mi_key_file_datatmp, mi_key_file_dfile, mi_key_file_kfile, 855 mi_key_file_log; 856 857 extern PSI_thread_key mi_key_thread_find_all_keys; 858 859 void init_myisam_psi_keys(); 860 #endif /* HAVE_PSI_INTERFACE */ 861 862 extern PSI_memory_key mi_key_memory_MYISAM_SHARE; 863 extern PSI_memory_key mi_key_memory_MI_INFO; 864 extern PSI_memory_key mi_key_memory_MI_INFO_ft1_to_ft2; 865 extern PSI_memory_key mi_key_memory_MI_INFO_bulk_insert; 866 extern PSI_memory_key mi_key_memory_record_buffer; 867 extern PSI_memory_key mi_key_memory_FTB; 868 extern PSI_memory_key mi_key_memory_FT_INFO; 869 extern PSI_memory_key mi_key_memory_FTPARSER_PARAM; 870 extern PSI_memory_key mi_key_memory_ft_memroot; 871 extern PSI_memory_key mi_key_memory_ft_stopwords; 872 extern PSI_memory_key mi_key_memory_MI_SORT_PARAM; 873 extern PSI_memory_key mi_key_memory_MI_SORT_PARAM_wordroot; 874 extern PSI_memory_key mi_key_memory_SORT_FT_BUF; 875 extern PSI_memory_key mi_key_memory_SORT_KEY_BLOCKS; 876 extern PSI_memory_key mi_key_memory_filecopy; 877 extern PSI_memory_key mi_key_memory_SORT_INFO_buffer; 878 extern PSI_memory_key mi_key_memory_MI_DECODE_TREE; 879 extern PSI_memory_key mi_key_memory_MYISAM_SHARE_decode_tables; 880 extern PSI_memory_key mi_key_memory_preload_buffer; 881 extern PSI_memory_key mi_key_memory_stPageList_pages; 882 extern PSI_memory_key mi_key_memory_keycache_thread_var; 883 extern PSI_memory_key key_memory_QUEUE; 884 885 #endif // STORAGE_MYISAM_MYISAMDEF_INCLUDED 886