@powersync/service-module-postgres 0.13.0 → 0.14.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 +35 -0
- package/dist/api/PostgresRouteAPIAdapter.d.ts +1 -1
- package/dist/api/PostgresRouteAPIAdapter.js +5 -1
- package/dist/api/PostgresRouteAPIAdapter.js.map +1 -1
- package/dist/replication/SnapshotQuery.d.ts +78 -0
- package/dist/replication/SnapshotQuery.js +175 -0
- package/dist/replication/SnapshotQuery.js.map +1 -0
- package/dist/replication/WalStream.d.ts +37 -4
- package/dist/replication/WalStream.js +318 -91
- package/dist/replication/WalStream.js.map +1 -1
- package/dist/replication/WalStreamReplicationJob.d.ts +2 -0
- package/dist/replication/WalStreamReplicationJob.js +14 -3
- package/dist/replication/WalStreamReplicationJob.js.map +1 -1
- package/dist/replication/WalStreamReplicator.d.ts +1 -0
- package/dist/replication/WalStreamReplicator.js +22 -0
- package/dist/replication/WalStreamReplicator.js.map +1 -1
- package/dist/replication/replication-utils.d.ts +4 -0
- package/dist/replication/replication-utils.js +46 -2
- package/dist/replication/replication-utils.js.map +1 -1
- package/package.json +11 -10
- package/src/api/PostgresRouteAPIAdapter.ts +5 -1
- package/src/replication/SnapshotQuery.ts +209 -0
- package/src/replication/WalStream.ts +373 -98
- package/src/replication/WalStreamReplicationJob.ts +15 -3
- package/src/replication/WalStreamReplicator.ts +26 -0
- package/src/replication/replication-utils.ts +60 -2
- package/test/src/__snapshots__/schema_changes.test.ts.snap +2 -2
- package/test/src/checkpoints.test.ts +17 -7
- package/test/src/chunked_snapshots.test.ts +156 -0
- package/test/src/large_batch.test.ts +5 -154
- package/test/src/resuming_snapshots.test.ts +150 -0
- package/test/src/schema_changes.test.ts +5 -10
- package/test/src/slow_tests.test.ts +13 -30
- package/test/src/util.ts +12 -1
- package/test/src/validation.test.ts +0 -1
- package/test/src/wal_stream.test.ts +4 -9
- package/test/src/wal_stream_utils.ts +15 -7
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @powersync/service-module-postgres
|
|
2
2
|
|
|
3
|
+
## 0.14.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0ccd470: Add powersync_replication_lag_seconds metric
|
|
8
|
+
- 951b010: Implement resuming of initial replication snapshots.
|
|
9
|
+
- d235f7b: [MongoDB Storage] Remove change streams on bucket storage database due to performance overhead.
|
|
10
|
+
- 08b7aa9: Add checks for RLS affecting replication.
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 1907356: Cleanly interrupt clearing of storage when the process is stopped/restarted.
|
|
15
|
+
- Updated dependencies [08b7aa9]
|
|
16
|
+
- Updated dependencies [0ccd470]
|
|
17
|
+
- Updated dependencies [1907356]
|
|
18
|
+
- Updated dependencies [08b7aa9]
|
|
19
|
+
- Updated dependencies [951b010]
|
|
20
|
+
- Updated dependencies [d235f7b]
|
|
21
|
+
- Updated dependencies [f9e8673]
|
|
22
|
+
- @powersync/service-core@1.13.0
|
|
23
|
+
- @powersync/service-types@0.12.0
|
|
24
|
+
- @powersync/service-jpgwire@0.20.0
|
|
25
|
+
- @powersync/lib-services-framework@0.7.0
|
|
26
|
+
- @powersync/lib-service-postgres@0.4.4
|
|
27
|
+
|
|
28
|
+
## 0.13.1
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies [100ccec]
|
|
33
|
+
- Updated dependencies [b57f938]
|
|
34
|
+
- Updated dependencies [5b39039]
|
|
35
|
+
- @powersync/service-core@1.12.1
|
|
36
|
+
- @powersync/service-sync-rules@0.27.0
|
|
37
|
+
|
|
3
38
|
## 0.13.0
|
|
4
39
|
|
|
5
40
|
### Minor Changes
|
|
@@ -20,7 +20,7 @@ export declare class PostgresRouteAPIAdapter implements api.RouteAPI {
|
|
|
20
20
|
executeQuery(query: string, params: any[]): Promise<service_types.internal_routes.ExecuteSqlResponse>;
|
|
21
21
|
getDebugTablesInfo(tablePatterns: sync_rules.TablePattern[], sqlSyncRules: sync_rules.SqlSyncRules): Promise<api.PatternResult[]>;
|
|
22
22
|
protected getDebugTableInfo(tablePattern: sync_rules.TablePattern, name: string, relationId: number | null, syncRules: sync_rules.SqlSyncRules): Promise<service_types.TableInfo>;
|
|
23
|
-
|
|
23
|
+
getReplicationLagBytes(options: api.ReplicationLagOptions): Promise<number | undefined>;
|
|
24
24
|
getReplicationHead(): Promise<string>;
|
|
25
25
|
createReplicationHead<T>(callback: ReplicationHeadCallback<T>): Promise<T>;
|
|
26
26
|
getConnectionSchema(): Promise<service_types.DatabaseSchema[]>;
|
|
@@ -190,7 +190,7 @@ export class PostgresRouteAPIAdapter {
|
|
|
190
190
|
syncRules: syncRules
|
|
191
191
|
});
|
|
192
192
|
}
|
|
193
|
-
async
|
|
193
|
+
async getReplicationLagBytes(options) {
|
|
194
194
|
const { bucketStorage } = options;
|
|
195
195
|
const slotName = bucketStorage.slot_name;
|
|
196
196
|
const results = await lib_postgres.retriedQuery(this.pool, {
|
|
@@ -224,6 +224,10 @@ FROM pg_replication_slots WHERE slot_name = $1 LIMIT 1;`,
|
|
|
224
224
|
async createReplicationHead(callback) {
|
|
225
225
|
const currentLsn = await this.getReplicationHead();
|
|
226
226
|
const r = await callback(currentLsn);
|
|
227
|
+
// Note: This may not reliably trigger a new replication message on Postgres 11 or 12,
|
|
228
|
+
// in which case there could be a delay in the client receiving the write checkpoint acknowledgement.
|
|
229
|
+
// Postgres 12 already reached EOL, and this is not a critical issue, so we're not fixing it.
|
|
230
|
+
// On postgres 13+, this works reliably.
|
|
227
231
|
await lib_postgres.retriedQuery(this.pool, KEEPALIVE_STATEMENT);
|
|
228
232
|
return r;
|
|
229
233
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresRouteAPIAdapter.js","sourceRoot":"","sources":["../../src/api/PostgresRouteAPIAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAE5E,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AACrD,OAAO,KAAK,UAAU,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,aAAa,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,iBAAiB,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C,MAAM,OAAO,uBAAuB;IAgBtB;IAEF;IAjBV,aAAa,CAAS;IACtB,oDAAoD;IACpD,eAAe,GAAG,gBAAgB,CAAC;IAEnC,MAAM,CAAC,UAAU,CAAC,MAAsC;QACtD,MAAM,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE;YAC5C,WAAW,EAAE,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,YACY,IAAqB,EAC/B,aAAsB,EACd,MAAuC;QAFrC,SAAI,GAAJ,IAAI,CAAiB;QAEvB,WAAM,GAAN,MAAM,CAAiC;QAE/C,IAAI,CAAC,aAAa,GAAG,aAAa,IAAI,UAAU,CAAC,WAAW,CAAC;IAC/D,CAAC;IAED,wBAAwB;QACtB,OAAO;YACL,aAAa,EAAE,QAAQ;SACxB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,OAAO,IAAI,CAAC,MAAO,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,MAAM,IAAI,GAAG;YACX,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE;YACzB,GAAG,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;SAC3D,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,oCAAoC,CAAC,CAAC;QACnF,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO;gBACL,GAAG,IAAI;gBACP,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;aACjD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,iBAAiB,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QACpF,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO;gBACL,GAAG,IAAI;gBACP,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;aACjD,CAAC;QACJ,CAAC;QAED,OAAO;YACL,GAAG,IAAI;YACP,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,EAAE;SACX,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,MAAa;QAC7C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;YAC5B,OAAO,aAAa,CAAC,eAAe,CAAC,kBAAkB,CAAC,MAAM,CAAC;gBAC7D,OAAO,EAAE;oBACP,OAAO,EAAE,EAAE;oBACX,IAAI,EAAE,EAAE;iBACT;gBACD,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,6BAA6B;aACrC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;gBACnC,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC;aAC/C,CAAC,CAAC;YAEH,OAAO,aAAa,CAAC,eAAe,CAAC,kBAAkB,CAAC,MAAM,CAAC;gBAC7D,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;oBAC1C,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;wBAC5B,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;4BACvB,MAAM,QAAQ,GAAG,UAAU,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;4BACpD,IAAI,OAAO,QAAQ,IAAI,QAAQ,EAAE,CAAC;gCAChC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;4BACvB,CAAC;iCAAM,IAAI,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;gCAC5C,OAAO,QAAQ,CAAC;4BAClB,CAAC;iCAAM,CAAC;gCACN,OAAO,IAAI,CAAC;4BACd,CAAC;wBACH,CAAC,CAAC,CAAC;oBACL,CAAC,CAAC;iBACH;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,aAAa,CAAC,eAAe,CAAC,kBAAkB,CAAC,MAAM,CAAC;gBAC7D,OAAO,EAAE;oBACP,OAAO,EAAE,EAAE;oBACX,IAAI,EAAE,EAAE;iBACT;gBACD,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,CAAC,CAAC,OAAO;aACjB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,CAAC,kBAAkB,CACtB,aAAwC,EACxC,YAAqC;QAErC,IAAI,MAAM,GAAwB,EAAE,CAAC;QAErC,KAAK,IAAI,YAAY,IAAI,aAAa,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;YAEnC,IAAI,aAAa,GAAsB;gBACrC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,YAAY,CAAC,YAAY;gBAClC,QAAQ,EAAE,YAAY,CAAC,UAAU;aAClC,CAAC;YACF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAE3B,IAAI,YAAY,CAAC,UAAU,EAAE,CAAC;gBAC5B,aAAa,CAAC,MAAM,GAAG,EAAE,CAAC;gBAC1B,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC;gBACxC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE;oBACzD,SAAS,EAAE;;;;;8BAKS;oBACpB,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE;wBAClC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,YAAY,EAAE;qBACtD;iBACF,CAAC,CAAC;gBAEH,KAAK,IAAI,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,UAAoB,CAAC;oBACtC,MAAM,UAAU,GAAG,GAAG,CAAC,KAAe,CAAC;oBACvC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC7B,SAAS;oBACX,CAAC;oBACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;oBAC3F,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE;oBACzD,SAAS,EAAE;;;;;2BAKM;oBACjB,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE;wBAClC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,YAAY,EAAE;qBACtD;iBACF,CAAC,CAAC;gBACH,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;oBAC7B,kBAAkB;oBAClB,aAAa,CAAC,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;gBAC1G,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,UAAoB,CAAC;oBACtC,MAAM,UAAU,GAAG,GAAG,CAAC,KAAe,CAAC;oBACvC,aAAa,CAAC,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;gBACnG,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAES,KAAK,CAAC,iBAAiB,CAC/B,YAAqC,EACrC,IAAY,EACZ,UAAyB,EACzB,SAAkC;QAElC,OAAO,iBAAiB,CAAC;YACvB,EAAE,EAAE,IAAI,CAAC,IAAI;YACb,IAAI,EAAE,IAAI;YACV,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,YAAY,EAAE,YAAY;YAC1B,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,SAAS;SACrB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"PostgresRouteAPIAdapter.js","sourceRoot":"","sources":["../../src/api/PostgresRouteAPIAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { SourceTable } from '@powersync/service-core';
|
|
2
|
+
import { PgChunk, PgConnection, PgTypeOid } from '@powersync/service-jpgwire';
|
|
3
|
+
import { SqliteValue } from '@powersync/service-sync-rules';
|
|
4
|
+
export interface SnapshotQuery {
|
|
5
|
+
initialize(): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Returns an async iterable iterator that yields chunks of data.
|
|
8
|
+
*
|
|
9
|
+
* If the last chunk has 0 rows, it indicates that there are no more rows to fetch.
|
|
10
|
+
*/
|
|
11
|
+
nextChunk(): AsyncIterableIterator<PgChunk>;
|
|
12
|
+
}
|
|
13
|
+
export type PrimaryKeyValue = Record<string, SqliteValue>;
|
|
14
|
+
export interface MissingRow {
|
|
15
|
+
table: SourceTable;
|
|
16
|
+
key: PrimaryKeyValue;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Snapshot query using a plain SELECT * FROM table; chunked using
|
|
20
|
+
* DELCLARE CURSOR / FETCH.
|
|
21
|
+
*
|
|
22
|
+
* This supports all tables, but does not efficiently resume the snapshot
|
|
23
|
+
* if the process is restarted.
|
|
24
|
+
*/
|
|
25
|
+
export declare class SimpleSnapshotQuery implements SnapshotQuery {
|
|
26
|
+
private readonly connection;
|
|
27
|
+
private readonly table;
|
|
28
|
+
private readonly chunkSize;
|
|
29
|
+
constructor(connection: PgConnection, table: SourceTable, chunkSize?: number);
|
|
30
|
+
initialize(): Promise<void>;
|
|
31
|
+
nextChunk(): AsyncIterableIterator<PgChunk>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Performs a table snapshot query, chunking by ranges of primary key data.
|
|
35
|
+
*
|
|
36
|
+
* This may miss some rows if they are modified during the snapshot query.
|
|
37
|
+
* In that case, logical replication will pick up those rows afterwards,
|
|
38
|
+
* possibly resulting in an IdSnapshotQuery.
|
|
39
|
+
*
|
|
40
|
+
* Currently, this only supports a table with a single primary key column,
|
|
41
|
+
* of a select few types.
|
|
42
|
+
*/
|
|
43
|
+
export declare class ChunkedSnapshotQuery implements SnapshotQuery {
|
|
44
|
+
private readonly connection;
|
|
45
|
+
private readonly table;
|
|
46
|
+
private readonly chunkSize;
|
|
47
|
+
/**
|
|
48
|
+
* Primary key types that we support for chunked snapshots.
|
|
49
|
+
*
|
|
50
|
+
* Can expand this over time as we add more tests,
|
|
51
|
+
* and ensure there are no issues with type conversion.
|
|
52
|
+
*/
|
|
53
|
+
static SUPPORTED_TYPES: PgTypeOid[];
|
|
54
|
+
static supports(table: SourceTable): boolean;
|
|
55
|
+
private readonly key;
|
|
56
|
+
lastKey: string | bigint | null;
|
|
57
|
+
constructor(connection: PgConnection, table: SourceTable, chunkSize: number | undefined, lastKeySerialized: Uint8Array | null);
|
|
58
|
+
initialize(): Promise<void>;
|
|
59
|
+
private deserializeKey;
|
|
60
|
+
getLastKeySerialized(): Uint8Array;
|
|
61
|
+
nextChunk(): AsyncIterableIterator<PgChunk>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* This performs a snapshot query using a list of primary keys.
|
|
65
|
+
*
|
|
66
|
+
* This is not used for general snapshots, but is used when we need to re-fetch specific rows
|
|
67
|
+
* during streaming replication.
|
|
68
|
+
*/
|
|
69
|
+
export declare class IdSnapshotQuery implements SnapshotQuery {
|
|
70
|
+
private readonly connection;
|
|
71
|
+
private readonly table;
|
|
72
|
+
private readonly keys;
|
|
73
|
+
private didChunk;
|
|
74
|
+
static supports(table: SourceTable): boolean;
|
|
75
|
+
constructor(connection: PgConnection, table: SourceTable, keys: PrimaryKeyValue[]);
|
|
76
|
+
initialize(): Promise<void>;
|
|
77
|
+
nextChunk(): AsyncIterableIterator<PgChunk>;
|
|
78
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { bson } from '@powersync/service-core';
|
|
2
|
+
import { PgType, PgTypeOid } from '@powersync/service-jpgwire';
|
|
3
|
+
import { escapeIdentifier } from '@powersync/lib-service-postgres';
|
|
4
|
+
import { ServiceAssertionError } from '@powersync/lib-services-framework';
|
|
5
|
+
/**
|
|
6
|
+
* Snapshot query using a plain SELECT * FROM table; chunked using
|
|
7
|
+
* DELCLARE CURSOR / FETCH.
|
|
8
|
+
*
|
|
9
|
+
* This supports all tables, but does not efficiently resume the snapshot
|
|
10
|
+
* if the process is restarted.
|
|
11
|
+
*/
|
|
12
|
+
export class SimpleSnapshotQuery {
|
|
13
|
+
connection;
|
|
14
|
+
table;
|
|
15
|
+
chunkSize;
|
|
16
|
+
constructor(connection, table, chunkSize = 10_000) {
|
|
17
|
+
this.connection = connection;
|
|
18
|
+
this.table = table;
|
|
19
|
+
this.chunkSize = chunkSize;
|
|
20
|
+
}
|
|
21
|
+
async initialize() {
|
|
22
|
+
await this.connection.query(`DECLARE snapshot_cursor CURSOR FOR SELECT * FROM ${this.table.escapedIdentifier}`);
|
|
23
|
+
}
|
|
24
|
+
nextChunk() {
|
|
25
|
+
return this.connection.stream(`FETCH ${this.chunkSize} FROM snapshot_cursor`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Performs a table snapshot query, chunking by ranges of primary key data.
|
|
30
|
+
*
|
|
31
|
+
* This may miss some rows if they are modified during the snapshot query.
|
|
32
|
+
* In that case, logical replication will pick up those rows afterwards,
|
|
33
|
+
* possibly resulting in an IdSnapshotQuery.
|
|
34
|
+
*
|
|
35
|
+
* Currently, this only supports a table with a single primary key column,
|
|
36
|
+
* of a select few types.
|
|
37
|
+
*/
|
|
38
|
+
export class ChunkedSnapshotQuery {
|
|
39
|
+
connection;
|
|
40
|
+
table;
|
|
41
|
+
chunkSize;
|
|
42
|
+
/**
|
|
43
|
+
* Primary key types that we support for chunked snapshots.
|
|
44
|
+
*
|
|
45
|
+
* Can expand this over time as we add more tests,
|
|
46
|
+
* and ensure there are no issues with type conversion.
|
|
47
|
+
*/
|
|
48
|
+
static SUPPORTED_TYPES = [
|
|
49
|
+
PgTypeOid.TEXT,
|
|
50
|
+
PgTypeOid.VARCHAR,
|
|
51
|
+
PgTypeOid.UUID,
|
|
52
|
+
PgTypeOid.INT2,
|
|
53
|
+
PgTypeOid.INT4,
|
|
54
|
+
PgTypeOid.INT8
|
|
55
|
+
];
|
|
56
|
+
static supports(table) {
|
|
57
|
+
if (table.replicaIdColumns.length != 1) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const primaryKey = table.replicaIdColumns[0];
|
|
61
|
+
return primaryKey.typeId != null && ChunkedSnapshotQuery.SUPPORTED_TYPES.includes(Number(primaryKey.typeId));
|
|
62
|
+
}
|
|
63
|
+
key;
|
|
64
|
+
lastKey = null;
|
|
65
|
+
constructor(connection, table, chunkSize = 10_000, lastKeySerialized) {
|
|
66
|
+
this.connection = connection;
|
|
67
|
+
this.table = table;
|
|
68
|
+
this.chunkSize = chunkSize;
|
|
69
|
+
this.key = table.replicaIdColumns[0];
|
|
70
|
+
if (lastKeySerialized != null) {
|
|
71
|
+
this.lastKey = this.deserializeKey(lastKeySerialized);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async initialize() {
|
|
75
|
+
// No-op
|
|
76
|
+
}
|
|
77
|
+
deserializeKey(key) {
|
|
78
|
+
const decoded = bson.deserialize(key, { useBigInt64: true });
|
|
79
|
+
const keys = Object.keys(decoded);
|
|
80
|
+
if (keys.length != 1) {
|
|
81
|
+
throw new ServiceAssertionError(`Multiple keys found: ${keys.join(', ')}`);
|
|
82
|
+
}
|
|
83
|
+
if (keys[0] != this.key.name) {
|
|
84
|
+
throw new ServiceAssertionError(`Key name mismatch: expected ${this.key.name}, got ${keys[0]}`);
|
|
85
|
+
}
|
|
86
|
+
const value = decoded[this.key.name];
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
getLastKeySerialized() {
|
|
90
|
+
return bson.serialize({ [this.key.name]: this.lastKey });
|
|
91
|
+
}
|
|
92
|
+
async *nextChunk() {
|
|
93
|
+
let stream;
|
|
94
|
+
const escapedKeyName = escapeIdentifier(this.key.name);
|
|
95
|
+
if (this.lastKey == null) {
|
|
96
|
+
stream = this.connection.stream(`SELECT * FROM ${this.table.escapedIdentifier} ORDER BY ${escapedKeyName} LIMIT ${this.chunkSize}`);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
if (this.key.typeId == null) {
|
|
100
|
+
throw new Error(`typeId required for primary key ${this.key.name}`);
|
|
101
|
+
}
|
|
102
|
+
let type = Number(this.key.typeId);
|
|
103
|
+
stream = this.connection.stream({
|
|
104
|
+
statement: `SELECT * FROM ${this.table.escapedIdentifier} WHERE ${escapedKeyName} > $1 ORDER BY ${escapedKeyName} LIMIT ${this.chunkSize}`,
|
|
105
|
+
params: [{ value: this.lastKey, type }]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
let primaryKeyIndex = -1;
|
|
109
|
+
for await (let chunk of stream) {
|
|
110
|
+
if (chunk.tag == 'RowDescription') {
|
|
111
|
+
// We get a RowDescription for each FETCH call, but they should
|
|
112
|
+
// all be the same.
|
|
113
|
+
let i = 0;
|
|
114
|
+
const pk = chunk.payload.findIndex((c) => c.name == this.key.name);
|
|
115
|
+
if (pk < 0) {
|
|
116
|
+
throw new Error(`Cannot find primary key column ${this.key} in results. Keys: ${chunk.payload.map((c) => c.name).join(', ')}`);
|
|
117
|
+
}
|
|
118
|
+
primaryKeyIndex = pk;
|
|
119
|
+
}
|
|
120
|
+
if (chunk.rows.length > 0) {
|
|
121
|
+
this.lastKey = chunk.rows[chunk.rows.length - 1][primaryKeyIndex];
|
|
122
|
+
}
|
|
123
|
+
yield chunk;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* This performs a snapshot query using a list of primary keys.
|
|
129
|
+
*
|
|
130
|
+
* This is not used for general snapshots, but is used when we need to re-fetch specific rows
|
|
131
|
+
* during streaming replication.
|
|
132
|
+
*/
|
|
133
|
+
export class IdSnapshotQuery {
|
|
134
|
+
connection;
|
|
135
|
+
table;
|
|
136
|
+
keys;
|
|
137
|
+
didChunk = false;
|
|
138
|
+
static supports(table) {
|
|
139
|
+
// We have the same requirements as ChunkedSnapshotQuery.
|
|
140
|
+
// This is typically only used as a fallback when ChunkedSnapshotQuery
|
|
141
|
+
// skipped some rows.
|
|
142
|
+
return ChunkedSnapshotQuery.supports(table);
|
|
143
|
+
}
|
|
144
|
+
constructor(connection, table, keys) {
|
|
145
|
+
this.connection = connection;
|
|
146
|
+
this.table = table;
|
|
147
|
+
this.keys = keys;
|
|
148
|
+
}
|
|
149
|
+
async initialize() {
|
|
150
|
+
// No-op
|
|
151
|
+
}
|
|
152
|
+
async *nextChunk() {
|
|
153
|
+
// Only produce one chunk
|
|
154
|
+
if (this.didChunk) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
this.didChunk = true;
|
|
158
|
+
const keyDefinition = this.table.replicaIdColumns[0];
|
|
159
|
+
const ids = this.keys.map((record) => record[keyDefinition.name]);
|
|
160
|
+
const type = PgType.getArrayType(keyDefinition.typeId);
|
|
161
|
+
if (type == null) {
|
|
162
|
+
throw new Error(`Cannot determine primary key array type for ${JSON.stringify(keyDefinition)}`);
|
|
163
|
+
}
|
|
164
|
+
yield* this.connection.stream({
|
|
165
|
+
statement: `SELECT * FROM ${this.table.escapedIdentifier} WHERE ${escapeIdentifier(keyDefinition.name)} = ANY($1)`,
|
|
166
|
+
params: [
|
|
167
|
+
{
|
|
168
|
+
type: type,
|
|
169
|
+
value: ids
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=SnapshotQuery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SnapshotQuery.js","sourceRoot":"","sources":["../../src/replication/SnapshotQuery.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Logger } from '@powersync/lib-services-framework';
|
|
2
|
+
import { MetricsEngine, SourceEntityDescriptor, SourceTable, storage } from '@powersync/service-core';
|
|
2
3
|
import * as pgwire from '@powersync/service-jpgwire';
|
|
3
4
|
import { DatabaseInputRow, SqliteRow, SqlSyncRules, TablePattern } from '@powersync/service-sync-rules';
|
|
4
5
|
import { PgManager } from './PgManager.js';
|
|
5
6
|
export interface WalStreamOptions {
|
|
7
|
+
logger?: Logger;
|
|
6
8
|
connections: PgManager;
|
|
7
9
|
storage: storage.SyncRulesBucketStorage;
|
|
8
10
|
metrics: MetricsEngine;
|
|
9
11
|
abort_signal: AbortSignal;
|
|
12
|
+
/**
|
|
13
|
+
* Override snapshot chunk length (number of rows), for testing.
|
|
14
|
+
*
|
|
15
|
+
* Defaults to 10_000.
|
|
16
|
+
*
|
|
17
|
+
* Note that queries are streamed, so we don't actually keep that much data in memory.
|
|
18
|
+
*/
|
|
19
|
+
snapshotChunkLength?: number;
|
|
10
20
|
}
|
|
11
21
|
interface InitResult {
|
|
12
22
|
/** True if initial snapshot is not yet done. */
|
|
@@ -29,13 +39,25 @@ export declare class WalStream {
|
|
|
29
39
|
sync_rules: SqlSyncRules;
|
|
30
40
|
group_id: number;
|
|
31
41
|
connection_id: number;
|
|
42
|
+
private logger;
|
|
32
43
|
private readonly storage;
|
|
33
44
|
private readonly metrics;
|
|
34
45
|
private readonly slot_name;
|
|
35
46
|
private connections;
|
|
36
47
|
private abort_signal;
|
|
37
|
-
private
|
|
48
|
+
private relationCache;
|
|
38
49
|
private startedStreaming;
|
|
50
|
+
private snapshotChunkLength;
|
|
51
|
+
/**
|
|
52
|
+
* Time of the oldest uncommitted change, according to the source db.
|
|
53
|
+
* This is used to determine the replication lag.
|
|
54
|
+
*/
|
|
55
|
+
private oldestUncommittedChange;
|
|
56
|
+
/**
|
|
57
|
+
* Keep track of whether we have done a commit or keepalive yet.
|
|
58
|
+
* We can only compute replication lag if isStartingReplication == false, or oldestUncommittedChange is present.
|
|
59
|
+
*/
|
|
60
|
+
private isStartingReplication;
|
|
39
61
|
constructor(options: WalStreamOptions);
|
|
40
62
|
get stopped(): boolean;
|
|
41
63
|
getQualifiedTableNames(batch: storage.BucketStorageBatch, db: pgwire.PgConnection, tablePattern: TablePattern): Promise<storage.SourceTable[]>;
|
|
@@ -44,7 +66,7 @@ export declare class WalStream {
|
|
|
44
66
|
* If a replication slot exists, check that it is healthy.
|
|
45
67
|
*/
|
|
46
68
|
private checkReplicationSlot;
|
|
47
|
-
|
|
69
|
+
estimatedCountNumber(db: pgwire.PgConnection, table: storage.SourceTable): Promise<number>;
|
|
48
70
|
/**
|
|
49
71
|
* Start initial replication.
|
|
50
72
|
*
|
|
@@ -54,8 +76,18 @@ export declare class WalStream {
|
|
|
54
76
|
startInitialReplication(replicationConnection: pgwire.PgConnection, status: InitResult): Promise<void>;
|
|
55
77
|
initialReplication(db: pgwire.PgConnection): Promise<void>;
|
|
56
78
|
static getQueryData(results: Iterable<DatabaseInputRow>): Generator<SqliteRow>;
|
|
79
|
+
private snapshotTableInTx;
|
|
57
80
|
private snapshotTable;
|
|
58
|
-
handleRelation(batch: storage.BucketStorageBatch, descriptor: SourceEntityDescriptor, snapshot: boolean): Promise<
|
|
81
|
+
handleRelation(batch: storage.BucketStorageBatch, descriptor: SourceEntityDescriptor, snapshot: boolean): Promise<SourceTable>;
|
|
82
|
+
/**
|
|
83
|
+
* Process rows that have missing TOAST values.
|
|
84
|
+
*
|
|
85
|
+
* This can happen during edge cases in the chunked intial snapshot process.
|
|
86
|
+
*
|
|
87
|
+
* We handle this similar to an inline table snapshot, but limited to the specific
|
|
88
|
+
* set of rows.
|
|
89
|
+
*/
|
|
90
|
+
private resnapshot;
|
|
59
91
|
private getTable;
|
|
60
92
|
writeChange(batch: storage.BucketStorageBatch, msg: pgwire.PgoutputMessage): Promise<storage.FlushedResult | null>;
|
|
61
93
|
replicate(): Promise<void>;
|
|
@@ -72,5 +104,6 @@ export declare class WalStream {
|
|
|
72
104
|
* viewing the contents of logical replication messages.
|
|
73
105
|
*/
|
|
74
106
|
protected checkLogicalMessageSupport(): Promise<boolean>;
|
|
107
|
+
getReplicationLagMillis(): Promise<number | undefined>;
|
|
75
108
|
}
|
|
76
109
|
export {};
|