diff --git a/.cargo/config.toml b/.cargo/config.toml
index 215eeab770..f19bad4211 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -3,3 +3,12 @@ linker = "aarch64-linux-gnu-gcc"
[alias]
sqlness = "run --bin sqlness-runner --"
+
+[unstable.git]
+shallow_index = true
+shallow_deps = true
+[unstable.gitoxide]
+fetch = true
+checkout = true
+list_files = true
+internal_use_git2 = false
diff --git a/.github/actions/build-dev-builder-images/action.yml b/.github/actions/build-dev-builder-images/action.yml
index 9c30caad35..41f6919396 100644
--- a/.github/actions/build-dev-builder-images/action.yml
+++ b/.github/actions/build-dev-builder-images/action.yml
@@ -41,7 +41,14 @@ runs:
username: ${{ inputs.dockerhub-image-registry-username }}
password: ${{ inputs.dockerhub-image-registry-token }}
- - name: Build and push dev-builder-ubuntu image
+ - name: Set up qemu for multi-platform builds
+ uses: docker/setup-qemu-action@v3
+ with:
+ platforms: linux/amd64,linux/arm64
+ # The latest version will lead to segmentation fault.
+ image: tonistiigi/binfmt:qemu-v7.0.0-28
+
+ - name: Build and push dev-builder-ubuntu image # Build image for amd64 and arm64 platform.
shell: bash
if: ${{ inputs.build-dev-builder-ubuntu == 'true' }}
run: |
@@ -52,7 +59,7 @@ runs:
IMAGE_NAMESPACE=${{ inputs.dockerhub-image-namespace }} \
DEV_BUILDER_IMAGE_TAG=${{ inputs.version }}
- - name: Build and push dev-builder-centos image
+ - name: Build and push dev-builder-centos image # Only build image for amd64 platform.
shell: bash
if: ${{ inputs.build-dev-builder-centos == 'true' }}
run: |
@@ -69,8 +76,7 @@ runs:
run: |
make dev-builder \
BASE_IMAGE=android \
+ BUILDX_MULTI_PLATFORM_BUILD=amd64 \
IMAGE_REGISTRY=${{ inputs.dockerhub-image-registry }} \
IMAGE_NAMESPACE=${{ inputs.dockerhub-image-namespace }} \
- DEV_BUILDER_IMAGE_TAG=${{ inputs.version }} && \
-
- docker push ${{ inputs.dockerhub-image-registry }}/${{ inputs.dockerhub-image-namespace }}/dev-builder-android:${{ inputs.version }}
+ DEV_BUILDER_IMAGE_TAG=${{ inputs.version }}
diff --git a/.github/actions/build-greptime-images/action.yml b/.github/actions/build-greptime-images/action.yml
index ff565fc910..a84c690281 100644
--- a/.github/actions/build-greptime-images/action.yml
+++ b/.github/actions/build-greptime-images/action.yml
@@ -34,8 +34,8 @@ inputs:
required: true
push-latest-tag:
description: Whether to push the latest tag
- required: false
- default: 'true'
+ required: true
+ default: 'false'
runs:
using: composite
steps:
diff --git a/.github/actions/build-images/action.yml b/.github/actions/build-images/action.yml
index a315106cc3..5fd963b00b 100644
--- a/.github/actions/build-images/action.yml
+++ b/.github/actions/build-images/action.yml
@@ -22,8 +22,8 @@ inputs:
required: true
push-latest-tag:
description: Whether to push the latest tag
- required: false
- default: 'true'
+ required: true
+ default: 'false'
dev-mode:
description: Enable dev mode, only build standard greptime
required: false
diff --git a/.github/actions/release-cn-artifacts/action.yaml b/.github/actions/release-cn-artifacts/action.yaml
index 062c482f68..886f79bbaf 100644
--- a/.github/actions/release-cn-artifacts/action.yaml
+++ b/.github/actions/release-cn-artifacts/action.yaml
@@ -51,8 +51,8 @@ inputs:
required: true
upload-to-s3:
description: Upload to S3
- required: false
- default: 'true'
+ required: true
+ default: 'false'
artifacts-dir:
description: Directory to store artifacts
required: false
@@ -77,13 +77,21 @@ runs:
with:
path: ${{ inputs.artifacts-dir }}
+ - name: Install s5cmd
+ shell: bash
+ run: |
+ wget https://github.com/peak/s5cmd/releases/download/v2.3.0/s5cmd_2.3.0_Linux-64bit.tar.gz
+ tar -xzf s5cmd_2.3.0_Linux-64bit.tar.gz
+ sudo mv s5cmd /usr/local/bin/
+ sudo chmod +x /usr/local/bin/s5cmd
+
- name: Release artifacts to cn region
uses: nick-invision/retry@v2
if: ${{ inputs.upload-to-s3 == 'true' }}
env:
AWS_ACCESS_KEY_ID: ${{ inputs.aws-cn-access-key-id }}
AWS_SECRET_ACCESS_KEY: ${{ inputs.aws-cn-secret-access-key }}
- AWS_DEFAULT_REGION: ${{ inputs.aws-cn-region }}
+ AWS_REGION: ${{ inputs.aws-cn-region }}
UPDATE_VERSION_INFO: ${{ inputs.update-version-info }}
with:
max_attempts: ${{ inputs.upload-max-retry-times }}
diff --git a/.github/actions/start-runner/action.yml b/.github/actions/start-runner/action.yml
index 10d482b2bf..78568e26d7 100644
--- a/.github/actions/start-runner/action.yml
+++ b/.github/actions/start-runner/action.yml
@@ -56,7 +56,7 @@ runs:
- name: Start EC2 runner
if: startsWith(inputs.runner, 'ec2')
- uses: machulav/ec2-github-runner@v2
+ uses: machulav/ec2-github-runner@v2.3.8
id: start-linux-arm64-ec2-runner
with:
mode: start
diff --git a/.github/actions/stop-runner/action.yml b/.github/actions/stop-runner/action.yml
index 24a720b624..e25a1d8dad 100644
--- a/.github/actions/stop-runner/action.yml
+++ b/.github/actions/stop-runner/action.yml
@@ -33,7 +33,7 @@ runs:
- name: Stop EC2 runner
if: ${{ inputs.label && inputs.ec2-instance-id }}
- uses: machulav/ec2-github-runner@v2
+ uses: machulav/ec2-github-runner@v2.3.8
with:
mode: stop
label: ${{ inputs.label }}
diff --git a/.github/scripts/upload-artifacts-to-s3.sh b/.github/scripts/upload-artifacts-to-s3.sh
index 5168ba6c40..84038c200b 100755
--- a/.github/scripts/upload-artifacts-to-s3.sh
+++ b/.github/scripts/upload-artifacts-to-s3.sh
@@ -33,7 +33,7 @@ function upload_artifacts() {
# ├── greptime-darwin-amd64-v0.2.0.sha256sum
# └── greptime-darwin-amd64-v0.2.0.tar.gz
find "$ARTIFACTS_DIR" -type f \( -name "*.tar.gz" -o -name "*.sha256sum" \) | while IFS= read -r file; do
- aws s3 cp \
+ s5cmd cp \
"$file" "s3://$AWS_S3_BUCKET/$RELEASE_DIRS/$VERSION/$(basename "$file")"
done
}
@@ -45,7 +45,7 @@ function update_version_info() {
if [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Updating latest-version.txt"
echo "$VERSION" > latest-version.txt
- aws s3 cp \
+ s5cmd cp \
latest-version.txt "s3://$AWS_S3_BUCKET/$RELEASE_DIRS/latest-version.txt"
fi
@@ -53,7 +53,7 @@ function update_version_info() {
if [[ "$VERSION" == *"nightly"* ]]; then
echo "Updating latest-nightly-version.txt"
echo "$VERSION" > latest-nightly-version.txt
- aws s3 cp \
+ s5cmd cp \
latest-nightly-version.txt "s3://$AWS_S3_BUCKET/$RELEASE_DIRS/latest-nightly-version.txt"
fi
fi
diff --git a/.github/workflows/apidoc.yml b/.github/workflows/apidoc.yml
index 6bbca5d9a2..eb7a720a42 100644
--- a/.github/workflows/apidoc.yml
+++ b/.github/workflows/apidoc.yml
@@ -14,7 +14,7 @@ name: Build API docs
jobs:
apidoc:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
diff --git a/.github/workflows/dev-build.yml b/.github/workflows/dev-build.yml
index 25a91291be..f325018ffa 100644
--- a/.github/workflows/dev-build.yml
+++ b/.github/workflows/dev-build.yml
@@ -16,11 +16,11 @@ on:
description: The runner uses to build linux-amd64 artifacts
default: ec2-c6i.4xlarge-amd64
options:
- - ubuntu-20.04
- - ubuntu-20.04-8-cores
- - ubuntu-20.04-16-cores
- - ubuntu-20.04-32-cores
- - ubuntu-20.04-64-cores
+ - ubuntu-22.04
+ - ubuntu-22.04-8-cores
+ - ubuntu-22.04-16-cores
+ - ubuntu-22.04-32-cores
+ - ubuntu-22.04-64-cores
- ec2-c6i.xlarge-amd64 # 4C8G
- ec2-c6i.2xlarge-amd64 # 8C16G
- ec2-c6i.4xlarge-amd64 # 16C32G
@@ -83,7 +83,7 @@ jobs:
allocate-runners:
name: Allocate runners
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
outputs:
linux-amd64-runner: ${{ steps.start-linux-amd64-runner.outputs.label }}
linux-arm64-runner: ${{ steps.start-linux-arm64-runner.outputs.label }}
@@ -218,7 +218,7 @@ jobs:
build-linux-amd64-artifacts,
build-linux-arm64-artifacts,
]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
outputs:
build-result: ${{ steps.set-build-result.outputs.build-result }}
steps:
@@ -251,7 +251,7 @@ jobs:
allocate-runners,
release-images-to-dockerhub,
]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
@@ -274,6 +274,7 @@ jobs:
aws-cn-access-key-id: ${{ secrets.AWS_CN_ACCESS_KEY_ID }}
aws-cn-secret-access-key: ${{ secrets.AWS_CN_SECRET_ACCESS_KEY }}
aws-cn-region: ${{ vars.AWS_RELEASE_BUCKET_REGION }}
+ upload-to-s3: false
dev-mode: true # Only build the standard images(exclude centos images).
push-latest-tag: false # Don't push the latest tag to registry.
update-version-info: false # Don't update the version info in S3.
@@ -282,7 +283,7 @@ jobs:
name: Stop linux-amd64 runner
# Only run this job when the runner is allocated.
if: ${{ always() }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
needs: [
allocate-runners,
build-linux-amd64-artifacts,
@@ -308,7 +309,7 @@ jobs:
name: Stop linux-arm64 runner
# Only run this job when the runner is allocated.
if: ${{ always() }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
needs: [
allocate-runners,
build-linux-arm64-artifacts,
@@ -336,7 +337,7 @@ jobs:
needs: [
release-images-to-dockerhub
]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
permissions:
issues: write
diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml
index da241305ee..473ca83a03 100644
--- a/.github/workflows/develop.yml
+++ b/.github/workflows/develop.yml
@@ -23,7 +23,7 @@ concurrency:
jobs:
check-typos-and-docs:
name: Check typos and docs
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
@@ -36,7 +36,7 @@ jobs:
|| (echo "'config/config.md' is not up-to-date, please run 'make config-docs'." && exit 1)
license-header-check:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
name: Check License Header
steps:
- uses: actions/checkout@v4
@@ -49,7 +49,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [ ubuntu-20.04 ]
+ os: [ ubuntu-latest ]
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
@@ -72,7 +72,7 @@ jobs:
toml:
name: Toml Check
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
@@ -89,7 +89,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [ ubuntu-20.04 ]
+ os: [ ubuntu-latest ]
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
@@ -248,7 +248,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [ ubuntu-20.04 ]
+ os: [ ubuntu-latest ]
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
@@ -568,7 +568,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [ ubuntu-20.04 ]
+ os: [ ubuntu-latest ]
mode:
- name: "Basic"
opts: ""
@@ -607,7 +607,7 @@ jobs:
fmt:
name: Rustfmt
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
@@ -624,7 +624,7 @@ jobs:
clippy:
name: Clippy
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
@@ -711,7 +711,7 @@ jobs:
coverage:
if: github.event_name == 'merge_group'
- runs-on: ubuntu-20.04-8-cores
+ runs-on: ubuntu-22.04-8-cores
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
@@ -772,7 +772,7 @@ jobs:
# compat:
# name: Compatibility Test
# needs: build
- # runs-on: ubuntu-20.04
+ # runs-on: ubuntu-22.04
# timeout-minutes: 60
# steps:
# - uses: actions/checkout@v4
diff --git a/.github/workflows/docbot.yml b/.github/workflows/docbot.yml
index 887c8c5942..250a150c02 100644
--- a/.github/workflows/docbot.yml
+++ b/.github/workflows/docbot.yml
@@ -3,9 +3,13 @@ on:
pull_request_target:
types: [opened, edited]
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
jobs:
docbot:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 61f78a84fd..650ea64597 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -31,7 +31,7 @@ name: CI
jobs:
typos:
name: Spell Check with Typos
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
@@ -39,7 +39,7 @@ jobs:
- uses: crate-ci/typos@master
license-header-check:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
name: Check License Header
steps:
- uses: actions/checkout@v4
@@ -49,29 +49,29 @@ jobs:
check:
name: Check
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- run: 'echo "No action required"'
fmt:
name: Rustfmt
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- run: 'echo "No action required"'
clippy:
name: Clippy
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- run: 'echo "No action required"'
coverage:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- run: 'echo "No action required"'
test:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- run: 'echo "No action required"'
@@ -80,7 +80,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [ ubuntu-20.04 ]
+ os: [ ubuntu-latest ]
mode:
- name: "Basic"
- name: "Remote WAL"
diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml
index 4492741521..6640d1d3df 100644
--- a/.github/workflows/nightly-build.yml
+++ b/.github/workflows/nightly-build.yml
@@ -14,11 +14,11 @@ on:
description: The runner uses to build linux-amd64 artifacts
default: ec2-c6i.4xlarge-amd64
options:
- - ubuntu-20.04
- - ubuntu-20.04-8-cores
- - ubuntu-20.04-16-cores
- - ubuntu-20.04-32-cores
- - ubuntu-20.04-64-cores
+ - ubuntu-22.04
+ - ubuntu-22.04-8-cores
+ - ubuntu-22.04-16-cores
+ - ubuntu-22.04-32-cores
+ - ubuntu-22.04-64-cores
- ec2-c6i.xlarge-amd64 # 4C8G
- ec2-c6i.2xlarge-amd64 # 8C16G
- ec2-c6i.4xlarge-amd64 # 16C32G
@@ -70,7 +70,7 @@ jobs:
allocate-runners:
name: Allocate runners
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
outputs:
linux-amd64-runner: ${{ steps.start-linux-amd64-runner.outputs.label }}
linux-arm64-runner: ${{ steps.start-linux-arm64-runner.outputs.label }}
@@ -182,7 +182,7 @@ jobs:
build-linux-amd64-artifacts,
build-linux-arm64-artifacts,
]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
outputs:
nightly-build-result: ${{ steps.set-nightly-build-result.outputs.nightly-build-result }}
steps:
@@ -200,7 +200,7 @@ jobs:
image-registry-username: ${{ secrets.DOCKERHUB_USERNAME }}
image-registry-password: ${{ secrets.DOCKERHUB_TOKEN }}
version: ${{ needs.allocate-runners.outputs.version }}
- push-latest-tag: true
+ push-latest-tag: false
- name: Set nightly build result
id: set-nightly-build-result
@@ -214,7 +214,7 @@ jobs:
allocate-runners,
release-images-to-dockerhub,
]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
# When we push to ACR, it's easy to fail due to some unknown network issues.
# However, we don't want to fail the whole workflow because of this.
# The ACR have daily sync with DockerHub, so don't worry about the image not being updated.
@@ -240,15 +240,16 @@ jobs:
aws-cn-access-key-id: ${{ secrets.AWS_CN_ACCESS_KEY_ID }}
aws-cn-secret-access-key: ${{ secrets.AWS_CN_SECRET_ACCESS_KEY }}
aws-cn-region: ${{ vars.AWS_RELEASE_BUCKET_REGION }}
+ upload-to-s3: false
dev-mode: false
update-version-info: false # Don't update version info in S3.
- push-latest-tag: true
+ push-latest-tag: false
stop-linux-amd64-runner: # It's always run as the last job in the workflow to make sure that the runner is released.
name: Stop linux-amd64 runner
# Only run this job when the runner is allocated.
if: ${{ always() }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
needs: [
allocate-runners,
build-linux-amd64-artifacts,
@@ -274,7 +275,7 @@ jobs:
name: Stop linux-arm64 runner
# Only run this job when the runner is allocated.
if: ${{ always() }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
needs: [
allocate-runners,
build-linux-arm64-artifacts,
@@ -302,7 +303,7 @@ jobs:
needs: [
release-images-to-dockerhub
]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
permissions:
issues: write
env:
diff --git a/.github/workflows/nightly-ci.yml b/.github/workflows/nightly-ci.yml
index 041e1ef673..ed172effe9 100644
--- a/.github/workflows/nightly-ci.yml
+++ b/.github/workflows/nightly-ci.yml
@@ -13,7 +13,7 @@ jobs:
sqlness-test:
name: Run sqlness test
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -133,7 +133,7 @@ jobs:
name: Check status
needs: [sqlness-test, sqlness-windows, test-on-windows]
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
outputs:
check-result: ${{ steps.set-check-result.outputs.check-result }}
steps:
@@ -146,7 +146,7 @@ jobs:
if: ${{ github.repository == 'GreptimeTeam/greptimedb' && always() }} # Not requiring successful dependent jobs, always run.
name: Send notification to Greptime team
needs: [check-status]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_DEVELOP_CHANNEL }}
steps:
diff --git a/.github/workflows/release-dev-builder-images.yaml b/.github/workflows/release-dev-builder-images.yaml
index 2e60736140..1abb359ba7 100644
--- a/.github/workflows/release-dev-builder-images.yaml
+++ b/.github/workflows/release-dev-builder-images.yaml
@@ -29,7 +29,7 @@ jobs:
release-dev-builder-images:
name: Release dev builder images
if: ${{ inputs.release_dev_builder_ubuntu_image || inputs.release_dev_builder_centos_image || inputs.release_dev_builder_android_image }} # Only manually trigger this job.
- runs-on: ubuntu-20.04-16-cores
+ runs-on: ubuntu-latest
outputs:
version: ${{ steps.set-version.outputs.version }}
steps:
@@ -63,7 +63,7 @@ jobs:
release-dev-builder-images-ecr:
name: Release dev builder images to AWS ECR
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
needs: [
release-dev-builder-images
]
@@ -148,7 +148,7 @@ jobs:
release-dev-builder-images-cn: # Note: Be careful issue: https://github.com/containers/skopeo/issues/1874 and we decide to use the latest stable skopeo container.
name: Release dev builder images to CN region
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
needs: [
release-dev-builder-images
]
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index c18f692ea0..35f62e174a 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -18,11 +18,11 @@ on:
description: The runner uses to build linux-amd64 artifacts
default: ec2-c6i.4xlarge-amd64
options:
- - ubuntu-20.04
- - ubuntu-20.04-8-cores
- - ubuntu-20.04-16-cores
- - ubuntu-20.04-32-cores
- - ubuntu-20.04-64-cores
+ - ubuntu-22.04
+ - ubuntu-22.04-8-cores
+ - ubuntu-22.04-16-cores
+ - ubuntu-22.04-32-cores
+ - ubuntu-22.04-64-cores
- ec2-c6i.xlarge-amd64 # 4C8G
- ec2-c6i.2xlarge-amd64 # 8C16G
- ec2-c6i.4xlarge-amd64 # 16C32G
@@ -91,13 +91,13 @@ env:
# The scheduled version is '${{ env.NEXT_RELEASE_VERSION }}-nightly-YYYYMMDD', like v0.2.0-nigthly-20230313;
NIGHTLY_RELEASE_PREFIX: nightly
# Note: The NEXT_RELEASE_VERSION should be modified manually by every formal release.
- NEXT_RELEASE_VERSION: v0.12.0
+ NEXT_RELEASE_VERSION: v0.13.0
jobs:
allocate-runners:
name: Allocate runners
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
outputs:
linux-amd64-runner: ${{ steps.start-linux-amd64-runner.outputs.label }}
linux-arm64-runner: ${{ steps.start-linux-arm64-runner.outputs.label }}
@@ -299,7 +299,7 @@ jobs:
build-linux-amd64-artifacts,
build-linux-arm64-artifacts,
]
- runs-on: ubuntu-2004-16-cores
+ runs-on: ubuntu-latest
outputs:
build-image-result: ${{ steps.set-build-image-result.outputs.build-image-result }}
steps:
@@ -317,6 +317,7 @@ jobs:
image-registry-username: ${{ secrets.DOCKERHUB_USERNAME }}
image-registry-password: ${{ secrets.DOCKERHUB_TOKEN }}
version: ${{ needs.allocate-runners.outputs.version }}
+ push-latest-tag: true
- name: Set build image result
id: set-build-image-result
@@ -334,7 +335,7 @@ jobs:
build-windows-artifacts,
release-images-to-dockerhub,
]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
# When we push to ACR, it's easy to fail due to some unknown network issues.
# However, we don't want to fail the whole workflow because of this.
# The ACR have daily sync with DockerHub, so don't worry about the image not being updated.
@@ -361,6 +362,7 @@ jobs:
aws-cn-secret-access-key: ${{ secrets.AWS_CN_SECRET_ACCESS_KEY }}
aws-cn-region: ${{ vars.AWS_RELEASE_BUCKET_REGION }}
dev-mode: false
+ upload-to-s3: true
update-version-info: true
push-latest-tag: true
@@ -375,7 +377,7 @@ jobs:
build-windows-artifacts,
release-images-to-dockerhub,
]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
@@ -394,7 +396,7 @@ jobs:
name: Stop linux-amd64 runner
# Only run this job when the runner is allocated.
if: ${{ always() }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
needs: [
allocate-runners,
build-linux-amd64-artifacts,
@@ -420,7 +422,7 @@ jobs:
name: Stop linux-arm64 runner
# Only run this job when the runner is allocated.
if: ${{ always() }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
needs: [
allocate-runners,
build-linux-arm64-artifacts,
@@ -446,7 +448,7 @@ jobs:
name: Bump doc version
if: ${{ github.event_name == 'push' || github.event_name == 'schedule' }}
needs: [allocate-runners]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
# Permission reference: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
permissions:
issues: write # Allows the action to create issues for cyborg.
@@ -473,7 +475,7 @@ jobs:
build-macos-artifacts,
build-windows-artifacts,
]
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
# Permission reference: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
permissions:
issues: write # Allows the action to create issues for cyborg.
diff --git a/.github/workflows/semantic-pull-request.yml b/.github/workflows/semantic-pull-request.yml
index a8fd6d05f4..8805b1e8c3 100644
--- a/.github/workflows/semantic-pull-request.yml
+++ b/.github/workflows/semantic-pull-request.yml
@@ -7,9 +7,13 @@ on:
- reopened
- edited
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
jobs:
check:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
diff --git a/AUTHOR.md b/AUTHOR.md
index ff9165697b..bdf0d6b39a 100644
--- a/AUTHOR.md
+++ b/AUTHOR.md
@@ -3,30 +3,28 @@
## Individual Committers (in alphabetical order)
* [CookiePieWw](https://github.com/CookiePieWw)
-* [KKould](https://github.com/KKould)
-* [NiwakaDev](https://github.com/NiwakaDev)
* [etolbakov](https://github.com/etolbakov)
* [irenjj](https://github.com/irenjj)
-* [tisonkun](https://github.com/tisonkun)
+* [KKould](https://github.com/KKould)
* [Lanqing Yang](https://github.com/lyang24)
+* [NiwakaDev](https://github.com/NiwakaDev)
+* [tisonkun](https://github.com/tisonkun)
+
## Team Members (in alphabetical order)
-* [Breeze-P](https://github.com/Breeze-P)
-* [GrepTime](https://github.com/GrepTime)
-* [MichaelScofield](https://github.com/MichaelScofield)
-* [Wenjie0329](https://github.com/Wenjie0329)
-* [WenyXu](https://github.com/WenyXu)
-* [ZonaHex](https://github.com/ZonaHex)
* [apdong2022](https://github.com/apdong2022)
* [beryl678](https://github.com/beryl678)
+* [Breeze-P](https://github.com/Breeze-P)
* [daviderli614](https://github.com/daviderli614)
* [discord9](https://github.com/discord9)
* [evenyag](https://github.com/evenyag)
* [fengjiachun](https://github.com/fengjiachun)
* [fengys1996](https://github.com/fengys1996)
+* [GrepTime](https://github.com/GrepTime)
* [holalengyu](https://github.com/holalengyu)
* [killme2008](https://github.com/killme2008)
+* [MichaelScofield](https://github.com/MichaelScofield)
* [nicecui](https://github.com/nicecui)
* [paomian](https://github.com/paomian)
* [shuiyisong](https://github.com/shuiyisong)
@@ -34,11 +32,14 @@
* [sunng87](https://github.com/sunng87)
* [v0y4g3r](https://github.com/v0y4g3r)
* [waynexia](https://github.com/waynexia)
+* [Wenjie0329](https://github.com/Wenjie0329)
+* [WenyXu](https://github.com/WenyXu)
* [xtang](https://github.com/xtang)
* [zhaoyingnan01](https://github.com/zhaoyingnan01)
* [zhongzc](https://github.com/zhongzc)
+* [ZonaHex](https://github.com/ZonaHex)
* [zyy17](https://github.com/zyy17)
## All Contributors
-[](https://github.com/GreptimeTeam/greptimedb/graphs/contributors)
+To see the full list of contributors, please visit our [Contributors page](https://github.com/GreptimeTeam/greptimedb/graphs/contributors)
diff --git a/Cargo.lock b/Cargo.lock
index b5a415271e..45f0b600fe 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -185,7 +185,7 @@ checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c"
[[package]]
name = "api"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"common-base",
"common-decimal",
@@ -432,7 +432,7 @@ dependencies = [
"arrow-schema",
"chrono",
"half",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"lexical-core",
"num",
"serde",
@@ -710,7 +710,7 @@ dependencies = [
[[package]]
name = "auth"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"async-trait",
@@ -1324,7 +1324,7 @@ dependencies = [
[[package]]
name = "cache"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"catalog",
"common-error",
@@ -1348,7 +1348,7 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "catalog"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"arrow",
@@ -1475,7 +1475,7 @@ version = "0.13.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6026d8cd82ada8bbcfe337805dd1eb6afdc9e80fa4d57e977b3a36315e0c5525"
dependencies = [
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"lazy_static",
"num-traits",
"regex",
@@ -1661,7 +1661,7 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "cli"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-trait",
"auth",
@@ -1703,7 +1703,7 @@ dependencies = [
"session",
"snafu 0.8.5",
"store-api",
- "substrait 0.12.0",
+ "substrait 0.13.0",
"table",
"tempfile",
"tokio",
@@ -1712,7 +1712,7 @@ dependencies = [
[[package]]
name = "client"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"arc-swap",
@@ -1739,7 +1739,7 @@ dependencies = [
"rand",
"serde_json",
"snafu 0.8.5",
- "substrait 0.12.0",
+ "substrait 0.13.0",
"substrait 0.37.3",
"tokio",
"tokio-stream",
@@ -1780,7 +1780,7 @@ dependencies = [
[[package]]
name = "cmd"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-trait",
"auth",
@@ -1841,7 +1841,7 @@ dependencies = [
"similar-asserts",
"snafu 0.8.5",
"store-api",
- "substrait 0.12.0",
+ "substrait 0.13.0",
"table",
"temp-env",
"tempfile",
@@ -1887,7 +1887,7 @@ checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335"
[[package]]
name = "common-base"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"anymap2",
"async-trait",
@@ -1909,11 +1909,11 @@ dependencies = [
[[package]]
name = "common-catalog"
-version = "0.12.0"
+version = "0.13.0"
[[package]]
name = "common-config"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"common-base",
"common-error",
@@ -1938,7 +1938,7 @@ dependencies = [
[[package]]
name = "common-datasource"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"arrow",
"arrow-schema",
@@ -1974,7 +1974,7 @@ dependencies = [
[[package]]
name = "common-decimal"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"bigdecimal 0.4.5",
"common-error",
@@ -1987,7 +1987,7 @@ dependencies = [
[[package]]
name = "common-error"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"http 1.1.0",
"snafu 0.8.5",
@@ -1997,7 +1997,7 @@ dependencies = [
[[package]]
name = "common-frontend"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-trait",
"common-error",
@@ -2007,12 +2007,14 @@ dependencies = [
[[package]]
name = "common-function"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
+ "ahash 0.8.11",
"api",
"approx 0.5.1",
"arc-swap",
"async-trait",
+ "bincode",
"common-base",
"common-catalog",
"common-error",
@@ -2024,12 +2026,15 @@ dependencies = [
"common-time",
"common-version",
"datafusion",
+ "datafusion-common",
+ "datafusion-expr",
"datatypes",
"derive_more",
"geo",
"geo-types",
"geohash",
"h3o",
+ "hyperloglogplus",
"jsonb",
"nalgebra 0.33.2",
"num",
@@ -2046,12 +2051,13 @@ dependencies = [
"store-api",
"table",
"tokio",
+ "uddsketch",
"wkt",
]
[[package]]
name = "common-greptimedb-telemetry"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-trait",
"common-runtime",
@@ -2068,7 +2074,7 @@ dependencies = [
[[package]]
name = "common-grpc"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"arrow-flight",
@@ -2096,7 +2102,7 @@ dependencies = [
[[package]]
name = "common-grpc-expr"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"common-base",
@@ -2115,7 +2121,7 @@ dependencies = [
[[package]]
name = "common-macro"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"arc-swap",
"common-query",
@@ -2129,7 +2135,7 @@ dependencies = [
[[package]]
name = "common-mem-prof"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"common-error",
"common-macro",
@@ -2142,7 +2148,7 @@ dependencies = [
[[package]]
name = "common-meta"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"anymap2",
"api",
@@ -2203,7 +2209,7 @@ dependencies = [
[[package]]
name = "common-options"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"common-grpc",
"humantime-serde",
@@ -2212,11 +2218,11 @@ dependencies = [
[[package]]
name = "common-plugins"
-version = "0.12.0"
+version = "0.13.0"
[[package]]
name = "common-pprof"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"common-error",
"common-macro",
@@ -2228,7 +2234,7 @@ dependencies = [
[[package]]
name = "common-procedure"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-stream",
"async-trait",
@@ -2255,7 +2261,7 @@ dependencies = [
[[package]]
name = "common-procedure-test"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-trait",
"common-procedure",
@@ -2263,7 +2269,7 @@ dependencies = [
[[package]]
name = "common-query"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"async-trait",
@@ -2289,7 +2295,7 @@ dependencies = [
[[package]]
name = "common-recordbatch"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"arc-swap",
"common-error",
@@ -2308,7 +2314,7 @@ dependencies = [
[[package]]
name = "common-runtime"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-trait",
"clap 4.5.19",
@@ -2338,7 +2344,7 @@ dependencies = [
[[package]]
name = "common-telemetry"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"atty",
"backtrace",
@@ -2366,7 +2372,7 @@ dependencies = [
[[package]]
name = "common-test-util"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"client",
"common-query",
@@ -2378,7 +2384,7 @@ dependencies = [
[[package]]
name = "common-time"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"arrow",
"chrono",
@@ -2396,7 +2402,7 @@ dependencies = [
[[package]]
name = "common-version"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"build-data",
"const_format",
@@ -2406,7 +2412,7 @@ dependencies = [
[[package]]
name = "common-wal"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"common-base",
"common-error",
@@ -2973,7 +2979,7 @@ dependencies = [
"chrono",
"half",
"hashbrown 0.14.5",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"libc",
"object_store",
"parquet",
@@ -3033,7 +3039,7 @@ dependencies = [
"datafusion-functions-aggregate-common",
"datafusion-functions-window-common",
"datafusion-physical-expr-common",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"paste",
"recursive",
"serde_json",
@@ -3155,7 +3161,7 @@ dependencies = [
"datafusion-physical-expr-common",
"datafusion-physical-plan",
"half",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"log",
"parking_lot 0.12.3",
"paste",
@@ -3206,7 +3212,7 @@ dependencies = [
"datafusion-common",
"datafusion-expr",
"datafusion-physical-expr",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"itertools 0.13.0",
"log",
"recursive",
@@ -3231,7 +3237,7 @@ dependencies = [
"datafusion-physical-expr-common",
"half",
"hashbrown 0.14.5",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"itertools 0.13.0",
"log",
"paste",
@@ -3290,7 +3296,7 @@ dependencies = [
"futures",
"half",
"hashbrown 0.14.5",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"itertools 0.13.0",
"log",
"once_cell",
@@ -3310,7 +3316,7 @@ dependencies = [
"arrow-schema",
"datafusion-common",
"datafusion-expr",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"log",
"recursive",
"regex",
@@ -3337,7 +3343,7 @@ dependencies = [
[[package]]
name = "datanode"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"arrow-flight",
@@ -3377,6 +3383,7 @@ dependencies = [
"meta-client",
"metric-engine",
"mito2",
+ "num_cpus",
"object-store",
"prometheus",
"prost 0.13.3",
@@ -3388,7 +3395,7 @@ dependencies = [
"session",
"snafu 0.8.5",
"store-api",
- "substrait 0.12.0",
+ "substrait 0.13.0",
"table",
"tokio",
"toml 0.8.19",
@@ -3397,7 +3404,7 @@ dependencies = [
[[package]]
name = "datatypes"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"arrow",
"arrow-array",
@@ -4041,7 +4048,7 @@ dependencies = [
[[package]]
name = "file-engine"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"async-trait",
@@ -4151,7 +4158,7 @@ checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8"
[[package]]
name = "flow"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"arrow",
@@ -4197,6 +4204,7 @@ dependencies = [
"meta-client",
"nom",
"num-traits",
+ "num_cpus",
"operator",
"partition",
"pretty_assertions",
@@ -4211,7 +4219,7 @@ dependencies = [
"snafu 0.8.5",
"store-api",
"strum 0.25.0",
- "substrait 0.12.0",
+ "substrait 0.13.0",
"table",
"tokio",
"tonic 0.12.3",
@@ -4266,7 +4274,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa"
[[package]]
name = "frontend"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"arc-swap",
@@ -4303,6 +4311,7 @@ dependencies = [
"log-query",
"log-store",
"meta-client",
+ "num_cpus",
"opentelemetry-proto 0.27.0",
"operator",
"partition",
@@ -4693,7 +4702,7 @@ dependencies = [
[[package]]
name = "greptime-proto"
version = "0.1.0"
-source = "git+https://github.com/GreptimeTeam/greptime-proto.git?rev=683e9d10ae7f3dfb8aaabd89082fc600c17e3795#683e9d10ae7f3dfb8aaabd89082fc600c17e3795"
+source = "git+https://github.com/GreptimeTeam/greptime-proto.git?rev=d92c9ac4e90ef4abdcf5c2eaf5a164e18ba09486#d92c9ac4e90ef4abdcf5c2eaf5a164e18ba09486"
dependencies = [
"prost 0.13.3",
"serde",
@@ -4716,7 +4725,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http 0.2.12",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"slab",
"tokio",
"tokio-util",
@@ -4735,7 +4744,7 @@ dependencies = [
"futures-core",
"futures-sink",
"http 1.1.0",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"slab",
"tokio",
"tokio-util",
@@ -5285,6 +5294,15 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "hyperloglogplus"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "621debdf94dcac33e50475fdd76d34d5ea9c0362a834b9db08c3024696c1fbe3"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "i_float"
version = "1.3.1"
@@ -5524,7 +5542,7 @@ dependencies = [
[[package]]
name = "index"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-trait",
"asynchronous-codec",
@@ -5573,9 +5591,9 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "2.6.0"
+version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
+checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
dependencies = [
"equivalent",
"hashbrown 0.15.2",
@@ -5589,7 +5607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "232929e1d75fe899576a3d5c7416ad0d88dbfbb3c3d6aa00873a7408a50ddb88"
dependencies = [
"ahash 0.8.11",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"is-terminal",
"itoa",
"log",
@@ -5936,7 +5954,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee7893dab2e44ae5f9d0173f26ff4aa327c10b01b06a72b52dd9405b628640d"
dependencies = [
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
]
[[package]]
@@ -6316,7 +6334,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "log-query"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"chrono",
"common-error",
@@ -6328,7 +6346,7 @@ dependencies = [
[[package]]
name = "log-store"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-stream",
"async-trait",
@@ -6419,7 +6437,7 @@ dependencies = [
"cactus",
"cfgrammar",
"filetime",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"lazy_static",
"lrtable",
"num-traits",
@@ -6621,7 +6639,7 @@ dependencies = [
[[package]]
name = "meta-client"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"async-trait",
@@ -6648,7 +6666,7 @@ dependencies = [
[[package]]
name = "meta-srv"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"async-trait",
@@ -6734,7 +6752,7 @@ dependencies = [
[[package]]
name = "metric-engine"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"aquamarine",
@@ -6832,7 +6850,7 @@ dependencies = [
[[package]]
name = "mito2"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"aquamarine",
@@ -7529,7 +7547,7 @@ dependencies = [
[[package]]
name = "object-store"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"anyhow",
"bytes",
@@ -7660,7 +7678,7 @@ checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a"
dependencies = [
"futures-core",
"futures-sink",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"js-sys",
"once_cell",
"pin-project-lite",
@@ -7778,7 +7796,7 @@ dependencies = [
[[package]]
name = "operator"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"ahash 0.8.11",
"api",
@@ -7826,7 +7844,7 @@ dependencies = [
"sql",
"sqlparser 0.52.0 (git+https://github.com/GreptimeTeam/sqlparser-rs.git?rev=71dd86058d2af97b9925093d40c4e03360403170)",
"store-api",
- "substrait 0.12.0",
+ "substrait 0.13.0",
"table",
"tokio",
"tokio-util",
@@ -8063,7 +8081,7 @@ dependencies = [
[[package]]
name = "partition"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"async-trait",
@@ -8232,7 +8250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
dependencies = [
"fixedbitset",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
]
[[package]]
@@ -8331,7 +8349,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pipeline"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"ahash 0.8.11",
"api",
@@ -8471,7 +8489,7 @@ dependencies = [
[[package]]
name = "plugins"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"auth",
"clap 4.5.19",
@@ -8733,7 +8751,7 @@ dependencies = [
[[package]]
name = "promql"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"ahash 0.8.11",
"async-trait",
@@ -8757,8 +8775,7 @@ dependencies = [
[[package]]
name = "promql-parser"
version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fe99e6f80a79abccf1e8fb48dd63473a36057e600cc6ea36147c8318698ae6f"
+source = "git+https://github.com/GreptimeTeam/promql-parser.git?rev=27abb8e16003a50c720f00d6c85f41f5fa2a2a8e#27abb8e16003a50c720f00d6c85f41f5fa2a2a8e"
dependencies = [
"cfgrammar",
"chrono",
@@ -8979,7 +8996,7 @@ dependencies = [
[[package]]
name = "puffin"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-compression 0.4.13",
"async-trait",
@@ -9020,7 +9037,7 @@ dependencies = [
[[package]]
name = "query"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"ahash 0.8.11",
"api",
@@ -9085,7 +9102,7 @@ dependencies = [
"sqlparser 0.52.0 (git+https://github.com/GreptimeTeam/sqlparser-rs.git?rev=71dd86058d2af97b9925093d40c4e03360403170)",
"statrs",
"store-api",
- "substrait 0.12.0",
+ "substrait 0.13.0",
"table",
"tokio",
"tokio-stream",
@@ -10324,7 +10341,7 @@ version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b"
dependencies = [
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"itoa",
"memchr",
"ryu",
@@ -10395,7 +10412,7 @@ dependencies = [
"chrono",
"hex",
"indexmap 1.9.3",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"serde",
"serde_derive",
"serde_json",
@@ -10421,7 +10438,7 @@ version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"itoa",
"ryu",
"serde",
@@ -10430,7 +10447,7 @@ dependencies = [
[[package]]
name = "servers"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"ahash 0.8.11",
"api",
@@ -10482,6 +10499,7 @@ dependencies = [
"humantime",
"humantime-serde",
"hyper 1.4.1",
+ "indexmap 2.7.1",
"influxdb_line_protocol",
"itertools 0.10.5",
"json5",
@@ -10546,7 +10564,7 @@ dependencies = [
[[package]]
name = "session"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"arc-swap",
@@ -10855,7 +10873,7 @@ dependencies = [
[[package]]
name = "sql"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"chrono",
@@ -10892,12 +10910,12 @@ dependencies = [
[[package]]
name = "sqlness"
version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "308a7338f2211813d6e9da117e9b9b7aee5d072872d11a934002fd2bd4ab5276"
+source = "git+https://github.com/CeresDB/sqlness.git?rev=bb91f31ff58993e07ea89845791235138283a24c#bb91f31ff58993e07ea89845791235138283a24c"
dependencies = [
"async-trait",
"derive_builder 0.11.2",
"duration-str",
+ "futures",
"minijinja",
"prettydiff",
"regex",
@@ -10909,7 +10927,7 @@ dependencies = [
[[package]]
name = "sqlness-runner"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-trait",
"clap 4.5.19",
@@ -10923,6 +10941,7 @@ dependencies = [
"hex",
"local-ip-address",
"mysql",
+ "num_cpus",
"reqwest",
"serde",
"serde_json",
@@ -11022,7 +11041,7 @@ dependencies = [
"futures-util",
"hashbrown 0.15.2",
"hashlink",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"log",
"memchr",
"once_cell",
@@ -11225,7 +11244,7 @@ dependencies = [
[[package]]
name = "store-api"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"aquamarine",
@@ -11355,7 +11374,7 @@ dependencies = [
[[package]]
name = "substrait"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"async-trait",
"bytes",
@@ -11536,7 +11555,7 @@ dependencies = [
[[package]]
name = "table"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"async-trait",
@@ -11787,7 +11806,7 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
[[package]]
name = "tests-fuzz"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"arbitrary",
"async-trait",
@@ -11831,7 +11850,7 @@ dependencies = [
[[package]]
name = "tests-integration"
-version = "0.12.0"
+version = "0.13.0"
dependencies = [
"api",
"arrow-flight",
@@ -11897,7 +11916,7 @@ dependencies = [
"sql",
"sqlx",
"store-api",
- "substrait 0.12.0",
+ "substrait 0.13.0",
"table",
"tempfile",
"time",
@@ -12318,7 +12337,7 @@ version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"toml_datetime",
"winnow 0.5.40",
]
@@ -12329,7 +12348,7 @@ version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"serde",
"serde_spanned",
"toml_datetime",
@@ -12467,7 +12486,7 @@ dependencies = [
"futures-core",
"futures-util",
"hdrhistogram",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"pin-project-lite",
"slab",
"sync_wrapper 1.0.1",
@@ -12955,6 +12974,14 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
+[[package]]
+name = "uddsketch"
+version = "0.1.0"
+source = "git+https://github.com/GreptimeTeam/timescaledb-toolkit.git?rev=84828fe8fb494a6a61412a3da96517fc80f7bb20#84828fe8fb494a6a61412a3da96517fc80f7bb20"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "unescaper"
version = "0.1.5"
diff --git a/Cargo.toml b/Cargo.toml
index 552cfd8297..3a208b18c2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -67,7 +67,7 @@ members = [
resolver = "2"
[workspace.package]
-version = "0.12.0"
+version = "0.13.0"
edition = "2021"
license = "Apache-2.0"
@@ -129,7 +129,7 @@ etcd-client = "0.14"
fst = "0.4.7"
futures = "0.3"
futures-util = "0.3"
-greptime-proto = { git = "https://github.com/GreptimeTeam/greptime-proto.git", rev = "683e9d10ae7f3dfb8aaabd89082fc600c17e3795" }
+greptime-proto = { git = "https://github.com/GreptimeTeam/greptime-proto.git", rev = "d92c9ac4e90ef4abdcf5c2eaf5a164e18ba09486" }
hex = "0.4"
http = "1"
humantime = "2.1"
@@ -160,7 +160,9 @@ parquet = { version = "53.0.0", default-features = false, features = ["arrow", "
paste = "1.0"
pin-project = "1.0"
prometheus = { version = "0.13.3", features = ["process"] }
-promql-parser = { version = "0.4.3", features = ["ser"] }
+promql-parser = { git = "https://github.com/GreptimeTeam/promql-parser.git", features = [
+ "ser",
+], rev = "27abb8e16003a50c720f00d6c85f41f5fa2a2a8e" }
prost = "0.13"
raft-engine = { version = "0.4.1", default-features = false }
rand = "0.8"
diff --git a/Makefile b/Makefile
index 98fd3db1be..81537ae976 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ CARGO_BUILD_OPTS := --locked
IMAGE_REGISTRY ?= docker.io
IMAGE_NAMESPACE ?= greptime
IMAGE_TAG ?= latest
-DEV_BUILDER_IMAGE_TAG ?= 2024-12-25-9d0fa5d5-20250124085746
+DEV_BUILDER_IMAGE_TAG ?= 2024-12-25-a71b93dd-20250305072908
BUILDX_MULTI_PLATFORM_BUILD ?= false
BUILDX_BUILDER_NAME ?= gtbuilder
BASE_IMAGE ?= ubuntu
@@ -60,6 +60,8 @@ ifeq ($(BUILDX_MULTI_PLATFORM_BUILD), all)
BUILDX_MULTI_PLATFORM_BUILD_OPTS := --platform linux/amd64,linux/arm64 --push
else ifeq ($(BUILDX_MULTI_PLATFORM_BUILD), amd64)
BUILDX_MULTI_PLATFORM_BUILD_OPTS := --platform linux/amd64 --push
+else ifeq ($(BUILDX_MULTI_PLATFORM_BUILD), arm64)
+ BUILDX_MULTI_PLATFORM_BUILD_OPTS := --platform linux/arm64 --push
else
BUILDX_MULTI_PLATFORM_BUILD_OPTS := -o type=docker
endif
diff --git a/config/config.md b/config/config.md
index 1831a2f644..107da0b35b 100644
--- a/config/config.md
+++ b/config/config.md
@@ -152,6 +152,7 @@
| `region_engine.mito.index` | -- | -- | The options for index in Mito engine. |
| `region_engine.mito.index.aux_path` | String | `""` | Auxiliary directory path for the index in filesystem, used to store intermediate files for creating the index and staging files for searching the index, defaults to `{data_home}/index_intermediate`. The default name for this directory is `index_intermediate` for backward compatibility. This path contains two subdirectories: - `__intm`: for storing intermediate files used during creating index. - `staging`: for storing staging files used during searching index. |
| `region_engine.mito.index.staging_size` | String | `2GB` | The max capacity of the staging directory. |
+| `region_engine.mito.index.staging_ttl` | String | `7d` | The TTL of the staging directory. Defaults to 7 days. Setting it to "0s" to disable TTL. |
| `region_engine.mito.index.metadata_cache_size` | String | `64MiB` | Cache size for inverted index metadata. |
| `region_engine.mito.index.content_cache_size` | String | `128MiB` | Cache size for inverted index content. |
| `region_engine.mito.index.content_cache_page_size` | String | `64KiB` | Page size for inverted index content cache. |
@@ -318,6 +319,7 @@
| `selector` | String | `round_robin` | Datanode selector type. - `round_robin` (default value) - `lease_based` - `load_based` For details, please see "https://docs.greptime.com/developer-guide/metasrv/selector". |
| `use_memory_store` | Bool | `false` | Store data in memory. |
| `enable_region_failover` | Bool | `false` | Whether to enable region failover. This feature is only available on GreptimeDB running on cluster mode and - Using Remote WAL - Using shared storage (e.g., s3). |
+| `node_max_idle_time` | String | `24hours` | Max allowed idle time before removing node info from metasrv memory. |
| `enable_telemetry` | Bool | `true` | Whether to enable greptimedb telemetry. Enabled by default. |
| `runtime` | -- | -- | The runtime options. |
| `runtime.global_rt_size` | Integer | `8` | The number of threads to execute the runtime for global read operations. |
@@ -491,6 +493,7 @@
| `region_engine.mito.index` | -- | -- | The options for index in Mito engine. |
| `region_engine.mito.index.aux_path` | String | `""` | Auxiliary directory path for the index in filesystem, used to store intermediate files for creating the index and staging files for searching the index, defaults to `{data_home}/index_intermediate`. The default name for this directory is `index_intermediate` for backward compatibility. This path contains two subdirectories: - `__intm`: for storing intermediate files used during creating index. - `staging`: for storing staging files used during searching index. |
| `region_engine.mito.index.staging_size` | String | `2GB` | The max capacity of the staging directory. |
+| `region_engine.mito.index.staging_ttl` | String | `7d` | The TTL of the staging directory. Defaults to 7 days. Setting it to "0s" to disable TTL. |
| `region_engine.mito.index.metadata_cache_size` | String | `64MiB` | Cache size for inverted index metadata. |
| `region_engine.mito.index.content_cache_size` | String | `128MiB` | Cache size for inverted index content. |
| `region_engine.mito.index.content_cache_page_size` | String | `64KiB` | Page size for inverted index content cache. |
diff --git a/config/datanode.example.toml b/config/datanode.example.toml
index a4acd1aa89..52eaea9190 100644
--- a/config/datanode.example.toml
+++ b/config/datanode.example.toml
@@ -497,6 +497,11 @@ aux_path = ""
## The max capacity of the staging directory.
staging_size = "2GB"
+## The TTL of the staging directory.
+## Defaults to 7 days.
+## Setting it to "0s" to disable TTL.
+staging_ttl = "7d"
+
## Cache size for inverted index metadata.
metadata_cache_size = "64MiB"
diff --git a/config/metasrv.example.toml b/config/metasrv.example.toml
index 18b203f204..842ac21530 100644
--- a/config/metasrv.example.toml
+++ b/config/metasrv.example.toml
@@ -50,6 +50,9 @@ use_memory_store = false
## - Using shared storage (e.g., s3).
enable_region_failover = false
+## Max allowed idle time before removing node info from metasrv memory.
+node_max_idle_time = "24hours"
+
## Whether to enable greptimedb telemetry. Enabled by default.
#+ enable_telemetry = true
diff --git a/config/standalone.example.toml b/config/standalone.example.toml
index bea6984a65..c42966e410 100644
--- a/config/standalone.example.toml
+++ b/config/standalone.example.toml
@@ -584,6 +584,11 @@ aux_path = ""
## The max capacity of the staging directory.
staging_size = "2GB"
+## The TTL of the staging directory.
+## Defaults to 7 days.
+## Setting it to "0s" to disable TTL.
+staging_ttl = "7d"
+
## Cache size for inverted index metadata.
metadata_cache_size = "64MiB"
diff --git a/docker/buildx/ubuntu/Dockerfile b/docker/buildx/ubuntu/Dockerfile
index 181ebd68bf..86bf9e2669 100644
--- a/docker/buildx/ubuntu/Dockerfile
+++ b/docker/buildx/ubuntu/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:20.04 as builder
+FROM ubuntu:22.04 as builder
ARG CARGO_PROFILE
ARG FEATURES
diff --git a/docker/ci/ubuntu/Dockerfile.fuzztests b/docker/ci/ubuntu/Dockerfile.fuzztests
index 247010f5ef..db49e11e03 100644
--- a/docker/ci/ubuntu/Dockerfile.fuzztests
+++ b/docker/ci/ubuntu/Dockerfile.fuzztests
@@ -1,4 +1,4 @@
-FROM ubuntu:22.04
+FROM ubuntu:latest
# The binary name of GreptimeDB executable.
# Defaults to "greptime", but sometimes in other projects it might be different.
diff --git a/docker/dev-builder/ubuntu/Dockerfile b/docker/dev-builder/ubuntu/Dockerfile
index d78046698c..198797b532 100644
--- a/docker/dev-builder/ubuntu/Dockerfile
+++ b/docker/dev-builder/ubuntu/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:20.04
+FROM ubuntu:22.04
# The root path under which contains all the dependencies to build this Dockerfile.
ARG DOCKER_BUILD_ROOT=.
@@ -41,7 +41,7 @@ RUN mv protoc3/include/* /usr/local/include/
# and the repositories are pulled from trusted sources (still us, of course). Doing so does not violate the intention
# of the Git's addition to the "safe.directory" at the first place (see the commit message here:
# https://github.com/git/git/commit/8959555cee7ec045958f9b6dd62e541affb7e7d9).
-# There's also another solution to this, that we add the desired submodules to the safe directory, instead of using
+# There's also another solution to this, that we add the desired submodules to the safe directory, instead of using
# wildcard here. However, that requires the git's config files and the submodules all owned by the very same user.
# It's troublesome to do this since the dev build runs in Docker, which is under user "root"; while outside the Docker,
# it can be a different user that have prepared the submodules.
diff --git a/docker/dev-builder/ubuntu/Dockerfile-18.10 b/docker/dev-builder/ubuntu/Dockerfile-18.10
deleted file mode 100644
index 07a8cb1103..0000000000
--- a/docker/dev-builder/ubuntu/Dockerfile-18.10
+++ /dev/null
@@ -1,51 +0,0 @@
-# Use the legacy glibc 2.28.
-FROM ubuntu:18.10
-
-ENV LANG en_US.utf8
-WORKDIR /greptimedb
-
-# Use old-releases.ubuntu.com to avoid 404s: https://help.ubuntu.com/community/EOLUpgrades.
-RUN echo "deb http://old-releases.ubuntu.com/ubuntu/ cosmic main restricted universe multiverse\n\
-deb http://old-releases.ubuntu.com/ubuntu/ cosmic-updates main restricted universe multiverse\n\
-deb http://old-releases.ubuntu.com/ubuntu/ cosmic-security main restricted universe multiverse" > /etc/apt/sources.list
-
-# Install dependencies.
-RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
- libssl-dev \
- tzdata \
- curl \
- ca-certificates \
- git \
- build-essential \
- unzip \
- pkg-config
-
-# Install protoc.
-ENV PROTOC_VERSION=29.3
-RUN if [ "$(uname -m)" = "x86_64" ]; then \
- PROTOC_ZIP=protoc-${PROTOC_VERSION}-linux-x86_64.zip; \
- elif [ "$(uname -m)" = "aarch64" ]; then \
- PROTOC_ZIP=protoc-${PROTOC_VERSION}-linux-aarch_64.zip; \
- else \
- echo "Unsupported architecture"; exit 1; \
- fi && \
- curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/${PROTOC_ZIP} && \
- unzip -o ${PROTOC_ZIP} -d /usr/local bin/protoc && \
- unzip -o ${PROTOC_ZIP} -d /usr/local 'include/*' && \
- rm -f ${PROTOC_ZIP}
-
-# Install Rust.
-SHELL ["/bin/bash", "-c"]
-RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --no-modify-path --default-toolchain none -y
-ENV PATH /root/.cargo/bin/:$PATH
-
-# Install Rust toolchains.
-ARG RUST_TOOLCHAIN
-RUN rustup toolchain install ${RUST_TOOLCHAIN}
-
-# Install cargo-binstall with a specific version to adapt the current rust toolchain.
-# Note: if we use the latest version, we may encounter the following `use of unstable library feature 'io_error_downcast'` error.
-RUN cargo install cargo-binstall --version 1.6.6 --locked
-
-# Install nextest.
-RUN cargo binstall cargo-nextest --no-confirm
diff --git a/docker/dev-builder/ubuntu/Dockerfile-20.04 b/docker/dev-builder/ubuntu/Dockerfile-20.04
new file mode 100644
index 0000000000..d78046698c
--- /dev/null
+++ b/docker/dev-builder/ubuntu/Dockerfile-20.04
@@ -0,0 +1,66 @@
+FROM ubuntu:20.04
+
+# The root path under which contains all the dependencies to build this Dockerfile.
+ARG DOCKER_BUILD_ROOT=.
+
+ENV LANG en_US.utf8
+WORKDIR /greptimedb
+
+RUN apt-get update && \
+ DEBIAN_FRONTEND=noninteractive apt-get install -y software-properties-common
+# Install dependencies.
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
+ libssl-dev \
+ tzdata \
+ curl \
+ unzip \
+ ca-certificates \
+ git \
+ build-essential \
+ pkg-config
+
+ARG TARGETPLATFORM
+RUN echo "target platform: $TARGETPLATFORM"
+
+ARG PROTOBUF_VERSION=29.3
+
+# Install protobuf, because the one in the apt is too old (v3.12).
+RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
+ curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-aarch_64.zip && \
+ unzip protoc-${PROTOBUF_VERSION}-linux-aarch_64.zip -d protoc3; \
+elif [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
+ curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip && \
+ unzip protoc-${PROTOBUF_VERSION}-linux-x86_64.zip -d protoc3; \
+fi
+RUN mv protoc3/bin/* /usr/local/bin/
+RUN mv protoc3/include/* /usr/local/include/
+
+# Silence all `safe.directory` warnings, to avoid the "detect dubious repository" error when building with submodules.
+# Disabling the safe directory check here won't pose extra security issues, because in our usage for this dev build
+# image, we use it solely on our own environment (that github action's VM, or ECS created dynamically by ourselves),
+# and the repositories are pulled from trusted sources (still us, of course). Doing so does not violate the intention
+# of the Git's addition to the "safe.directory" at the first place (see the commit message here:
+# https://github.com/git/git/commit/8959555cee7ec045958f9b6dd62e541affb7e7d9).
+# There's also another solution to this, that we add the desired submodules to the safe directory, instead of using
+# wildcard here. However, that requires the git's config files and the submodules all owned by the very same user.
+# It's troublesome to do this since the dev build runs in Docker, which is under user "root"; while outside the Docker,
+# it can be a different user that have prepared the submodules.
+RUN git config --global --add safe.directory '*'
+
+# Install Rust.
+SHELL ["/bin/bash", "-c"]
+RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --no-modify-path --default-toolchain none -y
+ENV PATH /root/.cargo/bin/:$PATH
+
+# Install Rust toolchains.
+ARG RUST_TOOLCHAIN
+RUN rustup toolchain install ${RUST_TOOLCHAIN}
+
+# Install cargo-binstall with a specific version to adapt the current rust toolchain.
+# Note: if we use the latest version, we may encounter the following `use of unstable library feature 'io_error_downcast'` error.
+# compile from source take too long, so we use the precompiled binary instead
+COPY $DOCKER_BUILD_ROOT/docker/dev-builder/binstall/pull_binstall.sh /usr/local/bin/pull_binstall.sh
+RUN chmod +x /usr/local/bin/pull_binstall.sh && /usr/local/bin/pull_binstall.sh
+
+# Install nextest.
+RUN cargo binstall cargo-nextest --no-confirm
diff --git a/docs/benchmarks/tsbs/v0.12.0.md b/docs/benchmarks/tsbs/v0.12.0.md
new file mode 100644
index 0000000000..7eae2ede75
--- /dev/null
+++ b/docs/benchmarks/tsbs/v0.12.0.md
@@ -0,0 +1,40 @@
+# TSBS benchmark - v0.12.0
+
+## Environment
+
+### Amazon EC2
+
+| | |
+|---------|-------------------------|
+| Machine | c5d.2xlarge |
+| CPU | 8 core |
+| Memory | 16GB |
+| Disk | 100GB (GP3) |
+| OS | Ubuntu Server 24.04 LTS |
+
+## Write performance
+
+| Environment | Ingest rate (rows/s) |
+|-----------------|----------------------|
+| EC2 c5d.2xlarge | 326839.28 |
+
+## Query performance
+
+| Query type | EC2 c5d.2xlarge (ms) |
+|-----------------------|----------------------|
+| cpu-max-all-1 | 12.46 |
+| cpu-max-all-8 | 24.20 |
+| double-groupby-1 | 673.08 |
+| double-groupby-5 | 963.99 |
+| double-groupby-all | 1330.05 |
+| groupby-orderby-limit | 952.46 |
+| high-cpu-1 | 5.08 |
+| high-cpu-all | 4638.57 |
+| lastpoint | 591.02 |
+| single-groupby-1-1-1 | 4.06 |
+| single-groupby-1-1-12 | 4.73 |
+| single-groupby-1-8-1 | 8.23 |
+| single-groupby-5-1-1 | 4.61 |
+| single-groupby-5-1-12 | 5.61 |
+| single-groupby-5-8-1 | 9.74 |
+
diff --git a/grafana/greptimedb-cluster.json b/grafana/greptimedb-cluster.json
index a9d3dc8210..01dd8528dd 100644
--- a/grafana/greptimedb-cluster.json
+++ b/grafana/greptimedb-cluster.json
@@ -76,7 +76,7 @@
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 1,
- "id": null,
+ "id": 522,
"links": [],
"liveNow": false,
"panels": [
@@ -144,7 +144,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -231,7 +231,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -318,7 +318,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -405,7 +405,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -492,7 +492,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -575,7 +575,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -658,7 +658,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -742,7 +742,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"datasource": {
@@ -809,7 +809,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"datasource": {
@@ -876,7 +876,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"datasource": {
@@ -943,7 +943,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"datasource": {
@@ -1009,7 +1009,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -1092,7 +1092,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -1178,7 +1178,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -1260,7 +1260,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -1342,7 +1342,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -1424,7 +1424,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"dataset": "information_schema",
@@ -1510,7 +1510,7 @@
"textMode": "auto",
"wideLayout": true
},
- "pluginVersion": "10.2.3",
+ "pluginVersion": "11.2.4",
"targets": [
{
"datasource": {
@@ -1546,6 +1546,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -1603,8 +1604,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1668,6 +1669,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -1725,8 +1727,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1816,6 +1818,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -1878,8 +1881,8 @@
"sortDesc": false
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1942,6 +1945,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -2004,8 +2008,8 @@
"sortDesc": false
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2068,6 +2072,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -2130,8 +2135,8 @@
"sortDesc": false
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2194,6 +2199,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -2256,8 +2262,8 @@
"sortDesc": false
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2321,6 +2327,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -2381,8 +2388,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2420,6 +2427,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -2480,8 +2488,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2519,6 +2527,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -2579,8 +2588,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2602,6 +2611,7 @@
},
{
"datasource": {
+ "default": false,
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
@@ -2618,6 +2628,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -2678,8 +2689,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2717,6 +2728,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -2779,8 +2791,8 @@
"sortDesc": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2818,6 +2830,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -2880,8 +2893,8 @@
"sortDesc": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2919,6 +2932,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -2981,8 +2995,8 @@
"sortDesc": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3020,6 +3034,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -3082,8 +3097,8 @@
"sortDesc": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3121,6 +3136,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -3183,8 +3199,8 @@
"sortDesc": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3222,6 +3238,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -3284,8 +3301,8 @@
"sortDesc": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3323,6 +3340,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -3385,8 +3403,8 @@
"sortDesc": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3424,6 +3442,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -3486,8 +3505,8 @@
"sortDesc": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3508,7 +3527,7 @@
"type": "timeseries"
},
{
- "collapsed": true,
+ "collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
@@ -3516,2335 +3535,788 @@
"y": 64
},
"id": 192,
- "panels": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "ops"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 25
- },
- "id": 202,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "sum by(pod, path, method, code) (rate(greptime_servers_http_requests_elapsed_count{pod=~\"$frontend\",path!~\"/health|/metrics\"}[$__rate_interval]))",
- "instant": false,
- "legendFormat": "[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-qps",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "HTTP QPS per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "points",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "s"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 25
- },
- "id": 203,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "histogram_quantile(0.99, sum by(pod, le, path, method, code) (rate(greptime_servers_http_requests_elapsed_bucket{pod=~\"$frontend\",path!~\"/health|/metrics\"}[$__rate_interval])))",
- "instant": false,
- "legendFormat": "[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "HTTP P99 per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "ops"
- },
- "overrides": [
- {
- "__systemRef": "hideSeriesFrom",
- "matcher": {
- "id": "byNames",
- "options": {
- "mode": "exclude",
- "names": [
- "[mycluster-frontend-5f94445cf8-mcmhf]-[/v1/prometheus/write]-[POST]-[204]-qps"
- ],
- "prefix": "All except:",
- "readOnly": true
- }
- },
- "properties": [
- {
- "id": "custom.hideFrom",
- "value": {
- "legend": false,
- "tooltip": false,
- "viz": true
- }
- }
- ]
- }
- ]
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 33
- },
- "id": 211,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "sum by(pod, path, code) (rate(greptime_servers_grpc_requests_elapsed_count{pod=~\"$frontend\"}[$__rate_interval]))",
- "instant": false,
- "legendFormat": "[{{pod}}]-[{{path}}]-[{{code}}]-qps",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "gRPC QPS per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "points",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "s"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 33
- },
- "id": 212,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "histogram_quantile(0.99, sum by(pod, le, path, code) (rate(greptime_servers_grpc_requests_elapsed_bucket{pod=~\"$frontend\"}[$__rate_interval])))",
- "instant": false,
- "legendFormat": "[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "gRPC P99 per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "ops"
- },
- "overrides": [
- {
- "__systemRef": "hideSeriesFrom",
- "matcher": {
- "id": "byNames",
- "options": {
- "mode": "exclude",
- "names": [
- "[mycluster-frontend-5c59b4cc9b-kpb6q]-qps"
- ],
- "prefix": "All except:",
- "readOnly": true
- }
- },
- "properties": [
- {
- "id": "custom.hideFrom",
- "value": {
- "legend": false,
- "tooltip": false,
- "viz": true
- }
- }
- ]
- }
- ]
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 41
- },
- "id": 213,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "sum by(pod)(rate(greptime_servers_mysql_query_elapsed_count{pod=~\"$frontend\"}[$__rate_interval]))",
- "instant": false,
- "legendFormat": "[{{pod}}]-qps",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "MySQL QPS per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "points",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "s"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 41
- },
- "id": 214,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "exemplar": false,
- "expr": "histogram_quantile(0.99, sum by(pod, le) (rate(greptime_servers_mysql_query_elapsed_bucket{pod=~\"$frontend\"}[$__rate_interval])))",
- "instant": false,
- "legendFormat": "[{{ pod }}]-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "MySQL P99 per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "ops"
- },
- "overrides": [
- {
- "__systemRef": "hideSeriesFrom",
- "matcher": {
- "id": "byNames",
- "options": {
- "mode": "exclude",
- "names": [
- "[mycluster-frontend-5f94445cf8-mcmhf]-[/v1/prometheus/write]-[POST]-[204]-qps"
- ],
- "prefix": "All except:",
- "readOnly": true
- }
- },
- "properties": [
- {
- "id": "custom.hideFrom",
- "value": {
- "legend": false,
- "tooltip": false,
- "viz": true
- }
- }
- ]
- }
- ]
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 49
- },
- "id": 215,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "sum by(pod) (rate(greptime_servers_postgres_query_elapsed_count{pod=~\"$frontend\"}[$__rate_interval]))",
- "instant": false,
- "legendFormat": "[{{pod}}]-qps",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "PostgreSQL QPS per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "points",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "s"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 49
- },
- "id": 216,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "histogram_quantile(0.99, sum by(pod, le) (rate(greptime_servers_postgres_query_elapsed_count{pod=~\"$frontend\"}[$__rate_interval])))",
- "instant": false,
- "legendFormat": "[{{pod}}]-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "PostgreSQL P99 per Instance",
- "type": "timeseries"
- }
- ],
+ "panels": [],
"title": "Frontend APIs",
"type": "row"
},
{
- "collapsed": true,
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "ops"
+ },
+ "overrides": []
+ },
"gridPos": {
- "h": 1,
- "w": 24,
+ "h": 8,
+ "w": 12,
"x": 0,
"y": 65
},
- "id": 217,
- "panels": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "rowsps"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 6,
- "w": 24,
- "x": 0,
- "y": 12
- },
- "id": 218,
- "options": {
- "legend": {
- "calcs": [
- "lastNotNull"
- ],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "sum by(pod)(rate(greptime_table_operator_ingest_rows{pod=~\"$frontend\"}[$__rate_interval]))",
- "instant": false,
- "legendFormat": "[{{pod}}]-rps",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Ingest Rows per Instance",
- "type": "timeseries"
+ "id": 202,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
},
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "ops"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 18
- },
- "id": 219,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "list",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "sum by(pod, request_type) (rate(greptime_grpc_region_request_count{pod=~\"$frontend\"}[$__rate_interval]))",
- "instant": false,
- "legendFormat": "[{{pod}}]-[{{request_type}}]-qps",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Region Call QPS per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "points",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "s"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 18
- },
- "id": 220,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "histogram_quantile(0.99, sum by(pod, le, request_type) (rate(greptime_grpc_region_request_bucket{pod=~\"$frontend\"}[$__rate_interval])))",
- "instant": false,
- "legendFormat": "[{{pod}}]-[{{request_type}}]-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Region Call P99 per Instance",
- "type": "timeseries"
+ "editorMode": "code",
+ "expr": "sum by(pod, path, method, code) (rate(greptime_servers_http_requests_elapsed_count{pod=~\"$frontend\",path!~\"/health|/metrics\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-qps",
+ "range": true,
+ "refId": "A"
}
],
- "title": "Frontend <-> Datanode",
- "type": "row"
+ "title": "HTTP QPS per Instance",
+ "type": "timeseries"
},
{
- "collapsed": true,
- "gridPos": {
- "h": 1,
- "w": 24,
- "x": 0,
- "y": 66
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
},
- "id": 194,
- "panels": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
},
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "ops"
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
},
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 27
- },
- "id": 201,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
},
- "tooltip": {
- "mode": "single",
- "sort": "none"
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
}
},
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
},
- "editorMode": "code",
- "expr": "sum by(pod, type) (rate(greptime_mito_handle_request_elapsed_count{pod=~\"$datanode\"}[$__rate_interval]))",
- "instant": false,
- "legendFormat": "[{{pod}}]-[{{type}}]-qps",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Request QPS per Instance",
- "type": "timeseries"
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
},
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "points",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "s"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 27
- },
- "id": 222,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "histogram_quantile(0.99, sum by(pod, le, type) (rate(greptime_mito_handle_request_elapsed_bucket{pod=~\"$datanode\"}[$__rate_interval])))",
- "instant": false,
- "legendFormat": "[{{pod}}]-[{{type}}]-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Request P99 per Instance",
- "type": "timeseries"
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 65
+ },
+ "id": 203,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
},
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "decbytes"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 35
- },
- "id": 200,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "greptime_mito_write_buffer_bytes{pod=~\"$datanode\"}",
- "instant": false,
- "legendFormat": "{{pod}}",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Write Buffer per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "decbytes"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 35
- },
- "id": 221,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "sum by(pod) (greptime_mito_write_stall_total{pod=~\"$datanode\"})",
- "instant": false,
- "legendFormat": "{{pod}}",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Write Stall per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "ops"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 43
- },
- "id": 224,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "sum by(pod, reason) (rate(greptime_mito_flush_requests_total{pod=~\"$datanode\"}[$__rate_interval]))",
- "instant": false,
- "legendFormat": "[{{pod}}]-[{{reason}}]-success",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Flush QPS per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "decbytes"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 43
- },
- "id": 229,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "greptime_mito_cache_bytes{pod=~\"$datanode\"}",
- "instant": false,
- "legendFormat": "{{pod}}-{{type}}",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Cached Bytes per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "ops"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 51
- },
- "id": 227,
- "options": {
- "legend": {
- "calcs": [
- "lastNotNull"
- ],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "sum by(pod) (rate(greptime_mito_read_stage_elapsed_count{pod=~\"$datanode\", stage=\"total\"}[$__rate_interval]))",
- "instant": false,
- "legendFormat": "{{pod}}-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Read Stage QPS per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "points",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "s"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 51
- },
- "id": 228,
- "options": {
- "legend": {
- "calcs": [
- "lastNotNull"
- ],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "histogram_quantile(0.99, sum by(pod, le, stage) (rate(greptime_mito_read_stage_elapsed_bucket{pod=~\"$datanode\"}[$__rate_interval])))",
- "instant": false,
- "legendFormat": "{{pod}}-{{stage}}-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Read Stage P99 per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "ops"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 59
- },
- "id": 231,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "sum by(pod) (rate(greptime_mito_compaction_total_elapsed_count{pod=~\"$datanode\"}[$__rate_interval]))",
- "instant": false,
- "legendFormat": "{{pod}}",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Compaction OPS per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "points",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "s"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 59
- },
- "id": 230,
- "options": {
- "legend": {
- "calcs": [
- "lastNotNull"
- ],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "histogram_quantile(0.99, sum by(pod, le) (rate(greptime_mito_compaction_total_elapsed_bucket{pod=~\"$datanode\"}[$__rate_interval])))",
- "instant": false,
- "legendFormat": "[{{pod}}]-compaction-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Compaction P99 per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "points",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "s"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 67
- },
- "id": 225,
- "options": {
- "legend": {
- "calcs": [
- "lastNotNull"
- ],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "histogram_quantile(0.99, sum by(pod, le, stage) (rate(greptime_mito_write_stage_elapsed_bucket{pod=~\"$datanode\"}[$__rate_interval])))",
- "instant": false,
- "legendFormat": "{{pod}}-{{stage}}-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Write Stage P99 per Instance",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "points",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "s"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 67
- },
- "id": 232,
- "options": {
- "legend": {
- "calcs": [
- "lastNotNull"
- ],
- "displayMode": "table",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "${DS_PROMETHEUS}"
- },
- "editorMode": "code",
- "expr": "histogram_quantile(0.99, sum by(pod, le, stage) (rate(greptime_mito_compaction_stage_elapsed_bucket{pod=~\"$datanode\"}[$__rate_interval])))",
- "instant": false,
- "legendFormat": "{{pod}}-{{stage}}-p99",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Compaction P99 per Instance",
- "type": "timeseries"
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(pod, le, path, method, code) (rate(greptime_servers_http_requests_elapsed_bucket{pod=~\"$frontend\",path!~\"/health|/metrics\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99",
+ "range": true,
+ "refId": "A"
}
],
- "title": "Mito Engine",
- "type": "row"
+ "title": "HTTP P99 per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "ops"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 73
+ },
+ "id": 211,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(pod, path, code) (rate(greptime_servers_grpc_requests_elapsed_count{pod=~\"$frontend\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-[{{path}}]-[{{code}}]-qps",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "gRPC QPS per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 73
+ },
+ "id": 212,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(pod, le, path, code) (rate(greptime_servers_grpc_requests_elapsed_bucket{pod=~\"$frontend\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "gRPC P99 per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "ops"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 81
+ },
+ "id": 213,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(pod)(rate(greptime_servers_mysql_query_elapsed_count{pod=~\"$frontend\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-qps",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "MySQL QPS per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "default": false,
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 81
+ },
+ "id": 214,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "histogram_quantile(0.99, sum by(pod, le) (rate(greptime_servers_mysql_query_elapsed_bucket{pod=~\"$frontend\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{ pod }}]-p99",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "MySQL P99 per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "ops"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 89
+ },
+ "id": 215,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(pod) (rate(greptime_servers_postgres_query_elapsed_count{pod=~\"$frontend\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-qps",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "PostgreSQL QPS per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "default": false,
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 89
+ },
+ "id": 216,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(pod, le) (rate(greptime_servers_postgres_query_elapsed_bucket{pod=~\"$frontend\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-p99",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "PostgreSQL P99 per Instance",
+ "type": "timeseries"
},
{
"collapsed": false,
@@ -5852,7 +4324,1501 @@
"h": 1,
"w": 24,
"x": 0,
- "y": 67
+ "y": 97
+ },
+ "id": 217,
+ "panels": [],
+ "title": "Frontend <-> Datanode",
+ "type": "row"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "rowsps"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 6,
+ "w": 24,
+ "x": 0,
+ "y": 98
+ },
+ "id": 218,
+ "options": {
+ "legend": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(pod)(rate(greptime_table_operator_ingest_rows{pod=~\"$frontend\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-rps",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Ingest Rows per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "ops"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 104
+ },
+ "id": 219,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(pod, request_type) (rate(greptime_grpc_region_request_count{pod=~\"$frontend\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-[{{request_type}}]-qps",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Region Call QPS per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 104
+ },
+ "id": 220,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(pod, le, request_type) (rate(greptime_grpc_region_request_bucket{pod=~\"$frontend\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-[{{request_type}}]-p99",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Region Call P99 per Instance",
+ "type": "timeseries"
+ },
+ {
+ "collapsed": false,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 112
+ },
+ "id": 194,
+ "panels": [],
+ "title": "Mito Engine",
+ "type": "row"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "ops"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 113
+ },
+ "id": 201,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(pod, type) (rate(greptime_mito_handle_request_elapsed_count{pod=~\"$datanode\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-[{{type}}]-qps",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Request QPS per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 113
+ },
+ "id": 222,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(pod, le, type) (rate(greptime_mito_handle_request_elapsed_bucket{pod=~\"$datanode\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-[{{type}}]-p99",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Request P99 per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "decbytes"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 121
+ },
+ "id": 200,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "greptime_mito_write_buffer_bytes{pod=~\"$datanode\"}",
+ "instant": false,
+ "legendFormat": "{{pod}}",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Write Buffer per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "decbytes"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 121
+ },
+ "id": 221,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(pod) (greptime_mito_write_stall_total{pod=~\"$datanode\"})",
+ "instant": false,
+ "legendFormat": "{{pod}}",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Write Stall per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "ops"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 129
+ },
+ "id": 224,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(pod, reason) (rate(greptime_mito_flush_requests_total{pod=~\"$datanode\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-[{{reason}}]-success",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Flush QPS per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "decbytes"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 129
+ },
+ "id": 229,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "greptime_mito_cache_bytes{pod=~\"$datanode\"}",
+ "instant": false,
+ "legendFormat": "{{pod}}-{{type}}",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Cached Bytes per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "ops"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 137
+ },
+ "id": 227,
+ "options": {
+ "legend": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(pod) (rate(greptime_mito_read_stage_elapsed_count{pod=~\"$datanode\", stage=\"total\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "{{pod}}-p99",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Read Stage QPS per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 137
+ },
+ "id": 228,
+ "options": {
+ "legend": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(pod, le, stage) (rate(greptime_mito_read_stage_elapsed_bucket{pod=~\"$datanode\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "{{pod}}-{{stage}}-p99",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Read Stage P99 per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "ops"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 145
+ },
+ "id": 231,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "sum by(pod) (rate(greptime_mito_compaction_total_elapsed_count{pod=~\"$datanode\"}[$__rate_interval]))",
+ "instant": false,
+ "legendFormat": "{{pod}}",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Compaction OPS per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 145
+ },
+ "id": 230,
+ "options": {
+ "legend": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(pod, le) (rate(greptime_mito_compaction_total_elapsed_bucket{pod=~\"$datanode\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "[{{pod}}]-compaction-p99",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Compaction P99 per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "points",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 153
+ },
+ "id": 225,
+ "options": {
+ "legend": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(pod, le, stage) (rate(greptime_mito_write_stage_elapsed_bucket{pod=~\"$datanode\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "{{pod}}-{{stage}}-p99",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Write Stage P99 per Instance",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "barWidthFactor": 0.6,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 153
+ },
+ "id": 232,
+ "options": {
+ "legend": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${DS_PROMETHEUS}"
+ },
+ "editorMode": "code",
+ "expr": "histogram_quantile(0.99, sum by(pod, le, stage) (rate(greptime_mito_compaction_stage_elapsed_bucket{pod=~\"$datanode\"}[$__rate_interval])))",
+ "instant": false,
+ "legendFormat": "{{pod}}-{{stage}}-p99",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Compaction P99 per Instance",
+ "type": "timeseries"
+ },
+ {
+ "collapsed": false,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 161
},
"id": 271,
"panels": [],
@@ -5876,6 +5842,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -5922,7 +5889,7 @@
"h": 8,
"w": 12,
"x": 0,
- "y": 68
+ "y": 162
},
"id": 276,
"options": {
@@ -5933,8 +5900,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -5971,6 +5938,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -6017,7 +5985,7 @@
"h": 8,
"w": 12,
"x": 12,
- "y": 68
+ "y": 162
},
"id": 274,
"options": {
@@ -6028,8 +5996,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -6079,6 +6047,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -6125,7 +6094,7 @@
"h": 8,
"w": 9,
"x": 0,
- "y": 76
+ "y": 170
},
"id": 277,
"options": {
@@ -6136,8 +6105,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -6187,6 +6156,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -6233,7 +6203,7 @@
"h": 8,
"w": 9,
"x": 9,
- "y": 76
+ "y": 170
},
"id": 272,
"options": {
@@ -6244,8 +6214,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -6282,6 +6252,7 @@
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
+ "barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
@@ -6328,7 +6299,7 @@
"h": 8,
"w": 6,
"x": 18,
- "y": 76
+ "y": 170
},
"id": 275,
"options": {
@@ -6339,8 +6310,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -6366,7 +6337,7 @@
"h": 1,
"w": 24,
"x": 0,
- "y": 84
+ "y": 178
},
"id": 195,
"panels": [
@@ -6417,8 +6388,7 @@
"mode": "absolute",
"steps": [
{
- "color": "green",
- "value": null
+ "color": "green"
},
{
"color": "red",
@@ -6445,8 +6415,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -6540,8 +6510,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -6635,8 +6605,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -6730,8 +6700,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -6825,8 +6795,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -6920,8 +6890,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -7016,8 +6986,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -7112,8 +7082,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -7207,8 +7177,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -7233,7 +7203,7 @@
"type": "row"
}
],
- "refresh": "10s",
+ "refresh": "1m",
"schemaVersion": 39,
"tags": [],
"templating": {
@@ -7241,8 +7211,8 @@
{
"current": {
"selected": false,
- "text": "prometheus",
- "value": "d27aa88d-8b10-40ab-b82f-a66e13e0ebe4"
+ "text": "internal-greptimedb-standalone-eks-us-east-1-qa1",
+ "value": "internal-greptimedb-standalone-eks-us-east-1-qa1"
},
"hide": 0,
"includeAll": false,
@@ -7258,9 +7228,9 @@
},
{
"current": {
- "selected": false,
- "text": "mysql",
- "value": "ede21e7b-28b4-4089-814f-477dcf893e29"
+ "selected": true,
+ "text": "downloads-report",
+ "value": "PA0FB0AF8177A6791"
},
"hide": 0,
"includeAll": false,
@@ -7275,7 +7245,15 @@
"type": "datasource"
},
{
- "current": {},
+ "current": {
+ "selected": true,
+ "text": [
+ "All"
+ ],
+ "value": [
+ "$__all"
+ ]
+ },
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
@@ -7298,7 +7276,11 @@
"type": "query"
},
{
- "current": {},
+ "current": {
+ "selected": false,
+ "text": "All",
+ "value": "$__all"
+ },
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
@@ -7321,7 +7303,11 @@
"type": "query"
},
{
- "current": {},
+ "current": {
+ "selected": false,
+ "text": "All",
+ "value": "$__all"
+ },
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
@@ -7344,7 +7330,11 @@
"type": "query"
},
{
- "current": {},
+ "current": {
+ "selected": false,
+ "text": "All",
+ "value": "$__all"
+ },
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
@@ -7367,7 +7357,11 @@
"type": "query"
},
{
- "current": {},
+ "current": {
+ "selected": false,
+ "text": "All",
+ "value": "$__all"
+ },
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
@@ -7390,7 +7384,11 @@
"type": "query"
},
{
- "current": {},
+ "current": {
+ "selected": false,
+ "text": "All",
+ "value": "$__all"
+ },
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
@@ -7421,7 +7419,7 @@
"timepicker": {},
"timezone": "",
"title": "GreptimeDB Cluster Metrics",
- "uid": "ce3q6xwn3xa0wa",
- "version": 2,
+ "uid": "ce3q6xwn3xa0qs",
+ "version": 8,
"weekStart": ""
}
diff --git a/grafana/greptimedb.json b/grafana/greptimedb.json
index f5b69608c8..a5913ee8e8 100644
--- a/grafana/greptimedb.json
+++ b/grafana/greptimedb.json
@@ -384,8 +384,8 @@
"rowHeight": 0.9,
"showValue": "auto",
"tooltip": {
- "mode": "none",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -483,8 +483,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"pluginVersion": "10.2.3",
@@ -578,8 +578,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"pluginVersion": "10.2.3",
@@ -601,7 +601,7 @@
"type": "timeseries"
},
{
- "collapsed": true,
+ "collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
@@ -684,8 +684,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -878,8 +878,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1124,8 +1124,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1223,8 +1223,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1322,8 +1322,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1456,8 +1456,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1573,8 +1573,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1673,8 +1673,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1773,8 +1773,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -1890,8 +1890,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2002,8 +2002,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2120,8 +2120,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2233,8 +2233,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2334,8 +2334,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2435,8 +2435,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2548,8 +2548,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2661,8 +2661,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2788,8 +2788,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2889,8 +2889,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -2990,8 +2990,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3091,8 +3091,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3191,8 +3191,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3302,8 +3302,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3432,8 +3432,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3543,8 +3543,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3657,8 +3657,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3808,8 +3808,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -3909,8 +3909,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -4011,8 +4011,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
@@ -4113,8 +4113,8 @@
"showLegend": true
},
"tooltip": {
- "mode": "single",
- "sort": "none"
+ "mode": "multi",
+ "sort": "desc"
}
},
"targets": [
diff --git a/src/api/Cargo.toml b/src/api/Cargo.toml
index 2225cbd2cc..d48bfdaf58 100644
--- a/src/api/Cargo.toml
+++ b/src/api/Cargo.toml
@@ -15,13 +15,10 @@ common-macro.workspace = true
common-time.workspace = true
datatypes.workspace = true
greptime-proto.workspace = true
-paste = "1.0"
+paste.workspace = true
prost.workspace = true
serde_json.workspace = true
snafu.workspace = true
[build-dependencies]
tonic-build = "0.11"
-
-[dev-dependencies]
-paste = "1.0"
diff --git a/src/api/src/v1/column_def.rs b/src/api/src/v1/column_def.rs
index a1d209c0e7..dab7784172 100644
--- a/src/api/src/v1/column_def.rs
+++ b/src/api/src/v1/column_def.rs
@@ -15,10 +15,10 @@
use std::collections::HashMap;
use datatypes::schema::{
- ColumnDefaultConstraint, ColumnSchema, FulltextAnalyzer, FulltextOptions, COMMENT_KEY,
- FULLTEXT_KEY, INVERTED_INDEX_KEY, SKIPPING_INDEX_KEY,
+ ColumnDefaultConstraint, ColumnSchema, FulltextAnalyzer, FulltextOptions, SkippingIndexOptions,
+ SkippingIndexType, COMMENT_KEY, FULLTEXT_KEY, INVERTED_INDEX_KEY, SKIPPING_INDEX_KEY,
};
-use greptime_proto::v1::Analyzer;
+use greptime_proto::v1::{Analyzer, SkippingIndexType as PbSkippingIndexType};
use snafu::ResultExt;
use crate::error::{self, Result};
@@ -103,6 +103,13 @@ pub fn contains_fulltext(options: &Option) -> bool {
.is_some_and(|o| o.options.contains_key(FULLTEXT_GRPC_KEY))
}
+/// Checks if the `ColumnOptions` contains skipping index options.
+pub fn contains_skipping(options: &Option) -> bool {
+ options
+ .as_ref()
+ .is_some_and(|o| o.options.contains_key(SKIPPING_INDEX_GRPC_KEY))
+}
+
/// Tries to construct a `ColumnOptions` from the given `FulltextOptions`.
pub fn options_from_fulltext(fulltext: &FulltextOptions) -> Result> {
let mut options = ColumnOptions::default();
@@ -113,6 +120,18 @@ pub fn options_from_fulltext(fulltext: &FulltextOptions) -> Result Result > {
+ let mut options = ColumnOptions::default();
+
+ let v = serde_json::to_string(skipping).context(error::SerializeJsonSnafu)?;
+ options
+ .options
+ .insert(SKIPPING_INDEX_GRPC_KEY.to_string(), v);
+
+ Ok((!options.options.is_empty()).then_some(options))
+}
+
/// Tries to construct a `FulltextAnalyzer` from the given analyzer.
pub fn as_fulltext_option(analyzer: Analyzer) -> FulltextAnalyzer {
match analyzer {
@@ -121,6 +140,13 @@ pub fn as_fulltext_option(analyzer: Analyzer) -> FulltextAnalyzer {
}
}
+/// Tries to construct a `SkippingIndexType` from the given skipping index type.
+pub fn as_skipping_index_type(skipping_index_type: PbSkippingIndexType) -> SkippingIndexType {
+ match skipping_index_type {
+ PbSkippingIndexType::BloomFilter => SkippingIndexType::BloomFilter,
+ }
+}
+
#[cfg(test)]
mod tests {
diff --git a/src/catalog/Cargo.toml b/src/catalog/Cargo.toml
index b7e19a44b9..b425aa02c6 100644
--- a/src/catalog/Cargo.toml
+++ b/src/catalog/Cargo.toml
@@ -15,7 +15,7 @@ api.workspace = true
arrow.workspace = true
arrow-schema.workspace = true
async-stream.workspace = true
-async-trait = "0.1"
+async-trait.workspace = true
bytes.workspace = true
common-catalog.workspace = true
common-error.workspace = true
@@ -31,7 +31,7 @@ common-version.workspace = true
dashmap.workspace = true
datafusion.workspace = true
datatypes.workspace = true
-futures = "0.3"
+futures.workspace = true
futures-util.workspace = true
humantime.workspace = true
itertools.workspace = true
@@ -39,7 +39,7 @@ lazy_static.workspace = true
meta-client.workspace = true
moka = { workspace = true, features = ["future", "sync"] }
partition.workspace = true
-paste = "1.0"
+paste.workspace = true
prometheus.workspace = true
rustc-hash.workspace = true
serde_json.workspace = true
@@ -49,7 +49,7 @@ sql.workspace = true
store-api.workspace = true
table.workspace = true
tokio.workspace = true
-tokio-stream = "0.1"
+tokio-stream.workspace = true
[dev-dependencies]
cache.workspace = true
diff --git a/src/catalog/src/kvbackend/manager.rs b/src/catalog/src/kvbackend/manager.rs
index ca20805d37..82e1c8f876 100644
--- a/src/catalog/src/kvbackend/manager.rs
+++ b/src/catalog/src/kvbackend/manager.rs
@@ -38,6 +38,7 @@ use partition::manager::{PartitionRuleManager, PartitionRuleManagerRef};
use session::context::{Channel, QueryContext};
use snafu::prelude::*;
use table::dist_table::DistTable;
+use table::metadata::TableId;
use table::table::numbers::{NumbersTable, NUMBERS_TABLE_NAME};
use table::table_name::TableName;
use table::TableRef;
@@ -286,6 +287,28 @@ impl CatalogManager for KvBackendCatalogManager {
return Ok(None);
}
+ async fn tables_by_ids(
+ &self,
+ catalog: &str,
+ schema: &str,
+ table_ids: &[TableId],
+ ) -> Result> {
+ let table_info_values = self
+ .table_metadata_manager
+ .table_info_manager()
+ .batch_get(table_ids)
+ .await
+ .context(TableMetadataManagerSnafu)?;
+
+ let tables = table_info_values
+ .into_values()
+ .filter(|t| t.table_info.catalog_name == catalog && t.table_info.schema_name == schema)
+ .map(build_table)
+ .collect::>>()?;
+
+ Ok(tables)
+ }
+
fn tables<'a>(
&'a self,
catalog: &'a str,
diff --git a/src/catalog/src/lib.rs b/src/catalog/src/lib.rs
index 729ea58724..34884f1355 100644
--- a/src/catalog/src/lib.rs
+++ b/src/catalog/src/lib.rs
@@ -87,6 +87,14 @@ pub trait CatalogManager: Send + Sync {
query_ctx: Option<&QueryContext>,
) -> Result>;
+ /// Returns the tables by table ids.
+ async fn tables_by_ids(
+ &self,
+ catalog: &str,
+ schema: &str,
+ table_ids: &[TableId],
+ ) -> Result>;
+
/// Returns all tables with a stream by catalog and schema.
fn tables<'a>(
&'a self,
diff --git a/src/catalog/src/memory/manager.rs b/src/catalog/src/memory/manager.rs
index 62ff863c46..9b53a20e3d 100644
--- a/src/catalog/src/memory/manager.rs
+++ b/src/catalog/src/memory/manager.rs
@@ -14,7 +14,7 @@
use std::any::Any;
use std::collections::hash_map::Entry;
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
use std::sync::{Arc, RwLock, Weak};
use async_stream::{stream, try_stream};
@@ -28,6 +28,7 @@ use common_meta::kv_backend::memory::MemoryKvBackend;
use futures_util::stream::BoxStream;
use session::context::QueryContext;
use snafu::OptionExt;
+use table::metadata::TableId;
use table::TableRef;
use crate::error::{CatalogNotFoundSnafu, Result, SchemaNotFoundSnafu, TableExistsSnafu};
@@ -143,6 +144,33 @@ impl CatalogManager for MemoryCatalogManager {
Ok(result)
}
+ async fn tables_by_ids(
+ &self,
+ catalog: &str,
+ schema: &str,
+ table_ids: &[TableId],
+ ) -> Result> {
+ let catalogs = self.catalogs.read().unwrap();
+
+ let schemas = catalogs.get(catalog).context(CatalogNotFoundSnafu {
+ catalog_name: catalog,
+ })?;
+
+ let tables = schemas
+ .get(schema)
+ .context(SchemaNotFoundSnafu { catalog, schema })?;
+
+ let filter_ids: HashSet<_> = table_ids.iter().collect();
+ // It is very inefficient, but we do not need to optimize it since it will not be called in `MemoryCatalogManager`.
+ let tables = tables
+ .values()
+ .filter(|t| filter_ids.contains(&t.table_info().table_id()))
+ .cloned()
+ .collect::>();
+
+ Ok(tables)
+ }
+
fn tables<'a>(
&'a self,
catalog: &'a str,
diff --git a/src/cmd/src/datanode.rs b/src/cmd/src/datanode.rs
index c26201e7c0..18427fef98 100644
--- a/src/cmd/src/datanode.rs
+++ b/src/cmd/src/datanode.rs
@@ -287,7 +287,6 @@ impl StartCommand {
.await
.context(StartDatanodeSnafu)?;
- let cluster_id = 0; // TODO(hl): read from config
let member_id = opts
.node_id
.context(MissingConfigSnafu { msg: "'node_id'" })?;
@@ -296,13 +295,10 @@ impl StartCommand {
msg: "'meta_client_options'",
})?;
- let meta_client = meta_client::create_meta_client(
- cluster_id,
- MetaClientType::Datanode { member_id },
- meta_config,
- )
- .await
- .context(MetaClientInitSnafu)?;
+ let meta_client =
+ meta_client::create_meta_client(MetaClientType::Datanode { member_id }, meta_config)
+ .await
+ .context(MetaClientInitSnafu)?;
let meta_backend = Arc::new(MetaKvBackend {
client: meta_client.clone(),
diff --git a/src/cmd/src/flownode.rs b/src/cmd/src/flownode.rs
index 9280202471..6bd02a6a46 100644
--- a/src/cmd/src/flownode.rs
+++ b/src/cmd/src/flownode.rs
@@ -241,9 +241,6 @@ impl StartCommand {
let mut opts = opts.component;
opts.grpc.detect_server_addr();
- // TODO(discord9): make it not optionale after cluster id is required
- let cluster_id = opts.cluster_id.unwrap_or(0);
-
let member_id = opts
.node_id
.context(MissingConfigSnafu { msg: "'node_id'" })?;
@@ -252,13 +249,10 @@ impl StartCommand {
msg: "'meta_client_options'",
})?;
- let meta_client = meta_client::create_meta_client(
- cluster_id,
- MetaClientType::Flownode { member_id },
- meta_config,
- )
- .await
- .context(MetaClientInitSnafu)?;
+ let meta_client =
+ meta_client::create_meta_client(MetaClientType::Flownode { member_id }, meta_config)
+ .await
+ .context(MetaClientInitSnafu)?;
let cache_max_capacity = meta_config.metadata_cache_max_capacity;
let cache_ttl = meta_config.metadata_cache_ttl;
diff --git a/src/cmd/src/frontend.rs b/src/cmd/src/frontend.rs
index 3324328a8c..030783cb2f 100644
--- a/src/cmd/src/frontend.rs
+++ b/src/cmd/src/frontend.rs
@@ -295,14 +295,10 @@ impl StartCommand {
let cache_ttl = meta_client_options.metadata_cache_ttl;
let cache_tti = meta_client_options.metadata_cache_tti;
- let cluster_id = 0; // (TODO: jeremy): It is currently a reserved field and has not been enabled.
- let meta_client = meta_client::create_meta_client(
- cluster_id,
- MetaClientType::Frontend,
- meta_client_options,
- )
- .await
- .context(MetaClientInitSnafu)?;
+ let meta_client =
+ meta_client::create_meta_client(MetaClientType::Frontend, meta_client_options)
+ .await
+ .context(MetaClientInitSnafu)?;
// TODO(discord9): add helper function to ease the creation of cache registry&such
let cached_meta_backend =
diff --git a/src/cmd/src/metasrv.rs b/src/cmd/src/metasrv.rs
index 127defe031..063f36ffa4 100644
--- a/src/cmd/src/metasrv.rs
+++ b/src/cmd/src/metasrv.rs
@@ -42,7 +42,7 @@ pub struct Instance {
}
impl Instance {
- fn new(instance: MetasrvInstance, guard: Vec) -> Self {
+ pub fn new(instance: MetasrvInstance, guard: Vec) -> Self {
Self {
instance,
_guard: guard,
diff --git a/src/common/base/Cargo.toml b/src/common/base/Cargo.toml
index 44eb5535ea..ae2945b1f5 100644
--- a/src/common/base/Cargo.toml
+++ b/src/common/base/Cargo.toml
@@ -18,7 +18,7 @@ bytes.workspace = true
common-error.workspace = true
common-macro.workspace = true
futures.workspace = true
-paste = "1.0"
+paste.workspace = true
pin-project.workspace = true
rand.workspace = true
serde = { version = "1.0", features = ["derive"] }
diff --git a/src/common/catalog/src/consts.rs b/src/common/catalog/src/consts.rs
index 34c6fa0fdb..0d39a27b9d 100644
--- a/src/common/catalog/src/consts.rs
+++ b/src/common/catalog/src/consts.rs
@@ -130,3 +130,10 @@ pub const SEMANTIC_TYPE_TIME_INDEX: &str = "TIMESTAMP";
pub fn is_readonly_schema(schema: &str) -> bool {
matches!(schema, INFORMATION_SCHEMA_NAME)
}
+
+// ---- special table and fields ----
+pub const TRACE_ID_COLUMN: &str = "trace_id";
+pub const SPAN_ID_COLUMN: &str = "span_id";
+pub const SPAN_NAME_COLUMN: &str = "span_name";
+pub const PARENT_SPAN_ID_COLUMN: &str = "parent_span_id";
+// ---- End of special table and fields ----
diff --git a/src/common/datasource/Cargo.toml b/src/common/datasource/Cargo.toml
index ae4fc221a9..63db292a52 100644
--- a/src/common/datasource/Cargo.toml
+++ b/src/common/datasource/Cargo.toml
@@ -35,7 +35,7 @@ orc-rust = { version = "0.5", default-features = false, features = [
"async",
] }
parquet.workspace = true
-paste = "1.0"
+paste.workspace = true
rand.workspace = true
regex = "1.7"
serde.workspace = true
diff --git a/src/common/function/Cargo.toml b/src/common/function/Cargo.toml
index 00500c67e5..f736c7f377 100644
--- a/src/common/function/Cargo.toml
+++ b/src/common/function/Cargo.toml
@@ -12,9 +12,11 @@ default = ["geo"]
geo = ["geohash", "h3o", "s2", "wkt", "geo-types", "dep:geo"]
[dependencies]
+ahash = "0.8"
api.workspace = true
arc-swap = "1.0"
async-trait.workspace = true
+bincode = "1.3"
common-base.workspace = true
common-catalog.workspace = true
common-error.workspace = true
@@ -26,18 +28,21 @@ common-telemetry.workspace = true
common-time.workspace = true
common-version.workspace = true
datafusion.workspace = true
+datafusion-common.workspace = true
+datafusion-expr.workspace = true
datatypes.workspace = true
derive_more = { version = "1", default-features = false, features = ["display"] }
geo = { version = "0.29", optional = true }
geo-types = { version = "0.7", optional = true }
geohash = { version = "0.13", optional = true }
h3o = { version = "0.6", optional = true }
+hyperloglogplus = "0.4"
jsonb.workspace = true
nalgebra.workspace = true
num = "0.4"
num-traits = "0.2"
once_cell.workspace = true
-paste = "1.0"
+paste.workspace = true
s2 = { version = "0.0.12", optional = true }
serde.workspace = true
serde_json.workspace = true
@@ -47,6 +52,7 @@ sql.workspace = true
statrs = "0.16"
store-api.workspace = true
table.workspace = true
+uddsketch = { git = "https://github.com/GreptimeTeam/timescaledb-toolkit.git", rev = "84828fe8fb494a6a61412a3da96517fc80f7bb20" }
wkt = { version = "0.11", optional = true }
[dev-dependencies]
diff --git a/src/common/function/src/table.rs b/src/common/function/src/admin.rs
similarity index 96%
rename from src/common/function/src/table.rs
rename to src/common/function/src/admin.rs
index 91ee6dd178..b2f916d876 100644
--- a/src/common/function/src/table.rs
+++ b/src/common/function/src/admin.rs
@@ -26,9 +26,9 @@ use crate::flush_flow::FlushFlowFunction;
use crate::function_registry::FunctionRegistry;
/// Table functions
-pub(crate) struct TableFunction;
+pub(crate) struct AdminFunction;
-impl TableFunction {
+impl AdminFunction {
/// Register all table functions to [`FunctionRegistry`].
pub fn register(registry: &FunctionRegistry) {
registry.register_async(Arc::new(MigrateRegionFunction));
diff --git a/src/common/function/src/table/flush_compact_region.rs b/src/common/function/src/admin/flush_compact_region.rs
similarity index 100%
rename from src/common/function/src/table/flush_compact_region.rs
rename to src/common/function/src/admin/flush_compact_region.rs
diff --git a/src/common/function/src/table/flush_compact_table.rs b/src/common/function/src/admin/flush_compact_table.rs
similarity index 100%
rename from src/common/function/src/table/flush_compact_table.rs
rename to src/common/function/src/admin/flush_compact_table.rs
diff --git a/src/common/function/src/table/migrate_region.rs b/src/common/function/src/admin/migrate_region.rs
similarity index 100%
rename from src/common/function/src/table/migrate_region.rs
rename to src/common/function/src/admin/migrate_region.rs
diff --git a/src/common/function/src/aggr.rs b/src/common/function/src/aggr.rs
new file mode 100644
index 0000000000..24bcb86618
--- /dev/null
+++ b/src/common/function/src/aggr.rs
@@ -0,0 +1,22 @@
+// Copyright 2023 Greptime Team
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+mod geo_path;
+mod hll;
+mod uddsketch_state;
+
+pub use geo_path::{GeoPathAccumulator, GEO_PATH_NAME};
+pub(crate) use hll::HllStateType;
+pub use hll::{HllState, HLL_MERGE_NAME, HLL_NAME};
+pub use uddsketch_state::{UddSketchState, UDDSKETCH_STATE_NAME};
diff --git a/src/common/function/src/aggr/geo_path.rs b/src/common/function/src/aggr/geo_path.rs
new file mode 100644
index 0000000000..d5a2f71b57
--- /dev/null
+++ b/src/common/function/src/aggr/geo_path.rs
@@ -0,0 +1,433 @@
+// Copyright 2023 Greptime Team
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use std::sync::Arc;
+
+use datafusion::arrow::array::{Array, ArrayRef};
+use datafusion::common::cast::as_primitive_array;
+use datafusion::error::{DataFusionError, Result as DfResult};
+use datafusion::logical_expr::{Accumulator as DfAccumulator, AggregateUDF, Volatility};
+use datafusion::prelude::create_udaf;
+use datafusion_common::cast::{as_list_array, as_struct_array};
+use datafusion_common::utils::SingleRowListArrayBuilder;
+use datafusion_common::ScalarValue;
+use datatypes::arrow::array::{Float64Array, Int64Array, ListArray, StructArray};
+use datatypes::arrow::datatypes::{
+ DataType, Field, Float64Type, Int64Type, TimeUnit, TimestampNanosecondType,
+};
+use datatypes::compute::{self, sort_to_indices};
+
+pub const GEO_PATH_NAME: &str = "geo_path";
+
+const LATITUDE_FIELD: &str = "lat";
+const LONGITUDE_FIELD: &str = "lng";
+const TIMESTAMP_FIELD: &str = "timestamp";
+const DEFAULT_LIST_FIELD_NAME: &str = "item";
+
+#[derive(Debug, Default)]
+pub struct GeoPathAccumulator {
+ lat: Vec>,
+ lng: Vec >,
+ timestamp: Vec >,
+}
+
+impl GeoPathAccumulator {
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ pub fn udf_impl() -> AggregateUDF {
+ create_udaf(
+ GEO_PATH_NAME,
+ // Input types: lat, lng, timestamp
+ vec![
+ DataType::Float64,
+ DataType::Float64,
+ DataType::Timestamp(TimeUnit::Nanosecond, None),
+ ],
+ // Output type: list of points {[lat], [lng]}
+ Arc::new(DataType::Struct(
+ vec![
+ Field::new(
+ LATITUDE_FIELD,
+ DataType::List(Arc::new(Field::new(
+ DEFAULT_LIST_FIELD_NAME,
+ DataType::Float64,
+ true,
+ ))),
+ false,
+ ),
+ Field::new(
+ LONGITUDE_FIELD,
+ DataType::List(Arc::new(Field::new(
+ DEFAULT_LIST_FIELD_NAME,
+ DataType::Float64,
+ true,
+ ))),
+ false,
+ ),
+ ]
+ .into(),
+ )),
+ Volatility::Immutable,
+ // Create the accumulator
+ Arc::new(|_| Ok(Box::new(GeoPathAccumulator::new()))),
+ // Intermediate state types
+ Arc::new(vec![DataType::Struct(
+ vec![
+ Field::new(
+ LATITUDE_FIELD,
+ DataType::List(Arc::new(Field::new(
+ DEFAULT_LIST_FIELD_NAME,
+ DataType::Float64,
+ true,
+ ))),
+ false,
+ ),
+ Field::new(
+ LONGITUDE_FIELD,
+ DataType::List(Arc::new(Field::new(
+ DEFAULT_LIST_FIELD_NAME,
+ DataType::Float64,
+ true,
+ ))),
+ false,
+ ),
+ Field::new(
+ TIMESTAMP_FIELD,
+ DataType::List(Arc::new(Field::new(
+ DEFAULT_LIST_FIELD_NAME,
+ DataType::Int64,
+ true,
+ ))),
+ false,
+ ),
+ ]
+ .into(),
+ )]),
+ )
+ }
+}
+
+impl DfAccumulator for GeoPathAccumulator {
+ fn update_batch(&mut self, values: &[ArrayRef]) -> datafusion::error::Result<()> {
+ if values.len() != 3 {
+ return Err(DataFusionError::Internal(format!(
+ "Expected 3 columns for geo_path, got {}",
+ values.len()
+ )));
+ }
+
+ let lat_array = as_primitive_array::(&values[0])?;
+ let lng_array = as_primitive_array::(&values[1])?;
+ let ts_array = as_primitive_array::(&values[2])?;
+
+ let size = lat_array.len();
+ self.lat.reserve(size);
+ self.lng.reserve(size);
+
+ for idx in 0..size {
+ self.lat.push(if lat_array.is_null(idx) {
+ None
+ } else {
+ Some(lat_array.value(idx))
+ });
+
+ self.lng.push(if lng_array.is_null(idx) {
+ None
+ } else {
+ Some(lng_array.value(idx))
+ });
+
+ self.timestamp.push(if ts_array.is_null(idx) {
+ None
+ } else {
+ Some(ts_array.value(idx))
+ });
+ }
+
+ Ok(())
+ }
+
+ fn evaluate(&mut self) -> DfResult {
+ let unordered_lng_array = Float64Array::from(self.lng.clone());
+ let unordered_lat_array = Float64Array::from(self.lat.clone());
+ let ts_array = Int64Array::from(self.timestamp.clone());
+
+ let ordered_indices = sort_to_indices(&ts_array, None, None)?;
+ let lat_array = compute::take(&unordered_lat_array, &ordered_indices, None)?;
+ let lng_array = compute::take(&unordered_lng_array, &ordered_indices, None)?;
+
+ let lat_list = Arc::new(SingleRowListArrayBuilder::new(lat_array).build_list_array());
+ let lng_list = Arc::new(SingleRowListArrayBuilder::new(lng_array).build_list_array());
+
+ let result = ScalarValue::Struct(Arc::new(StructArray::new(
+ vec![
+ Field::new(
+ LATITUDE_FIELD,
+ DataType::List(Arc::new(Field::new("item", DataType::Float64, true))),
+ false,
+ ),
+ Field::new(
+ LONGITUDE_FIELD,
+ DataType::List(Arc::new(Field::new("item", DataType::Float64, true))),
+ false,
+ ),
+ ]
+ .into(),
+ vec![lat_list, lng_list],
+ None,
+ )));
+
+ Ok(result)
+ }
+
+ fn size(&self) -> usize {
+ // Base size of GeoPathAccumulator struct fields
+ let mut total_size = std::mem::size_of::();
+
+ // Size of vectors (approximation)
+ total_size += self.lat.capacity() * std::mem::size_of::>();
+ total_size += self.lng.capacity() * std::mem::size_of:: >();
+ total_size += self.timestamp.capacity() * std::mem::size_of:: >();
+
+ total_size
+ }
+
+ fn state(&mut self) -> datafusion::error::Result> {
+ let lat_array = Arc::new(ListArray::from_iter_primitive::(vec![
+ Some(self.lat.clone()),
+ ]));
+ let lng_array = Arc::new(ListArray::from_iter_primitive::(vec![
+ Some(self.lng.clone()),
+ ]));
+ let ts_array = Arc::new(ListArray::from_iter_primitive::(vec![
+ Some(self.timestamp.clone()),
+ ]));
+
+ let state_struct = StructArray::new(
+ vec![
+ Field::new(
+ LATITUDE_FIELD,
+ DataType::List(Arc::new(Field::new("item", DataType::Float64, true))),
+ false,
+ ),
+ Field::new(
+ LONGITUDE_FIELD,
+ DataType::List(Arc::new(Field::new("item", DataType::Float64, true))),
+ false,
+ ),
+ Field::new(
+ TIMESTAMP_FIELD,
+ DataType::List(Arc::new(Field::new("item", DataType::Int64, true))),
+ false,
+ ),
+ ]
+ .into(),
+ vec![lat_array, lng_array, ts_array],
+ None,
+ );
+
+ Ok(vec![ScalarValue::Struct(Arc::new(state_struct))])
+ }
+
+ fn merge_batch(&mut self, states: &[ArrayRef]) -> datafusion::error::Result<()> {
+ if states.len() != 1 {
+ return Err(DataFusionError::Internal(format!(
+ "Expected 1 states for geo_path, got {}",
+ states.len()
+ )));
+ }
+
+ for state in states {
+ let state = as_struct_array(state)?;
+ let lat_list = as_list_array(state.column(0))?.value(0);
+ let lat_array = as_primitive_array::(&lat_list)?;
+ let lng_list = as_list_array(state.column(1))?.value(0);
+ let lng_array = as_primitive_array::(&lng_list)?;
+ let ts_list = as_list_array(state.column(2))?.value(0);
+ let ts_array = as_primitive_array::(&ts_list)?;
+
+ self.lat.extend(lat_array);
+ self.lng.extend(lng_array);
+ self.timestamp.extend(ts_array);
+ }
+
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use datafusion::arrow::array::{Float64Array, TimestampNanosecondArray};
+ use datafusion::scalar::ScalarValue;
+
+ use super::*;
+
+ #[test]
+ fn test_geo_path_basic() {
+ let mut accumulator = GeoPathAccumulator::new();
+
+ // Create test data
+ let lat_array = Arc::new(Float64Array::from(vec![1.0, 2.0, 3.0]));
+ let lng_array = Arc::new(Float64Array::from(vec![4.0, 5.0, 6.0]));
+ let ts_array = Arc::new(TimestampNanosecondArray::from(vec![100, 200, 300]));
+
+ // Update batch
+ accumulator
+ .update_batch(&[lat_array, lng_array, ts_array])
+ .unwrap();
+
+ // Evaluate
+ let result = accumulator.evaluate().unwrap();
+ if let ScalarValue::Struct(struct_array) = result {
+ // Verify structure
+ let fields = struct_array.fields().clone();
+ assert_eq!(fields.len(), 2);
+ assert_eq!(fields[0].name(), LATITUDE_FIELD);
+ assert_eq!(fields[1].name(), LONGITUDE_FIELD);
+
+ // Verify data
+ let columns = struct_array.columns();
+ assert_eq!(columns.len(), 2);
+
+ // Check latitude values
+ let lat_list = as_list_array(&columns[0]).unwrap().value(0);
+ let lat_array = as_primitive_array::(&lat_list).unwrap();
+ assert_eq!(lat_array.len(), 3);
+ assert_eq!(lat_array.value(0), 1.0);
+ assert_eq!(lat_array.value(1), 2.0);
+ assert_eq!(lat_array.value(2), 3.0);
+
+ // Check longitude values
+ let lng_list = as_list_array(&columns[1]).unwrap().value(0);
+ let lng_array = as_primitive_array::(&lng_list).unwrap();
+ assert_eq!(lng_array.len(), 3);
+ assert_eq!(lng_array.value(0), 4.0);
+ assert_eq!(lng_array.value(1), 5.0);
+ assert_eq!(lng_array.value(2), 6.0);
+ } else {
+ panic!("Expected Struct scalar value");
+ }
+ }
+
+ #[test]
+ fn test_geo_path_sort_by_timestamp() {
+ let mut accumulator = GeoPathAccumulator::new();
+
+ // Create test data with unordered timestamps
+ let lat_array = Arc::new(Float64Array::from(vec![1.0, 2.0, 3.0]));
+ let lng_array = Arc::new(Float64Array::from(vec![4.0, 5.0, 6.0]));
+ let ts_array = Arc::new(TimestampNanosecondArray::from(vec![300, 100, 200]));
+
+ // Update batch
+ accumulator
+ .update_batch(&[lat_array, lng_array, ts_array])
+ .unwrap();
+
+ // Evaluate
+ let result = accumulator.evaluate().unwrap();
+ if let ScalarValue::Struct(struct_array) = result {
+ // Extract arrays
+ let columns = struct_array.columns();
+
+ // Check latitude values
+ let lat_list = as_list_array(&columns[0]).unwrap().value(0);
+ let lat_array = as_primitive_array::(&lat_list).unwrap();
+ assert_eq!(lat_array.len(), 3);
+ assert_eq!(lat_array.value(0), 2.0); // timestamp 100
+ assert_eq!(lat_array.value(1), 3.0); // timestamp 200
+ assert_eq!(lat_array.value(2), 1.0); // timestamp 300
+
+ // Check longitude values (should be sorted by timestamp)
+ let lng_list = as_list_array(&columns[1]).unwrap().value(0);
+ let lng_array = as_primitive_array::(&lng_list).unwrap();
+ assert_eq!(lng_array.len(), 3);
+ assert_eq!(lng_array.value(0), 5.0); // timestamp 100
+ assert_eq!(lng_array.value(1), 6.0); // timestamp 200
+ assert_eq!(lng_array.value(2), 4.0); // timestamp 300
+ } else {
+ panic!("Expected Struct scalar value");
+ }
+ }
+
+ #[test]
+ fn test_geo_path_merge() {
+ let mut accumulator1 = GeoPathAccumulator::new();
+ let mut accumulator2 = GeoPathAccumulator::new();
+
+ // Create test data for first accumulator
+ let lat_array1 = Arc::new(Float64Array::from(vec![1.0]));
+ let lng_array1 = Arc::new(Float64Array::from(vec![4.0]));
+ let ts_array1 = Arc::new(TimestampNanosecondArray::from(vec![100]));
+
+ // Create test data for second accumulator
+ let lat_array2 = Arc::new(Float64Array::from(vec![2.0]));
+ let lng_array2 = Arc::new(Float64Array::from(vec![5.0]));
+ let ts_array2 = Arc::new(TimestampNanosecondArray::from(vec![200]));
+
+ // Update batches
+ accumulator1
+ .update_batch(&[lat_array1, lng_array1, ts_array1])
+ .unwrap();
+ accumulator2
+ .update_batch(&[lat_array2, lng_array2, ts_array2])
+ .unwrap();
+
+ // Get states
+ let state1 = accumulator1.state().unwrap();
+ let state2 = accumulator2.state().unwrap();
+
+ // Create a merged accumulator
+ let mut merged = GeoPathAccumulator::new();
+
+ // Extract the struct arrays from the states
+ let state_array1 = match &state1[0] {
+ ScalarValue::Struct(array) => array.clone(),
+ _ => panic!("Expected Struct scalar value"),
+ };
+
+ let state_array2 = match &state2[0] {
+ ScalarValue::Struct(array) => array.clone(),
+ _ => panic!("Expected Struct scalar value"),
+ };
+
+ // Merge state arrays
+ merged.merge_batch(&[state_array1]).unwrap();
+ merged.merge_batch(&[state_array2]).unwrap();
+
+ // Evaluate merged result
+ let result = merged.evaluate().unwrap();
+ if let ScalarValue::Struct(struct_array) = result {
+ // Extract arrays
+ let columns = struct_array.columns();
+
+ // Check latitude values
+ let lat_list = as_list_array(&columns[0]).unwrap().value(0);
+ let lat_array = as_primitive_array::(&lat_list).unwrap();
+ assert_eq!(lat_array.len(), 2);
+ assert_eq!(lat_array.value(0), 1.0); // timestamp 100
+ assert_eq!(lat_array.value(1), 2.0); // timestamp 200
+
+ // Check longitude values (should be sorted by timestamp)
+ let lng_list = as_list_array(&columns[1]).unwrap().value(0);
+ let lng_array = as_primitive_array::(&lng_list).unwrap();
+ assert_eq!(lng_array.len(), 2);
+ assert_eq!(lng_array.value(0), 4.0); // timestamp 100
+ assert_eq!(lng_array.value(1), 5.0); // timestamp 200
+ } else {
+ panic!("Expected Struct scalar value");
+ }
+ }
+}
diff --git a/src/common/function/src/aggr/hll.rs b/src/common/function/src/aggr/hll.rs
new file mode 100644
index 0000000000..2f37f1525b
--- /dev/null
+++ b/src/common/function/src/aggr/hll.rs
@@ -0,0 +1,329 @@
+// Copyright 2023 Greptime Team
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Two UDAFs are implemented for HyperLogLog:
+//!
+//! - `hll`: Accepts a string column and aggregates the values into a
+//! HyperLogLog state.
+//! - `hll_merge`: Accepts a binary column of states generated by `hll`
+//! and merges them into a single state.
+//!
+//! The states can be then used to estimate the cardinality of the
+//! values in the column by `hll_count` UDF.
+
+use std::sync::Arc;
+
+use common_query::prelude::*;
+use common_telemetry::trace;
+use datafusion::arrow::array::ArrayRef;
+use datafusion::common::cast::{as_binary_array, as_string_array};
+use datafusion::common::not_impl_err;
+use datafusion::error::{DataFusionError, Result as DfResult};
+use datafusion::logical_expr::function::AccumulatorArgs;
+use datafusion::logical_expr::{Accumulator as DfAccumulator, AggregateUDF};
+use datafusion::prelude::create_udaf;
+use datatypes::arrow::datatypes::DataType;
+use hyperloglogplus::{HyperLogLog, HyperLogLogPlus};
+
+use crate::utils::FixedRandomState;
+
+pub const HLL_NAME: &str = "hll";
+pub const HLL_MERGE_NAME: &str = "hll_merge";
+
+const DEFAULT_PRECISION: u8 = 14;
+
+pub(crate) type HllStateType = HyperLogLogPlus;
+
+pub struct HllState {
+ hll: HllStateType,
+}
+
+impl std::fmt::Debug for HllState {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "HllState")
+ }
+}
+
+impl Default for HllState {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl HllState {
+ pub fn new() -> Self {
+ Self {
+ // Safety: the DEFAULT_PRECISION is fixed and valid
+ hll: HllStateType::new(DEFAULT_PRECISION, FixedRandomState::new()).unwrap(),
+ }
+ }
+
+ /// Create a UDF for the `hll` function.
+ ///
+ /// `hll` accepts a string column and aggregates the
+ /// values into a HyperLogLog state.
+ pub fn state_udf_impl() -> AggregateUDF {
+ create_udaf(
+ HLL_NAME,
+ vec![DataType::Utf8],
+ Arc::new(DataType::Binary),
+ Volatility::Immutable,
+ Arc::new(Self::create_accumulator),
+ Arc::new(vec![DataType::Binary]),
+ )
+ }
+
+ /// Create a UDF for the `hll_merge` function.
+ ///
+ /// `hll_merge` accepts a binary column of states generated by `hll`
+ /// and merges them into a single state.
+ pub fn merge_udf_impl() -> AggregateUDF {
+ create_udaf(
+ HLL_MERGE_NAME,
+ vec![DataType::Binary],
+ Arc::new(DataType::Binary),
+ Volatility::Immutable,
+ Arc::new(Self::create_merge_accumulator),
+ Arc::new(vec![DataType::Binary]),
+ )
+ }
+
+ fn update(&mut self, value: &str) {
+ self.hll.insert(value);
+ }
+
+ fn merge(&mut self, raw: &[u8]) {
+ if let Ok(serialized) = bincode::deserialize::(raw) {
+ if let Ok(()) = self.hll.merge(&serialized) {
+ return;
+ }
+ }
+ trace!("Warning: Failed to merge HyperLogLog from {:?}", raw);
+ }
+
+ fn create_accumulator(acc_args: AccumulatorArgs) -> DfResult> {
+ let data_type = acc_args.exprs[0].data_type(acc_args.schema)?;
+
+ match data_type {
+ DataType::Utf8 => Ok(Box::new(HllState::new())),
+ other => not_impl_err!("{HLL_NAME} does not support data type: {other}"),
+ }
+ }
+
+ fn create_merge_accumulator(acc_args: AccumulatorArgs) -> DfResult> {
+ let data_type = acc_args.exprs[0].data_type(acc_args.schema)?;
+
+ match data_type {
+ DataType::Binary => Ok(Box::new(HllState::new())),
+ other => not_impl_err!("{HLL_MERGE_NAME} does not support data type: {other}"),
+ }
+ }
+}
+
+impl DfAccumulator for HllState {
+ fn update_batch(&mut self, values: &[ArrayRef]) -> DfResult<()> {
+ let array = &values[0];
+
+ match array.data_type() {
+ DataType::Utf8 => {
+ let string_array = as_string_array(array)?;
+ for value in string_array.iter().flatten() {
+ self.update(value);
+ }
+ }
+ DataType::Binary => {
+ let binary_array = as_binary_array(array)?;
+ for v in binary_array.iter().flatten() {
+ self.merge(v);
+ }
+ }
+ _ => {
+ return not_impl_err!(
+ "HLL functions do not support data type: {}",
+ array.data_type()
+ )
+ }
+ }
+
+ Ok(())
+ }
+
+ fn evaluate(&mut self) -> DfResult {
+ Ok(ScalarValue::Binary(Some(
+ bincode::serialize(&self.hll).map_err(|e| {
+ DataFusionError::Internal(format!("Failed to serialize HyperLogLog: {}", e))
+ })?,
+ )))
+ }
+
+ fn size(&self) -> usize {
+ std::mem::size_of_val(&self.hll)
+ }
+
+ fn state(&mut self) -> DfResult> {
+ Ok(vec![ScalarValue::Binary(Some(
+ bincode::serialize(&self.hll).map_err(|e| {
+ DataFusionError::Internal(format!("Failed to serialize HyperLogLog: {}", e))
+ })?,
+ ))])
+ }
+
+ fn merge_batch(&mut self, states: &[ArrayRef]) -> DfResult<()> {
+ let array = &states[0];
+ let binary_array = as_binary_array(array)?;
+ for v in binary_array.iter().flatten() {
+ self.merge(v);
+ }
+
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use datafusion::arrow::array::{BinaryArray, StringArray};
+
+ use super::*;
+
+ #[test]
+ fn test_hll_basic() {
+ let mut state = HllState::new();
+ state.update("1");
+ state.update("2");
+ state.update("3");
+
+ let result = state.evaluate().unwrap();
+ if let ScalarValue::Binary(Some(bytes)) = result {
+ let mut hll: HllStateType = bincode::deserialize(&bytes).unwrap();
+ assert_eq!(hll.count().trunc() as u32, 3);
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ }
+
+ #[test]
+ fn test_hll_roundtrip() {
+ let mut state = HllState::new();
+ state.update("1");
+ state.update("2");
+
+ // Serialize
+ let serialized = state.evaluate().unwrap();
+
+ // Create new state and merge the serialized data
+ let mut new_state = HllState::new();
+ if let ScalarValue::Binary(Some(bytes)) = &serialized {
+ new_state.merge(bytes);
+
+ // Verify the merged state matches original
+ let result = new_state.evaluate().unwrap();
+ if let ScalarValue::Binary(Some(new_bytes)) = result {
+ let mut original: HllStateType = bincode::deserialize(bytes).unwrap();
+ let mut merged: HllStateType = bincode::deserialize(&new_bytes).unwrap();
+ assert_eq!(original.count(), merged.count());
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ }
+
+ #[test]
+ fn test_hll_batch_update() {
+ let mut state = HllState::new();
+
+ // Test string values
+ let str_values = vec!["a", "b", "c", "d", "e", "f", "g", "h", "i"];
+ let str_array = Arc::new(StringArray::from(str_values)) as ArrayRef;
+ state.update_batch(&[str_array]).unwrap();
+
+ let result = state.evaluate().unwrap();
+ if let ScalarValue::Binary(Some(bytes)) = result {
+ let mut hll: HllStateType = bincode::deserialize(&bytes).unwrap();
+ assert_eq!(hll.count().trunc() as u32, 9);
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ }
+
+ #[test]
+ fn test_hll_merge_batch() {
+ let mut state1 = HllState::new();
+ state1.update("1");
+ let state1_binary = state1.evaluate().unwrap();
+
+ let mut state2 = HllState::new();
+ state2.update("2");
+ let state2_binary = state2.evaluate().unwrap();
+
+ let mut merged_state = HllState::new();
+ if let (ScalarValue::Binary(Some(bytes1)), ScalarValue::Binary(Some(bytes2))) =
+ (&state1_binary, &state2_binary)
+ {
+ let binary_array = Arc::new(BinaryArray::from(vec![
+ bytes1.as_slice(),
+ bytes2.as_slice(),
+ ])) as ArrayRef;
+ merged_state.merge_batch(&[binary_array]).unwrap();
+
+ let result = merged_state.evaluate().unwrap();
+ if let ScalarValue::Binary(Some(bytes)) = result {
+ let mut hll: HllStateType = bincode::deserialize(&bytes).unwrap();
+ assert_eq!(hll.count().trunc() as u32, 2);
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ } else {
+ panic!("Expected binary scalar values");
+ }
+ }
+
+ #[test]
+ fn test_hll_merge_function() {
+ // Create two HLL states with different values
+ let mut state1 = HllState::new();
+ state1.update("1");
+ state1.update("2");
+ let state1_binary = state1.evaluate().unwrap();
+
+ let mut state2 = HllState::new();
+ state2.update("2");
+ state2.update("3");
+ let state2_binary = state2.evaluate().unwrap();
+
+ // Create a merge state and merge both states
+ let mut merge_state = HllState::new();
+ if let (ScalarValue::Binary(Some(bytes1)), ScalarValue::Binary(Some(bytes2))) =
+ (&state1_binary, &state2_binary)
+ {
+ let binary_array = Arc::new(BinaryArray::from(vec![
+ bytes1.as_slice(),
+ bytes2.as_slice(),
+ ])) as ArrayRef;
+ merge_state.update_batch(&[binary_array]).unwrap();
+
+ let result = merge_state.evaluate().unwrap();
+ if let ScalarValue::Binary(Some(bytes)) = result {
+ let mut hll: HllStateType = bincode::deserialize(&bytes).unwrap();
+ // Should have 3 unique values: "1", "2", "3"
+ assert_eq!(hll.count().trunc() as u32, 3);
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ } else {
+ panic!("Expected binary scalar values");
+ }
+ }
+}
diff --git a/src/common/function/src/aggr/uddsketch_state.rs b/src/common/function/src/aggr/uddsketch_state.rs
new file mode 100644
index 0000000000..3ac138736d
--- /dev/null
+++ b/src/common/function/src/aggr/uddsketch_state.rs
@@ -0,0 +1,313 @@
+// Copyright 2023 Greptime Team
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Implementation of the `uddsketch_state` UDAF that generate the state of
+//! UDDSketch for a given set of values.
+//!
+//! The generated state can be used to compute approximate quantiles using
+//! `uddsketch_calc` UDF.
+
+use std::sync::Arc;
+
+use common_query::prelude::*;
+use common_telemetry::trace;
+use datafusion::common::cast::{as_binary_array, as_primitive_array};
+use datafusion::common::not_impl_err;
+use datafusion::error::{DataFusionError, Result as DfResult};
+use datafusion::logical_expr::function::AccumulatorArgs;
+use datafusion::logical_expr::{Accumulator as DfAccumulator, AggregateUDF};
+use datafusion::physical_plan::expressions::Literal;
+use datafusion::prelude::create_udaf;
+use datatypes::arrow::array::ArrayRef;
+use datatypes::arrow::datatypes::{DataType, Float64Type};
+use uddsketch::{SketchHashKey, UDDSketch};
+
+pub const UDDSKETCH_STATE_NAME: &str = "uddsketch_state";
+
+#[derive(Debug)]
+pub struct UddSketchState {
+ uddsketch: UDDSketch,
+}
+
+impl UddSketchState {
+ pub fn new(bucket_size: u64, error_rate: f64) -> Self {
+ Self {
+ uddsketch: UDDSketch::new(bucket_size, error_rate),
+ }
+ }
+
+ pub fn udf_impl() -> AggregateUDF {
+ create_udaf(
+ UDDSKETCH_STATE_NAME,
+ vec![DataType::Int64, DataType::Float64, DataType::Float64],
+ Arc::new(DataType::Binary),
+ Volatility::Immutable,
+ Arc::new(|args| {
+ let (bucket_size, error_rate) = downcast_accumulator_args(args)?;
+ Ok(Box::new(UddSketchState::new(bucket_size, error_rate)))
+ }),
+ Arc::new(vec![DataType::Binary]),
+ )
+ }
+
+ fn update(&mut self, value: f64) {
+ self.uddsketch.add_value(value);
+ }
+
+ fn merge(&mut self, raw: &[u8]) {
+ if let Ok(uddsketch) = bincode::deserialize::(raw) {
+ if uddsketch.count() != 0 {
+ self.uddsketch.merge_sketch(&uddsketch);
+ }
+ } else {
+ trace!("Warning: Failed to deserialize UDDSketch from {:?}", raw);
+ }
+ }
+}
+
+fn downcast_accumulator_args(args: AccumulatorArgs) -> DfResult<(u64, f64)> {
+ let bucket_size = match args.exprs[0]
+ .as_any()
+ .downcast_ref::()
+ .map(|lit| lit.value())
+ {
+ Some(ScalarValue::Int64(Some(value))) => *value as u64,
+ _ => {
+ return not_impl_err!(
+ "{} not supported for bucket size: {}",
+ UDDSKETCH_STATE_NAME,
+ &args.exprs[0]
+ )
+ }
+ };
+
+ let error_rate = match args.exprs[1]
+ .as_any()
+ .downcast_ref::()
+ .map(|lit| lit.value())
+ {
+ Some(ScalarValue::Float64(Some(value))) => *value,
+ _ => {
+ return not_impl_err!(
+ "{} not supported for error rate: {}",
+ UDDSKETCH_STATE_NAME,
+ &args.exprs[1]
+ )
+ }
+ };
+
+ Ok((bucket_size, error_rate))
+}
+
+impl DfAccumulator for UddSketchState {
+ fn update_batch(&mut self, values: &[ArrayRef]) -> DfResult<()> {
+ let array = &values[2]; // the third column is data value
+ let f64_array = as_primitive_array::(array)?;
+ for v in f64_array.iter().flatten() {
+ self.update(v);
+ }
+
+ Ok(())
+ }
+
+ fn evaluate(&mut self) -> DfResult {
+ Ok(ScalarValue::Binary(Some(
+ bincode::serialize(&self.uddsketch).map_err(|e| {
+ DataFusionError::Internal(format!("Failed to serialize UDDSketch: {}", e))
+ })?,
+ )))
+ }
+
+ fn size(&self) -> usize {
+ // Base size of UDDSketch struct fields
+ let mut total_size = std::mem::size_of::() * 3 + // alpha, gamma, values_sum
+ std::mem::size_of::() + // compactions
+ std::mem::size_of::() * 2; // max_buckets, num_values
+
+ // Size of buckets (SketchHashMap)
+ // Each bucket entry contains:
+ // - SketchHashKey (enum with i64/Zero/Invalid variants)
+ // - SketchHashEntry (count: u64, next: SketchHashKey)
+ let bucket_entry_size = std::mem::size_of::() + // key
+ std::mem::size_of::() + // count
+ std::mem::size_of::(); // next
+
+ total_size += self.uddsketch.current_buckets_count() * bucket_entry_size;
+
+ total_size
+ }
+
+ fn state(&mut self) -> DfResult> {
+ Ok(vec![ScalarValue::Binary(Some(
+ bincode::serialize(&self.uddsketch).map_err(|e| {
+ DataFusionError::Internal(format!("Failed to serialize UDDSketch: {}", e))
+ })?,
+ ))])
+ }
+
+ fn merge_batch(&mut self, states: &[ArrayRef]) -> DfResult<()> {
+ let array = &states[0];
+ let binary_array = as_binary_array(array)?;
+ for v in binary_array.iter().flatten() {
+ self.merge(v);
+ }
+
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use datafusion::arrow::array::{BinaryArray, Float64Array};
+
+ use super::*;
+
+ #[test]
+ fn test_uddsketch_state_basic() {
+ let mut state = UddSketchState::new(10, 0.01);
+ state.update(1.0);
+ state.update(2.0);
+ state.update(3.0);
+
+ let result = state.evaluate().unwrap();
+ if let ScalarValue::Binary(Some(bytes)) = result {
+ let deserialized: UDDSketch = bincode::deserialize(&bytes).unwrap();
+ assert_eq!(deserialized.count(), 3);
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ }
+
+ #[test]
+ fn test_uddsketch_state_roundtrip() {
+ let mut state = UddSketchState::new(10, 0.01);
+ state.update(1.0);
+ state.update(2.0);
+
+ // Serialize
+ let serialized = state.evaluate().unwrap();
+
+ // Create new state and merge the serialized data
+ let mut new_state = UddSketchState::new(10, 0.01);
+ if let ScalarValue::Binary(Some(bytes)) = &serialized {
+ new_state.merge(bytes);
+
+ // Verify the merged state matches original by comparing deserialized values
+ let original_sketch: UDDSketch = bincode::deserialize(bytes).unwrap();
+ let new_result = new_state.evaluate().unwrap();
+ if let ScalarValue::Binary(Some(new_bytes)) = new_result {
+ let new_sketch: UDDSketch = bincode::deserialize(&new_bytes).unwrap();
+ assert_eq!(original_sketch.count(), new_sketch.count());
+ assert_eq!(original_sketch.sum(), new_sketch.sum());
+ assert_eq!(original_sketch.mean(), new_sketch.mean());
+ assert_eq!(original_sketch.max_error(), new_sketch.max_error());
+ // Compare a few quantiles to ensure statistical equivalence
+ for q in [0.1, 0.5, 0.9].iter() {
+ assert!(
+ (original_sketch.estimate_quantile(*q) - new_sketch.estimate_quantile(*q))
+ .abs()
+ < 1e-10,
+ "Quantile {} mismatch: original={}, new={}",
+ q,
+ original_sketch.estimate_quantile(*q),
+ new_sketch.estimate_quantile(*q)
+ );
+ }
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ }
+
+ #[test]
+ fn test_uddsketch_state_batch_update() {
+ let mut state = UddSketchState::new(10, 0.01);
+ let values = vec![1.0f64, 2.0, 3.0];
+ let array = Arc::new(Float64Array::from(values)) as ArrayRef;
+
+ state
+ .update_batch(&[array.clone(), array.clone(), array])
+ .unwrap();
+
+ let result = state.evaluate().unwrap();
+ if let ScalarValue::Binary(Some(bytes)) = result {
+ let deserialized: UDDSketch = bincode::deserialize(&bytes).unwrap();
+ assert_eq!(deserialized.count(), 3);
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ }
+
+ #[test]
+ fn test_uddsketch_state_merge_batch() {
+ let mut state1 = UddSketchState::new(10, 0.01);
+ state1.update(1.0);
+ let state1_binary = state1.evaluate().unwrap();
+
+ let mut state2 = UddSketchState::new(10, 0.01);
+ state2.update(2.0);
+ let state2_binary = state2.evaluate().unwrap();
+
+ let mut merged_state = UddSketchState::new(10, 0.01);
+ if let (ScalarValue::Binary(Some(bytes1)), ScalarValue::Binary(Some(bytes2))) =
+ (&state1_binary, &state2_binary)
+ {
+ let binary_array = Arc::new(BinaryArray::from(vec![
+ bytes1.as_slice(),
+ bytes2.as_slice(),
+ ])) as ArrayRef;
+ merged_state.merge_batch(&[binary_array]).unwrap();
+
+ let result = merged_state.evaluate().unwrap();
+ if let ScalarValue::Binary(Some(bytes)) = result {
+ let deserialized: UDDSketch = bincode::deserialize(&bytes).unwrap();
+ assert_eq!(deserialized.count(), 2);
+ } else {
+ panic!("Expected binary scalar value");
+ }
+ } else {
+ panic!("Expected binary scalar values");
+ }
+ }
+
+ #[test]
+ fn test_uddsketch_state_size() {
+ let mut state = UddSketchState::new(10, 0.01);
+ let initial_size = state.size();
+
+ // Add some values to create buckets
+ state.update(1.0);
+ state.update(2.0);
+ state.update(3.0);
+
+ let size_with_values = state.size();
+ assert!(
+ size_with_values > initial_size,
+ "Size should increase after adding values: initial={}, with_values={}",
+ initial_size,
+ size_with_values
+ );
+
+ // Verify size increases with more buckets
+ state.update(10.0); // This should create a new bucket
+ assert!(
+ state.size() > size_with_values,
+ "Size should increase after adding new bucket: prev={}, new={}",
+ size_with_values,
+ state.size()
+ );
+ }
+}
diff --git a/src/common/function/src/function.rs b/src/common/function/src/function.rs
index d7e2d310e2..999361dc19 100644
--- a/src/common/function/src/function.rs
+++ b/src/common/function/src/function.rs
@@ -63,7 +63,7 @@ pub trait Function: fmt::Display + Sync + Send {
fn signature(&self) -> Signature;
/// Evaluate the function, e.g. run/execute the function.
- fn eval(&self, _func_ctx: FunctionContext, _columns: &[VectorRef]) -> Result;
+ fn eval(&self, ctx: &FunctionContext, columns: &[VectorRef]) -> Result;
}
pub type FunctionRef = Arc;
diff --git a/src/common/function/src/function_registry.rs b/src/common/function/src/function_registry.rs
index 0ce3f8abef..5141391693 100644
--- a/src/common/function/src/function_registry.rs
+++ b/src/common/function/src/function_registry.rs
@@ -18,17 +18,20 @@ use std::sync::{Arc, RwLock};
use once_cell::sync::Lazy;
+use crate::admin::AdminFunction;
use crate::function::{AsyncFunctionRef, FunctionRef};
use crate::scalars::aggregate::{AggregateFunctionMetaRef, AggregateFunctions};
use crate::scalars::date::DateFunction;
use crate::scalars::expression::ExpressionFunction;
+use crate::scalars::hll_count::HllCalcFunction;
+use crate::scalars::ip::IpFunctions;
use crate::scalars::json::JsonFunction;
use crate::scalars::matches::MatchesFunction;
use crate::scalars::math::MathFunction;
use crate::scalars::timestamp::TimestampFunction;
+use crate::scalars::uddsketch_calc::UddSketchCalcFunction;
use crate::scalars::vector::VectorFunction;
use crate::system::SystemFunction;
-use crate::table::TableFunction;
#[derive(Default)]
pub struct FunctionRegistry {
@@ -105,6 +108,8 @@ pub static FUNCTION_REGISTRY: Lazy> = Lazy::new(|| {
TimestampFunction::register(&function_registry);
DateFunction::register(&function_registry);
ExpressionFunction::register(&function_registry);
+ UddSketchCalcFunction::register(&function_registry);
+ HllCalcFunction::register(&function_registry);
// Aggregate functions
AggregateFunctions::register(&function_registry);
@@ -114,7 +119,7 @@ pub static FUNCTION_REGISTRY: Lazy> = Lazy::new(|| {
// System and administration functions
SystemFunction::register(&function_registry);
- TableFunction::register(&function_registry);
+ AdminFunction::register(&function_registry);
// Json related functions
JsonFunction::register(&function_registry);
@@ -126,6 +131,9 @@ pub static FUNCTION_REGISTRY: Lazy> = Lazy::new(|| {
#[cfg(feature = "geo")]
crate::scalars::geo::GeoFunctions::register(&function_registry);
+ // Ip functions
+ IpFunctions::register(&function_registry);
+
Arc::new(function_registry)
});
diff --git a/src/common/function/src/lib.rs b/src/common/function/src/lib.rs
index 1c718634dc..ea5e20ee3c 100644
--- a/src/common/function/src/lib.rs
+++ b/src/common/function/src/lib.rs
@@ -15,12 +15,13 @@
#![feature(let_chains)]
#![feature(try_blocks)]
+mod admin;
mod flush_flow;
mod macros;
pub mod scalars;
mod system;
-mod table;
+pub mod aggr;
pub mod function;
pub mod function_registry;
pub mod handlers;
diff --git a/src/common/function/src/scalars.rs b/src/common/function/src/scalars.rs
index 8a2556d733..d655e4b175 100644
--- a/src/common/function/src/scalars.rs
+++ b/src/common/function/src/scalars.rs
@@ -22,7 +22,10 @@ pub mod matches;
pub mod math;
pub mod vector;
+pub(crate) mod hll_count;
+pub mod ip;
#[cfg(test)]
pub(crate) mod test;
pub(crate) mod timestamp;
+pub(crate) mod uddsketch_calc;
pub mod udf;
diff --git a/src/common/function/src/scalars/aggregate.rs b/src/common/function/src/scalars/aggregate.rs
index 81eea378df..65c82ba99c 100644
--- a/src/common/function/src/scalars/aggregate.rs
+++ b/src/common/function/src/scalars/aggregate.rs
@@ -12,24 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-mod argmax;
-mod argmin;
-mod diff;
-mod mean;
-mod polyval;
-mod scipy_stats_norm_cdf;
-mod scipy_stats_norm_pdf;
+//! # Deprecate Warning:
+//!
+//! This module is deprecated and will be removed in the future.
+//! All UDAF implementation here are not maintained and should
+//! not be used before they are refactored into the `src/aggr`
+//! version.
use std::sync::Arc;
-pub use argmax::ArgmaxAccumulatorCreator;
-pub use argmin::ArgminAccumulatorCreator;
use common_query::logical_plan::AggregateFunctionCreatorRef;
-pub use diff::DiffAccumulatorCreator;
-pub use mean::MeanAccumulatorCreator;
-pub use polyval::PolyvalAccumulatorCreator;
-pub use scipy_stats_norm_cdf::ScipyStatsNormCdfAccumulatorCreator;
-pub use scipy_stats_norm_pdf::ScipyStatsNormPdfAccumulatorCreator;
use crate::function_registry::FunctionRegistry;
use crate::scalars::vector::product::VectorProductCreator;
@@ -76,31 +68,22 @@ pub(crate) struct AggregateFunctions;
impl AggregateFunctions {
pub fn register(registry: &FunctionRegistry) {
- macro_rules! register_aggr_func {
- ($name :expr, $arg_count :expr, $creator :ty) => {
- registry.register_aggregate_function(Arc::new(AggregateFunctionMeta::new(
- $name,
- $arg_count,
- Arc::new(|| Arc::new(<$creator>::default())),
- )));
- };
- }
-
- register_aggr_func!("diff", 1, DiffAccumulatorCreator);
- register_aggr_func!("mean", 1, MeanAccumulatorCreator);
- register_aggr_func!("polyval", 2, PolyvalAccumulatorCreator);
- register_aggr_func!("argmax", 1, ArgmaxAccumulatorCreator);
- register_aggr_func!("argmin", 1, ArgminAccumulatorCreator);
- register_aggr_func!("scipystatsnormcdf", 2, ScipyStatsNormCdfAccumulatorCreator);
- register_aggr_func!("scipystatsnormpdf", 2, ScipyStatsNormPdfAccumulatorCreator);
- register_aggr_func!("vec_sum", 1, VectorSumCreator);
- register_aggr_func!("vec_product", 1, VectorProductCreator);
+ registry.register_aggregate_function(Arc::new(AggregateFunctionMeta::new(
+ "vec_sum",
+ 1,
+ Arc::new(|| Arc::new(VectorSumCreator::default())),
+ )));
+ registry.register_aggregate_function(Arc::new(AggregateFunctionMeta::new(
+ "vec_product",
+ 1,
+ Arc::new(|| Arc::new(VectorProductCreator::default())),
+ )));
#[cfg(feature = "geo")]
- register_aggr_func!(
+ registry.register_aggregate_function(Arc::new(AggregateFunctionMeta::new(
"json_encode_path",
3,
- super::geo::encoding::JsonPathEncodeFunctionCreator
- );
+ Arc::new(|| Arc::new(super::geo::encoding::JsonPathEncodeFunctionCreator::default())),
+ )));
}
}
diff --git a/src/common/function/src/scalars/aggregate/argmax.rs b/src/common/function/src/scalars/aggregate/argmax.rs
deleted file mode 100644
index 4749ff9a3a..0000000000
--- a/src/common/function/src/scalars/aggregate/argmax.rs
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright 2023 Greptime Team
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use std::cmp::Ordering;
-use std::sync::Arc;
-
-use common_macro::{as_aggr_func_creator, AggrFuncTypeStore};
-use common_query::error::{
- BadAccumulatorImplSnafu, CreateAccumulatorSnafu, InvalidInputStateSnafu, Result,
-};
-use common_query::logical_plan::accumulator::AggrFuncTypeStore;
-use common_query::logical_plan::{Accumulator, AggregateFunctionCreator};
-use common_query::prelude::*;
-use datatypes::prelude::*;
-use datatypes::types::{LogicalPrimitiveType, WrapperType};
-use datatypes::vectors::{ConstantVector, Helper};
-use datatypes::with_match_primitive_type_id;
-use snafu::ensure;
-
-// https://numpy.org/doc/stable/reference/generated/numpy.argmax.html
-// return the index of the max value
-#[derive(Debug, Default)]
-pub struct Argmax {
- max: Option,
- n: u64,
-}
-
-impl Argmax
-where
- T: PartialOrd + Copy,
-{
- fn update(&mut self, value: T, index: u64) {
- if let Some(Ordering::Less) = self.max.partial_cmp(&Some(value)) {
- self.max = Some(value);
- self.n = index;
- }
- }
-}
-
-impl Accumulator for Argmax
-where
- T: WrapperType + PartialOrd,
-{
- fn state(&self) -> Result> {
- match self.max {
- Some(max) => Ok(vec![max.into(), self.n.into()]),
- _ => Ok(vec![Value::Null, self.n.into()]),
- }
- }
-
- fn update_batch(&mut self, values: &[VectorRef]) -> Result<()> {
- if values.is_empty() {
- return Ok(());
- }
-
- let column = &values[0];
- let column: &::VectorType = if column.is_const() {
- let column: &ConstantVector = unsafe { Helper::static_cast(column) };
- unsafe { Helper::static_cast(column.inner()) }
- } else {
- unsafe { Helper::static_cast(column) }
- };
- for (i, v) in column.iter_data().enumerate() {
- if let Some(value) = v {
- self.update(value, i as u64);
- }
- }
- Ok(())
- }
-
- fn merge_batch(&mut self, states: &[VectorRef]) -> Result<()> {
- if states.is_empty() {
- return Ok(());
- }
-
- ensure!(
- states.len() == 2,
- BadAccumulatorImplSnafu {
- err_msg: "expect 2 states in `merge_batch`",
- }
- );
-
- let max = &states[0];
- let index = &states[1];
- let max: &::VectorType = unsafe { Helper::static_cast(max) };
- let index: &::VectorType = unsafe { Helper::static_cast(index) };
- index
- .iter_data()
- .flatten()
- .zip(max.iter_data().flatten())
- .for_each(|(i, max)| self.update(max, i));
- Ok(())
- }
-
- fn evaluate(&self) -> Result {
- match self.max {
- Some(_) => Ok(self.n.into()),
- _ => Ok(Value::Null),
- }
- }
-}
-
-#[as_aggr_func_creator]
-#[derive(Debug, Default, AggrFuncTypeStore)]
-pub struct ArgmaxAccumulatorCreator {}
-
-impl AggregateFunctionCreator for ArgmaxAccumulatorCreator {
- fn creator(&self) -> AccumulatorCreatorFunction {
- let creator: AccumulatorCreatorFunction = Arc::new(move |types: &[ConcreteDataType]| {
- let input_type = &types[0];
- with_match_primitive_type_id!(
- input_type.logical_type_id(),
- |$S| {
- Ok(Box::new(Argmax::<<$S as LogicalPrimitiveType>::Wrapper>::default()))
- },
- {
- let err_msg = format!(
- "\"ARGMAX\" aggregate function not support data type {:?}",
- input_type.logical_type_id(),
- );
- CreateAccumulatorSnafu { err_msg }.fail()?
- }
- )
- });
- creator
- }
-
- fn output_type(&self) -> Result {
- Ok(ConcreteDataType::uint64_datatype())
- }
-
- fn state_types(&self) -> Result> {
- let input_types = self.input_types()?;
-
- ensure!(input_types.len() == 1, InvalidInputStateSnafu);
-
- Ok(vec![
- input_types.into_iter().next().unwrap(),
- ConcreteDataType::uint64_datatype(),
- ])
- }
-}
-
-#[cfg(test)]
-mod test {
- use datatypes::vectors::Int32Vector;
-
- use super::*;
- #[test]
- fn test_update_batch() {
- // test update empty batch, expect not updating anything
- let mut argmax = Argmax::::default();
- argmax.update_batch(&[]).unwrap();
- assert_eq!(Value::Null, argmax.evaluate().unwrap());
-
- // test update one not-null value
- let mut argmax = Argmax::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![Some(42)]))];
- argmax.update_batch(&v).unwrap();
- assert_eq!(Value::from(0_u64), argmax.evaluate().unwrap());
-
- // test update one null value
- let mut argmax = Argmax::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![Option::::None]))];
- argmax.update_batch(&v).unwrap();
- assert_eq!(Value::Null, argmax.evaluate().unwrap());
-
- // test update no null-value batch
- let mut argmax = Argmax::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![
- Some(-1i32),
- Some(1),
- Some(3),
- ]))];
- argmax.update_batch(&v).unwrap();
- assert_eq!(Value::from(2_u64), argmax.evaluate().unwrap());
-
- // test update null-value batch
- let mut argmax = Argmax::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![
- Some(-2i32),
- None,
- Some(4),
- ]))];
- argmax.update_batch(&v).unwrap();
- assert_eq!(Value::from(2_u64), argmax.evaluate().unwrap());
-
- // test update with constant vector
- let mut argmax = Argmax::::default();
- let v: Vec = vec![Arc::new(ConstantVector::new(
- Arc::new(Int32Vector::from_vec(vec![4])),
- 10,
- ))];
- argmax.update_batch(&v).unwrap();
- assert_eq!(Value::from(0_u64), argmax.evaluate().unwrap());
- }
-}
diff --git a/src/common/function/src/scalars/aggregate/argmin.rs b/src/common/function/src/scalars/aggregate/argmin.rs
deleted file mode 100644
index fe89184460..0000000000
--- a/src/common/function/src/scalars/aggregate/argmin.rs
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2023 Greptime Team
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use std::cmp::Ordering;
-use std::sync::Arc;
-
-use common_macro::{as_aggr_func_creator, AggrFuncTypeStore};
-use common_query::error::{
- BadAccumulatorImplSnafu, CreateAccumulatorSnafu, InvalidInputStateSnafu, Result,
-};
-use common_query::logical_plan::accumulator::AggrFuncTypeStore;
-use common_query::logical_plan::{Accumulator, AggregateFunctionCreator};
-use common_query::prelude::*;
-use datatypes::prelude::*;
-use datatypes::vectors::{ConstantVector, Helper};
-use datatypes::with_match_primitive_type_id;
-use snafu::ensure;
-
-// // https://numpy.org/doc/stable/reference/generated/numpy.argmin.html
-#[derive(Debug, Default)]
-pub struct Argmin {
- min: Option,
- n: u32,
-}
-
-impl Argmin
-where
- T: Copy + PartialOrd,
-{
- fn update(&mut self, value: T, index: u32) {
- match self.min {
- Some(min) => {
- if let Some(Ordering::Greater) = min.partial_cmp(&value) {
- self.min = Some(value);
- self.n = index;
- }
- }
- None => {
- self.min = Some(value);
- self.n = index;
- }
- }
- }
-}
-
-impl Accumulator for Argmin
-where
- T: WrapperType + PartialOrd,
-{
- fn state(&self) -> Result> {
- match self.min {
- Some(min) => Ok(vec![min.into(), self.n.into()]),
- _ => Ok(vec![Value::Null, self.n.into()]),
- }
- }
-
- fn update_batch(&mut self, values: &[VectorRef]) -> Result<()> {
- if values.is_empty() {
- return Ok(());
- }
-
- ensure!(values.len() == 1, InvalidInputStateSnafu);
-
- let column = &values[0];
- let column: &::VectorType = if column.is_const() {
- let column: &ConstantVector = unsafe { Helper::static_cast(column) };
- unsafe { Helper::static_cast(column.inner()) }
- } else {
- unsafe { Helper::static_cast(column) }
- };
- for (i, v) in column.iter_data().enumerate() {
- if let Some(value) = v {
- self.update(value, i as u32);
- }
- }
- Ok(())
- }
-
- fn merge_batch(&mut self, states: &[VectorRef]) -> Result<()> {
- if states.is_empty() {
- return Ok(());
- }
-
- ensure!(
- states.len() == 2,
- BadAccumulatorImplSnafu {
- err_msg: "expect 2 states in `merge_batch`",
- }
- );
-
- let min = &states[0];
- let index = &states[1];
- let min: &::VectorType = unsafe { Helper::static_cast(min) };
- let index: &::VectorType = unsafe { Helper::static_cast(index) };
- index
- .iter_data()
- .flatten()
- .zip(min.iter_data().flatten())
- .for_each(|(i, min)| self.update(min, i));
- Ok(())
- }
-
- fn evaluate(&self) -> Result {
- match self.min {
- Some(_) => Ok(self.n.into()),
- _ => Ok(Value::Null),
- }
- }
-}
-
-#[as_aggr_func_creator]
-#[derive(Debug, Default, AggrFuncTypeStore)]
-pub struct ArgminAccumulatorCreator {}
-
-impl AggregateFunctionCreator for ArgminAccumulatorCreator {
- fn creator(&self) -> AccumulatorCreatorFunction {
- let creator: AccumulatorCreatorFunction = Arc::new(move |types: &[ConcreteDataType]| {
- let input_type = &types[0];
- with_match_primitive_type_id!(
- input_type.logical_type_id(),
- |$S| {
- Ok(Box::new(Argmin::<<$S as LogicalPrimitiveType>::Wrapper>::default()))
- },
- {
- let err_msg = format!(
- "\"ARGMIN\" aggregate function not support data type {:?}",
- input_type.logical_type_id(),
- );
- CreateAccumulatorSnafu { err_msg }.fail()?
- }
- )
- });
- creator
- }
-
- fn output_type(&self) -> Result {
- Ok(ConcreteDataType::uint32_datatype())
- }
-
- fn state_types(&self) -> Result> {
- let input_types = self.input_types()?;
-
- ensure!(input_types.len() == 1, InvalidInputStateSnafu);
-
- Ok(vec![
- input_types.into_iter().next().unwrap(),
- ConcreteDataType::uint32_datatype(),
- ])
- }
-}
-
-#[cfg(test)]
-mod test {
- use datatypes::vectors::Int32Vector;
-
- use super::*;
- #[test]
- fn test_update_batch() {
- // test update empty batch, expect not updating anything
- let mut argmin = Argmin::::default();
- argmin.update_batch(&[]).unwrap();
- assert_eq!(Value::Null, argmin.evaluate().unwrap());
-
- // test update one not-null value
- let mut argmin = Argmin::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![Some(42)]))];
- argmin.update_batch(&v).unwrap();
- assert_eq!(Value::from(0_u32), argmin.evaluate().unwrap());
-
- // test update one null value
- let mut argmin = Argmin::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![Option::::None]))];
- argmin.update_batch(&v).unwrap();
- assert_eq!(Value::Null, argmin.evaluate().unwrap());
-
- // test update no null-value batch
- let mut argmin = Argmin::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![
- Some(-1i32),
- Some(1),
- Some(3),
- ]))];
- argmin.update_batch(&v).unwrap();
- assert_eq!(Value::from(0_u32), argmin.evaluate().unwrap());
-
- // test update null-value batch
- let mut argmin = Argmin::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![
- Some(-2i32),
- None,
- Some(4),
- ]))];
- argmin.update_batch(&v).unwrap();
- assert_eq!(Value::from(0_u32), argmin.evaluate().unwrap());
-
- // test update with constant vector
- let mut argmin = Argmin::::default();
- let v: Vec = vec![Arc::new(ConstantVector::new(
- Arc::new(Int32Vector::from_vec(vec![4])),
- 10,
- ))];
- argmin.update_batch(&v).unwrap();
- assert_eq!(Value::from(0_u32), argmin.evaluate().unwrap());
- }
-}
diff --git a/src/common/function/src/scalars/aggregate/diff.rs b/src/common/function/src/scalars/aggregate/diff.rs
deleted file mode 100644
index 25d1614e4b..0000000000
--- a/src/common/function/src/scalars/aggregate/diff.rs
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2023 Greptime Team
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use std::marker::PhantomData;
-use std::sync::Arc;
-
-use common_macro::{as_aggr_func_creator, AggrFuncTypeStore};
-use common_query::error::{
- CreateAccumulatorSnafu, DowncastVectorSnafu, FromScalarValueSnafu, InvalidInputStateSnafu,
- Result,
-};
-use common_query::logical_plan::accumulator::AggrFuncTypeStore;
-use common_query::logical_plan::{Accumulator, AggregateFunctionCreator};
-use common_query::prelude::*;
-use datatypes::prelude::*;
-use datatypes::value::ListValue;
-use datatypes::vectors::{ConstantVector, Helper, ListVector};
-use datatypes::with_match_primitive_type_id;
-use num_traits::AsPrimitive;
-use snafu::{ensure, OptionExt, ResultExt};
-
-// https://numpy.org/doc/stable/reference/generated/numpy.diff.html
-// I is the input type, O is the output type.
-#[derive(Debug, Default)]
-pub struct Diff {
- values: Vec,
- _phantom: PhantomData,
-}
-
-impl Diff {
- fn push(&mut self, value: I) {
- self.values.push(value);
- }
-}
-
-impl Accumulator for Diff
-where
- I: WrapperType,
- O: WrapperType,
- I::Native: AsPrimitive,
- O::Native: std::ops::Sub,
-{
- fn state(&self) -> Result> {
- let nums = self
- .values
- .iter()
- .map(|&n| n.into())
- .collect::>();
- Ok(vec![Value::List(ListValue::new(
- nums,
- I::LogicalType::build_data_type(),
- ))])
- }
-
- fn update_batch(&mut self, values: &[VectorRef]) -> Result<()> {
- if values.is_empty() {
- return Ok(());
- }
-
- ensure!(values.len() == 1, InvalidInputStateSnafu);
-
- let column = &values[0];
- let mut len = 1;
- let column: &::VectorType = if column.is_const() {
- len = column.len();
- let column: &ConstantVector = unsafe { Helper::static_cast(column) };
- unsafe { Helper::static_cast(column.inner()) }
- } else {
- unsafe { Helper::static_cast(column) }
- };
- (0..len).for_each(|_| {
- for v in column.iter_data().flatten() {
- self.push(v);
- }
- });
- Ok(())
- }
-
- fn merge_batch(&mut self, states: &[VectorRef]) -> Result<()> {
- if states.is_empty() {
- return Ok(());
- }
-
- let states = &states[0];
- let states = states
- .as_any()
- .downcast_ref::()
- .with_context(|| DowncastVectorSnafu {
- err_msg: format!(
- "expect ListVector, got vector type {}",
- states.vector_type_name()
- ),
- })?;
- for state in states.values_iter() {
- if let Some(state) = state.context(FromScalarValueSnafu)? {
- self.update_batch(&[state])?;
- }
- }
- Ok(())
- }
-
- fn evaluate(&self) -> Result {
- if self.values.is_empty() || self.values.len() == 1 {
- return Ok(Value::Null);
- }
- let diff = self
- .values
- .windows(2)
- .map(|x| {
- let native = x[1].into_native().as_() - x[0].into_native().as_();
- O::from_native(native).into()
- })
- .collect::>();
- let diff = Value::List(ListValue::new(diff, O::LogicalType::build_data_type()));
- Ok(diff)
- }
-}
-
-#[as_aggr_func_creator]
-#[derive(Debug, Default, AggrFuncTypeStore)]
-pub struct DiffAccumulatorCreator {}
-
-impl AggregateFunctionCreator for DiffAccumulatorCreator {
- fn creator(&self) -> AccumulatorCreatorFunction {
- let creator: AccumulatorCreatorFunction = Arc::new(move |types: &[ConcreteDataType]| {
- let input_type = &types[0];
- with_match_primitive_type_id!(
- input_type.logical_type_id(),
- |$S| {
- Ok(Box::new(Diff::<<$S as LogicalPrimitiveType>::Wrapper, <<$S as LogicalPrimitiveType>::LargestType as LogicalPrimitiveType>::Wrapper>::default()))
- },
- {
- let err_msg = format!(
- "\"DIFF\" aggregate function not support data type {:?}",
- input_type.logical_type_id(),
- );
- CreateAccumulatorSnafu { err_msg }.fail()?
- }
- )
- });
- creator
- }
-
- fn output_type(&self) -> Result {
- let input_types = self.input_types()?;
- ensure!(input_types.len() == 1, InvalidInputStateSnafu);
- with_match_primitive_type_id!(
- input_types[0].logical_type_id(),
- |$S| {
- Ok(ConcreteDataType::list_datatype($S::default().into()))
- },
- {
- unreachable!()
- }
- )
- }
-
- fn state_types(&self) -> Result> {
- let input_types = self.input_types()?;
- ensure!(input_types.len() == 1, InvalidInputStateSnafu);
- with_match_primitive_type_id!(
- input_types[0].logical_type_id(),
- |$S| {
- Ok(vec![ConcreteDataType::list_datatype($S::default().into())])
- },
- {
- unreachable!()
- }
- )
- }
-}
-
-#[cfg(test)]
-mod test {
- use datatypes::vectors::Int32Vector;
-
- use super::*;
-
- #[test]
- fn test_update_batch() {
- // test update empty batch, expect not updating anything
- let mut diff = Diff::::default();
- diff.update_batch(&[]).unwrap();
- assert!(diff.values.is_empty());
- assert_eq!(Value::Null, diff.evaluate().unwrap());
-
- // test update one not-null value
- let mut diff = Diff::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![Some(42)]))];
- diff.update_batch(&v).unwrap();
- assert_eq!(Value::Null, diff.evaluate().unwrap());
-
- // test update one null value
- let mut diff = Diff::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![Option::::None]))];
- diff.update_batch(&v).unwrap();
- assert_eq!(Value::Null, diff.evaluate().unwrap());
-
- // test update no null-value batch
- let mut diff = Diff::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![
- Some(-1i32),
- Some(1),
- Some(2),
- ]))];
- let values = vec![Value::from(2_i64), Value::from(1_i64)];
- diff.update_batch(&v).unwrap();
- assert_eq!(
- Value::List(ListValue::new(values, ConcreteDataType::int64_datatype())),
- diff.evaluate().unwrap()
- );
-
- // test update null-value batch
- let mut diff = Diff::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![
- Some(-2i32),
- None,
- Some(3),
- Some(4),
- ]))];
- let values = vec![Value::from(5_i64), Value::from(1_i64)];
- diff.update_batch(&v).unwrap();
- assert_eq!(
- Value::List(ListValue::new(values, ConcreteDataType::int64_datatype())),
- diff.evaluate().unwrap()
- );
-
- // test update with constant vector
- let mut diff = Diff::::default();
- let v: Vec = vec![Arc::new(ConstantVector::new(
- Arc::new(Int32Vector::from_vec(vec![4])),
- 4,
- ))];
- let values = vec![Value::from(0_i64), Value::from(0_i64), Value::from(0_i64)];
- diff.update_batch(&v).unwrap();
- assert_eq!(
- Value::List(ListValue::new(values, ConcreteDataType::int64_datatype())),
- diff.evaluate().unwrap()
- );
- }
-}
diff --git a/src/common/function/src/scalars/aggregate/mean.rs b/src/common/function/src/scalars/aggregate/mean.rs
deleted file mode 100644
index ed66c90bdb..0000000000
--- a/src/common/function/src/scalars/aggregate/mean.rs
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 2023 Greptime Team
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use std::marker::PhantomData;
-use std::sync::Arc;
-
-use common_macro::{as_aggr_func_creator, AggrFuncTypeStore};
-use common_query::error::{
- BadAccumulatorImplSnafu, CreateAccumulatorSnafu, DowncastVectorSnafu, InvalidInputStateSnafu,
- Result,
-};
-use common_query::logical_plan::accumulator::AggrFuncTypeStore;
-use common_query::logical_plan::{Accumulator, AggregateFunctionCreator};
-use common_query::prelude::*;
-use datatypes::prelude::*;
-use datatypes::types::WrapperType;
-use datatypes::vectors::{ConstantVector, Float64Vector, Helper, UInt64Vector};
-use datatypes::with_match_primitive_type_id;
-use num_traits::AsPrimitive;
-use snafu::{ensure, OptionExt};
-
-#[derive(Debug, Default)]
-pub struct Mean {
- sum: f64,
- n: u64,
- _phantom: PhantomData,
-}
-
-impl Mean
-where
- T: WrapperType,
- T::Native: AsPrimitive,
-{
- #[inline(always)]
- fn push(&mut self, value: T) {
- self.sum += value.into_native().as_();
- self.n += 1;
- }
-
- #[inline(always)]
- fn update(&mut self, sum: f64, n: u64) {
- self.sum += sum;
- self.n += n;
- }
-}
-
-impl Accumulator for Mean
-where
- T: WrapperType,
- T::Native: AsPrimitive,
-{
- fn state(&self) -> Result> {
- Ok(vec![self.sum.into(), self.n.into()])
- }
-
- fn update_batch(&mut self, values: &[VectorRef]) -> Result<()> {
- if values.is_empty() {
- return Ok(());
- }
-
- ensure!(values.len() == 1, InvalidInputStateSnafu);
- let column = &values[0];
- let mut len = 1;
- let column: &::VectorType = if column.is_const() {
- len = column.len();
- let column: &ConstantVector = unsafe { Helper::static_cast(column) };
- unsafe { Helper::static_cast(column.inner()) }
- } else {
- unsafe { Helper::static_cast(column) }
- };
- (0..len).for_each(|_| {
- for v in column.iter_data().flatten() {
- self.push(v);
- }
- });
-
- Ok(())
- }
-
- fn merge_batch(&mut self, states: &[VectorRef]) -> Result<()> {
- if states.is_empty() {
- return Ok(());
- }
-
- ensure!(
- states.len() == 2,
- BadAccumulatorImplSnafu {
- err_msg: "expect 2 states in `merge_batch`",
- }
- );
-
- let sum = &states[0];
- let n = &states[1];
-
- let sum = sum
- .as_any()
- .downcast_ref::()
- .with_context(|| DowncastVectorSnafu {
- err_msg: format!(
- "expect Float64Vector, got vector type {}",
- sum.vector_type_name()
- ),
- })?;
-
- let n = n
- .as_any()
- .downcast_ref::()
- .with_context(|| DowncastVectorSnafu {
- err_msg: format!(
- "expect UInt64Vector, got vector type {}",
- sum.vector_type_name()
- ),
- })?;
-
- sum.iter_data().zip(n.iter_data()).for_each(|(sum, n)| {
- if let (Some(sum), Some(n)) = (sum, n) {
- self.update(sum, n);
- }
- });
- Ok(())
- }
-
- fn evaluate(&self) -> Result {
- if self.n == 0 {
- return Ok(Value::Null);
- }
- let values = self.sum / self.n as f64;
- Ok(values.into())
- }
-}
-
-#[as_aggr_func_creator]
-#[derive(Debug, Default, AggrFuncTypeStore)]
-pub struct MeanAccumulatorCreator {}
-
-impl AggregateFunctionCreator for MeanAccumulatorCreator {
- fn creator(&self) -> AccumulatorCreatorFunction {
- let creator: AccumulatorCreatorFunction = Arc::new(move |types: &[ConcreteDataType]| {
- let input_type = &types[0];
- with_match_primitive_type_id!(
- input_type.logical_type_id(),
- |$S| {
- Ok(Box::new(Mean::<<$S as LogicalPrimitiveType>::Native>::default()))
- },
- {
- let err_msg = format!(
- "\"MEAN\" aggregate function not support data type {:?}",
- input_type.logical_type_id(),
- );
- CreateAccumulatorSnafu { err_msg }.fail()?
- }
- )
- });
- creator
- }
-
- fn output_type(&self) -> Result {
- let input_types = self.input_types()?;
- ensure!(input_types.len() == 1, InvalidInputStateSnafu);
- Ok(ConcreteDataType::float64_datatype())
- }
-
- fn state_types(&self) -> Result> {
- let input_types = self.input_types()?;
- ensure!(input_types.len() == 1, InvalidInputStateSnafu);
- Ok(vec![
- ConcreteDataType::float64_datatype(),
- ConcreteDataType::uint64_datatype(),
- ])
- }
-}
-
-#[cfg(test)]
-mod test {
- use datatypes::vectors::Int32Vector;
-
- use super::*;
- #[test]
- fn test_update_batch() {
- // test update empty batch, expect not updating anything
- let mut mean = Mean::::default();
- mean.update_batch(&[]).unwrap();
- assert_eq!(Value::Null, mean.evaluate().unwrap());
-
- // test update one not-null value
- let mut mean = Mean::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![Some(42)]))];
- mean.update_batch(&v).unwrap();
- assert_eq!(Value::from(42.0_f64), mean.evaluate().unwrap());
-
- // test update one null value
- let mut mean = Mean::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![Option::::None]))];
- mean.update_batch(&v).unwrap();
- assert_eq!(Value::Null, mean.evaluate().unwrap());
-
- // test update no null-value batch
- let mut mean = Mean::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![
- Some(-1i32),
- Some(1),
- Some(2),
- ]))];
- mean.update_batch(&v).unwrap();
- assert_eq!(Value::from(0.6666666666666666), mean.evaluate().unwrap());
-
- // test update null-value batch
- let mut mean = Mean::::default();
- let v: Vec = vec![Arc::new(Int32Vector::from(vec![
- Some(-2i32),
- None,
- Some(3),
- Some(4),
- ]))];
- mean.update_batch(&v).unwrap();
- assert_eq!(Value::from(1.6666666666666667), mean.evaluate().unwrap());
-
- // test update with constant vector
- let mut mean = Mean::::default();
- let v: Vec = vec![Arc::new(ConstantVector::new(
- Arc::new(Int32Vector::from_vec(vec![4])),
- 10,
- ))];
- mean.update_batch(&v).unwrap();
- assert_eq!(Value::from(4.0), mean.evaluate().unwrap());
- }
-}
diff --git a/src/common/function/src/scalars/aggregate/polyval.rs b/src/common/function/src/scalars/aggregate/polyval.rs
deleted file mode 100644
index bc3986fd0e..0000000000
--- a/src/common/function/src/scalars/aggregate/polyval.rs
+++ /dev/null
@@ -1,329 +0,0 @@
-// Copyright 2023 Greptime Team
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use std::marker::PhantomData;
-use std::sync::Arc;
-
-use common_macro::{as_aggr_func_creator, AggrFuncTypeStore};
-use common_query::error::{
- self, BadAccumulatorImplSnafu, CreateAccumulatorSnafu, DowncastVectorSnafu,
- FromScalarValueSnafu, InvalidInputColSnafu, InvalidInputStateSnafu, Result,
-};
-use common_query::logical_plan::accumulator::AggrFuncTypeStore;
-use common_query::logical_plan::{Accumulator, AggregateFunctionCreator};
-use common_query::prelude::*;
-use datatypes::prelude::*;
-use datatypes::types::{LogicalPrimitiveType, WrapperType};
-use datatypes::value::ListValue;
-use datatypes::vectors::{ConstantVector, Helper, Int64Vector, ListVector};
-use datatypes::with_match_primitive_type_id;
-use num_traits::AsPrimitive;
-use snafu::{ensure, OptionExt, ResultExt};
-
-// https://numpy.org/doc/stable/reference/generated/numpy.polyval.html
-#[derive(Debug, Default)]
-pub struct Polyval
-where
- T: WrapperType,
- T::Native: AsPrimitive,
- PolyT: WrapperType,
- PolyT::Native: std::ops::Mul,
-{
- values: Vec,
- // DataFusion casts constant in into i64 type.
- x: Option,
- _phantom: PhantomData,
-}
-
-impl Polyval
-where
- T: WrapperType,
- T::Native: AsPrimitive,
- PolyT: WrapperType,
- PolyT::Native: std::ops::Mul,
-{
- fn push(&mut self, value: T) {
- self.values.push(value);
- }
-}
-
-impl Accumulator for Polyval
-where
- T: WrapperType,
- T::Native: AsPrimitive,
- PolyT: WrapperType + std::iter::Sum<::Native>,
- PolyT::Native: std::ops::Mul + std::iter::Sum,
- i64: AsPrimitive<::Native>,
-{
- fn state(&self) -> Result> {
- let nums = self
- .values
- .iter()
- .map(|&n| n.into())
- .collect::>();
- Ok(vec![
- Value::List(ListValue::new(nums, T::LogicalType::build_data_type())),
- self.x.into(),
- ])
- }
-
- fn update_batch(&mut self, values: &[VectorRef]) -> Result<()> {
- if values.is_empty() {
- return Ok(());
- }
-
- ensure!(values.len() == 2, InvalidInputStateSnafu);
- ensure!(values[0].len() == values[1].len(), InvalidInputStateSnafu);
- if values[0].len() == 0 {
- return Ok(());
- }
- // This is a unary accumulator, so only one column is provided.
- let column = &values[0];
- let mut len = 1;
- let column: &::VectorType = if column.is_const() {
- len = column.len();
- let column: &ConstantVector = unsafe { Helper::static_cast(column) };
- unsafe { Helper::static_cast(column.inner()) }
- } else {
- unsafe { Helper::static_cast(column) }
- };
- (0..len).for_each(|_| {
- for v in column.iter_data().flatten() {
- self.push(v);
- }
- });
-
- let x = &values[1];
- let x = Helper::check_get_scalar::(x).context(error::InvalidInputTypeSnafu {
- err_msg: "expecting \"POLYVAL\" function's second argument to be a positive integer",
- })?;
- // `get(0)` is safe because we have checked `values[1].len() == values[0].len() != 0`
- let first = x.get(0);
- ensure!(!first.is_null(), InvalidInputColSnafu);
-
- for i in 1..x.len() {
- ensure!(first == x.get(i), InvalidInputColSnafu);
- }
-
- let first = match first {
- Value::Int64(v) => v,
- // unreachable because we have checked `first` is not null and is i64 above
- _ => unreachable!(),
- };
- if let Some(x) = self.x {
- ensure!(x == first, InvalidInputColSnafu);
- } else {
- self.x = Some(first);
- };
- Ok(())
- }
-
- // DataFusion executes accumulators in partitions. In some execution stage, DataFusion will
- // merge states from other accumulators (returned by `state()` method).
- fn merge_batch(&mut self, states: &[VectorRef]) -> Result<()> {
- if states.is_empty() {
- return Ok(());
- }
-
- ensure!(
- states.len() == 2,
- BadAccumulatorImplSnafu {
- err_msg: "expect 2 states in `merge_batch`",
- }
- );
-
- let x = &states[1];
- let x = x
- .as_any()
- .downcast_ref::()
- .with_context(|| DowncastVectorSnafu {
- err_msg: format!(
- "expect Int64Vector, got vector type {}",
- x.vector_type_name()
- ),
- })?;
- let x = x.get(0);
- if x.is_null() {
- return Ok(());
- }
- let x = match x {
- Value::Int64(x) => x,
- _ => unreachable!(),
- };
- self.x = Some(x);
-
- let values = &states[0];
- let values = values
- .as_any()
- .downcast_ref::()
- .with_context(|| DowncastVectorSnafu {
- err_msg: format!(
- "expect ListVector, got vector type {}",
- values.vector_type_name()
- ),
- })?;
- for value in values.values_iter() {
- if let Some(value) = value.context(FromScalarValueSnafu)? {
- let column: &::VectorType = unsafe { Helper::static_cast(&value) };
- for v in column.iter_data().flatten() {
- self.push(v);
- }
- }
- }
-
- Ok(())
- }
-
- // DataFusion expects this function to return the final value of this aggregator.
- fn evaluate(&self) -> Result {
- if self.values.is_empty() {
- return Ok(Value::Null);
- }
- let x = if let Some(x) = self.x {
- x
- } else {
- return Ok(Value::Null);
- };
- let len = self.values.len();
- let polyval: PolyT = self
- .values
- .iter()
- .enumerate()
- .map(|(i, &value)| value.into_native().as_() * x.pow((len - 1 - i) as u32).as_())
- .sum();
- Ok(polyval.into())
- }
-}
-
-#[as_aggr_func_creator]
-#[derive(Debug, Default, AggrFuncTypeStore)]
-pub struct PolyvalAccumulatorCreator {}
-
-impl AggregateFunctionCreator for PolyvalAccumulatorCreator {
- fn creator(&self) -> AccumulatorCreatorFunction {
- let creator: AccumulatorCreatorFunction = Arc::new(move |types: &[ConcreteDataType]| {
- let input_type = &types[0];
- with_match_primitive_type_id!(
- input_type.logical_type_id(),
- |$S| {
- Ok(Box::new(Polyval::<<$S as LogicalPrimitiveType>::Wrapper, <<$S as LogicalPrimitiveType>::LargestType as LogicalPrimitiveType>::Wrapper>::default()))
- },
- {
- let err_msg = format!(
- "\"POLYVAL\" aggregate function not support data type {:?}",
- input_type.logical_type_id(),
- );
- CreateAccumulatorSnafu { err_msg }.fail()?
- }
- )
- });
- creator
- }
-
- fn output_type(&self) -> Result {
- let input_types = self.input_types()?;
- ensure!(input_types.len() == 2, InvalidInputStateSnafu);
- let input_type = self.input_types()?[0].logical_type_id();
- with_match_primitive_type_id!(
- input_type,
- |$S| {
- Ok(<<$S as LogicalPrimitiveType>::LargestType as LogicalPrimitiveType>::build_data_type())
- },
- {
- unreachable!()
- }
- )
- }
-
- fn state_types(&self) -> Result> {
- let input_types = self.input_types()?;
- ensure!(input_types.len() == 2, InvalidInputStateSnafu);
- Ok(vec![
- ConcreteDataType::list_datatype(input_types.into_iter().next().unwrap()),
- ConcreteDataType::int64_datatype(),
- ])
- }
-}
-
-#[cfg(test)]
-mod test {
- use datatypes::vectors::Int32Vector;
-
- use super::*;
- #[test]
- fn test_update_batch() {
- // test update empty batch, expect not updating anything
- let mut polyval = Polyval::::default();
- polyval.update_batch(&[]).unwrap();
- assert!(polyval.values.is_empty());
- assert_eq!(Value::Null, polyval.evaluate().unwrap());
-
- // test update one not-null value
- let mut polyval = Polyval::::default();
- let v: Vec = vec![
- Arc::new(Int32Vector::from(vec![Some(3)])),
- Arc::new(Int64Vector::from(vec![Some(2_i64)])),
- ];
- polyval.update_batch(&v).unwrap();
- assert_eq!(Value::Int64(3), polyval.evaluate().unwrap());
-
- // test update one null value
- let mut polyval = Polyval::::default();
- let v: Vec = vec![
- Arc::new(Int32Vector::from(vec![Option::::None])),
- Arc::new(Int64Vector::from(vec![Some(2_i64)])),
- ];
- polyval.update_batch(&v).unwrap();
- assert_eq!(Value::Null, polyval.evaluate().unwrap());
-
- // test update no null-value batch
- let mut polyval = Polyval::::default();
- let v: Vec = vec![
- Arc::new(Int32Vector::from(vec![Some(3), Some(0), Some(1)])),
- Arc::new(Int64Vector::from(vec![
- Some(2_i64),
- Some(2_i64),
- Some(2_i64),
- ])),
- ];
- polyval.update_batch(&v).unwrap();
- assert_eq!(Value::Int64(13), polyval.evaluate().unwrap());
-
- // test update null-value batch
- let mut polyval = Polyval::::default();
- let v: Vec = vec![
- Arc::new(Int32Vector::from(vec![Some(3), Some(0), None, Some(1)])),
- Arc::new(Int64Vector::from(vec![
- Some(2_i64),
- Some(2_i64),
- Some(2_i64),
- Some(2_i64),
- ])),
- ];
- polyval.update_batch(&v).unwrap();
- assert_eq!(Value::Int64(13), polyval.evaluate().unwrap());
-
- // test update with constant vector
- let mut polyval = Polyval::::default();
- let v: Vec = vec![
- Arc::new(ConstantVector::new(
- Arc::new(Int32Vector::from_vec(vec![4])),
- 2,
- )),
- Arc::new(Int64Vector::from(vec![Some(5_i64), Some(5_i64)])),
- ];
- polyval.update_batch(&v).unwrap();
- assert_eq!(Value::Int64(24), polyval.evaluate().unwrap());
- }
-}
diff --git a/src/common/function/src/scalars/aggregate/scipy_stats_norm_cdf.rs b/src/common/function/src/scalars/aggregate/scipy_stats_norm_cdf.rs
deleted file mode 100644
index 09a9c820d8..0000000000
--- a/src/common/function/src/scalars/aggregate/scipy_stats_norm_cdf.rs
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2023 Greptime Team
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use std::sync::Arc;
-
-use common_macro::{as_aggr_func_creator, AggrFuncTypeStore};
-use common_query::error::{
- self, BadAccumulatorImplSnafu, CreateAccumulatorSnafu, DowncastVectorSnafu,
- FromScalarValueSnafu, GenerateFunctionSnafu, InvalidInputColSnafu, InvalidInputStateSnafu,
- Result,
-};
-use common_query::logical_plan::accumulator::AggrFuncTypeStore;
-use common_query::logical_plan::{Accumulator, AggregateFunctionCreator};
-use common_query::prelude::*;
-use datatypes::prelude::*;
-use datatypes::value::{ListValue, OrderedFloat};
-use datatypes::vectors::{ConstantVector, Float64Vector, Helper, ListVector};
-use datatypes::with_match_primitive_type_id;
-use num_traits::AsPrimitive;
-use snafu::{ensure, OptionExt, ResultExt};
-use statrs::distribution::{ContinuousCDF, Normal};
-use statrs::statistics::Statistics;
-
-// https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.norm.html
-
-#[derive(Debug, Default)]
-pub struct ScipyStatsNormCdf {
- values: Vec,
- x: Option,
-}
-
-impl ScipyStatsNormCdf {
- fn push(&mut self, value: T) {
- self.values.push(value);
- }
-}
-
-impl Accumulator for ScipyStatsNormCdf
-where
- T: WrapperType + std::iter::Sum,
- T::Native: AsPrimitive,
-{
- fn state(&self) -> Result> {
- let nums = self
- .values
- .iter()
- .map(|&x| x.into())
- .collect::>();
- Ok(vec![
- Value::List(ListValue::new(nums, T::LogicalType::build_data_type())),
- self.x.into(),
- ])
- }
-
- fn update_batch(&mut self, values: &[VectorRef]) -> Result<()> {
- if values.is_empty() {
- return Ok(());
- }
-
- ensure!(values.len() == 2, InvalidInputStateSnafu);
- ensure!(values[1].len() == values[0].len(), InvalidInputStateSnafu);
-
- if values[0].len() == 0 {
- return Ok(());
- }
-
- let column = &values[0];
- let mut len = 1;
- let column: &::VectorType = if column.is_const() {
- len = column.len();
- let column: &ConstantVector = unsafe { Helper::static_cast(column) };
- unsafe { Helper::static_cast(column.inner()) }
- } else {
- unsafe { Helper::static_cast(column) }
- };
-
- let x = &values[1];
- let x = Helper::check_get_scalar::(x).context(error::InvalidInputTypeSnafu {
- err_msg: "expecting \"SCIPYSTATSNORMCDF\" function's second argument to be a positive integer",
- })?;
- let first = x.get(0);
- ensure!(!first.is_null(), InvalidInputColSnafu);
- let first = match first {
- Value::Float64(OrderedFloat(v)) => v,
- // unreachable because we have checked `first` is not null and is i64 above
- _ => unreachable!(),
- };
- if let Some(x) = self.x {
- ensure!(x == first, InvalidInputColSnafu);
- } else {
- self.x = Some(first);
- };
-
- (0..len).for_each(|_| {
- for v in column.iter_data().flatten() {
- self.push(v);
- }
- });
- Ok(())
- }
-
- fn merge_batch(&mut self, states: &[VectorRef]) -> Result<()> {
- if states.is_empty() {
- return Ok(());
- }
-
- ensure!(
- states.len() == 2,
- BadAccumulatorImplSnafu {
- err_msg: "expect 2 states in `merge_batch`",
- }
- );
-
- let x = &states[1];
- let x = x
- .as_any()
- .downcast_ref::()
- .with_context(|| DowncastVectorSnafu {
- err_msg: format!(
- "expect Float64Vector, got vector type {}",
- x.vector_type_name()
- ),
- })?;
- let x = x.get(0);
- if x.is_null() {
- return Ok(());
- }
- let x = match x {
- Value::Float64(OrderedFloat(x)) => x,
- _ => unreachable!(),
- };
- self.x = Some(x);
-
- let values = &states[0];
- let values = values
- .as_any()
- .downcast_ref::()
- .with_context(|| DowncastVectorSnafu {
- err_msg: format!(
- "expect ListVector, got vector type {}",
- values.vector_type_name()
- ),
- })?;
- for value in values.values_iter() {
- if let Some(value) = value.context(FromScalarValueSnafu)? {
- let column: &::VectorType = unsafe { Helper::static_cast(&value) };
- for v in column.iter_data().flatten() {
- self.push(v);
- }
- }
- }
- Ok(())
- }
-
- fn evaluate(&self) -> Result {
- let mean = self.values.iter().map(|v| v.into_native().as_()).mean();
- let std_dev = self.values.iter().map(|v| v.into_native().as_()).std_dev();
- if mean.is_nan() || std_dev.is_nan() {
- Ok(Value::Null)
- } else {
- let x = if let Some(x) = self.x {
- x
- } else {
- return Ok(Value::Null);
- };
- let n = Normal::new(mean, std_dev).context(GenerateFunctionSnafu)?;
- Ok(n.cdf(x).into())
- }
- }
-}
-
-#[as_aggr_func_creator]
-#[derive(Debug, Default, AggrFuncTypeStore)]
-pub struct ScipyStatsNormCdfAccumulatorCreator {}
-
-impl AggregateFunctionCreator for ScipyStatsNormCdfAccumulatorCreator {
- fn creator(&self) -> AccumulatorCreatorFunction {
- let creator: AccumulatorCreatorFunction = Arc::new(move |types: &[ConcreteDataType]| {
- let input_type = &types[0];
- with_match_primitive_type_id!(
- input_type.logical_type_id(),
- |$S| {
- Ok(Box::new(ScipyStatsNormCdf::<<$S as LogicalPrimitiveType>::Wrapper>::default()))
- },
- {
- let err_msg = format!(
- "\"SCIPYSTATSNORMCDF\" aggregate function not support data type {:?}",
- input_type.logical_type_id(),
- );
- CreateAccumulatorSnafu { err_msg }.fail()?
- }
- )
- });
- creator
- }
-
- fn output_type(&self) -> Result {
- let input_types = self.input_types()?;
- ensure!(input_types.len() == 2, InvalidInputStateSnafu);
- Ok(ConcreteDataType::float64_datatype())
- }
-
- fn state_types(&self) -> Result> {
- let input_types = self.input_types()?;
- ensure!(input_types.len() == 2, InvalidInputStateSnafu);
- Ok(vec![
- ConcreteDataType::list_datatype(input_types[0].clone()),
- ConcreteDataType::float64_datatype(),
- ])
- }
-}
-
-#[cfg(test)]
-mod test {
- use datatypes::vectors::{Float64Vector, Int32Vector};
-
- use super::*;
- #[test]
- fn test_update_batch() {
- // test update empty batch, expect not updating anything
- let mut scipy_stats_norm_cdf = ScipyStatsNormCdf::::default();
- scipy_stats_norm_cdf.update_batch(&[]).unwrap();
- assert!(scipy_stats_norm_cdf.values.is_empty());
- assert_eq!(Value::Null, scipy_stats_norm_cdf.evaluate().unwrap());
-
- // test update no null-value batch
- let mut scipy_stats_norm_cdf = ScipyStatsNormCdf::::default();
- let v: Vec = vec![
- Arc::new(Int32Vector::from(vec![Some(-1i32), Some(1), Some(2)])),
- Arc::new(Float64Vector::from(vec![
- Some(2.0_f64),
- Some(2.0_f64),
- Some(2.0_f64),
- ])),
- ];
- scipy_stats_norm_cdf.update_batch(&v).unwrap();
- assert_eq!(
- Value::from(0.8086334555398362),
- scipy_stats_norm_cdf.evaluate().unwrap()
- );
-
- // test update null-value batch
- let mut scipy_stats_norm_cdf = ScipyStatsNormCdf::::default();
- let v: Vec = vec![
- Arc::new(Int32Vector::from(vec![Some(-2i32), None, Some(3), Some(4)])),
- Arc::new(Float64Vector::from(vec![
- Some(2.0_f64),
- None,
- Some(2.0_f64),
- Some(2.0_f64),
- ])),
- ];
- scipy_stats_norm_cdf.update_batch(&v).unwrap();
- assert_eq!(
- Value::from(0.5412943699039795),
- scipy_stats_norm_cdf.evaluate().unwrap()
- );
- }
-}
diff --git a/src/common/function/src/scalars/aggregate/scipy_stats_norm_pdf.rs b/src/common/function/src/scalars/aggregate/scipy_stats_norm_pdf.rs
deleted file mode 100644
index 2d5025ea3a..0000000000
--- a/src/common/function/src/scalars/aggregate/scipy_stats_norm_pdf.rs
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright 2023 Greptime Team
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-use std::sync::Arc;
-
-use common_macro::{as_aggr_func_creator, AggrFuncTypeStore};
-use common_query::error::{
- self, BadAccumulatorImplSnafu, CreateAccumulatorSnafu, DowncastVectorSnafu,
- FromScalarValueSnafu, GenerateFunctionSnafu, InvalidInputColSnafu, InvalidInputStateSnafu,
- Result,
-};
-use common_query::logical_plan::accumulator::AggrFuncTypeStore;
-use common_query::logical_plan::{Accumulator, AggregateFunctionCreator};
-use common_query::prelude::*;
-use datatypes::prelude::*;
-use datatypes::value::{ListValue, OrderedFloat};
-use datatypes::vectors::{ConstantVector, Float64Vector, Helper, ListVector};
-use datatypes::with_match_primitive_type_id;
-use num_traits::AsPrimitive;
-use snafu::{ensure, OptionExt, ResultExt};
-use statrs::distribution::{Continuous, Normal};
-use statrs::statistics::Statistics;
-
-// https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.norm.html
-
-#[derive(Debug, Default)]
-pub struct ScipyStatsNormPdf {
- values: Vec,
- x: Option,
-}
-
-impl ScipyStatsNormPdf {
- fn push(&mut self, value: T) {
- self.values.push(value);
- }
-}
-
-impl Accumulator for ScipyStatsNormPdf
-where
- T: WrapperType,
- T::Native: AsPrimitive + std::iter::Sum,
-{
- fn state(&self) -> Result> {
- let nums = self
- .values
- .iter()
- .map(|&x| x.into())
- .collect::>();
- Ok(vec![
- Value::List(ListValue::new(nums, T::LogicalType::build_data_type())),
- self.x.into(),
- ])
- }
-
- fn update_batch(&mut self, values: &[VectorRef]) -> Result<()> {
- if values.is_empty() {
- return Ok(());
- }
-
- ensure!(values.len() == 2, InvalidInputStateSnafu);
- ensure!(values[1].len() == values[0].len(), InvalidInputStateSnafu);
-
- if values[0].len() == 0 {
- return Ok(());
- }
-
- let column = &values[0];
- let mut len = 1;
- let column: &::VectorType = if column.is_const() {
- len = column.len();
- let column: &ConstantVector = unsafe { Helper::static_cast(column) };
- unsafe { Helper::static_cast(column.inner()) }
- } else {
- unsafe { Helper::static_cast(column) }
- };
-
- let x = &values[1];
- let x = Helper::check_get_scalar::(x).context(error::InvalidInputTypeSnafu {
- err_msg: "expecting \"SCIPYSTATSNORMPDF\" function's second argument to be a positive integer",
- })?;
- let first = x.get(0);
- ensure!(!first.is_null(), InvalidInputColSnafu);
- let first = match first {
- Value::Float64(OrderedFloat(v)) => v,
- // unreachable because we have checked `first` is not null and is i64 above
- _ => unreachable!(),
- };
- if let Some(x) = self.x {
- ensure!(x == first, InvalidInputColSnafu);
- } else {
- self.x = Some(first);
- };
-
- (0..len).for_each(|_| {
- for v in column.iter_data().flatten() {
- self.push(v);
- }
- });
- Ok(())
- }
-
- fn merge_batch(&mut self, states: &[VectorRef]) -> Result<()> {
- if states.is_empty() {
- return Ok(());
- }
-
- ensure!(
- states.len() == 2,
- BadAccumulatorImplSnafu {
- err_msg: "expect 2 states in `merge_batch`",
- }
- );
-
- let x = &states[1];
- let x = x
- .as_any()
- .downcast_ref::()
- .with_context(|| DowncastVectorSnafu {
- err_msg: format!(
- "expect Float64Vector, got vector type {}",
- x.vector_type_name()
- ),
- })?;
- let x = x.get(0);
- if x.is_null() {
- return Ok(());
- }
- let x = match x {
- Value::Float64(OrderedFloat(x)) => x,
- _ => unreachable!(),
- };
- self.x = Some(x);
-
- let values = &states[0];
- let values = values
- .as_any()
- .downcast_ref::()
- .with_context(|| DowncastVectorSnafu {
- err_msg: format!(
- "expect ListVector, got vector type {}",
- values.vector_type_name()
- ),
- })?;
- for value in values.values_iter() {
- if let Some(value) = value.context(FromScalarValueSnafu)? {
- let column: &::VectorType = unsafe { Helper::static_cast(&value) };
- for v in column.iter_data().flatten() {
- self.push(v);
- }
- }
- }
- Ok(())
- }
-
- fn evaluate(&self) -> Result {
- let mean = self.values.iter().map(|v| v.into_native().as_()).mean();
- let std_dev = self.values.iter().map(|v| v.into_native().as_()).std_dev();
-
- if mean.is_nan() || std_dev.is_nan() {
- Ok(Value::Null)
- } else {
- let x = if let Some(x) = self.x {
- x
- } else {
- return Ok(Value::Null);
- };
- let n = Normal::new(mean, std_dev).context(GenerateFunctionSnafu)?;
- Ok(n.pdf(x).into())
- }
- }
-}
-
-#[as_aggr_func_creator]
-#[derive(Debug, Default, AggrFuncTypeStore)]
-pub struct ScipyStatsNormPdfAccumulatorCreator {}
-
-impl AggregateFunctionCreator for ScipyStatsNormPdfAccumulatorCreator {
- fn creator(&self) -> AccumulatorCreatorFunction {
- let creator: AccumulatorCreatorFunction = Arc::new(move |types: &[ConcreteDataType]| {
- let input_type = &types[0];
- with_match_primitive_type_id!(
- input_type.logical_type_id(),
- |$S| {
- Ok(Box::new(ScipyStatsNormPdf::<<$S as LogicalPrimitiveType>::Wrapper>::default()))
- },
- {
- let err_msg = format!(
- "\"SCIPYSTATSNORMpdf\" aggregate function not support data type {:?}",
- input_type.logical_type_id(),
- );
- CreateAccumulatorSnafu { err_msg }.fail()?
- }
- )
- });
- creator
- }
-
- fn output_type(&self) -> Result {
- let input_types = self.input_types()?;
- ensure!(input_types.len() == 2, InvalidInputStateSnafu);
- Ok(ConcreteDataType::float64_datatype())
- }
-
- fn state_types(&self) -> Result> {
- let input_types = self.input_types()?;
- ensure!(input_types.len() == 2, InvalidInputStateSnafu);
- Ok(vec![
- ConcreteDataType::list_datatype(input_types[0].clone()),
- ConcreteDataType::float64_datatype(),
- ])
- }
-}
-
-#[cfg(test)]
-mod test {
- use datatypes::vectors::{Float64Vector, Int32Vector};
-
- use super::*;
- #[test]
- fn test_update_batch() {
- // test update empty batch, expect not updating anything
- let mut scipy_stats_norm_pdf = ScipyStatsNormPdf::::default();
- scipy_stats_norm_pdf.update_batch(&[]).unwrap();
- assert!(scipy_stats_norm_pdf.values.is_empty());
- assert_eq!(Value::Null, scipy_stats_norm_pdf.evaluate().unwrap());
-
- // test update no null-value batch
- let mut scipy_stats_norm_pdf = ScipyStatsNormPdf::::default();
- let v: Vec = vec![
- Arc::new(Int32Vector::from(vec![Some(-1i32), Some(1), Some(2)])),
- Arc::new(Float64Vector::from(vec![
- Some(2.0_f64),
- Some(2.0_f64),
- Some(2.0_f64),
- ])),
- ];
- scipy_stats_norm_pdf.update_batch(&v).unwrap();
- assert_eq!(
- Value::from(0.17843340219081558),
- scipy_stats_norm_pdf.evaluate().unwrap()
- );
-
- // test update null-value batch
- let mut scipy_stats_norm_pdf = ScipyStatsNormPdf::::default();
- let v: Vec = vec![
- Arc::new(Int32Vector::from(vec![Some(-2i32), None, Some(3), Some(4)])),
- Arc::new(Float64Vector::from(vec![
- Some(2.0_f64),
- None,
- Some(2.0_f64),
- Some(2.0_f64),
- ])),
- ];
- scipy_stats_norm_pdf.update_batch(&v).unwrap();
- assert_eq!(
- Value::from(0.12343972049858312),
- scipy_stats_norm_pdf.evaluate().unwrap()
- );
- }
-}
diff --git a/src/common/function/src/scalars/date/date_add.rs b/src/common/function/src/scalars/date/date_add.rs
index b2e5e4abe9..76cd3130c2 100644
--- a/src/common/function/src/scalars/date/date_add.rs
+++ b/src/common/function/src/scalars/date/date_add.rs
@@ -58,7 +58,7 @@ impl Function for DateAddFunction {
)
}
- fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result {
+ fn eval(&self, _func_ctx: &FunctionContext, columns: &[VectorRef]) -> Result {
ensure!(
columns.len() == 2,
InvalidFuncArgsSnafu {
@@ -146,7 +146,7 @@ mod tests {
let time_vector = TimestampSecondVector::from(times.clone());
let interval_vector = IntervalDayTimeVector::from_vec(intervals);
let args: Vec = vec![Arc::new(time_vector), Arc::new(interval_vector)];
- let vector = f.eval(FunctionContext::default(), &args).unwrap();
+ let vector = f.eval(&FunctionContext::default(), &args).unwrap();
assert_eq!(4, vector.len());
for (i, _t) in times.iter().enumerate() {
@@ -178,7 +178,7 @@ mod tests {
let date_vector = DateVector::from(dates.clone());
let interval_vector = IntervalYearMonthVector::from_vec(intervals);
let args: Vec = vec![Arc::new(date_vector), Arc::new(interval_vector)];
- let vector = f.eval(FunctionContext::default(), &args).unwrap();
+ let vector = f.eval(&FunctionContext::default(), &args).unwrap();
assert_eq!(4, vector.len());
for (i, _t) in dates.iter().enumerate() {
diff --git a/src/common/function/src/scalars/date/date_format.rs b/src/common/function/src/scalars/date/date_format.rs
index fc82dbe06e..ba1a31b1f6 100644
--- a/src/common/function/src/scalars/date/date_format.rs
+++ b/src/common/function/src/scalars/date/date_format.rs
@@ -53,7 +53,7 @@ impl Function for DateFormatFunction {
)
}
- fn eval(&self, func_ctx: FunctionContext, columns: &[VectorRef]) -> Result {
+ fn eval(&self, func_ctx: &FunctionContext, columns: &[VectorRef]) -> Result