Files
LinkPort/docs/database-clusters.md

166 lines
12 KiB
Markdown

# Database clusters
## Account remarks
Cluster discovery and Redis Sentinel account selectors identify target accounts
by their optional `remark` plus username. Creating a separate Sentinel account
does not generate required display metadata: the remark starts empty and may be
left empty. Existing `name` metadata is accepted when older configuration is
read, then saved and persisted as `remark`; account IDs, credentials and
Sentinel mappings are unchanged.
Target services own deployment mode, seed nodes and optional cluster name. New
targets default to single-node mode. Manually select a protocol-specific cluster
type or multi-node failover; the editor no longer offers automatic mode or an
enable-automatic button. Explicit cluster modes reject a mismatched cluster.
The target host is the first seed; add up to 31 alternative seeds. Every node uses
the target's selected account, TLS/CA settings and outbound transport. A Redis
Sentinel may use a separate account from the same target's account list.
Legacy saved `auto` configurations remain readable and continue to run for
compatibility. Opening one displays **请手动选择部署模式** without changing stored
data; saving or testing the draft requires a manual choice. Seeds, names and
credentials are retained until that choice; selecting single-node mode clears
cluster-only fields as before. The backend still accepts the legacy format for
existing backups/API clients. No database migration or automatic conversion occurs.
The diagnostic **识别集群** button remains a manual, read-only query and never
selects or changes the deployment mode. Protocol topology discovery after an
explicit mode is chosen remains necessary for primary selection and routing.
For Redis, **Sentinel 认证账号** offers **手动输入新账号** directly in the
cluster settings. Enter an optional account remark, Sentinel username and password there,
then save the target. Use `default` for password-only Sentinel authentication;
use the ACL username when Sentinel requires one. Selecting an existing account
also exposes these fields for editing. Changes apply to that selected account,
so create a new account when Sentinel credentials differ from Redis data access.
The new account is added to the target's account list and selected for Sentinel;
the existing data account remains available for cluster detection and gateway
connections. Passwords stay hidden on reload, and leaving the password field
empty retains the saved password. Switching back to automatic authentication or
single-node mode removes the Sentinel selection without deleting the account.
The existing encrypted account storage and `sentinelAccountId` format are reused;
there is no database migration or new plaintext credential field.
A Redis target with an empty account list sends no `AUTH` to a standalone node,
Cluster seed/discovered node, or an unauthenticated Sentinel. Adding a Sentinel
account makes the shared target account list nonempty, so an empty data-account
selection is no longer valid. When Sentinel requires credentials but the Redis
data nodes do not, create a separate data account with `authMethod: "none"`,
select that account for testing/gateway traffic, and select the credentialed
account only as **Sentinel 认证账号**. With no `sentinelAccountId`, the existing
**自动尝试目标账号或无认证** mode first uses the selected data account and may
retry only the Sentinel without authentication; selecting an explicit Sentinel
account disables that compatibility fallback. Cluster and replication nodes do
not downgrade after configured credentials are rejected.
The inline Sentinel flow is covered by an isolated RESP browser fixture: ACL and
password-only authentication, password retention/rotation, redacted responses and
separate Redis primary credentials. This is not live Sentinel validation; see
[change rationale](change-rationale.md) for the full check results.
## MongoDB connection strings
In a MongoDB target editor, paste a `mongodb://` URI into **MongoDB 连接串**
and click **解析并填入配置**. For example, using dummy credentials:
```text
mongodb://root:example%25pw%40%26value@mongo-a.internal:27017,mongo-b.internal:27017,mongo-c.internal:27017/?replicaSet=rs0&authSource=admin
```
The first node becomes the target host/port; the remaining nodes populate the
editable cluster seed list. Hosts may be DNS names, IPv4 or bracketed IPv6.
Missing ports default to 27017. `replicaSet` selects MongoDB replica-set mode and
sets the expected name. `directConnection=true` explicitly selects a single node.
Without either, the imported draft requires a manual deployment-mode selection
before saving or testing, including single-host URIs and `directConnection=false`.
Parsed seed nodes and credentials are retained while choosing. The draft-only
`manual` marker is never submitted by the editor; the backend rejects it.
Credentials are URL-decoded once into the selected target account (the first
account by default); its ID is preserved so existing gateway mappings remain
valid. A URI without credentials keeps the existing account list. Parsing only
updates the draft; review it and save the target to persist. The raw URI is
cleared after successful parsing and is not sent to the backend or stored.
Supported options are `replicaSet`, `authSource`, `tls`/`ssl`, `directConnection`
and `compressors=zlib`. TLS defaults to false as specified for `mongodb://`.
The URI database is the default authentication source when `authSource` is absent;
otherwise authentication defaults to `admin`. Application database selection
remains the client's responsibility. Unknown, duplicate or conflicting options,
SRV URIs and unsupported compression are rejected explicitly. Read preferences,
client pool settings and other MongoDB driver options cannot be imported.
All seed and discovered member addresses must be reachable through the chosen
outbound. Replica-set discovery selects a writable primary for new client sessions;
existing sessions must reconnect after a primary change.
**识别集群** reads the saved configuration and reports the type, known nodes,
selected endpoint and incomplete-discovery warnings without updating configuration.
Connection tests report the selected topology too. Discovery follows at most 64
nodes with a 20-second total budget and a 3-second budget per probe.
| Protocol | Discovery and connection behavior |
| --- | --- |
| Redis Cluster | Detects INFO cluster mode and CLUSTER SLOTS; routes keys through the gateway and follows bounded MOVED/ASK redirects, authenticating each destination with the selected target credentials. An empty-account Redis target omits `AUTH` on every destination. Client SLOTS/SHARDS responses advertise the gateway. |
| Redis Sentinel | Reads SENTINEL MASTERS, selects the named service and verifies the discovered primary. A single service can be selected automatically; multiple services require a name. |
| Redis replication | Reads INFO replication and follows the replica's primary address. |
| MongoDB replica set | Reads hello/setName/member addresses and selects a writable primary; optional replica-set name is checked. Gateway hello advertises the gateway rather than private member addresses. |
| MongoDB sharding | Detects isdbgrid and connects through a configured mongos; additional mongos seeds provide alternatives. It does not connect directly to shards. |
| MySQL replication / InnoDB Cluster | Reads read_only, replication status and online group members; selects a writable node. Replication/group metadata permissions are needed for a complete classification. |
| PostgreSQL replication | Checks pg_is_in_recovery, pg_stat_wal_receiver and pg_stat_replication. Sender addresses or configured primary seeds allow primary selection. |
| SQL Server Always On / FCI | Checks SERVERPROPERTY and the configured database's primary-replica role; discovers availability-group listeners where permitted. FCI uses its virtual endpoint; extra seeds can be configured. |
| RabbitMQ | Authenticates AMQP and reports the cluster name when advertised. AMQP does not expose a member list or prove multi-node membership; configure alternative brokers. Automatic classification remains unknown instead of inventing a topology. |
RabbitMQ discovery also reports the selected broker's advertised `version` as
**当前节点版本**. Connection tests show the broker version under server version.
An unknown cluster type can still have a known broker version. During rolling
upgrades this describes only the selected node, not every member. No management
HTTP plugin or extra permissions are required; AMQP authentication and access to
the configured vhost must succeed. If `version` is absent or not a string, discovery
omits it and connection tests show `AMQP 0-9-1 (server version unavailable)`.
The discovery response adds an optional `version` field; saved configuration and
database schema do not change.
Version regressions use isolated AMQP fixtures, including missing/non-string
properties, seed failover, rejected credentials/vhosts and the browser display.
The RabbitMQ/cluster Go tests and the dedicated browser test passed; this is not
live-server validation. Full-suite limitations are recorded in
[change rationale](change-rationale.md).
A writable SQL node with no visible replication connections cannot reliably be
distinguished from a standalone instance. Metadata denied by the server is reported
as incomplete discovery. No automatic election, promotion or database-side changes
are performed. No automatic read/write splitting is performed.
Session protocols remain pinned to the chosen endpoint. Following a primary change,
clients reconnect and new connections rediscover the topology. In-flight writes,
transactions, cursors and AMQP deliveries are never replayed. Redis redirects are
retried only for explicit MOVED/ASK responses, never for ambiguous network failures.
Redis transactions support one hash slot (including hash tags); cross-slot keys are
rejected. Redis command routing requires COMMAND GETKEYS permissions for keyed
commands. Subscription connections remain dedicated to subscription operations;
close them before issuing normal commands. This is not a replacement for a full
Redis command virtualization layer.
Discovery and redirected connections use the configured direct, SOCKS5 or SSH
transport and verify TLS against each destination hostname. Fixed Kubernetes
port-forward resources cannot address arbitrary discovered hosts; use a routable
outbound for cluster mode, or single-node mode with an existing service/router.
If the gateway is behind NAT, use a normal single-endpoint Redis client or MongoDB
directConnection=true; advertised socket addresses may not match the public NAT
endpoint. Clients never receive target passwords.
Tests use isolated protocol fixtures for topology, primary selection, credential
mapping, redirects, transaction slots, API/UI persistence and cancellation. Fixture
coverage does not establish compatibility with a particular production cluster.
Gateways with account-specific MongoDB targets send a local standalone hello
before authentication and select the upstream only after gateway authentication.
The local greeting advertises wire version 8 (MongoDB 4.2 baseline), so features
requiring newer wire versions are unavailable in this mode. It keeps the gateway
topology stable across different account destinations; upstream discovery still
selects the primary or mongos for the chosen target. RabbitMQ account routing
similarly uses a generic AMQP 0-9-1 PLAIN/en_US greeting with empty server properties
before selecting the broker. These modes were validated with protocol fixtures,
not live MongoDB or RabbitMQ clusters.