Exemple #1
0
/*******************************************************************//**
Roll back an active transaction. */
static
void
trx_rollback_active(
/*================*/
	trx_t*	trx)	/*!< in/out: transaction */
{
	mem_heap_t*	heap;
	que_fork_t*	fork;
	que_thr_t*	thr;
	roll_node_t*	roll_node;
	dict_table_t*	table;
	ib_int64_t	rows_to_undo;
	const char*	unit		= "";
	ibool		dictionary_locked = FALSE;

	heap = mem_heap_create(512);

	fork = que_fork_create(NULL, NULL, QUE_FORK_RECOVERY, heap);
	fork->trx = trx;

	thr = que_thr_create(fork, heap);

	roll_node = roll_node_create(heap);

	thr->child = roll_node;
	roll_node->common.parent = thr;

	mutex_enter(&kernel_mutex);

	trx->graph = fork;

	ut_a(thr == que_fork_start_command(fork));

	trx_roll_crash_recv_trx	= trx;
	trx_roll_max_undo_no = trx->undo_no;
	trx_roll_progress_printed_pct = 0;
	rows_to_undo = trx_roll_max_undo_no;

	if (rows_to_undo > 1000000000) {
		rows_to_undo = rows_to_undo / 1000000;
		unit = "M";
	}

	ut_print_timestamp(stderr);
	fprintf(stderr,
		"  InnoDB: Rolling back trx with id " TRX_ID_FMT ", %lu%s"
		" rows to undo\n",
		(ullint) trx->id,
		(ulong) rows_to_undo, unit);
	mutex_exit(&kernel_mutex);

	trx->mysql_thread_id = os_thread_get_curr_id();

	trx->mysql_process_no = os_proc_get_number();

	if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
		row_mysql_lock_data_dictionary(trx);
		dictionary_locked = TRUE;
	}

	que_run_threads(thr);

	mutex_enter(&kernel_mutex);

	while (trx->que_state != TRX_QUE_RUNNING) {

		mutex_exit(&kernel_mutex);

		fprintf(stderr,
			"InnoDB: Waiting for rollback of trx id "
			TRX_ID_FMT " to end\n",
			(ullint) trx->id);
		os_thread_sleep(100000);

		mutex_enter(&kernel_mutex);
	}

	mutex_exit(&kernel_mutex);

	if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE
	    && trx->table_id != 0) {

		/* If the transaction was for a dictionary operation, we
		drop the relevant table, if it still exists */

		fprintf(stderr,
			"InnoDB: Dropping table with id %llu"
			" in recovery if it exists\n",
			(ullint) trx->table_id);

		table = dict_table_get_on_id_low(trx->table_id);

		if (table) {
			ulint	err;

			fputs("InnoDB: Table found: dropping table ", stderr);
			ut_print_name(stderr, trx, TRUE, table->name);
			fputs(" in recovery\n", stderr);

			err = row_drop_table_for_mysql(table->name, trx, TRUE);
			trx_commit_for_mysql(trx);

			ut_a(err == (int) DB_SUCCESS);
		}
	}

	if (dictionary_locked) {
		row_mysql_unlock_data_dictionary(trx);
	}

	fprintf(stderr, "\nInnoDB: Rolling back of trx id " TRX_ID_FMT
		" completed\n",
		(ullint) trx->id);
	mem_heap_free(heap);

	trx_roll_crash_recv_trx	= NULL;
}
Exemple #2
0
/****************************************************************//**
Creates the foreign key constraints system tables inside InnoDB
at database creation or database start if they are not found or are
not of the right form.
@return	DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_create_or_check_foreign_constraint_tables(void)
/*================================================*/
{
    dict_table_t*	table1;
    dict_table_t*	table2;
    ulint		error;
    trx_t*		trx;

    mutex_enter(&(dict_sys->mutex));

    table1 = dict_table_get_low("SYS_FOREIGN");
    table2 = dict_table_get_low("SYS_FOREIGN_COLS");

    if (table1 && table2
            && UT_LIST_GET_LEN(table1->indexes) == 3
            && UT_LIST_GET_LEN(table2->indexes) == 1) {

        /* Foreign constraint system tables have already been
        created, and they are ok */

        mutex_exit(&(dict_sys->mutex));

        return(DB_SUCCESS);
    }

    mutex_exit(&(dict_sys->mutex));

    trx = trx_allocate_for_mysql();

    trx->op_info = "creating foreign key sys tables";

    row_mysql_lock_data_dictionary(trx);

    if (table1) {
        fprintf(stderr,
                "InnoDB: dropping incompletely created"
                " SYS_FOREIGN table\n");
        row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
    }

    if (table2) {
        fprintf(stderr,
                "InnoDB: dropping incompletely created"
                " SYS_FOREIGN_COLS table\n");
        row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
    }

    fprintf(stderr,
            "InnoDB: Creating foreign key constraint system tables\n");

    /* NOTE: in dict_load_foreigns we use the fact that
    there are 2 secondary indexes on SYS_FOREIGN, and they
    are defined just like below */

    /* NOTE: when designing InnoDB's foreign key support in 2001, we made
    an error and made the table names and the foreign key id of type
    'CHAR' (internally, really a VARCHAR). We should have made the type
    VARBINARY, like in other InnoDB system tables, to get a clean
    design. */

    error = que_eval_sql(NULL,
                         "PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
                         "BEGIN\n"
                         "CREATE TABLE\n"
                         "SYS_FOREIGN(ID CHAR, FOR_NAME CHAR,"
                         " REF_NAME CHAR, N_COLS INT);\n"
                         "CREATE UNIQUE CLUSTERED INDEX ID_IND"
                         " ON SYS_FOREIGN (ID);\n"
                         "CREATE INDEX FOR_IND"
                         " ON SYS_FOREIGN (FOR_NAME);\n"
                         "CREATE INDEX REF_IND"
                         " ON SYS_FOREIGN (REF_NAME);\n"
                         "CREATE TABLE\n"
                         "SYS_FOREIGN_COLS(ID CHAR, POS INT,"
                         " FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n"
                         "CREATE UNIQUE CLUSTERED INDEX ID_IND"
                         " ON SYS_FOREIGN_COLS (ID, POS);\n"
                         "END;\n"
                         , FALSE, trx);

    if (error != DB_SUCCESS) {
        fprintf(stderr, "InnoDB: error %lu in creation\n",
                (ulong) error);

        ut_a(error == DB_OUT_OF_FILE_SPACE
             || error == DB_TOO_MANY_CONCURRENT_TRXS);

        fprintf(stderr,
                "InnoDB: creation failed\n"
                "InnoDB: tablespace is full\n"
                "InnoDB: dropping incompletely created"
                " SYS_FOREIGN tables\n");

        row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
        row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);

        error = DB_MUST_GET_MORE_FILE_SPACE;
    }

    trx_commit_for_mysql(trx);

    row_mysql_unlock_data_dictionary(trx);

    trx_free_for_mysql(trx);

    if (error == DB_SUCCESS) {
        fprintf(stderr,
                "InnoDB: Foreign key constraint system tables"
                " created\n");
    }

    return(error);
}
Exemple #3
0
/****************************************************************//**
Creates the sys_added_cols_default table inside InnoDB
at database creation or database start if they are not found or are
not of the right form.
@return	DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_create_or_check_added_cols_default_tables(void)
/*================================================*/
{
    dict_table_t*	table1;

    ulint		error;
    trx_t*		trx;

    mutex_enter(&(dict_sys->mutex));

    table1 = dict_table_get_low("SYS_ADDED_COLS_DEFAULT");

    if (table1 && UT_LIST_GET_LEN(table1->indexes) == 1) {

        /* sys_added_cols_default table have already been
        created, and it's ok */

        mutex_exit(&(dict_sys->mutex));

#ifdef DEBUG
        fprintf(stderr,
                "SYS_ADDED_COLS_DEFAULT table have created success!!!!\n");
#endif
        return(DB_SUCCESS);
    }

#ifdef DEBUG
    fprintf(stderr,
            "SYS_ADDED_COLS_DEFAULT table have not created yet!!!\n");
#endif

    mutex_exit(&(dict_sys->mutex));

    trx = trx_allocate_for_mysql();

    trx->op_info = "creating added cols default";

    row_mysql_lock_data_dictionary(trx);

    /* sys_added_cols_default table have been created,but not OK,
    drop it and then recreate */
    if (table1) {
        fprintf(stderr,
                "InnoDB: dropping incompletely created"
                " SYS_ADDED_COLS_DEFAULT table\n");
        row_drop_table_for_mysql("SYS_ADDED_COLS_DEFAULT", trx, TRUE);
    }

    fprintf(stderr,
            "InnoDB: Creating sys_added_cols_default for fast add colums with default value\n");


    /*
        NOTE: We create the added cols default here.
        sys_added_cols_default(
        table_id    int,        //table id
        pos         int,        // column id
        def_val     varbinary,  //default value
        def_val_len int         //default value's length
        )
    */

    error = que_eval_sql(NULL,
                         "PROCEDURE CREATE_ADDED_COLS_DEFAULT_SYS_TABLES_PROC () IS\n"
                         "BEGIN\n"
                         "CREATE TABLE\n"
                         "SYS_ADDED_COLS_DEFAULT(TABLE_ID BINARY(8), POS INT,"
                         " DEF_VAL BINARY(65535), DEF_VAL_LEN INT);\n"
                         "CREATE UNIQUE CLUSTERED INDEX TID_POS"
                         " ON SYS_ADDED_COLS_DEFAULT (TABLE_ID,POS);\n"
                         "END;\n"
                         , FALSE, trx);

    if (error != DB_SUCCESS) {
        fprintf(stderr, "InnoDB: error %lu in creation\n",
                (ulong) error);

        ut_a(error == DB_OUT_OF_FILE_SPACE
             || error == DB_TOO_MANY_CONCURRENT_TRXS);

        fprintf(stderr,
                "InnoDB: creation failed\n"
                "InnoDB: tablespace is full\n"
                "InnoDB: dropping incompletely created"
                " SYS_FOREIGN tables\n");

        row_drop_table_for_mysql("SYS_ADDED_COLS_DEFAULT", trx, TRUE);

        error = DB_MUST_GET_MORE_FILE_SPACE;
    }

    trx_commit_for_mysql(trx);

    row_mysql_unlock_data_dictionary(trx);

    trx_free_for_mysql(trx);

    if (error == DB_SUCCESS) {
        fprintf(stderr,
                "InnoDB: Added columns default system tables"
                " created\n");
    }

    return(error);
}
Exemple #4
0
/****************************************************************//**
Creates the foreign key constraints system tables inside InnoDB
at database creation or database start if they are not found or are
not of the right form.
@return	DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_create_or_check_foreign_constraint_tables(void)
/*================================================*/
{
	dict_table_t*	table1;
	dict_table_t*	table2;
	ulint		error;
	trx_t*		trx;

	mutex_enter(&(dict_sys->mutex));

	table1 = dict_table_get_low("SYS_FOREIGN");
	table2 = dict_table_get_low("SYS_FOREIGN_COLS");

	if (table1 && table2
	    && UT_LIST_GET_LEN(table1->indexes) == 3
	    && UT_LIST_GET_LEN(table2->indexes) == 1) {

		/* Foreign constraint system tables have already been
		created, and they are ok */

		mutex_exit(&(dict_sys->mutex));

		return(DB_SUCCESS);
	}

	mutex_exit(&(dict_sys->mutex));

	trx = trx_allocate_for_mysql();

	trx->op_info = "creating foreign key sys tables";

	row_mysql_lock_data_dictionary(trx);

	if (table1) {
		fprintf(stderr,
			"InnoDB: dropping incompletely created"
			" SYS_FOREIGN table\n");
		row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
	}

	if (table2) {
		fprintf(stderr,
			"InnoDB: dropping incompletely created"
			" SYS_FOREIGN_COLS table\n");
		row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
	}

	fprintf(stderr,
		"InnoDB: Creating foreign key constraint system tables\n");

	/* NOTE: in dict_load_foreigns we use the fact that
	there are 2 secondary indexes on SYS_FOREIGN, and they
	are defined just like below */

	/* NOTE: when designing InnoDB's foreign key support in 2001, we made
	an error and made the table names and the foreign key id of type
	'CHAR' (internally, really a VARCHAR). We should have made the type
	VARBINARY, like in other InnoDB system tables, to get a clean
	design. */
#if 0
	error = que_eval_sql(NULL,
			     "PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
			     "BEGIN\n"
			     "CREATE TABLE\n"
			     "SYS_FOREIGN(ID CHAR, FOR_NAME CHAR,"
			     " REF_NAME CHAR, N_COLS INT);\n"
			     "CREATE UNIQUE CLUSTERED INDEX ID_IND"
			     " ON SYS_FOREIGN (ID);\n"
			     "CREATE INDEX FOR_IND"
			     " ON SYS_FOREIGN (FOR_NAME);\n"
			     "CREATE INDEX REF_IND"
			     " ON SYS_FOREIGN (REF_NAME);\n"
			     "CREATE TABLE\n"
			     "SYS_FOREIGN_COLS(ID CHAR, POS INT,"
			     " FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n"
			     "CREATE UNIQUE CLUSTERED INDEX ID_IND"
			     " ON SYS_FOREIGN_COLS (ID, POS);\n"
			     "END;\n"
			     , FALSE, trx);
#endif //zlqlxm //2011-10-13
/*
[
[
(gdb) info break
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08108861 in innobase_start_or_create_for_mysql at srv0start.c:2279
	breakpoint already hit 1 time
2       breakpoint     keep y   0x080b3796 in recv_recovery_from_checkpoint_start_func at log0recv.c:2925
	breakpoint already hit 1 time
3       breakpoint     keep y   0x08108886 in innobase_start_or_create_for_mysql at srv0start.c:2356
	breakpoint already hit 1 time
4       breakpoint     keep y   0x08075911 in dict_boot at dict0boot.c:260
	breakpoint already hit 1 time
5       breakpoint     keep y   0x08075994 in dict_boot at dict0boot.c:286
	breakpoint already hit 1 time
6       breakpoint     keep y   0x08076414 in dict_boot at dict0boot.c:446
	breakpoint already hit 1 time
7       breakpoint     keep y   0x0809e2f7 in ibuf_init_at_db_start at ibuf0ibuf.c:548
	breakpoint already hit 1 time
8       breakpoint     keep y   0x080953a7 in fseg_n_reserved_pages at fsp0fsp.c:2434
	breakpoint already hit 1 time
9       breakpoint     keep y   0x08094c8c in fseg_inode_try_get at fsp0fsp.c:2073
10      breakpoint     keep y   0x08094cbe in fseg_inode_try_get at fsp0fsp.c:2075
(gdb)
]/dict0boot
=>
/ ***************************************************************** // **
Creates the file page for the dictionary header. This function is
called only at the database creation.
@return	TRUE if succeed * /
static
ibool
dict_hdr_create(
/ *============* /
	mtr_t*	mtr)	/ *!< in: mtr * /
=>
dict_create

[
os0file.c:
	} else if (create_mode == OS_FILE_CREATE) {
		mode_str = "CREATE";
		create_flag = O_RDWR | O_CREAT | O_EXCL;
]

[os0file.h:
#ifdef UNIV_PFS_IO
# define os_file_create(key, name, create, purpose, type, success)	\
	pfs_os_file_create_func(key, name, create, purpose,	type,	\
				success, __FILE__, __LINE__)
...
#else
/ * If UNIV_PFS_IO is not defined, these I/O APIs point
to original un-instrumented file I/O APIs * /
# define os_file_create(key, name, create, purpose, type, success)	\
	os_file_create_func(name, create, purpose, type, success)               //=>“... create_flag = O_RDWR | O_CREAT | O_EXCL; ... file = open(name, create_flag, os_innodb_umask); ...”
...
#endif
]
]


[root@server01 InnoSQL-5.5.8]# grep "define UNIV_LIKELY" ./ -r
./storage/innobase/include/univ.i:# define UNIV_LIKELY_NULL(ptr) __builtin_expect((ulint) ptr, 0)
./storage/innobase/include/univ.i:# define UNIV_LIKELY_NULL(expr) (expr)
./storage/innobase/include/univ.i:# define UNIV_LIKELY_NULL(expr) (expr)
./storage/innobase/include/univ.i:#define UNIV_LIKELY(cond) UNIV_EXPECT(cond, TRUE)


[srv0start.c:
	if (create_new_db) {
		mtr_start(&mtr);

		fsp_header_init(0, sum_of_new_sizes, &mtr);  //=>mlog_write_ulint...

		mtr_commit(&mtr);  //=>把文件空间头写入文件!!;;
]
[fsp0fsp.c:
/ **
Initializes the space header of a new created space and creates also the
insert buffer tree root if space == 0. * /
UNIV_INTERN
void
fsp_header_init(
/ *============* /
	ulint	space,		/ *!< in: space id * /
	ulint	size,		/ *!< in: current size in blocks * /
	mtr_t*	mtr)		/ *!< in: mini-transaction handle * /
]


[srv0start.c:/p1253:
PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS
BEGIN
  CREATE TABLE SYS_FOREIGN(
    ID CHAR,
    FOR_NAME CHAR,
    REF_NAME CHAR, N_COLS INT
  );
  CREATE UNIQUE CLUSTERED INDEX ID_IND ON SYS_FOREIGN (ID);
  CREATE INDEX FOR_IND ON SYS_FOREIGN (FOR_NAME);
  CREATE INDEX REF_IND ON SYS_FOREIGN (REF_NAME);

  CREATE TABLE SYS_FOREIGN_COLS(
    ID CHAR,
    POS INT,
    FOR_COL_NAME CHAR,
    REF_COL_NAME CHAR
  );
  CREATE UNIQUE CLUSTERED INDEX ID_IND ON SYS_FOREIGN_COLS (ID, POS);
END;
]//----2011-10-09-21-13;+--21-17:R;
*/
error=DB_SUCCESS; //z+ //zlqlxm //--2011-10-09-21-30:OK;+--21-34:R; //-2011-10-12-20-14去除此句!!!;;;  //+z//lqlxm //2011-10-13
	if (error != DB_SUCCESS) {
		fprintf(stderr, "InnoDB: error %lu in creation\n",
			(ulong) error);

		ut_a(error == DB_OUT_OF_FILE_SPACE
		     || error == DB_TOO_MANY_CONCURRENT_TRXS);

		fprintf(stderr,
			"InnoDB: creation failed\n"
			"InnoDB: tablespace is full\n"
			"InnoDB: dropping incompletely created"
			" SYS_FOREIGN tables\n");

		row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
		row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);

		error = DB_MUST_GET_MORE_FILE_SPACE;
	}

	trx_commit_for_mysql(trx);

	row_mysql_unlock_data_dictionary(trx);

	trx_free_for_mysql(trx);

	if (error == DB_SUCCESS) {
		fprintf(stderr,
			"InnoDB: Foreign key constraint system tables"
			" created\n");
	}

	return(error);
}