This commit is contained in:
Igor Babaev 2010-10-14 15:46:20 -07:00
commit 3c9dcf9da7
15 changed files with 258 additions and 171 deletions

View File

@ -982,7 +982,7 @@ void _db_pop_()
} while (0)
#define str_to_buf(S) do { \
char_to_buf(','); \
buf=strnmov(buf, (S), len+1); \
buf=strnmov(buf, (S), (uint) (end-buf)); \
if (buf >= end) goto overflow; \
} while (0)
#define list_to_buf(l, f) do { \

View File

@ -470,9 +470,10 @@ WHERE table2.f1 = 2
GROUP BY table1.f1, table2.f2
HAVING (table2.f2 = 8 AND table1.f1 >= 6);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables
1 SIMPLE table2 const PRIMARY PRIMARY 4 const 1 100.00 Using filesort
1 SIMPLE table1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having 0
Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having (('7' = 8) and (`test`.`table1`.`f1` >= 6))
EXPLAIN EXTENDED
SELECT table1.f1, table2.f2
FROM t1 AS table1
@ -481,9 +482,10 @@ WHERE table2.f1 = 2
GROUP BY table1.f1, table2.f2
HAVING (table2.f2 = 8);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables
1 SIMPLE table2 const PRIMARY PRIMARY 4 const 1 100.00 Using filesort
1 SIMPLE table1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having 0
Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having ('7' = 8)
DROP TABLE t1;
#
# Bug#52336 Segfault / crash in 5.1 copy_fields (param=0x9872980) at sql_select.cc:15355

View File

@ -807,7 +807,7 @@ bool mysqld_embedded=1;
static my_bool plugins_are_initialized= FALSE;
#ifndef DBUG_OFF
static const char* default_dbug_option;
static const char* default_dbug_option, *current_dbug_option;
#endif
#ifdef HAVE_LIBWRAP
const char *libwrapName= NULL;
@ -6172,8 +6172,8 @@ struct my_option my_long_options[] =
&max_system_variables.wt_timeout_long,
0, GET_ULONG, REQUIRED_ARG, 50000000, 0, ULONG_MAX, 0, 0, 0},
#ifndef DBUG_OFF
{"debug", '#', "Debug log.", &default_dbug_option,
&default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"debug", '#', "Debug log.", &current_dbug_option,
&current_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"debug-crc-break", OPT_DEBUG_CRC,
"Call my_debug_put_break_here() if crc matches this number (for debug).",
&opt_my_crc_dbug_check, &opt_my_crc_dbug_check,
@ -6501,7 +6501,7 @@ each time the SQL thread starts.",
0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
#endif
{"myisam-recover", OPT_MYISAM_RECOVER,
"Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
"Syntax: myisam-recover=OFF or myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
&myisam_recover_options_str, &myisam_recover_options_str, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
@ -8326,6 +8326,7 @@ static int mysql_init_variables(void)
#ifndef DBUG_OFF
default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
"d:t:i:o,/tmp/mysqld.trace");
current_dbug_option= default_dbug_option;
#endif
opt_error_log= IF_WIN(1,0);
#ifdef COMMUNITY_SERVER

View File

@ -48,6 +48,9 @@
"FUNCTION" : "PROCEDURE")
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
static bool execute_show_status(THD *thd, TABLE_LIST *all_tables);
static bool execute_rename_table(THD *thd, TABLE_LIST *first_table,
TABLE_LIST *all_tables);
static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
const char *any_db="*any*"; // Special symbol for check_access
@ -1124,7 +1127,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
uint save_db_length= thd->db_length;
char *save_db= thd->db;
USER_CONN *save_user_connect= thd->user_connect;
Security_context save_security_ctx= *thd->security_ctx;
Security_context save_security_ctx= *thd->security_ctx;
CHARSET_INFO *save_character_set_client=
thd->variables.character_set_client;
CHARSET_INFO *save_collation_connection=
@ -1492,7 +1495,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
case COM_STATISTICS:
{
STATUS_VAR current_global_status_var;
STATUS_VAR *current_global_status_var; // Big; Don't allocate on stack
ulong uptime;
#if defined(SAFEMALLOC) || !defined(EMBEDDED_LIBRARY)
uint length;
@ -1501,9 +1504,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char buff[250];
uint buff_len= sizeof(buff);
if (!(current_global_status_var= (STATUS_VAR*)
thd->alloc(sizeof(STATUS_VAR))))
break;
general_log_print(thd, command, NullS);
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
calc_sum_of_all_status(&current_global_status_var);
calc_sum_of_all_status(current_global_status_var);
if (!(uptime= (ulong) (thd->start_time - server_start_time)))
queries_per_second1000= 0;
else
@ -1518,8 +1524,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
"Open tables: %u Queries per second avg: %u.%u",
uptime,
(int) thread_count, (ulong) thd->query_id,
current_global_status_var.long_query_count,
current_global_status_var.opened_tables,
current_global_status_var->long_query_count,
current_global_status_var->opened_tables,
refresh_version,
cached_open_tables(),
(uint) (queries_per_second1000 / 1000),
@ -2230,22 +2236,7 @@ mysql_execute_command(THD *thd)
break;
case SQLCOM_SHOW_STATUS:
{
system_status_var old_status_var= thd->status_var;
thd->initial_status_var= &old_status_var;
if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
res= execute_sqlcom_select(thd, all_tables);
/* Don't log SHOW STATUS commands to slow query log */
thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
SERVER_QUERY_NO_GOOD_INDEX_USED);
/*
restore status variables, as we don't want 'show status' to cause
changes
*/
pthread_mutex_lock(&LOCK_status);
add_diff_to_status(&global_status_var, &thd->status_var,
&old_status_var);
thd->status_var= old_status_var;
pthread_mutex_unlock(&LOCK_status);
execute_show_status(thd, all_tables);
break;
}
case SQLCOM_SHOW_DATABASES:
@ -2954,31 +2945,7 @@ end_with_restore_list:
}
case SQLCOM_RENAME_TABLE:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
TABLE_LIST *table;
for (table= first_table; table; table= table->next_local->next_local)
{
if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
&table->grant.privilege,0,0, test(table->schema_table)) ||
check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
&table->next_local->grant.privilege, 0, 0,
test(table->next_local->schema_table)))
goto error;
TABLE_LIST old_list, new_list;
/*
we do not need initialize old_list and new_list because we will
come table[0] and table->next[0] there
*/
old_list= table[0];
new_list= table->next_local[0];
if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) ||
(!test_all_bits(table->next_local->grant.privilege,
INSERT_ACL | CREATE_ACL) &&
check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0)))
goto error;
}
if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
if (execute_rename_table(thd, first_table, all_tables))
goto error;
break;
}
@ -5124,6 +5091,62 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
}
static bool execute_show_status(THD *thd, TABLE_LIST *all_tables)
{
bool res;
system_status_var old_status_var= thd->status_var;
thd->initial_status_var= &old_status_var;
if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
res= execute_sqlcom_select(thd, all_tables);
/* Don't log SHOW STATUS commands to slow query log */
thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
SERVER_QUERY_NO_GOOD_INDEX_USED);
/*
restore status variables, as we don't want 'show status' to cause
changes
*/
pthread_mutex_lock(&LOCK_status);
add_diff_to_status(&global_status_var, &thd->status_var,
&old_status_var);
thd->status_var= old_status_var;
pthread_mutex_unlock(&LOCK_status);
return res;
}
static bool execute_rename_table(THD *thd, TABLE_LIST *first_table,
TABLE_LIST *all_tables)
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
TABLE_LIST *table;
for (table= first_table; table; table= table->next_local->next_local)
{
if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
&table->grant.privilege,0,0, test(table->schema_table)) ||
check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
&table->next_local->grant.privilege, 0, 0,
test(table->next_local->schema_table)))
return 1;
TABLE_LIST old_list, new_list;
/*
we do not need initialize old_list and new_list because we will
come table[0] and table->next[0] there
*/
old_list= table[0];
new_list= table->next_local[0];
if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) ||
(!test_all_bits(table->next_local->grant.privilege,
INSERT_ACL | CREATE_ACL) &&
check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0)))
return 1;
}
if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
return 1;
return 0;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/**
Check grants for commands which work only with one table.

View File

@ -1129,29 +1129,6 @@ JOIN::optimize()
conds=new Item_int((longlong) 0,1); // Always false
}
/*
It's necessary to check const part of HAVING cond as there is a
chance that some cond parts may become const items after
make_join_statistics() (for example when Item is a reference to
cost table field from outer join).
This check is performed only for those conditions which do not use
aggregate functions. In such case temporary table may not be used
and const condition elements may be lost during further having
condition transformation in JOIN::exec.
*/
if (having && const_table_map && !having->with_sum_func)
{
having->update_used_tables();
having= remove_eq_conds(thd, having, &having_value);
if (having_value == Item::COND_FALSE)
{
having= new Item_int((longlong) 0,1);
zero_result_cause= "Impossible HAVING noticed after reading const tables";
DBUG_RETURN(0);
}
}
if (make_join_select(this, select, conds))
{
zero_result_cause=

View File

@ -1081,14 +1081,14 @@ int ha_maria::write_row(uchar * buf)
int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
{
if (!file)
return HA_ADMIN_INTERNAL_ERROR;
int error;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MARIA_SHARE *share= file->s;
const char *old_proc_info= thd_proc_info(thd, "Checking table");
TRN *old_trn= file->trn;
if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "check";
@ -1182,9 +1182,12 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
{
int error= 0;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MARIA_SHARE *share= file->s;
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "analyze";
@ -1319,7 +1322,10 @@ int ha_maria::backup(THD * thd, HA_CHECK_OPT *check_opt)
err:
{
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "backup";
@ -1335,10 +1341,10 @@ err:
int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
{
int error;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
ha_rows start_records;
if (!file)
if (!file || !&param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
@ -1390,11 +1396,11 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
{
int error;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
TRN *old_trn;
MARIA_SHARE *share= file->s;
if (!file)
if (!file || !&param)
return HA_ADMIN_INTERNAL_ERROR;
old_trn= file->trn;
@ -1420,9 +1426,9 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt)
{
int error;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!file)
if (!file || !&param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
@ -1661,7 +1667,10 @@ int ha_maria::assign_to_keycache(THD * thd, HA_CHECK_OPT *check_opt)
if (error != HA_ADMIN_OK)
{
/* Send error to user */
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "assign_to_keycache";
@ -1722,7 +1731,10 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt)
errmsg= buf;
}
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "preload_keys";
@ -1830,8 +1842,12 @@ int ha_maria::enable_indexes(uint mode)
else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
{
THD *thd= current_thd;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
const char *save_proc_info= thd_proc_info(thd, "Creating index");
maria_chk_init(&param);
param.op_name= "recreating_index";
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
@ -3314,6 +3330,8 @@ static int ha_maria_init(void *p)
/* We can only test for sub paths if my_symlink.c is using realpath */
maria_test_invalid_symlink= test_if_data_home_dir;
#endif
if (res)
maria_hton= 0;
return res ? HA_ERR_INITIALIZATION : 0;
}

View File

@ -1016,7 +1016,7 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
DBUG_PRINT("enter", ("size: %u", size));
LINT_INIT(best_pos);
DBUG_ASSERT(size <= FULL_PAGE_SIZE(bitmap->block_size));
DBUG_ASSERT(size <= MAX_TAIL_SIZE(bitmap->block_size));
for (; data < end; data += 6)
{
@ -1732,7 +1732,7 @@ my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
row_length= find_where_to_split_row(share, row, extents_length,
max_page_size);
full_page_size= FULL_PAGE_SIZE(share->block_size);
full_page_size= MAX_TAIL_SIZE(share->block_size);
position= 0;
if (head_length - row_length <= full_page_size)
position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */

View File

@ -489,7 +489,10 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
}
if (ret_value == 0 && anc_page->size > share->max_index_block_size)
{
/* parent buffer got too big ; We have to split the page */
/*
parent buffer got too big ; We have to split the page.
The | 2 is there to force write of anc page below
*/
save_flag= 3;
ret_value= _ma_split_page(info, key, anc_page,
share->max_index_block_size,
@ -595,6 +598,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
endpos= leaf_page->buff+ leaf_page->size;
if (ret_value == 1)
{
/* underflow writes "next_page" to disk */
ret_value= underflow(info, keyinfo, leaf_page, &next_page,
endpos);
if (ret_value == 0 && leaf_page->size >
@ -608,6 +612,9 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
}
else
{
if (_ma_write_keypage(&next_page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
DFLT_INIT_HITS))
goto err;
DBUG_PRINT("test",("Inserting of key when deleting"));
if (!_ma_get_last_key(&tmp_key, leaf_page, endpos))
goto err;
@ -702,7 +709,8 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
if (share->now_transactional &&
_ma_log_add(anc_page, a_length,
key_start, s_temp.changed_length, s_temp.move_length, 1))
key_start, s_temp.changed_length, s_temp.move_length, 1,
KEY_OP_DEBUG_LOG_ADD_2))
goto err;
DBUG_RETURN(new_leaf_length <=
@ -971,7 +979,8 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
anc_key_inserted.move_length,
key_deleted.changed_length),
anc_key_inserted.move_length -
key_deleted.move_length, 1))
key_deleted.move_length, 1,
KEY_OP_DEBUG_LOG_ADD_3))
goto err;
/*
@ -1211,7 +1220,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
anc_key_inserted.move_length,
key_deleted.changed_length),
anc_key_inserted.move_length -
key_deleted.move_length, 1))
key_deleted.move_length, 1,KEY_OP_DEBUG_LOG_ADD_4))
goto err;
/*
@ -1449,25 +1458,23 @@ my_bool _ma_log_delete(MARIA_PAGE *ma_page, const uchar *key_pos,
enum en_key_debug debug_marker __attribute__((unused)))
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 2 + 3 + 3 + 6 + 3 + 7];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 5+ 2 + 3 + 3 + 6 + 3 + 7];
uchar *log_pos;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 7];
uint translog_parts, current_size, extra_length;
uint offset= (uint) (key_pos - ma_page->buff);
MARIA_HA *info= ma_page->info;
MARIA_SHARE *share= info->s;
my_off_t page;
my_off_t page= ma_page->pos / share->block_size;
DBUG_ENTER("_ma_log_delete");
DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
(ulong) (ma_page->pos / share->block_size),
changed_length, move_length));
(ulong) page, changed_length, move_length));
DBUG_ASSERT(share->now_transactional && move_length);
DBUG_ASSERT(offset + changed_length <= ma_page->size);
DBUG_ASSERT(ma_page->org_size - move_length + append_length == ma_page->size);
DBUG_ASSERT(move_length <= ma_page->org_size - share->keypage_header);
/* Store address of new root page */
page= ma_page->pos / share->block_size;
page_store(log_data + FILEID_STORE_SIZE, page);
log_pos= log_data+ FILEID_STORE_SIZE + PAGE_STORE_SIZE;
current_size= ma_page->org_size;
@ -1475,6 +1482,11 @@ my_bool _ma_log_delete(MARIA_PAGE *ma_page, const uchar *key_pos,
#ifdef EXTRA_DEBUG_KEY_CHANGES
*log_pos++= KEY_OP_DEBUG;
*log_pos++= debug_marker;
*log_pos++= KEY_OP_DEBUG_2;
int2store(log_pos, ma_page->org_size);
int2store(log_pos+2, ma_page->size);
log_pos+=4;
#endif
/* Store keypage_flag */

View File

@ -321,15 +321,14 @@ my_bool _ma_log_prefix(MARIA_PAGE *ma_page, uint changed_length,
uchar *log_pos;
uchar *buff= ma_page->buff;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
pgcache_page_no_t page;
MARIA_HA *info= ma_page->info;
pgcache_page_no_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_prefix");
DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
(ulong) ma_page->pos, changed_length, move_length));
(ulong) page, changed_length, move_length));
DBUG_ASSERT(ma_page->size == ma_page->org_size + move_length);
page= ma_page->pos / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
@ -412,15 +411,13 @@ my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length)
int diff;
uint translog_parts, extra_length;
MARIA_HA *info= ma_page->info;
pgcache_page_no_t page;
pgcache_page_no_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_suffix");
DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u",
(ulong) ma_page->pos, org_length, new_length));
(ulong) page, org_length, new_length));
DBUG_ASSERT(ma_page->size == new_length);
DBUG_ASSERT(ma_page->org_size == org_length);
page= ma_page->pos / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
@ -488,7 +485,8 @@ my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length)
my_bool _ma_log_add(MARIA_PAGE *ma_page,
uint org_page_length __attribute__ ((unused)),
uchar *key_pos, uint changed_length, int move_length,
my_bool handle_overflow __attribute__ ((unused)))
my_bool handle_overflow __attribute__ ((unused)),
enum en_key_debug debug_marker __attribute__((unused)))
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 3 + 3 + 3 + 3 + 7 +
@ -500,32 +498,30 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page,
uint offset= (uint) (key_pos - buff);
uint max_page_size= info->s->max_index_block_size;
uint translog_parts, current_size;
pgcache_page_no_t page_pos;
pgcache_page_no_t page_pos= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_add");
DBUG_PRINT("enter", ("page: %lu org_page_length: %u changed_length: %u "
"move_length: %d",
(ulong) (ma_page->pos / info->s->block_size),
org_page_length, changed_length,
(ulong) page_pos, org_page_length, changed_length,
move_length));
DBUG_ASSERT(info->s->now_transactional);
DBUG_ASSERT(move_length <= (int) changed_length);
DBUG_ASSERT(ma_page->org_size == min(org_page_length, max_page_size));
DBUG_ASSERT(ma_page->size == org_page_length + move_length);
DBUG_ASSERT(offset < max_page_size);
DBUG_ASSERT(offset <= ma_page->org_size);
/*
Write REDO entry that contains the logical operations we need
to do the page
*/
log_pos= log_data + FILEID_STORE_SIZE;
page_pos= ma_page->pos / info->s->block_size;
page_store(log_pos, page_pos);
current_size= ma_page->org_size;
log_pos+= PAGE_STORE_SIZE;
#ifdef EXTRA_DEBUG_KEY_CHANGES
*log_pos++= KEY_OP_DEBUG;
*log_pos++= KEY_OP_DEBUG_LOG_ADD;
*log_pos++= debug_marker;
#endif
/* Store keypage_flag */
@ -575,11 +571,33 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page,
log_pos+= 3;
if (move_length)
{
if (move_length < 0)
{
DBUG_ASSERT(offset - move_length <= org_page_length);
if (offset - move_length > current_size)
{
/*
Truncate to end of page. We will add data to it from
the page buffer below
*/
move_length= (int) offset - (int) current_size;
}
}
log_pos[0]= KEY_OP_SHIFT;
int2store(log_pos+1, move_length);
log_pos+= 3;
current_size+= move_length;
}
/*
Handle case where page was shortend but 'changed_length' goes over
'current_size'. This can only happen when there was a page overflow
and we will below add back the overflow part
*/
if (offset + changed_length > current_size)
{
DBUG_ASSERT(offset + changed_length <= ma_page->size);
changed_length= current_size - offset;
}
log_pos[0]= KEY_OP_CHANGE;
}
int2store(log_pos+1, changed_length);
@ -1060,14 +1078,14 @@ uint _ma_apply_redo_index(MARIA_HA *info,
check_page_length= uint2korr(header);
crc= uint4korr(header+2);
_ma_store_page_used(share, buff, page_length);
DBUG_ASSERT(check_page_length == page_length);
if (crc != (uint32) my_checksum(0, buff + LSN_STORE_SIZE,
if (check_page_length != page_length ||
crc != (uint32) my_checksum(0, buff + LSN_STORE_SIZE,
page_length - LSN_STORE_SIZE))
{
DBUG_DUMP("KEY_OP_CHECK bad page", buff, page_length);
if (header + 6 + page_length <= header_end)
if (header + 6 + check_page_length <= header_end)
{
DBUG_DUMP("KEY_OP_CHECK org page", header + 6, page_length);
DBUG_DUMP("KEY_OP_CHECK org page", header + 6, check_page_length);
}
DBUG_ASSERT("crc failure in REDO_INDEX" == 0);
}
@ -1086,6 +1104,11 @@ uint _ma_apply_redo_index(MARIA_HA *info,
DBUG_PRINT("redo", ("Debug: %u", (uint) header[0]));
header++;
break;
case KEY_OP_DEBUG_2:
DBUG_PRINT("redo", ("org_page_length: %u new_page_length: %u",
uint2korr(header), uint2korr(header+2)));
header+= 4;
break;
case KEY_OP_MAX_PAGELENGTH:
DBUG_PRINT("redo", ("key_op_max_page_length"));
page_length= max_page_size;

View File

@ -70,7 +70,8 @@ my_bool _ma_log_suffix(MARIA_PAGE *page, uint org_length,
uint new_length);
my_bool _ma_log_add(MARIA_PAGE *page, uint buff_length, uchar *key_pos,
uint changed_length, int move_length,
my_bool handle_overflow);
my_bool handle_overflow,
enum en_key_debug debug_marker);
my_bool _ma_log_delete(MARIA_PAGE *page, const uchar *key_pos,
uint changed_length, uint move_length,
uint append_length, enum en_key_debug debug_marker);

View File

@ -169,7 +169,8 @@ enum en_key_op
KEY_OP_SET_PAGEFLAG, /* Set pageflag from next byte */
KEY_OP_COMPACT_PAGE, /* Compact key page */
KEY_OP_MAX_PAGELENGTH, /* Set page to max page length */
KEY_OP_DEBUG /* Entry for storing what triggered redo_index */
KEY_OP_DEBUG, /* Entry for storing what triggered redo_index */
KEY_OP_DEBUG_2 /* Entry for pagelengths */
};
enum en_key_debug
@ -180,18 +181,21 @@ enum en_key_debug
KEY_OP_DEBUG_FATHER_CHANGED_1, /* 3 */
KEY_OP_DEBUG_FATHER_CHANGED_2, /* 4 */
KEY_OP_DEBUG_LOG_SPLIT, /* 5 */
KEY_OP_DEBUG_LOG_ADD, /* 6 */
KEY_OP_DEBUG_LOG_PREFIX_1, /* 7 */
KEY_OP_DEBUG_LOG_PREFIX_2, /* 8 */
KEY_OP_DEBUG_LOG_PREFIX_3, /* 9 */
KEY_OP_DEBUG_LOG_PREFIX_4, /* 10 */
KEY_OP_DEBUG_LOG_PREFIX_5, /* 11 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_1, /* 12 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_2, /* 13 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_3, /* 14 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_RT, /* 15 */
KEY_OP_DEBUG_LOG_DEL_PREFIX, /* 16 */
KEY_OP_DEBUG_LOG_MIDDLE /* 17 */
KEY_OP_DEBUG_LOG_ADD_1, /* 6 */
KEY_OP_DEBUG_LOG_ADD_2, /* 7 */
KEY_OP_DEBUG_LOG_ADD_3, /* 8 */
KEY_OP_DEBUG_LOG_ADD_4, /* 9 */
KEY_OP_DEBUG_LOG_PREFIX_1, /* 10 */
KEY_OP_DEBUG_LOG_PREFIX_2, /* 11 */
KEY_OP_DEBUG_LOG_PREFIX_3, /* 12 */
KEY_OP_DEBUG_LOG_PREFIX_4, /* 13 */
KEY_OP_DEBUG_LOG_PREFIX_5, /* 14 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_1, /* 15 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_2, /* 16 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_3, /* 17 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_RT, /* 18 */
KEY_OP_DEBUG_LOG_DEL_PREFIX, /* 19 */
KEY_OP_DEBUG_LOG_MIDDLE /* 20 */
};

View File

@ -59,7 +59,8 @@ int maria_rtree_add_key(const MARIA_KEY *key, MARIA_PAGE *page,
page_store_size(share, page);
if (share->now_transactional &&
_ma_log_add(page, key_pos - page->buff,
key_pos, tot_key_length, tot_key_length, 0))
key_pos, tot_key_length, tot_key_length, 0,
KEY_OP_DEBUG_LOG_ADD_1))
DBUG_RETURN(-1);
DBUG_RETURN(0);
}

View File

@ -116,8 +116,9 @@ static int _ma_search_no_save(register MARIA_HA *info, MARIA_KEY *key,
MARIA_PAGE page;
MARIA_PINNED_PAGE *page_link;
DBUG_ENTER("_ma_search");
DBUG_PRINT("enter",("pos: %lu nextflag: %u lastpos: %lu",
(ulong) pos, nextflag, (ulong) info->cur_row.lastpos));
DBUG_PRINT("enter",("page: %lu nextflag: %u lastpos: %lu",
(ulong) (pos / info->s->block_size),
nextflag, (ulong) info->cur_row.lastpos));
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, key););
if (pos == HA_OFFSET_ERROR)

View File

@ -768,6 +768,10 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key,
DBUG_PRINT("enter",("key_pos: 0x%lx", (ulong) key_pos));
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, key););
/*
Note that anc_page->size can be bigger then block_size in case of
delete key that caused increase of page length
*/
org_anc_length= a_length= anc_page->size;
nod_flag= anc_page->node;
@ -887,7 +891,8 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0
{
if (share->now_transactional &&
_ma_log_add(anc_page, org_anc_length,
key_pos, s_temp.changed_length, t_length, 1))
key_pos, s_temp.changed_length, t_length, 1,
KEY_OP_DEBUG_LOG_ADD_1))
DBUG_RETURN(-1);
}
DBUG_RETURN(0); /* There is room on page */
@ -911,7 +916,9 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0
father_page, father_key_pos,
&s_temp));
}
DBUG_RETURN(_ma_split_page(info, key, anc_page, org_anc_length,
DBUG_RETURN(_ma_split_page(info, key, anc_page,
min(org_anc_length,
info->s->max_index_block_size),
key_pos, s_temp.changed_length, t_length,
key_buff, insert_last));
} /* _ma_insert */
@ -1239,7 +1246,8 @@ static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
father_key_pos+father_keylength);
left_page= curr_page;
right_page= &next_page;
DBUG_PRINT("info", ("use right page: %lu", (ulong) next_page.pos));
DBUG_PRINT("info", ("use right page: %lu",
(ulong) (next_page.pos / keyinfo->block_length)));
}
else
{
@ -1248,7 +1256,8 @@ static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
next_page.pos= _ma_kpos(share->base.key_reflength,father_key_pos);
left_page= &next_page;
right_page= curr_page;
DBUG_PRINT("info", ("use left page: %lu", (ulong) next_page.pos));
DBUG_PRINT("info", ("use left page: %lu",
(ulong) (next_page.pos / keyinfo->block_length)));
} /* father_key_pos ptr to parting key */
if (_ma_fetch_keypage(&next_page, info, keyinfo, next_page.pos,
@ -1864,14 +1873,13 @@ my_bool _ma_log_new(MARIA_PAGE *ma_page, my_bool root_page)
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
MARIA_HA *info= ma_page->info;
MARIA_SHARE *share= info->s;
my_off_t page;
my_off_t page= ma_page->pos / share->block_size;
DBUG_ENTER("_ma_log_new");
DBUG_PRINT("enter", ("page: %lu", (ulong) ma_page->pos));
DBUG_PRINT("enter", ("page: %lu", (ulong) page));
DBUG_ASSERT(share->now_transactional);
/* Store address of new root page */
page= ma_page->pos / share->block_size;
page_store(log_data + FILEID_STORE_SIZE, page);
/* Store link to next unused page */
@ -1920,10 +1928,10 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length,
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 6 + 7], *log_pos;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
uint offset= (uint) (key_pos - ma_page->buff), translog_parts;
my_off_t page;
MARIA_HA *info= ma_page->info;
my_off_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_change");
DBUG_PRINT("enter", ("page: %lu length: %u", (ulong) ma_page->pos, length));
DBUG_PRINT("enter", ("page: %lu length: %u", (ulong) page, length));
DBUG_ASSERT(info->s->now_transactional);
DBUG_ASSERT(offset + length <= ma_page->size);
@ -1971,7 +1979,8 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length,
@fn _ma_log_split()
@param
ma_page Page that is changed
org_length Original length of page
org_length Original length of page. Can be bigger than block_size
for block that overflowed
new_length New length of page
key_pos Where key is inserted on page (may be 0 if no key)
key_length Number of bytes changed at key_pos
@ -2005,16 +2014,17 @@ static my_bool _ma_log_split(MARIA_PAGE *ma_page,
uint offset= (uint) (key_pos - ma_page->buff);
uint translog_parts, extra_length;
MARIA_HA *info= ma_page->info;
my_off_t page;
my_off_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_split");
DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u",
(ulong) ma_page->pos, org_length, new_length));
(ulong) page, org_length, new_length));
DBUG_ASSERT(changed_length >= data_length);
DBUG_ASSERT(org_length <= info->s->max_index_block_size);
DBUG_ASSERT(new_length == ma_page->size);
DBUG_ASSERT(org_length == ma_page->org_size);
log_pos= log_data + FILEID_STORE_SIZE;
page= ma_page->pos / info->s->block_size;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
@ -2169,16 +2179,16 @@ static my_bool _ma_log_del_prefix(MARIA_PAGE *ma_page,
uint diff_length= org_length + move_length - new_length;
uint translog_parts, extra_length;
MARIA_HA *info= ma_page->info;
my_off_t page;
my_off_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_del_prefix");
DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u",
(ulong) ma_page->pos, org_length, new_length));
(ulong) page, org_length, new_length));
DBUG_ASSERT((int) diff_length > 0);
DBUG_ASSERT(ma_page->org_size == org_length);
DBUG_ASSERT(ma_page->size == new_length);
log_pos= log_data + FILEID_STORE_SIZE;
page= ma_page->pos / info->s->block_size;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
@ -2277,10 +2287,10 @@ static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page,
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 6];
uint key_offset;
uint translog_parts, extra_length;
my_off_t page;
MARIA_HA *info= ma_page->info;
my_off_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_key_middle");
DBUG_PRINT("enter", ("page: %lu", (ulong) ma_page->pos));
DBUG_PRINT("enter", ("page: %lu", (ulong) page));
DBUG_ASSERT(ma_page->size == new_length);
@ -2304,8 +2314,6 @@ static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page,
data_deleted_last+= move_length;
}
page= ma_page->pos / info->s->block_size;
/* First log changes to page */
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
@ -2400,7 +2408,7 @@ static my_bool _ma_log_middle(MARIA_PAGE *ma_page,
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3 + 5 + 7], *log_pos;
MARIA_HA *info= ma_page->info;
my_off_t page;
my_off_t page= ma_page->page / info->s->block_size;
uint translog_parts, extra_length;
DBUG_ENTER("_ma_log_middle");
DBUG_PRINT("enter", ("page: %lu", (ulong) page));
@ -2408,8 +2416,6 @@ static my_bool _ma_log_middle(MARIA_PAGE *ma_page,
DBUG_ASSERT(ma_page->org_size + data_added_first - data_deleted_last ==
ma_page->size);
page= ma_page->page / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;

View File

@ -797,10 +797,13 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
{
if (!file) return HA_ADMIN_INTERNAL_ERROR;
int error;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MYISAM_SHARE* share = file->s;
const char *old_proc_info=thd->proc_info;
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
thd_proc_info(thd, "Checking table");
myisamchk_init(&param);
param.thd = thd;
@ -889,9 +892,12 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
{
int error=0;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MYISAM_SHARE* share = file->s;
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd = thd;
param.op_name= "analyze";
@ -1019,7 +1025,9 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
err:
{
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd= thd;
param.op_name= "backup";
@ -1035,10 +1043,10 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
{
int error;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
ha_rows start_records;
if (!file) return HA_ADMIN_INTERNAL_ERROR;
if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd = thd;
@ -1086,8 +1094,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
{
int error;
if (!file) return HA_ADMIN_INTERNAL_ERROR;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd = thd;
@ -1281,7 +1290,10 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
if (error != HA_ADMIN_OK)
{
/* Send error to user */
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd= thd;
param.op_name= "assign_to_keycache";
@ -1345,7 +1357,9 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt)
err:
{
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd= thd;
param.op_name= "preload_keys";
@ -1455,8 +1469,12 @@ int ha_myisam::enable_indexes(uint mode)
else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
{
THD *thd=current_thd;
HA_CHECK param;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
const char *save_proc_info=thd->proc_info;
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
thd_proc_info(thd, "Creating index");
myisamchk_init(&param);
param.op_name= "recreating_index";