19
#include "drizzled/internal/my_bit.h"
18
#include <drizzled/server_includes.h>
19
#include <mysys/my_bit.h>
20
20
#include "myisampack.h"
21
21
#include "ha_myisam.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"
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/plugin/protocol.h>
29
#include <drizzled/table.h>
30
#include <drizzled/field/timestamp.h>
42
33
#include <algorithm>
44
35
using namespace std;
45
using namespace drizzled;
47
extern pthread_mutex_t LOCK_global_system_variables;
48
37
static const string engine_name("MyISAM");
39
ulong myisam_recover_options= HA_RECOVER_NONE;
50
40
pthread_mutex_t THR_LOCK_myisam= PTHREAD_MUTEX_INITIALIZER;
52
42
static uint32_t repair_threads;
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
static uint32_t block_size;
57
44
static uint64_t max_sort_file_size;
58
45
static uint64_t sort_buffer_size;
47
/* bits in myisam_recover_options */
48
const char *myisam_recover_names[] =
49
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NULL};
50
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
51
myisam_recover_names, NULL};
60
55
/*****************************************************************************
62
57
*****************************************************************************/
70
class MyisamEngine : public plugin::StorageEngine
65
class MyisamEngine : public StorageEngine
73
MyisamEngine(const MyisamEngine&);
74
MyisamEngine& operator=(const MyisamEngine&);
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);
68
MyisamEngine(string name_arg)
69
: StorageEngine(name_arg,
74
virtual handler *create(TableShare *table,
77
return new (mem_root) ha_myisam(this, table);
105
80
const char **bas_ext() const {
106
81
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);
84
int createTableImplementation(Session *, const char *table_name,
86
HA_CREATE_INFO *ha_create_info,
87
drizzled::message::Table*);
89
int renameTableImplementation(Session*, const char *from, const char *to);
91
int deleteTableImplementation(Session*, const string table_name);
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 )
94
// collect errors printed by mi_check routines
96
static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
97
const char *fmt, va_list args)
99
Session* session = (Session*)param->session;
100
drizzled::plugin::Protocol *protocol= session->protocol;
101
uint32_t length, msg_length;
102
char msgbuf[MI_MAX_MSG_BUF];
103
char name[NAME_LEN*2+2];
105
msg_length= vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
106
msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
108
if (!session->protocol->isConnected())
110
errmsg_printf(ERRMSG_LVL_ERROR, "%s",msgbuf);
114
if (param->testflag & (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR |
117
my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
120
length= sprintf(name,"%s.%s",param->db_name,param->table_name);
123
TODO: switch from protocol to push_warning here. The main reason we didn't
124
it yet is parallel repair. Due to following trace:
125
mi_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr.
127
Also we likely need to lock mutex here (in both cases with protocol and
130
protocol->prepareForResend();
131
protocol->store(name, length);
132
protocol->store(param->op_name);
133
protocol->store(msg_type);
134
protocol->store(msgbuf, msg_length);
135
if (protocol->write())
136
errmsg_printf(ERRMSG_LVL_ERROR, "Failed on drizzleclient_net_write, writing to stderr instead: %s\n",
1368
1363
MI_KEYDEF *keydef;
1369
1364
MI_COLUMNDEF *recinfo;
1370
1365
MI_CREATE_INFO create_info;
1371
TableShare *share= table_arg.s;
1366
TableShare *share= table_arg->s;
1372
1367
uint32_t options= share->db_options_in_use;
1373
if ((error= table2myisam(&table_arg, &keydef, &recinfo, &create_records)))
1368
if ((error= table2myisam(table_arg, &keydef, &recinfo, &create_records)))
1369
return(error); /* purecov: inspected */
1375
1370
memset(&create_info, 0, sizeof(create_info));
1376
create_info.max_rows= create_proto.options().max_rows();
1377
create_info.reloc_rows= create_proto.options().min_rows();
1371
create_info.max_rows= create_proto->options().max_rows();
1372
create_info.reloc_rows= create_proto->options().min_rows();
1378
1373
create_info.with_auto_increment= share->next_number_key_offset == 0;
1379
create_info.auto_increment= (create_proto.options().has_auto_increment_value() ?
1380
create_proto.options().auto_increment_value() -1 :
1374
create_info.auto_increment= (ha_create_info->auto_increment_value ?
1375
ha_create_info->auto_increment_value -1 :
1382
create_info.data_file_length= (create_proto.options().max_rows() *
1383
create_proto.options().avg_row_length());
1377
create_info.data_file_length= (create_proto->options().max_rows() *
1378
create_proto->options().avg_row_length());
1384
1379
create_info.data_file_name= NULL;
1385
1380
create_info.index_file_name= NULL;
1386
1381
create_info.language= share->table_charset->number;
1388
if (create_proto.type() == message::Table::TEMPORARY)
1383
if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE)
1389
1384
create_flags|= HA_CREATE_TMP_TABLE;
1385
if (ha_create_info->options & HA_CREATE_KEEP_FILES)
1386
create_flags|= HA_CREATE_KEEP_FILES;
1390
1387
if (options & HA_OPTION_PACK_RECORD)
1391
1388
create_flags|= HA_PACK_RECORD;
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),
1390
/* TODO: Check that the following fn_format is really needed */
1391
error= mi_create(fn_format(buff, table_name, "", "",
1392
MY_UNPACK_FILENAME|MY_APPEND_EXT),
1396
1393
share->keys, keydef,
1397
1394
create_records, recinfo,
1398
1395
0, (MI_UNIQUEDEF*) 0,
1399
1396
&create_info, create_flags);
1400
1397
free((unsigned char*) recinfo);
1402
session.storeTableMessage(identifier, create_proto);
1408
int MyisamEngine::doRenameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
1402
int MyisamEngine::renameTableImplementation(Session*,
1403
const char *from, const char *to)
1410
session.renameTableMessage(from, to);
1412
return mi_rename(from.getPath().c_str(), to.getPath().c_str());
1405
return mi_rename(from,to);
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,
1518
static int myisam_deinit(drizzled::plugin::Registry ®istry)
1520
registry.remove(engine);
1523
pthread_mutex_destroy(&THR_LOCK_myisam);
1524
end_key_cache(dflt_key_cache, 1); // Can never fail
1526
return mi_panic(HA_PANIC_CLOSE);
1529
static DRIZZLE_SYSVAR_UINT(block_size, block_size,
1530
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
1531
N_("Block size to be used for MyISAM index pages."),
1532
NULL, NULL, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH,
1533
MI_MAX_KEY_BLOCK_LENGTH, 0);
1670
1535
static DRIZZLE_SYSVAR_UINT(repair_threads, repair_threads,
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);
1536
PLUGIN_VAR_RQCMDARG,
1537
N_("Number of threads to use when repairing MyISAM tables. The value of "
1538
"1 disables parallel repair."),
1539
NULL, NULL, 1, 1, UINT32_MAX, 0);
1676
1541
static DRIZZLE_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size,
1677
1542
PLUGIN_VAR_RQCMDARG,