Commit 236141d4 authored by Michael Widenius's avatar Michael Widenius

Use less memory on stack in sql_parse.cc and in repair/check for MyISAM & Aria

sql/sql_parse.cc:
  Make some not commonly used functions with big local variables to separate functions to make default stack usage smaller.
  Decrease size of db_buff[] (Was bigger than needed)
  Allocate current_global_status_var with malloc().
storage/maria/ha_maria.cc:
  Don't allocate HA_CHECK on stack (it's > 100K)
storage/maria/ma_check.c:
  Removed duplicated code
parent 2f85f78d
...@@ -48,6 +48,9 @@ ...@@ -48,6 +48,9 @@
"FUNCTION" : "PROCEDURE") "FUNCTION" : "PROCEDURE")
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables); 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); static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
const char *any_db="*any*"; // Special symbol for check_access const char *any_db="*any*"; // Special symbol for check_access
...@@ -1125,7 +1128,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1125,7 +1128,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
Cast *passwd to an unsigned char, so that it doesn't extend the sign Cast *passwd to an unsigned char, so that it doesn't extend the sign
for *passwd > 127 and become 2**32-127 after casting to uint. for *passwd > 127 and become 2**32-127 after casting to uint.
*/ */
char db_buff[SAFE_NAME_LEN*2+1]; // buffer to store db in utf8 char db_buff[SAFE_NAME_LEN+1]; // buffer to store db in utf8
char *db= passwd; char *db= passwd;
char *save_db; char *save_db;
/* /*
...@@ -1556,7 +1559,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1556,7 +1559,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif #endif
case COM_STATISTICS: case COM_STATISTICS:
{ {
STATUS_VAR current_global_status_var; STATUS_VAR *current_global_status_var; // Big; Don't allocate on stack
ulong uptime; ulong uptime;
#if defined(SAFEMALLOC) || !defined(EMBEDDED_LIBRARY) #if defined(SAFEMALLOC) || !defined(EMBEDDED_LIBRARY)
uint length; uint length;
...@@ -1565,9 +1568,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1565,9 +1568,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char buff[250]; char buff[250];
uint buff_len= sizeof(buff); uint buff_len= sizeof(buff);
if (!(current_global_status_var= (STATUS_VAR*)
thd->alloc(sizeof(STATUS_VAR))))
break;
general_log_print(thd, command, NullS); general_log_print(thd, command, NullS);
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]); 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))) if (!(uptime= (ulong) (thd->start_time - server_start_time)))
queries_per_second1000= 0; queries_per_second1000= 0;
else else
...@@ -1582,8 +1588,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1582,8 +1588,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
"Open tables: %u Queries per second avg: %u.%u", "Open tables: %u Queries per second avg: %u.%u",
uptime, uptime,
(int) thread_count, (ulong) thd->query_id, (int) thread_count, (ulong) thd->query_id,
current_global_status_var.long_query_count, current_global_status_var->long_query_count,
current_global_status_var.opened_tables, current_global_status_var->opened_tables,
refresh_version, refresh_version,
cached_open_tables(), cached_open_tables(),
(uint) (queries_per_second1000 / 1000), (uint) (queries_per_second1000 / 1000),
...@@ -2285,22 +2291,7 @@ mysql_execute_command(THD *thd) ...@@ -2285,22 +2291,7 @@ mysql_execute_command(THD *thd)
break; break;
case SQLCOM_SHOW_STATUS: case SQLCOM_SHOW_STATUS:
{ {
system_status_var old_status_var= thd->status_var; execute_show_status(thd, all_tables);
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);
break; break;
} }
case SQLCOM_SHOW_DATABASES: case SQLCOM_SHOW_DATABASES:
...@@ -3005,31 +2996,7 @@ end_with_restore_list: ...@@ -3005,31 +2996,7 @@ end_with_restore_list:
} }
case SQLCOM_RENAME_TABLE: case SQLCOM_RENAME_TABLE:
{ {
DBUG_ASSERT(first_table == all_tables && first_table != 0); if (execute_rename_table(thd, first_table, all_tables))
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))
goto error; goto error;
break; break;
} }
...@@ -5172,6 +5139,62 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) ...@@ -5172,6 +5139,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 #ifndef NO_EMBEDDED_ACCESS_CHECKS
/** /**
Check grants for commands which work only with one table. Check grants for commands which work only with one table.
......
...@@ -1043,14 +1043,14 @@ int ha_maria::write_row(uchar * buf) ...@@ -1043,14 +1043,14 @@ int ha_maria::write_row(uchar * buf)
int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
{ {
if (!file)
return HA_ADMIN_INTERNAL_ERROR;
int error; int error;
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MARIA_SHARE *share= file->s; MARIA_SHARE *share= file->s;
const char *old_proc_info= thd_proc_info(thd, "Checking table"); const char *old_proc_info= thd_proc_info(thd, "Checking table");
TRN *old_trn= file->trn; TRN *old_trn= file->trn;
if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param); maria_chk_init(&param);
param.thd= thd; param.thd= thd;
param.op_name= "check"; param.op_name= "check";
...@@ -1144,9 +1144,12 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) ...@@ -1144,9 +1144,12 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt) int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
{ {
int error= 0; int error= 0;
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MARIA_SHARE *share= file->s; MARIA_SHARE *share= file->s;
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param); maria_chk_init(&param);
param.thd= thd; param.thd= thd;
param.op_name= "analyze"; param.op_name= "analyze";
...@@ -1281,7 +1284,10 @@ int ha_maria::backup(THD * thd, HA_CHECK_OPT *check_opt) ...@@ -1281,7 +1284,10 @@ int ha_maria::backup(THD * thd, HA_CHECK_OPT *check_opt)
err: err:
{ {
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param); maria_chk_init(&param);
param.thd= thd; param.thd= thd;
param.op_name= "backup"; param.op_name= "backup";
...@@ -1297,10 +1303,10 @@ err: ...@@ -1297,10 +1303,10 @@ err:
int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt) int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
{ {
int error; int error;
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
ha_rows start_records; ha_rows start_records;
if (!file) if (!file || !&param)
return HA_ADMIN_INTERNAL_ERROR; return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param); maria_chk_init(&param);
...@@ -1352,11 +1358,11 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt) ...@@ -1352,11 +1358,11 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt) int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
{ {
int error; int error;
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
TRN *old_trn; TRN *old_trn;
MARIA_SHARE *share= file->s; MARIA_SHARE *share= file->s;
if (!file) if (!file || !&param)
return HA_ADMIN_INTERNAL_ERROR; return HA_ADMIN_INTERNAL_ERROR;
old_trn= file->trn; old_trn= file->trn;
...@@ -1382,9 +1388,9 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt) ...@@ -1382,9 +1388,9 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt) int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt)
{ {
int error; int error;
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!file) if (!file || !&param)
return HA_ADMIN_INTERNAL_ERROR; return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param); maria_chk_init(&param);
...@@ -1623,7 +1629,10 @@ int ha_maria::assign_to_keycache(THD * thd, HA_CHECK_OPT *check_opt) ...@@ -1623,7 +1629,10 @@ int ha_maria::assign_to_keycache(THD * thd, HA_CHECK_OPT *check_opt)
if (error != HA_ADMIN_OK) if (error != HA_ADMIN_OK)
{ {
/* Send error to user */ /* 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); maria_chk_init(&param);
param.thd= thd; param.thd= thd;
param.op_name= "assign_to_keycache"; param.op_name= "assign_to_keycache";
...@@ -1684,7 +1693,10 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt) ...@@ -1684,7 +1693,10 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt)
errmsg= buf; 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); maria_chk_init(&param);
param.thd= thd; param.thd= thd;
param.op_name= "preload_keys"; param.op_name= "preload_keys";
...@@ -1792,8 +1804,12 @@ int ha_maria::enable_indexes(uint mode) ...@@ -1792,8 +1804,12 @@ int ha_maria::enable_indexes(uint mode)
else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
{ {
THD *thd= current_thd; 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"); const char *save_proc_info= thd_proc_info(thd, "Creating index");
maria_chk_init(&param); maria_chk_init(&param);
param.op_name= "recreating_index"; param.op_name= "recreating_index";
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK | param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
......
...@@ -4409,8 +4409,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, ...@@ -4409,8 +4409,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
goto err; goto err;
} }
} }
share->state.state.data_file_length= share->state.state.data_file_length= share->state.state.data_file_length= sort_param->filepos;
sort_param->filepos;
/* Only whole records */ /* Only whole records */
share->state.version= (ulong) time((time_t*) 0); share->state.version= (ulong) time((time_t*) 0);
/* /*
......
...@@ -799,10 +799,13 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) ...@@ -799,10 +799,13 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
{ {
if (!file) return HA_ADMIN_INTERNAL_ERROR; if (!file) return HA_ADMIN_INTERNAL_ERROR;
int error; int error;
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MYISAM_SHARE* share = file->s; MYISAM_SHARE* share = file->s;
const char *old_proc_info=thd->proc_info; const char *old_proc_info=thd->proc_info;
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
thd_proc_info(thd, "Checking table"); thd_proc_info(thd, "Checking table");
myisamchk_init(&param); myisamchk_init(&param);
param.thd = thd; param.thd = thd;
...@@ -891,9 +894,12 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) ...@@ -891,9 +894,12 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
{ {
int error=0; int error=0;
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MYISAM_SHARE* share = file->s; MYISAM_SHARE* share = file->s;
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param); myisamchk_init(&param);
param.thd = thd; param.thd = thd;
param.op_name= "analyze"; param.op_name= "analyze";
...@@ -1021,7 +1027,9 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) ...@@ -1021,7 +1027,9 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
err: err:
{ {
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param); myisamchk_init(&param);
param.thd= thd; param.thd= thd;
param.op_name= "backup"; param.op_name= "backup";
...@@ -1037,10 +1045,10 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) ...@@ -1037,10 +1045,10 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
{ {
int error; int error;
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
ha_rows start_records; ha_rows start_records;
if (!file) return HA_ADMIN_INTERNAL_ERROR; if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param); myisamchk_init(&param);
param.thd = thd; param.thd = thd;
...@@ -1088,8 +1096,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) ...@@ -1088,8 +1096,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
{ {
int error; int error;
if (!file) return HA_ADMIN_INTERNAL_ERROR; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK param;
if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param); myisamchk_init(&param);
param.thd = thd; param.thd = thd;
...@@ -1283,7 +1292,10 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) ...@@ -1283,7 +1292,10 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
if (error != HA_ADMIN_OK) if (error != HA_ADMIN_OK)
{ {
/* Send error to user */ /* 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); myisamchk_init(&param);
param.thd= thd; param.thd= thd;
param.op_name= "assign_to_keycache"; param.op_name= "assign_to_keycache";
...@@ -1347,7 +1359,9 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) ...@@ -1347,7 +1359,9 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt)
err: err:
{ {
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param); myisamchk_init(&param);
param.thd= thd; param.thd= thd;
param.op_name= "preload_keys"; param.op_name= "preload_keys";
...@@ -1457,8 +1471,12 @@ int ha_myisam::enable_indexes(uint mode) ...@@ -1457,8 +1471,12 @@ int ha_myisam::enable_indexes(uint mode)
else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
{ {
THD *thd=current_thd; THD *thd=current_thd;
HA_CHECK param; HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
const char *save_proc_info=thd->proc_info; const char *save_proc_info=thd->proc_info;
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
thd_proc_info(thd, "Creating index"); thd_proc_info(thd, "Creating index");
myisamchk_init(&param); myisamchk_init(&param);
param.op_name= "recreating_index"; param.op_name= "recreating_index";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment