Commit 96baf431 authored by Seppo Jaakola's avatar Seppo Jaakola

References lp:1115708 - merged innodb wsrep changes to xtradb between revisions 3809...3845

parent e51a884e
......@@ -5609,6 +5609,7 @@ wsrep_store_key_val_for_row(
/* Pad the unused space with spaces. */
#ifdef REMOVED
if (true_len < key_len) {
ulint pad_len = key_len - true_len;
ut_a(!(pad_len % cs->mbminlen));
......@@ -5617,6 +5618,7 @@ wsrep_store_key_val_for_row(
0x20 /* space */);
buff += pad_len;
}
#endif /* REMOVED */
}
}
......@@ -7988,30 +7990,35 @@ wsrep_append_foreign_key(
mutex_enter(&(dict_sys->mutex));
if (referenced)
{
foreign->referenced_table =
dict_table_check_if_in_cache_low(
foreign->referenced_table =
dict_table_get_low(
foreign->referenced_table_name_lookup);
foreign->referenced_index =
wsrep_dict_foreign_find_index(
foreign->referenced_table,
foreign->referenced_col_names,
foreign->n_fields,
foreign->foreign_index,
TRUE, FALSE);
if (foreign->referenced_table)
{
foreign->referenced_index =
wsrep_dict_foreign_find_index(
foreign->referenced_table,
foreign->referenced_col_names,
foreign->n_fields,
foreign->foreign_index,
TRUE, FALSE);
}
}
else
{
foreign->foreign_table =
dict_table_check_if_in_cache_low(
foreign->foreign_table =
dict_table_get_low(
foreign->foreign_table_name_lookup);
foreign->foreign_index =
wsrep_dict_foreign_find_index(
foreign->foreign_table,
foreign->foreign_col_names,
foreign->n_fields,
foreign->referenced_index,
TRUE, FALSE);
if (foreign->foreign_table)
{
foreign->foreign_index =
wsrep_dict_foreign_find_index(
foreign->foreign_table,
foreign->foreign_col_names,
foreign->n_fields,
foreign->referenced_index,
TRUE, FALSE);
}
}
mutex_exit(&(dict_sys->mutex));
}
......@@ -8030,7 +8037,7 @@ wsrep_append_foreign_key(
ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH;
dict_index_t *idx_target = (referenced) ?
foreign->referenced_index : foreign->foreign_index;
foreign->referenced_index : index;
dict_index_t *idx = (referenced) ?
UT_LIST_GET_FIRST(foreign->referenced_table->indexes) :
UT_LIST_GET_FIRST(foreign->foreign_table->indexes);
......@@ -8042,8 +8049,8 @@ wsrep_append_foreign_key(
ut_a(idx);
key[0] = (char)i;
rcode = wsrep_rec_get_primary_key(
&key[1], &len, rec, index,
rcode = wsrep_rec_get_foreign_key(
&key[1], &len, rec, index, idx,
wsrep_protocol_version > 1);
if (rcode != DB_SUCCESS) {
WSREP_ERROR(
......@@ -8192,6 +8199,15 @@ ha_innobase::wsrep_append_keys(
DBUG_ENTER("wsrep_append_keys");
trx_t *trx = thd_to_trx(thd);
if (table_share && table_share->tmp_table != NO_TMP_TABLE) {
WSREP_DEBUG("skipping tmp table DML: THD: %lu tmp: %d SQL: %s",
wsrep_thd_thread_id(thd),
table_share->tmp_table,
(wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void");
DBUG_RETURN(0);
}
/* if no PK, calculate hash of full row, to be the key value */
if (prebuilt->clust_index_was_generated && wsrep_certify_nonPK) {
uchar digest[16];
......@@ -12516,6 +12532,9 @@ innobase_xa_prepare(
to the session variable take effect only in the next transaction */
if (!trx->support_xa) {
#ifdef WITH_WSREP
thd_get_xid(thd, (MYSQL_XID*) &trx->xid);
#endif // WITH_WSREP
return(0);
}
......
......@@ -833,11 +833,12 @@ two upmost bits in a two byte offset for special purposes */
#define REC_MAX_DATA_SIZE (16 * 1024)
#ifdef WITH_WSREP
int wsrep_rec_get_primary_key(
int wsrep_rec_get_foreign_key(
byte *buf, /* out: extracted key */
ulint *buf_len, /* in/out: length of buf */
const rec_t* rec, /* in: physical record */
dict_index_t* index, /* in: record descriptor */
dict_index_t* index_for, /* in: index for foreign table */
dict_index_t* index_ref, /* in: index for referenced table */
ibool new_protocol); /* in: protocol > 1 */
#endif /* WITH_WSREP */
#ifndef UNIV_NONINL
......
......@@ -1777,11 +1777,12 @@ rec_print(
#endif /* !UNIV_HOTBACKUP */
#ifdef WITH_WSREP
int
wsrep_rec_get_primary_key(
wsrep_rec_get_foreign_key(
byte *buf, /* out: extracted key */
ulint *buf_len, /* in/out: length of buf */
const rec_t* rec, /* in: physical record */
dict_index_t* index, /* in: record descriptor */
dict_index_t* index_for, /* in: index in foreign table */
dict_index_t* index_ref, /* in: index in referenced table */
ibool new_protocol) /* in: protocol > 1 */
{
const byte* data;
......@@ -1793,26 +1794,32 @@ wsrep_rec_get_primary_key(
ulint offsets_[REC_OFFS_NORMAL_SIZE];
const ulint* offsets;
ut_ad(index);
ut_ad(index_for);
ut_ad(index_ref);
rec_offs_init(offsets_);
offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap);
offsets = rec_get_offsets(rec, index_for, offsets_,
ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_validate(rec, NULL, offsets));
ut_ad(rec);
key_parts = dict_index_get_n_unique_in_tree(index);
key_parts = dict_index_get_n_unique_in_tree(index_for);
for (i = 0;
i < key_parts && (index->type & DICT_CLUSTERED || i < key_parts - 1);
i < key_parts &&
(index_for->type & DICT_CLUSTERED || i < key_parts - 1);
i++) {
dict_field_t* field = dict_index_get_nth_field(index, i);
const dict_col_t* col = dict_field_get_col(field);
dict_field_t* field_f =
dict_index_get_nth_field(index_for, i);
const dict_col_t* col_f = dict_field_get_col(field_f);
dict_field_t* field_r =
dict_index_get_nth_field(index_ref, i);
const dict_col_t* col_r = dict_field_get_col(field_r);
data = rec_get_nth_field(rec, offsets, i, &len);
if (key_len + len > ((col->prtype & DATA_NOT_NULL) ?
*buf_len : *buf_len - 1)) {
if (key_len + ((len != UNIV_SQL_NULL) ? len + 1 : 1) >
*buf_len) {
fprintf (stderr,
"WSREP: FK key len exceeded %lu %lu %lu\n",
key_len, len, *buf_len);
......@@ -1820,25 +1827,25 @@ wsrep_rec_get_primary_key(
}
if (len == UNIV_SQL_NULL) {
ut_a(!(col->prtype & DATA_NOT_NULL));
ut_a(!(col_f->prtype & DATA_NOT_NULL));
*buf++ = 1;
key_len++;
} else if (!new_protocol) {
if (!(col->prtype & DATA_NOT_NULL)) {
if (!(col_r->prtype & DATA_NOT_NULL)) {
*buf++ = 0;
key_len++;
}
memcpy(buf, data, len);
wsrep_innobase_mysql_sort(
(int)(col->prtype & DATA_MYSQL_TYPE_MASK),
(uint)dtype_get_charset_coll(col->prtype),
(int)(col_f->prtype & DATA_MYSQL_TYPE_MASK),
(uint)dtype_get_charset_coll(col_f->prtype),
buf, len);
} else { /* new protocol */
if (!(col->prtype & DATA_NOT_NULL)) {
if (!(col_r->prtype & DATA_NOT_NULL)) {
*buf++ = 0;
key_len++;
}
switch (col->mtype) {
switch (col_f->mtype) {
case DATA_INT: {
byte* ptr = buf+len;
for (;;) {
......@@ -1850,7 +1857,7 @@ wsrep_rec_get_primary_key(
data++;
}
if (!(col->prtype & DATA_UNSIGNED)) {
if (!(col_f->prtype & DATA_UNSIGNED)) {
buf[len-1] = (byte) (buf[len-1] ^ 128);
}
......@@ -1858,16 +1865,19 @@ wsrep_rec_get_primary_key(
}
case DATA_VARCHAR:
case DATA_VARMYSQL:
case DATA_BINARY:
case DATA_CHAR:
case DATA_MYSQL:
/* Copy the actual data */
ut_memcpy(buf, data, len);
wsrep_innobase_mysql_sort(
(int)(col->prtype & DATA_MYSQL_TYPE_MASK),
(uint)dtype_get_charset_coll(col->prtype),
(int)
(col_f->prtype & DATA_MYSQL_TYPE_MASK),
(uint)
dtype_get_charset_coll(col_f->prtype),
buf, len);
break;
case DATA_BLOB:
case DATA_MYSQL:
case DATA_BINARY:
memcpy(buf, data, len);
break;
default:
......
......@@ -51,6 +51,9 @@ Created 12/27/1996 Heikki Tuuri
#include "pars0sym.h"
#include "eval0eval.h"
#include "buf0lru.h"
#ifdef WITH_WSREP
extern my_bool wsrep_debug;
#endif
/* What kind of latch and lock can we assume when the control comes to
......@@ -178,36 +181,6 @@ ulint wsrep_append_foreign_key(trx_t *trx,
ibool referenced,
ibool shared);
static
void
wsrep_append_fk_reference(
/*=================================*/
upd_node_t* node, /*!< in: row update node */
dict_table_t* table, /*!< in: table in question */
dict_index_t* index, /*!< in: index of the cursor */
que_thr_t* thr, /*!< in: query thread */
const rec_t* rec
) {
dict_foreign_t *foreign = UT_LIST_GET_FIRST(table->foreign_list);
while (foreign) {
if (foreign->foreign_index == index
&& node->is_delete)
{
if (DB_SUCCESS != wsrep_append_foreign_key(
thr_get_trx(thr),
foreign,
rec,
index,
TRUE, TRUE)
) {
fprintf(stderr,
"WSREP: FK key append failed\n");
}
}
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
}
#endif /* WITH_WSREP */
/*********************************************************************//**
......@@ -332,6 +305,122 @@ row_upd_check_references_constraints(
return(err);
}
#ifdef WITH_WSREP
static
ulint
wsrep_row_upd_check_foreign_constraints(
/*=================================*/
upd_node_t* node, /*!< in: row update node */
btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
cursor position is lost in this function! */
dict_table_t* table, /*!< in: table in question */
dict_index_t* index, /*!< in: index of the cursor */
ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr) /*!< in: mtr */
{
dict_foreign_t* foreign;
mem_heap_t* heap;
dtuple_t* entry;
trx_t* trx;
const rec_t* rec;
ulint n_ext;
ulint err;
ibool got_s_lock = FALSE;
if (UT_LIST_GET_FIRST(table->foreign_list) == NULL) {
return(DB_SUCCESS);
}
trx = thr_get_trx(thr);
rec = btr_pcur_get_rec(pcur);
ut_ad(rec_offs_validate(rec, index, offsets));
heap = mem_heap_create(500);
entry = row_rec_to_index_entry(ROW_COPY_DATA, rec, index, offsets,
&n_ext, heap);
mtr_commit(mtr);
mtr_start(mtr);
if (trx->dict_operation_lock_mode == 0) {
got_s_lock = TRUE;
row_mysql_freeze_data_dictionary(trx);
}
foreign = UT_LIST_GET_FIRST(table->foreign_list);
while (foreign) {
/* Note that we may have an update which updates the index
record, but does NOT update the first fields which are
referenced in a foreign key constraint. Then the update does
NOT break the constraint. */
if (foreign->foreign_index == index
&& (node->is_delete
|| row_upd_changes_first_fields_binary(
entry, index, node->update,
foreign->n_fields))) {
if (foreign->referenced_table == NULL) {
dict_table_get(foreign->referenced_table_name_lookup,
FALSE);
}
if (foreign->referenced_table) {
mutex_enter(&(dict_sys->mutex));
(foreign->referenced_table
->n_foreign_key_checks_running)++;
mutex_exit(&(dict_sys->mutex));
}
/* NOTE that if the thread ends up waiting for a lock
we will release dict_operation_lock temporarily!
But the counter on the table protects 'foreign' from
being dropped while the check is running. */
err = row_ins_check_foreign_constraint(
TRUE, foreign, table, entry, thr);
if (foreign->referenced_table) {
mutex_enter(&(dict_sys->mutex));
ut_a(foreign->referenced_table
->n_foreign_key_checks_running > 0);
(foreign->referenced_table
->n_foreign_key_checks_running)--;
mutex_exit(&(dict_sys->mutex));
}
if (err != DB_SUCCESS) {
goto func_exit;
}
}
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
err = DB_SUCCESS;
func_exit:
if (got_s_lock) {
row_mysql_unfreeze_data_dictionary(trx);
}
mem_heap_free(heap);
return(err);
}
#endif /* WITH_WSREP */
/*********************************************************************//**
Creates an update node for a query graph.
......@@ -1706,8 +1795,18 @@ row_upd_sec_index_entry(
}
#ifdef WITH_WSREP
if (err == DB_SUCCESS && !referenced) {
wsrep_append_fk_reference(node, index->table,
index, thr, rec);
ulint* offsets =
rec_get_offsets(
rec, index, NULL, ULINT_UNDEFINED,
&heap);
uint werr = wsrep_row_upd_check_foreign_constraints(
node, &pcur, index->table,
index, offsets, thr, &mtr);
if (wsrep_debug && werr != DB_SUCCESS)
fprintf (stderr,
"WSREP: FK check fail: %u",
werr);
}
#endif /* WITH_WSREP */
}
......@@ -1955,8 +2054,12 @@ row_upd_clust_rec_by_insert(
}
#ifdef WITH_WSREP
if (!referenced) {
wsrep_append_fk_reference(node, index->table,
index, thr, rec);
uint werr = wsrep_row_upd_check_foreign_constraints(
node, pcur, table, index, offsets, thr, mtr);
if (wsrep_debug && werr != DB_SUCCESS)
fprintf (stderr,
"WSREP: FK check fail: %u",
werr);
}
#endif /* WITH_WSREP */
}
......@@ -2199,13 +2302,15 @@ row_upd_del_mark_clust_rec(
if (err == DB_SUCCESS && referenced) {
/* NOTE that the following call loses the position of pcur ! */
err = row_upd_check_references_constraints(
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
}
#ifdef WITH_WSREP
if (err == DB_SUCCESS && !referenced) {
wsrep_append_fk_reference(node, index->table,
index, thr, rec);
uint werr = row_upd_check_references_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
if (wsrep_debug && werr != DB_SUCCESS)
fprintf (stderr, "WSREP: FK check fail: %u", werr);
}
#endif /* WITH_WSREP */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment