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