12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
19
#include <drizzled/internal/my_bit.h>
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
19
#include "drizzled/internal/my_bit.h"
20
20
#include "myisampack.h"
21
21
#include "ha_myisam.h"
22
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>
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"
31
32
#include <drizzled/plugin.h>
32
#include <drizzled/plugin/client.h>
33
#include <drizzled/table.h>
34
#include <drizzled/memory/multi_malloc.h>
35
#include <drizzled/plugin/daemon.h>
37
#include <drizzled/plugin/storage_engine.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"
39
39
#include <boost/algorithm/string.hpp>
40
#include <boost/scoped_ptr.hpp>
45
44
#include <algorithm>
47
45
#include <boost/program_options.hpp>
48
46
#include <drizzled/module/option_map.h>
55
53
static const string engine_name("MyISAM");
57
boost::mutex THR_LOCK_myisam;
55
pthread_mutex_t THR_LOCK_myisam= PTHREAD_MUTEX_INITIALIZER;
59
57
static uint32_t myisam_key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
60
58
static uint32_t myisam_key_cache_size;
61
59
static uint32_t myisam_key_cache_division_limit;
62
60
static uint32_t myisam_key_cache_age_threshold;
63
61
static uint64_t max_sort_file_size;
64
typedef constrained_check<size_t, SIZE_MAX, 1024, 1024> sort_buffer_constraint;
65
static sort_buffer_constraint sort_buffer_size;
62
static uint64_t sort_buffer_size;
67
64
void st_mi_isam_share::setKeyCache()
119
119
int doCreateTable(Session&,
120
120
Table& table_arg,
121
const identifier::Table &identifier,
121
const TableIdentifier &identifier,
122
122
message::Table&);
124
int doRenameTable(Session&, const identifier::Table &from, const identifier::Table &to);
124
int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
126
int doDropTable(Session&, const identifier::Table &identifier);
126
int doDropTable(Session&, const TableIdentifier &identifier);
128
128
int doGetTableDefinition(Session& session,
129
const identifier::Table &identifier,
129
const TableIdentifier &identifier,
130
130
message::Table &table_message);
132
/* Temp only engine, so do not return values. */
133
void doGetTableNames(CachedDirectory &, const SchemaIdentifier &, set<string>&) { };
132
135
uint32_t max_supported_keys() const { return MI_MAX_KEY; }
133
136
uint32_t max_supported_key_length() const { return MI_MAX_KEY_LENGTH; }
134
137
uint32_t max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; }
142
145
HA_KEYREAD_ONLY);
144
bool doDoesTableExist(Session& session, const identifier::Table &identifier);
147
bool doDoesTableExist(Session& session, const TableIdentifier &identifier);
146
149
void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
147
const drizzled::identifier::Schema &schema_identifier,
148
drizzled::identifier::Table::vector &set_of_identifiers);
150
const drizzled::SchemaIdentifier &schema_identifier,
151
drizzled::TableIdentifiers &set_of_identifiers);
149
152
bool validateCreateTableOption(const std::string &key, const std::string &state)
161
164
void MyisamEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
162
const drizzled::identifier::Schema&,
163
drizzled::identifier::Table::vector&)
165
const drizzled::SchemaIdentifier&,
166
drizzled::TableIdentifiers&)
167
bool MyisamEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
170
bool MyisamEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
169
return session.getMessageCache().doesTableMessageExist(identifier);
172
return session.doesTableMessageExist(identifier);
172
175
int MyisamEngine::doGetTableDefinition(Session &session,
173
const identifier::Table &identifier,
176
const TableIdentifier &identifier,
174
177
message::Table &table_message)
176
if (session.getMessageCache().getTableMessage(identifier, table_message))
179
if (session.getTableMessage(identifier, table_message))
534
535
Session *cur_session;
535
536
if ((cur_session= file->in_use))
537
errmsg_printf(error::ERROR, _("Got an error from thread_id=%"PRIu64", %s:%d"),
537
errmsg_printf(ERRMSG_LVL_ERROR, _("Got an error from thread_id=%"PRIu64", %s:%d"),
538
538
cur_session->thread_id,
543
errmsg_printf(error::ERROR, _("Got an error from unknown thread, %s:%d"), sfile, sline);
541
errmsg_printf(ERRMSG_LVL_ERROR, _("Got an error from unknown thread, %s:%d"), sfile, sline);
547
errmsg_printf(error::ERROR, "%s", message);
543
errmsg_printf(ERRMSG_LVL_ERROR, "%s", message);
549
544
list<Session *>::iterator it= file->s->in_use->begin();
550
545
while (it != file->s->in_use->end())
552
errmsg_printf(error::ERROR, "%s", _("Unknown thread accessing table"));
547
errmsg_printf(ERRMSG_LVL_ERROR, "%s", _("Unknown thread accessing table"));
557
552
ha_myisam::ha_myisam(plugin::StorageEngine &engine_arg,
553
TableShare &table_arg)
559
554
: Cursor(engine_arg, table_arg),
561
556
can_enable_indexes(true),
598
593
open of a table that is in use by other threads already (if the
599
594
MyISAM share exists already).
601
if (!(file= mi_open(identifier, mode, test_if_locked)))
596
if (!(file=mi_open(name, mode, test_if_locked)))
602
597
return (errno ? errno : -1);
604
if (!getTable()->getShare()->getType()) /* No need to perform a check for tmp table */
599
if (!table->getShare()->getType()) /* No need to perform a check for tmp table */
606
if ((errno= table2myisam(getTable(), &keyinfo, &recinfo, &recs)))
601
if ((errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
610
if (check_definition(keyinfo, recinfo, getTable()->getShare()->sizeKeys(), recs,
605
if (check_definition(keyinfo, recinfo, table->getShare()->sizeKeys(), recs,
611
606
file->s->keyinfo, file->s->rec,
612
607
file->s->base.keys, file->s->base.fields, true))
623
618
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
624
619
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
625
620
mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
626
if (!getTable()->getShare()->db_record_offset)
621
if (!table->getShare()->db_record_offset)
627
622
is_ordered= false;
630
625
keys_with_parts.reset();
631
for (i= 0; i < getTable()->getShare()->sizeKeys(); i++)
626
for (i= 0; i < table->getShare()->sizeKeys(); i++)
633
getTable()->key_info[i].block_size= file->s->keyinfo[i].block_length;
628
table->key_info[i].block_size= file->s->keyinfo[i].block_length;
635
KeyPartInfo *kp= getTable()->key_info[i].key_part;
636
KeyPartInfo *kp_end= kp + getTable()->key_info[i].key_parts;
630
KeyPartInfo *kp= table->key_info[i].key_part;
631
KeyPartInfo *kp_end= kp + table->key_info[i].key_parts;
637
632
for (; kp != kp_end; kp++)
639
634
if (!kp->field->part_of_key.test(i))
701
696
if (file->dfile == -1)
703
errmsg_printf(error::INFO, "Retrying repair of: '%s' failed. "
704
"Please try REPAIR EXTENDED or myisamchk",
705
getTable()->getShare()->getPath());
698
errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' failed. "
699
"Please try REPAIR EXTENDED or myisamchk",
700
table->getShare()->getPath());
706
701
return(HA_ADMIN_FAILED);
709
param.db_name= getTable()->getShare()->getSchemaName();
710
param.table_name= getTable()->getAlias();
704
param.db_name= table->getShare()->getSchemaName();
705
param.table_name= table->getAlias();
711
706
param.tmpfile_createflag = O_RDWR | O_TRUNC;
712
707
param.using_global_keycache = 1;
713
708
param.session= session;
714
709
param.out_flag= 0;
715
param.sort_buffer_length= static_cast<size_t>(sort_buffer_size);
710
param.sort_buffer_length= (size_t)sort_buffer_size;
716
711
strcpy(fixed_name,file->filename);
718
713
// Don't lock tables if we have used LOCK Table
719
if (mi_lock_database(file, getTable()->getShare()->getType() ? F_EXTRA_LCK : F_WRLCK))
714
if (mi_lock_database(file, table->getShare()->getType() ? F_EXTRA_LCK : F_WRLCK))
721
716
mi_check_print_error(¶m,ER(ER_CANT_LOCK),errno);
722
717
return(HA_ADMIN_FAILED);
923
917
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
924
918
T_CREATE_MISSING_KEYS);
925
919
param.myf_rw&= ~MY_WAIT_IF_FULL;
926
param.sort_buffer_length= static_cast<size_t>(sort_buffer_size);
920
param.sort_buffer_length= (size_t)sort_buffer_size;
927
921
param.stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
928
922
if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
930
errmsg_printf(error::WARN, "Warning: Enabling keys got errno %d on %s.%s, retrying",
924
errmsg_printf(ERRMSG_LVL_WARN, "Warning: Enabling keys got errno %d on %s.%s, retrying",
931
925
errno, param.db_name, param.table_name);
932
926
/* Repairing by sort failed. Now try standard repair method. */
933
927
param.testflag&= ~(T_REP_BY_SORT | T_QUICK);
1349
1343
int ha_myisam::external_lock(Session *session, int lock_type)
1351
1345
file->in_use= session;
1352
return mi_lock_database(file, !getTable()->getShare()->getType() ?
1346
return mi_lock_database(file, !table->getShare()->getType() ?
1353
1347
lock_type : ((lock_type == F_UNLCK) ?
1354
1348
F_UNLCK : F_EXTRA_LCK));
1357
1351
int MyisamEngine::doCreateTable(Session &session,
1358
1352
Table& table_arg,
1359
const identifier::Table &identifier,
1353
const TableIdentifier &identifier,
1360
1354
message::Table& create_proto)
1396
1390
&create_info, create_flags);
1397
1391
free((unsigned char*) recinfo);
1399
session.getMessageCache().storeTableMessage(identifier, create_proto);
1393
session.storeTableMessage(identifier, create_proto);
1405
int MyisamEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
1399
int MyisamEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
1407
session.getMessageCache().renameTableMessage(from, to);
1401
session.renameTableMessage(from, to);
1409
1403
return mi_rename(from.getPath().c_str(), to.getPath().c_str());
1432
1426
/* it's safe to call the following if bulk_insert isn't on */
1433
mi_flush_bulk_insert(file, getTable()->getShare()->next_number_index);
1427
mi_flush_bulk_insert(file, table->getShare()->next_number_index);
1435
1429
(void) extra(HA_EXTRA_KEYREAD);
1436
key_copy(key, getTable()->getInsertRecord(),
1437
&getTable()->key_info[getTable()->getShare()->next_number_index],
1438
getTable()->getShare()->next_number_key_offset);
1439
error= mi_rkey(file, getTable()->getUpdateRecord(), (int) getTable()->getShare()->next_number_index,
1440
key, make_prev_keypart_map(getTable()->getShare()->next_number_keypart),
1430
key_copy(key, table->getInsertRecord(),
1431
&table->key_info[table->getShare()->next_number_index],
1432
table->getShare()->next_number_key_offset);
1433
error= mi_rkey(file, table->getUpdateRecord(), (int) table->getShare()->next_number_index,
1434
key, make_prev_keypart_map(table->getShare()->next_number_keypart),
1441
1435
HA_READ_PREFIX_LAST);
1446
1440
/* Get data from getUpdateRecord() */
1447
nr= ((uint64_t) getTable()->next_number_field->
1448
val_int_offset(getTable()->getShare()->rec_buff_length)+1);
1441
nr= ((uint64_t) table->next_number_field->
1442
val_int_offset(table->getShare()->rec_buff_length)+1);
1450
1444
extra(HA_EXTRA_NO_KEYREAD);
1451
1445
*first_value= nr;
1496
1490
return (uint)file->state->checksum;
1493
static MyisamEngine *engine= NULL;
1499
1495
static int myisam_init(module::Context &context)
1501
context.add(new MyisamEngine(engine_name));
1502
context.registerVariable(new sys_var_constrained_value<size_t>("sort-buffer-size",
1504
context.registerVariable(new sys_var_uint64_t_ptr("max_sort_file_size",
1505
&max_sort_file_size,
1506
context.getOptions()["max-sort-file-size"].as<uint64_t>()));
1497
const module::option_map &vm= context.getOptions();
1499
if (vm.count("max-sort-file-size"))
1501
if (max_sort_file_size > UINT64_MAX)
1503
errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-sort-file-size\n"));
1508
if (vm.count("sort-buffer-size"))
1510
if (sort_buffer_size < 1024 || sort_buffer_size > SIZE_MAX)
1512
errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for sort-buffer-size\n"));
1517
engine= new MyisamEngine(engine_name);
1518
context.add(engine);
1524
static DRIZZLE_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size,
1525
PLUGIN_VAR_RQCMDARG,
1526
N_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."),
1527
NULL, NULL, INT32_MAX, 0, UINT64_MAX, 0);
1529
static DRIZZLE_SYSVAR_ULONGLONG(sort_buffer_size, sort_buffer_size,
1530
PLUGIN_VAR_RQCMDARG,
1531
N_("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."),
1532
NULL, NULL, 8192*1024, 1024, SIZE_MAX, 0);
1534
extern uint32_t data_pointer_size;
1535
static DRIZZLE_SYSVAR_UINT(data_pointer_size, data_pointer_size,
1536
PLUGIN_VAR_RQCMDARG,
1537
N_("Default pointer size to be used for MyISAM tables."),
1538
NULL, NULL, 6, 2, 7, 0);
1512
1540
static void init_options(drizzled::module::option_context &context)
1514
1542
context("max-sort-file-size",
1515
1543
po::value<uint64_t>(&max_sort_file_size)->default_value(INT32_MAX),
1516
_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."));
1544
N_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."));
1517
1545
context("sort-buffer-size",
1518
po::value<sort_buffer_constraint>(&sort_buffer_size)->default_value(8192*1024),
1519
_("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."));
1546
po::value<uint64_t>(&sort_buffer_size)->default_value(8192*1024),
1547
N_("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."));
1548
context("data-pointer-size",
1549
po::value<uint32_t>(&data_pointer_size)->default_value(6),
1550
N_("Default pointer size to be used for MyISAM tables."));
1553
static drizzle_sys_var* sys_variables[]= {
1554
DRIZZLE_SYSVAR(max_sort_file_size),
1555
DRIZZLE_SYSVAR(sort_buffer_size),
1556
DRIZZLE_SYSVAR(data_pointer_size),
1523
1561
DRIZZLE_DECLARE_PLUGIN