mirror of
https://github.com/MariaDB/server.git
synced 2025-06-13 13:01:51 +03:00
Merge bk-internal:/home/bk/mysql-4.1/
into serg.mylan:/usr/home/serg/Abk/mysql-4.1
This commit is contained in:
@ -68,6 +68,13 @@
|
|||||||
/* Size of buffer for dump's select query */
|
/* Size of buffer for dump's select query */
|
||||||
#define QUERY_LENGTH 1536
|
#define QUERY_LENGTH 1536
|
||||||
|
|
||||||
|
#define print_xml_tag(out_file, sbeg, sval, send) \
|
||||||
|
{ \
|
||||||
|
fputs(sbeg, out_file); \
|
||||||
|
print_quoted_xml(out_file, sval, 0); \
|
||||||
|
fputs(send, out_file); \
|
||||||
|
}
|
||||||
|
|
||||||
static char *add_load_option(char *ptr, const char *object,
|
static char *add_load_option(char *ptr, const char *object,
|
||||||
const char *statement);
|
const char *statement);
|
||||||
static ulong find_set(TYPELIB *lib, const char *x, uint length,
|
static ulong find_set(TYPELIB *lib, const char *x, uint length,
|
||||||
@ -298,7 +305,7 @@ static int init_dumping(char *);
|
|||||||
static int dump_databases(char **);
|
static int dump_databases(char **);
|
||||||
static int dump_all_databases();
|
static int dump_all_databases();
|
||||||
static char *quote_name(const char *name, char *buff, my_bool force);
|
static char *quote_name(const char *name, char *buff, my_bool force);
|
||||||
static void print_quoted_xml(FILE *output, char *fname, char *str, uint len);
|
static void print_quoted_xml(FILE *output, char *str, ulong len);
|
||||||
|
|
||||||
static void print_version(void)
|
static void print_version(void)
|
||||||
{
|
{
|
||||||
@ -339,8 +346,8 @@ static void write_header(FILE *sql_file, char *db_name)
|
|||||||
{
|
{
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
{
|
{
|
||||||
fprintf(sql_file,"<?xml version=\"1.0\"?>\n");
|
fputs("<?xml version=\"1.0\"?>\n", sql_file);
|
||||||
fprintf(sql_file,"<mysqldump>\n");
|
fputs("<mysqldump>\n", sql_file);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -366,7 +373,7 @@ static void write_header(FILE *sql_file, char *db_name)
|
|||||||
static void write_footer(FILE *sql_file)
|
static void write_footer(FILE *sql_file)
|
||||||
{
|
{
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(sql_file,"</mysqldump>");
|
fputs("</mysqldump>", sql_file);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(md_result_file,"\n\
|
fprintf(md_result_file,"\n\
|
||||||
@ -651,6 +658,29 @@ static char *quote_name(const char *name, char *buff, my_bool force)
|
|||||||
} /* quote_name */
|
} /* quote_name */
|
||||||
|
|
||||||
|
|
||||||
|
void print_xml_row(FILE *xml_file, const char *row_name, MYSQL_RES *tableRes,
|
||||||
|
MYSQL_ROW *row)
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
MYSQL_FIELD *field;
|
||||||
|
ulong *lengths= mysql_fetch_lengths(tableRes);
|
||||||
|
|
||||||
|
fprintf(xml_file, "\t\t<%s", row_name);
|
||||||
|
mysql_field_seek(tableRes, 0);
|
||||||
|
for (i= 0; (field= mysql_fetch_field(tableRes)); i++)
|
||||||
|
{
|
||||||
|
if ((*row)[i] && (*row)[i][0])
|
||||||
|
{
|
||||||
|
fputs(" ", xml_file);
|
||||||
|
print_quoted_xml(xml_file, field->name, 0);
|
||||||
|
fputs("=\"", xml_file);
|
||||||
|
print_quoted_xml(xml_file, (*row)[i], lengths[i]);
|
||||||
|
fputs("\"", xml_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fputs(" />\n", xml_file);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
getStructure -- retrievs database structure, prints out corresponding
|
getStructure -- retrievs database structure, prints out corresponding
|
||||||
CREATE statement and fills out insert_pat.
|
CREATE statement and fills out insert_pat.
|
||||||
@ -680,7 +710,7 @@ static uint getTableStructure(char *table, char* db)
|
|||||||
sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", (opt_quoted || opt_keywords));
|
sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", (opt_quoted || opt_keywords));
|
||||||
result_table= quote_name(table, table_buff, 1);
|
result_table= quote_name(table, table_buff, 1);
|
||||||
opt_quoted_table= quote_name(table, table_buff2, 0);
|
opt_quoted_table= quote_name(table, table_buff2, 0);
|
||||||
if (!mysql_query(sock,insert_pat))
|
if (!opt_xml && !mysql_query(sock,insert_pat))
|
||||||
{
|
{
|
||||||
/* using SHOW CREATE statement */
|
/* using SHOW CREATE statement */
|
||||||
if (!tFlag)
|
if (!tFlag)
|
||||||
@ -735,16 +765,14 @@ static uint getTableStructure(char *table, char* db)
|
|||||||
}
|
}
|
||||||
write_header(sql_file, db);
|
write_header(sql_file, db);
|
||||||
}
|
}
|
||||||
if (!opt_xml)
|
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
|
||||||
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
|
|
||||||
result_table);
|
result_table);
|
||||||
if (opt_drop)
|
if (opt_drop)
|
||||||
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table);
|
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table);
|
||||||
|
|
||||||
tableRes=mysql_store_result(sock);
|
tableRes=mysql_store_result(sock);
|
||||||
row=mysql_fetch_row(tableRes);
|
row=mysql_fetch_row(tableRes);
|
||||||
if (!opt_xml)
|
fprintf(sql_file, "%s;\n", row[1]);
|
||||||
fprintf(sql_file, "%s;\n", row[1]);
|
|
||||||
mysql_free_result(tableRes);
|
mysql_free_result(tableRes);
|
||||||
}
|
}
|
||||||
sprintf(insert_pat,"show fields from %s", result_table);
|
sprintf(insert_pat,"show fields from %s", result_table);
|
||||||
@ -818,7 +846,10 @@ static uint getTableStructure(char *table, char* db)
|
|||||||
result_table);
|
result_table);
|
||||||
if (opt_drop)
|
if (opt_drop)
|
||||||
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",result_table);
|
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",result_table);
|
||||||
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
|
if (!opt_xml)
|
||||||
|
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
|
||||||
|
else
|
||||||
|
print_xml_tag(sql_file, "\t<table_structure name=\"", table, "\">\n");
|
||||||
}
|
}
|
||||||
if (cFlag)
|
if (cFlag)
|
||||||
sprintf(insert_pat, "INSERT %sINTO %s (", delayed, result_table);
|
sprintf(insert_pat, "INSERT %sINTO %s (", delayed, result_table);
|
||||||
@ -835,7 +866,7 @@ static uint getTableStructure(char *table, char* db)
|
|||||||
ulong *lengths=mysql_fetch_lengths(tableRes);
|
ulong *lengths=mysql_fetch_lengths(tableRes);
|
||||||
if (init)
|
if (init)
|
||||||
{
|
{
|
||||||
if (!tFlag)
|
if (!opt_xml && !tFlag)
|
||||||
fputs(",\n",sql_file);
|
fputs(",\n",sql_file);
|
||||||
if (cFlag)
|
if (cFlag)
|
||||||
strpos=strmov(strpos,", ");
|
strpos=strmov(strpos,", ");
|
||||||
@ -845,6 +876,12 @@ static uint getTableStructure(char *table, char* db)
|
|||||||
strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME], name_buff, 0));
|
strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME], name_buff, 0));
|
||||||
if (!tFlag)
|
if (!tFlag)
|
||||||
{
|
{
|
||||||
|
if (opt_xml)
|
||||||
|
{
|
||||||
|
print_xml_row(sql_file, "field", tableRes, &row);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_keywords)
|
if (opt_keywords)
|
||||||
fprintf(sql_file, " %s.%s %s", result_table,
|
fprintf(sql_file, " %s.%s %s", result_table,
|
||||||
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
|
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
|
||||||
@ -906,6 +943,12 @@ static uint getTableStructure(char *table, char* db)
|
|||||||
keynr=0;
|
keynr=0;
|
||||||
while ((row=mysql_fetch_row(tableRes)))
|
while ((row=mysql_fetch_row(tableRes)))
|
||||||
{
|
{
|
||||||
|
if (opt_xml)
|
||||||
|
{
|
||||||
|
print_xml_row(sql_file, "key", tableRes, &row);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (atoi(row[3]) == 1)
|
if (atoi(row[3]) == 1)
|
||||||
{
|
{
|
||||||
if (keynr++)
|
if (keynr++)
|
||||||
@ -924,14 +967,26 @@ static uint getTableStructure(char *table, char* db)
|
|||||||
if (row[7])
|
if (row[7])
|
||||||
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
|
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
|
||||||
}
|
}
|
||||||
if (keynr)
|
if (!opt_xml)
|
||||||
putc(')', sql_file);
|
{
|
||||||
fputs("\n)",sql_file);
|
if (keynr)
|
||||||
|
putc(')', sql_file);
|
||||||
|
fputs("\n)",sql_file);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get MySQL specific create options */
|
/* Get MySQL specific create options */
|
||||||
if (create_options)
|
if (create_options)
|
||||||
{
|
{
|
||||||
sprintf(buff,"show table status like %s",result_table);
|
ulong len= strlen(table);
|
||||||
|
char *tmp= (char*) my_malloc(len * 2 + 1, MYF(MY_WME));
|
||||||
|
if (!tmp)
|
||||||
|
{
|
||||||
|
ignore_errors= 0;
|
||||||
|
safe_exit(EX_MYSQLERR);
|
||||||
|
}
|
||||||
|
mysql_real_escape_string(&mysql_connection, tmp, table, len);
|
||||||
|
sprintf(buff,"show table status like \"%s\"", tmp);
|
||||||
|
my_free(tmp, MYF(MY_WME));
|
||||||
if (mysql_query(sock, buff))
|
if (mysql_query(sock, buff))
|
||||||
{
|
{
|
||||||
if (mysql_errno(sock) != ER_PARSE_ERROR)
|
if (mysql_errno(sock) != ER_PARSE_ERROR)
|
||||||
@ -951,15 +1006,25 @@ static uint getTableStructure(char *table, char* db)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fputs("/*!",sql_file);
|
if (opt_xml)
|
||||||
print_value(sql_file,tableRes,row,"type=","Type",0);
|
{
|
||||||
print_value(sql_file,tableRes,row,"","Create_options",0);
|
print_xml_row(sql_file, "options", tableRes, &row);
|
||||||
print_value(sql_file,tableRes,row,"comment=","Comment",1);
|
}
|
||||||
fputs(" */",sql_file);
|
else
|
||||||
|
{
|
||||||
|
fputs("/*!",sql_file);
|
||||||
|
print_value(sql_file,tableRes,row,"type=","Type",0);
|
||||||
|
print_value(sql_file,tableRes,row,"","Create_options",0);
|
||||||
|
print_value(sql_file,tableRes,row,"comment=","Comment",1);
|
||||||
|
fputs(" */",sql_file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mysql_free_result(tableRes); /* Is always safe to free */
|
mysql_free_result(tableRes); /* Is always safe to free */
|
||||||
}
|
}
|
||||||
fputs(";\n", sql_file);
|
if (!opt_xml)
|
||||||
|
fputs(";\n", sql_file);
|
||||||
|
else
|
||||||
|
fputs("\t</table_structure>\n", sql_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cFlag)
|
if (cFlag)
|
||||||
@ -1127,7 +1192,9 @@ static void dumpTable(uint numFields, char *table)
|
|||||||
rownr=0;
|
rownr=0;
|
||||||
init_length=(uint) strlen(insert_pat)+4;
|
init_length=(uint) strlen(insert_pat)+4;
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(md_result_file, "\t<table name=\"%s\">\n", table);
|
{
|
||||||
|
print_xml_tag(md_result_file, "\t<table_data name=\"", table, "\">\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_autocommit)
|
if (opt_autocommit)
|
||||||
fprintf(md_result_file, "set autocommit=0;\n");
|
fprintf(md_result_file, "set autocommit=0;\n");
|
||||||
@ -1142,7 +1209,7 @@ static void dumpTable(uint numFields, char *table)
|
|||||||
mysql_field_seek(res,0);
|
mysql_field_seek(res,0);
|
||||||
|
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(md_result_file, "\t<row>\n");
|
fputs("\t<row>\n", md_result_file);
|
||||||
|
|
||||||
for (i = 0; i < mysql_num_fields(res); i++)
|
for (i = 0; i < mysql_num_fields(res); i++)
|
||||||
{
|
{
|
||||||
@ -1207,8 +1274,12 @@ static void dumpTable(uint numFields, char *table)
|
|||||||
if (!IS_NUM_FIELD(field))
|
if (!IS_NUM_FIELD(field))
|
||||||
{
|
{
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
print_quoted_xml(md_result_file, field->name, row[i],
|
{
|
||||||
lengths[i]);
|
print_xml_tag(md_result_file, "\t\t<field name=\"", field->name,
|
||||||
|
"\">");
|
||||||
|
print_quoted_xml(md_result_file, row[i], lengths[i]);
|
||||||
|
fputs("</field>\n", md_result_file);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
unescape(md_result_file, row[i], lengths[i]);
|
unescape(md_result_file, row[i], lengths[i]);
|
||||||
}
|
}
|
||||||
@ -1217,9 +1288,13 @@ static void dumpTable(uint numFields, char *table)
|
|||||||
/* change any strings ("inf","nan",..) into NULL */
|
/* change any strings ("inf","nan",..) into NULL */
|
||||||
char *ptr = row[i];
|
char *ptr = row[i];
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(md_result_file, "\t\t<field name=\"%s\">%s</field>\n",
|
{
|
||||||
field->name,
|
print_xml_tag(md_result_file, "\t\t<field name=\"", field->name,
|
||||||
!my_isalpha(charset_info, *ptr) ? ptr: "NULL");
|
"\">");
|
||||||
|
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
|
||||||
|
md_result_file);
|
||||||
|
fputs("</field>\n", md_result_file);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fputs((!my_isalpha(charset_info,*ptr)) ?
|
fputs((!my_isalpha(charset_info,*ptr)) ?
|
||||||
ptr : "NULL", md_result_file);
|
ptr : "NULL", md_result_file);
|
||||||
@ -1228,8 +1303,10 @@ static void dumpTable(uint numFields, char *table)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(md_result_file, "\t\t<field name=\"%s\">%s</field>\n",
|
{
|
||||||
field->name, "NULL");
|
print_xml_tag(md_result_file, "\t\t<field name=\"", field->name,
|
||||||
|
"\">NULL</field>\n");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fputs("NULL", md_result_file);
|
fputs("NULL", md_result_file);
|
||||||
}
|
}
|
||||||
@ -1237,7 +1314,7 @@ static void dumpTable(uint numFields, char *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(md_result_file, "\t</row>\n");
|
fputs("\t</row>\n", md_result_file);
|
||||||
|
|
||||||
if (extended_insert)
|
if (extended_insert)
|
||||||
{
|
{
|
||||||
@ -1267,7 +1344,7 @@ static void dumpTable(uint numFields, char *table)
|
|||||||
|
|
||||||
/* XML - close table tag and supress regular output */
|
/* XML - close table tag and supress regular output */
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(md_result_file, "\t</table>\n");
|
fputs("\t</table_data>\n", md_result_file);
|
||||||
else if (extended_insert && row_break)
|
else if (extended_insert && row_break)
|
||||||
fputs(";\n", md_result_file); /* If not empty table */
|
fputs(";\n", md_result_file); /* If not empty table */
|
||||||
fflush(md_result_file);
|
fflush(md_result_file);
|
||||||
@ -1295,25 +1372,30 @@ static void dumpTable(uint numFields, char *table)
|
|||||||
} /* dumpTable */
|
} /* dumpTable */
|
||||||
|
|
||||||
|
|
||||||
static void print_quoted_xml(FILE *output, char *fname, char *str, uint len)
|
static void print_quoted_xml(FILE *output, char *str, ulong len)
|
||||||
{
|
{
|
||||||
const char *end;
|
const char *end= str + (len ? len : strlen(str));
|
||||||
|
|
||||||
fprintf(output, "\t\t<field name=\"%s\">", fname);
|
for (; str != end; str++)
|
||||||
for (end = str + len; str != end; str++)
|
|
||||||
{
|
{
|
||||||
if (*str == '<')
|
switch (*str) {
|
||||||
|
case '<':
|
||||||
fputs("<", output);
|
fputs("<", output);
|
||||||
else if (*str == '>')
|
break;
|
||||||
|
case '>':
|
||||||
fputs(">", output);
|
fputs(">", output);
|
||||||
else if (*str == '&')
|
break;
|
||||||
|
case '&':
|
||||||
fputs("&", output);
|
fputs("&", output);
|
||||||
else if (*str == '\"')
|
break;
|
||||||
|
case '\"':
|
||||||
fputs(""", output);
|
fputs(""", output);
|
||||||
else
|
break;
|
||||||
|
default:
|
||||||
fputc(*str, output);
|
fputc(*str, output);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fprintf(output, "</field>\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *getTableName(int reset)
|
static char *getTableName(int reset)
|
||||||
@ -1434,7 +1516,9 @@ static int dump_all_tables_in_db(char *database)
|
|||||||
if (init_dumping(database))
|
if (init_dumping(database))
|
||||||
return 1;
|
return 1;
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(md_result_file, "<database name=\"%s\">\n", database);
|
{
|
||||||
|
print_xml_tag(md_result_file, "<database name=\"", database, "\">\n");
|
||||||
|
}
|
||||||
if (lock_tables)
|
if (lock_tables)
|
||||||
{
|
{
|
||||||
DYNAMIC_STRING query;
|
DYNAMIC_STRING query;
|
||||||
@ -1462,7 +1546,7 @@ static int dump_all_tables_in_db(char *database)
|
|||||||
dumpTable(numrows,table);
|
dumpTable(numrows,table);
|
||||||
}
|
}
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(md_result_file, "</database>\n");
|
fputs("</database>\n", md_result_file);
|
||||||
if (lock_tables)
|
if (lock_tables)
|
||||||
mysql_query(sock,"UNLOCK_TABLES");
|
mysql_query(sock,"UNLOCK_TABLES");
|
||||||
return 0;
|
return 0;
|
||||||
@ -1500,7 +1584,9 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
|
|||||||
/* We shall countinue here, if --force was given */
|
/* We shall countinue here, if --force was given */
|
||||||
}
|
}
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(md_result_file, "<database name=\"%s\">\n", db);
|
{
|
||||||
|
print_xml_tag(md_result_file, "<database name=\"", db, "\">\n");
|
||||||
|
}
|
||||||
for (; tables > 0 ; tables-- , table_names++)
|
for (; tables > 0 ; tables-- , table_names++)
|
||||||
{
|
{
|
||||||
numrows = getTableStructure(*table_names, db);
|
numrows = getTableStructure(*table_names, db);
|
||||||
@ -1508,7 +1594,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
|
|||||||
dumpTable(numrows, *table_names);
|
dumpTable(numrows, *table_names);
|
||||||
}
|
}
|
||||||
if (opt_xml)
|
if (opt_xml)
|
||||||
fprintf(md_result_file, "</database>\n");
|
fputs("</database>\n", md_result_file);
|
||||||
if (lock_tables)
|
if (lock_tables)
|
||||||
mysql_query(sock,"UNLOCK_TABLES");
|
mysql_query(sock,"UNLOCK_TABLES");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#define HA_OPEN_DELAY_KEY_WRITE 8 /* Don't update index */
|
#define HA_OPEN_DELAY_KEY_WRITE 8 /* Don't update index */
|
||||||
#define HA_OPEN_ABORT_IF_CRASHED 16
|
#define HA_OPEN_ABORT_IF_CRASHED 16
|
||||||
#define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */
|
#define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */
|
||||||
|
#define HA_OPEN_TO_ASSIGN 64 /* Open for key cache assignment */
|
||||||
|
|
||||||
/* The following is parameter to ha_rkey() how to use key */
|
/* The following is parameter to ha_rkey() how to use key */
|
||||||
|
|
||||||
@ -131,7 +132,8 @@ enum ha_extra_function {
|
|||||||
current query id */
|
current query id */
|
||||||
HA_EXTRA_PREPARE_FOR_DELETE,
|
HA_EXTRA_PREPARE_FOR_DELETE,
|
||||||
HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */
|
HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */
|
||||||
HA_EXTRA_PRELOAD_BUFFER_SIZE /* Set buffer size for preloading */
|
HA_EXTRA_PRELOAD_BUFFER_SIZE, /* Set buffer size for preloading */
|
||||||
|
HA_EXTRA_SET_KEY_CACHE /* Set ref to assigned key cache */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The following is parameter to ha_panic() */
|
/* The following is parameter to ha_panic() */
|
||||||
|
@ -558,6 +558,9 @@ typedef SOCKET_SIZE_TYPE size_socket;
|
|||||||
#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD)
|
#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD)
|
||||||
/* Typical key cash */
|
/* Typical key cash */
|
||||||
#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD)
|
#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD)
|
||||||
|
/* Default size of a key cache block */
|
||||||
|
#define KEY_CACHE_BLOCK_SIZE (uint) 1024
|
||||||
|
|
||||||
|
|
||||||
/* Some things that this system doesn't have */
|
/* Some things that this system doesn't have */
|
||||||
|
|
||||||
|
@ -111,8 +111,6 @@ extern int NEAR my_errno; /* Last error in mysys */
|
|||||||
#define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */
|
#define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */
|
||||||
#define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */
|
#define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */
|
||||||
#define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */
|
#define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */
|
||||||
#define DEFAULT_KEYCACHE_BLOCK_SIZE 1024
|
|
||||||
#define MAX_KEYCACHE_BLOCK_SIZE 16384
|
|
||||||
|
|
||||||
/* root_alloc flags */
|
/* root_alloc flags */
|
||||||
#define MY_KEEP_PREALLOC 1
|
#define MY_KEEP_PREALLOC 1
|
||||||
@ -267,7 +265,8 @@ enum cache_type
|
|||||||
|
|
||||||
enum flush_type
|
enum flush_type
|
||||||
{
|
{
|
||||||
FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, FLUSH_FORCE_WRITE
|
FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, FLUSH_FORCE_WRITE,
|
||||||
|
FLUSH_REMOVE
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct st_record_cache /* Used when cacheing records */
|
typedef struct st_record_cache /* Used when cacheing records */
|
||||||
@ -504,14 +503,46 @@ my_off_t my_b_append_tell(IO_CACHE* info);
|
|||||||
#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
|
#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
|
||||||
*(info)->current_pos)
|
*(info)->current_pos)
|
||||||
|
|
||||||
/* key_cache_variables */
|
|
||||||
typedef struct st_keycache
|
|
||||||
{
|
|
||||||
ulonglong size;
|
|
||||||
} KEY_CACHE;
|
|
||||||
|
|
||||||
typedef uint32 ha_checksum;
|
typedef uint32 ha_checksum;
|
||||||
|
|
||||||
|
/* Pointer to a key cache data structure (see the key cache module) */
|
||||||
|
typedef struct st_key_cache* KEY_CACHE_HANDLE;
|
||||||
|
|
||||||
|
/* Key cache variable structure */
|
||||||
|
/*
|
||||||
|
The structure contains the parameters of a key cache that can
|
||||||
|
be set and undated by regular set global statements.
|
||||||
|
It also contains read-only statistics parameters.
|
||||||
|
If the corresponding key cache data structure has been already
|
||||||
|
created the variable contains the key cache handle.
|
||||||
|
The variables are put into a named list called key_caches.
|
||||||
|
At present the variables are only added to this list.
|
||||||
|
*/
|
||||||
|
typedef struct st_key_cache_var
|
||||||
|
{
|
||||||
|
ulonglong buff_size; /* size the memory allocated for the cache */
|
||||||
|
ulong block_size; /* size of the blocks in the key cache */
|
||||||
|
ulong division_limit; /* min. percentage of warm blocks */
|
||||||
|
ulong age_threshold; /* determines when hot block is downgraded */
|
||||||
|
KEY_CACHE_HANDLE cache; /* handles for the current and registered */
|
||||||
|
ulong blocks_used; /* number of currently used blocks */
|
||||||
|
ulong blocks_changed; /* number of currently dirty blocks */
|
||||||
|
ulong cache_w_requests; /* number of write requests (write hits) */
|
||||||
|
ulong cache_write; /* number of writes from the cache to files */
|
||||||
|
ulong cache_r_requests; /* number of read requests (read hits) */
|
||||||
|
ulong cache_read; /* number of reads from files to the cache */
|
||||||
|
int blocks; /* max number of blocks in the cache */
|
||||||
|
struct st_key_cache_asmt *assign_list; /* list of assignments to the cache */
|
||||||
|
int assignments; /* number of not completed assignments */
|
||||||
|
void (*action)(void *); /* optional call back function */
|
||||||
|
void *extra_info; /* ptr to extra info */
|
||||||
|
} KEY_CACHE_VAR;
|
||||||
|
|
||||||
|
#define DEFAULT_KEY_CACHE_NAME "default"
|
||||||
|
extern KEY_CACHE_HANDLE *dflt_keycache;
|
||||||
|
extern KEY_CACHE_VAR dflt_key_cache_var;
|
||||||
|
#define DFLT_INIT_HITS 3
|
||||||
|
|
||||||
#include <my_alloc.h>
|
#include <my_alloc.h>
|
||||||
|
|
||||||
/* Prototypes for mysys and my_func functions */
|
/* Prototypes for mysys and my_func functions */
|
||||||
@ -650,16 +681,26 @@ extern int flush_write_cache(RECORD_CACHE *info);
|
|||||||
extern long my_clock(void);
|
extern long my_clock(void);
|
||||||
extern sig_handler sigtstp_handler(int signal_number);
|
extern sig_handler sigtstp_handler(int signal_number);
|
||||||
extern void handle_recived_signals(void);
|
extern void handle_recived_signals(void);
|
||||||
extern int init_key_cache(ulong use_mem);
|
extern int init_key_cache(KEY_CACHE_HANDLE *pkeycache,
|
||||||
extern int resize_key_cache(ulong use_mem);
|
uint key_cache_block_size,
|
||||||
extern byte *key_cache_read(File file,my_off_t filepos,byte* buff,uint length,
|
ulong use_mem, KEY_CACHE_VAR* env);
|
||||||
|
extern int resize_key_cache(KEY_CACHE_HANDLE *pkeycache,
|
||||||
|
uint key_cache_block_size, ulong use_mem);
|
||||||
|
extern void change_key_cache_param(KEY_CACHE_HANDLE keycache);
|
||||||
|
extern byte *key_cache_read(KEY_CACHE_HANDLE keycache,
|
||||||
|
File file, my_off_t filepos, int level,
|
||||||
|
byte* buff, uint length,
|
||||||
uint block_length,int return_buffer);
|
uint block_length,int return_buffer);
|
||||||
extern int key_cache_insert(File file, my_off_t filepos,
|
extern int key_cache_insert(KEY_CACHE_HANDLE keycache,
|
||||||
|
File file, my_off_t filepos, int level,
|
||||||
byte *buff, uint length);
|
byte *buff, uint length);
|
||||||
extern int key_cache_write(File file,my_off_t filepos,byte* buff,uint length,
|
extern int key_cache_write(KEY_CACHE_HANDLE keycache,
|
||||||
|
File file, my_off_t filepos, int level,
|
||||||
|
byte* buff, uint length,
|
||||||
uint block_length,int force_write);
|
uint block_length,int force_write);
|
||||||
extern int flush_key_blocks(int file, enum flush_type type);
|
extern int flush_key_blocks(KEY_CACHE_HANDLE keycache,
|
||||||
extern void end_key_cache(void);
|
int file, enum flush_type type);
|
||||||
|
extern void end_key_cache(KEY_CACHE_HANDLE *pkeycache,my_bool cleanup);
|
||||||
extern sig_handler my_set_alarm_variable(int signo);
|
extern sig_handler my_set_alarm_variable(int signo);
|
||||||
extern void my_string_ptr_sort(void *base,uint items,size_s size);
|
extern void my_string_ptr_sort(void *base,uint items,size_s size);
|
||||||
extern void radixsort_for_str_ptr(uchar* base[], uint number_of_elements,
|
extern void radixsort_for_str_ptr(uchar* base[], uint number_of_elements,
|
||||||
|
@ -408,6 +408,9 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map,
|
|||||||
int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows);
|
int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows);
|
||||||
void mi_flush_bulk_insert(MI_INFO *info, uint inx);
|
void mi_flush_bulk_insert(MI_INFO *info, uint inx);
|
||||||
void mi_end_bulk_insert(MI_INFO *info);
|
void mi_end_bulk_insert(MI_INFO *info);
|
||||||
|
int mi_assign_to_keycache(MI_INFO *info, ulonglong key_map,
|
||||||
|
KEY_CACHE_VAR *key_cache,
|
||||||
|
pthread_mutex_t *assign_lock);
|
||||||
int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves);
|
int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -50,7 +50,7 @@ int nisam_lock_database(N_INFO *info, int lock_type)
|
|||||||
else
|
else
|
||||||
count= --share->w_locks;
|
count= --share->w_locks;
|
||||||
if (info->lock_type == F_WRLCK && !share->w_locks &&
|
if (info->lock_type == F_WRLCK && !share->w_locks &&
|
||||||
flush_key_blocks(share->kfile,FLUSH_KEEP))
|
flush_key_blocks(*dflt_keycache,share->kfile,FLUSH_KEEP))
|
||||||
error=my_errno;
|
error=my_errno;
|
||||||
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
|
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
|
||||||
if (end_io_cache(&info->rec_cache))
|
if (end_io_cache(&info->rec_cache))
|
||||||
@ -329,7 +329,7 @@ int _nisam_test_if_changed(register N_INFO *info)
|
|||||||
share->state.uniq != info->last_uniq)
|
share->state.uniq != info->last_uniq)
|
||||||
{ /* Keyfile has changed */
|
{ /* Keyfile has changed */
|
||||||
if (share->state.process != share->this_process)
|
if (share->state.process != share->this_process)
|
||||||
VOID(flush_key_blocks(share->kfile,FLUSH_RELEASE));
|
VOID(flush_key_blocks(*dflt_keycache,share->kfile,FLUSH_RELEASE));
|
||||||
share->last_process=share->state.process;
|
share->last_process=share->state.process;
|
||||||
info->last_loop= share->state.loop;
|
info->last_loop= share->state.loop;
|
||||||
info->last_uniq= share->state.uniq;
|
info->last_uniq= share->state.uniq;
|
||||||
|
24
isam/_page.c
24
isam/_page.c
@ -27,10 +27,11 @@ uchar *_nisam_fetch_keypage(register N_INFO *info, N_KEYDEF *keyinfo,
|
|||||||
my_off_t page, uchar *buff, int return_buffer)
|
my_off_t page, uchar *buff, int return_buffer)
|
||||||
{
|
{
|
||||||
uchar *tmp;
|
uchar *tmp;
|
||||||
tmp=(uchar*) key_cache_read(info->s->kfile,page,(byte*) buff,
|
tmp=(uchar*) key_cache_read(*dflt_keycache,
|
||||||
(uint) keyinfo->base.block_length,
|
info->s->kfile,page,DFLT_INIT_HITS,(byte*) buff,
|
||||||
(uint) keyinfo->base.block_length,
|
(uint) keyinfo->base.block_length,
|
||||||
return_buffer);
|
(uint) keyinfo->base.block_length,
|
||||||
|
return_buffer);
|
||||||
if (tmp == info->buff)
|
if (tmp == info->buff)
|
||||||
{
|
{
|
||||||
info->update|=HA_STATE_BUFF_SAVED;
|
info->update|=HA_STATE_BUFF_SAVED;
|
||||||
@ -83,9 +84,11 @@ int _nisam_write_keypage(register N_INFO *info, register N_KEYDEF *keyinfo,
|
|||||||
length=keyinfo->base.block_length;
|
length=keyinfo->base.block_length;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return (key_cache_write(info->s->kfile,page,(byte*) buff,length,
|
return (key_cache_write(*dflt_keycache,
|
||||||
(uint) keyinfo->base.block_length,
|
info->s->kfile,page,DFLT_INIT_HITS,
|
||||||
(int) (info->lock_type != F_UNLCK)));
|
(byte*) buff,length,
|
||||||
|
(uint) keyinfo->base.block_length,
|
||||||
|
(int) (info->lock_type != F_UNLCK)));
|
||||||
} /* nisam_write_keypage */
|
} /* nisam_write_keypage */
|
||||||
|
|
||||||
|
|
||||||
@ -99,7 +102,9 @@ int _nisam_dispose(register N_INFO *info, N_KEYDEF *keyinfo, my_off_t pos)
|
|||||||
|
|
||||||
old_link=info->s->state.key_del[keynr];
|
old_link=info->s->state.key_del[keynr];
|
||||||
info->s->state.key_del[keynr]=(ulong) pos;
|
info->s->state.key_del[keynr]=(ulong) pos;
|
||||||
DBUG_RETURN(key_cache_write(info->s->kfile,pos,(byte*) &old_link,
|
DBUG_RETURN(key_cache_write(*dflt_keycache,
|
||||||
|
info->s->kfile,pos,DFLT_INIT_HITS,
|
||||||
|
(byte*) &old_link,
|
||||||
sizeof(long),
|
sizeof(long),
|
||||||
(uint) keyinfo->base.block_length,
|
(uint) keyinfo->base.block_length,
|
||||||
(int) (info->lock_type != F_UNLCK)));
|
(int) (info->lock_type != F_UNLCK)));
|
||||||
@ -126,7 +131,8 @@ ulong _nisam_new(register N_INFO *info, N_KEYDEF *keyinfo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!key_cache_read(info->s->kfile,pos,
|
if (!key_cache_read(*dflt_keycache,
|
||||||
|
info->s->kfile,pos,DFLT_INIT_HITS,
|
||||||
(byte*) &info->s->state.key_del[keynr],
|
(byte*) &info->s->state.key_del[keynr],
|
||||||
(uint) sizeof(long),
|
(uint) sizeof(long),
|
||||||
(uint) keyinfo->base.block_length,0))
|
(uint) keyinfo->base.block_length,0))
|
||||||
|
@ -56,7 +56,8 @@ int nisam_close(register N_INFO *info)
|
|||||||
|
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
if (share->kfile >= 0 && flush_key_blocks(share->kfile,FLUSH_RELEASE))
|
if (share->kfile >= 0 &&
|
||||||
|
flush_key_blocks(*dflt_keycache,share->kfile,FLUSH_RELEASE))
|
||||||
error=my_errno;
|
error=my_errno;
|
||||||
if (share->kfile >= 0 && my_close(share->kfile,MYF(0)))
|
if (share->kfile >= 0 && my_close(share->kfile,MYF(0)))
|
||||||
error = my_errno;
|
error = my_errno;
|
||||||
|
@ -516,7 +516,8 @@ static int nisamchk(my_string filename)
|
|||||||
if (!rep_quick)
|
if (!rep_quick)
|
||||||
{
|
{
|
||||||
if (testflag & T_EXTEND)
|
if (testflag & T_EXTEND)
|
||||||
VOID(init_key_cache(use_buffers));
|
VOID(init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,
|
||||||
|
use_buffers,&dflt_key_cache_var));
|
||||||
VOID(init_io_cache(&read_cache,datafile,(uint) read_buffer_length,
|
VOID(init_io_cache(&read_cache,datafile,(uint) read_buffer_length,
|
||||||
READ_CACHE,share->pack.header_length,1,
|
READ_CACHE,share->pack.header_length,1,
|
||||||
MYF(MY_WME)));
|
MYF(MY_WME)));
|
||||||
@ -1459,7 +1460,8 @@ my_string name;
|
|||||||
printf("Data records: %lu\n",(ulong) share->state.records);
|
printf("Data records: %lu\n",(ulong) share->state.records);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID(init_key_cache(use_buffers));
|
VOID(init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,use_buffers,
|
||||||
|
&dflt_key_cache_var));
|
||||||
if (init_io_cache(&read_cache,info->dfile,(uint) read_buffer_length,
|
if (init_io_cache(&read_cache,info->dfile,(uint) read_buffer_length,
|
||||||
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)))
|
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)))
|
||||||
goto err;
|
goto err;
|
||||||
@ -1887,12 +1889,12 @@ static void lock_memory(void)
|
|||||||
static int flush_blocks(file)
|
static int flush_blocks(file)
|
||||||
File file;
|
File file;
|
||||||
{
|
{
|
||||||
if (flush_key_blocks(file,FLUSH_RELEASE))
|
if (flush_key_blocks(dflt_keycache,file,FLUSH_RELEASE))
|
||||||
{
|
{
|
||||||
print_error("%d when trying to write bufferts",my_errno);
|
print_error("%d when trying to write bufferts",my_errno);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
end_key_cache();
|
end_key_cache(dflt_keycache,1);
|
||||||
return 0;
|
return 0;
|
||||||
} /* flush_blocks */
|
} /* flush_blocks */
|
||||||
|
|
||||||
@ -1936,7 +1938,8 @@ int write_info;
|
|||||||
if (share->state.key_root[sort_key] == NI_POS_ERROR)
|
if (share->state.key_root[sort_key] == NI_POS_ERROR)
|
||||||
DBUG_RETURN(0); /* Nothing to do */
|
DBUG_RETURN(0); /* Nothing to do */
|
||||||
|
|
||||||
init_key_cache(use_buffers);
|
init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,use_buffers,
|
||||||
|
&dflt_key_cache_var);
|
||||||
if (init_io_cache(&info->rec_cache,-1,(uint) write_buffer_length,
|
if (init_io_cache(&info->rec_cache,-1,(uint) write_buffer_length,
|
||||||
WRITE_CACHE,share->pack.header_length,1,
|
WRITE_CACHE,share->pack.header_length,1,
|
||||||
MYF(MY_WME | MY_WAIT_IF_FULL)))
|
MYF(MY_WME | MY_WAIT_IF_FULL)))
|
||||||
|
@ -329,8 +329,8 @@ static int examine_log(my_string file_name, char **table_names)
|
|||||||
bzero((gptr) com_count,sizeof(com_count));
|
bzero((gptr) com_count,sizeof(com_count));
|
||||||
init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
|
init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
|
||||||
(tree_element_free) file_info_free, NULL);
|
(tree_element_free) file_info_free, NULL);
|
||||||
VOID(init_key_cache(KEY_CACHE_SIZE));
|
VOID(init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE,
|
||||||
|
&dflt_key_cache_var));
|
||||||
files_open=0; access_time=0;
|
files_open=0; access_time=0;
|
||||||
while (access_time++ != number_of_commands &&
|
while (access_time++ != number_of_commands &&
|
||||||
!my_b_read(&cache,(byte*) head,9))
|
!my_b_read(&cache,(byte*) head,9))
|
||||||
@ -622,7 +622,7 @@ static int examine_log(my_string file_name, char **table_names)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end_key_cache();
|
end_key_cache(dflt_keycache,1);
|
||||||
delete_tree(&tree);
|
delete_tree(&tree);
|
||||||
VOID(end_io_cache(&cache));
|
VOID(end_io_cache(&cache));
|
||||||
VOID(my_close(file,MYF(0)));
|
VOID(my_close(file,MYF(0)));
|
||||||
@ -642,7 +642,7 @@ static int examine_log(my_string file_name, char **table_names)
|
|||||||
llstr(isamlog_filepos,llbuff)));
|
llstr(isamlog_filepos,llbuff)));
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
end:
|
end:
|
||||||
end_key_cache();
|
end_key_cache(dflt_keycache,1);
|
||||||
delete_tree(&tree);
|
delete_tree(&tree);
|
||||||
VOID(end_io_cache(&cache));
|
VOID(end_io_cache(&cache));
|
||||||
VOID(my_close(file,MYF(0)));
|
VOID(my_close(file,MYF(0)));
|
||||||
|
@ -48,7 +48,7 @@ int nisam_panic(enum ha_panic_function flag)
|
|||||||
if (info->s->base.options & HA_OPTION_READ_ONLY_DATA)
|
if (info->s->base.options & HA_OPTION_READ_ONLY_DATA)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
if (flush_key_blocks(info->s->kfile,FLUSH_RELEASE))
|
if (flush_key_blocks(*dflt_keycache,info->s->kfile,FLUSH_RELEASE))
|
||||||
error=my_errno;
|
error=my_errno;
|
||||||
if (info->opt_flag & WRITE_CACHE_USED)
|
if (info->opt_flag & WRITE_CACHE_USED)
|
||||||
if (flush_io_cache(&info->rec_cache))
|
if (flush_io_cache(&info->rec_cache))
|
||||||
|
@ -156,7 +156,7 @@ int main(int argc, char *argv[])
|
|||||||
goto err;
|
goto err;
|
||||||
printf("- Writing key:s\n");
|
printf("- Writing key:s\n");
|
||||||
if (key_cacheing)
|
if (key_cacheing)
|
||||||
init_key_cache(IO_SIZE*16); /* Use a small cache */
|
init_key_cache(dflt_keycache,512,IO_SIZE*16,0); /* Use a small cache */
|
||||||
if (locking)
|
if (locking)
|
||||||
nisam_lock_database(file,F_WRLCK);
|
nisam_lock_database(file,F_WRLCK);
|
||||||
if (write_cacheing)
|
if (write_cacheing)
|
||||||
@ -674,7 +674,7 @@ end:
|
|||||||
puts("Locking used");
|
puts("Locking used");
|
||||||
if (use_blob)
|
if (use_blob)
|
||||||
puts("blobs used");
|
puts("blobs used");
|
||||||
end_key_cache();
|
end_key_cache(&dflt_keycache,1);
|
||||||
if (blob_buffer)
|
if (blob_buffer)
|
||||||
my_free(blob_buffer,MYF(0));
|
my_free(blob_buffer,MYF(0));
|
||||||
my_end(MY_CHECK_ERROR | MY_GIVE_INFO);
|
my_end(MY_CHECK_ERROR | MY_GIVE_INFO);
|
||||||
|
@ -173,7 +173,7 @@ void start_test(int id)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (key_cacheing && rnd(2) == 0)
|
if (key_cacheing && rnd(2) == 0)
|
||||||
init_key_cache(65536L);
|
init_key_cache(dflt_keycache,512,65536L,0);
|
||||||
printf("Process %d, pid: %d\n",id,(int) getpid()); fflush(stdout);
|
printf("Process %d, pid: %d\n",id,(int) getpid()); fflush(stdout);
|
||||||
|
|
||||||
for (error=i=0 ; i < tests && !error; i++)
|
for (error=i=0 ; i < tests && !error; i++)
|
||||||
|
@ -47,7 +47,7 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
|
|||||||
mi_range.c mi_dbug.c mi_checksum.c mi_log.c \
|
mi_range.c mi_dbug.c mi_checksum.c mi_log.c \
|
||||||
mi_changed.c mi_static.c mi_delete_all.c \
|
mi_changed.c mi_static.c mi_delete_all.c \
|
||||||
mi_delete_table.c mi_rename.c mi_check.c \
|
mi_delete_table.c mi_rename.c mi_check.c \
|
||||||
mi_preload.c \
|
mi_keycache.c mi_preload.c \
|
||||||
ft_parser.c ft_stopwords.c ft_static.c \
|
ft_parser.c ft_stopwords.c ft_static.c \
|
||||||
ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \
|
ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \
|
||||||
rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c
|
rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c
|
||||||
|
@ -241,7 +241,9 @@ static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
|
|||||||
if (next_link > info->state->key_file_length ||
|
if (next_link > info->state->key_file_length ||
|
||||||
next_link & (info->s->blocksize-1))
|
next_link & (info->s->blocksize-1))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if (!(buff=key_cache_read(info->s->kfile, next_link, (byte*) info->buff,
|
if (!(buff=key_cache_read(*info->s->keycache,
|
||||||
|
info->s->kfile, next_link, DFLT_INIT_HITS,
|
||||||
|
(byte*) info->buff,
|
||||||
myisam_block_size, block_size, 1)))
|
myisam_block_size, block_size, 1)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
next_link=mi_sizekorr(buff);
|
next_link=mi_sizekorr(buff);
|
||||||
@ -270,7 +272,8 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
|
|||||||
|
|
||||||
if (!(param->testflag & T_SILENT)) puts("- check file-size");
|
if (!(param->testflag & T_SILENT)) puts("- check file-size");
|
||||||
|
|
||||||
flush_key_blocks(info->s->kfile, FLUSH_FORCE_WRITE); /* If called externally */
|
flush_key_blocks(*info->s->keycache,
|
||||||
|
info->s->kfile, FLUSH_FORCE_WRITE); /* If called externally */
|
||||||
|
|
||||||
size=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0));
|
size=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0));
|
||||||
if ((skr=(my_off_t) info->state->key_file_length) != size)
|
if ((skr=(my_off_t) info->state->key_file_length) != size)
|
||||||
@ -380,8 +383,8 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
|
|||||||
if (share->state.key_root[key] == HA_OFFSET_ERROR &&
|
if (share->state.key_root[key] == HA_OFFSET_ERROR &&
|
||||||
(info->state->records == 0 || keyinfo->flag & HA_FULLTEXT))
|
(info->state->records == 0 || keyinfo->flag & HA_FULLTEXT))
|
||||||
continue;
|
continue;
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,share->state.key_root[key],info->buff,
|
if (!_mi_fetch_keypage(info,keyinfo,share->state.key_root[key],
|
||||||
0))
|
DFLT_INIT_HITS,info->buff,0))
|
||||||
{
|
{
|
||||||
mi_check_print_error(param,"Can't read indexpage from filepos: %s",
|
mi_check_print_error(param,"Can't read indexpage from filepos: %s",
|
||||||
llstr(share->state.key_root[key],buff));
|
llstr(share->state.key_root[key],buff));
|
||||||
@ -559,7 +562,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
info->state->key_file_length=(max_length &
|
info->state->key_file_length=(max_length &
|
||||||
~ (my_off_t) (info->s->blocksize-1));
|
~ (my_off_t) (info->s->blocksize-1));
|
||||||
}
|
}
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,next_page,temp_buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,next_page,
|
||||||
|
DFLT_INIT_HITS,temp_buff,0))
|
||||||
{
|
{
|
||||||
mi_check_print_error(param,"Can't read key from filepos: %s",llstr(next_page,llbuff));
|
mi_check_print_error(param,"Can't read key from filepos: %s",llstr(next_page,llbuff));
|
||||||
goto err;
|
goto err;
|
||||||
@ -1138,7 +1142,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
|
|||||||
param->testflag|=T_REP; /* for easy checking */
|
param->testflag|=T_REP; /* for easy checking */
|
||||||
|
|
||||||
if (!param->using_global_keycache)
|
if (!param->using_global_keycache)
|
||||||
VOID(init_key_cache(param->use_buffers));
|
VOID(init_key_cache(dflt_keycache,dflt_key_cache_var.block_size,
|
||||||
|
param->use_buffers,&dflt_key_cache_var));
|
||||||
|
|
||||||
if (init_io_cache(¶m->read_cache,info->dfile,
|
if (init_io_cache(¶m->read_cache,info->dfile,
|
||||||
(uint) param->read_buffer_length,
|
(uint) param->read_buffer_length,
|
||||||
@ -1459,7 +1464,8 @@ int movepoint(register MI_INFO *info, byte *record, my_off_t oldpos,
|
|||||||
nod_flag=mi_test_if_nod(info->buff);
|
nod_flag=mi_test_if_nod(info->buff);
|
||||||
_mi_dpointer(info,info->int_keypos-nod_flag-
|
_mi_dpointer(info,info->int_keypos-nod_flag-
|
||||||
info->s->rec_reflength,newpos);
|
info->s->rec_reflength,newpos);
|
||||||
if (_mi_write_keypage(info,keyinfo,info->last_keypage,info->buff))
|
if (_mi_write_keypage(info,keyinfo,info->last_keypage,
|
||||||
|
DFLT_INIT_HITS,info->buff))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1496,13 +1502,13 @@ void lock_memory(MI_CHECK *param __attribute__((unused)))
|
|||||||
|
|
||||||
int flush_blocks(MI_CHECK *param, File file)
|
int flush_blocks(MI_CHECK *param, File file)
|
||||||
{
|
{
|
||||||
if (flush_key_blocks(file,FLUSH_RELEASE))
|
if (flush_key_blocks(*dflt_keycache,file,FLUSH_RELEASE))
|
||||||
{
|
{
|
||||||
mi_check_print_error(param,"%d when trying to write bufferts",my_errno);
|
mi_check_print_error(param,"%d when trying to write bufferts",my_errno);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
if (!param->using_global_keycache)
|
if (!param->using_global_keycache)
|
||||||
end_key_cache();
|
end_key_cache(dflt_keycache,1);
|
||||||
return 0;
|
return 0;
|
||||||
} /* flush_blocks */
|
} /* flush_blocks */
|
||||||
|
|
||||||
@ -1557,7 +1563,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Flush key cache for this file if we are calling this outside myisamchk */
|
/* Flush key cache for this file if we are calling this outside myisamchk */
|
||||||
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
|
flush_key_blocks(*share->keycache,share->kfile, FLUSH_IGNORE_CHANGED);
|
||||||
|
|
||||||
share->state.version=(ulong) time((time_t*) 0);
|
share->state.version=(ulong) time((time_t*) 0);
|
||||||
old_state= share->state; /* save state if not stored */
|
old_state= share->state; /* save state if not stored */
|
||||||
@ -1621,7 +1627,7 @@ static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
mi_check_print_error(param,"Not Enough memory");
|
mi_check_print_error(param,"Not Enough memory");
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,pagepos,buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,pagepos,DFLT_INIT_HITS,buff,0))
|
||||||
{
|
{
|
||||||
mi_check_print_error(param,"Can't read key block from filepos: %s",
|
mi_check_print_error(param,"Can't read key block from filepos: %s",
|
||||||
llstr(pagepos,llbuff));
|
llstr(pagepos,llbuff));
|
||||||
@ -1867,7 +1873,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||||||
Flush key cache for this file if we are calling this outside
|
Flush key cache for this file if we are calling this outside
|
||||||
myisamchk
|
myisamchk
|
||||||
*/
|
*/
|
||||||
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
|
flush_key_blocks(*share->keycache,share->kfile, FLUSH_IGNORE_CHANGED);
|
||||||
/* Clear the pointers to the given rows */
|
/* Clear the pointers to the given rows */
|
||||||
for (i=0 ; i < share->base.keys ; i++)
|
for (i=0 ; i < share->base.keys ; i++)
|
||||||
share->state.key_root[i]= HA_OFFSET_ERROR;
|
share->state.key_root[i]= HA_OFFSET_ERROR;
|
||||||
@ -1877,7 +1883,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (flush_key_blocks(share->kfile, FLUSH_FORCE_WRITE))
|
if (flush_key_blocks(*share->keycache,share->kfile, FLUSH_FORCE_WRITE))
|
||||||
goto err;
|
goto err;
|
||||||
key_map= ~key_map; /* Create the missing keys */
|
key_map= ~key_map; /* Create the missing keys */
|
||||||
}
|
}
|
||||||
@ -2230,7 +2236,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||||||
Flush key cache for this file if we are calling this outside
|
Flush key cache for this file if we are calling this outside
|
||||||
myisamchk
|
myisamchk
|
||||||
*/
|
*/
|
||||||
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
|
flush_key_blocks(*share->keycache,share->kfile, FLUSH_IGNORE_CHANGED);
|
||||||
/* Clear the pointers to the given rows */
|
/* Clear the pointers to the given rows */
|
||||||
for (i=0 ; i < share->base.keys ; i++)
|
for (i=0 ; i < share->base.keys ; i++)
|
||||||
share->state.key_root[i]= HA_OFFSET_ERROR;
|
share->state.key_root[i]= HA_OFFSET_ERROR;
|
||||||
@ -2240,7 +2246,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (flush_key_blocks(share->kfile, FLUSH_FORCE_WRITE))
|
if (flush_key_blocks(*share->keycache,share->kfile, FLUSH_FORCE_WRITE))
|
||||||
goto err;
|
goto err;
|
||||||
key_map= ~key_map; /* Create the missing keys */
|
key_map= ~key_map; /* Create the missing keys */
|
||||||
}
|
}
|
||||||
@ -3354,13 +3360,13 @@ static int sort_insert_key(MI_SORT_PARAM *sort_param,
|
|||||||
bzero((byte*) anc_buff+key_block->last_length,
|
bzero((byte*) anc_buff+key_block->last_length,
|
||||||
keyinfo->block_length- key_block->last_length);
|
keyinfo->block_length- key_block->last_length);
|
||||||
key_file_length=info->state->key_file_length;
|
key_file_length=info->state->key_file_length;
|
||||||
if ((filepos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
|
if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
/* If we read the page from the key cache, we have to write it back to it */
|
/* If we read the page from the key cache, we have to write it back to it */
|
||||||
if (key_file_length == info->state->key_file_length)
|
if (key_file_length == info->state->key_file_length)
|
||||||
{
|
{
|
||||||
if (_mi_write_keypage(info, keyinfo, filepos, anc_buff))
|
if (_mi_write_keypage(info, keyinfo, filepos, DFLT_INIT_HITS, anc_buff))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
else if (my_pwrite(info->s->kfile,(byte*) anc_buff,
|
else if (my_pwrite(info->s->kfile,(byte*) anc_buff,
|
||||||
@ -3458,13 +3464,14 @@ int flush_pending_blocks(MI_SORT_PARAM *sort_param)
|
|||||||
_mi_kpointer(info,key_block->end_pos,filepos);
|
_mi_kpointer(info,key_block->end_pos,filepos);
|
||||||
key_file_length=info->state->key_file_length;
|
key_file_length=info->state->key_file_length;
|
||||||
bzero((byte*) key_block->buff+length, keyinfo->block_length-length);
|
bzero((byte*) key_block->buff+length, keyinfo->block_length-length);
|
||||||
if ((filepos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
|
if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
/* If we read the page from the key cache, we have to write it back */
|
/* If we read the page from the key cache, we have to write it back */
|
||||||
if (key_file_length == info->state->key_file_length)
|
if (key_file_length == info->state->key_file_length)
|
||||||
{
|
{
|
||||||
if (_mi_write_keypage(info, keyinfo, filepos, key_block->buff))
|
if (_mi_write_keypage(info, keyinfo, filepos,
|
||||||
|
DFLT_INIT_HITS, key_block->buff))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
else if (my_pwrite(info->s->kfile,(byte*) key_block->buff,
|
else if (my_pwrite(info->s->kfile,(byte*) key_block->buff,
|
||||||
|
@ -64,7 +64,7 @@ int mi_close(register MI_INFO *info)
|
|||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
if (share->kfile >= 0 &&
|
if (share->kfile >= 0 &&
|
||||||
flush_key_blocks(share->kfile,
|
flush_key_blocks(*share->keycache,share->kfile,
|
||||||
share->temporary ? FLUSH_IGNORE_CHANGED :
|
share->temporary ? FLUSH_IGNORE_CHANGED :
|
||||||
FLUSH_RELEASE))
|
FLUSH_RELEASE))
|
||||||
error=my_errno;
|
error=my_errno;
|
||||||
|
@ -156,7 +156,7 @@ static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
DBUG_RETURN(my_errno=ENOMEM);
|
DBUG_RETURN(my_errno=ENOMEM);
|
||||||
}
|
}
|
||||||
DBUG_PRINT("info",("root_page: %ld",old_root));
|
DBUG_PRINT("info",("root_page: %ld",old_root));
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,old_root,root_buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,old_root,DFLT_INIT_HITS,root_buff,0))
|
||||||
{
|
{
|
||||||
error= -1;
|
error= -1;
|
||||||
goto err;
|
goto err;
|
||||||
@ -180,11 +180,12 @@ static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
*root=_mi_kpos(nod_flag,root_buff+2+nod_flag);
|
*root=_mi_kpos(nod_flag,root_buff+2+nod_flag);
|
||||||
else
|
else
|
||||||
*root=HA_OFFSET_ERROR;
|
*root=HA_OFFSET_ERROR;
|
||||||
if (_mi_dispose(info,keyinfo,old_root))
|
if (_mi_dispose(info,keyinfo,old_root,DFLT_INIT_HITS))
|
||||||
error= -1;
|
error= -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error=_mi_write_keypage(info,keyinfo,old_root,root_buff);
|
error=_mi_write_keypage(info,keyinfo,old_root,
|
||||||
|
DFLT_INIT_HITS,root_buff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err:
|
err:
|
||||||
@ -262,7 +263,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
if (subkeys == -1)
|
if (subkeys == -1)
|
||||||
{
|
{
|
||||||
/* the last entry in sub-tree */
|
/* the last entry in sub-tree */
|
||||||
_mi_dispose(info, keyinfo, root);
|
_mi_dispose(info, keyinfo, root,DFLT_INIT_HITS);
|
||||||
/* fall through to normal delete */
|
/* fall through to normal delete */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -276,7 +277,8 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
subkeys++;
|
subkeys++;
|
||||||
ft_intXstore(kpos, subkeys);
|
ft_intXstore(kpos, subkeys);
|
||||||
if (!ret_value)
|
if (!ret_value)
|
||||||
ret_value=_mi_write_keypage(info,keyinfo,page,anc_buff);
|
ret_value=_mi_write_keypage(info,keyinfo,page,
|
||||||
|
DFLT_INIT_HITS,anc_buff);
|
||||||
DBUG_PRINT("exit",("Return: %d",ret_value));
|
DBUG_PRINT("exit",("Return: %d",ret_value));
|
||||||
DBUG_RETURN(ret_value);
|
DBUG_RETURN(ret_value);
|
||||||
}
|
}
|
||||||
@ -295,7 +297,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
DBUG_PRINT("exit",("Return: %d",-1));
|
DBUG_PRINT("exit",("Return: %d",-1));
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,leaf_page,leaf_buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff,0))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +329,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
mi_putint(anc_buff,length,nod_flag);
|
mi_putint(anc_buff,length,nod_flag);
|
||||||
if (!nod_flag)
|
if (!nod_flag)
|
||||||
{ /* On leaf page */
|
{ /* On leaf page */
|
||||||
if (_mi_write_keypage(info,keyinfo,page,anc_buff))
|
if (_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("exit",("Return: %d",-1));
|
DBUG_PRINT("exit",("Return: %d",-1));
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -362,7 +364,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
ret_value=_mi_split_page(info,keyinfo,key,anc_buff,lastkey,0) | 2;
|
ret_value=_mi_split_page(info,keyinfo,key,anc_buff,lastkey,0) | 2;
|
||||||
}
|
}
|
||||||
if (save_flag && ret_value != 1)
|
if (save_flag && ret_value != 1)
|
||||||
ret_value|=_mi_write_keypage(info,keyinfo,page,anc_buff);
|
ret_value|=_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_DUMP("page",(byte*) anc_buff,mi_getint(anc_buff));
|
DBUG_DUMP("page",(byte*) anc_buff,mi_getint(anc_buff));
|
||||||
@ -406,7 +408,7 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
|
if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
|
||||||
MI_MAX_KEY_BUFF*2)))
|
MI_MAX_KEY_BUFF*2)))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,next_page,next_buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,next_buff,0))
|
||||||
ret_value= -1;
|
ret_value= -1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -434,7 +436,7 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
(uchar*) 0,(uchar*) 0,(my_off_t) 0,0);
|
(uchar*) 0,(uchar*) 0,(my_off_t) 0,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_mi_write_keypage(info,keyinfo,leaf_page,leaf_buff))
|
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
my_afree((byte*) next_buff);
|
my_afree((byte*) next_buff);
|
||||||
@ -444,7 +446,7 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
/* Remove last key from leaf page */
|
/* Remove last key from leaf page */
|
||||||
|
|
||||||
mi_putint(leaf_buff,key_start-leaf_buff,nod_flag);
|
mi_putint(leaf_buff,key_start-leaf_buff,nod_flag);
|
||||||
if (_mi_write_keypage(info,keyinfo,leaf_page,leaf_buff))
|
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* Place last key in ancestor page on deleted key position */
|
/* Place last key in ancestor page on deleted key position */
|
||||||
@ -532,7 +534,7 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
next_page= _mi_kpos(key_reflength,next_keypos);
|
next_page= _mi_kpos(key_reflength,next_keypos);
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,next_page,buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
|
||||||
goto err;
|
goto err;
|
||||||
buff_length=mi_getint(buff);
|
buff_length=mi_getint(buff);
|
||||||
DBUG_DUMP("next",(byte*) buff,buff_length);
|
DBUG_DUMP("next",(byte*) buff,buff_length);
|
||||||
@ -571,7 +573,7 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
if (buff_length <= keyinfo->block_length)
|
if (buff_length <= keyinfo->block_length)
|
||||||
{ /* Keys in one page */
|
{ /* Keys in one page */
|
||||||
memcpy((byte*) leaf_buff,(byte*) buff,(size_t) buff_length);
|
memcpy((byte*) leaf_buff,(byte*) buff,(size_t) buff_length);
|
||||||
if (_mi_dispose(info,keyinfo,next_page))
|
if (_mi_dispose(info,keyinfo,next_page,DFLT_INIT_HITS))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -620,10 +622,10 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
(*keyinfo->store_key)(keyinfo,buff+p_length,&s_temp);
|
(*keyinfo->store_key)(keyinfo,buff+p_length,&s_temp);
|
||||||
mi_putint(buff,length+t_length+p_length,nod_flag);
|
mi_putint(buff,length+t_length+p_length,nod_flag);
|
||||||
|
|
||||||
if (_mi_write_keypage(info,keyinfo,next_page,buff))
|
if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (_mi_write_keypage(info,keyinfo,leaf_page,leaf_buff))
|
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_RETURN(anc_length <= ((info->quick_mode ? MI_MIN_BLOCK_LENGTH :
|
DBUG_RETURN(anc_length <= ((info->quick_mode ? MI_MIN_BLOCK_LENGTH :
|
||||||
(uint) keyinfo->underflow_block_length)));
|
(uint) keyinfo->underflow_block_length)));
|
||||||
@ -635,7 +637,7 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
if (!keypos)
|
if (!keypos)
|
||||||
goto err;
|
goto err;
|
||||||
next_page= _mi_kpos(key_reflength,keypos);
|
next_page= _mi_kpos(key_reflength,keypos);
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,next_page,buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
|
||||||
goto err;
|
goto err;
|
||||||
buff_length=mi_getint(buff);
|
buff_length=mi_getint(buff);
|
||||||
endpos=buff+buff_length;
|
endpos=buff+buff_length;
|
||||||
@ -679,7 +681,7 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
|
|
||||||
if (buff_length <= keyinfo->block_length)
|
if (buff_length <= keyinfo->block_length)
|
||||||
{ /* Keys in one page */
|
{ /* Keys in one page */
|
||||||
if (_mi_dispose(info,keyinfo,leaf_page))
|
if (_mi_dispose(info,keyinfo,leaf_page,DFLT_INIT_HITS))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -726,11 +728,11 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
(size_t) length);
|
(size_t) length);
|
||||||
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp);
|
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp);
|
||||||
mi_putint(leaf_buff,length+t_length+p_length,nod_flag);
|
mi_putint(leaf_buff,length+t_length+p_length,nod_flag);
|
||||||
if (_mi_write_keypage(info,keyinfo,leaf_page,leaf_buff))
|
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
|
||||||
goto err;
|
goto err;
|
||||||
mi_putint(buff,endpos-buff,nod_flag);
|
mi_putint(buff,endpos-buff,nod_flag);
|
||||||
}
|
}
|
||||||
if (_mi_write_keypage(info,keyinfo,next_page,buff))
|
if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_RETURN(anc_length <= (uint) keyinfo->block_length/2);
|
DBUG_RETURN(anc_length <= (uint) keyinfo->block_length/2);
|
||||||
err:
|
err:
|
||||||
|
@ -53,7 +53,7 @@ int mi_delete_all_rows(MI_INFO *info)
|
|||||||
If we are using delayed keys or if the user has done changes to the tables
|
If we are using delayed keys or if the user has done changes to the tables
|
||||||
since it was locked then there may be key blocks in the key cache
|
since it was locked then there may be key blocks in the key cache
|
||||||
*/
|
*/
|
||||||
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
|
flush_key_blocks(*share->keycache, share->kfile, FLUSH_IGNORE_CHANGED);
|
||||||
if (my_chsize(info->dfile, 0, 0, MYF(MY_WME)) ||
|
if (my_chsize(info->dfile, 0, 0, MYF(MY_WME)) ||
|
||||||
my_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)) )
|
my_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)) )
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -283,7 +283,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
|
|||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
/* Close the isam and data files as Win32 can't drop an open table */
|
/* Close the isam and data files as Win32 can't drop an open table */
|
||||||
pthread_mutex_lock(&share->intern_lock);
|
pthread_mutex_lock(&share->intern_lock);
|
||||||
if (flush_key_blocks(share->kfile,
|
if (flush_key_blocks(*share->keycache, share->kfile,
|
||||||
(function == HA_EXTRA_FORCE_REOPEN ?
|
(function == HA_EXTRA_FORCE_REOPEN ?
|
||||||
FLUSH_RELEASE : FLUSH_IGNORE_CHANGED)))
|
FLUSH_RELEASE : FLUSH_IGNORE_CHANGED)))
|
||||||
{
|
{
|
||||||
@ -329,7 +329,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
|
|||||||
break;
|
break;
|
||||||
case HA_EXTRA_FLUSH:
|
case HA_EXTRA_FLUSH:
|
||||||
if (!share->temporary)
|
if (!share->temporary)
|
||||||
flush_key_blocks(share->kfile,FLUSH_KEEP);
|
flush_key_blocks(*share->keycache,share->kfile,FLUSH_KEEP);
|
||||||
#ifdef HAVE_PWRITE
|
#ifdef HAVE_PWRITE
|
||||||
_mi_decrement_open_count(info);
|
_mi_decrement_open_count(info);
|
||||||
#endif
|
#endif
|
||||||
@ -374,6 +374,9 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
|
|||||||
case HA_EXTRA_PRELOAD_BUFFER_SIZE:
|
case HA_EXTRA_PRELOAD_BUFFER_SIZE:
|
||||||
info->preload_buff_size= *((ulong *) extra_arg);
|
info->preload_buff_size= *((ulong *) extra_arg);
|
||||||
break;
|
break;
|
||||||
|
case HA_EXTRA_SET_KEY_CACHE:
|
||||||
|
share->reg_keycache= share->keycache= (KEY_CACHE_HANDLE *) extra_arg;
|
||||||
|
break;
|
||||||
case HA_EXTRA_KEY_CACHE:
|
case HA_EXTRA_KEY_CACHE:
|
||||||
case HA_EXTRA_NO_KEY_CACHE:
|
case HA_EXTRA_NO_KEY_CACHE:
|
||||||
default:
|
default:
|
||||||
|
107
myisam/mi_keycache.c
Normal file
107
myisam/mi_keycache.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Key cache assignments
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "myisamdef.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Assign pages of the index file for a table to a key cache
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
mi_assign_to_keycache()
|
||||||
|
info open table
|
||||||
|
map map of indexes to assign to the key cache
|
||||||
|
key_cache_ptr pointer to the key cache handle
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 if a success. error code - otherwise.
|
||||||
|
|
||||||
|
NOTES.
|
||||||
|
At present pages for all indexes must be assigned to the same key cache.
|
||||||
|
In future only pages for indexes specified in the key_map parameter
|
||||||
|
of the table will be assigned to the specified key cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct st_assign_extra_info
|
||||||
|
{
|
||||||
|
pthread_mutex_t *lock;
|
||||||
|
struct st_my_thread_var *waiting_thread;
|
||||||
|
} ASSIGN_EXTRA_INFO;
|
||||||
|
|
||||||
|
static void remove_key_cache_assign(void *arg)
|
||||||
|
{
|
||||||
|
KEY_CACHE_VAR *key_cache= (KEY_CACHE_VAR *) arg;
|
||||||
|
ASSIGN_EXTRA_INFO *extra_info= (ASSIGN_EXTRA_INFO *) key_cache->extra_info;
|
||||||
|
struct st_my_thread_var *waiting_thread;
|
||||||
|
pthread_mutex_t *lock= extra_info->lock;
|
||||||
|
pthread_mutex_lock(lock);
|
||||||
|
if (!(--key_cache->assignments) &&
|
||||||
|
(waiting_thread = extra_info->waiting_thread))
|
||||||
|
{
|
||||||
|
my_free(extra_info, MYF(0));
|
||||||
|
key_cache->extra_info= 0;
|
||||||
|
if (waiting_thread != my_thread_var)
|
||||||
|
pthread_cond_signal(&waiting_thread->suspend);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mi_assign_to_keycache(MI_INFO *info, ulonglong key_map,
|
||||||
|
KEY_CACHE_VAR *key_cache,
|
||||||
|
pthread_mutex_t *assign_lock)
|
||||||
|
{
|
||||||
|
ASSIGN_EXTRA_INFO *extra_info;
|
||||||
|
int error= 0;
|
||||||
|
MYISAM_SHARE* share= info->s;
|
||||||
|
|
||||||
|
DBUG_ENTER("mi_assign_to_keycache");
|
||||||
|
|
||||||
|
share->reg_keycache= &key_cache->cache;
|
||||||
|
pthread_mutex_lock(assign_lock);
|
||||||
|
if (!(extra_info= (ASSIGN_EXTRA_INFO *) key_cache->extra_info))
|
||||||
|
{
|
||||||
|
if (!(extra_info= (ASSIGN_EXTRA_INFO*) my_malloc(sizeof(ASSIGN_EXTRA_INFO),
|
||||||
|
MYF(MY_WME | MY_ZEROFILL))))
|
||||||
|
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
||||||
|
key_cache->extra_info= extra_info;
|
||||||
|
key_cache->action= remove_key_cache_assign;
|
||||||
|
extra_info->lock= assign_lock;
|
||||||
|
}
|
||||||
|
key_cache->assignments++;
|
||||||
|
pthread_mutex_unlock(assign_lock);
|
||||||
|
|
||||||
|
if (!(info->lock_type == F_WRLCK && share->w_locks))
|
||||||
|
{
|
||||||
|
if (flush_key_blocks(*share->keycache, share->kfile, FLUSH_REMOVE))
|
||||||
|
{
|
||||||
|
error=my_errno;
|
||||||
|
mi_mark_crashed(info); /* Mark that table must be checked */
|
||||||
|
}
|
||||||
|
share->keycache= &key_cache->cache;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
extra_info->waiting_thread= my_thread_var;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
@ -34,6 +34,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
|
|||||||
uint count;
|
uint count;
|
||||||
MYISAM_SHARE *share=info->s;
|
MYISAM_SHARE *share=info->s;
|
||||||
uint flag;
|
uint flag;
|
||||||
|
uint switch_fl= 0;
|
||||||
DBUG_ENTER("mi_lock_database");
|
DBUG_ENTER("mi_lock_database");
|
||||||
DBUG_PRINT("info",("lock_type: %d", lock_type));
|
DBUG_PRINT("info",("lock_type: %d", lock_type));
|
||||||
|
|
||||||
@ -60,12 +61,21 @@ int mi_lock_database(MI_INFO *info, int lock_type)
|
|||||||
else
|
else
|
||||||
count= --share->w_locks;
|
count= --share->w_locks;
|
||||||
--share->tot_locks;
|
--share->tot_locks;
|
||||||
|
/*
|
||||||
|
During a key cache reassignment the current and registered
|
||||||
|
key caches for the table are different.
|
||||||
|
*/
|
||||||
if (info->lock_type == F_WRLCK && !share->w_locks &&
|
if (info->lock_type == F_WRLCK && !share->w_locks &&
|
||||||
!share->delay_key_write && flush_key_blocks(share->kfile,FLUSH_KEEP))
|
((switch_fl= share->keycache != share->reg_keycache) ||
|
||||||
|
!share->delay_key_write) &&
|
||||||
|
flush_key_blocks(*share->keycache, share->kfile,
|
||||||
|
switch_fl ? FLUSH_REMOVE : FLUSH_KEEP))
|
||||||
{
|
{
|
||||||
error=my_errno;
|
error=my_errno;
|
||||||
mi_mark_crashed(info); /* Mark that table must be checked */
|
mi_mark_crashed(info); /* Mark that table must be checked */
|
||||||
}
|
}
|
||||||
|
if (switch_fl)
|
||||||
|
share->keycache= share->reg_keycache;
|
||||||
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
|
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
|
||||||
{
|
{
|
||||||
if (end_io_cache(&info->rec_cache))
|
if (end_io_cache(&info->rec_cache))
|
||||||
@ -400,7 +410,7 @@ int _mi_test_if_changed(register MI_INFO *info)
|
|||||||
{ /* Keyfile has changed */
|
{ /* Keyfile has changed */
|
||||||
DBUG_PRINT("info",("index file changed"));
|
DBUG_PRINT("info",("index file changed"));
|
||||||
if (share->state.process != share->this_process)
|
if (share->state.process != share->this_process)
|
||||||
VOID(flush_key_blocks(share->kfile,FLUSH_RELEASE));
|
VOID(flush_key_blocks(*share->keycache,share->kfile,FLUSH_RELEASE));
|
||||||
share->last_process=share->state.process;
|
share->last_process=share->state.process;
|
||||||
info->last_unique= share->state.unique;
|
info->last_unique= share->state.unique;
|
||||||
info->last_loop= share->state.update_count;
|
info->last_loop= share->state.update_count;
|
||||||
|
@ -24,14 +24,16 @@
|
|||||||
/* Fetch a key-page in memory */
|
/* Fetch a key-page in memory */
|
||||||
|
|
||||||
uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||||
my_off_t page, uchar *buff, int return_buffer)
|
my_off_t page, int level,
|
||||||
|
uchar *buff, int return_buffer)
|
||||||
{
|
{
|
||||||
uchar *tmp;
|
uchar *tmp;
|
||||||
uint page_size;
|
uint page_size;
|
||||||
DBUG_ENTER("_mi_fetch_keypage");
|
DBUG_ENTER("_mi_fetch_keypage");
|
||||||
DBUG_PRINT("enter",("page: %ld",page));
|
DBUG_PRINT("enter",("page: %ld",page));
|
||||||
|
|
||||||
tmp=(uchar*) key_cache_read(info->s->kfile,page,(byte*) buff,
|
tmp=(uchar*) key_cache_read(*info->s->keycache,
|
||||||
|
info->s->kfile, page, level, (byte*) buff,
|
||||||
(uint) keyinfo->block_length,
|
(uint) keyinfo->block_length,
|
||||||
(uint) keyinfo->block_length,
|
(uint) keyinfo->block_length,
|
||||||
return_buffer);
|
return_buffer);
|
||||||
@ -61,7 +63,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
/* Write a key-page on disk */
|
/* Write a key-page on disk */
|
||||||
|
|
||||||
int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
||||||
my_off_t page, uchar *buff)
|
my_off_t page, int level, uchar *buff)
|
||||||
{
|
{
|
||||||
reg3 uint length;
|
reg3 uint length;
|
||||||
DBUG_ENTER("_mi_write_keypage");
|
DBUG_ENTER("_mi_write_keypage");
|
||||||
@ -92,7 +94,8 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
length=keyinfo->block_length;
|
length=keyinfo->block_length;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DBUG_RETURN((key_cache_write(info->s->kfile,page,(byte*) buff,length,
|
DBUG_RETURN((key_cache_write(*info->s->keycache,
|
||||||
|
info->s->kfile,page, level, (byte*) buff,length,
|
||||||
(uint) keyinfo->block_length,
|
(uint) keyinfo->block_length,
|
||||||
(int) ((info->lock_type != F_UNLCK) ||
|
(int) ((info->lock_type != F_UNLCK) ||
|
||||||
info->s->delay_key_write))));
|
info->s->delay_key_write))));
|
||||||
@ -101,7 +104,8 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
|
|
||||||
/* Remove page from disk */
|
/* Remove page from disk */
|
||||||
|
|
||||||
int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos)
|
int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos,
|
||||||
|
int level)
|
||||||
{
|
{
|
||||||
my_off_t old_link;
|
my_off_t old_link;
|
||||||
char buff[8];
|
char buff[8];
|
||||||
@ -112,7 +116,8 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos)
|
|||||||
info->s->state.key_del[keyinfo->block_size]=pos;
|
info->s->state.key_del[keyinfo->block_size]=pos;
|
||||||
mi_sizestore(buff,old_link);
|
mi_sizestore(buff,old_link);
|
||||||
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
|
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
|
||||||
DBUG_RETURN(key_cache_write(info->s->kfile,pos,buff,
|
DBUG_RETURN(key_cache_write(*info->s->keycache,
|
||||||
|
info->s->kfile, pos , level, buff,
|
||||||
sizeof(buff),
|
sizeof(buff),
|
||||||
(uint) keyinfo->block_length,
|
(uint) keyinfo->block_length,
|
||||||
(int) (info->lock_type != F_UNLCK)));
|
(int) (info->lock_type != F_UNLCK)));
|
||||||
@ -121,7 +126,7 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos)
|
|||||||
|
|
||||||
/* Make new page on disk */
|
/* Make new page on disk */
|
||||||
|
|
||||||
my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo)
|
my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level)
|
||||||
{
|
{
|
||||||
my_off_t pos;
|
my_off_t pos;
|
||||||
char buff[8];
|
char buff[8];
|
||||||
@ -140,7 +145,8 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!key_cache_read(info->s->kfile,pos,
|
if (!key_cache_read(*info->s->keycache,
|
||||||
|
info->s->kfile, pos, level,
|
||||||
buff,
|
buff,
|
||||||
(uint) sizeof(buff),
|
(uint) sizeof(buff),
|
||||||
(uint) keyinfo->block_length,0))
|
(uint) keyinfo->block_length,0))
|
||||||
|
@ -48,7 +48,7 @@ int mi_panic(enum ha_panic_function flag)
|
|||||||
if (info->s->options & HA_OPTION_READ_ONLY_DATA)
|
if (info->s->options & HA_OPTION_READ_ONLY_DATA)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
if (flush_key_blocks(info->s->kfile,FLUSH_RELEASE))
|
if (flush_key_blocks(*info->s->keycache,info->s->kfile,FLUSH_RELEASE))
|
||||||
error=my_errno;
|
error=my_errno;
|
||||||
if (info->opt_flag & WRITE_CACHE_USED)
|
if (info->opt_flag & WRITE_CACHE_USED)
|
||||||
if (flush_io_cache(&info->rec_cache))
|
if (flush_io_cache(&info->rec_cache))
|
||||||
|
@ -69,7 +69,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
|
|||||||
if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME))))
|
if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME))))
|
||||||
DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM);
|
DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM);
|
||||||
|
|
||||||
if (flush_key_blocks(share->kfile, FLUSH_RELEASE))
|
if (flush_key_blocks(*share->keycache,share->kfile, FLUSH_RELEASE))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -87,7 +87,9 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
|
|||||||
{
|
{
|
||||||
if (mi_test_if_nod(buff))
|
if (mi_test_if_nod(buff))
|
||||||
{
|
{
|
||||||
if (key_cache_insert(share->kfile, pos, (byte*) buff, block_length))
|
if (key_cache_insert(*share->keycache,
|
||||||
|
share->kfile, pos, DFLT_INIT_HITS,
|
||||||
|
(byte*) buff, block_length))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
pos+= block_length;
|
pos+= block_length;
|
||||||
@ -97,7 +99,9 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (key_cache_insert(share->kfile, pos, (byte*) buff, length))
|
if (key_cache_insert(*share->keycache,
|
||||||
|
share->kfile, pos, DFLT_INIT_HITS,
|
||||||
|
(byte*) buff, length))
|
||||||
goto err;
|
goto err;
|
||||||
pos+= length;
|
pos+= length;
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ static double _mi_search_pos(register MI_INFO *info,
|
|||||||
if (pos == HA_OFFSET_ERROR)
|
if (pos == HA_OFFSET_ERROR)
|
||||||
DBUG_RETURN(0.5);
|
DBUG_RETURN(0.5);
|
||||||
|
|
||||||
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,1)))
|
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,1)))
|
||||||
goto err;
|
goto err;
|
||||||
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
|
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
|
||||||
&keypos,info->lastkey, &after_key);
|
&keypos,info->lastkey, &after_key);
|
||||||
|
@ -76,7 +76,7 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
DBUG_RETURN(1); /* Search at upper levels */
|
DBUG_RETURN(1); /* Search at upper levels */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,
|
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
|
||||||
test(!(nextflag & SEARCH_SAVE_BUFF)))))
|
test(!(nextflag & SEARCH_SAVE_BUFF)))))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_DUMP("page",(byte*) buff,mi_getint(buff));
|
DBUG_DUMP("page",(byte*) buff,mi_getint(buff));
|
||||||
@ -119,7 +119,7 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
if (pos != info->last_keypage)
|
if (pos != info->last_keypage)
|
||||||
{
|
{
|
||||||
uchar *old_buff=buff;
|
uchar *old_buff=buff;
|
||||||
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,
|
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
|
||||||
test(!(nextflag & SEARCH_SAVE_BUFF)))))
|
test(!(nextflag & SEARCH_SAVE_BUFF)))))
|
||||||
goto err;
|
goto err;
|
||||||
keypos=buff+(keypos-old_buff);
|
keypos=buff+(keypos-old_buff);
|
||||||
@ -1108,7 +1108,7 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
if (info->buff_used)
|
if (info->buff_used)
|
||||||
{
|
{
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,info->last_search_keypage,
|
if (!_mi_fetch_keypage(info,keyinfo,info->last_search_keypage,
|
||||||
info->buff,0))
|
DFLT_INIT_HITS,info->buff,0))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
info->buff_used=0;
|
info->buff_used=0;
|
||||||
}
|
}
|
||||||
@ -1177,7 +1177,7 @@ int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,pos,info->buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,0))
|
||||||
{
|
{
|
||||||
info->lastpos= HA_OFFSET_ERROR;
|
info->lastpos= HA_OFFSET_ERROR;
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -1220,7 +1220,7 @@ int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
buff=info->buff;
|
buff=info->buff;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,pos,buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,buff,0))
|
||||||
{
|
{
|
||||||
info->lastpos= HA_OFFSET_ERROR;
|
info->lastpos= HA_OFFSET_ERROR;
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
@ -50,7 +50,7 @@ int main(int argc,char *argv[])
|
|||||||
MY_INIT(argv[0]);
|
MY_INIT(argv[0]);
|
||||||
my_init();
|
my_init();
|
||||||
if (key_cacheing)
|
if (key_cacheing)
|
||||||
init_key_cache(IO_SIZE*16);
|
init_key_cache(dflt_keycache,512,IO_SIZE*16,0);
|
||||||
get_options(argc,argv);
|
get_options(argc,argv);
|
||||||
|
|
||||||
exit(run_test("test1"));
|
exit(run_test("test1"));
|
||||||
|
@ -49,6 +49,7 @@ static int verbose=0,testflag=0,
|
|||||||
static int pack_seg=HA_SPACE_PACK,pack_type=HA_PACK_KEY,remove_count=-1,
|
static int pack_seg=HA_SPACE_PACK,pack_type=HA_PACK_KEY,remove_count=-1,
|
||||||
create_flag=0;
|
create_flag=0;
|
||||||
static ulong key_cache_size=IO_SIZE*16;
|
static ulong key_cache_size=IO_SIZE*16;
|
||||||
|
static uint key_cache_block_size=IO_SIZE;
|
||||||
|
|
||||||
static uint keys=MYISAM_KEYS,recant=1000;
|
static uint keys=MYISAM_KEYS,recant=1000;
|
||||||
static uint use_blob=0;
|
static uint use_blob=0;
|
||||||
@ -214,7 +215,7 @@ int main(int argc, char *argv[])
|
|||||||
if (!silent)
|
if (!silent)
|
||||||
printf("- Writing key:s\n");
|
printf("- Writing key:s\n");
|
||||||
if (key_cacheing)
|
if (key_cacheing)
|
||||||
init_key_cache(key_cache_size); /* Use a small cache */
|
init_key_cache(dflt_keycache,key_cache_block_size,key_cache_size,0); /* Use a small cache */
|
||||||
if (locking)
|
if (locking)
|
||||||
mi_lock_database(file,F_WRLCK);
|
mi_lock_database(file,F_WRLCK);
|
||||||
if (write_cacheing)
|
if (write_cacheing)
|
||||||
@ -274,7 +275,7 @@ int main(int argc, char *argv[])
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (key_cacheing)
|
if (key_cacheing)
|
||||||
resize_key_cache(key_cache_size*2);
|
resize_key_cache(dflt_keycache,key_cache_block_size,key_cache_size*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
@ -816,16 +817,19 @@ end:
|
|||||||
puts("Locking used");
|
puts("Locking used");
|
||||||
if (use_blob)
|
if (use_blob)
|
||||||
puts("blobs used");
|
puts("blobs used");
|
||||||
|
#if 0
|
||||||
printf("key cache status: \n\
|
printf("key cache status: \n\
|
||||||
blocks used:%10lu\n\
|
blocks used:%10lu\n\
|
||||||
w_requests: %10lu\n\
|
w_requests: %10lu\n\
|
||||||
writes: %10lu\n\
|
writes: %10lu\n\
|
||||||
r_requests: %10lu\n\
|
r_requests: %10lu\n\
|
||||||
reads: %10lu\n",
|
reads: %10lu\n",
|
||||||
my_blocks_used, my_cache_w_requests, my_cache_write,
|
my_blocks_used,
|
||||||
|
my_cache_w_requests, my_cache_write,
|
||||||
my_cache_r_requests, my_cache_read);
|
my_cache_r_requests, my_cache_read);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
end_key_cache();
|
end_key_cache(dflt_keycache,1);
|
||||||
if (blob_buffer)
|
if (blob_buffer)
|
||||||
my_free(blob_buffer,MYF(0));
|
my_free(blob_buffer,MYF(0));
|
||||||
my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO);
|
my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO);
|
||||||
|
@ -177,7 +177,7 @@ void start_test(int id)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (key_cacheing && rnd(2) == 0)
|
if (key_cacheing && rnd(2) == 0)
|
||||||
init_key_cache(65536L);
|
init_key_cache(dflt_keycache,512,65536L,0);
|
||||||
printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
|
printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
|
||||||
|
|
||||||
for (error=i=0 ; i < tests && !error; i++)
|
for (error=i=0 ; i < tests && !error; i++)
|
||||||
|
@ -310,8 +310,8 @@ int _mi_enlarge_root(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
mi_putint(info->buff,t_length+2+nod_flag,nod_flag);
|
mi_putint(info->buff,t_length+2+nod_flag,nod_flag);
|
||||||
(*keyinfo->store_key)(keyinfo,info->buff+2+nod_flag,&s_temp);
|
(*keyinfo->store_key)(keyinfo,info->buff+2+nod_flag,&s_temp);
|
||||||
info->buff_used=info->page_changed=1; /* info->buff is used */
|
info->buff_used=info->page_changed=1; /* info->buff is used */
|
||||||
if ((*root= _mi_new(info,keyinfo)) == HA_OFFSET_ERROR ||
|
if ((*root= _mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
|
||||||
_mi_write_keypage(info,keyinfo,*root,info->buff))
|
_mi_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
} /* _mi_enlarge_root */
|
} /* _mi_enlarge_root */
|
||||||
@ -342,7 +342,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
|
if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
|
||||||
MI_MAX_KEY_BUFF*2)))
|
MI_MAX_KEY_BUFF*2)))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,page,temp_buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff,0))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length,
|
flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length,
|
||||||
@ -386,7 +386,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
DBUG_ASSERT(subkeys < 0);
|
DBUG_ASSERT(subkeys < 0);
|
||||||
ft_intXstore(keypos, subkeys);
|
ft_intXstore(keypos, subkeys);
|
||||||
if (!error)
|
if (!error)
|
||||||
error=_mi_write_keypage(info,keyinfo,page,temp_buff);
|
error=_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff);
|
||||||
my_afree((byte*) temp_buff);
|
my_afree((byte*) temp_buff);
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
@ -409,7 +409,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
{
|
{
|
||||||
error=_mi_insert(info,keyinfo,key,temp_buff,keypos,keybuff,father_buff,
|
error=_mi_insert(info,keyinfo,key,temp_buff,keypos,keybuff,father_buff,
|
||||||
father_keypos,father_page, insert_last);
|
father_keypos,father_page, insert_last);
|
||||||
if (_mi_write_keypage(info,keyinfo,page,temp_buff))
|
if (_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
my_afree((byte*) temp_buff);
|
my_afree((byte*) temp_buff);
|
||||||
@ -580,7 +580,7 @@ int _mi_split_page(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Move middle item to key and pointer to new page */
|
/* Move middle item to key and pointer to new page */
|
||||||
if ((new_pos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
|
if ((new_pos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
_mi_kpointer(info,_mi_move_key(keyinfo,key,key_buff),new_pos);
|
_mi_kpointer(info,_mi_move_key(keyinfo,key,key_buff),new_pos);
|
||||||
|
|
||||||
@ -596,7 +596,7 @@ int _mi_split_page(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
(*keyinfo->store_key)(keyinfo,info->buff+key_ref_length,&s_temp);
|
(*keyinfo->store_key)(keyinfo,info->buff+key_ref_length,&s_temp);
|
||||||
mi_putint(info->buff,length+t_length+key_ref_length,nod_flag);
|
mi_putint(info->buff,length+t_length+key_ref_length,nod_flag);
|
||||||
|
|
||||||
if (_mi_write_keypage(info,keyinfo,new_pos,info->buff))
|
if (_mi_write_keypage(info,keyinfo,new_pos,DFLT_INIT_HITS,info->buff))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
DBUG_DUMP("key",(byte*) key,_mi_keylength(keyinfo,key));
|
DBUG_DUMP("key",(byte*) key,_mi_keylength(keyinfo,key));
|
||||||
DBUG_RETURN(2); /* Middle key up */
|
DBUG_RETURN(2); /* Middle key up */
|
||||||
@ -747,7 +747,7 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
DBUG_PRINT("test",("use left page: %lu",next_page));
|
DBUG_PRINT("test",("use left page: %lu",next_page));
|
||||||
} /* father_key_pos ptr to parting key */
|
} /* father_key_pos ptr to parting key */
|
||||||
|
|
||||||
if (!_mi_fetch_keypage(info,keyinfo,next_page,info->buff,0))
|
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff,0))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_DUMP("next",(byte*) info->buff,mi_getint(info->buff));
|
DBUG_DUMP("next",(byte*) info->buff,mi_getint(info->buff));
|
||||||
|
|
||||||
@ -787,8 +787,8 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
memcpy((byte*) buff+2,(byte*) pos+k_length,(size_t) length);
|
memcpy((byte*) buff+2,(byte*) pos+k_length,(size_t) length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_mi_write_keypage(info,keyinfo,next_page,info->buff) ||
|
if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff) ||
|
||||||
_mi_write_keypage(info,keyinfo,father_page,father_buff))
|
_mi_write_keypage(info,keyinfo,father_page,DFLT_INIT_HITS,father_buff))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@ -828,12 +828,13 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
memcpy((byte*) (right ? key : father_key_pos),pos,(size_t) k_length);
|
memcpy((byte*) (right ? key : father_key_pos),pos,(size_t) k_length);
|
||||||
memcpy((byte*) (right ? father_key_pos : key),tmp_part_key, k_length);
|
memcpy((byte*) (right ? father_key_pos : key),tmp_part_key, k_length);
|
||||||
|
|
||||||
if ((new_pos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
|
if ((new_pos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
|
||||||
goto err;
|
goto err;
|
||||||
_mi_kpointer(info,key+k_length,new_pos);
|
_mi_kpointer(info,key+k_length,new_pos);
|
||||||
if (_mi_write_keypage(info,keyinfo,(right ? new_pos : next_page),
|
if (_mi_write_keypage(info,keyinfo,(right ? new_pos : next_page),
|
||||||
info->buff) ||
|
DFLT_INIT_HITS,info->buff) ||
|
||||||
_mi_write_keypage(info,keyinfo,(right ? next_page : new_pos),extra_buff))
|
_mi_write_keypage(info,keyinfo,(right ? next_page : new_pos),
|
||||||
|
DFLT_INIT_HITS,extra_buff))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
DBUG_RETURN(1); /* Middle key up */
|
DBUG_RETURN(1); /* Middle key up */
|
||||||
|
@ -44,6 +44,7 @@ static const char *load_default_groups[]= { "myisamchk", 0 };
|
|||||||
static const char *set_charset_name, *opt_tmpdir;
|
static const char *set_charset_name, *opt_tmpdir;
|
||||||
static CHARSET_INFO *set_charset;
|
static CHARSET_INFO *set_charset;
|
||||||
static long opt_myisam_block_size;
|
static long opt_myisam_block_size;
|
||||||
|
static long opt_key_cache_block_size;
|
||||||
static const char *my_progname_short;
|
static const char *my_progname_short;
|
||||||
static int stopwords_inited= 0;
|
static int stopwords_inited= 0;
|
||||||
static MY_TMPDIR myisamchk_tmpdir;
|
static MY_TMPDIR myisamchk_tmpdir;
|
||||||
@ -148,7 +149,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
enum options_mc {
|
enum options_mc {
|
||||||
OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS,
|
OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS,
|
||||||
OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE,
|
OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE,
|
||||||
|
OPT_KEY_CACHE_BLOCK_SIZE, OPT_MYISAM_BLOCK_SIZE,
|
||||||
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
|
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
|
||||||
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
|
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
|
||||||
OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT
|
OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT
|
||||||
@ -283,6 +285,11 @@ static struct my_option my_long_options[] =
|
|||||||
(gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0,
|
(gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0,
|
||||||
GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD,
|
GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD,
|
||||||
(long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0},
|
(long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0},
|
||||||
|
{ "key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "",
|
||||||
|
(gptr*) &opt_key_cache_block_size,
|
||||||
|
(gptr*) &opt_key_cache_block_size, 0,
|
||||||
|
GET_LONG, REQUIRED_ARG, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH,
|
||||||
|
MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0},
|
||||||
{ "myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "",
|
{ "myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "",
|
||||||
(gptr*) &opt_myisam_block_size, (gptr*) &opt_myisam_block_size, 0,
|
(gptr*) &opt_myisam_block_size, (gptr*) &opt_myisam_block_size, 0,
|
||||||
GET_LONG, REQUIRED_ARG, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH,
|
GET_LONG, REQUIRED_ARG, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH,
|
||||||
@ -1022,7 +1029,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
|
|||||||
!(param->testflag & (T_FAST | T_FORCE_CREATE)))
|
!(param->testflag & (T_FAST | T_FORCE_CREATE)))
|
||||||
{
|
{
|
||||||
if (param->testflag & (T_EXTEND | T_MEDIUM))
|
if (param->testflag & (T_EXTEND | T_MEDIUM))
|
||||||
VOID(init_key_cache(param->use_buffers));
|
VOID(init_key_cache(dflt_keycache,opt_key_cache_block_size,
|
||||||
|
param->use_buffers,&dflt_key_cache_var));
|
||||||
VOID(init_io_cache(¶m->read_cache,datafile,
|
VOID(init_io_cache(¶m->read_cache,datafile,
|
||||||
(uint) param->read_buffer_length,
|
(uint) param->read_buffer_length,
|
||||||
READ_CACHE,
|
READ_CACHE,
|
||||||
@ -1445,7 +1453,8 @@ static int mi_sort_records(MI_CHECK *param,
|
|||||||
if (share->state.key_root[sort_key] == HA_OFFSET_ERROR)
|
if (share->state.key_root[sort_key] == HA_OFFSET_ERROR)
|
||||||
DBUG_RETURN(0); /* Nothing to do */
|
DBUG_RETURN(0); /* Nothing to do */
|
||||||
|
|
||||||
init_key_cache(param->use_buffers);
|
init_key_cache(dflt_keycache,opt_key_cache_block_size,param->use_buffers,
|
||||||
|
&dflt_key_cache_var);
|
||||||
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
|
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
|
||||||
WRITE_CACHE,share->pack.header_length,1,
|
WRITE_CACHE,share->pack.header_length,1,
|
||||||
MYF(MY_WME | MY_WAIT_IF_FULL)))
|
MYF(MY_WME | MY_WAIT_IF_FULL)))
|
||||||
|
@ -166,6 +166,8 @@ typedef struct st_mi_isam_share { /* Shared between opens */
|
|||||||
char *data_file_name, /* Resolved path names from symlinks */
|
char *data_file_name, /* Resolved path names from symlinks */
|
||||||
*index_file_name;
|
*index_file_name;
|
||||||
byte *file_map; /* mem-map of file if possible */
|
byte *file_map; /* mem-map of file if possible */
|
||||||
|
KEY_CACHE_HANDLE *keycache; /* ref to the current key cache */
|
||||||
|
KEY_CACHE_HANDLE *reg_keycache; /* ref to the registered key cache */
|
||||||
MI_DECODE_TREE *decode_trees;
|
MI_DECODE_TREE *decode_trees;
|
||||||
uint16 *decode_tables;
|
uint16 *decode_tables;
|
||||||
int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
|
int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
|
||||||
@ -550,11 +552,12 @@ extern int _mi_search_next(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
|
|||||||
extern int _mi_search_first(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos);
|
extern int _mi_search_first(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos);
|
||||||
extern int _mi_search_last(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos);
|
extern int _mi_search_last(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos);
|
||||||
extern uchar *_mi_fetch_keypage(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t page,
|
extern uchar *_mi_fetch_keypage(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t page,
|
||||||
uchar *buff,int return_buffer);
|
int level,uchar *buff,int return_buffer);
|
||||||
extern int _mi_write_keypage(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t page,
|
extern int _mi_write_keypage(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t page,
|
||||||
uchar *buff);
|
int level, uchar *buff);
|
||||||
extern int _mi_dispose(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos);
|
extern int _mi_dispose(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos,
|
||||||
extern my_off_t _mi_new(MI_INFO *info,MI_KEYDEF *keyinfo);
|
int level);
|
||||||
|
extern my_off_t _mi_new(MI_INFO *info,MI_KEYDEF *keyinfo,int level);
|
||||||
extern uint _mi_make_key(MI_INFO *info,uint keynr,uchar *key,
|
extern uint _mi_make_key(MI_INFO *info,uint keynr,uchar *key,
|
||||||
const byte *record,my_off_t filepos);
|
const byte *record,my_off_t filepos);
|
||||||
extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old,
|
extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old,
|
||||||
|
@ -333,7 +333,8 @@ static int examine_log(my_string file_name, char **table_names)
|
|||||||
bzero((gptr) com_count,sizeof(com_count));
|
bzero((gptr) com_count,sizeof(com_count));
|
||||||
init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
|
init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
|
||||||
(tree_element_free) file_info_free, NULL);
|
(tree_element_free) file_info_free, NULL);
|
||||||
VOID(init_key_cache(KEY_CACHE_SIZE));
|
VOID(init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE,
|
||||||
|
&dflt_key_cache_var));
|
||||||
|
|
||||||
files_open=0; access_time=0;
|
files_open=0; access_time=0;
|
||||||
while (access_time++ != number_of_commands &&
|
while (access_time++ != number_of_commands &&
|
||||||
@ -647,7 +648,7 @@ static int examine_log(my_string file_name, char **table_names)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end_key_cache();
|
end_key_cache(dflt_keycache,1);
|
||||||
delete_tree(&tree);
|
delete_tree(&tree);
|
||||||
VOID(end_io_cache(&cache));
|
VOID(end_io_cache(&cache));
|
||||||
VOID(my_close(file,MYF(0)));
|
VOID(my_close(file,MYF(0)));
|
||||||
@ -667,7 +668,7 @@ static int examine_log(my_string file_name, char **table_names)
|
|||||||
llstr(isamlog_filepos,llbuff)));
|
llstr(isamlog_filepos,llbuff)));
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
end:
|
end:
|
||||||
end_key_cache();
|
end_key_cache(dflt_keycache,1);
|
||||||
delete_tree(&tree);
|
delete_tree(&tree);
|
||||||
VOID(end_io_cache(&cache));
|
VOID(end_io_cache(&cache));
|
||||||
VOID(my_close(file,MYF(0)));
|
VOID(my_close(file,MYF(0)));
|
||||||
|
@ -60,7 +60,7 @@ static int rtree_find_req(MI_INFO *info, MI_KEYDEF *keyinfo, uint search_flag, u
|
|||||||
my_errno = HA_ERR_OUT_OF_MEM;
|
my_errno = HA_ERR_OUT_OF_MEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!_mi_fetch_keypage(info, keyinfo, page, page_buf, 0))
|
if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = mi_test_if_nod(page_buf);
|
nod_flag = mi_test_if_nod(page_buf);
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ static int rtree_get_req(MI_INFO *info, MI_KEYDEF *keyinfo, uint key_length,
|
|||||||
|
|
||||||
if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
|
if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
|
||||||
return -1;
|
return -1;
|
||||||
if (!_mi_fetch_keypage(info, keyinfo, page, page_buf, 0))
|
if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = mi_test_if_nod(page_buf);
|
nod_flag = mi_test_if_nod(page_buf);
|
||||||
|
|
||||||
@ -429,7 +429,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
my_errno = HA_ERR_OUT_OF_MEM;
|
my_errno = HA_ERR_OUT_OF_MEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!_mi_fetch_keypage(info, keyinfo, page, page_buf, 0))
|
if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = mi_test_if_nod(page_buf);
|
nod_flag = mi_test_if_nod(page_buf);
|
||||||
|
|
||||||
@ -445,7 +445,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
case 0: /* child was not split */
|
case 0: /* child was not split */
|
||||||
{
|
{
|
||||||
rtree_combine_rect(keyinfo->seg, k, key, k, key_length);
|
rtree_combine_rect(keyinfo->seg, k, key, k, key_length);
|
||||||
if (_mi_write_keypage(info, keyinfo, page, page_buf))
|
if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
@ -462,7 +462,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
goto err1;
|
goto err1;
|
||||||
res = rtree_add_key(info, keyinfo, new_key, key_length,
|
res = rtree_add_key(info, keyinfo, new_key, key_length,
|
||||||
page_buf, new_page);
|
page_buf, new_page);
|
||||||
if (_mi_write_keypage(info, keyinfo, page, page_buf))
|
if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
@ -476,7 +476,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = rtree_add_key(info, keyinfo, key, key_length, page_buf, new_page);
|
res = rtree_add_key(info, keyinfo, key, key_length, page_buf, new_page);
|
||||||
if (_mi_write_keypage(info, keyinfo, page, page_buf))
|
if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
@ -509,12 +509,12 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if ((old_root = _mi_new(info, keyinfo)) == HA_OFFSET_ERROR)
|
if ((old_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
|
||||||
return -1;
|
return -1;
|
||||||
info->buff_used = 1;
|
info->buff_used = 1;
|
||||||
mi_putint(info->buff, 2, 0);
|
mi_putint(info->buff, 2, 0);
|
||||||
res = rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL);
|
res = rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL);
|
||||||
if (_mi_write_keypage(info, keyinfo, old_root, info->buff))
|
if (_mi_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff))
|
||||||
return 1;
|
return 1;
|
||||||
info->s->state.key_root[keynr] = old_root;
|
info->s->state.key_root[keynr] = old_root;
|
||||||
return res;
|
return res;
|
||||||
@ -542,7 +542,8 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mi_putint(new_root_buf, 2, nod_flag);
|
mi_putint(new_root_buf, 2, nod_flag);
|
||||||
if ((new_root = _mi_new(info, keyinfo)) == HA_OFFSET_ERROR)
|
if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
|
||||||
|
HA_OFFSET_ERROR)
|
||||||
goto err1;
|
goto err1;
|
||||||
|
|
||||||
new_key = new_root_buf + keyinfo->block_length + nod_flag;
|
new_key = new_root_buf + keyinfo->block_length + nod_flag;
|
||||||
@ -559,7 +560,8 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
|
|||||||
if (rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf, NULL)
|
if (rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf, NULL)
|
||||||
== -1)
|
== -1)
|
||||||
goto err1;
|
goto err1;
|
||||||
if (_mi_write_keypage(info, keyinfo, new_root, new_root_buf))
|
if (_mi_write_keypage(info, keyinfo, new_root,
|
||||||
|
DFLT_INIT_HITS, new_root_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
info->s->state.key_root[keynr] = new_root;
|
info->s->state.key_root[keynr] = new_root;
|
||||||
|
|
||||||
@ -636,7 +638,7 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
my_errno = HA_ERR_OUT_OF_MEM;
|
my_errno = HA_ERR_OUT_OF_MEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!_mi_fetch_keypage(info, keyinfo, page, page_buf, 0))
|
if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = mi_test_if_nod(page_buf);
|
nod_flag = mi_test_if_nod(page_buf);
|
||||||
|
|
||||||
@ -662,7 +664,8 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
if (rtree_set_key_mbr(info, keyinfo, k, key_length,
|
if (rtree_set_key_mbr(info, keyinfo, k, key_length,
|
||||||
_mi_kpos(nod_flag, k)))
|
_mi_kpos(nod_flag, k)))
|
||||||
goto err1;
|
goto err1;
|
||||||
if (_mi_write_keypage(info, keyinfo, page, page_buf))
|
if (_mi_write_keypage(info, keyinfo, page,
|
||||||
|
DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -672,7 +675,8 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
level + 1))
|
level + 1))
|
||||||
goto err1;
|
goto err1;
|
||||||
rtree_delete_key(info, page_buf, k, key_length, nod_flag);
|
rtree_delete_key(info, page_buf, k, key_length, nod_flag);
|
||||||
if (_mi_write_keypage(info, keyinfo, page, page_buf))
|
if (_mi_write_keypage(info, keyinfo, page,
|
||||||
|
DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
*page_size = mi_getint(page_buf);
|
*page_size = mi_getint(page_buf);
|
||||||
}
|
}
|
||||||
@ -686,7 +690,8 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
case 2: /* vacuous case: last key in the leaf */
|
case 2: /* vacuous case: last key in the leaf */
|
||||||
{
|
{
|
||||||
rtree_delete_key(info, page_buf, k, key_length, nod_flag);
|
rtree_delete_key(info, page_buf, k, key_length, nod_flag);
|
||||||
if (_mi_write_keypage(info, keyinfo, page, page_buf))
|
if (_mi_write_keypage(info, keyinfo, page,
|
||||||
|
DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
*page_size = mi_getint(page_buf);
|
*page_size = mi_getint(page_buf);
|
||||||
res = 0;
|
res = 0;
|
||||||
@ -711,13 +716,13 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
|||||||
{
|
{
|
||||||
/* last key in the leaf */
|
/* last key in the leaf */
|
||||||
res = 2;
|
res = 2;
|
||||||
if (_mi_dispose(info, keyinfo, page))
|
if (_mi_dispose(info, keyinfo, page, DFLT_INIT_HITS))
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
if (_mi_write_keypage(info, keyinfo, page, page_buf))
|
if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
goto ok;
|
goto ok;
|
||||||
@ -783,7 +788,7 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length)
|
|||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
if (!_mi_fetch_keypage(info, keyinfo, ReinsertList.pages[i].offs,
|
if (!_mi_fetch_keypage(info, keyinfo, ReinsertList.pages[i].offs,
|
||||||
page_buf, 0))
|
DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = mi_test_if_nod(page_buf);
|
nod_flag = mi_test_if_nod(page_buf);
|
||||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
||||||
@ -798,7 +803,8 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
my_afree((byte*)page_buf);
|
my_afree((byte*)page_buf);
|
||||||
if (_mi_dispose(info, keyinfo, ReinsertList.pages[i].offs))
|
if (_mi_dispose(info, keyinfo, ReinsertList.pages[i].offs,
|
||||||
|
DFLT_INIT_HITS))
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
if (ReinsertList.pages)
|
if (ReinsertList.pages)
|
||||||
@ -807,7 +813,8 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length)
|
|||||||
/* check for redundant root (not leaf, 1 child) and eliminate */
|
/* check for redundant root (not leaf, 1 child) and eliminate */
|
||||||
if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||||
goto err1;
|
goto err1;
|
||||||
if (!_mi_fetch_keypage(info, keyinfo, old_root, info->buff, 0))
|
if (!_mi_fetch_keypage(info, keyinfo, old_root, DFLT_INIT_HITS,
|
||||||
|
info->buff, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = mi_test_if_nod(info->buff);
|
nod_flag = mi_test_if_nod(info->buff);
|
||||||
page_size = mi_getint(info->buff);
|
page_size = mi_getint(info->buff);
|
||||||
@ -816,7 +823,7 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length)
|
|||||||
{
|
{
|
||||||
my_off_t new_root = _mi_kpos(nod_flag,
|
my_off_t new_root = _mi_kpos(nod_flag,
|
||||||
rt_PAGE_FIRST_KEY(info->buff, nod_flag));
|
rt_PAGE_FIRST_KEY(info->buff, nod_flag));
|
||||||
if (_mi_dispose(info, keyinfo, old_root))
|
if (_mi_dispose(info, keyinfo, old_root, DFLT_INIT_HITS))
|
||||||
goto err1;
|
goto err1;
|
||||||
info->s->state.key_root[keynr] = new_root;
|
info->s->state.key_root[keynr] = new_root;
|
||||||
}
|
}
|
||||||
@ -863,7 +870,7 @@ ha_rows rtree_estimate(MI_INFO *info, uint keynr, uchar *key,
|
|||||||
return HA_POS_ERROR;
|
return HA_POS_ERROR;
|
||||||
if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
|
if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
|
||||||
return HA_POS_ERROR;
|
return HA_POS_ERROR;
|
||||||
if (!_mi_fetch_keypage(info, keyinfo, root, page_buf, 0))
|
if (!_mi_fetch_keypage(info, keyinfo, root, DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = mi_test_if_nod(page_buf);
|
nod_flag = mi_test_if_nod(page_buf);
|
||||||
|
|
||||||
|
@ -88,7 +88,8 @@ int rtree_delete_key(MI_INFO *info, uchar *page_buf, uchar *key,
|
|||||||
int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
|
||||||
uint key_length, my_off_t child_page)
|
uint key_length, my_off_t child_page)
|
||||||
{
|
{
|
||||||
if (!_mi_fetch_keypage(info, keyinfo, child_page, info->buff, 0))
|
if (!_mi_fetch_keypage(info, keyinfo, child_page,
|
||||||
|
DFLT_INIT_HITS, info->buff, 0))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length);
|
return rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length);
|
||||||
|
@ -332,10 +332,12 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
|
|||||||
mi_putint(page, 2 + n1 * full_length, nod_flag);
|
mi_putint(page, 2 + n1 * full_length, nod_flag);
|
||||||
mi_putint(new_page, 2 + n2 * full_length, nod_flag);
|
mi_putint(new_page, 2 + n2 * full_length, nod_flag);
|
||||||
|
|
||||||
if ((*new_page_offs= _mi_new(info, keyinfo)) == HA_OFFSET_ERROR)
|
if ((*new_page_offs= _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
|
||||||
|
HA_OFFSET_ERROR)
|
||||||
err_code= -1;
|
err_code= -1;
|
||||||
else
|
else
|
||||||
err_code= _mi_write_keypage(info, keyinfo, *new_page_offs, new_page);
|
err_code= _mi_write_keypage(info, keyinfo, *new_page_offs,
|
||||||
|
DFLT_INIT_HITS, new_page);
|
||||||
|
|
||||||
my_afree((byte*)new_page);
|
my_afree((byte*)new_page);
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
explain
|
explain
|
||||||
select min(a1) from t1 where a1 != 'KKK';
|
select min(a1) from t1 where a1 != 'KKK';
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index NULL PRIMARY 3 NULL 14 Using where; Using index
|
1 SIMPLE t1 range PRIMARY PRIMARY 3 NULL 14 Using where; Using index
|
||||||
explain
|
explain
|
||||||
select max(a3) from t1 where a2 < 2 and a3 < 'SEA';
|
select max(a3) from t1 where a2 < 2 and a3 < 'SEA';
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
@ -560,7 +560,7 @@ explain
|
|||||||
select concat(min(t1.a1),min(t2.a4)) from t1, t2 where t2.a4 <> 'AME';
|
select concat(min(t1.a1),min(t2.a4)) from t1, t2 where t2.a4 <> 'AME';
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 index NULL PRIMARY 3 NULL 14 Using index
|
1 SIMPLE t1 index NULL PRIMARY 3 NULL 14 Using index
|
||||||
1 SIMPLE t2 index NULL k2 4 NULL 6 Using where; Using index
|
1 SIMPLE t2 range k2 k2 4 NULL 6 Using where; Using index
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
CREATE TABLE t1 (a int, b int);
|
CREATE TABLE t1 (a int, b int);
|
||||||
select count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1;
|
select count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1;
|
||||||
|
@ -41,3 +41,194 @@ SELECT @@default.key_buffer_size;
|
|||||||
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'default.key_buffer_size' at line 1
|
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'default.key_buffer_size' at line 1
|
||||||
SELECT @@skr.table_type="test";
|
SELECT @@skr.table_type="test";
|
||||||
ERROR HY000: Variable 'table_type' is not a variable component (Can't be used as XXXX.variable_name)
|
ERROR HY000: Variable 'table_type' is not a variable component (Can't be used as XXXX.variable_name)
|
||||||
|
select @@keycache1.key_cache_block_size;
|
||||||
|
@@keycache1.key_cache_block_size
|
||||||
|
0
|
||||||
|
select @@keycache1.key_buffer_size;
|
||||||
|
@@keycache1.key_buffer_size
|
||||||
|
0
|
||||||
|
set global keycache1.key_cache_block_size=2048;
|
||||||
|
select @@keycache1.key_buffer_size;
|
||||||
|
@@keycache1.key_buffer_size
|
||||||
|
0
|
||||||
|
select @@keycache1.key_cache_block_size;
|
||||||
|
@@keycache1.key_cache_block_size
|
||||||
|
2048
|
||||||
|
set global keycache1.key_buffer_size=1*1024*1024;
|
||||||
|
select @@keycache1.key_buffer_size;
|
||||||
|
@@keycache1.key_buffer_size
|
||||||
|
1048576
|
||||||
|
select @@keycache1.key_cache_block_size;
|
||||||
|
@@keycache1.key_cache_block_size
|
||||||
|
2048
|
||||||
|
set global keycache2.key_buffer_size=4*1024*1024;
|
||||||
|
select @@keycache2.key_buffer_size;
|
||||||
|
@@keycache2.key_buffer_size
|
||||||
|
4194304
|
||||||
|
select @@keycache2.key_cache_block_size;
|
||||||
|
@@keycache2.key_cache_block_size
|
||||||
|
1024
|
||||||
|
set global keycache1.key_buffer_size=0;
|
||||||
|
select @@keycache1.key_buffer_size;
|
||||||
|
@@keycache1.key_buffer_size
|
||||||
|
0
|
||||||
|
select @@keycache1.key_cache_block_size;
|
||||||
|
@@keycache1.key_cache_block_size
|
||||||
|
0
|
||||||
|
select @@key_buffer_size;
|
||||||
|
@@key_buffer_size
|
||||||
|
2097152
|
||||||
|
select @@key_cache_block_size;
|
||||||
|
@@key_cache_block_size
|
||||||
|
1024
|
||||||
|
drop table if exists t1, t2;
|
||||||
|
create table t1 (p int primary key, a char(10));
|
||||||
|
create table t2 (p int primary key, i int, a char(10), key k1(i), key k2(a));
|
||||||
|
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
|
||||||
|
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
|
||||||
|
(3, 1, 'yyyy'), (4, 3, 'zzzz');
|
||||||
|
select * from t1;
|
||||||
|
p a
|
||||||
|
1 qqqq
|
||||||
|
11 yyyy
|
||||||
|
select * from t2;
|
||||||
|
p i a
|
||||||
|
1 1 qqqq
|
||||||
|
2 1 pppp
|
||||||
|
3 1 yyyy
|
||||||
|
4 3 zzzz
|
||||||
|
update t1 set p=2 where p=1;
|
||||||
|
update t2 set i=2 where i=1;
|
||||||
|
cache index t1 keys in keycache1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 assign_to_keycache status OK
|
||||||
|
explain select p from t1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 Using index
|
||||||
|
select p from t1;
|
||||||
|
p
|
||||||
|
2
|
||||||
|
11
|
||||||
|
explain select i from t2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 index NULL k1 5 NULL 4 Using index
|
||||||
|
select i from t2;
|
||||||
|
i
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
3
|
||||||
|
explain select count(*) from t1, t2 where t1.p = t2.i;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 2 Using index
|
||||||
|
1 SIMPLE t2 ref k1 k1 5 test.t1.p 2 Using where; Using index
|
||||||
|
select count(*) from t1, t2 where t1.p = t2.i;
|
||||||
|
count(*)
|
||||||
|
3
|
||||||
|
cache index t2 keys in keycache1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t2 assign_to_keycache status OK
|
||||||
|
update t2 set p=p+1000, i=2 where a='qqqq';
|
||||||
|
cache index t2 keys in keycache2;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t2 assign_to_keycache status OK
|
||||||
|
insert into t2 values (2000, 3, 'yyyy');
|
||||||
|
cache index t2 keys in keycache1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t2 assign_to_keycache status OK
|
||||||
|
update t2 set p=3000 where a='zzzz';
|
||||||
|
select * from t2;
|
||||||
|
p i a
|
||||||
|
1001 2 qqqq
|
||||||
|
2 2 pppp
|
||||||
|
3 2 yyyy
|
||||||
|
3000 3 zzzz
|
||||||
|
2000 3 yyyy
|
||||||
|
explain select p from t2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 index NULL PRIMARY 4 NULL 5 Using index
|
||||||
|
select p from t2;
|
||||||
|
p
|
||||||
|
2
|
||||||
|
3
|
||||||
|
1001
|
||||||
|
2000
|
||||||
|
3000
|
||||||
|
explain select i from t2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 index NULL k1 5 NULL 5 Using index
|
||||||
|
select i from t2;
|
||||||
|
i
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
3
|
||||||
|
3
|
||||||
|
explain select a from t2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 index NULL k2 11 NULL 5 Using index
|
||||||
|
select a from t2;
|
||||||
|
a
|
||||||
|
pppp
|
||||||
|
qqqq
|
||||||
|
yyyy
|
||||||
|
yyyy
|
||||||
|
zzzz
|
||||||
|
select @@keycache2.key_buffer_size;
|
||||||
|
@@keycache2.key_buffer_size
|
||||||
|
4194304
|
||||||
|
select @@keycache2.key_cache_block_size;
|
||||||
|
@@keycache2.key_cache_block_size
|
||||||
|
1024
|
||||||
|
set global keycache2.key_buffer_size=0;
|
||||||
|
select @@keycache2.key_buffer_size;
|
||||||
|
@@keycache2.key_buffer_size
|
||||||
|
0
|
||||||
|
select @@keycache2.key_cache_block_size;
|
||||||
|
@@keycache2.key_cache_block_size
|
||||||
|
0
|
||||||
|
update t2 set p=4000 where a='zzzz';
|
||||||
|
update t1 set p=p+1;
|
||||||
|
set global keycache1.key_buffer_size=0;
|
||||||
|
select * from t2;
|
||||||
|
p i a
|
||||||
|
1001 2 qqqq
|
||||||
|
2 2 pppp
|
||||||
|
3 2 yyyy
|
||||||
|
4000 3 zzzz
|
||||||
|
2000 3 yyyy
|
||||||
|
select p from t2;
|
||||||
|
p
|
||||||
|
2
|
||||||
|
3
|
||||||
|
1001
|
||||||
|
2000
|
||||||
|
4000
|
||||||
|
explain select i from t2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 index NULL k1 5 NULL 5 Using index
|
||||||
|
select i from t2;
|
||||||
|
i
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
3
|
||||||
|
3
|
||||||
|
explain select a from t2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 index NULL k2 11 NULL 5 Using index
|
||||||
|
select a from t2;
|
||||||
|
a
|
||||||
|
pppp
|
||||||
|
qqqq
|
||||||
|
yyyy
|
||||||
|
yyyy
|
||||||
|
zzzz
|
||||||
|
select * from t1;
|
||||||
|
p a
|
||||||
|
3 qqqq
|
||||||
|
12 yyyy
|
||||||
|
select p from t1;
|
||||||
|
p
|
||||||
|
3
|
||||||
|
12
|
||||||
|
@ -4,14 +4,35 @@ INSERT INTO t1 VALUES (1), (2);
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<mysqldump>
|
<mysqldump>
|
||||||
<database name="test">
|
<database name="test">
|
||||||
<table name="t1">
|
<table_structure name="t1">
|
||||||
|
<field Field="a" Type="int(11)" Null="YES" />
|
||||||
|
</table_structure>
|
||||||
|
<table_data name="t1">
|
||||||
<row>
|
<row>
|
||||||
<field name="a">1</field>
|
<field name="a">1</field>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<field name="a">2</field>
|
<field name="a">2</field>
|
||||||
</row>
|
</row>
|
||||||
</table>
|
</table_data>
|
||||||
</database>
|
</database>
|
||||||
</mysqldump>
|
</mysqldump>
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE `t"1` (`a"b"c"` char(2));
|
||||||
|
INSERT INTO `t"1` VALUES ("\"1"), ("2\"");
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<mysqldump>
|
||||||
|
<database name="test">
|
||||||
|
<table_structure name="t"1">
|
||||||
|
<field Field="a"b"c"" Type="char(2)" Null="YES" />
|
||||||
|
</table_structure>
|
||||||
|
<table_data name="t"1">
|
||||||
|
<row>
|
||||||
|
<field name="a"b"c"">"1</field>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<field name="a"b"c"">2"</field>
|
||||||
|
</row>
|
||||||
|
</table_data>
|
||||||
|
</database>
|
||||||
|
</mysqldump>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
drop table if exists t1;
|
drop table if exists t1, t2;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
event_date date DEFAULT '0000-00-00' NOT NULL,
|
event_date date DEFAULT '0000-00-00' NOT NULL,
|
||||||
type int(11) DEFAULT '0' NOT NULL,
|
type int(11) DEFAULT '0' NOT NULL,
|
||||||
@ -215,17 +215,6 @@ select count(*) from t1 where art = 'J';
|
|||||||
count(*)
|
count(*)
|
||||||
213
|
213
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
|
|
||||||
insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
|
|
||||||
(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
|
|
||||||
(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
|
|
||||||
(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
|
|
||||||
(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
|
|
||||||
(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
|
|
||||||
(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
|
|
||||||
select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
|
|
||||||
id1 idnull
|
|
||||||
drop table t1;
|
|
||||||
create table t1 (x int, y int, index(x), index(y));
|
create table t1 (x int, y int, index(x), index(y));
|
||||||
insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
update t1 set y=x;
|
update t1 set y=x;
|
||||||
@ -286,3 +275,145 @@ id
|
|||||||
5
|
5
|
||||||
9
|
9
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
|
||||||
|
insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
|
||||||
|
(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
|
||||||
|
(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
|
||||||
|
(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
|
||||||
|
(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
|
||||||
|
(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
|
||||||
|
(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
|
||||||
|
select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
|
||||||
|
id1 idnull
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (
|
||||||
|
id int not null auto_increment,
|
||||||
|
name char(1) not null,
|
||||||
|
uid int not null,
|
||||||
|
primary key (id),
|
||||||
|
index uid_index (uid));
|
||||||
|
create table t2 (
|
||||||
|
id int not null auto_increment,
|
||||||
|
name char(1) not null,
|
||||||
|
uid int not null,
|
||||||
|
primary key (id),
|
||||||
|
index uid_index (uid));
|
||||||
|
insert into t1(id, uid, name) values(1, 0, ' ');
|
||||||
|
insert into t1(uid, name) values(0, ' ');
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
delete from t2;
|
||||||
|
insert into t2(uid, name) values
|
||||||
|
(1, CHAR(64+1)),
|
||||||
|
(2, CHAR(64+2)),
|
||||||
|
(3, CHAR(64+3)),
|
||||||
|
(4, CHAR(64+4)),
|
||||||
|
(5, CHAR(64+5)),
|
||||||
|
(6, CHAR(64+6)),
|
||||||
|
(7, CHAR(64+7)),
|
||||||
|
(8, CHAR(64+8)),
|
||||||
|
(9, CHAR(64+9)),
|
||||||
|
(10, CHAR(64+10)),
|
||||||
|
(11, CHAR(64+11)),
|
||||||
|
(12, CHAR(64+12)),
|
||||||
|
(13, CHAR(64+13)),
|
||||||
|
(14, CHAR(64+14)),
|
||||||
|
(15, CHAR(64+15)),
|
||||||
|
(16, CHAR(64+16)),
|
||||||
|
(17, CHAR(64+17)),
|
||||||
|
(18, CHAR(64+18)),
|
||||||
|
(19, CHAR(64+19)),
|
||||||
|
(20, CHAR(64+20)),
|
||||||
|
(21, CHAR(64+21)),
|
||||||
|
(22, CHAR(64+22)),
|
||||||
|
(23, CHAR(64+23)),
|
||||||
|
(24, CHAR(64+24)),
|
||||||
|
(25, CHAR(64+25)),
|
||||||
|
(26, CHAR(64+26));
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
delete from t2;
|
||||||
|
insert into t2(id, uid, name) select id, uid, name from t1;
|
||||||
|
select count(*) from t1;
|
||||||
|
count(*)
|
||||||
|
1026
|
||||||
|
select count(*) from t2;
|
||||||
|
count(*)
|
||||||
|
1026
|
||||||
|
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range uid_index uid_index 4 NULL 128 Using where
|
||||||
|
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
|
||||||
|
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range uid_index uid_index 4 NULL 129 Using where
|
||||||
|
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
|
||||||
|
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
|
||||||
|
id name uid id name uid
|
||||||
|
1001 A 1 1001 A 1
|
||||||
|
1002 B 2 1002 B 2
|
||||||
|
1003 C 3 1003 C 3
|
||||||
|
1004 D 4 1004 D 4
|
||||||
|
1005 E 5 1005 E 5
|
||||||
|
1006 F 6 1006 F 6
|
||||||
|
1007 G 7 1007 G 7
|
||||||
|
1008 H 8 1008 H 8
|
||||||
|
1009 I 9 1009 I 9
|
||||||
|
1010 J 10 1010 J 10
|
||||||
|
1011 K 11 1011 K 11
|
||||||
|
1012 L 12 1012 L 12
|
||||||
|
1013 M 13 1013 M 13
|
||||||
|
1014 N 14 1014 N 14
|
||||||
|
1015 O 15 1015 O 15
|
||||||
|
1016 P 16 1016 P 16
|
||||||
|
1017 Q 17 1017 Q 17
|
||||||
|
1018 R 18 1018 R 18
|
||||||
|
1019 S 19 1019 S 19
|
||||||
|
1020 T 20 1020 T 20
|
||||||
|
1021 U 21 1021 U 21
|
||||||
|
1022 V 22 1022 V 22
|
||||||
|
1023 W 23 1023 W 23
|
||||||
|
1024 X 24 1024 X 24
|
||||||
|
1025 Y 25 1025 Y 25
|
||||||
|
1026 Z 26 1026 Z 26
|
||||||
|
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
||||||
|
id name uid id name uid
|
||||||
|
1001 A 1 1001 A 1
|
||||||
|
1002 B 2 1002 B 2
|
||||||
|
1003 C 3 1003 C 3
|
||||||
|
1004 D 4 1004 D 4
|
||||||
|
1005 E 5 1005 E 5
|
||||||
|
1006 F 6 1006 F 6
|
||||||
|
1007 G 7 1007 G 7
|
||||||
|
1008 H 8 1008 H 8
|
||||||
|
1009 I 9 1009 I 9
|
||||||
|
1010 J 10 1010 J 10
|
||||||
|
1011 K 11 1011 K 11
|
||||||
|
1012 L 12 1012 L 12
|
||||||
|
1013 M 13 1013 M 13
|
||||||
|
1014 N 14 1014 N 14
|
||||||
|
1015 O 15 1015 O 15
|
||||||
|
1016 P 16 1016 P 16
|
||||||
|
1017 Q 17 1017 Q 17
|
||||||
|
1018 R 18 1018 R 18
|
||||||
|
1019 S 19 1019 S 19
|
||||||
|
1020 T 20 1020 T 20
|
||||||
|
1021 U 21 1021 U 21
|
||||||
|
1022 V 22 1022 V 22
|
||||||
|
1023 W 23 1023 W 23
|
||||||
|
1024 X 24 1024 X 24
|
||||||
|
1025 Y 25 1025 Y 25
|
||||||
|
1026 Z 26 1026 Z 26
|
||||||
|
drop table t1,t2;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Test of key cache
|
# Test of multiple key caches
|
||||||
#
|
#
|
||||||
|
|
||||||
SET @save_key_buffer=@@key_buffer_size;
|
SET @save_key_buffer=@@key_buffer_size;
|
||||||
@ -40,3 +40,83 @@ SET @@global.key_buffer_size=@save_key_buffer;
|
|||||||
SELECT @@default.key_buffer_size;
|
SELECT @@default.key_buffer_size;
|
||||||
--error 1271
|
--error 1271
|
||||||
SELECT @@skr.table_type="test";
|
SELECT @@skr.table_type="test";
|
||||||
|
|
||||||
|
select @@keycache1.key_cache_block_size;
|
||||||
|
select @@keycache1.key_buffer_size;
|
||||||
|
set global keycache1.key_cache_block_size=2048;
|
||||||
|
select @@keycache1.key_buffer_size;
|
||||||
|
select @@keycache1.key_cache_block_size;
|
||||||
|
set global keycache1.key_buffer_size=1*1024*1024;
|
||||||
|
select @@keycache1.key_buffer_size;
|
||||||
|
select @@keycache1.key_cache_block_size;
|
||||||
|
set global keycache2.key_buffer_size=4*1024*1024;
|
||||||
|
select @@keycache2.key_buffer_size;
|
||||||
|
select @@keycache2.key_cache_block_size;
|
||||||
|
set global keycache1.key_buffer_size=0;
|
||||||
|
select @@keycache1.key_buffer_size;
|
||||||
|
select @@keycache1.key_cache_block_size;
|
||||||
|
select @@key_buffer_size;
|
||||||
|
select @@key_cache_block_size;
|
||||||
|
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1, t2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create table t1 (p int primary key, a char(10));
|
||||||
|
create table t2 (p int primary key, i int, a char(10), key k1(i), key k2(a));
|
||||||
|
|
||||||
|
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
|
||||||
|
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
|
||||||
|
(3, 1, 'yyyy'), (4, 3, 'zzzz');
|
||||||
|
select * from t1;
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
update t1 set p=2 where p=1;
|
||||||
|
update t2 set i=2 where i=1;
|
||||||
|
|
||||||
|
cache index t1 keys in keycache1;
|
||||||
|
|
||||||
|
explain select p from t1;
|
||||||
|
select p from t1;
|
||||||
|
explain select i from t2;
|
||||||
|
select i from t2;
|
||||||
|
explain select count(*) from t1, t2 where t1.p = t2.i;
|
||||||
|
select count(*) from t1, t2 where t1.p = t2.i;
|
||||||
|
|
||||||
|
cache index t2 keys in keycache1;
|
||||||
|
update t2 set p=p+1000, i=2 where a='qqqq';
|
||||||
|
cache index t2 keys in keycache2;
|
||||||
|
insert into t2 values (2000, 3, 'yyyy');
|
||||||
|
cache index t2 keys in keycache1;
|
||||||
|
update t2 set p=3000 where a='zzzz';
|
||||||
|
select * from t2;
|
||||||
|
explain select p from t2;
|
||||||
|
select p from t2;
|
||||||
|
explain select i from t2;
|
||||||
|
select i from t2;
|
||||||
|
explain select a from t2;
|
||||||
|
select a from t2;
|
||||||
|
|
||||||
|
select @@keycache2.key_buffer_size;
|
||||||
|
select @@keycache2.key_cache_block_size;
|
||||||
|
set global keycache2.key_buffer_size=0;
|
||||||
|
select @@keycache2.key_buffer_size;
|
||||||
|
select @@keycache2.key_cache_block_size;
|
||||||
|
|
||||||
|
|
||||||
|
update t2 set p=4000 where a='zzzz';
|
||||||
|
update t1 set p=p+1;
|
||||||
|
|
||||||
|
set global keycache1.key_buffer_size=0;
|
||||||
|
select * from t2;
|
||||||
|
select p from t2;
|
||||||
|
explain select i from t2;
|
||||||
|
select i from t2;
|
||||||
|
explain select a from t2;
|
||||||
|
select a from t2;
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
select p from t1;
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,5 +6,14 @@ DROP TABLE IF EXISTS t1;
|
|||||||
|
|
||||||
CREATE TABLE t1(a int);
|
CREATE TABLE t1(a int);
|
||||||
INSERT INTO t1 VALUES (1), (2);
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
--exec $MYSQL_DUMP -X test t1
|
--exec $MYSQL_DUMP --skip-all -X test t1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #1707
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE `t"1` (`a"b"c"` char(2));
|
||||||
|
INSERT INTO `t"1` VALUES ("\"1"), ("2\"");
|
||||||
|
--exec $MYSQL_DUMP --skip-all -X test
|
||||||
|
DROP TABLE `t"1`;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t1;
|
drop table if exists t1, t2;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
@ -174,18 +174,6 @@ select count(*) from t1 where art = 'j' or art = 'J';
|
|||||||
select count(*) from t1 where art = 'j';
|
select count(*) from t1 where art = 'j';
|
||||||
select count(*) from t1 where art = 'J';
|
select count(*) from t1 where art = 'J';
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
|
|
||||||
insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
|
|
||||||
(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
|
|
||||||
(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
|
|
||||||
(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
|
|
||||||
(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
|
|
||||||
(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
|
|
||||||
(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
|
|
||||||
select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
|
|
||||||
drop table t1;
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# BETWEEN problems
|
# BETWEEN problems
|
||||||
#
|
#
|
||||||
@ -225,3 +213,96 @@ insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
|
|||||||
select id from t1 where id in (2,5,9) ;
|
select id from t1 where id in (2,5,9) ;
|
||||||
select id from t1 where id=2 or id=5 or id=9 ;
|
select id from t1 where id=2 or id=5 or id=9 ;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
|
||||||
|
insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
|
||||||
|
(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
|
||||||
|
(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
|
||||||
|
(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
|
||||||
|
(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
|
||||||
|
(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
|
||||||
|
(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
|
||||||
|
select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Problem with optimizing !=
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (
|
||||||
|
id int not null auto_increment,
|
||||||
|
name char(1) not null,
|
||||||
|
uid int not null,
|
||||||
|
primary key (id),
|
||||||
|
index uid_index (uid));
|
||||||
|
|
||||||
|
create table t2 (
|
||||||
|
id int not null auto_increment,
|
||||||
|
name char(1) not null,
|
||||||
|
uid int not null,
|
||||||
|
primary key (id),
|
||||||
|
index uid_index (uid));
|
||||||
|
|
||||||
|
insert into t1(id, uid, name) values(1, 0, ' ');
|
||||||
|
insert into t1(uid, name) values(0, ' ');
|
||||||
|
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t2(uid, name) select uid, name from t1;
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
|
||||||
|
delete from t2;
|
||||||
|
insert into t2(uid, name) values
|
||||||
|
(1, CHAR(64+1)),
|
||||||
|
(2, CHAR(64+2)),
|
||||||
|
(3, CHAR(64+3)),
|
||||||
|
(4, CHAR(64+4)),
|
||||||
|
(5, CHAR(64+5)),
|
||||||
|
(6, CHAR(64+6)),
|
||||||
|
(7, CHAR(64+7)),
|
||||||
|
(8, CHAR(64+8)),
|
||||||
|
(9, CHAR(64+9)),
|
||||||
|
(10, CHAR(64+10)),
|
||||||
|
(11, CHAR(64+11)),
|
||||||
|
(12, CHAR(64+12)),
|
||||||
|
(13, CHAR(64+13)),
|
||||||
|
(14, CHAR(64+14)),
|
||||||
|
(15, CHAR(64+15)),
|
||||||
|
(16, CHAR(64+16)),
|
||||||
|
(17, CHAR(64+17)),
|
||||||
|
(18, CHAR(64+18)),
|
||||||
|
(19, CHAR(64+19)),
|
||||||
|
(20, CHAR(64+20)),
|
||||||
|
(21, CHAR(64+21)),
|
||||||
|
(22, CHAR(64+22)),
|
||||||
|
(23, CHAR(64+23)),
|
||||||
|
(24, CHAR(64+24)),
|
||||||
|
(25, CHAR(64+25)),
|
||||||
|
(26, CHAR(64+26));
|
||||||
|
|
||||||
|
insert into t1(uid, name) select uid, name from t2;
|
||||||
|
|
||||||
|
delete from t2;
|
||||||
|
insert into t2(id, uid, name) select id, uid, name from t1;
|
||||||
|
|
||||||
|
select count(*) from t1;
|
||||||
|
select count(*) from t2;
|
||||||
|
|
||||||
|
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
|
||||||
|
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
||||||
|
|
||||||
|
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
|
||||||
|
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
||||||
|
|
||||||
|
drop table t1,t2;
|
||||||
|
1498
mysys/mf_keycache.c
1498
mysys/mf_keycache.c
File diff suppressed because it is too large
Load Diff
131
sql/ha_myisam.cc
131
sql/ha_myisam.cc
@ -228,6 +228,12 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
|
|||||||
{
|
{
|
||||||
if (!(file=mi_open(name, mode, test_if_locked)))
|
if (!(file=mi_open(name, mode, test_if_locked)))
|
||||||
return (my_errno ? my_errno : -1);
|
return (my_errno ? my_errno : -1);
|
||||||
|
|
||||||
|
/* Synchronize key cache assignment of the handler */
|
||||||
|
KEY_CACHE_VAR *key_cache= table->key_cache ? table->key_cache :
|
||||||
|
&dflt_key_cache_var;
|
||||||
|
VOID(mi_extra(file, HA_EXTRA_SET_KEY_CACHE,
|
||||||
|
(void*) &key_cache->cache));
|
||||||
|
|
||||||
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
|
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
|
||||||
VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
|
VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
|
||||||
@ -691,6 +697,131 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Assign table indexes to a key cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
|
||||||
|
{
|
||||||
|
uint len;
|
||||||
|
KEY_CACHE_VAR *old_key_cache;
|
||||||
|
KEY_CACHE_VAR *new_key_cache;
|
||||||
|
const char *errmsg=0;
|
||||||
|
int error= HA_ADMIN_OK;
|
||||||
|
ulonglong map= ~(ulonglong) 0;
|
||||||
|
TABLE_LIST *table_list= table->pos_in_table_list;
|
||||||
|
const char *new_key_cache_name= table_list->option ?
|
||||||
|
(const char *) table_list->option :
|
||||||
|
DEFAULT_KEY_CACHE_NAME;
|
||||||
|
KEY_CACHE_ASMT *key_cache_asmt= table->key_cache_asmt;
|
||||||
|
bool triggered= key_cache_asmt->triggered;
|
||||||
|
|
||||||
|
DBUG_ENTER("ha_myisam::assign_to_keycache");
|
||||||
|
|
||||||
|
VOID(pthread_mutex_lock(&LOCK_assign));
|
||||||
|
|
||||||
|
old_key_cache= key_cache_asmt->key_cache;
|
||||||
|
|
||||||
|
/* Check validity of the index references */
|
||||||
|
if (!triggered && table_list->use_index)
|
||||||
|
{
|
||||||
|
key_map kmap= get_key_map_from_key_list(table, table_list->use_index);
|
||||||
|
if (kmap == ~(key_map) 0)
|
||||||
|
{
|
||||||
|
errmsg= thd->net.last_error;
|
||||||
|
error= HA_ADMIN_FAILED;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (kmap)
|
||||||
|
map= kmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
len= strlen(new_key_cache_name);
|
||||||
|
new_key_cache= get_or_create_key_cache(new_key_cache_name, len);
|
||||||
|
if (old_key_cache == new_key_cache)
|
||||||
|
{
|
||||||
|
/* Nothing to do: table is assigned to the same key cache */
|
||||||
|
goto ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!new_key_cache ||
|
||||||
|
(!new_key_cache->cache && ha_key_cache(new_key_cache)))
|
||||||
|
{
|
||||||
|
if (key_cache_asmt->triggered)
|
||||||
|
error= HA_ERR_OUT_OF_MEM;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char buf[ERRMSGSIZE];
|
||||||
|
my_snprintf(buf, ERRMSGSIZE,
|
||||||
|
"Failed to create key cache %s", new_key_cache_name);
|
||||||
|
errmsg= buf;
|
||||||
|
error= HA_ADMIN_FAILED;
|
||||||
|
}
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
reassign_key_cache(key_cache_asmt, new_key_cache);
|
||||||
|
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_assign));
|
||||||
|
error= mi_assign_to_keycache(file, map, new_key_cache, &LOCK_assign);
|
||||||
|
VOID(pthread_mutex_lock(&LOCK_assign));
|
||||||
|
|
||||||
|
if (error && !key_cache_asmt->triggered)
|
||||||
|
{
|
||||||
|
switch (error) {
|
||||||
|
default:
|
||||||
|
char buf[ERRMSGSIZE+20];
|
||||||
|
my_snprintf(buf, ERRMSGSIZE,
|
||||||
|
"Failed to flush to index file (errno: %d)", my_errno);
|
||||||
|
errmsg= buf;
|
||||||
|
}
|
||||||
|
error= HA_ADMIN_CORRUPT;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto ok;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (!triggered)
|
||||||
|
{
|
||||||
|
MI_CHECK param;
|
||||||
|
myisamchk_init(¶m);
|
||||||
|
param.thd= thd;
|
||||||
|
param.op_name= (char*)"assign_to_keycache";
|
||||||
|
param.db_name= table->table_cache_key;
|
||||||
|
param.table_name= table->table_name;
|
||||||
|
param.testflag= 0;
|
||||||
|
mi_check_print_error(¶m, errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ok:
|
||||||
|
if (--key_cache_asmt->requests)
|
||||||
|
{
|
||||||
|
/* There is a queue of assignments for the table */
|
||||||
|
|
||||||
|
/* Remove the first member from the queue */
|
||||||
|
struct st_my_thread_var *last= key_cache_asmt->queue;
|
||||||
|
struct st_my_thread_var *thread= last->next;
|
||||||
|
if (thread->next == thread)
|
||||||
|
key_cache_asmt->queue= 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last->next= thread->next;
|
||||||
|
last->next->prev= &last->next;
|
||||||
|
thread->next= 0;
|
||||||
|
}
|
||||||
|
/* Signal the first waiting thread to proceed */
|
||||||
|
VOID(pthread_cond_signal(&thread->suspend));
|
||||||
|
}
|
||||||
|
|
||||||
|
key_cache_asmt->triggered= 0;
|
||||||
|
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_assign));
|
||||||
|
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Preload pages of the index file for a table into the key cache.
|
Preload pages of the index file for a table into the key cache.
|
||||||
*/
|
*/
|
||||||
|
@ -127,6 +127,7 @@ class ha_myisam: public handler
|
|||||||
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
|
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
int restore(THD* thd, HA_CHECK_OPT* check_opt);
|
int restore(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
int backup(THD* thd, HA_CHECK_OPT* check_opt);
|
int backup(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
|
int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
|
int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
int dump(THD* thd, int fd);
|
int dump(THD* thd, int fd);
|
||||||
|
@ -45,6 +45,12 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked)
|
|||||||
DBUG_PRINT("info", ("ha_myisammrg::open exit %d", my_errno));
|
DBUG_PRINT("info", ("ha_myisammrg::open exit %d", my_errno));
|
||||||
return (my_errno ? my_errno : -1);
|
return (my_errno ? my_errno : -1);
|
||||||
}
|
}
|
||||||
|
/* Synchronize key cache assignment for the file */
|
||||||
|
KEY_CACHE_VAR *key_cache= table->key_cache ? table->key_cache :
|
||||||
|
&dflt_key_cache_var;
|
||||||
|
VOID(myrg_extra(file, HA_EXTRA_SET_KEY_CACHE,
|
||||||
|
(void*) &key_cache->cache));
|
||||||
|
|
||||||
DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc..."))
|
DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc..."))
|
||||||
myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref);
|
myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref);
|
||||||
if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED ||
|
if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED ||
|
||||||
|
@ -736,6 +736,11 @@ int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt)
|
|||||||
return HA_ADMIN_NOT_IMPLEMENTED;
|
return HA_ADMIN_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int handler::assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
|
||||||
|
{
|
||||||
|
return HA_ADMIN_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
int handler::preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
|
int handler::preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
|
||||||
{
|
{
|
||||||
return HA_ADMIN_NOT_IMPLEMENTED;
|
return HA_ADMIN_NOT_IMPLEMENTED;
|
||||||
@ -1102,27 +1107,62 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
|
|||||||
|
|
||||||
/* Use key cacheing on all databases */
|
/* Use key cacheing on all databases */
|
||||||
|
|
||||||
void ha_key_cache(void)
|
int ha_key_cache(KEY_CACHE_VAR *key_cache)
|
||||||
{
|
{
|
||||||
/*
|
if (!key_cache->cache)
|
||||||
The following mutex is not really needed as long as keybuff_size is
|
{
|
||||||
treated as a long value, but we use the mutex here to guard for future
|
/*
|
||||||
changes.
|
The following mutex is not really needed as long as keybuff_size is
|
||||||
*/
|
treated as a long value, but we use the mutex here to guard for future
|
||||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
changes.
|
||||||
long tmp= (long) keybuff_size;
|
*/
|
||||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||||
if (tmp)
|
if (!key_cache->block_size)
|
||||||
(void) init_key_cache(tmp);
|
key_cache->block_size= dflt_key_cache_block_size;
|
||||||
|
if (!key_cache->buff_size)
|
||||||
|
key_cache->buff_size= dflt_key_buff_size;
|
||||||
|
long tmp_buff_size= (long) key_cache->buff_size;
|
||||||
|
long tmp_block_size= (long) key_cache->block_size;
|
||||||
|
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||||
|
return !init_key_cache(&key_cache->cache,
|
||||||
|
tmp_block_size,
|
||||||
|
tmp_buff_size,
|
||||||
|
key_cache);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ha_resize_key_cache(KEY_CACHE_VAR *key_cache)
|
||||||
void ha_resize_key_cache(void)
|
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
if (key_cache->cache)
|
||||||
long tmp= (long) keybuff_size;
|
{
|
||||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||||
(void) resize_key_cache(tmp);
|
long tmp_buff_size= (long) key_cache->buff_size;
|
||||||
|
long tmp_block_size= (long) key_cache->block_size;
|
||||||
|
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||||
|
return !resize_key_cache(&key_cache->cache, tmp_block_size,
|
||||||
|
tmp_buff_size);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ha_change_key_cache_param(KEY_CACHE_VAR *key_cache)
|
||||||
|
{
|
||||||
|
if (key_cache->cache)
|
||||||
|
{
|
||||||
|
change_key_cache_param(key_cache->cache);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ha_end_key_cache(KEY_CACHE_VAR *key_cache)
|
||||||
|
{
|
||||||
|
if (key_cache->cache)
|
||||||
|
{
|
||||||
|
end_key_cache(&key_cache->cache, 1);
|
||||||
|
return key_cache->cache ? 1 : 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -306,6 +306,7 @@ public:
|
|||||||
virtual bool check_and_repair(THD *thd) {return 1;}
|
virtual bool check_and_repair(THD *thd) {return 1;}
|
||||||
virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
|
virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
|
||||||
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
|
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
|
virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
|
virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
|
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
|
||||||
/*
|
/*
|
||||||
@ -389,8 +390,10 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
|
|||||||
bool update_create_info);
|
bool update_create_info);
|
||||||
int ha_delete_table(enum db_type db_type, const char *path);
|
int ha_delete_table(enum db_type db_type, const char *path);
|
||||||
void ha_drop_database(char* path);
|
void ha_drop_database(char* path);
|
||||||
void ha_key_cache(void);
|
int ha_key_cache(KEY_CACHE_VAR *key_cache);
|
||||||
void ha_resize_key_cache(void);
|
int ha_resize_key_cache(KEY_CACHE_VAR *key_cache);
|
||||||
|
int ha_change_key_cache_param(KEY_CACHE_VAR *key_cache);
|
||||||
|
int ha_end_key_cache(KEY_CACHE_VAR *key_cache);
|
||||||
int ha_start_stmt(THD *thd);
|
int ha_start_stmt(THD *thd);
|
||||||
int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name,
|
int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name,
|
||||||
my_off_t end_offset);
|
my_off_t end_offset);
|
||||||
|
@ -245,7 +245,7 @@ public:
|
|||||||
longlong val_int();
|
longlong val_int();
|
||||||
enum Functype functype() const { return NE_FUNC; }
|
enum Functype functype() const { return NE_FUNC; }
|
||||||
cond_result eq_cmp_result() const { return COND_FALSE; }
|
cond_result eq_cmp_result() const { return COND_FALSE; }
|
||||||
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
|
optimize_type select_optimize() const { return OPTIMIZE_KEY; }
|
||||||
const char *func_name() const { return "<>"; }
|
const char *func_name() const { return "<>"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -424,6 +424,10 @@ bool check_stack_overrun(THD *thd,char *dummy);
|
|||||||
void table_cache_init(void);
|
void table_cache_init(void);
|
||||||
void table_cache_free(void);
|
void table_cache_free(void);
|
||||||
uint cached_tables(void);
|
uint cached_tables(void);
|
||||||
|
void assign_cache_init(void);
|
||||||
|
void assign_cache_free(void);
|
||||||
|
void reassign_key_cache(KEY_CACHE_ASMT *key_cache_asmt,
|
||||||
|
KEY_CACHE_VAR *new_key_cache);
|
||||||
void kill_mysql(void);
|
void kill_mysql(void);
|
||||||
void close_connection(THD *thd, uint errcode, bool lock);
|
void close_connection(THD *thd, uint errcode, bool lock);
|
||||||
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
||||||
@ -453,7 +457,10 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* table_list,
|
|||||||
HA_CHECK_OPT* check_opt);
|
HA_CHECK_OPT* check_opt);
|
||||||
int mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
|
int mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
|
||||||
HA_CHECK_OPT* check_opt);
|
HA_CHECK_OPT* check_opt);
|
||||||
|
int mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list);
|
||||||
int mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
|
int mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
|
||||||
|
int reassign_keycache_tables(THD* thd, KEY_CACHE_VAR* src_cache,
|
||||||
|
char *dest_name, bool remove_fl);
|
||||||
|
|
||||||
bool check_simple_select();
|
bool check_simple_select();
|
||||||
|
|
||||||
@ -826,7 +833,7 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
|
|||||||
LOCK_error_log, LOCK_delayed_insert,
|
LOCK_error_log, LOCK_delayed_insert,
|
||||||
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
|
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
|
||||||
LOCK_slave_list, LOCK_active_mi, LOCK_manager,
|
LOCK_slave_list, LOCK_active_mi, LOCK_manager,
|
||||||
LOCK_global_system_variables, LOCK_user_conn;
|
LOCK_global_system_variables, LOCK_user_conn, LOCK_assign;
|
||||||
extern rw_lock_t LOCK_grant;
|
extern rw_lock_t LOCK_grant;
|
||||||
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
|
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
|
||||||
extern pthread_attr_t connection_attrib;
|
extern pthread_attr_t connection_attrib;
|
||||||
|
@ -307,8 +307,6 @@ ulong rpl_recovery_rank=0;
|
|||||||
ulong my_bind_addr; /* the address we bind to */
|
ulong my_bind_addr; /* the address we bind to */
|
||||||
volatile ulong cached_thread_count= 0;
|
volatile ulong cached_thread_count= 0;
|
||||||
|
|
||||||
ulonglong keybuff_size;
|
|
||||||
|
|
||||||
double log_10[32]; /* 10 potences */
|
double log_10[32]; /* 10 potences */
|
||||||
|
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
@ -371,6 +369,7 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
|
|||||||
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
|
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
|
||||||
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
||||||
LOCK_global_system_variables,
|
LOCK_global_system_variables,
|
||||||
|
LOCK_assign,
|
||||||
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
|
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
|
||||||
rw_lock_t LOCK_grant;
|
rw_lock_t LOCK_grant;
|
||||||
pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped,
|
pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped,
|
||||||
@ -897,6 +896,7 @@ void clean_up(bool print_message)
|
|||||||
#endif
|
#endif
|
||||||
query_cache_destroy();
|
query_cache_destroy();
|
||||||
table_cache_free();
|
table_cache_free();
|
||||||
|
assign_cache_free();
|
||||||
hostname_cache_free();
|
hostname_cache_free();
|
||||||
item_user_lock_free();
|
item_user_lock_free();
|
||||||
lex_free(); /* Free some memory */
|
lex_free(); /* Free some memory */
|
||||||
@ -906,7 +906,8 @@ void clean_up(bool print_message)
|
|||||||
udf_free();
|
udf_free();
|
||||||
#endif
|
#endif
|
||||||
(void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */
|
(void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */
|
||||||
end_key_cache();
|
process_key_caches(&ha_end_key_cache);
|
||||||
|
ha_end_key_cache(&dflt_key_cache_var);
|
||||||
delete_elements(&key_caches, free_key_cache);
|
delete_elements(&key_caches, free_key_cache);
|
||||||
end_thr_alarm(1); /* Free allocated memory */
|
end_thr_alarm(1); /* Free allocated memory */
|
||||||
#ifdef USE_RAID
|
#ifdef USE_RAID
|
||||||
@ -989,6 +990,7 @@ static void clean_up_mutexes()
|
|||||||
#endif
|
#endif
|
||||||
(void) pthread_mutex_destroy(&LOCK_active_mi);
|
(void) pthread_mutex_destroy(&LOCK_active_mi);
|
||||||
(void) pthread_mutex_destroy(&LOCK_global_system_variables);
|
(void) pthread_mutex_destroy(&LOCK_global_system_variables);
|
||||||
|
(void) pthread_mutex_destroy(&LOCK_assign);
|
||||||
(void) pthread_cond_destroy(&COND_thread_count);
|
(void) pthread_cond_destroy(&COND_thread_count);
|
||||||
(void) pthread_cond_destroy(&COND_refresh);
|
(void) pthread_cond_destroy(&COND_refresh);
|
||||||
(void) pthread_cond_destroy(&COND_thread_cache);
|
(void) pthread_cond_destroy(&COND_thread_cache);
|
||||||
@ -1558,14 +1560,15 @@ or misconfigured. This error can also be caused by malfunctioning hardware.\n",
|
|||||||
We will try our best to scrape up some info that will hopefully help diagnose\n\
|
We will try our best to scrape up some info that will hopefully help diagnose\n\
|
||||||
the problem, but since we have already crashed, something is definitely wrong\n\
|
the problem, but since we have already crashed, something is definitely wrong\n\
|
||||||
and this may fail.\n\n");
|
and this may fail.\n\n");
|
||||||
fprintf(stderr, "key_buffer_size=%lu\n", (ulong) keybuff_size);
|
fprintf(stderr, "key_buffer_size=%lu\n",
|
||||||
|
(ulong) dflt_key_cache_var.buff_size);
|
||||||
fprintf(stderr, "read_buffer_size=%ld\n", global_system_variables.read_buff_size);
|
fprintf(stderr, "read_buffer_size=%ld\n", global_system_variables.read_buff_size);
|
||||||
fprintf(stderr, "max_used_connections=%ld\n", max_used_connections);
|
fprintf(stderr, "max_used_connections=%ld\n", max_used_connections);
|
||||||
fprintf(stderr, "max_connections=%ld\n", max_connections);
|
fprintf(stderr, "max_connections=%ld\n", max_connections);
|
||||||
fprintf(stderr, "threads_connected=%d\n", thread_count);
|
fprintf(stderr, "threads_connected=%d\n", thread_count);
|
||||||
fprintf(stderr, "It is possible that mysqld could use up to \n\
|
fprintf(stderr, "It is possible that mysqld could use up to \n\
|
||||||
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = %ld K\n\
|
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = %ld K\n\
|
||||||
bytes of memory\n", ((ulong) keybuff_size +
|
bytes of memory\n", ((ulong) dflt_key_cache_var.buff_size +
|
||||||
(global_system_variables.read_buff_size +
|
(global_system_variables.read_buff_size +
|
||||||
global_system_variables.sortbuff_size) *
|
global_system_variables.sortbuff_size) *
|
||||||
max_connections)/ 1024);
|
max_connections)/ 1024);
|
||||||
@ -2186,6 +2189,7 @@ static int init_thread_environment()
|
|||||||
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
|
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
|
||||||
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
|
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
|
||||||
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
|
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
|
||||||
|
(void) pthread_mutex_init(&LOCK_assign, MY_MUTEX_INIT_FAST);
|
||||||
(void) my_rwlock_init(&LOCK_grant, NULL);
|
(void) my_rwlock_init(&LOCK_grant, NULL);
|
||||||
(void) pthread_cond_init(&COND_thread_count,NULL);
|
(void) pthread_cond_init(&COND_thread_count,NULL);
|
||||||
(void) pthread_cond_init(&COND_refresh,NULL);
|
(void) pthread_cond_init(&COND_refresh,NULL);
|
||||||
@ -2237,6 +2241,7 @@ static int init_server_components()
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("init_server_components");
|
DBUG_ENTER("init_server_components");
|
||||||
table_cache_init();
|
table_cache_init();
|
||||||
|
assign_cache_init();
|
||||||
hostname_cache_init();
|
hostname_cache_init();
|
||||||
query_cache_result_size_limit(query_cache_limit);
|
query_cache_result_size_limit(query_cache_limit);
|
||||||
query_cache_set_min_res_unit(query_cache_min_res_unit);
|
query_cache_set_min_res_unit(query_cache_min_res_unit);
|
||||||
@ -2307,7 +2312,10 @@ Now disabling --log-slave-updates.");
|
|||||||
}
|
}
|
||||||
if (opt_myisam_log)
|
if (opt_myisam_log)
|
||||||
(void) mi_log(1);
|
(void) mi_log(1);
|
||||||
ha_key_cache();
|
|
||||||
|
ha_key_cache(&dflt_key_cache_var);
|
||||||
|
process_key_caches(&ha_key_cache);
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
|
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
|
||||||
if (locked_in_memory && !geteuid())
|
if (locked_in_memory && !geteuid())
|
||||||
@ -3573,7 +3581,9 @@ enum options_mysqld
|
|||||||
OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN,
|
OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN,
|
||||||
OPT_FT_MAX_WORD_LEN, OPT_FT_QUERY_EXPANSION_LIMIT, OPT_FT_STOPWORD_FILE,
|
OPT_FT_MAX_WORD_LEN, OPT_FT_QUERY_EXPANSION_LIMIT, OPT_FT_STOPWORD_FILE,
|
||||||
OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
|
OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
|
||||||
OPT_KEY_BUFFER_SIZE, OPT_LONG_QUERY_TIME,
|
OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
|
||||||
|
OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
|
||||||
|
OPT_LONG_QUERY_TIME,
|
||||||
OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
|
OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
|
||||||
OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
|
OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
|
||||||
OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
|
OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
|
||||||
@ -4286,10 +4296,26 @@ replicating a LOAD DATA INFILE command.",
|
|||||||
IO_SIZE, 0},
|
IO_SIZE, 0},
|
||||||
{"key_buffer_size", OPT_KEY_BUFFER_SIZE,
|
{"key_buffer_size", OPT_KEY_BUFFER_SIZE,
|
||||||
"The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
|
"The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
|
||||||
(gptr*) &keybuff_size, (gptr*) &keybuff_size, 0,
|
(gptr*) &dflt_key_cache_var.buff_size,
|
||||||
|
(gptr*) &dflt_key_cache_var.buff_size, 0,
|
||||||
(enum get_opt_var_type) (GET_ULL | GET_ASK_ADDR),
|
(enum get_opt_var_type) (GET_ULL | GET_ASK_ADDR),
|
||||||
REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD,
|
REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD,
|
||||||
IO_SIZE, 0},
|
IO_SIZE, 0},
|
||||||
|
{"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
|
||||||
|
"The default size of key cache blocks",
|
||||||
|
(gptr*) &dflt_key_cache_var.block_size,
|
||||||
|
(gptr*) &dflt_key_cache_var.block_size, 0, GET_ULONG,
|
||||||
|
REQUIRED_ARG, KEY_CACHE_BLOCK_SIZE , 512, 1024*16, MALLOC_OVERHEAD, 512, 0},
|
||||||
|
{"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
|
||||||
|
"The minimum percentage of warm blocks in key cache",
|
||||||
|
(gptr*) &dflt_key_cache_var.division_limit,
|
||||||
|
(gptr*) &dflt_key_cache_var.division_limit, 0, GET_ULONG,
|
||||||
|
REQUIRED_ARG, 100, 1, 100, 0, 1, 0},
|
||||||
|
{"key_cache_division_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
|
||||||
|
"This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache",
|
||||||
|
(gptr*) &dflt_key_cache_var.age_threshold,
|
||||||
|
(gptr*) &dflt_key_cache_var.age_threshold, 0, GET_ULONG,
|
||||||
|
REQUIRED_ARG, 300, 100, ~0L, 0, 100, 0},
|
||||||
{"long_query_time", OPT_LONG_QUERY_TIME,
|
{"long_query_time", OPT_LONG_QUERY_TIME,
|
||||||
"Log all queries that have taken more than long_query_time seconds to execute to file.",
|
"Log all queries that have taken more than long_query_time seconds to execute to file.",
|
||||||
(gptr*) &global_system_variables.long_query_time,
|
(gptr*) &global_system_variables.long_query_time,
|
||||||
@ -4707,13 +4733,19 @@ struct show_var_st status_vars[]= {
|
|||||||
{"Handler_rollback", (char*) &ha_rollback_count, SHOW_LONG},
|
{"Handler_rollback", (char*) &ha_rollback_count, SHOW_LONG},
|
||||||
{"Handler_update", (char*) &ha_update_count, SHOW_LONG},
|
{"Handler_update", (char*) &ha_update_count, SHOW_LONG},
|
||||||
{"Handler_write", (char*) &ha_write_count, SHOW_LONG},
|
{"Handler_write", (char*) &ha_write_count, SHOW_LONG},
|
||||||
{"Key_blocks_used", (char*) &my_blocks_used, SHOW_LONG_CONST},
|
{"Key_blocks_used", (char*) &dflt_key_cache_var.blocks_used,
|
||||||
{"Key_read_requests", (char*) &my_cache_r_requests, SHOW_LONG},
|
SHOW_LONG_CONST},
|
||||||
{"Key_reads", (char*) &my_cache_read, SHOW_LONG},
|
{"Key_read_requests", (char*) &dflt_key_cache_var.cache_r_requests,
|
||||||
{"Key_write_requests", (char*) &my_cache_w_requests, SHOW_LONG},
|
SHOW_LONG},
|
||||||
{"Key_writes", (char*) &my_cache_write, SHOW_LONG},
|
{"Key_reads", (char*) &dflt_key_cache_var.cache_read,
|
||||||
|
SHOW_LONG},
|
||||||
|
{"Key_write_requests", (char*) &dflt_key_cache_var.cache_w_requests,
|
||||||
|
SHOW_LONG},
|
||||||
|
{"Key_writes", (char*) &dflt_key_cache_var.cache_write,
|
||||||
|
SHOW_LONG},
|
||||||
{"Max_used_connections", (char*) &max_used_connections, SHOW_LONG},
|
{"Max_used_connections", (char*) &max_used_connections, SHOW_LONG},
|
||||||
{"Not_flushed_key_blocks", (char*) &my_blocks_changed, SHOW_LONG_CONST},
|
{"Not_flushed_key_blocks", (char*) &dflt_key_cache_var.blocks_changed,
|
||||||
|
SHOW_LONG_CONST},
|
||||||
{"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_CONST},
|
{"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_CONST},
|
||||||
{"Open_tables", (char*) 0, SHOW_OPENTABLES},
|
{"Open_tables", (char*) 0, SHOW_OPENTABLES},
|
||||||
{"Open_files", (char*) &my_file_opened, SHOW_LONG_CONST},
|
{"Open_files", (char*) &my_file_opened, SHOW_LONG_CONST},
|
||||||
@ -4925,7 +4957,8 @@ static void mysql_init_variables(void)
|
|||||||
threads.empty();
|
threads.empty();
|
||||||
thread_cache.empty();
|
thread_cache.empty();
|
||||||
key_caches.empty();
|
key_caches.empty();
|
||||||
if (!get_or_create_key_cache("default", 7))
|
if (!get_or_create_key_cache(DEFAULT_KEY_CACHE_NAME,
|
||||||
|
strlen(DEFAULT_KEY_CACHE_NAME)))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
/* Initialize structures that is used when processing options */
|
/* Initialize structures that is used when processing options */
|
||||||
@ -5551,21 +5584,28 @@ extern "C" gptr *
|
|||||||
mysql_getopt_value(const char *keyname, uint key_length,
|
mysql_getopt_value(const char *keyname, uint key_length,
|
||||||
const struct my_option *option)
|
const struct my_option *option)
|
||||||
{
|
{
|
||||||
if (!key_length)
|
|
||||||
{
|
|
||||||
keyname= "default";
|
|
||||||
key_length= 7;
|
|
||||||
}
|
|
||||||
switch (option->id) {
|
switch (option->id) {
|
||||||
case OPT_KEY_BUFFER_SIZE:
|
case OPT_KEY_BUFFER_SIZE:
|
||||||
|
case OPT_KEY_CACHE_BLOCK_SIZE:
|
||||||
|
case OPT_KEY_CACHE_DIVISION_LIMIT:
|
||||||
|
case OPT_KEY_CACHE_AGE_THRESHOLD:
|
||||||
{
|
{
|
||||||
KEY_CACHE *key_cache;
|
KEY_CACHE_VAR *key_cache;
|
||||||
if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
|
if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
|
||||||
exit(1);
|
exit(1);
|
||||||
return (gptr*) &key_cache->size;
|
switch (option->id) {
|
||||||
|
case OPT_KEY_BUFFER_SIZE:
|
||||||
|
return (gptr*) &key_cache->buff_size;
|
||||||
|
case OPT_KEY_CACHE_BLOCK_SIZE:
|
||||||
|
return (gptr*) &key_cache->block_size;
|
||||||
|
case OPT_KEY_CACHE_DIVISION_LIMIT:
|
||||||
|
return (gptr*) &key_cache->division_limit;
|
||||||
|
case OPT_KEY_CACHE_AGE_THRESHOLD:
|
||||||
|
return (gptr*) &key_cache->age_threshold;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return option->value;
|
return option->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5629,16 +5669,16 @@ static void get_options(int argc,char **argv)
|
|||||||
table_alias_charset= (lower_case_table_names ?
|
table_alias_charset= (lower_case_table_names ?
|
||||||
files_charset_info :
|
files_charset_info :
|
||||||
&my_charset_bin);
|
&my_charset_bin);
|
||||||
/* QQ To be deleted when we have key cache variables in a struct */
|
|
||||||
{
|
|
||||||
NAMED_LIST *not_used;
|
|
||||||
keybuff_size= (((KEY_CACHE *) find_named(&key_caches, "default", 7,
|
|
||||||
¬_used))->size);
|
|
||||||
}
|
|
||||||
if (opt_short_log_format)
|
if (opt_short_log_format)
|
||||||
opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
|
opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
|
||||||
if (opt_log_queries_not_using_indexes)
|
if (opt_log_queries_not_using_indexes)
|
||||||
opt_specialflag|= SPECIAL_LOG_QUERIES_NOT_USING_INDEXES;
|
opt_specialflag|= SPECIAL_LOG_QUERIES_NOT_USING_INDEXES;
|
||||||
|
/* Set up default values for a key cache */
|
||||||
|
KEY_CACHE_VAR *key_cache= &dflt_key_cache_var;
|
||||||
|
dflt_key_cache_block_size= key_cache->block_size;
|
||||||
|
dflt_key_buff_size= key_cache->buff_size;
|
||||||
|
dflt_key_cache_division_limit= key_cache->division_limit;
|
||||||
|
dflt_key_cache_age_threshold= key_cache->age_threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -905,10 +905,17 @@ static SEL_TREE *
|
|||||||
get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
|
get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
|
||||||
Item *value, Item_result cmp_type)
|
Item *value, Item_result cmp_type)
|
||||||
{
|
{
|
||||||
|
bool ne_func= FALSE;
|
||||||
DBUG_ENTER("get_mm_parts");
|
DBUG_ENTER("get_mm_parts");
|
||||||
if (field->table != param->table)
|
if (field->table != param->table)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
if (type == Item_func::NE_FUNC)
|
||||||
|
{
|
||||||
|
ne_func= TRUE;
|
||||||
|
type= Item_func::LT_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
KEY_PART *key_part = param->key_parts;
|
KEY_PART *key_part = param->key_parts;
|
||||||
KEY_PART *end = param->key_parts_end;
|
KEY_PART *end = param->key_parts_end;
|
||||||
SEL_TREE *tree=0;
|
SEL_TREE *tree=0;
|
||||||
@ -943,6 +950,14 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
|
|||||||
tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
|
tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ne_func)
|
||||||
|
{
|
||||||
|
SEL_TREE *tree2= get_mm_parts(param, field, Item_func::GT_FUNC,
|
||||||
|
value, cmp_type);
|
||||||
|
if (tree2)
|
||||||
|
tree= tree_or(param,tree,tree2);
|
||||||
|
}
|
||||||
DBUG_RETURN(tree);
|
DBUG_RETURN(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
225
sql/set_var.cc
225
sql/set_var.cc
@ -60,6 +60,11 @@
|
|||||||
#include "ha_innodb.h"
|
#include "ha_innodb.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ulonglong dflt_key_buff_size;
|
||||||
|
uint dflt_key_cache_block_size;
|
||||||
|
uint dflt_key_cache_division_limit;
|
||||||
|
uint dflt_key_cache_age_threshold;
|
||||||
|
|
||||||
static HASH system_variable_hash;
|
static HASH system_variable_hash;
|
||||||
const char *bool_type_names[]= { "OFF", "ON", NullS };
|
const char *bool_type_names[]= { "OFF", "ON", NullS };
|
||||||
TYPELIB bool_typelib=
|
TYPELIB bool_typelib=
|
||||||
@ -92,7 +97,7 @@ static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type);
|
|||||||
static void fix_max_binlog_size(THD *thd, enum_var_type type);
|
static void fix_max_binlog_size(THD *thd, enum_var_type type);
|
||||||
static void fix_max_relay_log_size(THD *thd, enum_var_type type);
|
static void fix_max_relay_log_size(THD *thd, enum_var_type type);
|
||||||
static void fix_max_connections(THD *thd, enum_var_type type);
|
static void fix_max_connections(THD *thd, enum_var_type type);
|
||||||
static KEY_CACHE *create_key_cache(const char *name, uint length);
|
static KEY_CACHE_VAR *create_key_cache(const char *name, uint length);
|
||||||
void fix_sql_mode_var(THD *thd, enum_var_type type);
|
void fix_sql_mode_var(THD *thd, enum_var_type type);
|
||||||
static byte *get_error_count(THD *thd);
|
static byte *get_error_count(THD *thd);
|
||||||
static byte *get_warning_count(THD *thd);
|
static byte *get_warning_count(THD *thd);
|
||||||
@ -143,6 +148,11 @@ sys_var_thd_ulong sys_interactive_timeout("interactive_timeout",
|
|||||||
sys_var_thd_ulong sys_join_buffer_size("join_buffer_size",
|
sys_var_thd_ulong sys_join_buffer_size("join_buffer_size",
|
||||||
&SV::join_buff_size);
|
&SV::join_buff_size);
|
||||||
sys_var_key_buffer_size sys_key_buffer_size("key_buffer_size");
|
sys_var_key_buffer_size sys_key_buffer_size("key_buffer_size");
|
||||||
|
sys_var_key_cache_block_size sys_key_cache_block_size("key_cache_block_size");
|
||||||
|
sys_var_key_cache_division_limit
|
||||||
|
sys_key_cache_division_limit("key_cache_division_limit");
|
||||||
|
sys_var_key_cache_age_threshold
|
||||||
|
sys_key_cache_age_threshold("key_cache_age_threshold");
|
||||||
sys_var_bool_ptr sys_local_infile("local_infile",
|
sys_var_bool_ptr sys_local_infile("local_infile",
|
||||||
&opt_local_infile);
|
&opt_local_infile);
|
||||||
sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings);
|
sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings);
|
||||||
@ -422,6 +432,9 @@ sys_var *sys_variables[]=
|
|||||||
&sys_interactive_timeout,
|
&sys_interactive_timeout,
|
||||||
&sys_join_buffer_size,
|
&sys_join_buffer_size,
|
||||||
&sys_key_buffer_size,
|
&sys_key_buffer_size,
|
||||||
|
&sys_key_cache_block_size,
|
||||||
|
&sys_key_cache_division_limit,
|
||||||
|
&sys_key_cache_age_threshold,
|
||||||
&sys_last_insert_id,
|
&sys_last_insert_id,
|
||||||
&sys_local_infile,
|
&sys_local_infile,
|
||||||
&sys_log_binlog,
|
&sys_log_binlog,
|
||||||
@ -595,6 +608,12 @@ struct show_var_st init_vars[]= {
|
|||||||
{sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS},
|
{sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS},
|
||||||
{sys_join_buffer_size.name, (char*) &sys_join_buffer_size, SHOW_SYS},
|
{sys_join_buffer_size.name, (char*) &sys_join_buffer_size, SHOW_SYS},
|
||||||
{sys_key_buffer_size.name, (char*) &sys_key_buffer_size, SHOW_SYS},
|
{sys_key_buffer_size.name, (char*) &sys_key_buffer_size, SHOW_SYS},
|
||||||
|
{sys_key_cache_block_size.name, (char*) &sys_key_cache_block_size,
|
||||||
|
SHOW_SYS},
|
||||||
|
{sys_key_cache_division_limit.name, (char*) &sys_key_cache_division_limit,
|
||||||
|
SHOW_SYS},
|
||||||
|
{sys_key_cache_age_threshold.name, (char*) &sys_key_cache_age_threshold,
|
||||||
|
SHOW_SYS},
|
||||||
{"language", language, SHOW_CHAR},
|
{"language", language, SHOW_CHAR},
|
||||||
{"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
|
{"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
|
||||||
{sys_local_infile.name, (char*) &sys_local_infile, SHOW_SYS},
|
{sys_local_infile.name, (char*) &sys_local_infile, SHOW_SYS},
|
||||||
@ -1697,79 +1716,143 @@ void sys_var_collation_server::set_default(THD *thd, enum_var_type type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static LEX_STRING default_key_cache_base= {(char *) DEFAULT_KEY_CACHE_NAME, 7};
|
||||||
|
|
||||||
|
static KEY_CACHE_VAR zero_key_cache=
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
static KEY_CACHE_VAR *get_key_cache(LEX_STRING *cache_name)
|
||||||
|
{
|
||||||
|
if (!cache_name || !cache_name->str || !cache_name->length ||
|
||||||
|
cache_name->str == default_key_cache_base.str ||
|
||||||
|
(cache_name->length == default_key_cache_base.length &&
|
||||||
|
!memcmp(cache_name->str, default_key_cache_base.str,
|
||||||
|
default_key_cache_base.length)))
|
||||||
|
cache_name= &default_key_cache_base;
|
||||||
|
return ((KEY_CACHE_VAR*) find_named(&key_caches,
|
||||||
|
cache_name->str, cache_name->length,
|
||||||
|
0));
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type,
|
||||||
|
LEX_STRING *base)
|
||||||
|
{
|
||||||
|
KEY_CACHE_VAR *key_cache= get_key_cache(base);
|
||||||
|
if (!key_cache)
|
||||||
|
key_cache= &zero_key_cache;
|
||||||
|
return (byte*) key_cache + offset ;
|
||||||
|
}
|
||||||
|
|
||||||
bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
|
bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
|
||||||
{
|
{
|
||||||
ulonglong tmp= var->save_result.ulonglong_value;
|
ulonglong tmp= var->save_result.ulonglong_value;
|
||||||
|
|
||||||
NAMED_LIST *list;
|
|
||||||
LEX_STRING *base_name= &var->base;
|
LEX_STRING *base_name= &var->base;
|
||||||
|
|
||||||
if (!base_name->length)
|
if (!base_name->length)
|
||||||
{
|
base_name= &default_key_cache_base;
|
||||||
/* We are using SET KEY_BUFFER_SIZE=# */
|
KEY_CACHE_VAR *key_cache= get_key_cache(base_name);
|
||||||
base_name->str= (char*) "default";
|
|
||||||
base_name->length= 7;
|
|
||||||
}
|
|
||||||
KEY_CACHE *key_cache= (KEY_CACHE*) find_named(&key_caches, base_name->str,
|
|
||||||
base_name->length, &list);
|
|
||||||
if (!key_cache)
|
if (!key_cache)
|
||||||
{
|
{
|
||||||
if (!tmp) // Tried to delete cache
|
if (!tmp) // Tried to delete cache
|
||||||
return 0; // Ok, nothing to do
|
return 0; // Ok, nothing to do
|
||||||
if (!(key_cache= create_key_cache(base_name->str,
|
if (!(key_cache= create_key_cache(base_name->str,
|
||||||
base_name->length)))
|
base_name->length)))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!tmp) // Zero size means delete
|
if (!tmp) // Zero size means delete
|
||||||
{
|
{
|
||||||
/* Don't delete the default key cache */
|
if (!key_cache->cache)
|
||||||
if (base_name->length != 7 || memcmp(base_name->str, "default", 7))
|
return 0;
|
||||||
|
/* Delete not default key caches */
|
||||||
|
if (key_cache != &dflt_key_cache_var)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
QQ: Here we should move tables that is using the found key cache
|
Move tables using this key cache to the default key cache
|
||||||
to the default key cache
|
and remove this key cache if no tables are assigned to it
|
||||||
*/
|
*/
|
||||||
|
NAMED_LIST *list;
|
||||||
|
key_cache= (KEY_CACHE_VAR *) find_named(&key_caches, base_name->str,
|
||||||
|
base_name->length, &list);
|
||||||
delete list;
|
delete list;
|
||||||
|
int rc= reassign_keycache_tables(thd, key_cache,
|
||||||
|
default_key_cache_base.str, 1);
|
||||||
my_free((char*) key_cache, MYF(0));
|
my_free((char*) key_cache, MYF(0));
|
||||||
return 0;
|
return rc;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
key_cache->size= (ulonglong) getopt_ull_limit_value(tmp, option_limits);
|
key_cache->buff_size= (ulonglong) getopt_ull_limit_value(tmp, option_limits);
|
||||||
|
|
||||||
/* QQ: Needs to be updated when we have multiple key caches */
|
if (!key_cache->cache)
|
||||||
keybuff_size= key_cache->size;
|
return (bool)(ha_key_cache(key_cache));
|
||||||
ha_resize_key_cache();
|
else
|
||||||
|
return (bool)(ha_resize_key_cache(key_cache));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sys_var_key_cache_block_size::update(THD *thd, set_var *var)
|
||||||
|
{
|
||||||
|
ulong tmp= var->value->val_int();
|
||||||
|
LEX_STRING *base_name= &var->base;
|
||||||
|
if (!base_name->length)
|
||||||
|
base_name= &default_key_cache_base;
|
||||||
|
KEY_CACHE_VAR *key_cache= get_key_cache(base_name);
|
||||||
|
|
||||||
|
if (!key_cache && !(key_cache= create_key_cache(base_name->str,
|
||||||
|
base_name->length)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
key_cache->block_size= (ulong) getopt_ull_limit_value(tmp, option_limits);
|
||||||
|
|
||||||
|
if (key_cache->cache)
|
||||||
|
/* Do not build a new key cache here */
|
||||||
|
return (bool) (ha_resize_key_cache(key_cache));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sys_var_key_cache_division_limit::update(THD *thd, set_var *var)
|
||||||
static ulonglong zero=0;
|
|
||||||
|
|
||||||
byte *sys_var_key_buffer_size::value_ptr(THD *thd, enum_var_type type,
|
|
||||||
LEX_STRING *base)
|
|
||||||
{
|
{
|
||||||
const char *name;
|
ulong tmp= var->value->val_int();
|
||||||
uint length;
|
LEX_STRING *base_name= &var->base;
|
||||||
KEY_CACHE *key_cache;
|
if (!base_name->length)
|
||||||
NAMED_LIST *not_used;
|
base_name= &default_key_cache_base;
|
||||||
|
KEY_CACHE_VAR *key_cache= get_key_cache(base_name);
|
||||||
|
|
||||||
|
if (!key_cache && !(key_cache= create_key_cache(base_name->str,
|
||||||
|
base_name->length)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
key_cache->division_limit=
|
||||||
|
(ulong) getopt_ull_limit_value(tmp, option_limits);
|
||||||
|
|
||||||
if (!base->str)
|
if (key_cache->cache)
|
||||||
{
|
/* Do not build a new key cache here */
|
||||||
name= "default";
|
return (bool) (ha_change_key_cache_param(key_cache));
|
||||||
length= 7;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
bool sys_var_key_cache_age_threshold::update(THD *thd, set_var *var)
|
||||||
name= base->str;
|
{
|
||||||
length= base->length;
|
ulong tmp= var->value->val_int();
|
||||||
}
|
LEX_STRING *base_name= &var->base;
|
||||||
key_cache= (KEY_CACHE*) find_named(&key_caches, name, length, ¬_used);
|
if (!base_name->length)
|
||||||
if (!key_cache)
|
base_name= &default_key_cache_base;
|
||||||
return (byte*) &zero;
|
KEY_CACHE_VAR *key_cache= get_key_cache(base_name);
|
||||||
return (byte*) &key_cache->size;
|
|
||||||
|
if (!key_cache && !(key_cache= create_key_cache(base_name->str,
|
||||||
|
base_name->length)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
key_cache->division_limit=
|
||||||
|
(ulong) getopt_ull_limit_value(tmp, option_limits);
|
||||||
|
|
||||||
|
if (key_cache->cache)
|
||||||
|
/* Do not build a new key cache here */
|
||||||
|
return (bool) (ha_change_key_cache_param(key_cache));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -2355,7 +2438,8 @@ gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
|
|||||||
{
|
{
|
||||||
if (element->cmp(name, length))
|
if (element->cmp(name, length))
|
||||||
{
|
{
|
||||||
*found= element;
|
if (found)
|
||||||
|
*found= element;
|
||||||
return element->data;
|
return element->data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2378,29 +2462,41 @@ void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr))
|
|||||||
|
|
||||||
/* Key cache functions */
|
/* Key cache functions */
|
||||||
|
|
||||||
static KEY_CACHE *create_key_cache(const char *name, uint length)
|
static KEY_CACHE_VAR *create_key_cache(const char *name, uint length)
|
||||||
{
|
{
|
||||||
KEY_CACHE *key_cache;
|
KEY_CACHE_VAR *key_cache;
|
||||||
DBUG_PRINT("info",("Creating key cache: %.*s length: %d", length, name,
|
DBUG_PRINT("info",("Creating key cache: %.*s length: %d", length, name,
|
||||||
length));
|
length));
|
||||||
if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE),
|
if (length != default_key_cache_base.length ||
|
||||||
MYF(MY_ZEROFILL | MY_WME))))
|
memcmp(name, default_key_cache_base.str, length))
|
||||||
{
|
{
|
||||||
if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache))
|
if ((key_cache= (KEY_CACHE_VAR*) my_malloc(sizeof(KEY_CACHE_VAR),
|
||||||
|
MYF(MY_ZEROFILL | MY_WME))))
|
||||||
{
|
{
|
||||||
my_free((char*) key_cache, MYF(0));
|
if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache))
|
||||||
key_cache= 0;
|
{
|
||||||
|
my_free((char*) key_cache, MYF(0));
|
||||||
|
key_cache= 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
key_cache= &dflt_key_cache_var;
|
||||||
|
if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache))
|
||||||
|
key_cache= 0;
|
||||||
|
}
|
||||||
|
|
||||||
return key_cache;
|
return key_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
KEY_CACHE *get_or_create_key_cache(const char *name, uint length)
|
KEY_CACHE_VAR *get_or_create_key_cache(const char *name, uint length)
|
||||||
{
|
{
|
||||||
NAMED_LIST *not_used;
|
LEX_STRING key_cache_name;
|
||||||
KEY_CACHE *key_cache= (KEY_CACHE*) find_named(&key_caches, name,
|
key_cache_name.str= (char *) name;
|
||||||
length, ¬_used);
|
key_cache_name.length= length;
|
||||||
|
KEY_CACHE_VAR *key_cache= get_key_cache(&key_cache_name);
|
||||||
if (!key_cache)
|
if (!key_cache)
|
||||||
key_cache= create_key_cache(name, length);
|
key_cache= create_key_cache(name, length);
|
||||||
return key_cache;
|
return key_cache;
|
||||||
@ -2409,7 +2505,22 @@ KEY_CACHE *get_or_create_key_cache(const char *name, uint length)
|
|||||||
|
|
||||||
void free_key_cache(gptr key_cache)
|
void free_key_cache(gptr key_cache)
|
||||||
{
|
{
|
||||||
my_free(key_cache, MYF(0));
|
if (key_cache != (gptr) &dflt_key_cache_var)
|
||||||
|
my_free(key_cache, MYF(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool process_key_caches(int (* func) (KEY_CACHE_VAR *))
|
||||||
|
{
|
||||||
|
|
||||||
|
I_List_iterator<NAMED_LIST> it(key_caches);
|
||||||
|
NAMED_LIST *element;
|
||||||
|
while ((element= it++))
|
||||||
|
{
|
||||||
|
KEY_CACHE_VAR *key_cache= (KEY_CACHE_VAR *) element->data;
|
||||||
|
if (key_cache != &dflt_key_cache_var)
|
||||||
|
func(key_cache);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,11 @@ class set_var;
|
|||||||
typedef struct system_variables SV;
|
typedef struct system_variables SV;
|
||||||
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
|
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
|
||||||
|
|
||||||
|
extern ulonglong dflt_key_buff_size;
|
||||||
|
extern uint dflt_key_cache_block_size;
|
||||||
|
extern uint dflt_key_cache_division_limit;
|
||||||
|
extern uint dflt_key_cache_age_threshold;
|
||||||
|
|
||||||
enum enum_var_type
|
enum enum_var_type
|
||||||
{
|
{
|
||||||
OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL
|
OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL
|
||||||
@ -546,15 +551,71 @@ public:
|
|||||||
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
||||||
};
|
};
|
||||||
|
|
||||||
class sys_var_key_buffer_size :public sys_var
|
class sys_var_key_cache_param :public sys_var
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
uint offset;
|
||||||
|
public:
|
||||||
|
sys_var_key_cache_param(const char *name_arg)
|
||||||
|
:sys_var(name_arg)
|
||||||
|
{
|
||||||
|
offset= 0;
|
||||||
|
}
|
||||||
|
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
||||||
|
};
|
||||||
|
|
||||||
|
class sys_var_key_buffer_size :public sys_var_key_cache_param
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
sys_var_key_buffer_size(const char *name_arg)
|
sys_var_key_buffer_size(const char *name_arg)
|
||||||
:sys_var(name_arg)
|
:sys_var_key_cache_param(name_arg)
|
||||||
{}
|
{
|
||||||
|
offset= offsetof(KEY_CACHE_VAR, buff_size);
|
||||||
|
}
|
||||||
bool update(THD *thd, set_var *var);
|
bool update(THD *thd, set_var *var);
|
||||||
SHOW_TYPE type() { return SHOW_LONGLONG; }
|
SHOW_TYPE type() { return SHOW_LONGLONG; }
|
||||||
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
bool check_default(enum_var_type type) { return 1; }
|
||||||
|
bool is_struct() { return 1; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class sys_var_key_cache_block_size :public sys_var_key_cache_param
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sys_var_key_cache_block_size(const char *name_arg)
|
||||||
|
:sys_var_key_cache_param(name_arg)
|
||||||
|
{
|
||||||
|
offset= offsetof(KEY_CACHE_VAR, block_size);
|
||||||
|
}
|
||||||
|
bool update(THD *thd, set_var *var);
|
||||||
|
SHOW_TYPE type() { return SHOW_LONG; }
|
||||||
|
bool check_default(enum_var_type type) { return 1; }
|
||||||
|
bool is_struct() { return 1; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class sys_var_key_cache_division_limit :public sys_var_key_cache_param
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sys_var_key_cache_division_limit(const char *name_arg)
|
||||||
|
:sys_var_key_cache_param(name_arg)
|
||||||
|
{
|
||||||
|
offset= offsetof(KEY_CACHE_VAR, division_limit);
|
||||||
|
}
|
||||||
|
bool update(THD *thd, set_var *var);
|
||||||
|
SHOW_TYPE type() { return SHOW_LONG; }
|
||||||
|
bool check_default(enum_var_type type) { return 1; }
|
||||||
|
bool is_struct() { return 1; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class sys_var_key_cache_age_threshold :public sys_var_key_cache_param
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sys_var_key_cache_age_threshold(const char *name_arg)
|
||||||
|
:sys_var_key_cache_param(name_arg)
|
||||||
|
{
|
||||||
|
offset= offsetof(KEY_CACHE_VAR, age_threshold);
|
||||||
|
}
|
||||||
|
bool update(THD *thd, set_var *var);
|
||||||
|
SHOW_TYPE type() { return SHOW_LONG; }
|
||||||
bool check_default(enum_var_type type) { return 1; }
|
bool check_default(enum_var_type type) { return 1; }
|
||||||
bool is_struct() { return 1; }
|
bool is_struct() { return 1; }
|
||||||
};
|
};
|
||||||
@ -785,5 +846,6 @@ gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
|
|||||||
void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr));
|
void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr));
|
||||||
|
|
||||||
/* key_cache functions */
|
/* key_cache functions */
|
||||||
KEY_CACHE *get_or_create_key_cache(const char *name, uint length);
|
KEY_CACHE_VAR *get_or_create_key_cache(const char *name, uint length);
|
||||||
void free_key_cache(gptr key_cache);
|
void free_key_cache(gptr key_cache);
|
||||||
|
bool process_key_caches(int (* func) (KEY_CACHE_VAR *));
|
||||||
|
131
sql/sql_base.cc
131
sql/sql_base.cc
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
TABLE *unused_tables; /* Used by mysql_test */
|
TABLE *unused_tables; /* Used by mysql_test */
|
||||||
HASH open_cache; /* Used by mysql_test */
|
HASH open_cache; /* Used by mysql_test */
|
||||||
|
HASH assign_cache;
|
||||||
|
|
||||||
static int open_unireg_entry(THD *thd,TABLE *entry,const char *db,
|
static int open_unireg_entry(THD *thd,TABLE *entry,const char *db,
|
||||||
const char *name, const char *alias);
|
const char *name, const char *alias);
|
||||||
@ -53,7 +54,6 @@ void table_cache_init(void)
|
|||||||
mysql_rm_tmp_tables();
|
mysql_rm_tmp_tables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void table_cache_free(void)
|
void table_cache_free(void)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("table_cache_free");
|
DBUG_ENTER("table_cache_free");
|
||||||
@ -63,7 +63,6 @@ void table_cache_free(void)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint cached_tables(void)
|
uint cached_tables(void)
|
||||||
{
|
{
|
||||||
return open_cache.records;
|
return open_cache.records;
|
||||||
@ -762,6 +761,8 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
|
|||||||
reg1 TABLE *table;
|
reg1 TABLE *table;
|
||||||
char key[MAX_DBKEY_LENGTH];
|
char key[MAX_DBKEY_LENGTH];
|
||||||
uint key_length;
|
uint key_length;
|
||||||
|
KEY_CACHE_ASMT *key_cache_asmt;
|
||||||
|
KEY_CACHE_VAR *key_cache;
|
||||||
DBUG_ENTER("open_table");
|
DBUG_ENTER("open_table");
|
||||||
|
|
||||||
/* find a unused table in the open table cache */
|
/* find a unused table in the open table cache */
|
||||||
@ -802,6 +803,77 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
|
|||||||
my_printf_error(ER_TABLE_NOT_LOCKED,ER(ER_TABLE_NOT_LOCKED),MYF(0),alias);
|
my_printf_error(ER_TABLE_NOT_LOCKED,ER(ER_TABLE_NOT_LOCKED),MYF(0),alias);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID(pthread_mutex_lock(&LOCK_assign));
|
||||||
|
key_cache_asmt= (KEY_CACHE_ASMT*) hash_search(&assign_cache,
|
||||||
|
(byte*) key, key_length) ;
|
||||||
|
if (thd->open_options & HA_OPEN_TO_ASSIGN)
|
||||||
|
{
|
||||||
|
/* When executing a CACHE INDEX command*/
|
||||||
|
if (key_cache_asmt)
|
||||||
|
{
|
||||||
|
if (key_cache_asmt->requests++)
|
||||||
|
{
|
||||||
|
/* Another thread are assigning this table to some key cache*/
|
||||||
|
|
||||||
|
/* Put the assignment request into the queue of such requests */
|
||||||
|
struct st_my_thread_var *last;
|
||||||
|
struct st_my_thread_var *thread= thd->mysys_var;
|
||||||
|
if (! (last= key_cache_asmt->queue))
|
||||||
|
thread->next= thread;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thread->next= last->next;
|
||||||
|
last->next= thread;
|
||||||
|
}
|
||||||
|
key_cache_asmt->queue= thread;
|
||||||
|
|
||||||
|
/* Wait until the request can be processed */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
VOID(pthread_cond_wait(&thread->suspend, &LOCK_assign));
|
||||||
|
}
|
||||||
|
while (thread->next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The table has not been explicitly assigned to any key cache yet;
|
||||||
|
by default it's assigned to the default key cache;
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!(key_cache_asmt=
|
||||||
|
(KEY_CACHE_ASMT *) my_malloc(sizeof(*key_cache_asmt),
|
||||||
|
MYF(MY_WME | MY_ZEROFILL))) ||
|
||||||
|
!(key_cache_asmt->db_name= my_strdup(db, MYF(MY_WME))) ||
|
||||||
|
!(key_cache_asmt->table_name= my_strdup(table_name, MYF(MY_WME))) ||
|
||||||
|
!(key_cache_asmt->table_key= my_memdup((const byte *) key,
|
||||||
|
key_length, MYF(MY_WME))))
|
||||||
|
{
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_assign));
|
||||||
|
|
||||||
|
if (key_cache_asmt)
|
||||||
|
{
|
||||||
|
if (key_cache_asmt->db_name)
|
||||||
|
my_free((gptr) key_cache_asmt->db_name, MYF(0));
|
||||||
|
if (key_cache_asmt->table_name)
|
||||||
|
my_free((gptr) key_cache_asmt->table_name, MYF(0));
|
||||||
|
my_free((gptr) key_cache_asmt, MYF(0));
|
||||||
|
}
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
|
}
|
||||||
|
key_cache_asmt->key_length= key_length;
|
||||||
|
key_cache_asmt->key_cache= &dflt_key_cache_var;
|
||||||
|
VOID(my_hash_insert(&assign_cache, (byte *) key_cache_asmt));
|
||||||
|
key_cache_asmt->requests++;
|
||||||
|
}
|
||||||
|
key_cache_asmt->to_reassign= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_cache= key_cache_asmt ? key_cache_asmt->key_cache : &dflt_key_cache_var;
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_assign));
|
||||||
|
|
||||||
VOID(pthread_mutex_lock(&LOCK_open));
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
|
|
||||||
if (!thd->open_tables)
|
if (!thd->open_tables)
|
||||||
@ -844,6 +916,9 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
|
|||||||
}
|
}
|
||||||
table->prev->next=table->next; /* Remove from unused list */
|
table->prev->next=table->next; /* Remove from unused list */
|
||||||
table->next->prev=table->prev;
|
table->next->prev=table->prev;
|
||||||
|
|
||||||
|
table->key_cache= key_cache;
|
||||||
|
table->key_cache_asmt= key_cache_asmt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -857,6 +932,8 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
|
|||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
}
|
}
|
||||||
|
table->key_cache= key_cache;
|
||||||
|
table->key_cache_asmt= key_cache_asmt;
|
||||||
if (open_unireg_entry(thd, table,db,table_name,alias) ||
|
if (open_unireg_entry(thd, table,db,table_name,alias) ||
|
||||||
!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
|
!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
|
||||||
key_length)))
|
key_length)))
|
||||||
@ -875,6 +952,8 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
|
|||||||
|
|
||||||
table->in_use=thd;
|
table->in_use=thd;
|
||||||
check_unused();
|
check_unused();
|
||||||
|
|
||||||
|
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
if (refresh)
|
if (refresh)
|
||||||
{
|
{
|
||||||
@ -1646,6 +1725,54 @@ bool rm_temporary_table(enum db_type base, char *path)
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void free_assign_entry(KEY_CACHE_ASMT *key_cache_asmt)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("free_assign_entry");
|
||||||
|
my_free((gptr) key_cache_asmt->table_key, MYF(0));
|
||||||
|
my_free((gptr) key_cache_asmt, MYF(0));
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte *assign_cache_key(const byte *record,uint *length,
|
||||||
|
my_bool not_used __attribute__((unused)))
|
||||||
|
{
|
||||||
|
KEY_CACHE_ASMT *entry=(KEY_CACHE_ASMT *) record;
|
||||||
|
*length=entry->key_length;
|
||||||
|
return (byte*) entry->table_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void assign_cache_init(void)
|
||||||
|
{
|
||||||
|
VOID(hash_init(&assign_cache, &my_charset_bin,
|
||||||
|
table_cache_size+16, 0, 0, assign_cache_key,
|
||||||
|
(hash_free_key) free_assign_entry,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void assign_cache_free(void)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("assign_cache_free");
|
||||||
|
hash_free(&assign_cache);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reassign_key_cache(KEY_CACHE_ASMT *key_cache_asmt,
|
||||||
|
KEY_CACHE_VAR *new_key_cache)
|
||||||
|
{
|
||||||
|
if (key_cache_asmt->prev)
|
||||||
|
{
|
||||||
|
/* Unlink key_cache_asmt from the assignment list for the old key cache */
|
||||||
|
if ((*key_cache_asmt->prev= key_cache_asmt->next))
|
||||||
|
key_cache_asmt->next->prev= key_cache_asmt->prev;
|
||||||
|
}
|
||||||
|
/* Link key_cache_asmt into the assignment list for the new key cache */
|
||||||
|
key_cache_asmt->prev= &new_key_cache->assign_list;
|
||||||
|
if ((key_cache_asmt->next= new_key_cache->assign_list))
|
||||||
|
key_cache_asmt->next->prev= &key_cache_asmt->next;
|
||||||
|
new_key_cache->assign_list= key_cache_asmt;
|
||||||
|
|
||||||
|
key_cache_asmt->key_cache= new_key_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** find field in list or tables. if field is unqualifed and unique,
|
** find field in list or tables. if field is unqualifed and unique,
|
||||||
|
@ -1218,7 +1218,16 @@ TABLE_LIST* st_select_lex_node::get_table_list() { return 0; }
|
|||||||
List<Item>* st_select_lex_node::get_item_list() { return 0; }
|
List<Item>* st_select_lex_node::get_item_list() { return 0; }
|
||||||
List<String>* st_select_lex_node::get_use_index() { return 0; }
|
List<String>* st_select_lex_node::get_use_index() { return 0; }
|
||||||
List<String>* st_select_lex_node::get_ignore_index() { return 0; }
|
List<String>* st_select_lex_node::get_ignore_index() { return 0; }
|
||||||
|
TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table,
|
||||||
|
LEX_STRING *alias,
|
||||||
|
ulong table_join_options,
|
||||||
|
thr_lock_type flags,
|
||||||
|
List<String> *use_index,
|
||||||
|
List<String> *ignore_index,
|
||||||
|
LEX_STRING *option)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
ulong st_select_lex_node::get_table_join_options()
|
ulong st_select_lex_node::get_table_join_options()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -1242,6 +1251,28 @@ bool st_select_lex::test_limit()
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Interface method of table list creation for query
|
Interface method of table list creation for query
|
||||||
|
|
||||||
|
@ -59,7 +59,8 @@ enum enum_sql_command {
|
|||||||
SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
|
SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
|
||||||
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
|
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
|
||||||
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
|
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
|
||||||
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, SQLCOM_PRELOAD_KEYS,
|
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
|
||||||
|
SQLCOM_ASSIGN_TO_KEYCACHE, SQLCOM_PRELOAD_KEYS,
|
||||||
SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
|
SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
|
||||||
SQLCOM_ROLLBACK, SQLCOM_ROLLBACK_TO_SAVEPOINT,
|
SQLCOM_ROLLBACK, SQLCOM_ROLLBACK_TO_SAVEPOINT,
|
||||||
SQLCOM_COMMIT, SQLCOM_SAVEPOINT,
|
SQLCOM_COMMIT, SQLCOM_SAVEPOINT,
|
||||||
@ -257,6 +258,13 @@ public:
|
|||||||
virtual List<String>* get_use_index();
|
virtual List<String>* get_use_index();
|
||||||
virtual List<String>* get_ignore_index();
|
virtual List<String>* get_ignore_index();
|
||||||
virtual ulong get_table_join_options();
|
virtual ulong get_table_join_options();
|
||||||
|
virtual TABLE_LIST *add_table_to_list(THD *thd, Table_ident *table,
|
||||||
|
LEX_STRING *alias,
|
||||||
|
ulong table_options,
|
||||||
|
thr_lock_type flags= TL_UNLOCK,
|
||||||
|
List<String> *use_index= 0,
|
||||||
|
List<String> *ignore_index= 0,
|
||||||
|
LEX_STRING *option= 0);
|
||||||
virtual void set_lock_for_tables(thr_lock_type lock_type) {}
|
virtual void set_lock_for_tables(thr_lock_type lock_type) {}
|
||||||
|
|
||||||
friend class st_select_lex_unit;
|
friend class st_select_lex_unit;
|
||||||
@ -443,8 +451,8 @@ public:
|
|||||||
ulong table_options,
|
ulong table_options,
|
||||||
thr_lock_type flags= TL_UNLOCK,
|
thr_lock_type flags= TL_UNLOCK,
|
||||||
List<String> *use_index= 0,
|
List<String> *use_index= 0,
|
||||||
List<String> *ignore_index= 0);
|
List<String> *ignore_index= 0,
|
||||||
|
LEX_STRING *option= 0);
|
||||||
TABLE_LIST* get_table_list();
|
TABLE_LIST* get_table_list();
|
||||||
List<Item>* get_item_list();
|
List<Item>* get_item_list();
|
||||||
List<String>* get_use_index();
|
List<String>* get_use_index();
|
||||||
|
@ -1907,10 +1907,20 @@ mysql_execute_command(THD *thd)
|
|||||||
res = mysql_restore_table(thd, tables);
|
res = mysql_restore_table(thd, tables);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SQLCOM_ASSIGN_TO_KEYCACHE:
|
||||||
|
{
|
||||||
|
if (check_db_used(thd, tables) ||
|
||||||
|
check_access(thd, INDEX_ACL, tables->db,
|
||||||
|
&tables->grant.privilege, 0, 0))
|
||||||
|
goto error;
|
||||||
|
res = mysql_assign_to_keycache(thd, tables);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SQLCOM_PRELOAD_KEYS:
|
case SQLCOM_PRELOAD_KEYS:
|
||||||
{
|
{
|
||||||
if (check_db_used(thd, tables) ||
|
if (check_db_used(thd, tables) ||
|
||||||
check_access(thd, INDEX_ACL, tables->db, &tables->grant.privilege,0,0))
|
check_access(thd, INDEX_ACL, tables->db,
|
||||||
|
&tables->grant.privilege, 0, 0))
|
||||||
goto error;
|
goto error;
|
||||||
res = mysql_preload_keys(thd, tables);
|
res = mysql_preload_keys(thd, tables);
|
||||||
break;
|
break;
|
||||||
@ -4213,7 +4223,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||||||
ulong table_options,
|
ulong table_options,
|
||||||
thr_lock_type lock_type,
|
thr_lock_type lock_type,
|
||||||
List<String> *use_index,
|
List<String> *use_index,
|
||||||
List<String> *ignore_index)
|
List<String> *ignore_index,
|
||||||
|
LEX_STRING *option)
|
||||||
{
|
{
|
||||||
register TABLE_LIST *ptr;
|
register TABLE_LIST *ptr;
|
||||||
char *alias_str;
|
char *alias_str;
|
||||||
@ -4274,7 +4285,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||||||
if (ignore_index)
|
if (ignore_index)
|
||||||
ptr->ignore_index=(List<String> *) thd->memdup((gptr) ignore_index,
|
ptr->ignore_index=(List<String> *) thd->memdup((gptr) ignore_index,
|
||||||
sizeof(*ignore_index));
|
sizeof(*ignore_index));
|
||||||
|
ptr->option= option ? option->str : 0;
|
||||||
/* check that used name is unique */
|
/* check that used name is unique */
|
||||||
if (lock_type != TL_IGNORE)
|
if (lock_type != TL_IGNORE)
|
||||||
{
|
{
|
||||||
|
106
sql/sql_table.cc
106
sql/sql_table.cc
@ -1612,6 +1612,112 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Assigned specified indexes for a table into key cache
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
mysql_assign_to_keycache()
|
||||||
|
thd Thread object
|
||||||
|
tables Table list (one table only)
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
0 ok
|
||||||
|
-1 error
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("mysql_assign_to_keycache");
|
||||||
|
DBUG_RETURN(mysql_admin_table(thd, tables, 0,
|
||||||
|
"assign_to_keycache", TL_READ, 0,
|
||||||
|
HA_OPEN_TO_ASSIGN, 0,
|
||||||
|
&handler::assign_to_keycache));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reassign all tables assigned to a key cache to another key cache
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
reassign_keycache_tables()
|
||||||
|
thd Thread object
|
||||||
|
src_cache Reference to the key cache to clean up
|
||||||
|
dest_name Name of the cache to assign tables to
|
||||||
|
remove_fl Flag to destroy key cache when all tables are reassigned
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
0 ok
|
||||||
|
-1 error
|
||||||
|
*/
|
||||||
|
|
||||||
|
int reassign_keycache_tables(THD* thd, KEY_CACHE_VAR* src_cache,
|
||||||
|
char *dest_name, bool remove_fl)
|
||||||
|
{
|
||||||
|
int rc= 0;
|
||||||
|
TABLE_LIST table;
|
||||||
|
KEY_CACHE_ASMT *key_cache_asmt;
|
||||||
|
|
||||||
|
DBUG_ENTER("reassign_keycache_tables");
|
||||||
|
|
||||||
|
VOID(pthread_mutex_lock(&LOCK_assign));
|
||||||
|
for (key_cache_asmt= src_cache->assign_list ;
|
||||||
|
key_cache_asmt;
|
||||||
|
key_cache_asmt= key_cache_asmt->next)
|
||||||
|
key_cache_asmt->to_reassign = 1;
|
||||||
|
key_cache_asmt= src_cache->assign_list;
|
||||||
|
while (key_cache_asmt)
|
||||||
|
{
|
||||||
|
if (key_cache_asmt->to_reassign)
|
||||||
|
{
|
||||||
|
bool refresh;
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_assign));
|
||||||
|
bzero((byte *) &table, sizeof(table));
|
||||||
|
table.option= dest_name;
|
||||||
|
table.db= key_cache_asmt->db_name;
|
||||||
|
table.alias= table.real_name= key_cache_asmt->table_name;
|
||||||
|
thd->open_options|= HA_OPEN_TO_ASSIGN;
|
||||||
|
while (!(table.table=open_table(thd,table.db,
|
||||||
|
table.real_name,table.alias,
|
||||||
|
&refresh)) && refresh) ;
|
||||||
|
thd->open_options&= ~HA_OPEN_TO_ASSIGN;
|
||||||
|
if (!table.table)
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
table.table->pos_in_table_list= &table;
|
||||||
|
key_cache_asmt->triggered= 1;
|
||||||
|
rc= table.table->file->assign_to_keycache(thd, 0);
|
||||||
|
close_thread_tables(thd);
|
||||||
|
if (rc)
|
||||||
|
DBUG_RETURN(rc);
|
||||||
|
VOID(pthread_mutex_lock(&LOCK_assign));
|
||||||
|
key_cache_asmt= src_cache->assign_list;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
key_cache_asmt= key_cache_asmt->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (src_cache->assignments)
|
||||||
|
{
|
||||||
|
struct st_my_thread_var *waiting_thread= my_thread_var;
|
||||||
|
pthread_cond_wait(&waiting_thread->suspend, &LOCK_assign);
|
||||||
|
}
|
||||||
|
if (src_cache->extra_info)
|
||||||
|
{
|
||||||
|
my_free((char *) src_cache->extra_info, MYF(0));
|
||||||
|
src_cache->extra_info= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove_fl && !src_cache->assign_list && src_cache != &dflt_key_cache_var)
|
||||||
|
{
|
||||||
|
end_key_cache(&src_cache->cache, 1);
|
||||||
|
src_cache->buff_size= 0;
|
||||||
|
src_cache->block_size= 0;
|
||||||
|
}
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_assign));
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Preload specified indexes for a table into key cache
|
Preload specified indexes for a table into key cache
|
||||||
|
|
||||||
|
@ -323,8 +323,9 @@ w_requests: %10lu\n\
|
|||||||
writes: %10lu\n\
|
writes: %10lu\n\
|
||||||
r_requests: %10lu\n\
|
r_requests: %10lu\n\
|
||||||
reads: %10lu\n",
|
reads: %10lu\n",
|
||||||
my_blocks_used,my_blocks_changed,my_cache_w_requests,
|
dflt_key_cache_var.blocks_used,dflt_key_cache_var.blocks_changed,
|
||||||
my_cache_write,my_cache_r_requests,my_cache_read);
|
dflt_key_cache_var.cache_w_requests,dflt_key_cache_var.cache_write,
|
||||||
|
dflt_key_cache_var.cache_r_requests,dflt_key_cache_var.cache_read);
|
||||||
pthread_mutex_unlock(&THR_LOCK_keycache);
|
pthread_mutex_unlock(&THR_LOCK_keycache);
|
||||||
|
|
||||||
if (thd)
|
if (thd)
|
||||||
|
@ -685,12 +685,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
%type <NONE>
|
%type <NONE>
|
||||||
query verb_clause create change select do drop insert replace insert2
|
query verb_clause create change select do drop insert replace insert2
|
||||||
insert_values update delete truncate rename
|
insert_values update delete truncate rename
|
||||||
show describe load alter optimize preload flush
|
show describe load alter optimize keycache preload flush
|
||||||
reset purge begin commit rollback savepoint
|
reset purge begin commit rollback savepoint
|
||||||
slave master_def master_defs master_file_def
|
slave master_def master_defs master_file_def
|
||||||
repair restore backup analyze check start checksum
|
repair restore backup analyze check start checksum
|
||||||
field_list field_list_item field_spec kill column_def key_def
|
field_list field_list_item field_spec kill column_def key_def
|
||||||
preload_list preload_keys
|
keycache_list assign_to_keycache preload_list preload_keys
|
||||||
select_item_list select_item values_list no_braces
|
select_item_list select_item values_list no_braces
|
||||||
opt_limit_clause delete_limit_clause fields opt_values values
|
opt_limit_clause delete_limit_clause fields opt_values values
|
||||||
procedure_list procedure_list2 procedure_item
|
procedure_list procedure_list2 procedure_item
|
||||||
@ -762,6 +762,7 @@ verb_clause:
|
|||||||
| load
|
| load
|
||||||
| lock
|
| lock
|
||||||
| optimize
|
| optimize
|
||||||
|
| keycache
|
||||||
| preload
|
| preload
|
||||||
| purge
|
| purge
|
||||||
| rename
|
| rename
|
||||||
@ -1986,6 +1987,45 @@ table_to_table:
|
|||||||
YYABORT;
|
YYABORT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
keycache:
|
||||||
|
CACHE_SYM INDEX
|
||||||
|
{
|
||||||
|
LEX *lex=Lex;
|
||||||
|
lex->sql_command=SQLCOM_ASSIGN_TO_KEYCACHE;
|
||||||
|
}
|
||||||
|
keycache_list
|
||||||
|
{}
|
||||||
|
;
|
||||||
|
|
||||||
|
keycache_list:
|
||||||
|
assign_to_keycache
|
||||||
|
| keycache_list ',' assign_to_keycache;
|
||||||
|
|
||||||
|
assign_to_keycache:
|
||||||
|
table_ident cache_keys_spec IN_SYM ident
|
||||||
|
{
|
||||||
|
LEX *lex=Lex;
|
||||||
|
SELECT_LEX *sel= &lex->select_lex;
|
||||||
|
if (!sel->add_table_to_list(lex->thd, $1, NULL, 0,
|
||||||
|
TL_READ,
|
||||||
|
sel->get_use_index(),
|
||||||
|
(List<String> *)0,
|
||||||
|
&($4)))
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
table_ident cache_keys_spec IN_SYM DEFAULT
|
||||||
|
{
|
||||||
|
LEX *lex=Lex;
|
||||||
|
SELECT_LEX *sel= &lex->select_lex;
|
||||||
|
if (!sel->add_table_to_list(lex->thd, $1, NULL, 0,
|
||||||
|
TL_READ,
|
||||||
|
sel->get_use_index(),
|
||||||
|
(List<String> *)0))
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
preload:
|
preload:
|
||||||
LOAD INDEX INTO CACHE_SYM
|
LOAD INDEX INTO CACHE_SYM
|
||||||
{
|
{
|
||||||
@ -2001,7 +2041,7 @@ preload_list:
|
|||||||
| preload_list ',' preload_keys;
|
| preload_list ',' preload_keys;
|
||||||
|
|
||||||
preload_keys:
|
preload_keys:
|
||||||
table_ident preload_keys_spec opt_ignore_leaves
|
table_ident cache_keys_spec opt_ignore_leaves
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
SELECT_LEX *sel= &lex->select_lex;
|
SELECT_LEX *sel= &lex->select_lex;
|
||||||
@ -2013,18 +2053,18 @@ preload_keys:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
preload_keys_spec:
|
cache_keys_spec:
|
||||||
keys_or_index { Select->interval_list.empty(); }
|
keys_or_index { Select->interval_list.empty(); }
|
||||||
preload_key_list_or_empty
|
cache_key_list_or_empty
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
SELECT_LEX *sel= &lex->select_lex;
|
SELECT_LEX *sel= &lex->select_lex;
|
||||||
sel->use_index= sel->interval_list;
|
sel->use_index= sel->interval_list;
|
||||||
sel->use_index_ptr= &sel->use_index;
|
sel->use_index_ptr= &sel->use_index;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
preload_key_list_or_empty:
|
cache_key_list_or_empty:
|
||||||
/* empty */
|
/* empty */
|
||||||
| '(' key_usage_list2 ')' {}
|
| '(' key_usage_list2 ')' {}
|
||||||
;
|
;
|
||||||
|
34
sql/table.h
34
sql/table.h
@ -55,6 +55,31 @@ typedef struct st_filesort_info
|
|||||||
ha_rows found_records; /* How many records in sort */
|
ha_rows found_records; /* How many records in sort */
|
||||||
} FILESORT_INFO;
|
} FILESORT_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
/* Table key cache assignment descriptor */
|
||||||
|
/*
|
||||||
|
In future the similar structure is to be used for
|
||||||
|
an assignment of an index to a key cache: the index name will be added.
|
||||||
|
The name of the database catalog will be added as well.
|
||||||
|
The descriptors for the current assignments are put in the
|
||||||
|
assignment cache: assign_cache. If a table is not found in the cache
|
||||||
|
it is considered assigned to the default key cache.
|
||||||
|
*/
|
||||||
|
typedef struct st_key_cache_asmt
|
||||||
|
{
|
||||||
|
char *db_name; /* db the table belongs to */
|
||||||
|
char *table_name; /* the name of the table */
|
||||||
|
char *table_key; /* key for the assignment cache */
|
||||||
|
uint key_length; /* the length of this key */
|
||||||
|
struct st_key_cache_var *key_cache; /* reference to the key cache */
|
||||||
|
struct st_key_cache_asmt **prev; /* links in the chain all assignments */
|
||||||
|
struct st_key_cache_asmt *next; /* to this cache */
|
||||||
|
struct st_my_thread_var *queue; /* queue of requests for assignment */
|
||||||
|
uint requests; /* number of current requests */
|
||||||
|
bool to_reassign; /* marked when reassigning all cache */
|
||||||
|
bool triggered; /* marked when assignment is triggered*/
|
||||||
|
} KEY_CACHE_ASMT;
|
||||||
|
|
||||||
/* Table cache entry struct */
|
/* Table cache entry struct */
|
||||||
|
|
||||||
class Field_timestamp;
|
class Field_timestamp;
|
||||||
@ -62,11 +87,13 @@ class Field_blob;
|
|||||||
|
|
||||||
struct st_table {
|
struct st_table {
|
||||||
handler *file;
|
handler *file;
|
||||||
Field **field; /* Pointer to fields */
|
KEY_CACHE_VAR *key_cache; /* Ref to the key cache the table assigned to*/
|
||||||
|
KEY_CACHE_ASMT *key_cache_asmt;/* Only when opened for key cache assignment */
|
||||||
|
Field **field; /* Pointer to fields */
|
||||||
Field_blob **blob_field; /* Pointer to blob fields */
|
Field_blob **blob_field; /* Pointer to blob fields */
|
||||||
HASH name_hash; /* hash of field names */
|
HASH name_hash; /* hash of field names */
|
||||||
byte *record[2]; /* Pointer to records */
|
byte *record[2]; /* Pointer to records */
|
||||||
byte *default_values; /* record with default values for INSERT */
|
byte *default_values; /* Record with default values for INSERT */
|
||||||
byte *insert_values; /* used by INSERT ... UPDATE */
|
byte *insert_values; /* used by INSERT ... UPDATE */
|
||||||
uint fields; /* field count */
|
uint fields; /* field count */
|
||||||
uint reclength; /* Recordlength */
|
uint reclength; /* Recordlength */
|
||||||
@ -161,6 +188,7 @@ typedef struct st_table_list
|
|||||||
{
|
{
|
||||||
struct st_table_list *next;
|
struct st_table_list *next;
|
||||||
char *db, *alias, *real_name;
|
char *db, *alias, *real_name;
|
||||||
|
char *option; /* Used by cache index */
|
||||||
Item *on_expr; /* Used with outer join */
|
Item *on_expr; /* Used with outer join */
|
||||||
struct st_table_list *natural_join; /* natural join on this table*/
|
struct st_table_list *natural_join; /* natural join on this table*/
|
||||||
/* ... join ... USE INDEX ... IGNORE INDEX */
|
/* ... join ... USE INDEX ... IGNORE INDEX */
|
||||||
@ -192,3 +220,5 @@ typedef struct st_open_table_list
|
|||||||
char *db,*table;
|
char *db,*table;
|
||||||
uint32 in_use,locked;
|
uint32 in_use,locked;
|
||||||
} OPEN_TABLE_LIST;
|
} OPEN_TABLE_LIST;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user