mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
References:
https://mariadb.atlassian.net/browse/MDEV-4179 https://bugs.launchpad.net/codership-mysql/+bug/1130888 https://bugs.launchpad.net/codership-mysql/+bug/1019473 Merged revisions 3847-3850 from lp:~codership/codership-mysql/5.5-23
This commit is contained in:
parent
68154e62b1
commit
2b0f16c577
8 changed files with 299 additions and 48 deletions
|
@ -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 @@ err_exit:
|
|||
}
|
||||
#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 @@ err_exit:
|
|||
}
|
||||
#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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue