Migrating to 0.16
From 0.15 to 0.16
Protean 0.16 is a stability and reliability release. Most upgrades are drop-in. The one structural change that may require operator action is the outbox column bounds described below.
On this page:
- Outbox column bounds — a one-time
ALTER TABLEfor existing outbox tables
Outbox column bounds
Tier-3 structural change
The string fields on the Outbox aggregate now declare max_length. SQL
providers therefore emit VARCHAR(N) columns instead of TEXT /
VARCHAR(MAX). This unblocks index creation on the outbox table: SQL Server
refuses to index VARCHAR(MAX), MySQL requires a blind prefix length on
indexed TEXT, and bounded columns are cheaper to store and scan
everywhere.
The affected fields and their bounds:
| Field | max_length |
|---|---|
status |
32 |
target_broker |
128 |
stream_name |
255 |
type |
255 |
locked_by |
128 |
correlation_id |
255 |
causation_id |
255 |
message_id |
255 |
message_id, causation_id, and correlation_id are bounded at 255 rather
than a UUID-sized value because they hold composite Protean message ids (for
example testdomain::order-<aggregate-id>-3) or caller-supplied tracing
strings, not bare UUIDs.
The data and metadata_ columns remain unbounded JSON blobs.
Who is affected
- New deployments: nothing to do. Tables created on 0.16 get the bounded
VARCHAR(N)columns automatically. - Existing deployments with a populated
outboxtable: Protean never alters a populated table. The table keeps working as-is, but to gain the storage and indexing benefits (and to match the schema Protean now emits) run the one-timeALTER TABLEfor your backend below.
Pre-flight verification
No value Protean writes to these fields exceeds the new bounds. Before applying the migration, confirm your existing data also fits:
SELECT
MAX(LENGTH(status)) AS max_status,
MAX(LENGTH(target_broker)) AS max_target_broker,
MAX(LENGTH(stream_name)) AS max_stream_name,
MAX(LENGTH(type)) AS max_type,
MAX(LENGTH(locked_by)) AS max_locked_by,
MAX(LENGTH(correlation_id)) AS max_correlation_id,
MAX(LENGTH(causation_id)) AS max_causation_id,
MAX(LENGTH(message_id)) AS max_message_id
FROM outbox;
On SQL Server, substitute LEN(...) for LENGTH(...) (SQL Server has no
LENGTH function).
If any column exceeds its bound, investigate before applying the migration.
Migration recipes
=== "PostgreSQL"
```sql
ALTER TABLE outbox
ALTER COLUMN status TYPE varchar(32),
ALTER COLUMN target_broker TYPE varchar(128),
ALTER COLUMN stream_name TYPE varchar(255),
ALTER COLUMN type TYPE varchar(255),
ALTER COLUMN locked_by TYPE varchar(128),
ALTER COLUMN correlation_id TYPE varchar(255),
ALTER COLUMN causation_id TYPE varchar(255),
ALTER COLUMN message_id TYPE varchar(255);
```
=== "MySQL"
```sql
ALTER TABLE outbox
MODIFY status varchar(32) NOT NULL,
MODIFY target_broker varchar(128) NULL,
MODIFY stream_name varchar(255) NOT NULL,
MODIFY type varchar(255) NOT NULL,
MODIFY locked_by varchar(128) NULL,
MODIFY correlation_id varchar(255) NULL,
MODIFY causation_id varchar(255) NULL,
MODIFY message_id varchar(255) NOT NULL;
```
=== "SQL Server"
```sql
ALTER TABLE outbox ALTER COLUMN status varchar(32) NOT NULL;
ALTER TABLE outbox ALTER COLUMN target_broker varchar(128) NULL;
ALTER TABLE outbox ALTER COLUMN stream_name varchar(255) NOT NULL;
ALTER TABLE outbox ALTER COLUMN type varchar(255) NOT NULL;
ALTER TABLE outbox ALTER COLUMN locked_by varchar(128) NULL;
ALTER TABLE outbox ALTER COLUMN correlation_id varchar(255) NULL;
ALTER TABLE outbox ALTER COLUMN causation_id varchar(255) NULL;
ALTER TABLE outbox ALTER COLUMN message_id varchar(255) NOT NULL;
```
=== "SQLite"
SQLite does not enforce declared column lengths, so the migration is a
no-op for storage. New databases get the `VARCHAR(N)` declaration;
existing databases continue to function unchanged.