📄 srv0start.c
字号:
been shut down normally: this is the normal startup path */ err = recv_recovery_from_checkpoint_start(LOG_CHECKPOINT, ut_dulint_max, min_flushed_lsn, max_flushed_lsn); if (err != DB_SUCCESS) { return(DB_ERROR); } /* Since the insert buffer init is in dict_boot, and the insert buffer is needed in any disk i/o, first we call dict_boot(). Note that trx_sys_init_at_db_start() only needs to access space 0, and the insert buffer at this stage already works for space 0. */ dict_boot(); trx_sys_init_at_db_start(); if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) { /* The following call is necessary for the insert buffer to work with multiple tablespaces. We must know the mapping between space id's and .ibd file names. In a crash recovery, we check that the info in data dictionary is consistent with what we already know about space id's from the call of fil_load_single_table_tablespaces(). In a normal startup, we create the space objects for every table in the InnoDB data dictionary that has an .ibd file. We also determine the maximum tablespace id used. TODO: We may have incomplete transactions in the data dictionary tables. Does that harm the scanning of the data dictionary below? */ dict_check_tablespaces_and_store_max_id( recv_needed_recovery); } srv_startup_is_before_trx_rollback_phase = FALSE; /* Initialize the fsp free limit global variable in the log system */ fsp_header_get_free_limit(0); /* recv_recovery_from_checkpoint_finish needs trx lists which are initialized in trx_sys_init_at_db_start(). */ recv_recovery_from_checkpoint_finish(); } if (!create_new_db && sum_of_new_sizes > 0) { /* New data file(s) were added */ mtr_start(&mtr); fsp_header_inc_size(0, sum_of_new_sizes, &mtr); mtr_commit(&mtr); /* Immediately write the log record about increased tablespace size to disk, so that it is durable even if mysqld would crash quickly */ log_buffer_flush_to_disk(); }#ifdef UNIV_LOG_ARCHIVE /* Archiving is always off under MySQL */ if (!srv_log_archive_on) { ut_a(DB_SUCCESS == log_archive_noarchivelog()); } else { mutex_enter(&(log_sys->mutex)); start_archive = FALSE; if (log_sys->archiving_state == LOG_ARCH_OFF) { start_archive = TRUE; } mutex_exit(&(log_sys->mutex)); if (start_archive) { ut_a(DB_SUCCESS == log_archive_archivelog()); } }#endif /* UNIV_LOG_ARCHIVE */ if (srv_measure_contention) { /* os_thread_create(&test_measure_cont, NULL, thread_ids + SRV_MAX_N_IO_THREADS); */ } /* fprintf(stderr, "Max allowed record size %lu\n", page_get_free_space_of_empty() / 2); */ /* Create the thread which watches the timeouts for lock waits and prints InnoDB monitor info */ os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL, thread_ids + 2 + SRV_MAX_N_IO_THREADS); /* Create the thread which warns of long semaphore waits */ os_thread_create(&srv_error_monitor_thread, NULL, thread_ids + 3 + SRV_MAX_N_IO_THREADS); srv_was_started = TRUE; srv_is_being_started = FALSE;#ifdef UNIV_DEBUG /* Wait a while so that the created threads have time to suspend themselves before we switch sync debugging on; otherwise a thread may execute mutex_enter() before the checks are on, and mutex_exit() after the checks are on, which will cause an assertion failure in sync debug. */ os_thread_sleep(3000000);#endif sync_order_checks_on = TRUE; if (trx_doublewrite == NULL) { /* Create the doublewrite buffer to a new tablespace */ trx_sys_create_doublewrite_buf(); } err = dict_create_or_check_foreign_constraint_tables(); if (err != DB_SUCCESS) { return((int)DB_ERROR); } /* Create the master thread which does purge and other utility operations */ os_thread_create(&srv_master_thread, NULL, thread_ids + 1 + SRV_MAX_N_IO_THREADS);#ifdef UNIV_DEBUG /* buf_debug_prints = TRUE; */#endif /* UNIV_DEBUG */ sum_of_data_file_sizes = 0; for (i = 0; i < srv_n_data_files; i++) { sum_of_data_file_sizes += srv_data_file_sizes[i]; } tablespace_size_in_header = fsp_header_get_tablespace_size(0); if (!srv_auto_extend_last_data_file && sum_of_data_file_sizes != tablespace_size_in_header) { fprintf(stderr,"InnoDB: Error: tablespace size stored in header is %lu pages, but\n""InnoDB: the sum of data file sizes is %lu pages\n", (ulong) tablespace_size_in_header, (ulong) sum_of_data_file_sizes); if (srv_force_recovery == 0 && sum_of_data_file_sizes < tablespace_size_in_header) { /* This is a fatal error, the tail of a tablespace is missing */ fprintf(stderr,"InnoDB: Cannot start InnoDB. The tail of the system tablespace is\n""InnoDB: missing. Have you edited innodb_data_file_path in my.cnf in an\n""InnoDB: inappropriate way, removing ibdata files from there?\n""InnoDB: You can set innodb_force_recovery=1 in my.cnf to force\n""InnoDB: a startup if you are trying to recover a badly corrupt database.\n"); return(DB_ERROR); } } if (srv_auto_extend_last_data_file && sum_of_data_file_sizes < tablespace_size_in_header) { fprintf(stderr,"InnoDB: Error: tablespace size stored in header is %lu pages, but\n""InnoDB: the sum of data file sizes is only %lu pages\n", (ulong) tablespace_size_in_header, (ulong) sum_of_data_file_sizes); if (srv_force_recovery == 0) { fprintf(stderr,"InnoDB: Cannot start InnoDB. The tail of the system tablespace is\n""InnoDB: missing. Have you edited innodb_data_file_path in my.cnf in an\n""InnoDB: inappropriate way, removing ibdata files from there?\n""InnoDB: You can set innodb_force_recovery=1 in my.cnf to force\n""InnoDB: a startup if you are trying to recover a badly corrupt database.\n"); return(DB_ERROR); } } /* Check that os_fast_mutexes work as expected */ os_fast_mutex_init(&srv_os_test_mutex); if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) { fprintf(stderr,"InnoDB: Error: pthread_mutex_trylock returns an unexpected value on\n""InnoDB: success! Cannot continue.\n"); exit(1); } os_fast_mutex_unlock(&srv_os_test_mutex); os_fast_mutex_lock(&srv_os_test_mutex); os_fast_mutex_unlock(&srv_os_test_mutex); os_fast_mutex_free(&srv_os_test_mutex); if (srv_print_verbose_log) { ut_print_timestamp(stderr); fprintf(stderr," InnoDB: Started; log sequence number %lu %lu\n", (ulong) ut_dulint_get_high(srv_start_lsn), (ulong) ut_dulint_get_low(srv_start_lsn)); } if (srv_force_recovery > 0) { fprintf(stderr, "InnoDB: !!! innodb_force_recovery is set to %lu !!!\n", (ulong) srv_force_recovery); } fflush(stderr); if (trx_doublewrite_must_reset_space_ids) { /* Actually, we did not change the undo log format between 4.0 and 4.1.1, and we would not need to run purge to completion. Note also that the purge algorithm in 4.1.1 can process the the history list again even after a full purge, because our algorithm does not cut the end of the history list in all cases so that it would become empty after a full purge. That mean that we may purge 4.0 type undo log even after this phase. The insert buffer record format changed between 4.0 and 4.1.1. It is essential that the insert buffer is emptied here! */ fprintf(stderr,"InnoDB: You are upgrading to an InnoDB version which allows multiple\n""InnoDB: tablespaces. Wait that purge and insert buffer merge run to\n""InnoDB: completion...\n"); for (;;) { os_thread_sleep(1000000); if (0 == strcmp(srv_main_thread_op_info, "waiting for server activity")) { ut_a(ibuf_is_empty()); break; } } fprintf(stderr,"InnoDB: Full purge and insert buffer merge completed.\n"); trx_sys_mark_upgraded_to_multiple_tablespaces(); fprintf(stderr,"InnoDB: You have now successfully upgraded to the multiple tablespaces\n""InnoDB: format. You should NOT DOWNGRADE to an earlier version of\n""InnoDB: InnoDB! But if you absolutely need to downgrade, see\n""InnoDB: http://dev.mysql.com/doc/mysql/en/Multiple_tablespaces.html\n""InnoDB: for instructions.\n"); } if (srv_force_recovery == 0) { /* In the insert buffer we may have even bigger tablespace id's, because we may have dropped those tablespaces, but insert buffer merge has not had time to clean the records from the ibuf tree. */ ibuf_update_max_tablespace_id(); } srv_file_per_table = srv_file_per_table_original_value; return((int) DB_SUCCESS);}/********************************************************************Shuts down the InnoDB database. */intinnobase_shutdown_for_mysql(void) /*=============================*/ /* out: DB_SUCCESS or error code */{ ulint i;#ifdef __NETWARE__ extern ibool panic_shutdown;#endif if (!srv_was_started) { if (srv_is_being_started) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Warning: shutting down a not properly started\n"" InnoDB: or created database!\n"); } return(DB_SUCCESS); } /* 1. Flush the buffer pool to disk, write the current lsn to the tablespace header(s), and copy all log data to archive. The step 1 is the real InnoDB shutdown. The remaining steps 2 - ... just free data structures after the shutdown. */ if (srv_fast_shutdown == 2) { ut_print_timestamp(stderr); fprintf(stderr," InnoDB: MySQL has requested a very fast shutdown without flushing ""the InnoDB buffer pool to data files. At the next mysqld startup ""InnoDB will do a crash recovery!\n"); }#ifdef __NETWARE__ if(!panic_shutdown)#endif logs_empty_and_mark_files_at_shutdown(); if (srv_conc_n_threads != 0) { fprintf(stderr, "InnoDB: Warning: query counter shows %ld queries still\n" "InnoDB: inside InnoDB at shutdown\n", srv_conc_n_threads); } /* 2. Make all threads created by InnoDB to exit */ srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS; /* In a 'very fast' shutdown, we do not need to wait for these threads to die; all which counts is that we flushed the log; a 'very fast' shutdown is essentially a crash. */ if (srv_fast_shutdown == 2) { return(DB_SUCCESS); } /* All threads end up waiting for certain events. Put those events to the signaled state. Then the threads will exit themselves in os_thread_event_wait(). */ for (i = 0; i < 1000; i++) { /* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM HERE OR EARLIER */ /* a. Let the lock timeout thread exit */ os_event_set(srv_lock_timeout_thread_event); /* b. srv error monitor thread exits automatically, no need to do anything here */ /* c. We wake the master thread so that it exits */ srv_wake_master_thread(); /* d. Exit the i/o threads */ os_aio_wake_all_threads_at_shutdown(); os_mutex_enter(os_sync_mutex); if (os_thread_count == 0) { /* All the threads have exited or are just exiting; NOTE that the threads may not have completed their exit yet. Should we use pthread_join() to make sure they have exited? Now we just sleep 0.1 seconds and hope that is enough! */ os_mutex_exit(os_sync_mutex); os_thread_sleep(100000); break; } os_mutex_exit(os_sync_mutex); os_thread_sleep(100000); } if (i == 1000) { fprintf(stderr,"InnoDB: Warning: %lu threads created by InnoDB had not exited at shutdown!\n", (ulong) os_thread_count); } if (srv_monitor_file) { fclose(srv_monitor_file); srv_monitor_file = 0; if (srv_monitor_file_name) { unlink(srv_monitor_file_name); mem_free(srv_monitor_file_name); } } if (srv_dict_tmpfile) { fclose(srv_dict_tmpfile); srv_dict_tmpfile = 0; } if (srv_misc_tmpfile) { fclose(srv_misc_tmpfile); srv_misc_tmpfile = 0; } mutex_free(&srv_monitor_file_mutex); mutex_free(&srv_dict_tmpfile_mutex); mutex_free(&srv_misc_tmpfile_mutex); /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside them */ sync_close(); /* 4. Free the os_conc_mutex and all os_events and os_mutexes */ srv_free(); os_sync_free(); /* Check that all read views are closed except read view owned by a purge. */ if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) { fprintf(stderr,"InnoDB: Error: all read views were not closed before shutdown:\n""InnoDB: %lu read views open \n", UT_LIST_GET_LEN(trx_sys->view_list) - 1); } /* 5. Free all allocated memory and the os_fast_mutex created in ut0mem.c */ ut_free_all_mem(); if (os_thread_count != 0 || os_event_count != 0 || os_mutex_count != 0 || os_fast_mutex_count != 0) { fprintf(stderr,"InnoDB: Warning: some resources were not cleaned up in shutdown:\n""InnoDB: threads %lu, events %lu, os_mutexes %lu, os_fast_mutexes %lu\n", (ulong) os_thread_count, (ulong) os_event_count, (ulong) os_mutex_count, (ulong) os_fast_mutex_count); } if (dict_foreign_err_file) { fclose(dict_foreign_err_file); } if (lock_latest_err_file) { fclose(lock_latest_err_file); } if (srv_print_verbose_log) { ut_print_timestamp(stderr); fprintf(stderr," InnoDB: Shutdown completed; log sequence number %lu %lu\n", (ulong) ut_dulint_get_high(srv_shutdown_lsn), (ulong) ut_dulint_get_low(srv_shutdown_lsn)); } return((int) DB_SUCCESS);}#ifdef __NETWARE__void set_panic_flag_for_netware(){ extern ibool panic_shutdown; panic_shutdown = TRUE;}#endif /* __NETWARE__ */#endif /* !UNIV_HOTBACKUP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -