1 /* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #include "sql_reload.h"
24 #include "sql_priv.h"
25 #include "mysqld.h"      // select_errors
26 #include "sql_class.h"   // THD
27 #include "sql_acl.h"     // acl_reload
28 #include "sql_servers.h" // servers_reload
29 #include "sql_connect.h" // reset_mqh
30 #include "sql_base.h"    // close_cached_tables
31 #include "sql_db.h"      // my_dbopt_cleanup
32 #include "hostname.h"    // hostname_cache_refresh
33 #include "rpl_master.h"  // reset_master
34 #include "rpl_slave.h"   // reset_slave
35 #include "rpl_rli.h"     // rotate_relay_log
36 #include "rpl_mi.h"
37 #include "debug_sync.h"
38 #include "des_key_file.h"
39 
40 /**
41   Reload/resets privileges and the different caches.
42 
43   @param thd Thread handler (can be NULL!)
44   @param options What should be reset/reloaded (tables, privileges, slave...)
45   @param tables Tables to flush (if any)
46   @param write_to_binlog < 0 if there was an error while interacting with the binary log inside
47                          reload_acl_and_cache,
48                          0 if we should not write to the binary log,
49                          > 0 if we can write to the binlog.
50 
51 
52   @note Depending on 'options', it may be very bad to write the
53     query to the binlog (e.g. FLUSH SLAVE); this is a
54     pointer where reload_acl_and_cache() will put 0 if
55     it thinks we really should not write to the binlog.
56     Otherwise it will put 1.
57 
58   @return Error status code
59     @retval 0 Ok
60     @retval !=0  Error; thd->killed is set or thd->is_error() is true
61 */
62 
reload_acl_and_cache(THD * thd,unsigned long options,TABLE_LIST * tables,int * write_to_binlog)63 bool reload_acl_and_cache(THD *thd, unsigned long options,
64                           TABLE_LIST *tables, int *write_to_binlog)
65 {
66   bool result=0;
67   select_errors=0;				/* Write if more errors */
68   int tmp_write_to_binlog= *write_to_binlog= 1;
69 
70   DBUG_ASSERT(!thd || !thd->in_sub_stmt);
71 
72 #ifndef NO_EMBEDDED_ACCESS_CHECKS
73   if (options & REFRESH_GRANT)
74   {
75     THD *tmp_thd= 0;
76     /*
77       If reload_acl_and_cache() is called from SIGHUP handler we have to
78       allocate temporary THD for execution of acl_reload()/grant_reload().
79     */
80     if (!thd && (thd= (tmp_thd= new THD)))
81     {
82       thd->thread_stack= (char*) &tmp_thd;
83       thd->store_globals();
84     }
85 
86     if (thd)
87     {
88       bool reload_acl_failed= acl_reload(thd);
89       bool reload_grants_failed= grant_reload(thd);
90       bool reload_servers_failed= servers_reload(thd);
91 
92       if (reload_acl_failed || reload_grants_failed || reload_servers_failed)
93       {
94         result= 1;
95         /*
96           When an error is returned, my_message may have not been called and
97           the client will hang waiting for a response.
98         */
99         my_error(ER_UNKNOWN_ERROR, MYF(0));
100       }
101     }
102 
103     if (tmp_thd)
104     {
105       delete tmp_thd;
106       /* Remember that we don't have a THD */
107       my_pthread_setspecific_ptr(THR_THD,  0);
108       thd= 0;
109     }
110     reset_mqh((LEX_USER *)NULL, TRUE);
111   }
112 #endif
113   if (options & REFRESH_LOG)
114   {
115     /*
116       Flush the normal query log, the update log, the binary log,
117       the slow query log, the relay log (if it exists) and the log
118       tables.
119     */
120 
121     options|= REFRESH_BINARY_LOG;
122     options|= REFRESH_RELAY_LOG;
123     options|= REFRESH_SLOW_LOG;
124     options|= REFRESH_GENERAL_LOG;
125     options|= REFRESH_ENGINE_LOG;
126     options|= REFRESH_ERROR_LOG;
127   }
128 
129   if (options & REFRESH_ERROR_LOG)
130     if (flush_error_log())
131     {
132       /*
133         When flush_error_log() failed, my_error() has not been called.
134         So, we have to do it here to keep the protocol.
135       */
136       my_error(ER_UNKNOWN_ERROR, MYF(0));
137       result= 1;
138     }
139 
140   if ((options & REFRESH_SLOW_LOG) && opt_slow_log)
141     if (logger.flush_slow_log())
142       result= 1;
143 
144   if ((options & REFRESH_GENERAL_LOG) && opt_log)
145     if (logger.flush_general_log())
146       result= 1;
147 
148   if (options & REFRESH_ENGINE_LOG)
149     if (ha_flush_logs(NULL))
150       result= 1;
151   if ((options & REFRESH_BINARY_LOG) || (options & REFRESH_RELAY_LOG ))
152   {
153     /*
154       If reload_acl_and_cache() is called from SIGHUP handler we have to
155       allocate temporary THD for execution of binlog/relay log rotation.
156      */
157     THD *tmp_thd= 0;
158     if (!thd && (thd= (tmp_thd= new THD)))
159     {
160       thd->thread_stack= (char *) (&tmp_thd);
161       thd->store_globals();
162     }
163 
164     if (options & REFRESH_BINARY_LOG)
165     {
166       /*
167         Writing this command to the binlog may result in infinite loops
168         when doing mysqlbinlog|mysql, and anyway it does not really make
169         sense to log it automatically (would cause more trouble to users
170         than it would help them)
171        */
172       tmp_write_to_binlog= 0;
173       if (mysql_bin_log.is_open())
174       {
175         if (mysql_bin_log.rotate_and_purge(thd, true))
176           *write_to_binlog= -1;
177       }
178     }
179     if (options & REFRESH_RELAY_LOG)
180     {
181 #ifdef HAVE_REPLICATION
182       mysql_mutex_lock(&LOCK_active_mi);
183       if (active_mi != NULL)
184       {
185         mysql_mutex_lock(&active_mi->data_lock);
186         if (rotate_relay_log(active_mi, true/*need_log_space_lock=true*/))
187           *write_to_binlog= -1;
188         mysql_mutex_unlock(&active_mi->data_lock);
189       }
190       mysql_mutex_unlock(&LOCK_active_mi);
191 #endif
192     }
193     if (tmp_thd)
194     {
195       delete tmp_thd;
196       /* Remember that we don't have a THD */
197       my_pthread_setspecific_ptr(THR_THD,  0);
198       thd= 0;
199     }
200   }
201 #ifdef HAVE_QUERY_CACHE
202   if (options & REFRESH_QUERY_CACHE_FREE)
203   {
204     query_cache.pack();				// FLUSH QUERY CACHE
205     options &= ~REFRESH_QUERY_CACHE;    // Don't flush cache, just free memory
206   }
207   if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
208   {
209     query_cache.flush();			// RESET QUERY CACHE
210   }
211 #endif /*HAVE_QUERY_CACHE*/
212 
213   DBUG_ASSERT(!thd || thd->locked_tables_mode ||
214               !thd->mdl_context.has_locks() ||
215               thd->handler_tables_hash.records ||
216               thd->ull_hash.records ||
217               thd->global_read_lock.is_acquired() ||
218               thd->backup_tables_lock.is_acquired() ||
219               thd->backup_binlog_lock.is_acquired());
220 
221   /*
222     Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too
223     (see sql_yacc.yy)
224   */
225   if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
226   {
227     if ((options & REFRESH_READ_LOCK) && thd)
228     {
229       /*
230         On the first hand we need write lock on the tables to be flushed,
231         on the other hand we must not try to aspire a global read lock
232         if we have a write locked table as this would lead to a deadlock
233         when trying to reopen (and re-lock) the table after the flush.
234       */
235       if (thd->locked_tables_mode)
236       {
237         my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
238         return 1;
239       }
240       /*
241 	Writing to the binlog could cause deadlocks, as we don't log
242 	UNLOCK TABLES
243       */
244       tmp_write_to_binlog= 0;
245       if (thd->global_read_lock.lock_global_read_lock(thd))
246 	return 1;                               // Killed
247       if (close_cached_tables(thd, tables,
248                               ((options & REFRESH_FAST) ?  FALSE : TRUE),
249                               thd->variables.lock_wait_timeout))
250       {
251         /*
252           NOTE: my_error() has been already called by reopen_tables() within
253           close_cached_tables().
254         */
255         result= 1;
256       }
257 
258       if (thd->global_read_lock.make_global_read_lock_block_commit(thd)) // Killed
259       {
260         /* Don't leave things in a half-locked state */
261         thd->global_read_lock.unlock_global_read_lock(thd);
262         return 1;
263       }
264     }
265     else
266     {
267       if (thd && thd->locked_tables_mode)
268       {
269         /*
270           If we are under LOCK TABLES we should have a write
271           lock on tables which we are going to flush.
272         */
273         if (tables)
274         {
275           for (TABLE_LIST *t= tables; t; t= t->next_local)
276             if (!find_table_for_mdl_upgrade(thd, t->db, t->table_name, false))
277               return 1;
278         }
279         else
280         {
281           /*
282             It is not safe to upgrade the metadata lock without GLOBAL IX lock.
283             This can happen with FLUSH TABLES <list> WITH READ LOCK as we in these
284             cases don't take a GLOBAL IX lock in order to be compatible with
285             global read lock.
286           */
287           if (thd->open_tables &&
288               !thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "",
289                                               MDL_INTENTION_EXCLUSIVE))
290           {
291             my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),
292                      thd->open_tables->s->table_name.str);
293             return true;
294           }
295 
296           for (TABLE *tab= thd->open_tables; tab; tab= tab->next)
297           {
298             if (! tab->mdl_ticket->is_upgradable_or_exclusive())
299             {
300               my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),
301                        tab->s->table_name.str);
302               return 1;
303             }
304           }
305         }
306       }
307 
308       if (close_cached_tables(thd, tables,
309                               ((options & REFRESH_FAST) ?  FALSE : TRUE),
310                               (thd ? thd->variables.lock_wait_timeout :
311                                LONG_TIMEOUT)))
312       {
313         /*
314           NOTE: my_error() has been already called by reopen_tables() within
315           close_cached_tables().
316         */
317         result= 1;
318       }
319     }
320     my_dbopt_cleanup();
321   }
322   if (options & REFRESH_HOSTS)
323     hostname_cache_refresh();
324   if (thd && (options & REFRESH_STATUS))
325     refresh_status(thd);
326   if (options & REFRESH_THREADS)
327     kill_blocked_pthreads();
328 #ifdef HAVE_REPLICATION
329   if (options & REFRESH_MASTER)
330   {
331     DBUG_ASSERT(thd);
332     tmp_write_to_binlog= 0;
333     if (reset_master(thd))
334     {
335       /* NOTE: my_error() has been already called by reset_master(). */
336       result= 1;
337     }
338   }
339 #endif
340 #ifdef HAVE_OPENSSL
341    if (options & REFRESH_DES_KEY_FILE)
342    {
343      if (des_key_file && load_des_key_file(des_key_file))
344      {
345        /* NOTE: my_error() has been already called by load_des_key_file(). */
346        result= 1;
347      }
348    }
349 #endif
350 #ifdef HAVE_REPLICATION
351  if (options & REFRESH_SLAVE)
352  {
353    tmp_write_to_binlog= 0;
354    mysql_mutex_lock(&LOCK_active_mi);
355    if (active_mi != NULL && reset_slave(thd, active_mi))
356    {
357      /* NOTE: my_error() has been already called by reset_slave(). */
358      result= 1;
359    }
360    else if (active_mi == NULL)
361    {
362      result= 1;
363      my_error(ER_SLAVE_CONFIGURATION, MYF(0));
364    }
365    mysql_mutex_unlock(&LOCK_active_mi);
366  }
367 #endif
368   if (options & REFRESH_USER_RESOURCES)
369     reset_mqh((LEX_USER *) NULL, 0);             /* purecov: inspected */
370 #ifndef EMBEDDED_LIBRARY
371   if (options & REFRESH_TABLE_STATS)
372   {
373     mysql_mutex_lock(&LOCK_global_table_stats);
374     free_global_table_stats();
375     init_global_table_stats();
376     mysql_mutex_unlock(&LOCK_global_table_stats);
377   }
378   if (options & REFRESH_INDEX_STATS)
379   {
380     mysql_mutex_lock(&LOCK_global_index_stats);
381     free_global_index_stats();
382     init_global_index_stats();
383     mysql_mutex_unlock(&LOCK_global_index_stats);
384   }
385   if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS | REFRESH_THREAD_STATS))
386   {
387     mysql_mutex_lock(&LOCK_global_user_client_stats);
388     if (options & REFRESH_USER_STATS)
389     {
390       free_global_user_stats();
391       init_global_user_stats();
392     }
393     if (options & REFRESH_CLIENT_STATS)
394     {
395       free_global_client_stats();
396       init_global_client_stats();
397     }
398     if (options & REFRESH_THREAD_STATS)
399     {
400       free_global_thread_stats();
401       init_global_thread_stats();
402     }
403     mysql_mutex_unlock(&LOCK_global_user_client_stats);
404   }
405 #endif
406   if (options & REFRESH_FLUSH_PAGE_BITMAPS)
407   {
408     result= ha_flush_changed_page_bitmaps();
409     if (result)
410     {
411       my_error(ER_UNKNOWN_ERROR, MYF(0), "FLUSH CHANGED_PAGE_BITMAPS");
412     }
413   }
414   if (options & REFRESH_RESET_PAGE_BITMAPS)
415   {
416     result= ha_purge_changed_page_bitmaps(0);
417     if (result)
418     {
419       my_error(ER_UNKNOWN_ERROR, MYF(0), "RESET CHANGED_PAGE_BITMAPS");
420     }
421   }
422  if (*write_to_binlog != -1)
423  {
424    if (thd == NULL || thd->security_ctx == NULL)
425    {
426      *write_to_binlog=
427        opt_binlog_skip_flush_commands ? 0 : tmp_write_to_binlog;
428    }
429    else if ((thd->security_ctx->master_access & SUPER_ACL) != 0)
430    {
431      /*
432        For users with 'SUPER' privilege 'FLUSH XXX' statements must not be
433        binlogged if 'super_read_only' is set to 'ON'.
434      */
435      if (opt_super_readonly)
436        *write_to_binlog= 0;
437      else
438        *write_to_binlog=
439          opt_binlog_skip_flush_commands ? 0 : tmp_write_to_binlog;
440    }
441    else
442    {
443      /*
444        For users without 'SUPER' privilege 'FLUSH XXX' statements must not be
445        binlogged if 'read_only' or 'super_read_only' is set to 'ON'.
446        Checking only 'opt_readonly' here as in 'super_read_only' mode this
447        variable is implicitly set to 'true'.
448      */
449      if (opt_readonly)
450        *write_to_binlog= 0;
451      else
452        *write_to_binlog=
453          opt_binlog_skip_flush_commands ? 0 : tmp_write_to_binlog;
454    }
455  }
456  /*
457    If the query was killed then this function must fail.
458  */
459  return result || (thd ? thd->killed : 0);
460 }
461 
462 
463 /**
464   Implementation of FLUSH TABLES <table_list> WITH READ LOCK.
465 
466   In brief: take exclusive locks, expel tables from the table
467   cache, reopen the tables, enter the 'LOCKED TABLES' mode,
468   downgrade the locks.
469   Note: the function is written to be called from
470   mysql_execute_command(), it is not reusable in arbitrary
471   execution context.
472 
473   Required privileges
474   -------------------
475   Since the statement implicitly enters LOCK TABLES mode,
476   it requires LOCK TABLES privilege on every table.
477   But since the rest of FLUSH commands require
478   the global RELOAD_ACL, it also requires RELOAD_ACL.
479 
480   Compatibility with the global read lock
481   ---------------------------------------
482   We don't wait for the GRL, since neither the
483   5.1 combination that this new statement is intended to
484   replace (LOCK TABLE <list> WRITE; FLUSH TABLES;),
485   nor FLUSH TABLES WITH READ LOCK do.
486   @todo: this is not implemented, Dmitry disagrees.
487   Currently we wait for GRL in another connection,
488   but are compatible with a GRL in our own connection.
489 
490   Behaviour under LOCK TABLES
491   ---------------------------
492   Bail out: i.e. don't perform an implicit UNLOCK TABLES.
493   This is not consistent with LOCK TABLES statement, but is
494   in line with behaviour of FLUSH TABLES WITH READ LOCK, and we
495   try to not introduce any new statements with implicit
496   semantics.
497 
498   Compatibility with parallel updates
499   -----------------------------------
500   As a result, we will wait for all open transactions
501   against the tables to complete. After the lock downgrade,
502   new transactions will be able to read the tables, but not
503   write to them.
504 
505   Differences from FLUSH TABLES <list>
506   -------------------------------------
507   - you can't flush WITH READ LOCK a non-existent table
508   - you can't flush WITH READ LOCK under LOCK TABLES
509 
510   Effect on views and temporary tables.
511   ------------------------------------
512   You can only apply this command to existing base tables.
513   If a view with such name exists, ER_WRONG_OBJECT is returned.
514   If a temporary table with such name exists, it's ignored:
515   if there is a base table, it's used, otherwise ER_NO_SUCH_TABLE
516   is returned.
517 
518   Handling of MERGE tables
519   ------------------------
520   For MERGE table this statement will open and lock child tables
521   for read (it is impossible to lock parent table without it).
522   Child tables won't be flushed unless they are explicitly present
523   in the statement's table list.
524 
525   Implicit commit
526   ---------------
527   This statement causes an implicit commit before and
528   after it.
529 
530   HANDLER SQL
531   -----------
532   If this connection has HANDLERs open against
533   some of the tables being FLUSHed, these handlers
534   are implicitly flushed (lose their position).
535 */
536 
flush_tables_with_read_lock(THD * thd,TABLE_LIST * all_tables)537 bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
538 {
539   Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
540   TABLE_LIST *table_list;
541 
542   /*
543     This is called from SQLCOM_FLUSH, the transaction has
544     been committed implicitly.
545   */
546 
547   if (thd->locked_tables_mode)
548   {
549     my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
550     goto error;
551   }
552 
553   /*
554     Acquire SNW locks on tables to be flushed. Don't acquire global
555     IX and database-scope IX locks on the tables as this will make
556     this statement incompatible with FLUSH TABLES WITH READ LOCK.
557   */
558   if (lock_table_names(thd, all_tables, NULL,
559                        thd->variables.lock_wait_timeout,
560                        MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK))
561     goto error;
562 
563   DEBUG_SYNC(thd,"flush_tables_with_read_lock_after_acquire_locks");
564 
565   for (table_list= all_tables; table_list;
566        table_list= table_list->next_global)
567   {
568     /* Request removal of table from cache. */
569     tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
570                      table_list->db,
571                      table_list->table_name, FALSE);
572     /* Reset ticket to satisfy asserts in open_tables(). */
573     table_list->mdl_request.ticket= NULL;
574   }
575 
576   /*
577     Before opening and locking tables the below call also waits
578     for old shares to go away, so the fact that we don't pass
579     MYSQL_OPEN_IGNORE_FLUSH flag to it is important.
580     Also we don't pass MYSQL_OPEN_HAS_MDL_LOCK flag as we want
581     to open underlying tables if merge table is flushed.
582     For underlying tables of the merge the below call has to
583     acquire SNW locks to ensure that they can be locked for
584     read without further waiting.
585   */
586   if (open_and_lock_tables(thd, all_tables, FALSE,
587                            MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK,
588                            &lock_tables_prelocking_strategy) ||
589       thd->locked_tables_list.init_locked_tables(thd))
590   {
591     goto error;
592   }
593   thd->variables.option_bits|= OPTION_TABLE_LOCK;
594 
595   /*
596     We don't downgrade MDL_SHARED_NO_WRITE here as the intended
597     post effect of this call is identical to LOCK TABLES <...> READ,
598     and we didn't use thd->in_lock_talbes and
599     thd->sql_command= SQLCOM_LOCK_TABLES hacks to enter the LTM.
600   */
601 
602   return FALSE;
603 
604 error:
605   return TRUE;
606 }
607 
608 
609 /**
610   Prepare tables for export (transportable tablespaces) by
611   a) waiting until write transactions/DDL operations using these
612      tables have completed.
613   b) block new write operations/DDL operations on these tables.
614 
615   Once this is done, notify the storage engines using handler::extra().
616 
617   Finally, enter LOCK TABLES mode, so that locks are held
618   until UNLOCK TABLES is executed.
619 
620   @param thd         Thread handler
621   @param all_tables  TABLE_LIST for tables to be exported
622 
623   @retval false  Ok
624   @retval true   Error
625 */
626 
flush_tables_for_export(THD * thd,TABLE_LIST * all_tables)627 bool flush_tables_for_export(THD *thd, TABLE_LIST *all_tables)
628 {
629   Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
630 
631   /*
632     This is called from SQLCOM_FLUSH, the transaction has
633     been committed implicitly.
634   */
635 
636   if (thd->locked_tables_mode)
637   {
638     my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
639     return true;
640   }
641 
642   /*
643     Acquire SNW locks on tables to be exported. Don't acquire
644     global IX as this will make this statement incompatible
645     with FLUSH TABLES WITH READ LOCK.
646   */
647   if (open_and_lock_tables(thd, all_tables, false,
648                            MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK,
649                            &lock_tables_prelocking_strategy))
650   {
651     return true;
652   }
653 
654   // Check if all storage engines support FOR EXPORT.
655   for (TABLE_LIST *table_list= all_tables; table_list;
656        table_list= table_list->next_global)
657   {
658     if (!(table_list->table->file->ha_table_flags() & HA_CAN_EXPORT))
659     {
660       my_error(ER_ILLEGAL_HA, MYF(0), table_list->table_name);
661       return true;
662     }
663   }
664 
665   // Notify the storage engines that the tables should be made ready for export.
666   for (TABLE_LIST *table_list= all_tables; table_list;
667        table_list= table_list->next_global)
668   {
669     handler *handler_file= table_list->table->file;
670     int error= handler_file->extra(HA_EXTRA_EXPORT);
671     if (error)
672     {
673       handler_file->print_error(error, MYF(0));
674       return true;
675     }
676   }
677 
678   // Enter LOCKED TABLES mode.
679   if (thd->locked_tables_list.init_locked_tables(thd))
680     return true;
681   thd->variables.option_bits|= OPTION_TABLE_LOCK;
682 
683   return false;
684 }
685