Stockage Aurora DSQL
L’implémentation du stockage Aurora DSQL fournit un stockage basé sur Amazon Aurora DSQL avec authentification IAM.
Aurora DSQL ne prend pas en charge les extensions PostgreSQL (CREATE EXTENSION), notamment pgvector. Pour le stockage vectoriel, utilisez une base vectorielle distincte telle que @mastra/s3vectors.
InstallationLien direct vers Installation
npm install @mastra/dsql@beta
PrérequisLien direct vers Prérequis
- Cluster Amazon Aurora DSQL
- Identifiants AWS donnant accès au cluster DSQL (authentification IAM)
UtilisationLien direct vers Utilisation
import { DSQLStore } from '@mastra/dsql'
const storage = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
// region is auto-detected from host, or specify explicitly:
// region: 'us-east-1',
// user: 'admin', // default
// database: 'postgres', // default
})
// Initialize the store (creates tables if needed)
await storage.init()
ParamètresLien direct vers Paramètres
id:
host:
pool?:
user?:
database?:
region?:
schemaName?:
customCredentialsProvider?:
max?:
min?:
idleTimeoutMillis?:
maxLifetimeSeconds?:
connectionTimeoutMillis?:
allowExitOnIdle?:
Exemples de constructionLien direct vers Exemples de construction
Vous pouvez instancier DSQLStore de différentes manières :
import { DSQLStore } from '@mastra/dsql'
// Basic configuration (region auto-detected from host)
const store1 = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
})
// With explicit region and schema
const store2 = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
region: 'us-east-1',
schemaName: 'my_app',
})
// With custom credentials provider
import { fromNodeProviderChain } from '@aws-sdk/credential-providers'
const store3 = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
customCredentialsProvider: fromNodeProviderChain(),
})
// With connection pool settings
const store4 = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
max: 20,
min: 2,
idleTimeoutMillis: 300000,
maxLifetimeSeconds: 3000,
connectionTimeoutMillis: 10000,
})
// Using a pre-configured pg.Pool
import { Pool } from 'pg'
import { AuroraDSQLClient } from '@aws/aurora-dsql-node-postgres-connector'
const pool = new Pool({
host: 'abc123.dsql.us-east-1.on.aws',
Client: AuroraDSQLClient,
region: 'us-east-1',
})
const store5 = new DSQLStore({
id: 'my-dsql-store',
pool,
})
Remarques supplémentairesLien direct vers Remarques supplémentaires
Gestion du schémaLien direct vers Gestion du schéma
L’implémentation du stockage gère automatiquement la création et la mise à jour du schéma. Elle crée les tables suivantes :
mastra_workflow_snapshot: stocke l’état et les données d’exécution des Workflowsmastra_threads: stocke les fils de conversationmastra_messages: stocke les messages individuelsmastra_ai_spans: stocke les données de spans pour l’observabilitémastra_scorers: stocke les données de scoring et d’évaluationmastra_resources: stocke les données de mémoire de travail des ressourcesmastra_agents: stocke les données des Agents
InitialisationLien direct vers Initialisation
Lorsque vous transmettez le stockage à la classe Mastra, init() est appelée automatiquement avant toute opération de stockage :
import { Mastra } from '@mastra/core'
import { DSQLStore } from '@mastra/dsql'
const storage = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
})
const mastra = new Mastra({
storage, // init() is called automatically
})
Si vous utilisez directement le stockage sans Mastra, vous devez appeler explicitement init() pour créer les tables :
import { DSQLStore } from '@mastra/dsql'
const storage = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
})
// Required when using storage directly
await storage.init()
// Access domain-specific stores via getStore()
const memoryStore = await storage.getStore('memory')
const thread = await memoryStore?.getThreadById({ threadId: '...' })
Si init() n’est pas appelée, les tables ne seront pas créées et les opérations de stockage échoueront silencieusement ou déclencheront des erreurs.
Accès direct à la base de données et au poolLien direct vers Accès direct à la base de données et au pool
DSQLStore expose le client de base de données sous-jacent et l’instance pg.Pool comme champs publics :
storage.db // Database client for executing queries
storage.pool // Underlying pg.Pool instance
Il prend en charge les requêtes directes et la gestion personnalisée des transactions. Lorsque vous utilisez ces champs :
- Vous êtes responsable de la bonne gestion des connexions et des transactions.
- La fermeture du stockage (
storage.close()) détruira le pool de connexions s’il a été créé par le stockage. - L’accès direct contourne toute logique ou validation supplémentaire fournie par les méthodes de DSQLStore.
Cette approche est destinée aux scénarios avancés qui nécessitent un accès de bas niveau.
Particularités d’Aurora DSQLLien direct vers Particularités d’Aurora DSQL
Authentification IAM uniquementLien direct vers Authentification IAM uniquement
Les connexions sont authentifiées avec IAM. Aucun mot de passe de base de données n’est requis. @mastra/dsql utilise @aws/aurora-dsql-node-postgres-connector pour générer des tokens d’authentification de courte durée. Vous pouvez fournir un Provider d’identifiants personnalisé via customCredentialsProvider.
Base de données unique et isolation par schémaLien direct vers Base de données unique et isolation par schéma
Chaque cluster expose une seule base de données postgres. La séparation logique s’effectue au moyen de schémas. L’option schemaName détermine l’emplacement de création des tables Mastra.
Aucune extension PostgreSQLLien direct vers Aucune extension PostgreSQL
CREATE EXTENSION n’est pas pris en charge. Cela inclut pgvector, PostGIS et d’autres extensions. Pour le stockage vectoriel, utilisez une base distincte telle que @mastra/s3vectors avec DSQLStore.
JSON stocké sous forme de texteLien direct vers JSON stocké sous forme de texte
JSON/JSONB sont disponibles comme types de requête, mais pas comme types de colonne. @mastra/dsql stocke les champs structurés (métadonnées, contenu, etc.) dans des colonnes TEXT et les convertit en JSON lors des requêtes.
Contraintes de schéma et DDLLien direct vers Contraintes de schéma et DDL
Certaines fonctionnalités PostgreSQL ne sont pas disponibles :
- Contraintes de clé étrangère
TRUNCATECREATE INDEXsynchrone
Les index sont créés de manière asynchrone avec CREATE INDEX ASYNC. init() et les API auxiliaires d’index du stockage respectent ces contraintes.
Transactions et accès concurrent optimisteLien direct vers Transactions et accès concurrent optimiste
Aurora DSQL utilise le contrôle de concurrence optimiste (OCC) et peut renvoyer des erreurs OCC réessayables en cas de contention. La durée et la taille des transactions sont limitées. Les opérations groupées volumineuses doivent être divisées en lots plus petits au niveau de l’application.
Durée de vie des connexionsLien direct vers Durée de vie des connexions
Les connexions individuelles sont limitées à environ 60 minutes. La valeur par défaut maxLifetimeSeconds: 3300 garantit leur renouvellement avant cette limite.
Exemple d’utilisationLien direct vers Exemple d’utilisation
Ajouter une Memory à un AgentLien direct vers Ajouter une Memory à un Agent
Pour ajouter une Memory Aurora DSQL à un Agent, utilisez la classe Memory et créez une nouvelle clé storage avec DSQLStore. host doit pointer vers le point de terminaison de votre cluster Aurora DSQL.
import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'
import { DSQLStore } from '@mastra/dsql'
export const dsqlAgent = new Agent({
id: 'dsql-agent',
name: 'DSQL Agent',
instructions:
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
storage: new DSQLStore({
id: 'dsql-agent-storage',
host: process.env.DSQL_HOST!,
}),
options: {
generateTitle: true, // Explicitly enable automatic title generation
},
}),
})
Utiliser l’AgentLien direct vers Utiliser l’Agent
Utilisez memoryOptions pour délimiter le rappel de cette requête. Définissez lastMessages: 5 afin de limiter le rappel fondé sur la récence, puis utilisez semanticRecall pour récupérer les topK: 3 messages les plus pertinents, ainsi que messageRange: 2 messages voisins fournissant du contexte autour de chaque correspondance.
import 'dotenv/config'
import { mastra } from './mastra'
const threadId = '123'
const resourceId = 'user-456'
const agent = mastra.getAgent('dsql-agent')
const message = await agent.stream('My name is Mastra', {
memory: {
thread: threadId,
resource: resourceId,
},
})
await message.textStream.pipeTo(new WritableStream())
const stream = await agent.stream("What's my name?", {
memory: {
thread: threadId,
resource: resourceId,
},
memoryOptions: {
lastMessages: 5,
semanticRecall: {
topK: 3,
messageRange: 2,
},
},
})
for await (const chunk of stream.textStream) {
process.stdout.write(chunk)
}
Gestion des indexLien direct vers Gestion des index
Le stockage Aurora DSQL fournit des fonctionnalités de gestion des index pour optimiser les performances des requêtes.
Index de performance automatiquesLien direct vers Index de performance automatiques
Lors de l’initialisation, le stockage Aurora DSQL crée automatiquement des index composites pour les modèles de requête courants :
mastra_threads_resourceid_createdat_idx: (resourceId, createdAt)mastra_messages_thread_id_createdat_idx: (thread_id, createdAt)mastra_ai_spans_traceid_startedat_idx: (traceId, startedAt)mastra_ai_spans_parentspanid_startedat_idx: (parentSpanId, startedAt)mastra_ai_spans_name_idx: (name)mastra_ai_spans_spantype_startedat_idx: (spanType, startedAt)mastra_scores_trace_id_span_id_created_at_idx: (traceId, spanId, createdAt)
Aurora DSQL crée ces index de manière asynchrone avec CREATE INDEX ASYNC. Leur création étant asynchrone, les nouveaux index peuvent ne pas être immédiatement disponibles après init(). Le stockage continuera de fonctionner sans eux, mais les requêtes pourront être plus lentes jusqu’à la fin de leur création.
Créer des index personnalisésLien direct vers Créer des index personnalisés
Créez des index supplémentaires afin d’optimiser certains modèles de requête :
await storage.createIndex({
name: 'idx_threads_resource',
table: 'mastra_threads',
columns: ['resourceId'],
})
await storage.createIndex({
name: 'idx_messages_composite',
table: 'mastra_messages',
columns: ['thread_id', 'createdAt'],
})
Aurora DSQL n’autorise pas ASC/DESC dans CREATE INDEX ASYNC. Si vous les incluez, ils seront automatiquement supprimés.
Options des indexLien direct vers Options des index
name:
table:
columns:
unique?:
concurrent?:
where?:
method?:
opclass?:
storage?:
tablespace?:
Gérer les indexLien direct vers Gérer les index
Répertoriez et surveillez les index existants :
// List all indexes
const allIndexes = await storage.listIndexes()
console.log(allIndexes)
// [
// {
// name: 'mastra_threads_pkey',
// table: 'mastra_threads',
// columns: ['id'],
// unique: true,
// size: '16 KB',
// definition: 'CREATE UNIQUE INDEX...'
// },
// ...
// ]
// List indexes for a specific table
const threadIndexes = await storage.listIndexes('mastra_threads')
// Get detailed statistics for an index
const stats = await storage.describeIndex('idx_threads_resource')
console.log(stats)
// {
// name: 'idx_threads_resource',
// table: 'mastra_threads',
// columns: ['resourceId'],
// unique: false,
// size: '128 KB',
// definition: 'CREATE INDEX idx_threads_resource...',
// method: 'btree',
// scans: 1542,
// tuples_read: 45230,
// tuples_fetched: 12050
// }
// Drop an index
await storage.dropIndex('idx_threads_status')
Index propres au schémaLien direct vers Index propres au schéma
Lorsque vous utilisez des schémas personnalisés, les index sont créés avec des préfixes de schéma :
const storage = new DSQLStore({
id: 'my-dsql-store',
host: 'abc123.dsql.us-east-1.on.aws',
schemaName: 'custom_schema',
})
// Creates index as: custom_schema_idx_threads_status
await storage.createIndex({
name: 'idx_threads_status',
table: 'mastra_threads',
columns: ['status'],
})