~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/main.cc

  • Committer: Lee Bieber
  • Date: 2010-11-20 22:04:04 UTC
  • mfrom: (1942.1.4 b)
  • Revision ID: kalebral@gmail.com-20101120220404-2qpb4xuik9wv9u1q
Merge Lee -  Run bzr ignore for leftover files
Merge Shrews - Add a --replicate-query option to the server which controls whether or not the SQL query string is included in the GPB Statement messages.
Merge Andrew - fix bug 665119: drizzleslap has -i mapped to two options
Merge Andrew fix bug 674145: Table Names Not Case Matched

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
44
44
 
45
45
#include <boost/filesystem.hpp>
46
46
 
47
 
#include <drizzled/abort_exception.h>
48
 
#include <drizzled/catalog/local.h>
49
 
#include <drizzled/configmake.h>
50
 
#include <drizzled/data_home.h>
51
 
#include <drizzled/debug.h>
52
 
#include <drizzled/drizzled.h>
53
 
#include <drizzled/errmsg_print.h>
54
 
#include <drizzled/gettext.h>
55
 
#include <drizzled/internal/my_sys.h>
56
 
#include <drizzled/plugin.h>
57
 
#include <drizzled/plugin/client.h>
58
 
#include <drizzled/plugin/listen.h>
59
 
#include <drizzled/plugin/monitored_in_transaction.h>
60
 
#include <drizzled/pthread_globals.h>
61
 
#include <drizzled/replication_services.h>
62
 
#include <drizzled/session.h>
63
 
#include <drizzled/session/cache.h>
64
 
#include <drizzled/signal_handler.h>
65
 
#include <drizzled/transaction_services.h>
66
 
#include <drizzled/tztime.h>
67
 
#include <drizzled/unireg.h>
68
 
#include <drizzled/util/backtrace.h>
 
47
#include "drizzled/plugin.h"
 
48
#include "drizzled/gettext.h"
 
49
#include "drizzled/configmake.h"
 
50
#include "drizzled/session.h"
 
51
#include "drizzled/session_list.h"
 
52
#include "drizzled/internal/my_sys.h"
 
53
#include "drizzled/unireg.h"
 
54
#include "drizzled/drizzled.h"
 
55
#include "drizzled/errmsg_print.h"
 
56
#include "drizzled/data_home.h"
 
57
#include "drizzled/plugin/listen.h"
 
58
#include "drizzled/plugin/client.h"
 
59
#include "drizzled/pthread_globals.h"
 
60
#include "drizzled/tztime.h"
 
61
#include "drizzled/signal_handler.h"
 
62
#include "drizzled/replication_services.h"
 
63
#include "drizzled/transaction_services.h"
69
64
 
70
 
extern "C" int daemonize(int nochdir, int noclose, int wait_sigusr1);
71
 
extern "C" int daemon_is_ready(void);
 
65
#include "drizzled/util/backtrace.h"
72
66
 
73
67
using namespace drizzled;
74
68
using namespace std;
77
71
static pthread_t select_thread;
78
72
static uint32_t thr_kill_signal;
79
73
 
80
 
extern bool opt_daemon;
81
 
 
82
74
 
83
75
/**
84
76
  All global error messages are sent here where the first one is stored
85
77
  for the client.
86
78
*/
87
 
static void my_message_sql(drizzled::error_t error, const char *str, myf MyFlags)
 
79
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
88
80
{
89
81
  Session *session;
90
82
  /*
97
89
      session->is_fatal_error= 1;
98
90
 
99
91
    /*
100
 
      @TODO There are two exceptions mechanism (Session and sp_rcontext),
 
92
      TODO: There are two exceptions mechanism (Session and sp_rcontext),
101
93
      this could be improved by having a common stack of handlers.
102
94
    */
103
 
    if (session->handle_error(error, str, DRIZZLE_ERROR::WARN_LEVEL_ERROR))
104
 
      return;
 
95
    if (session->handle_error(error, str,
 
96
                          DRIZZLE_ERROR::WARN_LEVEL_ERROR))
 
97
      return;;
105
98
 
106
99
    /*
107
100
      session->lex->current_select == 0 if lex structure is not inited
108
101
      (not query command (COM_QUERY))
109
102
    */
110
103
    if (! (session->lex->current_select &&
111
 
           session->lex->current_select->no_error && !session->is_fatal_error))
 
104
        session->lex->current_select->no_error && !session->is_fatal_error))
112
105
    {
113
106
      if (! session->main_da.is_error())            // Return only first message
114
107
      {
115
 
        if (error == EE_OK)
 
108
        if (error == 0)
116
109
          error= ER_UNKNOWN_ERROR;
117
 
 
118
110
        if (str == NULL)
119
111
          str= ER(error);
120
 
 
121
112
        session->main_da.set_error_status(error, str);
122
113
      }
123
114
    }
131
122
      session->no_warnings_for_error= true;
132
123
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
133
124
      session->no_warnings_for_error= false;
 
125
      }
134
126
    }
135
 
  }
136
 
 
137
 
  if (not session || MyFlags & ME_NOREFRESH)
138
 
  {
139
 
    errmsg_printf(error::ERROR, "%s: %s",internal::my_progname,str);
140
 
  }
 
127
    if (!session || MyFlags & ME_NOREFRESH)
 
128
        errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
141
129
}
142
130
 
143
131
static void init_signals(void)
145
133
  sigset_t set;
146
134
  struct sigaction sa;
147
135
 
148
 
  if (not (getDebug().test(debug::NO_STACKTRACE) || 
149
 
        getDebug().test(debug::CORE_ON_SIGNAL)))
 
136
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
 
137
        test_flags.test(TEST_CORE_ON_SIGNAL)))
150
138
  {
151
139
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
152
140
    sigemptyset(&sa.sa_mask);
162
150
    sigaction(SIGFPE, &sa, NULL);
163
151
  }
164
152
 
165
 
  if (getDebug().test(debug::CORE_ON_SIGNAL))
 
153
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
166
154
  {
167
155
    /* Change limits so that we will get a core file */
168
156
    struct rlimit rl;
169
157
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
170
158
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
171
 
        errmsg_printf(error::WARN,
 
159
        errmsg_printf(ERRMSG_LVL_WARN,
172
160
                      _("setrlimit could not change the size of core files "
173
161
                        "to 'infinity';  We may not be able to generate a "
174
162
                        "core file on signals"));
193
181
#ifdef SIGTSTP
194
182
  sigaddset(&set,SIGTSTP);
195
183
#endif
196
 
  if (getDebug().test(debug::ALLOW_SIGINT))
 
184
  if (test_flags.test(TEST_SIGINT))
197
185
  {
198
186
    sa.sa_flags= 0;
199
187
    sa.sa_handler= drizzled_end_thread_signal;
211
199
  return;
212
200
}
213
201
 
214
 
static void GoogleProtoErrorThrower(google::protobuf::LogLevel level,
215
 
                                    const char* ,
216
 
                                    int, const string& ) throw(const char *)
 
202
static void GoogleProtoErrorThrower(google::protobuf::LogLevel level, const char* filename,
 
203
                       int line, const string& message) throw(const char *)
217
204
{
 
205
  (void)filename;
 
206
  (void)line;
 
207
  (void)message;
 
208
  std::cerr << "\n";
 
209
  drizzled::util::custom_backtrace();
 
210
  std::cerr << "\n";
218
211
  switch(level)
219
212
  {
220
213
  case google::protobuf::LOGLEVEL_INFO:
223
216
  case google::protobuf::LOGLEVEL_ERROR:
224
217
  case google::protobuf::LOGLEVEL_FATAL:
225
218
  default:
 
219
    std::cerr << "GoogleProtoErrorThrower(" << filename << ", " << line << ", " << message << ")";
226
220
    throw("error in google protocol buffer parsing");
227
221
  }
228
222
}
233
227
# if defined(HAVE_LOCALE_H)
234
228
  setlocale(LC_ALL, "");
235
229
# endif
236
 
  bindtextdomain("drizzle7", LOCALEDIR);
237
 
  textdomain("drizzle7");
 
230
  bindtextdomain("drizzle", LOCALEDIR);
 
231
  textdomain("drizzle");
238
232
#endif
239
233
 
240
234
  module::Registry &modules= module::Registry::singleton();
 
235
  plugin::Client *client;
241
236
 
242
237
  MY_INIT(argv[0]);             // init my_sys library & pthreads
243
238
  /* nothing should come before this line ^^^ */
249
244
 
250
245
  /* Function generates error messages before abort */
251
246
  error_handler_hook= my_message_sql;
252
 
 
253
247
  /* init_common_variables must get basic settings such as data_home_dir
254
248
     and plugin_load_list. */
255
 
  if (init_basic_variables(argc, argv))
256
 
    unireg_abort(1);                            // Will do exit
257
 
 
258
 
  if (opt_daemon)
259
 
  {
260
 
    if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
261
 
    {
262
 
      perror("Failed to ignore SIGHUP");
263
 
    }
264
 
    if (daemonize(1, 1, 1) == -1)
265
 
    {
266
 
      fprintf(stderr, "failed to daemon() in order to daemonize\n");
267
 
      exit(EXIT_FAILURE);
268
 
    }
269
 
  }
270
 
 
271
 
  if (init_remaining_variables(modules))
 
249
  if (init_common_variables(argc, argv, modules))
272
250
    unireg_abort(1);                            // Will do exit
273
251
 
274
252
  /*
285
263
  {
286
264
    if (chdir(getDataHome().file_string().c_str()))
287
265
    {
288
 
      errmsg_printf(error::ERROR,
 
266
      errmsg_printf(ERRMSG_LVL_ERROR,
289
267
                    _("Data directory %s does not exist\n"),
290
268
                    getDataHome().file_string().c_str());
291
269
      unireg_abort(1);
296
274
    }
297
275
    if (chdir("local"))
298
276
    {
299
 
      errmsg_printf(error::ERROR,
 
277
      errmsg_printf(ERRMSG_LVL_ERROR,
300
278
                    _("Local catalog %s/local does not exist\n"),
301
279
                    getDataHome().file_string().c_str());
302
280
      unireg_abort(1);
303
281
    }
304
282
 
305
 
    fs::path &full_data_home= getFullDataHome();
306
283
    full_data_home= fs::system_complete(getDataHome());
307
 
    std::cerr << "home " << full_data_home << std::endl;
 
284
    getDataHomeCatalog()= "./";
 
285
    getDataHome()= "../";
308
286
  }
309
287
 
310
288
 
314
292
    server_id= 1;
315
293
  }
316
294
 
317
 
  try
318
 
  {
319
 
    if (init_server_components(modules))
320
 
      DRIZZLE_ABORT;
321
 
  }
322
 
  catch (abort_exception& ex)
323
 
  {
324
 
#if defined(DEBUG)
325
 
    cout << _("Drizzle has receieved an abort event.") << endl;
326
 
    cout << _("In Function: ") << *::boost::get_error_info<boost::throw_function>(ex) << endl;
327
 
    cout << _("In File: ") << *::boost::get_error_info<boost::throw_file>(ex) << endl;
328
 
    cout << _("On Line: ") << *::boost::get_error_info<boost::throw_line>(ex) << endl;
329
 
#endif
 
295
  if (init_server_components(modules))
330
296
    unireg_abort(1);
331
 
  }
332
 
 
333
297
 
334
298
  /**
335
299
   * This check must be done after init_server_components for now
348
312
  if (plugin::Listen::setup())
349
313
    unireg_abort(1);
350
314
 
 
315
 
351
316
  assert(plugin::num_trx_monitored_objects > 0);
352
 
  if (drizzle_rm_tmp_tables() || my_tz_init((Session *)0, default_tz_name))
 
317
  if (drizzle_rm_tmp_tables() ||
 
318
      my_tz_init((Session *)0, default_tz_name))
353
319
  {
354
320
    abort_loop= true;
355
321
    select_thread_in_use=0;
357
323
 
358
324
    (void) unlink(pid_file.file_string().c_str());      // Not needed anymore
359
325
 
360
 
    unireg_abort(1);
 
326
    exit(1);
361
327
  }
362
328
 
363
 
  errmsg_printf(error::INFO, _(ER(ER_STARTUP)), internal::my_progname,
 
329
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
364
330
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
365
331
 
366
332
 
368
334
 
369
335
  /* Send server startup event */
370
336
  {
371
 
    Session::shared_ptr session;
 
337
    Session *session;
372
338
 
373
 
    if ((session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local())))
 
339
    if ((session= new Session(plugin::Listen::getNullClient())))
374
340
    {
375
341
      currentSession().release();
376
 
      currentSession().reset(session.get());
377
 
 
378
 
 
379
 
      transaction_services.sendStartupEvent(*session);
380
 
 
381
 
      plugin_startup_window(modules, *(session.get()));
 
342
      currentSession().reset(session);
 
343
      transaction_services.sendStartupEvent(session);
 
344
      delete session;
382
345
    }
383
346
  }
384
347
 
385
 
  if (opt_daemon)
386
 
    daemon_is_ready();
387
348
 
388
 
  /* 
389
 
    Listen for new connections and start new session for each connection
 
349
  /* Listen for new connections and start new session for each connection
390
350
     accepted. The listen.getClient() method will return NULL when the server
391
 
     should be shutdown.
392
 
   */
393
 
  plugin::Client *client;
 
351
     should be shutdown. */
394
352
  while ((client= plugin::Listen::getClient()) != NULL)
395
353
  {
396
 
    Session::shared_ptr session;
397
 
    session= Session::make_shared(client, client->catalog());
 
354
    Session::shared_ptr session(new Session(client));
398
355
 
399
356
    if (not session)
400
357
    {
409
366
 
410
367
  /* Send server shutdown event */
411
368
  {
412
 
    Session::shared_ptr session;
 
369
    Session *session;
413
370
 
414
 
    if ((session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local())))
 
371
    if ((session= new Session(plugin::Listen::getNullClient())))
415
372
    {
416
373
      currentSession().release();
417
 
      currentSession().reset(session.get());
418
 
      transaction_services.sendShutdownEvent(*session.get());
 
374
      currentSession().reset(session);
 
375
      transaction_services.sendShutdownEvent(session);
 
376
      delete session;
419
377
    }
420
378
  }
421
379
 
426
384
  COND_thread_count.notify_all();
427
385
 
428
386
  /* Wait until cleanup is done */
429
 
  session::Cache::singleton().shutdownSecond();
 
387
  {
 
388
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
 
389
    while (not ready_to_exit)
 
390
      COND_server_end.wait(scopedLock);
 
391
  }
430
392
 
431
393
  clean_up(1);
432
394
  module::Registry::shutdown();