Commit 2b0f16c5 authored by Seppo Jaakola's avatar Seppo Jaakola
parent 68154e62
......@@ -17,7 +17,7 @@
# so WSREP_VERSION is produced regardless
# Set the patch version
SET(WSREP_PATCH_VERSION "7.1")
SET(WSREP_PATCH_VERSION "7.3")
# Obtain patch revision number
SET(WSREP_PATCH_REVNO $ENV{WSREP_REV})
......
......@@ -5590,6 +5590,14 @@ int mysqld_main(int argc, char **argv)
my_str_malloc= &my_str_malloc_mysqld;
my_str_free= &my_str_free_mysqld;
#ifdef WITH_WSREP /* WSREP AFTER SE */
if (wsrep_recovery)
{
select_thread_in_use= 0;
wsrep_recover();
unireg_abort(0);
}
#endif /* WITH_WSREP */
/*
init signals & alarm
After this we can't quit by a simple unireg_abort
......@@ -5662,13 +5670,6 @@ int mysqld_main(int argc, char **argv)
unireg_abort(1);
#ifdef WITH_WSREP /* WSREP AFTER SE */
if (wsrep_recovery)
{
select_thread_in_use= 0;
wsrep_recover();
unireg_abort(0);
}
if (opt_bootstrap)
{
/*! bootstrap wsrep init was taken care of above */
......
......@@ -6040,7 +6040,84 @@ calc_row_difference(
return(0);
}
#ifdef WITH_WSREP
static
int
wsrep_calc_row_hash(
/*================*/
byte* digest, /*!< in/out: md5 sum */
const uchar* row, /*!< in: row in MySQL format */
TABLE* table, /*!< in: table in MySQL data
dictionary */
row_prebuilt_t* prebuilt, /*!< in: InnoDB prebuilt struct */
THD* thd) /*!< in: user thread */
{
Field* field;
enum_field_types field_mysql_type;
uint n_fields;
ulint len;
const byte* ptr;
ulint col_type;
uint i;
my_MD5Context ctx;
my_MD5Init (&ctx);
n_fields = table->s->fields;
for (i = 0; i < n_fields; i++) {
byte null_byte=0;
byte true_byte=1;
field = table->field[i];
ptr = (const byte*) row + get_field_offset(table, field);
len = field->pack_length();
field_mysql_type = field->type();
col_type = prebuilt->table->cols[i].mtype;
switch (col_type) {
case DATA_BLOB:
ptr = row_mysql_read_blob_ref(&len, ptr, len);
break;
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_VARMYSQL:
if (field_mysql_type == MYSQL_TYPE_VARCHAR) {
/* This is a >= 5.0.3 type true VARCHAR where
the real payload data length is stored in
1 or 2 bytes */
ptr = row_mysql_read_true_varchar(
&len, ptr,
(ulint)
(((Field_varstring*)field)->length_bytes));
}
break;
default:
;
}
if (field->null_ptr &&
field_in_record_is_null(table, field, (char*) row)) {
my_MD5Update (&ctx, &null_byte, 1);
} else {
my_MD5Update (&ctx, &true_byte, 1);
my_MD5Update (&ctx, ptr, len);
}
}
my_MD5Final (digest, &ctx);
return(0);
}
#endif /* WITH_WSREP */
/**********************************************************************//**
Updates a row given as a parameter to a new value. Note that we are given
whole rows, not just the fields which are updated: this incurs some
......@@ -7297,14 +7374,15 @@ ha_innobase::wsrep_append_keys(
uchar digest[16];
int rcode;
MY_MD5_HASH(digest, (uchar *)record0, table->s->reclength);
wsrep_calc_row_hash(digest, record0, table, prebuilt, thd);
if ((rcode = wsrep_append_key(thd, trx, table_share, table,
(const char*) digest, 16,
shared))) {
DBUG_RETURN(rcode);
}
if (record1) {
MY_MD5_HASH(digest, (uchar *)record1, table->s->reclength);
wsrep_calc_row_hash(digest, record1, table, prebuilt, thd);
if ((rcode = wsrep_append_key(thd, trx, table_share,
table,
(const char*) digest,
......@@ -7312,6 +7390,7 @@ ha_innobase::wsrep_append_keys(
DBUG_RETURN(rcode);
}
}
DBUG_RETURN(0);
}
if (wsrep_protocol_version == 0) {
uint len;
......
......@@ -1827,22 +1827,30 @@ lock_rec_create(
*/
if (c_lock && c_lock->trx->que_state == TRX_QUE_LOCK_WAIT) {
c_lock->trx->was_chosen_as_deadlock_victim = TRUE;
if (wsrep_debug && c_lock->trx->wait_lock != c_lock) {
fprintf(stderr, "WSREP: c_lock != wait lock\n");
lock_rec_print(stderr, c_lock);
lock_rec_print(stderr, c_lock->trx->wait_lock);
}
trx->que_state = TRX_QUE_LOCK_WAIT;
lock_set_lock_and_trx_wait(lock, trx);
lock_cancel_waiting_and_release(c_lock->trx->wait_lock);
/* trx might not wait for c_lock, but some other lock */
if (wsrep_debug && c_lock->trx->wait_lock != c_lock) {
fprintf(stderr, "WSREP: c_lock != wait lock\n");
}
/* trx might not wait for c_lock, but some other lock
does not matter if wait_lock was released above
*/
if (c_lock->trx->wait_lock == c_lock) {
lock_reset_lock_and_trx_wait(lock);
}
if (wsrep_debug)
fprintf(stderr, "WSREP: c_lock canceled %llu\n",
if (wsrep_debug) fprintf(
stderr,
"WSREP: c_lock canceled %llu\n",
(ulonglong) c_lock->trx->id);
/* have to bail out here to avoid lock_set_lock... */
return(lock);
}
......
......@@ -1780,14 +1780,25 @@ row_upd_sec_index_entry(
rec_get_offsets(
rec, index, NULL, ULINT_UNDEFINED,
&heap);
uint werr = wsrep_row_upd_check_foreign_constraints(
err = wsrep_row_upd_check_foreign_constraints(
node, &pcur, index->table,
index, offsets, thr, &mtr);
if (wsrep_debug && werr != DB_SUCCESS)
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
if (wsrep_debug)
fprintf (stderr,
"WSREP: sec index FK check fail for deadlock");
break;
default:
fprintf (stderr,
"WSREP: FK check fail: %u",
werr);
"WSREP: referenced FK check fail: %lu",
err);
break;
}
}
#endif /* WITH_WSREP */
}
......@@ -2033,12 +2044,26 @@ row_upd_clust_rec_by_insert(
}
#ifdef WITH_WSREP
if (!referenced) {
uint werr = wsrep_row_upd_check_foreign_constraints(
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, table, index, offsets, thr, mtr);
if (wsrep_debug && werr != DB_SUCCESS)
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
if (wsrep_debug) fprintf (stderr,
"WSREP: insert FK check fail for deadlock");
break;
default:
fprintf (stderr,
"WSREP: FK check fail: %u",
werr);
"WSREP: referenced FK check fail: %lu",
err);
break;
}
if (err != DB_SUCCESS) {
goto err_exit;
}
}
#endif /* WITH_WSREP */
}
......@@ -2281,10 +2306,23 @@ row_upd_del_mark_clust_rec(
}
#ifdef WITH_WSREP
if (err == DB_SUCCESS && !referenced) {
uint werr = wsrep_row_upd_check_foreign_constraints(
err = 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);
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
if (wsrep_debug) fprintf (stderr,
"WSREP: clust rec FK check fail for deadlock");
break;
default:
fprintf (stderr,
"WSREP: clust rec referenced FK check fail: %lu",
err);
break;
}
}
#endif /* WITH_WSREP */
......
......@@ -6896,7 +6896,84 @@ calc_row_difference(
return(0);
}
#ifdef WITH_WSREP
static
int
wsrep_calc_row_hash(
/*================*/
byte* digest, /*!< in/out: md5 sum */
const uchar* row, /*!< in: row in MySQL format */
TABLE* table, /*!< in: table in MySQL data
dictionary */
row_prebuilt_t* prebuilt, /*!< in: InnoDB prebuilt struct */
THD* thd) /*!< in: user thread */
{
Field* field;
enum_field_types field_mysql_type;
uint n_fields;
ulint len;
const byte* ptr;
ulint col_type;
uint i;
my_MD5Context ctx;
my_MD5Init (&ctx);
n_fields = table->s->fields;
for (i = 0; i < n_fields; i++) {
byte null_byte=0;
byte true_byte=1;
field = table->field[i];
ptr = (const byte*) row + get_field_offset(table, field);
len = field->pack_length();
field_mysql_type = field->type();
col_type = prebuilt->table->cols[i].mtype;
switch (col_type) {
case DATA_BLOB:
ptr = row_mysql_read_blob_ref(&len, ptr, len);
break;
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_VARMYSQL:
if (field_mysql_type == MYSQL_TYPE_VARCHAR) {
/* This is a >= 5.0.3 type true VARCHAR where
the real payload data length is stored in
1 or 2 bytes */
ptr = row_mysql_read_true_varchar(
&len, ptr,
(ulint)
(((Field_varstring*)field)->length_bytes));
}
break;
default:
;
}
if (field->null_ptr &&
field_in_record_is_null(table, field, (char*) row)) {
my_MD5Update (&ctx, &null_byte, 1);
} else {
my_MD5Update (&ctx, &true_byte, 1);
my_MD5Update (&ctx, ptr, len);
}
}
my_MD5Final (digest, &ctx);
return(0);
}
#endif /* WITH_WSREP */
/**********************************************************************//**
Updates a row given as a parameter to a new value. Note that we are given
whole rows, not just the fields which are updated: this incurs some
......@@ -8213,14 +8290,15 @@ ha_innobase::wsrep_append_keys(
uchar digest[16];
int rcode;
MY_MD5_HASH(digest, (uchar *)record0, table->s->reclength);
wsrep_calc_row_hash(digest, record0, table, prebuilt, thd);
if ((rcode = wsrep_append_key(thd, trx, table_share, table,
(const char*) digest, 16,
shared))) {
DBUG_RETURN(rcode);
}
if (record1) {
MY_MD5_HASH(digest, (uchar *)record1, table->s->reclength);
wsrep_calc_row_hash(digest, record1, table, prebuilt, thd);
if ((rcode = wsrep_append_key(thd, trx, table_share,
table,
(const char*) digest,
......@@ -8228,6 +8306,7 @@ ha_innobase::wsrep_append_keys(
DBUG_RETURN(rcode);
}
}
DBUG_RETURN(0);
}
if (wsrep_protocol_version == 0) {
uint len;
......
......@@ -1800,22 +1800,30 @@ lock_rec_create(
*/
if (c_lock && c_lock->trx->que_state == TRX_QUE_LOCK_WAIT) {
c_lock->trx->was_chosen_as_deadlock_victim = TRUE;
if (wsrep_debug && c_lock->trx->wait_lock != c_lock) {
fprintf(stderr, "WSREP: c_lock != wait lock\n");
lock_rec_print(stderr, c_lock);
lock_rec_print(stderr, c_lock->trx->wait_lock);
}
trx->que_state = TRX_QUE_LOCK_WAIT;
lock_set_lock_and_trx_wait(lock, trx);
lock_cancel_waiting_and_release(c_lock->trx->wait_lock);
/* trx might not wait for c_lock, but some other lock */
if (wsrep_debug && c_lock->trx->wait_lock != c_lock) {
fprintf(stderr, "WSREP: c_lock != wait lock\n");
}
/* trx might not wait for c_lock, but some other lock
does not matter if wait_lock was released above
*/
if (c_lock->trx->wait_lock == c_lock) {
lock_reset_lock_and_trx_wait(lock);
}
if (wsrep_debug)
fprintf(stderr, "WSREP: c_lock canceled %llu\n",
if (wsrep_debug) fprintf(
stderr,
"WSREP: c_lock canceled %llu\n",
(ulonglong) c_lock->trx->id);
/* have to bail out here to avoid lock_set_lock... */
return(lock);
}
......
......@@ -1799,14 +1799,25 @@ row_upd_sec_index_entry(
rec_get_offsets(
rec, index, NULL, ULINT_UNDEFINED,
&heap);
uint werr = wsrep_row_upd_check_foreign_constraints(
err = wsrep_row_upd_check_foreign_constraints(
node, &pcur, index->table,
index, offsets, thr, &mtr);
if (wsrep_debug && werr != DB_SUCCESS)
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
if (wsrep_debug)
fprintf (stderr,
"WSREP: sec index FK check fail for deadlock");
break;
default:
fprintf (stderr,
"WSREP: FK check fail: %u",
werr);
"WSREP: referenced FK check fail: %lu",
err);
break;
}
}
#endif /* WITH_WSREP */
}
......@@ -2054,12 +2065,26 @@ row_upd_clust_rec_by_insert(
}
#ifdef WITH_WSREP
if (!referenced) {
uint werr = wsrep_row_upd_check_foreign_constraints(
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, table, index, offsets, thr, mtr);
if (wsrep_debug && werr != DB_SUCCESS)
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
if (wsrep_debug) fprintf (stderr,
"WSREP: insert FK check fail for deadlock");
break;
default:
fprintf (stderr,
"WSREP: FK check fail: %u",
werr);
"WSREP: referenced FK check fail: %lu",
err);
break;
}
if (err != DB_SUCCESS) {
goto err_exit;
}
}
#endif /* WITH_WSREP */
}
......@@ -2307,10 +2332,23 @@ row_upd_del_mark_clust_rec(
}
#ifdef WITH_WSREP
if (err == DB_SUCCESS && !referenced) {
uint werr = wsrep_row_upd_check_foreign_constraints(
err = 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);
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
if (wsrep_debug) fprintf (stderr,
"WSREP: clust rec FK check fail for deadlock");
break;
default:
fprintf (stderr,
"WSREP: clust rec referenced FK check fail: %lu",
err);
break;
}
}
#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