1 /* 2 Copyright (c) 2000, 2016, 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 should be included when using myisam_funktions */ 25 26 #ifndef _myisam_h 27 #define _myisam_h 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #ifndef _my_base_h 33 #include <my_base.h> 34 #endif 35 #ifndef _m_ctype_h 36 #include <m_ctype.h> 37 #endif 38 #ifndef _keycache_h 39 #include "keycache.h" 40 #endif 41 #include "my_compare.h" 42 #include <mysql/plugin.h> 43 #include <my_check_opt.h> 44 /* 45 Limit max keys according to HA_MAX_POSSIBLE_KEY 46 */ 47 48 #if MAX_INDEXES > HA_MAX_POSSIBLE_KEY 49 #define MI_MAX_KEY HA_MAX_POSSIBLE_KEY /* Max allowed keys */ 50 #else 51 #define MI_MAX_KEY MAX_INDEXES /* Max allowed keys */ 52 #endif 53 54 #define MI_MAX_POSSIBLE_KEY_BUFF HA_MAX_POSSIBLE_KEY_BUFF 55 /* 56 The following defines can be increased if necessary. 57 But beware the dependency of MI_MAX_POSSIBLE_KEY_BUFF and MI_MAX_KEY_LENGTH. 58 */ 59 #define MI_MAX_KEY_LENGTH 4000 /* Max length in bytes */ 60 #define MI_MAX_KEY_SEG 16 /* Max segments for key */ 61 62 #define MI_MAX_KEY_BUFF (MI_MAX_KEY_LENGTH+MI_MAX_KEY_SEG*6+8+8) 63 #define MI_MAX_MSG_BUF 1024 /* used in CHECK TABLE, REPAIR TABLE */ 64 #define MI_NAME_IEXT ".MYI" 65 #define MI_NAME_DEXT ".MYD" 66 67 /* Possible values for myisam_block_size (must be power of 2) */ 68 #define MI_KEY_BLOCK_LENGTH 1024 /* default key block length */ 69 #define MI_MIN_KEY_BLOCK_LENGTH 1024 /* Min key block length */ 70 #define MI_MAX_KEY_BLOCK_LENGTH 16384 71 72 /* 73 In the following macros '_keyno_' is 0 .. keys-1. 74 If there can be more keys than bits in the key_map, the highest bit 75 is for all upper keys. They cannot be switched individually. 76 This means that clearing of high keys is ignored, setting one high key 77 sets all high keys. 78 */ 79 #define MI_KEYMAP_BITS (8 * SIZEOF_LONG_LONG) 80 #define MI_KEYMAP_HIGH_MASK (ULL(1) << (MI_KEYMAP_BITS - 1)) 81 #define mi_get_mask_all_keys_active(_keys_) \ 82 (((_keys_) < MI_KEYMAP_BITS) ? \ 83 ((ULL(1) << (_keys_)) - ULL(1)) : \ 84 (~ ULL(0))) 85 86 #if MI_MAX_KEY > MI_KEYMAP_BITS 87 88 #define mi_is_key_active(_keymap_,_keyno_) \ 89 (((_keyno_) < MI_KEYMAP_BITS) ? \ 90 MY_TEST((_keymap_) & (ULL(1) << (_keyno_))) : \ 91 MY_TEST((_keymap_) & MI_KEYMAP_HIGH_MASK)) 92 #define mi_set_key_active(_keymap_,_keyno_) \ 93 (_keymap_)|= (((_keyno_) < MI_KEYMAP_BITS) ? \ 94 (ULL(1) << (_keyno_)) : \ 95 MI_KEYMAP_HIGH_MASK) 96 #define mi_clear_key_active(_keymap_,_keyno_) \ 97 (_keymap_)&= (((_keyno_) < MI_KEYMAP_BITS) ? \ 98 (~ (ULL(1) << (_keyno_))) : \ 99 (~ (ULL(0))) /*ignore*/ ) 100 101 #else 102 103 #define mi_is_key_active(_keymap_,_keyno_) \ 104 MY_TEST((_keymap_) & (ULL(1) << (_keyno_))) 105 #define mi_set_key_active(_keymap_,_keyno_) \ 106 (_keymap_)|= (ULL(1) << (_keyno_)) 107 #define mi_clear_key_active(_keymap_,_keyno_) \ 108 (_keymap_)&= (~ (ULL(1) << (_keyno_))) 109 110 #endif 111 112 #define mi_is_any_key_active(_keymap_) \ 113 MY_TEST((_keymap_)) 114 #define mi_is_all_keys_active(_keymap_,_keys_) \ 115 ((_keymap_) == mi_get_mask_all_keys_active(_keys_)) 116 #define mi_set_all_keys_active(_keymap_,_keys_) \ 117 (_keymap_)= mi_get_mask_all_keys_active(_keys_) 118 #define mi_clear_all_keys_active(_keymap_) \ 119 (_keymap_)= 0 120 #define mi_intersect_keys_active(_to_,_from_) \ 121 (_to_)&= (_from_) 122 #define mi_is_any_intersect_keys_active(_keymap1_,_keys_,_keymap2_) \ 123 ((_keymap1_) & (_keymap2_) & \ 124 mi_get_mask_all_keys_active(_keys_)) 125 #define mi_copy_keys_active(_to_,_maxkeys_,_from_) \ 126 (_to_)= (mi_get_mask_all_keys_active(_maxkeys_) & \ 127 (_from_)) 128 129 /* Param to/from mi_status */ 130 131 typedef struct st_mi_isaminfo /* Struct from h_info */ 132 { 133 ha_rows records; /* Records in database */ 134 ha_rows deleted; /* Deleted records in database */ 135 my_off_t recpos; /* Pos for last used record */ 136 my_off_t newrecpos; /* Pos if we write new record */ 137 my_off_t dupp_key_pos; /* Position to record with dupp key */ 138 my_off_t data_file_length, /* Length of data file */ 139 max_data_file_length, 140 index_file_length, 141 max_index_file_length, 142 delete_length; 143 ulong reclength; /* Recordlength */ 144 ulong mean_reclength; /* Mean recordlength (if packed) */ 145 ulonglong auto_increment; 146 ulonglong key_map; /* Which keys are used */ 147 char *data_file_name, *index_file_name; 148 uint keys; /* Number of keys in use */ 149 uint options; /* HA_OPTION_... used */ 150 int errkey, /* With key was dupplicated on err */ 151 sortkey; /* clustered by this key */ 152 File filenr; /* (uniq) filenr for datafile */ 153 time_t create_time; /* When table was created */ 154 time_t check_time; 155 time_t update_time; 156 uint reflength; 157 ulong record_offset; 158 ulong *rec_per_key; /* for sql optimizing */ 159 } MI_ISAMINFO; 160 161 162 typedef struct st_mi_create_info 163 { 164 const char *index_file_name, *data_file_name; /* If using symlinks */ 165 ha_rows max_rows; 166 ha_rows reloc_rows; 167 ulonglong auto_increment; 168 ulonglong data_file_length; 169 ulonglong key_file_length; 170 uint old_options; 171 uint16 language; 172 my_bool with_auto_increment; 173 } MI_CREATE_INFO; 174 175 struct st_myisam_info; /* For referense */ 176 struct st_mi_isam_share; 177 typedef struct st_myisam_info MI_INFO; 178 struct st_mi_s_param; 179 180 typedef struct st_mi_keydef /* Key definition with open & info */ 181 { 182 struct st_mi_isam_share *share; /* Pointer to base (set in mi_open) */ 183 uint16 keysegs; /* Number of key-segment */ 184 uint16 flag; /* NOSAME, PACK_USED */ 185 186 uint8 key_alg; /* BTREE, RTREE */ 187 uint16 block_length; /* Length of keyblock (auto) */ 188 uint16 underflow_block_length; /* When to execute underflow */ 189 uint16 keylength; /* Tot length of keyparts (auto) */ 190 uint16 minlength; /* min length of (packed) key (auto) */ 191 uint16 maxlength; /* max length of (packed) key (auto) */ 192 uint16 block_size_index; /* block_size (auto) */ 193 uint32 version; /* For concurrent read/write */ 194 uint32 ftkey_nr; /* full-text index number */ 195 196 HA_KEYSEG *seg,*end; 197 struct st_mysql_ftparser *parser; /* Fulltext [pre]parser */ 198 int (*bin_search)(struct st_myisam_info *info,struct st_mi_keydef *keyinfo, 199 uchar *page,uchar *key, 200 uint key_len,uint comp_flag,uchar * *ret_pos, 201 uchar *buff, my_bool *was_last_key); 202 uint (*get_key)(struct st_mi_keydef *keyinfo,uint nod_flag,uchar * *page, 203 uchar *key); 204 int (*pack_key)(struct st_mi_keydef *keyinfo,uint nod_flag,uchar *next_key, 205 uchar *org_key, uchar *prev_key, uchar *key, 206 struct st_mi_s_param *s_temp); 207 void (*store_key)(struct st_mi_keydef *keyinfo, uchar *key_pos, 208 struct st_mi_s_param *s_temp); 209 int (*ck_insert)(struct st_myisam_info *inf, uint k_nr, uchar *k, uint klen); 210 int (*ck_delete)(struct st_myisam_info *inf, uint k_nr, uchar *k, uint klen); 211 } MI_KEYDEF; 212 213 214 #define MI_UNIQUE_HASH_LENGTH 4 215 216 typedef struct st_unique_def /* Segment definition of unique */ 217 { 218 uint16 keysegs; /* Number of key-segment */ 219 uchar key; /* Mapped to which key */ 220 uint8 null_are_equal; 221 HA_KEYSEG *seg,*end; 222 } MI_UNIQUEDEF; 223 224 typedef struct st_mi_decode_tree /* Decode huff-table */ 225 { 226 uint16 *table; 227 uint quick_table_bits; 228 uchar *intervalls; 229 } MI_DECODE_TREE; 230 231 232 struct st_mi_bit_buff; 233 234 /* 235 Note that null markers should always be first in a row ! 236 When creating a column, one should only specify: 237 type, length, null_bit and null_pos 238 */ 239 240 typedef struct st_columndef /* column information */ 241 { 242 int16 type; /* en_fieldtype */ 243 uint16 length; /* length of field */ 244 uint32 offset; /* Offset to position in row */ 245 uint8 null_bit; /* If column may be 0 */ 246 uint16 null_pos; /* position for null marker */ 247 248 #ifndef NOT_PACKED_DATABASES 249 void (*unpack)(struct st_columndef *rec,struct st_mi_bit_buff *buff, 250 uchar *start,uchar *end); 251 enum en_fieldtype base_type; 252 uint space_length_bits,pack_type; 253 MI_DECODE_TREE *huff_tree; 254 #endif 255 } MI_COLUMNDEF; 256 257 258 extern char * myisam_log_filename; /* Name of logfile */ 259 extern ulong myisam_block_size; 260 extern ulong myisam_concurrent_insert; 261 extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user; 262 extern my_off_t myisam_max_temp_length; 263 extern ulong myisam_data_pointer_size; 264 265 /* usually used to check if a symlink points into the mysql data home */ 266 /* which is normally forbidden */ 267 extern int (*myisam_test_invalid_symlink)(const char *filename); 268 extern ulonglong myisam_mmap_size, myisam_mmap_used; 269 extern mysql_mutex_t THR_LOCK_myisam_mmap; 270 271 /* Prototypes for myisam-functions */ 272 273 extern int mi_close(struct st_myisam_info *file); 274 extern int mi_delete(struct st_myisam_info *file,const uchar *buff); 275 extern struct st_myisam_info *mi_open(const char *name,int mode, 276 uint wait_if_locked); 277 extern int mi_panic(enum ha_panic_function function); 278 extern int mi_rfirst(struct st_myisam_info *file,uchar *buf,int inx); 279 extern int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, 280 key_part_map keypart_map, enum ha_rkey_function search_flag); 281 extern int mi_rlast(struct st_myisam_info *file,uchar *buf,int inx); 282 extern int mi_rnext(struct st_myisam_info *file,uchar *buf,int inx); 283 extern int mi_rnext_same(struct st_myisam_info *info, uchar *buf); 284 extern int mi_rprev(struct st_myisam_info *file,uchar *buf,int inx); 285 extern int mi_rrnd(struct st_myisam_info *file,uchar *buf, my_off_t pos); 286 extern int mi_scan_init(struct st_myisam_info *file); 287 extern int mi_scan(struct st_myisam_info *file,uchar *buf); 288 extern int mi_rsame(struct st_myisam_info *file,uchar *record,int inx); 289 extern int mi_rsame_with_pos(struct st_myisam_info *file,uchar *record, 290 int inx, my_off_t pos); 291 extern int mi_update(struct st_myisam_info *file,const uchar *old, 292 uchar *new_record); 293 extern int mi_write(struct st_myisam_info *file,uchar *buff); 294 extern my_off_t mi_position(struct st_myisam_info *file); 295 extern int mi_status(struct st_myisam_info *info, MI_ISAMINFO *x, uint flag); 296 extern int mi_lock_database(struct st_myisam_info *file,int lock_type); 297 extern int mi_create(const char *name,uint keys,MI_KEYDEF *keydef, 298 uint columns, MI_COLUMNDEF *columndef, 299 uint uniques, MI_UNIQUEDEF *uniquedef, 300 MI_CREATE_INFO *create_info, uint flags); 301 extern int mi_delete_table(const char *name); 302 extern int mi_rename(const char *from, const char *to); 303 extern int mi_extra(struct st_myisam_info *file, 304 enum ha_extra_function function, 305 void *extra_arg); 306 extern int mi_reset(struct st_myisam_info *file); 307 extern ha_rows mi_records_in_range(MI_INFO *info, int inx, 308 key_range *min_key, key_range *max_key); 309 extern int mi_log(int activate_log); 310 extern int mi_is_changed(struct st_myisam_info *info); 311 extern int mi_delete_all_rows(struct st_myisam_info *info); 312 extern ulong _mi_calc_blob_length(uint length , const uchar *pos); 313 extern uint mi_get_pointer_length(ulonglong file_length, uint def); 314 315 #define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for mmap file */ 316 /* this is used to pass to mysql_myisamchk_table */ 317 318 #define MYISAMCHK_REPAIR 1 /* equivalent to myisamchk -r */ 319 #define MYISAMCHK_VERIFY 2 /* Verify, run repair if failure */ 320 321 /* 322 Flags used by myisamchk.c or/and ha_myisam.cc that are NOT passed 323 to mi_check.c follows: 324 */ 325 326 #define TT_USEFRM 1 327 #define TT_FOR_UPGRADE 2 328 329 #define O_NEW_INDEX 1 /* Bits set in out_flag */ 330 #define O_NEW_DATA 2 331 #define O_DATA_LOST 4 332 333 /* these struct is used by my_check to tell it what to do */ 334 335 typedef struct st_sort_key_blocks /* Used when sorting */ 336 { 337 uchar *buff,*end_pos; 338 uchar lastkey[MI_MAX_POSSIBLE_KEY_BUFF]; 339 uint last_length; 340 int inited; 341 } SORT_KEY_BLOCKS; 342 343 344 /* 345 MyISAM supports several statistics collection methods. Currently statistics 346 collection method is not stored in MyISAM file and has to be specified for 347 each table analyze/repair operation in MI_CHECK::stats_method. 348 */ 349 350 typedef enum 351 { 352 /* Treat NULLs as inequal when collecting statistics (default for 4.1/5.0) */ 353 MI_STATS_METHOD_NULLS_NOT_EQUAL, 354 /* Treat NULLs as equal when collecting statistics (like 4.0 did) */ 355 MI_STATS_METHOD_NULLS_EQUAL, 356 /* Ignore NULLs - count only tuples without NULLs in the index components */ 357 MI_STATS_METHOD_IGNORE_NULLS 358 } enum_mi_stats_method; 359 360 typedef struct st_mi_check_param 361 { 362 ulonglong auto_increment_value; 363 ulonglong max_data_file_length; 364 ulonglong keys_in_use; 365 ulonglong max_record_length; 366 ulonglong sort_buffer_length; 367 my_off_t search_after_block; 368 my_off_t new_file_pos,key_file_blocks; 369 my_off_t keydata,totaldata,key_blocks,start_check_pos; 370 ha_rows total_records,total_deleted; 371 ha_checksum record_checksum,glob_crc; 372 ulonglong use_buffers; 373 ulong read_buffer_length, write_buffer_length, sort_key_blocks; 374 uint out_flag,warning_printed,error_printed,verbose; 375 uint opt_sort_key,total_files,max_level; 376 uint testflag, key_cache_block_size; 377 uint16 language; 378 my_bool using_global_keycache, opt_lock_memory, opt_follow_links; 379 my_bool retry_repair, force_sort; 380 char temp_filename[FN_REFLEN],*isam_file_name; 381 MY_TMPDIR *tmpdir; 382 int tmpfile_createflag; 383 myf myf_rw; 384 IO_CACHE read_cache; 385 386 /* 387 The next two are used to collect statistics, see update_key_parts for 388 description. 389 */ 390 ulonglong unique_count[MI_MAX_KEY_SEG+1]; 391 ulonglong notnull_count[MI_MAX_KEY_SEG+1]; 392 393 ha_checksum key_crc[HA_MAX_POSSIBLE_KEY]; 394 ulong rec_per_key_part[MI_MAX_KEY_SEG*HA_MAX_POSSIBLE_KEY]; 395 void *thd; 396 const char *db_name, *table_name; 397 const char *op_name; 398 enum_mi_stats_method stats_method; 399 mysql_mutex_t print_msg_mutex; 400 my_bool need_print_msg_lock; 401 } MI_CHECK; 402 403 typedef struct st_sort_ft_buf 404 { 405 uchar *buf, *end; 406 int count; 407 uchar lastkey[MI_MAX_KEY_BUFF]; 408 } SORT_FT_BUF; 409 410 typedef struct st_sort_info 411 { 412 my_off_t filelength,dupp,buff_length; 413 ha_rows max_records; 414 uint current_key, total_keys; 415 myf myf_rw; 416 enum data_file_type new_data_file_type; 417 MI_INFO *info; 418 MI_CHECK *param; 419 uchar *buff; 420 SORT_KEY_BLOCKS *key_block,*key_block_end; 421 SORT_FT_BUF *ft_buf; 422 /* sync things */ 423 uint got_error, threads_running; 424 mysql_mutex_t mutex; 425 mysql_cond_t cond; 426 } SORT_INFO; 427 428 /* functions in mi_check */ 429 void myisamchk_init(MI_CHECK *param); 430 int chk_status(MI_CHECK *param, MI_INFO *info); 431 int chk_del(MI_CHECK *param, MI_INFO *info, uint test_flag); 432 int chk_size(MI_CHECK *param, MI_INFO *info); 433 int chk_key(MI_CHECK *param, MI_INFO *info); 434 int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend); 435 int mi_repair(MI_CHECK *param, MI_INFO *info, 436 char * name, int rep_quick, my_bool no_copy_stat); 437 int mi_sort_index(MI_CHECK *param, MI_INFO *info, char * name, 438 my_bool no_copy_stat); 439 int mi_repair_by_sort(MI_CHECK *param, MI_INFO *info, 440 const char * name, int rep_quick, my_bool no_copy_stat); 441 int mi_repair_parallel(MI_CHECK *param, MI_INFO *info, 442 const char * name, int rep_quick, my_bool no_copy_stat); 443 int change_to_newfile(const char * filename, const char * old_ext, 444 const char * new_ext, myf myflags); 445 int lock_file(MI_CHECK *param, File file, my_off_t start, int lock_type, 446 const char *filetype, const char *filename); 447 void lock_memory(MI_CHECK *param); 448 void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, 449 my_bool repair); 450 int update_state_info(MI_CHECK *param, MI_INFO *info,uint update); 451 void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part, 452 ulonglong *unique, ulonglong *notnull, 453 ulonglong records); 454 int filecopy(MI_CHECK *param, File to,File from,my_off_t start, 455 my_off_t length, const char *type); 456 int movepoint(MI_INFO *info,uchar *record,my_off_t oldpos, 457 my_off_t newpos, uint prot_key); 458 int write_data_suffix(SORT_INFO *sort_info, my_bool fix_datafile); 459 int test_if_almost_full(MI_INFO *info); 460 int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename); 461 void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); 462 my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map, 463 my_bool force); 464 465 int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows); 466 void mi_flush_bulk_insert(MI_INFO *info, uint inx); 467 void mi_end_bulk_insert(MI_INFO *info); 468 int mi_assign_to_key_cache(MI_INFO *info, ulonglong key_map, 469 KEY_CACHE *key_cache); 470 void mi_change_key_cache(KEY_CACHE *old_key_cache, 471 KEY_CACHE *new_key_cache); 472 int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves); 473 474 #ifdef __cplusplus 475 } 476 #endif 477 #endif 478