MySQL 9.0.0
Source Code Documentation
mi_check.cc File Reference
#include "my_config.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdarg.h>
#include <sys/types.h>
#include <time.h>
#include <algorithm>
#include "my_byteorder.h"
#include "my_compiler.h"
#include "my_dbug.h"
#include "my_double2ulonglong.h"
#include "my_getopt.h"
#include "my_inttypes.h"
#include "my_io.h"
#include "my_macros.h"
#include "my_pointer_arithmetic.h"
#include "mysql/strings/int2str.h"
#include "mysql/strings/m_ctype.h"
#include "storage/myisam/ftdefs.h"
#include "storage/myisam/myisam_sys.h"
#include <sys/mman.h>
#include "storage/myisam/rt_index.h"

Functions

static int check_k_link (MI_CHECK *param, MI_INFO *info, uint nr)
 
static int chk_index (MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t page, uchar *buff, ha_rows *keys, ha_checksum *key_checksum, uint level)
 
static uint isam_key_length (MI_INFO *info, MI_KEYDEF *keyinfo)
 
static ha_checksum calc_checksum (ha_rows count)
 
static int writekeys (MI_SORT_PARAM *sort_param)
 
static int sort_one_index (MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pagepos, File new_file)
 
static int sort_key_read (MI_SORT_PARAM *sort_param, void *key)
 
static int sort_ft_key_read (MI_SORT_PARAM *sort_param, void *key)
 
static int sort_get_next_record (MI_SORT_PARAM *sort_param)
 
static int sort_key_cmp (void *cmp_arg, unsigned char *a, unsigned char *b)
 
static int sort_ft_key_write (MI_SORT_PARAM *sort_param, const void *a)
 
static int sort_key_write (MI_SORT_PARAM *sort_param, const void *a)
 
static my_off_t get_record_for_key (MI_INFO *info, MI_KEYDEF *keyinfo, const uchar *key)
 
static int sort_insert_key (MI_SORT_PARAM *sort_param, SORT_KEY_BLOCKS *key_block, const uchar *key, my_off_t prev_block)
 
static int sort_delete_record (MI_SORT_PARAM *sort_param)
 
static SORT_KEY_BLOCKSalloc_key_blocks (MI_CHECK *param, uint blocks, uint buffer_length)
 
static ha_checksum mi_byte_checksum (const uchar *buf, uint length)
 
static void set_data_file_type (SORT_INFO *sort_info, MYISAM_SHARE *share)
 
static HA_KEYSEGha_find_null (HA_KEYSEG *keyseg, const uchar *a)
 
void myisamchk_init (MI_CHECK *param)
 
int chk_status (MI_CHECK *param, MI_INFO *info)
 
int chk_del (MI_CHECK *param, MI_INFO *info, uint test_flag)
 
int chk_size (MI_CHECK *param, MI_INFO *info)
 
int chk_key (MI_CHECK *param, MI_INFO *info)
 
static int chk_index_down (MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t page, uchar *buff, ha_rows *keys, ha_checksum *key_checksum, uint level)
 
static void mi_collect_stats_nonulls_first (HA_KEYSEG *keyseg, ulonglong *notnull, const uchar *key)
 
static int mi_collect_stats_nonulls_next (HA_KEYSEG *keyseg, ulonglong *notnull, uchar *prev_key, const uchar *last_key)
 
int chk_data_link (MI_CHECK *param, MI_INFO *info, int extend)
 
static int mi_drop_all_indexes (MI_CHECK *param, MI_INFO *info, bool force)
 Drop all indexes. More...
 
int mi_repair (MI_CHECK *param, MI_INFO *info, char *name, int rep_quick, bool no_copy_stat)
 
int movepoint (MI_INFO *info, uchar *record, my_off_t oldpos, my_off_t newpos, uint prot_key)
 
int flush_blocks (MI_CHECK *param, KEY_CACHE *key_cache, File file)
 
int mi_sort_index (MI_CHECK *param, MI_INFO *info, char *name, bool no_copy_stat)
 
int change_to_newfile (const char *filename, const char *old_ext, const char *new_ext, myf MyFlags)
 
int lock_file (MI_CHECK *param, File file, int lock_type, const char *filetype, const char *filename)
 
int filecopy (MI_CHECK *param, File to, File from, my_off_t start, my_off_t length, const char *type)
 
int mi_repair_by_sort (MI_CHECK *param, MI_INFO *info, const char *name, int rep_quick, bool no_copy_stat)
 
int sort_write_record (MI_SORT_PARAM *sort_param)
 
int sort_ft_buf_flush (MI_SORT_PARAM *sort_param)
 
int flush_pending_blocks (MI_SORT_PARAM *sort_param)
 
int test_if_almost_full (MI_INFO *info)
 
int recreate_table (MI_CHECK *param, MI_INFO **org_info, char *filename)
 
int write_data_suffix (SORT_INFO *sort_info, bool fix_datafile)
 
int update_state_info (MI_CHECK *param, MI_INFO *info, uint update)
 
void update_auto_increment_key (MI_CHECK *param, MI_INFO *info, bool repair_only)
 
void update_key_parts (MI_KEYDEF *keyinfo, ulong *rec_per_key_part, ulonglong *unique, ulonglong *notnull, ulonglong records)
 
static bool mi_too_big_key_for_sort (MI_KEYDEF *key, ha_rows rows)
 
void mi_disable_non_unique_index (MI_INFO *info, ha_rows rows)
 
bool mi_test_if_sort_rep (MI_INFO *info, ha_rows rows, ulonglong key_map, bool force)
 

Function Documentation

◆ alloc_key_blocks()

static SORT_KEY_BLOCKS * alloc_key_blocks ( MI_CHECK param,
uint  blocks,
uint  buffer_length 
)
static

◆ calc_checksum()

static ha_checksum calc_checksum ( ha_rows  count)
static

◆ change_to_newfile()

int change_to_newfile ( const char *  filename,
const char *  old_ext,
const char *  new_ext,
myf  MyFlags 
)

◆ check_k_link()

static int check_k_link ( MI_CHECK param,
MI_INFO info,
uint  nr 
)
static

◆ chk_data_link()

int chk_data_link ( MI_CHECK param,
MI_INFO info,
int  extend 
)

◆ chk_del()

int chk_del ( MI_CHECK param,
MI_INFO info,
uint  test_flag 
)

◆ chk_index()

static int chk_index ( MI_CHECK param,
MI_INFO info,
MI_KEYDEF keyinfo,
my_off_t  page,
uchar buff,
ha_rows keys,
ha_checksum key_checksum,
uint  level 
)
static

◆ chk_index_down()

static int chk_index_down ( MI_CHECK param,
MI_INFO info,
MI_KEYDEF keyinfo,
my_off_t  page,
uchar buff,
ha_rows keys,
ha_checksum key_checksum,
uint  level 
)
static

◆ chk_key()

int chk_key ( MI_CHECK param,
MI_INFO info 
)

◆ chk_size()

int chk_size ( MI_CHECK param,
MI_INFO info 
)

◆ chk_status()

int chk_status ( MI_CHECK param,
MI_INFO info 
)

◆ filecopy()

int filecopy ( MI_CHECK param,
File  to,
File  from,
my_off_t  start,
my_off_t  length,
const char *  type 
)

◆ flush_blocks()

int flush_blocks ( MI_CHECK param,
KEY_CACHE key_cache,
File  file 
)

◆ flush_pending_blocks()

int flush_pending_blocks ( MI_SORT_PARAM sort_param)

◆ get_record_for_key()

static my_off_t get_record_for_key ( MI_INFO info,
MI_KEYDEF keyinfo,
const uchar key 
)
static

◆ ha_find_null()

static HA_KEYSEG * ha_find_null ( HA_KEYSEG keyseg,
const uchar a 
)
static

◆ isam_key_length()

static uint isam_key_length ( MI_INFO info,
MI_KEYDEF keyinfo 
)
static

◆ lock_file()

int lock_file ( MI_CHECK param,
File  file,
int  lock_type,
const char *  filetype,
const char *  filename 
)

◆ mi_byte_checksum()

static ha_checksum mi_byte_checksum ( const uchar buf,
uint  length 
)
static

◆ mi_collect_stats_nonulls_first()

static void mi_collect_stats_nonulls_first ( HA_KEYSEG keyseg,
ulonglong notnull,
const uchar key 
)
static

◆ mi_collect_stats_nonulls_next()

static int mi_collect_stats_nonulls_next ( HA_KEYSEG keyseg,
ulonglong notnull,
uchar prev_key,
const uchar last_key 
)
static

◆ mi_disable_non_unique_index()

void mi_disable_non_unique_index ( MI_INFO info,
ha_rows  rows 
)

◆ mi_drop_all_indexes()

static int mi_drop_all_indexes ( MI_CHECK param,
MI_INFO info,
bool  force 
)
static

Drop all indexes.

Parameters
[in]paramcheck parameters
[in]infoMI_INFO handle
[in]forceif to force drop all indexes
Returns
status
Return values
0OK
!=0 Error
Note
Once allocated, index blocks remain part of the key file forever. When indexes are disabled, no block is freed. When enabling indexes, no block is freed either. The new indexes are create from new blocks. (Bug #4692)

Before recreating formerly disabled indexes, the unused blocks must be freed. There are two options to do this:

  • Follow the tree of disabled indexes, add all blocks to the deleted blocks chain. Would require a lot of random I/O.
  • Drop all blocks by clearing all index root pointers and all delete chain pointers and resetting key_file_length to the end of the index file header. This requires to recreate all indexes, even those that may still be intact. The second method is probably faster in most cases.

When disabling indexes, MySQL disables either all indexes or all non-unique indexes. When MySQL [re-]enables disabled indexes (T_CREATE_MISSING_KEYS), then we either have "lost" blocks in the index file, or there are no non-unique indexes. In the latter case, mi_repair*() would not be called as there would be no disabled indexes.

If there would be more unique indexes than disabled (non-unique) indexes, we could do the first method. But this is not implemented yet. By now we drop and recreate all indexes when repair is called.

However, there is an exception. Sometimes MySQL disables non-unique indexes when the table is empty (e.g. when copying a table in mysql_alter_table()). When enabling the non-unique indexes, they are still empty. So there is no index block that can be lost. This optimization is implemented in this function.

Note that in normal repair (T_CREATE_MISSING_KEYS not set) we recreate all enabled indexes unconditonally. We do not change the key_map. Otherwise we invert the key map temporarily (outside of this function) and recreate the then "seemingly" enabled indexes. When we cannot use the optimization, and drop all indexes, we pretend that all indexes were disabled. By the inversion, we will then recrate all indexes.

◆ mi_repair()

int mi_repair ( MI_CHECK param,
MI_INFO info,
char *  name,
int  rep_quick,
bool  no_copy_stat 
)

◆ mi_repair_by_sort()

int mi_repair_by_sort ( MI_CHECK param,
MI_INFO info,
const char *  name,
int  rep_quick,
bool  no_copy_stat 
)

◆ mi_sort_index()

int mi_sort_index ( MI_CHECK param,
MI_INFO info,
char *  name,
bool  no_copy_stat 
)

◆ mi_test_if_sort_rep()

bool mi_test_if_sort_rep ( MI_INFO info,
ha_rows  rows,
ulonglong  key_map,
bool  force 
)

◆ mi_too_big_key_for_sort()

static bool mi_too_big_key_for_sort ( MI_KEYDEF key,
ha_rows  rows 
)
static

◆ movepoint()

int movepoint ( MI_INFO info,
uchar record,
my_off_t  oldpos,
my_off_t  newpos,
uint  prot_key 
)

◆ myisamchk_init()

void myisamchk_init ( MI_CHECK param)

◆ recreate_table()

int recreate_table ( MI_CHECK param,
MI_INFO **  org_info,
char *  filename 
)

◆ set_data_file_type()

static void set_data_file_type ( SORT_INFO sort_info,
MYISAM_SHARE share 
)
static

◆ sort_delete_record()

static int sort_delete_record ( MI_SORT_PARAM sort_param)
static

◆ sort_ft_buf_flush()

int sort_ft_buf_flush ( MI_SORT_PARAM sort_param)

◆ sort_ft_key_read()

static int sort_ft_key_read ( MI_SORT_PARAM sort_param,
void *  key 
)
static

◆ sort_ft_key_write()

static int sort_ft_key_write ( MI_SORT_PARAM sort_param,
const void *  a 
)
static

◆ sort_get_next_record()

static int sort_get_next_record ( MI_SORT_PARAM sort_param)
static

◆ sort_insert_key()

static int sort_insert_key ( MI_SORT_PARAM sort_param,
SORT_KEY_BLOCKS key_block,
const uchar key,
my_off_t  prev_block 
)
static

◆ sort_key_cmp()

static int sort_key_cmp ( void *  cmp_arg,
unsigned char *  a,
unsigned char *  b 
)
static

◆ sort_key_read()

static int sort_key_read ( MI_SORT_PARAM sort_param,
void *  key 
)
static

◆ sort_key_write()

static int sort_key_write ( MI_SORT_PARAM sort_param,
const void *  a 
)
static

◆ sort_one_index()

static int sort_one_index ( MI_CHECK param,
MI_INFO info,
MI_KEYDEF keyinfo,
my_off_t  pagepos,
File  new_file 
)
static

◆ sort_write_record()

int sort_write_record ( MI_SORT_PARAM sort_param)

◆ test_if_almost_full()

int test_if_almost_full ( MI_INFO info)

◆ update_auto_increment_key()

void update_auto_increment_key ( MI_CHECK param,
MI_INFO info,
bool  repair_only 
)

◆ update_key_parts()

void update_key_parts ( MI_KEYDEF keyinfo,
ulong *  rec_per_key_part,
ulonglong unique,
ulonglong notnull,
ulonglong  records 
)

◆ update_state_info()

int update_state_info ( MI_CHECK param,
MI_INFO info,
uint  update 
)

◆ write_data_suffix()

int write_data_suffix ( SORT_INFO sort_info,
bool  fix_datafile 
)

◆ writekeys()

static int writekeys ( MI_SORT_PARAM sort_param)
static