@powersync/service-module-postgres 0.0.0-dev-20260225160713 → 0.0.0-dev-20260511080634
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/dist/api/PostgresRouteAPIAdapter.d.ts +1 -1
- package/dist/api/PostgresRouteAPIAdapter.js +63 -72
- package/dist/api/PostgresRouteAPIAdapter.js.map +1 -1
- package/dist/module/PostgresModule.js.map +1 -1
- package/dist/replication/MissingReplicationSlotError.d.ts +41 -0
- package/dist/replication/MissingReplicationSlotError.js +33 -0
- package/dist/replication/MissingReplicationSlotError.js.map +1 -0
- package/dist/replication/PgManager.js +3 -2
- package/dist/replication/PgManager.js.map +1 -1
- package/dist/replication/PostgresErrorRateLimiter.js +1 -1
- package/dist/replication/PostgresErrorRateLimiter.js.map +1 -1
- package/dist/replication/SnapshotQuery.js +8 -7
- package/dist/replication/SnapshotQuery.js.map +1 -1
- package/dist/replication/WalStream.d.ts +46 -16
- package/dist/replication/WalStream.js +203 -69
- package/dist/replication/WalStream.js.map +1 -1
- package/dist/replication/WalStreamReplicationJob.d.ts +1 -1
- package/dist/replication/WalStreamReplicationJob.js +9 -6
- package/dist/replication/WalStreamReplicationJob.js.map +1 -1
- package/dist/replication/WalStreamReplicator.d.ts +0 -1
- package/dist/replication/WalStreamReplicator.js +0 -22
- package/dist/replication/WalStreamReplicator.js.map +1 -1
- package/dist/replication/replication-index.d.ts +3 -1
- package/dist/replication/replication-index.js +3 -1
- package/dist/replication/replication-index.js.map +1 -1
- package/dist/replication/replication-utils.d.ts +3 -11
- package/dist/replication/replication-utils.js +103 -165
- package/dist/replication/replication-utils.js.map +1 -1
- package/dist/replication/rquery.d.ts +5 -0
- package/dist/replication/rquery.js +35 -0
- package/dist/replication/rquery.js.map +1 -0
- package/dist/replication/wal-budget-utils.d.ts +23 -0
- package/dist/replication/wal-budget-utils.js +57 -0
- package/dist/replication/wal-budget-utils.js.map +1 -0
- package/dist/types/registry.js +1 -1
- package/dist/types/registry.js.map +1 -1
- package/dist/utils/errors.d.ts +2 -0
- package/dist/utils/errors.js +30 -0
- package/dist/utils/errors.js.map +1 -0
- package/package.json +17 -13
- package/sql/check-source-configuration.plpgsql +13 -0
- package/sql/debug-tables-info-batched.plpgsql +230 -0
- package/CHANGELOG.md +0 -794
- package/src/api/PostgresRouteAPIAdapter.ts +0 -356
- package/src/index.ts +0 -1
- package/src/module/PostgresModule.ts +0 -122
- package/src/replication/ConnectionManagerFactory.ts +0 -33
- package/src/replication/PgManager.ts +0 -122
- package/src/replication/PgRelation.ts +0 -41
- package/src/replication/PostgresErrorRateLimiter.ts +0 -48
- package/src/replication/SnapshotQuery.ts +0 -213
- package/src/replication/WalStream.ts +0 -1138
- package/src/replication/WalStreamReplicationJob.ts +0 -138
- package/src/replication/WalStreamReplicator.ts +0 -79
- package/src/replication/replication-index.ts +0 -5
- package/src/replication/replication-utils.ts +0 -398
- package/src/types/registry.ts +0 -275
- package/src/types/resolver.ts +0 -227
- package/src/types/types.ts +0 -44
- package/src/utils/application-name.ts +0 -8
- package/src/utils/migration_lib.ts +0 -80
- package/src/utils/populate_test_data.ts +0 -37
- package/src/utils/populate_test_data_worker.ts +0 -53
- package/src/utils/postgres_version.ts +0 -8
- package/test/src/checkpoints.test.ts +0 -88
- package/test/src/chunked_snapshots.test.ts +0 -160
- package/test/src/env.ts +0 -11
- package/test/src/large_batch.test.ts +0 -239
- package/test/src/pg_test.test.ts +0 -729
- package/test/src/resuming_snapshots.test.ts +0 -163
- package/test/src/route_api_adapter.test.ts +0 -62
- package/test/src/schema_changes.test.ts +0 -675
- package/test/src/setup.ts +0 -12
- package/test/src/slow_tests.test.ts +0 -412
- package/test/src/storage_combination.test.ts +0 -35
- package/test/src/types/registry.test.ts +0 -149
- package/test/src/util.ts +0 -145
- package/test/src/validation.test.ts +0 -63
- package/test/src/wal_stream.test.ts +0 -618
- package/test/src/wal_stream_utils.ts +0 -292
- package/test/tsconfig.json +0 -27
- package/tsconfig.json +0 -34
- package/tsconfig.tsbuildinfo +0 -1
- package/vitest.config.ts +0 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { container
|
|
2
|
-
import { MissingReplicationSlotError,
|
|
1
|
+
import { container } from '@powersync/lib-services-framework';
|
|
2
|
+
import { MissingReplicationSlotError, shouldRetryReplication } from './MissingReplicationSlotError.js';
|
|
3
|
+
import { sendKeepAlive, WalStream } from './WalStream.js';
|
|
3
4
|
import { replication } from '@powersync/service-core';
|
|
4
5
|
import { getApplicationName } from '../utils/application-name.js';
|
|
5
6
|
export class WalStreamReplicationJob extends replication.AbstractReplicationJob {
|
|
@@ -8,7 +9,7 @@ export class WalStreamReplicationJob extends replication.AbstractReplicationJob
|
|
|
8
9
|
lastStream = null;
|
|
9
10
|
constructor(options) {
|
|
10
11
|
super(options);
|
|
11
|
-
this.logger =
|
|
12
|
+
this.logger = options.storage.logger;
|
|
12
13
|
this.connectionFactory = options.connectionFactory;
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
@@ -78,8 +79,10 @@ export class WalStreamReplicationJob extends replication.AbstractReplicationJob
|
|
|
78
79
|
this.rateLimiter.reportError(e);
|
|
79
80
|
}
|
|
80
81
|
if (e instanceof MissingReplicationSlotError) {
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
if (shouldRetryReplication(e)) {
|
|
83
|
+
// This stops replication on this slot and restarts with a new slot
|
|
84
|
+
await this.options.storage.factory.restartReplication(this.storage.group_id);
|
|
85
|
+
}
|
|
83
86
|
}
|
|
84
87
|
// No need to rethrow - the error is already logged, and retry behavior is the same on error
|
|
85
88
|
}
|
|
@@ -118,7 +121,7 @@ export class WalStreamReplicationJob extends replication.AbstractReplicationJob
|
|
|
118
121
|
await connectionManager.end();
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
|
-
|
|
124
|
+
getReplicationLagMillis() {
|
|
122
125
|
return this.lastStream?.getReplicationLagMillis();
|
|
123
126
|
}
|
|
124
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WalStreamReplicationJob.js","sourceRoot":"","sources":["../../src/replication/WalStreamReplicationJob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"WalStreamReplicationJob.js","sourceRoot":"","sources":["../../src/replication/WalStreamReplicationJob.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,5 +11,4 @@ export declare class WalStreamReplicator extends replication.AbstractReplicator<
|
|
|
11
11
|
cleanUp(syncRulesStorage: storage.SyncRulesBucketStorage): Promise<void>;
|
|
12
12
|
stop(): Promise<void>;
|
|
13
13
|
testConnection(): Promise<replication.ConnectionTestResult>;
|
|
14
|
-
getReplicationLagMillis(): Promise<number | undefined>;
|
|
15
14
|
}
|
|
@@ -40,27 +40,5 @@ export class WalStreamReplicator extends replication.AbstractReplicator {
|
|
|
40
40
|
async testConnection() {
|
|
41
41
|
return await PostgresModule.testConnection(this.connectionFactory.dbConnectionConfig);
|
|
42
42
|
}
|
|
43
|
-
async getReplicationLagMillis() {
|
|
44
|
-
const lag = await super.getReplicationLagMillis();
|
|
45
|
-
if (lag != null) {
|
|
46
|
-
return lag;
|
|
47
|
-
}
|
|
48
|
-
// Booting or in an error loop. Check last active replication status.
|
|
49
|
-
// This includes sync rules in an ERROR state.
|
|
50
|
-
const content = await this.storage.getActiveSyncRulesContent();
|
|
51
|
-
if (content == null) {
|
|
52
|
-
return undefined;
|
|
53
|
-
}
|
|
54
|
-
// Measure the lag from the last commit or keepalive timestamp.
|
|
55
|
-
// This is not 100% accurate since it is the commit time in the storage db rather than
|
|
56
|
-
// the source db, but it's the best we have for postgres.
|
|
57
|
-
const checkpointTs = content.last_checkpoint_ts?.getTime() ?? 0;
|
|
58
|
-
const keepaliveTs = content.last_keepalive_ts?.getTime() ?? 0;
|
|
59
|
-
const latestTs = Math.max(checkpointTs, keepaliveTs);
|
|
60
|
-
if (latestTs != 0) {
|
|
61
|
-
return Date.now() - latestTs;
|
|
62
|
-
}
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
43
|
}
|
|
66
44
|
//# sourceMappingURL=WalStreamReplicator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WalStreamReplicator.js","sourceRoot":"","sources":["../../src/replication/WalStreamReplicator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAW,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAMvE,MAAM,OAAO,mBAAoB,SAAQ,WAAW,CAAC,kBAA2C;IAC7E,iBAAiB,CAA2B;IAE7D,YAAY,OAAmC;QAC7C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IACrD,CAAC;IAED,SAAS,CAAC,OAAqC;QAC7C,OAAO,IAAI,uBAAuB,CAAC;YACjC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC9C,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,gBAAgD;QAC5D,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;YACtD,eAAe,EAAE,kBAAkB,EAAE;YACrC,WAAW,EAAE,MAAM;YACnB,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;QACH,IAAI,CAAC;YACH,iFAAiF;YACjF,MAAM,sBAAsB,CAAC,gBAAgB,CAAC,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACnF,CAAC;gBAAS,CAAC;YACT,MAAM,iBAAiB,CAAC,GAAG,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,MAAM,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IACxF,CAAC;
|
|
1
|
+
{"version":3,"file":"WalStreamReplicator.js","sourceRoot":"","sources":["../../src/replication/WalStreamReplicator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAW,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAMvE,MAAM,OAAO,mBAAoB,SAAQ,WAAW,CAAC,kBAA2C;IAC7E,iBAAiB,CAA2B;IAE7D,YAAY,OAAmC;QAC7C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IACrD,CAAC;IAED,SAAS,CAAC,OAAqC;QAC7C,OAAO,IAAI,uBAAuB,CAAC;YACjC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC9C,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,gBAAgD;QAC5D,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;YACtD,eAAe,EAAE,kBAAkB,EAAE;YACrC,WAAW,EAAE,MAAM;YACnB,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;QACH,IAAI,CAAC;YACH,iFAAiF;YACjF,MAAM,sBAAsB,CAAC,gBAAgB,CAAC,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACnF,CAAC;gBAAS,CAAC;YACT,MAAM,iBAAiB,CAAC,GAAG,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,MAAM,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IACxF,CAAC;CACF"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
export * from './MissingReplicationSlotError.js';
|
|
1
2
|
export * from './PgRelation.js';
|
|
2
3
|
export * from './replication-utils.js';
|
|
4
|
+
export * from './wal-budget-utils.js';
|
|
3
5
|
export * from './WalStream.js';
|
|
4
|
-
export * from './WalStreamReplicator.js';
|
|
5
6
|
export * from './WalStreamReplicationJob.js';
|
|
7
|
+
export * from './WalStreamReplicator.js';
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
export * from './MissingReplicationSlotError.js';
|
|
1
2
|
export * from './PgRelation.js';
|
|
2
3
|
export * from './replication-utils.js';
|
|
4
|
+
export * from './wal-budget-utils.js';
|
|
3
5
|
export * from './WalStream.js';
|
|
4
|
-
export * from './WalStreamReplicator.js';
|
|
5
6
|
export * from './WalStreamReplicationJob.js';
|
|
7
|
+
export * from './WalStreamReplicator.js';
|
|
6
8
|
//# sourceMappingURL=replication-index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replication-index.js","sourceRoot":"","sources":["../../src/replication/replication-index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,
|
|
1
|
+
{"version":3,"file":"replication-index.js","sourceRoot":"","sources":["../../src/replication/replication-index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC;AACjD,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as pgwire from '@powersync/service-jpgwire';
|
|
2
2
|
import { PatternResult, storage } from '@powersync/service-core';
|
|
3
3
|
import * as sync_rules from '@powersync/service-sync-rules';
|
|
4
|
-
import * as service_types from '@powersync/service-types';
|
|
5
4
|
import { ReplicationIdentity } from './PgRelation.js';
|
|
6
5
|
export interface ReplicaIdentityResult {
|
|
7
6
|
replicationColumns: storage.ColumnDescriptor[];
|
|
@@ -22,15 +21,8 @@ export interface GetDebugTablesInfoOptions {
|
|
|
22
21
|
tablePatterns: sync_rules.TablePattern[];
|
|
23
22
|
syncRules: sync_rules.SyncConfig;
|
|
24
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Note: This must use a dedicated connection, not a connection pool.
|
|
26
|
+
*/
|
|
25
27
|
export declare function getDebugTablesInfo(options: GetDebugTablesInfoOptions): Promise<PatternResult[]>;
|
|
26
|
-
export interface GetDebugTableInfoOptions {
|
|
27
|
-
db: pgwire.PgClient;
|
|
28
|
-
name: string;
|
|
29
|
-
publicationName: string;
|
|
30
|
-
connectionTag: string;
|
|
31
|
-
tablePattern: sync_rules.TablePattern;
|
|
32
|
-
relationId: number | null;
|
|
33
|
-
syncRules: sync_rules.SyncConfig;
|
|
34
|
-
}
|
|
35
|
-
export declare function getDebugTableInfo(options: GetDebugTableInfoOptions): Promise<service_types.TableInfo>;
|
|
36
28
|
export declare function cleanUpReplicationSlot(slotName: string, db: pgwire.PgClient): Promise<void>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as pgwire from '@powersync/service-jpgwire';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
2
3
|
import * as lib_postgres from '@powersync/lib-service-postgres';
|
|
3
4
|
import { ErrorCode, logger, ServiceAssertionError, ServiceError } from '@powersync/lib-services-framework';
|
|
4
5
|
import { storage } from '@powersync/service-core';
|
|
6
|
+
import { rquery } from './rquery.js';
|
|
5
7
|
export async function getPrimaryKeyColumns(db, relationId, mode) {
|
|
6
8
|
const indexFlag = mode == 'primary' ? `i.indisprimary` : `i.indisreplident`;
|
|
7
9
|
const attrRows = await lib_postgres.retriedQuery(db, {
|
|
@@ -76,19 +78,7 @@ WHERE oid = $1::oid LIMIT 1`,
|
|
|
76
78
|
}
|
|
77
79
|
export async function checkSourceConfiguration(db, publicationName) {
|
|
78
80
|
// Check basic config
|
|
79
|
-
await lib_postgres.retriedQuery(db,
|
|
80
|
-
BEGIN
|
|
81
|
-
if current_setting('wal_level') is distinct from 'logical' then
|
|
82
|
-
raise exception 'wal_level must be set to ''logical'', your database has it set to ''%''. Please edit your config file and restart PostgreSQL.', current_setting('wal_level');
|
|
83
|
-
end if;
|
|
84
|
-
if (current_setting('max_replication_slots')::int >= 1) is not true then
|
|
85
|
-
raise exception 'Your max_replication_slots setting is too low, it must be greater than 1. Please edit your config file and restart PostgreSQL.';
|
|
86
|
-
end if;
|
|
87
|
-
if (current_setting('max_wal_senders')::int >= 1) is not true then
|
|
88
|
-
raise exception 'Your max_wal_senders setting is too low, it must be greater than 1. Please edit your config file and restart PostgreSQL.';
|
|
89
|
-
end if;
|
|
90
|
-
end;
|
|
91
|
-
$$ LANGUAGE plpgsql;`);
|
|
81
|
+
await lib_postgres.retriedQuery(db, await getCheckSourceConfigurationSql());
|
|
92
82
|
// Check that publication exists
|
|
93
83
|
const rs = await lib_postgres.retriedQuery(db, {
|
|
94
84
|
statement: `SELECT * FROM pg_publication WHERE pubname = $1`,
|
|
@@ -147,174 +137,122 @@ WHERE c.oid = $1::oid;
|
|
|
147
137
|
}
|
|
148
138
|
return { canRead: true };
|
|
149
139
|
}
|
|
140
|
+
let getDebugTablesInfoBatchedSqlPromise;
|
|
141
|
+
let checkSourceConfigurationSqlPromise;
|
|
142
|
+
function getDebugTablesInfoBatchedSql() {
|
|
143
|
+
return (getDebugTablesInfoBatchedSqlPromise ??= readFile(new URL('../../sql/debug-tables-info-batched.plpgsql', import.meta.url), 'utf8'));
|
|
144
|
+
}
|
|
145
|
+
function getCheckSourceConfigurationSql() {
|
|
146
|
+
return (checkSourceConfigurationSqlPromise ??= readFile(new URL('../../sql/check-source-configuration.plpgsql', import.meta.url), 'utf8'));
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Note: This must use a dedicated connection, not a connection pool.
|
|
150
|
+
*/
|
|
150
151
|
export async function getDebugTablesInfo(options) {
|
|
151
152
|
const { db, publicationName, connectionTag, tablePatterns, syncRules } = options;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const relationId = row.relid;
|
|
179
|
-
if (!name.startsWith(prefix)) {
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
const details = await getDebugTableInfo({
|
|
183
|
-
db,
|
|
184
|
-
name,
|
|
185
|
-
publicationName,
|
|
186
|
-
connectionTag,
|
|
187
|
-
tablePattern,
|
|
188
|
-
relationId,
|
|
189
|
-
syncRules: syncRules
|
|
190
|
-
});
|
|
191
|
-
patternResult.tables.push(details);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
const results = await lib_postgres.retriedQuery(db, {
|
|
196
|
-
statement: `SELECT c.oid AS relid, c.relname AS table_name
|
|
197
|
-
FROM pg_class c
|
|
198
|
-
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
199
|
-
WHERE n.nspname = $1
|
|
200
|
-
AND c.relkind = 'r'
|
|
201
|
-
AND c.relname = $2`,
|
|
202
|
-
params: [
|
|
203
|
-
{ type: 'varchar', value: schema },
|
|
204
|
-
{ type: 'varchar', value: tablePattern.tablePattern }
|
|
205
|
-
]
|
|
206
|
-
});
|
|
207
|
-
if (results.rows.length == 0) {
|
|
208
|
-
// Table not found
|
|
209
|
-
patternResult.table = await getDebugTableInfo({
|
|
210
|
-
db,
|
|
211
|
-
name: tablePattern.name,
|
|
212
|
-
publicationName,
|
|
213
|
-
connectionTag,
|
|
214
|
-
tablePattern,
|
|
215
|
-
relationId: null,
|
|
216
|
-
syncRules: syncRules
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
const row = pgwire.pgwireRows(results)[0];
|
|
221
|
-
const name = row.table_name;
|
|
222
|
-
const relationId = row.relid;
|
|
223
|
-
patternResult.table = await getDebugTableInfo({
|
|
224
|
-
db,
|
|
225
|
-
name,
|
|
226
|
-
publicationName,
|
|
227
|
-
connectionTag,
|
|
228
|
-
tablePattern,
|
|
229
|
-
relationId,
|
|
230
|
-
syncRules: syncRules
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
}
|
|
153
|
+
const patternPayload = JSON.stringify(tablePatterns.map((tablePattern, pattern_ord) => ({
|
|
154
|
+
pattern_ord,
|
|
155
|
+
schema_name: tablePattern.schema,
|
|
156
|
+
table_pattern: tablePattern.tablePattern,
|
|
157
|
+
is_wildcard: tablePattern.isWildcard,
|
|
158
|
+
table_prefix: tablePattern.isWildcard ? tablePattern.tablePrefix : '',
|
|
159
|
+
input_name: tablePattern.isWildcard ? tablePattern.tablePattern : tablePattern.name
|
|
160
|
+
})));
|
|
161
|
+
let rows;
|
|
162
|
+
await rquery(db, 'BEGIN');
|
|
163
|
+
try {
|
|
164
|
+
// Anonymous DO blocks cannot take bind parameters directly, so pass the
|
|
165
|
+
// pattern payload through transaction-local settings on the pinned connection.
|
|
166
|
+
const fetched = await rquery(db, {
|
|
167
|
+
statement: `SELECT set_config('powersync.debug.table_patterns', $1, true)`,
|
|
168
|
+
params: [{ type: 'varchar', value: patternPayload }]
|
|
169
|
+
}, {
|
|
170
|
+
statement: `SELECT set_config('powersync.debug.publication_name', $1, true)`,
|
|
171
|
+
params: [{ type: 'varchar', value: publicationName }]
|
|
172
|
+
}, {
|
|
173
|
+
statement: await getDebugTablesInfoBatchedSql()
|
|
174
|
+
}, {
|
|
175
|
+
statement: `FETCH ALL FROM powersync_debug_tables_cursor`
|
|
176
|
+
});
|
|
177
|
+
rows = pgwire.pgwireRows(fetched);
|
|
178
|
+
await rquery(db, 'COMMIT');
|
|
234
179
|
}
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
export async function getDebugTableInfo(options) {
|
|
238
|
-
const { db, name, publicationName, connectionTag, tablePattern, relationId, syncRules } = options;
|
|
239
|
-
const schema = tablePattern.schema;
|
|
240
|
-
let id_columns_result = undefined;
|
|
241
|
-
let id_columns_error = null;
|
|
242
|
-
if (relationId != null) {
|
|
180
|
+
catch (e) {
|
|
243
181
|
try {
|
|
244
|
-
|
|
182
|
+
await rquery(db, 'ROLLBACK');
|
|
245
183
|
}
|
|
246
|
-
catch
|
|
247
|
-
|
|
184
|
+
catch {
|
|
185
|
+
// Ignore rollback errors after a failed transaction.
|
|
248
186
|
}
|
|
187
|
+
throw e;
|
|
249
188
|
}
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
189
|
+
const result = tablePatterns.map((tablePattern) => ({
|
|
190
|
+
schema: tablePattern.schema,
|
|
191
|
+
pattern: tablePattern.tablePattern,
|
|
192
|
+
wildcard: tablePattern.isWildcard,
|
|
193
|
+
...(tablePattern.isWildcard ? { tables: [] } : {})
|
|
194
|
+
}));
|
|
195
|
+
for (const row of rows) {
|
|
196
|
+
const tablePattern = tablePatterns[row.pattern_ord];
|
|
197
|
+
const idColumns = JSON.parse(row.replication_id_json);
|
|
198
|
+
const sourceTable = new storage.SourceTable({
|
|
199
|
+
id: '',
|
|
200
|
+
connectionTag,
|
|
201
|
+
objectId: row.relation_id ?? 0,
|
|
202
|
+
schema: tablePattern.schema,
|
|
203
|
+
name: row.name,
|
|
204
|
+
replicaIdColumns: idColumns.map((name) => ({ name })),
|
|
205
|
+
snapshotComplete: true
|
|
206
|
+
});
|
|
207
|
+
const syncData = syncRules.tableSyncsData(sourceTable);
|
|
208
|
+
const syncParameters = syncRules.tableSyncsParameters(sourceTable);
|
|
209
|
+
let errors;
|
|
210
|
+
if (row.relation_id == null) {
|
|
211
|
+
errors = [{ level: 'warning', message: `Table ${sourceTable.qualifiedName} not found.` }];
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
const idColumnsError = idColumns.length == 0 && row.replication_identity != 'nothing'
|
|
215
|
+
? {
|
|
216
|
+
level: 'fatal',
|
|
217
|
+
message: `No replication id found for ${sourceTable.qualifiedName}. Replica identity: ${row.replication_identity}.${row.replication_identity == 'default' ? ' Configure a primary key on the table.' : ''}`
|
|
218
|
+
}
|
|
219
|
+
: null;
|
|
220
|
+
const selectError = row.select_error == null ? null : { level: 'fatal', message: row.select_error };
|
|
221
|
+
const replicateError = row.in_publication === false
|
|
222
|
+
? {
|
|
223
|
+
level: 'fatal',
|
|
224
|
+
message: `Table ${sourceTable.qualifiedName} is not part of publication '${publicationName}'. Run: \`ALTER PUBLICATION ${publicationName} ADD TABLE ${sourceTable.qualifiedName}\`.`
|
|
225
|
+
}
|
|
226
|
+
: null;
|
|
227
|
+
const rlsError = row.rls_enabled && !row.is_superuser && !row.bypasses_rls && row.username != null
|
|
228
|
+
? {
|
|
229
|
+
level: 'warning',
|
|
230
|
+
message: `[${ErrorCode.PSYNC_S1145}] Row Level Security is enabled on table "${row.name}". To make sure that ${row.username} can read the table, run: 'ALTER ROLE ${row.username} BYPASSRLS'.`
|
|
231
|
+
}
|
|
232
|
+
: null;
|
|
233
|
+
errors = [idColumnsError, selectError, replicateError, rlsError].filter((error) => error != null);
|
|
234
|
+
}
|
|
235
|
+
const tableInfo = {
|
|
236
|
+
schema: tablePattern.schema,
|
|
237
|
+
name: row.name,
|
|
266
238
|
pattern: tablePattern.isWildcard ? tablePattern.tablePattern : undefined,
|
|
267
|
-
replication_id:
|
|
239
|
+
replication_id: idColumns,
|
|
268
240
|
data_queries: syncData,
|
|
269
241
|
parameter_queries: syncParameters,
|
|
270
|
-
|
|
271
|
-
errors: [{ level: 'warning', message: `Table ${sourceTable.qualifiedName} not found.` }]
|
|
242
|
+
errors
|
|
272
243
|
};
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
244
|
+
if (tablePattern.isWildcard) {
|
|
245
|
+
result[row.pattern_ord].tables.push(tableInfo);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
result[row.pattern_ord].table = tableInfo;
|
|
278
249
|
}
|
|
279
|
-
id_columns_error = { level: 'fatal', message };
|
|
280
|
-
}
|
|
281
|
-
let selectError = null;
|
|
282
|
-
try {
|
|
283
|
-
await lib_postgres.retriedQuery(db, `SELECT * FROM ${sourceTable.qualifiedName} LIMIT 1`);
|
|
284
|
-
}
|
|
285
|
-
catch (e) {
|
|
286
|
-
selectError = { level: 'fatal', message: e.message };
|
|
287
|
-
}
|
|
288
|
-
let replicateError = null;
|
|
289
|
-
const publications = await lib_postgres.retriedQuery(db, {
|
|
290
|
-
statement: `SELECT tablename FROM pg_publication_tables WHERE pubname = $1 AND schemaname = $2 AND tablename = $3`,
|
|
291
|
-
params: [
|
|
292
|
-
{ type: 'varchar', value: publicationName },
|
|
293
|
-
{ type: 'varchar', value: tablePattern.schema },
|
|
294
|
-
{ type: 'varchar', value: name }
|
|
295
|
-
]
|
|
296
|
-
});
|
|
297
|
-
if (publications.rows.length == 0) {
|
|
298
|
-
replicateError = {
|
|
299
|
-
level: 'fatal',
|
|
300
|
-
message: `Table ${sourceTable.qualifiedName} is not part of publication '${publicationName}'. Run: \`ALTER PUBLICATION ${publicationName} ADD TABLE ${sourceTable.qualifiedName}\`.`
|
|
301
|
-
};
|
|
302
250
|
}
|
|
303
|
-
|
|
304
|
-
const rlsError = rlsCheck.canRead ? null : { message: rlsCheck.message, level: 'warning' };
|
|
305
|
-
return {
|
|
306
|
-
schema: schema,
|
|
307
|
-
name: name,
|
|
308
|
-
pattern: tablePattern.isWildcard ? tablePattern.tablePattern : undefined,
|
|
309
|
-
replication_id: id_columns.map((c) => c.name),
|
|
310
|
-
data_queries: syncData,
|
|
311
|
-
parameter_queries: syncParameters,
|
|
312
|
-
errors: [id_columns_error, selectError, replicateError, rlsError].filter((error) => error != null)
|
|
313
|
-
};
|
|
251
|
+
return result;
|
|
314
252
|
}
|
|
315
253
|
export async function cleanUpReplicationSlot(slotName, db) {
|
|
316
254
|
logger.info(`Cleaning up Postgres replication slot: ${slotName}...`);
|
|
317
|
-
await db
|
|
255
|
+
await rquery(db, {
|
|
318
256
|
statement: 'SELECT pg_drop_replication_slot(slot_name) FROM pg_replication_slots WHERE slot_name = $1',
|
|
319
257
|
params: [{ type: 'varchar', value: slotName }]
|
|
320
258
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replication-utils.js","sourceRoot":"","sources":["../../src/replication/replication-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"replication-utils.js","sourceRoot":"","sources":["../../src/replication/replication-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { PgChunk, PgClient, PgResult, Statement } from '@powersync/service-jpgwire';
|
|
2
|
+
export declare function rquery(db: PgClient, query: string): Promise<PgResult>;
|
|
3
|
+
export declare function rquery(db: PgClient, ...statements: Statement[]): Promise<PgResult>;
|
|
4
|
+
export declare function rstream(db: PgClient, query: string): AsyncIterableIterator<PgChunk>;
|
|
5
|
+
export declare function rstream(db: PgClient, ...statements: Statement[]): AsyncIterableIterator<PgChunk>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { mapPostgresReplicationError } from '../utils/errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Run a replication query, mapping errors.
|
|
4
|
+
*/
|
|
5
|
+
export async function rquery(db, ...args) {
|
|
6
|
+
try {
|
|
7
|
+
return await db.query(...args);
|
|
8
|
+
}
|
|
9
|
+
catch (e) {
|
|
10
|
+
let query;
|
|
11
|
+
if (typeof args[0] == 'string') {
|
|
12
|
+
query = args[0];
|
|
13
|
+
}
|
|
14
|
+
else if (typeof args[0]?.statement == 'string') {
|
|
15
|
+
query = args[0].statement;
|
|
16
|
+
}
|
|
17
|
+
throw mapPostgresReplicationError(e, query);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export async function* rstream(db, ...args) {
|
|
21
|
+
try {
|
|
22
|
+
yield* db.stream(...args);
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
let query;
|
|
26
|
+
if (typeof args[0] == 'string') {
|
|
27
|
+
query = args[0];
|
|
28
|
+
}
|
|
29
|
+
else if (typeof args[0]?.statement == 'string') {
|
|
30
|
+
query = args[0].statement;
|
|
31
|
+
}
|
|
32
|
+
throw mapPostgresReplicationError(e, query);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=rquery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rquery.js","sourceRoot":"","sources":["../../src/replication/rquery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAKjE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,EAAY,EAAE,GAAG,IAAW;IACvD,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,KAAyB,CAAC;QAC9B,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;YAC/B,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,QAAQ,EAAE,CAAC;YACjD,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5B,CAAC;QACD,MAAM,2BAA2B,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAID,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,OAAO,CAAC,EAAY,EAAE,GAAG,IAAW;IACzD,IAAI,CAAC;QACH,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,KAAyB,CAAC;QAC9B,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;YAC/B,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,QAAQ,EAAE,CAAC;YACjD,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5B,CAAC;QACD,MAAM,2BAA2B,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare function formatBytes(bytes: number): string;
|
|
2
|
+
export declare function formatDuration(hours: number): string;
|
|
3
|
+
export interface WalBudgetSample {
|
|
4
|
+
safeWalSize: number;
|
|
5
|
+
timestamp: number;
|
|
6
|
+
}
|
|
7
|
+
export interface WalBudgetReport {
|
|
8
|
+
budgetRemainingPct: number;
|
|
9
|
+
safeWalSize: number;
|
|
10
|
+
maxSize: number;
|
|
11
|
+
walStatus: string;
|
|
12
|
+
ratePerHour: number | null;
|
|
13
|
+
etaHours: number | null;
|
|
14
|
+
isWarning: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function computeWalBudgetReport(opts: {
|
|
17
|
+
safeWalSize: number;
|
|
18
|
+
maxSize: number;
|
|
19
|
+
walStatus: string;
|
|
20
|
+
prevSample: WalBudgetSample | null;
|
|
21
|
+
now: number;
|
|
22
|
+
}): WalBudgetReport;
|
|
23
|
+
export declare function formatWalBudgetLine(report: WalBudgetReport): string;
|