~ubuntu-branches/ubuntu/precise/mysql-5.5/precise-201203300109

« back to all changes in this revision

Viewing changes to sql/log.cc

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-02-14 23:59:22 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20120214235922-cux5uek1e5l0hje9
Tags: 5.5.20-0ubuntu1
* New upstream release.
* d/mysql-server-5.5.mysql.upstart: Fix stop on to make sure mysql is
  fully stopped before shutdown commences. (LP: #688541) Also simplify
  start on as it is redundant.
* d/control: Depend on upstart version which has apparmor profile load
  script to prevent failure on upgrade from lucid to precise.
  (LP: #907465)
* d/apparmor-profile: need to allow /run since that is the true path
  of /var/run files. (LP: #917542)
* d/control: mysql-server-5.5 has files in it that used to be owned
  by libmysqlclient-dev, so it must break/replace it. (LP: #912487)
* d/rules, d/control: 5.5.20 Fixes segfault on tests with gcc 4.6,
  change compiler back to system default.
* d/rules: Turn off embedded libedit/readline.(Closes: #659566)

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
 
50
50
#include "sql_plugin.h"
51
51
#include "rpl_handler.h"
52
 
 
 
52
#include "debug_sync.h"
53
53
/* max size of the log message */
54
54
#define MAX_LOG_BUFFER_SIZE 1024
55
55
#define MAX_TIME_SIZE 32
3242
3242
                            bool need_lock)
3243
3243
{
3244
3244
  int error= 0;
3245
 
  char *fname= linfo->log_file_name;
3246
 
  uint log_name_len= log_name ? (uint) strlen(log_name) : 0;
 
3245
  char *full_fname= linfo->log_file_name;
 
3246
  char full_log_name[FN_REFLEN], fname[FN_REFLEN];
 
3247
  uint log_name_len= 0, fname_len= 0;
3247
3248
  DBUG_ENTER("find_log_pos");
3248
 
  DBUG_PRINT("enter",("log_name: %s", log_name ? log_name : "NULL"));
 
3249
  full_log_name[0]= full_fname[0]= 0;
3249
3250
 
3250
3251
  /*
3251
3252
    Mutex needed because we need to make sure the file pointer does not
3255
3256
    mysql_mutex_lock(&LOCK_index);
3256
3257
  mysql_mutex_assert_owner(&LOCK_index);
3257
3258
 
 
3259
  // extend relative paths for log_name to be searched
 
3260
  if (log_name)
 
3261
  {
 
3262
    if(normalize_binlog_name(full_log_name, log_name, is_relay_log))
 
3263
    {
 
3264
      error= LOG_INFO_EOF;
 
3265
      goto end;
 
3266
    }
 
3267
  }
 
3268
 
 
3269
  log_name_len= log_name ? (uint) strlen(full_log_name) : 0;
 
3270
  DBUG_PRINT("enter", ("log_name: %s, full_log_name: %s", 
 
3271
                       log_name ? log_name : "NULL", full_log_name));
 
3272
 
3258
3273
  /* As the file is flushed, we can't get an error here */
3259
3274
  (void) reinit_io_cache(&index_file, READ_CACHE, (my_off_t) 0, 0, 0);
3260
3275
 
3273
3288
      break;
3274
3289
    }
3275
3290
 
 
3291
    // extend relative paths and match against full path
 
3292
    if (normalize_binlog_name(full_fname, fname, is_relay_log))
 
3293
    {
 
3294
      error= LOG_INFO_EOF;
 
3295
      break;
 
3296
    }
 
3297
    fname_len= (uint) strlen(full_fname);
 
3298
 
3276
3299
    // if the log entry matches, null string matching anything
3277
3300
    if (!log_name ||
3278
 
        (log_name_len == length-1 && fname[log_name_len] == '\n' &&
3279
 
         !memcmp(fname, log_name, log_name_len)))
 
3301
        (log_name_len == fname_len-1 && full_fname[log_name_len] == '\n' &&
 
3302
         !memcmp(full_fname, full_log_name, log_name_len)))
3280
3303
    {
3281
 
      DBUG_PRINT("info",("Found log file entry"));
3282
 
      fname[length-1]=0;                        // remove last \n
 
3304
      DBUG_PRINT("info", ("Found log file entry"));
 
3305
      full_fname[fname_len-1]= 0;                       // remove last \n
3283
3306
      linfo->index_file_start_offset= offset;
3284
3307
      linfo->index_file_offset = my_b_tell(&index_file);
3285
3308
      break;
3286
3309
    }
3287
3310
  }
3288
3311
 
 
3312
end:
3289
3313
  if (need_lock)
3290
3314
    mysql_mutex_unlock(&LOCK_index);
3291
3315
  DBUG_RETURN(error);
3320
3344
{
3321
3345
  int error= 0;
3322
3346
  uint length;
3323
 
  char *fname= linfo->log_file_name;
 
3347
  char fname[FN_REFLEN];
 
3348
  char *full_fname= linfo->log_file_name;
3324
3349
 
3325
3350
  if (need_lock)
3326
3351
    mysql_mutex_lock(&LOCK_index);
3336
3361
    error = !index_file.error ? LOG_INFO_EOF : LOG_INFO_IO;
3337
3362
    goto err;
3338
3363
  }
3339
 
  fname[length-1]=0;                            // kill \n
3340
 
  linfo->index_file_offset = my_b_tell(&index_file);
 
3364
 
 
3365
  if (fname[0] != 0)
 
3366
  {
 
3367
    if(normalize_binlog_name(full_fname, fname, is_relay_log))
 
3368
    {
 
3369
      error= LOG_INFO_EOF;
 
3370
      goto err;
 
3371
    }
 
3372
    length= strlen(full_fname);
 
3373
  }
 
3374
 
 
3375
  full_fname[length-1]= 0;                      // kill \n
 
3376
  linfo->index_file_offset= my_b_tell(&index_file);
3341
3377
 
3342
3378
err:
3343
3379
  if (need_lock)
5002
5038
      {
5003
5039
        bool synced;
5004
5040
        if ((error= flush_and_sync(&synced)))
5005
 
          goto unlock;
5006
 
 
5007
 
        if ((error= RUN_HOOK(binlog_storage, after_flush,
 
5041
        {
 
5042
          mysql_mutex_unlock(&LOCK_log);
 
5043
        }
 
5044
        else if ((error= RUN_HOOK(binlog_storage, after_flush,
5008
5045
                 (thd, log_file_name, file->pos_in_file, synced))))
5009
5046
        {
5010
5047
          sql_print_error("Failed to run 'after_flush' hooks");
5011
 
          goto unlock;
 
5048
          mysql_mutex_unlock(&LOCK_log);
 
5049
        } 
 
5050
        else
 
5051
        {
 
5052
          bool check_purge;
 
5053
          signal_update();
 
5054
          error= rotate(false, &check_purge);
 
5055
          mysql_mutex_unlock(&LOCK_log);
 
5056
          if (!error && check_purge)
 
5057
            purge();
5012
5058
        }
5013
 
        signal_update();
5014
 
        rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
5015
 
      }
5016
 
unlock:
5017
 
      mysql_mutex_unlock(&LOCK_log);
 
5059
      }
 
5060
      else
 
5061
      {
 
5062
        mysql_mutex_unlock(&LOCK_log);
 
5063
      }
5018
5064
    }
5019
5065
 
5020
5066
    if (error)
5100
5146
}
5101
5147
 
5102
5148
/**
 
5149
  The method executes rotation when LOCK_log is already acquired
 
5150
  by the caller.
 
5151
 
 
5152
  @param force_rotate  caller can request the log rotation
 
5153
  @param check_purge   is set to true if rotation took place
 
5154
 
5103
5155
  @note
5104
5156
    If rotation fails, for instance the server was unable 
5105
5157
    to create a new log file, we still try to write an 
5106
5158
    incident event to the current log.
5107
5159
 
5108
5160
  @retval
5109
 
    nonzero - error 
 
5161
    nonzero - error in rotating routine.
5110
5162
*/
5111
 
int MYSQL_BIN_LOG::rotate_and_purge(uint flags)
 
5163
int MYSQL_BIN_LOG::rotate(bool force_rotate, bool* check_purge)
5112
5164
{
5113
5165
  int error= 0;
5114
 
  DBUG_ENTER("MYSQL_BIN_LOG::rotate_and_purge");
5115
 
#ifdef HAVE_REPLICATION
5116
 
  bool check_purge= false;
5117
 
#endif
5118
 
  if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
5119
 
    mysql_mutex_lock(&LOCK_log);
5120
 
  if ((flags & RP_FORCE_ROTATE) ||
5121
 
      (my_b_tell(&log_file) >= (my_off_t) max_size))
 
5166
  DBUG_ENTER("MYSQL_BIN_LOG::rotate");
 
5167
 
 
5168
  //todo: fix the macro def and restore safe_mutex_assert_owner(&LOCK_log);
 
5169
  *check_purge= false;
 
5170
 
 
5171
  if (force_rotate || (my_b_tell(&log_file) >= (my_off_t) max_size))
5122
5172
  {
5123
5173
    if ((error= new_file_without_locking()))
5124
5174
      /** 
5133
5183
      if (!write_incident(current_thd, FALSE))
5134
5184
        flush_and_sync(0);
5135
5185
 
5136
 
#ifdef HAVE_REPLICATION
5137
 
    check_purge= true;
5138
 
#endif
 
5186
    *check_purge= true;
5139
5187
  }
5140
 
  if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
5141
 
    mysql_mutex_unlock(&LOCK_log);
 
5188
  DBUG_RETURN(error);
 
5189
}
 
5190
 
 
5191
/**
 
5192
  The method executes logs purging routine.
 
5193
 
 
5194
  @retval
 
5195
    nonzero - error in rotating routine.
 
5196
*/
 
5197
void MYSQL_BIN_LOG::purge()
 
5198
{
5142
5199
#ifdef HAVE_REPLICATION
5143
 
  /*
5144
 
    NOTE: Run purge_logs wo/ holding LOCK_log
5145
 
          as it otherwise will deadlock in ndbcluster_binlog_index_purge_file
5146
 
  */
5147
 
  if (!error && check_purge && expire_logs_days)
 
5200
  if (expire_logs_days)
5148
5201
  {
 
5202
    DEBUG_SYNC(current_thd, "at_purge_logs_before_date");
5149
5203
    time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
5150
5204
    if (purge_time >= 0)
 
5205
    {
5151
5206
      purge_logs_before_date(purge_time);
 
5207
    }
5152
5208
  }
5153
5209
#endif
 
5210
}
 
5211
 
 
5212
/**
 
5213
  The method is a shortcut of @c rotate() and @c purge().
 
5214
  LOCK_log is acquired prior to rotate and is released after it.
 
5215
 
 
5216
  @param force_rotate  caller can request the log rotation
 
5217
 
 
5218
  @retval
 
5219
    nonzero - error in rotating routine.
 
5220
*/
 
5221
int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate)
 
5222
{
 
5223
  int error= 0;
 
5224
  DBUG_ENTER("MYSQL_BIN_LOG::rotate_and_purge");
 
5225
  bool check_purge= false;
 
5226
 
 
5227
  //todo: fix the macro def and restore safe_mutex_assert_not_owner(&LOCK_log);
 
5228
  mysql_mutex_lock(&LOCK_log);
 
5229
  error= rotate(force_rotate, &check_purge);
 
5230
  /*
 
5231
    NOTE: Run purge_logs wo/ holding LOCK_log because it does not need
 
5232
          the mutex. Otherwise causes various deadlocks.
 
5233
  */
 
5234
  mysql_mutex_unlock(&LOCK_log);
 
5235
 
 
5236
  if (!error && check_purge)
 
5237
    purge();
 
5238
 
5154
5239
  DBUG_RETURN(error);
5155
5240
}
5156
5241
 
5352
5437
  {
5353
5438
    if (!error && !(error= flush_and_sync(0)))
5354
5439
    {
 
5440
      bool check_purge= false;
5355
5441
      signal_update();
5356
 
      error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
5357
 
    }
5358
 
    mysql_mutex_unlock(&LOCK_log);
 
5442
      error= rotate(false, &check_purge);
 
5443
      mysql_mutex_unlock(&LOCK_log);
 
5444
      if (!error && check_purge)
 
5445
        purge();
 
5446
    }
 
5447
    else
 
5448
    {
 
5449
      mysql_mutex_unlock(&LOCK_log);
 
5450
    }
5359
5451
  }
5360
5452
  DBUG_RETURN(error);
5361
5453
}
5388
5480
                          bool incident)
5389
5481
{
5390
5482
  DBUG_ENTER("MYSQL_BIN_LOG::write(THD *, IO_CACHE *, Log_event *)");
5391
 
  mysql_mutex_lock(&LOCK_log);
5392
5483
 
5393
5484
  DBUG_ASSERT(is_open());
5394
5485
  if (likely(is_open()))                       // Should always be true
5395
5486
  {
 
5487
    bool check_purge;
 
5488
    
 
5489
    mysql_mutex_lock(&LOCK_log);
5396
5490
    /*
5397
5491
      We only bother to write to the binary log if there is anything
5398
5492
      to write.
5460
5554
      mysql_mutex_lock(&LOCK_prep_xids);
5461
5555
      prepared_xids++;
5462
5556
      mysql_mutex_unlock(&LOCK_prep_xids);
 
5557
      mysql_mutex_unlock(&LOCK_log);
5463
5558
    }
5464
5559
    else
5465
 
      if (rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED))
 
5560
    {
 
5561
      if (rotate(false, &check_purge))
5466
5562
        goto err;
 
5563
      mysql_mutex_unlock(&LOCK_log);
 
5564
      if (check_purge) 
 
5565
        purge();
 
5566
    }
5467
5567
  }
5468
 
  mysql_mutex_unlock(&LOCK_log);
5469
5568
 
5470
5569
  DBUG_RETURN(0);
5471
5570