~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/ha_myisam.cc

  • Committer: Lee Bieber
  • Date: 2010-08-21 22:42:44 UTC
  • mto: (1727.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1728.
  • Revision ID: lbieber@kalebral-2.local-20100821224244-kh3gmsvi45dlbuu1
For the feature request (https://blueprints.launchpad.net/drizzle/+spec/limit-maximum-sort-size) 
that is requesting the ability to cap various buffers, we first tried setting the join buffer to 
1 to see how that would affect the test results and expose test results that need to 
sorted (by adding --sorted_result). 

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"
36
37
#include "drizzled/plugin/daemon.h"
37
38
 
38
39
#include <boost/algorithm/string.hpp>
39
 
#include <boost/scoped_ptr.hpp>
40
40
 
41
41
#include <string>
42
42
#include <sstream>
43
43
#include <map>
44
44
#include <algorithm>
45
 
#include <memory>
46
45
#include <boost/program_options.hpp>
47
46
#include <drizzled/module/option_map.h>
48
47
 
60
59
static uint32_t myisam_key_cache_division_limit;
61
60
static uint32_t myisam_key_cache_age_threshold;
62
61
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;
 
62
static uint64_t sort_buffer_size;
65
63
 
66
64
void st_mi_isam_share::setKeyCache()
67
65
{
106
104
    mi_panic(HA_PANIC_CLOSE);
107
105
  }
108
106
 
109
 
  virtual Cursor *create(Table &table)
 
107
  virtual Cursor *create(TableShare &table)
110
108
  {
111
109
    return new ha_myisam(*this, table);
112
110
  }
128
126
                           const TableIdentifier &identifier,
129
127
                           message::Table &table_message);
130
128
 
 
129
  /* Temp only engine, so do not return values. */
 
130
  void doGetTableNames(CachedDirectory &, const SchemaIdentifier &, set<string>&) { };
 
131
 
131
132
  uint32_t max_supported_keys()          const { return MI_MAX_KEY; }
132
133
  uint32_t max_supported_key_length()    const { return MI_MAX_KEY_LENGTH; }
133
134
  uint32_t max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; }
144
145
 
145
146
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
146
147
                             const drizzled::SchemaIdentifier &schema_identifier,
147
 
                             drizzled::TableIdentifier::vector &set_of_identifiers);
 
148
                             drizzled::TableIdentifiers &set_of_identifiers);
148
149
  bool validateCreateTableOption(const std::string &key, const std::string &state)
149
150
  {
150
151
    (void)state;
159
160
 
160
161
void MyisamEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
161
162
                                         const drizzled::SchemaIdentifier&,
162
 
                                         drizzled::TableIdentifier::vector&)
 
163
                                         drizzled::TableIdentifiers&)
163
164
{
164
165
}
165
166
 
166
167
bool MyisamEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
167
168
{
168
 
  return session.getMessageCache().doesTableMessageExist(identifier);
 
169
  return session.doesTableMessageExist(identifier);
169
170
}
170
171
 
171
172
int MyisamEngine::doGetTableDefinition(Session &session,
172
173
                                       const TableIdentifier &identifier,
173
174
                                       message::Table &table_message)
174
175
{
175
 
  if (session.getMessageCache().getTableMessage(identifier, table_message))
 
176
  if (session.getTableMessage(identifier, table_message))
176
177
    return EEXIST;
177
178
  return ENOENT;
178
179
}
479
480
volatile int *killed_ptr(MI_CHECK *param)
480
481
{
481
482
  /* In theory Unsafe conversion, but should be ok for now */
482
 
  return (int*) (((Session *)(param->session))->getKilledPtr());
 
483
  return (int*) &(((Session *)(param->session))->killed);
483
484
}
484
485
 
485
486
void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
546
547
}
547
548
 
548
549
ha_myisam::ha_myisam(plugin::StorageEngine &engine_arg,
549
 
                     Table &table_arg)
 
550
                     TableShare &table_arg)
550
551
  : Cursor(engine_arg, table_arg),
551
552
  file(0),
552
553
  can_enable_indexes(true),
567
568
}
568
569
 
569
570
/* Name is here without an extension */
570
 
int ha_myisam::doOpen(const drizzled::TableIdentifier &identifier, int mode, uint32_t test_if_locked)
 
571
int ha_myisam::open(const char *name, int mode, uint32_t test_if_locked)
571
572
{
572
573
  MI_KEYDEF *keyinfo;
573
574
  MI_COLUMNDEF *recinfo= 0;
589
590
    open of a table that is in use by other threads already (if the
590
591
    MyISAM share exists already).
591
592
  */
592
 
  if (!(file= mi_open(identifier, mode, test_if_locked)))
 
593
  if (!(file=mi_open(name, mode, test_if_locked)))
593
594
    return (errno ? errno : -1);
594
595
 
595
 
  if (!getTable()->getShare()->getType()) /* No need to perform a check for tmp table */
 
596
  if (!table->getShare()->getType()) /* No need to perform a check for tmp table */
596
597
  {
597
 
    if ((errno= table2myisam(getTable(), &keyinfo, &recinfo, &recs)))
 
598
    if ((errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
598
599
    {
599
600
      goto err;
600
601
    }
601
 
    if (check_definition(keyinfo, recinfo, getTable()->getShare()->sizeKeys(), recs,
 
602
    if (check_definition(keyinfo, recinfo, table->getShare()->sizeKeys(), recs,
602
603
                         file->s->keyinfo, file->s->rec,
603
604
                         file->s->base.keys, file->s->base.fields, true))
604
605
    {
614
615
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
615
616
  if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
616
617
    mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
617
 
  if (!getTable()->getShare()->db_record_offset)
 
618
  if (!table->getShare()->db_record_offset)
618
619
    is_ordered= false;
619
620
 
620
621
 
621
622
  keys_with_parts.reset();
622
 
  for (i= 0; i < getTable()->getShare()->sizeKeys(); i++)
 
623
  for (i= 0; i < table->getShare()->sizeKeys(); i++)
623
624
  {
624
 
    getTable()->key_info[i].block_size= file->s->keyinfo[i].block_length;
 
625
    table->key_info[i].block_size= file->s->keyinfo[i].block_length;
625
626
 
626
 
    KeyPartInfo *kp= getTable()->key_info[i].key_part;
627
 
    KeyPartInfo *kp_end= kp + getTable()->key_info[i].key_parts;
 
627
    KeyPartInfo *kp= table->key_info[i].key_part;
 
628
    KeyPartInfo *kp_end= kp + table->key_info[i].key_parts;
628
629
    for (; kp != kp_end; kp++)
629
630
    {
630
631
      if (!kp->field->part_of_key.test(i))
661
662
    If we have an auto_increment column and we are writing a changed row
662
663
    or a new row, then update the auto_increment value in the record.
663
664
  */
664
 
  if (getTable()->next_number_field && buf == getTable()->getInsertRecord())
 
665
  if (table->next_number_field && buf == table->getInsertRecord())
665
666
  {
666
667
    int error;
667
668
    if ((error= update_auto_increment()))
693
694
  {
694
695
    errmsg_printf(ERRMSG_LVL_INFO, "Retrying repair of: '%s' failed. "
695
696
                          "Please try REPAIR EXTENDED or myisamchk",
696
 
                          getTable()->getShare()->getPath());
 
697
                          table->getShare()->getPath());
697
698
    return(HA_ADMIN_FAILED);
698
699
  }
699
700
 
700
 
  param.db_name=    getTable()->getShare()->getSchemaName();
701
 
  param.table_name= getTable()->getAlias();
 
701
  param.db_name=    table->getShare()->getSchemaName();
 
702
  param.table_name= table->getAlias();
702
703
  param.tmpfile_createflag = O_RDWR | O_TRUNC;
703
704
  param.using_global_keycache = 1;
704
705
  param.session= session;
705
706
  param.out_flag= 0;
706
 
  param.sort_buffer_length= static_cast<size_t>(sort_buffer_size);
 
707
  param.sort_buffer_length= (size_t)sort_buffer_size;
707
708
  strcpy(fixed_name,file->filename);
708
709
 
709
710
  // Don't lock tables if we have used LOCK Table
710
 
  if (mi_lock_database(file, getTable()->getShare()->getType() ? F_EXTRA_LCK : F_WRLCK))
 
711
  if (mi_lock_database(file, table->getShare()->getType() ? F_EXTRA_LCK : F_WRLCK))
711
712
  {
712
713
    mi_check_print_error(&param,ER(ER_CANT_LOCK),errno);
713
714
    return(HA_ADMIN_FAILED);
904
905
  }
905
906
  else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
906
907
  {
907
 
    Session *session= getTable()->in_use;
908
 
    boost::scoped_ptr<MI_CHECK> param_ap(new MI_CHECK);
909
 
    MI_CHECK &param= *param_ap.get();
 
908
    Session *session= table->in_use;
 
909
    MI_CHECK param;
910
910
    const char *save_proc_info= session->get_proc_info();
911
911
    session->set_proc_info("Creating index");
912
912
    myisamchk_init(&param);
914
914
    param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
915
915
                     T_CREATE_MISSING_KEYS);
916
916
    param.myf_rw&= ~MY_WAIT_IF_FULL;
917
 
    param.sort_buffer_length=  static_cast<size_t>(sort_buffer_size);
 
917
    param.sort_buffer_length=  (size_t)sort_buffer_size;
918
918
    param.stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
919
919
    if ((error= (repair(session,param,0) != HA_ADMIN_OK)) && param.retry_repair)
920
920
    {
981
981
 
982
982
void ha_myisam::start_bulk_insert(ha_rows rows)
983
983
{
984
 
  Session *session= getTable()->in_use;
 
984
  Session *session= table->in_use;
985
985
  ulong size= session->variables.read_buff_size;
986
986
 
987
987
  /* don't enable row cache if too few rows */
1066
1066
  assert(inited==INDEX);
1067
1067
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1068
1068
  int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
1069
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1069
  table->status=error ? STATUS_NOT_FOUND: 0;
1070
1070
  return error;
1071
1071
}
1072
1072
 
1076
1076
{
1077
1077
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1078
1078
  int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
1079
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1079
  table->status=error ? STATUS_NOT_FOUND: 0;
1080
1080
  return error;
1081
1081
}
1082
1082
 
1087
1087
  ha_statistic_increment(&system_status_var::ha_read_key_count);
1088
1088
  int error=mi_rkey(file, buf, active_index, key, keypart_map,
1089
1089
                    HA_READ_PREFIX_LAST);
1090
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1090
  table->status=error ? STATUS_NOT_FOUND: 0;
1091
1091
  return(error);
1092
1092
}
1093
1093
 
1096
1096
  assert(inited==INDEX);
1097
1097
  ha_statistic_increment(&system_status_var::ha_read_next_count);
1098
1098
  int error=mi_rnext(file,buf,active_index);
1099
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1099
  table->status=error ? STATUS_NOT_FOUND: 0;
1100
1100
  return error;
1101
1101
}
1102
1102
 
1105
1105
  assert(inited==INDEX);
1106
1106
  ha_statistic_increment(&system_status_var::ha_read_prev_count);
1107
1107
  int error=mi_rprev(file,buf, active_index);
1108
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1108
  table->status=error ? STATUS_NOT_FOUND: 0;
1109
1109
  return error;
1110
1110
}
1111
1111
 
1114
1114
  assert(inited==INDEX);
1115
1115
  ha_statistic_increment(&system_status_var::ha_read_first_count);
1116
1116
  int error=mi_rfirst(file, buf, active_index);
1117
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1117
  table->status=error ? STATUS_NOT_FOUND: 0;
1118
1118
  return error;
1119
1119
}
1120
1120
 
1123
1123
  assert(inited==INDEX);
1124
1124
  ha_statistic_increment(&system_status_var::ha_read_last_count);
1125
1125
  int error=mi_rlast(file, buf, active_index);
1126
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1126
  table->status=error ? STATUS_NOT_FOUND: 0;
1127
1127
  return error;
1128
1128
}
1129
1129
 
1138
1138
  {
1139
1139
    error= mi_rnext_same(file,buf);
1140
1140
  } while (error == HA_ERR_RECORD_DELETED);
1141
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1141
  table->status=error ? STATUS_NOT_FOUND: 0;
1142
1142
  return error;
1143
1143
}
1144
1144
 
1179
1179
{
1180
1180
  ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
1181
1181
  int error=mi_scan(file, buf);
1182
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1182
  table->status=error ? STATUS_NOT_FOUND: 0;
1183
1183
  return error;
1184
1184
}
1185
1185
 
1187
1187
{
1188
1188
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
1189
1189
  int error=mi_rrnd(file, buf, internal::my_get_ptr(pos,ref_length));
1190
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
1190
  table->status=error ? STATUS_NOT_FOUND: 0;
1191
1191
  return error;
1192
1192
}
1193
1193
 
1216
1216
  }
1217
1217
  if (flag & HA_STATUS_CONST)
1218
1218
  {
1219
 
    TableShare *share= getTable()->getMutableShare();
 
1219
    TableShare *share= table->getMutableShare();
1220
1220
    stats.max_data_file_length=  misam_info.max_data_file_length;
1221
1221
    stats.max_index_file_length= misam_info.max_index_file_length;
1222
1222
    stats.create_time= misam_info.create_time;
1273
1273
    share->keys_for_keyread&= share->keys_in_use;
1274
1274
    share->db_record_offset= misam_info.record_offset;
1275
1275
    if (share->key_parts)
1276
 
      memcpy(getTable()->key_info[0].rec_per_key,
 
1276
      memcpy(table->key_info[0].rec_per_key,
1277
1277
             misam_info.rec_per_key,
1278
 
             sizeof(getTable()->key_info[0].rec_per_key)*share->key_parts);
 
1278
             sizeof(table->key_info[0].rec_per_key)*share->key_parts);
1279
1279
    assert(share->getType() != message::Table::STANDARD);
1280
1280
 
1281
1281
   /*
1331
1331
int MyisamEngine::doDropTable(Session &session,
1332
1332
                              const TableIdentifier &identifier)
1333
1333
{
1334
 
  session.getMessageCache().removeTableMessage(identifier);
 
1334
  session.removeTableMessage(identifier);
1335
1335
 
1336
1336
  return mi_delete_table(identifier.getPath().c_str());
1337
1337
}
1340
1340
int ha_myisam::external_lock(Session *session, int lock_type)
1341
1341
{
1342
1342
  file->in_use= session;
1343
 
  return mi_lock_database(file, !getTable()->getShare()->getType() ?
 
1343
  return mi_lock_database(file, !table->getShare()->getType() ?
1344
1344
                          lock_type : ((lock_type == F_UNLCK) ?
1345
1345
                                       F_UNLCK : F_EXTRA_LCK));
1346
1346
}
1387
1387
                   &create_info, create_flags);
1388
1388
  free((unsigned char*) recinfo);
1389
1389
 
1390
 
  session.getMessageCache().storeTableMessage(identifier, create_proto);
 
1390
  session.storeTableMessage(identifier, create_proto);
1391
1391
 
1392
1392
  return error;
1393
1393
}
1395
1395
 
1396
1396
int MyisamEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
1397
1397
{
1398
 
  session.getMessageCache().renameTableMessage(from, to);
 
1398
  session.renameTableMessage(from, to);
1399
1399
 
1400
1400
  return mi_rename(from.getPath().c_str(), to.getPath().c_str());
1401
1401
}
1411
1411
  int error;
1412
1412
  unsigned char key[MI_MAX_KEY_LENGTH];
1413
1413
 
1414
 
  if (!getTable()->getShare()->next_number_key_offset)
 
1414
  if (!table->getShare()->next_number_key_offset)
1415
1415
  {                                             // Autoincrement at key-start
1416
1416
    ha_myisam::info(HA_STATUS_AUTO);
1417
1417
    *first_value= stats.auto_increment_value;
1421
1421
  }
1422
1422
 
1423
1423
  /* it's safe to call the following if bulk_insert isn't on */
1424
 
  mi_flush_bulk_insert(file, getTable()->getShare()->next_number_index);
 
1424
  mi_flush_bulk_insert(file, table->getShare()->next_number_index);
1425
1425
 
1426
1426
  (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),
 
1427
  key_copy(key, table->getInsertRecord(),
 
1428
           &table->key_info[table->getShare()->next_number_index],
 
1429
           table->getShare()->next_number_key_offset);
 
1430
  error= mi_rkey(file, table->getUpdateRecord(), (int) table->getShare()->next_number_index,
 
1431
                 key, make_prev_keypart_map(table->getShare()->next_number_keypart),
1432
1432
                 HA_READ_PREFIX_LAST);
1433
1433
  if (error)
1434
1434
    nr= 1;
1435
1435
  else
1436
1436
  {
1437
1437
    /* Get data from getUpdateRecord() */
1438
 
    nr= ((uint64_t) getTable()->next_number_field->
1439
 
         val_int_offset(getTable()->getShare()->rec_buff_length)+1);
 
1438
    nr= ((uint64_t) table->next_number_field->
 
1439
         val_int_offset(table->getShare()->rec_buff_length)+1);
1440
1440
  }
1441
1441
  extra(HA_EXTRA_NO_KEYREAD);
1442
1442
  *first_value= nr;
1487
1487
  return (uint)file->state->checksum;
1488
1488
}
1489
1489
 
 
1490
static MyisamEngine *engine= NULL;
 
1491
 
1490
1492
static int myisam_init(module::Context &context)
1491
1493
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>()));
 
1494
  const module::option_map &vm= context.getOptions();
 
1495
 
 
1496
  if (vm.count("max-sort-file-size"))
 
1497
  {
 
1498
    if (max_sort_file_size > UINT64_MAX)
 
1499
    {
 
1500
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-sort-file-size\n"));
 
1501
      exit(-1);
 
1502
    }
 
1503
  }
 
1504
 
 
1505
  if (vm.count("sort-buffer-size"))
 
1506
  {
 
1507
    if (sort_buffer_size < 1024 || sort_buffer_size > SIZE_MAX)
 
1508
    {
 
1509
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for sort-buffer-size\n"));
 
1510
      exit(-1);
 
1511
    }
 
1512
  }
 
1513
 
 
1514
  engine= new MyisamEngine(engine_name);
 
1515
  context.add(engine);
1498
1516
 
1499
1517
  return 0;
1500
1518
}
1501
1519
 
1502
1520
 
 
1521
static DRIZZLE_SYSVAR_ULONGLONG(max_sort_file_size, max_sort_file_size,
 
1522
                                PLUGIN_VAR_RQCMDARG,
 
1523
                                N_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."),
 
1524
                                NULL, NULL, INT32_MAX, 0, UINT64_MAX, 0);
 
1525
 
 
1526
static DRIZZLE_SYSVAR_ULONGLONG(sort_buffer_size, sort_buffer_size,
 
1527
                                PLUGIN_VAR_RQCMDARG,
 
1528
                                N_("The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE."),
 
1529
                                NULL, NULL, 8192*1024, 1024, SIZE_MAX, 0);
 
1530
 
1503
1531
static void init_options(drizzled::module::option_context &context)
1504
1532
{
1505
1533
  context("max-sort-file-size",
1506
1534
          po::value<uint64_t>(&max_sort_file_size)->default_value(INT32_MAX),
1507
1535
          N_("Don't use the fast sort index method to created index if the temporary file would get bigger than this."));
1508
1536
  context("sort-buffer-size",
1509
 
          po::value<sort_buffer_constraint>(&sort_buffer_size)->default_value(8192*1024),
 
1537
          po::value<uint64_t>(&sort_buffer_size)->default_value(8192*1024),
1510
1538
          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
1539
}
1512
1540
 
 
1541
static drizzle_sys_var* sys_variables[]= {
 
1542
  DRIZZLE_SYSVAR(max_sort_file_size),
 
1543
  DRIZZLE_SYSVAR(sort_buffer_size),
 
1544
  NULL
 
1545
};
 
1546
 
1513
1547
 
1514
1548
DRIZZLE_DECLARE_PLUGIN
1515
1549
{
1520
1554
  "Default engine as of MySQL 3.23 with great performance",
1521
1555
  PLUGIN_LICENSE_GPL,
1522
1556
  myisam_init, /* Plugin Init */
1523
 
  NULL,           /* system variables */
 
1557
  sys_variables,           /* system variables */
1524
1558
  init_options                        /* config options                  */
1525
1559
}
1526
1560
DRIZZLE_DECLARE_PLUGIN_END;