@@ -120,7 +120,7 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
120120 opt_include_master_host_port = 0 ,
121121 opt_events = 0 , opt_comments_used = 0 ,
122122 opt_alltspcs = 0 , opt_notspcs = 0 , opt_drop_trigger = 0 ,
123- opt_secure_auth = TRUE;
123+ opt_skip_mysql_schema = 0 , opt_secure_auth = TRUE;
124124static my_bool insert_pat_inited = 0 , debug_info_flag = 0 , debug_check_flag = 0 ;
125125static ulong opt_max_allowed_packet , opt_net_buffer_length ;
126126static MYSQL mysql_connection ,* mysql = 0 ;
@@ -524,6 +524,9 @@ static struct my_option my_long_options[] =
524524 {"dump-date" , OPT_DUMP_DATE , "Put a dump date to the end of the output." ,
525525 & opt_dump_date , & opt_dump_date , 0 ,
526526 GET_BOOL , NO_ARG , 1 , 0 , 0 , 0 , 0 , 0 },
527+ {"skip_mysql_schema" , OPT_SKIP_MYSQL_SCHEMA , "Skip adding DROP DATABASE for mysql schema." ,
528+ & opt_skip_mysql_schema , & opt_skip_mysql_schema , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 ,
529+ 0 },
527530 {"skip-opt" , OPT_SKIP_OPTIMIZATION ,
528531 "Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys." ,
529532 0 , 0 , 0 , GET_NO_ARG , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 },
@@ -584,9 +587,9 @@ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
584587 int string_value );
585588static int dump_selected_tables (char * db , char * * table_names , int tables );
586589static int dump_all_tables_in_db (char * db );
587- static int init_dumping_views (char * );
588- static int init_dumping_tables (char * );
589- static int init_dumping (char * , int init_func (char * ));
590+ static int init_dumping_views (char * , my_bool );
591+ static int init_dumping_tables (char * , my_bool );
592+ static int init_dumping (char * , int init_func (char * , my_bool ));
590593static int dump_databases (char * * );
591594static int dump_all_databases ();
592595static char * quote_name (const char * name , char * buff , my_bool force );
@@ -4735,12 +4738,14 @@ View Specific database initalization.
47354738SYNOPSIS
47364739 init_dumping_views
47374740 qdatabase quoted name of the database
4741+ is_mysql_db TRUE if the db is mysql, else FALSE
47384742
47394743RETURN VALUES
47404744 0 Success.
47414745 1 Failure.
47424746*/
4743- int init_dumping_views (char * qdatabase MY_ATTRIBUTE ((unused )))
4747+ int init_dumping_views (char * qdatabase MY_ATTRIBUTE ((unused )),
4748+ my_bool is_mysql_db MY_ATTRIBUTE ( (unused )))
47444749{
47454750 return 0 ;
47464751} /* init_dumping_views */
@@ -4752,13 +4757,14 @@ Table Specific database initalization.
47524757SYNOPSIS
47534758 init_dumping_tables
47544759 qdatabase quoted name of the database
4760+ is_mysql_db TRUE if the db is mysql, else FALSE
47554761
47564762RETURN VALUES
47574763 0 Success.
47584764 1 Failure.
47594765*/
47604766
4761- int init_dumping_tables (char * qdatabase )
4767+ int init_dumping_tables (char * qdatabase , my_bool is_mysql_db )
47624768{
47634769 DBUG_ENTER ("init_dumping_tables" );
47644770
@@ -4775,7 +4781,7 @@ int init_dumping_tables(char *qdatabase)
47754781 if (mysql_query (mysql , qbuf ) || !(dbinfo = mysql_store_result (mysql )))
47764782 {
47774783 /* Old server version, dump generic CREATE DATABASE */
4778- if (opt_drop_database )
4784+ if (opt_drop_database && (! opt_skip_mysql_schema || ! is_mysql_db ) )
47794785 fprintf (md_result_file ,
47804786 "\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n" ,
47814787 qdatabase );
@@ -4785,7 +4791,7 @@ int init_dumping_tables(char *qdatabase)
47854791 }
47864792 else
47874793 {
4788- if (opt_drop_database )
4794+ if (opt_drop_database && (! opt_skip_mysql_schema || ! is_mysql_db ) )
47894795 fprintf (md_result_file ,
47904796 "\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n" ,
47914797 qdatabase );
@@ -4801,7 +4807,7 @@ int init_dumping_tables(char *qdatabase)
48014807} /* init_dumping_tables */
48024808
48034809
4804- static int init_dumping (char * database , int init_func (char * ))
4810+ static int init_dumping (char * database , int init_func (char * , my_bool ))
48054811{
48064812 if (is_ndbinfo (mysql , database ))
48074813 {
@@ -4825,14 +4831,15 @@ static int init_dumping(char *database, int init_func(char*))
48254831 char * qdatabase = quote_name (database ,quoted_database_buf ,opt_quoted );
48264832 my_bool freemem = FALSE;
48274833 char const * text = fix_identifier_with_newline (qdatabase , & freemem );
4834+ my_bool is_mysql_db = !my_strcasecmp (charset_info , database , "mysql" );
48284835
48294836 print_comment (md_result_file , 0 , "\n--\n-- Current Database: %s\n--\n" ,
48304837 text );
48314838 if (freemem )
48324839 my_free ((void * )text );
48334840
48344841 /* Call the view or table specific function */
4835- init_func (qdatabase );
4842+ init_func (qdatabase , is_mysql_db );
48364843
48374844 fprintf (md_result_file ,"\nUSE %s;\n" , qdatabase );
48384845 check_io (md_result_file );
@@ -5839,24 +5846,20 @@ static int replace(DYNAMIC_STRING *ds_str,
58395846
58405847 @note: md_result_file should have been opened, before
58415848 this function is called.
5842-
5843- @param[in] flag If FALSE, disable binlog.
5844- If TRUE and binlog disabled previously,
5845- restore the session binlog.
58465849*/
58475850
5848- static void set_session_binlog (my_bool flag )
5851+ static void set_session_binlog ()
58495852{
58505853 static my_bool is_binlog_disabled = FALSE;
58515854
5852- if (!flag && ! is_binlog_disabled )
5855+ if (!is_binlog_disabled )
58535856 {
58545857 fprintf (md_result_file ,
58555858 "SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;\n" );
58565859 fprintf (md_result_file , "SET @@SESSION.SQL_LOG_BIN= 0;\n" );
58575860 is_binlog_disabled = 1 ;
58585861 }
5859- else if ( flag && is_binlog_disabled )
5862+ else
58605863 {
58615864 fprintf (md_result_file ,
58625865 "SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;\n" );
@@ -5894,7 +5897,7 @@ static my_bool add_set_gtid_purged(MYSQL *mysql_con)
58945897 {
58955898 if (opt_comments )
58965899 fprintf (md_result_file ,
5897- "\n--\n-- GTID state at the beginning of the backup \n--\n\n" );
5900+ "\n--\n-- GTID state at the end of the backup \n--\n\n" );
58985901
58995902 fprintf (md_result_file ,"SET @@GLOBAL.GTID_PURGED='" );
59005903
@@ -5917,79 +5920,98 @@ static my_bool add_set_gtid_purged(MYSQL *mysql_con)
59175920
59185921/**
59195922 This function processes the opt_set_gtid_purged option.
5920- This function also calls set_session_binlog() function before
5921- setting the SET @@GLOBAL.GTID_PURGED in the output.
5923+ This function when called with the flag as FALSE, just
5924+ disables the binlog by calling set_session_binlog().
5925+ Later when this function is called with the flag as TRUE,
5926+ SET @@GLOBAL.GTID_PURGED is written in the output and the
5927+ session binlog is restored if disabled previously.
59225928
59235929 @param[in] mysql_con the connection to the server
5930+ @param[in] flag If FALSE, just disable binlog and not
5931+ set the gtid purged as it will be set
5932+ at a later point of time.
5933+ If TRUE, set the gtid purged and
5934+ restore the session binlog if disabled
5935+ previously.
59245936
59255937 @retval FALSE successful according to the value
59265938 of opt_set_gtid_purged.
59275939 @retval TRUE fail.
59285940*/
59295941
5930- static my_bool process_set_gtid_purged (MYSQL * mysql_con )
5942+ static my_bool process_set_gtid_purged (MYSQL * mysql_con , my_bool flag )
59315943{
5932- MYSQL_RES * gtid_mode_res ;
5933- MYSQL_ROW gtid_mode_row ;
5934- char * gtid_mode_val = 0 ;
5944+ MYSQL_RES * gtid_mode_res ;
5945+ MYSQL_ROW gtid_mode_row ;
5946+ char * gtid_mode_val = 0 ;
5947+ static int gtid_mode = -1 ;
59355948 char buf [32 ], query [64 ];
59365949
59375950 if (opt_set_gtid_purged_mode == SET_GTID_PURGED_OFF )
59385951 return FALSE; /* nothing to be done */
59395952
59405953 /*
5941- Check if the server has the knowledge of GTIDs(pre mysql-5.6)
5942- or if the gtid_mode is ON or OFF.
5954+ Set gtid_mode, by fetching gtid_mode from server, if its not
5955+ yet populated. gtid_mode is set to -1 if gtid_mode is not yet
5956+ fetched from the server.
59435957 */
5944- my_snprintf (query , sizeof (query ), "SHOW VARIABLES LIKE %s" ,
5945- quote_for_like ("gtid_mode" , buf ));
5958+ if (gtid_mode < 0 )
5959+ {
5960+ /*
5961+ Check if the server has the knowledge of GTIDs(pre mysql-5.6)
5962+ or if the gtid_mode is ON or OFF.
5963+ */
5964+ my_snprintf (query , sizeof (query ), "SHOW VARIABLES LIKE %s" ,
5965+ quote_for_like ("gtid_mode" , buf ));
59465966
5947- if (mysql_query_with_error_report (mysql_con , & gtid_mode_res , query ))
5948- return TRUE;
5967+ if (mysql_query_with_error_report (mysql_con , & gtid_mode_res , query ))
5968+ return TRUE;
59495969
5950- gtid_mode_row = mysql_fetch_row (gtid_mode_res );
5970+ gtid_mode_row = mysql_fetch_row (gtid_mode_res );
59515971
5952- /*
5953- gtid_mode_row is NULL for pre 5.6 versions. For versions >= 5.6,
5954- get the gtid_mode value from the second column.
5955- */
5956- gtid_mode_val = gtid_mode_row ? (char * )gtid_mode_row [1 ] : NULL ;
5972+ /*
5973+ gtid_mode_row is NULL for pre 5.6 versions. For versions >= 5.6,
5974+ get the gtid_mode value from the second column.
5975+ */
5976+ gtid_mode_val = gtid_mode_row ? (char * )gtid_mode_row [1 ] : NULL ;
5977+ gtid_mode = (gtid_mode_val && strcmp (gtid_mode_val , "OFF" )) ? 1 : 0 ;
5978+ mysql_free_result (gtid_mode_res );
5979+ }
59575980
5958- if (gtid_mode_val && strcmp ( gtid_mode_val , "OFF" ) )
5981+ if (gtid_mode )
59595982 {
59605983 /*
59615984 For any gtid_mode !=OFF and irrespective of --set-gtid-purged
59625985 being AUTO or ON, add GTID_PURGED in the output.
59635986 */
5964- if (opt_databases || !opt_alldbs || !opt_dump_triggers
5965- || !opt_routines || !opt_events )
5987+ if (!flag )
5988+ set_session_binlog ();
5989+ else
59665990 {
5967- fprintf (stderr ,"Warning: A partial dump from a server that has GTIDs will "
5968- "by default include the GTIDs of all transactions, even "
5969- "those that changed suppressed parts of the database. If "
5970- "you don't want to restore GTIDs, pass "
5971- "--set-gtid-purged=OFF. To make a complete dump, pass "
5972- "--all-databases --triggers --routines --events. \n" );
5973- }
5991+ if (flag && (opt_databases || !opt_alldbs || !opt_dump_triggers
5992+ || !opt_routines || !opt_events ))
5993+ {
5994+ fprintf (stderr ,"Warning: A partial dump from a server that has GTIDs will "
5995+ "by default include the GTIDs of all transactions, even "
5996+ "those that changed suppressed parts of the database. If "
5997+ "you don't want to restore GTIDs, pass "
5998+ "--set-gtid-purged=OFF. To make a complete dump, pass "
5999+ "--all-databases --triggers --routines --events. \n" );
6000+ }
59746001
5975- set_session_binlog (FALSE);
5976- if (add_set_gtid_purged (mysql_con ))
5977- {
5978- mysql_free_result (gtid_mode_res );
5979- return TRUE;
6002+ if (add_set_gtid_purged (mysql_con ))
6003+ return TRUE;
59806004 }
59816005 }
59826006 else /* gtid_mode is off */
59836007 {
5984- if (opt_set_gtid_purged_mode == SET_GTID_PURGED_ON )
6008+ if (flag && opt_set_gtid_purged_mode == SET_GTID_PURGED_ON )
59856009 {
59866010 fprintf (stderr , "Error: Server has GTIDs disabled.\n" );
5987- mysql_free_result (gtid_mode_res );
59886011 return TRUE;
59896012 }
59906013 }
59916014
5992- mysql_free_result (gtid_mode_res );
59936015 return FALSE;
59946016}
59956017
@@ -6323,12 +6345,10 @@ int main(int argc, char **argv)
63236345 if (opt_slave_apply && add_stop_slave ())
63246346 goto err ;
63256347
6326-
6327- /* Process opt_set_gtid_purged and add SET @@GLOBAL.GTID_PURGED if required. */
6328- if (process_set_gtid_purged (mysql ))
6348+ /* Process opt_set_gtid_purged and add SET disable binlog if required. */
6349+ if (process_set_gtid_purged (mysql , FALSE))
63296350 goto err ;
63306351
6331-
63326352 if (opt_master_data && do_show_master_status (mysql ))
63336353 goto err ;
63346354 if (opt_slave_data && do_show_slave_status (mysql ))
@@ -6381,11 +6401,9 @@ int main(int argc, char **argv)
63816401 if (opt_slave_data && do_start_slave_sql (mysql ))
63826402 goto err ;
63836403
6384- /*
6385- if --set-gtid-purged, restore binlog at the end of the session
6386- if required.
6387- */
6388- set_session_binlog (TRUE);
6404+ /* Process opt_set_gtid_purged and add SET @@GLOBAL.GTID_PURGED if required. */
6405+ if (process_set_gtid_purged (mysql , TRUE))
6406+ goto err ;
63896407
63906408 /* add 'START SLAVE' to end of dump */
63916409 if (opt_slave_apply && add_slave_statements ())
0 commit comments