Drizzled Public API Documentation

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