@powersync/service-module-mysql 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/api/MySQLRouteAPIAdapter.js +3 -3
- package/dist/api/MySQLRouteAPIAdapter.js.map +1 -1
- package/dist/common/ReplicatedGTID.d.ts +16 -9
- package/dist/common/ReplicatedGTID.js +49 -25
- package/dist/common/ReplicatedGTID.js.map +1 -1
- package/dist/common/check-source-configuration.js +11 -0
- package/dist/common/check-source-configuration.js.map +1 -1
- package/dist/common/read-executed-gtid.d.ts +11 -1
- package/dist/common/read-executed-gtid.js +67 -5
- package/dist/common/read-executed-gtid.js.map +1 -1
- package/dist/replication/BinLogStream.d.ts +2 -0
- package/dist/replication/BinLogStream.js +42 -14
- package/dist/replication/BinLogStream.js.map +1 -1
- package/dist/replication/zongji/BinLogListener.d.ts +17 -2
- package/dist/replication/zongji/BinLogListener.js +42 -29
- package/dist/replication/zongji/BinLogListener.js.map +1 -1
- package/package.json +4 -4
- package/src/api/MySQLRouteAPIAdapter.ts +4 -4
- package/src/common/ReplicatedGTID.ts +65 -32
- package/src/common/check-source-configuration.ts +15 -0
- package/src/common/read-executed-gtid.ts +76 -6
- package/src/replication/BinLogStream.ts +45 -14
- package/src/replication/zongji/BinLogListener.ts +61 -29
- package/test/src/BinLogListener.test.ts +18 -0
- package/test/src/ReplicatedGTID.test.ts +138 -0
- package/test/src/check-source-configuration.test.ts +70 -0
- package/test/src/read-executed-gtid.test.ts +188 -0
- package/test/src/util.ts +25 -2
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @powersync/service-module-mysql
|
|
2
2
|
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 41dcd7a: Improve MySQL GTID consistency and resume safety. PowerSync now derives replication heads from the active server's executed GTID set, validates stored GTIDs and binlog coordinates before resuming, and re-snapshots after source rewinds or server UUID changes. Replica sources and foreign-origin binlog transactions are rejected until multi-origin transaction ordering is supported, while heartbeat keepalives use the last committed position to prevent idle checkpoint stalls.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [27b56cb]
|
|
12
|
+
- Updated dependencies [798d739]
|
|
13
|
+
- @powersync/service-core@1.25.0
|
|
14
|
+
|
|
3
15
|
## 0.15.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
|
@@ -224,11 +224,11 @@ export class MySQLRouteAPIAdapter {
|
|
|
224
224
|
async getReplicationLagBytes(options) {
|
|
225
225
|
const { bucketStorage } = options;
|
|
226
226
|
const lastCheckpoint = await bucketStorage.getCheckpoint();
|
|
227
|
-
const current = lastCheckpoint.lsn
|
|
228
|
-
? common.ReplicatedGTID.fromSerialized(lastCheckpoint.lsn)
|
|
229
|
-
: common.ReplicatedGTID.ZERO;
|
|
230
227
|
const connection = await this.pool.getConnection();
|
|
231
228
|
const head = await common.readExecutedGtid(connection);
|
|
229
|
+
const current = lastCheckpoint.lsn
|
|
230
|
+
? common.ReplicatedGTID.fromSerialized(lastCheckpoint.lsn)
|
|
231
|
+
: common.ReplicatedGTID.ZERO(await common.readServerUuid(connection));
|
|
232
232
|
const lag = await current.distanceTo(connection, head);
|
|
233
233
|
connection.release();
|
|
234
234
|
if (lag == null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MySQLRouteAPIAdapter.js","sourceRoot":"","sources":["../../src/api/MySQLRouteAPIAdapter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"MySQLRouteAPIAdapter.js","sourceRoot":"","sources":["../../src/api/MySQLRouteAPIAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,18 +4,22 @@ export type BinLogPosition = {
|
|
|
4
4
|
offset: number;
|
|
5
5
|
};
|
|
6
6
|
export type ReplicatedGTIDSpecification = {
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The raw Global Transaction ID. This is of the format `server_uuid:transaction_id`.
|
|
9
|
+
* Must be a single GTID — not a GTID set (multiple UUIDs) or interval range.
|
|
10
|
+
*/
|
|
11
|
+
rawGtid: string;
|
|
8
12
|
/**
|
|
9
13
|
* The (end) position in a BinLog file where this transaction has been replicated in.
|
|
10
14
|
*/
|
|
11
15
|
position: BinLogPosition;
|
|
12
16
|
};
|
|
13
17
|
export type BinLogGTIDFormat = {
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
serverUuid: Buffer;
|
|
19
|
+
transactionId: number;
|
|
16
20
|
};
|
|
17
21
|
export type BinLogGTIDEvent = {
|
|
18
|
-
|
|
22
|
+
rawGtid: BinLogGTIDFormat;
|
|
19
23
|
position: BinLogPosition;
|
|
20
24
|
};
|
|
21
25
|
/**
|
|
@@ -24,24 +28,27 @@ export type BinLogGTIDEvent = {
|
|
|
24
28
|
* and position where this GTID could be located.
|
|
25
29
|
*/
|
|
26
30
|
export declare class ReplicatedGTID {
|
|
27
|
-
|
|
31
|
+
private options;
|
|
32
|
+
constructor(options: ReplicatedGTIDSpecification);
|
|
28
33
|
static fromSerialized(comparable: string): ReplicatedGTID;
|
|
29
34
|
private static deserialize;
|
|
30
35
|
static fromBinLogEvent(event: BinLogGTIDEvent): ReplicatedGTID;
|
|
31
36
|
/**
|
|
32
37
|
* Special case for the zero GTID which means no transactions have been executed.
|
|
33
38
|
*/
|
|
34
|
-
static ZERO: ReplicatedGTID;
|
|
35
|
-
constructor(options: ReplicatedGTIDSpecification);
|
|
39
|
+
static ZERO(serverUuid: string): ReplicatedGTID;
|
|
36
40
|
/**
|
|
37
41
|
* Get the BinLog position of this replicated GTID event
|
|
38
42
|
*/
|
|
39
43
|
get position(): BinLogPosition;
|
|
40
44
|
/**
|
|
41
|
-
* Get the raw Global Transaction ID. This of the format `
|
|
45
|
+
* Get the raw Global Transaction ID. This is of the format `server_uuid:transaction_id`
|
|
42
46
|
*/
|
|
43
47
|
get raw(): string;
|
|
44
|
-
|
|
48
|
+
/**
|
|
49
|
+
* The server UUID of the server this transaction originated from
|
|
50
|
+
*/
|
|
51
|
+
get serverUuid(): string;
|
|
45
52
|
/**
|
|
46
53
|
* Transforms a GTID into a comparable string format, ensuring lexicographical
|
|
47
54
|
* order aligns with the GTID's relative age. This assumes that all GTIDs
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ReplicationAssertionError } from '@powersync/lib-services-framework';
|
|
1
2
|
import * as uuid from 'uuid';
|
|
2
3
|
import * as mysql_utils from '../utils/mysql-utils.js';
|
|
3
4
|
/**
|
|
@@ -7,36 +8,47 @@ import * as mysql_utils from '../utils/mysql-utils.js';
|
|
|
7
8
|
*/
|
|
8
9
|
export class ReplicatedGTID {
|
|
9
10
|
options;
|
|
11
|
+
constructor(options) {
|
|
12
|
+
const rawGtid = options.rawGtid.trim();
|
|
13
|
+
assertSingleGtid(rawGtid);
|
|
14
|
+
this.options = { ...options, rawGtid };
|
|
15
|
+
}
|
|
10
16
|
static fromSerialized(comparable) {
|
|
11
17
|
return new ReplicatedGTID(ReplicatedGTID.deserialize(comparable));
|
|
12
18
|
}
|
|
13
19
|
static deserialize(comparable) {
|
|
14
20
|
const components = comparable.split('|');
|
|
15
|
-
if (components.length <
|
|
16
|
-
throw new
|
|
21
|
+
if (components.length < 4) {
|
|
22
|
+
throw new ReplicationAssertionError(`Invalid serialized GTID: ${comparable}`);
|
|
23
|
+
}
|
|
24
|
+
const offset = parseInt(components[3], 10);
|
|
25
|
+
if (Number.isNaN(offset)) {
|
|
26
|
+
throw new ReplicationAssertionError(`Invalid BinLog offset in serialized GTID: ${comparable}`);
|
|
17
27
|
}
|
|
18
28
|
return {
|
|
19
|
-
|
|
29
|
+
rawGtid: components[1],
|
|
20
30
|
position: {
|
|
21
31
|
filename: components[2],
|
|
22
|
-
offset:
|
|
32
|
+
offset: offset
|
|
23
33
|
}
|
|
24
34
|
};
|
|
25
35
|
}
|
|
26
36
|
static fromBinLogEvent(event) {
|
|
27
|
-
const {
|
|
28
|
-
const stringGTID = `${uuid.stringify(
|
|
37
|
+
const { rawGtid, position } = event;
|
|
38
|
+
const stringGTID = `${uuid.stringify(rawGtid.serverUuid)}:${rawGtid.transactionId}`;
|
|
29
39
|
return new ReplicatedGTID({
|
|
30
|
-
|
|
40
|
+
rawGtid: stringGTID,
|
|
31
41
|
position
|
|
32
42
|
});
|
|
33
43
|
}
|
|
34
44
|
/**
|
|
35
45
|
* Special case for the zero GTID which means no transactions have been executed.
|
|
36
46
|
*/
|
|
37
|
-
static ZERO
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
static ZERO(serverUuid) {
|
|
48
|
+
return new ReplicatedGTID({
|
|
49
|
+
rawGtid: `${serverUuid}:0`,
|
|
50
|
+
position: { filename: '', offset: 0 }
|
|
51
|
+
});
|
|
40
52
|
}
|
|
41
53
|
/**
|
|
42
54
|
* Get the BinLog position of this replicated GTID event
|
|
@@ -45,13 +57,16 @@ export class ReplicatedGTID {
|
|
|
45
57
|
return this.options.position;
|
|
46
58
|
}
|
|
47
59
|
/**
|
|
48
|
-
* Get the raw Global Transaction ID. This of the format `
|
|
60
|
+
* Get the raw Global Transaction ID. This is of the format `server_uuid:transaction_id`
|
|
49
61
|
*/
|
|
50
62
|
get raw() {
|
|
51
|
-
return this.options.
|
|
63
|
+
return this.options.rawGtid;
|
|
52
64
|
}
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
/**
|
|
66
|
+
* The server UUID of the server this transaction originated from
|
|
67
|
+
*/
|
|
68
|
+
get serverUuid() {
|
|
69
|
+
return this.options.rawGtid.split(':')[0];
|
|
55
70
|
}
|
|
56
71
|
/**
|
|
57
72
|
* Transforms a GTID into a comparable string format, ensuring lexicographical
|
|
@@ -63,17 +78,8 @@ export class ReplicatedGTID {
|
|
|
63
78
|
*/
|
|
64
79
|
get comparable() {
|
|
65
80
|
const { raw, position } = this;
|
|
66
|
-
const [,
|
|
67
|
-
|
|
68
|
-
if (!transactionRanges) {
|
|
69
|
-
return ReplicatedGTID.ZERO.comparable;
|
|
70
|
-
}
|
|
71
|
-
let maxTransactionId = 0;
|
|
72
|
-
for (const range of transactionRanges.split(',')) {
|
|
73
|
-
const [start, end] = range.split('-');
|
|
74
|
-
maxTransactionId = Math.max(maxTransactionId, parseInt(start, 10), parseInt(end || start, 10));
|
|
75
|
-
}
|
|
76
|
-
const paddedTransactionId = maxTransactionId.toString().padStart(16, '0');
|
|
81
|
+
const [, transactionId] = this.raw.split(':');
|
|
82
|
+
const paddedTransactionId = transactionId.toString().padStart(16, '0');
|
|
77
83
|
return [paddedTransactionId, raw, position.filename, position.offset].join('|');
|
|
78
84
|
}
|
|
79
85
|
toString() {
|
|
@@ -112,4 +118,22 @@ export class ReplicatedGTID {
|
|
|
112
118
|
logFiles.slice(startFileIndex + 1, endFileIndex).reduce((sum, file) => sum + file['File_size'], 0));
|
|
113
119
|
}
|
|
114
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Asserts that the given gtid string is a single GTID of the form `server_uuid:transaction_id`,
|
|
123
|
+
* not a GTID set such as `uuid:1-17` or `uuid1:1,uuid2:2`.
|
|
124
|
+
*/
|
|
125
|
+
function assertSingleGtid(gtid) {
|
|
126
|
+
// GTID sets join UUID sets with commas (often with newlines: `,\n`).
|
|
127
|
+
if (gtid.includes(',') || gtid.includes('\n')) {
|
|
128
|
+
throw new ReplicationAssertionError(`Expected a single GTID (server_uuid:transaction_id), got a GTID set: ${gtid}`);
|
|
129
|
+
}
|
|
130
|
+
const parts = gtid.split(':');
|
|
131
|
+
if (parts.length !== 2 || parts[0].length === 0 || parts[1].length === 0) {
|
|
132
|
+
throw new ReplicationAssertionError(`Expected a single GTID (server_uuid:transaction_id), got: ${gtid}`);
|
|
133
|
+
}
|
|
134
|
+
// Intervals use `n-m`; a single transaction id must be a non-negative integer.
|
|
135
|
+
if (!/^\d+$/.test(parts[1])) {
|
|
136
|
+
throw new ReplicationAssertionError(`Expected a single transaction id, got: ${gtid}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
115
139
|
//# sourceMappingURL=ReplicatedGTID.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReplicatedGTID.js","sourceRoot":"","sources":["../../src/common/ReplicatedGTID.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ReplicatedGTID.js","sourceRoot":"","sources":["../../src/common/ReplicatedGTID.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import * as mysql_utils from '../utils/mysql-utils.js';
|
|
2
2
|
const MIN_SUPPORTED_VERSION = '5.7.0';
|
|
3
|
+
const REPLICA_TERMINOLOGY_VERSION = '8.0.22';
|
|
3
4
|
export async function checkSourceConfiguration(connection) {
|
|
4
5
|
const errors = [];
|
|
5
6
|
const version = await mysql_utils.getMySQLVersion(connection);
|
|
6
7
|
if (!mysql_utils.isVersionAtLeast(version, MIN_SUPPORTED_VERSION)) {
|
|
7
8
|
errors.push(`MySQL versions older than ${MIN_SUPPORTED_VERSION} are not supported. Your version is: ${version}.`);
|
|
8
9
|
}
|
|
10
|
+
const replicaStatusQuery = mysql_utils.isVersionAtLeast(version, REPLICA_TERMINOLOGY_VERSION)
|
|
11
|
+
? 'SHOW REPLICA STATUS'
|
|
12
|
+
: 'SHOW SLAVE STATUS';
|
|
13
|
+
const [replicaStatuses] = await mysql_utils.retriedQuery({
|
|
14
|
+
connection,
|
|
15
|
+
query: replicaStatusQuery
|
|
16
|
+
});
|
|
17
|
+
if (replicaStatuses.length > 0) {
|
|
18
|
+
errors.push('Connecting PowerSync to a MySQL replica is not supported. Please connect PowerSync directly to the primary server.');
|
|
19
|
+
}
|
|
9
20
|
const [[result]] = await mysql_utils.retriedQuery({
|
|
10
21
|
connection,
|
|
11
22
|
query: `
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-source-configuration.js","sourceRoot":"","sources":["../../src/common/check-source-configuration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAEvD,MAAM,qBAAqB,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"check-source-configuration.js","sourceRoot":"","sources":["../../src/common/check-source-configuration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAEvD,MAAM,qBAAqB,GAAG,OAAO,CAAC;AACtC,MAAM,2BAA2B,GAAG,QAAQ,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,UAAmC;IAChF,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IAC9D,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,CAAC,EAAE,CAAC;QAClE,MAAM,CAAC,IAAI,CAAC,6BAA6B,qBAAqB,wCAAwC,OAAO,GAAG,CAAC,CAAC;IACpH,CAAC;IAED,MAAM,kBAAkB,GAAG,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,2BAA2B,CAAC;QAC3F,CAAC,CAAC,qBAAqB;QACvB,CAAC,CAAC,mBAAmB,CAAC;IACxB,MAAM,CAAC,eAAe,CAAC,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC;QACvD,UAAU;QACV,KAAK,EAAE,kBAAkB;KAC1B,CAAC,CAAC;IAEH,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CACT,oHAAoH,CACrH,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC;QAChD,UAAU;QACV,KAAK,EAAE;;;;;;;OAOJ;KACJ,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,+CAA+C,MAAM,CAAC,SAAS,qBAAqB,CAAC,CAAC;IACpG,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CACT,iFAAiF,MAAM,CAAC,SAAS,sCAAsC,CACxI,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;IAC/E,CAAC;IAED,oBAAoB;IACpB,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC;QAC5D,UAAU;QACV,KAAK,EAAE,sCAAsC;KAC9C,CAAC,CAAC;IAEH,IAAI,kBAAkB,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;IAC5F,CAAC;IAED,6CAA6C;IAC7C,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC;QACxD,UAAU;QACV,KAAK,EAAE,gDAAgD;KACxD,CAAC,CAAC;IAEH,IAAI,cAAc,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;QAClD,MAAM,CAAC,IAAI,CACT,mEAAmE,cAAc,CAAC,KAAK,IAAI,SAAS,IAAI;YACtG,iFAAiF;YACjF,4EAA4E,CAC/E,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import mysqlPromise from 'mysql2/promise';
|
|
2
2
|
import { ReplicatedGTID } from './ReplicatedGTID.js';
|
|
3
|
+
/**
|
|
4
|
+
* Gets the `@@server_uuid` of the current connected server
|
|
5
|
+
*/
|
|
6
|
+
export declare function readServerUuid(connection: mysqlPromise.Connection): Promise<string>;
|
|
3
7
|
/**
|
|
4
8
|
* Gets the current master HEAD GTID
|
|
5
9
|
*/
|
|
6
10
|
export declare function readExecutedGtid(connection: mysqlPromise.Connection): Promise<ReplicatedGTID>;
|
|
7
|
-
export declare function
|
|
11
|
+
export declare function getLatestActiveGtid(gtidSets: string[], activeServerUuid: string): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Checks that a stored resume GTID is still part of the server's executed history and that its
|
|
14
|
+
* binlog coordinate is still readable. This detects source rewinds where a restored server keeps
|
|
15
|
+
* the same UUID or recreates a binlog with the same filename but a shorter length.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isGtidPositionStillAvailable(connection: mysqlPromise.Connection, gtid: ReplicatedGTID): Promise<boolean>;
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import * as mysql_utils from '../utils/mysql-utils.js';
|
|
2
2
|
import { ReplicatedGTID } from './ReplicatedGTID.js';
|
|
3
|
+
/**
|
|
4
|
+
* Gets the `@@server_uuid` of the current connected server
|
|
5
|
+
*/
|
|
6
|
+
export async function readServerUuid(connection) {
|
|
7
|
+
const [[result]] = await mysql_utils.retriedQuery({
|
|
8
|
+
connection,
|
|
9
|
+
query: `SELECT @@server_uuid AS server_uuid`
|
|
10
|
+
});
|
|
11
|
+
return result.server_uuid;
|
|
12
|
+
}
|
|
3
13
|
/**
|
|
4
14
|
* Gets the current master HEAD GTID
|
|
5
15
|
*/
|
|
@@ -25,17 +35,69 @@ export async function readExecutedGtid(connection) {
|
|
|
25
35
|
filename: binlogStatus.File,
|
|
26
36
|
offset: parseInt(binlogStatus.Position)
|
|
27
37
|
};
|
|
38
|
+
const activeServerUuid = await readServerUuid(connection);
|
|
39
|
+
const executedGtidSet = binlogStatus.Executed_Gtid_Set.trim();
|
|
40
|
+
if (executedGtidSet.length === 0) {
|
|
41
|
+
// New server with no transactions executed yet. Keep the current binlog
|
|
42
|
+
// coordinate so this synthetic GTID can still be validated after a restart.
|
|
43
|
+
return new ReplicatedGTID({
|
|
44
|
+
rawGtid: `${activeServerUuid}:0`,
|
|
45
|
+
position
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const gtidSets = executedGtidSet.split(',');
|
|
49
|
+
const latestActiveGtid = await getLatestActiveGtid(gtidSets, activeServerUuid);
|
|
28
50
|
return new ReplicatedGTID({
|
|
29
|
-
|
|
30
|
-
position
|
|
31
|
-
raw_gtid: binlogStatus.Executed_Gtid_Set
|
|
51
|
+
rawGtid: latestActiveGtid,
|
|
52
|
+
position
|
|
32
53
|
});
|
|
33
54
|
}
|
|
34
|
-
export async function
|
|
55
|
+
export async function getLatestActiveGtid(gtidSets, activeServerUuid) {
|
|
56
|
+
for (const gtidSet of gtidSets) {
|
|
57
|
+
const [serverUuid, ...intervals] = gtidSet.trim().split(':');
|
|
58
|
+
if (serverUuid === activeServerUuid) {
|
|
59
|
+
let maxTransactionId = null;
|
|
60
|
+
for (const interval of intervals) {
|
|
61
|
+
const [start, end] = interval.split('-');
|
|
62
|
+
const startId = parseInt(start, 10);
|
|
63
|
+
const endId = end !== undefined ? parseInt(end, 10) : startId;
|
|
64
|
+
if (!Number.isNaN(startId)) {
|
|
65
|
+
maxTransactionId = Math.max(maxTransactionId ?? 0, startId);
|
|
66
|
+
}
|
|
67
|
+
if (!Number.isNaN(endId)) {
|
|
68
|
+
maxTransactionId = Math.max(maxTransactionId ?? 0, endId);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return activeServerUuid + ':' + maxTransactionId;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return `${activeServerUuid}:0`;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Checks that a stored resume GTID is still part of the server's executed history and that its
|
|
78
|
+
* binlog coordinate is still readable. This detects source rewinds where a restored server keeps
|
|
79
|
+
* the same UUID or recreates a binlog with the same filename but a shorter length.
|
|
80
|
+
*/
|
|
81
|
+
export async function isGtidPositionStillAvailable(connection, gtid) {
|
|
35
82
|
const [logFiles] = await mysql_utils.retriedQuery({
|
|
36
83
|
connection,
|
|
37
84
|
query: `SHOW BINARY LOGS;`
|
|
38
85
|
});
|
|
39
|
-
|
|
86
|
+
const logFile = logFiles.find((file) => file['Log_name'] == gtid.position.filename);
|
|
87
|
+
if (!logFile || Number(logFile['File_size']) < gtid.position.offset) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
// Transaction zero is PowerSync's synthetic position before the first
|
|
91
|
+
// transaction from this server UUID. It is not valid MySQL GTID_SET syntax,
|
|
92
|
+
// so its availability is determined by the binlog coordinate above.
|
|
93
|
+
if (gtid.raw.split(':')[1] === '0') {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
const [[result]] = await mysql_utils.retriedQuery({
|
|
97
|
+
connection,
|
|
98
|
+
query: `SELECT GTID_SUBSET(?, @@GLOBAL.gtid_executed) AS is_executed`,
|
|
99
|
+
params: [gtid.raw]
|
|
100
|
+
});
|
|
101
|
+
return result.is_executed === 1;
|
|
40
102
|
}
|
|
41
103
|
//# sourceMappingURL=read-executed-gtid.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-executed-gtid.js","sourceRoot":"","sources":["../../src/common/read-executed-gtid.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,UAAmC;IACxE,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IAE9D,IAAI,YAAwC,CAAC;IAC7C,IAAI,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;QACnD,8CAA8C;QAC9C,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC;YACtD,UAAU;YACV,KAAK,EAAE,wBAAwB;SAChC,CAAC,CAAC;QACH,YAAY,GAAG,YAAY,CAAC;IAC9B,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC;YACtD,UAAU;YACV,KAAK,EAAE,oBAAoB;SAC5B,CAAC,CAAC;QACH,YAAY,GAAG,YAAY,CAAC;IAC9B,CAAC;IACD,MAAM,QAAQ,GAAG;QACf,QAAQ,EAAE,YAAY,CAAC,IAAI;QAC3B,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC;KACxC,CAAC;IAEF,
|
|
1
|
+
{"version":3,"file":"read-executed-gtid.js","sourceRoot":"","sources":["../../src/common/read-executed-gtid.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,7 @@ export declare class BinLogStream {
|
|
|
21
21
|
private readonly connections;
|
|
22
22
|
private readonly abortSignal;
|
|
23
23
|
private readonly logger;
|
|
24
|
+
private activeServerUuid;
|
|
24
25
|
private tableCache;
|
|
25
26
|
private replicationLag;
|
|
26
27
|
constructor(options: BinLogStreamOptions);
|
|
@@ -45,6 +46,7 @@ export declare class BinLogStream {
|
|
|
45
46
|
startInitialReplication(): Promise<void>;
|
|
46
47
|
private snapshotTable;
|
|
47
48
|
replicate(): Promise<void>;
|
|
49
|
+
private ensureActiveServerUuid;
|
|
48
50
|
initReplication(): Promise<void>;
|
|
49
51
|
private getTables;
|
|
50
52
|
streamChanges(): Promise<void>;
|
|
@@ -27,6 +27,7 @@ export class BinLogStream {
|
|
|
27
27
|
connections;
|
|
28
28
|
abortSignal;
|
|
29
29
|
logger;
|
|
30
|
+
activeServerUuid = null;
|
|
30
31
|
tableCache = new Map();
|
|
31
32
|
replicationLag = new ReplicationLagTracker();
|
|
32
33
|
constructor(options) {
|
|
@@ -145,14 +146,18 @@ export class BinLogStream {
|
|
|
145
146
|
if (status.snapshotDone) {
|
|
146
147
|
this.logger.info(`Initial replication already done.`);
|
|
147
148
|
if (lastKnowGTID) {
|
|
148
|
-
// Check if the specific binlog file is still available. If it isn't, we need to snapshot again.
|
|
149
149
|
const connection = await this.connections.getConnection();
|
|
150
150
|
try {
|
|
151
|
-
|
|
151
|
+
// Check if the active server uuid matches the one in the GTID
|
|
152
|
+
if (this.activeServerUuid !== lastKnowGTID.serverUuid) {
|
|
153
|
+
this.logger.info(`The source server uuid has changed. Active server uuid ${this.activeServerUuid} does not match the server uuid from the resume checkpoint: ${lastKnowGTID.serverUuid}, re-snapshotting to ensure consistency.`);
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const isAvailable = await common.isGtidPositionStillAvailable(connection, lastKnowGTID);
|
|
152
157
|
if (!isAvailable) {
|
|
153
|
-
this.logger.info(`
|
|
158
|
+
this.logger.info(`Resume GTID ${lastKnowGTID.raw} at ${lastKnowGTID.position.filename}:${lastKnowGTID.position.offset} is no longer present in the executed GTID history or available BinLogs, re-snapshotting to ensure consistency.`);
|
|
159
|
+
return false;
|
|
154
160
|
}
|
|
155
|
-
return isAvailable;
|
|
156
161
|
}
|
|
157
162
|
finally {
|
|
158
163
|
connection.release();
|
|
@@ -184,7 +189,7 @@ export class BinLogStream {
|
|
|
184
189
|
const sourceTables = this.syncRules.getSourceTables();
|
|
185
190
|
const flushResults = await this.storage.startBatch({
|
|
186
191
|
logger: this.logger,
|
|
187
|
-
zeroLSN: common.ReplicatedGTID.ZERO.comparable,
|
|
192
|
+
zeroLSN: common.ReplicatedGTID.ZERO(this.activeServerUuid).comparable,
|
|
188
193
|
defaultSchema: this.defaultSchema,
|
|
189
194
|
storeCurrentData: false
|
|
190
195
|
}, async (batch) => {
|
|
@@ -264,7 +269,19 @@ export class BinLogStream {
|
|
|
264
269
|
throw e;
|
|
265
270
|
}
|
|
266
271
|
}
|
|
272
|
+
async ensureActiveServerUuid() {
|
|
273
|
+
if (this.activeServerUuid == null) {
|
|
274
|
+
const connection = await this.connections.getConnection();
|
|
275
|
+
try {
|
|
276
|
+
this.activeServerUuid = await common.readServerUuid(connection);
|
|
277
|
+
}
|
|
278
|
+
finally {
|
|
279
|
+
connection.release();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
267
283
|
async initReplication() {
|
|
284
|
+
await this.ensureActiveServerUuid();
|
|
268
285
|
const connection = await this.connections.getConnection();
|
|
269
286
|
const errors = await common.checkSourceConfiguration(connection);
|
|
270
287
|
connection.release();
|
|
@@ -281,7 +298,7 @@ export class BinLogStream {
|
|
|
281
298
|
const sourceTables = this.syncRules.getSourceTables();
|
|
282
299
|
await this.storage.startBatch({
|
|
283
300
|
logger: this.logger,
|
|
284
|
-
zeroLSN: common.ReplicatedGTID.ZERO.comparable,
|
|
301
|
+
zeroLSN: common.ReplicatedGTID.ZERO(this.activeServerUuid).comparable,
|
|
285
302
|
defaultSchema: this.defaultSchema,
|
|
286
303
|
storeCurrentData: false
|
|
287
304
|
}, async (batch) => {
|
|
@@ -301,18 +318,28 @@ export class BinLogStream {
|
|
|
301
318
|
return tables;
|
|
302
319
|
}
|
|
303
320
|
async streamChanges() {
|
|
321
|
+
await this.ensureActiveServerUuid();
|
|
304
322
|
const serverId = createRandomServerId(this.storage.replicationStreamId);
|
|
305
323
|
const connection = await this.connections.getConnection();
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
324
|
+
let fromGTID;
|
|
325
|
+
try {
|
|
326
|
+
const { resumeLsn: resume_lsn } = await this.storage.getStatus();
|
|
327
|
+
if (resume_lsn) {
|
|
328
|
+
this.logger.info(`Existing resume LSN found: ${resume_lsn}`);
|
|
329
|
+
}
|
|
330
|
+
fromGTID = resume_lsn
|
|
331
|
+
? common.ReplicatedGTID.fromSerialized(resume_lsn)
|
|
332
|
+
: await common.readExecutedGtid(connection);
|
|
333
|
+
}
|
|
334
|
+
finally {
|
|
335
|
+
connection.release();
|
|
309
336
|
}
|
|
310
|
-
const fromGTID = resume_lsn
|
|
311
|
-
? common.ReplicatedGTID.fromSerialized(resume_lsn)
|
|
312
|
-
: await common.readExecutedGtid(connection);
|
|
313
|
-
connection.release();
|
|
314
337
|
if (!this.stopped) {
|
|
315
|
-
await this.storage.startBatch({
|
|
338
|
+
await this.storage.startBatch({
|
|
339
|
+
zeroLSN: common.ReplicatedGTID.ZERO(this.activeServerUuid).comparable,
|
|
340
|
+
defaultSchema: this.defaultSchema,
|
|
341
|
+
storeCurrentData: false
|
|
342
|
+
}, async (batch) => {
|
|
316
343
|
const binlogEventHandler = this.createBinlogEventHandler(batch);
|
|
317
344
|
const binlogListener = new BinLogListener({
|
|
318
345
|
logger: this.logger,
|
|
@@ -320,6 +347,7 @@ export class BinLogStream {
|
|
|
320
347
|
startGTID: fromGTID,
|
|
321
348
|
connectionManager: this.connections,
|
|
322
349
|
serverId: serverId,
|
|
350
|
+
activeServerUuid: this.activeServerUuid,
|
|
323
351
|
eventHandler: binlogEventHandler
|
|
324
352
|
});
|
|
325
353
|
this.abortSignal.addEventListener('abort', async () => {
|