SlideShare una empresa de Scribd logo
1 de 19
Descargar para leer sin conexión
How Drizzle Approaches
Performance of the Server
                 April 22, 2008
Hi, I'm Jay.
I'm a Drizzle code
          monkey.

And you can too.
(A few of) our values

    Open and public discourse about performance



        And problems!
    −



    Focus on the interface, not the implementation



        No “One Right Way” of doing something
    −


        Innovation happens in the community
    −



    Say no to magic



        Let compiler developers do their job
    −



    Use standard, open source libraries



        Let the experts be experts
    −



    No new global contention points

Open and public discourse

    Benchmarks should be published online and



    peer-reviewed
    Methodology for benchmarks should be clear



    and well-documented on our wiki
    Discussions and debates about performance



    issues are actively encouraged on the list
    No shame



    No hiding



    No secrets

Storage Engines

 Authorization
                                      Logging
 Caching
                        Kernel
                     Core Services
Gearman                               Error Handling

                                       Parsing
                        Plugin API
                     (GPB Messages)

                            Replication
    Authentication

                 Module Ecosystem
Interface vs. Implementation

    Features are implemented in modules



    The kernel provides interfaces for modules to



    communicate with the kernel
    Recognize that one implementation of



    something may perform well for one problem
    domain, but poorly for others
        So, provide interfaces so different, targeted
    −


        implementations may be built to address differences
        in application domains
Interfaces

    The community should play an active role in


    defining interfaces
        Well, duh, they're the ones who will be using the
    −


        interfaces
    Interfaces pass “messages”, which are GPB-


    generated classes
    The message classes simply define the


    information which is passed-on from the kernel
    to the module
Google Protobuffers

    GPB Message classes provide a serializable


    container for information
        Think: XML on crack.
    −



    Eventually, all interfaces between the kernel


    and the module subsystems will pass only GPB
    messages
    No more having to understand kernel internals


    in order to add features
Say NO to Crack Magic

    Magic is code that works but is difficult or


    impossible to understand
    Magic is code which attempts to fix problems


    better fixed by compiler and library developers
    Magic is code which only one or two people


    know how to use
    The amount of magic in the code is inversely


    proportional to the number of developers who
    can contribute
Cleaning up the code

    So much mess, so little time



    Any code base gets some cobwebs over the


    years -- MySQL is no different
    We're focusing on cleaning and refactoring the


    code base to make it easier for lots of
    developers to contribute


But sometimes, you run into a few road blocks...
The following makes
     baby kittens cry
/*
 Preparation for table creation

 SYNOPSIS                                                                              /*                                                                                     else /* not NULL */                                                             create_info->varchar= true;
  mysql_prepare_create_table()                                                          Starting from 5.1 we work here with a copy of Create_field                            {                                                                             sql_field->offset= record_offset;
   session               Thread object.                                                 created by the caller, not with the instance that was                                   def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));             if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
   create_info          Create information (like MAX_ROWS).                             originally created during parsing. It's OK to create                                    if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */ auto_increment++;
   alter_info          List of columns and indexes to create                            a temporary item and initialize with it a member of the                                 {                                                                           /*
   tmp_table            If a temporary table is to be created.                          copy -- this item will be thrown away along with the copy                                 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);                    For now skip fields that are not physically stored in the database
   db_options       INOUT Table options (like HA_OPTION_PACK_RECORD).                   at the end of execution, and thus not introduce a dangling                                return(true);                                                                   (virtual fields) and update their offset later
   file              The handler for the new table.                                     pointer in the parsed tree of a prepared statement or a                                 }                                                                                 (see the next loop).
   key_info_buffer    OUT An array of KEY structs for the indexes.                      stored procedure statement.                                                           }                                                                                 */
   key_count        OUT The number of elements in the array.                           */                                                                                   }                                                                               if (sql_field->is_stored)
   select_field_count      The number of fields coming from a select table.            sql_field->def= sql_field->def->safe_charset_converter(save_cs);                     calculate_interval_lengths(cs, interval, &field_length, &dummy);                  record_offset+= sql_field->pack_length;
                                                                                                                                                                            sql_field->length= field_length;                                              }
 DESCRIPTION                                                                           if (sql_field->def == NULL)                                                        }                                                                               /* Update virtual fields' offset */
  Prepares the table and key structures for table creation.                            {                                                                                  set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);                           it.rewind();
                                                                                         /* Could not convert */                                                        }                                                                                 while ((sql_field=it++))
 NOTES                                                                                   my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);                                                                                                     {
  sets create_info->varchar if the table has a varchar                                   return(true);                                                                  sql_field->create_length_to_internal_length();                                      if (not sql_field->is_stored)
                                                                                       }                                                                                if (prepare_blob_field(session, sql_field))                                         {
 RETURN VALUES                                                                     }                                                                                      return(true);                                                                       sql_field->offset= record_offset;
   false OK                                                                                                                                                                                                                                                   record_offset+= sql_field->pack_length;
   true  error                                                                     if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)                                        if (!(sql_field->flags & NOT_NULL_FLAG))                                            }
*/                                                                                 {                                                                                      null_fields++;                                                                  }
                                                                                     uint32_t dummy;                                                                                                                                                      if (timestamps_with_niladic > 1)
static int                                                                           const CHARSET_INFO * const cs= sql_field->charset;                                 if (check_column_name(sql_field->field_name))                                     {
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,            TYPELIB *interval= sql_field->interval;                                            {                                                                                   my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
                    Alter_info *alter_info,                                                                                                                               my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);                              ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
                    bool tmp_table,                                                    /*                                                                                 return(true);                                                                     return(true);
                       uint32_t *db_options,                                             Create typelib from interval_list, and if necessary                            }                                                                                 }
                       handler *file, KEY **key_info_buffer,                             convert strings from client character set to the                                                                                                                 if (auto_increment > 1)
                       uint32_t *key_count, int select_field_count)                      column character set.                                                          /* Check if we have used the same field name before */                            {
{                                                                                      */                                                                               for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)                            my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
  const char     *key_name;                                                            if (!interval)                                                                   {                                                                                   return(true);
  Create_field *sql_field,*dup_field;                                                  {                                                                                  if (my_strcasecmp(system_charset_info,                                          }
  uint                            field,null_fields,blob_columns,max_key_length;         /*                                                                                               sql_field->field_name,                                          if (auto_increment &&
  ulong                           record_offset= 0;                                        Create the typelib in runtime memory - we will free the                                        dup_field->field_name) == 0)                                        (file->ha_table_flags() & HA_NO_AUTO_INCREMENT))
  KEY                             *key_info;                                               occupied memory at the same time when we free this                             {                                                                               {
  KEY_PART_INFO *key_part_info;                                                            sql_field -- at the end of execution.                                                         /*                                                                 my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
  int                             timestamps= 0, timestamps_with_niladic= 0;             */                                                                                                If this was a CREATE ... SELECT statement, accept a field                  ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
  int                             field_no,dup_no;                                       interval= sql_field->interval= typelib(session->mem_root,                                         redefinition if we are changing a field in the SELECT part       return(true);
  int                             select_field_pos,auto_increment=0;                                                  sql_field->interval_list);                                         */                                                               }
  List_iterator<Create_field> it(alter_info->create_list);                               List_iterator<String> int_it(sql_field->interval_list);                                         if (field_no < select_field_pos || dup_no >= select_field_pos)
  List_iterator<Create_field> it2(alter_info->create_list);                              String conv, *tmp;                                                                              {                                                                if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS))
  uint32_t total_uneven_bit_length= 0;                                                   char comma_buf[4];                                                                                my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name);     {
                                                                                         int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,                            return(true);                                                    my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
 select_field_pos= alter_info->create_list.elements - select_field_count;                                         (unsigned char*) comma_buf +                                           }                                                                            MYF(0));
 null_fields=blob_columns=0;                                                                                      sizeof(comma_buf));                                                    else                                                               return(true);
 create_info->varchar= 0;                                                                assert(comma_length > 0);                                                                       {                                                                }
 max_key_length= file->max_key_length();                                                 for (uint32_t i= 0; (tmp= int_it++); i++)                                                         /* Field redefined */
                                                                                         {                                                                                                 sql_field->def=                                 dup_field->def; Create keys */
                                                                                                                                                                                                                                                          /*
 for (field_no=0; (sql_field=it++) ; field_no++)                                           uint32_t lengthsp;                                                                              sql_field->sql_type=                            dup_field->sql_type;
 {                                                                                         if (String::needs_conversion(tmp->length(), tmp->charset(),                                     sql_field->charset=                             (dup_field->charset ?
                                                                                                                                                                                                                                                          List_iterator<Key> key_iterator(alter_info->key_list);
   const CHARSET_INFO *save_cs;                                                                                 cs, &dummy))                                                                                                                              List_iterator<Key> key_iterator2(alter_info->key_list);
                                                                                           {                                                                        dup_field->charset :                                                                  uint32_t key_parts=0, fk_key_count=0;
  /*                                                                                         uint32_t cnv_errs;                                                                                                                                           bool primary_key=0,unique_key=0;
    Initialize length from its original value (number of characters),                        conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);   create_info->default_table_charset);                                                  Key *key, *key2;
    which was set in the parser. This is necessary if we're                                  interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(),                          sql_field->length=                              dup_field-     uint32_t tmp, key_number;
    executing a prepared statement for the second time.                                                                 conv.length());                             >char_length;                                                                         /* special marker for keys to be ignored */
  */                                                                                         interval->type_lengths[i]= conv.length();                                        sql_field->pack_length= dup_field->pack_length;                             static char ignore_key[1];
  sql_field->length= sql_field->char_length;                                               }                                                                                  sql_field->key_length= dup_field->key_length;
  if (!sql_field->charset)                                                                                                                                                                 sql_field->decimals=                            dup_field->decimals;
                                                                                                                                                                                                                                                          /* Calculate number of key segements */
    sql_field->charset= create_info->default_table_charset;                                 // Strip trailing spaces.                                                                      sql_field->create_length_to_internal_length();                 *key_count= 0;
  /*                                                                                        lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],                                      sql_field->unireg_check=        dup_field->unireg_check;
    table_charset is set in ALTER Table if we want change character set                                          interval->type_lengths[i]);                                  /*                                                                          while ((key=key_iterator++))
    for all varchar/char columns.                                                           interval->type_lengths[i]= lengthsp;                                                We're making one field from two, the result field will have               {
    But the table charset must not affect the BLOB fields, so don't                         ((unsigned char *)interval->type_names[i])[lengthsp]= '0';                         dup_field->flags as flags. If we've incremented null_fields                 if (key->type == Key::FOREIGN_KEY)
    allow to change my_charset_bin to somethig else.                                       }                                                                                    because of sql_field->flags, decrement it back.                             {
  */                                                                                       sql_field->interval_list.empty(); // Don't need interval_list anymore              */                                                                              fk_key_count++;
  if (create_info->table_charset && sql_field->charset != &my_charset_bin)             }                                                                                      if (!(sql_field->flags & NOT_NULL_FLAG))                                        if (((Foreign_key *)key)->validate(alter_info->create_list))
    sql_field->charset= create_info->table_charset;                                                                                                                             null_fields--;                                                                  return true;
                                                                                       /* DRIZZLE_TYPE_ENUM */                                                                             sql_field->flags=                               dup_field->flags; Foreign_key *fk_key= (Foreign_key*) key;
  save_cs= sql_field->charset;                                                         {                                                                                      sql_field->interval=          dup_field->interval;                              if (fk_key->ref_columns.elements &&
  if ((sql_field->flags & BINCMP_FLAG) &&                                                uint32_t field_length;                                                               sql_field->vcol_info=          dup_field->vcol_info;                                            fk_key->ref_columns.elements != fk_key->columns.elements)
      !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,            assert(sql_field->sql_type == DRIZZLE_TYPE_ENUM);                                    sql_field->is_stored=        dup_field->is_stored;                              {
                                    MY_CS_BINSORT,MYF(0))))                              if (sql_field->def != NULL)                                                                       it2.remove();                                   // Remove first my_error(ER_WRONG_FK_DEF MYF(0),     ,
  {                                                                                      {                                                                          (create) definition                                                                                (fk_key->name.str ? fk_key->name.str :
    char tmp[64];                                                                          String str, *def= sql_field->def->val_str(&str);                                                select_field_pos--;                                                                        quot;foreign key without namequot;),
    strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),                                  if (def == NULL) /* SQL quot;NULLquot; maps to NULL */                                                  break;                                                                      ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
           STRING_WITH_LEN(quot;_binquot;));                                                       {                                                                                             }                                                                                  return(true);
    my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);                                             if ((sql_field->flags & NOT_NULL_FLAG) != 0)                                 }                                                                                   }
    return(true);                                                                            {                                                                          }                                                                                     continue;
  }                                                                                            my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);             /* Don't pack rows in old tables if the user has requested this */                  }
                                                                                               return(true);                                                            if ((sql_field->flags & BLOB_FLAG) ||                                               (*key_count)++;
  /*                                                                                         }                                                                                           (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info-       tmp=file->max_key_parts();
    Convert the default value from client character                                                                                                                 >row_type != ROW_TYPE_FIXED))                                                           if (key->columns.elements > tmp)
    set into the column character set if necessary.                                           /* else, the defaults yield the correct length for NULLs. */                (*db_options)|= HA_OPTION_PACK_RECORD;                                            {
  */                                                                                        }                                                                           it2.rewind();                                                                         my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
  if (sql_field->def &&                                                                     else /* not NULL */                                                       }                                                                                       return(true);
      save_cs != sql_field->def->collation.collation &&                                                                                                                                                                                                     }
      (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
  {
if (not sql_field->is_stored)
                                                                                                                                                                                                                                                              /* Create the key name based on the first column (if not given) */
                                                                                                                                                                                 {
                                                                                                                                                                                                                                                                    if (column_nr == 0)
                                                                                           key_info->key_parts=(uint8_t) key->columns.elements;                                    /* Key fields must always be physically stored. */
  if (check_identifier_name(&key->name, ER_TOO_LONG_IDENT))                                                                                                                                                                                                         {
                                                                                           key_info->key_part=key_part_info;                                                       my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0));
    return(true);                                                                                                                                                                                                                                                                  if (key->type == Key::PRIMARY)
                                                                                           key_info->usable_key_parts= key_number;                                                 return(true);
  key_iterator2.rewind ();                                                                                                                                                                                                                                                         {
                                                                                           key_info->algorithm= key->key_create_info.algorithm;                                  }
  if (key->type != Key::FOREIGN_KEY)                                                                                                                                                                                                                                                 if (primary_key)
                                                                                                                                                                                 if (key->type == Key::PRIMARY && sql_field->vcol_info)
  {                                                                                                                                                                                                                                                                                  {
                                                                                           /* Take block size from key part or table part */                                     {
    while ((key2 = key_iterator2++) != key)                                                                                                                                                                                                                                            my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
                                                                                           /*                                                                                      my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0));
    {                                                                                                                                                                                                                                                                              MYF(0));
                                                                                             TODO: Add warning if block size changes. We can't do it here, as                      return(true);
                  /*                                                                                                                                                                                                                                                                   return(true);
                                                                                             this may depend on the size of the key                                              }
        foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is                                                                                                                                                                                                          }
                                                                                           */                                                                                                  if (!(sql_field->flags & NOT_NULL_FLAG))
        'generated', and a generated key is a prefix of the other key.                                                                                                                                                                                                               key_name=primary_key_name;
                                                                                           key_info->block_size= (key->key_create_info.block_size ?                                            {
        Then we do not need the generated shorter key.                                                                                                                                                                                                                               primary_key=1;
                                                                                                               key->key_create_info.block_size :                                                 if (key->type == Key::PRIMARY)
      */                                                                                                                                                                                                                                                                           }
                                                                                                               create_info->key_block_size);                                                     {
      if ((key2->type != Key::FOREIGN_KEY &&                                                                                                                                                                                                                                       else if (!(key_name= key->name.str))
                                                                                                                                                                                                   /* Implicitly set primary key fields to NOT NULL for ISO conf. */
           key2->name.str != ignore_key &&                                                                                                                                                                                                                                           key_name=make_unique_key_name(sql_field->field_name,
                                                                                           if (key_info->block_size)                                                                               sql_field->flags|= NOT_NULL_FLAG;
           !foreign_key_prefix(key, key2)))                                                                                                                                                                                                                                                                                                     *key_info_buffer,
                                                                                             key_info->flags|= HA_USES_BLOCK_SIZE;                                                                 sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
      {                                                                                                                                                                                                                                                       key_info);
                                                                                                                                                                                     null_fields--;
        /* TODO: issue warning message */                                                                                                                                                                                                                                          if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
                                                                                           uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,                             }
        /* mark that the generated key should be ignored */                                                                                                                                                                                                                        {
                                                                                                                           key->key_create_info.comment.str,                                     else
        if (!key2->generated ||                                                                                                                                                                                                                                                      my_error(ER_DUP_KEYNAME, MYF(0), key_name);
                                                                                                                           key->key_create_info.comment.str +                      {
            (key->generated && key->columns.elements <                                                                                                                                                                                                                               return(true);
                                                                                                                           key->key_create_info.comment.length,                      key_info->flags|= HA_NULL_PART_KEY;
             key2->columns.elements))                                                                                                                                                                                                                                              }
                                                                                                                           INDEX_COMMENT_MAXLEN);                                    if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
          key->name.str= ignore_key;                                                                                                                                                                                                                                               key_info->name=(char*) key_name;
                                                                                                                                                                                     {
        else                                                                                                                                                                                                                                                        }
                                                                                           if (tmp_len < key->key_create_info.comment.length)                                          my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str);
        {                                                                                                                                                                                                                                                         }
                                                                                           {                                                                                           return(true);
          key2->name.str= ignore_key;                                                                                                                                                                                                                             if (!key_info->name || check_column_name(key_info->name))
                                                                                             my_error(ER_WRONG_STRING_LENGTH, MYF(0),                                                }
          key_parts-= key2->columns.elements;                                                                                                                                                                                                                     {
                                                                                                     key->key_create_info.comment.str,quot;INDEX COMMENTquot;,                             }
          (*key_count)--;                                                                                                                                                                                                                                           my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
                                                                                                     (uint) INDEX_COMMENT_MAXLEN);                                                             }
        }                                                                                                                                                                                                                                                           return(true);
                                                                                             return(-1);                                                                                       if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
        break;                                                                                                                                                                                                                                                    }
                                                                                           }                                                                                                   {
      }                                                                                                                                                                                                                                                           if (!(key_info->flags & HA_NULL_PART_KEY))
                                                                                                                                                                                                 if (column_nr == 0 || (file->ha_table_flags() &
    }                                                                                                                                                                                                                                                               unique_key=1;
                                                                                           key_info->comment.length= key->key_create_info.comment.length;                  HA_AUTO_PART_KEY))
  }                                                                                                                                                                                                                                                               key_info->key_length=(uint16_t) key_length;
                                                                                           if (key_info->comment.length > 0)                                                                       auto_increment--;                                              //
  if (key->name.str != ignore_key)                                                                                                                                                                                                                                if (key_length > max_key_length)
                                                                                           {                                                                               Field is used
    key_parts+=key->columns.elements;                                                                                                                                                                                                                             {
                                                                                             key_info->flags|= HA_USES_COMMENT;                                                                }
  else                                                                                                                                                                                                                                                              my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
                                                                                             key_info->comment.str= key->key_create_info.comment.str;                          }
    (*key_count)--;                                                                                                                                                                                                                                                 return(true);
                                                                                           }
  if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&                                                                                                                                                                                               }
                                                                                                                                                                               key_part_info->fieldnr= field;
                  !my_strcasecmp(system_charset_info,key->name.str, primary_key_name))                                                                                                                                                                            key_info++;
                                                                                           List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);               key_part_info->offset= (uint16_t) sql_field->offset;
  {                                                                                                                                                                                                                                                             }
                                                                                           for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)                          key_part_info->key_type=sql_field->pack_flag;
    my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);                                                                                                                                                                                                   if (!unique_key && !primary_key &&
                                                                                           {                                                                                   length= sql_field->key_length;
    return(true);                                                                                                                                                                                                                                                   (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY))
                                                                                             uint32_t length;
  }                                                                                                                                                                                                                                                             {
                                                                                             Key_part_spec *dup_column;                                                        if (column->length)
}                                                                                                                                                                                                                                                                 my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
                                                                                                                                                                               {
tmp=file->max_keys();                                                                                                                                                                                                                                             return(true);
                                                                                             it.rewind();                                                                                      if (f_is_blob(sql_field->pack_flag))
if (*key_count > tmp)                                                                                                                                                                                                                                           }
                                                                                             field=0;                                                                                          {
{                                                                                                                                                                                                                                                               if (auto_increment > 0)
                                                                                             while ((sql_field=it++) &&                                                                          if ((length=column->length) > max_key_length ||
  my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);                                                                                                                                                                                                                        {
                                                                                                                my_strcasecmp(system_charset_info,                                                   length > file->max_key_part_length())
  return(true);                                                                                                                                                                                                                                                   my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
                                                                                                                                               column->field_name.str,                           {
}                                                                                                                                                                                                                                                                 return(true);
                                                                                                                                               sql_field->field_name))                             length=cmin(max_key_length, file->max_key_part_length());
                                                                                                                                                                                                                                                                }
                                                                                                           field++;                                                                                if (key->type == Key::MULTIPLE)
(*key_info_buffer)= key_info= (KEY*) sql_calloc(sizeof(KEY) * (*key_count));                                                                                                                                                                                    /* Sort keys in optimized order */
                                                                                             if (!sql_field)                                                                                       {
key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);                                                                                                                                                                                     my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KEY),
                                                                                             {                                                                                                       /* not a critical problem */
if (!*key_info_buffer || ! key_part_info)                                                                                                                                                                                                                                             (qsort_cmp) sort_keys);
                                                                                                           my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column-                                    char warn_buff[DRIZZLE_ERRMSG_SIZE];
  return(true);                                                   // Out of memory                                                                                                                                                                              create_info->null_bits= null_fields;
                                                                                        >field_name.str);                                                                                            snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
                                                                                                           return(true);                                                                       length);
key_iterator.rewind();                                                                                                                                                                                                                                          /* Check fields. */
                                                                                             }                                                                                                       push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
key_number=0;                                                                                                                                                                                                                                                   it.rewind();
                                                                                             while ((dup_column= cols2++) != column)                                                                                                 ER_TOO_LONG_KEY, warn_buff);
for (; (key=key_iterator++) ; key_number++)                                                                                                                                                                                                                     while ((sql_field=it++))
                                                                                             {                                                                                         /* Align key length to multibyte char boundary */
{                                                                                                                                                                                                                                                               {
                                                                                               if (!my_strcasecmp(system_charset_info,                                                 length-= length % sql_field->charset->mbmaxlen;
  uint32_t key_length=0;                                                                                                                                                                                                                                          Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
                                                                                                                                     column->field_name.str, dup_column-                           }
  Key_part_spec *column;
                                                                                        >field_name.str))                                                                                          else
                                                                                                                                                                                                                                                                  if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
                                                                                                           {                                                                                       {
  if (key->name.str == ignore_key)                                                                                                                                                                                                                                    !sql_field->def &&
                                                                                                             my_printf_error(ER_DUP_FIELDNAME,                                                       my_error(ER_TOO_LONG_KEY,MYF(0),length);
  {                                                                                                                                                                                                                                                                   sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
                                                                                                                                              ER(ER_DUP_FIELDNAME),MYF(0),                           return(true);
    /* ignore redundant keys */                                                                                                                                                                                                                                       (sql_field->flags & NOT_NULL_FLAG) &&
                                                                                                                                              column->field_name.str);                             }
    do                                                                                                                                                                                                                                                                (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
                                                                                                             return(true);                                                                       }
                  key=key_iterator++;                                                                                                                                                                                                                             {
                                                                                                           }                                                                                   }
    while (key && key->name.str == ignore_key);                                                                                                                                                                                                                     /*
                                                                                             }                                                                                                 else if ((column->length > length ||
    if (!key)                                                                                                                                                                                                                                                         An error should be reported if:
                                                                                             cols2.rewind();                                                                               !Field::type_can_have_key_part (sql_field->sql_type) ||
                  break;                                                                                                                                                                                                                                                - NO_ZERO_DATE SQL mode is active;
                                                                                             {                                                                                                                      ((f_is_packed(sql_field->pack_flag) ||
  }                                                                                                                                                                                                                                                                     - there is no explicit DEFAULT clause (default column value);
                                                                                                           column->length*= sql_field->charset->mbmaxlen;                                                             ((file->ha_table_flags() &
                                                                                                                                                                                                                                                                        - this is a TIMESTAMP column;
                                                                                                                                                                           HA_NO_PREFIX_CHAR_KEYS) &&
  switch (key->type) {                                                                                                                                                                                                                                                  - the column is not NULL;
                                                                                                           if (f_is_blob(sql_field->pack_flag))                                                                        (key_info->flags & HA_NOSAME))) &&
  case Key::MULTIPLE:                                                                                                                                                                                                                                                   - this is not the DEFAULT CURRENT_TIMESTAMP column.
                                                                                                           {                                                                                                         column->length != length)))
                  key_info->flags= 0;
                                                                                                             if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))                               {
                  break;                                                                                                                                                                                                                                              In other words, an error should be reported if
                                                                                                             {                                                                                   my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY),
  case Key::FOREIGN_KEY:                                                                                                                                                                                                                                                - NO_ZERO_DATE SQL mode is active;
                                                                                                               my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str);
                                                                                                                                                                           MYF(0));
    key_number--;                                                               // Skip this key                                                                                                                                                                        - the column definition is equivalent to
                                                                                                               return(true);                                                                     return(true);
    continue;                                                                                                                                                                                                                                                             'column_name TIMESTAMP DEFAULT 0'.
                                                                                                             }                                                                                 }
  default:                                                                                                                                                                                                                                                          */
                                                                                                             if (!column->length)                                                              else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
    key_info->flags = HA_NOSAME;
                                                                                                             {                                                                                   length=column->length;
    break;                                                                                                                                                                                                                                                          my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
                                                                                                               my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column-            }
  }                                                                                                                                                                                                                                                                 return(true);
                                                                                        >field_name.str);                                                                      else if (length == 0)
  if (key->generated)                                                                                                                                                                                                                                             }
                                                                                                               return(true);                                                   {
    key_info->flags|= HA_GENERATED_KEY;                                                                                                                                                                                                                         }
                                                                                                             }                                                                                 my_error(ER_WRONG_KEY_COLUMN, MYF(0), column-
                                                                                                           }                                                               >field_name.str);
                                                                                                                                                                                                                                                                return(false);
                                                                                                                                                                                                 return(true);
                                                                                                                                                                                                                                                              }
                                                                                                                                                                               }
Use standard libraries

    Related to magic in the code



    Enables code re-use and allows Drizzle to take


    advantage of a large community of domain
    experts and developers
    Allows Drizzle to focus on Drizzle, and library


    developers to focus on library code
    Happy to send patches to library developers,


    but not good to reinvent the wheel
No new global contention points

    Performance != scalability



    Drizzle is focused more on scalability than raw


    performance
    The days of 16 concurrent connections are OVER



    Drizzle is targeting applications which


    consistently serve 1024+ concurrent connections
    Global mutexes negatively impact scalability, so


    no new global mutexes
    Remove existing global contention points in


    favor of atomics, RCU, and other strategies
The soundbite

    More contributors



        Focus on APIs, clean code, standard libraries, open
    −


        and public discourse
    Easier to contribute



        Cleaner, more standardized code, fully public peer
    −


        and code review, friendly community of mentors
    Scalability over raw performance



        No new global mutexes, research on atomics, RCU,
    −


        and other modern lock-free techniques
And we hope this leads to...




   More eyes capable of
disecting and discussing the
code, which leads to steady
progress in performance and
         scalability
Join us.
Resources

Launchpad - http://launchpad.net/drizzle
Wiki - http://drizzle.org/wiki/Main_Page
Discuss - https://launchpad.net/~drizzle-discuss
Freenode - #drizzle

Más contenido relacionado

La actualidad más candente

Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
Data Tracking: On the Hunt for Information about Your Database
Data Tracking: On the Hunt for Information about Your DatabaseData Tracking: On the Hunt for Information about Your Database
Data Tracking: On the Hunt for Information about Your DatabaseMichael Rosenblum
 
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...Michael Rosenblum
 
Clean code in JavaScript
Clean code in JavaScriptClean code in JavaScript
Clean code in JavaScriptMathieu Breton
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128PrinceGuru MS
 
Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Michelangelo van Dam
 
PyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating DecoratorsPyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating DecoratorsGraham Dumpleton
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskellnebuta
 
Managing Unstructured Data: Lobs in the World of JSON
Managing Unstructured Data: Lobs in the World of JSONManaging Unstructured Data: Lobs in the World of JSON
Managing Unstructured Data: Lobs in the World of JSONMichael Rosenblum
 
JavaFX Your Way: Building JavaFX Applications with Alternative Languages
JavaFX Your Way: Building JavaFX Applications with Alternative LanguagesJavaFX Your Way: Building JavaFX Applications with Alternative Languages
JavaFX Your Way: Building JavaFX Applications with Alternative LanguagesStephen Chin
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable codeGeshan Manandhar
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objectsjulien pauli
 
Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Rafael Soto
 
Database administration commands
Database administration commands Database administration commands
Database administration commands Varsha Ajith
 
Rails 3.1 Asset Pipeline
Rails 3.1 Asset PipelineRails 3.1 Asset Pipeline
Rails 3.1 Asset PipelineJames Daniels
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Fabien Potencier
 
Sql server difference faqs- 9
Sql server difference faqs- 9Sql server difference faqs- 9
Sql server difference faqs- 9Umar Ali
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Railselliando dias
 

La actualidad más candente (20)

Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Data Tracking: On the Hunt for Information about Your Database
Data Tracking: On the Hunt for Information about Your DatabaseData Tracking: On the Hunt for Information about Your Database
Data Tracking: On the Hunt for Information about Your Database
 
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...
 
Clean code in JavaScript
Clean code in JavaScriptClean code in JavaScript
Clean code in JavaScript
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
 
Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010
 
PyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating DecoratorsPyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating Decorators
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
Managing Unstructured Data: Lobs in the World of JSON
Managing Unstructured Data: Lobs in the World of JSONManaging Unstructured Data: Lobs in the World of JSON
Managing Unstructured Data: Lobs in the World of JSON
 
JavaFX Your Way: Building JavaFX Applications with Alternative Languages
JavaFX Your Way: Building JavaFX Applications with Alternative LanguagesJavaFX Your Way: Building JavaFX Applications with Alternative Languages
JavaFX Your Way: Building JavaFX Applications with Alternative Languages
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objects
 
Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011
 
Database administration commands
Database administration commands Database administration commands
Database administration commands
 
Rails 3.1 Asset Pipeline
Rails 3.1 Asset PipelineRails 3.1 Asset Pipeline
Rails 3.1 Asset Pipeline
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
 
Oracle ORA Errors
Oracle ORA ErrorsOracle ORA Errors
Oracle ORA Errors
 
Sql server difference faqs- 9
Sql server difference faqs- 9Sql server difference faqs- 9
Sql server difference faqs- 9
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
 
Compiler
CompilerCompiler
Compiler
 

Similar a Drizzles Approach To Improving Performance Of The Server

Go Faster With Native Compilation
Go Faster With Native CompilationGo Faster With Native Compilation
Go Faster With Native CompilationPGConf APAC
 
Go faster with_native_compilation Part-2
Go faster with_native_compilation Part-2Go faster with_native_compilation Part-2
Go faster with_native_compilation Part-2Rajeev Rastogi (KRR)
 
External Language Stored Procedures for MySQL
External Language Stored Procedures for MySQLExternal Language Stored Procedures for MySQL
External Language Stored Procedures for MySQLAntony T Curtis
 
Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from insidejulien pauli
 
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...Alex Zaballa
 
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...Alex Zaballa
 
Berlin buzzwords 2018
Berlin buzzwords 2018Berlin buzzwords 2018
Berlin buzzwords 2018Matija Gobec
 
CUDA lab's slides of "parallel programming" course
CUDA lab's slides of "parallel programming" courseCUDA lab's slides of "parallel programming" course
CUDA lab's slides of "parallel programming" courseShuai Yuan
 
Threaded Programming
Threaded ProgrammingThreaded Programming
Threaded ProgrammingSri Prasanna
 
Processing massive amount of data with Map Reduce using Apache Hadoop - Indi...
Processing massive amount of data with Map Reduce using Apache Hadoop  - Indi...Processing massive amount of data with Map Reduce using Apache Hadoop  - Indi...
Processing massive amount of data with Map Reduce using Apache Hadoop - Indi...IndicThreads
 
Using Spark to Load Oracle Data into Cassandra
Using Spark to Load Oracle Data into CassandraUsing Spark to Load Oracle Data into Cassandra
Using Spark to Load Oracle Data into CassandraJim Hatcher
 
Using Spark to Load Oracle Data into Cassandra (Jim Hatcher, IHS Markit) | C*...
Using Spark to Load Oracle Data into Cassandra (Jim Hatcher, IHS Markit) | C*...Using Spark to Load Oracle Data into Cassandra (Jim Hatcher, IHS Markit) | C*...
Using Spark to Load Oracle Data into Cassandra (Jim Hatcher, IHS Markit) | C*...DataStax
 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptCaridy Patino
 
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...Vincenzo Iozzo
 
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...TAISEEREISA
 
Introduction to Apache Mesos
Introduction to Apache MesosIntroduction to Apache Mesos
Introduction to Apache MesosJoe Stein
 
Cascading talk in Etsy (http://www.meetup.com/cascading/events/169390262/)
Cascading talk in Etsy (http://www.meetup.com/cascading/events/169390262/)Cascading talk in Etsy (http://www.meetup.com/cascading/events/169390262/)
Cascading talk in Etsy (http://www.meetup.com/cascading/events/169390262/)Jyotirmoy Sundi
 

Similar a Drizzles Approach To Improving Performance Of The Server (20)

Go Faster With Native Compilation
Go Faster With Native CompilationGo Faster With Native Compilation
Go Faster With Native Compilation
 
Go faster with_native_compilation Part-2
Go faster with_native_compilation Part-2Go faster with_native_compilation Part-2
Go faster with_native_compilation Part-2
 
External Language Stored Procedures for MySQL
External Language Stored Procedures for MySQLExternal Language Stored Procedures for MySQL
External Language Stored Procedures for MySQL
 
Go Faster With Native Compilation
Go Faster With Native CompilationGo Faster With Native Compilation
Go Faster With Native Compilation
 
Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from inside
 
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
 
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
 
Berlin buzzwords 2018
Berlin buzzwords 2018Berlin buzzwords 2018
Berlin buzzwords 2018
 
CUDA lab's slides of "parallel programming" course
CUDA lab's slides of "parallel programming" courseCUDA lab's slides of "parallel programming" course
CUDA lab's slides of "parallel programming" course
 
Threaded Programming
Threaded ProgrammingThreaded Programming
Threaded Programming
 
Processing massive amount of data with Map Reduce using Apache Hadoop - Indi...
Processing massive amount of data with Map Reduce using Apache Hadoop  - Indi...Processing massive amount of data with Map Reduce using Apache Hadoop  - Indi...
Processing massive amount of data with Map Reduce using Apache Hadoop - Indi...
 
Using Spark to Load Oracle Data into Cassandra
Using Spark to Load Oracle Data into CassandraUsing Spark to Load Oracle Data into Cassandra
Using Spark to Load Oracle Data into Cassandra
 
Using Spark to Load Oracle Data into Cassandra (Jim Hatcher, IHS Markit) | C*...
Using Spark to Load Oracle Data into Cassandra (Jim Hatcher, IHS Markit) | C*...Using Spark to Load Oracle Data into Cassandra (Jim Hatcher, IHS Markit) | C*...
Using Spark to Load Oracle Data into Cassandra (Jim Hatcher, IHS Markit) | C*...
 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScript
 
Sqlapi0.1
Sqlapi0.1Sqlapi0.1
Sqlapi0.1
 
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
 
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
 
Introduction to Apache Mesos
Introduction to Apache MesosIntroduction to Apache Mesos
Introduction to Apache Mesos
 
COLLADA & WebGL
COLLADA & WebGLCOLLADA & WebGL
COLLADA & WebGL
 
Cascading talk in Etsy (http://www.meetup.com/cascading/events/169390262/)
Cascading talk in Etsy (http://www.meetup.com/cascading/events/169390262/)Cascading talk in Etsy (http://www.meetup.com/cascading/events/169390262/)
Cascading talk in Etsy (http://www.meetup.com/cascading/events/169390262/)
 

Más de PerconaPerformance

E M T Better Performance Monitoring
E M T  Better  Performance  MonitoringE M T  Better  Performance  Monitoring
E M T Better Performance MonitoringPerconaPerformance
 
Covering Indexes Ordersof Magnitude Improvements
Covering  Indexes  Ordersof Magnitude  ImprovementsCovering  Indexes  Ordersof Magnitude  Improvements
Covering Indexes Ordersof Magnitude ImprovementsPerconaPerformance
 
Automated Performance Testing With J Meter And Maven
Automated  Performance  Testing With  J Meter And  MavenAutomated  Performance  Testing With  J Meter And  Maven
Automated Performance Testing With J Meter And MavenPerconaPerformance
 
Galera Multi Master Synchronous My S Q L Replication Clusters
Galera  Multi Master  Synchronous  My S Q L  Replication  ClustersGalera  Multi Master  Synchronous  My S Q L  Replication  Clusters
Galera Multi Master Synchronous My S Q L Replication ClustersPerconaPerformance
 
My S Q L Replication Getting The Most From Slaves
My S Q L  Replication  Getting  The  Most  From  SlavesMy S Q L  Replication  Getting  The  Most  From  Slaves
My S Q L Replication Getting The Most From SlavesPerconaPerformance
 
Performance Instrumentation Beyond What You Do Now
Performance  Instrumentation  Beyond  What  You  Do  NowPerformance  Instrumentation  Beyond  What  You  Do  Now
Performance Instrumentation Beyond What You Do NowPerconaPerformance
 
Boost Performance With My S Q L 51 Partitions
Boost Performance With  My S Q L 51 PartitionsBoost Performance With  My S Q L 51 Partitions
Boost Performance With My S Q L 51 PartitionsPerconaPerformance
 
Trees And More With Postgre S Q L
Trees And  More With  Postgre S Q LTrees And  More With  Postgre S Q L
Trees And More With Postgre S Q LPerconaPerformance
 
Database Performance With Proxy Architectures
Database  Performance With  Proxy  ArchitecturesDatabase  Performance With  Proxy  Architectures
Database Performance With Proxy ArchitecturesPerconaPerformance
 
Running A Realtime Stats Service On My Sql
Running A Realtime Stats Service On My SqlRunning A Realtime Stats Service On My Sql
Running A Realtime Stats Service On My SqlPerconaPerformance
 
How To Think About Performance
How To Think About PerformanceHow To Think About Performance
How To Think About PerformancePerconaPerformance
 
Object Oriented Css For High Performance Websites And Applications
Object Oriented Css For High Performance Websites And ApplicationsObject Oriented Css For High Performance Websites And Applications
Object Oriented Css For High Performance Websites And ApplicationsPerconaPerformance
 
Your Disk Array Is Slower Than It Should Be
Your Disk Array Is Slower Than It Should BeYour Disk Array Is Slower Than It Should Be
Your Disk Array Is Slower Than It Should BePerconaPerformance
 

Más de PerconaPerformance (17)

E M T Better Performance Monitoring
E M T  Better  Performance  MonitoringE M T  Better  Performance  Monitoring
E M T Better Performance Monitoring
 
Covering Indexes Ordersof Magnitude Improvements
Covering  Indexes  Ordersof Magnitude  ImprovementsCovering  Indexes  Ordersof Magnitude  Improvements
Covering Indexes Ordersof Magnitude Improvements
 
Automated Performance Testing With J Meter And Maven
Automated  Performance  Testing With  J Meter And  MavenAutomated  Performance  Testing With  J Meter And  Maven
Automated Performance Testing With J Meter And Maven
 
Galera Multi Master Synchronous My S Q L Replication Clusters
Galera  Multi Master  Synchronous  My S Q L  Replication  ClustersGalera  Multi Master  Synchronous  My S Q L  Replication  Clusters
Galera Multi Master Synchronous My S Q L Replication Clusters
 
My S Q L Replication Getting The Most From Slaves
My S Q L  Replication  Getting  The  Most  From  SlavesMy S Q L  Replication  Getting  The  Most  From  Slaves
My S Q L Replication Getting The Most From Slaves
 
Performance Instrumentation Beyond What You Do Now
Performance  Instrumentation  Beyond  What  You  Do  NowPerformance  Instrumentation  Beyond  What  You  Do  Now
Performance Instrumentation Beyond What You Do Now
 
Boost Performance With My S Q L 51 Partitions
Boost Performance With  My S Q L 51 PartitionsBoost Performance With  My S Q L 51 Partitions
Boost Performance With My S Q L 51 Partitions
 
High Performance Erlang
High  Performance  ErlangHigh  Performance  Erlang
High Performance Erlang
 
Websites On Speed
Websites On  SpeedWebsites On  Speed
Websites On Speed
 
Trees And More With Postgre S Q L
Trees And  More With  Postgre S Q LTrees And  More With  Postgre S Q L
Trees And More With Postgre S Q L
 
Database Performance With Proxy Architectures
Database  Performance With  Proxy  ArchitecturesDatabase  Performance With  Proxy  Architectures
Database Performance With Proxy Architectures
 
Using Storage Class Memory
Using Storage Class MemoryUsing Storage Class Memory
Using Storage Class Memory
 
Websites On Speed
Websites On SpeedWebsites On Speed
Websites On Speed
 
Running A Realtime Stats Service On My Sql
Running A Realtime Stats Service On My SqlRunning A Realtime Stats Service On My Sql
Running A Realtime Stats Service On My Sql
 
How To Think About Performance
How To Think About PerformanceHow To Think About Performance
How To Think About Performance
 
Object Oriented Css For High Performance Websites And Applications
Object Oriented Css For High Performance Websites And ApplicationsObject Oriented Css For High Performance Websites And Applications
Object Oriented Css For High Performance Websites And Applications
 
Your Disk Array Is Slower Than It Should Be
Your Disk Array Is Slower Than It Should BeYour Disk Array Is Slower Than It Should Be
Your Disk Array Is Slower Than It Should Be
 

Último

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 

Último (20)

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 

Drizzles Approach To Improving Performance Of The Server

  • 1. How Drizzle Approaches Performance of the Server April 22, 2008
  • 2. Hi, I'm Jay. I'm a Drizzle code monkey. And you can too.
  • 3. (A few of) our values Open and public discourse about performance  And problems! − Focus on the interface, not the implementation  No “One Right Way” of doing something − Innovation happens in the community − Say no to magic  Let compiler developers do their job − Use standard, open source libraries  Let the experts be experts − No new global contention points 
  • 4. Open and public discourse Benchmarks should be published online and  peer-reviewed Methodology for benchmarks should be clear  and well-documented on our wiki Discussions and debates about performance  issues are actively encouraged on the list No shame  No hiding  No secrets 
  • 5. Storage Engines Authorization Logging Caching Kernel Core Services Gearman Error Handling Parsing Plugin API (GPB Messages) Replication Authentication Module Ecosystem
  • 6. Interface vs. Implementation Features are implemented in modules  The kernel provides interfaces for modules to  communicate with the kernel Recognize that one implementation of  something may perform well for one problem domain, but poorly for others So, provide interfaces so different, targeted − implementations may be built to address differences in application domains
  • 7. Interfaces The community should play an active role in  defining interfaces Well, duh, they're the ones who will be using the − interfaces Interfaces pass “messages”, which are GPB-  generated classes The message classes simply define the  information which is passed-on from the kernel to the module
  • 8. Google Protobuffers GPB Message classes provide a serializable  container for information Think: XML on crack. − Eventually, all interfaces between the kernel  and the module subsystems will pass only GPB messages No more having to understand kernel internals  in order to add features
  • 9. Say NO to Crack Magic Magic is code that works but is difficult or  impossible to understand Magic is code which attempts to fix problems  better fixed by compiler and library developers Magic is code which only one or two people  know how to use The amount of magic in the code is inversely  proportional to the number of developers who can contribute
  • 10. Cleaning up the code So much mess, so little time  Any code base gets some cobwebs over the  years -- MySQL is no different We're focusing on cleaning and refactoring the  code base to make it easier for lots of developers to contribute But sometimes, you run into a few road blocks...
  • 11. The following makes baby kittens cry
  • 12. /* Preparation for table creation SYNOPSIS /* else /* not NULL */ create_info->varchar= true; mysql_prepare_create_table() Starting from 5.1 we work here with a copy of Create_field { sql_field->offset= record_offset; session Thread object. created by the caller, not with the instance that was def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) create_info Create information (like MAX_ROWS). originally created during parsing. It's OK to create if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */ auto_increment++; alter_info List of columns and indexes to create a temporary item and initialize with it a member of the { /* tmp_table If a temporary table is to be created. copy -- this item will be thrown away along with the copy my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); For now skip fields that are not physically stored in the database db_options INOUT Table options (like HA_OPTION_PACK_RECORD). at the end of execution, and thus not introduce a dangling return(true); (virtual fields) and update their offset later file The handler for the new table. pointer in the parsed tree of a prepared statement or a } (see the next loop). key_info_buffer OUT An array of KEY structs for the indexes. stored procedure statement. } */ key_count OUT The number of elements in the array. */ } if (sql_field->is_stored) select_field_count The number of fields coming from a select table. sql_field->def= sql_field->def->safe_charset_converter(save_cs); calculate_interval_lengths(cs, interval, &field_length, &dummy); record_offset+= sql_field->pack_length; sql_field->length= field_length; } DESCRIPTION if (sql_field->def == NULL) } /* Update virtual fields' offset */ Prepares the table and key structures for table creation. { set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1); it.rewind(); /* Could not convert */ } while ((sql_field=it++)) NOTES my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); { sets create_info->varchar if the table has a varchar return(true); sql_field->create_length_to_internal_length(); if (not sql_field->is_stored) } if (prepare_blob_field(session, sql_field)) { RETURN VALUES } return(true); sql_field->offset= record_offset; false OK record_offset+= sql_field->pack_length; true error if (sql_field->sql_type == DRIZZLE_TYPE_ENUM) if (!(sql_field->flags & NOT_NULL_FLAG)) } */ { null_fields++; } uint32_t dummy; if (timestamps_with_niladic > 1) static int const CHARSET_INFO * const cs= sql_field->charset; if (check_column_name(sql_field->field_name)) { mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info, TYPELIB *interval= sql_field->interval; { my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS, Alter_info *alter_info, my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name); ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0)); bool tmp_table, /* return(true); return(true); uint32_t *db_options, Create typelib from interval_list, and if necessary } } handler *file, KEY **key_info_buffer, convert strings from client character set to the if (auto_increment > 1) uint32_t *key_count, int select_field_count) column character set. /* Check if we have used the same field name before */ { { */ for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++) my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0)); const char *key_name; if (!interval) { return(true); Create_field *sql_field,*dup_field; { if (my_strcasecmp(system_charset_info, } uint field,null_fields,blob_columns,max_key_length; /* sql_field->field_name, if (auto_increment && ulong record_offset= 0; Create the typelib in runtime memory - we will free the dup_field->field_name) == 0) (file->ha_table_flags() & HA_NO_AUTO_INCREMENT)) KEY *key_info; occupied memory at the same time when we free this { { KEY_PART_INFO *key_part_info; sql_field -- at the end of execution. /* my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, int timestamps= 0, timestamps_with_niladic= 0; */ If this was a CREATE ... SELECT statement, accept a field ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0)); int field_no,dup_no; interval= sql_field->interval= typelib(session->mem_root, redefinition if we are changing a field in the SELECT part return(true); int select_field_pos,auto_increment=0; sql_field->interval_list); */ } List_iterator<Create_field> it(alter_info->create_list); List_iterator<String> int_it(sql_field->interval_list); if (field_no < select_field_pos || dup_no >= select_field_pos) List_iterator<Create_field> it2(alter_info->create_list); String conv, *tmp; { if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS)) uint32_t total_uneven_bit_length= 0; char comma_buf[4]; my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name); { int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf, return(true); my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB), select_field_pos= alter_info->create_list.elements - select_field_count; (unsigned char*) comma_buf + } MYF(0)); null_fields=blob_columns=0; sizeof(comma_buf)); else return(true); create_info->varchar= 0; assert(comma_length > 0); { } max_key_length= file->max_key_length(); for (uint32_t i= 0; (tmp= int_it++); i++) /* Field redefined */ { sql_field->def= dup_field->def; Create keys */ /* for (field_no=0; (sql_field=it++) ; field_no++) uint32_t lengthsp; sql_field->sql_type= dup_field->sql_type; { if (String::needs_conversion(tmp->length(), tmp->charset(), sql_field->charset= (dup_field->charset ? List_iterator<Key> key_iterator(alter_info->key_list); const CHARSET_INFO *save_cs; cs, &dummy)) List_iterator<Key> key_iterator2(alter_info->key_list); { dup_field->charset : uint32_t key_parts=0, fk_key_count=0; /* uint32_t cnv_errs; bool primary_key=0,unique_key=0; Initialize length from its original value (number of characters), conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs); create_info->default_table_charset); Key *key, *key2; which was set in the parser. This is necessary if we're interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(), sql_field->length= dup_field- uint32_t tmp, key_number; executing a prepared statement for the second time. conv.length()); >char_length; /* special marker for keys to be ignored */ */ interval->type_lengths[i]= conv.length(); sql_field->pack_length= dup_field->pack_length; static char ignore_key[1]; sql_field->length= sql_field->char_length; } sql_field->key_length= dup_field->key_length; if (!sql_field->charset) sql_field->decimals= dup_field->decimals; /* Calculate number of key segements */ sql_field->charset= create_info->default_table_charset; // Strip trailing spaces. sql_field->create_length_to_internal_length(); *key_count= 0; /* lengthsp= cs->cset->lengthsp(cs, interval->type_names[i], sql_field->unireg_check= dup_field->unireg_check; table_charset is set in ALTER Table if we want change character set interval->type_lengths[i]); /* while ((key=key_iterator++)) for all varchar/char columns. interval->type_lengths[i]= lengthsp; We're making one field from two, the result field will have { But the table charset must not affect the BLOB fields, so don't ((unsigned char *)interval->type_names[i])[lengthsp]= '0'; dup_field->flags as flags. If we've incremented null_fields if (key->type == Key::FOREIGN_KEY) allow to change my_charset_bin to somethig else. } because of sql_field->flags, decrement it back. { */ sql_field->interval_list.empty(); // Don't need interval_list anymore */ fk_key_count++; if (create_info->table_charset && sql_field->charset != &my_charset_bin) } if (!(sql_field->flags & NOT_NULL_FLAG)) if (((Foreign_key *)key)->validate(alter_info->create_list)) sql_field->charset= create_info->table_charset; null_fields--; return true; /* DRIZZLE_TYPE_ENUM */ sql_field->flags= dup_field->flags; Foreign_key *fk_key= (Foreign_key*) key; save_cs= sql_field->charset; { sql_field->interval= dup_field->interval; if (fk_key->ref_columns.elements && if ((sql_field->flags & BINCMP_FLAG) && uint32_t field_length; sql_field->vcol_info= dup_field->vcol_info; fk_key->ref_columns.elements != fk_key->columns.elements) !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname, assert(sql_field->sql_type == DRIZZLE_TYPE_ENUM); sql_field->is_stored= dup_field->is_stored; { MY_CS_BINSORT,MYF(0)))) if (sql_field->def != NULL) it2.remove(); // Remove first my_error(ER_WRONG_FK_DEF MYF(0), , { { (create) definition (fk_key->name.str ? fk_key->name.str : char tmp[64]; String str, *def= sql_field->def->val_str(&str); select_field_pos--; quot;foreign key without namequot;), strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4), if (def == NULL) /* SQL quot;NULLquot; maps to NULL */ break; ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); STRING_WITH_LEN(quot;_binquot;)); { } return(true); my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp); if ((sql_field->flags & NOT_NULL_FLAG) != 0) } } return(true); { } continue; } my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); /* Don't pack rows in old tables if the user has requested this */ } return(true); if ((sql_field->flags & BLOB_FLAG) || (*key_count)++; /* } (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info- tmp=file->max_key_parts(); Convert the default value from client character >row_type != ROW_TYPE_FIXED)) if (key->columns.elements > tmp) set into the column character set if necessary. /* else, the defaults yield the correct length for NULLs. */ (*db_options)|= HA_OPTION_PACK_RECORD; { */ } it2.rewind(); my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp); if (sql_field->def && else /* not NULL */ } return(true); save_cs != sql_field->def->collation.collation && } (sql_field->sql_type == DRIZZLE_TYPE_ENUM)) {
  • 13. if (not sql_field->is_stored) /* Create the key name based on the first column (if not given) */ { if (column_nr == 0) key_info->key_parts=(uint8_t) key->columns.elements; /* Key fields must always be physically stored. */ if (check_identifier_name(&key->name, ER_TOO_LONG_IDENT)) { key_info->key_part=key_part_info; my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0)); return(true); if (key->type == Key::PRIMARY) key_info->usable_key_parts= key_number; return(true); key_iterator2.rewind (); { key_info->algorithm= key->key_create_info.algorithm; } if (key->type != Key::FOREIGN_KEY) if (primary_key) if (key->type == Key::PRIMARY && sql_field->vcol_info) { { /* Take block size from key part or table part */ { while ((key2 = key_iterator2++) != key) my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY), /* my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0)); { MYF(0)); TODO: Add warning if block size changes. We can't do it here, as return(true); /* return(true); this may depend on the size of the key } foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is } */ if (!(sql_field->flags & NOT_NULL_FLAG)) 'generated', and a generated key is a prefix of the other key. key_name=primary_key_name; key_info->block_size= (key->key_create_info.block_size ? { Then we do not need the generated shorter key. primary_key=1; key->key_create_info.block_size : if (key->type == Key::PRIMARY) */ } create_info->key_block_size); { if ((key2->type != Key::FOREIGN_KEY && else if (!(key_name= key->name.str)) /* Implicitly set primary key fields to NOT NULL for ISO conf. */ key2->name.str != ignore_key && key_name=make_unique_key_name(sql_field->field_name, if (key_info->block_size) sql_field->flags|= NOT_NULL_FLAG; !foreign_key_prefix(key, key2))) *key_info_buffer, key_info->flags|= HA_USES_BLOCK_SIZE; sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL; { key_info); null_fields--; /* TODO: issue warning message */ if (check_if_keyname_exists(key_name, *key_info_buffer, key_info)) uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info, } /* mark that the generated key should be ignored */ { key->key_create_info.comment.str, else if (!key2->generated || my_error(ER_DUP_KEYNAME, MYF(0), key_name); key->key_create_info.comment.str + { (key->generated && key->columns.elements < return(true); key->key_create_info.comment.length, key_info->flags|= HA_NULL_PART_KEY; key2->columns.elements)) } INDEX_COMMENT_MAXLEN); if (!(file->ha_table_flags() & HA_NULL_IN_KEY)) key->name.str= ignore_key; key_info->name=(char*) key_name; { else } if (tmp_len < key->key_create_info.comment.length) my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str); { } { return(true); key2->name.str= ignore_key; if (!key_info->name || check_column_name(key_info->name)) my_error(ER_WRONG_STRING_LENGTH, MYF(0), } key_parts-= key2->columns.elements; { key->key_create_info.comment.str,quot;INDEX COMMENTquot;, } (*key_count)--; my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name); (uint) INDEX_COMMENT_MAXLEN); } } return(true); return(-1); if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) break; } } { } if (!(key_info->flags & HA_NULL_PART_KEY)) if (column_nr == 0 || (file->ha_table_flags() & } unique_key=1; key_info->comment.length= key->key_create_info.comment.length; HA_AUTO_PART_KEY)) } key_info->key_length=(uint16_t) key_length; if (key_info->comment.length > 0) auto_increment--; // if (key->name.str != ignore_key) if (key_length > max_key_length) { Field is used key_parts+=key->columns.elements; { key_info->flags|= HA_USES_COMMENT; } else my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length); key_info->comment.str= key->key_create_info.comment.str; } (*key_count)--; return(true); } if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) && } key_part_info->fieldnr= field; !my_strcasecmp(system_charset_info,key->name.str, primary_key_name)) key_info++; List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns); key_part_info->offset= (uint16_t) sql_field->offset; { } for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++) key_part_info->key_type=sql_field->pack_flag; my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str); if (!unique_key && !primary_key && { length= sql_field->key_length; return(true); (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY)) uint32_t length; } { Key_part_spec *dup_column; if (column->length) } my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0)); { tmp=file->max_keys(); return(true); it.rewind(); if (f_is_blob(sql_field->pack_flag)) if (*key_count > tmp) } field=0; { { if (auto_increment > 0) while ((sql_field=it++) && if ((length=column->length) > max_key_length || my_error(ER_TOO_MANY_KEYS,MYF(0),tmp); { my_strcasecmp(system_charset_info, length > file->max_key_part_length()) return(true); my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0)); column->field_name.str, { } return(true); sql_field->field_name)) length=cmin(max_key_length, file->max_key_part_length()); } field++; if (key->type == Key::MULTIPLE) (*key_info_buffer)= key_info= (KEY*) sql_calloc(sizeof(KEY) * (*key_count)); /* Sort keys in optimized order */ if (!sql_field) { key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts); my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KEY), { /* not a critical problem */ if (!*key_info_buffer || ! key_part_info) (qsort_cmp) sort_keys); my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column- char warn_buff[DRIZZLE_ERRMSG_SIZE]; return(true); // Out of memory create_info->null_bits= null_fields; >field_name.str); snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY), return(true); length); key_iterator.rewind(); /* Check fields. */ } push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, key_number=0; it.rewind(); while ((dup_column= cols2++) != column) ER_TOO_LONG_KEY, warn_buff); for (; (key=key_iterator++) ; key_number++) while ((sql_field=it++)) { /* Align key length to multibyte char boundary */ { { if (!my_strcasecmp(system_charset_info, length-= length % sql_field->charset->mbmaxlen; uint32_t key_length=0; Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check); column->field_name.str, dup_column- } Key_part_spec *column; >field_name.str)) else if (session->variables.sql_mode & MODE_NO_ZERO_DATE && { { if (key->name.str == ignore_key) !sql_field->def && my_printf_error(ER_DUP_FIELDNAME, my_error(ER_TOO_LONG_KEY,MYF(0),length); { sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP && ER(ER_DUP_FIELDNAME),MYF(0), return(true); /* ignore redundant keys */ (sql_field->flags & NOT_NULL_FLAG) && column->field_name.str); } do (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD)) return(true); } key=key_iterator++; { } } while (key && key->name.str == ignore_key); /* } else if ((column->length > length || if (!key) An error should be reported if: cols2.rewind(); !Field::type_can_have_key_part (sql_field->sql_type) || break; - NO_ZERO_DATE SQL mode is active; { ((f_is_packed(sql_field->pack_flag) || } - there is no explicit DEFAULT clause (default column value); column->length*= sql_field->charset->mbmaxlen; ((file->ha_table_flags() & - this is a TIMESTAMP column; HA_NO_PREFIX_CHAR_KEYS) && switch (key->type) { - the column is not NULL; if (f_is_blob(sql_field->pack_flag)) (key_info->flags & HA_NOSAME))) && case Key::MULTIPLE: - this is not the DEFAULT CURRENT_TIMESTAMP column. { column->length != length))) key_info->flags= 0; if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS)) { break; In other words, an error should be reported if { my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), case Key::FOREIGN_KEY: - NO_ZERO_DATE SQL mode is active; my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str); MYF(0)); key_number--; // Skip this key - the column definition is equivalent to return(true); return(true); continue; 'column_name TIMESTAMP DEFAULT 0'. } } default: */ if (!column->length) else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS)) key_info->flags = HA_NOSAME; { length=column->length; break; my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column- } } return(true); >field_name.str); else if (length == 0) if (key->generated) } return(true); { key_info->flags|= HA_GENERATED_KEY; } } my_error(ER_WRONG_KEY_COLUMN, MYF(0), column- } >field_name.str); return(false); return(true); } }
  • 14. Use standard libraries Related to magic in the code  Enables code re-use and allows Drizzle to take  advantage of a large community of domain experts and developers Allows Drizzle to focus on Drizzle, and library  developers to focus on library code Happy to send patches to library developers,  but not good to reinvent the wheel
  • 15. No new global contention points Performance != scalability  Drizzle is focused more on scalability than raw  performance The days of 16 concurrent connections are OVER  Drizzle is targeting applications which  consistently serve 1024+ concurrent connections Global mutexes negatively impact scalability, so  no new global mutexes Remove existing global contention points in  favor of atomics, RCU, and other strategies
  • 16. The soundbite More contributors  Focus on APIs, clean code, standard libraries, open − and public discourse Easier to contribute  Cleaner, more standardized code, fully public peer − and code review, friendly community of mentors Scalability over raw performance  No new global mutexes, research on atomics, RCU, − and other modern lock-free techniques
  • 17. And we hope this leads to... More eyes capable of disecting and discussing the code, which leads to steady progress in performance and scalability
  • 19. Resources Launchpad - http://launchpad.net/drizzle Wiki - http://drizzle.org/wiki/Main_Page Discuss - https://launchpad.net/~drizzle-discuss Freenode - #drizzle