Esempio n. 1
0
/********************************************************//**
Parses a log record written by mlog_open_and_write_index.
@return	parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_index(
/*=============*/
	byte*		ptr,	/*!< in: buffer */
	const byte*	end_ptr,/*!< in: buffer end */
	ibool		comp,	/*!< in: TRUE=compact record format */
	dict_index_t**	index)	/*!< out, own: dummy index */
{
	ulint		i, n, n_uniq;
	dict_table_t*	table;
	dict_index_t*	ind;

	ut_ad(comp == FALSE || comp == TRUE);

	if (comp) {
		if (end_ptr < ptr + 4) {
			return(NULL);
		}
		n = mach_read_from_2(ptr);
		ptr += 2;
		n_uniq = mach_read_from_2(ptr);
		ptr += 2;
		ut_ad(n_uniq <= n);
		if (end_ptr < ptr + n * 2) {
			return(NULL);
		}
	} else {
		n = n_uniq = 1;
	}
	table = dict_mem_table_create("LOG_DUMMY", DICT_HDR_SPACE, n,
				      comp ? DICT_TF_COMPACT : 0);
	ind = dict_mem_index_create("LOG_DUMMY", "LOG_DUMMY",
				    DICT_HDR_SPACE, 0, n);
	ind->table = table;
	ind->n_uniq = (unsigned int) n_uniq;
	if (n_uniq != n) {
		ut_a(n_uniq + DATA_ROLL_PTR <= n);
		ind->type = DICT_CLUSTERED;
	}
	if (comp) {
		for (i = 0; i < n; i++) {
			ulint	len = mach_read_from_2(ptr);
			ptr += 2;
			/* The high-order bit of len is the NOT NULL flag;
			the rest is 0 or 0x7fff for variable-length fields,
			and 1..0x7ffe for fixed-length fields. */
			dict_mem_table_add_col(
				table, NULL, NULL,
				((len + 1) & 0x7fff) <= 1
				? DATA_BINARY : DATA_FIXBINARY,
				len & 0x8000 ? DATA_NOT_NULL : 0,
				len & 0x7fff);

			dict_index_add_col(ind, table,
					   dict_table_get_nth_col(table, i),
					   0);
		}
		dict_table_add_system_columns(table, table->heap);
		if (n_uniq != n) {
			/* Identify DB_TRX_ID and DB_ROLL_PTR in the index. */
			ut_a(DATA_TRX_ID_LEN
			     == dict_index_get_nth_col(ind, DATA_TRX_ID - 1
						       + n_uniq)->len);
			ut_a(DATA_ROLL_PTR_LEN
			     == dict_index_get_nth_col(ind, DATA_ROLL_PTR - 1
						       + n_uniq)->len);
			ind->fields[DATA_TRX_ID - 1 + n_uniq].col
				= &table->cols[n + DATA_TRX_ID];
			ind->fields[DATA_ROLL_PTR - 1 + n_uniq].col
				= &table->cols[n + DATA_ROLL_PTR];
		}
	}
	/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
	ind->cached = TRUE;
	*index = ind;
	return(ptr);
}
Esempio n. 2
0
/********************************************************//**
Parses a log record written by mlog_open_and_write_index.
@return	parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_index(
/*=============*/
	byte*		ptr,	/*!< in: buffer */
	const byte*	end_ptr,/*!< in: buffer end */
	ibool		comp,	/*!< in: TRUE=compact record format */
	dict_index_t**	index)	/*!< out, own: dummy index */
{
	ulint		i, n, n_uniq;
	dict_table_t*	table;
	dict_index_t*	ind;
    ibool           is_gcs = FALSE;
    ulint           n_fields_before_alter = 0;        /* 快速alter table前聚集索引的字段数 */

	ut_ad(comp == FALSE || comp == TRUE);

	if (comp) {
		if (end_ptr < ptr + 4) {
			return(NULL);
		}
		n = mach_read_from_2(ptr);
        if (n & 0x8000)                     /* 最高位为1表示GCS表 */
        {
            is_gcs = TRUE;
            n &= 0x7FFF;
        }

        ptr += 2;
        if (is_gcs)
        {
            n_fields_before_alter = mach_read_from_2(ptr);
            ut_ad(n_fields_before_alter < n && n_fields_before_alter > 0);
            ptr += 2;

            /* 确保地址有效!*/
            if (end_ptr < ptr + 2) {
                return(NULL);
            }
        }

		n_uniq = mach_read_from_2(ptr);
		ptr += 2;
		ut_ad(n_uniq <= n);
		if (end_ptr < ptr + n * 2) {
			return(NULL);
		}
	} else {
		n = n_uniq = 1;
	}
	table = dict_mem_table_create("LOG_DUMMY", DICT_HDR_SPACE, n,
				      comp ? DICT_TF_COMPACT : 0, is_gcs, n_fields_before_alter);
	ind = dict_mem_index_create("LOG_DUMMY", "LOG_DUMMY",
				    DICT_HDR_SPACE, 0, n);
	ind->table = table;
	ind->n_uniq = (unsigned int) n_uniq;
	if (n_uniq != n) {
		ut_a(n_uniq + DATA_ROLL_PTR <= n);
		ind->type = DICT_CLUSTERED;
	}
	if (comp) {
		for (i = 0; i < n; i++) {
			ulint	len = mach_read_from_2(ptr);
			ptr += 2;
			/* The high-order bit of len is the NOT NULL flag;
			the rest is 0 or 0x7fff for variable-length fields,
			and 1..0x7ffe for fixed-length fields. */
            /* redo阶段压缩属性不需指定 */
			dict_mem_table_add_col(
				table, NULL, NULL,
				((len + 1) & 0x7fff) <= 1
				? DATA_BINARY : DATA_FIXBINARY,         /* 若len 为0或0x7fff,可认为是变长字段;否则是定长字段 */
				len & 0x8000 ? DATA_NOT_NULL : 0,
				len & 0x7fff);

            if (is_gcs && n_fields_before_alter > 0 && n_fields_before_alter <= i)
            {
                dict_col_t*     col = NULL;

                col = dict_table_get_nth_col(table, i);

                /* 添加默认值信息,但只是占位符,并不需真正的默认值信息 */
                if (!dict_col_is_nullable(col))
                    dict_mem_table_set_col_default(table, col, table->heap);
            }

			dict_index_add_col(ind, table,
					   dict_table_get_nth_col(table, i),
					   0);
		}
		dict_table_add_system_columns(table, table->heap);
		if (n_uniq != n) {
			/* Identify DB_TRX_ID and DB_ROLL_PTR in the index. */
			ut_a(DATA_TRX_ID_LEN
			     == dict_index_get_nth_col(ind, DATA_TRX_ID - 1
						       + n_uniq)->len);
			ut_a(DATA_ROLL_PTR_LEN
			     == dict_index_get_nth_col(ind, DATA_ROLL_PTR - 1
						       + n_uniq)->len);
			ind->fields[DATA_TRX_ID - 1 + n_uniq].col
				= &table->cols[n + DATA_TRX_ID];
			ind->fields[DATA_ROLL_PTR - 1 + n_uniq].col
				= &table->cols[n + DATA_ROLL_PTR];

            /* set the col_ind col->ind */
            ind->fields[DATA_TRX_ID - 1 + n_uniq].col_ind
                = ind->fields[DATA_TRX_ID - 1 + n_uniq].col->ind;
            ind->fields[DATA_ROLL_PTR - 1 + n_uniq].col_ind
                = ind->fields[DATA_ROLL_PTR - 1 + n_uniq].col->ind;
		}

        if (dict_index_is_gcs_clust_after_alter_table(ind))
        {
            ut_ad(table->n_cols == table->n_def);
            ut_a(table->n_cols_before_alter_table > 0 &&
                table->n_cols_before_alter_table <= table->n_cols);
            ind->n_fields_before_alter = n_fields_before_alter;
            ind->n_nullable_before_alter  = dict_index_get_first_n_field_n_nullable(ind, ind->n_fields_before_alter);
        }
        else
        {
            ind->n_fields_before_alter = 0;
            ind->n_nullable_before_alter  = 0;
        }
        
	}
	/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
	ind->cached = TRUE;
	*index = ind;
	return(ptr);
}