~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/ha_myisam.cc

  • Committer: Monty Taylor
  • Date: 2010-04-22 02:46:23 UTC
  • mto: (1497.3.4 enable-dtrace)
  • mto: This revision was merged to the branch mainline in revision 1527.
  • Revision ID: mordred@inaugust.com-20100422024623-4urw8fi8eraci08p
Don't overwrite the pandora_vc_revinfo file if we don't have new
authoratative information.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
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 */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
 
28
28
#include "drizzled/errmsg_print.h"
29
29
#include "drizzled/gettext.h"
30
30
#include "drizzled/session.h"
31
 
#include "drizzled/plugin.h"
 
31
#include "drizzled/set_var.h"
 
32
#include <drizzled/plugin.h>
32
33
#include "drizzled/plugin/client.h"
33
34
#include "drizzled/table.h"
34
35
#include "drizzled/field/timestamp.h"
35
36
#include "drizzled/memory/multi_malloc.h"
36
37
#include "drizzled/plugin/daemon.h"
37
38
 
38
 
#include <boost/algorithm/string.hpp>
39
 
#include <boost/scoped_ptr.hpp>
40
 
 
41
39
#include <string>
42
40
#include <sstream>
43
41
#include <map>
44
42
#include <algorithm>
45
 
#include <memory>
46
 
#include <boost/program_options.hpp>
47
 
#include <drizzled/module/option_map.h>
48
 
 
49
 
namespace po= boost::program_options;
50
43
 
51
44
using namespace std;
52
45
using namespace drizzled;
53
46
 
 
47
extern pthread_mutex_t LOCK_global_system_variables;
54
48
static const string engine_name("MyISAM");
55
49
 
56
 
boost::mutex THR_LOCK_myisam;
 
50
pthread_mutex_t THR_LOCK_myisam= PTHREAD_MUTEX_INITIALIZER;
57
51
 
58
 
static uint32_t myisam_key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
 
52
static uint32_t repair_threads;
 
53
static uint32_t myisam_key_cache_block_size;
59
54
static uint32_t myisam_key_cache_size;
60
55
static uint32_t myisam_key_cache_division_limit;
61
56
static uint32_t myisam_key_cache_age_threshold;
62
57
static uint64_t max_sort_file_size;
63
 
typedef constrained_check<size_t, SIZE_MAX, 1024, 1024> sort_buffer_constraint;
64
 
static sort_buffer_constraint sort_buffer_size;
65
 
 
66
 
void st_mi_isam_share::setKeyCache()
67
 
{
68
 
  (void)init_key_cache(&key_cache,
69
 
                       myisam_key_cache_block_size,
70
 
                       myisam_key_cache_size,
71
 
                       myisam_key_cache_division_limit, 
72
 
                       myisam_key_cache_age_threshold);
73
 
}
 
58
static uint64_t sort_buffer_size;
74
59
 
75
60
/*****************************************************************************
76
61
** MyISAM tables
99
84
                          HTON_AUTO_PART_KEY |
100
85
                          HTON_SKIP_STORE_LOCK)
101
86
  {
 
87
    pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_FAST);
102
88
  }
103
89
 
104
90
  virtual ~MyisamEngine()
105
91
  { 
 
92
    pthread_mutex_destroy(&THR_LOCK_myisam);
 
93
    end_key_cache(dflt_key_cache, 1);           // Can never fail
 
94
 
106
95
    mi_panic(HA_PANIC_CLOSE);
107
96
  }
108
97
 
109
 
  virtual Cursor *create(Table &table)
 
98
  virtual Cursor *create(TableShare &table,
 
99
                         memory::Root *mem_root)
110
100
  {
111
 
    return new ha_myisam(*this, table);
 
101
    return new (mem_root) ha_myisam(*this, table);
112
102
  }
113
103
 
114
104
  const char **bas_ext() const {
117
107
 
118
108
  int doCreateTable(Session&,
119
109
                    Table& table_arg,
120
 
                    const TableIdentifier &identifier,
 
110
                    drizzled::TableIdentifier &identifier,
121
111
                    message::Table&);
122
112
 
123
 
  int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
 
113
  int doRenameTable(Session&, TableIdentifier &from, TableIdentifier &to);
124
114
 
125
 
  int doDropTable(Session&, const TableIdentifier &identifier);
 
115
  int doDropTable(Session&, drizzled::TableIdentifier &identifier);
126
116
 
127
117
  int doGetTableDefinition(Session& session,
128
 
                           const TableIdentifier &identifier,
 
118
                           drizzled::TableIdentifier &identifier,
129
119
                           message::Table &table_message);
130
120
 
 
121
  /* Temp only engine, so do not return values. */
 
122
  void doGetTableNames(CachedDirectory &, SchemaIdentifier &, set<string>&) { };
 
123
 
131
124
  uint32_t max_supported_keys()          const { return MI_MAX_KEY; }
132
125
  uint32_t max_supported_key_length()    const { return MI_MAX_KEY_LENGTH; }
133
126
  uint32_t max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; }
140
133
            HA_READ_ORDER |
141
134
            HA_KEYREAD_ONLY);
142
135
  }
143
 
  bool doDoesTableExist(Session& session, const TableIdentifier &identifier);
 
136
  bool doDoesTableExist(Session& session, TableIdentifier &identifier);
144
137
 
145
138
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
146
 
                             const drizzled::SchemaIdentifier &schema_identifier,
147
 
                             drizzled::TableIdentifier::vector &set_of_identifiers);
148
 
  bool validateCreateTableOption(const std::string &key, const std::string &state)
149
 
  {
150
 
    (void)state;
151
 
    if (boost::iequals(key, "ROW_FORMAT"))
152
 
    {
153
 
      return true;
154
 
    }
155
 
 
156
 
    return false;
157
 
  }
 
139
                             drizzled::SchemaIdentifier &schema_identifier,
 
140
                             drizzled::TableIdentifiers &set_of_identifiers);
158
141
};
159
142
 
160
143
void MyisamEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
161
 
                                         const drizzled::SchemaIdentifier&,
162
 
                                         drizzled::TableIdentifier::vector&)
 
144
                                         drizzled::SchemaIdentifier&,
 
145
                                         drizzled::TableIdentifiers&)
163
146
{
164
147
}
165
148
 
166
 
bool MyisamEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
 
149
bool MyisamEngine::doDoesTableExist(Session &session, TableIdentifier &identifier)
167
150
{
168
 
  return session.getMessageCache().doesTableMessageExist(identifier);
 
151
  return session.doesTableMessageExist(identifier);
169
152
}
170
153
 
171
154
int MyisamEngine::doGetTableDefinition(Session &session,
172
 
                                       const TableIdentifier &identifier,
 
155
                                       drizzled::TableIdentifier &identifier,
173
156
                                       message::Table &table_message)
174
157
{
175
 
  if (session.getMessageCache().getTableMessage(identifier, table_message))
 
158
  if (session.getTableMessage(identifier, table_message))
176
159
    return EEXIST;
177
160
  return ENOENT;
178
161
}
217
200
  uint32_t i, j, recpos, minpos, fieldpos, temp_length, length;
218
201
  enum ha_base_keytype type= HA_KEYTYPE_BINARY;
219
202
  unsigned char *record;
 
203
  KEY *pos;
220
204
  MI_KEYDEF *keydef;
221
205
  MI_COLUMNDEF *recinfo, *recinfo_pos;
222
206
  HA_KEYSEG *keyseg;
223
 
  TableShare *share= table_arg->getMutableShare();
 
207
  TableShare *share= table_arg->s;
224
208
  uint32_t options= share->db_options_in_use;
225
209
  if (!(memory::multi_malloc(false,
226
 
          recinfo_out, (share->sizeFields() * 2 + 2) * sizeof(MI_COLUMNDEF),
227
 
          keydef_out, share->sizeKeys() * sizeof(MI_KEYDEF),
228
 
          &keyseg, (share->key_parts + share->sizeKeys()) * sizeof(HA_KEYSEG),
 
210
          recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF),
 
211
          keydef_out, share->keys * sizeof(MI_KEYDEF),
 
212
          &keyseg, (share->key_parts + share->keys) * sizeof(HA_KEYSEG),
229
213
          NULL)))
230
214
    return(HA_ERR_OUT_OF_MEM);
231
215
  keydef= *keydef_out;
232
216
  recinfo= *recinfo_out;
233
 
  for (i= 0; i < share->sizeKeys(); i++)
 
217
  pos= table_arg->key_info;
 
218
  for (i= 0; i < share->keys; i++, pos++)
234
219
  {
235
 
    KeyInfo *pos= &table_arg->key_info[i];
236
220
    keydef[i].flag= ((uint16_t) pos->flags & (HA_NOSAME));
237
221
    keydef[i].key_alg= HA_KEY_ALG_BTREE;
238
222
    keydef[i].block_length= pos->block_size;
273
257
      {
274
258
        keydef[i].seg[j].null_bit= field->null_bit;
275
259
        keydef[i].seg[j].null_pos= (uint) (field->null_ptr-
276
 
                                           (unsigned char*) table_arg->getInsertRecord());
 
260
                                           (unsigned char*) table_arg->record[0]);
277
261
      }
278
262
      else
279
263
      {
292
276
  }
293
277
  if (table_arg->found_next_number_field)
294
278
    keydef[share->next_number_index].flag|= HA_AUTO_KEY;
295
 
  record= table_arg->getInsertRecord();
 
279
  record= table_arg->record[0];
296
280
  recpos= 0;
297
281
  recinfo_pos= recinfo;
298
282
  while (recpos < (uint) share->stored_rec_length)
299
283
  {
300
284
    Field **field, *found= 0;
301
 
    minpos= share->getRecordLength();
 
285
    minpos= share->reclength;
302
286
    length= 0;
303
287
 
304
 
    for (field= table_arg->getFields(); *field; field++)
 
288
    for (field= table_arg->field; *field; field++)
305
289
    {
306
290
      if ((fieldpos= (*field)->offset(record)) >= recpos &&
307
291
          fieldpos <= minpos)
341
325
    {
342
326
      recinfo_pos->null_bit= found->null_bit;
343
327
      recinfo_pos->null_pos= (uint) (found->null_ptr -
344
 
                                     (unsigned char*) table_arg->getInsertRecord());
 
328
                                     (unsigned char*) table_arg->record[0]);
345
329
    }
346
330
    else
347
331
    {
479
463
volatile int *killed_ptr(MI_CHECK *param)
480
464
{
481
465
  /* In theory Unsafe conversion, but should be ok for now */
482
 
  return (int*) (((Session *)(param->session))->getKilledPtr());
 
466
  return (int*) &(((Session *)(param->session))->killed);
483
467
}
484
468
 
485
469
void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
529
513
                        const char *sfile, uint32_t sline)
530
514
{
531
515
  Session *cur_session;
 
516
  pthread_mutex_lock(&file->s->intern_lock);
532
517
  if ((cur_session= file->in_use))
533
518
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got an error from thread_id=%"PRIu64", %s:%d"),
534
519
                    cur_session->thread_id,
543
528
    errmsg_printf(ERRMSG_LVL_ERROR, "%s", _("Unknown thread accessing table"));
544
529
    ++it;
545
530
  }
 
531
  pthread_mutex_unlock(&file->s->intern_lock);
546
532
}
547
533
 
548
534
ha_myisam::ha_myisam(plugin::StorageEngine &engine_arg,
549
 
                     Table &table_arg)
 
535
                     TableShare &table_arg)
550
536
  : Cursor(engine_arg, table_arg),
551
537
  file(0),
552
538
  can_enable_indexes(true),
567
553
}
568
554
 
569
555
/* Name is here without an extension */
570
 
int ha_myisam::doOpen(const drizzled::TableIdentifier &identifier, int mode, uint32_t test_if_locked)
 
556
int ha_myisam::open(const char *name, int mode, uint32_t test_if_locked)
571
557
{
572
558
  MI_KEYDEF *keyinfo;
573
559
  MI_COLUMNDEF *recinfo= 0;
589
575
    open of a table that is in use by other threads already (if the
590
576
    MyISAM share exists already).
591
577
  */
592
 
  if (!(file= mi_open(identifier, mode, test_if_locked)))
 
578
  if (!(file=mi_open(name, mode, test_if_locked)))
593
579
    return (errno ? errno : -1);
594
580
 
595
 
  if (!getTable()->getShare()->getType()) /* No need to perform a check for tmp table */
 
581
  if (!table->s->tmp_table) /* No need to perform a check for tmp table */
596
582
  {
597
 
    if ((errno= table2myisam(getTable(), &keyinfo, &recinfo, &recs)))
 
583
    if ((errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
598
584
    {
599
585
      goto err;
600
586
    }
601
 
    if (check_definition(keyinfo, recinfo, getTable()->getShare()->sizeKeys(), recs,
 
587
    if (check_definition(keyinfo, recinfo, table->s->keys, recs,
602
588
                         file->s->keyinfo, file->s->rec,
603
589
                         file->s->base.keys, file->s->base.fields, true))
604
590
    {
607
593
    }
608
594
  }
609
595
 
610
 
  assert(test_if_locked);
611
596
  if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
612
597
    mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
613
598
 
614
599
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
615
600
  if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
616
601
    mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
617
 
  if (!getTable()->getShare()->db_record_offset)
 
602
  if (!table->s->db_record_offset)
618
603
    is_ordered= false;
619
604
 
620
605
 
621
606
  keys_with_parts.reset();
622
 
  for (i= 0; i < getTable()->getShare()->sizeKeys(); i++)
 
607
  for (i= 0; i < table->s->keys; i++)
623
608
  {
624
 
    getTable()->key_info[i].block_size= file->s->keyinfo[i].block_length;
 
609
    table->key_info[i].block_size= file->s->keyinfo[i].block_length;
625
610
 
626
 
    KeyPartInfo *kp= getTable()->key_info[i].key_part;
627
 
    KeyPartInfo *kp_end= kp + getTable()->key_info[i].key_parts;
 
611
    KEY_PART_INFO *kp= table->key_info[i].key_part;
 
612
    KEY_PART_INFO *kp_end= kp + table->key_info[i].key_parts;
628
613
    for (; kp != kp_end; kp++)
629
614
    {
630
615
      if (!kp->field->part_of_key.test(i))
657
642
 
658
643
int ha_myisam::doInsertRecord(unsigned char *buf)
659
644
{
 
645
  ha_statistic_increment(&system_status_var::ha_write_count);
 
646
 
660
647
  /*
661
648
    If we have an auto_increment column and we are writing a changed row
662
649
    or a new row, then update the auto_increment value in the record.
663
650
  */
664
 
  if (getTable()->next_number_field && buf == getTable()->getInsertRecord())
 
651
  if (table->next_number_field && buf == table->record[0])
665
652
  {
666
653
    int error;
667
654
    if ((error= update_auto_increment()))
693
680
  {
694
681
    errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' failed. "
695
682
                          "Please try REPAIR EXTENDED or myisamchk",
696
 
                          getTable()->getShare()->getPath());
 
683
                          table->s->path.str);
697
684
    return(HA_ADMIN_FAILED);
698
685
  }
699
686
 
700
 
  param.db_name=    getTable()->getShare()->getSchemaName();
701
 
  param.table_name= getTable()->getAlias();
 
687
  param.db_name=    table->s->getSchemaName();
 
688
  param.table_name= table->alias;
702
689
  param.tmpfile_createflag = O_RDWR | O_TRUNC;
703
690
  param.using_global_keycache = 1;
704
691
  param.session= session;
705
692
  param.out_flag= 0;
706
 
  param.sort_buffer_length= static_cast<size_t>(sort_buffer_size);
 
693
  param.sort_buffer_length= (size_t)sort_buffer_size;
707
694
  strcpy(fixed_name,file->filename);
708
695
 
709
696
  // Don't lock tables if we have used LOCK Table
710
 
  if (mi_lock_database(file, getTable()->getShare()->getType() ? F_EXTRA_LCK : F_WRLCK))
 
697
  if (mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
711
698
  {
712
699
    mi_check_print_error(&param,ER(ER_CANT_LOCK),errno);
713
700
    return(HA_ADMIN_FAILED);
728
715
      local_testflag|= T_STATISTICS;
729
716
      param.testflag|= T_STATISTICS;            // We get this for free
730
717
      statistics_done=1;
 
718
      if (repair_threads > 1)
 
719
      {
 
720
        char buf[40];
 
721
        /* TODO: respect myisam_repair_threads variable */
 
722
        snprintf(buf, 40, "Repair with %d threads", internal::my_count_bits(key_map));
 
723
        session->set_proc_info(buf);
 
724
        error = mi_repair_parallel(&param, file, fixed_name,
 
725
            param.testflag & T_QUICK);
 
726
        session->set_proc_info("Repair done"); // to reset proc_info, as
 
727
                                      // it was pointing to local buffer
 
728
      }
 
729
      else
731
730
      {
732
731
        session->set_proc_info("Repair by sorting");
733
732
        error = mi_repair_by_sort(&param, file, fixed_name,
904
903
  }
905
904
  else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
906
905
  {
907
 
    Session *session= getTable()->in_use;
908
 
    boost::scoped_ptr<MI_CHECK> param_ap(new MI_CHECK);
909
 
    MI_CHECK &param= *param_ap.get();
 
906
    Session *session=current_session;
 
907
    MI_CHECK param;
910
908
    const char *save_proc_info= session->get_proc_info();
911
909
    session->set_proc_info("Creating index");
912
910
    myisamchk_init(&param);
914
912
    param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
915
913
                     T_CREATE_MISSING_KEYS);
916
914
    param.myf_rw&= ~MY_WAIT_IF_FULL;
917
 
    param.sort_buffer_length=  static_cast<size_t>(sort_buffer_size);
 
915
    param.sort_buffer_length=  (size_t)sort_buffer_size;
918
916
    param.stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
919
917
    if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
920
918
    {
981
979
 
982
980
void ha_myisam::start_bulk_insert(ha_rows rows)
983
981
{
984
 
  Session *session= getTable()->in_use;
 
982
  Session *session= current_session;
985
983
  ulong size= session->variables.read_buff_size;
986
984
 
987
985
  /* don't enable row cache if too few rows */
1035
1033
 
1036
1034
int ha_myisam::doUpdateRecord(const unsigned char *old_data, unsigned char *new_data)
1037
1035
{
 
1036
  ha_statistic_increment(&system_status_var::ha_update_count);
 
1037
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
 
1038
    table->timestamp_field->set_time();
1038
1039
  return mi_update(file,old_data,new_data);
1039
1040
}
1040
1041
 
1041
1042
int ha_myisam::doDeleteRecord(const unsigned char *buf)
1042
1043
{
 
1044
  ha_statistic_increment(&system_status_var::ha_delete_count);
1043
1045
  return mi_delete(file,buf);
1044
1046
}
1045
1047
 
1046
1048
 
1047
 
int ha_myisam::doStartIndexScan(uint32_t idx, bool )
 
1049
int ha_myisam::index_init(uint32_t idx, bool )
1048
1050
{
1049
1051
  active_index=idx;
1050
1052
  //in_range_read= false;
1052
1054
}
1053
1055
 
1054
1056
 
1055
 
int ha_myisam::doEndIndexScan()
 
1057
int ha_myisam::index_end()
1056
1058
{
1057
1059
  active_index=MAX_KEY;
1058
1060
  return 0;
1066
1068
  assert(inited==INDEX);
1067
1069
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1068
1070
  int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
1069
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1071
  table->status=error ? STATUS_NOT_FOUND: 0;
1070
1072
  return error;
1071
1073
}
1072
1074
 
1076
1078
{
1077
1079
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1078
1080
  int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
1079
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1081
  table->status=error ? STATUS_NOT_FOUND: 0;
1080
1082
  return error;
1081
1083
}
1082
1084
 
1087
1089
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1088
1090
  int error=mi_rkey(file, buf, active_index, key, keypart_map,
1089
1091
                    HA_READ_PREFIX_LAST);
1090
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1092
  table->status=error ? STATUS_NOT_FOUND: 0;
1091
1093
  return(error);
1092
1094
}
1093
1095
 
1096
1098
  assert(inited==INDEX);
1097
1099
  ha_statistic_increment(&system_status_var::ha_read_next_count);
1098
1100
  int error=mi_rnext(file,buf,active_index);
1099
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1101
  table->status=error ? STATUS_NOT_FOUND: 0;
1100
1102
  return error;
1101
1103
}
1102
1104
 
1105
1107
  assert(inited==INDEX);
1106
1108
  ha_statistic_increment(&system_status_var::ha_read_prev_count);
1107
1109
  int error=mi_rprev(file,buf, active_index);
1108
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1110
  table->status=error ? STATUS_NOT_FOUND: 0;
1109
1111
  return error;
1110
1112
}
1111
1113
 
1114
1116
  assert(inited==INDEX);
1115
1117
  ha_statistic_increment(&system_status_var::ha_read_first_count);
1116
1118
  int error=mi_rfirst(file, buf, active_index);
1117
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1119
  table->status=error ? STATUS_NOT_FOUND: 0;
1118
1120
  return error;
1119
1121
}
1120
1122
 
1123
1125
  assert(inited==INDEX);
1124
1126
  ha_statistic_increment(&system_status_var::ha_read_last_count);
1125
1127
  int error=mi_rlast(file, buf, active_index);
1126
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1128
  table->status=error ? STATUS_NOT_FOUND: 0;
1127
1129
  return error;
1128
1130
}
1129
1131
 
1138
1140
  {
1139
1141
    error= mi_rnext_same(file,buf);
1140
1142
  } while (error == HA_ERR_RECORD_DELETED);
1141
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1143
  table->status=error ? STATUS_NOT_FOUND: 0;
1142
1144
  return error;
1143
1145
}
1144
1146
 
1168
1170
}
1169
1171
 
1170
1172
 
1171
 
int ha_myisam::doStartTableScan(bool scan)
 
1173
int ha_myisam::rnd_init(bool scan)
1172
1174
{
1173
1175
  if (scan)
1174
1176
    return mi_scan_init(file);
1179
1181
{
1180
1182
  ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
1181
1183
  int error=mi_scan(file, buf);
1182
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1184
  table->status=error ? STATUS_NOT_FOUND: 0;
1183
1185
  return error;
1184
1186
}
1185
1187
 
 
1188
int ha_myisam::restart_rnd_next(unsigned char *buf, unsigned char *pos)
 
1189
{
 
1190
  return rnd_pos(buf,pos);
 
1191
}
 
1192
 
1186
1193
int ha_myisam::rnd_pos(unsigned char *buf, unsigned char *pos)
1187
1194
{
1188
1195
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
1189
1196
  int error=mi_rrnd(file, buf, internal::my_get_ptr(pos,ref_length));
1190
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1197
  table->status=error ? STATUS_NOT_FOUND: 0;
1191
1198
  return error;
1192
1199
}
1193
1200
 
1216
1223
  }
1217
1224
  if (flag & HA_STATUS_CONST)
1218
1225
  {
1219
 
    TableShare *share= getTable()->getMutableShare();
 
1226
    TableShare *share= table->s;
1220
1227
    stats.max_data_file_length=  misam_info.max_data_file_length;
1221
1228
    stats.max_index_file_length= misam_info.max_index_file_length;
1222
1229
    stats.create_time= misam_info.create_time;
1224
1231
    share->db_options_in_use= misam_info.options;
1225
1232
    stats.block_size= myisam_key_cache_block_size;        /* record block size */
1226
1233
 
1227
 
    set_prefix(share->keys_in_use, share->sizeKeys());
 
1234
    /* Update share */
 
1235
    if (share->tmp_table == message::Table::STANDARD)
 
1236
      pthread_mutex_lock(&share->mutex);
 
1237
    set_prefix(share->keys_in_use, share->keys);
1228
1238
    /*
1229
1239
     * Due to bug 394932 (32-bit solaris build failure), we need
1230
1240
     * to convert the uint64_t key_map member of the misam_info
1273
1283
    share->keys_for_keyread&= share->keys_in_use;
1274
1284
    share->db_record_offset= misam_info.record_offset;
1275
1285
    if (share->key_parts)
1276
 
      memcpy(getTable()->key_info[0].rec_per_key,
 
1286
      memcpy(table->key_info[0].rec_per_key,
1277
1287
             misam_info.rec_per_key,
1278
 
             sizeof(getTable()->key_info[0].rec_per_key)*share->key_parts);
1279
 
    assert(share->getType() != message::Table::STANDARD);
 
1288
             sizeof(table->key_info[0].rec_per_key)*share->key_parts);
 
1289
    if (share->tmp_table == message::Table::STANDARD)
 
1290
      pthread_mutex_unlock(&share->mutex);
1280
1291
 
1281
1292
   /*
1282
1293
     Set data_file_name and index_file_name to point at the symlink value
1329
1340
}
1330
1341
 
1331
1342
int MyisamEngine::doDropTable(Session &session,
1332
 
                              const TableIdentifier &identifier)
 
1343
                              drizzled::TableIdentifier &identifier)
1333
1344
{
1334
 
  session.getMessageCache().removeTableMessage(identifier);
 
1345
  session.removeTableMessage(identifier);
1335
1346
 
1336
1347
  return mi_delete_table(identifier.getPath().c_str());
1337
1348
}
1340
1351
int ha_myisam::external_lock(Session *session, int lock_type)
1341
1352
{
1342
1353
  file->in_use= session;
1343
 
  return mi_lock_database(file, !getTable()->getShare()->getType() ?
 
1354
  return mi_lock_database(file, !table->s->tmp_table ?
1344
1355
                          lock_type : ((lock_type == F_UNLCK) ?
1345
1356
                                       F_UNLCK : F_EXTRA_LCK));
1346
1357
}
1347
1358
 
1348
1359
int MyisamEngine::doCreateTable(Session &session,
1349
1360
                                Table& table_arg,
1350
 
                                const TableIdentifier &identifier,
 
1361
                                drizzled::TableIdentifier &identifier,
1351
1362
                                message::Table& create_proto)
1352
1363
{
1353
1364
  int error;
1356
1367
  MI_KEYDEF *keydef;
1357
1368
  MI_COLUMNDEF *recinfo;
1358
1369
  MI_CREATE_INFO create_info;
1359
 
  TableShare *share= table_arg.getMutableShare();
 
1370
  TableShare *share= table_arg.s;
1360
1371
  uint32_t options= share->db_options_in_use;
1361
1372
  if ((error= table2myisam(&table_arg, &keydef, &recinfo, &create_records)))
1362
1373
    return(error);
1381
1392
  /* TODO: Check that the following internal::fn_format is really needed */
1382
1393
  error= mi_create(internal::fn_format(buff, identifier.getPath().c_str(), "", "",
1383
1394
                                       MY_UNPACK_FILENAME|MY_APPEND_EXT),
1384
 
                   share->sizeKeys(), keydef,
 
1395
                   share->keys, keydef,
1385
1396
                   create_records, recinfo,
1386
1397
                   0, (MI_UNIQUEDEF*) 0,
1387
1398
                   &create_info, create_flags);
1388
1399
  free((unsigned char*) recinfo);
1389
1400
 
1390
 
  session.getMessageCache().storeTableMessage(identifier, create_proto);
 
1401
  session.storeTableMessage(identifier, create_proto);
1391
1402
 
1392
1403
  return error;
1393
1404
}
1394
1405
 
1395
1406
 
1396
 
int MyisamEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
 
1407
int MyisamEngine::doRenameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
1397
1408
{
1398
 
  session.getMessageCache().renameTableMessage(from, to);
 
1409
  session.renameTableMessage(from, to);
1399
1410
 
1400
1411
  return mi_rename(from.getPath().c_str(), to.getPath().c_str());
1401
1412
}
1411
1422
  int error;
1412
1423
  unsigned char key[MI_MAX_KEY_LENGTH];
1413
1424
 
1414
 
  if (!getTable()->getShare()->next_number_key_offset)
 
1425
  if (!table->s->next_number_key_offset)
1415
1426
  {                                             // Autoincrement at key-start
1416
1427
    ha_myisam::info(HA_STATUS_AUTO);
1417
1428
    *first_value= stats.auto_increment_value;
1421
1432
  }
1422
1433
 
1423
1434
  /* it's safe to call the following if bulk_insert isn't on */
1424
 
  mi_flush_bulk_insert(file, getTable()->getShare()->next_number_index);
 
1435
  mi_flush_bulk_insert(file, table->s->next_number_index);
1425
1436
 
1426
1437
  (void) extra(HA_EXTRA_KEYREAD);
1427
 
  key_copy(key, getTable()->getInsertRecord(),
1428
 
           &getTable()->key_info[getTable()->getShare()->next_number_index],
1429
 
           getTable()->getShare()->next_number_key_offset);
1430
 
  error= mi_rkey(file, getTable()->getUpdateRecord(), (int) getTable()->getShare()->next_number_index,
1431
 
                 key, make_prev_keypart_map(getTable()->getShare()->next_number_keypart),
 
1438
  key_copy(key, table->record[0],
 
1439
           table->key_info + table->s->next_number_index,
 
1440
           table->s->next_number_key_offset);
 
1441
  error= mi_rkey(file, table->record[1], (int) table->s->next_number_index,
 
1442
                 key, make_prev_keypart_map(table->s->next_number_keypart),
1432
1443
                 HA_READ_PREFIX_LAST);
1433
1444
  if (error)
1434
1445
    nr= 1;
1435
1446
  else
1436
1447
  {
1437
 
    /* Get data from getUpdateRecord() */
1438
 
    nr= ((uint64_t) getTable()->next_number_field->
1439
 
         val_int_offset(getTable()->getShare()->rec_buff_length)+1);
 
1448
    /* Get data from record[1] */
 
1449
    nr= ((uint64_t) table->next_number_field->
 
1450
         val_int_offset(table->s->rec_buff_length)+1);
1440
1451
  }
1441
1452
  extra(HA_EXTRA_NO_KEYREAD);
1442
1453
  *first_value= nr;
1487
1498
  return (uint)file->state->checksum;
1488
1499
}
1489
1500
 
1490
 
static int myisam_init(module::Context &context)
1491
 
1492
 
  context.add(new MyisamEngine(engine_name));
1493
 
  context.registerVariable(new sys_var_constrained_value<size_t>("sort-buffer-size",
1494
 
                                                                 sort_buffer_size));
1495
 
  context.registerVariable(new sys_var_uint64_t_ptr("max_sort_file_size",
1496
 
                                                    &max_sort_file_size,
1497
 
                                                    context.getOptions()["max-sort-file-size"].as<uint64_t>()));
 
1501
static MyisamEngine *engine= NULL;
 
1502
 
 
1503
static int myisam_init(plugin::Context &context)
 
1504
{
 
1505
  engine= new MyisamEngine(engine_name);
 
1506
  context.add(engine);
 
1507
 
 
1508
  /* call ha_init_key_cache() on all key caches to init them */
 
1509
  int error= init_key_cache(dflt_key_cache,
 
1510
                            myisam_key_cache_block_size,
 
1511
                            myisam_key_cache_size,
 
1512
                            myisam_key_cache_division_limit, 
 
1513
                            myisam_key_cache_age_threshold);
 
1514
 
 
1515
  if (error == 0)
 
1516
    exit(1); /* Memory Allocation Failure */
1498
1517
 
1499
1518
  return 0;
1500
1519
}
1501
1520
 
1502
1521
 
1503
 
static void init_options(drizzled::module::option_context &context)
1504
 
{
1505
 
  context("max-sort-file-size",
1506
 
          po::value<uint64_t>(&max_sort_file_size)->default_value(INT32_MAX),
1507
 
          N_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."));
1508
 
  context("sort-buffer-size",
1509
 
          po::value<sort_buffer_constraint>(&sort_buffer_size)->default_value(8192*1024),
1510
 
          N_("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."));
1511
 
}
 
1522
static void sys_var_key_cache_size_update(Session *session, drizzle_sys_var *var, void *, const void *save)
 
1523
{
 
1524
  uint32_t tmp= *static_cast<const uint32_t *>(save);
 
1525
  bool error= 0;
 
1526
 
 
1527
        struct option option_limits;
 
1528
  plugin_opt_set_limits(&option_limits, var);
 
1529
        option_limits.name= "myisam_key_cache_size";
 
1530
 
 
1531
  if (dflt_key_cache->in_init)
 
1532
    return;
 
1533
 
 
1534
  myisam_key_cache_size= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
 
1535
 
 
1536
  /* If key cache didn't existed initialize it, else resize it */
 
1537
  dflt_key_cache->in_init= 1;
 
1538
 
 
1539
  error= ! resize_key_cache(dflt_key_cache,
 
1540
                                                                                                                myisam_key_cache_block_size,
 
1541
                            myisam_key_cache_size,
 
1542
                            myisam_key_cache_division_limit,
 
1543
                                                                                                          myisam_key_cache_age_threshold);
 
1544
  dflt_key_cache->in_init= 0;
 
1545
}
 
1546
 
 
1547
static void sys_var_key_cache_block_size_update(Session *session, drizzle_sys_var *var, void *, const void *save)
 
1548
{
 
1549
  uint32_t tmp= *static_cast<const uint32_t *>(save);
 
1550
  bool error= 0;
 
1551
 
 
1552
        struct option option_limits;
 
1553
  plugin_opt_set_limits(&option_limits, var);
 
1554
        option_limits.name= "myisam_key_cache_block_size";
 
1555
 
 
1556
  if (dflt_key_cache->in_init)
 
1557
    return;
 
1558
 
 
1559
  myisam_key_cache_block_size= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
 
1560
 
 
1561
  dflt_key_cache->in_init= 1;
 
1562
 
 
1563
  error= ! resize_key_cache(dflt_key_cache,
 
1564
                                                                                                                myisam_key_cache_block_size,
 
1565
                            myisam_key_cache_size,
 
1566
                            myisam_key_cache_division_limit,
 
1567
                                                                                                          myisam_key_cache_age_threshold);
 
1568
 
 
1569
  dflt_key_cache->in_init= 0;
 
1570
}
 
1571
 
 
1572
static void sys_var_key_cache_division_limit_update(Session *session, drizzle_sys_var *var, void *, const void *save)
 
1573
{
 
1574
  uint32_t tmp= *static_cast<const uint32_t *>(save);
 
1575
  bool error= 0;
 
1576
 
 
1577
        struct option option_limits;
 
1578
  plugin_opt_set_limits(&option_limits, var);
 
1579
        option_limits.name= "myisam_key_cache_division_limit";
 
1580
 
 
1581
  if (dflt_key_cache->in_init)
 
1582
    return;
 
1583
 
 
1584
  myisam_key_cache_division_limit= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
 
1585
 
 
1586
  dflt_key_cache->in_init= 1;
 
1587
 
 
1588
  error= ! resize_key_cache(dflt_key_cache,
 
1589
                                                                                                                myisam_key_cache_block_size,
 
1590
                            myisam_key_cache_size,
 
1591
                            myisam_key_cache_division_limit,
 
1592
                                                                                                          myisam_key_cache_age_threshold);
 
1593
 
 
1594
  dflt_key_cache->in_init= 0;
 
1595
}
 
1596
 
 
1597
static void sys_var_key_cache_age_threshold_update(Session *session, drizzle_sys_var *var, void *, const void *save)
 
1598
{
 
1599
  uint32_t tmp= *static_cast<const uint32_t *>(save);
 
1600
  bool error= 0;
 
1601
 
 
1602
        struct option option_limits;
 
1603
  plugin_opt_set_limits(&option_limits, var);
 
1604
        option_limits.name= "myisam_key_cache_age_threshold";
 
1605
 
 
1606
  if (dflt_key_cache->in_init)
 
1607
    return;
 
1608
 
 
1609
  myisam_key_cache_age_threshold= static_cast<uint32_t>(fix_unsigned(session, static_cast<uint64_t>(tmp), &option_limits));
 
1610
 
 
1611
  dflt_key_cache->in_init= 1;
 
1612
 
 
1613
  error= ! resize_key_cache(dflt_key_cache,
 
1614
                                                                                                                myisam_key_cache_block_size,
 
1615
                            myisam_key_cache_size,
 
1616
                            myisam_key_cache_division_limit,
 
1617
                                                                                                          myisam_key_cache_age_threshold);
 
1618
 
 
1619
  dflt_key_cache->in_init= 0;
 
1620
}
 
1621
 
 
1622
static DRIZZLE_SYSVAR_UINT(key_cache_block_size,
 
1623
                            myisam_key_cache_block_size,
 
1624
                            PLUGIN_VAR_RQCMDARG,
 
1625
                            N_("Block size to be used for MyISAM index pages."),
 
1626
                            NULL,
 
1627
                            sys_var_key_cache_block_size_update,
 
1628
                            KEY_CACHE_BLOCK_SIZE,
 
1629
                            512, 
 
1630
                            16 * 1024,
 
1631
                            0);
 
1632
 
 
1633
static DRIZZLE_SYSVAR_UINT(key_cache_age_threshold, myisam_key_cache_age_threshold,
 
1634
                            PLUGIN_VAR_RQCMDARG,
 
1635
                            N_("This characterizes the number of hits a hot block has to be untouched "
 
1636
                            "until it is considered aged enough to be downgraded to a warm block. "
 
1637
                            "This specifies the percentage ratio of that number of hits to the "
 
1638
                            "total number of blocks in key cache"),
 
1639
                            NULL,
 
1640
                            sys_var_key_cache_age_threshold_update,
 
1641
                            300,
 
1642
                            100, 
 
1643
                            UINT32_MAX,
 
1644
                            0);
 
1645
 
 
1646
static DRIZZLE_SYSVAR_UINT(key_cache_division_limit, myisam_key_cache_division_limit,
 
1647
                            PLUGIN_VAR_RQCMDARG,
 
1648
                            N_("The minimum percentage of warm blocks in key cache"),
 
1649
                            NULL,
 
1650
                            sys_var_key_cache_division_limit_update,
 
1651
                            100,
 
1652
                            1, 
 
1653
                            100,
 
1654
                            0);
 
1655
 
 
1656
static DRIZZLE_SYSVAR_UINT(key_cache_size,
 
1657
                            myisam_key_cache_size,
 
1658
                            PLUGIN_VAR_RQCMDARG,
 
1659
                            N_("The size of the buffer used for index blocks for MyISAM tables. "
 
1660
                            "Increase this to get better index handling (for all reads and multiple "
 
1661
                            "writes) to as much as you can afford;"),
 
1662
                            NULL,
 
1663
                            sys_var_key_cache_size_update,
 
1664
                            KEY_CACHE_SIZE,
 
1665
                            1 * 1024 * 1024, 
 
1666
                            UINT32_MAX,
 
1667
                            IO_SIZE);
 
1668
 
 
1669
static DRIZZLE_SYSVAR_UINT(repair_threads, repair_threads,
 
1670
                            PLUGIN_VAR_RQCMDARG,
 
1671
                            N_("Number of threads to use when repairing MyISAM tables. The value of "
 
1672
                            "1 disables parallel repair."),
 
1673
                            NULL, NULL, 1, 1, UINT32_MAX, 0);
 
1674
 
 
1675
static DRIZZLE_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size,
 
1676
                                PLUGIN_VAR_RQCMDARG,
 
1677
                                N_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."),
 
1678
                                NULL, NULL, INT32_MAX, 0, UINT64_MAX, 0);
 
1679
 
 
1680
static DRIZZLE_SYSVAR_ULONGLONG(sort_buffer_size, sort_buffer_size,
 
1681
                                PLUGIN_VAR_RQCMDARG,
 
1682
                                N_("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."),
 
1683
                                NULL, NULL, 8192*1024, 1024, SIZE_MAX, 0);
 
1684
 
 
1685
extern uint32_t data_pointer_size;
 
1686
static DRIZZLE_SYSVAR_UINT(data_pointer_size, data_pointer_size,
 
1687
                            PLUGIN_VAR_RQCMDARG,
 
1688
                            N_("Default pointer size to be used for MyISAM tables."),
 
1689
                            NULL, NULL, 6, 2, 7, 0);
 
1690
 
 
1691
static drizzle_sys_var* sys_variables[]= {
 
1692
  DRIZZLE_SYSVAR(key_cache_block_size),
 
1693
  DRIZZLE_SYSVAR(key_cache_size),
 
1694
  DRIZZLE_SYSVAR(key_cache_division_limit),
 
1695
  DRIZZLE_SYSVAR(key_cache_age_threshold),
 
1696
  DRIZZLE_SYSVAR(repair_threads),
 
1697
  DRIZZLE_SYSVAR(max_sort_file_size),
 
1698
  DRIZZLE_SYSVAR(sort_buffer_size),
 
1699
  DRIZZLE_SYSVAR(data_pointer_size),
 
1700
  NULL
 
1701
};
1512
1702
 
1513
1703
 
1514
1704
DRIZZLE_DECLARE_PLUGIN
1515
1705
{
1516
1706
  DRIZZLE_VERSION_ID,
1517
1707
  "MyISAM",
1518
 
  "2.0",
 
1708
  "1.0",
1519
1709
  "MySQL AB",
1520
1710
  "Default engine as of MySQL 3.23 with great performance",
1521
1711
  PLUGIN_LICENSE_GPL,
1522
1712
  myisam_init, /* Plugin Init */
1523
 
  NULL,           /* system variables */
1524
 
  init_options                        /* config options                  */
 
1713
  sys_variables,           /* system variables */
 
1714
  NULL                        /* config options                  */
1525
1715
}
1526
1716
DRIZZLE_DECLARE_PLUGIN_END;