summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/btr/btr0cur.cc11
-rw-r--r--storage/innobase/fil/fil0fil.cc16
-rw-r--r--storage/innobase/handler/ha_innodb.cc14
-rw-r--r--storage/innobase/include/mtr0types.h14
-rw-r--r--storage/innobase/include/page0page.ic2
-rw-r--r--storage/innobase/include/trx0rec.h24
-rw-r--r--storage/innobase/include/trx0sys.ic2
-rw-r--r--storage/innobase/include/trx0undo.h28
-rw-r--r--storage/innobase/log/log0recv.cc104
-rw-r--r--storage/innobase/rem/rem0rec.cc38
-rw-r--r--storage/innobase/row/row0log.cc33
-rw-r--r--storage/innobase/row/row0purge.cc8
-rw-r--r--storage/innobase/row/row0row.cc6
-rw-r--r--storage/innobase/row/row0sel.cc10
-rw-r--r--storage/innobase/row/row0upd.cc12
-rw-r--r--storage/innobase/srv/srv0start.cc11
-rw-r--r--storage/innobase/trx/trx0rec.cc152
-rw-r--r--storage/innobase/trx/trx0roll.cc7
-rw-r--r--storage/innobase/trx/trx0sys.cc2
-rw-r--r--storage/innobase/trx/trx0trx.cc9
-rw-r--r--storage/innobase/trx/trx0undo.cc84
-rw-r--r--storage/maria/ma_open.c2
-rw-r--r--storage/maria/ma_search.c14
-rw-r--r--storage/myisam/ha_myisam.cc47
-rw-r--r--storage/myisam/mi_search.c14
-rw-r--r--storage/rocksdb/CMakeLists.txt15
-rw-r--r--storage/rocksdb/build_rocksdb.cmake1
-rw-r--r--storage/rocksdb/ha_rocksdb.cc8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/disabled.def11
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/my.cnf1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_binlog_xid_count.result204
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/singledelete_idempotent_table.result10
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def30
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test20
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf10
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_git_hash_basic.test6
-rw-r--r--storage/rocksdb/rdb_datadic.cc3
-rw-r--r--storage/rocksdb/rdb_source_revision.h.in1
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result2
46 files changed, 725 insertions, 275 deletions
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index e3ac8fb7605..fc13537d364 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -3713,7 +3713,15 @@ btr_cur_parse_update_in_place(
/* We do not need to reserve search latch, as the page is only
being recovered, and there cannot be a hash index to it. */
- offsets = rec_get_offsets(rec, index, NULL, true,
+ /* The function rtr_update_mbr_field_in_place() is generating
+ these records on node pointer pages; therefore we have to
+ check if this is a leaf page. */
+
+ offsets = rec_get_offsets(rec, index, NULL,
+ flags != (BTR_NO_UNDO_LOG_FLAG
+ | BTR_NO_LOCKING_FLAG
+ | BTR_KEEP_SYS_FLAG)
+ || page_is_leaf(page),
ULINT_UNDEFINED, &heap);
if (!(flags & BTR_KEEP_SYS_FLAG)) {
@@ -3849,6 +3857,7 @@ btr_cur_update_in_place(
roll_ptr_t roll_ptr = 0;
ulint was_delete_marked;
+ ut_ad(page_is_leaf(cursor->page_cur.block->frame));
rec = btr_cur_get_rec(cursor);
index = cursor->index;
ut_ad(rec_offs_validate(rec, index, offsets));
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 8c86e272853..dd02295eb42 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -188,19 +188,19 @@ bool
fil_validate_skip(void)
/*===================*/
{
- /** The fil_validate() call skip counter. Use a signed type
- because of the race condition below. */
+ /** The fil_validate() call skip counter. */
static int fil_validate_count = FIL_VALIDATE_SKIP;
- /* There is a race condition below, but it does not matter,
- because this call is only for heuristic purposes. We want to
- reduce the call frequency of the costly fil_validate() check
- in debug builds. */
- if (--fil_validate_count > 0) {
+ /* We want to reduce the call frequency of the costly fil_validate()
+ check in debug builds. */
+ int count = my_atomic_add32_explicit(&fil_validate_count, -1,
+ MY_MEMORY_ORDER_RELAXED);
+ if (count > 0) {
return(true);
}
- fil_validate_count = FIL_VALIDATE_SKIP;
+ my_atomic_store32_explicit(&fil_validate_count, FIL_VALIDATE_SKIP,
+ MY_MEMORY_ORDER_RELAXED);
return(fil_validate());
}
#endif /* UNIV_DEBUG */
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 04812fa7adc..e8b1ea7350e 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -14837,7 +14837,7 @@ ha_innobase::defragment_table(
"Table %s is encrypted but encryption service or"
" used key_id is not available. "
" Can't continue checking table.",
- index->table->name);
+ index->table->name.m_name);
ret = convert_error_code_to_mysql(err, 0, current_thd);
break;
@@ -15057,7 +15057,7 @@ ha_innobase::check(
"Table %s is encrypted but encryption service or"
" used key_id is not available. "
" Can't continue checking table.",
- index->table->name);
+ index->table->name.m_name);
} else {
push_warning_printf(
thd,
@@ -22377,7 +22377,7 @@ ib_push_frm_error(
"InnoDB: Table %s has a "
"primary key in InnoDB data "
"dictionary, but not in "
- "MariaDB!", ib_table->name);
+ "MariaDB!", ib_table->name.m_name);
}
break;
case DICT_NO_PK_FRM_HAS:
@@ -22390,7 +22390,7 @@ ib_push_frm_error(
"columns, then MariaDB internally treats that "
"key as the primary key. You can fix this "
"error by dump + DROP + CREATE + reimport "
- "of the table.", ib_table->name);
+ "of the table.", ib_table->name.m_name);
if (push_warning) {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
@@ -22399,7 +22399,7 @@ ib_push_frm_error(
"primary key in InnoDB data "
"dictionary, but has one in "
"MariaDB!",
- ib_table->name);
+ ib_table->name.m_name);
}
break;
@@ -22423,7 +22423,7 @@ ib_push_frm_error(
"indexes inside InnoDB, which "
"is different from the number of "
"indexes %u defined in the MariaDB ",
- ib_table->name, n_keys,
+ ib_table->name.m_name, n_keys,
table->s->keys);
}
break;
@@ -22433,7 +22433,7 @@ ib_push_frm_error(
sql_print_error("InnoDB: Table %s is consistent "
"on InnoDB data dictionary and MariaDB "
" FRM file.",
- ib_table->name);
+ ib_table->name.m_name);
ut_error;
break;
}
diff --git a/storage/innobase/include/mtr0types.h b/storage/innobase/include/mtr0types.h
index 9b0e19d100f..94d904e8efd 100644
--- a/storage/innobase/include/mtr0types.h
+++ b/storage/innobase/include/mtr0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -100,6 +100,18 @@ enum mlog_id_t {
/** Create an index page */
MLOG_PAGE_CREATE = 19,
+ /** insert an undo log record (used in MariaDB 10.2) */
+ MLOG_UNDO_INSERT = 20,
+
+ /** erase an undo log page end (used in MariaDB 10.2) */
+ MLOG_UNDO_ERASE_END = 21,
+
+ /** initialize a page in an undo log (used in MariaDB 10.2) */
+ MLOG_UNDO_INIT = 22,
+
+ /** reuse an insert undo log header (used in MariaDB 10.2) */
+ MLOG_UNDO_HDR_REUSE = 24,
+
/** create an undo log header */
MLOG_UNDO_HDR_CREATE = 25,
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index ee908896050..e23b223ed1e 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -1116,7 +1116,7 @@ page_get_instant(const page_t* page)
ut_ad(i <= PAGE_NO_DIRECTION || !page_is_comp(page));
break;
case FIL_PAGE_RTREE:
- ut_ad(i == PAGE_NO_DIRECTION || i == 0);
+ ut_ad(i <= PAGE_NO_DIRECTION);
break;
default:
ut_ad(!"invalid page type");
diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h
index 8d5f271dd9b..955a726eb50 100644
--- a/storage/innobase/include/trx0rec.h
+++ b/storage/innobase/include/trx0rec.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -155,6 +155,7 @@ trx_undo_rec_get_partial_row(
used, as we do NOT copy the data in the
record! */
dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: updated columns */
dtuple_t** row, /*!< out, own: partial row */
ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
@@ -195,8 +196,8 @@ trx_undo_report_row_operation(
marking, the record in the clustered
index; NULL if insert */
const ulint* offsets, /*!< in: rec_get_offsets(rec) */
- roll_ptr_t* roll_ptr) /*!< out: rollback pointer to the
- inserted undo log record */
+ roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the
+ undo log record */
MY_ATTRIBUTE((nonnull(1,2,8), warn_unused_result));
/** status bit used for trx_undo_prev_version_build() */
@@ -243,6 +244,23 @@ trx_undo_prev_version_build(
into this function by purge thread or not.
And if we read "after image" of undo log */
+/** Parse MLOG_UNDO_INSERT for crash-upgrade from MariaDB 10.2.
+@param[in] ptr log record
+@param[in] end_ptr end of log record buffer
+@param[in,out] page page or NULL
+@return end of log record
+@retval NULL if the log record is incomplete */
+byte*
+trx_undo_parse_add_undo_rec(
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* page);
+/** Erase the unused undo log page end.
+@param[in,out] undo_page undo log page
+@return whether the page contained something */
+bool
+trx_undo_erase_page_end(page_t* undo_page);
+
/** Read from an undo log record a non-virtual column value.
@param[in,out] ptr pointer to remaining part of the undo record
@param[in,out] field stored field
diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic
index 5271601b4ea..020a46fb028 100644
--- a/storage/innobase/include/trx0sys.ic
+++ b/storage/innobase/include/trx0sys.ic
@@ -376,10 +376,8 @@ trx_id_t
trx_sys_get_new_trx_id()
/*====================*/
{
-#ifndef WITH_WSREP
/* wsrep_fake_trx_id violates this assert */
ut_ad(trx_sys_mutex_own());
-#endif /* WITH_WSREP */
/* VERY important: after the database is started, max_trx_id value is
divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the following if
diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h
index b51484a61cb..cd7cdca28ca 100644
--- a/storage/innobase/include/trx0undo.h
+++ b/storage/innobase/include/trx0undo.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -315,6 +315,32 @@ bool
trx_undo_truncate_tablespace(
undo::Truncate* undo_trunc);
+/** Parse MLOG_UNDO_INIT for crash-upgrade from MariaDB 10.2.
+@param[in] ptr log record
+@param[in] end_ptr end of log record buffer
+@param[in,out] page page or NULL
+@param[in,out] mtr mini-transaction
+@return end of log record
+@retval NULL if the log record is incomplete */
+byte*
+trx_undo_parse_page_init(
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* page,
+ mtr_t* mtr);
+/** Parse MLOG_UNDO_HDR_REUSE for crash-upgrade from MariaDB 10.2.
+@param[in] ptr redo log record
+@param[in] end_ptr end of log buffer
+@param[in,out] page undo page or NULL
+@param[in,out] mtr mini-transaction
+@return end of log record or NULL */
+byte*
+trx_undo_parse_page_header_reuse(
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* page,
+ mtr_t* mtr);
+
/** Parse the redo log entry of an undo log page header create.
@param[in] ptr redo log record
@param[in] end_ptr end of log buffer
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index a4db6d078df..92373afbeff 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -902,58 +902,6 @@ recv_log_format_0_recover(lsn_t lsn)
return(DB_SUCCESS);
}
-/** Determine if a redo log from MySQL 5.7.9/MariaDB 10.2.2 is clean.
-@return error code
-@retval DB_SUCCESS if the redo log is clean
-@retval DB_CORRUPTION if the redo log is corrupted
-@retval DB_ERROR if the redo log is not empty */
-static
-dberr_t
-recv_log_recover_10_2()
-{
- log_group_t* group = &log_sys->log;
- const lsn_t lsn = group->lsn;
- const lsn_t source_offset = log_group_calc_lsn_offset(lsn, group);
- const ulint page_no
- = (ulint) (source_offset / univ_page_size.physical());
- byte* buf = log_sys->buf;
-
- fil_io(IORequestLogRead, true,
- page_id_t(SRV_LOG_SPACE_FIRST_ID, page_no),
- univ_page_size,
- (ulint) ((source_offset & ~(OS_FILE_LOG_BLOCK_SIZE - 1))
- % univ_page_size.physical()),
- OS_FILE_LOG_BLOCK_SIZE, buf, NULL);
-
- if (log_block_calc_checksum(buf) != log_block_get_checksum(buf)) {
- return(DB_CORRUPTION);
- }
-
- if (group->is_encrypted()) {
- log_crypt(buf, lsn, OS_FILE_LOG_BLOCK_SIZE, true);
- }
-
- /* On a clean shutdown, the redo log will be logically empty
- after the checkpoint lsn. */
-
- if (log_block_get_data_len(buf)
- != (source_offset & (OS_FILE_LOG_BLOCK_SIZE - 1))) {
- return(DB_ERROR);
- }
-
- /* Mark the redo log for upgrading. */
- srv_log_file_size = 0;
- recv_sys->parse_start_lsn = recv_sys->recovered_lsn
- = recv_sys->scanned_lsn
- = recv_sys->mlog_checkpoint_lsn = lsn;
- log_sys->last_checkpoint_lsn = log_sys->next_checkpoint_lsn
- = log_sys->lsn = log_sys->write_lsn
- = log_sys->current_flush_lsn = log_sys->flushed_to_disk_lsn
- = lsn;
- log_sys->next_checkpoint_no = 0;
- return(DB_SUCCESS);
-}
-
/** Find the latest checkpoint in the log header.
@param[out] max_field LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2
@return error code or DB_SUCCESS */
@@ -1063,20 +1011,6 @@ recv_find_max_checkpoint(ulint* max_field)
return(DB_ERROR);
}
- switch (group->format) {
- case LOG_HEADER_FORMAT_10_2:
- case LOG_HEADER_FORMAT_10_2 | LOG_HEADER_FORMAT_ENCRYPTED:
- dberr_t err = recv_log_recover_10_2();
- if (err != DB_SUCCESS) {
- ib::error()
- << "Upgrade after a crash is not supported."
- " The redo log was created with " << creator
- << (err == DB_ERROR
- ? "." : ", and it appears corrupted.");
- }
- return(err);
- }
-
return(DB_SUCCESS);
}
@@ -1394,6 +1328,25 @@ parse_log:
page_parse_create(block, type == MLOG_COMP_PAGE_CREATE_RTREE,
true);
break;
+ case MLOG_UNDO_INSERT:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
+ ptr = trx_undo_parse_add_undo_rec(ptr, end_ptr, page);
+ break;
+ case MLOG_UNDO_ERASE_END:
+ if (page) {
+ ut_ad(page_type == FIL_PAGE_UNDO_LOG);
+ trx_undo_erase_page_end(page);
+ }
+ break;
+ case MLOG_UNDO_INIT:
+ /* Allow anything in page_type when creating a page. */
+ ptr = trx_undo_parse_page_init(ptr, end_ptr, page, mtr);
+ break;
+ case MLOG_UNDO_HDR_REUSE:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
+ ptr = trx_undo_parse_page_header_reuse(ptr, end_ptr, page,
+ mtr);
+ break;
case MLOG_UNDO_HDR_CREATE:
ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
ptr = trx_undo_parse_page_header(ptr, end_ptr, page, mtr);
@@ -3176,10 +3129,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
err = recv_find_max_checkpoint(&max_cp_field);
- if (err != DB_SUCCESS
- || (log_sys->log.format != LOG_HEADER_FORMAT_3_23
- && (log_sys->log.format & ~LOG_HEADER_FORMAT_ENCRYPTED)
- != LOG_HEADER_FORMAT_CURRENT)) {
+ if (err != DB_SUCCESS) {
srv_start_lsn = recv_sys->recovered_lsn = log_sys->lsn;
log_mutex_exit();
@@ -3620,6 +3570,18 @@ get_mlog_string(mlog_id_t type)
case MLOG_PAGE_CREATE:
return("MLOG_PAGE_CREATE");
+ case MLOG_UNDO_INSERT:
+ return("MLOG_UNDO_INSERT");
+
+ case MLOG_UNDO_ERASE_END:
+ return("MLOG_UNDO_ERASE_END");
+
+ case MLOG_UNDO_INIT:
+ return("MLOG_UNDO_INIT");
+
+ case MLOG_UNDO_HDR_REUSE:
+ return("MLOG_UNDO_HDR_REUSE");
+
case MLOG_UNDO_HDR_CREATE:
return("MLOG_UNDO_HDR_CREATE");
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index 8fb24855e97..38359e17b8f 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -344,9 +344,6 @@ ordinary:
/* We would have !index->is_instant() when rolling back
an instant ADD COLUMN operation. */
nulls -= REC_N_NEW_EXTRA_BYTES;
- if (rec_offs_n_fields(offsets) <= n_fields) {
- goto ordinary;
- }
/* fall through */
case REC_LEAF_TEMP_COLUMNS_ADDED:
ut_ad(index->is_instant());
@@ -1851,6 +1848,7 @@ rec_copy_prefix_to_buf(
ulint null_mask;
bool is_rtr_node_ptr = false;
+ ut_ad(n_fields <= index->n_fields || dict_index_is_ibuf(index));
ut_ad(index->n_core_null_bytes <= UT_BITS_IN_BYTES(index->n_nullable));
UNIV_PREFETCH_RW(*buf);
@@ -1863,21 +1861,11 @@ rec_copy_prefix_to_buf(
}
switch (rec_get_status(rec)) {
- case REC_STATUS_COLUMNS_ADDED:
- /* We would have !index->is_instant() when rolling back
- an instant ADD COLUMN operation. */
- ut_ad(index->is_instant() || page_rec_is_default_row(rec));
- if (n_fields >= index->n_core_fields) {
- ut_ad(index->is_instant());
- ut_ad(n_fields <= index->n_fields);
- nulls = &rec[-REC_N_NEW_EXTRA_BYTES];
- const ulint n_rec = n_fields + 1
- + rec_get_n_add_field(nulls);
- const uint n_nullable = index->get_n_nullable(n_rec);
- lens = --nulls - UT_BITS_IN_BYTES(n_nullable);
- break;
- }
- /* fall through */
+ case REC_STATUS_INFIMUM:
+ case REC_STATUS_SUPREMUM:
+ /* infimum or supremum record: no sense to copy anything */
+ ut_error;
+ return(NULL);
case REC_STATUS_ORDINARY:
ut_ad(n_fields <= index->n_core_fields);
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
@@ -1897,11 +1885,15 @@ rec_copy_prefix_to_buf(
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
lens = nulls - index->n_core_null_bytes;
break;
- case REC_STATUS_INFIMUM:
- case REC_STATUS_SUPREMUM:
- /* infimum or supremum record: no sense to copy anything */
- ut_error;
- return(NULL);
+ case REC_STATUS_COLUMNS_ADDED:
+ /* We would have !index->is_instant() when rolling back
+ an instant ADD COLUMN operation. */
+ ut_ad(index->is_instant() || page_rec_is_default_row(rec));
+ nulls = &rec[-REC_N_NEW_EXTRA_BYTES];
+ const ulint n_rec = index->n_core_fields + 1
+ + rec_get_n_add_field(nulls);
+ const uint n_nullable = index->get_n_nullable(n_rec);
+ lens = --nulls - UT_BITS_IN_BYTES(n_nullable);
}
UNIV_PREFETCH_R(lens);
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index cb902776e26..9b5c9873604 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -1695,13 +1695,10 @@ row_log_table_apply_insert_low(
return(error);
}
- do {
- n_index++;
-
- if (!(index = dict_table_get_next_index(index))) {
- break;
- }
+ ut_ad(dict_index_is_clust(index));
+ for (n_index += index->type != DICT_CLUSTERED;
+ (index = dict_table_get_next_index(index)); n_index++) {
if (index->type & DICT_FTS) {
continue;
}
@@ -1712,12 +1709,13 @@ row_log_table_apply_insert_low(
index, offsets_heap, heap, entry,
thr_get_trx(thr)->id, thr, false);
- /* Report correct index name for duplicate key error. */
- if (error == DB_DUPLICATE_KEY) {
- thr_get_trx(thr)->error_key_num = n_index;
+ if (error != DB_SUCCESS) {
+ if (error == DB_DUPLICATE_KEY) {
+ thr_get_trx(thr)->error_key_num = n_index;
+ }
+ break;
}
-
- } while (error == DB_SUCCESS);
+ }
return(error);
}
@@ -2297,17 +2295,16 @@ func_exit_committed:
dtuple_big_rec_free(big_rec);
}
- while ((index = dict_table_get_next_index(index)) != NULL) {
- if (error != DB_SUCCESS) {
- break;
- }
-
- n_index++;
-
+ for (n_index += index->type != DICT_CLUSTERED;
+ (index = dict_table_get_next_index(index)); n_index++) {
if (index->type & DICT_FTS) {
continue;
}
+ if (error != DB_SUCCESS) {
+ break;
+ }
+
if (!row_upd_changes_ord_field_binary(
index, update, thr, old_row, NULL)) {
continue;
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 62085e4d2af..46c6dda4ec8 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -705,6 +705,10 @@ row_purge_reset_trx_id(purge_node_t* node, mtr_t* mtr)
== row_get_rec_roll_ptr(rec, index, offsets)) {
ut_ad(!rec_get_deleted_flag(rec,
rec_offs_comp(offsets)));
+ DBUG_LOG("purge", "reset DB_TRX_ID="
+ << ib::hex(row_get_rec_trx_id(
+ rec, index, offsets)));
+
mtr->set_named_space(index->space);
if (page_zip_des_t* page_zip
= buf_block_get_page_zip(
@@ -1004,7 +1008,7 @@ err_exit:
if (!(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
ptr = trx_undo_rec_get_partial_row(
- ptr, clust_index, &node->row,
+ ptr, clust_index, node->update, &node->row,
type == TRX_UNDO_UPD_DEL_REC,
node->heap);
}
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index 93b84bdb209..3611b8c3fc7 100644
--- a/storage/innobase/row/row0row.cc
+++ b/storage/innobase/row/row0row.cc
@@ -195,13 +195,13 @@ row_build_index_entry_low(
dfield2);
break;
+ case SPATIAL_UNKNOWN:
+ ut_ad(0);
+ /* fall through */
case SPATIAL_NONE:
/* Undo record is logged before
spatial index is created.*/
return(NULL);
-
- case SPATIAL_UNKNOWN:
- ut_ad(0);
}
memcpy(mbr, ptr, DATA_MBR_LEN);
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index e43a0fb76f0..78e5bbcd15b 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -3414,8 +3414,14 @@ row_sel_get_clust_rec_for_mysql(
goto func_exit;
}
- buf_block_t* block = btr_pcur_get_block(
- prebuilt->pcur);
+ /* FIXME: Why is this block not the
+ same as btr_pcur_get_block(prebuilt->pcur),
+ and is it not unsafe to use RW_NO_LATCH here? */
+ buf_block_t* block = buf_page_get_gen(
+ btr_pcur_get_block(prebuilt->pcur)->page.id,
+ dict_table_page_size(sec_index->table),
+ RW_NO_LATCH, NULL, BUF_GET,
+ __FILE__, __LINE__, mtr, &err);
mem_heap_t* heap = mem_heap_create(256);
dtuple_t* tuple = dict_index_build_data_tuple(
rec, sec_index, true,
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index a3e8e8a5a3c..4c2fd94c1cd 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -714,9 +714,19 @@ row_upd_rec_in_place(
case REC_STATUS_COLUMNS_ADDED:
ut_ad(index->is_instant());
break;
+ case REC_STATUS_NODE_PTR:
+ if (recv_recovery_is_on()
+ && fil_page_get_type(page_align(rec))
+ == FIL_PAGE_RTREE) {
+ /* The function rtr_update_mbr_field_in_place()
+ is generating MLOG_COMP_REC_UPDATE_IN_PLACE
+ and MLOG_REC_UPDATE_IN_PLACE records for
+ node pointer pages. */
+ break;
+ }
+ /* fall through */
case REC_STATUS_INFIMUM:
case REC_STATUS_SUPREMUM:
- case REC_STATUS_NODE_PTR:
ut_ad(!"wrong record status in update");
}
#endif /* UNIV_DEBUG */
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 9135f2e19f7..4f508c149e9 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1405,7 +1405,10 @@ srv_prepare_to_delete_redo_log_files(
{
ib::info info;
- if (srv_log_file_size == 0) {
+ if (srv_log_file_size == 0
+ || (log_sys->log.format
+ & ~LOG_HEADER_FORMAT_ENCRYPTED)
+ != LOG_HEADER_FORMAT_CURRENT) {
info << "Upgrading redo log: ";
} else if (n_files != srv_n_log_files
|| srv_log_file_size
@@ -2350,7 +2353,11 @@ files_checked:
/* Leave the redo log alone. */
} else if (srv_log_file_size_requested == srv_log_file_size
&& srv_n_log_files_found == srv_n_log_files
- && log_sys->is_encrypted() == srv_encrypt_log) {
+ && log_sys->log.format
+ == (srv_encrypt_log
+ ? LOG_HEADER_FORMAT_CURRENT
+ | LOG_HEADER_FORMAT_ENCRYPTED
+ : LOG_HEADER_FORMAT_CURRENT)) {
/* No need to upgrade or resize the redo log. */
} else {
/* Prepare to delete the old redo log files */
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index 170a79e4d0c..a7fcca97a98 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -76,6 +76,49 @@ trx_undof_page_add_undo_rec_log(
mlog_log_string(undo_page + old_free, new_free - old_free, mtr);
}
+/** Parse MLOG_UNDO_INSERT for crash-upgrade from MariaDB 10.2.
+@param[in] ptr log record
+@param[in] end_ptr end of log record buffer
+@param[in,out] page page or NULL
+@return end of log record
+@retval NULL if the log record is incomplete */
+byte*
+trx_undo_parse_add_undo_rec(
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* page)
+{
+ ulint len;
+
+ if (end_ptr < ptr + 2) {
+
+ return(NULL);
+ }
+
+ len = mach_read_from_2(ptr);
+ ptr += 2;
+
+ if (end_ptr < ptr + len) {
+
+ return(NULL);
+ }
+
+ if (page) {
+ ulint first_free = mach_read_from_2(page + TRX_UNDO_PAGE_HDR
+ + TRX_UNDO_PAGE_FREE);
+ byte* rec = page + first_free;
+
+ mach_write_to_2(rec, first_free + 4 + len);
+ mach_write_to_2(rec + 2 + len, first_free);
+
+ mach_write_to_2(page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE,
+ first_free + 4 + len);
+ memcpy(rec + 2, ptr, len);
+ }
+
+ return(const_cast<byte*>(ptr + len));
+}
+
/**********************************************************************//**
Calculates the free space left for extending an undo log record.
@return bytes left */
@@ -1148,14 +1191,43 @@ trx_undo_page_report_modify(
const dict_col_t* col
= dict_table_get_nth_col(table, col_no);
- const char* col_name = dict_table_get_col_name(table,
- col_no);
if (!col->ord_part) {
continue;
}
- if (update) {
+ const ulint pos = dict_index_get_nth_col_pos(
+ index, col_no, NULL);
+ /* All non-virtual columns must be present in
+ the clustered index. */
+ ut_ad(pos != ULINT_UNDEFINED);
+
+ const bool is_ext = rec_offs_nth_extern(offsets, pos);
+ const spatial_status_t spatial_status = is_ext
+ ? dict_col_get_spatial_status(col)
+ : SPATIAL_NONE;
+
+ switch (spatial_status) {
+ case SPATIAL_UNKNOWN:
+ ut_ad(0);
+ /* fall through */
+ case SPATIAL_MIXED:
+ case SPATIAL_ONLY:
+ /* Externally stored spatially indexed
+ columns will be (redundantly) logged
+ again, because we did not write the
+ MBR yet, that is, the previous call to
+ trx_undo_page_report_modify_ext()
+ was with SPATIAL_UNKNOWN. */
+ break;
+ case SPATIAL_NONE:
+ if (!update) {
+ /* This is a DELETE operation. */
+ break;
+ }
+ /* Avoid redundantly logging indexed
+ columns that were updated. */
+
for (i = 0; i < update->n_fields; i++) {
const ulint field_no
= upd_get_nth_field(update, i)
@@ -1170,37 +1242,19 @@ trx_undo_page_report_modify(
}
if (true) {
- ulint pos;
- spatial_status_t spatial_status;
-
- spatial_status = SPATIAL_NONE;
-
/* Write field number to undo log */
if (trx_undo_left(undo_page, ptr) < 5 + 15) {
return(0);
}
- pos = dict_index_get_nth_col_pos(index,
- col_no,
- NULL);
- if (pos == ULINT_UNDEFINED) {
- ib::error() << "Column " << col_no
- << " name " << col_name
- << " not found from index " << index->name
- << " table. " << table->name.m_name
- << " Table has " << dict_table_get_n_cols(table)
- << " and index has " << dict_index_get_n_fields(index)
- << " fields.";
- }
-
ptr += mach_write_compressed(ptr, pos);
/* Save the old value of field */
field = rec_get_nth_cfield(
rec, index, offsets, pos, &flen);
- if (rec_offs_nth_extern(offsets, pos)) {
+ if (is_ext) {
const dict_col_t* col =
dict_index_get_nth_col(
index, pos);
@@ -1210,10 +1264,6 @@ trx_undo_page_report_modify(
ut_a(prefix_len < sizeof ext_buf);
- spatial_status =
- dict_col_get_spatial_status(
- col);
-
/* If there is a spatial index on it,
log its MBR */
if (spatial_status != SPATIAL_NONE) {
@@ -1612,6 +1662,7 @@ trx_undo_rec_get_partial_row(
used, as we do NOT copy the data in the
record! */
dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: updated columns */
dtuple_t** row, /*!< out, own: partial row */
ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
@@ -1642,6 +1693,16 @@ trx_undo_rec_get_partial_row(
dtuple_init_v_fld(*row);
+ for (const upd_field_t* uf = update->fields, * const ue
+ = update->fields + update->n_fields;
+ uf != ue; uf++) {
+ if (uf->old_v_val) {
+ continue;
+ }
+ ulint c = dict_index_get_nth_col(index, uf->field_no)->ind;
+ *dtuple_get_nth_field(*row, c) = uf->new_val;
+ }
+
end_ptr = ptr + mach_read_from_2(ptr);
ptr += 2;
@@ -1687,6 +1748,13 @@ trx_undo_rec_get_partial_row(
col = dict_index_get_nth_col(index, field_no);
col_no = dict_col_get_no(col);
dfield = dtuple_get_nth_field(*row, col_no);
+ ut_ad(dfield->type.mtype == DATA_MISSING
+ || dict_col_type_assert_equal(col,
+ &dfield->type));
+ ut_ad(dfield->type.mtype == DATA_MISSING
+ || dfield->len == len
+ || (len != UNIV_SQL_NULL
+ && len >= UNIV_EXTERN_STORAGE_FIELD));
dict_col_copy_type(
dict_table_get_nth_col(index->table, col_no),
dfield_get_type(dfield));
@@ -1758,15 +1826,11 @@ trx_undo_rec_get_partial_row(
return(const_cast<byte*>(ptr));
}
-/***********************************************************************//**
-Erases the unused undo log page end.
-@return TRUE if the page contained something, FALSE if it was empty */
-static MY_ATTRIBUTE((nonnull))
-ibool
-trx_undo_erase_page_end(
-/*====================*/
- page_t* undo_page, /*!< in/out: undo page whose end to erase */
- mtr_t* mtr) /*!< in/out: mini-transaction */
+/** Erase the unused undo log page end.
+@param[in,out] undo_page undo log page
+@return whether the page contained something */
+bool
+trx_undo_erase_page_end(page_t* undo_page)
{
ulint first_free;
@@ -1790,8 +1854,9 @@ ulint
trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
buf_block_t* block, mtr_t* mtr)
{
- ulint first_free = mach_read_from_2(block->frame + TRX_UNDO_PAGE_HDR
- + TRX_UNDO_PAGE_FREE);
+ byte* ptr_first_free = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
+ + block->frame;
+ ulint first_free = mach_read_from_2(ptr_first_free);
ut_ad(first_free >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
ut_ad(first_free <= UNIV_PAGE_SIZE);
byte* start = block->frame + first_free;
@@ -1819,11 +1884,10 @@ trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
ptr += 2;
ulint offset = page_offset(ptr);
mach_write_to_2(start, offset);
- mach_write_to_2(block->frame + TRX_UNDO_PAGE_HDR
- + TRX_UNDO_PAGE_FREE, offset);
+ mach_write_to_2(ptr_first_free, offset);
trx_undof_page_add_undo_rec_log(block->frame, first_free, offset, mtr);
- return offset;
+ return first_free;
}
/** Report a RENAME TABLE operation.
@@ -1917,8 +1981,8 @@ trx_undo_report_row_operation(
marking, the record in the clustered
index; NULL if insert */
const ulint* offsets, /*!< in: rec_get_offsets(rec) */
- roll_ptr_t* roll_ptr) /*!< out: rollback pointer to the
- inserted undo log record */
+ roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the
+ undo log record */
{
trx_t* trx;
ulint page_no;
@@ -1993,7 +2057,7 @@ trx_undo_report_row_operation(
version the replicate page constructed using the log
records stays identical to the original page */
- if (!trx_undo_erase_page_end(undo_page, &mtr)) {
+ if (!trx_undo_erase_page_end(undo_page)) {
/* The record did not fit on an empty
undo page. Discard the freshly allocated
page and return an error. */
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index a95891d8cd4..be4e4c3294a 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -820,7 +820,8 @@ trx_roll_must_shutdown()
mutex_enter(&recv_sys->mutex);
if (recv_sys->report(time)) {
- ulint n_trx = 0, n_rows = 0;
+ ulint n_trx = 0;
+ ulonglong n_rows = 0;
for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
t != NULL;
t = UT_LIST_GET_NEXT(trx_list, t)) {
@@ -835,7 +836,7 @@ trx_roll_must_shutdown()
ib::info() << "To roll back: " << n_trx << " transactions, "
<< n_rows << " rows";
sd_notifyf(0, "STATUS=To roll back: " ULINTPF " transactions, "
- ULINTPF " rows", n_trx, n_rows);
+ "%llu rows", n_trx, n_rows);
}
mutex_exit(&recv_sys->mutex);
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index a332f6047d1..c2e15fea953 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -98,12 +98,10 @@ trx_sys_flush_max_trx_id(void)
mtr_t mtr;
trx_sysf_t* sys_header;
-#ifndef WITH_WSREP
/* wsrep_fake_trx_id violates this assert
Copied from trx_sys_get_new_trx_id
*/
ut_ad(trx_sys_mutex_own());
-#endif /* WITH_WSREP */
if (!srv_read_only_mode) {
mtr_start(&mtr);
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index cd2a60bcc87..882fd6f90a4 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1739,12 +1739,7 @@ trx_commit_in_memory(
trx->state = TRX_STATE_NOT_STARTED;
} else {
- const bool rw = trx->rsegs.m_redo.rseg != NULL;
-
- ut_ad(!trx->read_only || !rw);
- ut_ad(trx->id || !rw);
-
- if (rw) {
+ if (trx->id > 0) {
/* For consistent snapshot, we need to remove current
transaction from running transaction id list for mvcc
before doing commit and releasing locks. */
@@ -1759,7 +1754,7 @@ trx_commit_in_memory(
ut_ad(trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY));
DEBUG_SYNC_C("after_trx_committed_in_memory");
- if (!rw) {
+ if (trx->read_only || trx->rsegs.m_redo.rseg == NULL) {
MONITOR_INC(MONITOR_TRX_RO_COMMIT);
if (trx->read_view != NULL) {
trx_sys->mvcc->view_close(
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index 1340d19aee8..49c1ab15fe8 100644
--- a/storage/innobase/trx/trx0undo.cc
+++ b/storage/innobase/trx/trx0undo.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2014, 2018, 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
@@ -309,6 +309,88 @@ trx_undo_get_first_rec(
/*============== UNDO LOG FILE COPY CREATION AND FREEING ==================*/
+/** Parse MLOG_UNDO_INIT for crash-upgrade from MariaDB 10.2.
+@param[in] ptr log record
+@param[in] end_ptr end of log record buffer
+@param[in,out] page page or NULL
+@param[in,out] mtr mini-transaction
+@return end of log record
+@retval NULL if the log record is incomplete */
+byte*
+trx_undo_parse_page_init(
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* page,
+ mtr_t* mtr)
+{
+ ulint type = mach_parse_compressed(&ptr, end_ptr);
+
+ if (!ptr) {
+ } else if (type != 1 && type != 2) {
+ recv_sys->found_corrupt_log = true;
+ } else if (page) {
+ mach_write_to_2(FIL_PAGE_TYPE + page, FIL_PAGE_UNDO_LOG);
+ mach_write_to_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + page,
+ type);
+ mach_write_to_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_START + page,
+ TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
+ mach_write_to_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE + page,
+ TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
+ }
+
+ return(const_cast<byte*>(ptr));
+}
+
+/** Parse MLOG_UNDO_HDR_REUSE for crash-upgrade from MariaDB 10.2.
+@param[in] ptr redo log record
+@param[in] end_ptr end of log buffer
+@param[in,out] page undo log page or NULL
+@param[in,out] mtr mini-transaction
+@return end of log record or NULL */
+byte*
+trx_undo_parse_page_header_reuse(
+ const byte* ptr,
+ const byte* end_ptr,
+ page_t* undo_page,
+ mtr_t* mtr)
+{
+ trx_id_t trx_id = mach_u64_parse_compressed(&ptr, end_ptr);
+
+ if (!ptr || !undo_page) {
+ return(const_cast<byte*>(ptr));
+ }
+
+ compile_time_assert(TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE
+ + TRX_UNDO_LOG_XA_HDR_SIZE
+ < UNIV_PAGE_SIZE_MIN - 100);
+
+ const ulint new_free = TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE
+ + TRX_UNDO_LOG_OLD_HDR_SIZE;
+
+ /* Insert undo data is not needed after commit: we may free all
+ the space on the page */
+
+ ut_ad(mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE
+ + undo_page)
+ == TRX_UNDO_INSERT);
+
+ byte* page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
+ mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START, new_free);
+ mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE, new_free);
+ mach_write_to_2(TRX_UNDO_SEG_HDR + TRX_UNDO_STATE + undo_page,
+ TRX_UNDO_ACTIVE);
+
+ byte* log_hdr = undo_page + TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE;
+
+ mach_write_to_8(log_hdr + TRX_UNDO_TRX_ID, trx_id);
+ mach_write_to_2(log_hdr + TRX_UNDO_LOG_START, new_free);
+
+ mach_write_to_1(log_hdr + TRX_UNDO_XID_EXISTS, FALSE);
+ mach_write_to_1(log_hdr + TRX_UNDO_DICT_TRANS, FALSE);
+
+ return(const_cast<byte*>(ptr));
+}
+
/********************************************************************//**
Initializes the fields in an undo log segment page. */
static
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 2092e024e28..3febf879ec6 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -280,7 +280,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
size_t info_length;
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
data_name[FN_REFLEN];
- uchar *disk_cache, *disk_pos, *end_pos;
+ uchar *UNINIT_VAR(disk_cache), *disk_pos, *end_pos;
MARIA_HA info, *UNINIT_VAR(m_info), *old_info;
MARIA_SHARE share_buff,*share;
double *rec_per_key_part;
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index 089e3fabdb2..39d9322d903 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -745,11 +745,11 @@ void _ma_kpointer(register MARIA_HA *info, register uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
@@ -881,13 +881,13 @@ void _ma_dpointer(MARIA_SHARE *share, uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 8: *buff++=0;
- /* fall trough */
+ /* fall through */
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 62c400b1c07..a52a306ce22 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -757,6 +757,7 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{
MI_KEYDEF *keyinfo;
MI_COLUMNDEF *recinfo= 0;
+ char readlink_buf[FN_REFLEN], name_buff[FN_REFLEN];
uint recs;
uint i;
@@ -812,6 +813,30 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
(void) mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0);
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
+
+ /*
+ Set data_file_name and index_file_name to point at the symlink value
+ if table is symlinked (Ie; Real name is not same as generated name)
+ */
+ fn_format(name_buff, file->filename, "", MI_NAME_DEXT,
+ MY_APPEND_EXT | MY_UNPACK_FILENAME);
+ if (my_is_symlink(name_buff))
+ {
+ my_readlink(readlink_buf, name_buff, MYF(0));
+ data_file_name= strdup_root(&table->mem_root, readlink_buf);
+ }
+ else
+ data_file_name= 0;
+ fn_format(name_buff, file->filename, "", MI_NAME_IEXT,
+ MY_APPEND_EXT | MY_UNPACK_FILENAME);
+ if (my_is_symlink(name_buff))
+ {
+ my_readlink(readlink_buf, name_buff, MYF(0));
+ index_file_name= strdup_root(&table->mem_root, readlink_buf);
+ }
+ else
+ index_file_name= 0;
+
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
(void) mi_extra(file, HA_EXTRA_WAIT_LOCK, 0);
if (!table->s->db_record_offset)
@@ -1953,7 +1978,6 @@ void ha_myisam::position(const uchar *record)
int ha_myisam::info(uint flag)
{
MI_ISAMINFO misam_info;
- char name_buff[FN_REFLEN];
if (!table)
return 1;
@@ -2001,27 +2025,6 @@ int ha_myisam::info(uint flag)
sizeof(table->key_info[0].rec_per_key[0])*share->key_parts);
if (table_share->tmp_table == NO_TMP_TABLE)
mysql_mutex_unlock(&table_share->LOCK_share);
-
- /*
- Set data_file_name and index_file_name to point at the symlink value
- if table is symlinked (Ie; Real name is not same as generated name)
- */
- char buf[FN_REFLEN];
- data_file_name= index_file_name= 0;
- fn_format(name_buff, file->filename, "", MI_NAME_DEXT,
- MY_APPEND_EXT | MY_UNPACK_FILENAME);
- if (my_is_symlink(name_buff))
- {
- my_readlink(buf, name_buff, MYF(0));
- data_file_name= ha_thd()->strdup(buf);
- }
- fn_format(name_buff, file->filename, "", MI_NAME_IEXT,
- MY_APPEND_EXT | MY_UNPACK_FILENAME);
- if (my_is_symlink(name_buff))
- {
- my_readlink(buf, name_buff, MYF(0));
- index_file_name= ha_thd()->strdup(buf);
- }
}
if (flag & HA_STATUS_ERRKEY)
{
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index 79ed846ce7e..d570f273b74 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -607,11 +607,11 @@ void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
@@ -728,13 +728,13 @@ void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 8: *buff++=0;
- /* fall trough */
+ /* fall through */
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index 1e20e0fa4a3..6cb7eb1d439 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -220,3 +220,18 @@ IF(MSVC)
# Some checks in C++ runtime that make debug build much slower
ADD_DEFINITIONS(-D_ITERATOR_DEBUG_LEVEL=0)
ENDIF()
+
+IF(GIT_EXECUTABLE)
+ EXECUTE_PROCESS(
+ COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb
+ OUTPUT_VARIABLE OUT RESULT_VARIABLE RES)
+ IF(RES EQUAL 0)
+ STRING(REGEX REPLACE "\n$" "" ROCKSDB_GIT_HASH "${OUT}")
+ ENDIF()
+ENDIF()
+IF(ROCKSDB_GIT_HASH OR
+ (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/rdb_source_revision.h))
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/rdb_source_revision.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/rdb_source_revision.h )
+ENDIF()
diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake
index dd23304a223..5810412f566 100644
--- a/storage/rocksdb/build_rocksdb.cmake
+++ b/storage/rocksdb/build_rocksdb.cmake
@@ -6,6 +6,7 @@ endif()
SET(ROCKSDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb)
INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_BINARY_DIR}
${ROCKSDB_SOURCE_DIR}
${ROCKSDB_SOURCE_DIR}/include
${ROCKSDB_SOURCE_DIR}/third-party/gtest-1.7.0/fused-src
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index d79f15c458b..479e290374e 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -70,6 +70,7 @@
#include "rocksdb/utilities/memory_util.h"
#include "rocksdb/utilities/sim_cache.h"
#include "util/stop_watch.h"
+#include "./rdb_source_revision.h"
/* MyRocks includes */
#include "./event_listener.h"
@@ -494,6 +495,7 @@ static uint32_t rocksdb_table_stats_sampling_pct;
static my_bool rocksdb_enable_bulk_load_api = 1;
static my_bool rocksdb_print_snapshot_conflict_queries = 0;
static my_bool rocksdb_large_prefix = 0;
+static char* rocksdb_git_hash;
char *compression_types_val=
const_cast<char*>(get_rocksdb_supported_compression_types());
@@ -650,6 +652,11 @@ static MYSQL_SYSVAR_BOOL(enable_bulk_load_api, rocksdb_enable_bulk_load_api,
"Enables using SstFileWriter for bulk loading",
nullptr, nullptr, rocksdb_enable_bulk_load_api);
+static MYSQL_SYSVAR_STR(git_hash, rocksdb_git_hash,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Git revision of the RocksDB library used by MyRocks",
+ nullptr, nullptr, ROCKSDB_GIT_HASH);
+
static MYSQL_THDVAR_STR(tmpdir, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_MEMALLOC,
"Directory for temporary files during DDL operations.",
nullptr, nullptr, "");
@@ -1633,6 +1640,7 @@ static struct st_mysql_sys_var *rocksdb_system_variables[] = {
MYSQL_SYSVAR(table_stats_sampling_pct),
MYSQL_SYSVAR(large_prefix),
+ MYSQL_SYSVAR(git_hash),
nullptr};
static rocksdb::WriteOptions
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
index d791cf98bb0..9b084e63cd5 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
@@ -924,6 +924,7 @@ rocksdb_force_compute_memtable_stats_cachetime 0
rocksdb_force_flush_memtable_and_lzero_now OFF
rocksdb_force_flush_memtable_now OFF
rocksdb_force_index_records_in_range 0
+rocksdb_git_hash #
rocksdb_hash_index_allow_collision ON
rocksdb_index_type kBinarySearch
rocksdb_info_log_level error_level
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
index 118d8598de3..63c3d259d4c 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
+++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
@@ -41,7 +41,7 @@ rocksdb_deadlock_stress_rr: stress test
##
persistent_cache: Upstream RocksDB bug https://github.com/facebook/mysql-5.6/issues/579
collation: Fails on gcc 4.8 and before, MDEV-12433
-col_opt_zerofill: MDEV-14165: not MyRocks -problem in ps-protocol, happens in upstream too
+col_opt_zerofill: MDEV-14729 (also MDEV-14165 which was fixed): problem in the client
##
@@ -70,17 +70,10 @@ blind_delete_without_tx_api: MDEV-12286: rocksdb.blind_delete_without_tx_api tes
unique_check: wrong error number
autoinc_vars_thread: debug sync point wait timed out
-# Enabling these didn't seem to cause any trouble:
-# autoinc_vars_thread : MDEV-12474 Regularly fails on buildbot
-# unique_check : MDEV-12474 Regularly fails on buildbot
-# bloomfilter : MDEV-12474 Regularly fails on buildbot
-# unique_sec : Intermittent failures in BB
-
-
##
## Tests that fail for some other reason
##
+
information_schema : MariaRocks: requires GTIDs
mysqlbinlog_gtid_skip_empty_trans_rocksdb : MariaRocks: requires GTIDs
-#read_only_tx : MariaRocks: requires GTIDs
rpl_row_triggers : MariaRocks: requires GTIDs
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
index 5c8fa9ed443..9199c572933 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
@@ -786,6 +786,8 @@ drop table t45;
--echo # Now it fails if there is data overlap with what
--echo # already exists
--echo #
+
+--replace_regex /[a-f0-9]{40}/#/
show variables
where
variable_name like 'rocksdb%' and
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/my.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/my.cnf
index 2beaf514cee..ec7370b65f0 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/my.cnf
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/my.cnf
@@ -1,3 +1,4 @@
+!include rpl_1slave_base.cnf
!include include/default_my.cnf
[server]
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_binlog_xid_count.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_binlog_xid_count.result
new file mode 100644
index 00000000000..9b46a5b5227
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_binlog_xid_count.result
@@ -0,0 +1,204 @@
+CREATE TABLE `t` (
+`a` text DEFAULT NULL
+) ENGINE=ROCKSDB;
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+INSERT INTO t SET a=repeat('a', 4096);
+INSERT INTO t SET a=repeat('a', 4096/2);
+DROP TABLE t;
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/singledelete_idempotent_table.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/singledelete_idempotent_table.result
index 609d4a8821a..979e2cbf6c3 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/r/singledelete_idempotent_table.result
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/singledelete_idempotent_table.result
@@ -1,16 +1,19 @@
include/master-slave.inc
-Warnings:
-Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
-Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
[connection master]
+connection master;
drop table if exists r1;
create table r1 (id1 int, id2 int, primary key (id1, id2), index i (id2)) engine=rocksdb;
insert into r1 values (1, 1000);
set sql_log_bin=0;
delete from r1 where id1=1 and id2=1000;
set sql_log_bin=1;
+connection slave;
+connection slave;
set global rocksdb_force_flush_memtable_now=1;
+connection master;
insert into r1 values (1, 1000);
+connection slave;
+connection slave;
delete r1 from r1 force index (i) where id2=1000;
select id1,id2 from r1 force index (primary);
id1 id2
@@ -21,5 +24,6 @@ select id1,id2 from r1 force index (primary);
id1 id2
select id2 from r1 force index (i);
id2
+connection master;
drop table r1;
include/rpl_end.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
index 07a2738eee5..956355dceee 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
@@ -1,19 +1,29 @@
+##
+## Tests that require FB/MySQL specific features for which there are
+## no plans to port them to MariaDB
+##
+rpl_no_unique_check_on_lag : unique_check_lag_threshold is not available in MariaDB
+rpl_no_unique_check_on_lag_mts : unique_check_lag_threshold is not available in MariaDB
+consistent_snapshot_mixed_engines : Tests START TRANSACTION WITH CONSISTENT $ENGINE_NAME SNAPSHOT
+rpl_skip_trx_api_binlog_format : requires @@rpl_skip_tx_api
+rpl_ddl_high_priority : DDL commands with HIGH_PRIORITY syntax are not in MariaDB
+rpl_gtid_rocksdb_sys_header : MariaDB doesn't support printing "RocksDB: Last MySQL Gtid UUID" into server stderr on startup
+singledelete_idempotent_recovery: MariaDB doesn't support --slave-use-idempotent-for-recovery
-# rpl_rocksdb_2pc_crash_recover
+##
+## Tests that do not fit MariaDB's test environment (Functional tests only,
+## can't have stress tests)
+##
+rpl_rocksdb_stress_crash : Stress test
+
+##
+## Tests that are disabled for other reasons
+##
-consistent_snapshot_mixed_engines : Didn't try with MariaDB, yet
multiclient_2pc : Didn't try with MariaDB, yet
rpl_crash_safe_wal_corrupt : Didn't try with MariaDB, yet
-rpl_ddl_high_priority : Didn't try with MariaDB, yet
rpl_gtid_crash_safe : Didn't try with MariaDB, yet
rpl_gtid_crash_safe_wal_corrupt : Didn't try with MariaDB, yet
-rpl_gtid_rocksdb_sys_header : Didn't try with MariaDB, yet
-rpl_no_unique_check_on_lag : Didn't try with MariaDB, yet
-rpl_no_unique_check_on_lag_mts : Didn't try with MariaDB, yet
rpl_rocksdb_snapshot : Didn't try with MariaDB, yet
rpl_rocksdb_snapshot_without_gtid : Didn't try with MariaDB, yet
-rpl_rocksdb_stress_crash : Didn't try with MariaDB, yet
-rpl_skip_trx_api_binlog_format : Didn't try with MariaDB, yet
-singledelete_idempotent_recovery : Didn't try with MariaDB, yet
-singledelete_idempotent_table : Didn't try with MariaDB, yet
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt
new file mode 100644
index 00000000000..ed50a8a3deb
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count-master.opt
@@ -0,0 +1,3 @@
+--innodb --max-binlog-size=4096
+
+
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test
new file mode 100644
index 00000000000..7667f153cde
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_binlog_xid_count.test
@@ -0,0 +1,20 @@
+--source include/have_rocksdb.inc
+--source include/have_binlog_format_row.inc
+
+CREATE TABLE `t` (
+ `a` text DEFAULT NULL
+) ENGINE=ROCKSDB;
+
+
+--let $size=`SELECT @@GLOBAL.max_binlog_size`
+--let $loop_cnt= 100
+while ($loop_cnt)
+{
+ --eval INSERT INTO t SET a=repeat('a', $size)
+ --eval INSERT INTO t SET a=repeat('a', $size/2)
+
+ --dec $loop_cnt
+}
+
+# Cleanup
+DROP TABLE t;
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf
index ad4894f5b38..5f1f87d762f 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.cnf
@@ -2,14 +2,10 @@
[mysqld.1]
log_slave_updates
-gtid_mode=ON
-enforce_gtid_consistency=ON
[mysqld.2]
relay_log_recovery=1
-relay_log_info_repository=FILE
+#relay_log_info_repository=FILE
log_slave_updates
-gtid_mode=ON
-enforce_gtid_consistency=ON
-rbr_idempotent_tables='r1'
-
+#rbr_idempotent_tables='r1'
+slave_exec_mode=IDEMPOTENT
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test
index 23d335d6b57..00dce7c2ca9 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/singledelete_idempotent_table.test
@@ -2,7 +2,7 @@
--source include/have_binlog_format_row.inc
--source include/have_rocksdb.inc
--source include/master-slave.inc
---source include/have_gtid.inc
+#--source include/have_gtid.inc
--source include/not_valgrind.inc
# This is a test case for issue#655 -- SingleDelete on Primary Key may
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_git_hash_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_git_hash_basic.test
new file mode 100644
index 00000000000..7b314e47d4b
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_git_hash_basic.test
@@ -0,0 +1,6 @@
+--source include/have_rocksdb.inc
+
+--let $sys_var=ROCKSDB_GIT_HASH
+--let $read_only=1
+--let $session=0
+--source include/rocksdb_sys_var.inc
diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc
index f4749d0c7cf..ff8a4faee55 100644
--- a/storage/rocksdb/rdb_datadic.cc
+++ b/storage/rocksdb/rdb_datadic.cc
@@ -1461,7 +1461,8 @@ int Rdb_key_def::unpack_record(TABLE *const table, uchar *const buf,
if (has_covered_bitmap && field->real_type() == MYSQL_TYPE_VARCHAR &&
!m_pack_info[i].m_covered) {
covered_column = curr_bitmap_pos < MAX_REF_PARTS &&
- bitmap_is_set(&covered_bitmap, curr_bitmap_pos++);
+ bitmap_is_set(&covered_bitmap, curr_bitmap_pos);
+ curr_bitmap_pos++;
}
if (fpi->m_unpack_func && covered_column) {
/* It is possible to unpack this column. Do it. */
diff --git a/storage/rocksdb/rdb_source_revision.h.in b/storage/rocksdb/rdb_source_revision.h.in
new file mode 100644
index 00000000000..617b39c9186
--- /dev/null
+++ b/storage/rocksdb/rdb_source_revision.h.in
@@ -0,0 +1 @@
+#define ROCKSDB_GIT_HASH "@ROCKSDB_GIT_HASH@"
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result
index 16b3571db9f..a80e1664663 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result
@@ -1,7 +1,7 @@
drop table if exists t;
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
create table t (id int not null, x int not null, y int not null, primary key(id), key(x)) engine=innodb;
insert into t values (0,0,0),(1,1,1),(2,2,2),(3,2,3),(4,2,4);
explain select x,id from t force index (x) where x=0 and id=0;
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result
index 961504412a9..96d681407fe 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result
@@ -1,7 +1,7 @@
drop table if exists t;
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
create table t (id int not null, x int not null, y int not null, primary key(id), key(x)) engine=tokudb;
insert into t values (0,0,0),(1,1,1),(2,2,2),(3,2,3),(4,2,4);
explain select x,id from t force index (x) where x=0 and id=0;
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result
index e5796f7a9b1..43737c7753e 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result
@@ -1,7 +1,7 @@
drop table if exists t;
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
create table t (a int not null, b int not null, c int not null, d int not null, primary key(a,b), key(c,a)) engine=innodb;
insert into t values (0,0,0,0),(0,1,0,1);
explain select c,a,b from t where c=0 and a=0 and b=1;
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
index 3f1ed9971c3..1dcb1ee1b8b 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
@@ -1,7 +1,7 @@
drop table if exists t;
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_grouping_derived=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
create table t (a int not null, b int not null, c int not null, d int not null, primary key(a,b), key(c,a)) engine=tokudb;
insert into t values (0,0,0,0),(0,1,0,1);
explain select c,a,b from t where c=0 and a=0 and b=1;