Skip to content

Commit 10a5138

Browse files
authored
Merge pull request #409 from percona/ps-9502
PS-9502 Redo binlogging-replication-improvements topic for 8.4
2 parents 6b50ea6 + 0e8c325 commit 10a5138

File tree

1 file changed

+97
-35
lines changed

1 file changed

+97
-35
lines changed

docs/binlogging-replication-improvements.md

+97-35
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,57 @@
11
# Binary logs and replication improvements
22

33
Due to continuous development, Percona Server for MySQL incorporated a number of
4-
improvements related to replication and binary logs handling. This resulted in replication specifics, which distinguishes it from *MySQL*.
4+
improvements related to replication and binary logs handling. This resulted in replication specifics, which distinguishes it from MySQL.
55

6-
## Safety of statements with a `LIMIT` clause
6+
## Statements with a `LIMIT` clause
77

8-
### Summary of the fix
8+
In MySQL 8.0, any UPDATE/DELETE/INSERT ... SELECT statements that include a LIMIT clause are indeed considered unsafe for statement-based replication. These statements will cause MySQL to automatically switch from statement-based logging to row-based logging if binlog_format is set to MIXED.
99

10-
*MySQL* considers all `UPDATE/DELETE/INSERT ... SELECT` statements with
11-
`LIMIT` clause to be unsafe, no matter wether they are really producing
12-
non-deterministic result or not, and switches from statement-based logging
13-
to row-based one. *Percona Server for MySQL* is more accurate, it acknowledges such
14-
instructions as safe when they include `ORDER BY PK` or `WHERE`
15-
condition. This fix has been ported from the upstream bug report
16-
[#42415](https://bugs.mysql.com/bug.php?id=42415) ([#44](https://jira.percona.com/browse/PS-44)).
10+
Here's why:
1711

18-
## Performance improvement on relay log position update
12+
* The LIMIT clause without an ORDER BY makes the result set non-deterministic
1913

20-
### Relay log position fix
14+
* The same statement might affect different rows on the primary and replicas
15+
16+
```sql
17+
UPDATE table1 LIMIT 10 SET col1 = 'value';
18+
DELETE FROM table1 LIMIT 5;
19+
INSERT INTO table2 SELECT * FROM table1 LIMIT 3;
20+
```
21+
22+
To make these statements safe for statement-based replication, you should do one of the following:
23+
24+
* Remove the LIMIT clause
25+
26+
* Add an ORDER BY clause to make the result set deterministic
27+
28+
```sql
29+
UPDATE table1 SET col1 = 'value' ORDER BY id LIMIT 10;
30+
DELETE FROM table1 ORDER BY id LIMIT 5;
31+
INSERT INTO table2 SELECT * FROM table1 ORDER BY id LIMIT 3;
32+
```
33+
34+
The exception is when the LIMIT is used with an ORDER BY clause that uses a unique key - in this case, the statement becomes deterministic and safe for statement-based replication.
35+
36+
Percona Server for MySQL acknowledges statements as safe when they include either an `ORDER BY PK` or `WHERE`
37+
condition.
38+
39+
40+
## Relay log position fix
2141

2242
*MySQL* always updated relay log position in multi-source replications setups
2343
regardless of whether the committed transaction has already been executed or
2444
not. Percona Server omits relay log position updates for the already logged
2545
GTIDs.
2646

27-
### Relay log position details
47+
## Relay log position details
2848

2949
Particularly, such unconditional relay log position updates caused additional
3050
fsync operations in case of `relay-log-info-repository=TABLE`, and with the
3151
higher number of channels transmitting such duplicate (already executed)
3252
transactions the situation became proportionally worse. Bug fixed [#1786](https://jira.percona.com/browse/PS-1786), (upstream [#85141](https://bugs.mysql.com/bug.php?id=85141)).
3353

34-
## Performance improvement on source and connection status updates
35-
36-
### Source and connection status update fix
54+
## Source and connection status update fix
3755

3856
Replica nodes configured to update source status and connection information
3957
only on log file rotation did not experience the expected reduction in load.
@@ -43,7 +61,7 @@ replication when replica had to skip the already executed GTID event.
4361
## Write `FLUSH` commands to the binary log
4462

4563
`FLUSH` commands, such as `FLUSH SLOW LOGS`, are not written to the
46-
binary log if the system variable binlog_skip_flush_commands is set
64+
binary log if the system variable `binlog_skip_flush_commands` is set
4765
to **ON**.
4866

4967
In addition, the following changes were implemented in the behavior of
@@ -71,17 +89,32 @@ regardless of the value of the binlog_skip_flush_commands variable.
7189
| Dynamic | Yes |
7290
| Default | OFF |
7391

74-
When binlog_skip_flush_commands is set to **ON**, `FLUSH ...` commands are not written to the binary
75-
log. See Writing FLUSH Commands to the Binary Log for more information
76-
about what else affects the writing of `FLUSH` commands to the binary log.
92+
When `binlog_skip_flush_commands` is set to **ON**, `FLUSH ...` commands are not written to the binary
93+
log.
94+
95+
The `binlog_skip_flush_commands` setting does not affect the following commands because they are not written to binary log:
96+
97+
• `FLUSH LOGS`
98+
99+
• `FLUSH BINARY LOGS`
100+
101+
• `FLUSH TABLES WITH READ LOCK`
102+
103+
• `FLUSH TABLES ... FOR EXPORT`
104+
77105

78-
!!! note
106+
The `FLUSH` command does not record to the binary log, and it ignores the `binlog_skip_flush_commands` value when you run it with the `NO_WRITE_TO_BINLOG` keyword (or its alias `LOCAL`).
79107

80-
`FLUSH LOGS`, `FLUSH BINARY LOGS`, `FLUSH TABLES WITH READ LOCK`, and `FLUSH TABLES ... FOR EXPORT` are not written to the binary log no matter what value the binlog_skip_flush_commands variable contains. The `FLUSH` command is not recorded to the binary log and the value of binlog_skip_flush_commands is ignored if the `FLUSH` command is run with the `NO_WRITE_TO_BINLOG` keyword (or its alias `LOCAL`).
108+
## Keep comments with DDL commands
81109

82-
## Maintaining comments with DROP TABLE
110+
When you run a DDL command, such as `DROP TABLE`, the server does the following in the binary log.
83111

84-
When you issue a `DROP TABLE` command, the binary log stores the command but removes comments and encloses the table name in quotation marks. If you require the binary log to maintain the comments and not add quotation marks, enable `binlog_ddl_skip_rewrite`.
112+
| Actions | Description |
113+
|---|---|
114+
| Removes Comments | The server deletes any comments in the original command. For example, if you use `DROP TABLE my_table /* This is a comment */;`, the binary log does not save the comment. |
115+
| Adds Quotation Marks | The server puts quotation marks around the table name. So, if you run `DROP TABLE my_table;`, it logs it as `DROP TABLE "my_table";`. |
116+
117+
These actions simplify the logging format, but sometimes, you want the original format.
85118

86119
### binlog_ddl_skip_rewrite
87120

@@ -93,7 +126,38 @@ When you issue a `DROP TABLE` command, the binary log stores the command but rem
93126
| Dynamic | Yes |
94127
| Default | OFF |
95128

96-
If the variable is enabled, single table `DROP TABLE` DDL statements are logged in the binary log with comments. Multi-table `DROP TABLE` DDL statements are not supported and return an error.
129+
When disabled (default setting), the server removes comments and adds quotation marks.
130+
131+
If the variable is enabled, all single table `DROP TABLE` DDL statements are logged in the binary log with the following:
132+
133+
• Comments are preserved, so any notes you add to the command stay in the binary log.
134+
135+
• Quotation marks are not added.
136+
137+
138+
You can enable `binlog_ddl_skip_rewrite` at runtime:
139+
140+
```sql
141+
-- Check current setting
142+
SHOW VARIABLES LIKE 'binlog_ddl_skip_rewrite';
143+
144+
-- Enable feature
145+
SET GLOBAL binlog_ddl_skip_rewrite = ON;
146+
147+
-- Disable feature
148+
SET GLOBAL binlog_ddl_skip_rewrite = OFF;
149+
```
150+
151+
You can enable it permanently by adding it to the my.cnf configuration file:
152+
153+
```text
154+
[mysqld]
155+
binlog_ddl_skip_rewrite = ON
156+
```
157+
158+
After adding the statement to the configuration file, restart the MySQL service.
159+
160+
Multi-table `DROP TABLE` DDL statements are not supported and return an error.
97161

98162
```sql
99163
SET binlog_ddl_skip_rewrite = ON;
@@ -113,9 +177,7 @@ To implement Point in Time recovery, we have added the `binlog_utils_udf`. The f
113177
| get_first_record_timestamp_by_binlog() | Timestamp as INTEGER | Returns the timestamp of the first event in the specified binlog |
114178
| get_last_record_timestamp_by_binlog() | Timestamp as INTEGER | Returns the timestamp of the last event in the specified binlog |
115179

116-
!!! note
117-
118-
All functions returning timestamps return their values as microsecond precision UNIX time. In other words, they represent the number of microseconds since 1-JAN-1970.
180+
All functions returning timestamps return their values as microsecond precision UNIX time. In other words, they represent the number of microseconds since 1-JAN-1970.
119181

120182
All functions accepting a binlog name as the parameter accepts only short names, without a path component. If the path separator (‘/’) is found in the input, an error is returned. This serves the purpose of restricting the locations from where binlogs can be read. They are always read from the current binlog directory ([@@log_bin_basename system variable]).
121183

@@ -127,7 +189,7 @@ The basic syntax for `get_binlog_by_gtid()` is the following:
127189

128190
Usage: SELECT get_binlog_by_gtid(string) [AS] alias
129191

130-
Example:
192+
An example of using the `get_binlog_gtid` command:
131193

132194
```sql
133195
CREATE FUNCTION get_binlog_by_gtid RETURNS STRING SONAME 'binlog_utils_udf.so';
@@ -153,7 +215,7 @@ The basic syntax for `get_last_gtid_from_binlog()` is the following:
153215

154216
Usage: SELECT get_last_gtid_from_binlog(string) [AS] alias
155217

156-
For example:
218+
An example of using the `get_last_gtid_from_binlog` command:
157219

158220
```sql
159221
CREATE FUNCTION get_last_gtid_from_binlog RETURNS STRING SONAME 'binlog_utils_udf.so';
@@ -180,7 +242,7 @@ The basic syntax for `get_gtid_set_by_binlog()` is the following:
180242

181243
Usage: SELECT get_gtid_set_by_binlog(string) [AS] alias
182244

183-
For example:
245+
An example of using the `get_gtid_set_by_binlog` command:
184246

185247
```sql
186248
CREATE FUNCTION get_gtid_set_by_binlog RETURNS STRING SONAME 'binlog_utils_udf.so';
@@ -207,7 +269,7 @@ The basic syntax for `get_binlog_by_gtid_set()` is the following:
207269

208270
Usage: SELECT get_binlog_by_gtid_set(string) [AS] alias
209271

210-
Example:
272+
An example of using the `get_binlog_by_gtid_set` command:
211273

212274
```sql
213275
CREATE FUNCTION get_binlog_by_gtid_set RETURNS STRING SONAME 'binlog_utils_udf.so';
@@ -233,7 +295,7 @@ The basic syntax for `get_first_record_timestamp_by_binlog()` is the following:
233295

234296
Usage: SELECT get_first_record_timestamp_by_binlog(TIMESTAMP) [AS] alias
235297

236-
For example:
298+
An example of using the `get_first_record_timestamp_by_binlog` command:
237299

238300
```sql
239301
CREATE FUNCTION get_first_record_timestamp_by_binlog RETURNS INTEGER SONAME 'binlog_utils_udf.so';
@@ -260,7 +322,7 @@ The basic syntax for `get_last_record_timestamp_by_binlog()` is the following:
260322

261323
Usage: SELECT get_last_record_timestamp_by_binlog(TIMESTAMP) [AS] alias
262324

263-
For example:
325+
An example of using the `get_last_record_timestamp_by_binlog` command:
264326

265327
```sql
266328
CREATE FUNCTION get_last_record_timestamp_by_binlog RETURNS INTEGER SONAME 'binlog_utils_udf.so';
@@ -289,7 +351,7 @@ For the following variables, do not define values with one or more dot (.) chara
289351

290352
* [log_bin_index]
291353

292-
A value defined with these characters is handled differently in *MySQL* and Percona XtraBackup and can cause unpredictable behavior.
354+
A value defined with the dot (.) character is handled differently in MySQL and Percona XtraBackup and can cause unpredictable behavior.
293355

294356
[@@log_bin_basename system variable]: https://dev.mysql.com/doc/refman/{{vers}}/en/replication-options-binary-log.html#sysvar_log_bin_basename
295357

0 commit comments

Comments
 (0)