18
#include <drizzled/server_includes.h>
19
#include <mysys/my_bit.h>
19
#include "drizzled/internal/my_bit.h"
20
20
#include "myisampack.h"
21
21
#include "ha_myisam.h"
22
#include "myisamdef.h"
23
#include <drizzled/util/test.h>
24
#include <drizzled/error.h>
25
#include <drizzled/errmsg_print.h>
26
#include <drizzled/gettext.h>
27
#include <drizzled/session.h>
28
#include <drizzled/protocol.h>
29
#include <drizzled/table.h>
30
#include <drizzled/field/timestamp.h>
22
#include "myisam_priv.h"
23
#include "drizzled/option.h"
24
#include "drizzled/internal/my_bit.h"
25
#include "drizzled/internal/m_string.h"
26
#include "drizzled/util/test.h"
27
#include "drizzled/error.h"
28
#include "drizzled/errmsg_print.h"
29
#include "drizzled/gettext.h"
30
#include "drizzled/session.h"
31
#include "drizzled/set_var.h"
32
#include <drizzled/plugin.h>
33
#include "drizzled/plugin/client.h"
34
#include "drizzled/table.h"
35
#include "drizzled/field/timestamp.h"
36
#include "drizzled/memory/multi_malloc.h"
37
#include "drizzled/plugin/daemon.h"
34
44
using namespace std;
45
using namespace drizzled;
47
extern pthread_mutex_t LOCK_global_system_variables;
36
48
static const string engine_name("MyISAM");
38
ulong myisam_recover_options= HA_RECOVER_NONE;
39
50
pthread_mutex_t THR_LOCK_myisam= PTHREAD_MUTEX_INITIALIZER;
41
52
static uint32_t repair_threads;
42
static uint32_t block_size;
53
static uint32_t myisam_key_cache_block_size;
54
static uint32_t myisam_key_cache_size;
55
static uint32_t myisam_key_cache_division_limit;
56
static uint32_t myisam_key_cache_age_threshold;
43
57
static uint64_t max_sort_file_size;
44
58
static uint64_t sort_buffer_size;
46
/* bits in myisam_recover_options */
47
const char *myisam_recover_names[] =
48
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NULL};
49
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
50
myisam_recover_names, NULL};
52
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
53
"nulls_ignored", NULL};
54
TYPELIB myisam_stats_method_typelib= {
55
array_elements(myisam_stats_method_names) - 1, "",
56
myisam_stats_method_names, NULL};
59
60
/*****************************************************************************
61
62
*****************************************************************************/
63
class MyisamEngine : public StorageEngine
64
static const char *ha_myisam_exts[] = {
70
class MyisamEngine : public plugin::StorageEngine
73
MyisamEngine(const MyisamEngine&);
74
MyisamEngine& operator=(const MyisamEngine&);
66
MyisamEngine(string name_arg)
67
: StorageEngine(name_arg, HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES) {}
69
virtual handler *create(TABLE_SHARE *table,
72
return new (mem_root) ha_myisam(this, table);
76
explicit MyisamEngine(string name_arg) :
77
plugin::StorageEngine(name_arg,
78
HTON_CAN_INDEX_BLOBS |
79
HTON_STATS_RECORDS_IS_EXACT |
85
HTON_SKIP_STORE_LOCK |
88
pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_FAST);
91
virtual ~MyisamEngine()
93
pthread_mutex_destroy(&THR_LOCK_myisam);
94
end_key_cache(dflt_key_cache, 1); // Can never fail
96
mi_panic(HA_PANIC_CLOSE);
99
virtual Cursor *create(TableShare &table,
100
memory::Root *mem_root)
102
return new (mem_root) ha_myisam(*this, table);
105
const char **bas_ext() const {
106
return ha_myisam_exts;
109
int doCreateTable(Session&,
111
drizzled::TableIdentifier &identifier,
114
int doRenameTable(Session&, TableIdentifier &from, TableIdentifier &to);
116
int doDropTable(Session&, drizzled::TableIdentifier &identifier);
118
int doGetTableDefinition(Session& session,
119
drizzled::TableIdentifier &identifier,
120
message::Table &table_message);
122
/* Temp only engine, so do not return values. */
123
void doGetTableNames(CachedDirectory &, SchemaIdentifier &, set<string>&) { };
125
uint32_t max_supported_keys() const { return MI_MAX_KEY; }
126
uint32_t max_supported_key_length() const { return MI_MAX_KEY_LENGTH; }
127
uint32_t max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; }
129
uint32_t index_flags(enum ha_key_alg) const
131
return (HA_READ_NEXT |
137
bool doDoesTableExist(Session& session, TableIdentifier &identifier);
139
void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
140
drizzled::SchemaIdentifier &schema_identifier,
141
drizzled::TableIdentifiers &set_of_identifiers);
76
// collect errors printed by mi_check routines
78
static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
79
const char *fmt, va_list args)
81
Session* session = (Session*)param->session;
82
Protocol *protocol= session->protocol;
83
uint32_t length, msg_length;
84
char msgbuf[MI_MAX_MSG_BUF];
85
char name[NAME_LEN*2+2];
87
msg_length= vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
88
msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
90
if (!session->protocol->isConnected())
92
errmsg_printf(ERRMSG_LVL_ERROR, "%s",msgbuf);
96
if (param->testflag & (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR |
99
my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
102
length= sprintf(name,"%s.%s",param->db_name,param->table_name);
105
TODO: switch from protocol to push_warning here. The main reason we didn't
106
it yet is parallel repair. Due to following trace:
107
mi_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr.
109
Also we likely need to lock mutex here (in both cases with protocol and
112
protocol->prepareForResend();
113
protocol->store(name, length, system_charset_info);
114
protocol->store(param->op_name, system_charset_info);
115
protocol->store(msg_type, system_charset_info);
116
protocol->store(msgbuf, msg_length, system_charset_info);
117
if (protocol->write())
118
errmsg_printf(ERRMSG_LVL_ERROR, "Failed on drizzleclient_net_write, writing to stderr instead: %s\n",
144
void MyisamEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
145
drizzled::SchemaIdentifier&,
146
drizzled::TableIdentifiers&)
150
bool MyisamEngine::doDoesTableExist(Session &session, TableIdentifier &identifier)
152
return session.doesTableMessageExist(identifier);
155
int MyisamEngine::doGetTableDefinition(Session &session,
156
drizzled::TableIdentifier &identifier,
157
message::Table &table_message)
159
if (session.getTableMessage(identifier, table_message))
165
Convert to push_Warnings if you ever care about this, otherwise, it is a no-op.
168
static void mi_check_print_msg(MI_CHECK *, const char* ,
169
const char *, va_list )
635
658
return mi_write(file,buf);
638
int ha_myisam::check(Session* session, HA_CHECK_OPT* check_opt)
640
if (!file) return HA_ADMIN_INTERNAL_ERROR;
643
MYISAM_SHARE* share = file->s;
644
const char *old_proc_info= session->get_proc_info();
646
session->set_proc_info("Checking table");
647
myisamchk_init(¶m);
648
param.session = session;
649
param.op_name = "check";
650
param.db_name= table->s->db.str;
651
param.table_name= table->alias;
652
param.testflag = check_opt->flags | T_CHECK | T_SILENT;
653
param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
655
if (!(table->db_stat & HA_READ_ONLY))
656
param.testflag|= T_STATISTICS;
657
param.using_global_keycache = 1;
659
if (!mi_is_crashed(file) &&
660
(((param.testflag & T_CHECK_ONLY_CHANGED) &&
661
!(share->state.changed & (STATE_CHANGED | STATE_CRASHED |
662
STATE_CRASHED_ON_REPAIR)) &&
663
share->state.open_count == 0) ||
664
((param.testflag & T_FAST) && (share->state.open_count ==
665
(uint) (share->global_changed ? 1 : 0)))))
666
return HA_ADMIN_ALREADY_DONE;
668
error = chk_status(¶m, file); // Not fatal
669
error = chk_size(¶m, file);
671
error |= chk_del(¶m, file, param.testflag);
673
error = chk_key(¶m, file);
676
if ((!(param.testflag & T_QUICK) &&
678
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ||
679
(param.testflag & (T_EXTEND | T_MEDIUM)))) ||
682
uint32_t old_testflag=param.testflag;
683
param.testflag|=T_MEDIUM;
684
if (!(error= init_io_cache(¶m.read_cache, file->dfile,
685
my_default_record_cache_size, READ_CACHE,
686
share->pack.header_length, 1, MYF(MY_WME))))
688
error= chk_data_link(¶m, file, param.testflag & T_EXTEND);
689
end_io_cache(&(param.read_cache));
691
param.testflag= old_testflag;
696
if ((share->state.changed & (STATE_CHANGED |
697
STATE_CRASHED_ON_REPAIR |
698
STATE_CRASHED | STATE_NOT_ANALYZED)) ||
699
(param.testflag & T_STATISTICS) ||
702
file->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
703
pthread_mutex_lock(&share->intern_lock);
704
share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
705
STATE_CRASHED_ON_REPAIR);
706
if (!(table->db_stat & HA_READ_ONLY))
707
error=update_state_info(¶m,file,UPDATE_TIME | UPDATE_OPEN_COUNT |
709
pthread_mutex_unlock(&share->intern_lock);
710
info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE |
714
else if (!mi_is_crashed(file) && !session->killed)
716
mi_mark_crashed(file);
717
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
720
session->set_proc_info(old_proc_info);
721
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
726
analyze the key distribution in the table
727
As the table may be only locked for read, we have to take into account that
728
two threads may do an analyze at the same time!
731
int ha_myisam::analyze(Session *session,
736
MYISAM_SHARE* share = file->s;
738
myisamchk_init(¶m);
739
param.session = session;
740
param.op_name= "analyze";
741
param.db_name= table->s->db.str;
742
param.table_name= table->alias;
743
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
744
T_DONT_CHECK_CHECKSUM);
745
param.using_global_keycache = 1;
746
param.stats_method= (enum_mi_stats_method)session->variables.myisam_stats_method;
748
if (!(share->state.changed & STATE_NOT_ANALYZED))
749
return HA_ADMIN_ALREADY_DONE;
751
error = chk_key(¶m, file);
754
pthread_mutex_lock(&share->intern_lock);
755
error=update_state_info(¶m,file,UPDATE_STAT);
756
pthread_mutex_unlock(&share->intern_lock);
758
else if (!mi_is_crashed(file) && !session->killed)
759
mi_mark_crashed(file);
760
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
764
int ha_myisam::repair(Session* session, HA_CHECK_OPT *check_opt)
768
ha_rows start_records;
770
if (!file) return HA_ADMIN_INTERNAL_ERROR;
772
myisamchk_init(¶m);
773
param.session = session;
774
param.op_name= "repair";
775
param.testflag= ((check_opt->flags & ~(T_EXTEND)) |
776
T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM |
777
(check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
778
param.sort_buffer_length= (size_t)sort_buffer_size;
780
// Release latches since this can take a long time
781
ha_release_temporary_latches(session);
783
start_records=file->state->records;
784
while ((error=repair(session,param,0)) && param.retry_repair)
786
param.retry_repair=0;
787
if (test_all_bits(param.testflag,
788
(uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
790
param.testflag&= ~T_RETRY_WITHOUT_QUICK;
791
errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' without quick",
795
param.testflag&= ~T_QUICK;
796
if ((param.testflag & T_REP_BY_SORT))
798
param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
799
errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' with keycache",
805
if (!error && start_records != file->state->records &&
806
!(check_opt->flags & T_VERY_SILENT))
808
char llbuff[22],llbuff2[22];
809
errmsg_printf(ERRMSG_LVL_INFO, "Found %s of %s rows when repairing '%s'",
810
llstr(file->state->records, llbuff),
811
llstr(start_records, llbuff2),
817
int ha_myisam::optimize(Session* session, HA_CHECK_OPT *check_opt)
820
if (!file) return HA_ADMIN_INTERNAL_ERROR;
823
myisamchk_init(¶m);
824
param.session = session;
825
param.op_name= "optimize";
826
param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
827
T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
828
param.sort_buffer_length= (size_t)sort_buffer_size;
829
if ((error= repair(session,param,1)) && param.retry_repair)
831
errmsg_printf(ERRMSG_LVL_WARN, "Warning: Optimize table got errno %d on %s.%s, retrying",
832
my_errno, param.db_name, param.table_name);
833
param.testflag&= ~T_REP_BY_SORT;
834
error= repair(session,param,1);
840
662
int ha_myisam::repair(Session *session, MI_CHECK ¶m, bool do_optimize)
1262
bool ha_myisam::check_and_repair(Session *session)
1267
uint32_t old_query_length;
1268
HA_CHECK_OPT check_opt;
1271
check_opt.flags= T_MEDIUM | T_AUTO_REPAIR;
1272
// Don't use quick if deleted rows
1273
if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK))
1274
check_opt.flags|=T_QUICK;
1275
errmsg_printf(ERRMSG_LVL_WARN, "Checking table: '%s'",table->s->path.str);
1277
old_query= session->query;
1278
old_query_length= session->query_length;
1279
pthread_mutex_lock(&LOCK_thread_count);
1280
session->query= table->s->table_name.str;
1281
session->query_length= table->s->table_name.length;
1282
pthread_mutex_unlock(&LOCK_thread_count);
1284
if ((marked_crashed= mi_is_crashed(file)) || check(session, &check_opt))
1286
errmsg_printf(ERRMSG_LVL_WARN, "Recovering table: '%s'",table->s->path.str);
1288
((myisam_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) |
1289
(marked_crashed ? 0 : T_QUICK) |
1290
(myisam_recover_options & HA_RECOVER_FORCE ? 0 : T_SAFE_REPAIR) |
1292
if (repair(session, &check_opt))
1295
pthread_mutex_lock(&LOCK_thread_count);
1296
session->query= old_query;
1297
session->query_length= old_query_length;
1298
pthread_mutex_unlock(&LOCK_thread_count);
1302
bool ha_myisam::is_crashed() const
1304
return (file->s->state.changed & STATE_CRASHED ||
1305
(file->s->state.open_count));
1308
1035
int ha_myisam::update_row(const unsigned char *old_data, unsigned char *new_data)
1310
ha_statistic_increment(&SSV::ha_update_count);
1037
ha_statistic_increment(&system_status_var::ha_update_count);
1311
1038
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1312
1039
table->timestamp_field->set_time();
1313
1040
return mi_update(file,old_data,new_data);
1533
1225
if (flag & HA_STATUS_CONST)
1535
TABLE_SHARE *share= table->s;
1227
TableShare *share= table->s;
1536
1228
stats.max_data_file_length= misam_info.max_data_file_length;
1537
1229
stats.max_index_file_length= misam_info.max_index_file_length;
1538
1230
stats.create_time= misam_info.create_time;
1539
1231
ref_length= misam_info.reflength;
1540
1232
share->db_options_in_use= misam_info.options;
1541
stats.block_size= block_size; /* record block size */
1233
stats.block_size= myisam_key_cache_block_size; /* record block size */
1543
1235
/* Update share */
1544
if (share->tmp_table == NO_TMP_TABLE)
1236
if (share->tmp_table == message::Table::STANDARD)
1545
1237
pthread_mutex_lock(&share->mutex);
1546
share->keys_in_use.set_prefix(share->keys);
1547
share->keys_in_use.intersect_extended(misam_info.key_map);
1548
share->keys_for_keyread.intersect(share->keys_in_use);
1238
set_prefix(share->keys_in_use, share->keys);
1240
* Due to bug 394932 (32-bit solaris build failure), we need
1241
* to convert the uint64_t key_map member of the misam_info
1242
* structure in to a std::bitset so that we can logically and
1243
* it with the share->key_in_use key_map.
1246
string binary_key_map;
1247
uint64_t num= misam_info.key_map;
1249
* Convert the uint64_t to a binary
1250
* string representation of it.
1254
uint64_t bin_digit= num % 2;
1258
binary_key_map.append(ostr.str());
1260
* Now we have the binary string representation of the
1261
* flags, we need to fill that string representation out
1262
* with the appropriate number of bits. This is needed
1263
* since key_map is declared as a std::bitset of a certain bit
1264
* width that depends on the MAX_INDEXES variable.
1266
if (MAX_INDEXES <= 64)
1268
size_t len= 72 - binary_key_map.length();
1269
string all_zeros(len, '0');
1270
binary_key_map.insert(binary_key_map.begin(),
1276
size_t len= (MAX_INDEXES + 7) / 8 * 8;
1277
string all_zeros(len, '0');
1278
binary_key_map.insert(binary_key_map.begin(),
1282
key_map tmp_map(binary_key_map);
1283
share->keys_in_use&= tmp_map;
1284
share->keys_for_keyread&= share->keys_in_use;
1549
1285
share->db_record_offset= misam_info.record_offset;
1550
1286
if (share->key_parts)
1551
1287
memcpy(table->key_info[0].rec_per_key,
1552
1288
misam_info.rec_per_key,
1553
1289
sizeof(table->key_info[0].rec_per_key)*share->key_parts);
1554
if (share->tmp_table == NO_TMP_TABLE)
1290
if (share->tmp_table == message::Table::STANDARD)
1555
1291
pthread_mutex_unlock(&share->mutex);
1653
1368
MI_KEYDEF *keydef;
1654
1369
MI_COLUMNDEF *recinfo;
1655
1370
MI_CREATE_INFO create_info;
1656
TABLE_SHARE *share= table_arg->s;
1371
TableShare *share= table_arg.s;
1657
1372
uint32_t options= share->db_options_in_use;
1658
if ((error= table2myisam(table_arg, &keydef, &recinfo, &create_records)))
1659
return(error); /* purecov: inspected */
1373
if ((error= table2myisam(&table_arg, &keydef, &recinfo, &create_records)))
1660
1375
memset(&create_info, 0, sizeof(create_info));
1661
create_info.max_rows= share->max_rows;
1662
create_info.reloc_rows= share->min_rows;
1376
create_info.max_rows= create_proto.options().max_rows();
1377
create_info.reloc_rows= create_proto.options().min_rows();
1663
1378
create_info.with_auto_increment= share->next_number_key_offset == 0;
1664
create_info.auto_increment= (ha_create_info->auto_increment_value ?
1665
ha_create_info->auto_increment_value -1 :
1379
create_info.auto_increment= (create_proto.options().has_auto_increment_value() ?
1380
create_proto.options().auto_increment_value() -1 :
1667
create_info.data_file_length= ((uint64_t) share->max_rows *
1668
share->avg_row_length);
1669
create_info.data_file_name= ha_create_info->data_file_name;
1670
create_info.index_file_name= ha_create_info->index_file_name;
1382
create_info.data_file_length= (create_proto.options().max_rows() *
1383
create_proto.options().avg_row_length());
1384
create_info.data_file_name= NULL;
1385
create_info.index_file_name= NULL;
1671
1386
create_info.language= share->table_charset->number;
1673
if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE)
1388
if (create_proto.type() == message::Table::TEMPORARY)
1674
1389
create_flags|= HA_CREATE_TMP_TABLE;
1675
if (ha_create_info->options & HA_CREATE_KEEP_FILES)
1676
create_flags|= HA_CREATE_KEEP_FILES;
1677
1390
if (options & HA_OPTION_PACK_RECORD)
1678
1391
create_flags|= HA_PACK_RECORD;
1679
if (options & HA_OPTION_CHECKSUM)
1680
create_flags|= HA_CREATE_CHECKSUM;
1681
if (options & HA_OPTION_DELAY_KEY_WRITE)
1682
create_flags|= HA_CREATE_DELAY_KEY_WRITE;
1684
/* TODO: Check that the following fn_format is really needed */
1685
error= mi_create(fn_format(buff, name, "", "",
1686
MY_UNPACK_FILENAME|MY_APPEND_EXT),
1393
/* TODO: Check that the following internal::fn_format is really needed */
1394
error= mi_create(internal::fn_format(buff, identifier.getPath().c_str(), "", "",
1395
MY_UNPACK_FILENAME|MY_APPEND_EXT),
1687
1396
share->keys, keydef,
1688
1397
create_records, recinfo,
1689
1398
0, (MI_UNIQUEDEF*) 0,
1690
1399
&create_info, create_flags);
1691
1400
free((unsigned char*) recinfo);
1402
session.storeTableMessage(identifier, create_proto);
1696
int ha_myisam::rename_table(const char * from, const char * to)
1408
int MyisamEngine::doRenameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
1698
return mi_rename(from,to);
1410
session.renameTableMessage(from, to);
1412
return mi_rename(from.getPath().c_str(), to.getPath().c_str());
1785
1499
return (uint)file->state->checksum;
1789
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info,
1790
uint32_t table_changes)
1792
uint32_t options= table->s->db_options_in_use;
1794
if (create_info->auto_increment_value != stats.auto_increment_value ||
1795
create_info->data_file_name != data_file_name ||
1796
create_info->index_file_name != index_file_name ||
1797
table_changes == IS_EQUAL_NO ||
1798
table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
1799
return COMPATIBLE_DATA_NO;
1801
if ((options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM |
1802
HA_OPTION_DELAY_KEY_WRITE)) !=
1803
(create_info->table_options & (HA_OPTION_PACK_RECORD |
1804
HA_OPTION_CHECKSUM |
1805
HA_OPTION_DELAY_KEY_WRITE)))
1806
return COMPATIBLE_DATA_NO;
1807
return COMPATIBLE_DATA_YES;
1810
1502
static MyisamEngine *engine= NULL;
1812
static int myisam_init(PluginRegistry ®istry)
1504
static int myisam_init(plugin::Context &context)
1814
1506
engine= new MyisamEngine(engine_name);
1815
registry.add(engine);
1817
pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_FAST);
1507
context.add(engine);
1509
/* call ha_init_key_cache() on all key caches to init them */
1510
int error= init_key_cache(dflt_key_cache,
1511
myisam_key_cache_block_size,
1512
myisam_key_cache_size,
1513
myisam_key_cache_division_limit,
1514
myisam_key_cache_age_threshold);
1517
exit(1); /* Memory Allocation Failure */
1822
int myisam_deinit(PluginRegistry ®istry)
1824
registry.remove(engine);
1827
pthread_mutex_destroy(&THR_LOCK_myisam);
1829
return mi_panic(HA_PANIC_CLOSE);
1833
/****************************************************************************
1834
* MyISAM MRR implementation: use DS-MRR
1835
***************************************************************************/
1837
int ha_myisam::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
1838
uint32_t n_ranges, uint32_t mode,
1839
HANDLER_BUFFER *buf)
1841
return ds_mrr.dsmrr_init(this, &table->key_info[active_index],
1842
seq, seq_init_param, n_ranges, mode, buf);
1845
int ha_myisam::multi_range_read_next(char **range_info)
1847
return ds_mrr.dsmrr_next(this, range_info);
1850
ha_rows ha_myisam::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
1851
void *seq_init_param,
1852
uint32_t n_ranges, uint32_t *bufsz,
1853
uint32_t *flags, COST_VECT *cost)
1856
This call is here because there is no location where this->table would
1858
TODO: consider moving it into some per-query initialization call.
1860
ds_mrr.init(this, table);
1861
return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
1865
int ha_myisam::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
1866
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
1868
ds_mrr.init(this, table);
1869
return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
1872
/* MyISAM MRR implementation ends */
1875
/* Index condition pushdown implementation*/
1878
Item *ha_myisam::idx_cond_push(uint32_t keyno_arg, Item* idx_cond_arg)
1880
pushed_idx_cond_keyno= keyno_arg;
1881
pushed_idx_cond= idx_cond_arg;
1882
in_range_check_pushed_down= true;
1883
if (active_index == pushed_idx_cond_keyno)
1884
mi_set_index_cond_func(file, index_cond_func_myisam, this);
1888
static DRIZZLE_SYSVAR_UINT(block_size, block_size,
1889
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
1890
N_("Block size to be used for MyISAM index pages."),
1891
NULL, NULL, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH,
1892
MI_MAX_KEY_BLOCK_LENGTH, 0);
1523
static void sys_var_key_cache_size_update(Session *session, drizzle_sys_var *var, void *, const void *save)
1525
uint32_t tmp= *static_cast<const uint32_t *>(save);
1528
struct option option_limits;
1529
plugin_opt_set_limits(&option_limits, var);
1530
option_limits.name= "myisam_key_cache_size";
1532
if (dflt_key_cache->in_init)
1535
myisam_key_cache_size= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
1537
/* If key cache didn't existed initialize it, else resize it */
1538
dflt_key_cache->in_init= 1;
1540
error= ! resize_key_cache(dflt_key_cache,
1541
myisam_key_cache_block_size,
1542
myisam_key_cache_size,
1543
myisam_key_cache_division_limit,
1544
myisam_key_cache_age_threshold);
1545
dflt_key_cache->in_init= 0;
1548
static void sys_var_key_cache_block_size_update(Session *session, drizzle_sys_var *var, void *, const void *save)
1550
uint32_t tmp= *static_cast<const uint32_t *>(save);
1553
struct option option_limits;
1554
plugin_opt_set_limits(&option_limits, var);
1555
option_limits.name= "myisam_key_cache_block_size";
1557
if (dflt_key_cache->in_init)
1560
myisam_key_cache_block_size= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
1562
dflt_key_cache->in_init= 1;
1564
error= ! resize_key_cache(dflt_key_cache,
1565
myisam_key_cache_block_size,
1566
myisam_key_cache_size,
1567
myisam_key_cache_division_limit,
1568
myisam_key_cache_age_threshold);
1570
dflt_key_cache->in_init= 0;
1573
static void sys_var_key_cache_division_limit_update(Session *session, drizzle_sys_var *var, void *, const void *save)
1575
uint32_t tmp= *static_cast<const uint32_t *>(save);
1578
struct option option_limits;
1579
plugin_opt_set_limits(&option_limits, var);
1580
option_limits.name= "myisam_key_cache_division_limit";
1582
if (dflt_key_cache->in_init)
1585
myisam_key_cache_division_limit= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
1587
dflt_key_cache->in_init= 1;
1589
error= ! resize_key_cache(dflt_key_cache,
1590
myisam_key_cache_block_size,
1591
myisam_key_cache_size,
1592
myisam_key_cache_division_limit,
1593
myisam_key_cache_age_threshold);
1595
dflt_key_cache->in_init= 0;
1598
static void sys_var_key_cache_age_threshold_update(Session *session, drizzle_sys_var *var, void *, const void *save)
1600
uint32_t tmp= *static_cast<const uint32_t *>(save);
1603
struct option option_limits;
1604
plugin_opt_set_limits(&option_limits, var);
1605
option_limits.name= "myisam_key_cache_age_threshold";
1607
if (dflt_key_cache->in_init)
1610
myisam_key_cache_age_threshold= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
1612
dflt_key_cache->in_init= 1;
1614
error= ! resize_key_cache(dflt_key_cache,
1615
myisam_key_cache_block_size,
1616
myisam_key_cache_size,
1617
myisam_key_cache_division_limit,
1618
myisam_key_cache_age_threshold);
1620
dflt_key_cache->in_init= 0;
1623
static DRIZZLE_SYSVAR_UINT(key_cache_block_size,
1624
myisam_key_cache_block_size,
1625
PLUGIN_VAR_RQCMDARG,
1626
N_("Block size to be used for MyISAM index pages."),
1628
sys_var_key_cache_block_size_update,
1629
KEY_CACHE_BLOCK_SIZE,
1634
static DRIZZLE_SYSVAR_UINT(key_cache_age_threshold, myisam_key_cache_age_threshold,
1635
PLUGIN_VAR_RQCMDARG,
1636
N_("This characterizes the number of hits a hot block has to be untouched "
1637
"until it is considered aged enough to be downgraded to a warm block. "
1638
"This specifies the percentage ratio of that number of hits to the "
1639
"total number of blocks in key cache"),
1641
sys_var_key_cache_age_threshold_update,
1647
static DRIZZLE_SYSVAR_UINT(key_cache_division_limit, myisam_key_cache_division_limit,
1648
PLUGIN_VAR_RQCMDARG,
1649
N_("The minimum percentage of warm blocks in key cache"),
1651
sys_var_key_cache_division_limit_update,
1657
static DRIZZLE_SYSVAR_UINT(key_cache_size,
1658
myisam_key_cache_size,
1659
PLUGIN_VAR_RQCMDARG,
1660
N_("The size of the buffer used for index blocks for MyISAM tables. "
1661
"Increase this to get better index handling (for all reads and multiple "
1662
"writes) to as much as you can afford;"),
1664
sys_var_key_cache_size_update,
1894
1670
static DRIZZLE_SYSVAR_UINT(repair_threads, repair_threads,
1895
PLUGIN_VAR_RQCMDARG,
1896
N_("Number of threads to use when repairing MyISAM tables. The value of "
1897
"1 disables parallel repair."),
1898
NULL, NULL, 1, 1, UINT32_MAX, 0);
1671
PLUGIN_VAR_RQCMDARG,
1672
N_("Number of threads to use when repairing MyISAM tables. The value of "
1673
"1 disables parallel repair."),
1674
NULL, NULL, 1, 1, UINT32_MAX, 0);
1900
1676
static DRIZZLE_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size,
1901
1677
PLUGIN_VAR_RQCMDARG,