Repository: VictoriaMetrics/VictoriaMetrics
Pull request #3049 (2022-08-31 12:41:02)

vmselect/{promql, prometheus}: show flag names which user can update in error message
Updated error messages when user is using flags like `-search.maxPointsPerTimeseries` and `-search.maxPointsSubqueryPerTimeseries`.
User will be able to see which flag must be updated.

Related issue: https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2922#issuecomment-1230518416

codecov[bot]: # [Codecov](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3049?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) Report
> Merging [#3049](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3049?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) (223c4c2) into [master](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/commit/6b0050a028c396be63df65551fcd64ee14ce6a0f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) (6b0050a) will **decrease** coverage by `0.05%`.
> The diff coverage is `33.33%`.

> :exclamation: Current head 223c4c2 differs from pull request most recent head 6d94e7f. Consider uploading reports for the commit 6d94e7f to get more accurate results

```diff
@@            Coverage Diff             @@
##           master    #3049      +/-   ##
==========================================
- Coverage   58.02%   57.97%   -0.06%     
==========================================
  Files         275      275              
  Lines       46510    46510              
==========================================
- Hits        26988    26962      -26     
- Misses      17751    17773      +22     
- Partials     1771     1775       +4     
```


| [Impacted Files](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3049?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) | Coverage Δ | |
|---|---|---|
| [app/vmselect/prometheus/prometheus.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3049/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21ldGhldXMvcHJvbWV0aGV1cy5nbw==) | `6.30% <0.00%> (ø)` | |
| [app/vmselect/promql/eval.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3049/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC9ldmFsLmdv) | `61.15% <50.00%> (ø)` | |
| [app/vmselect/promql/aggr\_incremental.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3049/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC9hZ2dyX2luY3JlbWVudGFsLmdv) | `81.92% <0.00%> (-4.52%)` | :arrow_down: |
| [lib/bloomfilter/filter.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3049/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-bGliL2Jsb29tZmlsdGVyL2ZpbHRlci5nbw==) | `98.00% <0.00%> (-2.00%)` | :arrow_down: |
| [lib/mergeset/table.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3049/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-bGliL21lcmdlc2V0L3RhYmxlLmdv) | `65.22% <0.00%> (-1.35%)` | :arrow_down: |
| [lib/storage/storage.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3049/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-bGliL3N0b3JhZ2Uvc3RvcmFnZS5nbw==) | `69.57% <0.00%> (+0.11%)` | :arrow_up: |
| [app/vmalert/remotewrite/remotewrite.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3049/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvcmVtb3Rld3JpdGUvcmVtb3Rld3JpdGUuZ28=) | `66.44% <0.00%> (+1.34%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics)


Patch:
diff --git a/Makefile b/Makefile
index 04705006f..1cecae609 100644
--- a/Makefile
+++ b/Makefile
@@ -170,6 +170,7 @@ publish-release:
 		git checkout $(TAG)-cluster && $(MAKE) release publish && \
 		git checkout $(TAG)-enterprise && $(MAKE) release publish && \
 		git checkout $(TAG)-enterprise-cluster && $(MAKE) release publish && \
+		git checkout $(TAG) && git push public $(TAG) && git push public $(TAG)-cluster && \
 		$(MAKE) github-create-release && \
 		$(MAKE) github-upload-assets
 
diff --git a/README.md b/README.md
index 51a3a9881..dc351320d 100644
--- a/README.md
+++ b/README.md
@@ -326,11 +326,45 @@ See also [vmagent](https://docs.victoriametrics.com/vmagent.html), which can be
 
 VictoriaMetrics accepts data from [DataDog agent](https://docs.datadoghq.com/agent/) or [DogStatsD](https://docs.datadoghq.com/developers/dogstatsd/) via ["submit metrics" API](https://docs.datadoghq.com/api/latest/metrics/#submit-metrics) at `/datadog/api/v1/series` path.
 
-Run DataDog agent with `DD_DD_URL=http://victoriametrics-host:8428/datadog` environment variable in order to write data to VictoriaMetrics at `victoriametrics-host` host. Another option is to set `dd_url` param at [DataDog agent configuration file](https://docs.datadoghq.com/agent/guide/agent-configuration-files/) to `http://victoriametrics-host:8428/datadog`.
+Single-node VictoriaMetrics:
+
+Run DataDog agent with environment variable `DD_DD_URL=http://victoriametrics-host:8428/datadog`. Alternatively, set `dd_url` param at [DataDog agent configuration file](https://docs.datadoghq.com/agent/guide/agent-configuration-files/) to `http://victoriametrics-host:8428/datadog`.
+
+Cluster version of VictoriaMetrics:
+
+Run DataDog agent with environment variable `DD_DD_URL=http://vinsert-host:8480/insert/0/datadog`. Alternatively, set `dd_url` param at [DataDog agent configuration file](https://docs.datadoghq.com/agent/guide/agent-configuration-files/) to `DD_DD_URL=http://vinsert-host:8480/insert/0/datadog`.
 
 VictoriaMetrics doesn't check `DD_API_KEY` param, so it can be set to arbitrary value.
 
-Example on how to send data to VictoriaMetrics via DataDog "submit metrics" API from command line:
+Example of how to send data to VictoriaMetrics via [DataDog "submit metrics"](https://docs.victoriametrics.com/url-examples.html#datadogapiv1series) from command line:
+
+Single-node VictoriaMetrics:
+
+```console
+echo '
+{
+  "series": [
+    {
+      "host": "test.example.com",
+      "interval": 20,
+      "metric": "system.load.1",
+      "points": [[
+        0,
+        0.5
+      ]],
+      "tags": [
+        "environment:test"
+      ],
+      "type": "rate"
+    }
+  ]
+}
+' | curl -X POST --data-binary @- http://victoriametrics-host:8428/datadog/api/v1/series
+```
+
+Cluster version of VictoriaMetrics:
+
+<div class="with-copy" markdown="1">
 
 ```console
 echo '
@@ -351,15 +385,30 @@ echo '
     }
   ]
 }
-' | curl -X POST --data-binary @- http://localhost:8428/datadog/api/v1/series
+' | curl -X POST --data-binary @- http://vminsert-host:8480/insert/0/datadog/api/v1/series
+```
+
+</div>
+
+
+The imported data can be read via [export API](https://docs.victoriametrics.com/url-examples.html#apiv1export):
+
+Single-node VictoriaMetrics:
+
+<div class="with-copy" markdown="1">
+
+```console
+curl http://victoriametrics-host:8428/api/v1/export -d 'match[]=system.load.1'
 ```
 
-The imported data can be read via [export API](https://docs.victoriametrics.com/#how-to-export-data-in-json-line-format):
+</div>
+
+Cluster version of VictoriaMetrics:
 
 <div class="with-copy" markdown="1">
 
 ```console
-curl http://localhost:8428/api/v1/export -d 'match[]=system.load.1'
+curl http://vmselect-host:8481/select/0/prometheus/api/v1/export -d 'match[]=system.load.1'
 ```
 
 </div>
@@ -638,7 +687,7 @@ VictoriaMetrics accepts `round_digits` query arg for `/api/v1/query` and `/api/v
 
 VictoriaMetrics accepts `limit` query arg for `/api/v1/labels` and `/api/v1/label/<labelName>/values` handlers for limiting the number of returned entries. For example, the query to `/api/v1/labels?limit=5` returns a sample of up to 5 unique labels, while ignoring the rest of labels. If the provided `limit` value exceeds the corresponding `-search.maxTagKeys` / `-search.maxTagValues` command-line flag values, then limits specified in the command-line flags are used.
 
-By default, VictoriaMetrics returns time series for the last 5 minutes from `/api/v1/series`, while the Prometheus API defaults to all time.  Use `start` and `end` to select a different time range.
+By default, VictoriaMetrics returns time series for the last 5 minutes from `/api/v1/series`, `/api/v1/labels` and `/api/v1/label/<labelName>/values` while the Prometheus API defaults to all time.  Explicitly set `start` and `end` to select the desired time range.
 VictoriaMetrics accepts `limit` query arg for `/api/v1/series` handlers for limiting the number of returned entries. For example, the query to `/api/v1/series?limit=5` returns a sample of up to 5 series, while ignoring the rest. If the provided `limit` value exceeds the corresponding `-search.maxSeries` command-line flag values, then limits specified in the command-line flags are used.
 
 Additionally, VictoriaMetrics provides the following handlers:
diff --git a/app/vmctl/README.md b/app/vmctl/README.md
index cb5b23e8e..ae33f2daa 100644
--- a/app/vmctl/README.md
+++ b/app/vmctl/README.md
@@ -521,6 +521,74 @@ To avoid such situation try to filter out VM process metrics via `--vm-native-fi
 Instead, use [relabeling in VictoriaMetrics](https://github.com/VictoriaMetrics/vmctl/issues/4#issuecomment-683424375).
 5. When importing in or from cluster version remember to use correct [URL format](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#url-format)
 and specify `accountID` param.
+6. When migrating large volumes of data it might be useful to use `--vm-native-step-interval` flag to split single process into smaller steps.
+
+#### Using time-based chunking of migration
+
+It is possible split migration process into set of smaller batches based on time. This is especially useful when migrating large volumes of data as this adds indication of progress and ability to restore process from certain point in case of failure.
+
+To use this you need to specify `--vm-native-step-interval` flag. Supported values are: `month`, `day`, `hour`.
+Note that in order to use this it is required `--vm-native-filter-time-start` to be set to calculate time ranges for export process.
+
+Every range is being processed independently, which means that:
+- after range processing is finished all data within range is migrated
+- if process fails on one of stages it is guaranteed that data of prior stages is already written, so it is possible to restart process starting from failed range
+
+It is recommended using the `month` step when migrating the data over multiple months, since the migration with `day` and `hour` steps may take longer time to complete
+because of additional overhead.
+
+Usage example:
+```console
+./vmctl vm-native 
+    --vm-native-filter-time-start 2022-06-17T00:07:00Z \
+    --vm-native-filter-time-end 2022-10-03T00:07:00Z \
+    --vm-native-src-addr http://localhost:8428 \
+    --vm-native-dst-addr http://localhost:8528 \
+    --vm-native-step-interval=month
+VictoriaMetrics Native import mode
+2022/08/30 19:48:24 Processing range 1/5: 2022-06-17T00:07:00Z - 2022-06-30T23:59:59Z 
+2022/08/30 19:48:24 Initing export pipe from "http://localhost:8428" with filters: 
+        filter: match[]={__name__!=""}
+        start: 2022-06-17T00:07:00Z
+        end: 2022-06-30T23:59:59Z
+Initing import process to "http://localhost:8428":
+2022/08/30 19:48:24 Import finished!
+Total: 16 B ↗ Speed: 28.89 KiB p/s 
+2022/08/30 19:48:24 Processing range 2/5: 2022-07-01T00:00:00Z - 2022-07-31T23:59:59Z 
+2022/08/30 19:48:24 Initing export pipe from "http://localhost:8428" with filters: 
+        filter: match[]={__name__!=""}
+        start: 2022-07-01T00:00:00Z
+        end: 2022-07-31T23:59:59Z
+Initing import process to "http://localhost:8428":
+2022/08/30 19:48:24 Import finished!
+Total: 16 B ↗ Speed: 164.35 KiB p/s 
+2022/08/30 19:48:24 Processing range 3/5: 2022-08-01T00:00:00Z - 2022-08-31T23:59:59Z 
+2022/08/30 19:48:24 Initing export pipe from "http://localhost:8428" with filters: 
+        filter: match[]={__name__!=""}
+        start: 2022-08-01T00:00:00Z
+        end: 2022-08-31T23:59:59Z
+Initing import process to "http://localhost:8428":
+2022/08/30 19:48:24 Import finished!
+Total: 16 B ↗ Speed: 191.42 KiB p/s 
+2022/08/30 19:48:24 Processing range 4/5: 2022-09-01T00:00:00Z - 2022-09-30T23:59:59Z 
+2022/08/30 19:48:24 Initing export pipe from "http://localhost:8428" with filters: 
+        filter: match[]={__name__!=""}
+        start: 2022-09-01T00:00:00Z
+        end: 2022-09-30T23:59:59Z
+Initing import process to "http://localhost:8428":
+2022/08/30 19:48:24 Import finished!
+Total: 16 B ↗ Speed: 141.04 KiB p/s 
+2022/08/30 19:48:24 Processing range 5/5: 2022-10-01T00:00:00Z - 2022-10-03T00:07:00Z 
+2022/08/30 19:48:24 Initing export pipe from "http://localhost:8428" with filters: 
+        filter: match[]={__name__!=""}
+        start: 2022-10-01T00:00:00Z
+        end: 2022-10-03T00:07:00Z
+Initing import process to "http://localhost:8428":
+2022/08/30 19:48:24 Import finished!
+Total: 16 B ↗ Speed: 186.32 KiB p/s 
+2022/08/30 19:48:24 Total time: 12.680582ms
+```
+
 
 ## Verifying exported blocks from VictoriaMetrics
 
diff --git a/app/vmctl/flags.go b/app/vmctl/flags.go
index 348d983b8..3a8dd0c4e 100644
--- a/app/vmctl/flags.go
+++ b/app/vmctl/flags.go
@@ -4,6 +4,8 @@ import (
 	"fmt"
 
 	"github.com/urfave/cli/v2"
+
+	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmctl/stepper"
 )
 
 const (
@@ -318,6 +320,7 @@ const (
 	vmNativeFilterMatch     = "vm-native-filter-match"
 	vmNativeFilterTimeStart = "vm-native-filter-time-start"
 	vmNativeFilterTimeEnd   = "vm-native-filter-time-end"
+	vmNativeStepInterval    = "vm-native-step-interval"
 
 	vmNativeSrcAddr     = "vm-native-src-addr"
 	vmNativeSrcUser     = "vm-native-src-user"
@@ -345,6 +348,10 @@ var (
 			Name:  vmNativeFilterTimeEnd,
 			Usage: "The time filter may contain either unix timestamp in seconds or RFC3339 values. E.g. '2020-01-01T20:07:00Z'",
 		},
+		&cli.StringFlag{
+			Name:  vmNativeStepInterval,
+			Usage: fmt.Sprintf("Split export data into chunks. Requires setting --%s. Valid values are '%s','%s','%s'.", vmNativeFilterTimeStart, stepper.StepMonth, stepper.StepDay, stepper.StepHour),
+		},
 		&cli.StringFlag{
 			Name: vmNativeSrcAddr,
 			Usage: "VictoriaMetrics address to perform export from. \n" +
diff --git a/app/vmctl/main.go b/app/vmctl/main.go
index 3c37fdd24..891ff0c78 100644
--- a/app/vmctl/main.go
+++ b/app/vmctl/main.go
@@ -11,6 +11,8 @@ import (
 	"syscall"
 	"time"
 
+	"github.com/urfave/cli/v2"
+
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmctl/influx"
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmctl/opentsdb"
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmctl/prometheus"
@@ -18,7 +20,6 @@ import (
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/buildinfo"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/protoparser/common"
 	parser "github.com/VictoriaMetrics/VictoriaMetrics/lib/protoparser/native"
-	"github.com/urfave/cli/v2"
 )
 
 func main() {
@@ -161,6 +162,7 @@ func main() {
 							match:     c.String(vmNativeFilterMatch),
 							timeStart: c.String(vmNativeFilterTimeStart),
 							timeEnd:   c.String(vmNativeFilterTimeEnd),
+							chunk:     c.String(vmNativeStepInterval),
 						},
 						src: &vmNativeClient{
 							addr:     strings.Trim(c.String(vmNativeSrcAddr), "/"),
diff --git a/app/vmctl/stepper/split.go b/app/vmctl/stepper/split.go
new file mode 100644
index 000000000..15c176b09
--- /dev/null
+++ b/app/vmctl/stepper/split.go
@@ -0,0 +1,63 @@
+package stepper
+
+import (
+	"fmt"
+	"time"
+)
+
+const (
+	// StepMonth represents a one month interval
+	StepMonth string = "month"
+	// StepDay represents a one day interval
+	StepDay string = "day"
+	// StepHour represents a one hour interval
+	StepHour string = "hour"
+)
+
+// SplitDateRange splits start-end range in a subset of ranges respecting the given step
+// Ranges with granularity of StepMonth are aligned to 1st of each month in order to improve export efficiency at block transfer level
+func SplitDateRange(start, end time.Time, step string) ([][]time.Time, error) {
+
+	if start.After(end) {
+		return nil, fmt.Errorf("start time %q should come before end time %q", start.Format(time.RFC3339), end.Format(time.RFC3339))
+	}
+
+	var nextStep func(time.Time) (time.Time, time.Time)
+
+	switch step {
+	case StepMonth:
+		nextStep = func(t time.Time) (time.Time, time.Time) {
+			endOfMonth := time.Date(t.Year(), t.Month()+1, 1, 0, 0, 0, 0, t.Location()).Add(-1 * time.Nanosecond)
+			if t == endOfMonth {
+				endOfMonth = time.Date(t.Year(), t.Month()+2, 1, 0, 0, 0, 0, t.Location()).Add(-1 * time.Nanosecond)
+				t = time.Date(t.Year(), t.Month()+1, 1, 0, 0, 0, 0, t.Location())
+			}
+			return t, endOfMonth
+		}
+	case StepDay:
+		nextStep = func(t time.Time) (time.Time, time.Time) {
+			return t, t.AddDate(0, 0, 1)
+		}
+	case StepHour:
+		nextStep = func(t time.Time) (time.Time, time.Time) {
+			return t, t.Add(time.Hour * 1)
+		}
+	default:
+		return nil, fmt.Errorf("failed to parse step value, valid values are: '%s', '%s', '%s'. provided: '%s'", StepMonth, StepDay, StepHour, step)
+	}
+
+	currentStep := start
+
+	ranges := make([][]time.Time, 0)
+
+	for end.After(currentStep) {
+		s, e := nextStep(currentStep)
+		if e.After(end) {
+			e = end
+		}
+		ranges = append(ranges, []time.Time{s, e})
+		currentStep = e
+	}
+
+	return ranges, nil
+}
diff --git a/app/vmctl/vm_native.go b/app/vmctl/vm_native.go
index 85b0a9539..0f6becfaa 100644
--- a/app/vmctl/vm_native.go
+++ b/app/vmctl/vm_native.go
@@ -6,9 +6,12 @@ import (
 	"io"
 	"log"
 	"net/http"
+	"time"
+
+	"github.com/dmitryk-dk/pb/v3"
 
-	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmctl/barpool"
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmctl/limiter"
+	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmctl/stepper"
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmctl/vm"
 )
 
@@ -31,6 +34,7 @@ type filter struct {
 	match     string
 	timeStart string
 	timeEnd   string
+	chunk     string
 }
 
 func (f filter) String() string {
@@ -52,10 +56,54 @@ const (
 )
 
 func (p *vmNativeProcessor) run(ctx context.Context) error {
+	if p.filter.chunk == "" {
+		return p.runSingle(ctx, p.filter)
+	}
+
+	startOfRange, err := time.Parse(time.RFC3339, p.filter.timeStart)
+	if err != nil {
+		return fmt.Errorf("failed to parse %s, provided: %s, expected format: %s, error: %v", vmNativeFilterTimeStart, p.filter.timeStart, time.RFC3339, err)
+	}
+
+	var endOfRange time.Time
+	if p.filter.timeEnd != "" {
+		endOfRange, err = time.Parse(time.RFC3339, p.filter.timeEnd)
+		if err != nil {
+			return fmt.Errorf("failed to parse %s, provided: %s, expected format: %s, error: %v", vmNativeFilterTimeEnd, p.filter.timeEnd, time.RFC3339, err)
+		}
+	} else {
+		endOfRange = time.Now()
+	}
+
+	ranges, err := stepper.SplitDateRange(startOfRange, endOfRange, p.filter.chunk)
+	if err != nil {
+		return fmt.Errorf("failed to create date ranges for the given time filters: %v", err)
+	}
+
+	for rangeIdx, r := range ranges {
+		formattedStartTime := r[0].Format(time.RFC3339)
+		formattedEndTime := r[1].Format(time.RFC3339)
+		log.Printf("Processing range %d/%d: %s - %s \n", rangeIdx+1, len(ranges), formattedStartTime, formattedEndTime)
+		f := filter{
+			match:     p.filter.match,
+			timeStart: formattedStartTime,
+			timeEnd:   formattedEndTime,
+		}
+		err := p.runSingle(ctx, f)
+
+		if err != nil {
+			log.Printf("processing failed for range %d/%d: %s - %s \n", rangeIdx+1, len(ranges), formattedStartTime, formattedEndTime)
+			return err
+		}
+	}
+	return nil
+}
+
+func (p *vmNativeProcessor) runSingle(ctx context.Context, f filter) error {
 	pr, pw := io.Pipe()
 
-	fmt.Printf("Initing export pipe from %q with filters: %s\n", p.src.addr, p.filter)
-	exportReader, err := p.exportPipe(ctx)
+	log.Printf("Initing export pipe from %q with filters: %s\n", p.src.addr, f)
+	exportReader, err := p.exportPipe(ctx, f)
 	if err != nil {
 		return fmt.Errorf("failed to init export pipe: %s", err)
 	}
@@ -83,13 +131,20 @@ func (p *vmNativeProcessor) run(ctx context.Context) error {
 	}()
 
 	fmt.Printf("Initing import process to %q:\n", p.dst.addr)
-	bar := barpool.AddWithTemplate(nativeBarTpl, 0)
+	pool := pb.NewPool()
+	bar := pb.ProgressBarTemplate(nativeBarTpl).New(0)
+	pool.Add(bar)
 	barReader := bar.NewProxyReader(exportReader)
-	if err := barpool.Start(); err != nil {
+	if err := pool.Start(); err != nil {
 		log.Printf("error start process bars pool: %s", err)
 		return err
 	}
-	defer barpool.Stop()
+	defer func() {
+		bar.Finish()
+		if err := pool.Stop(); err != nil {
+			fmt.Printf("failed to stop barpool: %+v\n", err)
+		}
+	}()
 
 	w := io.Writer(pw)
 	if p.rateLimit > 0 {
@@ -111,7 +166,7 @@ func (p *vmNativeProcessor) run(ctx context.Context) error {
 	return nil
 }
 
-func (p *vmNativeProcessor) exportPipe(ctx context.Context) (io.ReadCloser, error) {
+func (p *vmNativeProcessor) exportPipe(ctx context.Context, f filter) (io.ReadCloser, error) {
 	u := fmt.Sprintf("%s/%s", p.src.addr, nativeExportAddr)
 	req, err := http.NewRequestWithContext(ctx, "GET", u, nil)
 	if err != nil {
@@ -119,12 +174,12 @@ func (p *vmNativeProcessor) exportPipe(ctx context.Context) (io.ReadCloser, erro
 	}
 
 	params := req.URL.Query()
-	params.Set("match[]", p.filter.match)
-	if p.filter.timeStart != "" {
-		params.Set("start", p.filter.timeStart)
+	params.Set("match[]", f.match)
+	if f.timeStart != "" {
+		params.Set("start", f.timeStart)
 	}
-	if p.filter.timeEnd != "" {
-		params.Set("end", p.filter.timeEnd)
+	if f.timeEnd != "" {
+		params.Set("end", f.timeEnd)
 	}
 	req.URL.RawQuery = params.Encode()
 
diff --git a/app/vmselect/prometheus/prometheus.go b/app/vmselect/prometheus/prometheus.go
index c5ec39e6b..9a48b8689 100644
--- a/app/vmselect/prometheus/prometheus.go
+++ b/app/vmselect/prometheus/prometheus.go
@@ -450,7 +450,7 @@ var deleteDuration = metrics.NewSummary(`vm_request_duration_seconds{path="/api/
 func LabelValuesHandler(qt *querytracer.Tracer, startTime time.Time, labelName string, w http.ResponseWriter, r *http.Request) error {
 	defer labelValuesDuration.UpdateDuration(startTime)
 
-	cp, err := getCommonParams(r, startTime, false)
+	cp, err := getCommonParamsWithDefaultDuration(r, startTime, false)
 	if err != nil {
 		return err
 	}
@@ -547,7 +547,7 @@ var tsdbStatusDuration = metrics.NewSummary(`vm_request_duration_seconds{path="/
 func LabelsHandler(qt *querytracer.Tracer, startTime time.Time, w http.ResponseWriter, r *http.Request) error {
 	defer labelsDuration.UpdateDuration(startTime)
 
-	cp, err := getCommonParams(r, startTime, false)
+	cp, err := getCommonParamsWithDefaultDuration(r, startTime, false)
 	if err != nil {
 		return err
 	}
@@ -600,17 +600,14 @@ var seriesCountDuration = metrics.NewSummary(`vm_request_duration_seconds{path="
 func SeriesHandler(qt *querytracer.Tracer, startTime time.Time, w http.ResponseWriter, r *http.Request) error {
 	defer seriesDuration.UpdateDuration(startTime)
 
-	cp, err := getCommonParams(r, startTime, true)
-	if err != nil {
-		return err
-	}
 	// Do not set start to searchutils.minTimeMsecs by default as Prometheus does,
 	// since this leads to fetching and scanning all the data from the storage,
 	// which can take a lot of time for big storages.
 	// It is better setting start as end-defaultStep by default.
 	// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/91
-	if cp.start == 0 {
-		cp.start = cp.end - defaultStep
+	cp, err := getCommonParamsWithDefaultDuration(r, startTime, true)
+	if err != nil {
+		return err
 	}
 	limit, err := searchutils.GetInt(r, "limit")
 	if err != nil {
@@ -828,7 +825,7 @@ func queryRangeHandler(qt *querytracer.Tracer, startTime time.Time, w http.Respo
 		end = start + defaultStep
 	}
 	if err := promql.ValidateMaxPointsPerSeries(start, end, step, *maxPointsPerTimeseries); err != nil {
-		return err
+		return fmt.Errorf("%w; (see -search.maxPointsPerTimeseries command-line flag)", err)
 	}
 	if mayCache {
 		start, end = promql.AdjustStartEnd(start, end, step)
@@ -1062,6 +1059,17 @@ func getExportParams(r *http.Request, startTime time.Time) (*commonParams, error
 	return cp, nil
 }
 
+func getCommonParamsWithDefaultDuration(r *http.Request, startTime time.Time, requireNonEmptyMatch bool) (*commonParams, error) {
+	cp, err := getCommonParams(r, startTime, requireNonEmptyMatch)
+	if err != nil {
+		return nil, err
+	}
+	if cp.start == 0 {
+		cp.start = cp.end - defaultStep
+	}
+	return cp, nil
+}
+
 // getCommonParams obtains common params from r, which are used in /api/v1/* handlers:
 //
 // - timeout
diff --git a/app/vmselect/promql/eval.go b/app/vmselect/promql/eval.go
index d59770538..1b1b860a0 100644
--- a/app/vmselect/promql/eval.go
+++ b/app/vmselect/promql/eval.go
@@ -42,7 +42,7 @@ func ValidateMaxPointsPerSeries(start, end, step int64, maxPoints int) error {
 	}
 	points := (end-start)/step + 1
 	if points > int64(maxPoints) {
-		return fmt.Errorf("too many points for the given start=%d, end=%d and step=%d: %d; the maximum number of points is %d (see -search.maxPoints* command-line flags)",
+		return fmt.Errorf("too many points for the given start=%d, end=%d and step=%d: %d; the maximum number of points is %d",
 			start, end, step, points, maxPoints)
 	}
 	return nil
@@ -301,7 +301,14 @@ func evalTransformFunc(qt *querytracer.Tracer, ec *EvalConfig, fe *metricsql.Fun
 			Err: fmt.Errorf(`unknown func %q`, fe.Name),
 		}
 	}
-	args, err := evalExprs(qt, ec, fe.Args)
+	var args [][]*timeseries
+	var err error
+	switch fe.Name {
+	case "", "union":
+		args, err = evalExprsInParallel(qt, ec, fe.Args)
+	default:
+		args, err = evalExprsSequentially(qt, ec, fe.Args)
+	}
 	if err != nil {
 		return nil, err
 	}
@@ -337,7 +344,7 @@ func evalAggrFunc(qt *querytracer.Tracer, ec *EvalConfig, ae *metricsql.AggrFunc
 			return evalRollupFunc(qt, ec, fe.Name, rf, ae, re, iafc)
 		}
 	}
-	args, err := evalExprs(qt, ec, ae.Args)
+	args, err := evalExprsInParallel(qt, ec, ae.Args)
 	if err != nil {
 		return nil, err
 	}
@@ -616,7 +623,7 @@ func tryGetArgRollupFuncWithMetricExpr(ae *metricsql.AggrFuncExpr) (*metricsql.F
 	return nil, nil
 }
 
-func evalExprs(qt *querytracer.Tracer, ec *EvalConfig, es []metricsql.Expr) ([][]*timeseries, error) {
+func evalExprsSequentially(qt *querytracer.Tracer, ec *EvalConfig, es []metricsql.Expr) ([][]*timeseries, error) {
 	var rvs [][]*timeseries
 	for _, e := range es {
 		rv, err := evalExpr(qt, ec, e)
@@ -628,6 +635,36 @@ func evalExprs(qt *querytracer.Tracer, ec *EvalConfig, es []metricsql.Expr) ([][
 	return rvs, nil
 }
 
+func evalExprsInParallel(qt *querytracer.Tracer, ec *EvalConfig, es []metricsql.Expr) ([][]*timeseries, error) {
+	if len(es) < 2 {
+		return evalExprsSequentially(qt, ec, es)
+	}
+	rvs := make([][]*timeseries, len(es))
+	errs := make([]error, len(es))
+	var wg sync.WaitGroup
+	for i, e := range es {
+		qt.Printf("eval function args in parallel")
+		wg.Add(1)
+		qtChild := qt.NewChild("eval arg %d", i)
+		go func(e metricsql.Expr, i int) {
+			defer func() {
+				qtChild.Done()
+				wg.Done()
+			}()
+			rv, err := evalExpr(qtChild, ec, e)
+			rvs[i] = rv
+			errs[i] = err
+		}(e, i)
+	}
+	wg.Wait()
+	for _, err := range errs {
+		if err != nil {
+			return nil, err
+		}
+	}
+	return rvs, nil
+}
+
 func evalRollupFuncArgs(qt *querytracer.Tracer, ec *EvalConfig, fe *metricsql.FuncExpr) ([]interface{}, *metricsql.RollupExpr, error) {
 	var re *metricsql.RollupExpr
 	rollupArgIdx := metricsql.GetRollupArgIdx(fe)
@@ -813,7 +850,7 @@ func evalRollupFuncWithSubquery(qt *querytracer.Tracer, ec *EvalConfig, funcName
 	ecSQ.Step = step
 	ecSQ.MaxPointsPerSeries = *maxPointsSubqueryPerTimeseries
 	if err := ValidateMaxPointsPerSeries(ecSQ.Start, ecSQ.End, ecSQ.Step, ecSQ.MaxPointsPerSeries); err != nil {
-		return nil, err
+		return nil, fmt.Errorf("%w; (see -search.maxPointsSubqueryPerTimeseries command-line flag)", err)
 	}
 	// unconditionally align start and end args to step for subquery as Prometheus does.
 	ecSQ.Start, ecSQ.End = alignStartEnd(ecSQ.Start, ecSQ.End, ecSQ.Step)
diff --git a/app/vmselect/promql/rollup.go b/app/vmselect/promql/rollup.go
index 57f0cd62c..be6ade111 100644
--- a/app/vmselect/promql/rollup.go
+++ b/app/vmselect/promql/rollup.go
@@ -1349,15 +1349,11 @@ func rollupRateOverSum(rfa *rollupFuncArg) float64 {
 		// Assume that the value didn't change since rfa.prevValue.
 		return 0
 	}
-	dt := rfa.window
-	if !math.IsNaN(rfa.prevValue) {
-		dt = timestamps[len(timestamps)-1] - rfa.prevTimestamp
-	}
 	sum := float64(0)
 	for _, v := range rfa.values {
 		sum += v
 	}
-	return sum / (float64(dt) / 1e3)
+	return sum / (float64(rfa.window) / 1e3)
 }
 
 func rollupRange(rfa *rollupFuncArg) float64 {
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index eb65f38d3..5326403cb 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -15,8 +15,29 @@ The following tip changes can be tested by building VictoriaMetrics components f
 
 ## tip
 
+**Update note:** this release changes data format for [/api/v1/export/native](https://docs.victoriametrics.com/#how-to-export-data-in-native-format) in incompatible way, so it cannot be imported into older version of VictoriaMetrics via [/api/v1/import/native](https://docs.victoriametrics.com/#how-to-import-data-in-native-format).
+
+
+* FEATURE: check the correctess of raw sample timestamps stored on disk when reading them. This reduces the probability of possible silent corruption of the data stored on disk. This should help [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2998) and [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3011).
+* FEATURE: set the `start` arg to `end - 5 minutes` if isn't passed explicitly to [/api/v1/labels](https://docs.victoriametrics.com/url-examples.html#apiv1labels) and [/api/v1/label/.../values](https://docs.victoriametrics.com/url-examples.html#apiv1labelvalues). See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3052).
+* FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): add `vm-native-step-interval` command line flag for `vm-native` mode. New option allows splitting the import process into chunks by time interval. This helps migrating data sets with high churn rate and provides better control over the process. See [feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2733).
+
+* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): properly calculate `rate_over_sum(m[d])` as `sum_over_time(m[d])/d`. Previously the `sum_over_time(m[d])` could be improperly divided by smaller than `d` time range. See [rate_over_sum() docs](https://docs.victoriametrics.com/MetricsQL.html#rate_over_sum) and [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3045).
+
+
+## [v1.81.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.81.1)
+
+Released at 02-09-2022
+
+* FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): evaluate `q1`, ..., `qN` in parallel when calculating `union(q1, .., qN)`. Previously [union](https://docs.victoriametrics.com/MetricsQL.html#union) args were evaluated sequentially. This could result in lower than expected performance.
+
+* BUGFIX: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): fix potential panic at `vmselect` under high load, which has been introduced in [v1.81.0](https://docs.victoriametrics.com/CHANGELOG.html#v1810). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3058).
+
+
 ## [v1.81.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.81.0)
 
+**It isn't recommended to use VictoriaMetrics cluster v1.81.0 because of [the bug](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3058), which may result in `vmselect` crashes under high load. Upgrade to [v1.81.1](https://docs.victoriametrics.com/CHANGELOG.html#v1811) instead.**
+
 Released at 31-08-2022
 
 **Update note 1:** [vmalert](https://docs.victoriametrics.com/vmalert.html) by default hides values of `-remoteWrite.url`, `-remoteRead.url` and `-datasource.url` in logs and at `http://vmalert:8880/flags` for security reasons. See the corresponding SECURITY change in the Chagelog below for additional info.
diff --git a/docs/README.md b/docs/README.md
index 51a3a9881..dc351320d 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -326,11 +326,45 @@ See also [vmagent](https://docs.victoriametrics.com/vmagent.html), which can be
 
 VictoriaMetrics accepts data from [DataDog agent](https://docs.datadoghq.com/agent/) or [DogStatsD](https://docs.datadoghq.com/developers/dogstatsd/) via ["submit metrics" API](https://docs.datadoghq.com/api/latest/metrics/#submit-metrics) at `/datadog/api/v1/series` path.
 
-Run DataDog agent with `DD_DD_URL=http://victoriametrics-host:8428/datadog` environment variable in order to write data to VictoriaMetrics at `victoriametrics-host` host. Another option is to set `dd_url` param at [DataDog agent configuration file](https://docs.datadoghq.com/agent/guide/agent-configuration-files/) to `http://victoriametrics-host:8428/datadog`.
+Single-node VictoriaMetrics:
+
+Run DataDog agent with environment variable `DD_DD_URL=http://victoriametrics-host:8428/datadog`. Alternatively, set `dd_url` param at [DataDog agent configuration file](https://docs.datadoghq.com/agent/guide/agent-configuration-files/) to `http://victoriametrics-host:8428/datadog`.
+
+Cluster version of VictoriaMetrics:
+
+Run DataDog agent with environment variable `DD_DD_URL=http://vinsert-host:8480/insert/0/datadog`. Alternatively, set `dd_url` param at [DataDog agent configuration file](https://docs.datadoghq.com/agent/guide/agent-configuration-files/) to `DD_DD_URL=http://vinsert-host:8480/insert/0/datadog`.
 
 VictoriaMetrics doesn't check `DD_API_KEY` param, so it can be set to arbitrary value.
 
-Example on how to send data to VictoriaMetrics via DataDog "submit metrics" API from command line:
+Example of how to send data to VictoriaMetrics via [DataDog "submit metrics"](https://docs.victoriametrics.com/url-examples.html#datadogapiv1series) from command line:
+
+Single-node VictoriaMetrics:
+
+```console
+echo '
+{
+  "series": [
+    {
+      "host": "test.example.com",
+      "interval": 20,
+      "metric": "system.load.1",
+      "points": [[
+        0,
+        0.5
+      ]],
+      "tags": [
+        "environment:test"
+      ],
+      "type": "rate"
+    }
+  ]
+}
+' | curl -X POST --data-binary @- http://victoriametrics-host:8428/datadog/api/v1/series
+```
+
+Cluster version of VictoriaMetrics:
+
+<div class="with-copy" markdown="1">
 
 ```console
 echo '
@@ -351,15 +385,30 @@ echo '
     }
   ]
 }
-' | curl -X POST --data-binary @- http://localhost:8428/datadog/api/v1/series
+' | curl -X POST --data-binary @- http://vminsert-host:8480/insert/0/datadog/api/v1/series
+```
+
+</div>
+
+
+The imported data can be read via [export API](https://docs.victoriametrics.com/url-examples.html#apiv1export):
+
+Single-node VictoriaMetrics:
+
+<div class="with-copy" markdown="1">
+
+```console
+curl http://victoriametrics-host:8428/api/v1/export -d 'match[]=system.load.1'
 ```
 
-The imported data can be read via [export API](https://docs.victoriametrics.com/#how-to-export-data-in-json-line-format):
+</div>
+
+Cluster version of VictoriaMetrics:
 
 <div class="with-copy" markdown="1">
 
 ```console
-curl http://localhost:8428/api/v1/export -d 'match[]=system.load.1'
+curl http://vmselect-host:8481/select/0/prometheus/api/v1/export -d 'match[]=system.load.1'
 ```
 
 </div>
@@ -638,7 +687,7 @@ VictoriaMetrics accepts `round_digits` query arg for `/api/v1/query` and `/api/v
 
 VictoriaMetrics accepts `limit` query arg for `/api/v1/labels` and `/api/v1/label/<labelName>/values` handlers for limiting the number of returned entries. For example, the query to `/api/v1/labels?limit=5` returns a sample of up to 5 unique labels, while ignoring the rest of labels. If the provided `limit` value exceeds the corresponding `-search.maxTagKeys` / `-search.maxTagValues` command-line flag values, then limits specified in the command-line flags are used.
 
-By default, VictoriaMetrics returns time series for the last 5 minutes from `/api/v1/series`, while the Prometheus API defaults to all time.  Use `start` and `end` to select a different time range.
+By default, VictoriaMetrics returns time series for the last 5 minutes from `/api/v1/series`, `/api/v1/labels` and `/api/v1/label/<labelName>/values` while the Prometheus API defaults to all time.  Explicitly set `start` and `end` to select the desired time range.
 VictoriaMetrics accepts `limit` query arg for `/api/v1/series` handlers for limiting the number of returned entries. For example, the query to `/api/v1/series?limit=5` returns a sample of up to 5 series, while ignoring the rest. If the provided `limit` value exceeds the corresponding `-search.maxSeries` command-line flag values, then limits specified in the command-line flags are used.
 
 Additionally, VictoriaMetrics provides the following handlers:
diff --git a/docs/Single-server-VictoriaMetrics.md b/docs/Single-server-VictoriaMetrics.md
index 5b847e470..0af953557 100644
--- a/docs/Single-server-VictoriaMetrics.md
+++ b/docs/Single-server-VictoriaMetrics.md
@@ -330,11 +330,45 @@ See also [vmagent](https://docs.victoriametrics.com/vmagent.html), which can be
 
 VictoriaMetrics accepts data from [DataDog agent](https://docs.datadoghq.com/agent/) or [DogStatsD](https://docs.datadoghq.com/developers/dogstatsd/) via ["submit metrics" API](https://docs.datadoghq.com/api/latest/metrics/#submit-metrics) at `/datadog/api/v1/series` path.
 
-Run DataDog agent with `DD_DD_URL=http://victoriametrics-host:8428/datadog` environment variable in order to write data to VictoriaMetrics at `victoriametrics-host` host. Another option is to set `dd_url` param at [DataDog agent configuration file](https://docs.datadoghq.com/agent/guide/agent-configuration-files/) to `http://victoriametrics-host:8428/datadog`.
+Single-node VictoriaMetrics:
+
+Run DataDog agent with environment variable `DD_DD_URL=http://victoriametrics-host:8428/datadog`. Alternatively, set `dd_url` param at [DataDog agent configuration file](https://docs.datadoghq.com/agent/guide/agent-configuration-files/) to `http://victoriametrics-host:8428/datadog`.
+
+Cluster version of VictoriaMetrics:
+
+Run DataDog agent with environment variable `DD_DD_URL=http://vinsert-host:8480/insert/0/datadog`. Alternatively, set `dd_url` param at [DataDog agent configuration file](https://docs.datadoghq.com/agent/guide/agent-configuration-files/) to `DD_DD_URL=http://vinsert-host:8480/insert/0/datadog`.
 
 VictoriaMetrics doesn't check `DD_API_KEY` param, so it can be set to arbitrary value.
 
-Example on how to send data to VictoriaMetrics via DataDog "submit metrics" API from command line:
+Example of how to send data to VictoriaMetrics via [DataDog "submit metrics"](https://docs.victoriametrics.com/url-examples.html#datadogapiv1series) from command line:
+
+Single-node VictoriaMetrics:
+
+```console
+echo '
+{
+  "series": [
+    {
+      "host": "test.example.com",
+      "interval": 20,
+      "metric": "system.load.1",
+      "points": [[
+        0,
+        0.5
+      ]],
+      "tags": [
+        "environment:test"
+      ],
+      "type": "rate"
+    }
+  ]
+}
+' | curl -X POST --data-binary @- http://victoriametrics-host:8428/datadog/api/v1/series
+```
+
+Cluster version of VictoriaMetrics:
+
+<div class="with-copy" markdown="1">
 
 ```console
 echo '
@@ -355,15 +389,30 @@ echo '
     }
   ]
 }
-' | curl -X POST --data-binary @- http://localhost:8428/datadog/api/v1/series
+' | curl -X POST --data-binary @- http://vminsert-host:8480/insert/0/datadog/api/v1/series
+```
+
+</div>
+
+
+The imported data can be read via [export API](https://docs.victoriametrics.com/url-examples.html#apiv1export):
+
+Single-node VictoriaMetrics:
+
+<div class="with-copy" markdown="1">
+
+```console
+curl http://victoriametrics-host:8428/api/v1/export -d 'match[]=system.load.1'
 ```
 
-The imported data can be read via [export API](https://docs.victoriametrics.com/#how-to-export-data-in-json-line-format):
+</div>
+
+Cluster version of VictoriaMetrics:
 
 <div class="with-copy" markdown="1">
 
 ```console
-curl http://localhost:8428/api/v1/export -d 'match[]=system.load.1'
+curl http://vmselect-host:8481/select/0/prometheus/api/v1/export -d 'match[]=system.load.1'
 ```
 
 </div>
@@ -642,7 +691,7 @@ VictoriaMetrics accepts `round_digits` query arg for `/api/v1/query` and `/api/v
 
 VictoriaMetrics accepts `limit` query arg for `/api/v1/labels` and `/api/v1/label/<labelName>/values` handlers for limiting the number of returned entries. For example, the query to `/api/v1/labels?limit=5` returns a sample of up to 5 unique labels, while ignoring the rest of labels. If the provided `limit` value exceeds the corresponding `-search.maxTagKeys` / `-search.maxTagValues` command-line flag values, then limits specified in the command-line flags are used.
 
-By default, VictoriaMetrics returns time series for the last 5 minutes from `/api/v1/series`, while the Prometheus API defaults to all time.  Use `start` and `end` to select a different time range.
+By default, VictoriaMetrics returns time series for the last 5 minutes from `/api/v1/series`, `/api/v1/labels` and `/api/v1/label/<labelName>/values` while the Prometheus API defaults to all time.  Explicitly set `start` and `end` to select the desired time range.
 VictoriaMetrics accepts `limit` query arg for `/api/v1/series` handlers for limiting the number of returned entries. For example, the query to `/api/v1/series?limit=5` returns a sample of up to 5 series, while ignoring the rest. If the provided `limit` value exceeds the corresponding `-search.maxSeries` command-line flag values, then limits specified in the command-line flags are used.
 
 Additionally, VictoriaMetrics provides the following handlers:
diff --git a/docs/keyConcepts.md b/docs/keyConcepts.md
index f079eb31e..ca1418345 100644
--- a/docs/keyConcepts.md
+++ b/docs/keyConcepts.md
@@ -33,7 +33,7 @@ requests_total{path="/", code="200"}
 requests_total{path="/", code="403"} 
 ```
 
-The meta-information - set of `labels` in curly braces - gives us a context for which `path` and with what `code`
+The meta-information - a set of `labels` in curly braces - gives us a context for which `path` and with what `code`
 the `request` was served. Label-value pairs are always of a `string` type. VictoriaMetrics data model is schemaless,
 which means there is no need to define metric names or their labels in advance. User is free to add or change ingested
 metrics anytime.
@@ -63,9 +63,9 @@ See [these docs](https://docs.victoriametrics.com/FAQ.html#what-is-high-cardinal
 
 #### Raw samples
 
-Every unique time series may consist of arbitrary number of `(value, timestamp)` data points (aka `raw samples`) sorted by `timestamp`.
+Every unique time series may consist of an arbitrary number of `(value, timestamp)` data points (aka `raw samples`) sorted by `timestamp`.
 The `value` is a [double-precision floating-point number](https://en.wikipedia.org/wiki/Double-precision_floating-point_format).
-The `timestamp` is a [unix timestamp](https://en.wikipedia.org/wiki/Unix_time) with millisecond precision.
+The `timestamp` is a [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time) with millisecond precision.
 
 Below is an example of a single raw sample
 in [Prometheus text exposition format](https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md#text-based-format):
@@ -108,8 +108,8 @@ The most common [MetricsQL](#metricsql) functions used with counters are:
   time period specified in square brackets.
   For example, `increase(requests_total[1h])` shows the number of requests served over the last hour.
 
-It is OK to have fractional counters. For example, `request_duration_seconds_sum` counter may sum durations of all the requests.
-Every duration may have fractional value in seconds, e.g. `0.5` seconds. So the cumulative sum of all the request durations
+It is OK to have fractional counters. For example, `request_duration_seconds_sum` counter may sum the durations of all the requests.
+Every duration may have a fractional value in seconds, e.g. `0.5` of a second. So the cumulative sum of all the request durations
 may be fractional too.
 
 It is recommended to put `_total`, `_sum` or `_count` suffix to `counter` metric names, so such metrics can be easily differentiated
@@ -121,7 +121,7 @@ Gauge is used for measuring a value that can go up and down:
 
 {% include img.html href="keyConcepts_gauge.png" %}
 
-The metric `process_resident_memory_anon_bytes` on the graph shows memory usage of the application at every given time.
+The metric `process_resident_memory_anon_bytes` on the graph shows the memory usage of the application at every given time.
 It is changing frequently, going up and down showing how the process allocates and frees the memory.
 In programming, `gauge` is a variable to which you **set** a specific value as it changes.
 
@@ -177,7 +177,7 @@ This query works in the following way:
 2. The `sum(...) by (vmrange)` calculates per-bucket events by summing per-instance buckets
    with the same `vmrange` values.
 
-3. The `histogram_quantile(0.99, ...)` calculates 99th percentile over `vmrange` buckets returned at the step 2.
+3. The `histogram_quantile(0.99, ...)` calculates 99th percentile over `vmrange` buckets returned at step 2.
 
 Histogram metric type exposes two additional counters ending with `_sum` and `_count` suffixes:
 
@@ -227,7 +227,7 @@ function must be used for converting buckets with `vmrange` labels to buckets wi
 Histograms are usually used for measuring the distribution of latency, sizes of elements (batch size, for example) etc. There are two
 implementations of a histogram supported by VictoriaMetrics:
 
-1. [Prometheus histogram](https://prometheus.io/docs/practices/histograms/). The canonical histogram implementation
+1. [Prometheus histogram](https://prometheus.io/docs/practices/histograms/). The canonical histogram implementation is
    supported by most of
    the [client libraries for metrics instrumentation](https://prometheus.io/docs/instrumenting/clientlibs/). Prometheus
    histogram requires a user to define ranges (`buckets`) statically.
@@ -263,7 +263,7 @@ The visualisation of summaries is pretty straightforward:
 
 {% include img.html href="keyConcepts_summary.png" %}
 
-Such an approach makes summaries easier to use but also puts significant limitations comparing to [histograms](#histogram):
+Such an approach makes summaries easier to use but also puts significant limitations compared to [histograms](#histogram):
 
 - It is impossible to calculate quantile over multiple summary metrics, e.g. `sum(go_gc_duration_seconds{quantile="0.75"})`,
   `avg(go_gc_duration_seconds{quantile="0.75"})` or `max(go_gc_duration_seconds{quantile="0.75"})`
@@ -272,7 +272,7 @@ Such an approach makes summaries easier to use but also puts significant limitat
 
 - It is impossible to calculate quantiles other than the already pre-calculated quantiles.
 
-- It is impossible to calculate quantiles for measurements collected over arbitrary time range. Usually `summary`
+- It is impossible to calculate quantiles for measurements collected over an arbitrary time range. Usually, `summary`
   quantiles are calculated over a fixed time range such as the last 5 minutes.
 
 Summaries are usually used for tracking the pre-defined percentiles for latency, sizes of elements (batch size, for example) etc.
@@ -280,7 +280,7 @@ Summaries are usually used for tracking the pre-defined percentiles for latency,
 ### Instrumenting application with metrics
 
 As was said at the beginning of the [types of metrics](#types-of-metrics) section, metric type defines how it was
-measured. VictoriaMetrics TSDB doesn't know about metric types, all it sees are metric names, labels, values, and timestamps.
+measured. VictoriaMetrics TSDB doesn't know about metric types. All it sees are metric names, labels, values, and timestamps.
 What are these metrics, what do they measure, and how - all this depends on the application which emits them.
 
 To instrument your application with metrics compatible with VictoriaMetrics we recommend
@@ -292,18 +292,18 @@ VictoriaMetrics is also compatible with [Prometheus client libraries for metrics
 #### Naming
 
 We recommend following [Prometheus naming convention for metrics](https://prometheus.io/docs/practices/naming/). There
-are no strict restrictions, so any metric name and labels are be accepted by VictoriaMetrics.
-But the convention helps to keep names meaningful, descriptive and clear to other people.
+are no strict restrictions, so any metric name and labels are accepted by VictoriaMetrics.
+But the convention helps to keep names meaningful, descriptive, and clear to other people.
 Following convention is a good practice.
 
 #### Labels
 
 Every measurement can contain an arbitrary number of `key="value"` labels. The good practice is to keep this number limited.
-Otherwise, it would be difficult to deal with measurements containing big number of labels.
+Otherwise, it would be difficult to deal with measurements containing a big number of labels.
 By default, VictoriaMetrics limits the number of labels per measurement to `30` and drops other labels.
 This limit can be changed via `-maxLabelsPerTimeseries` command-line flag if necessary (but this isn't recommended).
 
-Every label value can contain arbitrary string value. The good practice is to use short and meaningful label values to
+Every label value can contain an arbitrary string value. The good practice is to use short and meaningful label values to
 describe the attribute of the metric, not to tell the story about it. For example, label-value pair
 `environment="prod"` is ok, but `log_message="long log message with a lot of details..."` is not ok. By default,
 VcitoriaMetrics limits label's value size with 16kB. This limit can be changed via `-maxLabelValueLen` command-line flag.
@@ -318,7 +318,7 @@ VictoriaMetrics supports both models used in modern monitoring applications: [pu
 
 ### Push model
 
-Client regularly sends the collected metrics to the server in push model:
+Client regularly sends the collected metrics to the server in the push model:
 
 {% include img.html href="keyConcepts_push_model.png" %}
 
@@ -366,9 +366,9 @@ elaborating more on why Percona switched from pull to push model.
 The cons of push protocol:
 
 * Increased configuration complexity for monitored applications.
-  Every application needs te be individually configured with the address of the monitoring system
+  Every application needs to be individually configured with the address of the monitoring system
   for metrics delivery. It also needs to be configured with the interval between metric pushes
-  and the strategy on metric delivery failure.
+  and the strategy in case of metric delivery failure.
 * Non-trivial setup for metrics' delivery into multiple monitoring systems.
 * It may be hard to tell whether the application went down or just stopped sending metrics for a different reason.
 * Applications can overload the monitoring system by pushing metrics at too short intervals.
@@ -394,12 +394,12 @@ The pros of the pull model:
 * Easier to debug - VictoriaMetrics knows about all the monitored applications (aka `scrape targets`).
   The `up == 0` query instantly shows unavailable scrape targets.
   The actual information about scrape targets is available at `http://victoriametrics:8428/targets` and `http://vmagent:8429/targets`.
-* Monitoring system controls the frequency of metrics' scrape, so it is easier to control its' load.
-* Applications aren't aware of the monitoring system and don't need to implement the logic for metrics' delivery.
+* Monitoring system controls the frequency of metrics' scrape, so it is easier to control its load.
+* Applications aren't aware of the monitoring system and don't need to implement the logic for metrics delivery.
 
 The cons of the pull model:
 
-* Harder security setup - monitoring system needs have access to applications it monitors.
+* Harder security setup - monitoring system needs to have access to applications it monitors.
 * Pull model needs non-trivial [service discovery schemes](https://docs.victoriametrics.com/sd_configs.html).
 
 ### Common approaches for data collection
@@ -426,7 +426,7 @@ VictoriaMetrics components allow building more advanced topologies. For example,
 
 {% include img.html href="keyConcepts_two_dcs.png" %}
 
-VictoriaMetrics in this example the may be either [single-node VictoriaMetrics](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html)
+VictoriaMetrics in this example may be either [single-node VictoriaMetrics](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html)
 or [VictoriaMetrics Cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html). Vmagent also allows
 [replicating the same data to multiple destinations](https://docs.victoriametrics.com/vmagent.html#replication-and-high-availability).
 
@@ -436,7 +436,7 @@ VictoriaMetrics provides
 an [HTTP API](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#prometheus-querying-api-usage)
 for serving read queries. The API is used in various integrations such as
 [Grafana](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#grafana-setup). The same API is also used by
-[VMUI](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#vmui) - graphical User Interface for querying
+[VMUI](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#vmui) - a graphical User Interface for querying
 and visualizing metrics.
 
 The API consists of two main handlers for serving [instant queries](#instant-query) and [range queries](#range-query).
@@ -455,9 +455,9 @@ Params:
 * `time` - optional timestamp when to evaluate the `query`. If `time` is skipped, then the current timestamp is used.
   The `time` param can be specified in the following formats:
   * [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) such as `2022-08-10T12:45:43.000Z`.
-  * [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time) in seconds. It can contains fractional part for millisecond precision.
+  * [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time) in seconds. It can contain a fractional part for millisecond precision.
   * [Relative duration](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations)
-    comparing to the current timestamp. For example, `-1h` means `one hour before the current time`.
+    compared to the current timestamp. For example, `-1h` means `one hour before the current time`.
 * `step` - optional max lookback window for searching for raw samples when executing the `query`.
   If `step` is skipped, then it is set to `5m` (5 minutes) by default.
 
@@ -517,8 +517,8 @@ curl "http://<victoria-metrics-addr>/api/v1/query?query=foo_bar&time=2022-05-10T
 
 In response, VictoriaMetrics returns a single sample-timestamp pair with a value of `3` for the series
 `foo_bar` at the given moment of time `2022-05-10 10:03`. But, if we take a look at the original data sample again,
-we'll see that there is no a raw sample at `2022-05-10 10:03`. What happens here is if there is no a raw sample at the
-requested timestamp, VictoriaMetrics will try to locate the closest sample on the left to the requested timestamp:
+we'll see that there is no raw sample at `2022-05-10 10:03`. What happens here if there is no raw sample at the
+requested timestamp - VictoriaMetrics will try to locate the closest sample on the left to the requested timestamp:
 
 <p style="text-align: center">
     <a href="keyConcepts_instant_query.png" target="_blank">
@@ -550,9 +550,9 @@ Params:
 * `start` - the starting timestamp of the time range for `query` evaluation.
   The `start` param can be specified in the following formats:
   * [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) such as `2022-08-10T12:45:43.000Z`.
-  * [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time) in seconds. It can contains fractional part for millisecond precision.
+  * [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time) in seconds. It can contain a fractional part for millisecond precision.
   * [Relative duration](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations)
-    comparing to the current timestamp. For example, `-1h` means `one hour before the current time`.
+    compared to the current timestamp. For example, `-1h` means `one hour before the current time`.
 * `end` - the ending timestamp of the time range for `query` evaluation.
   If the `end` isn't set, then the `end` is automatically set to the current time.
 * `step` - the [interval](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations) between datapoints,
@@ -560,7 +560,7 @@ Params:
   The `query` is executed at `start`, `start+step`, `start+2*step`, ..., `end` timestamps.
   If the `step` isn't set, then it is automatically set to `5m` (5 minutes).
 
-To get the values of `foo_bar` on time range from `2022-05-10 09:59:00` to `2022-05-10 10:17:00`, in VictoriaMetrics we
+To get the values of `foo_bar` on the time range from `2022-05-10 09:59:00` to `2022-05-10 10:17:00`, in VictoriaMetrics we
 need to issue a range query:
 
 ```console
@@ -665,7 +665,7 @@ this request in VictoriaMetrics the graph will be shown as the following:
     </a>
 </p>
 
-The blue dotted lines on the pic are the moments when instant query was executed. Since instant query retains the
+The blue dotted lines on the pic are the moments when the instant query was executed. Since instant query retains the
 ability to locate the missing point, the graph contains two types of points: `real` and `ephemeral` data
 points. `ephemeral` data point always repeats the left closest raw sample (see red arrow on the pic above).
 
@@ -692,14 +692,14 @@ useful in the following scenarios:
 * Correlate changes between multiple metrics on the time interval;
 * Observe trends and dynamics of the metric change.
 
-If you need exporting raw samples from VictoriaMetrics, then take a look at [export APIs](https://docs.victoriametrics.com/#how-to-export-time-series).
+If you need to export raw samples from VictoriaMetrics, then take a look at [export APIs](https://docs.victoriametrics.com/#how-to-export-time-series).
 
 ### MetricsQL
 
 VictoriaMetrics provide a special query language for executing read queries - [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html).
 It is a [PromQL](https://prometheus.io/docs/prometheus/latest/querying/basics)-like query language with a powerful set of
-functions and features for working specifically with time series data. MetricsQL is backwards-compatible with PromQL,
-so it shares most of the query concepts. The basics concepts for PromQL and MetricsQL are
+functions and features for working specifically with time series data. MetricsQL is backward-compatible with PromQL,
+so it shares most of the query concepts. The basic concepts for PromQL and MetricsQL are
 described [here](https://valyala.medium.com/promql-tutorial-for-beginners-9ab455142085).
 
 #### Filtering
@@ -805,7 +805,7 @@ process_resident_memory_bytes > 100*1024*1024
 
 #### Aggregation and grouping functions
 
-MetricsQL allows aggregating and grouping time series. Time series are grouped by the given set of labels and then the
+MetricsQL allows aggregating and grouping of time series. Time series are grouped by the given set of labels and then the
 given aggregation function is applied individually per each group. For instance, the following query returns
 summary memory usage for each `job`:
 
@@ -838,7 +838,7 @@ as [duration](https://prometheus.io/docs/prometheus/latest/querying/basics/#time
 In this case VictoriaMetrics uses the specified lookbehind window - `5m` (5 minutes) - for calculating the average per-second increase rate.
 Bigger lookbehind windows usually lead to smoother graphs.
 
-`rate` strips metric name while leaving all the labels for the inner time series. If you need keeping the metric name,
+`rate` strips metric name while leaving all the labels for the inner time series. If you need to keep the metric name,
 then add [keep_metric_names](https://docs.victoriametrics.com/MetricsQL.html#keep_metric_names) modifier
 after the `rate(..)`. For example, the following query leaves metric names after calculating the `rate()`:
 
@@ -846,7 +846,7 @@ after the `rate(..)`. For example, the following query leaves metric names after
 rate(node_network_receive_bytes_total) keep_metric_names
 ```
 
-`rate()` must be apllied only to [counters](#counter). The result of applying the `rate()` to [gauge](#gauge) is undefined.
+`rate()` must be applied only to [counters](#counter). The result of applying the `rate()` to [gauge](#gauge) is undefined.
 
 ### Visualizing time series
 
@@ -885,4 +885,4 @@ VictoriaMetrics supports data deduplication. See [these docs](https://docs.victo
 
 ### Downsampling
 
-VictoriaMetrics supports data downsampling - see [these docs](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#downsampling).
+VictoriaMetrics supports data downsampling. See [these docs](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#downsampling).
diff --git a/docs/url-examples.md b/docs/url-examples.md
index 9700b7326..35e610765 100644
--- a/docs/url-examples.md
+++ b/docs/url-examples.md
@@ -101,6 +101,7 @@ Additional information:
 
 * [How to export time series](https://docs.victoriametrics.com/#how-to-export-time-series)
 * [How to import time series](https://docs.victoriametrics.com/#how-to-import-time-series-data)
+* [How to export data in JSON line format](https://docs.victoriametrics.com/#how-to-export-data-in-json-line-format)
 * [URL format for VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#url-format)
 
 ## /api/v1/export/csv
@@ -267,7 +268,7 @@ Additional information:
 
 ## /api/v1/labels
 
-**Get a list of label names**
+**Get a list of label names at the given time range**
 
 Single-node VictoriaMetrics:
 <div class="with-copy" markdown="1">
@@ -287,6 +288,8 @@ curl http://<vmselect>:8481/select/0/prometheus/api/v1/labels
 
 </div>
 
+By default VictoriaMetrics returns labels seen during the last 5 minutes. An arbitrary time range can be set via `start` and `end` query args.
+
 Additional information:
 * [Prometheus querying API usage](https://docs.victoriametrics.com/#prometheus-querying-api-usage)
 * [Querying label values](https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values)
@@ -294,7 +297,7 @@ Additional information:
 
 ## /api/v1/label/.../values
 
-**Get a list of values for a particular label**
+**Get a list of values for a particular label on the given time range**
 
 Single-node VictoriaMetrics:
 <div class="with-copy" markdown="1">
@@ -314,6 +317,8 @@ curl http://<vmselect>:8481/select/0/prometheus/api/v1/label/job/values
 
 </div>
 
+By default VictoriaMetrics returns label values seen during the last 5 minutes. An arbitrary time range can be set via `start` and `end` query args.
+
 Additional information:
 * [Prometheus querying API usage](https://docs.victoriametrics.com/#prometheus-querying-api-usage)
 * [Getting label names](https://prometheus.io/docs/prometheus/latest/querying/api/#getting-label-names)
@@ -377,7 +382,7 @@ Additional information:
 
 ## /api/v1/series
 
-**Returns series names with their labels**
+**Returns series names with their labels on the given time range**
 
 Single-node VictoriaMetrics:
 <div class="with-copy" markdown="1">
@@ -397,6 +402,8 @@ curl http://<vmselect>:8481/select/0/prometheus/api/v1/series -d 'match[]=vm_htt
 
 </div>
 
+By default VictoriaMetrics returns time series seen during the last 5 minutes. An arbitrary time range can be set via `start` and `end` query args.
+
 Additional information:
 * [Prometheus querying API usage](https://docs.victoriametrics.com/#prometheus-querying-api-usage)
 * [Finding series by label matchers](https://prometheus.io/docs/prometheus/latest/querying/api/#finding-series-by-label-matchers)
diff --git a/docs/vmctl.md b/docs/vmctl.md
index fa7e71e12..bfbff6ef2 100644
--- a/docs/vmctl.md
+++ b/docs/vmctl.md
@@ -525,6 +525,74 @@ To avoid such situation try to filter out VM process metrics via `--vm-native-fi
 Instead, use [relabeling in VictoriaMetrics](https://github.com/VictoriaMetrics/vmctl/issues/4#issuecomment-683424375).
 5. When importing in or from cluster version remember to use correct [URL format](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#url-format)
 and specify `accountID` param.
+6. When migrating large volumes of data it might be useful to use `--vm-native-step-interval` flag to split single process into smaller steps.
+
+#### Using time-based chunking of migration
+
+It is possible split migration process into set of smaller batches based on time. This is especially useful when migrating large volumes of data as this adds indication of progress and ability to restore process from certain point in case of failure.
+
+To use this you need to specify `--vm-native-step-interval` flag. Supported values are: `month`, `day`, `hour`.
+Note that in order to use this it is required `--vm-native-filter-time-start` to be set to calculate time ranges for export process.
+
+Every range is being processed independently, which means that:
+- after range processing is finished all data within range is migrated
+- if process fails on one of stages it is guaranteed that data of prior stages is already written, so it is possible to restart process starting from failed range
+
+It is recommended using the `month` step when migrating the data over multiple months, since the migration with `day` and `hour` steps may take longer time to complete
+because of additional overhead.
+
+Usage example:
+```console
+./vmctl vm-native 
+    --vm-native-filter-time-start 2022-06-17T00:07:00Z \
+    --vm-native-filter-time-end 2022-10-03T00:07:00Z \
+    --vm-native-src-addr http://localhost:8428 \
+    --vm-native-dst-addr http://localhost:8528 \
+    --vm-native-step-interval=month
+VictoriaMetrics Native import mode
+2022/08/30 19:48:24 Processing range 1/5: 2022-06-17T00:07:00Z - 2022-06-30T23:59:59Z 
+2022/08/30 19:48:24 Initing export pipe from "http://localhost:8428" with filters: 
+        filter: match[]={__name__!=""}
+        start: 2022-06-17T00:07:00Z
+        end: 2022-06-30T23:59:59Z
+Initing import process to "http://localhost:8428":
+2022/08/30 19:48:24 Import finished!
+Total: 16 B ↗ Speed: 28.89 KiB p/s 
+2022/08/30 19:48:24 Processing range 2/5: 2022-07-01T00:00:00Z - 2022-07-31T23:59:59Z 
+2022/08/30 19:48:24 Initing export pipe from "http://localhost:8428" with filters: 
+        filter: match[]={__name__!=""}
+        start: 2022-07-01T00:00:00Z
+        end: 2022-07-31T23:59:59Z
+Initing import process to "http://localhost:8428":
+2022/08/30 19:48:24 Import finished!
+Total: 16 B ↗ Speed: 164.35 KiB p/s 
+2022/08/30 19:48:24 Processing range 3/5: 2022-08-01T00:00:00Z - 2022-08-31T23:59:59Z 
+2022/08/30 19:48:24 Initing export pipe from "http://localhost:8428" with filters: 
+        filter: match[]={__name__!=""}
+        start: 2022-08-01T00:00:00Z
+        end: 2022-08-31T23:59:59Z
+Initing import process to "http://localhost:8428":
+2022/08/30 19:48:24 Import finished!
+Total: 16 B ↗ Speed: 191.42 KiB p/s 
+2022/08/30 19:48:24 Processing range 4/5: 2022-09-01T00:00:00Z - 2022-09-30T23:59:59Z 
+2022/08/30 19:48:24 Initing export pipe from "http://localhost:8428" with filters: 
+        filter: match[]={__name__!=""}
+        start: 2022-09-01T00:00:00Z
+        end: 2022-09-30T23:59:59Z
+Initing import process to "http://localhost:8428":
+2022/08/30 19:48:24 Import finished!
+Total: 16 B ↗ Speed: 141.04 KiB p/s 
+2022/08/30 19:48:24 Processing range 5/5: 2022-10-01T00:00:00Z - 2022-10-03T00:07:00Z 
+2022/08/30 19:48:24 Initing export pipe from "http://localhost:8428" with filters: 
+        filter: match[]={__name__!=""}
+        start: 2022-10-01T00:00:00Z
+        end: 2022-10-03T00:07:00Z
+Initing import process to "http://localhost:8428":
+2022/08/30 19:48:24 Import finished!
+Total: 16 B ↗ Speed: 186.32 KiB p/s 
+2022/08/30 19:48:24 Total time: 12.680582ms
+```
+
 
 ## Verifying exported blocks from VictoriaMetrics
 
diff --git a/go.mod b/go.mod
index 5f1146538..470c3d1c5 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
 	github.com/VictoriaMetrics/fasthttp v1.1.0
 	github.com/VictoriaMetrics/metrics v1.22.2
 	github.com/VictoriaMetrics/metricsql v0.44.1
-	github.com/aws/aws-sdk-go v1.44.87
+	github.com/aws/aws-sdk-go v1.44.91
 	github.com/cespare/xxhash/v2 v2.1.2
 
 	// TODO: switch back to https://github.com/cheggaaa/pb/v3 when v3-pooling branch
@@ -22,7 +22,7 @@ require (
 	github.com/influxdata/influxdb v1.10.0
 	github.com/klauspost/compress v1.15.9
 	github.com/prometheus/prometheus v1.8.2-0.20201119142752-3ad25a6dc3d9
-	github.com/urfave/cli/v2 v2.11.2
+	github.com/urfave/cli/v2 v2.14.0
 	github.com/valyala/fastjson v1.6.3
 	github.com/valyala/fastrand v1.1.0
 	github.com/valyala/fasttemplate v1.2.1
@@ -75,7 +75,7 @@ require (
 	golang.org/x/text v0.3.7 // indirect
 	golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
 	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf // indirect
+	google.golang.org/genproto v0.0.0-20220902135211-223410557253 // indirect
 	google.golang.org/grpc v1.49.0 // indirect
 	google.golang.org/protobuf v1.28.1 // indirect
 )
diff --git a/go.sum b/go.sum
index 758118a47..71d6508d9 100644
--- a/go.sum
+++ b/go.sum
@@ -147,8 +147,8 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ
 github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
 github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
 github.com/aws/aws-sdk-go v1.35.31/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
-github.com/aws/aws-sdk-go v1.44.87 h1:u/1sm8MNUSQHt8MGLEQHAj4r3lns3w0B1IXelPKbpn4=
-github.com/aws/aws-sdk-go v1.44.87/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
+github.com/aws/aws-sdk-go v1.44.91 h1:SRWmuX7PTyhBdLuvSfM7KWrWISJsrRsUPcFDSFduRxY=
+github.com/aws/aws-sdk-go v1.44.91/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
 github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -826,8 +826,8 @@ github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMW
 github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/urfave/cli/v2 v2.11.2 h1:FVfNg4m3vbjbBpLYxW//WjxUoHvJ9TlppXcqY9Q9ZfA=
-github.com/urfave/cli/v2 v2.11.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
+github.com/urfave/cli/v2 v2.14.0 h1:sFRL29Dm9JhXSMYb96raDeo/Q/JRyPXPs8u+4CkMlI8=
+github.com/urfave/cli/v2 v2.14.0/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
@@ -1379,8 +1379,8 @@ google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP
 google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
 google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
 google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
-google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf h1:Q5xNKbTSFwkuaaGaR7CMcXEM5sy19KYdUU8iF8/iRC0=
-google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
+google.golang.org/genproto v0.0.0-20220902135211-223410557253 h1:vXJMM8Shg7TGaYxZsQ++A/FOSlbDmDtWhS/o+3w/hj4=
+google.golang.org/genproto v0.0.0-20220902135211-223410557253/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
diff --git a/lib/encoding/encoding.go b/lib/encoding/encoding.go
index 01829c815..b53ee2284 100644
--- a/lib/encoding/encoding.go
+++ b/lib/encoding/encoding.go
@@ -240,7 +240,7 @@ var bbPool bytesutil.ByteBufferPool
 // EnsureNonDecreasingSequence makes sure the first item in a is vMin, the last
 // item in a is vMax and all the items in a are non-decreasing.
 //
-// If this isn't the case the a is fixed accordingly.
+// If this isn't the case then a is fixed accordingly.
 func EnsureNonDecreasingSequence(a []int64, vMin, vMax int64) {
 	if vMax < vMin {
 		logger.Panicf("BUG: vMax cannot be smaller than vMin; got %d vs %d", vMax, vMin)
diff --git a/lib/storage/block.go b/lib/storage/block.go
index edc7507e6..84c7ee626 100644
--- a/lib/storage/block.go
+++ b/lib/storage/block.go
@@ -2,7 +2,6 @@ package storage
 
 import (
 	"fmt"
-	"math"
 	"sync"
 	"sync/atomic"
 
@@ -272,6 +271,11 @@ func (b *Block) UnmarshalData() error {
 	if b.bh.PrecisionBits < 64 {
 		// Recover timestamps order after lossy compression.
 		encoding.EnsureNonDecreasingSequence(b.timestamps, b.bh.MinTimestamp, b.bh.MaxTimestamp)
+	} else {
+		// Ensure timestamps are in the range [MinTimestamp ... MaxTimestamps] and are ordered.
+		if err := checkTimestampsBounds(b.timestamps, b.bh.MinTimestamp, b.bh.MaxTimestamp); err != nil {
+			return err
+		}
 	}
 	b.timestampsData = b.timestampsData[:0]
 
@@ -290,6 +294,27 @@ func (b *Block) UnmarshalData() error {
 	return nil
 }
 
+func checkTimestampsBounds(timestamps []int64, minTimestamp, maxTimestamp int64) error {
+	if len(timestamps) == 0 {
+		return nil
+	}
+	tsPrev := timestamps[0]
+	if tsPrev < minTimestamp {
+		return fmt.Errorf("timestamp for the row 0 out of %d rows cannot be smaller than %d; got %d", len(timestamps), minTimestamp, tsPrev)
+	}
+	for i, ts := range timestamps[1:] {
+		if ts < tsPrev {
+			return fmt.Errorf("timestamp for the row %d cannot be smaller than the timestamp for the row %d (total %d rows); got %d vs %d",
+				i+1, i, len(timestamps), ts, tsPrev)
+		}
+		tsPrev = ts
+	}
+	if tsPrev > maxTimestamp {
+		return fmt.Errorf("timestamp for the row %d (the last one) cannot be bigger than %d; got %d", len(timestamps)-1, maxTimestamp, tsPrev)
+	}
+	return nil
+}
+
 // AppendRowsWithTimeRangeFilter filters samples from b according to tr and appends them to dst*.
 //
 // It is expected that UnmarshalData has been already called on b.
@@ -326,16 +351,9 @@ func (b *Block) filterTimestamps(tr TimeRange) ([]int64, []int64) {
 // The marshaled value must be unmarshaled with UnmarshalPortable function.
 func (b *Block) MarshalPortable(dst []byte) []byte {
 	b.MarshalData(0, 0)
-
-	dst = encoding.MarshalVarInt64(dst, b.bh.MinTimestamp)
-	dst = encoding.MarshalVarInt64(dst, b.bh.FirstValue)
-	dst = encoding.MarshalVarUint64(dst, uint64(b.bh.RowsCount))
-	dst = encoding.MarshalVarInt64(dst, int64(b.bh.Scale))
-	dst = append(dst, byte(b.bh.TimestampsMarshalType))
-	dst = append(dst, byte(b.bh.ValuesMarshalType))
+	dst = b.bh.marshalPortable(dst)
 	dst = encoding.MarshalBytes(dst, b.timestampsData)
 	dst = encoding.MarshalBytes(dst, b.valuesData)
-
 	return dst
 }
 
@@ -344,50 +362,10 @@ func (b *Block) MarshalPortable(dst []byte) []byte {
 // It is assumed that the block has been marshaled with MarshalPortable.
 func (b *Block) UnmarshalPortable(src []byte) ([]byte, error) {
 	b.Reset()
-
-	// Read header
-	src, firstTimestamp, err := encoding.UnmarshalVarInt64(src)
+	src, err := b.bh.unmarshalPortable(src)
 	if err != nil {
-		return src, fmt.Errorf("cannot unmarshal firstTimestamp: %w", err)
+		return src, err
 	}
-	b.bh.MinTimestamp = firstTimestamp
-	src, firstValue, err := encoding.UnmarshalVarInt64(src)
-	if err != nil {
-		return src, fmt.Errorf("cannot unmarshal firstValue: %w", err)
-	}
-	b.bh.FirstValue = firstValue
-	src, rowsCount, err := encoding.UnmarshalVarUint64(src)
-	if err != nil {
-		return src, fmt.Errorf("cannot unmarshal rowsCount: %w", err)
-	}
-	if rowsCount > math.MaxUint32 {
-		return src, fmt.Errorf("got too big rowsCount=%d; it mustn't exceed %d", rowsCount, uint32(math.MaxUint32))
-	}
-	b.bh.RowsCount = uint32(rowsCount)
-	src, scale, err := encoding.UnmarshalVarInt64(src)
-	if err != nil {
-		return src, fmt.Errorf("cannot unmarshal scale: %w", err)
-	}
-	if scale < math.MinInt16 {
-		return src, fmt.Errorf("got too small scale=%d; it mustn't be smaller than %d", scale, math.MinInt16)
-	}
-	if scale > math.MaxInt16 {
-		return src, fmt.Errorf("got too big scale=%d; it mustn't exceeed %d", scale, math.MaxInt16)
-	}
-	b.bh.Scale = int16(scale)
-	if len(src) < 1 {
-		return src, fmt.Errorf("cannot unmarshal marshalType for timestamps from %d bytes; need at least %d bytes", len(src), 1)
-	}
-	b.bh.TimestampsMarshalType = encoding.MarshalType(src[0])
-	src = src[1:]
-	if len(src) < 1 {
-		return src, fmt.Errorf("cannot unmarshal marshalType for values from %d bytes; need at least %d bytes", len(src), 1)
-	}
-	b.bh.ValuesMarshalType = encoding.MarshalType(src[0])
-	src = src[1:]
-	b.bh.PrecisionBits = 64
-
-	// Read data
 	src, timestampsData, err := encoding.UnmarshalBytes(src)
 	if err != nil {
 		return src, fmt.Errorf("cannot read timestampsData: %w", err)
@@ -399,7 +377,6 @@ func (b *Block) UnmarshalPortable(src []byte) ([]byte, error) {
 	}
 	b.valuesData = append(b.valuesData[:0], valuesData...)
 
-	// Validate
 	if err := b.bh.validate(); err != nil {
 		return src, fmt.Errorf("invalid blockHeader: %w", err)
 	}
diff --git a/lib/storage/block_header.go b/lib/storage/block_header.go
index 38b49c44f..6bade6216 100644
--- a/lib/storage/block_header.go
+++ b/lib/storage/block_header.go
@@ -2,6 +2,7 @@ package storage
 
 import (
 	"fmt"
+	"math"
 	"sort"
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding"
@@ -154,6 +155,69 @@ func (bh *blockHeader) Unmarshal(src []byte) ([]byte, error) {
 	return src, err
 }
 
+func (bh *blockHeader) marshalPortable(dst []byte) []byte {
+	dst = encoding.MarshalVarInt64(dst, bh.MinTimestamp)
+	dst = encoding.MarshalVarInt64(dst, bh.MaxTimestamp)
+	dst = encoding.MarshalVarInt64(dst, bh.FirstValue)
+	dst = encoding.MarshalVarUint64(dst, uint64(bh.RowsCount))
+	dst = encoding.MarshalVarInt64(dst, int64(bh.Scale))
+	dst = append(dst, byte(bh.TimestampsMarshalType), byte(bh.ValuesMarshalType), byte(bh.PrecisionBits))
+	return dst
+}
+
+func (bh *blockHeader) unmarshalPortable(src []byte) ([]byte, error) {
+	src, minTimestamp, err := encoding.UnmarshalVarInt64(src)
+	if err != nil {
+		return src, fmt.Errorf("cannot unmarshal firstTimestamp: %w", err)
+	}
+	bh.MinTimestamp = minTimestamp
+	src, maxTimestamp, err := encoding.UnmarshalVarInt64(src)
+	if err != nil {
+		return src, fmt.Errorf("cannot unmarshal firstTimestamp: %w", err)
+	}
+	bh.MaxTimestamp = maxTimestamp
+	src, firstValue, err := encoding.UnmarshalVarInt64(src)
+	if err != nil {
+		return src, fmt.Errorf("cannot unmarshal firstValue: %w", err)
+	}
+	bh.FirstValue = firstValue
+	src, rowsCount, err := encoding.UnmarshalVarUint64(src)
+	if err != nil {
+		return src, fmt.Errorf("cannot unmarshal rowsCount: %w", err)
+	}
+	if rowsCount > math.MaxUint32 {
+		return src, fmt.Errorf("got too big rowsCount=%d; it mustn't exceed %d", rowsCount, uint32(math.MaxUint32))
+	}
+	bh.RowsCount = uint32(rowsCount)
+	src, scale, err := encoding.UnmarshalVarInt64(src)
+	if err != nil {
+		return src, fmt.Errorf("cannot unmarshal scale: %w", err)
+	}
+	if scale < math.MinInt16 {
+		return src, fmt.Errorf("got too small scale=%d; it mustn't be smaller than %d", scale, math.MinInt16)
+	}
+	if scale > math.MaxInt16 {
+		return src, fmt.Errorf("got too big scale=%d; it mustn't exceeed %d", scale, math.MaxInt16)
+	}
+	bh.Scale = int16(scale)
+	if len(src) < 1 {
+		return src, fmt.Errorf("cannot unmarshal marshalType for timestamps from %d bytes; need at least %d bytes", len(src), 1)
+	}
+	bh.TimestampsMarshalType = encoding.MarshalType(src[0])
+	src = src[1:]
+	if len(src) < 1 {
+		return src, fmt.Errorf("cannot unmarshal marshalType for values from %d bytes; need at least %d bytes", len(src), 1)
+	}
+	bh.ValuesMarshalType = encoding.MarshalType(src[0])
+	src = src[1:]
+	if len(src) < 1 {
+		return src, fmt.Errorf("cannot unmarshal precisionBits for values from %d bytes; need at least %d bytes", len(src), 1)
+	}
+	bh.PrecisionBits = uint8(src[0])
+	src = src[1:]
+	return src, nil
+}
+
 func (bh *blockHeader) validate() error {
 	if bh.RowsCount == 0 {
 		return fmt.Errorf("RowsCount in block header cannot be zero")
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
index ff1af4848..0d2ea8151 100644
--- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
+++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
@@ -33,6 +33,7 @@ const (
 	EuWest1RegionID      = "eu-west-1"      // Europe (Ireland).
 	EuWest2RegionID      = "eu-west-2"      // Europe (London).
 	EuWest3RegionID      = "eu-west-3"      // Europe (Paris).
+	MeCentral1RegionID   = "me-central-1"   // Middle East (UAE).
 	MeSouth1RegionID     = "me-south-1"     // Middle East (Bahrain).
 	SaEast1RegionID      = "sa-east-1"      // South America (Sao Paulo).
 	UsEast1RegionID      = "us-east-1"      // US East (N. Virginia).
@@ -186,6 +187,9 @@ var awsPartition = partition{
 		"eu-west-3": region{
 			Description: "Europe (Paris)",
 		},
+		"me-central-1": region{
+			Description: "Middle East (UAE)",
+		},
 		"me-south-1": region{
 			Description: "Middle East (Bahrain)",
 		},
@@ -314,6 +318,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -437,6 +444,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -1298,6 +1308,14 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{
+					Hostname: "api.ecr.me-central-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "me-central-1",
+					},
+				},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{
@@ -1948,9 +1966,18 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "ap-southeast-2",
 				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-3",
+				}: endpoint{},
 				endpointKey{
 					Region: "ca-central-1",
 				}: endpoint{},
+				endpointKey{
+					Region:  "ca-central-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "apigateway-fips.ca-central-1.amazonaws.com",
+				},
 				endpointKey{
 					Region: "eu-central-1",
 				}: endpoint{},
@@ -1969,6 +1996,54 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "fips-ca-central-1",
+				}: endpoint{
+					Hostname: "apigateway-fips.ca-central-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "ca-central-1",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-east-1",
+				}: endpoint{
+					Hostname: "apigateway-fips.us-east-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-east-2",
+				}: endpoint{
+					Hostname: "apigateway-fips.us-east-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-2",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-west-1",
+				}: endpoint{
+					Hostname: "apigateway-fips.us-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-1",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-west-2",
+				}: endpoint{
+					Hostname: "apigateway-fips.us-west-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-2",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -1978,15 +2053,39 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "us-east-1",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-east-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "apigateway-fips.us-east-1.amazonaws.com",
+				},
 				endpointKey{
 					Region: "us-east-2",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-east-2",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "apigateway-fips.us-east-2.amazonaws.com",
+				},
 				endpointKey{
 					Region: "us-west-1",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-west-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "apigateway-fips.us-west-1.amazonaws.com",
+				},
 				endpointKey{
 					Region: "us-west-2",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-west-2",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "apigateway-fips.us-west-2.amazonaws.com",
+				},
 			},
 		},
 		"app-integrations": service{
@@ -2073,6 +2172,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -2267,6 +2369,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -2836,6 +2941,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "ap-southeast-2",
 				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-3",
+				}: endpoint{},
 				endpointKey{
 					Region: "ca-central-1",
 				}: endpoint{},
@@ -3032,6 +3140,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -3884,6 +3995,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -4183,6 +4297,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -4601,6 +4718,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -5613,6 +5733,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -5735,6 +5858,115 @@ var awsPartition = partition{
 				}: endpoint{},
 			},
 		},
+		"controltower": service{
+			Endpoints: serviceEndpoints{
+				endpointKey{
+					Region: "ap-northeast-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-northeast-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-south-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "ca-central-1",
+				}: endpoint{},
+				endpointKey{
+					Region:  "ca-central-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "controltower-fips.ca-central-1.amazonaws.com",
+				},
+				endpointKey{
+					Region: "ca-central-1-fips",
+				}: endpoint{
+					Hostname: "controltower-fips.ca-central-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "ca-central-1",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "eu-central-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-north-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-3",
+				}: endpoint{},
+				endpointKey{
+					Region: "sa-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region:  "us-east-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "controltower-fips.us-east-1.amazonaws.com",
+				},
+				endpointKey{
+					Region: "us-east-1-fips",
+				}: endpoint{
+					Hostname: "controltower-fips.us-east-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "us-east-2",
+				}: endpoint{},
+				endpointKey{
+					Region:  "us-east-2",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "controltower-fips.us-east-2.amazonaws.com",
+				},
+				endpointKey{
+					Region: "us-east-2-fips",
+				}: endpoint{
+					Hostname: "controltower-fips.us-east-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-2",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "us-west-2",
+				}: endpoint{},
+				endpointKey{
+					Region:  "us-west-2",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "controltower-fips.us-west-2.amazonaws.com",
+				},
+				endpointKey{
+					Region: "us-west-2-fips",
+				}: endpoint{
+					Hostname: "controltower-fips.us-west-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-2",
+					},
+					Deprecated: boxedTrue,
+				},
+			},
+		},
 		"cur": service{
 			Endpoints: serviceEndpoints{
 				endpointKey{
@@ -6091,21 +6323,81 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "fips-us-east-1",
+				}: endpoint{
+					Hostname: "databrew-fips.us-east-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-east-2",
+				}: endpoint{
+					Hostname: "databrew-fips.us-east-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-2",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-west-1",
+				}: endpoint{
+					Hostname: "databrew-fips.us-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-1",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-west-2",
+				}: endpoint{
+					Hostname: "databrew-fips.us-west-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-2",
+					},
+					Deprecated: boxedTrue,
+				},
 				endpointKey{
 					Region: "sa-east-1",
 				}: endpoint{},
 				endpointKey{
 					Region: "us-east-1",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-east-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "databrew-fips.us-east-1.amazonaws.com",
+				},
 				endpointKey{
 					Region: "us-east-2",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-east-2",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "databrew-fips.us-east-2.amazonaws.com",
+				},
 				endpointKey{
 					Region: "us-west-1",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-west-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "databrew-fips.us-west-1.amazonaws.com",
+				},
 				endpointKey{
 					Region: "us-west-2",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-west-2",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "databrew-fips.us-west-2.amazonaws.com",
+				},
 			},
 		},
 		"dataexchange": service{
@@ -6526,6 +6818,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -6742,6 +7037,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -7031,6 +7329,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "ap-southeast-2",
 				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-3",
+				}: endpoint{},
 				endpointKey{
 					Region: "ca-central-1",
 				}: endpoint{},
@@ -7226,6 +7527,9 @@ var awsPartition = partition{
 						Region: "us-east-1",
 					},
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -7569,6 +7873,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -7723,6 +8030,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -7989,6 +8299,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -8690,6 +9003,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -8843,6 +9159,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -9258,6 +9577,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -9424,6 +9746,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -12697,6 +13022,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -13153,6 +13481,15 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
+				endpointKey{
+					Region:  "me-central-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "kms-fips.me-central-1.amazonaws.com",
+				},
 				endpointKey{
 					Region: "me-central-1-fips",
 				}: endpoint{
@@ -13581,6 +13918,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -14050,6 +14390,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -15027,6 +15370,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -15375,6 +15721,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -16388,6 +16737,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -17170,6 +17522,12 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "ca-central-1",
 				}: endpoint{},
+				endpointKey{
+					Region:  "ca-central-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "rbin-fips.ca-central-1.amazonaws.com",
+				},
 				endpointKey{
 					Region: "eu-central-1",
 				}: endpoint{},
@@ -17188,6 +17546,54 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "fips-ca-central-1",
+				}: endpoint{
+					Hostname: "rbin-fips.ca-central-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "ca-central-1",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-east-1",
+				}: endpoint{
+					Hostname: "rbin-fips.us-east-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-east-2",
+				}: endpoint{
+					Hostname: "rbin-fips.us-east-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-2",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-west-1",
+				}: endpoint{
+					Hostname: "rbin-fips.us-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-1",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-west-2",
+				}: endpoint{
+					Hostname: "rbin-fips.us-west-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-2",
+					},
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -17197,15 +17603,39 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "us-east-1",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-east-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "rbin-fips.us-east-1.amazonaws.com",
+				},
 				endpointKey{
 					Region: "us-east-2",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-east-2",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "rbin-fips.us-east-2.amazonaws.com",
+				},
 				endpointKey{
 					Region: "us-west-1",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-west-1",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "rbin-fips.us-west-1.amazonaws.com",
+				},
 				endpointKey{
 					Region: "us-west-2",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-west-2",
+					Variant: fipsVariant,
+				}: endpoint{
+					Hostname: "rbin-fips.us-west-2.amazonaws.com",
+				},
 			},
 		},
 		"rds": service{
@@ -17273,6 +17703,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -17698,6 +18131,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -18972,6 +19408,15 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
+				endpointKey{
+					Region:  "me-central-1",
+					Variant: dualStackVariant,
+				}: endpoint{
+					Hostname: "s3.dualstack.me-central-1.amazonaws.com",
+				},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -19893,6 +20338,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -21397,6 +21845,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -21533,6 +21984,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -21681,6 +22135,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -21924,6 +22381,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -22189,6 +22649,9 @@ var awsPartition = partition{
 						Region: "us-east-1",
 					},
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -22268,6 +22731,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -22460,6 +22926,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -22590,6 +23059,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -22684,6 +23156,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-3",
 				}: endpoint{},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
@@ -23375,12 +23850,32 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "eu-west-2",
 				}: endpoint{},
+				endpointKey{
+					Region: "fips-us-east-1",
+				}: endpoint{
+
+					Deprecated: boxedTrue,
+				},
+				endpointKey{
+					Region: "fips-us-west-2",
+				}: endpoint{
+
+					Deprecated: boxedTrue,
+				},
 				endpointKey{
 					Region: "us-east-1",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-east-1",
+					Variant: fipsVariant,
+				}: endpoint{},
 				endpointKey{
 					Region: "us-west-2",
 				}: endpoint{},
+				endpointKey{
+					Region:  "us-west-2",
+					Variant: fipsVariant,
+				}: endpoint{},
 			},
 		},
 		"waf": service{
@@ -24934,6 +25429,9 @@ var awsPartition = partition{
 					},
 					Deprecated: boxedTrue,
 				},
+				endpointKey{
+					Region: "me-central-1",
+				}: endpoint{},
 				endpointKey{
 					Region: "me-south-1",
 				}: endpoint{},
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go
index 7091b12ad..f09b245b0 100644
--- a/vendor/github.com/aws/aws-sdk-go/aws/version.go
+++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go
@@ -5,4 +5,4 @@ package aws
 const SDKName = "aws-sdk-go"
 
 // SDKVersion is the version of this SDK
-const SDKVersion = "1.44.87"
+const SDKVersion = "1.44.91"
diff --git a/vendor/github.com/aws/aws-sdk-go/service/sso/api.go b/vendor/github.com/aws/aws-sdk-go/service/sso/api.go
index bdb8c2f7e..b8f590f71 100644
--- a/vendor/github.com/aws/aws-sdk-go/service/sso/api.go
+++ b/vendor/github.com/aws/aws-sdk-go/service/sso/api.go
@@ -156,8 +156,7 @@ func (c *SSO) ListAccountRolesRequest(input *ListAccountRolesInput) (req *reques
 
 // ListAccountRoles API operation for AWS Single Sign-On.
 //
-// Lists all roles that are assigned to the user for a given Amazon Web Services
-// account.
+// Lists all roles that are assigned to the user for a given AWS account.
 //
 // Returns awserr.Error for service API and SDK errors. Use runtime type assertions
 // with awserr.Error's Code and Message methods to get detailed information about
@@ -306,10 +305,10 @@ func (c *SSO) ListAccountsRequest(input *ListAccountsInput) (req *request.Reques
 
 // ListAccounts API operation for AWS Single Sign-On.
 //
-// Lists all Amazon Web Services accounts assigned to the user. These Amazon
-// Web Services accounts are assigned by the administrator of the account. For
-// more information, see Assign User Access (https://docs.aws.amazon.com/singlesignon/latest/userguide/useraccess.html#assignusers)
-// in the Amazon Web Services SSO User Guide. This operation returns a paginated
+// Lists all AWS accounts assigned to the user. These AWS accounts are assigned
+// by the administrator of the account. For more information, see Assign User
+// Access (https://docs.aws.amazon.com/singlesignon/latest/userguide/useraccess.html#assignusers)
+// in the IAM Identity Center User Guide. This operation returns a paginated
 // response.
 //
 // Returns awserr.Error for service API and SDK errors. Use runtime type assertions
@@ -455,20 +454,20 @@ func (c *SSO) LogoutRequest(input *LogoutInput) (req *request.Request, output *L
 // Logout API operation for AWS Single Sign-On.
 //
 // Removes the locally stored SSO tokens from the client-side cache and sends
-// an API call to the Amazon Web Services SSO service to invalidate the corresponding
-// server-side Amazon Web Services SSO sign in session.
+// an API call to the IAM Identity Center service to invalidate the corresponding
+// server-side IAM Identity Center sign in session.
 //
-// If a user uses Amazon Web Services SSO to access the AWS CLI, the user’s
-// Amazon Web Services SSO sign in session is used to obtain an IAM session,
-// as specified in the corresponding Amazon Web Services SSO permission set.
-// More specifically, Amazon Web Services SSO assumes an IAM role in the target
-// account on behalf of the user, and the corresponding temporary Amazon Web
-// Services credentials are returned to the client.
+// If a user uses IAM Identity Center to access the AWS CLI, the user’s IAM
+// Identity Center sign in session is used to obtain an IAM session, as specified
+// in the corresponding IAM Identity Center permission set. More specifically,
+// IAM Identity Center assumes an IAM role in the target account on behalf of
+// the user, and the corresponding temporary AWS credentials are returned to
+// the client.
 //
 // After user logout, any existing IAM role sessions that were created by using
-// Amazon Web Services SSO permission sets continue based on the duration configured
+// IAM Identity Center permission sets continue based on the duration configured
 // in the permission set. For more information, see User authentications (https://docs.aws.amazon.com/singlesignon/latest/userguide/authconcept.html)
-// in the Amazon Web Services SSO User Guide.
+// in the IAM Identity Center User Guide.
 //
 // Returns awserr.Error for service API and SDK errors. Use runtime type assertions
 // with awserr.Error's Code and Message methods to get detailed information about
@@ -513,20 +512,17 @@ func (c *SSO) LogoutWithContext(ctx aws.Context, input *LogoutInput, opts ...req
 	return out, req.Send()
 }
 
-// Provides information about your Amazon Web Services account.
+// Provides information about your AWS account.
 type AccountInfo struct {
 	_ struct{} `type:"structure"`
 
-	// The identifier of the Amazon Web Services account that is assigned to the
-	// user.
+	// The identifier of the AWS account that is assigned to the user.
 	AccountId *string `locationName:"accountId" type:"string"`
 
-	// The display name of the Amazon Web Services account that is assigned to the
-	// user.
+	// The display name of the AWS account that is assigned to the user.
 	AccountName *string `locationName:"accountName" type:"string"`
 
-	// The email address of the Amazon Web Services account that is assigned to
-	// the user.
+	// The email address of the AWS account that is assigned to the user.
 	EmailAddress *string `locationName:"emailAddress" min:"1" type:"string"`
 }
 
@@ -571,7 +567,7 @@ type GetRoleCredentialsInput struct {
 
 	// The token issued by the CreateToken API call. For more information, see CreateToken
 	// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html)
-	// in the Amazon Web Services SSO OIDC API Reference Guide.
+	// in the IAM Identity Center OIDC API Reference Guide.
 	//
 	// AccessToken is a sensitive parameter and its value will be
 	// replaced with "sensitive" in string returned by GetRoleCredentialsInput's
@@ -580,8 +576,7 @@ type GetRoleCredentialsInput struct {
 	// AccessToken is a required field
 	AccessToken *string `location:"header" locationName:"x-amz-sso_bearer_token" type:"string" required:"true" sensitive:"true"`
 
-	// The identifier for the Amazon Web Services account that is assigned to the
-	// user.
+	// The identifier for the AWS account that is assigned to the user.
 	//
 	// AccountId is a required field
 	AccountId *string `location:"querystring" locationName:"account_id" type:"string" required:"true"`
@@ -748,7 +743,7 @@ type ListAccountRolesInput struct {
 
 	// The token issued by the CreateToken API call. For more information, see CreateToken
 	// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html)
-	// in the Amazon Web Services SSO OIDC API Reference Guide.
+	// in the IAM Identity Center OIDC API Reference Guide.
 	//
 	// AccessToken is a sensitive parameter and its value will be
 	// replaced with "sensitive" in string returned by ListAccountRolesInput's
@@ -757,8 +752,7 @@ type ListAccountRolesInput struct {
 	// AccessToken is a required field
 	AccessToken *string `location:"header" locationName:"x-amz-sso_bearer_token" type:"string" required:"true" sensitive:"true"`
 
-	// The identifier for the Amazon Web Services account that is assigned to the
-	// user.
+	// The identifier for the AWS account that is assigned to the user.
 	//
 	// AccountId is a required field
 	AccountId *string `location:"querystring" locationName:"account_id" type:"string" required:"true"`
@@ -878,7 +872,7 @@ type ListAccountsInput struct {
 
 	// The token issued by the CreateToken API call. For more information, see CreateToken
 	// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html)
-	// in the Amazon Web Services SSO OIDC API Reference Guide.
+	// in the IAM Identity Center OIDC API Reference Guide.
 	//
 	// AccessToken is a sensitive parameter and its value will be
 	// replaced with "sensitive" in string returned by ListAccountsInput's
@@ -993,7 +987,7 @@ type LogoutInput struct {
 
 	// The token issued by the CreateToken API call. For more information, see CreateToken
 	// (https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html)
-	// in the Amazon Web Services SSO OIDC API Reference Guide.
+	// in the IAM Identity Center OIDC API Reference Guide.
 	//
 	// AccessToken is a sensitive parameter and its value will be
 	// replaced with "sensitive" in string returned by LogoutInput's
@@ -1132,18 +1126,17 @@ type RoleCredentials struct {
 	_ struct{} `type:"structure"`
 
 	// The identifier used for the temporary security credentials. For more information,
-	// see Using Temporary Security Credentials to Request Access to Amazon Web
-	// Services Resources (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)
-	// in the Amazon Web Services IAM User Guide.
+	// see Using Temporary Security Credentials to Request Access to AWS Resources
+	// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)
+	// in the AWS IAM User Guide.
 	AccessKeyId *string `locationName:"accessKeyId" type:"string"`
 
 	// The date on which temporary security credentials expire.
 	Expiration *int64 `locationName:"expiration" type:"long"`
 
 	// The key that is used to sign the request. For more information, see Using
-	// Temporary Security Credentials to Request Access to Amazon Web Services Resources
-	// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)
-	// in the Amazon Web Services IAM User Guide.
+	// Temporary Security Credentials to Request Access to AWS Resources (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)
+	// in the AWS IAM User Guide.
 	//
 	// SecretAccessKey is a sensitive parameter and its value will be
 	// replaced with "sensitive" in string returned by RoleCredentials's
@@ -1151,9 +1144,8 @@ type RoleCredentials struct {
 	SecretAccessKey *string `locationName:"secretAccessKey" type:"string" sensitive:"true"`
 
 	// The token used for temporary credentials. For more information, see Using
-	// Temporary Security Credentials to Request Access to Amazon Web Services Resources
-	// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)
-	// in the Amazon Web Services IAM User Guide.
+	// Temporary Security Credentials to Request Access to AWS Resources (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)
+	// in the AWS IAM User Guide.
 	//
 	// SessionToken is a sensitive parameter and its value will be
 	// replaced with "sensitive" in string returned by RoleCredentials's
@@ -1207,7 +1199,7 @@ func (s *RoleCredentials) SetSessionToken(v string) *RoleCredentials {
 type RoleInfo struct {
 	_ struct{} `type:"structure"`
 
-	// The identifier of the Amazon Web Services account assigned to the user.
+	// The identifier of the AWS account assigned to the user.
 	AccountId *string `locationName:"accountId" type:"string"`
 
 	// The friendly name of the role that is assigned to the user.
diff --git a/vendor/github.com/aws/aws-sdk-go/service/sso/doc.go b/vendor/github.com/aws/aws-sdk-go/service/sso/doc.go
index ebcc9b405..15e61a322 100644
--- a/vendor/github.com/aws/aws-sdk-go/service/sso/doc.go
+++ b/vendor/github.com/aws/aws-sdk-go/service/sso/doc.go
@@ -3,25 +3,24 @@
 // Package sso provides the client and types for making API
 // requests to AWS Single Sign-On.
 //
-// Amazon Web Services Single Sign On Portal is a web service that makes it
-// easy for you to assign user access to Amazon Web Services SSO resources such
-// as the AWS access portal. Users can get Amazon Web Services account applications
-// and roles assigned to them and get federated into the application.
+// AWS IAM Identity Center (successor to AWS Single Sign-On) Portal is a web
+// service that makes it easy for you to assign user access to IAM Identity
+// Center resources such as the AWS access portal. Users can get AWS account
+// applications and roles assigned to them and get federated into the application.
 //
-// Although Amazon Web Services Single Sign-On was renamed, the sso and identitystore
-// API namespaces will continue to retain their original name for backward compatibility
-// purposes. For more information, see Amazon Web Services SSO rename (https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html#renamed).
+// Although AWS Single Sign-On was renamed, the sso and identitystore API namespaces
+// will continue to retain their original name for backward compatibility purposes.
+// For more information, see IAM Identity Center rename (https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html#renamed).
 //
-// This reference guide describes the Amazon Web Services SSO Portal operations
+// This reference guide describes the IAM Identity Center Portal operations
 // that you can call programatically and includes detailed information on data
 // types and errors.
 //
-// Amazon Web Services provides SDKs that consist of libraries and sample code
-// for various programming languages and platforms, such as Java, Ruby, .Net,
-// iOS, or Android. The SDKs provide a convenient way to create programmatic
-// access to Amazon Web Services SSO and other Amazon Web Services services.
-// For more information about the Amazon Web Services SDKs, including how to
-// download and install them, see Tools for Amazon Web Services (http://aws.amazon.com/tools/).
+// AWS provides SDKs that consist of libraries and sample code for various programming
+// languages and platforms, such as Java, Ruby, .Net, iOS, or Android. The SDKs
+// provide a convenient way to create programmatic access to IAM Identity Center
+// and other AWS services. For more information about the AWS SDKs, including
+// how to download and install them, see Tools for Amazon Web Services (http://aws.amazon.com/tools/).
 //
 // See https://docs.aws.amazon.com/goto/WebAPI/sso-2019-06-10 for more information on this service.
 //
diff --git a/vendor/github.com/urfave/cli/v2/.gitignore b/vendor/github.com/urfave/cli/v2/.gitignore
index c04fcc538..d7d26b1fc 100644
--- a/vendor/github.com/urfave/cli/v2/.gitignore
+++ b/vendor/github.com/urfave/cli/v2/.gitignore
@@ -1,10 +1,13 @@
 *.coverprofile
+*.exe
 *.orig
-vendor
+.*envrc
+.envrc
 .idea
-internal/*/built-example
-coverage.txt
 /.local/
 /site/
-
+coverage.txt
+internal/*/built-example
+vendor
+/cmd/urfave-cli-genflags/urfave-cli-genflags
 *.exe
diff --git a/vendor/github.com/urfave/cli/v2/app.go b/vendor/github.com/urfave/cli/v2/app.go
index 0b3f45cfd..1d2f6e89a 100644
--- a/vendor/github.com/urfave/cli/v2/app.go
+++ b/vendor/github.com/urfave/cli/v2/app.go
@@ -78,6 +78,8 @@ type App struct {
 	CommandNotFound CommandNotFoundFunc
 	// Execute this function if a usage error occurs
 	OnUsageError OnUsageErrorFunc
+	// Execute this function when an invalid flag is accessed from the context
+	InvalidFlagAccessHandler InvalidFlagAccessFunc
 	// Compilation date
 	Compiled time.Time
 	// List of all authors who contributed
@@ -304,7 +306,7 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
 		return err
 	}
 
-	if a.After != nil {
+	if a.After != nil && !cCtx.shellComplete {
 		defer func() {
 			if afterErr := a.After(cCtx); afterErr != nil {
 				if err != nil {
@@ -332,7 +334,7 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
 		return cerr
 	}
 
-	if a.Before != nil {
+	if a.Before != nil && !cCtx.shellComplete {
 		beforeErr := a.Before(cCtx)
 		if beforeErr != nil {
 			a.handleExitCoder(cCtx, beforeErr)
@@ -499,7 +501,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
 		return cerr
 	}
 
-	if a.After != nil {
+	if a.After != nil && !cCtx.shellComplete {
 		defer func() {
 			afterErr := a.After(cCtx)
 			if afterErr != nil {
@@ -513,7 +515,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
 		}()
 	}
 
-	if a.Before != nil {
+	if a.Before != nil && !cCtx.shellComplete {
 		beforeErr := a.Before(cCtx)
 		if beforeErr != nil {
 			a.handleExitCoder(cCtx, beforeErr)
diff --git a/vendor/github.com/urfave/cli/v2/cli.go b/vendor/github.com/urfave/cli/v2/cli.go
index 2a11c5ad4..b3b864cf5 100644
--- a/vendor/github.com/urfave/cli/v2/cli.go
+++ b/vendor/github.com/urfave/cli/v2/cli.go
@@ -1,23 +1,25 @@
 // Package cli provides a minimal framework for creating and organizing command line
 // Go applications. cli is designed to be easy to understand and write, the most simple
 // cli application can be written as follows:
-//   func main() {
-//     (&cli.App{}).Run(os.Args)
-//   }
+//
+//	func main() {
+//		(&cli.App{}).Run(os.Args)
+//	}
 //
 // Of course this application does not do much, so let's make this an actual application:
-//   func main() {
-//     app := &cli.App{
-//			 Name: "greet",
-//			 Usage: "say a greeting",
-//			 Action: func(c *cli.Context) error {
-//				 fmt.Println("Greetings")
-//				 return nil
-//			 },
-//		 }
 //
-//     app.Run(os.Args)
-//   }
+//	func main() {
+//		app := &cli.App{
+//	  		Name: "greet",
+//	  		Usage: "say a greeting",
+//	  		Action: func(c *cli.Context) error {
+//	  			fmt.Println("Greetings")
+//	  			return nil
+//	  		},
+//		}
+//
+//		app.Run(os.Args)
+//	}
 package cli
 
-//go:generate go run internal/genflags/cmd/genflags/main.go
+//go:generate go run cmd/urfave-cli-genflags/main.go
diff --git a/vendor/github.com/urfave/cli/v2/context.go b/vendor/github.com/urfave/cli/v2/context.go
index 6b497ed20..dc0d1ef0e 100644
--- a/vendor/github.com/urfave/cli/v2/context.go
+++ b/vendor/github.com/urfave/cli/v2/context.go
@@ -46,6 +46,9 @@ func (cCtx *Context) NumFlags() int {
 
 // Set sets a context flag to a value.
 func (cCtx *Context) Set(name, value string) error {
+	if cCtx.flagSet.Lookup(name) == nil {
+		cCtx.onInvalidFlag(name)
+	}
 	return cCtx.flagSet.Set(name, value)
 }
 
@@ -158,7 +161,7 @@ func (cCtx *Context) lookupFlagSet(name string) *flag.FlagSet {
 			return c.flagSet
 		}
 	}
-
+	cCtx.onInvalidFlag(name)
 	return nil
 }
 
@@ -170,9 +173,7 @@ func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
 			var flagName string
 
 			for _, key := range f.Names() {
-				if len(key) > 1 {
-					flagName = key
-				}
+				flagName = key
 
 				if cCtx.IsSet(strings.TrimSpace(key)) {
 					flagPresent = true
@@ -192,6 +193,16 @@ func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
 	return nil
 }
 
+func (cCtx *Context) onInvalidFlag(name string) {
+	for cCtx != nil {
+		if cCtx.App != nil && cCtx.App.InvalidFlagAccessHandler != nil {
+			cCtx.App.InvalidFlagAccessHandler(cCtx, name)
+			break
+		}
+		cCtx = cCtx.parentContext
+	}
+}
+
 func makeFlagNameVisitor(names *[]string) func(*flag.Flag) {
 	return func(f *flag.Flag) {
 		nameParts := strings.Split(f.Name, ",")
diff --git a/vendor/github.com/urfave/cli/v2/flag-spec.yaml b/vendor/github.com/urfave/cli/v2/flag-spec.yaml
index 45f054d6e..1c594d723 100644
--- a/vendor/github.com/urfave/cli/v2/flag-spec.yaml
+++ b/vendor/github.com/urfave/cli/v2/flag-spec.yaml
@@ -1,15 +1,23 @@
 # NOTE: this file is used by the tool defined in
-# ./internal/genflags/cmd/genflags/main.go which uses the
-# `genflags.Spec` type that maps to this file structure.
+# ./cmd/urfave-cli-genflags/main.go which uses the
+# `Spec` type that maps to this file structure.
 
 flag_types:
   bool: {}
   float64: {}
-  int64: {}
-  int: {}
+  int64:
+    struct_fields:
+      - { name: Base, type: int }
+  int:
+    struct_fields:
+      - { name: Base, type: int }
   time.Duration: {}
-  uint64: {}
-  uint: {}
+  uint64:
+    struct_fields:
+      - { name: Base, type: int }
+  uint:
+    struct_fields:
+      - { name: Base, type: int }
 
   string:
     struct_fields:
diff --git a/vendor/github.com/urfave/cli/v2/flag.go b/vendor/github.com/urfave/cli/v2/flag.go
index dbed577cd..37c9fdab2 100644
--- a/vendor/github.com/urfave/cli/v2/flag.go
+++ b/vendor/github.com/urfave/cli/v2/flag.go
@@ -7,7 +7,6 @@ import (
 	"io/ioutil"
 	"regexp"
 	"runtime"
-	"strconv"
 	"strings"
 	"syscall"
 	"time"
@@ -318,53 +317,6 @@ func stringifyFlag(f Flag) string {
 		fmt.Sprintf("%s\t%s", prefixedNames(df.Names(), placeholder), usageWithDefault))
 }
 
-func stringifyIntSliceFlag(f *IntSliceFlag) string {
-	var defaultVals []string
-	if f.Value != nil && len(f.Value.Value()) > 0 {
-		for _, i := range f.Value.Value() {
-			defaultVals = append(defaultVals, strconv.Itoa(i))
-		}
-	}
-
-	return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
-}
-
-func stringifyInt64SliceFlag(f *Int64SliceFlag) string {
-	var defaultVals []string
-	if f.Value != nil && len(f.Value.Value()) > 0 {
-		for _, i := range f.Value.Value() {
-			defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
-		}
-	}
-
-	return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
-}
-
-func stringifyFloat64SliceFlag(f *Float64SliceFlag) string {
-	var defaultVals []string
-
-	if f.Value != nil && len(f.Value.Value()) > 0 {
-		for _, i := range f.Value.Value() {
-			defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
-		}
-	}
-
-	return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
-}
-
-func stringifyStringSliceFlag(f *StringSliceFlag) string {
-	var defaultVals []string
-	if f.Value != nil && len(f.Value.Value()) > 0 {
-		for _, s := range f.Value.Value() {
-			if len(s) > 0 {
-				defaultVals = append(defaultVals, strconv.Quote(s))
-			}
-		}
-	}
-
-	return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
-}
-
 func stringifySliceFlag(usage string, names, defaultVals []string) string {
 	placeholder, usage := unquoteUsage(usage)
 	if placeholder == "" {
@@ -377,11 +329,8 @@ func stringifySliceFlag(usage string, names, defaultVals []string) string {
 	}
 
 	usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal))
-	multiInputString := "(accepts multiple inputs)"
-	if usageWithDefault != "" {
-		multiInputString = "\t" + multiInputString
-	}
-	return fmt.Sprintf("%s\t%s%s", prefixedNames(names, placeholder), usageWithDefault, multiInputString)
+	pn := prefixedNames(names, placeholder)
+	return fmt.Sprintf("%s [ %s ]\t%s", pn, pn, usageWithDefault)
 }
 
 func hasFlag(flags []Flag, fl Flag) bool {
diff --git a/vendor/github.com/urfave/cli/v2/flag_float64_slice.go b/vendor/github.com/urfave/cli/v2/flag_float64_slice.go
index 031ec1d1a..e4aff73da 100644
--- a/vendor/github.com/urfave/cli/v2/flag_float64_slice.go
+++ b/vendor/github.com/urfave/cli/v2/flag_float64_slice.go
@@ -83,7 +83,7 @@ func (f *Float64Slice) Get() interface{} {
 // String returns a readable representation of this value
 // (for usage defaults)
 func (f *Float64SliceFlag) String() string {
-	return withEnvHint(f.GetEnvVars(), stringifyFloat64SliceFlag(f))
+	return withEnvHint(f.GetEnvVars(), f.stringify())
 }
 
 // TakesValue returns true if the flag takes a value, otherwise false
@@ -169,6 +169,18 @@ func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
 	return ctx.Float64Slice(f.Name)
 }
 
+func (f *Float64SliceFlag) stringify() string {
+	var defaultVals []string
+
+	if f.Value != nil && len(f.Value.Value()) > 0 {
+		for _, i := range f.Value.Value() {
+			defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
+		}
+	}
+
+	return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
+}
+
 // Float64Slice looks up the value of a local Float64SliceFlag, returns
 // nil if not found
 func (cCtx *Context) Float64Slice(name string) []float64 {
diff --git a/vendor/github.com/urfave/cli/v2/flag_int.go b/vendor/github.com/urfave/cli/v2/flag_int.go
index c70b88985..0f5c403b3 100644
--- a/vendor/github.com/urfave/cli/v2/flag_int.go
+++ b/vendor/github.com/urfave/cli/v2/flag_int.go
@@ -44,7 +44,7 @@ func (f *IntFlag) GetEnvVars() []string {
 func (f *IntFlag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
 		if val != "" {
-			valInt, err := strconv.ParseInt(val, 0, 64)
+			valInt, err := strconv.ParseInt(val, f.Base, 64)
 
 			if err != nil {
 				return fmt.Errorf("could not parse %q as int value from %s for flag %s: %s", val, source, f.Name, err)
diff --git a/vendor/github.com/urfave/cli/v2/flag_int64.go b/vendor/github.com/urfave/cli/v2/flag_int64.go
index 5e7038cfb..a392275de 100644
--- a/vendor/github.com/urfave/cli/v2/flag_int64.go
+++ b/vendor/github.com/urfave/cli/v2/flag_int64.go
@@ -44,7 +44,7 @@ func (f *Int64Flag) GetEnvVars() []string {
 func (f *Int64Flag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
 		if val != "" {
-			valInt, err := strconv.ParseInt(val, 0, 64)
+			valInt, err := strconv.ParseInt(val, f.Base, 64)
 
 			if err != nil {
 				return fmt.Errorf("could not parse %q as int value from %s for flag %s: %s", val, source, f.Name, err)
diff --git a/vendor/github.com/urfave/cli/v2/flag_int64_slice.go b/vendor/github.com/urfave/cli/v2/flag_int64_slice.go
index 657aaaaf3..ead4e7757 100644
--- a/vendor/github.com/urfave/cli/v2/flag_int64_slice.go
+++ b/vendor/github.com/urfave/cli/v2/flag_int64_slice.go
@@ -84,7 +84,7 @@ func (i *Int64Slice) Get() interface{} {
 // String returns a readable representation of this value
 // (for usage defaults)
 func (f *Int64SliceFlag) String() string {
-	return withEnvHint(f.GetEnvVars(), stringifyInt64SliceFlag(f))
+	return withEnvHint(f.GetEnvVars(), f.stringify())
 }
 
 // TakesValue returns true of the flag takes a value, otherwise false
@@ -168,6 +168,17 @@ func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
 	return ctx.Int64Slice(f.Name)
 }
 
+func (f *Int64SliceFlag) stringify() string {
+	var defaultVals []string
+	if f.Value != nil && len(f.Value.Value()) > 0 {
+		for _, i := range f.Value.Value() {
+			defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
+		}
+	}
+
+	return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
+}
+
 // Int64Slice looks up the value of a local Int64SliceFlag, returns
 // nil if not found
 func (cCtx *Context) Int64Slice(name string) []int64 {
diff --git a/vendor/github.com/urfave/cli/v2/flag_int_slice.go b/vendor/github.com/urfave/cli/v2/flag_int_slice.go
index 7c383935a..b40e0d8d1 100644
--- a/vendor/github.com/urfave/cli/v2/flag_int_slice.go
+++ b/vendor/github.com/urfave/cli/v2/flag_int_slice.go
@@ -95,7 +95,7 @@ func (i *IntSlice) Get() interface{} {
 // String returns a readable representation of this value
 // (for usage defaults)
 func (f *IntSliceFlag) String() string {
-	return withEnvHint(f.GetEnvVars(), stringifyIntSliceFlag(f))
+	return withEnvHint(f.GetEnvVars(), f.stringify())
 }
 
 // TakesValue returns true of the flag takes a value, otherwise false
@@ -179,6 +179,17 @@ func (f *IntSliceFlag) Get(ctx *Context) []int {
 	return ctx.IntSlice(f.Name)
 }
 
+func (f *IntSliceFlag) stringify() string {
+	var defaultVals []string
+	if f.Value != nil && len(f.Value.Value()) > 0 {
+		for _, i := range f.Value.Value() {
+			defaultVals = append(defaultVals, strconv.Itoa(i))
+		}
+	}
+
+	return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
+}
+
 // IntSlice looks up the value of a local IntSliceFlag, returns
 // nil if not found
 func (cCtx *Context) IntSlice(name string) []int {
diff --git a/vendor/github.com/urfave/cli/v2/flag_string_slice.go b/vendor/github.com/urfave/cli/v2/flag_string_slice.go
index bcdfd4c55..9d69342db 100644
--- a/vendor/github.com/urfave/cli/v2/flag_string_slice.go
+++ b/vendor/github.com/urfave/cli/v2/flag_string_slice.go
@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"flag"
 	"fmt"
+	"strconv"
 	"strings"
 )
 
@@ -73,7 +74,7 @@ func (s *StringSlice) Get() interface{} {
 // String returns a readable representation of this value
 // (for usage defaults)
 func (f *StringSliceFlag) String() string {
-	return withEnvHint(f.GetEnvVars(), stringifyStringSliceFlag(f))
+	return withEnvHint(f.GetEnvVars(), f.stringify())
 }
 
 // TakesValue returns true of the flag takes a value, otherwise false
@@ -157,6 +158,19 @@ func (f *StringSliceFlag) Get(ctx *Context) []string {
 	return ctx.StringSlice(f.Name)
 }
 
+func (f *StringSliceFlag) stringify() string {
+	var defaultVals []string
+	if f.Value != nil && len(f.Value.Value()) > 0 {
+		for _, s := range f.Value.Value() {
+			if len(s) > 0 {
+				defaultVals = append(defaultVals, strconv.Quote(s))
+			}
+		}
+	}
+
+	return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
+}
+
 // StringSlice looks up the value of a local StringSliceFlag, returns
 // nil if not found
 func (cCtx *Context) StringSlice(name string) []string {
diff --git a/vendor/github.com/urfave/cli/v2/flag_uint.go b/vendor/github.com/urfave/cli/v2/flag_uint.go
index 6092b1ad6..d25ff73ad 100644
--- a/vendor/github.com/urfave/cli/v2/flag_uint.go
+++ b/vendor/github.com/urfave/cli/v2/flag_uint.go
@@ -25,7 +25,7 @@ func (f *UintFlag) GetCategory() string {
 func (f *UintFlag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
 		if val != "" {
-			valInt, err := strconv.ParseUint(val, 0, 64)
+			valInt, err := strconv.ParseUint(val, f.Base, 64)
 			if err != nil {
 				return fmt.Errorf("could not parse %q as uint value from %s for flag %s: %s", val, source, f.Name, err)
 			}
diff --git a/vendor/github.com/urfave/cli/v2/flag_uint64.go b/vendor/github.com/urfave/cli/v2/flag_uint64.go
index a37f30d9f..975c73393 100644
--- a/vendor/github.com/urfave/cli/v2/flag_uint64.go
+++ b/vendor/github.com/urfave/cli/v2/flag_uint64.go
@@ -25,7 +25,7 @@ func (f *Uint64Flag) GetCategory() string {
 func (f *Uint64Flag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
 		if val != "" {
-			valInt, err := strconv.ParseUint(val, 0, 64)
+			valInt, err := strconv.ParseUint(val, f.Base, 64)
 			if err != nil {
 				return fmt.Errorf("could not parse %q as uint64 value from %s for flag %s: %s", val, source, f.Name, err)
 			}
diff --git a/vendor/github.com/urfave/cli/v2/funcs.go b/vendor/github.com/urfave/cli/v2/funcs.go
index 0a9b22c94..e77b0d0a1 100644
--- a/vendor/github.com/urfave/cli/v2/funcs.go
+++ b/vendor/github.com/urfave/cli/v2/funcs.go
@@ -23,6 +23,9 @@ type CommandNotFoundFunc func(*Context, string)
 // is displayed and the execution is interrupted.
 type OnUsageErrorFunc func(cCtx *Context, err error, isSubcommand bool) error
 
+// InvalidFlagAccessFunc is executed when an invalid flag is accessed from the context.
+type InvalidFlagAccessFunc func(*Context, string)
+
 // ExitErrHandlerFunc is executed if provided in order to handle exitError values
 // returned by Actions and Before/After functions.
 type ExitErrHandlerFunc func(cCtx *Context, err error)
diff --git a/vendor/github.com/urfave/cli/v2/godoc-current.txt b/vendor/github.com/urfave/cli/v2/godoc-current.txt
index 1ba48cc65..a6a3887ec 100644
--- a/vendor/github.com/urfave/cli/v2/godoc-current.txt
+++ b/vendor/github.com/urfave/cli/v2/godoc-current.txt
@@ -64,8 +64,8 @@ GLOBAL OPTIONS:
 COPYRIGHT:
    {{wrap .Copyright 3}}{{end}}
 `
-    AppHelpTemplate is the text template for the Default help topic. cli.go uses
-    text/template to render templates. You can render custom help text by
+    AppHelpTemplate is the text template for the Default help topic. cli.go
+    uses text/template to render templates. You can render custom help text by
     setting this variable.
 
 var CommandHelpTemplate = `NAME:
@@ -201,9 +201,9 @@ func DefaultAppComplete(cCtx *Context)
 func DefaultCompleteWithFlags(cmd *Command) func(cCtx *Context)
 func FlagNames(name string, aliases []string) []string
 func HandleAction(action interface{}, cCtx *Context) (err error)
-    HandleAction attempts to figure out which Action signature was used. If it's
-    an ActionFunc or a func with the legacy signature for Action, the func is
-    run!
+    HandleAction attempts to figure out which Action signature was used.
+    If it's an ActionFunc or a func with the legacy signature for Action,
+    the func is run!
 
 func HandleExitCoder(err error)
     HandleExitCoder handles errors implementing ExitCoder by printing their
@@ -360,14 +360,14 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error)
     to generate command-specific flags
 
 func (a *App) RunContext(ctx context.Context, arguments []string) (err error)
-    RunContext is like Run except it takes a Context that will be passed to its
-    commands and sub-commands. Through this, you can propagate timeouts and
+    RunContext is like Run except it takes a Context that will be passed to
+    its commands and sub-commands. Through this, you can propagate timeouts and
     cancellation requests
 
 func (a *App) Setup()
-    Setup runs initialization code to ensure all data structures are ready for
-    `Run` or inspection prior to `Run`. It is internally called by `Run`, but
-    will return early if setup has already happened.
+    Setup runs initialization code to ensure all data structures are ready
+    for `Run` or inspection prior to `Run`. It is internally called by `Run`,
+    but will return early if setup has already happened.
 
 func (a *App) ToFishCompletion() (string, error)
     ToFishCompletion creates a fish completion string for the `*App` The
@@ -799,9 +799,9 @@ func Exit(message interface{}, exitCode int) ExitCoder
     Exit wraps a message and exit code into an error, which by default is
     handled with a call to os.Exit during default error handling.
 
-    This is the simplest way to trigger a non-zero exit code for an App without
-    having to call os.Exit manually. During testing, this behavior can be
-    avoided by overiding the ExitErrHandler function on an App or the
+    This is the simplest way to trigger a non-zero exit code for an App
+    without having to call os.Exit manually. During testing, this behavior
+    can be avoided by overiding the ExitErrHandler function on an App or the
     package-global OsExiter function.
 
 func NewExitError(message interface{}, exitCode int) ExitCoder
@@ -1131,6 +1131,8 @@ type Int64Flag struct {
 
 	Aliases []string
 	EnvVars []string
+
+	Base int
 }
     Int64Flag is a flag with type int64
 
@@ -1280,6 +1282,8 @@ type IntFlag struct {
 
 	Aliases []string
 	EnvVars []string
+
+	Base int
 }
     IntFlag is a flag with type int
 
@@ -1431,8 +1435,8 @@ type MultiInt64Flag = SliceFlag[*Int64SliceFlag, []int64, int64]
     directly, as Value and/or Destination. See also SliceFlag.
 
 type MultiIntFlag = SliceFlag[*IntSliceFlag, []int, int]
-    MultiIntFlag extends IntSliceFlag with support for using slices directly, as
-    Value and/or Destination. See also SliceFlag.
+    MultiIntFlag extends IntSliceFlag with support for using slices directly,
+    as Value and/or Destination. See also SliceFlag.
 
 type MultiStringFlag = SliceFlag[*StringSliceFlag, []string, string]
     MultiStringFlag extends StringSliceFlag with support for using slices
@@ -1513,8 +1517,8 @@ type RequiredFlag interface {
 
 	IsRequired() bool
 }
-    RequiredFlag is an interface that allows us to mark flags as required it
-    allows flags required flags to be backwards compatible with the Flag
+    RequiredFlag is an interface that allows us to mark flags as required
+    it allows flags required flags to be backwards compatible with the Flag
     interface
 
 type Serializer interface {
@@ -1527,9 +1531,9 @@ type SliceFlag[T SliceFlagTarget[E], S ~[]E, E any] struct {
 	Value       S
 	Destination *S
 }
-    SliceFlag extends implementations like StringSliceFlag and IntSliceFlag with
-    support for using slices directly, as Value and/or Destination. See also
-    SliceFlagTarget, MultiStringFlag, MultiFloat64Flag, MultiInt64Flag,
+    SliceFlag extends implementations like StringSliceFlag and IntSliceFlag
+    with support for using slices directly, as Value and/or Destination.
+    See also SliceFlagTarget, MultiStringFlag, MultiFloat64Flag, MultiInt64Flag,
     MultiIntFlag.
 
 func (x *SliceFlag[T, S, E]) Apply(set *flag.FlagSet) error
@@ -1850,6 +1854,8 @@ type Uint64Flag struct {
 
 	Aliases []string
 	EnvVars []string
+
+	Base int
 }
     Uint64Flag is a flag with type uint64
 
@@ -1910,6 +1916,8 @@ type UintFlag struct {
 
 	Aliases []string
 	EnvVars []string
+
+	Base int
 }
     UintFlag is a flag with type uint
 
@@ -1986,9 +1994,9 @@ func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceCont
     that are supported by the input source
 
 func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(cCtx *cli.Context) (InputSourceContext, error)) cli.BeforeFunc
-    InitInputSourceWithContext is used to to setup an InputSourceContext on a
-    cli.Command Before method. It will create a new input source based on the
-    func provided with potentially using existing cli.Context values to
+    InitInputSourceWithContext is used to to setup an InputSourceContext on
+    a cli.Command Before method. It will create a new input source based on
+    the func provided with potentially using existing cli.Context values to
     initialize itself. If there is no error it will then apply the new input
     source to any flags that are supported by the input source
 
diff --git a/vendor/github.com/urfave/cli/v2/help.go b/vendor/github.com/urfave/cli/v2/help.go
index 9a8d2437d..d6caea426 100644
--- a/vendor/github.com/urfave/cli/v2/help.go
+++ b/vendor/github.com/urfave/cli/v2/help.go
@@ -295,12 +295,14 @@ func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs
 	const maxLineLength = 10000
 
 	funcMap := template.FuncMap{
-		"join":    strings.Join,
-		"indent":  indent,
-		"nindent": nindent,
-		"trim":    strings.TrimSpace,
-		"wrap":    func(input string, offset int) string { return wrap(input, offset, maxLineLength) },
-		"offset":  offset,
+		"join":           strings.Join,
+		"subtract":       subtract,
+		"indent":         indent,
+		"nindent":        nindent,
+		"trim":           strings.TrimSpace,
+		"wrap":           func(input string, offset int) string { return wrap(input, offset, maxLineLength) },
+		"offset":         offset,
+		"offsetCommands": offsetCommands,
 	}
 
 	if customFuncs["wrapAt"] != nil {
@@ -416,6 +418,10 @@ func checkCommandCompletions(c *Context, name string) bool {
 	return true
 }
 
+func subtract(a, b int) int {
+	return a - b
+}
+
 func indent(spaces int, v string) string {
 	pad := strings.Repeat(" ", spaces)
 	return pad + strings.Replace(v, "\n", "\n"+pad, -1)
@@ -476,3 +482,28 @@ func wrapLine(input string, offset int, wrapAt int, padding string) string {
 func offset(input string, fixed int) int {
 	return len(input) + fixed
 }
+
+// this function tries to find the max width of the names column
+// so say we have the following rows for help
+//
+//	foo1, foo2, foo3  some string here
+//	bar1, b2 some other string here
+//
+// We want to offset the 2nd row usage by some amount so that everything
+// is aligned
+//
+//	foo1, foo2, foo3  some string here
+//	bar1, b2          some other string here
+//
+// to find that offset we find the length of all the rows and use the max
+// to calculate the offset
+func offsetCommands(cmds []*Command, fixed int) int {
+	var max int = 0
+	for _, cmd := range cmds {
+		s := strings.Join(cmd.Names(), ", ")
+		if len(s) > max {
+			max = len(s)
+		}
+	}
+	return max + fixed
+}
diff --git a/vendor/github.com/urfave/cli/v2/mkdocs.yml b/vendor/github.com/urfave/cli/v2/mkdocs.yml
index 73b88c509..02657b9ed 100644
--- a/vendor/github.com/urfave/cli/v2/mkdocs.yml
+++ b/vendor/github.com/urfave/cli/v2/mkdocs.yml
@@ -9,9 +9,45 @@ site_url: https://cli.urfave.org/
 repo_url: https://github.com/urfave/cli
 edit_uri: edit/main/docs/
 nav:
-  - Home: index.md
-  - v2 Manual: v2/index.md
-  - v1 Manual: v1/index.md
+  - Home:
+      - Welcome: index.md
+      - Contributing: CONTRIBUTING.md
+      - Code of Conduct: CODE_OF_CONDUCT.md
+      - Releasing: RELEASING.md
+      - Security: SECURITY.md
+      - Migrate v1 to v2: migrate-v1-to-v2.md
+  - v2 Manual:
+      - Getting Started: v2/getting-started.md
+      - Migrating From Older Releases: v2/migrating-from-older-releases.md
+      - Examples:
+          - Greet: v2/examples/greet.md
+          - Arguments: v2/examples/arguments.md
+          - Flags: v2/examples/flags.md
+          - Subcommands: v2/examples/subcommands.md
+          - Subcommands Categories: v2/examples/subcommands-categories.md
+          - Exit Codes: v2/examples/exit-codes.md
+          - Combining Short Options: v2/examples/combining-short-options.md
+          - Bash Completions: v2/examples/bash-completions.md
+          - Generated Help Text: v2/examples/generated-help-text.md
+          - Version Flag: v2/examples/version-flag.md
+          - Timestamp Flag: v2/examples/timestamp-flag.md
+          - Suggestions: v2/examples/suggestions.md
+          - Full API Example: v2/examples/full-api-example.md
+  - v1 Manual:
+      - Getting Started: v1/getting-started.md
+      - Migrating to v2: v1/migrating-to-v2.md
+      - Examples:
+          - Greet: v1/examples/greet.md
+          - Arguments: v1/examples/arguments.md
+          - Flags: v1/examples/flags.md
+          - Subcommands: v1/examples/subcommands.md
+          - Subcommands (Categories): v1/examples/subcommands-categories.md
+          - Exit Codes: v1/examples/exit-codes.md
+          - Combining Short Options: v1/examples/combining-short-options.md
+          - Bash Completions: v1/examples/bash-completions.md
+          - Generated Help Text: v1/examples/generated-help-text.md
+          - Version Flag: v1/examples/version-flag.md
+
 theme:
   name: material
   palette:
@@ -25,9 +61,18 @@ theme:
       toggle:
         icon: material/brightness-7
         name: light mode
+  features:
+    - content.code.annotate
+    - navigation.top
+    - navigation.instant
+    - navigation.expand
+    - navigation.sections
+    - navigation.tabs
+    - navigation.tabs.sticky
 plugins:
   - git-revision-date-localized
   - search
+  - tags
 # NOTE: this is the recommended configuration from
 # https://squidfunk.github.io/mkdocs-material/setup/extensions/#recommended-configuration
 markdown_extensions:
diff --git a/vendor/github.com/urfave/cli/v2/template.go b/vendor/github.com/urfave/cli/v2/template.go
index f3116fd2c..7ed237099 100644
--- a/vendor/github.com/urfave/cli/v2/template.go
+++ b/vendor/github.com/urfave/cli/v2/template.go
@@ -21,8 +21,8 @@ AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
 
 COMMANDS:{{range .VisibleCategories}}{{if .Name}}
    {{.Name}}:{{range .VisibleCommands}}
-     {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}}
-   {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}}
+     {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
+   {{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}}
 
 GLOBAL OPTIONS:{{range .VisibleFlagCategories}}
    {{if .Name}}{{.Name}}
@@ -76,8 +76,8 @@ DESCRIPTION:
 
 COMMANDS:{{range .VisibleCategories}}{{if .Name}}
    {{.Name}}:{{range .VisibleCommands}}
-     {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}}
-   {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
+     {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
+     {{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
 
 OPTIONS:
    {{range .VisibleFlags}}{{.}}
diff --git a/vendor/github.com/urfave/cli/v2/zz_generated.flags.go b/vendor/github.com/urfave/cli/v2/zz_generated.flags.go
index b89566f90..f5b73ba24 100644
--- a/vendor/github.com/urfave/cli/v2/zz_generated.flags.go
+++ b/vendor/github.com/urfave/cli/v2/zz_generated.flags.go
@@ -417,6 +417,8 @@ type IntFlag struct {
 
 	Aliases []string
 	EnvVars []string
+
+	Base int
 }
 
 // String returns a readable representation of this value (for usage defaults)
@@ -462,6 +464,8 @@ type Int64Flag struct {
 
 	Aliases []string
 	EnvVars []string
+
+	Base int
 }
 
 // String returns a readable representation of this value (for usage defaults)
@@ -599,6 +603,8 @@ type UintFlag struct {
 
 	Aliases []string
 	EnvVars []string
+
+	Base int
 }
 
 // String returns a readable representation of this value (for usage defaults)
@@ -644,6 +650,8 @@ type Uint64Flag struct {
 
 	Aliases []string
 	EnvVars []string
+
+	Base int
 }
 
 // String returns a readable representation of this value (for usage defaults)
diff --git a/vendor/modules.txt b/vendor/modules.txt
index be9a4bbbb..ab66a8ff8 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -35,7 +35,7 @@ github.com/VictoriaMetrics/metricsql/binaryop
 # github.com/VividCortex/ewma v1.2.0
 ## explicit; go 1.12
 github.com/VividCortex/ewma
-# github.com/aws/aws-sdk-go v1.44.87
+# github.com/aws/aws-sdk-go v1.44.91
 ## explicit; go 1.11
 github.com/aws/aws-sdk-go/aws
 github.com/aws/aws-sdk-go/aws/arn
@@ -228,7 +228,7 @@ github.com/rivo/uniseg
 # github.com/russross/blackfriday/v2 v2.1.0
 ## explicit
 github.com/russross/blackfriday/v2
-# github.com/urfave/cli/v2 v2.11.2
+# github.com/urfave/cli/v2 v2.14.0
 ## explicit; go 1.18
 github.com/urfave/cli/v2
 # github.com/valyala/bytebufferpool v1.0.0
@@ -353,7 +353,7 @@ google.golang.org/appengine/internal/socket
 google.golang.org/appengine/internal/urlfetch
 google.golang.org/appengine/socket
 google.golang.org/appengine/urlfetch
-# google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf
+# google.golang.org/genproto v0.0.0-20220902135211-223410557253
 ## explicit; go 1.19
 google.golang.org/genproto/googleapis/api/annotations
 google.golang.org/genproto/googleapis/iam/v1


Test patch:
diff --git a/app/vmctl/stepper/split_test.go b/app/vmctl/stepper/split_test.go
new file mode 100644
index 000000000..dec06b18f
--- /dev/null
+++ b/app/vmctl/stepper/split_test.go
@@ -0,0 +1,152 @@
+package stepper
+
+import (
+	"reflect"
+	"testing"
+	"time"
+)
+
+type testTimeRange []string
+
+func mustParseDatetime(t string) time.Time {
+	result, err := time.Parse(time.RFC3339, t)
+	if err != nil {
+		panic(err)
+	}
+	return result
+}
+
+func Test_splitDateRange(t *testing.T) {
+	type args struct {
+		start       string
+		end         string
+		granularity string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    []testTimeRange
+		wantErr bool
+	}{
+		{
+			name: "validates start is before end",
+			args: args{
+				start:       "2022-02-01T00:00:00Z",
+				end:         "2022-01-01T00:00:00Z",
+				granularity: StepMonth,
+			},
+			want:    nil,
+			wantErr: true,
+		},
+		{
+			name: "validates granularity value",
+			args: args{
+				start:       "2022-01-01T00:00:00Z",
+				end:         "2022-02-01T00:00:00Z",
+				granularity: "non-existent-format",
+			},
+			want:    nil,
+			wantErr: true,
+		},
+		{
+			name: "month chunking",
+			args: args{
+				start:       "2022-01-03T11:11:11Z",
+				end:         "2022-03-03T12:12:12Z",
+				granularity: StepMonth,
+			},
+			want: []testTimeRange{
+				{
+					"2022-01-03T11:11:11Z",
+					"2022-01-31T23:59:59.999999999Z",
+				},
+				{
+					"2022-02-01T00:00:00Z",
+					"2022-02-28T23:59:59.999999999Z",
+				},
+				{
+					"2022-03-01T00:00:00Z",
+					"2022-03-03T12:12:12Z",
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "daily chunking",
+			args: args{
+				start:       "2022-01-03T11:11:11Z",
+				end:         "2022-01-05T12:12:12Z",
+				granularity: StepDay,
+			},
+			want: []testTimeRange{
+				{
+					"2022-01-03T11:11:11Z",
+					"2022-01-04T11:11:11Z",
+				},
+				{
+					"2022-01-04T11:11:11Z",
+					"2022-01-05T11:11:11Z",
+				},
+				{
+					"2022-01-05T11:11:11Z",
+					"2022-01-05T12:12:12Z",
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "hourly chunking",
+			args: args{
+				start:       "2022-01-03T11:11:11Z",
+				end:         "2022-01-03T14:14:14Z",
+				granularity: StepHour,
+			},
+			want: []testTimeRange{
+				{
+					"2022-01-03T11:11:11Z",
+					"2022-01-03T12:11:11Z",
+				},
+				{
+					"2022-01-03T12:11:11Z",
+					"2022-01-03T13:11:11Z",
+				},
+				{
+					"2022-01-03T13:11:11Z",
+					"2022-01-03T14:11:11Z",
+				},
+				{
+					"2022-01-03T14:11:11Z",
+					"2022-01-03T14:14:14Z",
+				},
+			},
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			start := mustParseDatetime(tt.args.start)
+			end := mustParseDatetime(tt.args.end)
+
+			got, err := SplitDateRange(start, end, tt.args.granularity)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("splitDateRange() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+			var testExpectedResults [][]time.Time
+			if tt.want != nil {
+				testExpectedResults = make([][]time.Time, 0)
+				for _, dr := range tt.want {
+					testExpectedResults = append(testExpectedResults, []time.Time{
+						mustParseDatetime(dr[0]),
+						mustParseDatetime(dr[1]),
+					})
+				}
+			}
+
+			if !reflect.DeepEqual(got, testExpectedResults) {
+				t.Errorf("splitDateRange() got = %v, want %v", got, testExpectedResults)
+			}
+		})
+	}
+}
diff --git a/app/vmctl/vm_native_test.go b/app/vmctl/vm_native_test.go
index 3e229bcbc..b254dc33c 100644
--- a/app/vmctl/vm_native_test.go
+++ b/app/vmctl/vm_native_test.go
@@ -4,6 +4,8 @@ import (
 	"context"
 	"testing"
 	"time"
+
+	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmctl/stepper"
 )
 
 // If you want to run this test:
@@ -16,6 +18,7 @@ import (
 const (
 	matchFilter     = `{job="avalanche"}`
 	timeStartFilter = "2020-01-01T20:07:00Z"
+	timeEndFilter   = "2020-08-01T20:07:00Z"
 	srcAddr         = "http://127.0.0.1:8428"
 	dstAddr         = "http://127.0.0.1:8528"
 )
@@ -74,6 +77,26 @@ func Test_vmNativeProcessor_run(t *testing.T) {
 			closer:  func(cancelFunc context.CancelFunc) {},
 			wantErr: false,
 		},
+		{
+			name: "simulate correct work with chunking",
+			fields: fields{
+				filter: filter{
+					match:     matchFilter,
+					timeStart: timeStartFilter,
+					timeEnd:   timeEndFilter,
+					chunk:     stepper.StepMonth,
+				},
+				rateLimit: 0,
+				dst: &vmNativeClient{
+					addr: dstAddr,
+				},
+				src: &vmNativeClient{
+					addr: srcAddr,
+				},
+			},
+			closer:  func(cancelFunc context.CancelFunc) {},
+			wantErr: false,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
diff --git a/app/vmselect/promql/rollup_test.go b/app/vmselect/promql/rollup_test.go
index fa589a0b1..ae3362814 100644
--- a/app/vmselect/promql/rollup_test.go
+++ b/app/vmselect/promql/rollup_test.go
@@ -1307,7 +1307,7 @@ func TestRollupFuncsNoWindow(t *testing.T) {
 		if samplesScanned == 0 {
 			t.Fatalf("expecting non-zero samplesScanned from rollupConfig.Do")
 		}
-		valuesExpected := []float64{nan, 2775, 5262.5, 3678.5714285714284, 2880}
+		valuesExpected := []float64{nan, 2775, 5262.5, 3862.5, 1800}
 		timestampsExpected := []int64{0, 40, 80, 120, 160}
 		testRowsEqual(t, values, rc.Timestamps, valuesExpected, timestampsExpected)
 	})
diff --git a/lib/storage/block_test.go b/lib/storage/block_test.go
index e057b465a..86701860c 100644
--- a/lib/storage/block_test.go
+++ b/lib/storage/block_test.go
@@ -1,10 +1,13 @@
 package storage
 
 import (
+	"fmt"
 	"math/rand"
 	"reflect"
 	"strings"
 	"testing"
+
+	"github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding"
 )
 
 func TestBlockMarshalUnmarshalPortable(t *testing.T) {
@@ -15,15 +18,15 @@ func TestBlockMarshalUnmarshalPortable(t *testing.T) {
 		b.timestamps = getRandTimestamps(rowsCount)
 		b.values = getRandValues(rowsCount)
 		b.bh.Scale = int16(rand.Intn(30) - 15)
-		b.bh.PrecisionBits = 64
+		b.bh.PrecisionBits = uint8(64 - (i % 64))
 		testBlockMarshalUnmarshalPortable(t, &b)
 	}
 }
 
 func testBlockMarshalUnmarshalPortable(t *testing.T, b *Block) {
 	var b1, b2 Block
-	b1.CopyFrom(b)
 	rowsCount := len(b.values)
+	b1.CopyFrom(b)
 	data := b1.MarshalPortable(nil)
 	if b1.bh.RowsCount != uint32(rowsCount) {
 		t.Fatalf("unexpected number of rows marshaled; got %d; want %d", b1.bh.RowsCount, rowsCount)
@@ -60,11 +63,14 @@ func testBlockMarshalUnmarshalPortable(t *testing.T, b *Block) {
 	compareBlocksPortable(t, &b2, b, &b1.bh)
 }
 
-func compareBlocksPortable(t *testing.T, b1, b2 *Block, bhExpected *blockHeader) {
+func compareBlocksPortable(t *testing.T, b1, bExpected *Block, bhExpected *blockHeader) {
 	t.Helper()
 	if b1.bh.MinTimestamp != bhExpected.MinTimestamp {
 		t.Fatalf("unexpected MinTimestamp; got %d; want %d", b1.bh.MinTimestamp, bhExpected.MinTimestamp)
 	}
+	if b1.bh.MaxTimestamp != bhExpected.MaxTimestamp {
+		t.Fatalf("unexpected MinTimestamp; got %d; want %d", b1.bh.MaxTimestamp, bhExpected.MaxTimestamp)
+	}
 	if b1.bh.FirstValue != bhExpected.FirstValue {
 		t.Fatalf("unexpected FirstValue; got %d; want %d", b1.bh.FirstValue, bhExpected.FirstValue)
 	}
@@ -83,11 +89,15 @@ func compareBlocksPortable(t *testing.T, b1, b2 *Block, bhExpected *blockHeader)
 	if b1.bh.PrecisionBits != bhExpected.PrecisionBits {
 		t.Fatalf("unexpected PrecisionBits; got %d; want %d", b1.bh.PrecisionBits, bhExpected.PrecisionBits)
 	}
-	if !reflect.DeepEqual(b1.values, b2.values) {
-		t.Fatalf("unexpected values; got %d; want %d", b1.values, b2.values)
+
+	timestampsExpected := getTimestampsForPrecisionBits(bExpected.timestamps, bhExpected.PrecisionBits)
+	valuesExpected := getValuesForPrecisionBits(bExpected.values, bhExpected.PrecisionBits)
+
+	if !reflect.DeepEqual(b1.values, valuesExpected) {
+		t.Fatalf("unexpected values for precisionBits=%d; got\n%d\nwant\n%d", b1.bh.PrecisionBits, b1.values, valuesExpected)
 	}
-	if !reflect.DeepEqual(b1.timestamps, b2.timestamps) {
-		t.Fatalf("unexpected timestamps; got %d; want %d", b1.timestamps, b2.timestamps)
+	if !reflect.DeepEqual(b1.timestamps, timestampsExpected) {
+		t.Fatalf("unexpected timestamps for precisionBits=%d; got\n%d\nwant\n%d", b1.bh.PrecisionBits, b1.timestamps, timestampsExpected)
 	}
 	if len(b1.values) != int(bhExpected.RowsCount) {
 		t.Fatalf("unexpected number of values; got %d; want %d", len(b1.values), bhExpected.RowsCount)
@@ -97,6 +107,27 @@ func compareBlocksPortable(t *testing.T, b1, b2 *Block, bhExpected *blockHeader)
 	}
 }
 
+func getTimestampsForPrecisionBits(timestamps []int64, precisionBits uint8) []int64 {
+	data, marshalType, firstTimestamp := encoding.MarshalTimestamps(nil, timestamps, precisionBits)
+	timestampsAdjusted, err := encoding.UnmarshalTimestamps(nil, data, marshalType, firstTimestamp, len(timestamps))
+	if err != nil {
+		panic(fmt.Errorf("BUG: cannot unmarshal timestamps with precisionBits %d: %s", precisionBits, err))
+	}
+	minTimestamp := timestamps[0]
+	maxTimestamp := timestamps[len(timestamps)-1]
+	encoding.EnsureNonDecreasingSequence(timestampsAdjusted, minTimestamp, maxTimestamp)
+	return timestampsAdjusted
+}
+
+func getValuesForPrecisionBits(values []int64, precisionBits uint8) []int64 {
+	data, marshalType, firstValue := encoding.MarshalValues(nil, values, precisionBits)
+	valuesAdjusted, err := encoding.UnmarshalValues(nil, data, marshalType, firstValue, len(values))
+	if err != nil {
+		panic(fmt.Errorf("BUG: cannot unmarshal values with precisionBits %d: %s", precisionBits, err))
+	}
+	return valuesAdjusted
+}
+
 func getRandValues(rowsCount int) []int64 {
 	a := make([]int64, rowsCount)
 	for i := 0; i < rowsCount; i++ {