⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 row0mysql.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
	trx->op_info = "";	return((int) err);}/*************************************************************************Does an index creation operation for MySQL. TODO: currently failureto create an index results in dropping the whole table! This is no problemcurrently as all indexes must be created at the same time as the table. */introw_create_index_for_mysql(/*=======================*/					/* out: error number or DB_SUCCESS */	dict_index_t*	index,		/* in: index definition */	trx_t*		trx,		/* in: transaction handle */	const ulint*	field_lengths)	/* in: if not NULL, must contain					dict_index_get_n_fields(index)					actual field lengths for the					index columns, which are					then checked for not being too					large. */{	ind_node_t*	node;	mem_heap_t*	heap;	que_thr_t*	thr;	ulint		err;	ulint		i, j;	ulint		len;	#ifdef UNIV_SYNC_DEBUG	ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));	ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());		trx->op_info = "creating index";	trx_start_if_not_started(trx);	/* Check that the same column does not appear twice in the index.	Starting from 4.0.14, InnoDB should be able to cope with that, but	safer not to allow them. */	for (i = 0; i < dict_index_get_n_fields(index); i++) {		for (j = 0; j < i; j++) {			if (0 == ut_strcmp(			      dict_index_get_nth_field(index, j)->name,			      dict_index_get_nth_field(index, i)->name)) {				ut_print_timestamp(stderr);				fputs("  InnoDB: Error: column ", stderr);				ut_print_name(stderr, trx,				dict_index_get_nth_field(index, i)->name);				fputs(" appears twice in ", stderr);				dict_index_name_print(stderr, trx, index);				fputs("\n"				"InnoDB: This is not allowed in InnoDB.\n",					stderr);				err = DB_COL_APPEARS_TWICE_IN_INDEX;				goto error_handling;			}		}				/* Check also that prefix_len and actual length		< DICT_MAX_INDEX_COL_LEN */		len = dict_index_get_nth_field(index, i)->prefix_len;		if (field_lengths) {			len = ut_max(len, field_lengths[i]);		}				if (len >= DICT_MAX_INDEX_COL_LEN) {			err = DB_TOO_BIG_RECORD;			goto error_handling;		}	}	if (row_mysql_is_recovered_tmp_table(index->table_name)) {		return(DB_SUCCESS);	}	heap = mem_heap_create(512);	trx->dict_operation = TRUE;	/* Note that the space id where we store the index is inherited from	the table in dict_build_index_def_step() in dict0crea.c. */	node = ind_create_graph_create(index, heap);	thr = pars_complete_graph_for_exec(node, trx, heap);	ut_a(thr == que_fork_start_command(que_node_get_parent(thr)));	que_run_threads(thr); 	err = trx->error_state;	que_graph_free((que_t*) que_node_get_parent(thr));error_handling:	if (err != DB_SUCCESS) {		/* We have special error handling here */				trx->error_state = DB_SUCCESS;		trx_general_rollback_for_mysql(trx, FALSE, NULL);		row_drop_table_for_mysql(index->table_name, trx, FALSE);		trx->error_state = DB_SUCCESS;	}		trx->op_info = "";	return((int) err);}/*************************************************************************Scans a table create SQL string and adds to the data dictionarythe foreign key constraints declared in the string. This functionshould be called after the indexes for a table have been created.Each foreign key constraint must be accompanied with indexes inbot participating tables. The indexes are allowed to contain morefields than mentioned in the constraint. Check also that foreign keyconstraints which reference this table are ok. */introw_table_add_foreign_constraints(/*==============================*/					/* out: error code or DB_SUCCESS */	trx_t*		trx,		/* in: transaction */	const char*	sql_string,	/* in: table create statement where					foreign keys are declared like:				FOREIGN KEY (a, b) REFERENCES table2(c, d),					table2 can be written also with the					database name before it: test.table2 */	const char*	name,		/* in: table full name in the					normalized form					database_name/table_name */	ibool		reject_fks)	/* in: if TRUE, fail with error					code DB_CANNOT_ADD_CONSTRAINT if					any foreign keys are found. */{	ulint	err;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(dict_sys->mutex)));	ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));#endif /* UNIV_SYNC_DEBUG */	ut_a(sql_string);		trx->op_info = "adding foreign keys";	trx_start_if_not_started(trx);	if (row_mysql_is_recovered_tmp_table(name)) {		return(DB_SUCCESS);	}	trx->dict_operation = TRUE;	err = dict_create_foreign_constraints(trx, sql_string, name,		reject_fks);	if (err == DB_SUCCESS) {		/* Check that also referencing constraints are ok */		err = dict_load_foreigns(name, TRUE);	}	if (err != DB_SUCCESS) {		/* We have special error handling here */				trx->error_state = DB_SUCCESS;		trx_general_rollback_for_mysql(trx, FALSE, NULL);		row_drop_table_for_mysql(name, trx, FALSE);		trx->error_state = DB_SUCCESS;	}	return((int) err);}/*************************************************************************Drops a table for MySQL as a background operation. MySQL relies on Unixin ALTER TABLE to the fact that the table handler does not remove thetable before all handles to it has been removed. Furhermore, the MySQL'scall to drop table must be non-blocking. Therefore we do the drop tableas a background operation, which is taken care of by the master threadin srv0srv.c. */staticintrow_drop_table_for_mysql_in_background(/*===================================*/				/* out: error code or DB_SUCCESS */	const char*	name)	/* in: table name */{	ulint	error;	trx_t*	trx;	trx = trx_allocate_for_background();	/* If the original transaction was dropping a table referenced by	foreign keys, we must set the following to be able to drop the	table: */	trx->check_foreigns = FALSE;/*	fputs("InnoDB: Error: Dropping table ", stderr);	ut_print_name(stderr, name);	fputs(" in background drop list\n", stderr); */  	/* Try to drop the table in InnoDB */  	error = row_drop_table_for_mysql(name, trx, FALSE);  		/* Flush the log to reduce probability that the .frm files and	the InnoDB data dictionary get out-of-sync if the user runs	with innodb_flush_log_at_trx_commit = 0 */		log_buffer_flush_to_disk();  	trx_commit_for_mysql(trx);  	trx_free_for_background(trx);	return((int) error);}/*************************************************************************The master thread in srv0srv.c calls this regularly to drop tables whichwe must drop in background after queries to them have ended. Such lazydropping of tables is needed in ALTER TABLE on Unix. */ulintrow_drop_tables_for_mysql_in_background(void)/*=========================================*/					/* out: how many tables dropped					+ remaining tables in list */{	row_mysql_drop_t*	drop;	dict_table_t*		table;	ulint			n_tables;	ulint			n_tables_dropped = 0;loop:		mutex_enter(&kernel_mutex);	if (!row_mysql_drop_list_inited) {		UT_LIST_INIT(row_mysql_drop_list);		row_mysql_drop_list_inited = TRUE;	}	drop = UT_LIST_GET_FIRST(row_mysql_drop_list);		n_tables = UT_LIST_GET_LEN(row_mysql_drop_list);	mutex_exit(&kernel_mutex);	if (drop == NULL) {		/* All tables dropped */		return(n_tables + n_tables_dropped);	}	mutex_enter(&(dict_sys->mutex));	table = dict_table_get_low(drop->table_name);	mutex_exit(&(dict_sys->mutex));	if (table == NULL) {	        /* If for some reason the table has already been dropped		through some other mechanism, do not try to drop it */	        goto already_dropped;	}								if (DB_SUCCESS != row_drop_table_for_mysql_in_background(							drop->table_name)) {		/* If the DROP fails for some table, we return, and let the		main thread retry later */		return(n_tables + n_tables_dropped);	}	n_tables_dropped++;already_dropped:	mutex_enter(&kernel_mutex);	UT_LIST_REMOVE(row_mysql_drop_list, row_mysql_drop_list, drop);        ut_print_timestamp(stderr);	fprintf(stderr,		"  InnoDB: Dropped table %s in background drop queue.\n",		drop->table_name);	mem_free(drop->table_name);	mem_free(drop);	mutex_exit(&kernel_mutex);	goto loop;}/*************************************************************************Get the background drop list length. NOTE: the caller must own the kernelmutex! */ulintrow_get_background_drop_list_len_low(void)/*======================================*/					/* out: how many tables in list */{#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&kernel_mutex));#endif /* UNIV_SYNC_DEBUG */	if (!row_mysql_drop_list_inited) {		UT_LIST_INIT(row_mysql_drop_list);		row_mysql_drop_list_inited = TRUE;	}		return(UT_LIST_GET_LEN(row_mysql_drop_list));}/*************************************************************************If a table is not yet in the drop list, adds the table to the list of tableswhich the master thread drops in background. We need this on Unix because inALTER TABLE MySQL may call drop table even if the table has running queries onit. Also, if there are running foreign key checks on the table, we drop thetable lazily. */staticiboolrow_add_table_to_background_drop_list(/*==================================*/				/* out: TRUE if the table was not yet in the				drop list, and was added there */	dict_table_t*	table)	/* in: table */{	row_mysql_drop_t*	drop;		mutex_enter(&kernel_mutex);	if (!row_mysql_drop_list_inited) {		UT_LIST_INIT(row_mysql_drop_list);		row_mysql_drop_list_inited = TRUE;	}		/* Look if the table already is in the drop list */	drop = UT_LIST_GET_FIRST(row_mysql_drop_list);	while (drop != NULL) {		if (strcmp(drop->table_name, table->name) == 0) {			/* Already in the list */						mutex_exit(&kernel_mutex);			return(FALSE);		}		drop = UT_LIST_GET_NEXT(row_mysql_drop_list, drop);	}	drop = mem_alloc(sizeof(row_mysql_drop_t));	drop->table_name = mem_strdup(table->name); 	UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop);	/*	fputs("InnoDB: Adding table ", stderr);	ut_print_name(stderr, drop->table_name);	fputs(" to background drop list\n", stderr); */	mutex_exit(&kernel_mutex);	return(TRUE);}#ifndef UNIV_HOTBACKUP/*************************************************************************Discards the tablespace of a table which stored in an .ibd file. Discardingmeans that this function deletes the .ibd file and assigns a new table id forthe table. Also the flag table->ibd_file_missing is set TRUE. */introw_discard_tablespace_for_mysql(/*=============================*/				/* out: error code or DB_SUCCESS */	const char*	name,	/* in: table name */	trx_t*		trx)	/* in: transaction handle */{	dict_foreign_t*	foreign;	dulint		new_id;	dict_table_t*	table;	que_thr_t*	thr;	que_t*		graph			= NULL;	ibool		success;	ulint		err;	char*		buf;/* How do we prevent crashes caused by ongoing operations on the table? Oldoperations could try to access non-existent pages.1) SQL queries, INSERT, SELECT, ...: we must get an exclusive MySQL table lockon the table before we can do DISCARD TABLESPACE. Then there are no runningqueries on the table.2) Purge and rollback: we assign a new table id for the table. Since purge androllback look for the table based on the table id, they see the table as'dropped' and discard their operations.3) Insert buffer: we remove all entries for the tablespace in the insertbuffer tree; as long as the tablespace mem object does not exist, ongoinginsert buffer page merges are discarded in buf0rea.c. If we recreate thetablespace mem object with IMPORT TABLESPACE later, then the tablespace willhave the same id, but the tablespace_version field in the mem object isdifferent, and ongoing old insert buffer page merges get discarded.4) Linear readahead and random readahead: we use the same method as in 3) todiscard ongoing operations.5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, wedo not allow the discard. We also reserve the data dictionary latch. */	static const char discard_tablespace_proc1[] =	"PROCEDURE DISCARD_TABLESPACE_PROC () IS\n"	"old_id CHAR;\n"	"new_id CHAR;\n"	"new_id_low INT;\n"	"new_id_high INT;\n"	"table_name CHAR;\n"	"BEGIN\n"	"table_name := '";	static const char discard_tablespace_proc2[] =	"';\n"	"new_id_high := %lu;\n"	"new_id_low := %lu;\n"   "new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n"	"SELECT ID INTO old_id\n"	"FROM SYS_TABLES\n"	"WHERE NAME = table_name;\n"	"IF (SQL %% NOTFOUND) THEN\n"	"	COMMIT WORK;\n"	"	RETURN;\n"	"END IF;\n"	"UPDATE SYS_TABLES SET ID = new_id\n"	"WHERE ID = old_id;\n"	"UPDATE SYS_COLUMNS SET TABLE_ID = new_id\n"	"WHERE TABLE_ID = old_id;\n"	"UPDATE SYS_INDEXES SET TABLE_ID = new_id\n"	"WHERE TABLE_ID = old_id;\n"	"COMMIT WORK;\n"	"END;\n";	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());	trx->op_info = "discarding tablespace";	trx_start_if_not_started(trx);	/* Serialize data dictionary operations with dictionary mutex:	no deadlocks can occur then in these operations */	row_mysql_lock_data_dictionary(trx);	table = dict_table_get_low(name);	if (!table) {		err = DB_TABLE_NOT_FOUND;		goto funct_exit;	}	if (table->space == 0) {		ut_print_timestamp(stderr);		fputs("  InnoDB: Error: table ", stderr);		ut_print_name(stderr, trx, name);		fputs("\n""InnoDB: is in the system 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -