~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/log_event.cc

  • Committer: Brian Aker
  • Date: 2008-11-23 00:59:08 UTC
  • Revision ID: brian@tangent.org-20081123005908-yydyfzf60h8cc2zy
Update bits for replication

Show diffs side-by-side

added added

removed removed

Lines of Context:
1103
1103
 
1104
1104
 
1105
1105
/**
1106
 
  Utility function for the next method (Query_log_event::write()) .
1107
 
*/
1108
 
static void write_str_with_code_and_len(char **dst, const char *src,
1109
 
                                        int len, uint32_t code)
1110
 
{
1111
 
  assert(src);
1112
 
  *((*dst)++)= code;
1113
 
  *((*dst)++)= (unsigned char) len;
1114
 
  memcpy(*dst, src, len);
1115
 
  (*dst)+= len;
1116
 
}
1117
 
 
1118
 
 
1119
 
/**
1120
1106
  Query_log_event::write().
1121
1107
 
1122
1108
  @note
1201
1187
    int4store(start, flags2);
1202
1188
    start+= 4;
1203
1189
  }
1204
 
  if (sql_mode_inited)
1205
 
  {
1206
 
    *start++= Q_SQL_MODE_CODE;
1207
 
    int8store(start, (uint64_t)sql_mode);
1208
 
    start+= 8;
1209
 
  }
1210
 
  if (catalog_len) // i.e. this var is inited (false for 4.0 events)
1211
 
  {
1212
 
    write_str_with_code_and_len((char **)(&start),
1213
 
                                catalog, catalog_len, Q_CATALOG_NZ_CODE);
1214
 
    /*
1215
 
      In 5.0.x where x<4 masters we used to store the end zero here. This was
1216
 
      a waste of one byte so we don't do it in x>=4 masters. We change code to
1217
 
      Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
1218
 
      of this x>=4 master segfault (expecting a zero when there is
1219
 
      none). Remaining compatibility problems are: the older slave will not
1220
 
      find the catalog; but it is will not crash, and it's not an issue
1221
 
      that it does not find the catalog as catalogs were not used in these
1222
 
      older MySQL versions (we store it in binlog and read it from relay log
1223
 
      but do nothing useful with it). What is an issue is that the older slave
1224
 
      will stop processing the Q_* blocks (and jumps to the db/query) as soon
1225
 
      as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
1226
 
      Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
1227
 
      various ways. Documented that you should not mix alpha/beta versions if
1228
 
      they are not exactly the same version, with example of 5.0.3->5.0.2 and
1229
 
      5.0.4->5.0.3. If replication is from older to new, the new will
1230
 
      recognize Q_CATALOG_CODE and have no problem.
1231
 
    */
1232
 
  }
1233
 
  if (auto_increment_increment != 1 || auto_increment_offset != 1)
1234
 
  {
1235
 
    *start++= Q_AUTO_INCREMENT;
1236
 
    int2store(start, auto_increment_increment);
1237
 
    int2store(start+2, auto_increment_offset);
1238
 
    start+= 4;
1239
 
  }
1240
 
  if (charset_inited)
1241
 
  {
1242
 
    *start++= Q_CHARSET_CODE;
1243
 
    memcpy(start, charset, 6);
1244
 
    start+= 6;
1245
 
  }
1246
 
  if (time_zone_len)
1247
 
  {
1248
 
    /* In the TZ sys table, column Name is of length 64 so this should be ok */
1249
 
    assert(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
1250
 
    *start++= Q_TIME_ZONE_CODE;
1251
 
    *start++= time_zone_len;
1252
 
    memcpy(start, time_zone_str, time_zone_len);
1253
 
    start+= time_zone_len;
1254
 
  }
1255
1190
  if (lc_time_names_number)
1256
1191
  {
1257
1192
    assert(lc_time_names_number <= 0xFFFF);
1325
1260
  The value for local `killed_status' can be supplied by caller.
1326
1261
*/
1327
1262
Query_log_event::Query_log_event(Session* session_arg, const char* query_arg,
1328
 
                                 ulong query_length, bool using_trans,
1329
 
                                 bool suppress_use,
 
1263
                                 ulong query_length, bool using_trans,
 
1264
                                 bool suppress_use,
1330
1265
                                 Session::killed_state killed_status_arg)
1331
 
  :Log_event(session_arg,
1332
 
             (session_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
1333
 
              0) |
1334
 
             (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
1335
 
             using_trans),
1336
 
   data_buf(0), query(query_arg), catalog(session_arg->catalog),
1337
 
   db(session_arg->db), q_len((uint32_t) query_length),
1338
 
   thread_id(session_arg->thread_id),
1339
 
   /* save the original thread id; we already know the server id */
1340
 
   slave_proxy_id(session_arg->variables.pseudo_thread_id),
1341
 
   flags2_inited(1), sql_mode_inited(1), charset_inited(1),
1342
 
   sql_mode(0),
1343
 
   auto_increment_increment(session_arg->variables.auto_increment_increment),
1344
 
   auto_increment_offset(session_arg->variables.auto_increment_offset),
1345
 
   lc_time_names_number(session_arg->variables.lc_time_names->number),
 
1266
:Log_event(session_arg,
 
1267
           (session_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0) |
 
1268
           (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
 
1269
           using_trans),
 
1270
  data_buf(0), query(query_arg), catalog(session_arg->catalog),
 
1271
  db(session_arg->db), q_len((uint32_t) query_length),
 
1272
  thread_id(session_arg->thread_id),
 
1273
  /* save the original thread id; we already know the server id */
 
1274
  slave_proxy_id(session_arg->variables.pseudo_thread_id),
 
1275
  flags2_inited(1), sql_mode_inited(1), charset_inited(1),
 
1276
  sql_mode(0),
 
1277
  auto_increment_increment(session_arg->variables.auto_increment_increment),
 
1278
  auto_increment_offset(session_arg->variables.auto_increment_offset),
 
1279
  lc_time_names_number(session_arg->variables.lc_time_names->number),
1346
1280
   charset_database_number(0)
1347
1281
{
1348
1282
  time_t end_time;
1382
1316
  int2store(charset, session_arg->variables.character_set_client->number);
1383
1317
  int2store(charset+2, session_arg->variables.collation_connection->number);
1384
1318
  int2store(charset+4, session_arg->variables.collation_server->number);
1385
 
  if (session_arg->time_zone_used)
1386
 
  {
1387
 
    /*
1388
 
      Note that our event becomes dependent on the Time_zone object
1389
 
      representing the time zone. Fortunately such objects are never deleted
1390
 
      or changed during mysqld's lifetime.
1391
 
    */
1392
 
    time_zone_len= session_arg->variables.time_zone->get_name()->length();
1393
 
    time_zone_str= session_arg->variables.time_zone->get_name()->ptr();
1394
 
  }
1395
 
  else
1396
 
    time_zone_len= 0;
1397
 
}
1398
 
 
1399
 
 
1400
 
/* 2 utility functions for the next method */
1401
 
 
1402
 
/**
1403
 
   Read a string with length from memory.
1404
 
 
1405
 
   This function reads the string-with-length stored at
1406
 
   <code>src</code> and extract the length into <code>*len</code> and
1407
 
   a pointer to the start of the string into <code>*dst</code>. The
1408
 
   string can then be copied using <code>memcpy()</code> with the
1409
 
   number of bytes given in <code>*len</code>.
1410
 
 
1411
 
   @param src Pointer to variable holding a pointer to the memory to
1412
 
              read the string from.
1413
 
   @param dst Pointer to variable holding a pointer where the actual
1414
 
              string starts. Starting from this position, the string
1415
 
              can be copied using @c memcpy().
1416
 
   @param len Pointer to variable where the length will be stored.
1417
 
   @param end One-past-the-end of the memory where the string is
1418
 
              stored.
1419
 
 
1420
 
   @return    Zero if the entire string can be copied successfully,
1421
 
              @c UINT_MAX if the length could not be read from memory
1422
 
              (that is, if <code>*src >= end</code>), otherwise the
1423
 
              number of bytes that are missing to read the full
1424
 
              string, which happends <code>*dst + *len >= end</code>.
1425
 
*/
1426
 
static int
1427
 
get_str_len_and_pointer(const Log_event::Byte **src,
1428
 
                        const char **dst,
1429
 
                        uint32_t *len,
1430
 
                        const Log_event::Byte *end)
1431
 
{
1432
 
  if (*src >= end)
1433
 
    return -1;       // Will be UINT_MAX in two-complement arithmetics
1434
 
  uint32_t length= **src;
1435
 
  if (length > 0)
1436
 
  {
1437
 
    if (*src + length >= end)
1438
 
      return *src + length - end + 1;       // Number of bytes missing
1439
 
    *dst= (char *)*src + 1;                    // Will be copied later
1440
 
  }
1441
 
  *len= length;
1442
 
  *src+= length + 1;
1443
 
  return 0;
 
1319
  time_zone_len= 0;
1444
1320
}
1445
1321
 
1446
1322
static void copy_str_and_move(const char **src, 
1551
1427
      flags2= uint4korr(pos);
1552
1428
      pos+= 4;
1553
1429
      break;
1554
 
    case Q_SQL_MODE_CODE:
1555
 
    {
1556
 
      CHECK_SPACE(pos, end, 8);
1557
 
      sql_mode_inited= 1;
1558
 
      sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is uint64_t
1559
 
      pos+= 8;
1560
 
      break;
1561
 
    }
1562
 
    case Q_CATALOG_NZ_CODE:
1563
 
      if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
1564
 
      {
1565
 
        query= 0;
1566
 
        return;
1567
 
      }
1568
 
      break;
1569
 
    case Q_AUTO_INCREMENT:
1570
 
      CHECK_SPACE(pos, end, 4);
1571
 
      auto_increment_increment= uint2korr(pos);
1572
 
      auto_increment_offset=    uint2korr(pos+2);
1573
 
      pos+= 4;
1574
 
      break;
1575
 
    case Q_TIME_ZONE_CODE:
1576
 
    {
1577
 
      if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
1578
 
      {
1579
 
        query= 0;
1580
 
        return;
1581
 
      }
1582
 
      break;
1583
 
    }
1584
 
    case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
1585
 
      CHECK_SPACE(pos, end, 1);
1586
 
      if ((catalog_len= *pos))
1587
 
        catalog= (char*) pos+1;                           // Will be copied later
1588
 
      CHECK_SPACE(pos, end, catalog_len + 2);
1589
 
      pos+= catalog_len+2; // leap over end 0
1590
 
      catalog_nz= 0; // catalog has end 0 in event
1591
 
      break;
1592
1430
    case Q_LC_TIME_NAMES_CODE:
1593
1431
      CHECK_SPACE(pos, end, 2);
1594
1432
      lc_time_names_number= uint2korr(pos);