• unknown's avatar
    BUG#9953: CONVERT_TZ requires mysql.time_zone_name to be locked · 0ea47f3e
    unknown authored
    The problem was that some facilities (like CONVERT_TZ() function or
    server HELP statement) may require implicit access to some tables in
    'mysql' database.  This access was done by ordinary means of adding
    such tables to the list of tables the query is going to open.
    However, if we issued LOCK TABLES before that, we would get "table
    was not locked" error trying to open such implicit tables.
    
    The solution is to treat certain tables as MySQL system tables, like
    we already do for mysql.proc.  Such tables may be opened for reading
    at any moment regardless of any locks in effect.  The cost of this is
    that system table may be locked for writing only together with other
    system tables, it is disallowed to lock system tables for writing and
    have any other lock on any other table.
    
    After this patch the following tables are treated as MySQL system
    tables:
      mysql.help_category
      mysql.help_keyword
      mysql.help_relation
      mysql.help_topic
      mysql.proc (it already was)
      mysql.time_zone
      mysql.time_zone_leap_second
      mysql.time_zone_name
      mysql.time_zone_transition
      mysql.time_zone_transition_type
    
    These tables are now opened with open_system_tables_for_read() and
    closed with close_system_tables(), or one table may be opened with
    open_system_table_for_update() and closed with close_thread_tables()
    (the latter is used for mysql.proc table, which is updated as part of
    normal MySQL server operation).  These functions may be used when
    some tables were opened and locked already.
    
    NOTE: online update of time zone tables is not possible during
    replication, because there's no time zone cache flush neither on LOCK
    TABLES, nor on FLUSH TABLES, so the master may serve stale time zone
    data from cache, while on slave updated data will be loaded from the
    time zone tables.
    
    
    mysql-test/r/help.result:
      Update result.
    mysql-test/r/lock.result:
      Update result.
    mysql-test/r/sp-error.result:
      Update result.
    mysql-test/r/timezone2.result:
      Add result for bug#9953: CONVERT_TZ requires mysql.time_zone_name
      to be locked.
    mysql-test/r/view.result:
      Update result: use table t3 rather than utilize MySQL system table.
    mysql-test/t/help.test:
      Test that we can use HELP even under LOCK TABLES.
    mysql-test/t/lock.test:
      Test LOCK TABLE on system tables.
    mysql-test/t/timezone2.test:
      Add test case for bug#9953: CONVERT_TZ requires mysql.time_zone_name
      to be locked.
    mysql-test/t/view.test:
      Update test: use table t3 rather that utilize MySQL system table.
    sql/handler.h:
      Fix comment for 'count' parameter of check_if_locking_is_allowed().
      Add 'current' and 'system_count' parameters.
    sql/item_create.cc:
      We no longer have LEX::add_time_zone_tables_to_query_tables().
    sql/item_timefunc.cc:
      We no longer have LEX::time_zone_tables_used, so
      Item_func_convert_tz::fix_fields() became the same as base
      Item_date_func::fix_fields().
      
      my_tz_find() no longer takes table list, but takes THD pointer now.
    sql/item_timefunc.h:
      Remove dead field and method.
    sql/lock.cc:
      Pass values for 'current' and 'system_count' to
      check_if_locking_is_allowed().
    sql/log_event.cc:
      We no longer have my_tz_find_with_opening_tz_tables(), its functions is
      performed by my_tz_find().
    sql/mysql_priv.h:
      Add functions to work with MySQL system tables.
    sql/set_var.cc:
      my_tz_find() no longer takes table list, but takes THD pointer now.
    sql/sp.cc:
      Remove close_proc_table().  Use close_system_tables() instead.
      
      Use open_system_tables_for_read() and open_system_table_for_update().
    sql/sp.h:
      Remove close_proc_table() declaration.
    sql/sql_base.cc:
      Add implementation of open_system_tables_for_read(),
      close_system_tables(), open_system_table_for_update().
    sql/sql_help.cc:
      Operate on MySQL system tables mysql.help_* with
      open_system_tables_for_read() and close_system_tables() to allow the
      usage of HELP statement under LOCK TABLES.
    sql/sql_lex.cc:
      Remove LEX::time_zone_tables_used and
      LEX::add_time_zone_tables_to_query_tables() which are no longer used.
    sql/sql_lex.h:
      Remove LEX::time_zone_tables_used and
      LEX::add_time_zone_tables_to_query_tables() which are no longer used.
    sql/sql_parse.cc:
      Remove references to LEX::time_zone_tables_used and
      my_tz_check_n_skip_implicit_tables() which are no longer used.
    sql/sql_show.cc:
      Use close_system_tables() instead of removed close_proc_table().
    sql/sql_view.cc:
      LEX::time_zone_tables_used is no longer there.
    sql/sql_yacc.yy:
      LEX::add_time_zone_tables_to_query_tables() is no longer there.
    sql/table.cc:
      Add more tables that should be treated as MySQL system tables.
    sql/share/errmsg.txt:
      Change the error message, as now we allow write-locking of several
      system tables if not mixed with ordinary tables.
    sql/tztime.cc:
      Do not add time zone tables to the list of query tables in
      tz_init_table_list().
      
      Remove fake_time_zone_tables_list and my_tz_get_tables_list().
      
      In my_tz_init(), open mysql.time_zone_leap_second with
      simple_open_n_lock_tables(), but pass time zone name to my_tz_find(),
      which will open and close time zone tables as necessary.
      
      In tz_load_from_open_tables() do not call table->use_all_columns(), as
      this was already done in open_system_tables_for_read().
      
      my_tz_find() takes THD pointer instead of table list, and calls
      open_system_tables_for_read() and close_system_tables() as necessary.
      
      Remove my_tz_find_with_opening_tz_tables().
    sql/tztime.h:
      Remove declarations of my_tz_get_table_list(),
      my_tz_find_with_opening_tz_tables(), fake_time_zone_tables_list,
      definition of my_tz_check_n_skip_implicit_tables().
      Update prototype for my_tz_find().
    storage/csv/ha_tina.cc:
      Add new parameters to check_if_locking_is_allowed().
    storage/csv/ha_tina.h:
      Add new parameters to check_if_locking_is_allowed().
    storage/myisam/ha_myisam.cc:
      Add new parameters to check_if_locking_is_allowed().  In this
      function we count system tables.  If there are system tables, but
      there are also non-system tables, we report an error.
    storage/myisam/ha_myisam.h:
      Add new parameters to check_if_locking_is_allowed().
    0ea47f3e
set_var.cc 128 KB