~ubuntu-branches/ubuntu/natty/mysql-5.1/natty

« back to all changes in this revision

Viewing changes to sql/log.cc

Tags: 5.1.54-1ubuntu1
* Synchronize from Debian Experimental:
* Merge from debian unstable:
  + debian/control:
     * Update maintainer according to spec.
     * Move section from "misc" to "database".
     * Added libmysqlclient16-dev an empty transitional package. 
     * Added mysql-client-core-5.1 package.
     * Suggest mailx for mysql-server-5.1
     * Add mysql-testsuite package so you can run the testsuite seperately.
  + debian/additions/my.cnf:
    * Remove language options. Error message files are located in a different directory in Mysql
      5.0. Setting the language option to use /usr/share/mysql/english breaks Mysql 5.0. Both 5.0
      and 5.1 use a different value that works. (LP: #316974)
  + Add apparmor profile:
    + debian/apparmor-profile: apparmor-profile
    + debian/rules, debian/mysql-server-5.1.files: install apparmor profile
    + debian/mysql-server-5.1.dirs: add etc/apparmor.d/fore-complain
    + debian/mysql-server-5.1.postrm: remove symlink in force-complain/ on purge.
    + debian/mysql-server-5.1.README.Debian: add apparmor documentation.
    + debian/additions/my.cnf: Add warning about apparmor. (LP: #201799)
    + debian/mysql-server-5.1.postinst: reload apparmor profiles
  * Convert the package from sysvinit to upstart:
    + debian/mysql-server-5.1.mysql.upstart: Add upstart script.
    + debian/mysql-server-5.1.mysql.init: Dropped, unused now with upstart.
    + debian/additions/mysqld_safe_syslog.cnf: Dropped, unused now with upstart.
    + debian/additons/my.cnf: Remove pid declaration and setup error logging to /var/log/mysql since
      we're not piping anything around logger anymore.
    + debian/rules, debian/mysql-server-5.1.logcheck.ignore.{paranoid,worstation},
      debian/mysql-server-5.1.logcheck.ignore.server: : Remove references to mysqld_safe
    + debian/patches/38_scripts_mysqld_safe.sh_signals.dpatch: Dropped
  * Added -fno-strict-aliasing to CFLAGS to get around mysql testsuite build failures.
  * Add Apport hook (LP: #354188):
    + debian/mysql-server-5.1.py: apport package hook
    + debian/rules: Make it installable
  * debian/mysql-server-5.1.mysql-server.logrotate: Check to see if mysql is running before
    running logrotate. (LP: #513135)
  * Make the testsuite installable. (LP: #530752)
    + debian/mysql-server-5.1.files, debian/rules: install apport package hook
  * debian/mysql-server-5.1.preinst: Set mysql user's home directory
    to /nonexistent to protect against having the /var/lib/mysql
    user-writeable. If an attacker can trick mysqld into creating
    dot files in the home directory, he could do .rhost-like attacks
    on the system. (LP: #293258)
  * debian/control: mysql-client-5.1 should depend on mysql-core-client-5.1.
    (LP: #590952)
  * debian/mysql-server.5.1.postinst: Specify the mysql user when installing 
    the mysql databases. (LP: #591875)
  * Installing mysql_config_pic in /usr/bin so users of libmysqld-pic
    can extract the appropriate compile flags. (LP: #605021) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1217
1217
    file_log= file_log_handler->get_mysql_log();
1218
1218
    break;
1219
1219
  default:
1220
 
    assert(0);                                  // Impossible
 
1220
    MY_ASSERT_UNREACHABLE();
1221
1221
  }
1222
1222
 
1223
1223
  if (!(*tmp_opt))
1628
1628
  DBUG_RETURN(error);
1629
1629
}
1630
1630
 
 
1631
/**
 
1632
  Cleanup the cache.
 
1633
 
 
1634
  @param thd   The client thread that wants to clean up the cache.
 
1635
*/
 
1636
void MYSQL_BIN_LOG::reset_gathered_updates(THD *thd)
 
1637
{
 
1638
  binlog_trx_data *const trx_data=
 
1639
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
 
1640
 
 
1641
  trx_data->reset();
 
1642
}
 
1643
 
1631
1644
void MYSQL_BIN_LOG::set_write_error(THD *thd)
1632
1645
{
1633
1646
  DBUG_ENTER("MYSQL_BIN_LOG::set_write_error");
1699
1712
 
1700
1713
  String log_query;
1701
1714
  if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) ||
1702
 
      log_query.append(thd->lex->ident.str, thd->lex->ident.length))
 
1715
      log_query.append("`") ||
 
1716
      log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
 
1717
      log_query.append("`"))
1703
1718
    DBUG_RETURN(1);
1704
1719
  int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
1705
1720
  Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
1721
1736
  {
1722
1737
    String log_query;
1723
1738
    if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) ||
1724
 
        log_query.append(thd->lex->ident.str, thd->lex->ident.length))
 
1739
        log_query.append("`") ||
 
1740
        log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
 
1741
        log_query.append("`"))
1725
1742
      DBUG_RETURN(1);
1726
1743
    int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
1727
1744
    Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
1862
1879
  file_info= dir_info->dir_entry;
1863
1880
  for (i=dir_info->number_off_files ; i-- ; file_info++)
1864
1881
  {
1865
 
    if (bcmp((uchar*) file_info->name, (uchar*) start, length) == 0 &&
 
1882
    if (memcmp(file_info->name, start, length) == 0 &&
1866
1883
        test_if_number(file_info->name+length, &number,0))
1867
1884
    {
1868
1885
      set_if_bigger(max_found,(ulong) number);
2583
2600
    sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file.");
2584
2601
    DBUG_RETURN(1);
2585
2602
  }
2586
 
  DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", abort(););
 
2603
  DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_SUICIDE(););
2587
2604
#endif
2588
2605
 
2589
2606
  write_error= 0;
2680
2697
    if (write_file_name_to_index_file)
2681
2698
    {
2682
2699
#ifdef HAVE_REPLICATION
2683
 
      DBUG_EXECUTE_IF("crash_create_critical_before_update_index", abort(););
 
2700
      DBUG_EXECUTE_IF("crash_create_critical_before_update_index", DBUG_SUICIDE(););
2684
2701
#endif
2685
2702
 
2686
2703
      DBUG_ASSERT(my_b_inited(&index_file) != 0);
2699
2716
        goto err;
2700
2717
 
2701
2718
#ifdef HAVE_REPLICATION
2702
 
      DBUG_EXECUTE_IF("crash_create_after_update_index", abort(););
 
2719
      DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_SUICIDE(););
2703
2720
#endif
2704
2721
    }
2705
2722
  }
3151
3168
  /* Store where we are in the new file for the execution thread */
3152
3169
  flush_relay_log_info(rli);
3153
3170
 
3154
 
  DBUG_EXECUTE_IF("crash_before_purge_logs", abort(););
 
3171
  DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE(););
3155
3172
 
3156
3173
  pthread_mutex_lock(&rli->log_space_lock);
3157
3174
  rli->relay_log.purge_logs(to_purge_if_included, included,
3279
3296
      break;
3280
3297
  }
3281
3298
 
3282
 
  DBUG_EXECUTE_IF("crash_purge_before_update_index", abort(););
 
3299
  DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_SUICIDE(););
3283
3300
 
3284
3301
  if ((error= sync_purge_index_file()))
3285
3302
  {
3294
3311
    goto err;
3295
3312
  }
3296
3313
 
3297
 
  DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", abort(););
 
3314
  DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", DBUG_SUICIDE(););
3298
3315
 
3299
3316
err:
3300
3317
  /* Read each entry from purge_index_file and delete the file. */
3304
3321
                    " that would be purged.");
3305
3322
  close_purge_index_file();
3306
3323
 
3307
 
  DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", abort(););
 
3324
  DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", DBUG_SUICIDE(););
3308
3325
 
3309
3326
  if (need_mutex)
3310
3327
    pthread_mutex_unlock(&LOCK_index);
4815
4832
                          DBUG_PRINT("info", ("error writing binlog cache: %d",
4816
4833
                                               write_error));
4817
4834
                        DBUG_PRINT("info", ("crashing before writing xid"));
4818
 
                        abort();
 
4835
                        DBUG_SUICIDE();
4819
4836
                      });
4820
4837
 
4821
4838
      if ((write_error= write_cache(cache, false, false)))
4829
4846
 
4830
4847
      if (flush_and_sync())
4831
4848
        goto err;
4832
 
      DBUG_EXECUTE_IF("half_binlogged_transaction", abort(););
 
4849
      DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE(););
4833
4850
      if (cache->error)                         // Error on read
4834
4851
      {
4835
4852
        sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
5050
5067
}
5051
5068
 
5052
5069
 
 
5070
#ifdef __WIN__
 
5071
extern "C" my_bool reopen_fstreams(const char *filename,
 
5072
                                   FILE *outstream, FILE *errstream)
 
5073
{
 
5074
  int handle_fd;
 
5075
  int err_fd, out_fd;
 
5076
  HANDLE osfh;
 
5077
 
 
5078
  DBUG_ASSERT(filename && errstream);
 
5079
 
 
5080
  // Services don't have stdout/stderr on Windows, so _fileno returns -1.
 
5081
  err_fd= _fileno(errstream);
 
5082
  if (err_fd < 0)
 
5083
  {
 
5084
    if (!freopen(filename, "a+", errstream))
 
5085
      return TRUE;
 
5086
 
 
5087
    setbuf(errstream, NULL);
 
5088
    err_fd= _fileno(errstream);
 
5089
  }
 
5090
 
 
5091
  if (outstream)
 
5092
  {
 
5093
    out_fd= _fileno(outstream);
 
5094
    if (out_fd < 0)
 
5095
    {
 
5096
      if (!freopen(filename, "a+", outstream))
 
5097
        return TRUE;
 
5098
      out_fd= _fileno(outstream);
 
5099
    }
 
5100
  }
 
5101
 
 
5102
  if ((osfh= CreateFile(filename, GENERIC_READ | GENERIC_WRITE,
 
5103
                        FILE_SHARE_READ | FILE_SHARE_WRITE |
 
5104
                        FILE_SHARE_DELETE, NULL,
 
5105
                        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
 
5106
                        NULL)) == INVALID_HANDLE_VALUE)
 
5107
    return TRUE;
 
5108
 
 
5109
  if ((handle_fd= _open_osfhandle((intptr_t)osfh,
 
5110
                                  _O_APPEND | _O_TEXT)) == -1)
 
5111
  {
 
5112
    CloseHandle(osfh);
 
5113
    return TRUE;
 
5114
  }
 
5115
 
 
5116
  if (_dup2(handle_fd, err_fd) < 0)
 
5117
  {
 
5118
    CloseHandle(osfh);
 
5119
    return TRUE;
 
5120
  }
 
5121
 
 
5122
  if (outstream && _dup2(handle_fd, out_fd) < 0)
 
5123
  {
 
5124
    CloseHandle(osfh);
 
5125
    return TRUE;
 
5126
  }
 
5127
 
 
5128
  _close(handle_fd);
 
5129
  return FALSE;
 
5130
}
 
5131
#else
 
5132
extern "C" my_bool reopen_fstreams(const char *filename,
 
5133
                                   FILE *outstream, FILE *errstream)
 
5134
{
 
5135
  if (outstream && !freopen(filename, "a+", outstream))
 
5136
    return TRUE;
 
5137
 
 
5138
  if (errstream && !freopen(filename, "a+", errstream))
 
5139
    return TRUE;
 
5140
 
 
5141
  return FALSE;
 
5142
}
 
5143
#endif
 
5144
 
 
5145
 
 
5146
/*
 
5147
  Unfortunately, there seems to be no good way
 
5148
  to restore the original streams upon failure.
 
5149
*/
 
5150
static bool redirect_std_streams(const char *file)
 
5151
{
 
5152
  if (reopen_fstreams(file, stdout, stderr))
 
5153
    return TRUE;
 
5154
 
 
5155
  setbuf(stderr, NULL);
 
5156
  return FALSE;
 
5157
}
 
5158
 
 
5159
 
5053
5160
bool flush_error_log()
5054
5161
{
5055
 
  bool result=0;
 
5162
  bool result= 0;
5056
5163
  if (opt_error_log)
5057
5164
  {
5058
 
    char err_renamed[FN_REFLEN], *end;
5059
 
    end= strmake(err_renamed,log_error_file,FN_REFLEN-5);
5060
 
    strmov(end, "-old");
5061
5165
    VOID(pthread_mutex_lock(&LOCK_error_log));
5062
 
#ifdef __WIN__
5063
 
    char err_temp[FN_REFLEN+5];
5064
 
    /*
5065
 
     On Windows is necessary a temporary file for to rename
5066
 
     the current error file.
5067
 
    */
5068
 
    strxmov(err_temp, err_renamed,"-tmp",NullS);
5069
 
    (void) my_delete(err_temp, MYF(0)); 
5070
 
    if (freopen(err_temp,"a+",stdout))
5071
 
    {
5072
 
      int fd;
5073
 
      size_t bytes;
5074
 
      uchar buf[IO_SIZE];
5075
 
 
5076
 
      freopen(err_temp,"a+",stderr);
5077
 
      setbuf(stderr, NULL);
5078
 
      (void) my_delete(err_renamed, MYF(0));
5079
 
      my_rename(log_error_file,err_renamed,MYF(0));
5080
 
      if (freopen(log_error_file,"a+",stdout))
5081
 
      {
5082
 
        freopen(log_error_file,"a+",stderr);
5083
 
        setbuf(stderr, NULL);
5084
 
      }
5085
 
 
5086
 
      if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
5087
 
      {
5088
 
        while ((bytes= my_read(fd, buf, IO_SIZE, MYF(0))) &&
5089
 
               bytes != MY_FILE_ERROR)
5090
 
          my_fwrite(stderr, buf, bytes, MYF(0));
5091
 
        my_close(fd, MYF(0));
5092
 
      }
5093
 
      (void) my_delete(err_temp, MYF(0)); 
5094
 
    }
5095
 
    else
5096
 
     result= 1;
5097
 
#else
5098
 
   my_rename(log_error_file,err_renamed,MYF(0));
5099
 
   if (freopen(log_error_file,"a+",stdout))
5100
 
   {
5101
 
     FILE *reopen;
5102
 
     reopen= freopen(log_error_file,"a+",stderr);
5103
 
     setbuf(stderr, NULL);
5104
 
   }
5105
 
   else
5106
 
     result= 1;
5107
 
#endif
 
5166
    if (redirect_std_streams(log_error_file))
 
5167
      result= 1;
5108
5168
    VOID(pthread_mutex_unlock(&LOCK_error_log));
5109
5169
  }
5110
 
   return result;
 
5170
  return result;
5111
5171
}
5112
5172
 
5113
5173
void MYSQL_BIN_LOG::signal_update()
5153
5213
#endif /* __NT__ */
5154
5214
 
5155
5215
 
5156
 
/**
5157
 
  Prints a printf style message to the error log and, under NT, to the
5158
 
  Windows event log.
5159
 
 
5160
 
  This function prints the message into a buffer and then sends that buffer
5161
 
  to other functions to write that message to other logging sources.
5162
 
 
5163
 
  @param event_type          Type of event to write (Error, Warning, or Info)
5164
 
  @param format              Printf style format of message
5165
 
  @param args                va_list list of arguments for the message
5166
 
 
5167
 
  @returns
5168
 
    The function always returns 0. The return value is present in the
5169
 
    signature to be compatible with other logging routines, which could
5170
 
    return an error (e.g. logging to the log tables)
5171
 
*/
5172
 
 
5173
5216
#ifndef EMBEDDED_LIBRARY
5174
 
static void print_buffer_to_file(enum loglevel level, const char *buffer)
 
5217
static void print_buffer_to_file(enum loglevel level, const char *buffer,
 
5218
                                 size_t length)
5175
5219
{
5176
5220
  time_t skr;
5177
5221
  struct tm tm_tmp;
5185
5229
  localtime_r(&skr, &tm_tmp);
5186
5230
  start=&tm_tmp;
5187
5231
 
5188
 
  fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n",
 
5232
  fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %.*s\n",
5189
5233
          start->tm_year % 100,
5190
5234
          start->tm_mon+1,
5191
5235
          start->tm_mday,
5194
5238
          start->tm_sec,
5195
5239
          (level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ?
5196
5240
           "Warning" : "Note"),
5197
 
          buffer);
 
5241
          (int) length, buffer);
5198
5242
 
5199
5243
  fflush(stderr);
5200
5244
 
5202
5246
  DBUG_VOID_RETURN;
5203
5247
}
5204
5248
 
5205
 
 
 
5249
/**
 
5250
  Prints a printf style message to the error log and, under NT, to the
 
5251
  Windows event log.
 
5252
 
 
5253
  This function prints the message into a buffer and then sends that buffer
 
5254
  to other functions to write that message to other logging sources.
 
5255
 
 
5256
  @param level          The level of the msg significance
 
5257
  @param format         Printf style format of message
 
5258
  @param args           va_list list of arguments for the message
 
5259
 
 
5260
  @returns
 
5261
    The function always returns 0. The return value is present in the
 
5262
    signature to be compatible with other logging routines, which could
 
5263
    return an error (e.g. logging to the log tables)
 
5264
*/
5206
5265
int vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
5207
5266
{
5208
5267
  char   buff[1024];
5210
5269
  DBUG_ENTER("vprint_msg_to_log");
5211
5270
 
5212
5271
  length= my_vsnprintf(buff, sizeof(buff), format, args);
5213
 
  print_buffer_to_file(level, buff);
 
5272
  print_buffer_to_file(level, buff, length);
5214
5273
 
5215
5274
#ifdef __NT__
5216
5275
  print_buffer_to_nt_eventlog(level, buff, length, sizeof(buff));
5218
5277
 
5219
5278
  DBUG_RETURN(0);
5220
5279
}
5221
 
#endif /*EMBEDDED_LIBRARY*/
 
5280
#endif /* EMBEDDED_LIBRARY */
5222
5281
 
5223
5282
 
5224
5283
void sql_print_error(const char *format, ...)