You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/features/sharding/cross-shard-queries/insert.md
+71-4Lines changed: 71 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -86,14 +86,81 @@ Finally, if the `INSERT` statement has more than one tuple, the statement is aut
86
86
87
87
## Sharded tables
88
88
89
-
If the `INSERT`is creating a row in a sharded table, but the primary key is [database-generated](schema_management/primary_keys.md)_and_ used for sharding that table, the statement is sent to only one of the shards, using the round robin algorithm.
89
+
`INSERT`statements targetting sharded tables will commonly provide the sharding key. A notable exception to this rule is tables that shard on the primary key, which is often database-generated, e.g., using a sequence.
90
90
91
-
For example:
91
+
The simplest way to work around this is to use the `pgdog.unique_id()` function to create a unique identifier on the fly, for example:
92
92
93
93
```postgresql
94
-
INSERT INTO users (id, email) VALUES (DEFAULT, 'test@acme.com') RETURNING *;
94
+
INSERT INTO users
95
+
(id, email, created_at)
96
+
VALUES
97
+
(pgdog.unqiue_id(), $1, $2)
98
+
RETURNING *;
95
99
```
96
100
97
-
Instead of creating one user per shard, which would cause duplicate entries, PgDog will let the database generate a _globally_ unique primary key and place it on one of the shards only. This ensures even data distribution across the entire database cluster.
101
+
If however, you prefer to use sequences instead, you can rely on [database-generated](../schema_management/primary_keys.md) primary keys.
102
+
103
+
Statements that don't include the primary key in the `INSERT` tuple will be sent to one of the shards, using same round robin algorithm used for [omnisharded](#omnisharded-tables) tables. The shard will then generate the primary key value using PgDog's [sharded sequences](../schema_management/primary_keys.md#pgdognext_id_seq).
104
+
105
+
For example, assuming the table `users` is sharded on the primary key `id`, omitting it from the `INSERT` statement will send it to only one of the shards:
106
+
107
+
```postgresql
108
+
INSERT INTO users (email, created_at) VALUES ($1, $2) RETURNING *;
109
+
```
98
110
99
111
## Multiple tuples
112
+
113
+
In order to create multiple rows at once, the PostgreSQL query syntax supports sending multiple tuples in one statement. For example:
114
+
115
+
```postgresql
116
+
INSERT INTO users
117
+
(id, email, created_at)
118
+
VALUES
119
+
($1, $2, $3),
120
+
($4, $5, $6);
121
+
```
122
+
123
+
In sharded databases, however, the individual tuples are likley to belong on different shards. To make this work, PgDog can automatically rewrite the statement and send each tuple to the right shard. Using the example above, the result of that operation produces two single-tuple statements:
124
+
125
+
=== "Statement 1"
126
+
```postgresql
127
+
INSERT INTO users
128
+
(id, email, created_at)
129
+
VALUES
130
+
($1, $2, $3)
131
+
```
132
+
=== "Statement 2"
133
+
```postgresql
134
+
INSERT INTO users
135
+
(id, email, created_at)
136
+
VALUES
137
+
($1, $2, $3)
138
+
```
139
+
140
+
This works for all queries, including prepared statements. PgDog will rewrite all Postgres protocol messages (e.g., `Bind`, `Describe`, etc.) without the application having to change its queries.
141
+
142
+
Since this feature has additional overhead by using multiple shards for each query, it is **disabled** by default and can be enabled in [`pgdog.toml`](../../../configuration/pgdog.toml/rewrite.md):
143
+
144
+
```toml
145
+
[rewrite]
146
+
enabled = true
147
+
split_inserts = "rewrite"
148
+
```
149
+
150
+
### Transaction required
151
+
152
+
Since multi-tuple inserts will likely write rows to several shards, PgDog requires the application to start a transaction before executing such queries. For example:
153
+
154
+
```postgresql
155
+
BEGIN;
156
+
INSERT INTO users (email, created_at) VALUES ($1, $2), ($3, $4);
157
+
COMMIT; -- or ROLLBACK;
158
+
```
159
+
160
+
If a transaction isn't started and a multi-tuple statement is sent by the application, PgDog will return an error and abort the request.
161
+
162
+
Requiring transactions ensures that if one of the `INSERT` statements fails, e.g., because of a unique constraint violation, the transaction can be rolled back, leaving the database in a consistent state.
163
+
164
+
!!! note "Consistency guarantees"
165
+
166
+
Much like [omnisharded](#omnisharded-tables) table inserts, it's best to enable [2pc](../2pc.md) before attempting cross-shard multi-tuple inserts. This feature increases the likelihood that cross-shard transactions are atomic.
0 commit comments