Skip to content

Commit dc98835

Browse files
nwoolmermtopolnik
andauthored
9.0.0 release roundup (#207)
Rounds up a few changes from 9.0.0. --------- Co-authored-by: Marko Topolnik <[email protected]>
1 parent e2fb6d0 commit dc98835

File tree

7 files changed

+358
-130
lines changed

7 files changed

+358
-130
lines changed

documentation/concept/array.md

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,21 +103,6 @@ QuestDB always stores arrays in vanilla form. If you transform an array's shape
103103
and then store it to the database, QuestDB will physically rearrange the
104104
elements, and store the new array in vanilla shape.
105105

106-
## Array and NULL/Nan/Infinity values
107-
108-
QuestDB does not support `NULL` values in arrays. In a scalar `DOUBLE` column,
109-
if the value is `NaN`, it is treated as `NULL` in calculations. However, when it
110-
appears inside an array, it is treated as such, and not `NULL`. If it appears in
111-
an array and you take it out using the array access expression, the resulting
112-
scalar value will again be treated as `NULL`, however whole-array operations
113-
like `array_sum` will treat it according to its floating-point number semantics.
114-
115-
QuestDB currently has an inconsistency in treating floating-point infinities.
116-
They are sometimes treated as `NULL`, and sometimes not. Infinity values
117-
currently produce unspecified behavior as scalar `DOUBLE` values, but inside an
118-
array, while performing whole-array operations, they are consistently treated as
119-
infinity.
120-
121106
## The ARRAY literal
122107

123108
You can create an array from scalar values using the `ARRAY[...]` syntax, as

documentation/concept/replication.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ timeline
8787
Currently : AWS S3
8888
: Azure Blob Store
8989
: NFS Filesystem
90+
: Google Cloud Storage
9091
Next-up : HDFS
91-
Later on : Google Cloud Storage
9292
```
9393

9494
Something missing? Want to see it sooner? [Contact us](/enterprise/contact)!
@@ -109,6 +109,12 @@ is:
109109
An example of a replication object store configuration using NFS is:
110110
`replication.object.store=fs::root=/mnt/nfs_replication/final;atomic_write_dir=/mnt/nfs_replication/scratch;`
111111

112+
An example of a replication object store configuration using GCS is:
113+
114+
`replication.object.store=gcs::bucket=<bucket name here>;root=/;credential=<base64 encoded key>;`
115+
116+
For `GCS`, you can also use `credential_path` to set a key-file location.
117+
112118
See the [Replication setup guide](/docs/operations/replication) for direct
113119
examples.
114120

documentation/operations/replication.md

Lines changed: 105 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ cost-effective WAL file storage. For further information, see the
7878
section.
7979

8080
After that,
81-
[create a Blob Container ](https://learn.microsoft.com/en-us/azure/storage/blobs/quickstart-storage-explorer)to
81+
[create a Blob Container](https://learn.microsoft.com/en-us/azure/storage/blobs/quickstart-storage-explorer) to
8282
be the root of your replicated data blobs.
8383

8484
It will will soon be referenced in the `BLOB_CONTAINER` variable.
@@ -133,8 +133,8 @@ For appropriate balance, be sure to:
133133
- Disable blob versioning
134134

135135
Finally,
136-
[set up bucket lifecycle configuration policy ](https://docs.aws.amazon.com/AmazonS3/latest/userguide/how-to-set-lifecycle-configuration-intro.html)to
137-
clean up WAL files after a period of time. There are considerations to ensure
136+
[set up bucket lifecycle configuration policy](https://docs.aws.amazon.com/AmazonS3/latest/userguide/how-to-set-lifecycle-configuration-intro.html)
137+
to clean up WAL files after a period of time. There are considerations to ensure
138138
that the storage of the WAL files remains cost-effective. For deeper background,
139139
see the
140140
[object storage expiration policy](/docs/operations/replication/#snapshot-schedule-and-object-store-expiration-policy)
@@ -201,6 +201,38 @@ With your values, skip to the
201201
[Setup database replication](/docs/operations/replication/#setup-database-replication)
202202
section.
203203

204+
### Google GCP GCS
205+
206+
First, create a new Google Cloud Storage (GCS) bucket, most likely with
207+
`Public access: Not public`.
208+
209+
Then create a new service account, and give it read-write permissions for the
210+
bucket. The simplest role is `Storage Admin`, but you may set up more granular
211+
permissions as needed.
212+
213+
Create a new private key for this user and download it in `JSON` format. Then
214+
encode this key as `Base64`.
215+
216+
If you are on Linux, you can `cat` the file and pass it to `base64`:
217+
218+
```
219+
cat <key>.json | base64
220+
```
221+
222+
Then construct the connection string:
223+
224+
```
225+
replication.object.store=gcs::bucket=<bucket name here>;root=/;credential=<base64 encoded key>;
226+
```
227+
228+
If you do not want to put the credentials directly in the connection string, you
229+
can swap the `credential` key for `credential_path`, and give it a path to the
230+
key-file.
231+
232+
With your values, continue to the
233+
[Setup database replication](/docs/operations/replication/#setup-database-replication)
234+
section.
235+
204236
## Setup database replication
205237

206238
Set the following changes in their respective `server.conf` files:
@@ -340,36 +372,42 @@ In general, we can group them into a small matrix:
340372
| primary | restart primary | promote replica, create new replica |
341373
| replica | restart replica | destroy and recreate replica |
342374

343-
To successfully recover from serious failures, we strongly advise that operators:
375+
To successfully recover from serious failures, we strongly advise that operators:
344376

345-
* Follow best practices
346-
* **Regularly back up data**
377+
- Follow best practices
378+
- **Regularly back up data**
347379

348380
### Network partitions
349381

350-
Temporary network partitions introduce delays between when data is written to the primary, and when it becomes available
351-
for read in the replica. A temporary network partition is not necessarily a problem.
382+
Temporary network partitions introduce delays between when data is written to
383+
the primary, and when it becomes available for read in the replica. A temporary
384+
network partition is not necessarily a problem.
352385

353-
For example, data can be ingested into the primary when the object-store is not available. In this case, the replicas will contain stale data,
354-
and then catch-up when the primary reconnects and successfully uploads to the object store.
386+
For example, data can be ingested into the primary when the object-store is not
387+
available. In this case, the replicas will contain stale data, and then catch-up
388+
when the primary reconnects and successfully uploads to the object store.
355389

356-
Permanent network partitions are not recoverable, and the [emergency primary migration](#emergency-primary-migration) flow should be followed.
390+
Permanent network partitions are not recoverable, and the
391+
[emergency primary migration](#emergency-primary-migration) flow should be
392+
followed.
357393

358394
### Instance crashes
359395

360-
An instance crash may be recoverable or unrecoverable, depending on the specific cause of the crash.
361-
If the instance crashes during ingestion, then it is possible for transactions to be corrupted.
362-
This will lead to a table suspension on restart.
396+
An instance crash may be recoverable or unrecoverable, depending on the specific
397+
cause of the crash. If the instance crashes during ingestion, then it is
398+
possible for transactions to be corrupted. This will lead to a table suspension
399+
on restart.
363400

364401
To recover in this case, you can skip the transaction,
365402
and reload any missing data.
366403

367-
In the event that the corruption is severe, or confidence in the underlying instance is removed, you should follow the
404+
In the event that the corruption is severe, or confidence in the underlying
405+
instance is removed, you should follow the
368406
[emergency primary migration](#emergency-primary-migration) flow.
369407

370408
### Disk or block storage failure
371409

372-
Disk failures can present in several forms, which may be difficult to detect.
410+
Disk failures can present in several forms, which may be difficult to detect.
373411

374412
Look for the following symptoms:
375413

@@ -383,28 +421,31 @@ Look for the following symptoms:
383421
- This is usually caused by writes to disk partially or completely failing
384422
- This can also be caused by running out of disk space
385423

386-
As with an instance crash, the consequences can be far-reaching and not immediately clear in all cases.
387-
388-
To migrate to a new disk, follow the [emergency primary migration](#emergency-primary-migration) flow. When you create a new replica, you
389-
can populate it with the latest snapshot you have taken, and then recover the rest using replicated WALs in the object
390-
store.
424+
As with an instance crash, the consequences can be far-reaching and not
425+
immediately clear in all cases.
391426

427+
To migrate to a new disk, follow the
428+
[emergency primary migration](#emergency-primary-migration) flow. When you
429+
create a new replica, you can populate it with the latest snapshot you have
430+
taken, and then recover the rest using replicated WALs in the object store.
392431

393432
### Flows
394433

395434
#### Planned primary migration
396435

397-
Use this flow when you want to change your primary to another instance, but the primary has not failed.
436+
Use this flow when you want to change your primary to another instance, but the
437+
primary has not failed.
398438

399-
The database can be started in a mode which disallows further ingestion, but allows replication. With this method, you can ensure that all outstanding data has been replicated before you start ingesting into a new primary instance.
439+
The database can be started in a mode which disallows further ingestion, but
440+
allows replication. With this method, you can ensure that all outstanding data
441+
has been replicated before you start ingesting into a new primary instance.
400442

401443
- Ensure primary instance is still capable of replicating data to the object store
402444
- Stop primary instance
403445
- Restart primary instance with `replication.role=primary-catchup-uploads`
404446
- Wait for the instance to complete its uploads and exit with `code 0`
405447
- Then follow the [emergency primary migration](#emergency-primary-migration) flow
406448

407-
408449
#### Emergency primary migration
409450

410451
Use this flow when you wish to discard a failed primary instance and move to a new one.
@@ -413,56 +454,72 @@ Use this flow when you wish to discard a failed primary instance and move to a n
413454
- Stop the replica instance
414455
- Set `replication.role=primary` on the replica
415456
- Ensure other primary-related settings are configured appropriately
416-
- for example, snapshotting policies
417-
- Create an empty `_migrate_primary` file in your database installation directory (i.e. the parent of `conf` and `db`)
457+
- for example, snapshotting policies
458+
- Create an empty `_migrate_primary` file in your database installation
459+
directory (i.e. the parent of `conf` and `db`)
418460
- Start the replica instance, which is now the new primary
419461
- Create a new replica instance to replace the promoted replica
420462

421463
:::warning
422464

423-
Any data committed to the primary, but not yet replicated, will be lost. If the primary has not
424-
completely failed, you can follow the [planned primary migration](#planned-primary-migration) flow
425-
to ensure that all remaining data has been replicated before switching primary.
465+
Any data committed to the primary, but not yet replicated, will be lost. If the
466+
primary has not completely failed, you can follow the
467+
[planned primary migration](#planned-primary-migration) flow to ensure that all
468+
remaining data has been replicated before switching primary.
426469

427470
:::
428471

429472
#### When could migration fail?
430473

431-
Two primaries started within the same `replication.primary.keepalive.interval=10s` may still break.
474+
Two primaries started within the same
475+
`replication.primary.keepalive.interval=10s` may still break.
432476

433-
It is important not to migrate the primary without stopping the first primary, if it is still within this interval.
477+
It is important not to migrate the primary without stopping the first primary,
478+
if it is still within this interval.
434479

435480
This config can be set in the range of 1 to 300 seconds.
436481

437482
#### Point-in-time recovery
438483

439-
Create a QuestDB instance matching a specific historical point in time.
484+
Create a QuestDB instance matching a specific historical point in time.
440485

441-
This is builds a new instance based on a recently recovered snapshot and WAL data in the object store.
486+
This is builds a new instance based on a recently recovered snapshot and WAL
487+
data in the object store.
442488

443-
It can also be used if you wish to remove the latest transactions from the database, or if you encounter corrupted
444-
transactions (though replicating a corrupt transaction has never been observed).
489+
It can also be used if you wish to remove the latest transactions from the
490+
database, or if you encounter corrupted transactions (though replicating a
491+
corrupt transaction has never been observed).
445492

446493
**Flow**
447494

448-
- (Recommended) Locate a recent primary instance snapshot that predates your intended recovery timestamp.
449-
- A snapshot taken from **after** your intended recovery timestamp will not work.
450-
- Create the new primary instance, ideally from a snapshot, and ensure it is not running.
495+
- (Recommended) Locate a recent primary instance snapshot that predates your
496+
intended recovery timestamp.
497+
- A snapshot taken from **after** your intended recovery timestamp will not work.
498+
- Create the new primary instance, ideally from a snapshot, and ensure it is not
499+
running.
451500
- Touch a `_recover_point_in_time` file.
452-
- Inside this file, add a `replication.object.store` setting pointing to the object store you wish to load transactions from.
453-
- Also add a `replication.recovery.timestamp` setting with the UTC time to which you would like to recover.
454-
- The format is `YYYY-MM-DDThh:mm:ss.mmmZ`.
455-
- (Optional) Configure replication settings in `server.conf` pointing at a **new** object store location.
456-
- You can either configure this instance as a standalone (non-replicated) instance, or
457-
- Configure it as a new primary by setting `replication.role=primary`. In this case, the `replication.object.store` **must** point to a fresh, empty location.
458-
- If you have created the new primary using a snapshot, touch a `_restore` file to trigger the snapshot recovery process.
459-
- More details can be found in the [backup and restore](/documentation/operations/backup.md) documentation.
501+
- Inside this file, add a `replication.object.store` setting pointing to the
502+
object store you wish to load transactions from.
503+
- Also add a `replication.recovery.timestamp` setting with the UTC time to which
504+
you would like to recover.
505+
- The format is `YYYY-MM-DDThh:mm:ss.mmmZ`.
506+
- (Optional) Configure replication settings in `server.conf` pointing at a
507+
**new** object store location.
508+
- You can either configure this instance as a standalone (non-replicated)
509+
instance, or
510+
- Configure it as a new primary by setting `replication.role=primary`. In this
511+
case, the `replication.object.store` **must** point to a fresh, empty
512+
location.
513+
- If you have created the new primary using a snapshot, touch a `_restore` file
514+
to trigger the snapshot recovery process.
515+
- More details can be found in the
516+
[backup and restore](/documentation/operations/backup.md) documentation.
460517
- Start new primary instance.
461518

462519
## Multi-primary ingestion
463520

464521
[QuestDB Enterprise](/enterprise/) supports multi-primary ingestion, where
465522
multiple primaries can write to the same database.
466523

467-
See the [Multi-primary ingestion](/docs/operations/multi-primary-ingestion/) page for
468-
more information.
524+
See the [Multi-primary ingestion](/docs/operations/multi-primary-ingestion/)
525+
page for more information.

0 commit comments

Comments
 (0)