|
1 | 1 | import { NavigationPage } from '@/components/navigation/NavigationPage'; |
2 | | -import { NewStreamSubscription } from '@/components/widgets/NewStreamSubscription'; |
3 | | -import { StreamsTable } from '@/components/widgets/StreamsTable'; |
4 | | -import { clearData, connector, db, sync, useSyncStatus } from '@/library/powersync/ConnectionManager'; |
5 | | -import { getTokenUserId, decodeTokenPayload } from '@/library/powersync/TokenConnector'; |
6 | | -import React, { useState } from 'react'; |
7 | | -import { useQuery as useTanstackQuery, useQueryClient } from '@tanstack/react-query'; |
| 2 | +import { Alert, AlertDescription } from '@/components/ui/alert'; |
8 | 3 | import { Button } from '@/components/ui/button'; |
9 | | -import { Spinner } from '@/components/ui/spinner'; |
10 | 4 | import { Card, CardContent } from '@/components/ui/card'; |
11 | | -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; |
12 | 5 | import { DataTable, DataTableColumn } from '@/components/ui/data-table'; |
13 | | -import { Alert, AlertDescription } from '@/components/ui/alert'; |
| 6 | +import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'; |
| 7 | +import { Spinner } from '@/components/ui/spinner'; |
| 8 | +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; |
| 9 | +import { NewStreamSubscription } from '@/components/widgets/NewStreamSubscription'; |
| 10 | +import { StreamsTable } from '@/components/widgets/StreamsTable'; |
14 | 11 | import { formatBytes } from '@/lib/utils'; |
15 | | -import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog'; |
16 | | -import { ChevronDown, ChevronUp, Info, Eye } from 'lucide-react'; |
| 12 | +import { clearData, connector, db, sync, useSyncStatus } from '@/library/powersync/ConnectionManager'; |
| 13 | +import { decodeTokenPayload, getTokenUserId } from '@/library/powersync/TokenConnector'; |
| 14 | +import { useQueryClient, useQuery as useTanstackQuery } from '@tanstack/react-query'; |
| 15 | +import { ChevronDown, ChevronUp, Eye, Info } from 'lucide-react'; |
| 16 | +import React, { useState } from 'react'; |
17 | 17 |
|
18 | 18 | const BUCKETS_QUERY = ` |
19 | 19 | WITH |
@@ -51,8 +51,22 @@ FROM local_bucket_data local |
51 | 51 | LEFT JOIN ps_buckets ON ps_buckets.name = local.id |
52 | 52 | LEFT JOIN oplog_stats stats ON stats.bucket_id = ps_buckets.id`; |
53 | 53 |
|
54 | | -const TABLES_QUERY = ` |
55 | | -SELECT row_type as name, count() as count, sum(length(data)) as size FROM ps_oplog GROUP BY row_type |
| 54 | +/** |
| 55 | + * Groups ps_oplog entries by row_type (table/view name) to get the list |
| 56 | + * of tables and their total data sizes. |
| 57 | + * - row_count: number of unique row_id values per row_type (actual row count, robust across multiple buckets/keys) |
| 58 | + * - synced_count: This is not quite number of ops since they're de-duplicated per key already, but it counts the number of times the same row is synced via different buckets or different keys. |
| 59 | + */ |
| 60 | +const TABLES_SIZE_QUERY = /* sql */ ` |
| 61 | + SELECT |
| 62 | + row_type as name, |
| 63 | + count(distinct row_id) as count, |
| 64 | + count() as synced_count, |
| 65 | + sum(length (data)) as size |
| 66 | + FROM |
| 67 | + ps_oplog |
| 68 | + GROUP BY |
| 69 | + row_type |
56 | 70 | `; |
57 | 71 |
|
58 | 72 | const BUCKETS_QUERY_FAST = ` |
@@ -88,12 +102,12 @@ async function fetchSyncStats(): Promise<SyncStats> { |
88 | 102 |
|
89 | 103 | if (synced_at != null && !sync?.syncStatus.dataFlowStatus.downloading) { |
90 | 104 | const bucketRows = await db.getAll(BUCKETS_QUERY); |
91 | | - const tableRows = await db.getAll(TABLES_QUERY); |
| 105 | + const tableRows = await db.getAll(TABLES_SIZE_QUERY); |
92 | 106 | return { bucketRows, tableRows, lastSyncedAt }; |
93 | 107 | } |
94 | 108 | if (synced_at != null) { |
95 | 109 | const bucketRows = await db.getAll(BUCKETS_QUERY_FAST); |
96 | | - const tableRows = await db.getAll(TABLES_QUERY); |
| 110 | + const tableRows = await db.getAll(TABLES_SIZE_QUERY); |
97 | 111 | return { bucketRows, tableRows, lastSyncedAt }; |
98 | 112 | } |
99 | 113 | const bucketRows = await db.getAll(BUCKETS_QUERY_FAST); |
@@ -218,7 +232,21 @@ export default function SyncDiagnosticsPage() { |
218 | 232 |
|
219 | 233 | const tablesColumns: DataTableColumn<any>[] = [ |
220 | 234 | { field: 'name', headerName: 'Name', flex: 2 }, |
221 | | - { field: 'count', headerName: 'Row Count', flex: 1, type: 'number' }, |
| 235 | + { |
| 236 | + field: 'count', |
| 237 | + headerName: 'Row Count', |
| 238 | + flex: 1, |
| 239 | + type: 'number', |
| 240 | + tooltip: 'Number of unique rows synced to this database.' |
| 241 | + }, |
| 242 | + { |
| 243 | + field: 'synced_count', |
| 244 | + headerName: 'Synced Count', |
| 245 | + flex: 1, |
| 246 | + type: 'number', |
| 247 | + hideOnMobile: true, |
| 248 | + tooltip: 'Total number of rows synced via different buckets or different replication keys.' |
| 249 | + }, |
222 | 250 | { |
223 | 251 | field: 'size', |
224 | 252 | headerName: 'Data Size', |
@@ -385,9 +413,9 @@ export default function SyncDiagnosticsPage() { |
385 | 413 | <Info className="h-4 w-4" /> |
386 | 414 | <AlertDescription> |
387 | 415 | Total operations ({totals.total_operations.toLocaleString()}) significantly exceeds total rows ( |
388 | | - {totals.row_count.toLocaleString()}). This indicates bucket history has accumulated which negatively |
389 | | - affects sync times for new clients. Performing a Compact or Defragment operation on your instance, |
390 | | - could improve this.{' '} |
| 416 | + {totals.row_count.toLocaleString()}). This indicates bucket history has accumulated which negatively |
| 417 | + affects sync times for new clients. Performing a Compact or Defragment operation on your instance, could |
| 418 | + improve this.{' '} |
391 | 419 | <a |
392 | 420 | href="https://docs.powersync.com/maintenance-ops/compacting-buckets" |
393 | 421 | target="_blank" |
@@ -491,8 +519,7 @@ function TruncatedTablesList({ tables }: { tables: string }) { |
491 | 519 | </> |
492 | 520 | ) : ( |
493 | 521 | <> |
494 | | - <ChevronDown className="h-3 w-3" /> |
495 | | - +{hiddenCount} more |
| 522 | + <ChevronDown className="h-3 w-3" />+{hiddenCount} more |
496 | 523 | </> |
497 | 524 | )} |
498 | 525 | </button> |
|
0 commit comments