diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-07-05 17:43:32 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-07-05 17:43:32 +0400 |
commit | 3b9273d20334f95b85047058ae978615b61a57ed (patch) | |
tree | 78ce9901370c84f6e5f6d1b07e6cc487a6fee7bb /storage/innobase | |
parent | a4d9fa99ea25fa87f7a8ecf36579ec1585d1c397 (diff) | |
parent | 58dd72f18cca5e706a5bd0dfcf3e22aba9bb8448 (diff) | |
download | mariadb-git-3b9273d20334f95b85047058ae978615b61a57ed.tar.gz |
Merge remote-tracking branch 'origin/bb-10.2-ext' into 10.3
Diffstat (limited to 'storage/innobase')
48 files changed, 551 insertions, 832 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 89ebe5b8783..64a14d0e959 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -4673,29 +4673,12 @@ btr_index_rec_validate( rec_get_nth_field_offs(offsets, i, &len); /* Note that if fixed_size != 0, it equals the - length of a fixed-size column in the clustered index, - except the DATA_POINT, whose length would be MBR_LEN - when it's indexed in a R-TREE. We should adjust it here. + length of a fixed-size column in the clustered index. + We should adjust it here. A prefix index of the column is of fixed, but different length. When fixed_size == 0, prefix_len is the maximum length of the prefix index column. */ - if (dict_field_get_col(field)->mtype == DATA_POINT) { - ut_ad(fixed_size == DATA_POINT_LEN); - if (dict_index_is_spatial(index)) { - /* For DATA_POINT data, when it has R-tree - index, the fixed_len is the MBR of the point. - But if it's a primary key and on R-TREE - as the PK pointer, the length shall be - DATA_POINT_LEN as well. */ - ut_ad((field->fixed_len == DATA_MBR_LEN - && i == 0) - || (field->fixed_len == DATA_POINT_LEN - && i != 0)); - fixed_size = field->fixed_len; - } - } - if ((field->prefix_len == 0 && len != UNIV_SQL_NULL && fixed_size && len != fixed_size) diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 9e7d4f6a0bb..37f5d12379c 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -3679,6 +3679,11 @@ btr_cur_update_in_place( was_delete_marked = rec_get_deleted_flag( rec, page_is_comp(buf_block_get_frame(block))); + /* In delete-marked records, DB_TRX_ID must always refer to an + existing undo log record. */ + ut_ad(!was_delete_marked + || !dict_index_is_clust(index) + || row_get_rec_trx_id(rec, index, offsets)); #ifdef BTR_CUR_HASH_ADAPT if (block->index) { @@ -4321,6 +4326,10 @@ btr_cur_pessimistic_update( stored fields */ btr_cur_unmark_extern_fields( page_zip, rec, index, *offsets, mtr); + } else { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(row_get_rec_trx_id(rec, index, *offsets)); } bool adjust = big_rec_vec && (flags & BTR_KEEP_POS_FLAG); @@ -4448,6 +4457,10 @@ btr_cur_pessimistic_update( btr_cur_unmark_extern_fields(page_zip, rec, index, *offsets, mtr); + } else { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(row_get_rec_trx_id(rec, index, *offsets)); } if (!dict_table_is_locking_disabled(index->table)) { @@ -4573,6 +4586,10 @@ btr_cur_parse_del_mark_set_clust_rec( ut_a(offset <= UNIV_PAGE_SIZE); + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(trx_id || (flags & BTR_KEEP_SYS_FLAG)); + if (page) { rec = page + offset; @@ -4582,20 +4599,37 @@ btr_cur_parse_del_mark_set_clust_rec( and the adaptive hash index does not depend on them. */ btr_rec_set_deleted_flag(rec, page_zip, val); + /* pos is the offset of DB_TRX_ID in the clustered index. + Debug assertions may also access DB_ROLL_PTR at pos+1. + Therefore, we must compute offsets for the first pos+2 + clustered index fields. */ + ut_ad(pos <= MAX_REF_PARTS); - if (!(flags & BTR_KEEP_SYS_FLAG)) { - mem_heap_t* heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - rec_offs_init(offsets_); + ulint offsets[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2]; + rec_offs_init(offsets); + mem_heap_t* heap = NULL; + if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_rec_sys_fields_in_recovery( rec, page_zip, - rec_get_offsets(rec, index, offsets_, - ULINT_UNDEFINED, &heap), + rec_get_offsets(rec, index, offsets, + pos + 2, &heap), pos, trx_id, roll_ptr); - if (UNIV_LIKELY_NULL(heap)) { - mem_heap_free(heap); - } + } else { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(memcmp(rec_get_nth_field( + rec, + rec_get_offsets(rec, index, + offsets, pos, + &heap), + pos, &offset), + field_ref_zero, DATA_TRX_ID_LEN)); + ut_ad(offset == DATA_TRX_ID_LEN); + } + + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); } } @@ -4633,8 +4667,10 @@ btr_cur_del_mark_set_clust_rec( ut_ad(mtr->is_named_space(index->space)); if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))) { - /* While cascading delete operations, this becomes possible. */ - ut_ad(rec_get_trx_id(rec, index) == thr_get_trx(thr)->id); + /* We may already have delete-marked this record + when executing an ON DELETE CASCADE operation. */ + ut_ad(row_get_rec_trx_id(rec, index, offsets) + == thr_get_trx(thr)->id); return(DB_SUCCESS); } @@ -4663,10 +4699,6 @@ btr_cur_del_mark_set_clust_rec( btr_rec_set_deleted_flag(rec, page_zip, TRUE); trx = thr_get_trx(thr); - /* This function must not be invoked during rollback - (of a TRX_STATE_PREPARE transaction or otherwise). */ - ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); - ut_ad(!trx->in_rollback); DBUG_LOG("ib_cur", "delete-mark clust " << index->table->name diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 8d6d95a020e..61006c8d89d 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -5959,9 +5959,8 @@ database_corrupted: error injection */ DBUG_EXECUTE_IF( "buf_page_import_corrupt_failure", - if (bpage->id.space() - > srv_undo_tablespaces_open - && bpage->id.space() != SRV_TMP_SPACE_ID) { + if (!is_predefined_tablespace( + bpage->id.space())) { buf_mark_space_corrupt(bpage); ib::info() << "Simulated IMPORT " "corruption"; @@ -6027,8 +6026,7 @@ database_corrupted: if (uncompressed && !recv_no_ibuf_operations && (bpage->id.space() == 0 - || (bpage->id.space() > srv_undo_tablespaces_open - && bpage->id.space() != SRV_TMP_SPACE_ID)) + || !is_predefined_tablespace(bpage->id.space())) && !srv_is_tablespace_truncated(bpage->id.space()) && fil_page_get_type(frame) == FIL_PAGE_INDEX && page_is_leaf(frame)) { diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index 20603021072..b8b7643702e 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -813,23 +813,26 @@ buf_read_ibuf_merge_pages( #endif for (ulint i = 0; i < n_stored; i++) { - const page_id_t page_id(space_ids[i], page_nos[i]); - - buf_pool_t* buf_pool = buf_pool_get(page_id); - bool found; const page_size_t page_size(fil_space_get_page_size( space_ids[i], &found)); if (!found) { tablespace_deleted: - /* The tablespace was not found, remove the - entries for that page */ - ibuf_merge_or_delete_for_page(NULL, page_id, - NULL, FALSE); + /* The tablespace was not found: remove all + entries for it */ + ibuf_delete_for_discarded_space(space_ids[i]); + while (i + 1 < n_stored + && space_ids[i + 1] == space_ids[i]) { + i++; + } continue; } + const page_id_t page_id(space_ids[i], page_nos[i]); + + buf_pool_t* buf_pool = buf_pool_get(page_id); + while (buf_pool->n_pend_reads > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) { os_thread_sleep(500000); diff --git a/storage/innobase/data/data0type.cc b/storage/innobase/data/data0type.cc index a40724b303d..d4b809c3f59 100644 --- a/storage/innobase/data/data0type.cc +++ b/storage/innobase/data/data0type.cc @@ -193,14 +193,6 @@ dtype_print(const dtype_t* type) fputs("DATA_BLOB", stderr); break; - case DATA_POINT: - fputs("DATA_POINT", stderr); - break; - - case DATA_VAR_POINT: - fputs("DATA_VAR_POINT", stderr); - break; - case DATA_GEOMETRY: fputs("DATA_GEOMETRY", stderr); break; diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index df36a320616..943a37ef4e0 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -2892,22 +2892,9 @@ dict_index_add_col( field = dict_index_get_nth_field(index, index->n_def - 1); field->col = col; - /* DATA_POINT is a special type, whose fixed_len should be: - 1) DATA_MBR_LEN, when it's indexed in R-TREE. In this case, - it must be the first col to be added. - 2) DATA_POINT_LEN(be equal to fixed size of column), when it's - indexed in B-TREE, - 3) DATA_POINT_LEN, if a POINT col is the PRIMARY KEY, and we are - adding the PK col to other B-TREE/R-TREE. */ - /* TODO: We suppose the dimension is 2 now. */ - if (dict_index_is_spatial(index) && DATA_POINT_MTYPE(col->mtype) - && index->n_def == 1) { - field->fixed_len = DATA_MBR_LEN; - } else { - field->fixed_len = static_cast<unsigned int>( - dict_col_get_fixed_size( - col, dict_table_is_comp(table))); - } + field->fixed_len = static_cast<unsigned int>( + dict_col_get_fixed_size( + col, dict_table_is_comp(table))); if (prefix_len && field->fixed_len > prefix_len) { field->fixed_len = (unsigned int) prefix_len; diff --git a/storage/innobase/fsp/fsp0space.cc b/storage/innobase/fsp/fsp0space.cc index 7ca81898f70..94fae3d973b 100644 --- a/storage/innobase/fsp/fsp0space.cc +++ b/storage/innobase/fsp/fsp0space.cc @@ -39,11 +39,8 @@ bool Tablespace::intersection( const Tablespace* other_space) { - files_t::const_iterator end = other_space->m_files.end(); - - for (files_t::const_iterator it = other_space->m_files.begin(); - it != end; - ++it) { + for (files_t::const_iterator it(other_space->begin()), + end(other_space->end()); it != end; ++it) { if (find(it->m_filename)) { @@ -58,14 +55,13 @@ Tablespace::intersection( void Tablespace::shutdown() { - files_t::iterator end = m_files.end(); - - for (files_t::iterator it = m_files.begin(); it != end; ++it) { + for (iterator it = begin(); it != end(); ++it) { it->shutdown(); } m_files.clear(); - + ut_free(m_path); + m_path = NULL; m_space_id = ULINT_UNDEFINED; } @@ -94,10 +90,7 @@ Tablespace::open_or_create(bool is_temp) ut_ad(!m_files.empty()); - files_t::iterator begin = m_files.begin(); - files_t::iterator end = m_files.end(); - - for (files_t::iterator it = begin; it != end; ++it) { + for (iterator it = begin(); it != end(); ++it) { if (it->m_exists) { err = it->open_or_create( @@ -123,7 +116,7 @@ Tablespace::open_or_create(bool is_temp) the proper way. */ it->close(); - if (it == begin) { + if (it == begin()) { /* First data file. */ /* Create the tablespace entry for the multi-file @@ -153,11 +146,9 @@ Tablespace::open_or_create(bool is_temp) /** Find a filename in the list of Datafiles for a tablespace @return true if the filename exists in the data files */ bool -Tablespace::find(const char* filename) +Tablespace::find(const char* filename) const { - files_t::const_iterator end = m_files.end(); - - for (files_t::const_iterator it = m_files.begin(); it != end; ++it) { + for (const_iterator it = begin(); it != end(); ++it) { if (innobase_strcasecmp(filename, it->m_filename) == 0) { return(true); @@ -171,9 +162,7 @@ Tablespace::find(const char* filename) void Tablespace::delete_files() { - files_t::iterator end = m_files.end(); - - for (files_t::iterator it = m_files.begin(); it != end; ++it) { + for (iterator it = begin(); it != end(); ++it) { it->close(); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ebf8f38368b..f41827270a5 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -206,7 +206,7 @@ static ulong innobase_commit_concurrency = 0; static ulong innobase_read_io_threads; static ulong innobase_write_io_threads; -static long long innobase_buffer_pool_size, innobase_log_file_size; +static long long innobase_buffer_pool_size; /** Percentage of the buffer pool to reserve for 'old' blocks. Connected to buf_LRU_old_ratio. */ @@ -4050,8 +4050,6 @@ innobase_change_buffering_inited_ok: srv_file_flush_method_str = innobase_file_flush_method; - srv_log_file_size = (ib_uint64_t) innobase_log_file_size; - if (UNIV_PAGE_SIZE_DEF != srv_page_size) { ib::info() << "innodb_page_size=" << srv_page_size; @@ -5774,14 +5772,6 @@ innobase_match_index_columns( spatial index on it and we intend to use DATA_GEOMETRY for legacy GIS data types which are of var-length. */ switch (col_type) { - case DATA_POINT: - case DATA_VAR_POINT: - if (DATA_POINT_MTYPE(mtype) - || mtype == DATA_GEOMETRY - || mtype == DATA_BLOB) { - break; - } - /* Fall through */ case DATA_GEOMETRY: if (mtype == DATA_BLOB) { break; @@ -7761,12 +7751,6 @@ build_template_field( prebuilt->templ_contains_blob = TRUE; } - if (templ->type == DATA_POINT) { - /* We set this only when it's DATA_POINT, but not - DATA_VAR_POINT */ - prebuilt->templ_contains_fixed_point = TRUE; - } - return(templ); } @@ -7852,7 +7836,6 @@ ha_innobase::build_template( /* Prepare to build m_prebuilt->mysql_template[]. */ m_prebuilt->templ_contains_blob = FALSE; - m_prebuilt->templ_contains_fixed_point = FALSE; m_prebuilt->mysql_prefix_len = 0; m_prebuilt->n_template = 0; m_prebuilt->idx_cond_n_cols = 0; @@ -8289,15 +8272,15 @@ ha_innobase::write_row( || sql_command == SQLCOM_OPTIMIZE || sql_command == SQLCOM_CREATE_INDEX #ifdef WITH_WSREP - || (wsrep_on(m_user_thd) && wsrep_load_data_splitting && - sql_command == SQLCOM_LOAD && - !thd_test_options( - m_user_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) + || (sql_command == SQLCOM_LOAD + && wsrep_load_data_splitting && wsrep_on(m_user_thd) + && !thd_test_options( + m_user_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) #endif /* WITH_WSREP */ || sql_command == SQLCOM_DROP_INDEX) && m_num_write_row >= 10000) { #ifdef WITH_WSREP - if (wsrep_on(m_user_thd) && sql_command == SQLCOM_LOAD) { + if (sql_command == SQLCOM_LOAD && wsrep_on(m_user_thd)) { WSREP_DEBUG("forced trx split for LOAD: %s", wsrep_thd_query(m_user_thd)); } @@ -8743,8 +8726,6 @@ calc_row_difference( switch (col_type) { case DATA_BLOB: - case DATA_POINT: - case DATA_VAR_POINT: case DATA_GEOMETRY: o_ptr = row_mysql_read_blob_ref(&o_len, o_ptr, o_len); n_ptr = row_mysql_read_blob_ref(&n_len, n_ptr, n_len); @@ -11507,10 +11488,6 @@ create_table_info_t::create_table_def() } } - if (col_type == DATA_POINT) { - col_len = DATA_POINT_LEN; - } - is_virtual = (innobase_is_v_fld(field)) ? DATA_VIRTUAL : 0; is_stored = innobase_is_s_fld(field); @@ -12767,8 +12744,6 @@ create_table_info_t::set_tablespace_type( int create_table_info_t::initialize() { - trx_t* parent_trx __attribute__((unused)); - DBUG_ENTER("create_table_info_t::initialize"); ut_ad(m_thd != NULL); @@ -12790,7 +12765,7 @@ create_table_info_t::initialize() /* Get the transaction associated with the current thd, or create one if not yet created */ - parent_trx = check_trx_exists(m_thd); + check_trx_exists(m_thd); DBUG_RETURN(0); } @@ -20569,10 +20544,12 @@ static MYSQL_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size, "The size of the buffer which InnoDB uses to write log to the log files on disk.", NULL, NULL, 16*1024*1024L, 256*1024L, LONG_MAX, 1024); -static MYSQL_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size, +static MYSQL_SYSVAR_ULONGLONG(log_file_size, srv_log_file_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Size of each log file in a log group.", - NULL, NULL, 48 << 20, 1 << 20, 512ULL << 30, 1 << 20); + NULL, NULL, 48 << 20, 1 << 20, 512ULL << 30, UNIV_PAGE_SIZE_MAX); +/* OS_FILE_LOG_BLOCK_SIZE would be more appropriate than UNIV_PAGE_SIZE_MAX, +but fil_space_t is being used for the redo log, and it uses data pages. */ static MYSQL_SYSVAR_ULONG(log_files_in_group, srv_n_log_files, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 24bfb31b1fb..0f8e1e8178d 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1760,7 +1760,6 @@ innobase_col_to_mysql( memcpy(dest, data, len); break; - case DATA_VAR_POINT: case DATA_GEOMETRY: case DATA_BLOB: /* Skip MySQL BLOBs when reporting an erroneous row @@ -1785,7 +1784,6 @@ innobase_col_to_mysql( case DATA_FLOAT: case DATA_DOUBLE: case DATA_DECIMAL: - case DATA_POINT: /* Above are the valid column types for MySQL data. */ ut_ad(flen == len); /* fall through */ @@ -3011,29 +3009,6 @@ innobase_check_foreigns( return(false); } -/** Get the default POINT value in MySQL format -@param[in] heap memory heap where allocated -@param[in] length length of MySQL format -@return mysql format data */ -static -const byte* -innobase_build_default_mysql_point( - mem_heap_t* heap, - ulint length) -{ - byte* buf = static_cast<byte*>(mem_heap_alloc( - heap, DATA_POINT_LEN + length)); - - byte* wkb = buf + length; - - ulint len = get_wkb_of_default_point(SPDIMS, wkb, DATA_POINT_LEN); - ut_ad(len == DATA_POINT_LEN); - - row_mysql_store_blob_ref(buf, length, wkb, len); - - return(buf); -} - /** Convert a default value for ADD COLUMN. @param heap Memory heap where allocated @@ -3060,16 +3035,6 @@ innobase_build_col_map_add( const byte* mysql_data = field->ptr; - if (dfield_get_type(dfield)->mtype == DATA_POINT) { - /** If the DATA_POINT field is NOT NULL, we need to - give it a default value, since DATA_POINT is a fixed length - type, we couldn't store a value of length 0, like other - geom types. Server doesn't provide the default value, and - we would use POINT(0 0) here instead. */ - - mysql_data = innobase_build_default_mysql_point(heap, size); - } - row_mysql_store_col_in_innobase_format( dfield, buf, true, mysql_data, size, comp); } @@ -4703,12 +4668,6 @@ prepare_inplace_alter_table_dict( } - if (col_type == DATA_POINT) { - /* DATA_POINT should be of fixed length, - instead of the pack_length(blob length). */ - col_len = DATA_POINT_LEN; - } - if (dict_col_name_is_reserved(field->field_name.str)) { dict_mem_table_free(ctx->new_table); my_error(ER_WRONG_COLUMN_NAME, MYF(0), diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h index 3fa8320b5aa..35dcf2f3397 100644 --- a/storage/innobase/include/data0type.h +++ b/storage/innobase/include/data0type.h @@ -77,28 +77,18 @@ binary strings */ charset-collation for tables created with it can also be latin1_swedish_ci */ -/* DATA_POINT&DATA_VAR_POINT are for standard geometry datatype 'point' and -DATA_GEOMETRY include all other standard geometry datatypes as described in -OGC standard(line_string, polygon, multi_point, multi_polygon, +/* DATA_GEOMETRY includes all standard geometry datatypes as described in +OGC standard(point, line_string, polygon, multi_point, multi_polygon, multi_line_string, geometry_collection, geometry). Currently, geometry data is stored in the standard Well-Known Binary(WKB) format (http://www.opengeospatial.org/standards/sfa). -We use BLOB as underlying datatype for DATA_GEOMETRY and DATA_VAR_POINT -while CHAR for DATA_POINT */ +We use BLOB as the underlying datatype. */ #define DATA_GEOMETRY 14 /* geometry datatype of variable length */ -/* The following two are disabled temporarily, we won't create them in -get_innobase_type_from_mysql_type(). -TODO: We will enable DATA_POINT/them when we come to the fixed-length POINT -again. */ -#define DATA_POINT 15 /* geometry datatype of fixed length POINT */ -#define DATA_VAR_POINT 16 /* geometry datatype of variable length - POINT, used when we want to store POINT - as BLOB internally */ #define DATA_MTYPE_MAX 63 /* dtype_store_for_order_and_null_size() requires the values are <= 63 */ #define DATA_MTYPE_CURRENT_MIN DATA_VARCHAR /* minimum value of mtype */ -#define DATA_MTYPE_CURRENT_MAX DATA_VAR_POINT /* maximum value of mtype */ +#define DATA_MTYPE_CURRENT_MAX DATA_GEOMETRY /* maximum value of mtype */ /*-------------------------------------------*/ /* The 'PRECISE TYPE' of a column */ /* @@ -211,15 +201,6 @@ store the charset-collation number; one byte is left unused, though */ /* Maximum multi-byte character length in bytes, plus 1 */ #define DATA_MBMAX 5 -/* For DATA_POINT of dimension 2, the length of value in btree is always 25, -which is the summary of: -SRID_SIZE(4) + WKB_HEADER_SIZE(1+4) + POINT_DATA_SIZE(8*2). -So the length of physical record or POINT KEYs on btree are 25. -GIS_TODO: When we support multi-dimensions DATA_POINT, we should get the -length from corresponding column or index definition, instead of this MACRO -*/ -#define DATA_POINT_LEN 25 - /* Pack mbminlen, mbmaxlen to mbminmaxlen. */ #define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \ unsigned((mbmaxlen) * DATA_MBMAX + (mbminlen)) @@ -229,18 +210,12 @@ length from corresponding column or index definition, instead of this MACRO /* Get mbmaxlen from mbminmaxlen. */ #define DATA_MBMAXLEN(mbminmaxlen) unsigned((mbminmaxlen) / DATA_MBMAX) -/* For checking if a geom_type is POINT */ -#define DATA_POINT_MTYPE(mtype) ((mtype) == DATA_POINT \ - || (mtype) == DATA_VAR_POINT) - /* For checking if mtype is GEOMETRY datatype */ -#define DATA_GEOMETRY_MTYPE(mtype) (DATA_POINT_MTYPE(mtype) \ - || (mtype) == DATA_GEOMETRY) +#define DATA_GEOMETRY_MTYPE(mtype) ((mtype) == DATA_GEOMETRY) /* For checking if mtype is BLOB or GEOMETRY, since we use BLOB as -the underling datatype of GEOMETRY(not DATA_POINT) data. */ +the underlying datatype of GEOMETRY data. */ #define DATA_LARGE_MTYPE(mtype) ((mtype) == DATA_BLOB \ - || (mtype) == DATA_VAR_POINT \ || (mtype) == DATA_GEOMETRY) /* For checking if data type is big length data type. */ diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic index b5a467455b9..3d2f46ed877 100644 --- a/storage/innobase/include/data0type.ic +++ b/storage/innobase/include/data0type.ic @@ -504,7 +504,6 @@ dtype_get_fixed_size_low( case DATA_INT: case DATA_FLOAT: case DATA_DOUBLE: - case DATA_POINT: return(len); case DATA_MYSQL: if (prtype & DATA_BINARY_TYPE) { @@ -533,7 +532,6 @@ dtype_get_fixed_size_low( case DATA_BINARY: case DATA_DECIMAL: case DATA_VARMYSQL: - case DATA_VAR_POINT: case DATA_GEOMETRY: case DATA_BLOB: return(0); @@ -580,7 +578,6 @@ dtype_get_min_size_low( case DATA_INT: case DATA_FLOAT: case DATA_DOUBLE: - case DATA_POINT: return(len); case DATA_MYSQL: if (prtype & DATA_BINARY_TYPE) { @@ -603,7 +600,6 @@ dtype_get_min_size_low( case DATA_BINARY: case DATA_DECIMAL: case DATA_VARMYSQL: - case DATA_VAR_POINT: case DATA_GEOMETRY: case DATA_BLOB: return(0); @@ -637,9 +633,7 @@ dtype_get_max_size_low( case DATA_BINARY: case DATA_DECIMAL: case DATA_VARMYSQL: - case DATA_POINT: return(len); - case DATA_VAR_POINT: case DATA_GEOMETRY: case DATA_BLOB: break; diff --git a/storage/innobase/include/fsp0space.h b/storage/innobase/include/fsp0space.h index 3928f8362b9..2c28ecc5c7b 100644 --- a/storage/innobase/include/fsp0space.h +++ b/storage/innobase/include/fsp0space.h @@ -44,6 +44,10 @@ public: /** Data file information - each Datafile can be accessed globally */ files_t m_files; + /** Data file iterator */ + typedef files_t::iterator iterator; + /** Data file iterator */ + typedef files_t::const_iterator const_iterator; Tablespace() : @@ -62,16 +66,21 @@ public: shutdown(); ut_ad(m_files.empty()); ut_ad(m_space_id == ULINT_UNDEFINED); - if (m_path != NULL) { - ut_free(m_path); - m_path = NULL; - } } // Disable copying Tablespace(const Tablespace&); Tablespace& operator=(const Tablespace&); + /** Data file iterator */ + const_iterator begin() const { return m_files.begin(); } + /** Data file iterator */ + const_iterator end() const { return m_files.end(); } + /** Data file iterator */ + iterator begin() { return m_files.begin(); } + /** Data file iterator */ + iterator end() { return m_files.end(); } + void set_name(const char* name) { m_name = name; } const char* name() const { return m_name; } @@ -160,8 +169,7 @@ public: { ulint sum = 0; - for (files_t::const_iterator it = m_files.begin(); - it != m_files.end(); ++it) { + for (const_iterator it = begin(); it != end(); ++it) { sum += it->m_size; } @@ -204,7 +212,7 @@ private: /** @param[in] filename Name to lookup in the data files. @return true if the filename exists in the data files */ - bool find(const char* filename); + bool find(const char* filename) const; /** Note that the data file was found. @param[in] file data file object */ diff --git a/storage/innobase/include/fsp0sysspace.h b/storage/innobase/include/fsp0sysspace.h index 4c88b268f34..b8890adad74 100644 --- a/storage/innobase/include/fsp0sysspace.h +++ b/storage/innobase/include/fsp0sysspace.h @@ -287,16 +287,6 @@ is_system_tablespace(ulint id) return(id == TRX_SYS_SPACE || id == SRV_TMP_SPACE_ID); } -/** Check if shared-system or undo tablespace. -@return true if shared-system or undo tablespace */ -UNIV_INLINE -bool -is_system_or_undo_tablespace( - ulint id) -{ - return(id <= srv_undo_tablespaces_open); -} - /** Check if predefined shared tablespace. @return true if predefined shared tablespace */ UNIV_INLINE @@ -306,7 +296,8 @@ is_predefined_tablespace( { ut_ad(srv_sys_space.space_id() == TRX_SYS_SPACE); ut_ad(TRX_SYS_SPACE == 0); - return(id <= srv_undo_tablespaces_open - || id == SRV_TMP_SPACE_ID); + return(id == TRX_SYS_SPACE + || id == SRV_TMP_SPACE_ID + || srv_is_undo_tablespace(id)); } #endif /* fsp0sysspace_h */ diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 05e53e23f28..1062a785fdb 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -156,17 +156,17 @@ void log_sys_init(); /** Initialize the redo log. -@param[in] n_files number of files -@param[in] file_size file size in bytes */ +@param[in] n_files number of files */ void -log_init(ulint n_files, lsn_t file_size); +log_init(ulint n_files); /** Calculate the recommended highest values for lsn - last_checkpoint_lsn and lsn - buf_get_oldest_modification(). +@param[in] file_size requested innodb_log_file_size @retval true on success @retval false if the smallest log group is too small to accommodate the number of OS threads in the database server */ bool -log_set_capacity() +log_set_capacity(ulonglong file_size) MY_ATTRIBUTE((warn_unused_result)); /******************************************************//** @@ -407,16 +407,9 @@ Closes all log groups. */ void log_group_close_all(void); /*=====================*/ -/********************************************************//** -Shutdown the log system but do not release all the memory. */ -void -log_shutdown(void); -/*==============*/ -/********************************************************//** -Free the log system data structures. */ +/** Shut down the redo log subsystem. */ void -log_mem_free(void); -/*==============*/ +log_shutdown(); /** Whether to generate and require checksums on the redo log pages */ extern my_bool innodb_log_checksums; diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 784699279d4..bacfb86cc07 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -81,27 +81,12 @@ recv_reset_logs( OS_FILE_LOG_BLOCK_SIZE, after which we add LOG_BLOCK_HDR_SIZE */ -/********************************************************//** -Creates the recovery system. */ -void -recv_sys_create(void); -/*=================*/ -/**********************************************************//** -Release recovery system mutexes. */ -void -recv_sys_close(void); -/*================*/ -/********************************************************//** -Frees the recovery system memory. */ +/** Clean up after recv_sys_init() */ void -recv_sys_mem_free(void); -/*===================*/ -/********************************************************//** -Inits the recovery system for a recovery operation. */ +recv_sys_close(); +/** Initialize the redo log recovery subsystem. */ void -recv_sys_init( -/*==========*/ - ulint available_memory); /*!< in: available memory in bytes */ +recv_sys_init(); /********************************************************//** Frees the recovery system. */ void diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 1852dbdf1df..c06a61ef1be 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -977,7 +977,7 @@ pfs_os_file_close_func( this function! This is the performance schema instrumented wrapper function for os_file_read() which requests a synchronous read operation. -@param[in, out] type IO request context +@param[in] type IO request context @param[in] file Open file handle @param[out] buf buffer where to read @param[in] offset file offset where to read @@ -988,20 +988,20 @@ os_file_read() which requests a synchronous read operation. UNIV_INLINE dberr_t pfs_os_file_read_func( - IORequest& type, - pfs_os_file_t file, - void* buf, - os_offset_t offset, - ulint n, - const char* src_file, - uint src_line); + const IORequest& type, + pfs_os_file_t file, + void* buf, + os_offset_t offset, + ulint n, + const char* src_file, + uint src_line); /** NOTE! Please use the corresponding macro os_file_read_no_error_handling(), not directly this function! This is the performance schema instrumented wrapper function for os_file_read_no_error_handling_func() which requests a synchronous read operation. -@param[in, out] type IO request context +@param[in] type IO request context @param[in] file Open file handle @param[out] buf buffer where to read @param[in] offset file offset where to read @@ -1013,20 +1013,20 @@ read operation. UNIV_INLINE dberr_t pfs_os_file_read_no_error_handling_func( - IORequest& type, - pfs_os_file_t file, - void* buf, - os_offset_t offset, - ulint n, - ulint* o, - const char* src_file, - uint src_line); + const IORequest& type, + pfs_os_file_t file, + void* buf, + os_offset_t offset, + ulint n, + ulint* o, + const char* src_file, + uint src_line); /** NOTE! Please use the corresponding macro os_aio(), not directly this function! Performance schema wrapper function of os_aio() which requests an asynchronous I/O operation. -@param[in] type IO request context +@param[in,out] type IO request context @param[in] mode IO mode @param[in] name Name of the file or path as NUL terminated string @@ -1064,7 +1064,7 @@ pfs_os_aio_func( this function! This is the performance schema instrumented wrapper function for os_file_write() which requests a synchronous write operation. -@param[in, out] type IO request context +@param[in] type IO request context @param[in] name Name of the file or path as NUL terminated string @param[in] file Open file handle @@ -1077,14 +1077,14 @@ os_file_write() which requests a synchronous write operation. UNIV_INLINE dberr_t pfs_os_file_write_func( - IORequest& type, - const char* name, - pfs_os_file_t file, - const void* buf, - os_offset_t offset, - ulint n, - const char* src_file, - uint src_line); + const IORequest& type, + const char* name, + pfs_os_file_t file, + const void* buf, + os_offset_t offset, + ulint n, + const char* src_file, + uint src_line); /** NOTE! Please use the corresponding macro os_file_flush(), not directly this function! @@ -1291,11 +1291,11 @@ Requests a synchronous read operation. @return DB_SUCCESS if request was successful */ dberr_t os_file_read_func( - IORequest& type, - os_file_t file, - void* buf, - os_offset_t offset, - ulint n) + const IORequest& type, + os_file_t file, + void* buf, + os_offset_t offset, + ulint n) MY_ATTRIBUTE((warn_unused_result)); /** Rewind file to its start, read at most size - 1 bytes from it to str, and @@ -1323,18 +1323,18 @@ any error handling. In case of error it returns FALSE. @return DB_SUCCESS or error code */ dberr_t os_file_read_no_error_handling_func( - IORequest& type, - os_file_t file, - void* buf, - os_offset_t offset, - ulint n, - ulint* o) + const IORequest& type, + os_file_t file, + void* buf, + os_offset_t offset, + ulint n, + ulint* o) MY_ATTRIBUTE((warn_unused_result)); /** NOTE! Use the corresponding macro os_file_write(), not directly this function! Requests a synchronous write operation. -@param[in,out] type IO request context +@param[in] type IO request context @param[in] file Open file handle @param[out] buf buffer where to read @param[in] offset file offset where to read @@ -1342,12 +1342,12 @@ Requests a synchronous write operation. @return DB_SUCCESS if request was successful */ dberr_t os_file_write_func( - IORequest& type, - const char* name, - os_file_t file, - const void* buf, - os_offset_t offset, - ulint n) + const IORequest& type, + const char* name, + os_file_t file, + const void* buf, + os_offset_t offset, + ulint n) MY_ATTRIBUTE((warn_unused_result)); /** Check the existence and type of the given file. @@ -1430,7 +1430,7 @@ os_aio_free(); /** NOTE! Use the corresponding macro os_aio(), not directly this function! Requests an asynchronous i/o operation. -@param[in] type IO request context +@param[in,out] type IO request context @param[in] mode IO mode @param[in] name Name of the file or path as NUL terminated string diff --git a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic index 07c2b6212ed..6cb67af94ca 100644 --- a/storage/innobase/include/os0file.ic +++ b/storage/innobase/include/os0file.ic @@ -207,7 +207,7 @@ pfs_os_file_close_func( function! Performance schema wrapper function of os_aio() which requests an asynchronous i/o operation. -@param[in] type IO request context +@param[in,type] type IO request context @param[in] mode IO mode @param[in] name Name of the file or path as NUL terminated string @@ -264,7 +264,7 @@ pfs_os_aio_func( this function! This is the performance schema instrumented wrapper function for os_file_read() which requests a synchronous read operation. -@param[in, out] type IO request context +@param[in] type IO request context @param[in] file Open file handle @param[out] buf buffer where to read @param[in] offset file offset where to read @@ -275,13 +275,13 @@ os_file_read() which requests a synchronous read operation. UNIV_INLINE dberr_t pfs_os_file_read_func( - IORequest& type, - pfs_os_file_t file, - void* buf, - os_offset_t offset, - ulint n, - const char* src_file, - uint src_line) + const IORequest& type, + pfs_os_file_t file, + void* buf, + os_offset_t offset, + ulint n, + const char* src_file, + uint src_line) { PSI_file_locker_state state; struct PSI_file_locker* locker = NULL; @@ -305,7 +305,7 @@ not directly this function! This is the performance schema instrumented wrapper function for os_file_read_no_error_handling_func() which requests a synchronous read operation. -@param[in, out] type IO request context +@param[in] type IO request context @param[in] file Open file handle @param[out] buf buffer where to read @param[in] offset file offset where to read @@ -317,14 +317,14 @@ read operation. UNIV_INLINE dberr_t pfs_os_file_read_no_error_handling_func( - IORequest& type, - pfs_os_file_t file, - void* buf, - os_offset_t offset, - ulint n, - ulint* o, - const char* src_file, - uint src_line) + const IORequest& type, + pfs_os_file_t file, + void* buf, + os_offset_t offset, + ulint n, + ulint* o, + const char* src_file, + uint src_line) { PSI_file_locker_state state; struct PSI_file_locker* locker = NULL; @@ -343,7 +343,7 @@ pfs_os_file_read_no_error_handling_func( /** NOTE! Please use the corresponding macro os_file_read_no_error_handling_int_fd() to request a synchronous read operation. -@param[in,out] type read request +@param[in] type read request @param[in] file file handle @param[out] buf buffer where to read @param[in] offset file offset where to read @@ -354,13 +354,13 @@ a synchronous read operation. UNIV_INLINE bool pfs_os_file_read_no_error_handling_int_fd_func( - IORequest& type, - int file, - void* buf, - os_offset_t offset, - ulint n, - const char* src_file, - uint src_line) + const IORequest& type, + int file, + void* buf, + os_offset_t offset, + ulint n, + const char* src_file, + uint src_line) { PSI_file_locker_state state; @@ -387,7 +387,7 @@ pfs_os_file_read_no_error_handling_int_fd_func( this function! This is the performance schema instrumented wrapper function for os_file_write() which requests a synchronous write operation. -@param[in, out] type IO request context +@param[in] type IO request context @param[in] name Name of the file or path as NUL terminated string @param[in] file Open file handle @@ -401,14 +401,14 @@ os_file_write() which requests a synchronous write operation. UNIV_INLINE dberr_t pfs_os_file_write_func( - IORequest& type, - const char* name, - pfs_os_file_t file, - const void* buf, - os_offset_t offset, - ulint n, - const char* src_file, - uint src_line) + const IORequest& type, + const char* name, + pfs_os_file_t file, + const void* buf, + os_offset_t offset, + ulint n, + const char* src_file, + uint src_line) { PSI_file_locker_state state; struct PSI_file_locker* locker = NULL; @@ -429,7 +429,7 @@ pfs_os_file_write_func( not directly this function! This is the performance schema instrumented wrapper function for os_file_write_int_fd() which requests a synchronous write operation. -@param[in,out] type write request +@param[in] type write request @param[in] name file name @param[in] file file handle @param[in] buf buffer to write @@ -441,14 +441,14 @@ os_file_write_int_fd() which requests a synchronous write operation. UNIV_INLINE bool pfs_os_file_write_int_fd_func( - IORequest& type, - const char* name, - int file, - const void* buf, - os_offset_t offset, - ulint n, - const char* src_file, - uint src_line) + const IORequest& type, + const char* name, + int file, + const void* buf, + os_offset_t offset, + ulint n, + const char* src_file, + uint src_line) { PSI_file_locker_state state; struct PSI_file_locker* locker; diff --git a/storage/innobase/include/os0thread.h b/storage/innobase/include/os0thread.h index 071e7422894..d4430f5ebce 100644 --- a/storage/innobase/include/os0thread.h +++ b/storage/innobase/include/os0thread.h @@ -151,10 +151,4 @@ os_thread_sleep( /*============*/ ulint tm); /*!< in: time in microseconds */ -/*****************************************************************//** -Check if there are threads active. -@return true if the thread count > 0. */ -bool -os_thread_active(); - #endif diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index 916222d5fdb..96d3bdfab8f 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -1080,14 +1080,14 @@ private: # endif /* !DBUG_OFF */ # ifdef UNIV_DEBUG -/************************************************************//** -Reads the DB_TRX_ID of a clustered index record. +/** Read the DB_TRX_ID of a clustered index record. +@param[in] rec clustered index record +@param[in] index clustered index @return the value of DB_TRX_ID */ trx_id_t rec_get_trx_id( -/*===========*/ - const rec_t* rec, /*!< in: record */ - const dict_index_t* index) /*!< in: clustered index */ + const rec_t* rec, + const dict_index_t* index) MY_ATTRIBUTE((nonnull, warn_unused_result)); # endif /* UNIV_DEBUG */ diff --git a/storage/innobase/include/row0ftsort.h b/storage/innobase/include/row0ftsort.h index 207fd783cac..b1f3b8ab328 100644 --- a/storage/innobase/include/row0ftsort.h +++ b/storage/innobase/include/row0ftsort.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2016, MariaDB Corporation. +Copyright (c) 2015, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -103,7 +103,6 @@ struct fts_psort_t { /** Row fts token for plugin parser */ struct row_fts_token_t { fts_string_t* text; /*!< token */ - ulint position; /*!< token position in the document */ UT_LIST_NODE_T(row_fts_token_t) token_list; /*!< next token link */ }; diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 6164366628e..8dfff46e78b 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -681,12 +681,6 @@ struct row_prebuilt_t { not to be confused with InnoDB externally stored columns (VARCHAR can be off-page too) */ - unsigned templ_contains_fixed_point:1;/*!< TRUE if the - template contains a column with - DATA_POINT. Since InnoDB regards - DATA_POINT as non-BLOB type, the - templ_contains_blob can't tell us - if there is DATA_POINT */ mysql_row_templ_t* mysql_template;/*!< template used to transform rows fast between MySQL and Innobase formats; memory for this template diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 344507aae20..30f2eac33d3 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -308,6 +308,22 @@ segment). It is quite possible that some of the tablespaces doesn't host any of the rollback-segment based on configuration used. */ extern ulint srv_undo_tablespaces_active; +/** Undo tablespaces starts with space_id. */ +extern ulint srv_undo_space_id_start; + +/** Check whether given space id is undo tablespace id +@param[in] space_id space id to check +@return true if it is undo tablespace else false. */ +inline +bool +srv_is_undo_tablespace(ulint space_id) +{ + return srv_undo_space_id_start > 0 + && space_id >= srv_undo_space_id_start + && space_id < (srv_undo_space_id_start + + srv_undo_tablespaces_open); +} + /** The number of undo segments to use */ extern ulong srv_undo_logs; @@ -335,17 +351,9 @@ extern char* srv_log_group_home_dir; /** Maximum number of srv_n_log_files, or innodb_log_files_in_group */ #define SRV_N_LOG_FILES_MAX 100 extern ulong srv_n_log_files; -/** At startup, this is the current redo log file size. -During startup, if this is different from srv_log_file_size_requested -(innodb_log_file_size), the redo log will be rebuilt and this size -will be initialized to srv_log_file_size_requested. -When upgrading from a previous redo log format, this will be set to 0, -and writing to the redo log is not allowed. - -During startup, this is in bytes, and later converted to pages. */ -extern ib_uint64_t srv_log_file_size; -/** The value of the startup parameter innodb_log_file_size */ -extern ib_uint64_t srv_log_file_size_requested; +/** The InnoDB redo log file size, or 0 when changing the redo log format +at startup (while disallowing writes to the redo log). */ +extern ulonglong srv_log_file_size; extern ulint srv_log_buffer_size; extern ulong srv_flush_log_at_trx_commit; extern uint srv_flush_log_at_timeout; @@ -521,7 +529,10 @@ extern my_bool srv_purge_view_update_only_debug; /** Value of MySQL global used to disable master thread. */ extern my_bool srv_master_thread_disabled_debug; +/** InnoDB system tablespace to set during recovery */ extern uint srv_sys_space_size_debug; +/** whether redo log files have been created at startup */ +extern bool srv_log_files_created; #endif /* UNIV_DEBUG */ #define SRV_SEMAPHORE_WAIT_EXTENSION 7200 diff --git a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h index 47b42725541..93ea0be2662 100644 --- a/storage/innobase/include/srv0start.h +++ b/storage/innobase/include/srv0start.h @@ -105,22 +105,6 @@ extern bool srv_startup_is_before_trx_rollback_phase; /** TRUE if a raw partition is in use */ extern ibool srv_start_raw_disk_in_use; -/** Undo tablespaces starts with space_id. */ -extern ulint srv_undo_space_id_start; - -/** Check whether given space id is undo tablespace id -@param[in] space_id space id to check -@return true if it is undo tablespace else false. */ -inline -bool -srv_is_undo_tablespace(ulint space_id) -{ - return srv_undo_space_id_start > 0 - && space_id >= srv_undo_space_id_start - && space_id < (srv_undo_space_id_start - + srv_undo_tablespaces_open); -} - /** Shutdown state */ enum srv_shutdown_t { SRV_SHUTDOWN_NONE = 0, /*!< Database running normally */ diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h index b2a82ec5fe7..c2864fa2f56 100644 --- a/storage/innobase/include/sync0types.h +++ b/storage/innobase/include/sync0types.h @@ -1076,6 +1076,7 @@ struct latch_t { /** Subclass this to iterate over a thread's acquired latch levels. */ struct sync_check_functor_t { + virtual ~sync_check_functor_t() { } virtual bool operator()(const latch_level_t) const = 0; }; diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index d8e96f2ea5f..62ef8ec0d7a 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -236,16 +236,12 @@ trx_sys_update_mysql_binlog_offset( /*===============================*/ const char* file_name,/*!< in: MySQL log file name */ int64_t offset, /*!< in: position in that log file */ - ulint field, /*!< in: offset of the MySQL log info field in - the trx sys header */ trx_sysf_t* sys_header, /*!< in: trx sys header */ mtr_t* mtr); /*!< in: mtr */ -/*****************************************************************//** -Prints to stderr the MySQL binlog offset info in the trx system header if -the magic number shows it valid. */ +/** Display the MySQL binlog offset info if it is present in the trx +system header. */ void -trx_sys_print_mysql_binlog_offset(void); -/*===================================*/ +trx_sys_print_mysql_binlog_offset(); #ifdef WITH_WSREP /** Update WSREP checkpoint XID in sys header. */ void @@ -255,11 +251,11 @@ trx_sys_update_wsrep_checkpoint( trx_sysf_t* sys_header, /*!< in: sys_header */ mtr_t* mtr); /*!< in: mtr */ -void -/** Read WSREP checkpoint XID from sys header. */ -trx_sys_read_wsrep_checkpoint( -/*==========================*/ - XID* xid); /*!< out: WSREP XID */ +/** Read WSREP checkpoint XID from sys header. +@param[out] xid WSREP XID +@return whether the checkpoint was present */ +bool +trx_sys_read_wsrep_checkpoint(XID* xid); #endif /* WITH_WSREP */ /*****************************************************************//** @@ -354,9 +350,7 @@ impose the 7 bit restriction. e.g., mach_write_to_3() */ TRX_SYS_MYSQL_LOG_MAGIC_N if we have valid data in the MySQL binlog info */ -#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH 4 /*!< high 4 bytes of the offset - within that file */ -#define TRX_SYS_MYSQL_LOG_OFFSET_LOW 8 /*!< low 4 bytes of the offset +#define TRX_SYS_MYSQL_LOG_OFFSET 4 /*!< the 64-bit offset within that file */ #define TRX_SYS_MYSQL_LOG_NAME 12 /*!< MySQL log file name */ diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 4f924e064a8..182df269015 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -669,18 +669,17 @@ log_group_set_fields( /** Calculate the recommended highest values for lsn - last_checkpoint_lsn and lsn - buf_get_oldest_modification(). +@param[in] file_size requested innodb_log_file_size @retval true on success @retval false if the smallest log group is too small to accommodate the number of OS threads in the database server */ bool -log_set_capacity() +log_set_capacity(ulonglong file_size) { lsn_t margin; ulint free; - lsn_t smallest_capacity = ((srv_log_file_size_requested - << srv_page_size_shift) - - LOG_FILE_HDR_SIZE) + lsn_t smallest_capacity = (file_size - LOG_FILE_HDR_SIZE) * srv_n_log_files; /* Add extra safety */ smallest_capacity -= smallest_capacity / 10; @@ -798,10 +797,9 @@ log_sys_init() } /** Initialize the redo log. -@param[in] n_files number of files -@param[in] file_size file size in bytes */ +@param[in] n_files number of files */ void -log_init(ulint n_files, lsn_t file_size) +log_init(ulint n_files) { ulint i; log_group_t* group = &log_sys->log; @@ -810,7 +808,7 @@ log_init(ulint n_files, lsn_t file_size) group->format = srv_encrypt_log ? LOG_HEADER_FORMAT_CURRENT | LOG_HEADER_FORMAT_ENCRYPTED : LOG_HEADER_FORMAT_CURRENT; - group->file_size = file_size; + group->file_size = srv_log_file_size; group->state = LOG_GROUP_OK; group->lsn = LOG_START_LSN; group->lsn_offset = LOG_FILE_HDR_SIZE; @@ -2261,11 +2259,9 @@ log_group_close_all(void) log_group_close(&log_sys->log); } -/********************************************************//** -Shutdown the log system but do not release all the memory. */ +/** Shut down the redo log subsystem. */ void -log_shutdown(void) -/*==============*/ +log_shutdown() { log_group_close_all(); @@ -2289,20 +2285,8 @@ log_shutdown(void) } recv_sys_close(); -} - -/********************************************************//** -Free the log system data structures. */ -void -log_mem_free(void) -/*==============*/ -{ - if (log_sys != NULL) { - recv_sys_mem_free(); - ut_free(log_sys); - - log_sys = NULL; - } + ut_free(log_sys); + log_sys = NULL; } /******************************************************//** diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index e48e185274a..021d897e172 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -415,31 +415,9 @@ fil_name_parse( return(end_ptr); } -/********************************************************//** -Creates the recovery system. */ -void -recv_sys_create(void) -/*=================*/ -{ - if (recv_sys != NULL) { - - return; - } - - recv_sys = static_cast<recv_sys_t*>(ut_zalloc_nokey(sizeof(*recv_sys))); - - mutex_create(LATCH_ID_RECV_SYS, &recv_sys->mutex); - mutex_create(LATCH_ID_RECV_WRITER, &recv_sys->writer_mutex); - - recv_sys->heap = NULL; - recv_sys->addr_hash = NULL; -} - -/********************************************************//** -Release recovery system mutexes. */ +/** Clean up after recv_sys_init() */ void -recv_sys_close(void) -/*================*/ +recv_sys_close() { if (recv_sys != NULL) { recv_sys->dblwr.pages.clear(); @@ -578,56 +556,41 @@ DECLARE_THREAD(recv_writer_thread)( OS_THREAD_DUMMY_RETURN; } -/************************************************************ -Inits the recovery system for a recovery operation. */ +/** Initialize the redo log recovery subsystem. */ void -recv_sys_init( -/*==========*/ - ulint available_memory) /*!< in: available memory in bytes */ +recv_sys_init() { - if (recv_sys->heap != NULL) { + ut_ad(recv_sys == NULL); - return; - } + recv_sys = static_cast<recv_sys_t*>(ut_zalloc_nokey(sizeof(*recv_sys))); - mutex_enter(&(recv_sys->mutex)); + mutex_create(LATCH_ID_RECV_SYS, &recv_sys->mutex); + mutex_create(LATCH_ID_RECV_WRITER, &recv_sys->writer_mutex); - recv_sys->heap = mem_heap_create_typed(256, - MEM_HEAP_FOR_RECV_SYS); + recv_sys->heap = mem_heap_create_typed(256, MEM_HEAP_FOR_RECV_SYS); if (!srv_read_only_mode) { recv_sys->flush_start = os_event_create(0); recv_sys->flush_end = os_event_create(0); } + ulint size = buf_pool_get_curr_size(); /* Set appropriate value of recv_n_pool_free_frames. */ - if (buf_pool_get_curr_size() >= (10 * 1024 * 1024)) { + if (size >= 10 << 20) { /* Buffer pool of size greater than 10 MB. */ recv_n_pool_free_frames = 512; } recv_sys->buf = static_cast<byte*>( ut_malloc_nokey(RECV_PARSING_BUF_SIZE)); - recv_sys->len = 0; - recv_sys->recovered_offset = 0; - - recv_sys->addr_hash = hash_create(available_memory / 512); - recv_sys->n_addrs = 0; - - recv_sys->apply_log_recs = FALSE; - recv_sys->apply_batch_on = FALSE; - recv_sys->found_corrupt_log = false; - recv_sys->found_corrupt_fs = false; - recv_sys->mlog_checkpoint_lsn = 0; + recv_sys->addr_hash = hash_create(size / 512); recv_sys->progress_time = ut_time(); recv_max_page_lsn = 0; /* Call the constructor for recv_sys_t::dblwr member */ new (&recv_sys->dblwr) recv_dblwr_t(); - - mutex_exit(&(recv_sys->mutex)); } /** Empty a fully processed hash table. */ @@ -2806,7 +2769,24 @@ recv_scan_log_recs( scanned_lsn += data_len; + if (data_len == LOG_BLOCK_HDR_SIZE + SIZE_OF_MLOG_CHECKPOINT + && scanned_lsn == checkpoint_lsn + SIZE_OF_MLOG_CHECKPOINT + && log_block[LOG_BLOCK_HDR_SIZE] == MLOG_CHECKPOINT + && checkpoint_lsn == mach_read_from_8(LOG_BLOCK_HDR_SIZE + + 1 + log_block)) { + /* The redo log is logically empty. */ + ut_ad(recv_sys->mlog_checkpoint_lsn == 0 + || recv_sys->mlog_checkpoint_lsn + == checkpoint_lsn); + recv_sys->mlog_checkpoint_lsn = checkpoint_lsn; + DBUG_PRINT("ib_log", ("found empty log; LSN=" LSN_PF, + scanned_lsn)); + finished = true; + break; + } + if (scanned_lsn > recv_sys->scanned_lsn) { + ut_ad(!srv_log_files_created); if (!recv_needed_recovery) { recv_needed_recovery = true; @@ -3244,7 +3224,11 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) there is something wrong we will print a message to the user about recovery: */ - if (checkpoint_lsn != flush_lsn) { + if (flush_lsn == checkpoint_lsn + SIZE_OF_MLOG_CHECKPOINT + && recv_sys->mlog_checkpoint_lsn == checkpoint_lsn) { + /* The redo log is logically empty. */ + } else if (checkpoint_lsn != flush_lsn) { + ut_ad(!srv_log_files_created); if (checkpoint_lsn + SIZE_OF_MLOG_CHECKPOINT < flush_lsn) { ib::warn() << " Are you sure you are using the" diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index d8c7d59fe27..54b9ff5d8d8 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -829,7 +829,7 @@ mtr_t::Command::prepare_write() fil_space_t* space = m_impl->m_user_space; - if (space != NULL && space->id <= srv_undo_tablespaces_open) { + if (space != NULL && is_predefined_tablespace(space->id)) { /* Omit MLOG_FILE_NAME for predefined tablespaces. */ space = NULL; } diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 94021a5b0f4..1217d438b96 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -107,9 +107,6 @@ static ulint os_innodb_umask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; #else /** Umask for creating files */ static ulint os_innodb_umask = 0; -#ifndef ECANCELED -#define ECANCELED 125 -#endif static HANDLE completion_port; static HANDLE read_completion_port; static DWORD fls_sync_io = FLS_OUT_OF_INDEXES; @@ -303,7 +300,7 @@ public: /** Requests for a slot in the aio array. If no slot is available, waits until not_full-event becomes signaled. - @param[in,out] type IO context + @param[in] type IO context @param[in,out] m1 message to be passed along with the AIO operation @param[in,out] m2 message to be passed along with the AIO @@ -316,14 +313,14 @@ public: @param[in] len length of the block to read or write @return pointer to slot */ Slot* reserve_slot( - IORequest& type, - fil_node_t* m1, - void* m2, - pfs_os_file_t file, - const char* name, - void* buf, - os_offset_t offset, - ulint len) + const IORequest& type, + fil_node_t* m1, + void* m2, + pfs_os_file_t file, + const char* name, + void* buf, + os_offset_t offset, + ulint len) MY_ATTRIBUTE((warn_unused_result)); /** @return number of reserved slots */ @@ -510,14 +507,14 @@ public: MY_ATTRIBUTE((warn_unused_result)); /** Select the IO slot array - @param[in] type Type of IO, READ or WRITE + @param[in,out] type Type of IO, READ or WRITE @param[in] read_only true if running in read-only mode @param[in] mode IO mode @return slot array or NULL if invalid mode specified */ static AIO* select_slot_array( - IORequest& type, - bool read_only, - ulint mode) + IORequest& type, + bool read_only, + ulint mode) MY_ATTRIBUTE((warn_unused_result)); /** Calculates segment number for a slot. @@ -4931,14 +4928,15 @@ os_file_io( static MY_ATTRIBUTE((warn_unused_result)) ssize_t os_file_pwrite( - IORequest& type, - os_file_t file, - const byte* buf, - ulint n, - os_offset_t offset, - dberr_t* err) + const IORequest& type, + os_file_t file, + const byte* buf, + ulint n, + os_offset_t offset, + dberr_t* err) { ut_ad(type.validate()); + ut_ad(type.is_write()); ++os_n_file_writes; @@ -4951,26 +4949,25 @@ os_file_pwrite( return(n_bytes); } -/** Requests a synchronous write operation. +/** NOTE! Use the corresponding macro os_file_write(), not directly +Requests a synchronous write operation. @param[in] type IO flags @param[in] file handle to an open file @param[out] buf buffer from which to write @param[in] offset file offset from the start where to read @param[in] n number of bytes to read, starting from offset @return DB_SUCCESS if request was successful, false if fail */ -static MY_ATTRIBUTE((warn_unused_result)) dberr_t -os_file_write_page( - IORequest& type, - const char* name, - os_file_t file, - const void* buf, - os_offset_t offset, - ulint n) +os_file_write_func( + const IORequest& type, + const char* name, + os_file_t file, + const void* buf, + os_offset_t offset, + ulint n) { dberr_t err; - ut_ad(type.is_write()); ut_ad(type.validate()); ut_ad(n > 0); @@ -5017,13 +5014,15 @@ os_file_write_page( static MY_ATTRIBUTE((warn_unused_result)) ssize_t os_file_pread( - IORequest& type, - os_file_t file, - void* buf, - ulint n, - os_offset_t offset, - dberr_t* err) + const IORequest& type, + os_file_t file, + void* buf, + ulint n, + os_offset_t offset, + dberr_t* err) { + ut_ad(type.is_read()); + ++os_n_file_reads; const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_READS); @@ -5047,13 +5046,13 @@ os_file_pread( static MY_ATTRIBUTE((warn_unused_result)) dberr_t os_file_read_page( - IORequest& type, - os_file_t file, - void* buf, - os_offset_t offset, - ulint n, - ulint* o, - bool exit_on_err) + const IORequest& type, + os_file_t file, + void* buf, + os_offset_t offset, + ulint n, + ulint* o, + bool exit_on_err) { dberr_t err; @@ -5421,14 +5420,12 @@ Requests a synchronous positioned read operation. @return DB_SUCCESS or error code */ dberr_t os_file_read_func( - IORequest& type, - os_file_t file, - void* buf, - os_offset_t offset, - ulint n) + const IORequest& type, + os_file_t file, + void* buf, + os_offset_t offset, + ulint n) { - ut_ad(type.is_read()); - return(os_file_read_page(type, file, buf, offset, n, NULL, true)); } @@ -5445,43 +5442,16 @@ Requests a synchronous positioned read operation. @return DB_SUCCESS or error code */ dberr_t os_file_read_no_error_handling_func( - IORequest& type, - os_file_t file, - void* buf, - os_offset_t offset, - ulint n, - ulint* o) + const IORequest& type, + os_file_t file, + void* buf, + os_offset_t offset, + ulint n, + ulint* o) { - ut_ad(type.is_read()); - return(os_file_read_page(type, file, buf, offset, n, o, false)); } -/** NOTE! Use the corresponding macro os_file_write(), not directly -Requests a synchronous write operation. -@param[in] type IO flags -@param[in] file handle to an open file -@param[out] buf buffer from which to write -@param[in] offset file offset from the start where to read -@param[in] n number of bytes to read, starting from offset -@return DB_SUCCESS if request was successful, false if fail */ -dberr_t -os_file_write_func( - IORequest& type, - const char* name, - os_file_t file, - const void* buf, - os_offset_t offset, - ulint n) -{ - ut_ad(type.validate()); - ut_ad(type.is_write()); - - const byte* ptr = reinterpret_cast<const byte*>(buf); - - return(os_file_write_page(type, name, file, ptr, offset, n)); -} - /** Check the existence and type of the given file. @param[in] path path name of file @param[out] exists true if the file exists @@ -6146,7 +6116,7 @@ AIO::get_segment_no_from_slot( /** Requests for a slot in the aio array. If no slot is available, waits until not_full-event becomes signaled. -@param[in,out] type IO context +@param[in] type IO context @param[in,out] m1 message to be passed along with the AIO operation @param[in,out] m2 message to be passed along with the AIO @@ -6160,14 +6130,14 @@ not_full-event becomes signaled. @return pointer to slot */ Slot* AIO::reserve_slot( - IORequest& type, - fil_node_t* m1, - void* m2, - pfs_os_file_t file, - const char* name, - void* buf, - os_offset_t offset, - ulint len) + const IORequest& type, + fil_node_t* m1, + void* m2, + pfs_os_file_t file, + const char* name, + void* buf, + os_offset_t offset, + ulint len) { #ifdef WIN_ASYNC_IO ut_a((len & 0xFFFFFFFFUL) == len); @@ -6378,7 +6348,7 @@ os_aio_simulated_wake_handler_threads() } /** Select the IO slot array -@param[in] type Type of IO, READ or WRITE +@param[in,out] type Type of IO, READ or WRITE @param[in] read_only true if running in read-only mode @param[in] mode IO mode @return slot array or NULL if invalid mode specified */ @@ -6595,7 +6565,7 @@ os_aio_windows_handler( /** NOTE! Use the corresponding macro os_aio(), not directly this function! Requests an asynchronous i/o operation. -@param[in] type IO request context +@param[in,out] type IO request context @param[in] mode IO mode @param[in] name Name of the file or path as NUL terminated string diff --git a/storage/innobase/os/os0thread.cc b/storage/innobase/os/os0thread.cc index 0462c62f4b2..fde743a9074 100644 --- a/storage/innobase/os/os0thread.cc +++ b/storage/innobase/os/os0thread.cc @@ -237,21 +237,3 @@ os_thread_sleep( select(0, NULL, NULL, NULL, &t); #endif /* _WIN32 */ } - -/*****************************************************************//** -Check if there are threads active. -@return true if the thread count > 0. */ -bool -os_thread_active() -/*==============*/ -{ - /* 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? If we did, we would have to - remove the pthread_detach() from - os_thread_exit(). Now we just sleep 0.1 - seconds and hope that is enough! */ - - return(my_atomic_loadlint(&os_thread_count) > 0); -} diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 59022dbe301..f556c887520 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -3711,6 +3711,10 @@ page_zip_write_rec( ut_a(slot); /* Copy the delete mark. */ if (rec_get_deleted_flag(rec, TRUE)) { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(!dict_index_is_clust(index) + || row_get_rec_trx_id(rec, index, offsets)); *slot |= PAGE_ZIP_DIR_SLOT_DEL >> 8; } else { *slot &= ~(PAGE_ZIP_DIR_SLOT_DEL >> 8); diff --git a/storage/innobase/rem/rem0cmp.cc b/storage/innobase/rem/rem0cmp.cc index b14d9c77ad1..ffe93ac8612 100644 --- a/storage/innobase/rem/rem0cmp.cc +++ b/storage/innobase/rem/rem0cmp.cc @@ -378,8 +378,6 @@ cmp_whole_field( case DATA_MYSQL: return(innobase_mysql_cmp(prtype, a, a_length, b, b_length)); - case DATA_POINT: - case DATA_VAR_POINT: case DATA_GEOMETRY: return(cmp_geometry_field(mtype, prtype, a, a_length, b, b_length)); @@ -437,11 +435,6 @@ cmp_data( case DATA_SYS: pad = ULINT_UNDEFINED; break; - case DATA_POINT: - case DATA_VAR_POINT: - /* Since DATA_POINT has a fixed length of DATA_POINT_LEN, - currently, pad is not needed. Meanwhile, DATA_VAR_POINT acts - the same as DATA_GEOMETRY */ case DATA_GEOMETRY: ut_ad(prtype & DATA_BINARY_TYPE); pad = ULINT_UNDEFINED; diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index c78df489179..4ad4730f37d 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -308,7 +308,6 @@ rec_init_offsets_comp_ordinary( if (!field->fixed_len || (temp && !dict_col_get_fixed_size(col, temp))) { - ut_ad(col->mtype != DATA_POINT); /* Variable-length field: read the length */ len = *lens--; /* If the maximum length of the field is up @@ -445,9 +444,6 @@ rec_init_offsets( if (UNIV_UNLIKELY(!field->fixed_len)) { const dict_col_t* col = dict_field_get_col(field); - /* DATA_POINT should always be a fixed - length column. */ - ut_ad(col->mtype != DATA_POINT); /* Variable-length field: read the length */ len = *lens--; /* If the maximum length of the field @@ -858,8 +854,6 @@ rec_get_converted_size_comp_prefix_low( } ut_ad(len <= col->len || DATA_LARGE_MTYPE(col->mtype) - || (DATA_POINT_MTYPE(col->mtype) - && len == DATA_MBR_LEN) || (col->len == 0 && col->mtype == DATA_VARCHAR)); fixed_len = field->fixed_len; @@ -1337,8 +1331,6 @@ rec_convert_dtuple_to_rec_comp( *lens-- = (byte) (len >> 8) | 0xc0; *lens-- = (byte) len; } else { - /* DATA_POINT would have a fixed_len */ - ut_ad(dtype_get_mtype(type) != DATA_POINT); ut_ad(len <= dtype_get_len(type) || DATA_LARGE_MTYPE(dtype_get_mtype(type)) || !strcmp(index->name, @@ -2106,8 +2098,6 @@ rec_print_mbr_rec( /***************************************************************//** Prints a physical record. */ -/***************************************************************//** -Prints a physical record. */ void rec_print_new( /*==========*/ @@ -2254,14 +2244,14 @@ operator<<(std::ostream& o, const rec_offsets_print& r) } #ifdef UNIV_DEBUG -/************************************************************//** -Reads the DB_TRX_ID of a clustered index record. +/** Read the DB_TRX_ID of a clustered index record. +@param[in] rec clustered index record +@param[in] index clustered index @return the value of DB_TRX_ID */ trx_id_t rec_get_trx_id( -/*===========*/ - const rec_t* rec, /*!< in: record */ - const dict_index_t* index) /*!< in: clustered index */ + const rec_t* rec, + const dict_index_t* index) { const page_t* page = page_align(rec); @@ -2270,10 +2260,11 @@ rec_get_trx_id( const byte* trx_id; ulint len; mem_heap_t* heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; + ulint offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2]; rec_offs_init(offsets_); + ulint* offsets = offsets_; + ut_ad(trx_id_col <= MAX_REF_PARTS); ut_ad(fil_page_index_page_check(page)); ut_ad(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID) == index->id); @@ -2287,7 +2278,7 @@ rec_get_trx_id( ut_ad(len == DATA_TRX_ID_LEN); - if (heap) { + if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 321b55e9894..da5d96ccc18 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -527,7 +527,6 @@ row_merge_fts_doc_tokenize( doc id and position to sort buffer */ while (t_ctx->processed_len < doc->text.f_len) { ulint idx = 0; - ib_uint32_t position; ulint cur_len; doc_id_t write_doc_id; row_fts_token_t* fts_token = NULL; @@ -679,20 +678,18 @@ row_merge_fts_doc_tokenize( ++field; - /* The third field is the position */ - if (parser != NULL) { - mach_write_to_4( - reinterpret_cast<byte*>(&position), - (fts_token->position + t_ctx->init_pos)); - } else { - mach_write_to_4( - reinterpret_cast<byte*>(&position), - (t_ctx->processed_len + inc - str.f_len + t_ctx->init_pos)); + /* The third field is the position. + MySQL 5.7 changed the fulltext parser plugin interface + by adding MYSQL_FTPARSER_BOOLEAN_INFO::position. + Below we assume that the field is always 0. */ + unsigned pos = t_ctx->init_pos; + byte position[4]; + if (parser == NULL) { + pos += t_ctx->processed_len + inc - str.f_len; } - - dfield_set_data(field, &position, sizeof(position)); - len = dfield_get_len(field); - ut_ad(len == sizeof(ib_uint32_t)); + len = 4; + mach_write_to_4(position, pos); + dfield_set_data(field, &position, len); field->type.mtype = DATA_INT; field->type.prtype = DATA_NOT_NULL; diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 87c2b61a3cb..d8d83a6bccc 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -346,6 +346,9 @@ row_ins_clust_index_entry_by_modify( ut_ad(rec_get_deleted_flag(rec, dict_table_is_comp(cursor->index->table))); + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(rec_get_trx_id(rec, cursor->index)); /* Build an update vector containing all the fields to be modified; NOTE that this vector may NOT contain system columns trx_id or @@ -1266,6 +1269,9 @@ row_ins_foreign_check_on_constraint( } if (rec_get_deleted_flag(clust_rec, dict_table_is_comp(table))) { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(rec_get_trx_id(clust_rec, clust_index)); /* This can happen if there is a circular reference of rows such that cascading delete comes to delete a row already in the process of being delete marked */ @@ -1274,7 +1280,6 @@ row_ins_foreign_check_on_constraint( goto nonstandard_exit_func; } - if (table->fts) { doc_id = fts_get_doc_id_from_rec(table, clust_rec, clust_index, tmp_heap); @@ -1758,6 +1763,12 @@ row_ins_check_foreign_constraint( if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))) { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(!dict_index_is_clust(check_index) + || row_get_rec_trx_id(rec, check_index, + offsets)); + err = row_ins_set_shared_rec_lock( lock_type, block, rec, check_index, offsets, thr); diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index ea332adfdc3..73cb3fcea6f 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -840,9 +840,7 @@ row_merge_buf_add( } ut_ad(len <= col->len - || DATA_LARGE_MTYPE(col->mtype) - || (col->mtype == DATA_POINT - && len == DATA_MBR_LEN)); + || DATA_LARGE_MTYPE(col->mtype)); fixed_len = ifield->fixed_len; if (fixed_len && !dict_table_is_comp(index->table) @@ -2130,10 +2128,10 @@ end_of_index: rec = page_cur_get_rec(cur); - offsets = rec_get_offsets(rec, clust_index, NULL, - ULINT_UNDEFINED, &row_heap); - if (online) { + offsets = rec_get_offsets(rec, clust_index, NULL, + ULINT_UNDEFINED, &row_heap); + /* Perform a REPEATABLE READ. When rebuilding the table online, @@ -2176,6 +2174,10 @@ end_of_index: if (rec_get_deleted_flag( rec, dict_table_is_comp(old_table))) { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(row_get_rec_trx_id(rec, clust_index, + offsets)); /* This record was deleted in the latest committed version, or it was deleted and then reinserted-by-update before purge @@ -2186,6 +2188,9 @@ end_of_index: ut_ad(!rec_offs_any_null_extern(rec, offsets)); } else if (rec_get_deleted_flag( rec, dict_table_is_comp(old_table))) { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(rec_get_trx_id(rec, clust_index)); /* Skip delete-marked records. Skipping delete-marked records will make the @@ -2195,6 +2200,9 @@ end_of_index: would make it tricky to detect duplicate keys. */ continue; + } else { + offsets = rec_get_offsets(rec, clust_index, NULL, + ULINT_UNDEFINED, &row_heap); } /* When !online, we are holding a lock on old_table, preventing diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 061fc25a55e..947b7d67df8 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -628,8 +628,6 @@ row_mysql_store_col_in_innobase_format( ptr = row_mysql_read_blob_ref(&col_len, mysql_data, col_len); } else if (DATA_GEOMETRY_MTYPE(type)) { - /* We use blob to store geometry data except DATA_POINT - internally, but in MySQL Layer the datatype is always blob. */ ptr = row_mysql_read_geometry(&col_len, mysql_data, col_len); } diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index 86a9e1259ac..cecd127e71e 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -160,6 +160,9 @@ row_purge_remove_clust_if_poss_low( } ut_ad(rec_get_deleted_flag(rec, rec_offs_comp(offsets))); + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(row_get_rec_trx_id(rec, index, offsets)); if (mode == BTR_MODIFY_LEAF) { success = btr_cur_optimistic_delete( diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 0b7d9bb33f3..876f608e43c 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -183,6 +183,9 @@ row_sel_sec_rec_is_for_clust_rec( if (rec_get_deleted_flag(clust_rec, dict_table_is_comp(clust_index->table))) { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(rec_get_trx_id(clust_rec, clust_index)); /* The clustered index record is delete-marked; it is not visible in the read view. Besides, @@ -2042,6 +2045,11 @@ skip_lock: if (rec_get_deleted_flag(clust_rec, dict_table_is_comp(plan->table))) { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing update_undo log record. */ + ut_ad(rec_get_trx_id(clust_rec, + dict_table_get_first_index( + plan->table))); /* The record is delete marked: we can skip it */ @@ -2611,10 +2619,9 @@ row_sel_convert_mysql_key_to_innobase( data_field_len = data_offset + data_len; } else { /* The key field is a column prefix of a BLOB - or TEXT, except DATA_POINT of GEOMETRY. */ + or TEXT. */ - ut_a(field->prefix_len > 0 - || DATA_POINT_MTYPE(type)); + ut_a(field->prefix_len > 0); /* MySQL stores the actual data length to the first 2 bytes after the optional SQL NULL @@ -2624,18 +2631,12 @@ row_sel_convert_mysql_key_to_innobase( seems to reserve field->prefix_len bytes for storing this field in the key value buffer, even though the actual value only takes data - len bytes from the start. - For POINT of GEOMETRY, which has no prefix - because it's now a fixed length type in - InnoDB, we have to get DATA_POINT_LEN bytes, - which is original prefix length of POINT. */ + len bytes from the start. */ data_len = key_ptr[data_offset] + 256 * key_ptr[data_offset + 1]; data_field_len = data_offset + 2 - + (type == DATA_POINT - ? DATA_POINT_LEN - : field->prefix_len); + + field->prefix_len; data_offset += 2; @@ -2897,8 +2898,6 @@ row_sel_field_store_in_mysql_format_func( len); break; - case DATA_POINT: - case DATA_VAR_POINT: case DATA_GEOMETRY: /* We store all geometry data as BLOB data at server layer. */ row_mysql_store_geometry(dest, templ->mysql_col_len, data, len); @@ -3019,7 +3018,6 @@ row_sel_store_mysql_field_func( /* Copy an externally stored field to a temporary heap */ ut_ad(field_no == templ->clust_rec_field_no); - ut_ad(templ->type != DATA_POINT); if (DATA_LARGE_MTYPE(templ->type)) { if (prebuilt->blob_heap == NULL) { @@ -3099,10 +3097,7 @@ row_sel_store_mysql_field_func( will be invalid as soon as the mini-transaction is committed and the page latch on the clustered index page is - released. - For DATA_POINT, it's stored like CHAR in InnoDB, - but it should be a BLOB field in MySQL layer. So we - still treated it as BLOB here. */ + released. */ if (prebuilt->blob_heap == NULL) { prebuilt->blob_heap = mem_heap_create( @@ -3934,6 +3929,9 @@ row_sel_try_search_shortcut_for_mysql( } if (rec_get_deleted_flag(rec, dict_table_is_comp(index->table))) { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(row_get_rec_trx_id(rec, index, *offsets)); return(SEL_EXHAUSTED); } @@ -5129,6 +5127,10 @@ locks_ok: page_rec_is_comp() cannot be used! */ if (rec_get_deleted_flag(rec, comp)) { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing undo log record. */ + ut_ad(index != clust_index + || row_get_rec_trx_id(rec, index, offsets)); /* The record is delete-marked: we can skip it */ @@ -5364,7 +5366,6 @@ requires_clust_rec: && prebuilt->select_lock_type == LOCK_NONE && !prebuilt->m_no_prefetch && !prebuilt->templ_contains_blob - && !prebuilt->templ_contains_fixed_point && !prebuilt->clust_index_was_generated && !prebuilt->used_in_HANDLER && prebuilt->template_type != ROW_MYSQL_DUMMY_TEMPLATE diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index 934b5ad5a7a..ef0c3ed9cc3 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -230,6 +230,14 @@ row_undo_ins_remove_sec_low( case ROW_NOT_FOUND: goto func_exit; case ROW_FOUND: + if (dict_index_is_spatial(index) + && rec_get_deleted_flag( + btr_pcur_get_rec(&pcur), + dict_table_is_comp(index->table))) { + ib::error() << "Record found in index " << index->name + << " is deleted marked on insert rollback."; + ut_ad(0); + } break; case ROW_BUFFERED: @@ -240,15 +248,6 @@ row_undo_ins_remove_sec_low( ut_error; } - if (search_result == ROW_FOUND && dict_index_is_spatial(index)) { - rec_t* rec = btr_pcur_get_rec(&pcur); - if (rec_get_deleted_flag(rec, - dict_table_is_comp(index->table))) { - ib::error() << "Record found in index " << index->name - << " is deleted marked on insert rollback."; - } - } - btr_cur = btr_pcur_get_btr_cur(&pcur); if (modify_leaf) { diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index c6e188c1ba3..aa8972ed781 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -215,6 +215,9 @@ row_undo_mod_remove_clust_low( than the rolling-back one. */ ut_ad(rec_get_deleted_flag(btr_cur_get_rec(btr_cur), dict_table_is_comp(node->table))); + /* In delete-marked records, DB_TRX_ID must + always refer to an existing update_undo log record. */ + ut_ad(rec_get_trx_id(btr_cur_get_rec(btr_cur), btr_cur->index)); if (mode == BTR_MODIFY_LEAF) { err = btr_cur_optimistic_delete(btr_cur, 0, mtr) @@ -350,8 +353,9 @@ row_undo_mod_clust( * it can be reallocated at any time after this mtr-commits * which is just below */ - ut_ad(srv_immediate_scrub_data_uncompressed || - rec_get_trx_id(btr_pcur_get_rec(pcur), index) == node->new_trx_id); + ut_ad(srv_immediate_scrub_data_uncompressed + || row_get_rec_trx_id(btr_pcur_get_rec(pcur), index, offsets) + == node->new_trx_id); btr_pcur_commit_specify_mtr(pcur, &mtr); @@ -515,6 +519,7 @@ row_undo_mod_del_mark_or_remove_sec_low( ib::error() << "Record found in index " << index->name << " is deleted marked" " on rollback update."; + ut_ad(0); } } diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 176af0400ce..b639fd583c4 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -2663,7 +2663,8 @@ row_upd_clust_rec_by_insert( marked, then we are here after a DB_LOCK_WAIT. Skip delete marking clustered index and disowning its blobs. */ - ut_ad(rec_get_trx_id(rec, index) == trx->id); + ut_ad(row_get_rec_trx_id(rec, index, offsets) + == trx->id); ut_ad(!trx_undo_roll_ptr_is_insert( row_get_rec_roll_ptr(rec, index, offsets))); diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index c89930ecb2c..d30136615af 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -188,17 +188,9 @@ static os_event_t srv_master_thread_disabled_event; char* srv_log_group_home_dir; ulong srv_n_log_files; -/** At startup, this is the current redo log file size. -During startup, if this is different from srv_log_file_size_requested -(innodb_log_file_size), the redo log will be rebuilt and this size -will be initialized to srv_log_file_size_requested. -When upgrading from a previous redo log format, this will be set to 0, -and writing to the redo log is not allowed. - -During startup, this is in bytes, and later converted to pages. */ -ib_uint64_t srv_log_file_size; -/** The value of the startup parameter innodb_log_file_size */ -ib_uint64_t srv_log_file_size_requested; +/** The InnoDB redo log file size, or 0 when changing the redo log format +at startup (while disallowing writes to the redo log). */ +ulonglong srv_log_file_size; /** copy of innodb_log_buffer_size, but in database pages */ ulint srv_log_buffer_size; /** innodb_flush_log_at_trx_commit */ @@ -1143,8 +1135,6 @@ srv_normalize_init_values(void) srv_tmp_space.normalize(); - srv_log_file_size /= UNIV_PAGE_SIZE; - srv_log_buffer_size /= UNIV_PAGE_SIZE; srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 7150fd2343e..985e2cf9b72 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -138,6 +138,8 @@ bool srv_is_being_started; bool srv_sys_tablespaces_open; /** TRUE if the server was successfully started */ bool srv_was_started; +/** The original value of srv_log_file_size (innodb_log_file_size) */ +static ulonglong srv_log_file_size_requested; /** TRUE if innobase_start_or_create_for_mysql() has been called */ static bool srv_start_has_been_called; @@ -147,6 +149,8 @@ UNIV_INTERN bool srv_undo_sources; #ifdef UNIV_DEBUG /** InnoDB system tablespace to set during recovery */ UNIV_INTERN uint srv_sys_space_size_debug; +/** whether redo log files have been created at startup */ +UNIV_INTERN bool srv_log_files_created; #endif /* UNIV_DEBUG */ /** Bit flags for tracking background thread creation. They are used to @@ -372,17 +376,13 @@ create_log_file( } ib::info() << "Setting log file " << name << " size to " - << (srv_log_file_size >> (20 - UNIV_PAGE_SIZE_SHIFT)) - << " MB"; + << srv_log_file_size << " bytes"; - ret = os_file_set_size(name, *file, - (os_offset_t) srv_log_file_size - << UNIV_PAGE_SIZE_SHIFT, + ret = os_file_set_size(name, *file, srv_log_file_size, srv_read_only_mode); if (!ret) { - ib::error() << "Cannot set log file " << name << " to size " - << (srv_log_file_size >> (20 - UNIV_PAGE_SIZE_SHIFT)) - << " MB"; + ib::error() << "Cannot set log file " << name << " size to " + << srv_log_file_size << " bytes"; return(DB_ERROR); } @@ -465,17 +465,17 @@ create_log_files( ut_a(fil_validate()); ut_a(log_space != NULL); + const ulint size = ulint(srv_log_file_size >> srv_page_size_shift); + logfile0 = fil_node_create( - logfilename, (ulint) srv_log_file_size, - log_space, false, false); + logfilename, size, log_space, false, false); ut_a(logfile0); for (unsigned i = 1; i < srv_n_log_files; i++) { sprintf(logfilename + dirnamelen, "ib_logfile%u", i); - if (!fil_node_create(logfilename, - (ulint) srv_log_file_size, + if (!fil_node_create(logfilename, size, log_space, false, false)) { ib::error() @@ -486,8 +486,8 @@ create_log_files( } } - log_init(srv_n_log_files, srv_log_file_size * UNIV_PAGE_SIZE); - if (!log_set_capacity()) { + log_init(srv_n_log_files); + if (!log_set_capacity(srv_log_file_size_requested)) { return(DB_ERROR); } @@ -526,6 +526,9 @@ create_log_files_rename( we need to explicitly flush the log buffers. */ fil_flush(SRV_LOG_SPACE_FIRST_ID); + ut_ad(!srv_log_files_created); + ut_d(srv_log_files_created = true); + DBUG_EXECUTE_IF("innodb_log_abort_9", return(DB_ERROR);); DBUG_PRINT("ib_log", ("After innodb_log_abort_9")); @@ -959,8 +962,6 @@ srv_undo_tablespaces_init(bool create_new_db) if (0 == srv_undo_tablespaces_open++) { srv_undo_space_id_start = undo_tablespace_ids[i]; } - - ++srv_undo_tablespaces_open; } /* Open any extra unused undo tablespaces. These must be contiguous. @@ -1231,6 +1232,7 @@ static void srv_shutdown_all_bg_threads() { + ut_ad(!srv_undo_sources); srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS; /* All threads end up waiting for certain events. Put those events @@ -1282,13 +1284,7 @@ srv_shutdown_all_bg_threads() os_event_set(buf_flush_event); - /* f. dict_stats_thread is signaled from - logs_empty_and_mark_files_at_shutdown() and - should have already quit or is quitting right - now. */ - if (srv_use_mtflush) { - /* g. Exit the multi threaded flush threads */ buf_mtflu_io_thread_exit(); } } @@ -1297,13 +1293,11 @@ srv_shutdown_all_bg_threads() os_aio_wake_all_threads_at_shutdown(); } - const bool active = os_thread_active(); - - os_thread_sleep(100000); - - if (!active) { + if (!os_thread_count) { return; } + + os_thread_sleep(100000); } ib::warn() << os_thread_count << " threads created by InnoDB" @@ -1414,7 +1408,7 @@ srv_prepare_to_delete_redo_log_files( info << srv_n_log_files << "*" << srv_log_file_size_requested - << " pages; LSN=" << flushed_lsn; + << " bytes; LSN=" << flushed_lsn; } /* Flush the old log files. */ @@ -1642,10 +1636,10 @@ innobase_start_or_create_for_mysql() /* Do not allocate too large of a buffer pool on Windows 32-bit systems, which can have trouble allocating larger single contiguous memory blocks. */ + srv_buf_pool_size = static_cast<ulint>(ut_uint64_align_up(srv_buf_pool_size, srv_buf_pool_chunk_unit)); srv_buf_pool_instances = ut_min( static_cast<ulong>(MAX_BUFFER_POOLS), - static_cast<ulong>(srv_buf_pool_size - / (128 * 1024 * 1024))); + static_cast<ulong>(srv_buf_pool_size / srv_buf_pool_chunk_unit)); #else /* defined(_WIN32) && !defined(_WIN64) */ /* Default to 8 instances when size > 1GB. */ srv_buf_pool_instances = 8; @@ -1835,8 +1829,7 @@ innobase_start_or_create_for_mysql() fsp_init(); log_sys_init(); - recv_sys_create(); - recv_sys_init(buf_pool_get_curr_size()); + recv_sys_init(); lock_sys_create(srv_lock_table_size); /* Create i/o-handler threads: */ @@ -1868,8 +1861,7 @@ innobase_start_or_create_for_mysql() srv_start_state_set(SRV_START_STATE_IO); } - if (srv_n_log_files * srv_log_file_size * UNIV_PAGE_SIZE - >= 512ULL * 1024ULL * 1024ULL * 1024ULL) { + if (srv_n_log_files * srv_log_file_size >= 512ULL << 30) { /* log_block_convert_lsn_to_no() limits the returned block number to 1G and given that OS_FILE_LOG_BLOCK_SIZE is 512 bytes, then we have a limit of 512 GB. If that limit is to @@ -1880,18 +1872,8 @@ innobase_start_or_create_for_mysql() return(srv_init_abort(DB_ERROR)); } - if (srv_n_log_files * srv_log_file_size >= ULINT_MAX) { - /* fil_io() takes ulint as an argument and we are passing - (next_offset / UNIV_PAGE_SIZE) to it in log_group_write_buf(). - So (next_offset / UNIV_PAGE_SIZE) must be less than ULINT_MAX. - So next_offset must be < ULINT_MAX * UNIV_PAGE_SIZE. This - means that we are limited to ULINT_MAX * UNIV_PAGE_SIZE which - is 64 TB on 32 bit systems. */ - ib::error() << "Combined size of log files must be < " - << ULINT_MAX / 1073741824 * UNIV_PAGE_SIZE << " GB"; - - return(srv_init_abort(DB_ERROR)); - } + compile_time_assert(ulonglong(ULINT_MAX) * UNIV_PAGE_SIZE_MIN + >= 512ULL << 30); os_normalize_path(srv_data_home); @@ -2030,27 +2012,22 @@ innobase_start_or_create_for_mysql() ut_a(size != (os_offset_t) -1); - if (size & ((1 << UNIV_PAGE_SIZE_SHIFT) - 1)) { + if (size & (OS_FILE_LOG_BLOCK_SIZE - 1)) { ib::error() << "Log file " << logfilename << " size " << size << " is not a" - " multiple of innodb_page_size"; + " multiple of 512 bytes"; return(srv_init_abort(DB_ERROR)); } - size >>= UNIV_PAGE_SIZE_SHIFT; - if (i == 0) { srv_log_file_size = size; } else if (size != srv_log_file_size) { ib::error() << "Log file " << logfilename - << " is of different size " - << (size << UNIV_PAGE_SIZE_SHIFT) + << " is of different size " << size << " bytes than other log files " - << (srv_log_file_size - << UNIV_PAGE_SIZE_SHIFT) - << " bytes!"; + << srv_log_file_size << " bytes!"; return(srv_init_abort(DB_ERROR)); } } @@ -2071,23 +2048,23 @@ innobase_start_or_create_for_mysql() ut_a(fil_validate()); ut_a(log_space); - /* srv_log_file_size is measured in pages; if page size is 16KB, - then we have a limit of 64TB on 32 bit systems */ - ut_a(srv_log_file_size <= ULINT_MAX); + ut_a(srv_log_file_size <= 512ULL << 30); + + const ulint size = 1 + ulint((srv_log_file_size - 1) + >> srv_page_size_shift); - for (unsigned j = 0; j < i; j++) { + for (unsigned j = 0; j < srv_n_log_files_found; j++) { sprintf(logfilename + dirnamelen, "ib_logfile%u", j); - if (!fil_node_create(logfilename, - (ulint) srv_log_file_size, + if (!fil_node_create(logfilename, size, log_space, false, false)) { return(srv_init_abort(DB_ERROR)); } } - log_init(i, srv_log_file_size * UNIV_PAGE_SIZE); + log_init(srv_n_log_files_found); - if (!log_set_capacity()) { + if (!log_set_capacity(srv_log_file_size_requested)) { return(srv_init_abort(DB_ERROR)); } } @@ -2764,11 +2741,7 @@ innodb_shutdown() ut_ad(!srv_running); ut_ad(!srv_undo_sources); - /* 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. */ - + /* Shut down the persistent files. */ logs_empty_and_mark_files_at_shutdown(); if (ulint n_threads = srv_conc_get_active_threads()) { @@ -2777,7 +2750,7 @@ innodb_shutdown() " inside InnoDB at shutdown"; } - /* 2. Make all threads created by InnoDB to exit */ + /* Exit any remaining threads. */ srv_shutdown_all_bg_threads(); if (srv_monitor_file) { @@ -2881,7 +2854,8 @@ innodb_shutdown() /* 4. Free all allocated memory */ pars_lexer_close(); - log_mem_free(); + recv_sys_close(); + ut_ad(buf_pool_ptr || !srv_was_started); if (buf_pool_ptr) { buf_pool_free(srv_buf_pool_instances); diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc index 0d2dcea7605..97842fb878b 100644 --- a/storage/innobase/sync/sync0debug.cc +++ b/storage/innobase/sync/sync0debug.cc @@ -1265,11 +1265,6 @@ LatchDebug::shutdown() mutex_free(&rw_lock_debug_mutex); - if (instance() == NULL) { - - return; - } - ut_a(s_initialized); s_initialized = false; diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 735e25a7e1e..a60e42dcea4 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -906,6 +906,10 @@ trx_undo_page_report_modify( ut_ad(!rec_get_deleted_flag(rec, dict_table_is_comp(table))); type_cmpl = TRX_UNDO_DEL_MARK_REC; } else if (rec_get_deleted_flag(rec, dict_table_is_comp(table))) { + /* In delete-marked records, DB_TRX_ID must + always refer to an existing update_undo log record. */ + ut_ad(row_get_rec_trx_id(rec, index, offsets)); + type_cmpl = TRX_UNDO_UPD_DEL_REC; /* We are about to update a delete marked record. We don't typically need the prefix in this case unless @@ -1874,6 +1878,10 @@ trx_undo_report_row_operation( ut_ad(!srv_read_only_mode); trx = thr_get_trx(thr); + /* This function must not be invoked during rollback + (of a TRX_STATE_PREPARE transaction or otherwise). */ + ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); + ut_ad(!trx->in_rollback); mtr.start(); trx_undo_t** pundo; @@ -1887,6 +1895,7 @@ trx_undo_report_row_operation( pundo = &trx->rsegs.m_noredo.undo; } else { ut_ad(!trx->read_only); + ut_ad(trx->id); /* Keep INFORMATION_SCHEMA.TABLES.UPDATE_TIME up-to-date for persistent tables. Temporary tables are not listed there. */ diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index e3f3ba81016..f633be96fa4 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -128,95 +128,67 @@ trx_sys_update_mysql_binlog_offset( /*===============================*/ const char* file_name,/*!< in: MySQL log file name */ int64_t offset, /*!< in: position in that log file */ - ulint field, /*!< in: offset of the MySQL log info field in - the trx sys header */ trx_sysf_t* sys_header, /*!< in: trx sys header */ mtr_t* mtr) /*!< in: mtr */ { DBUG_PRINT("InnoDB",("trx_mysql_binlog_offset: %lld", (longlong) offset)); - if (ut_strlen(file_name) >= TRX_SYS_MYSQL_LOG_NAME_LEN) { + const size_t len = strlen(file_name) + 1; + + if (len > TRX_SYS_MYSQL_LOG_NAME_LEN) { /* We cannot fit the name to the 512 bytes we have reserved */ return; } - if (mach_read_from_4(sys_header + field - + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD) + if (mach_read_from_4(TRX_SYS_MYSQL_LOG_MAGIC_N_FLD + + TRX_SYS_MYSQL_LOG_INFO + sys_header) != TRX_SYS_MYSQL_LOG_MAGIC_N) { - mlog_write_ulint(sys_header + field - + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD, + mlog_write_ulint(TRX_SYS_MYSQL_LOG_MAGIC_N_FLD + + TRX_SYS_MYSQL_LOG_INFO + sys_header, TRX_SYS_MYSQL_LOG_MAGIC_N, MLOG_4BYTES, mtr); } - if (0 != strcmp((char*) (sys_header + field + TRX_SYS_MYSQL_LOG_NAME), - file_name)) { - - mlog_write_string(sys_header + field - + TRX_SYS_MYSQL_LOG_NAME, - (byte*) file_name, 1 + ut_strlen(file_name), - mtr); + if (memcmp(file_name, TRX_SYS_MYSQL_LOG_NAME + TRX_SYS_MYSQL_LOG_INFO + + sys_header, len)) { + mlog_write_string(TRX_SYS_MYSQL_LOG_NAME + + TRX_SYS_MYSQL_LOG_INFO + + sys_header, + reinterpret_cast<const byte*>(file_name), + len, mtr); } - if (mach_read_from_4(sys_header + field - + TRX_SYS_MYSQL_LOG_OFFSET_HIGH) > 0 - || (offset >> 32) > 0) { - - mlog_write_ulint(sys_header + field - + TRX_SYS_MYSQL_LOG_OFFSET_HIGH, - (ulint)(offset >> 32), - MLOG_4BYTES, mtr); - } - - mlog_write_ulint(sys_header + field - + TRX_SYS_MYSQL_LOG_OFFSET_LOW, - (ulint)(offset & 0xFFFFFFFFUL), - MLOG_4BYTES, mtr); + mlog_write_ull(TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_OFFSET + + sys_header, offset, mtr); } -/*****************************************************************//** -Stores the MySQL binlog offset info in the trx system header if -the magic number shows it valid, and print the info to stderr */ +/** Display the MySQL binlog offset info if it is present in the trx +system header. */ void -trx_sys_print_mysql_binlog_offset(void) -/*===================================*/ +trx_sys_print_mysql_binlog_offset() { - trx_sysf_t* sys_header; mtr_t mtr; - ulint trx_sys_mysql_bin_log_pos_high; - ulint trx_sys_mysql_bin_log_pos_low; - - mtr_start(&mtr); - sys_header = trx_sysf_get(&mtr); - - if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO - + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD) - != TRX_SYS_MYSQL_LOG_MAGIC_N) { - - mtr_commit(&mtr); + mtr.start(); - return; + const trx_sysf_t* sys_header = trx_sysf_get(&mtr); + + if (mach_read_from_4(TRX_SYS_MYSQL_LOG_INFO + + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD + sys_header) + == TRX_SYS_MYSQL_LOG_MAGIC_N) { + ib::info() << "Last binlog file '" + << TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME + + sys_header + << "', position " + << mach_read_from_8(TRX_SYS_MYSQL_LOG_INFO + + TRX_SYS_MYSQL_LOG_OFFSET + + sys_header); } - trx_sys_mysql_bin_log_pos_high = mach_read_from_4( - sys_header + TRX_SYS_MYSQL_LOG_INFO - + TRX_SYS_MYSQL_LOG_OFFSET_HIGH); - trx_sys_mysql_bin_log_pos_low = mach_read_from_4( - sys_header + TRX_SYS_MYSQL_LOG_INFO - + TRX_SYS_MYSQL_LOG_OFFSET_LOW); - - fprintf(stderr, - "InnoDB: Last MySQL binlog file position " ULINTPF " " ULINTPF - ", file name %s\n", - trx_sys_mysql_bin_log_pos_high, trx_sys_mysql_bin_log_pos_low, - sys_header + TRX_SYS_MYSQL_LOG_INFO - + TRX_SYS_MYSQL_LOG_NAME); - - mtr_commit(&mtr); + mtr.commit(); } #ifdef WITH_WSREP @@ -301,10 +273,11 @@ trx_sys_update_wsrep_checkpoint( } -void -trx_sys_read_wsrep_checkpoint( -/*==========================*/ - XID* xid) +/** Read WSREP checkpoint XID from sys header. +@param[out] xid WSREP XID +@return whether the checkpoint was present */ +bool +trx_sys_read_wsrep_checkpoint(XID* xid) { trx_sysf_t* sys_header; mtr_t mtr; @@ -324,7 +297,7 @@ trx_sys_read_wsrep_checkpoint( memcpy(xid->data + 24, &seqno, sizeof(long long)); xid->formatID = -1; mtr_commit(&mtr); - return; + return false; } xid->formatID = (int)mach_read_from_4( @@ -341,6 +314,7 @@ trx_sys_read_wsrep_checkpoint( XIDDATASIZE); mtr_commit(&mtr); + return true; } #endif /* WITH_WSREP */ diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 7fdbd808a60..d397a2d2880 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -548,6 +548,10 @@ static void trx_validate_state_before_free(trx_t* trx) { + ut_ad(!trx->declared_to_be_inside_innodb); + ut_ad(!trx->n_mysql_tables_in_use); + ut_ad(!trx->mysql_n_tables_locked); + if (trx->declared_to_be_inside_innodb) { ib::error() << "Freeing a trx (" << trx << ", " @@ -558,7 +562,7 @@ trx_validate_state_before_free(trx_t* trx) putc('\n', stderr); /* This is an error but not a fatal error. We must keep - the counters like srv_conc_n_threads accurate. */ + the counters like srv_conc.n_active accurate. */ srv_conc_force_exit_innodb(trx); } @@ -1492,7 +1496,6 @@ trx_write_serialisation_history( trx_sys_update_mysql_binlog_offset( trx->mysql_log_file_name, trx->mysql_log_offset, - TRX_SYS_MYSQL_LOG_INFO, sys_header, mtr); |