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