@@ -318,29 +318,82 @@ func (c *PGConfig) validateCompatibility(requested ConfigMap) (ConfigMap, error)
318
318
// Wal-level
319
319
if v , ok := requested ["wal_level" ]; ok {
320
320
value := v .(string )
321
+ switch value {
322
+ case "minimal" :
323
+ var maxWalSenders int64
321
324
322
- // Postgres will not boot properly if minimal is set with archive_mode enabled .
323
- if value == "minimal" {
324
- valid := false
325
- if val , ok := requested [ "archive_mode" ]; ok {
326
- if val == "off" {
327
- valid = true
328
- }
325
+ // flyctl passes in `max_wal_senders` in as a string .
326
+ maxWalSendersInterface := resolveConfigValue ( requested , current , "max_wal_senders" , "10" )
327
+
328
+ // Convert string to int
329
+ maxWalSenders , err = strconv . ParseInt ( maxWalSendersInterface .( string ), 10 , 64 )
330
+ if err != nil {
331
+ return requested , fmt . Errorf ( "failed to parse max-wal-senders: %s" , err )
329
332
}
330
333
331
- if ! valid && current [ "archive_mode" ] == "off" {
332
- valid = true
334
+ if maxWalSenders > 0 {
335
+ return requested , fmt . Errorf ( "max_wal_senders must be set to `0` before wal-level can be set to `minimal`" )
333
336
}
334
337
335
- if ! valid {
338
+ archiveMode := resolveConfigValue (requested , current , "archive_mode" , "off" )
339
+ if archiveMode .(string ) != "off" {
336
340
return requested , errors .New ("archive_mode must be set to `off` before wal_level can be set to `minimal`" )
337
341
}
342
+
343
+ case "replica" , "logical" :
344
+ var maxWalSenders int64
345
+ maxWalSendersInterface := resolveConfigValue (requested , current , "max_wal_senders" , "10" )
346
+
347
+ // Convert string to int
348
+ maxWalSenders , err = strconv .ParseInt (maxWalSendersInterface .(string ), 10 , 64 )
349
+ if err != nil {
350
+ return requested , fmt .Errorf ("failed to parse max-wal-senders: %s" , err )
351
+ }
352
+
353
+ if maxWalSenders == 0 {
354
+ return requested , fmt .Errorf ("max_wal_senders must be greater than `0`" )
355
+ }
356
+ }
357
+ }
358
+
359
+ // Max-wal-senders
360
+ if v , ok := requested ["max_wal_senders" ]; ok {
361
+ val := v .(string )
362
+
363
+ // Convert string to int
364
+ maxWalSenders , err := strconv .ParseInt (val , 10 , 64 )
365
+ if err != nil {
366
+ return requested , fmt .Errorf ("failed to parse max-wal-senders: %s" , err )
338
367
}
368
+
369
+ walLevel := resolveConfigValue (requested , current , "wal_level" , "replica" )
370
+
371
+ if maxWalSenders > 0 && walLevel == "minimal" {
372
+ return requested , fmt .Errorf ("max_wal_senders must be set to `0` when wal_level is `minimal`" )
373
+ }
374
+
375
+ if maxWalSenders == 0 && walLevel != "minimal" {
376
+ return requested , fmt .Errorf ("max_wal_senders must be greater than `0` when wal_level is set to `%s`" , walLevel .(string ))
377
+ }
378
+
339
379
}
340
380
341
381
return requested , nil
342
382
}
343
383
384
+ func resolveConfigValue (requested ConfigMap , current ConfigMap , key string , defaultVal interface {}) interface {} {
385
+ val := requested [key ]
386
+ if val == nil {
387
+ val = current [key ]
388
+ }
389
+
390
+ if val == nil {
391
+ val = defaultVal
392
+ }
393
+
394
+ return val
395
+ }
396
+
344
397
type HBAEntry struct {
345
398
Type string
346
399
Database string
0 commit comments