-
-
Notifications
You must be signed in to change notification settings - Fork 2k
MDEV-35879 Slave_heartbeat_period is imprecise #4441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 10.11
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,7 +16,7 @@ show status like 'Slave_heartbeat_period';; | |
| Variable_name Slave_heartbeat_period | ||
| Value 5.000 | ||
| connection slave; | ||
| change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_heartbeat_period= 0.0009999; | ||
| change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_heartbeat_period= 0.0004999; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should I keep the rounding method change out of 10.11?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should put the whole patch into
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Can you please clarify: Not just the rounding method change, but also the imprecision (main topic of MDEV-35879)? Then, perhaps some or all of the points in MDEV-37529 should only be addressed on the |
||
| Warnings: | ||
| Warning 1703 The requested value for the heartbeat period is less than 1 millisecond. The value is reset to 0, meaning that heartbeating will effectively be disabled | ||
| show status like 'Slave_heartbeat_period';; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -190,26 +190,36 @@ let $slave_heartbeat_timeout= query_get_value(SHOW GLOBAL STATUS LIKE 'slave_hea | |
| # | ||
| # Check limits for slave_heartbeat_timeout | ||
| # | ||
| --let $status_items= Slave_heartbeat_period | ||
| --let $all_slaves_status= 1 | ||
|
|
||
| --echo *** Min slave_heartbeat_timeout *** | ||
| --replace_result $MASTER_MYPORT MASTER_PORT | ||
| eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.001; | ||
| SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; | ||
| --source include/show_slave_status.inc | ||
| RESET SLAVE; | ||
| --replace_result $MASTER_MYPORT MASTER_PORT | ||
| eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.0009; | ||
| eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.00049; | ||
| SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; | ||
| --source include/show_slave_status.inc | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd suggest adding a comment to why you show this twice from different sources. |
||
| RESET SLAVE; | ||
| --echo | ||
|
|
||
| --echo *** Max slave_heartbeat_timeout *** | ||
| --replace_result $MASTER_MYPORT MASTER_PORT | ||
| eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=4294966.999; | ||
| SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; | ||
| --source include/show_slave_status.inc | ||
| RESET SLAVE; | ||
| --replace_result $MASTER_MYPORT MASTER_PORT | ||
| eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=4294967; | ||
| SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; | ||
| --source include/show_slave_status.inc | ||
| RESET SLAVE; | ||
| --replace_result $MASTER_MYPORT MASTER_PORT | ||
| --error ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE | ||
| eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=4294968; | ||
| eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=4294967.001; | ||
| RESET SLAVE; | ||
| # Check double size of max allowed value for master_heartbeat_period | ||
| --replace_result $MASTER_MYPORT MASTER_PORT | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -229,11 +229,8 @@ void init_master_log_pos(Master_info* mi) | |
| if CHANGE MASTER did not specify it. (no data loss in conversion | ||
| as hb period has a max) | ||
| */ | ||
| mi->heartbeat_period= (float) MY_MIN(SLAVE_MAX_HEARTBEAT_PERIOD, | ||
| (slave_net_timeout/2.0)); | ||
| DBUG_ASSERT(mi->heartbeat_period > (float) 0.001 | ||
| || mi->heartbeat_period == 0); | ||
|
|
||
| mi->heartbeat_period= MY_MIN(SLAVE_MAX_HEARTBEAT_PERIOD, | ||
| slave_net_timeout*500ULL); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume this is an optimization of (x*1000)/2. I think the compiler should automatically do it though, and it would improve readability to have the full equation. Do you know how to disassemble code? I'd be curious if the generated instructions are the same or not. If not, then we can keep it (though I'd suggest a comment with the full equation). |
||
| DBUG_VOID_RETURN; | ||
| } | ||
|
|
||
|
|
@@ -450,7 +447,7 @@ file '%s')", fname); | |
| mi->fd = fd; | ||
| int port, connect_retry, master_log_pos, lines; | ||
| int ssl= 0, ssl_verify_server_cert= 0; | ||
| float master_heartbeat_period= 0.0; | ||
| double master_heartbeat_period= 0.0; | ||
| char *first_non_digit; | ||
| char buf[HOSTNAME_LENGTH+1]; | ||
|
|
||
|
|
@@ -674,7 +671,8 @@ file '%s')", fname); | |
| mi->connect_retry= (uint) connect_retry; | ||
| mi->ssl= (my_bool) ssl; | ||
| mi->ssl_verify_server_cert= ssl_verify_server_cert; | ||
| mi->heartbeat_period= MY_MIN(SLAVE_MAX_HEARTBEAT_PERIOD, master_heartbeat_period); | ||
| mi->heartbeat_period= MY_MIN(SLAVE_MAX_HEARTBEAT_PERIOD, | ||
| static_cast<uint32_t>(master_heartbeat_period*1000)); | ||
| } | ||
| DBUG_PRINT("master_info",("log_file_name: %s position: %ld", | ||
| mi->master_log_name, | ||
|
|
@@ -811,7 +809,7 @@ int flush_master_info(Master_info* mi, | |
| of file we don't care about this garbage. | ||
| */ | ||
| char heartbeat_buf[FLOATING_POINT_BUFFER]; | ||
| my_fcvt(mi->heartbeat_period, 3, heartbeat_buf, NULL); | ||
| my_fcvt(mi->heartbeat_period/1000.0, 3, heartbeat_buf, NULL); | ||
| my_b_seek(file, 0L); | ||
| my_b_printf(file, | ||
| "%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n" | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2267,30 +2267,37 @@ master_def: | |||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| | MASTER_HEARTBEAT_PERIOD_SYM '=' NUM_literal | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| Lex->mi.heartbeat_period= (float) $3->val_real(); | ||||||||||||||||||||||||||||||
| if (unlikely(Lex->mi.heartbeat_period > | ||||||||||||||||||||||||||||||
| SLAVE_MAX_HEARTBEAT_PERIOD) || | ||||||||||||||||||||||||||||||
| unlikely(Lex->mi.heartbeat_period < 0.0)) | ||||||||||||||||||||||||||||||
| my_yyabort_error((ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, MYF(0), | ||||||||||||||||||||||||||||||
| SLAVE_MAX_HEARTBEAT_PERIOD)); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (unlikely(Lex->mi.heartbeat_period > slave_net_timeout)) | ||||||||||||||||||||||||||||||
| static const struct Decimal_from_double: my_decimal | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| Decimal_from_double(double value): my_decimal() | ||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I wonder why |
||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| int unexpected_error __attribute__((unused))= | ||||||||||||||||||||||||||||||
| double2my_decimal(E_DEC_ERROR, value, this); | ||||||||||||||||||||||||||||||
| DBUG_ASSERT(!unexpected_error); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } MAX_PERIOD= SLAVE_MAX_HEARTBEAT_PERIOD/1000.0, THOUSAND= 1000; | ||||||||||||||||||||||||||||||
|
Comment on lines
+2272
to
+2278
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||
| auto decimal_buffer= my_decimal(); | ||||||||||||||||||||||||||||||
| my_decimal *decimal= $3->val_decimal(&decimal_buffer); | ||||||||||||||||||||||||||||||
| if (!decimal || | ||||||||||||||||||||||||||||||
| decimal->sign() || decimal_cmp(&MAX_PERIOD, decimal) < 0) | ||||||||||||||||||||||||||||||
| my_yyabort_error((ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, MYF(0), | ||||||||||||||||||||||||||||||
| SLAVE_MAX_HEARTBEAT_PERIOD/1000)); | ||||||||||||||||||||||||||||||
| bool overprecise= decimal->frac > 3; | ||||||||||||||||||||||||||||||
| // decomposed from my_decimal2int() to reduce a bit of computations | ||||||||||||||||||||||||||||||
| auto rounded= my_decimal(); | ||||||||||||||||||||||||||||||
| int unexpected_error __attribute__((unused))= | ||||||||||||||||||||||||||||||
| decimal_round(decimal, &rounded, 3, HALF_UP) | | ||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think the compiler guarantees the order-of-operations with bitwise OR (i.e., the three functions involved here may run in any order, which is not what you intend, I think). I think this would be better served by or I think that it reads better as well (either way), as it is clear you are working with a single boolean outcome.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call; also affects #4430 |
||||||||||||||||||||||||||||||
| decimal_mul(&rounded, &THOUSAND, &decimal_buffer) | | ||||||||||||||||||||||||||||||
| decimal2ulonglong(&decimal_buffer, &(Lex->mi.heartbeat_period)); | ||||||||||||||||||||||||||||||
|
Comment on lines
+2290
to
+2291
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd suggest avoiding emotion in code comments, and stick to the facts. I.e., instead of
to something like
|
||||||||||||||||||||||||||||||
| DBUG_ASSERT(!unexpected_error); | ||||||||||||||||||||||||||||||
| if (unlikely(Lex->mi.heartbeat_period > slave_net_timeout*1000ULL)) | ||||||||||||||||||||||||||||||
| push_warning(thd, Sql_condition::WARN_LEVEL_WARN, | ||||||||||||||||||||||||||||||
| ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX, | ||||||||||||||||||||||||||||||
| ER_THD(thd, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX)); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| if (unlikely(Lex->mi.heartbeat_period < 0.001)) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| if (unlikely(Lex->mi.heartbeat_period != 0.0)) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| else if (unlikely(!Lex->mi.heartbeat_period && overprecise)) | ||||||||||||||||||||||||||||||
| push_warning(thd, Sql_condition::WARN_LEVEL_WARN, | ||||||||||||||||||||||||||||||
| ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN, | ||||||||||||||||||||||||||||||
| ER_THD(thd, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN)); | ||||||||||||||||||||||||||||||
| Lex->mi.heartbeat_period= 0.0; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| Lex->mi.heartbeat_opt= LEX_MASTER_INFO::LEX_MI_DISABLE; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| Lex->mi.heartbeat_opt= LEX_MASTER_INFO::LEX_MI_ENABLE; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| | IGNORE_SERVER_IDS_SYM '=' '(' ignore_server_id_list ')' | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Range testing of
master_heartbeat_periodis duplicated betweenrpl_heartbeat_basic(runs withmixonly) andrpl_heartbeat(tests all three binlog formats).