List:Commits« Previous MessageNext Message »
From:Marc Alff Date:June 4 2009 9:26pm
Subject:bzr push into mysql-6.0-perfschema branch (marc.alff:3159 to 3161)
View as plain text  
 3161 Marc Alff	2009-06-04
      Added doxygen comments, fixed a crash for test sp-security
      modified:
        sql/sql_acl.cc
        sql/sql_acl.h
        sql/table.h

 3160 Marc Alff	2009-06-04
      WL#4876 Parse options before initializing mysys
      
      Implemented code review comments
      modified:
        include/my_pthread.h
        mysys/my_getopt.c
        mysys/my_init.c
        mysys/my_thr_init.c
        mysys/waiting_threads.c
        sql/mysql_priv.h
        sql/mysqld.cc
        sql/set_var.cc
        sql/set_var.h
        sql/sql_plugin.cc
        sql/sql_repl.cc

 3159 Marc Alff	2009-06-03
      Implementing comments from QA
      modified:
        mysql-test/suite/perfschema/t/maria_mutex.test
        mysql-test/suite/perfschema/t/no_threads.test
        mysql-test/suite/perfschema/t/one_thread_per_con.test

=== modified file 'include/my_pthread.h'
--- a/include/my_pthread.h	2009-05-29 01:48:47 +0000
+++ b/include/my_pthread.h	2009-06-04 17:02:25 +0000
@@ -622,7 +622,7 @@ typedef ulong my_thread_id;
 
 extern void my_threadattr_global_init(void);
 extern my_bool my_thread_basic_global_init(void);
-extern my_bool my_thread_basic_global_reinit(void);
+extern void my_thread_basic_global_reinit(void);
 extern my_bool my_thread_global_init(void);
 extern void my_reinit_mutexes(void);
 extern void my_thread_global_end(void);

=== modified file 'mysys/my_getopt.c'
--- a/mysys/my_getopt.c	2009-05-14 08:56:34 +0000
+++ b/mysys/my_getopt.c	2009-06-04 17:02:25 +0000
@@ -417,9 +417,9 @@ invalid value '%s'",
 				       my_progname, optp->name, optend);
 	      continue;
 	    }
-	    if (get_one_option(optp->id, optp,
-                               *((my_bool*) value) ?
-                               (char*) "1" : disabled_my_option))
+	    if (get_one_option && get_one_option(optp->id, optp,
+                                                 *((my_bool*) value) ?
+                                                 (char*) "1" : disabled_my_option))
               return EXIT_ARGUMENT_INVALID;
 	    continue;
 	  }
@@ -482,7 +482,7 @@ invalid value '%s'",
 		  optp->arg_type == NO_ARG)
 	      {
 		*((my_bool*) optp->value)= (my_bool) 1;
-		if (get_one_option(optp->id, optp, argument))
+		if (get_one_option && get_one_option(optp->id, optp, argument))
                   return EXIT_UNSPECIFIED_ERROR;
 		continue;
 	      }
@@ -502,7 +502,7 @@ invalid value '%s'",
                   {
                     if (optp->var_type == GET_BOOL)
                       *((my_bool*) optp->value)= (my_bool) 1;
-                    if (get_one_option(optp->id, optp, argument))
+                    if (get_one_option && get_one_option(optp->id, optp, argument))
                       return EXIT_UNSPECIFIED_ERROR;
                     continue;
                   }
@@ -528,7 +528,7 @@ invalid value '%s'",
                                          my_progname, argument, optp->name);
 		return error;
 	      }
-	      if (get_one_option(optp->id, optp, argument))
+	      if (get_one_option && get_one_option(optp->id, optp, argument))
                 return EXIT_UNSPECIFIED_ERROR;
 	      break;
 	    }
@@ -552,7 +552,7 @@ invalid value '%s'",
                                  my_progname, argument, optp->name);
 	return error;
       }
-      if (get_one_option(optp->id, optp, argument))
+      if (get_one_option && get_one_option(optp->id, optp, argument))
         return EXIT_UNSPECIFIED_ERROR;
 
       (*argc)--; /* option handled (short or long), decrease argument count */

=== modified file 'mysys/my_init.c'
--- a/mysys/my_init.c	2009-05-28 21:33:45 +0000
+++ b/mysys/my_init.c	2009-06-04 17:02:25 +0000
@@ -43,6 +43,7 @@ static void netware_init();
 #endif
 
 my_bool my_init_done= 0;
+/** True if @c my_basic_init() has been called. */
 my_bool my_basic_init_done= 0;
 uint	mysys_usage_id= 0;              /* Incremented for each my_init() */
 ulong   my_thread_stack_size= 65536;
@@ -67,12 +68,32 @@ static MYSQL_FILE instrumented_stdout;
 static MYSQL_FILE instrumented_stderr;
 #endif
 
+/**
+  Perform a limited initialisation of mysys.
+  This initialisation is sufficient to:
+  - allocate memory,
+  - read configuration files,
+  - parse command lines arguments.
+  To complete the mysys initialisation,
+  call my_init().
+  @return 0 on success
+*/
 my_bool my_basic_init(void)
 {
   if (my_basic_init_done)
     return 0;
   my_basic_init_done= 1;
 
+  mysys_usage_id++;
+  my_umask= 0660;                       /* Default umask for new files */
+  my_umask_dir= 0700;                   /* Default umask for new directories */
+
+  init_glob_errs();
+  if (my_progname)
+    my_progname_short= base_name(my_progname);
+  else
+    my_progname_short= "unknown";
+
 #ifdef HAVE_PSI_INTERFACE
   instrumented_stdin.m_file= stdin;
   instrumented_stdin.m_psi= NULL;
@@ -130,15 +151,6 @@ my_bool my_init(void)
   if (my_basic_init())
     return 1;
 
-  mysys_usage_id++;
-  my_umask= 0660;                       /* Default umask for new files */
-  my_umask_dir= 0700;                   /* Default umask for new directories */
-
-  init_glob_errs();
-  my_progname_short= "unknown";
-  if (my_progname)
-    my_progname_short= my_progname + dirname_length(my_progname);
-
 #ifdef THREAD
   if (my_thread_global_init())
     return 1;

=== modified file 'mysys/my_thr_init.c'
--- a/mysys/my_thr_init.c	2009-05-28 21:33:45 +0000
+++ b/mysys/my_thr_init.c	2009-06-04 17:02:25 +0000
@@ -102,8 +102,14 @@ void my_threadattr_global_init(void)
 
 static uint get_thread_lib(void);
 
+/** True if @c my_thread_basic_global_init() has been called. */
 static my_bool my_thread_basic_global_init_done= 0;
 
+/**
+  Perform a minimal initialisation of mysys, when compiled with threads.
+  @sa my_basic_init
+  @sa my_thread_basic_global_init
+*/
 my_bool my_thread_basic_global_init(void)
 {
   int pth_ret;
@@ -132,20 +138,20 @@ my_bool my_thread_basic_global_init(void
   return 0;
 }
 
-my_bool my_thread_basic_global_reinit(void)
+/**
+  Re-initialize components initialized early with @c my_thread_basic_global_init.
+  Some mutexes were initialized before the instrumentation.
+  Destroy + create them again, now that the instrumentation
+  is in place.
+  This is safe, since this function() is called before creating new threads,
+  so the mutexes are not in use.
+*/
+void my_thread_basic_global_reinit(void)
 {
   struct st_my_thread_var *tmp;
 
   DBUG_ASSERT(my_thread_basic_global_init_done);
 
-  /*
-    These mutexes were initialized before the instrumentation.
-    Destroy + create them again, now that the instrumentation
-    is in place.
-    This is safe, since my_thread_basic_global_reinit()
-    is called before creating new threads, so the mutexes
-    are not in use.
-  */
   mysql_mutex_destroy(&THR_LOCK_threads);
   mysql_mutex_init_extra(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST,
                          "THR_LOCK_threads", MYF_NO_DEADLOCK_DETECTION);
@@ -168,8 +174,6 @@ my_bool my_thread_basic_global_reinit(vo
 
   mysql_cond_destroy(&tmp->suspend);
   mysql_cond_init(key_my_thread_var_suspend, &tmp->suspend, NULL);
-
-  return 0;
 }
 
 

=== modified file 'mysys/waiting_threads.c'
--- a/mysys/waiting_threads.c	2009-05-18 15:36:08 +0000
+++ b/mysys/waiting_threads.c	2009-06-04 17:02:25 +0000
@@ -464,6 +464,10 @@ void wt_init()
   DBUG_ENTER("wt_init");
   DBUG_ASSERT(reshash.alloc.constructor != wt_resource_init);
 
+#ifdef HAVE_PSI_INTERFACE
+  my_init_wt_psi_keys();
+#endif
+
   lf_hash_init(&reshash, sizeof(WT_RESOURCE), LF_HASH_UNIQUE, 0,
                sizeof_WT_RESOURCE_ID, 0, 0);
   reshash.alloc.constructor= wt_resource_init;

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2009-06-03 17:55:20 +0000
+++ b/sql/mysql_priv.h	2009-06-04 17:02:25 +0000
@@ -2294,7 +2294,8 @@ extern HASH table_def_cache, lock_db_cac
 extern TABLE *unused_tables;
 extern uint  table_cache_count;
 extern const char* any_db;
-extern struct my_option my_long_options[];
+extern struct my_option my_long_early_options[];
+extern struct my_option my_long_late_options[];
 extern const LEX_STRING view_type;
 extern scheduler_functions thread_scheduler;
 extern TYPELIB thread_handling_typelib;

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2009-06-03 17:55:20 +0000
+++ b/sql/mysqld.cc	2009-06-04 17:02:25 +0000
@@ -775,13 +775,29 @@ static ulong opt_specialflag, opt_myisam
 static char *opt_update_logname, *opt_binlog_index_name;
 static char *opt_tc_heuristic_recover;
 static char *mysql_home_ptr, *pidfile_name_ptr;
+/** Initial command line arguments (count), after load_defaults().*/
 static int defaults_argc;
+/**
+  Initial command line arguments (arguments), after load_defaults().
+  This memory is allocated by @c load_defaults() and should be freed
+  using @c free_defaults().
+  Do not modify defaults_argc / defaults_argv,
+  use remaining_argc / remaining_argv instead to parse the command
+  line arguments in multiple steps.
+*/
 static char **defaults_argv;
+/** Remaining command line arguments (count), filtered by handle_options().*/
+static int remaining_argc;
+/** Remaining command line arguments (arguments), filtered by handle_options().*/
+static char **remaining_argv;
 static char *opt_bin_logname;
 
 int orig_argc;
 char **orig_argv;
 
+/** Error reported before a logger is available. */
+static String buffered_errors;
+
 static my_socket unix_sock,ip_sock;
 struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()
 
@@ -3346,6 +3362,18 @@ static int init_common_variables()
       mysql_init_variables())
     return 1;
 
+  /*
+    Now that the logger is finally available,
+    print the buffered messages to the log.
+    These must be only warnings, otherwise handle_options would have failed.
+  */
+  if (buffered_errors.length() > 0)
+  {
+    const char* str= buffered_errors.c_ptr_safe();
+    sql_print_warning("Buffered warnings:\n%s", str);
+    buffered_errors.length(0);
+  }
+
 #ifdef HAVE_TZNAME
   {
     struct tm tm_tmp;
@@ -3420,7 +3448,7 @@ static int init_common_variables()
                      SQLCOM_END + 8);
 #endif
 
-  if (get_options(&defaults_argc, defaults_argv))
+  if (get_options(&remaining_argc, remaining_argv))
     return 1;
   set_server_version();
 
@@ -4109,7 +4137,7 @@ server.");
     DBUG_RETURN(1);
 
   { 
-    if (plugin_init(&defaults_argc, defaults_argv,
+    if (plugin_init(&remaining_argc, remaining_argv,
 		    (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
 		    (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
     {
@@ -4131,10 +4159,9 @@ server.");
     unireg_abort(0);
 
   /* we do want to exit if there are any other unknown options */
-  if (defaults_argc > 1)
+  if (remaining_argc > 1)
   {
     int ho_error;
-    char **tmp_argv= defaults_argv;
     struct my_option no_opts[]=
     {
       {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
@@ -4142,21 +4169,19 @@ server.");
     /*
       We need to eat any 'loose' arguments first before we conclude
       that there are unprocessed options.
-      But we need to preserve defaults_argv pointer intact for
-      free_defaults() to work. Thus we use a copy here.
     */
     my_getopt_skip_unknown= 0;
 
-    if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
+    if ((ho_error= handle_options(&remaining_argc, &remaining_argv, no_opts,
                                   mysqld_get_one_option)))
       unireg_abort(ho_error);
     my_getopt_skip_unknown= TRUE;
 
-    if (defaults_argc)
+    if (remaining_argc)
     {
       fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n"
               "Use --verbose --help to get a list of available options\n",
-              my_progname, *tmp_argv);
+              my_progname, *remaining_argv);
       unireg_abort(1);
     }
   }
@@ -4496,14 +4521,17 @@ static void test_lc_time_sz()
 }
 #endif//DBUG_OFF
 
-#ifdef HAVE_PERFORMANCE_SCHEMA
-extern struct my_option my_long_perfschema_options[];
-
-my_bool get_one_perfschema_option(int, const struct my_option *, char *)
+void buffered_option_error_reporter(enum loglevel level, const char *format, ...)
 {
-  return 0;
+  va_list args;
+  char buffer[1024];
+
+  va_start(args, format);
+  my_vsnprintf(buffer, sizeof(buffer), format, args);
+  va_end(args);
+  buffered_errors.append(buffer);
+  buffered_errors.append("\n");
 }
-#endif
 
 #ifdef __WIN__
 int win_main(int argc, char **argv)
@@ -4511,7 +4539,11 @@ int win_main(int argc, char **argv)
 int main(int argc, char **argv)
 #endif
 {
-  /* Perform basic thread library and malloc initialization. */
+  /*
+    Perform basic thread library and malloc initialization,
+    to be able to read defaults files and parse options.
+  */
+  my_progname= argv[0];
   if (my_basic_init())
   {
     fprintf(stderr, "my_basic_init() failed.");
@@ -4523,29 +4555,42 @@ int main(int argc, char **argv)
   load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv);
   defaults_argc= argc;
   defaults_argv= argv;
+  remaining_argc= argc;
+  remaining_argv= argv;
 
-#ifdef HAVE_PERFORMANCE_SCHEMA
-  {
-    int ho_error;
+  /*
+    Some server components:
+    - the performance schema,
+    - the safe_mutex deadlock detector
+    needs to be initialized as early as possible,
+    before to-be-instrumented objects of the server are initialized.
+  */
+  int ho_error;
 
-    my_getopt_register_get_addr(NULL);
-    my_getopt_error_reporter= option_error_reporter;
+  my_getopt_register_get_addr(NULL);
+  my_getopt_error_reporter= buffered_option_error_reporter;
 
-    /* Skip unknown options so that they may be processed later */
-    my_getopt_skip_unknown= TRUE;
+  /* Skip unknown options so that they may be processed later */
+  my_getopt_skip_unknown= TRUE;
 
-    if ((ho_error= handle_options(&argc, &argv, my_long_perfschema_options,
-                                  get_one_perfschema_option)))
+  if ((ho_error= handle_options(&argc, &argv, my_long_early_options, NULL)))
+  {
+    fprintf(stderr, "Failed to parse early options\n");
+    if (buffered_errors.length() > 0)
+    {
+      fprintf(stderr, "Buffered errors: %s", buffered_errors.c_ptr_safe());
       return ho_error;
-    /* Add back the program name handle_options removes */
-    argc++;
-    argv--;
-    /* Remove the performance schema options parsed. */
-    defaults_argc= argc;
-    defaults_argv= argv;
-
-    PSI_hook= initialize_performance_schema(& pfs_param);
+    }
   }
+  /* Add back the program name handle_options removes */
+  argc++;
+  argv--;
+  /* Remove the early options parsed. */
+  remaining_argc= argc;
+  remaining_argv= argv;
+
+#ifdef HAVE_PERFORMANCE_SCHEMA
+  PSI_hook= initialize_performance_schema(& pfs_param);
 #else
   /*
     Other provider of the instrumentation interface should
@@ -4576,27 +4621,31 @@ int main(int argc, char **argv)
       the performance schema itself, the next step is to register all the
       server and mysys instruments.
     */
-    my_init_wt_psi_keys();
     my_init_mysys_psi_keys();
     init_server_psi_keys();
     /* Instrument the main thread */
     PSI_thread *psi= PSI_server->new_thread(key_thread_main, NULL, 0);
     if (psi)
       PSI_server->set_thread(psi);
-
-    if (my_thread_basic_global_reinit())
-      return 1;
   }
 #endif /* HAVE_PSI_INTERFACE */
 
-  MY_INIT(orig_argv[0]);                       // init my_sys library & pthreads
+  /*
+    Now that some instrumentation is in place,
+    recreate objects which were initialised early,
+    so that they are instrumented as well.
+  */
+  if (PSI_server || safe_mutex_deadlock_detector)
+    my_thread_basic_global_reinit();
+
+  my_init();                                   // init my_sys library & pthreads
 
   /* Initialize audit interface globals. Audit plugins are inited later. */
   mysql_audit_initialize();
 
   /*
     Perform basic logger initialization logger. Should be called after
-    MY_INIT, as it initializes mutexes. Log tables are inited later.
+    my_init, as it initializes mutexes. Log tables are initialised later.
   */
   logger.init_base();
 
@@ -6035,7 +6084,109 @@ enum options_mysqld
 
 #define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
 
-struct my_option my_long_options[] =
+/**
+  Command lines options that are parsed early during the server startup.
+  Options listed here must be safe to initialize by themselves,
+  and are typically just global variables.
+  @sa my_long_late_options
+*/
+struct my_option my_long_early_options[]=
+{
+#ifdef SAFE_MUTEX
+  {"mutex-deadlock-detector", OPT_MUTEX_DEADLOCK_DETECTOR,
+   "Enable checking of wrong mutex usage.",
+   (uchar**) &safe_mutex_deadlock_detector,
+   (uchar**) &safe_mutex_deadlock_detector,
+   0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+#endif
+#ifdef HAVE_PERFORMANCE_SCHEMA
+  {"performance_schema", OPT_PFS_ENABLED,
+   "Enable the performance schema.",
+   (uchar**) &pfs_param.m_enabled,
+   (uchar**) &pfs_param.m_enabled,
+   NULL, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, NULL},
+  {"performance_schema_events_waits_history_long_size", OPT_PFS_EVENTS_WAITS_HISTORY_LONG,
+   "Number of rows in EVENTS_WAITS_HISTORY_LONG.",
+   (uchar**) &pfs_param.m_events_waits_history_long_sizing,
+   (uchar**) &pfs_param.m_events_waits_history_long_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_WAITS_HISTORY_LONG_SIZE, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_events_waits_history_size", OPT_PFS_EVENTS_WAITS_HISTORY,
+   "Number of rows per thread in EVENTS_WAITS_HISTORY.",
+   (uchar**) &pfs_param.m_events_waits_history_sizing,
+   (uchar**) &pfs_param.m_events_waits_history_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_WAITS_HISTORY_SIZE, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_cond", OPT_PFS_MAX_COND,
+   "Maximum number of instrumented condition objects.",
+   (uchar**) &pfs_param.m_cond_sizing,
+   (uchar**) &pfs_param.m_cond_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_COND, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_cond_instruments", OPT_PFS_MAX_COND_INSTRUMENTS,
+   "Maximum number of condition instruments.",
+   (uchar**) &pfs_param.m_cond_class_sizing,
+   (uchar**) &pfs_param.m_cond_class_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_COND_CLASS, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_file", OPT_PFS_MAX_FILE,
+   "Maximum number of instrumented files.",
+   (uchar**) &pfs_param.m_file_sizing,
+   (uchar**) &pfs_param.m_file_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_FILE, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_file_instruments", OPT_PFS_MAX_FILE_INSTRUMENTS,
+   "Maximum number of file instruments.",
+   (uchar**) &pfs_param.m_file_class_sizing,
+   (uchar**) &pfs_param.m_file_class_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_FILE_CLASS, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_mutex", OPT_PFS_MAX_MUTEX,
+   "Maximum number of instrumented MUTEX objects.",
+   (uchar**) &pfs_param.m_mutex_sizing,
+   (uchar**) &pfs_param.m_mutex_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_MUTEX, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_mutex_instruments", OPT_PFS_MAX_MUTEX_INSTRUMENTS,
+   "Maximum number of mutex instruments.",
+   (uchar**) &pfs_param.m_mutex_class_sizing,
+   (uchar**) &pfs_param.m_mutex_class_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_MUTEX_CLASS, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_rwlock", OPT_PFS_MAX_RWLOCK,
+   "Maximum number of instrumented RWLOCK objects.",
+   (uchar**) &pfs_param.m_rwlock_sizing,
+   (uchar**) &pfs_param.m_rwlock_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_RWLOCK, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_rwlock_instruments", OPT_PFS_MAX_RWLOCK_INSTRUMENTS,
+   "Maximum number of rwlock instruments.",
+   (uchar**) &pfs_param.m_rwlock_class_sizing,
+   (uchar**) &pfs_param.m_rwlock_class_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_RWLOCK_CLASS, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_table", OPT_PFS_MAX_TABLE,
+   "Maximum number of instrumented tables.",
+   (uchar**) &pfs_param.m_table_sizing,
+   (uchar**) &pfs_param.m_table_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_TABLE, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_table_instruments", OPT_PFS_MAX_TABLE_INSTRUMENTS,
+   "Maximum number of table instruments.",
+   (uchar**) &pfs_param.m_table_share_sizing,
+   (uchar**) &pfs_param.m_table_share_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_TABLE_SHARE, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_thread", OPT_PFS_MAX_THREAD,
+   "Maximum number of instrumented threads.",
+   (uchar**) &pfs_param.m_thread_sizing,
+   (uchar**) &pfs_param.m_thread_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_THREAD, 0, ULONG_MAX, 0, 1, NULL},
+  {"performance_schema_max_thread_instruments", OPT_PFS_MAX_THREAD_INSTRUMENTS,
+   "Maximum number of thread instruments.",
+   (uchar**) &pfs_param.m_thread_class_sizing,
+   (uchar**) &pfs_param.m_thread_class_sizing,
+   NULL, GET_ULONG, OPT_ARG, PFS_MAX_THREAD_CLASS, 0, ULONG_MAX, 0, 1, NULL},
+#endif /* HAVE_PERFORMANCE_SCHEMA */
+  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+/**
+  Command lines options that are parsed late during the server startup.
+  Options listed here may not be safe to initialize by themselves,
+  and may alter the runtime state of a server component already initialized.
+  For example, see rpl_filter.
+  @sa my_long_late_options
+*/
+struct my_option my_long_late_options[]=
 {
   {"help", '?', "Display this help and exit.",
    (uchar**) &opt_help, (uchar**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
@@ -6441,13 +6592,6 @@ thread is in the master's binlogs.",
 #endif /* HAVE_REPLICATION */
   {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", (uchar**) &locked_in_memory,
    (uchar**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef SAFE_MUTEX
-  {"mutex-deadlock-detector", OPT_MUTEX_DEADLOCK_DETECTOR,
-   "Enable checking of wrong mutex usage.",
-   (uchar**) &safe_mutex_deadlock_detector,
-   (uchar**) &safe_mutex_deadlock_detector,
-   0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
-#endif
   {"myisam-recover", OPT_MYISAM_RECOVER,
    "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
    (uchar**) &myisam_recover_options_str, (uchar**) &myisam_recover_options_str, 0,
@@ -7452,88 +7596,6 @@ The minimum value for this variable is 4
   {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
-#ifdef HAVE_PERFORMANCE_SCHEMA
-struct my_option my_long_perfschema_options[] =
-{
-  {"performance_schema", OPT_PFS_ENABLED,
-   "Enable the performance schema.",
-   (uchar**) &pfs_param.m_enabled,
-   (uchar**) &pfs_param.m_enabled,
-   NULL, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, NULL},
-  {"performance_schema_events_waits_history_long_size", OPT_PFS_EVENTS_WAITS_HISTORY_LONG,
-   "Number of rows in EVENTS_WAITS_HISTORY_LONG.",
-   (uchar**) &pfs_param.m_events_waits_history_long_sizing,
-   (uchar**) &pfs_param.m_events_waits_history_long_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_WAITS_HISTORY_LONG_SIZE, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_events_waits_history_size", OPT_PFS_EVENTS_WAITS_HISTORY,
-   "Number of rows per thread in EVENTS_WAITS_HISTORY.",
-   (uchar**) &pfs_param.m_events_waits_history_sizing,
-   (uchar**) &pfs_param.m_events_waits_history_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_WAITS_HISTORY_SIZE, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_cond", OPT_PFS_MAX_COND,
-   "Maximum number of instrumented condition objects.",
-   (uchar**) &pfs_param.m_cond_sizing,
-   (uchar**) &pfs_param.m_cond_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_COND, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_cond_instruments", OPT_PFS_MAX_COND_INSTRUMENTS,
-   "Maximum number of condition instruments.",
-   (uchar**) &pfs_param.m_cond_class_sizing,
-   (uchar**) &pfs_param.m_cond_class_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_COND_CLASS, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_file", OPT_PFS_MAX_FILE,
-   "Maximum number of instrumented files.",
-   (uchar**) &pfs_param.m_file_sizing,
-   (uchar**) &pfs_param.m_file_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_FILE, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_file_instruments", OPT_PFS_MAX_FILE_INSTRUMENTS,
-   "Maximum number of file instruments.",
-   (uchar**) &pfs_param.m_file_class_sizing,
-   (uchar**) &pfs_param.m_file_class_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_FILE_CLASS, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_mutex", OPT_PFS_MAX_MUTEX,
-   "Maximum number of instrumented MUTEX objects.",
-   (uchar**) &pfs_param.m_mutex_sizing,
-   (uchar**) &pfs_param.m_mutex_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_MUTEX, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_mutex_instruments", OPT_PFS_MAX_MUTEX_INSTRUMENTS,
-   "Maximum number of mutex instruments.",
-   (uchar**) &pfs_param.m_mutex_class_sizing,
-   (uchar**) &pfs_param.m_mutex_class_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_MUTEX_CLASS, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_rwlock", OPT_PFS_MAX_RWLOCK,
-   "Maximum number of instrumented RWLOCK objects.",
-   (uchar**) &pfs_param.m_rwlock_sizing,
-   (uchar**) &pfs_param.m_rwlock_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_RWLOCK, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_rwlock_instruments", OPT_PFS_MAX_RWLOCK_INSTRUMENTS,
-   "Maximum number of rwlock instruments.",
-   (uchar**) &pfs_param.m_rwlock_class_sizing,
-   (uchar**) &pfs_param.m_rwlock_class_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_RWLOCK_CLASS, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_table", OPT_PFS_MAX_TABLE,
-   "Maximum number of instrumented tables.",
-   (uchar**) &pfs_param.m_table_sizing,
-   (uchar**) &pfs_param.m_table_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_TABLE, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_table_instruments", OPT_PFS_MAX_TABLE_INSTRUMENTS,
-   "Maximum number of table instruments.",
-   (uchar**) &pfs_param.m_table_share_sizing,
-   (uchar**) &pfs_param.m_table_share_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_TABLE_SHARE, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_thread", OPT_PFS_MAX_THREAD,
-   "Maximum number of instrumented threads.",
-   (uchar**) &pfs_param.m_thread_sizing,
-   (uchar**) &pfs_param.m_thread_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_THREAD, 0, ULONG_MAX, 0, 1, NULL},
-  {"performance_schema_max_thread_instruments", OPT_PFS_MAX_THREAD_INSTRUMENTS,
-   "Maximum number of thread instruments.",
-   (uchar**) &pfs_param.m_thread_class_sizing,
-   (uchar**) &pfs_param.m_thread_class_sizing,
-   NULL, GET_ULONG, OPT_ARG, PFS_MAX_THREAD_CLASS, 0, ULONG_MAX, 0, 1, NULL},
-  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-};
-#endif /* HAVE_PERFORMANCE_SCHEMA */
-
 static int show_queries(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type= SHOW_LONGLONG;
@@ -8110,17 +8172,9 @@ Starts the MySQL database server\n");
   puts("");
   set_ports();
 
-  my_option *more_options= NULL;
-  uint more_option_size= 0;
-
-#ifdef HAVE_PERFORMANCE_SCHEMA
-  more_options= my_long_perfschema_options;
-  more_option_size= array_elements(my_long_perfschema_options);
-#endif
-
   /* Print out all the options including plugin supplied options */
-  my_print_help_inc_plugins(my_long_options, array_elements(my_long_options),
-                            more_options, more_option_size);
+  my_print_help_inc_plugins(my_long_early_options, array_elements(my_long_early_options),
+                            my_long_late_options, array_elements(my_long_late_options));
 
   if (! plugins_are_initialized)
   {
@@ -9053,7 +9107,7 @@ static int get_options(int *argc,char **
   /* Skip unknown options so that they may be processed later by plugins */
   my_getopt_skip_unknown= TRUE;
 
-  if ((ho_error= handle_options(argc, &argv, my_long_options,
+  if ((ho_error= handle_options(argc, &argv, my_long_late_options,
                                 mysqld_get_one_option)))
     return ho_error;
   (*argc)++; /* add back one for the progname handle_options removes */

=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc	2009-05-18 15:36:08 +0000
+++ b/sql/set_var.cc	2009-06-04 17:02:25 +0000
@@ -3885,7 +3885,8 @@ static uchar *get_sys_var_length(const s
 */
 
 
-int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
+int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options_1,
+                            struct my_option *long_options_2)
 {
   sys_var *var;
   
@@ -3897,8 +3898,10 @@ int mysql_add_sys_var_chain(sys_var *fir
     /* this fails if there is a conflicting variable name. see HASH_UNIQUE */
     if (my_hash_insert(&system_variable_hash, (uchar*) var))
       goto error;
-    if (long_options)
-      var->option_limits= find_option(long_options, var->name);
+    if (long_options_1)
+      var->option_limits= find_option(long_options_1, var->name);
+    if (long_options_2 && (var->option_limits == NULL))
+      var->option_limits= find_option(long_options_2, var->name);
   }
   return 0;
 
@@ -4007,7 +4010,7 @@ int set_var_init()
     goto error;
 
   vars.last->next= NULL;
-  if (mysql_add_sys_var_chain(vars.first, my_long_options))
+  if (mysql_add_sys_var_chain(vars.first, my_long_early_options, my_long_late_options))
     goto error;
 
   /*

=== modified file 'sql/set_var.h'
--- a/sql/set_var.h	2009-04-17 18:44:53 +0000
+++ b/sql/set_var.h	2009-06-04 17:02:25 +0000
@@ -1516,7 +1516,8 @@ struct sys_var_with_base
 int set_var_init();
 void set_var_free();
 SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted);
-int mysql_add_sys_var_chain(sys_var *chain, struct my_option *long_options);
+int mysql_add_sys_var_chain(sys_var *chain, struct my_option *long_options_1,
+                            struct my_option *long_options_2);
 int mysql_del_sys_var_chain(sys_var *chain);
 sys_var *find_sys_var(THD *thd, const char *str, uint length=0);
 int sql_set_variables(THD *thd, List<set_var_base> *var_list);

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2009-06-03 17:55:20 +0000
+++ b/sql/sql_acl.cc	2009-06-04 21:25:06 +0000
@@ -6913,6 +6913,9 @@ void ACL_internal_schema_registry::regis
 const ACL_internal_schema_access *
 ACL_internal_schema_registry::lookup(const char *name)
 {
+  if (name == NULL)
+    return NULL;
+
   uint i;
   uint len= strlen(name);
 

=== modified file 'sql/sql_acl.h'
--- a/sql/sql_acl.h	2009-06-03 17:55:20 +0000
+++ b/sql/sql_acl.h	2009-06-04 21:25:06 +0000
@@ -284,16 +284,35 @@ bool has_any_table_level_privileges(THD
 #define check_grant_db(A,B) 0
 #endif
 
+/**
+  Result of an access check for an internal schema or table.
+  Internal ACL checks are always performed *before* using
+  the grant tables.
+  This mechanism enforces that the server implementation has full
+  control on its internal tables.
+  Depending on the internal check result, the server implementation
+  can choose to:
+  - always allow access,
+  - always deny access,
+  - delegate the decision to the database administrator,
+  by using the grant tables.
+*/
 enum ACL_internal_access_result
 {
-  /** Access granted, no matter what the grants say. */
+  /** Access granted, do not use the grant tables. */
   ACL_INTERNAL_ACCESS_GRANTED,
-  /** Access denied, no matter what the grants say. */
+  /** Access denied, do not use the grant tables. */
   ACL_INTERNAL_ACCESS_DENIED,
-  /** No decision yet, proceed with the grant tables. */
+  /** No decision yet, use the grant tables. */
   ACL_INTERNAL_ACCESS_CHECK_GRANT
 };
 
+/**
+  Per internal table ACL access rules.
+  This class is an interface.
+  Per table(s) specific access rule should be implemented in a subclass.
+  @sa ACL_internal_schema_access
+*/
 class ACL_internal_table_access
 {
 public:
@@ -303,10 +322,26 @@ public:
   virtual ~ACL_internal_table_access()
   {}
 
+  /**
+    Check access to an internal table.
+    @param command the sql operation requested
+    @param want_access the privileges requested
+    @return the access check result
+  */
   virtual ACL_internal_access_result check(enum_sql_command command,
                                            ulong want_access) const= 0;
 };
 
+/**
+  Per internal schema ACL access rules.
+  This class is an interface.
+  Each per schema specific access rule should be implemented
+  in a different subclass, and registered.
+  Per schema access rules can control:
+  - every schema privileges on schema.*
+  - every table privileges on schema.table
+  @sa ACL_internal_schema_registry
+*/
 class ACL_internal_schema_access
 {
 public:
@@ -316,24 +351,63 @@ public:
   virtual ~ACL_internal_schema_access()
   {}
 
+  /**
+    Check access to an internal schema.
+    @param command the sql operation requested
+    @param want_access the privileges requested
+    @param [out] save_priv the privileges granted
+    @return the access check result
+  */
   virtual ACL_internal_access_result check(enum_sql_command command,
                                            ulong want_access,
                                            ulong *save_priv) const= 0;
+
+  /**
+    Search for per table ACL access rules by table name.
+    @param name the table name
+    @return per table access rules, or NULL
+  */
   virtual const ACL_internal_table_access *lookup(const char *name) const= 0;
 };
 
+/**
+  A registry for per internal schema ACL.
+  An 'internal schema' is a database schema maintained by the
+  server implementation, such as 'performance_schema' and 'INFORMATION_SCHEMA'.
+*/
 class ACL_internal_schema_registry
 {
 public:
+  /**
+    Add an internal schema to the registry.
+    @param name the schema name
+    @param access the schema ACL specific rules
+  */
   static void register_schema(const LEX_STRING *name,
                               const ACL_internal_schema_access *access);
+  /**
+    Search per internal schema ACL by name.
+    @param name a schema name
+    @return per schema rules, or NULL
+  */
   static const ACL_internal_schema_access *lookup(const char *name);
 };
 
+/**
+  Get a cached internal schema access.
+  @param grant_internal_info the cache
+  @param schema_name the name of the internal schema
+*/
 const ACL_internal_schema_access *
 get_cached_schema_access(GRANT_INTERNAL_INFO *grant_internal_info,
                          const char *schema_name);
 
+/**
+  Get a cached internal table access.
+  @param grant_internal_info the cache
+  @param schema_name the name of the internal schema
+  @param table_name the name of the internal table
+*/
 const ACL_internal_table_access *
 get_cached_table_access(GRANT_INTERNAL_INFO *grant_internal_info,
                         const char *schema_name,

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	2009-05-28 21:33:45 +0000
+++ b/sql/sql_plugin.cc	2009-06-04 17:02:25 +0000
@@ -2893,17 +2893,6 @@ static void plugin_opt_set_limits(struct
     options->arg_type= OPT_ARG;
 }
 
-extern "C" my_bool get_one_plugin_option(int optid, const struct my_option *,
-                                         char *);
-
-my_bool get_one_plugin_option(int optid __attribute__((unused)),
-                              const struct my_option *opt,
-                              char *argument)
-{
-  return 0;
-}
-
-
 static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
                              my_option *options, my_bool **enabled,
                              bool can_disable)
@@ -3214,7 +3203,7 @@ static int test_plugin_options(MEM_ROOT
       DBUG_RETURN(-1);
     }
 
-    error= handle_options(argc, &argv, opts, get_one_plugin_option);
+    error= handle_options(argc, &argv, opts, NULL);
     (*argc)++; /* add back one for the program name */
 
     if (error)
@@ -3267,7 +3256,7 @@ static int test_plugin_options(MEM_ROOT
     if (chain.first)
     {
       chain.last->next = NULL;
-      if (mysql_add_sys_var_chain(chain.first, NULL))
+      if (mysql_add_sys_var_chain(chain.first, NULL, NULL))
       {
         sql_print_error("Plugin '%s' has conflicting system variables",
                         tmp->name.str);
@@ -3298,14 +3287,14 @@ static int option_cmp(my_option *a, my_o
 }
 
 
-void my_print_help_inc_plugins(my_option *main_options, uint main_options_size,
-                               my_option *more_options, uint more_options_size)
+void my_print_help_inc_plugins(my_option *options_1, uint options_1_size,
+                               my_option *options_2, uint options_2_size)
 {
   DYNAMIC_ARRAY all_options;
   struct st_plugin_int *p;
   MEM_ROOT mem_root;
   my_option *opt;
-  uint size= main_options_size + more_options_size;
+  uint size= options_1_size + options_2_size;
 
   init_alloc_root(&mem_root, 4096, 4096);
   my_init_dynamic_array(&all_options, sizeof(my_option), size, size/4);
@@ -3325,17 +3314,16 @@ void my_print_help_inc_plugins(my_option
           insert_dynamic(&all_options, (uchar*) opt);
     }
 
-  for (;main_options->id; main_options++)
-    insert_dynamic(&all_options, (uchar*) main_options);
+  for ( ; options_1->id; options_1++)
+    insert_dynamic(&all_options, (uchar*) options_1);
 
-  if (more_options)
-    for ( ; more_options->id; more_options++)
-      insert_dynamic(&all_options, (uchar*) more_options);
+  for ( ; options_2->id; options_2++)
+    insert_dynamic(&all_options, (uchar*) options_2);
 
   sort_dynamic(&all_options, (qsort_cmp) option_cmp);
 
-  /* main_options now points to the empty option terminator */
-  insert_dynamic(&all_options, (uchar*) main_options);
+  /* options_2 now points to the empty option terminator */
+  insert_dynamic(&all_options, (uchar*) options_2);
 
   my_print_help((my_option*) all_options.buffer);
   my_print_variables((my_option*) all_options.buffer);

=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc	2009-06-03 17:55:20 +0000
+++ b/sql/sql_repl.cc	2009-06-04 17:02:25 +0000
@@ -2131,7 +2131,7 @@ bool sys_var_slave_skip_counter::update(
 
 int init_replication_sys_vars()
 {
-  if (mysql_add_sys_var_chain(vars.first, my_long_options))
+  if (mysql_add_sys_var_chain(vars.first, my_long_early_options, my_long_late_options))
   {
     /* should not happen */
     fprintf(stderr, "failed to initialize replication system variables");

=== modified file 'sql/table.h'
--- a/sql/table.h	2009-06-03 17:55:20 +0000
+++ b/sql/table.h	2009-06-04 21:25:06 +0000
@@ -76,6 +76,9 @@ typedef struct st_order {
 
 /**
   State information for internal tables grants.
+  This structure is part of the TABLE_LIST, and is updated
+  during the ACL check process.
+  @sa GRANT_INFO
 */
 struct st_grant_internal_info
 {
@@ -151,9 +154,7 @@ typedef struct st_grant_info
     check access rights to the underlying tables of a view.
   */
   ulong orig_want_privilege;
-  /**
-    The grant state for internal tables.
-  */
+  /** The grant state for internal tables. */
   GRANT_INTERNAL_INFO m_internal;
 } GRANT_INFO;
 

Thread
bzr push into mysql-6.0-perfschema branch (marc.alff:3159 to 3161) Marc Alff5 Jun