mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2025-12-23 14:40:01 +00:00
Compare commits
361 Commits
async_deco
...
basic_with
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af90fad499 | ||
|
|
22c61432f6 | ||
|
|
91f373e66e | ||
|
|
1d53dd26ae | ||
|
|
01796c9cc0 | ||
|
|
9469a8f8f2 | ||
|
|
2fabe346a1 | ||
|
|
c26138963e | ||
|
|
12648f388a | ||
|
|
2979aa048e | ||
|
|
74222c3070 | ||
|
|
0311db3089 | ||
|
|
e434294a0c | ||
|
|
8d2c1b7f6a | ||
|
|
c50e84095e | ||
|
|
d3d233257d | ||
|
|
fdf32a8f46 | ||
|
|
69870e2762 | ||
|
|
f9f4ac1dca | ||
|
|
99e56af98c | ||
|
|
538b5abaae | ||
|
|
a2b3ad77df | ||
|
|
0eb9e97f79 | ||
|
|
06b1627da5 | ||
|
|
0d4f27a699 | ||
|
|
c4da8bb69d | ||
|
|
0bd8856e2f | ||
|
|
92c5a9f5f4 | ||
|
|
80c5af0ecf | ||
|
|
7afb77fd35 | ||
|
|
0b9af77fe9 | ||
|
|
cbafb6e00b | ||
|
|
744a754246 | ||
|
|
9cd4a2c525 | ||
|
|
180920327b | ||
|
|
ee4f830be6 | ||
|
|
69975f1f71 | ||
|
|
38cac301f2 | ||
|
|
083c22b90a | ||
|
|
fdd164c0fa | ||
|
|
078afb2bd6 | ||
|
|
477e4cc344 | ||
|
|
078d83cec2 | ||
|
|
7705d84d83 | ||
|
|
0d81400bb4 | ||
|
|
1d7ae66e75 | ||
|
|
af6cf999c1 | ||
|
|
54869a1329 | ||
|
|
3104d49434 | ||
|
|
b4d00fb499 | ||
|
|
4ae6df607b | ||
|
|
183e1dc031 | ||
|
|
886c2dba76 | ||
|
|
4e615e8906 | ||
|
|
9afc61f778 | ||
|
|
d22084e90c | ||
|
|
5e9b5d981f | ||
|
|
b01fce95a0 | ||
|
|
9fbcf9b7e7 | ||
|
|
dc3591655e | ||
|
|
aca7ad82b1 | ||
|
|
10fa6d8736 | ||
|
|
92422dafca | ||
|
|
53752e4f6c | ||
|
|
40bfa98d4b | ||
|
|
49986b03d6 | ||
|
|
493440a802 | ||
|
|
77e2fee755 | ||
|
|
b85429c0f1 | ||
|
|
3d942f6763 | ||
|
|
3901863432 | ||
|
|
27e339f628 | ||
|
|
cf2712e6f4 | ||
|
|
4b71e493f7 | ||
|
|
bf496e05cc | ||
|
|
513ca951ee | ||
|
|
791f530a78 | ||
|
|
1de6d8c619 | ||
|
|
a4d0420727 | ||
|
|
fc6300a2ba | ||
|
|
f55af5838c | ||
|
|
5a0da5b6bb | ||
|
|
d5f0006864 | ||
|
|
ede82331b2 | ||
|
|
56e696bd55 | ||
|
|
bc0cdf62ba | ||
|
|
eaf7b4b9dd | ||
|
|
7ae0e150e5 | ||
|
|
43c30b55ae | ||
|
|
153e80450a | ||
|
|
1624dc41c5 | ||
|
|
300262562b | ||
|
|
b2377d4b87 | ||
|
|
8d36ffb4e1 | ||
|
|
955ad644f7 | ||
|
|
c2e3c3d398 | ||
|
|
400229c384 | ||
|
|
cd9b6990bf | ||
|
|
a56e6e04c2 | ||
|
|
d324439014 | ||
|
|
038acda7cd | ||
|
|
a0d89c9ed1 | ||
|
|
3a5534722c | ||
|
|
1010a0c2ad | ||
|
|
f46cdbd66b | ||
|
|
864cc117b3 | ||
|
|
0ea9ab385d | ||
|
|
c7e9485534 | ||
|
|
57b53211d9 | ||
|
|
01076069a3 | ||
|
|
73b4b710cd | ||
|
|
14b655ea57 | ||
|
|
c780746171 | ||
|
|
1f62c3b545 | ||
|
|
5a9023d6b3 | ||
|
|
209f8371f2 | ||
|
|
30f1cbf0bf | ||
|
|
bbb6f8685e | ||
|
|
29540b55ee | ||
|
|
ca1641d1c4 | ||
|
|
b275793b36 | ||
|
|
265b144ca2 | ||
|
|
2ce5631d3c | ||
|
|
36d9346ffc | ||
|
|
36ff36e094 | ||
|
|
9cf5f0e940 | ||
|
|
2a0e9c930d | ||
|
|
787a50631b | ||
|
|
50df275097 | ||
|
|
8dca448baf | ||
|
|
828f69a562 | ||
|
|
04cae4b21e | ||
|
|
79f584316e | ||
|
|
6ab0f0cc5c | ||
|
|
8685ceb232 | ||
|
|
b442414422 | ||
|
|
51f2cb1053 | ||
|
|
fbf50c594e | ||
|
|
5739302845 | ||
|
|
148d96fc38 | ||
|
|
e787007eb5 | ||
|
|
60acf28f3c | ||
|
|
06126147d2 | ||
|
|
cce1285b16 | ||
|
|
4b5ab75312 | ||
|
|
56f31d5933 | ||
|
|
df31f0b9ec | ||
|
|
07e84a28a3 | ||
|
|
f298a110f9 | ||
|
|
6a5936468e | ||
|
|
49a936e2e1 | ||
|
|
41a706c7cd | ||
|
|
d6e98206b6 | ||
|
|
7b4df6343f | ||
|
|
bb4890cff8 | ||
|
|
b0ad3f0bb4 | ||
|
|
8726bf9f7a | ||
|
|
44e75b142d | ||
|
|
a706edbb73 | ||
|
|
0bf07d7f91 | ||
|
|
b8f9915d47 | ||
|
|
6166f2072e | ||
|
|
8338aa14d3 | ||
|
|
a18dc632c8 | ||
|
|
a9f486e493 | ||
|
|
06e8d46ba9 | ||
|
|
89661c0626 | ||
|
|
a3ae2d7b52 | ||
|
|
789f585a7f | ||
|
|
133f404547 | ||
|
|
bdd44fd7ec | ||
|
|
13ac4d5048 | ||
|
|
c6448a6ccc | ||
|
|
86aae6733d | ||
|
|
ed1ce8438f | ||
|
|
4b921b8425 | ||
|
|
1a517ec8ac | ||
|
|
21044c7339 | ||
|
|
8e1ec2a201 | ||
|
|
5ed0a095b6 | ||
|
|
3c943be189 | ||
|
|
eeba466717 | ||
|
|
2ff54486d3 | ||
|
|
66e2242e46 | ||
|
|
489b16ae30 | ||
|
|
85d564b0fb | ||
|
|
d5026f3491 | ||
|
|
e30753fc31 | ||
|
|
b476584f56 | ||
|
|
ff3a46b1d0 | ||
|
|
a533ac2555 | ||
|
|
cc5629b4a1 | ||
|
|
f3d000f6ec | ||
|
|
9557b76224 | ||
|
|
a0900f5b90 | ||
|
|
45a05fb08c | ||
|
|
71db79c8d6 | ||
|
|
79ed7bbc44 | ||
|
|
02e9a66d7a | ||
|
|
55cadcd2c0 | ||
|
|
8c4796734a | ||
|
|
919956999b | ||
|
|
7e5f6cbeae | ||
|
|
5c07f0dec7 | ||
|
|
9fb0487e67 | ||
|
|
6e407ae4b9 | ||
|
|
bcefc6b83f | ||
|
|
0f77135ef9 | ||
|
|
0a4594c9e2 | ||
|
|
d9437c6da7 | ||
|
|
35f4fa3c3e | ||
|
|
60e4607b64 | ||
|
|
3b8c6d5ce3 | ||
|
|
7a8e1bc3f9 | ||
|
|
ee07b9bfa8 | ||
|
|
90ffaa8a62 | ||
|
|
56f319a707 | ||
|
|
9df493988b | ||
|
|
ad1b77ab04 | ||
|
|
e817a65d75 | ||
|
|
41814bb49f | ||
|
|
1e394af583 | ||
|
|
a9065f5319 | ||
|
|
b8c6f1c8ed | ||
|
|
115e5a03a8 | ||
|
|
a5c443f734 | ||
|
|
5287b87925 | ||
|
|
4d38d8aa1e | ||
|
|
cc1b297831 | ||
|
|
e4556ce12b | ||
|
|
0f252c4d24 | ||
|
|
c58217ccec | ||
|
|
d27b9fc3a1 | ||
|
|
fdab5d198e | ||
|
|
7274ceba30 | ||
|
|
55c9a0de42 | ||
|
|
0fb9e1995e | ||
|
|
799c7cbfa9 | ||
|
|
dcf1a486f6 | ||
|
|
6700c0762d | ||
|
|
032df4c533 | ||
|
|
7b13376239 | ||
|
|
2189631efd | ||
|
|
96fbce1797 | ||
|
|
8d485e9be0 | ||
|
|
6a50d71920 | ||
|
|
747b71bf74 | ||
|
|
c522893552 | ||
|
|
7ddd7a9888 | ||
|
|
e3675494b4 | ||
|
|
7cd6b0f04b | ||
|
|
be837ddc24 | ||
|
|
5b0c75c85f | ||
|
|
5a36fa5e18 | ||
|
|
84e2bc52c2 | ||
|
|
71255b3cbd | ||
|
|
382eacdc13 | ||
|
|
74d8fd00a4 | ||
|
|
dce5e35d7c | ||
|
|
54ef29f394 | ||
|
|
e052c65a58 | ||
|
|
e23979df9f | ||
|
|
4b82ec7409 | ||
|
|
08d0f31865 | ||
|
|
dda7496265 | ||
|
|
df362be012 | ||
|
|
2ebe005e3c | ||
|
|
746b4e2369 | ||
|
|
6c66ec3ffc | ||
|
|
95d0c650ec | ||
|
|
311727939d | ||
|
|
7e3cad8a55 | ||
|
|
72625958bf | ||
|
|
7ea04817bd | ||
|
|
c26e165887 | ||
|
|
7335293983 | ||
|
|
609e228852 | ||
|
|
c16bae32c4 | ||
|
|
ee4fe9d273 | ||
|
|
6e6e335a81 | ||
|
|
981d51785b | ||
|
|
cf1eda28aa | ||
|
|
cf1440fc32 | ||
|
|
21a209f7ba | ||
|
|
917510ffd0 | ||
|
|
7b48ef1e97 | ||
|
|
ac0f9ab575 | ||
|
|
f2907bb009 | ||
|
|
1695919ee7 | ||
|
|
eab702cc02 | ||
|
|
dd63068df6 | ||
|
|
f73b61e767 | ||
|
|
2acecd3620 | ||
|
|
f797de3497 | ||
|
|
d53afa849d | ||
|
|
3aebfc1716 | ||
|
|
dbb79c9671 | ||
|
|
054056fcbb | ||
|
|
aa486db8b7 | ||
|
|
4ef9afd8d8 | ||
|
|
f9221e9e66 | ||
|
|
6c26fe9c80 | ||
|
|
33c9fb737c | ||
|
|
68ce796771 | ||
|
|
d701c18150 | ||
|
|
d3a60d8821 | ||
|
|
5d688c6565 | ||
|
|
41aee1f1b7 | ||
|
|
c5b55fd8cf | ||
|
|
8051dbbc31 | ||
|
|
2d3192984d | ||
|
|
bef45ed0e8 | ||
|
|
a9e990768d | ||
|
|
7e1ba49d3d | ||
|
|
737558ef53 | ||
|
|
dbc25dd8da | ||
|
|
76a58a07e1 | ||
|
|
c2ba7fb16c | ||
|
|
09ef24fd75 | ||
|
|
9b7b012620 | ||
|
|
898e0bd828 | ||
|
|
2b4ed43692 | ||
|
|
8f2ae4e136 | ||
|
|
0cd219a5d2 | ||
|
|
2b2ea5bf72 | ||
|
|
e107bd5529 | ||
|
|
a31f0e255b | ||
|
|
40b52f3b13 | ||
|
|
f13a43647a | ||
|
|
7bcb01d269 | ||
|
|
e81213728b | ||
|
|
d88482b996 | ||
|
|
3b547d9d13 | ||
|
|
278553fc3f | ||
|
|
a36901a653 | ||
|
|
c4ac242c69 | ||
|
|
9f9307de73 | ||
|
|
c77ce958a3 | ||
|
|
5ad2d8b3b8 | ||
|
|
2724c3c142 | ||
|
|
4eb0771afe | ||
|
|
a0739a96e4 | ||
|
|
77ccf1eac8 | ||
|
|
1dc4a196bf | ||
|
|
2431cd3bdf | ||
|
|
cd730e0486 | ||
|
|
a19441bed8 | ||
|
|
162e3b8620 | ||
|
|
83642dab87 | ||
|
|
46070958c9 | ||
|
|
eea8b1c730 | ||
|
|
1ab4ddab8d | ||
|
|
9e63018198 | ||
|
|
594bec8c36 | ||
|
|
1586732d20 | ||
|
|
16fddd97a7 | ||
|
|
2260782c12 | ||
|
|
09dacc8e9b | ||
|
|
dec439db2b | ||
|
|
dc76571166 | ||
|
|
3e17f8c426 |
@@ -1,15 +0,0 @@
|
|||||||
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
|
||||||
language: "en-US"
|
|
||||||
early_access: false
|
|
||||||
reviews:
|
|
||||||
profile: "chill"
|
|
||||||
request_changes_workflow: false
|
|
||||||
high_level_summary: true
|
|
||||||
poem: true
|
|
||||||
review_status: true
|
|
||||||
collapse_walkthrough: false
|
|
||||||
auto_review:
|
|
||||||
enabled: false
|
|
||||||
drafts: false
|
|
||||||
chat:
|
|
||||||
auto_reply: true
|
|
||||||
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
* @GreptimeTeam/db-approver
|
* @GreptimeTeam/db-approver
|
||||||
|
|
||||||
## [Module] Databse Engine
|
## [Module] Database Engine
|
||||||
/src/index @zhongzc
|
/src/index @zhongzc
|
||||||
/src/mito2 @evenyag @v0y4g3r @waynexia
|
/src/mito2 @evenyag @v0y4g3r @waynexia
|
||||||
/src/query @evenyag
|
/src/query @evenyag
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ runs:
|
|||||||
uses: ./.github/actions/build-greptime-binary
|
uses: ./.github/actions/build-greptime-binary
|
||||||
with:
|
with:
|
||||||
base-image: ubuntu
|
base-image: ubuntu
|
||||||
features: servers/dashboard,pg_kvbackend,mysql_kvbackend
|
features: servers/dashboard
|
||||||
cargo-profile: ${{ inputs.cargo-profile }}
|
cargo-profile: ${{ inputs.cargo-profile }}
|
||||||
artifacts-dir: greptime-linux-${{ inputs.arch }}-${{ inputs.version }}
|
artifacts-dir: greptime-linux-${{ inputs.arch }}-${{ inputs.version }}
|
||||||
version: ${{ inputs.version }}
|
version: ${{ inputs.version }}
|
||||||
@@ -70,7 +70,7 @@ runs:
|
|||||||
if: ${{ inputs.arch == 'amd64' && inputs.dev-mode == 'false' }} # Builds greptime for centos if the host machine is amd64.
|
if: ${{ inputs.arch == 'amd64' && inputs.dev-mode == 'false' }} # Builds greptime for centos if the host machine is amd64.
|
||||||
with:
|
with:
|
||||||
base-image: centos
|
base-image: centos
|
||||||
features: servers/dashboard,pg_kvbackend,mysql_kvbackend
|
features: servers/dashboard
|
||||||
cargo-profile: ${{ inputs.cargo-profile }}
|
cargo-profile: ${{ inputs.cargo-profile }}
|
||||||
artifacts-dir: greptime-linux-${{ inputs.arch }}-centos-${{ inputs.version }}
|
artifacts-dir: greptime-linux-${{ inputs.arch }}-centos-${{ inputs.version }}
|
||||||
version: ${{ inputs.version }}
|
version: ${{ inputs.version }}
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ runs:
|
|||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: make test sqlness-test
|
run: make test sqlness-test
|
||||||
env:
|
env:
|
||||||
RUSTUP_WINDOWS_PATH_ADD_BIN: 1 # Workaround for https://github.com/nextest-rs/nextest/issues/1493
|
|
||||||
RUST_BACKTRACE: 1
|
RUST_BACKTRACE: 1
|
||||||
SQLNESS_OPTS: "--preserve-state"
|
SQLNESS_OPTS: "--preserve-state"
|
||||||
|
|
||||||
|
|||||||
@@ -64,11 +64,11 @@ inputs:
|
|||||||
upload-max-retry-times:
|
upload-max-retry-times:
|
||||||
description: Max retry times for uploading artifacts to S3
|
description: Max retry times for uploading artifacts to S3
|
||||||
required: false
|
required: false
|
||||||
default: "20"
|
default: "30"
|
||||||
upload-retry-timeout:
|
upload-retry-timeout:
|
||||||
description: Timeout for uploading artifacts to S3
|
description: Timeout for uploading artifacts to S3
|
||||||
required: false
|
required: false
|
||||||
default: "30" # minutes
|
default: "120" # minutes
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ inputs:
|
|||||||
default: 2
|
default: 2
|
||||||
description: "Number of Datanode replicas"
|
description: "Number of Datanode replicas"
|
||||||
meta-replicas:
|
meta-replicas:
|
||||||
default: 1
|
default: 2
|
||||||
description: "Number of Metasrv replicas"
|
description: "Number of Metasrv replicas"
|
||||||
image-registry:
|
image-registry:
|
||||||
default: "docker.io"
|
default: "docker.io"
|
||||||
@@ -59,7 +59,7 @@ runs:
|
|||||||
--set base.podTemplate.main.resources.requests.cpu=50m \
|
--set base.podTemplate.main.resources.requests.cpu=50m \
|
||||||
--set base.podTemplate.main.resources.requests.memory=256Mi \
|
--set base.podTemplate.main.resources.requests.memory=256Mi \
|
||||||
--set base.podTemplate.main.resources.limits.cpu=2000m \
|
--set base.podTemplate.main.resources.limits.cpu=2000m \
|
||||||
--set base.podTemplate.main.resources.limits.memory=2Gi \
|
--set base.podTemplate.main.resources.limits.memory=3Gi \
|
||||||
--set frontend.replicas=${{ inputs.frontend-replicas }} \
|
--set frontend.replicas=${{ inputs.frontend-replicas }} \
|
||||||
--set datanode.replicas=${{ inputs.datanode-replicas }} \
|
--set datanode.replicas=${{ inputs.datanode-replicas }} \
|
||||||
--set meta.replicas=${{ inputs.meta-replicas }} \
|
--set meta.replicas=${{ inputs.meta-replicas }} \
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ meta:
|
|||||||
provider = "kafka"
|
provider = "kafka"
|
||||||
broker_endpoints = ["kafka.kafka-cluster.svc.cluster.local:9092"]
|
broker_endpoints = ["kafka.kafka-cluster.svc.cluster.local:9092"]
|
||||||
num_topics = 3
|
num_topics = 3
|
||||||
|
auto_prune_interval = "30s"
|
||||||
|
trigger_flush_threshold = 100
|
||||||
|
|
||||||
[datanode]
|
[datanode]
|
||||||
[datanode.client]
|
[datanode.client]
|
||||||
@@ -21,7 +22,7 @@ datanode:
|
|||||||
[wal]
|
[wal]
|
||||||
provider = "kafka"
|
provider = "kafka"
|
||||||
broker_endpoints = ["kafka.kafka-cluster.svc.cluster.local:9092"]
|
broker_endpoints = ["kafka.kafka-cluster.svc.cluster.local:9092"]
|
||||||
linger = "2ms"
|
overwrite_entry_start_id = true
|
||||||
frontend:
|
frontend:
|
||||||
configData: |-
|
configData: |-
|
||||||
[runtime]
|
[runtime]
|
||||||
|
|||||||
29
.github/scripts/create-version.sh
vendored
29
.github/scripts/create-version.sh
vendored
@@ -8,24 +8,25 @@ set -e
|
|||||||
# - If it's a nightly build, the version is 'nightly-YYYYMMDD-$(git rev-parse --short HEAD)', like 'nightly-20230712-e5b243c'.
|
# - If it's a nightly build, the version is 'nightly-YYYYMMDD-$(git rev-parse --short HEAD)', like 'nightly-20230712-e5b243c'.
|
||||||
# create_version ${GIHUB_EVENT_NAME} ${NEXT_RELEASE_VERSION} ${NIGHTLY_RELEASE_PREFIX}
|
# create_version ${GIHUB_EVENT_NAME} ${NEXT_RELEASE_VERSION} ${NIGHTLY_RELEASE_PREFIX}
|
||||||
function create_version() {
|
function create_version() {
|
||||||
# Read from envrionment variables.
|
# Read from environment variables.
|
||||||
if [ -z "$GITHUB_EVENT_NAME" ]; then
|
if [ -z "$GITHUB_EVENT_NAME" ]; then
|
||||||
echo "GITHUB_EVENT_NAME is empty"
|
echo "GITHUB_EVENT_NAME is empty" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$NEXT_RELEASE_VERSION" ]; then
|
if [ -z "$NEXT_RELEASE_VERSION" ]; then
|
||||||
echo "NEXT_RELEASE_VERSION is empty"
|
echo "NEXT_RELEASE_VERSION is empty, use version from Cargo.toml" >&2
|
||||||
exit 1
|
# NOTE: Need a `v` prefix for the version string.
|
||||||
|
export NEXT_RELEASE_VERSION=v$(grep '^version = ' Cargo.toml | cut -d '"' -f 2 | head -n 1)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$NIGHTLY_RELEASE_PREFIX" ]; then
|
if [ -z "$NIGHTLY_RELEASE_PREFIX" ]; then
|
||||||
echo "NIGHTLY_RELEASE_PREFIX is empty"
|
echo "NIGHTLY_RELEASE_PREFIX is empty" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Reuse $NEXT_RELEASE_VERSION to identify whether it's a nightly build.
|
# Reuse $NEXT_RELEASE_VERSION to identify whether it's a nightly build.
|
||||||
# It will be like 'nigtly-20230808-7d0d8dc6'.
|
# It will be like 'nightly-20230808-7d0d8dc6'.
|
||||||
if [ "$NEXT_RELEASE_VERSION" = nightly ]; then
|
if [ "$NEXT_RELEASE_VERSION" = nightly ]; then
|
||||||
echo "$NIGHTLY_RELEASE_PREFIX-$(date "+%Y%m%d")-$(git rev-parse --short HEAD)"
|
echo "$NIGHTLY_RELEASE_PREFIX-$(date "+%Y%m%d")-$(git rev-parse --short HEAD)"
|
||||||
exit 0
|
exit 0
|
||||||
@@ -35,7 +36,7 @@ function create_version() {
|
|||||||
# It will be like 'dev-2023080819-f0e7216c'.
|
# It will be like 'dev-2023080819-f0e7216c'.
|
||||||
if [ "$NEXT_RELEASE_VERSION" = dev ]; then
|
if [ "$NEXT_RELEASE_VERSION" = dev ]; then
|
||||||
if [ -z "$COMMIT_SHA" ]; then
|
if [ -z "$COMMIT_SHA" ]; then
|
||||||
echo "COMMIT_SHA is empty in dev build"
|
echo "COMMIT_SHA is empty in dev build" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "dev-$(date "+%Y%m%d-%s")-$(echo "$COMMIT_SHA" | cut -c1-8)"
|
echo "dev-$(date "+%Y%m%d-%s")-$(echo "$COMMIT_SHA" | cut -c1-8)"
|
||||||
@@ -45,7 +46,7 @@ function create_version() {
|
|||||||
# Note: Only output 'version=xxx' to stdout when everything is ok, so that it can be used in GitHub Actions Outputs.
|
# Note: Only output 'version=xxx' to stdout when everything is ok, so that it can be used in GitHub Actions Outputs.
|
||||||
if [ "$GITHUB_EVENT_NAME" = push ]; then
|
if [ "$GITHUB_EVENT_NAME" = push ]; then
|
||||||
if [ -z "$GITHUB_REF_NAME" ]; then
|
if [ -z "$GITHUB_REF_NAME" ]; then
|
||||||
echo "GITHUB_REF_NAME is empty in push event"
|
echo "GITHUB_REF_NAME is empty in push event" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "$GITHUB_REF_NAME"
|
echo "$GITHUB_REF_NAME"
|
||||||
@@ -54,15 +55,15 @@ function create_version() {
|
|||||||
elif [ "$GITHUB_EVENT_NAME" = schedule ]; then
|
elif [ "$GITHUB_EVENT_NAME" = schedule ]; then
|
||||||
echo "$NEXT_RELEASE_VERSION-$NIGHTLY_RELEASE_PREFIX-$(date "+%Y%m%d")"
|
echo "$NEXT_RELEASE_VERSION-$NIGHTLY_RELEASE_PREFIX-$(date "+%Y%m%d")"
|
||||||
else
|
else
|
||||||
echo "Unsupported GITHUB_EVENT_NAME: $GITHUB_EVENT_NAME"
|
echo "Unsupported GITHUB_EVENT_NAME: $GITHUB_EVENT_NAME" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# You can run as following examples:
|
# You can run as following examples:
|
||||||
# GITHUB_EVENT_NAME=push NEXT_RELEASE_VERSION=v0.4.0 NIGHTLY_RELEASE_PREFIX=nigtly GITHUB_REF_NAME=v0.3.0 ./create-version.sh
|
# GITHUB_EVENT_NAME=push NEXT_RELEASE_VERSION=v0.4.0 NIGHTLY_RELEASE_PREFIX=nightly GITHUB_REF_NAME=v0.3.0 ./create-version.sh
|
||||||
# GITHUB_EVENT_NAME=workflow_dispatch NEXT_RELEASE_VERSION=v0.4.0 NIGHTLY_RELEASE_PREFIX=nigtly ./create-version.sh
|
# GITHUB_EVENT_NAME=workflow_dispatch NEXT_RELEASE_VERSION=v0.4.0 NIGHTLY_RELEASE_PREFIX=nightly ./create-version.sh
|
||||||
# GITHUB_EVENT_NAME=schedule NEXT_RELEASE_VERSION=v0.4.0 NIGHTLY_RELEASE_PREFIX=nigtly ./create-version.sh
|
# GITHUB_EVENT_NAME=schedule NEXT_RELEASE_VERSION=v0.4.0 NIGHTLY_RELEASE_PREFIX=nightly ./create-version.sh
|
||||||
# GITHUB_EVENT_NAME=schedule NEXT_RELEASE_VERSION=nightly NIGHTLY_RELEASE_PREFIX=nigtly ./create-version.sh
|
# GITHUB_EVENT_NAME=schedule NEXT_RELEASE_VERSION=nightly NIGHTLY_RELEASE_PREFIX=nightly ./create-version.sh
|
||||||
# GITHUB_EVENT_NAME=workflow_dispatch COMMIT_SHA=f0e7216c4bb6acce9b29a21ec2d683be2e3f984a NEXT_RELEASE_VERSION=dev NIGHTLY_RELEASE_PREFIX=nigtly ./create-version.sh
|
# GITHUB_EVENT_NAME=workflow_dispatch COMMIT_SHA=f0e7216c4bb6acce9b29a21ec2d683be2e3f984a NEXT_RELEASE_VERSION=dev NIGHTLY_RELEASE_PREFIX=nightly ./create-version.sh
|
||||||
create_version
|
create_version
|
||||||
|
|||||||
2
.github/scripts/deploy-greptimedb.sh
vendored
2
.github/scripts/deploy-greptimedb.sh
vendored
@@ -10,7 +10,7 @@ GREPTIMEDB_IMAGE_TAG=${GREPTIMEDB_IMAGE_TAG:-latest}
|
|||||||
ETCD_CHART="oci://registry-1.docker.io/bitnamicharts/etcd"
|
ETCD_CHART="oci://registry-1.docker.io/bitnamicharts/etcd"
|
||||||
GREPTIME_CHART="https://greptimeteam.github.io/helm-charts/"
|
GREPTIME_CHART="https://greptimeteam.github.io/helm-charts/"
|
||||||
|
|
||||||
# Ceate a cluster with 1 control-plane node and 5 workers.
|
# Create a cluster with 1 control-plane node and 5 workers.
|
||||||
function create_kind_cluster() {
|
function create_kind_cluster() {
|
||||||
cat <<EOF | kind create cluster --name "${CLUSTER}" --image kindest/node:"$KUBERNETES_VERSION" --config=-
|
cat <<EOF | kind create cluster --name "${CLUSTER}" --image kindest/node:"$KUBERNETES_VERSION" --config=-
|
||||||
kind: Cluster
|
kind: Cluster
|
||||||
|
|||||||
37
.github/scripts/update-dev-builder-version.sh
vendored
Executable file
37
.github/scripts/update-dev-builder-version.sh
vendored
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DEV_BUILDER_IMAGE_TAG=$1
|
||||||
|
|
||||||
|
update_dev_builder_version() {
|
||||||
|
if [ -z "$DEV_BUILDER_IMAGE_TAG" ]; then
|
||||||
|
echo "Error: Should specify the dev-builder image tag"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure Git configs.
|
||||||
|
git config --global user.email greptimedb-ci@greptime.com
|
||||||
|
git config --global user.name greptimedb-ci
|
||||||
|
|
||||||
|
# Checkout a new branch.
|
||||||
|
BRANCH_NAME="ci/update-dev-builder-$(date +%Y%m%d%H%M%S)"
|
||||||
|
git checkout -b $BRANCH_NAME
|
||||||
|
|
||||||
|
# Update the dev-builder image tag in the Makefile.
|
||||||
|
sed -i "s/DEV_BUILDER_IMAGE_TAG ?=.*/DEV_BUILDER_IMAGE_TAG ?= ${DEV_BUILDER_IMAGE_TAG}/g" Makefile
|
||||||
|
|
||||||
|
# Commit the changes.
|
||||||
|
git add Makefile
|
||||||
|
git commit -m "ci: update dev-builder image tag"
|
||||||
|
git push origin $BRANCH_NAME
|
||||||
|
|
||||||
|
# Create a Pull Request.
|
||||||
|
gh pr create \
|
||||||
|
--title "ci: update dev-builder image tag" \
|
||||||
|
--body "This PR updates the dev-builder image tag" \
|
||||||
|
--base main \
|
||||||
|
--head $BRANCH_NAME \
|
||||||
|
--reviewer zyy17 \
|
||||||
|
--reviewer daviderli614
|
||||||
|
}
|
||||||
|
|
||||||
|
update_dev_builder_version
|
||||||
46
.github/scripts/update-helm-charts-version.sh
vendored
Executable file
46
.github/scripts/update-helm-charts-version.sh
vendored
Executable file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
VERSION=${VERSION}
|
||||||
|
GITHUB_TOKEN=${GITHUB_TOKEN}
|
||||||
|
|
||||||
|
update_helm_charts_version() {
|
||||||
|
# Configure Git configs.
|
||||||
|
git config --global user.email update-helm-charts-version@greptime.com
|
||||||
|
git config --global user.name update-helm-charts-version
|
||||||
|
|
||||||
|
# Clone helm-charts repository.
|
||||||
|
git clone "https://x-access-token:${GITHUB_TOKEN}@github.com/GreptimeTeam/helm-charts.git"
|
||||||
|
cd helm-charts
|
||||||
|
|
||||||
|
# Set default remote for gh CLI
|
||||||
|
gh repo set-default GreptimeTeam/helm-charts
|
||||||
|
|
||||||
|
# Checkout a new branch.
|
||||||
|
BRANCH_NAME="chore/greptimedb-${VERSION}"
|
||||||
|
git checkout -b $BRANCH_NAME
|
||||||
|
|
||||||
|
# Update version.
|
||||||
|
make update-version CHART=greptimedb-cluster VERSION=${VERSION}
|
||||||
|
make update-version CHART=greptimedb-standalone VERSION=${VERSION}
|
||||||
|
|
||||||
|
# Update docs.
|
||||||
|
make docs
|
||||||
|
|
||||||
|
# Commit the changes.
|
||||||
|
git add .
|
||||||
|
git commit -s -m "chore: Update GreptimeDB version to ${VERSION}"
|
||||||
|
git push origin $BRANCH_NAME
|
||||||
|
|
||||||
|
# Create a Pull Request.
|
||||||
|
gh pr create \
|
||||||
|
--title "chore: Update GreptimeDB version to ${VERSION}" \
|
||||||
|
--body "This PR updates the GreptimeDB version." \
|
||||||
|
--base main \
|
||||||
|
--head $BRANCH_NAME \
|
||||||
|
--reviewer zyy17 \
|
||||||
|
--reviewer daviderli614
|
||||||
|
}
|
||||||
|
|
||||||
|
update_helm_charts_version
|
||||||
42
.github/scripts/update-homebrew-greptme-version.sh
vendored
Executable file
42
.github/scripts/update-homebrew-greptme-version.sh
vendored
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
VERSION=${VERSION}
|
||||||
|
GITHUB_TOKEN=${GITHUB_TOKEN}
|
||||||
|
|
||||||
|
update_homebrew_greptime_version() {
|
||||||
|
# Configure Git configs.
|
||||||
|
git config --global user.email update-greptime-version@greptime.com
|
||||||
|
git config --global user.name update-greptime-version
|
||||||
|
|
||||||
|
# Clone helm-charts repository.
|
||||||
|
git clone "https://x-access-token:${GITHUB_TOKEN}@github.com/GreptimeTeam/homebrew-greptime.git"
|
||||||
|
cd homebrew-greptime
|
||||||
|
|
||||||
|
# Set default remote for gh CLI
|
||||||
|
gh repo set-default GreptimeTeam/homebrew-greptime
|
||||||
|
|
||||||
|
# Checkout a new branch.
|
||||||
|
BRANCH_NAME="chore/greptimedb-${VERSION}"
|
||||||
|
git checkout -b $BRANCH_NAME
|
||||||
|
|
||||||
|
# Update version.
|
||||||
|
make update-greptime-version VERSION=${VERSION}
|
||||||
|
|
||||||
|
# Commit the changes.
|
||||||
|
git add .
|
||||||
|
git commit -s -m "chore: Update GreptimeDB version to ${VERSION}"
|
||||||
|
git push origin $BRANCH_NAME
|
||||||
|
|
||||||
|
# Create a Pull Request.
|
||||||
|
gh pr create \
|
||||||
|
--title "chore: Update GreptimeDB version to ${VERSION}" \
|
||||||
|
--body "This PR updates the GreptimeDB version." \
|
||||||
|
--base main \
|
||||||
|
--head $BRANCH_NAME \
|
||||||
|
--reviewer zyy17 \
|
||||||
|
--reviewer daviderli614
|
||||||
|
}
|
||||||
|
|
||||||
|
update_homebrew_greptime_version
|
||||||
2
.github/scripts/upload-artifacts-to-s3.sh
vendored
2
.github/scripts/upload-artifacts-to-s3.sh
vendored
@@ -41,7 +41,7 @@ function upload_artifacts() {
|
|||||||
# Updates the latest version information in AWS S3 if UPDATE_VERSION_INFO is true.
|
# Updates the latest version information in AWS S3 if UPDATE_VERSION_INFO is true.
|
||||||
function update_version_info() {
|
function update_version_info() {
|
||||||
if [ "$UPDATE_VERSION_INFO" == "true" ]; then
|
if [ "$UPDATE_VERSION_INFO" == "true" ]; then
|
||||||
# If it's the officail release(like v1.0.0, v1.0.1, v1.0.2, etc.), update latest-version.txt.
|
# If it's the official release(like v1.0.0, v1.0.1, v1.0.2, etc.), update latest-version.txt.
|
||||||
if [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
if [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
echo "Updating latest-version.txt"
|
echo "Updating latest-version.txt"
|
||||||
echo "$VERSION" > latest-version.txt
|
echo "$VERSION" > latest-version.txt
|
||||||
|
|||||||
7
.github/workflows/dev-build.yml
vendored
7
.github/workflows/dev-build.yml
vendored
@@ -55,6 +55,11 @@ on:
|
|||||||
description: Build and push images to DockerHub and ACR
|
description: Build and push images to DockerHub and ACR
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
|
upload_artifacts_to_s3:
|
||||||
|
type: boolean
|
||||||
|
description: Whether upload artifacts to s3
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
cargo_profile:
|
cargo_profile:
|
||||||
type: choice
|
type: choice
|
||||||
description: The cargo profile to use in building GreptimeDB.
|
description: The cargo profile to use in building GreptimeDB.
|
||||||
@@ -281,7 +286,7 @@ jobs:
|
|||||||
aws-cn-access-key-id: ${{ secrets.AWS_CN_ACCESS_KEY_ID }}
|
aws-cn-access-key-id: ${{ secrets.AWS_CN_ACCESS_KEY_ID }}
|
||||||
aws-cn-secret-access-key: ${{ secrets.AWS_CN_SECRET_ACCESS_KEY }}
|
aws-cn-secret-access-key: ${{ secrets.AWS_CN_SECRET_ACCESS_KEY }}
|
||||||
aws-cn-region: ${{ vars.AWS_RELEASE_BUCKET_REGION }}
|
aws-cn-region: ${{ vars.AWS_RELEASE_BUCKET_REGION }}
|
||||||
upload-to-s3: false
|
upload-to-s3: ${{ inputs.upload_artifacts_to_s3 }}
|
||||||
dev-mode: true # Only build the standard images(exclude centos images).
|
dev-mode: true # Only build the standard images(exclude centos images).
|
||||||
push-latest-tag: false # Don't push the latest tag to registry.
|
push-latest-tag: false # Don't push the latest tag to registry.
|
||||||
update-version-info: false # Don't update the version info in S3.
|
update-version-info: false # Don't update the version info in S3.
|
||||||
|
|||||||
57
.github/workflows/develop.yml
vendored
57
.github/workflows/develop.yml
vendored
@@ -22,6 +22,7 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-typos-and-docs:
|
check-typos-and-docs:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Check typos and docs
|
name: Check typos and docs
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -36,6 +37,7 @@ jobs:
|
|||||||
|| (echo "'config/config.md' is not up-to-date, please run 'make config-docs'." && exit 1)
|
|| (echo "'config/config.md' is not up-to-date, please run 'make config-docs'." && exit 1)
|
||||||
|
|
||||||
license-header-check:
|
license-header-check:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Check License Header
|
name: Check License Header
|
||||||
steps:
|
steps:
|
||||||
@@ -45,6 +47,7 @@ jobs:
|
|||||||
- uses: korandoru/hawkeye@v5
|
- uses: korandoru/hawkeye@v5
|
||||||
|
|
||||||
check:
|
check:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Check
|
name: Check
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
@@ -71,6 +74,7 @@ jobs:
|
|||||||
run: cargo check --locked --workspace --all-targets
|
run: cargo check --locked --workspace --all-targets
|
||||||
|
|
||||||
toml:
|
toml:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Toml Check
|
name: Toml Check
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
@@ -85,6 +89,7 @@ jobs:
|
|||||||
run: taplo format --check
|
run: taplo format --check
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Build GreptimeDB binaries
|
name: Build GreptimeDB binaries
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
@@ -127,6 +132,7 @@ jobs:
|
|||||||
version: current
|
version: current
|
||||||
|
|
||||||
fuzztest:
|
fuzztest:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Fuzz Test
|
name: Fuzz Test
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -183,11 +189,13 @@ jobs:
|
|||||||
max-total-time: 120
|
max-total-time: 120
|
||||||
|
|
||||||
unstable-fuzztest:
|
unstable-fuzztest:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Unstable Fuzz Test
|
name: Unstable Fuzz Test
|
||||||
needs: build-greptime-ci
|
needs: build-greptime-ci
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
target: [ "unstable_fuzz_create_table_standalone" ]
|
target: [ "unstable_fuzz_create_table_standalone" ]
|
||||||
steps:
|
steps:
|
||||||
@@ -215,12 +223,12 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
sudo apt update && sudo apt install -y libfuzzer-14-dev
|
sudo apt update && sudo apt install -y libfuzzer-14-dev
|
||||||
cargo install cargo-fuzz cargo-gc-bin --force
|
cargo install cargo-fuzz cargo-gc-bin --force
|
||||||
- name: Download pre-built binariy
|
- name: Download pre-built binary
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: bin
|
name: bin
|
||||||
path: .
|
path: .
|
||||||
- name: Unzip bianry
|
- name: Unzip binary
|
||||||
run: |
|
run: |
|
||||||
tar -xvf ./bin.tar.gz
|
tar -xvf ./bin.tar.gz
|
||||||
rm ./bin.tar.gz
|
rm ./bin.tar.gz
|
||||||
@@ -242,8 +250,14 @@ jobs:
|
|||||||
name: unstable-fuzz-logs
|
name: unstable-fuzz-logs
|
||||||
path: /tmp/unstable-greptime/
|
path: /tmp/unstable-greptime/
|
||||||
retention-days: 3
|
retention-days: 3
|
||||||
|
- name: Describe pods
|
||||||
|
if: failure()
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
kubectl describe pod -n my-greptimedb
|
||||||
|
|
||||||
build-greptime-ci:
|
build-greptime-ci:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Build GreptimeDB binary (profile-CI)
|
name: Build GreptimeDB binary (profile-CI)
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
@@ -267,7 +281,7 @@ jobs:
|
|||||||
- name: Install cargo-gc-bin
|
- name: Install cargo-gc-bin
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cargo install cargo-gc-bin --force
|
run: cargo install cargo-gc-bin --force
|
||||||
- name: Build greptime bianry
|
- name: Build greptime binary
|
||||||
shell: bash
|
shell: bash
|
||||||
# `cargo gc` will invoke `cargo build` with specified args
|
# `cargo gc` will invoke `cargo build` with specified args
|
||||||
run: cargo gc --profile ci -- --bin greptime --features "pg_kvbackend,mysql_kvbackend"
|
run: cargo gc --profile ci -- --bin greptime --features "pg_kvbackend,mysql_kvbackend"
|
||||||
@@ -285,11 +299,13 @@ jobs:
|
|||||||
version: current
|
version: current
|
||||||
|
|
||||||
distributed-fuzztest:
|
distributed-fuzztest:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Fuzz Test (Distributed, ${{ matrix.mode.name }}, ${{ matrix.target }})
|
name: Fuzz Test (Distributed, ${{ matrix.mode.name }}, ${{ matrix.target }})
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build-greptime-ci
|
needs: build-greptime-ci
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
target: [ "fuzz_create_table", "fuzz_alter_table", "fuzz_create_database", "fuzz_create_logical_table", "fuzz_alter_logical_table", "fuzz_insert", "fuzz_insert_logical_table" ]
|
target: [ "fuzz_create_table", "fuzz_alter_table", "fuzz_create_database", "fuzz_create_logical_table", "fuzz_alter_logical_table", "fuzz_insert", "fuzz_insert_logical_table" ]
|
||||||
mode:
|
mode:
|
||||||
@@ -319,9 +335,9 @@ jobs:
|
|||||||
name: Setup Minio
|
name: Setup Minio
|
||||||
uses: ./.github/actions/setup-minio
|
uses: ./.github/actions/setup-minio
|
||||||
- if: matrix.mode.kafka
|
- if: matrix.mode.kafka
|
||||||
name: Setup Kafka cluser
|
name: Setup Kafka cluster
|
||||||
uses: ./.github/actions/setup-kafka-cluster
|
uses: ./.github/actions/setup-kafka-cluster
|
||||||
- name: Setup Etcd cluser
|
- name: Setup Etcd cluster
|
||||||
uses: ./.github/actions/setup-etcd-cluster
|
uses: ./.github/actions/setup-etcd-cluster
|
||||||
# Prepares for fuzz tests
|
# Prepares for fuzz tests
|
||||||
- uses: arduino/setup-protoc@v3
|
- uses: arduino/setup-protoc@v3
|
||||||
@@ -394,6 +410,11 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
kubectl describe nodes
|
kubectl describe nodes
|
||||||
|
- name: Describe pod
|
||||||
|
if: failure()
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
kubectl describe pod -n my-greptimedb
|
||||||
- name: Export kind logs
|
- name: Export kind logs
|
||||||
if: failure()
|
if: failure()
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -416,11 +437,13 @@ jobs:
|
|||||||
docker system prune -f
|
docker system prune -f
|
||||||
|
|
||||||
distributed-fuzztest-with-chaos:
|
distributed-fuzztest-with-chaos:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Fuzz Test with Chaos (Distributed, ${{ matrix.mode.name }}, ${{ matrix.target }})
|
name: Fuzz Test with Chaos (Distributed, ${{ matrix.mode.name }}, ${{ matrix.target }})
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build-greptime-ci
|
needs: build-greptime-ci
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
target: ["fuzz_migrate_mito_regions", "fuzz_migrate_metric_regions", "fuzz_failover_mito_regions", "fuzz_failover_metric_regions"]
|
target: ["fuzz_migrate_mito_regions", "fuzz_migrate_metric_regions", "fuzz_failover_mito_regions", "fuzz_failover_metric_regions"]
|
||||||
mode:
|
mode:
|
||||||
@@ -465,9 +488,9 @@ jobs:
|
|||||||
name: Setup Minio
|
name: Setup Minio
|
||||||
uses: ./.github/actions/setup-minio
|
uses: ./.github/actions/setup-minio
|
||||||
- if: matrix.mode.kafka
|
- if: matrix.mode.kafka
|
||||||
name: Setup Kafka cluser
|
name: Setup Kafka cluster
|
||||||
uses: ./.github/actions/setup-kafka-cluster
|
uses: ./.github/actions/setup-kafka-cluster
|
||||||
- name: Setup Etcd cluser
|
- name: Setup Etcd cluster
|
||||||
uses: ./.github/actions/setup-etcd-cluster
|
uses: ./.github/actions/setup-etcd-cluster
|
||||||
# Prepares for fuzz tests
|
# Prepares for fuzz tests
|
||||||
- uses: arduino/setup-protoc@v3
|
- uses: arduino/setup-protoc@v3
|
||||||
@@ -541,6 +564,11 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
kubectl describe nodes
|
kubectl describe nodes
|
||||||
|
- name: Describe pods
|
||||||
|
if: failure()
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
kubectl describe pod -n my-greptimedb
|
||||||
- name: Export kind logs
|
- name: Export kind logs
|
||||||
if: failure()
|
if: failure()
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -563,10 +591,12 @@ jobs:
|
|||||||
docker system prune -f
|
docker system prune -f
|
||||||
|
|
||||||
sqlness:
|
sqlness:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Sqlness Test (${{ matrix.mode.name }})
|
name: Sqlness Test (${{ matrix.mode.name }})
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ ubuntu-latest ]
|
os: [ ubuntu-latest ]
|
||||||
mode:
|
mode:
|
||||||
@@ -576,9 +606,12 @@ jobs:
|
|||||||
- name: "Remote WAL"
|
- name: "Remote WAL"
|
||||||
opts: "-w kafka -k 127.0.0.1:9092"
|
opts: "-w kafka -k 127.0.0.1:9092"
|
||||||
kafka: true
|
kafka: true
|
||||||
- name: "Pg Kvbackend"
|
- name: "PostgreSQL KvBackend"
|
||||||
opts: "--setup-pg"
|
opts: "--setup-pg"
|
||||||
kafka: false
|
kafka: false
|
||||||
|
- name: "MySQL Kvbackend"
|
||||||
|
opts: "--setup-mysql"
|
||||||
|
kafka: false
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -606,6 +639,7 @@ jobs:
|
|||||||
retention-days: 3
|
retention-days: 3
|
||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Rustfmt
|
name: Rustfmt
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
@@ -623,6 +657,7 @@ jobs:
|
|||||||
run: make fmt-check
|
run: make fmt-check
|
||||||
|
|
||||||
clippy:
|
clippy:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Clippy
|
name: Clippy
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
@@ -648,6 +683,7 @@ jobs:
|
|||||||
run: make clippy
|
run: make clippy
|
||||||
|
|
||||||
conflict-check:
|
conflict-check:
|
||||||
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
name: Check for conflict
|
name: Check for conflict
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -658,7 +694,7 @@ jobs:
|
|||||||
uses: olivernybroe/action-conflict-finder@v4.0
|
uses: olivernybroe/action-conflict-finder@v4.0
|
||||||
|
|
||||||
test:
|
test:
|
||||||
if: github.event_name != 'merge_group'
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' && github.event_name != 'merge_group' }}
|
||||||
runs-on: ubuntu-22.04-arm
|
runs-on: ubuntu-22.04-arm
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
needs: [conflict-check, clippy, fmt]
|
needs: [conflict-check, clippy, fmt]
|
||||||
@@ -710,7 +746,7 @@ jobs:
|
|||||||
UNITTEST_LOG_DIR: "__unittest_logs"
|
UNITTEST_LOG_DIR: "__unittest_logs"
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
if: github.event_name == 'merge_group'
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' && github.event_name == 'merge_group' }}
|
||||||
runs-on: ubuntu-22.04-8-cores
|
runs-on: ubuntu-22.04-8-cores
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
@@ -770,6 +806,7 @@ jobs:
|
|||||||
verbose: true
|
verbose: true
|
||||||
|
|
||||||
# compat:
|
# compat:
|
||||||
|
# if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
# name: Compatibility Test
|
# name: Compatibility Test
|
||||||
# needs: build
|
# needs: build
|
||||||
# runs-on: ubuntu-22.04
|
# runs-on: ubuntu-22.04
|
||||||
|
|||||||
30
.github/workflows/grafana.yml
vendored
30
.github/workflows/grafana.yml
vendored
@@ -21,32 +21,6 @@ jobs:
|
|||||||
run: sudo apt-get install -y jq
|
run: sudo apt-get install -y jq
|
||||||
|
|
||||||
# Make the check.sh script executable
|
# Make the check.sh script executable
|
||||||
- name: Make check.sh executable
|
- name: Check grafana dashboards
|
||||||
run: chmod +x grafana/check.sh
|
|
||||||
|
|
||||||
# Run the check.sh script
|
|
||||||
- name: Run check.sh
|
|
||||||
run: ./grafana/check.sh
|
|
||||||
|
|
||||||
# Only run summary.sh for pull_request events (not for merge queues or final pushes)
|
|
||||||
- name: Check if this is a pull request
|
|
||||||
id: check-pr
|
|
||||||
run: |
|
run: |
|
||||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
make check-dashboards
|
||||||
echo "is_pull_request=true" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "is_pull_request=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make the summary.sh script executable
|
|
||||||
- name: Make summary.sh executable
|
|
||||||
if: steps.check-pr.outputs.is_pull_request == 'true'
|
|
||||||
run: chmod +x grafana/summary.sh
|
|
||||||
|
|
||||||
# Run the summary.sh script and add its output to the GitHub Job Summary
|
|
||||||
- name: Run summary.sh and add to Job Summary
|
|
||||||
if: steps.check-pr.outputs.is_pull_request == 'true'
|
|
||||||
run: |
|
|
||||||
SUMMARY=$(./grafana/summary.sh)
|
|
||||||
echo "### Summary of Grafana Panels" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "$SUMMARY" >> $GITHUB_STEP_SUMMARY
|
|
||||||
|
|||||||
11
.github/workflows/nightly-ci.yml
vendored
11
.github/workflows/nightly-ci.yml
vendored
@@ -107,7 +107,6 @@ jobs:
|
|||||||
CARGO_BUILD_RUSTFLAGS: "-C linker=lld-link"
|
CARGO_BUILD_RUSTFLAGS: "-C linker=lld-link"
|
||||||
RUST_BACKTRACE: 1
|
RUST_BACKTRACE: 1
|
||||||
CARGO_INCREMENTAL: 0
|
CARGO_INCREMENTAL: 0
|
||||||
RUSTUP_WINDOWS_PATH_ADD_BIN: 1 # Workaround for https://github.com/nextest-rs/nextest/issues/1493
|
|
||||||
GT_S3_BUCKET: ${{ vars.AWS_CI_TEST_BUCKET }}
|
GT_S3_BUCKET: ${{ vars.AWS_CI_TEST_BUCKET }}
|
||||||
GT_S3_ACCESS_KEY_ID: ${{ secrets.AWS_CI_TEST_ACCESS_KEY_ID }}
|
GT_S3_ACCESS_KEY_ID: ${{ secrets.AWS_CI_TEST_ACCESS_KEY_ID }}
|
||||||
GT_S3_ACCESS_KEY: ${{ secrets.AWS_CI_TEST_SECRET_ACCESS_KEY }}
|
GT_S3_ACCESS_KEY: ${{ secrets.AWS_CI_TEST_SECRET_ACCESS_KEY }}
|
||||||
@@ -118,16 +117,16 @@ jobs:
|
|||||||
name: Run clean build on Linux
|
name: Run clean build on Linux
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' }}
|
||||||
timeout-minutes: 60
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: cachix/install-nix-action@v27
|
- uses: cachix/install-nix-action@v31
|
||||||
with:
|
- run: nix develop --command cargo check --bin greptime
|
||||||
nix_path: nixpkgs=channel:nixos-24.11
|
env:
|
||||||
- run: nix develop --command cargo build
|
CARGO_BUILD_RUSTFLAGS: "-C link-arg=-fuse-ld=mold"
|
||||||
|
|
||||||
check-status:
|
check-status:
|
||||||
name: Check status
|
name: Check status
|
||||||
|
|||||||
@@ -24,11 +24,19 @@ on:
|
|||||||
description: Release dev-builder-android image
|
description: Release dev-builder-android image
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
|
update_dev_builder_image_tag:
|
||||||
|
type: boolean
|
||||||
|
description: Update the DEV_BUILDER_IMAGE_TAG in Makefile and create a PR
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release-dev-builder-images:
|
release-dev-builder-images:
|
||||||
name: 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.
|
# The jobs are triggered by the following events:
|
||||||
|
# 1. Manually triggered workflow_dispatch event
|
||||||
|
# 2. Push event when the PR that modifies the `rust-toolchain.toml` or `docker/dev-builder/**` is merged to main
|
||||||
|
if: ${{ github.event_name == 'push' || inputs.release_dev_builder_ubuntu_image || inputs.release_dev_builder_centos_image || inputs.release_dev_builder_android_image }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
version: ${{ steps.set-version.outputs.version }}
|
version: ${{ steps.set-version.outputs.version }}
|
||||||
@@ -57,9 +65,9 @@ jobs:
|
|||||||
version: ${{ env.VERSION }}
|
version: ${{ env.VERSION }}
|
||||||
dockerhub-image-registry-username: ${{ secrets.DOCKERHUB_USERNAME }}
|
dockerhub-image-registry-username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
dockerhub-image-registry-token: ${{ secrets.DOCKERHUB_TOKEN }}
|
dockerhub-image-registry-token: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
build-dev-builder-ubuntu: ${{ inputs.release_dev_builder_ubuntu_image }}
|
build-dev-builder-ubuntu: ${{ inputs.release_dev_builder_ubuntu_image || github.event_name == 'push' }}
|
||||||
build-dev-builder-centos: ${{ inputs.release_dev_builder_centos_image }}
|
build-dev-builder-centos: ${{ inputs.release_dev_builder_centos_image || github.event_name == 'push' }}
|
||||||
build-dev-builder-android: ${{ inputs.release_dev_builder_android_image }}
|
build-dev-builder-android: ${{ inputs.release_dev_builder_android_image || github.event_name == 'push' }}
|
||||||
|
|
||||||
release-dev-builder-images-ecr:
|
release-dev-builder-images-ecr:
|
||||||
name: Release dev builder images to AWS ECR
|
name: Release dev builder images to AWS ECR
|
||||||
@@ -85,7 +93,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Push dev-builder-ubuntu image
|
- name: Push dev-builder-ubuntu image
|
||||||
shell: bash
|
shell: bash
|
||||||
if: ${{ inputs.release_dev_builder_ubuntu_image }}
|
if: ${{ inputs.release_dev_builder_ubuntu_image || github.event_name == 'push' }}
|
||||||
env:
|
env:
|
||||||
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
||||||
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
||||||
@@ -106,7 +114,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Push dev-builder-centos image
|
- name: Push dev-builder-centos image
|
||||||
shell: bash
|
shell: bash
|
||||||
if: ${{ inputs.release_dev_builder_centos_image }}
|
if: ${{ inputs.release_dev_builder_centos_image || github.event_name == 'push' }}
|
||||||
env:
|
env:
|
||||||
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
||||||
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
||||||
@@ -127,7 +135,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Push dev-builder-android image
|
- name: Push dev-builder-android image
|
||||||
shell: bash
|
shell: bash
|
||||||
if: ${{ inputs.release_dev_builder_android_image }}
|
if: ${{ inputs.release_dev_builder_android_image || github.event_name == 'push' }}
|
||||||
env:
|
env:
|
||||||
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
||||||
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
||||||
@@ -162,7 +170,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Push dev-builder-ubuntu image
|
- name: Push dev-builder-ubuntu image
|
||||||
shell: bash
|
shell: bash
|
||||||
if: ${{ inputs.release_dev_builder_ubuntu_image }}
|
if: ${{ inputs.release_dev_builder_ubuntu_image || github.event_name == 'push' }}
|
||||||
env:
|
env:
|
||||||
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
||||||
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
||||||
@@ -176,7 +184,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Push dev-builder-centos image
|
- name: Push dev-builder-centos image
|
||||||
shell: bash
|
shell: bash
|
||||||
if: ${{ inputs.release_dev_builder_centos_image }}
|
if: ${{ inputs.release_dev_builder_centos_image || github.event_name == 'push' }}
|
||||||
env:
|
env:
|
||||||
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
||||||
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
||||||
@@ -190,7 +198,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Push dev-builder-android image
|
- name: Push dev-builder-android image
|
||||||
shell: bash
|
shell: bash
|
||||||
if: ${{ inputs.release_dev_builder_android_image }}
|
if: ${{ inputs.release_dev_builder_android_image || github.event_name == 'push' }}
|
||||||
env:
|
env:
|
||||||
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
IMAGE_VERSION: ${{ needs.release-dev-builder-images.outputs.version }}
|
||||||
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
IMAGE_NAMESPACE: ${{ vars.IMAGE_NAMESPACE }}
|
||||||
@@ -201,3 +209,24 @@ jobs:
|
|||||||
quay.io/skopeo/stable:latest \
|
quay.io/skopeo/stable:latest \
|
||||||
copy -a docker://docker.io/$IMAGE_NAMESPACE/dev-builder-android:$IMAGE_VERSION \
|
copy -a docker://docker.io/$IMAGE_NAMESPACE/dev-builder-android:$IMAGE_VERSION \
|
||||||
docker://$ACR_IMAGE_REGISTRY/$IMAGE_NAMESPACE/dev-builder-android:$IMAGE_VERSION
|
docker://$ACR_IMAGE_REGISTRY/$IMAGE_NAMESPACE/dev-builder-android:$IMAGE_VERSION
|
||||||
|
|
||||||
|
update-dev-builder-image-tag:
|
||||||
|
name: Update dev-builder image tag
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
if: ${{ github.event_name == 'push' || inputs.update_dev_builder_image_tag }}
|
||||||
|
needs: [
|
||||||
|
release-dev-builder-images
|
||||||
|
]
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Update dev-builder image tag
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
./.github/scripts/update-dev-builder-version.sh ${{ needs.release-dev-builder-images.outputs.version }}
|
||||||
|
|||||||
68
.github/workflows/release.yml
vendored
68
.github/workflows/release.yml
vendored
@@ -88,10 +88,8 @@ env:
|
|||||||
# Controls whether to run tests, include unit-test, integration-test and sqlness.
|
# Controls whether to run tests, include unit-test, integration-test and sqlness.
|
||||||
DISABLE_RUN_TESTS: ${{ inputs.skip_test || vars.DEFAULT_SKIP_TEST }}
|
DISABLE_RUN_TESTS: ${{ inputs.skip_test || vars.DEFAULT_SKIP_TEST }}
|
||||||
|
|
||||||
# The scheduled version is '${{ env.NEXT_RELEASE_VERSION }}-nightly-YYYYMMDD', like v0.2.0-nigthly-20230313;
|
# The scheduled version is '${{ env.NEXT_RELEASE_VERSION }}-nightly-YYYYMMDD', like v0.2.0-nightly-20230313;
|
||||||
NIGHTLY_RELEASE_PREFIX: nightly
|
NIGHTLY_RELEASE_PREFIX: nightly
|
||||||
# Note: The NEXT_RELEASE_VERSION should be modified manually by every formal release.
|
|
||||||
NEXT_RELEASE_VERSION: v0.13.0
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
allocate-runners:
|
allocate-runners:
|
||||||
@@ -126,7 +124,7 @@ jobs:
|
|||||||
|
|
||||||
# The create-version will create a global variable named 'version' in the global workflows.
|
# The create-version will create a global variable named 'version' in the global workflows.
|
||||||
# - If it's a tag push release, the version is the tag name(${{ github.ref_name }});
|
# - If it's a tag push release, the version is the tag name(${{ github.ref_name }});
|
||||||
# - If it's a scheduled release, the version is '${{ env.NEXT_RELEASE_VERSION }}-nightly-$buildTime', like v0.2.0-nigthly-20230313;
|
# - If it's a scheduled release, the version is '${{ env.NEXT_RELEASE_VERSION }}-nightly-$buildTime', like v0.2.0-nightly-20230313;
|
||||||
# - If it's a manual release, the version is '${{ env.NEXT_RELEASE_VERSION }}-<short-git-sha>-YYYYMMDDSS', like v0.2.0-e5b243c-2023071245;
|
# - If it's a manual release, the version is '${{ env.NEXT_RELEASE_VERSION }}-<short-git-sha>-YYYYMMDDSS', like v0.2.0-e5b243c-2023071245;
|
||||||
- name: Create version
|
- name: Create version
|
||||||
id: create-version
|
id: create-version
|
||||||
@@ -135,7 +133,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
||||||
GITHUB_REF_NAME: ${{ github.ref_name }}
|
GITHUB_REF_NAME: ${{ github.ref_name }}
|
||||||
NEXT_RELEASE_VERSION: ${{ env.NEXT_RELEASE_VERSION }}
|
|
||||||
NIGHTLY_RELEASE_PREFIX: ${{ env.NIGHTLY_RELEASE_PREFIX }}
|
NIGHTLY_RELEASE_PREFIX: ${{ env.NIGHTLY_RELEASE_PREFIX }}
|
||||||
|
|
||||||
- name: Allocate linux-amd64 runner
|
- name: Allocate linux-amd64 runner
|
||||||
@@ -317,7 +314,7 @@ jobs:
|
|||||||
image-registry-username: ${{ secrets.DOCKERHUB_USERNAME }}
|
image-registry-username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
image-registry-password: ${{ secrets.DOCKERHUB_TOKEN }}
|
image-registry-password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
version: ${{ needs.allocate-runners.outputs.version }}
|
version: ${{ needs.allocate-runners.outputs.version }}
|
||||||
push-latest-tag: true
|
push-latest-tag: ${{ github.ref_type == 'tag' && !contains(github.ref_name, 'nightly') && github.event_name != 'schedule' }}
|
||||||
|
|
||||||
- name: Set build image result
|
- name: Set build image result
|
||||||
id: set-build-image-result
|
id: set-build-image-result
|
||||||
@@ -364,7 +361,7 @@ jobs:
|
|||||||
dev-mode: false
|
dev-mode: false
|
||||||
upload-to-s3: true
|
upload-to-s3: true
|
||||||
update-version-info: true
|
update-version-info: true
|
||||||
push-latest-tag: true
|
push-latest-tag: ${{ github.ref_type == 'tag' && !contains(github.ref_name, 'nightly') && github.event_name != 'schedule' }}
|
||||||
|
|
||||||
publish-github-release:
|
publish-github-release:
|
||||||
name: Create GitHub release and upload artifacts
|
name: Create GitHub release and upload artifacts
|
||||||
@@ -391,7 +388,7 @@ jobs:
|
|||||||
|
|
||||||
### Stop runners ###
|
### Stop runners ###
|
||||||
# It's very necessary to split the job of releasing runners into 'stop-linux-amd64-runner' and 'stop-linux-arm64-runner'.
|
# It's very necessary to split the job of releasing runners into 'stop-linux-amd64-runner' and 'stop-linux-arm64-runner'.
|
||||||
# Because we can terminate the specified EC2 instance immediately after the job is finished without uncessary waiting.
|
# Because we can terminate the specified EC2 instance immediately after the job is finished without unnecessary waiting.
|
||||||
stop-linux-amd64-runner: # It's always run as the last job in the workflow to make sure that the runner is released.
|
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
|
name: Stop linux-amd64 runner
|
||||||
# Only run this job when the runner is allocated.
|
# Only run this job when the runner is allocated.
|
||||||
@@ -444,10 +441,10 @@ jobs:
|
|||||||
aws-region: ${{ vars.EC2_RUNNER_REGION }}
|
aws-region: ${{ vars.EC2_RUNNER_REGION }}
|
||||||
github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
|
github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
|
||||||
|
|
||||||
bump-doc-version:
|
bump-downstream-repo-versions:
|
||||||
name: Bump doc version
|
name: Bump downstream repo versions
|
||||||
if: ${{ github.event_name == 'push' || github.event_name == 'schedule' }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'schedule' }}
|
||||||
needs: [allocate-runners]
|
needs: [allocate-runners, publish-github-release]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# Permission reference: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
# Permission reference: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
||||||
permissions:
|
permissions:
|
||||||
@@ -459,13 +456,58 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: ./.github/actions/setup-cyborg
|
- uses: ./.github/actions/setup-cyborg
|
||||||
- name: Bump doc version
|
- name: Bump downstream repo versions
|
||||||
working-directory: cyborg
|
working-directory: cyborg
|
||||||
run: pnpm tsx bin/bump-doc-version.ts
|
run: pnpm tsx bin/bump-versions.ts
|
||||||
env:
|
env:
|
||||||
|
TARGET_REPOS: website,docs,demo
|
||||||
VERSION: ${{ needs.allocate-runners.outputs.version }}
|
VERSION: ${{ needs.allocate-runners.outputs.version }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
WEBSITE_REPO_TOKEN: ${{ secrets.WEBSITE_REPO_TOKEN }}
|
||||||
DOCS_REPO_TOKEN: ${{ secrets.DOCS_REPO_TOKEN }}
|
DOCS_REPO_TOKEN: ${{ secrets.DOCS_REPO_TOKEN }}
|
||||||
|
DEMO_REPO_TOKEN: ${{ secrets.DEMO_REPO_TOKEN }}
|
||||||
|
|
||||||
|
bump-helm-charts-version:
|
||||||
|
name: Bump helm charts version
|
||||||
|
if: ${{ github.ref_type == 'tag' && !contains(github.ref_name, 'nightly') && github.event_name != 'schedule' }}
|
||||||
|
needs: [allocate-runners, publish-github-release]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Bump helm charts version
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.HELM_CHARTS_REPO_TOKEN }}
|
||||||
|
VERSION: ${{ needs.allocate-runners.outputs.version }}
|
||||||
|
run: |
|
||||||
|
./.github/scripts/update-helm-charts-version.sh
|
||||||
|
|
||||||
|
bump-homebrew-greptime-version:
|
||||||
|
name: Bump homebrew greptime version
|
||||||
|
if: ${{ github.ref_type == 'tag' && !contains(github.ref_name, 'nightly') && github.event_name != 'schedule' }}
|
||||||
|
needs: [allocate-runners, publish-github-release]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Bump homebrew greptime version
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.HOMEBREW_GREPTIME_REPO_TOKEN }}
|
||||||
|
VERSION: ${{ needs.allocate-runners.outputs.version }}
|
||||||
|
run: |
|
||||||
|
./.github/scripts/update-homebrew-greptme-version.sh
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
if: ${{ github.repository == 'GreptimeTeam/greptimedb' && (github.event_name == 'push' || github.event_name == 'schedule') && always() }}
|
if: ${{ github.repository == 'GreptimeTeam/greptimedb' && (github.event_name == 'push' || github.event_name == 'schedule') && always() }}
|
||||||
|
|||||||
3
.github/workflows/semantic-pull-request.yml
vendored
3
.github/workflows/semantic-pull-request.yml
vendored
@@ -14,6 +14,9 @@ concurrency:
|
|||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
pull-requests: write # Add permissions to modify PRs
|
||||||
|
issues: write
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -28,6 +28,7 @@ debug/
|
|||||||
# Logs
|
# Logs
|
||||||
**/__unittest_logs
|
**/__unittest_logs
|
||||||
logs/
|
logs/
|
||||||
|
!grafana/dashboards/logs/
|
||||||
|
|
||||||
# cpython's generated python byte code
|
# cpython's generated python byte code
|
||||||
**/__pycache__/
|
**/__pycache__/
|
||||||
@@ -54,3 +55,9 @@ tests-fuzz/corpus/
|
|||||||
# Nix
|
# Nix
|
||||||
.direnv
|
.direnv
|
||||||
.envrc
|
.envrc
|
||||||
|
|
||||||
|
## default data home
|
||||||
|
greptimedb_data
|
||||||
|
|
||||||
|
# github
|
||||||
|
!/.github
|
||||||
@@ -108,7 +108,7 @@ of what you were trying to do and what went wrong. You can also reach for help i
|
|||||||
The core team will be thrilled if you would like to participate in any way you like. When you are stuck, try to ask for help by filing an issue, with a detailed description of what you were trying to do and what went wrong. If you have any questions or if you would like to get involved in our community, please check out:
|
The core team will be thrilled if you would like to participate in any way you like. When you are stuck, try to ask for help by filing an issue, with a detailed description of what you were trying to do and what went wrong. If you have any questions or if you would like to get involved in our community, please check out:
|
||||||
|
|
||||||
- [GreptimeDB Community Slack](https://greptime.com/slack)
|
- [GreptimeDB Community Slack](https://greptime.com/slack)
|
||||||
- [GreptimeDB Github Discussions](https://github.com/GreptimeTeam/greptimedb/discussions)
|
- [GreptimeDB GitHub Discussions](https://github.com/GreptimeTeam/greptimedb/discussions)
|
||||||
|
|
||||||
Also, see some extra GreptimeDB content:
|
Also, see some extra GreptimeDB content:
|
||||||
|
|
||||||
|
|||||||
4222
Cargo.lock
generated
4222
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
119
Cargo.toml
119
Cargo.toml
@@ -29,12 +29,15 @@ members = [
|
|||||||
"src/common/query",
|
"src/common/query",
|
||||||
"src/common/recordbatch",
|
"src/common/recordbatch",
|
||||||
"src/common/runtime",
|
"src/common/runtime",
|
||||||
|
"src/common/session",
|
||||||
|
"src/common/stat",
|
||||||
"src/common/substrait",
|
"src/common/substrait",
|
||||||
"src/common/telemetry",
|
"src/common/telemetry",
|
||||||
"src/common/test-util",
|
"src/common/test-util",
|
||||||
"src/common/time",
|
"src/common/time",
|
||||||
"src/common/version",
|
"src/common/version",
|
||||||
"src/common/wal",
|
"src/common/wal",
|
||||||
|
"src/common/workload",
|
||||||
"src/datanode",
|
"src/datanode",
|
||||||
"src/datatypes",
|
"src/datatypes",
|
||||||
"src/file-engine",
|
"src/file-engine",
|
||||||
@@ -67,16 +70,17 @@ members = [
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.13.0"
|
version = "0.15.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
||||||
[workspace.lints]
|
[workspace.lints]
|
||||||
clippy.print_stdout = "warn"
|
|
||||||
clippy.print_stderr = "warn"
|
|
||||||
clippy.dbg_macro = "warn"
|
clippy.dbg_macro = "warn"
|
||||||
clippy.implicit_clone = "warn"
|
clippy.implicit_clone = "warn"
|
||||||
clippy.readonly_write_lock = "allow"
|
clippy.result_large_err = "allow"
|
||||||
|
clippy.large_enum_variant = "allow"
|
||||||
|
clippy.doc_overindented_list_items = "allow"
|
||||||
|
clippy.uninlined_format_args = "allow"
|
||||||
rust.unknown_lints = "deny"
|
rust.unknown_lints = "deny"
|
||||||
rust.unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }
|
rust.unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }
|
||||||
|
|
||||||
@@ -88,20 +92,20 @@ rust.unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }
|
|||||||
#
|
#
|
||||||
# See for more detaiils: https://github.com/rust-lang/cargo/issues/11329
|
# See for more detaiils: https://github.com/rust-lang/cargo/issues/11329
|
||||||
ahash = { version = "0.8", features = ["compile-time-rng"] }
|
ahash = { version = "0.8", features = ["compile-time-rng"] }
|
||||||
aquamarine = "0.3"
|
aquamarine = "0.6"
|
||||||
arrow = { version = "53.0.0", features = ["prettyprint"] }
|
arrow = { version = "54.2", features = ["prettyprint"] }
|
||||||
arrow-array = { version = "53.0.0", default-features = false, features = ["chrono-tz"] }
|
arrow-array = { version = "54.2", default-features = false, features = ["chrono-tz"] }
|
||||||
arrow-flight = "53.0"
|
arrow-flight = "54.2"
|
||||||
arrow-ipc = { version = "53.0.0", default-features = false, features = ["lz4", "zstd"] }
|
arrow-ipc = { version = "54.2", default-features = false, features = ["lz4", "zstd"] }
|
||||||
arrow-schema = { version = "53.0", features = ["serde"] }
|
arrow-schema = { version = "54.2", features = ["serde"] }
|
||||||
async-stream = "0.3"
|
async-stream = "0.3"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
# Remember to update axum-extra, axum-macros when updating axum
|
# Remember to update axum-extra, axum-macros when updating axum
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
axum-extra = "0.10"
|
axum-extra = "0.10"
|
||||||
axum-macros = "0.4"
|
axum-macros = "0.5"
|
||||||
backon = "1"
|
backon = "1"
|
||||||
base64 = "0.21"
|
base64 = "0.22"
|
||||||
bigdecimal = "0.4.2"
|
bigdecimal = "0.4.2"
|
||||||
bitflags = "2.4.1"
|
bitflags = "2.4.1"
|
||||||
bytemuck = "1.12"
|
bytemuck = "1.12"
|
||||||
@@ -111,43 +115,44 @@ chrono-tz = "0.10.1"
|
|||||||
clap = { version = "4.4", features = ["derive"] }
|
clap = { version = "4.4", features = ["derive"] }
|
||||||
config = "0.13.0"
|
config = "0.13.0"
|
||||||
crossbeam-utils = "0.8"
|
crossbeam-utils = "0.8"
|
||||||
dashmap = "5.4"
|
dashmap = "6.1"
|
||||||
datafusion = { git = "https://github.com/apache/datafusion.git", rev = "2464703c84c400a09cc59277018813f0e797bb4e" }
|
datafusion = { git = "https://github.com/waynexia/arrow-datafusion.git", rev = "12c0381babd52c681043957e9d6ee083a03f7646" }
|
||||||
datafusion-common = { git = "https://github.com/apache/datafusion.git", rev = "2464703c84c400a09cc59277018813f0e797bb4e" }
|
datafusion-common = { git = "https://github.com/waynexia/arrow-datafusion.git", rev = "12c0381babd52c681043957e9d6ee083a03f7646" }
|
||||||
datafusion-expr = { git = "https://github.com/apache/datafusion.git", rev = "2464703c84c400a09cc59277018813f0e797bb4e" }
|
datafusion-expr = { git = "https://github.com/waynexia/arrow-datafusion.git", rev = "12c0381babd52c681043957e9d6ee083a03f7646" }
|
||||||
datafusion-functions = { git = "https://github.com/apache/datafusion.git", rev = "2464703c84c400a09cc59277018813f0e797bb4e" }
|
datafusion-functions = { git = "https://github.com/waynexia/arrow-datafusion.git", rev = "12c0381babd52c681043957e9d6ee083a03f7646" }
|
||||||
datafusion-optimizer = { git = "https://github.com/apache/datafusion.git", rev = "2464703c84c400a09cc59277018813f0e797bb4e" }
|
datafusion-optimizer = { git = "https://github.com/waynexia/arrow-datafusion.git", rev = "12c0381babd52c681043957e9d6ee083a03f7646" }
|
||||||
datafusion-physical-expr = { git = "https://github.com/apache/datafusion.git", rev = "2464703c84c400a09cc59277018813f0e797bb4e" }
|
datafusion-physical-expr = { git = "https://github.com/waynexia/arrow-datafusion.git", rev = "12c0381babd52c681043957e9d6ee083a03f7646" }
|
||||||
datafusion-physical-plan = { git = "https://github.com/apache/datafusion.git", rev = "2464703c84c400a09cc59277018813f0e797bb4e" }
|
datafusion-physical-plan = { git = "https://github.com/waynexia/arrow-datafusion.git", rev = "12c0381babd52c681043957e9d6ee083a03f7646" }
|
||||||
datafusion-sql = { git = "https://github.com/apache/datafusion.git", rev = "2464703c84c400a09cc59277018813f0e797bb4e" }
|
datafusion-sql = { git = "https://github.com/waynexia/arrow-datafusion.git", rev = "12c0381babd52c681043957e9d6ee083a03f7646" }
|
||||||
datafusion-substrait = { git = "https://github.com/apache/datafusion.git", rev = "2464703c84c400a09cc59277018813f0e797bb4e" }
|
datafusion-substrait = { git = "https://github.com/waynexia/arrow-datafusion.git", rev = "12c0381babd52c681043957e9d6ee083a03f7646" }
|
||||||
deadpool = "0.10"
|
deadpool = "0.12"
|
||||||
deadpool-postgres = "0.12"
|
deadpool-postgres = "0.14"
|
||||||
derive_builder = "0.12"
|
derive_builder = "0.20"
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
etcd-client = "0.14"
|
etcd-client = "0.14"
|
||||||
flate2 = { version = "1.1.0", default-features = false, features = ["zlib-rs"] }
|
|
||||||
fst = "0.4.7"
|
fst = "0.4.7"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
greptime-proto = { git = "https://github.com/GreptimeTeam/greptime-proto.git", rev = "c5419bbd20cb42e568ec325a4d71a3c94cc327e1" }
|
greptime-proto = { git = "https://github.com/GreptimeTeam/greptime-proto.git", rev = "454c52634c3bac27de10bf0d85d5533eed1cf03f" }
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
http = "1"
|
http = "1"
|
||||||
humantime = "2.1"
|
humantime = "2.1"
|
||||||
humantime-serde = "1.1"
|
humantime-serde = "1.1"
|
||||||
hyper = "1.1"
|
hyper = "1.1"
|
||||||
hyper-util = "0.1"
|
hyper-util = "0.1"
|
||||||
itertools = "0.10"
|
itertools = "0.14"
|
||||||
jsonb = { git = "https://github.com/databendlabs/jsonb.git", rev = "8c8d2fc294a39f3ff08909d60f718639cfba3875", default-features = false }
|
jsonb = { git = "https://github.com/databendlabs/jsonb.git", rev = "8c8d2fc294a39f3ff08909d60f718639cfba3875", default-features = false }
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
local-ip-address = "0.6"
|
local-ip-address = "0.6"
|
||||||
loki-proto = { git = "https://github.com/GreptimeTeam/loki-proto.git", rev = "1434ecf23a2654025d86188fb5205e7a74b225d3" }
|
loki-proto = { git = "https://github.com/GreptimeTeam/loki-proto.git", rev = "1434ecf23a2654025d86188fb5205e7a74b225d3" }
|
||||||
meter-core = { git = "https://github.com/GreptimeTeam/greptime-meter.git", rev = "5618e779cf2bb4755b499c630fba4c35e91898cb" }
|
meter-core = { git = "https://github.com/GreptimeTeam/greptime-meter.git", rev = "5618e779cf2bb4755b499c630fba4c35e91898cb" }
|
||||||
mockall = "0.11.4"
|
mockall = "0.13"
|
||||||
moka = "0.12"
|
moka = "0.12"
|
||||||
nalgebra = "0.33"
|
nalgebra = "0.33"
|
||||||
notify = "6.1"
|
nix = { version = "0.30.1", default-features = false, features = ["event", "fs", "process"] }
|
||||||
|
notify = "8.0"
|
||||||
num_cpus = "1.16"
|
num_cpus = "1.16"
|
||||||
|
object_store_opendal = "0.50"
|
||||||
once_cell = "1.18"
|
once_cell = "1.18"
|
||||||
opentelemetry-proto = { version = "0.27", features = [
|
opentelemetry-proto = { version = "0.27", features = [
|
||||||
"gen-tonic",
|
"gen-tonic",
|
||||||
@@ -157,15 +162,17 @@ opentelemetry-proto = { version = "0.27", features = [
|
|||||||
"logs",
|
"logs",
|
||||||
] }
|
] }
|
||||||
parking_lot = "0.12"
|
parking_lot = "0.12"
|
||||||
parquet = { version = "53.0.0", default-features = false, features = ["arrow", "async", "object_store"] }
|
parquet = { version = "54.2", default-features = false, features = ["arrow", "async", "object_store"] }
|
||||||
paste = "1.0"
|
paste = "1.0"
|
||||||
pin-project = "1.0"
|
pin-project = "1.0"
|
||||||
prometheus = { version = "0.13.3", features = ["process"] }
|
prometheus = { version = "0.13.3", features = ["process"] }
|
||||||
promql-parser = { version = "0.5", features = ["ser"] }
|
promql-parser = { git = "https://github.com/GreptimeTeam/promql-parser.git", rev = "0410e8b459dda7cb222ce9596f8bf3971bd07bd2", features = [
|
||||||
prost = "0.13"
|
"ser",
|
||||||
|
] }
|
||||||
|
prost = { version = "0.13", features = ["no-recursion-limit"] }
|
||||||
raft-engine = { version = "0.4.1", default-features = false }
|
raft-engine = { version = "0.4.1", default-features = false }
|
||||||
rand = "0.8"
|
rand = "0.9"
|
||||||
ratelimit = "0.9"
|
ratelimit = "0.10"
|
||||||
regex = "1.8"
|
regex = "1.8"
|
||||||
regex-automata = "0.4"
|
regex-automata = "0.4"
|
||||||
reqwest = { version = "0.12", default-features = false, features = [
|
reqwest = { version = "0.12", default-features = false, features = [
|
||||||
@@ -174,36 +181,39 @@ reqwest = { version = "0.12", default-features = false, features = [
|
|||||||
"stream",
|
"stream",
|
||||||
"multipart",
|
"multipart",
|
||||||
] }
|
] }
|
||||||
rskafka = { git = "https://github.com/influxdata/rskafka.git", rev = "75535b5ad9bae4a5dbb582c82e44dfd81ec10105", features = [
|
rskafka = { git = "https://github.com/influxdata/rskafka.git", rev = "8dbd01ed809f5a791833a594e85b144e36e45820", features = [
|
||||||
"transport-tls",
|
"transport-tls",
|
||||||
] }
|
] }
|
||||||
rstest = "0.21"
|
rstest = "0.25"
|
||||||
rstest_reuse = "0.7"
|
rstest_reuse = "0.7"
|
||||||
rust_decimal = "1.33"
|
rust_decimal = "1.33"
|
||||||
rustc-hash = "2.0"
|
rustc-hash = "2.0"
|
||||||
rustls = { version = "0.23.20", default-features = false } # override by patch, see [patch.crates-io]
|
# It is worth noting that we should try to avoid using aws-lc-rs until it can be compiled on various platforms.
|
||||||
|
rustls = { version = "0.23.25", default-features = false }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = { version = "1.0", features = ["float_roundtrip"] }
|
serde_json = { version = "1.0", features = ["float_roundtrip"] }
|
||||||
serde_with = "3"
|
serde_with = "3"
|
||||||
shadow-rs = "0.38"
|
shadow-rs = "1.1"
|
||||||
|
simd-json = "0.15"
|
||||||
similar-asserts = "1.6.0"
|
similar-asserts = "1.6.0"
|
||||||
smallvec = { version = "1", features = ["serde"] }
|
smallvec = { version = "1", features = ["serde"] }
|
||||||
snafu = "0.8"
|
snafu = "0.8"
|
||||||
|
sqlparser = { git = "https://github.com/GreptimeTeam/sqlparser-rs.git", rev = "0cf6c04490d59435ee965edd2078e8855bd8471e", features = [
|
||||||
|
"visitor",
|
||||||
|
"serde",
|
||||||
|
] } # branch = "v0.54.x"
|
||||||
sqlx = { version = "0.8", features = [
|
sqlx = { version = "0.8", features = [
|
||||||
"runtime-tokio-rustls",
|
"runtime-tokio-rustls",
|
||||||
"mysql",
|
"mysql",
|
||||||
|
"postgres",
|
||||||
|
"chrono",
|
||||||
] }
|
] }
|
||||||
sysinfo = "0.30"
|
strum = { version = "0.27", features = ["derive"] }
|
||||||
# on branch v0.52.x
|
sysinfo = "0.33"
|
||||||
sqlparser = { git = "https://github.com/GreptimeTeam/sqlparser-rs.git", rev = "71dd86058d2af97b9925093d40c4e03360403170", features = [
|
|
||||||
"visitor",
|
|
||||||
"serde",
|
|
||||||
] } # on branch v0.44.x
|
|
||||||
strum = { version = "0.25", features = ["derive"] }
|
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
tokio = { version = "1.40", features = ["full"] }
|
tokio = { version = "1.40", features = ["full"] }
|
||||||
tokio-postgres = "0.7"
|
tokio-postgres = "0.7"
|
||||||
tokio-rustls = { version = "0.26.0", default-features = false } # override by patch, see [patch.crates-io]
|
tokio-rustls = { version = "0.26.2", default-features = false }
|
||||||
tokio-stream = "0.1"
|
tokio-stream = "0.1"
|
||||||
tokio-util = { version = "0.7", features = ["io-util", "compat"] }
|
tokio-util = { version = "0.7", features = ["io-util", "compat"] }
|
||||||
toml = "0.8.8"
|
toml = "0.8.8"
|
||||||
@@ -246,11 +256,13 @@ common-procedure-test = { path = "src/common/procedure-test" }
|
|||||||
common-query = { path = "src/common/query" }
|
common-query = { path = "src/common/query" }
|
||||||
common-recordbatch = { path = "src/common/recordbatch" }
|
common-recordbatch = { path = "src/common/recordbatch" }
|
||||||
common-runtime = { path = "src/common/runtime" }
|
common-runtime = { path = "src/common/runtime" }
|
||||||
|
common-session = { path = "src/common/session" }
|
||||||
common-telemetry = { path = "src/common/telemetry" }
|
common-telemetry = { path = "src/common/telemetry" }
|
||||||
common-test-util = { path = "src/common/test-util" }
|
common-test-util = { path = "src/common/test-util" }
|
||||||
common-time = { path = "src/common/time" }
|
common-time = { path = "src/common/time" }
|
||||||
common-version = { path = "src/common/version" }
|
common-version = { path = "src/common/version" }
|
||||||
common-wal = { path = "src/common/wal" }
|
common-wal = { path = "src/common/wal" }
|
||||||
|
common-workload = { path = "src/common/workload" }
|
||||||
datanode = { path = "src/datanode" }
|
datanode = { path = "src/datanode" }
|
||||||
datatypes = { path = "src/datatypes" }
|
datatypes = { path = "src/datatypes" }
|
||||||
file-engine = { path = "src/file-engine" }
|
file-engine = { path = "src/file-engine" }
|
||||||
@@ -265,6 +277,9 @@ metric-engine = { path = "src/metric-engine" }
|
|||||||
mito2 = { path = "src/mito2" }
|
mito2 = { path = "src/mito2" }
|
||||||
object-store = { path = "src/object-store" }
|
object-store = { path = "src/object-store" }
|
||||||
operator = { path = "src/operator" }
|
operator = { path = "src/operator" }
|
||||||
|
otel-arrow-rust = { git = "https://github.com/open-telemetry/otel-arrow", rev = "5d551412d2a12e689cde4d84c14ef29e36784e51", features = [
|
||||||
|
"server",
|
||||||
|
] }
|
||||||
partition = { path = "src/partition" }
|
partition = { path = "src/partition" }
|
||||||
pipeline = { path = "src/pipeline" }
|
pipeline = { path = "src/pipeline" }
|
||||||
plugins = { path = "src/plugins" }
|
plugins = { path = "src/plugins" }
|
||||||
@@ -274,19 +289,11 @@ query = { path = "src/query" }
|
|||||||
servers = { path = "src/servers" }
|
servers = { path = "src/servers" }
|
||||||
session = { path = "src/session" }
|
session = { path = "src/session" }
|
||||||
sql = { path = "src/sql" }
|
sql = { path = "src/sql" }
|
||||||
|
stat = { path = "src/common/stat" }
|
||||||
store-api = { path = "src/store-api" }
|
store-api = { path = "src/store-api" }
|
||||||
substrait = { path = "src/common/substrait" }
|
substrait = { path = "src/common/substrait" }
|
||||||
table = { path = "src/table" }
|
table = { path = "src/table" }
|
||||||
|
|
||||||
[patch.crates-io]
|
|
||||||
# change all rustls dependencies to use our fork to default to `ring` to make it "just work"
|
|
||||||
hyper-rustls = { git = "https://github.com/GreptimeTeam/hyper-rustls", rev = "a951e03" } # version = "0.27.5" with ring patch
|
|
||||||
rustls = { git = "https://github.com/GreptimeTeam/rustls", rev = "34fd0c6" } # version = "0.23.20" with ring patch
|
|
||||||
tokio-rustls = { git = "https://github.com/GreptimeTeam/tokio-rustls", rev = "4604ca6" } # version = "0.26.0" with ring patch
|
|
||||||
# This is commented, since we are not using aws-lc-sys, if we need to use it, we need to uncomment this line or use a release after this commit, or it wouldn't compile with gcc < 8.1
|
|
||||||
# see https://github.com/aws/aws-lc-rs/pull/526
|
|
||||||
# aws-lc-sys = { git ="https://github.com/aws/aws-lc-rs", rev = "556558441e3494af4b156ae95ebc07ebc2fd38aa" }
|
|
||||||
|
|
||||||
[workspace.dependencies.meter-macros]
|
[workspace.dependencies.meter-macros]
|
||||||
git = "https://github.com/GreptimeTeam/greptime-meter.git"
|
git = "https://github.com/GreptimeTeam/greptime-meter.git"
|
||||||
rev = "5618e779cf2bb4755b499c630fba4c35e91898cb"
|
rev = "5618e779cf2bb4755b499c630fba4c35e91898cb"
|
||||||
|
|||||||
17
Makefile
17
Makefile
@@ -8,7 +8,7 @@ CARGO_BUILD_OPTS := --locked
|
|||||||
IMAGE_REGISTRY ?= docker.io
|
IMAGE_REGISTRY ?= docker.io
|
||||||
IMAGE_NAMESPACE ?= greptime
|
IMAGE_NAMESPACE ?= greptime
|
||||||
IMAGE_TAG ?= latest
|
IMAGE_TAG ?= latest
|
||||||
DEV_BUILDER_IMAGE_TAG ?= 2024-12-25-a71b93dd-20250305072908
|
DEV_BUILDER_IMAGE_TAG ?= 2025-05-19-b2377d4b-20250520045554
|
||||||
BUILDX_MULTI_PLATFORM_BUILD ?= false
|
BUILDX_MULTI_PLATFORM_BUILD ?= false
|
||||||
BUILDX_BUILDER_NAME ?= gtbuilder
|
BUILDX_BUILDER_NAME ?= gtbuilder
|
||||||
BASE_IMAGE ?= ubuntu
|
BASE_IMAGE ?= ubuntu
|
||||||
@@ -32,6 +32,10 @@ ifneq ($(strip $(BUILD_JOBS)),)
|
|||||||
NEXTEST_OPTS += --build-jobs=${BUILD_JOBS}
|
NEXTEST_OPTS += --build-jobs=${BUILD_JOBS}
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(strip $(BUILD_JOBS)),)
|
||||||
|
SQLNESS_OPTS += --jobs ${BUILD_JOBS}
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(strip $(CARGO_PROFILE)),)
|
ifneq ($(strip $(CARGO_PROFILE)),)
|
||||||
CARGO_BUILD_OPTS += --profile ${CARGO_PROFILE}
|
CARGO_BUILD_OPTS += --profile ${CARGO_PROFILE}
|
||||||
endif
|
endif
|
||||||
@@ -193,6 +197,7 @@ fix-clippy: ## Fix clippy violations.
|
|||||||
fmt-check: ## Check code format.
|
fmt-check: ## Check code format.
|
||||||
cargo fmt --all -- --check
|
cargo fmt --all -- --check
|
||||||
python3 scripts/check-snafu.py
|
python3 scripts/check-snafu.py
|
||||||
|
python3 scripts/check-super-imports.py
|
||||||
|
|
||||||
.PHONY: start-etcd
|
.PHONY: start-etcd
|
||||||
start-etcd: ## Start single node etcd for testing purpose.
|
start-etcd: ## Start single node etcd for testing purpose.
|
||||||
@@ -217,6 +222,16 @@ start-cluster: ## Start the greptimedb cluster with etcd by using docker compose
|
|||||||
stop-cluster: ## Stop the greptimedb cluster that created by docker compose.
|
stop-cluster: ## Stop the greptimedb cluster that created by docker compose.
|
||||||
docker compose -f ./docker/docker-compose/cluster-with-etcd.yaml stop
|
docker compose -f ./docker/docker-compose/cluster-with-etcd.yaml stop
|
||||||
|
|
||||||
|
##@ Grafana
|
||||||
|
|
||||||
|
.PHONY: check-dashboards
|
||||||
|
check-dashboards: ## Check the Grafana dashboards.
|
||||||
|
@./grafana/scripts/check.sh
|
||||||
|
|
||||||
|
.PHONY: dashboards
|
||||||
|
dashboards: ## Generate the Grafana dashboards for standalone mode and intermediate dashboards.
|
||||||
|
@./grafana/scripts/gen-dashboards.sh
|
||||||
|
|
||||||
##@ Docs
|
##@ Docs
|
||||||
config-docs: ## Generate configuration documentation from toml files.
|
config-docs: ## Generate configuration documentation from toml files.
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
|
|||||||
194
README.md
194
README.md
@@ -6,7 +6,9 @@
|
|||||||
</picture>
|
</picture>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 align="center">Unified & Cost-Effective Time Series Database for Metrics, Logs, and Events</h2>
|
<h2 align="center">Real-Time & Cloud-Native Observability Database<br/>for metrics, logs, and traces</h2>
|
||||||
|
|
||||||
|
> Delivers sub-second querying at PB scale and exceptional cost efficiency from edge to cloud.
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<h3 align="center">
|
<h3 align="center">
|
||||||
@@ -49,70 +51,77 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
- [Introduction](#introduction)
|
- [Introduction](#introduction)
|
||||||
- [**Features: Why GreptimeDB**](#why-greptimedb)
|
- [⭐ Key Features](#features)
|
||||||
- [Architecture](https://docs.greptime.com/contributor-guide/overview/#architecture)
|
- [Quick Comparison](#quick-comparison)
|
||||||
- [Try it for free](#try-greptimedb)
|
- [Architecture](#architecture)
|
||||||
|
- [Try GreptimeDB](#try-greptimedb)
|
||||||
- [Getting Started](#getting-started)
|
- [Getting Started](#getting-started)
|
||||||
- [Project Status](#project-status)
|
- [Build From Source](#build-from-source)
|
||||||
- [Join the community](#community)
|
|
||||||
- [Contributing](#contributing)
|
|
||||||
- [Tools & Extensions](#tools--extensions)
|
- [Tools & Extensions](#tools--extensions)
|
||||||
|
- [Project Status](#project-status)
|
||||||
|
- [Community](#community)
|
||||||
- [License](#license)
|
- [License](#license)
|
||||||
|
- [Commercial Support](#commercial-support)
|
||||||
|
- [Contributing](#contributing)
|
||||||
- [Acknowledgement](#acknowledgement)
|
- [Acknowledgement](#acknowledgement)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
**GreptimeDB** is an open-source unified & cost-effective time-series database for **Metrics**, **Logs**, and **Events** (also **Traces** in plan). You can gain real-time insights from Edge to Cloud at Any Scale.
|
**GreptimeDB** is an open-source, cloud-native database purpose-built for the unified collection and analysis of observability data (metrics, logs, and traces). Whether you’re operating on the edge, in the cloud, or across hybrid environments, GreptimeDB empowers real-time insights at massive scale — all in one system.
|
||||||
|
|
||||||
## Why GreptimeDB
|
## Features
|
||||||
|
|
||||||
Our core developers have been building time-series data platforms for years. Based on our best practices, GreptimeDB was born to give you:
|
| Feature | Description |
|
||||||
|
| --------- | ----------- |
|
||||||
|
| [Unified Observability Data](https://docs.greptime.com/user-guide/concepts/why-greptimedb) | Store metrics, logs, and traces as timestamped, contextual wide events. Query via [SQL](https://docs.greptime.com/user-guide/query-data/sql), [PromQL](https://docs.greptime.com/user-guide/query-data/promql), and [streaming](https://docs.greptime.com/user-guide/flow-computation/overview). |
|
||||||
|
| [High Performance & Cost Effective](https://docs.greptime.com/user-guide/manage-data/data-index) | Written in Rust, with a distributed query engine, [rich indexing](https://docs.greptime.com/user-guide/manage-data/data-index), and optimized columnar storage, delivering sub-second responses at PB scale. |
|
||||||
|
| [Cloud-Native Architecture](https://docs.greptime.com/user-guide/concepts/architecture) | Designed for [Kubernetes](https://docs.greptime.com/user-guide/deployments/deploy-on-kubernetes/greptimedb-operator-management), with compute/storage separation, native object storage (AWS S3, Azure Blob, etc.) and seamless cross-cloud access. |
|
||||||
|
| [Developer-Friendly](https://docs.greptime.com/user-guide/protocols/overview) | Access via SQL/PromQL interfaces, REST API, MySQL/PostgreSQL protocols, and popular ingestion [protocols](https://docs.greptime.com/user-guide/protocols/overview). |
|
||||||
|
| [Flexible Deployment](https://docs.greptime.com/user-guide/deployments/overview) | Deploy anywhere: edge (including ARM/[Android](https://docs.greptime.com/user-guide/deployments/run-on-android)) or cloud, with unified APIs and efficient data sync. |
|
||||||
|
|
||||||
* **Unified Processing of Metrics, Logs, and Events**
|
Learn more in [Why GreptimeDB](https://docs.greptime.com/user-guide/concepts/why-greptimedb) and [Observability 2.0 and the Database for It](https://greptime.com/blogs/2025-04-25-greptimedb-observability2-new-database).
|
||||||
|
|
||||||
GreptimeDB unifies time series data processing by treating all data - whether metrics, logs, or events - as timestamped events with context. Users can analyze this data using either [SQL](https://docs.greptime.com/user-guide/query-data/sql) or [PromQL](https://docs.greptime.com/user-guide/query-data/promql) and leverage stream processing ([Flow](https://docs.greptime.com/user-guide/flow-computation/overview)) to enable continuous aggregation. [Read more](https://docs.greptime.com/user-guide/concepts/data-model).
|
## Quick Comparison
|
||||||
|
|
||||||
* **Cloud-native Distributed Database**
|
| Feature | GreptimeDB | Traditional TSDB | Log Stores |
|
||||||
|
|----------------------------------|-----------------------|--------------------|-----------------|
|
||||||
|
| Data Types | Metrics, Logs, Traces | Metrics only | Logs only |
|
||||||
|
| Query Language | SQL, PromQL, Streaming| Custom/PromQL | Custom/DSL |
|
||||||
|
| Deployment | Edge + Cloud | Cloud/On-prem | Mostly central |
|
||||||
|
| Indexing & Performance | PB-Scale, Sub-second | Varies | Varies |
|
||||||
|
| Integration | REST, SQL, Common protocols | Varies | Varies |
|
||||||
|
|
||||||
Built for [Kubernetes](https://docs.greptime.com/user-guide/deployments/deploy-on-kubernetes/greptimedb-operator-management). GreptimeDB achieves seamless scalability with its [cloud-native architecture](https://docs.greptime.com/user-guide/concepts/architecture) of separated compute and storage, built on object storage (AWS S3, Azure Blob Storage, etc.) while enabling cross-cloud deployment through a unified data access layer.
|
**Performance:**
|
||||||
|
* [GreptimeDB tops JSONBench's billion-record cold run test!](https://greptime.com/blogs/2025-03-18-jsonbench-greptimedb-performance)
|
||||||
|
* [TSBS Benchmark](https://github.com/GreptimeTeam/greptimedb/tree/main/docs/benchmarks/tsbs)
|
||||||
|
|
||||||
* **Performance and Cost-effective**
|
Read [more benchmark reports](https://docs.greptime.com/user-guide/concepts/features-that-you-concern#how-is-greptimedbs-performance-compared-to-other-solutions).
|
||||||
|
|
||||||
Written in pure Rust for superior performance and reliability. GreptimeDB features a distributed query engine with intelligent indexing to handle high cardinality data efficiently. Its optimized columnar storage achieves 50x cost efficiency on cloud object storage through advanced compression. [Benchmark reports](https://www.greptime.com/blogs/2024-09-09-report-summary).
|
## Architecture
|
||||||
|
|
||||||
* **Cloud-Edge Collaboration**
|
* Read the [architecture](https://docs.greptime.com/contributor-guide/overview/#architecture) document.
|
||||||
|
* [DeepWiki](https://deepwiki.com/GreptimeTeam/greptimedb/1-overview) provides an in-depth look at GreptimeDB:
|
||||||
GreptimeDB seamlessly operates across cloud and edge (ARM/Android/Linux), providing consistent APIs and control plane for unified data management and efficient synchronization. [Learn how to run on Android](https://docs.greptime.com/user-guide/deployments/run-on-android/).
|
<img alt="GreptimeDB System Overview" src="docs/architecture.png">
|
||||||
|
|
||||||
* **Multi-protocol Ingestion, SQL & PromQL Ready**
|
|
||||||
|
|
||||||
Widely adopted database protocols and APIs, including MySQL, PostgreSQL, InfluxDB, OpenTelemetry, Loki and Prometheus, etc. Effortless Adoption & Seamless Migration. [Supported Protocols Overview](https://docs.greptime.com/user-guide/protocols/overview).
|
|
||||||
|
|
||||||
For more detailed info please read [Why GreptimeDB](https://docs.greptime.com/user-guide/concepts/why-greptimedb).
|
|
||||||
|
|
||||||
## Try GreptimeDB
|
## Try GreptimeDB
|
||||||
|
|
||||||
### 1. [Live Demo](https://greptime.com/playground)
|
### 1. [Live Demo](https://greptime.com/playground)
|
||||||
|
|
||||||
Try out the features of GreptimeDB right from your browser.
|
Experience GreptimeDB directly in your browser.
|
||||||
|
|
||||||
### 2. [GreptimeCloud](https://console.greptime.cloud/)
|
### 2. [GreptimeCloud](https://console.greptime.cloud/)
|
||||||
|
|
||||||
Start instantly with a free cluster.
|
Start instantly with a free cluster.
|
||||||
|
|
||||||
### 3. Docker Image
|
### 3. Docker (Local Quickstart)
|
||||||
|
|
||||||
To install GreptimeDB locally, the recommended way is via Docker:
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker pull greptime/greptimedb
|
docker pull greptime/greptimedb
|
||||||
```
|
```
|
||||||
|
|
||||||
Start a GreptimeDB container with:
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker run -p 127.0.0.1:4000-4003:4000-4003 \
|
docker run -p 127.0.0.1:4000-4003:4000-4003 \
|
||||||
-v "$(pwd)/greptimedb:/tmp/greptimedb" \
|
-v "$(pwd)/greptimedb_data:/greptimedb_data" \
|
||||||
--name greptime --rm \
|
--name greptime --rm \
|
||||||
greptime/greptimedb:latest standalone start \
|
greptime/greptimedb:latest standalone start \
|
||||||
--http-addr 0.0.0.0:4000 \
|
--http-addr 0.0.0.0:4000 \
|
||||||
@@ -120,112 +129,89 @@ docker run -p 127.0.0.1:4000-4003:4000-4003 \
|
|||||||
--mysql-addr 0.0.0.0:4002 \
|
--mysql-addr 0.0.0.0:4002 \
|
||||||
--postgres-addr 0.0.0.0:4003
|
--postgres-addr 0.0.0.0:4003
|
||||||
```
|
```
|
||||||
|
Dashboard: [http://localhost:4000/dashboard](http://localhost:4000/dashboard)
|
||||||
|
[Full Install Guide](https://docs.greptime.com/getting-started/installation/overview)
|
||||||
|
|
||||||
Access the dashboard via `http://localhost:4000/dashboard`.
|
**Troubleshooting:**
|
||||||
|
* Cannot connect to the database? Ensure that ports `4000`, `4001`, `4002`, and `4003` are not blocked by a firewall or used by other services.
|
||||||
Read more about [Installation](https://docs.greptime.com/getting-started/installation/overview) on docs.
|
* Failed to start? Check the container logs with `docker logs greptime` for further details.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
* [Quickstart](https://docs.greptime.com/getting-started/quick-start)
|
- [Quickstart](https://docs.greptime.com/getting-started/quick-start)
|
||||||
* [User Guide](https://docs.greptime.com/user-guide/overview)
|
- [User Guide](https://docs.greptime.com/user-guide/overview)
|
||||||
* [Demos](https://github.com/GreptimeTeam/demo-scene)
|
- [Demo Scenes](https://github.com/GreptimeTeam/demo-scene)
|
||||||
* [FAQ](https://docs.greptime.com/faq-and-others/faq)
|
- [FAQ](https://docs.greptime.com/faq-and-others/faq)
|
||||||
|
|
||||||
## Build
|
## Build From Source
|
||||||
|
|
||||||
Check the prerequisite:
|
|
||||||
|
|
||||||
|
**Prerequisites:**
|
||||||
* [Rust toolchain](https://www.rust-lang.org/tools/install) (nightly)
|
* [Rust toolchain](https://www.rust-lang.org/tools/install) (nightly)
|
||||||
* [Protobuf compiler](https://grpc.io/docs/protoc-installation/) (>= 3.15)
|
* [Protobuf compiler](https://grpc.io/docs/protoc-installation/) (>= 3.15)
|
||||||
* C/C++ building essentials, including `gcc`/`g++`/`autoconf` and glibc library (eg. `libc6-dev` on Ubuntu and `glibc-devel` on Fedora)
|
* C/C++ building essentials, including `gcc`/`g++`/`autoconf` and glibc library (eg. `libc6-dev` on Ubuntu and `glibc-devel` on Fedora)
|
||||||
* Python toolchain (optional): Required only if using some test scripts.
|
* Python toolchain (optional): Required only if using some test scripts.
|
||||||
|
|
||||||
Build GreptimeDB binary:
|
**Build and Run:**
|
||||||
|
```bash
|
||||||
```shell
|
|
||||||
make
|
make
|
||||||
```
|
|
||||||
|
|
||||||
Run a standalone server:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
cargo run -- standalone start
|
cargo run -- standalone start
|
||||||
```
|
```
|
||||||
|
|
||||||
## Tools & Extensions
|
## Tools & Extensions
|
||||||
|
|
||||||
### Kubernetes
|
- **Kubernetes:** [GreptimeDB Operator](https://github.com/GrepTimeTeam/greptimedb-operator)
|
||||||
|
- **Helm Charts:** [Greptime Helm Charts](https://github.com/GreptimeTeam/helm-charts)
|
||||||
- [GreptimeDB Operator](https://github.com/GrepTimeTeam/greptimedb-operator)
|
- **Dashboard:** [Web UI](https://github.com/GreptimeTeam/dashboard)
|
||||||
|
- **SDKs/Ingester:** [Go](https://github.com/GreptimeTeam/greptimedb-ingester-go), [Java](https://github.com/GreptimeTeam/greptimedb-ingester-java), [C++](https://github.com/GreptimeTeam/greptimedb-ingester-cpp), [Erlang](https://github.com/GreptimeTeam/greptimedb-ingester-erl), [Rust](https://github.com/GreptimeTeam/greptimedb-ingester-rust), [JS](https://github.com/GreptimeTeam/greptimedb-ingester-js)
|
||||||
### Dashboard
|
- **Grafana**: [Official Dashboard](https://github.com/GreptimeTeam/greptimedb/blob/main/grafana/README.md)
|
||||||
|
|
||||||
- [The dashboard UI for GreptimeDB](https://github.com/GreptimeTeam/dashboard)
|
|
||||||
|
|
||||||
### SDK
|
|
||||||
|
|
||||||
- [GreptimeDB Go Ingester](https://github.com/GreptimeTeam/greptimedb-ingester-go)
|
|
||||||
- [GreptimeDB Java Ingester](https://github.com/GreptimeTeam/greptimedb-ingester-java)
|
|
||||||
- [GreptimeDB C++ Ingester](https://github.com/GreptimeTeam/greptimedb-ingester-cpp)
|
|
||||||
- [GreptimeDB Erlang Ingester](https://github.com/GreptimeTeam/greptimedb-ingester-erl)
|
|
||||||
- [GreptimeDB Rust Ingester](https://github.com/GreptimeTeam/greptimedb-ingester-rust)
|
|
||||||
- [GreptimeDB JavaScript Ingester](https://github.com/GreptimeTeam/greptimedb-ingester-js)
|
|
||||||
|
|
||||||
### Grafana Dashboard
|
|
||||||
|
|
||||||
Our official Grafana dashboard for monitoring GreptimeDB is available at [grafana](grafana/README.md) directory.
|
|
||||||
|
|
||||||
## Project Status
|
## Project Status
|
||||||
|
|
||||||
GreptimeDB is currently in Beta. We are targeting GA (General Availability) with v1.0 release by Early 2025.
|
> **Status:** Beta.
|
||||||
|
> **GA (v1.0):** Targeted for mid 2025.
|
||||||
|
|
||||||
While in Beta, GreptimeDB is already:
|
- Being used in production by early adopters
|
||||||
|
- Stable, actively maintained, with regular releases ([version info](https://docs.greptime.com/nightly/reference/about-greptimedb-version))
|
||||||
* Being used in production by early adopters
|
- Suitable for evaluation and pilot deployments
|
||||||
* Actively maintained with regular releases, [about version number](https://docs.greptime.com/nightly/reference/about-greptimedb-version)
|
|
||||||
* Suitable for testing and evaluation
|
|
||||||
|
|
||||||
For production use, we recommend using the latest stable release.
|
For production use, we recommend using the latest stable release.
|
||||||
|
[](https://www.star-history.com/#GreptimeTeam/GreptimeDB&Date)
|
||||||
|
|
||||||
|
If you find this project useful, a ⭐ would mean a lot to us!
|
||||||
|
<img alt="Known Users" src="https://greptime.com/logo/img/users.png"/>
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
Our core team is thrilled to see you participate in any ways you like. When you are stuck, try to
|
We invite you to engage and contribute!
|
||||||
ask for help by filling an issue with a detailed description of what you were trying to do
|
|
||||||
and what went wrong. If you have any questions or if you would like to get involved in our
|
|
||||||
community, please check out:
|
|
||||||
|
|
||||||
- GreptimeDB Community on [Slack](https://greptime.com/slack)
|
- [Slack](https://greptime.com/slack)
|
||||||
- GreptimeDB [GitHub Discussions forum](https://github.com/GreptimeTeam/greptimedb/discussions)
|
- [Discussions](https://github.com/GreptimeTeam/greptimedb/discussions)
|
||||||
- Greptime official [website](https://greptime.com)
|
- [Official Website](https://greptime.com/)
|
||||||
|
- [Blog](https://greptime.com/blogs/)
|
||||||
In addition, you may:
|
- [LinkedIn](https://www.linkedin.com/company/greptime/)
|
||||||
|
- [Twitter](https://twitter.com/greptime)
|
||||||
- View our official [Blog](https://greptime.com/blogs/)
|
|
||||||
- Connect us with [Linkedin](https://www.linkedin.com/company/greptime/)
|
|
||||||
- Follow us on [Twitter](https://twitter.com/greptime)
|
|
||||||
|
|
||||||
## Commercial Support
|
|
||||||
|
|
||||||
If you are running GreptimeDB OSS in your organization, we offer additional
|
|
||||||
enterprise add-ons, installation services, training, and consulting. [Contact
|
|
||||||
us](https://greptime.com/contactus) and we will reach out to you with more
|
|
||||||
detail of our commercial license.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
GreptimeDB uses the [Apache License 2.0](https://apache.org/licenses/LICENSE-2.0.txt) to strike a balance between
|
GreptimeDB is licensed under the [Apache License 2.0](https://apache.org/licenses/LICENSE-2.0.txt).
|
||||||
open contributions and allowing you to use the software however you want.
|
|
||||||
|
## Commercial Support
|
||||||
|
|
||||||
|
Running GreptimeDB in your organization?
|
||||||
|
We offer enterprise add-ons, services, training, and consulting.
|
||||||
|
[Contact us](https://greptime.com/contactus) for details.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Please refer to [contribution guidelines](CONTRIBUTING.md) and [internal concepts docs](https://docs.greptime.com/contributor-guide/overview.html) for more information.
|
- Read our [Contribution Guidelines](https://github.com/GreptimeTeam/greptimedb/blob/main/CONTRIBUTING.md).
|
||||||
|
- Explore [Internal Concepts](https://docs.greptime.com/contributor-guide/overview.html) and [DeepWiki](https://deepwiki.com/GreptimeTeam/greptimedb).
|
||||||
|
- Pick up a [good first issue](https://github.com/GreptimeTeam/greptimedb/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) and join the #contributors [Slack](https://greptime.com/slack) channel.
|
||||||
|
|
||||||
## Acknowledgement
|
## Acknowledgement
|
||||||
|
|
||||||
Special thanks to all the contributors who have propelled GreptimeDB forward. For a complete list of contributors, please refer to [AUTHOR.md](AUTHOR.md).
|
Special thanks to all contributors! See [AUTHORS.md](https://github.com/GreptimeTeam/greptimedb/blob/main/AUTHOR.md).
|
||||||
|
|
||||||
- GreptimeDB uses [Apache Arrow™](https://arrow.apache.org/) as the memory model and [Apache Parquet™](https://parquet.apache.org/) as the persistent file format.
|
- Uses [Apache Arrow™](https://arrow.apache.org/) (memory model)
|
||||||
- GreptimeDB's query engine is powered by [Apache Arrow DataFusion™](https://arrow.apache.org/datafusion/).
|
- [Apache Parquet™](https://parquet.apache.org/) (file storage)
|
||||||
- [Apache OpenDAL™](https://opendal.apache.org) gives GreptimeDB a very general and elegant data access abstraction layer.
|
- [Apache Arrow DataFusion™](https://arrow.apache.org/datafusion/) (query engine)
|
||||||
- GreptimeDB's meta service is based on [etcd](https://etcd.io/).
|
- [Apache OpenDAL™](https://opendal.apache.org/) (data access abstraction)
|
||||||
|
|||||||
124
config/config.md
124
config/config.md
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
| Key | Type | Default | Descriptions |
|
| Key | Type | Default | Descriptions |
|
||||||
| --- | -----| ------- | ----------- |
|
| --- | -----| ------- | ----------- |
|
||||||
| `mode` | String | `standalone` | The running mode of the datanode. It can be `standalone` or `distributed`. |
|
|
||||||
| `default_timezone` | String | Unset | The default timezone of the server. |
|
| `default_timezone` | String | Unset | The default timezone of the server. |
|
||||||
| `init_regions_in_background` | Bool | `false` | Initialize all regions in the background during the startup.<br/>By default, it provides services after all regions have been initialized. |
|
| `init_regions_in_background` | Bool | `false` | Initialize all regions in the background during the startup.<br/>By default, it provides services after all regions have been initialized. |
|
||||||
| `init_regions_parallelism` | Integer | `16` | Parallelism of initializing regions. |
|
| `init_regions_parallelism` | Integer | `16` | Parallelism of initializing regions. |
|
||||||
@@ -24,10 +23,11 @@
|
|||||||
| `runtime.compact_rt_size` | Integer | `4` | The number of threads to execute the runtime for global write operations. |
|
| `runtime.compact_rt_size` | Integer | `4` | The number of threads to execute the runtime for global write operations. |
|
||||||
| `http` | -- | -- | The HTTP server options. |
|
| `http` | -- | -- | The HTTP server options. |
|
||||||
| `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. |
|
| `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. |
|
||||||
| `http.timeout` | String | `30s` | HTTP request timeout. Set to 0 to disable timeout. |
|
| `http.timeout` | String | `0s` | HTTP request timeout. Set to 0 to disable timeout. |
|
||||||
| `http.body_limit` | String | `64MB` | HTTP request body limit.<br/>The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.<br/>Set to 0 to disable limit. |
|
| `http.body_limit` | String | `64MB` | HTTP request body limit.<br/>The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.<br/>Set to 0 to disable limit. |
|
||||||
| `http.enable_cors` | Bool | `true` | HTTP CORS support, it's turned on by default<br/>This allows browser to access http APIs without CORS restrictions |
|
| `http.enable_cors` | Bool | `true` | HTTP CORS support, it's turned on by default<br/>This allows browser to access http APIs without CORS restrictions |
|
||||||
| `http.cors_allowed_origins` | Array | Unset | Customize allowed origins for HTTP CORS. |
|
| `http.cors_allowed_origins` | Array | Unset | Customize allowed origins for HTTP CORS. |
|
||||||
|
| `http.prom_validation_mode` | String | `strict` | Whether to enable validation for Prometheus remote write requests.<br/>Available options:<br/>- strict: deny invalid UTF-8 strings (default).<br/>- lossy: allow invalid UTF-8 strings, replace invalid characters with REPLACEMENT_CHARACTER(U+FFFD).<br/>- unchecked: do not valid strings. |
|
||||||
| `grpc` | -- | -- | The gRPC server options. |
|
| `grpc` | -- | -- | The gRPC server options. |
|
||||||
| `grpc.bind_addr` | String | `127.0.0.1:4001` | The address to bind the gRPC server. |
|
| `grpc.bind_addr` | String | `127.0.0.1:4001` | The address to bind the gRPC server. |
|
||||||
| `grpc.runtime_size` | Integer | `8` | The number of server worker threads. |
|
| `grpc.runtime_size` | Integer | `8` | The number of server worker threads. |
|
||||||
@@ -86,10 +86,6 @@
|
|||||||
| `wal.create_topic_timeout` | String | `30s` | Above which a topic creation operation will be cancelled.<br/>**It's only used when the provider is `kafka`**. |
|
| `wal.create_topic_timeout` | String | `30s` | Above which a topic creation operation will be cancelled.<br/>**It's only used when the provider is `kafka`**. |
|
||||||
| `wal.max_batch_bytes` | String | `1MB` | The max size of a single producer batch.<br/>Warning: Kafka has a default limit of 1MB per message in a topic.<br/>**It's only used when the provider is `kafka`**. |
|
| `wal.max_batch_bytes` | String | `1MB` | The max size of a single producer batch.<br/>Warning: Kafka has a default limit of 1MB per message in a topic.<br/>**It's only used when the provider is `kafka`**. |
|
||||||
| `wal.consumer_wait_timeout` | String | `100ms` | The consumer wait timeout.<br/>**It's only used when the provider is `kafka`**. |
|
| `wal.consumer_wait_timeout` | String | `100ms` | The consumer wait timeout.<br/>**It's only used when the provider is `kafka`**. |
|
||||||
| `wal.backoff_init` | String | `500ms` | The initial backoff delay.<br/>**It's only used when the provider is `kafka`**. |
|
|
||||||
| `wal.backoff_max` | String | `10s` | The maximum backoff delay.<br/>**It's only used when the provider is `kafka`**. |
|
|
||||||
| `wal.backoff_base` | Integer | `2` | The exponential backoff rate, i.e. next backoff = base * current backoff.<br/>**It's only used when the provider is `kafka`**. |
|
|
||||||
| `wal.backoff_deadline` | String | `5mins` | The deadline of retries.<br/>**It's only used when the provider is `kafka`**. |
|
|
||||||
| `wal.overwrite_entry_start_id` | Bool | `false` | Ignore missing entries during read WAL.<br/>**It's only used when the provider is `kafka`**.<br/><br/>This option ensures that when Kafka messages are deleted, the system<br/>can still successfully replay memtable data without throwing an<br/>out-of-range error.<br/>However, enabling this option might lead to unexpected data loss,<br/>as the system will skip over missing entries instead of treating<br/>them as critical errors. |
|
| `wal.overwrite_entry_start_id` | Bool | `false` | Ignore missing entries during read WAL.<br/>**It's only used when the provider is `kafka`**.<br/><br/>This option ensures that when Kafka messages are deleted, the system<br/>can still successfully replay memtable data without throwing an<br/>out-of-range error.<br/>However, enabling this option might lead to unexpected data loss,<br/>as the system will skip over missing entries instead of treating<br/>them as critical errors. |
|
||||||
| `metadata_store` | -- | -- | Metadata storage options. |
|
| `metadata_store` | -- | -- | Metadata storage options. |
|
||||||
| `metadata_store.file_size` | String | `64MB` | The size of the metadata store log file. |
|
| `metadata_store.file_size` | String | `64MB` | The size of the metadata store log file. |
|
||||||
@@ -98,10 +94,13 @@
|
|||||||
| `procedure` | -- | -- | Procedure storage options. |
|
| `procedure` | -- | -- | Procedure storage options. |
|
||||||
| `procedure.max_retry_times` | Integer | `3` | Procedure max retry time. |
|
| `procedure.max_retry_times` | Integer | `3` | Procedure max retry time. |
|
||||||
| `procedure.retry_delay` | String | `500ms` | Initial retry delay of procedures, increases exponentially |
|
| `procedure.retry_delay` | String | `500ms` | Initial retry delay of procedures, increases exponentially |
|
||||||
|
| `procedure.max_running_procedures` | Integer | `128` | Max running procedures.<br/>The maximum number of procedures that can be running at the same time.<br/>If the number of running procedures exceeds this limit, the procedure will be rejected. |
|
||||||
| `flow` | -- | -- | flow engine options. |
|
| `flow` | -- | -- | flow engine options. |
|
||||||
| `flow.num_workers` | Integer | `0` | The number of flow worker in flownode.<br/>Not setting(or set to 0) this value will use the number of CPU cores divided by 2. |
|
| `flow.num_workers` | Integer | `0` | The number of flow worker in flownode.<br/>Not setting(or set to 0) this value will use the number of CPU cores divided by 2. |
|
||||||
|
| `query` | -- | -- | The query engine options. |
|
||||||
|
| `query.parallelism` | Integer | `0` | Parallelism of the query engine.<br/>Default to 0, which means the number of CPU cores. |
|
||||||
| `storage` | -- | -- | The data storage options. |
|
| `storage` | -- | -- | The data storage options. |
|
||||||
| `storage.data_home` | String | `/tmp/greptimedb/` | The working home directory. |
|
| `storage.data_home` | String | `./greptimedb_data` | The working home directory. |
|
||||||
| `storage.type` | String | `File` | The storage type used to store the data.<br/>- `File`: the data is stored in the local file system.<br/>- `S3`: the data is stored in the S3 object storage.<br/>- `Gcs`: the data is stored in the Google Cloud Storage.<br/>- `Azblob`: the data is stored in the Azure Blob Storage.<br/>- `Oss`: the data is stored in the Aliyun OSS. |
|
| `storage.type` | String | `File` | The storage type used to store the data.<br/>- `File`: the data is stored in the local file system.<br/>- `S3`: the data is stored in the S3 object storage.<br/>- `Gcs`: the data is stored in the Google Cloud Storage.<br/>- `Azblob`: the data is stored in the Azure Blob Storage.<br/>- `Oss`: the data is stored in the Aliyun OSS. |
|
||||||
| `storage.cache_path` | String | Unset | Read cache configuration for object storage such as 'S3' etc, it's configured by default when using object storage. It is recommended to configure it when using object storage for better performance.<br/>A local file directory, defaults to `{data_home}`. An empty string means disabling. |
|
| `storage.cache_path` | String | Unset | Read cache configuration for object storage such as 'S3' etc, it's configured by default when using object storage. It is recommended to configure it when using object storage for better performance.<br/>A local file directory, defaults to `{data_home}`. An empty string means disabling. |
|
||||||
| `storage.cache_capacity` | String | Unset | The local file cache capacity in bytes. If your disk space is sufficient, it is recommended to set it larger. |
|
| `storage.cache_capacity` | String | Unset | The local file cache capacity in bytes. If your disk space is sufficient, it is recommended to set it larger. |
|
||||||
@@ -156,6 +155,7 @@
|
|||||||
| `region_engine.mito.index.metadata_cache_size` | String | `64MiB` | Cache size for inverted index metadata. |
|
| `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_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. |
|
| `region_engine.mito.index.content_cache_page_size` | String | `64KiB` | Page size for inverted index content cache. |
|
||||||
|
| `region_engine.mito.index.result_cache_size` | String | `128MiB` | Cache size for index result. |
|
||||||
| `region_engine.mito.inverted_index` | -- | -- | The options for inverted index in Mito engine. |
|
| `region_engine.mito.inverted_index` | -- | -- | The options for inverted index in Mito engine. |
|
||||||
| `region_engine.mito.inverted_index.create_on_flush` | String | `auto` | Whether to create the index on flush.<br/>- `auto`: automatically (default)<br/>- `disable`: never |
|
| `region_engine.mito.inverted_index.create_on_flush` | String | `auto` | Whether to create the index on flush.<br/>- `auto`: automatically (default)<br/>- `disable`: never |
|
||||||
| `region_engine.mito.inverted_index.create_on_compaction` | String | `auto` | Whether to create the index on compaction.<br/>- `auto`: automatically (default)<br/>- `disable`: never |
|
| `region_engine.mito.inverted_index.create_on_compaction` | String | `auto` | Whether to create the index on compaction.<br/>- `auto`: automatically (default)<br/>- `disable`: never |
|
||||||
@@ -181,7 +181,7 @@
|
|||||||
| `region_engine.metric` | -- | -- | Metric engine options. |
|
| `region_engine.metric` | -- | -- | Metric engine options. |
|
||||||
| `region_engine.metric.experimental_sparse_primary_key_encoding` | Bool | `false` | Whether to enable the experimental sparse primary key encoding. |
|
| `region_engine.metric.experimental_sparse_primary_key_encoding` | Bool | `false` | Whether to enable the experimental sparse primary key encoding. |
|
||||||
| `logging` | -- | -- | The logging options. |
|
| `logging` | -- | -- | The logging options. |
|
||||||
| `logging.dir` | String | `/tmp/greptimedb/logs` | The directory to store the log files. If set to empty, logs will not be written to files. |
|
| `logging.dir` | String | `./greptimedb_data/logs` | The directory to store the log files. If set to empty, logs will not be written to files. |
|
||||||
| `logging.level` | String | Unset | The log level. Can be `info`/`debug`/`warn`/`error`. |
|
| `logging.level` | String | Unset | The log level. Can be `info`/`debug`/`warn`/`error`. |
|
||||||
| `logging.enable_otlp_tracing` | Bool | `false` | Enable OTLP tracing. |
|
| `logging.enable_otlp_tracing` | Bool | `false` | Enable OTLP tracing. |
|
||||||
| `logging.otlp_endpoint` | String | `http://localhost:4317` | The OTLP tracing endpoint. |
|
| `logging.otlp_endpoint` | String | `http://localhost:4317` | The OTLP tracing endpoint. |
|
||||||
@@ -190,17 +190,18 @@
|
|||||||
| `logging.max_log_files` | Integer | `720` | The maximum amount of log files. |
|
| `logging.max_log_files` | Integer | `720` | The maximum amount of log files. |
|
||||||
| `logging.tracing_sample_ratio` | -- | -- | The percentage of tracing will be sampled and exported.<br/>Valid range `[0, 1]`, 1 means all traces are sampled, 0 means all traces are not sampled, the default value is 1.<br/>ratio > 1 are treated as 1. Fractions < 0 are treated as 0 |
|
| `logging.tracing_sample_ratio` | -- | -- | The percentage of tracing will be sampled and exported.<br/>Valid range `[0, 1]`, 1 means all traces are sampled, 0 means all traces are not sampled, the default value is 1.<br/>ratio > 1 are treated as 1. Fractions < 0 are treated as 0 |
|
||||||
| `logging.tracing_sample_ratio.default_ratio` | Float | `1.0` | -- |
|
| `logging.tracing_sample_ratio.default_ratio` | Float | `1.0` | -- |
|
||||||
| `logging.slow_query` | -- | -- | The slow query log options. |
|
| `slow_query` | -- | -- | The slow query log options. |
|
||||||
| `logging.slow_query.enable` | Bool | `false` | Whether to enable slow query log. |
|
| `slow_query.enable` | Bool | `false` | Whether to enable slow query log. |
|
||||||
| `logging.slow_query.threshold` | String | Unset | The threshold of slow query. |
|
| `slow_query.record_type` | String | Unset | The record type of slow queries. It can be `system_table` or `log`. |
|
||||||
| `logging.slow_query.sample_ratio` | Float | Unset | The sampling ratio of slow query log. The value should be in the range of (0, 1]. |
|
| `slow_query.threshold` | String | Unset | The threshold of slow query. |
|
||||||
| `export_metrics` | -- | -- | The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.<br/>This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. |
|
| `slow_query.sample_ratio` | Float | Unset | The sampling ratio of slow query log. The value should be in the range of (0, 1]. |
|
||||||
|
| `export_metrics` | -- | -- | The standalone can export its metrics and send to Prometheus compatible service (e.g. `greptimedb`) from remote-write API.<br/>This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. |
|
||||||
| `export_metrics.enable` | Bool | `false` | whether enable export metrics. |
|
| `export_metrics.enable` | Bool | `false` | whether enable export metrics. |
|
||||||
| `export_metrics.write_interval` | String | `30s` | The interval of export metrics. |
|
| `export_metrics.write_interval` | String | `30s` | The interval of export metrics. |
|
||||||
| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommended to collect metrics generated by itself<br/>You must create the database before enabling it. |
|
| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommended to collect metrics generated by itself<br/>You must create the database before enabling it. |
|
||||||
| `export_metrics.self_import.db` | String | Unset | -- |
|
| `export_metrics.self_import.db` | String | Unset | -- |
|
||||||
| `export_metrics.remote_write` | -- | -- | -- |
|
| `export_metrics.remote_write` | -- | -- | -- |
|
||||||
| `export_metrics.remote_write.url` | String | `""` | The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`. |
|
| `export_metrics.remote_write.url` | String | `""` | The prometheus remote write endpoint that the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`. |
|
||||||
| `export_metrics.remote_write.headers` | InlineTable | -- | HTTP headers of Prometheus remote-write carry. |
|
| `export_metrics.remote_write.headers` | InlineTable | -- | HTTP headers of Prometheus remote-write carry. |
|
||||||
| `tracing` | -- | -- | The tracing options. Only effect when compiled with `tokio-console` feature. |
|
| `tracing` | -- | -- | The tracing options. Only effect when compiled with `tokio-console` feature. |
|
||||||
| `tracing.tokio_console_addr` | String | Unset | The tokio console address. |
|
| `tracing.tokio_console_addr` | String | Unset | The tokio console address. |
|
||||||
@@ -222,14 +223,16 @@
|
|||||||
| `heartbeat.retry_interval` | String | `3s` | Interval for retrying to send heartbeat messages to the metasrv. |
|
| `heartbeat.retry_interval` | String | `3s` | Interval for retrying to send heartbeat messages to the metasrv. |
|
||||||
| `http` | -- | -- | The HTTP server options. |
|
| `http` | -- | -- | The HTTP server options. |
|
||||||
| `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. |
|
| `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. |
|
||||||
| `http.timeout` | String | `30s` | HTTP request timeout. Set to 0 to disable timeout. |
|
| `http.timeout` | String | `0s` | HTTP request timeout. Set to 0 to disable timeout. |
|
||||||
| `http.body_limit` | String | `64MB` | HTTP request body limit.<br/>The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.<br/>Set to 0 to disable limit. |
|
| `http.body_limit` | String | `64MB` | HTTP request body limit.<br/>The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.<br/>Set to 0 to disable limit. |
|
||||||
| `http.enable_cors` | Bool | `true` | HTTP CORS support, it's turned on by default<br/>This allows browser to access http APIs without CORS restrictions |
|
| `http.enable_cors` | Bool | `true` | HTTP CORS support, it's turned on by default<br/>This allows browser to access http APIs without CORS restrictions |
|
||||||
| `http.cors_allowed_origins` | Array | Unset | Customize allowed origins for HTTP CORS. |
|
| `http.cors_allowed_origins` | Array | Unset | Customize allowed origins for HTTP CORS. |
|
||||||
|
| `http.prom_validation_mode` | String | `strict` | Whether to enable validation for Prometheus remote write requests.<br/>Available options:<br/>- strict: deny invalid UTF-8 strings (default).<br/>- lossy: allow invalid UTF-8 strings, replace invalid characters with REPLACEMENT_CHARACTER(U+FFFD).<br/>- unchecked: do not valid strings. |
|
||||||
| `grpc` | -- | -- | The gRPC server options. |
|
| `grpc` | -- | -- | The gRPC server options. |
|
||||||
| `grpc.bind_addr` | String | `127.0.0.1:4001` | The address to bind the gRPC server. |
|
| `grpc.bind_addr` | String | `127.0.0.1:4001` | The address to bind the gRPC server. |
|
||||||
| `grpc.server_addr` | String | `127.0.0.1:4001` | The address advertised to the metasrv, and used for connections from outside the host.<br/>If left empty or unset, the server will automatically use the IP address of the first network interface<br/>on the host, with the same port number as the one specified in `grpc.bind_addr`. |
|
| `grpc.server_addr` | String | `127.0.0.1:4001` | The address advertised to the metasrv, and used for connections from outside the host.<br/>If left empty or unset, the server will automatically use the IP address of the first network interface<br/>on the host, with the same port number as the one specified in `grpc.bind_addr`. |
|
||||||
| `grpc.runtime_size` | Integer | `8` | The number of server worker threads. |
|
| `grpc.runtime_size` | Integer | `8` | The number of server worker threads. |
|
||||||
|
| `grpc.flight_compression` | String | `arrow_ipc` | Compression mode for frontend side Arrow IPC service. Available options:<br/>- `none`: disable all compression<br/>- `transport`: only enable gRPC transport compression (zstd)<br/>- `arrow_ipc`: only enable Arrow IPC compression (lz4)<br/>- `all`: enable all compression. |
|
||||||
| `grpc.tls` | -- | -- | gRPC server TLS options, see `mysql.tls` section. |
|
| `grpc.tls` | -- | -- | gRPC server TLS options, see `mysql.tls` section. |
|
||||||
| `grpc.tls.mode` | String | `disable` | TLS mode. |
|
| `grpc.tls.mode` | String | `disable` | TLS mode. |
|
||||||
| `grpc.tls.cert_path` | String | Unset | Certificate file path. |
|
| `grpc.tls.cert_path` | String | Unset | Certificate file path. |
|
||||||
@@ -274,12 +277,14 @@
|
|||||||
| `meta_client.metadata_cache_max_capacity` | Integer | `100000` | The configuration about the cache of the metadata. |
|
| `meta_client.metadata_cache_max_capacity` | Integer | `100000` | The configuration about the cache of the metadata. |
|
||||||
| `meta_client.metadata_cache_ttl` | String | `10m` | TTL of the metadata cache. |
|
| `meta_client.metadata_cache_ttl` | String | `10m` | TTL of the metadata cache. |
|
||||||
| `meta_client.metadata_cache_tti` | String | `5m` | -- |
|
| `meta_client.metadata_cache_tti` | String | `5m` | -- |
|
||||||
|
| `query` | -- | -- | The query engine options. |
|
||||||
|
| `query.parallelism` | Integer | `0` | Parallelism of the query engine.<br/>Default to 0, which means the number of CPU cores. |
|
||||||
| `datanode` | -- | -- | Datanode options. |
|
| `datanode` | -- | -- | Datanode options. |
|
||||||
| `datanode.client` | -- | -- | Datanode client options. |
|
| `datanode.client` | -- | -- | Datanode client options. |
|
||||||
| `datanode.client.connect_timeout` | String | `10s` | -- |
|
| `datanode.client.connect_timeout` | String | `10s` | -- |
|
||||||
| `datanode.client.tcp_nodelay` | Bool | `true` | -- |
|
| `datanode.client.tcp_nodelay` | Bool | `true` | -- |
|
||||||
| `logging` | -- | -- | The logging options. |
|
| `logging` | -- | -- | The logging options. |
|
||||||
| `logging.dir` | String | `/tmp/greptimedb/logs` | The directory to store the log files. If set to empty, logs will not be written to files. |
|
| `logging.dir` | String | `./greptimedb_data/logs` | The directory to store the log files. If set to empty, logs will not be written to files. |
|
||||||
| `logging.level` | String | Unset | The log level. Can be `info`/`debug`/`warn`/`error`. |
|
| `logging.level` | String | Unset | The log level. Can be `info`/`debug`/`warn`/`error`. |
|
||||||
| `logging.enable_otlp_tracing` | Bool | `false` | Enable OTLP tracing. |
|
| `logging.enable_otlp_tracing` | Bool | `false` | Enable OTLP tracing. |
|
||||||
| `logging.otlp_endpoint` | String | `http://localhost:4317` | The OTLP tracing endpoint. |
|
| `logging.otlp_endpoint` | String | `http://localhost:4317` | The OTLP tracing endpoint. |
|
||||||
@@ -288,17 +293,17 @@
|
|||||||
| `logging.max_log_files` | Integer | `720` | The maximum amount of log files. |
|
| `logging.max_log_files` | Integer | `720` | The maximum amount of log files. |
|
||||||
| `logging.tracing_sample_ratio` | -- | -- | The percentage of tracing will be sampled and exported.<br/>Valid range `[0, 1]`, 1 means all traces are sampled, 0 means all traces are not sampled, the default value is 1.<br/>ratio > 1 are treated as 1. Fractions < 0 are treated as 0 |
|
| `logging.tracing_sample_ratio` | -- | -- | The percentage of tracing will be sampled and exported.<br/>Valid range `[0, 1]`, 1 means all traces are sampled, 0 means all traces are not sampled, the default value is 1.<br/>ratio > 1 are treated as 1. Fractions < 0 are treated as 0 |
|
||||||
| `logging.tracing_sample_ratio.default_ratio` | Float | `1.0` | -- |
|
| `logging.tracing_sample_ratio.default_ratio` | Float | `1.0` | -- |
|
||||||
| `logging.slow_query` | -- | -- | The slow query log options. |
|
| `slow_query` | -- | -- | The slow query log options. |
|
||||||
| `logging.slow_query.enable` | Bool | `false` | Whether to enable slow query log. |
|
| `slow_query.enable` | Bool | `true` | Whether to enable slow query log. |
|
||||||
| `logging.slow_query.threshold` | String | Unset | The threshold of slow query. |
|
| `slow_query.record_type` | String | `system_table` | The record type of slow queries. It can be `system_table` or `log`.<br/>If `system_table` is selected, the slow queries will be recorded in a system table `greptime_private.slow_queries`.<br/>If `log` is selected, the slow queries will be logged in a log file `greptimedb-slow-queries.*`. |
|
||||||
| `logging.slow_query.sample_ratio` | Float | Unset | The sampling ratio of slow query log. The value should be in the range of (0, 1]. |
|
| `slow_query.threshold` | String | `30s` | The threshold of slow query. It can be human readable time string, for example: `10s`, `100ms`, `1s`. |
|
||||||
| `export_metrics` | -- | -- | The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.<br/>This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. |
|
| `slow_query.sample_ratio` | Float | `1.0` | The sampling ratio of slow query log. The value should be in the range of (0, 1]. For example, `0.1` means 10% of the slow queries will be logged and `1.0` means all slow queries will be logged. |
|
||||||
|
| `slow_query.ttl` | String | `30d` | The TTL of the `slow_queries` system table. Default is `30d` when `record_type` is `system_table`. |
|
||||||
|
| `export_metrics` | -- | -- | The frontend can export its metrics and send to Prometheus compatible service (e.g. `greptimedb` itself) from remote-write API.<br/>This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. |
|
||||||
| `export_metrics.enable` | Bool | `false` | whether enable export metrics. |
|
| `export_metrics.enable` | Bool | `false` | whether enable export metrics. |
|
||||||
| `export_metrics.write_interval` | String | `30s` | The interval of export metrics. |
|
| `export_metrics.write_interval` | String | `30s` | The interval of export metrics. |
|
||||||
| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself<br/>You must create the database before enabling it. |
|
|
||||||
| `export_metrics.self_import.db` | String | Unset | -- |
|
|
||||||
| `export_metrics.remote_write` | -- | -- | -- |
|
| `export_metrics.remote_write` | -- | -- | -- |
|
||||||
| `export_metrics.remote_write.url` | String | `""` | The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`. |
|
| `export_metrics.remote_write.url` | String | `""` | The prometheus remote write endpoint that the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`. |
|
||||||
| `export_metrics.remote_write.headers` | InlineTable | -- | HTTP headers of Prometheus remote-write carry. |
|
| `export_metrics.remote_write.headers` | InlineTable | -- | HTTP headers of Prometheus remote-write carry. |
|
||||||
| `tracing` | -- | -- | The tracing options. Only effect when compiled with `tokio-console` feature. |
|
| `tracing` | -- | -- | The tracing options. Only effect when compiled with `tokio-console` feature. |
|
||||||
| `tracing.tokio_console_addr` | String | Unset | The tokio console address. |
|
| `tracing.tokio_console_addr` | String | Unset | The tokio console address. |
|
||||||
@@ -308,26 +313,36 @@
|
|||||||
|
|
||||||
| Key | Type | Default | Descriptions |
|
| Key | Type | Default | Descriptions |
|
||||||
| --- | -----| ------- | ----------- |
|
| --- | -----| ------- | ----------- |
|
||||||
| `data_home` | String | `/tmp/metasrv/` | The working home directory. |
|
| `data_home` | String | `./greptimedb_data` | The working home directory. |
|
||||||
| `bind_addr` | String | `127.0.0.1:3002` | The bind address of metasrv. |
|
|
||||||
| `server_addr` | String | `127.0.0.1:3002` | The communication server address for the frontend and datanode to connect to metasrv.<br/>If left empty or unset, the server will automatically use the IP address of the first network interface<br/>on the host, with the same port number as the one specified in `bind_addr`. |
|
|
||||||
| `store_addrs` | Array | -- | Store server address default to etcd store.<br/>For postgres store, the format is:<br/>"password=password dbname=postgres user=postgres host=localhost port=5432"<br/>For etcd store, the format is:<br/>"127.0.0.1:2379" |
|
| `store_addrs` | Array | -- | Store server address default to etcd store.<br/>For postgres store, the format is:<br/>"password=password dbname=postgres user=postgres host=localhost port=5432"<br/>For etcd store, the format is:<br/>"127.0.0.1:2379" |
|
||||||
| `store_key_prefix` | String | `""` | If it's not empty, the metasrv will store all data with this key prefix. |
|
| `store_key_prefix` | String | `""` | If it's not empty, the metasrv will store all data with this key prefix. |
|
||||||
| `backend` | String | `etcd_store` | The datastore for meta server.<br/>Available values:<br/>- `etcd_store` (default value)<br/>- `memory_store`<br/>- `postgres_store` |
|
| `backend` | String | `etcd_store` | The datastore for meta server.<br/>Available values:<br/>- `etcd_store` (default value)<br/>- `memory_store`<br/>- `postgres_store`<br/>- `mysql_store` |
|
||||||
| `meta_table_name` | String | `greptime_metakv` | Table name in RDS to store metadata. Effect when using a RDS kvbackend.<br/>**Only used when backend is `postgres_store`.** |
|
| `meta_table_name` | String | `greptime_metakv` | Table name in RDS to store metadata. Effect when using a RDS kvbackend.<br/>**Only used when backend is `postgres_store`.** |
|
||||||
| `meta_election_lock_id` | Integer | `1` | Advisory lock id in PostgreSQL for election. Effect when using PostgreSQL as kvbackend<br/>Only used when backend is `postgres_store`. |
|
| `meta_election_lock_id` | Integer | `1` | Advisory lock id in PostgreSQL for election. Effect when using PostgreSQL as kvbackend<br/>Only used when backend is `postgres_store`. |
|
||||||
| `selector` | String | `round_robin` | Datanode selector type.<br/>- `round_robin` (default value)<br/>- `lease_based`<br/>- `load_based`<br/>For details, please see "https://docs.greptime.com/developer-guide/metasrv/selector". |
|
| `selector` | String | `round_robin` | Datanode selector type.<br/>- `round_robin` (default value)<br/>- `lease_based`<br/>- `load_based`<br/>For details, please see "https://docs.greptime.com/developer-guide/metasrv/selector". |
|
||||||
| `use_memory_store` | Bool | `false` | Store data in memory. |
|
| `use_memory_store` | Bool | `false` | Store data in memory. |
|
||||||
| `enable_region_failover` | Bool | `false` | Whether to enable region failover.<br/>This feature is only available on GreptimeDB running on cluster mode and<br/>- Using Remote WAL<br/>- Using shared storage (e.g., s3). |
|
| `enable_region_failover` | Bool | `false` | Whether to enable region failover.<br/>This feature is only available on GreptimeDB running on cluster mode and<br/>- Using Remote WAL<br/>- Using shared storage (e.g., s3). |
|
||||||
|
| `allow_region_failover_on_local_wal` | Bool | `false` | Whether to allow region failover on local WAL.<br/>**This option is not recommended to be set to true, because it may lead to data loss during failover.** |
|
||||||
| `node_max_idle_time` | String | `24hours` | Max allowed idle time before removing node info from metasrv memory. |
|
| `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. |
|
| `enable_telemetry` | Bool | `true` | Whether to enable greptimedb telemetry. Enabled by default. |
|
||||||
| `runtime` | -- | -- | The runtime options. |
|
| `runtime` | -- | -- | The runtime options. |
|
||||||
| `runtime.global_rt_size` | Integer | `8` | The number of threads to execute the runtime for global read operations. |
|
| `runtime.global_rt_size` | Integer | `8` | The number of threads to execute the runtime for global read operations. |
|
||||||
| `runtime.compact_rt_size` | Integer | `4` | The number of threads to execute the runtime for global write operations. |
|
| `runtime.compact_rt_size` | Integer | `4` | The number of threads to execute the runtime for global write operations. |
|
||||||
|
| `grpc` | -- | -- | The gRPC server options. |
|
||||||
|
| `grpc.bind_addr` | String | `127.0.0.1:3002` | The address to bind the gRPC server. |
|
||||||
|
| `grpc.server_addr` | String | `127.0.0.1:3002` | The communication server address for the frontend and datanode to connect to metasrv.<br/>If left empty or unset, the server will automatically use the IP address of the first network interface<br/>on the host, with the same port number as the one specified in `bind_addr`. |
|
||||||
|
| `grpc.runtime_size` | Integer | `8` | The number of server worker threads. |
|
||||||
|
| `grpc.max_recv_message_size` | String | `512MB` | The maximum receive message size for gRPC server. |
|
||||||
|
| `grpc.max_send_message_size` | String | `512MB` | The maximum send message size for gRPC server. |
|
||||||
|
| `http` | -- | -- | The HTTP server options. |
|
||||||
|
| `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. |
|
||||||
|
| `http.timeout` | String | `0s` | HTTP request timeout. Set to 0 to disable timeout. |
|
||||||
|
| `http.body_limit` | String | `64MB` | HTTP request body limit.<br/>The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.<br/>Set to 0 to disable limit. |
|
||||||
| `procedure` | -- | -- | Procedure storage options. |
|
| `procedure` | -- | -- | Procedure storage options. |
|
||||||
| `procedure.max_retry_times` | Integer | `12` | Procedure max retry time. |
|
| `procedure.max_retry_times` | Integer | `12` | Procedure max retry time. |
|
||||||
| `procedure.retry_delay` | String | `500ms` | Initial retry delay of procedures, increases exponentially |
|
| `procedure.retry_delay` | String | `500ms` | Initial retry delay of procedures, increases exponentially |
|
||||||
| `procedure.max_metadata_value_size` | String | `1500KiB` | Auto split large value<br/>GreptimeDB procedure uses etcd as the default metadata storage backend.<br/>The etcd the maximum size of any request is 1.5 MiB<br/>1500KiB = 1536KiB (1.5MiB) - 36KiB (reserved size of key)<br/>Comments out the `max_metadata_value_size`, for don't split large value (no limit). |
|
| `procedure.max_metadata_value_size` | String | `1500KiB` | Auto split large value<br/>GreptimeDB procedure uses etcd as the default metadata storage backend.<br/>The etcd the maximum size of any request is 1.5 MiB<br/>1500KiB = 1536KiB (1.5MiB) - 36KiB (reserved size of key)<br/>Comments out the `max_metadata_value_size`, for don't split large value (no limit). |
|
||||||
|
| `procedure.max_running_procedures` | Integer | `128` | Max running procedures.<br/>The maximum number of procedures that can be running at the same time.<br/>If the number of running procedures exceeds this limit, the procedure will be rejected. |
|
||||||
| `failure_detector` | -- | -- | -- |
|
| `failure_detector` | -- | -- | -- |
|
||||||
| `failure_detector.threshold` | Float | `8.0` | The threshold value used by the failure detector to determine failure conditions. |
|
| `failure_detector.threshold` | Float | `8.0` | The threshold value used by the failure detector to determine failure conditions. |
|
||||||
| `failure_detector.min_std_deviation` | String | `100ms` | The minimum standard deviation of the heartbeat intervals, used to calculate acceptable variations. |
|
| `failure_detector.min_std_deviation` | String | `100ms` | The minimum standard deviation of the heartbeat intervals, used to calculate acceptable variations. |
|
||||||
@@ -342,17 +357,16 @@
|
|||||||
| `wal.provider` | String | `raft_engine` | -- |
|
| `wal.provider` | String | `raft_engine` | -- |
|
||||||
| `wal.broker_endpoints` | Array | -- | The broker endpoints of the Kafka cluster. |
|
| `wal.broker_endpoints` | Array | -- | The broker endpoints of the Kafka cluster. |
|
||||||
| `wal.auto_create_topics` | Bool | `true` | Automatically create topics for WAL.<br/>Set to `true` to automatically create topics for WAL.<br/>Otherwise, use topics named `topic_name_prefix_[0..num_topics)` |
|
| `wal.auto_create_topics` | Bool | `true` | Automatically create topics for WAL.<br/>Set to `true` to automatically create topics for WAL.<br/>Otherwise, use topics named `topic_name_prefix_[0..num_topics)` |
|
||||||
|
| `wal.auto_prune_interval` | String | `0s` | Interval of automatically WAL pruning.<br/>Set to `0s` to disable automatically WAL pruning which delete unused remote WAL entries periodically. |
|
||||||
|
| `wal.trigger_flush_threshold` | Integer | `0` | The threshold to trigger a flush operation of a region in automatically WAL pruning.<br/>Metasrv will send a flush request to flush the region when:<br/>`trigger_flush_threshold` + `prunable_entry_id` < `max_prunable_entry_id`<br/>where:<br/>- `prunable_entry_id` is the maximum entry id that can be pruned of the region.<br/>- `max_prunable_entry_id` is the maximum prunable entry id among all regions in the same topic.<br/>Set to `0` to disable the flush operation. |
|
||||||
|
| `wal.auto_prune_parallelism` | Integer | `10` | Concurrent task limit for automatically WAL pruning. |
|
||||||
| `wal.num_topics` | Integer | `64` | Number of topics. |
|
| `wal.num_topics` | Integer | `64` | Number of topics. |
|
||||||
| `wal.selector_type` | String | `round_robin` | Topic selector type.<br/>Available selector types:<br/>- `round_robin` (default) |
|
| `wal.selector_type` | String | `round_robin` | Topic selector type.<br/>Available selector types:<br/>- `round_robin` (default) |
|
||||||
| `wal.topic_name_prefix` | String | `greptimedb_wal_topic` | A Kafka topic is constructed by concatenating `topic_name_prefix` and `topic_id`.<br/>Only accepts strings that match the following regular expression pattern:<br/>[a-zA-Z_:-][a-zA-Z0-9_:\-\.@#]*<br/>i.g., greptimedb_wal_topic_0, greptimedb_wal_topic_1. |
|
| `wal.topic_name_prefix` | String | `greptimedb_wal_topic` | A Kafka topic is constructed by concatenating `topic_name_prefix` and `topic_id`.<br/>Only accepts strings that match the following regular expression pattern:<br/>[a-zA-Z_:-][a-zA-Z0-9_:\-\.@#]*<br/>i.g., greptimedb_wal_topic_0, greptimedb_wal_topic_1. |
|
||||||
| `wal.replication_factor` | Integer | `1` | Expected number of replicas of each partition. |
|
| `wal.replication_factor` | Integer | `1` | Expected number of replicas of each partition. |
|
||||||
| `wal.create_topic_timeout` | String | `30s` | Above which a topic creation operation will be cancelled. |
|
| `wal.create_topic_timeout` | String | `30s` | Above which a topic creation operation will be cancelled. |
|
||||||
| `wal.backoff_init` | String | `500ms` | The initial backoff for kafka clients. |
|
|
||||||
| `wal.backoff_max` | String | `10s` | The maximum backoff for kafka clients. |
|
|
||||||
| `wal.backoff_base` | Integer | `2` | Exponential backoff rate, i.e. next backoff = base * current backoff. |
|
|
||||||
| `wal.backoff_deadline` | String | `5mins` | Stop reconnecting if the total wait time reaches the deadline. If this config is missing, the reconnecting won't terminate. |
|
|
||||||
| `logging` | -- | -- | The logging options. |
|
| `logging` | -- | -- | The logging options. |
|
||||||
| `logging.dir` | String | `/tmp/greptimedb/logs` | The directory to store the log files. If set to empty, logs will not be written to files. |
|
| `logging.dir` | String | `./greptimedb_data/logs` | The directory to store the log files. If set to empty, logs will not be written to files. |
|
||||||
| `logging.level` | String | Unset | The log level. Can be `info`/`debug`/`warn`/`error`. |
|
| `logging.level` | String | Unset | The log level. Can be `info`/`debug`/`warn`/`error`. |
|
||||||
| `logging.enable_otlp_tracing` | Bool | `false` | Enable OTLP tracing. |
|
| `logging.enable_otlp_tracing` | Bool | `false` | Enable OTLP tracing. |
|
||||||
| `logging.otlp_endpoint` | String | `http://localhost:4317` | The OTLP tracing endpoint. |
|
| `logging.otlp_endpoint` | String | `http://localhost:4317` | The OTLP tracing endpoint. |
|
||||||
@@ -361,17 +375,11 @@
|
|||||||
| `logging.max_log_files` | Integer | `720` | The maximum amount of log files. |
|
| `logging.max_log_files` | Integer | `720` | The maximum amount of log files. |
|
||||||
| `logging.tracing_sample_ratio` | -- | -- | The percentage of tracing will be sampled and exported.<br/>Valid range `[0, 1]`, 1 means all traces are sampled, 0 means all traces are not sampled, the default value is 1.<br/>ratio > 1 are treated as 1. Fractions < 0 are treated as 0 |
|
| `logging.tracing_sample_ratio` | -- | -- | The percentage of tracing will be sampled and exported.<br/>Valid range `[0, 1]`, 1 means all traces are sampled, 0 means all traces are not sampled, the default value is 1.<br/>ratio > 1 are treated as 1. Fractions < 0 are treated as 0 |
|
||||||
| `logging.tracing_sample_ratio.default_ratio` | Float | `1.0` | -- |
|
| `logging.tracing_sample_ratio.default_ratio` | Float | `1.0` | -- |
|
||||||
| `logging.slow_query` | -- | -- | The slow query log options. |
|
| `export_metrics` | -- | -- | The metasrv can export its metrics and send to Prometheus compatible service (e.g. `greptimedb` itself) from remote-write API.<br/>This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. |
|
||||||
| `logging.slow_query.enable` | Bool | `false` | Whether to enable slow query log. |
|
|
||||||
| `logging.slow_query.threshold` | String | Unset | The threshold of slow query. |
|
|
||||||
| `logging.slow_query.sample_ratio` | Float | Unset | The sampling ratio of slow query log. The value should be in the range of (0, 1]. |
|
|
||||||
| `export_metrics` | -- | -- | The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.<br/>This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. |
|
|
||||||
| `export_metrics.enable` | Bool | `false` | whether enable export metrics. |
|
| `export_metrics.enable` | Bool | `false` | whether enable export metrics. |
|
||||||
| `export_metrics.write_interval` | String | `30s` | The interval of export metrics. |
|
| `export_metrics.write_interval` | String | `30s` | The interval of export metrics. |
|
||||||
| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself<br/>You must create the database before enabling it. |
|
|
||||||
| `export_metrics.self_import.db` | String | Unset | -- |
|
|
||||||
| `export_metrics.remote_write` | -- | -- | -- |
|
| `export_metrics.remote_write` | -- | -- | -- |
|
||||||
| `export_metrics.remote_write.url` | String | `""` | The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`. |
|
| `export_metrics.remote_write.url` | String | `""` | The prometheus remote write endpoint that the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`. |
|
||||||
| `export_metrics.remote_write.headers` | InlineTable | -- | HTTP headers of Prometheus remote-write carry. |
|
| `export_metrics.remote_write.headers` | InlineTable | -- | HTTP headers of Prometheus remote-write carry. |
|
||||||
| `tracing` | -- | -- | The tracing options. Only effect when compiled with `tokio-console` feature. |
|
| `tracing` | -- | -- | The tracing options. Only effect when compiled with `tokio-console` feature. |
|
||||||
| `tracing.tokio_console_addr` | String | Unset | The tokio console address. |
|
| `tracing.tokio_console_addr` | String | Unset | The tokio console address. |
|
||||||
@@ -381,7 +389,6 @@
|
|||||||
|
|
||||||
| Key | Type | Default | Descriptions |
|
| Key | Type | Default | Descriptions |
|
||||||
| --- | -----| ------- | ----------- |
|
| --- | -----| ------- | ----------- |
|
||||||
| `mode` | String | `standalone` | The running mode of the datanode. It can be `standalone` or `distributed`. |
|
|
||||||
| `node_id` | Integer | Unset | The datanode identifier and should be unique in the cluster. |
|
| `node_id` | Integer | Unset | The datanode identifier and should be unique in the cluster. |
|
||||||
| `require_lease_before_startup` | Bool | `false` | Start services after regions have obtained leases.<br/>It will block the datanode start if it can't receive leases in the heartbeat from metasrv. |
|
| `require_lease_before_startup` | Bool | `false` | Start services after regions have obtained leases.<br/>It will block the datanode start if it can't receive leases in the heartbeat from metasrv. |
|
||||||
| `init_regions_in_background` | Bool | `false` | Initialize all regions in the background during the startup.<br/>By default, it provides services after all regions have been initialized. |
|
| `init_regions_in_background` | Bool | `false` | Initialize all regions in the background during the startup.<br/>By default, it provides services after all regions have been initialized. |
|
||||||
@@ -390,7 +397,7 @@
|
|||||||
| `enable_telemetry` | Bool | `true` | Enable telemetry to collect anonymous usage data. Enabled by default. |
|
| `enable_telemetry` | Bool | `true` | Enable telemetry to collect anonymous usage data. Enabled by default. |
|
||||||
| `http` | -- | -- | The HTTP server options. |
|
| `http` | -- | -- | The HTTP server options. |
|
||||||
| `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. |
|
| `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. |
|
||||||
| `http.timeout` | String | `30s` | HTTP request timeout. Set to 0 to disable timeout. |
|
| `http.timeout` | String | `0s` | HTTP request timeout. Set to 0 to disable timeout. |
|
||||||
| `http.body_limit` | String | `64MB` | HTTP request body limit.<br/>The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.<br/>Set to 0 to disable limit. |
|
| `http.body_limit` | String | `64MB` | HTTP request body limit.<br/>The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.<br/>Set to 0 to disable limit. |
|
||||||
| `grpc` | -- | -- | The gRPC server options. |
|
| `grpc` | -- | -- | The gRPC server options. |
|
||||||
| `grpc.bind_addr` | String | `127.0.0.1:3001` | The address to bind the gRPC server. |
|
| `grpc.bind_addr` | String | `127.0.0.1:3001` | The address to bind the gRPC server. |
|
||||||
@@ -398,6 +405,7 @@
|
|||||||
| `grpc.runtime_size` | Integer | `8` | The number of server worker threads. |
|
| `grpc.runtime_size` | Integer | `8` | The number of server worker threads. |
|
||||||
| `grpc.max_recv_message_size` | String | `512MB` | The maximum receive message size for gRPC server. |
|
| `grpc.max_recv_message_size` | String | `512MB` | The maximum receive message size for gRPC server. |
|
||||||
| `grpc.max_send_message_size` | String | `512MB` | The maximum send message size for gRPC server. |
|
| `grpc.max_send_message_size` | String | `512MB` | The maximum send message size for gRPC server. |
|
||||||
|
| `grpc.flight_compression` | String | `arrow_ipc` | Compression mode for datanode side Arrow IPC service. Available options:<br/>- `none`: disable all compression<br/>- `transport`: only enable gRPC transport compression (zstd)<br/>- `arrow_ipc`: only enable Arrow IPC compression (lz4)<br/>- `all`: enable all compression. |
|
||||||
| `grpc.tls` | -- | -- | gRPC server TLS options, see `mysql.tls` section. |
|
| `grpc.tls` | -- | -- | gRPC server TLS options, see `mysql.tls` section. |
|
||||||
| `grpc.tls.mode` | String | `disable` | TLS mode. |
|
| `grpc.tls.mode` | String | `disable` | TLS mode. |
|
||||||
| `grpc.tls.cert_path` | String | Unset | Certificate file path. |
|
| `grpc.tls.cert_path` | String | Unset | Certificate file path. |
|
||||||
@@ -434,15 +442,13 @@
|
|||||||
| `wal.broker_endpoints` | Array | -- | The Kafka broker endpoints.<br/>**It's only used when the provider is `kafka`**. |
|
| `wal.broker_endpoints` | Array | -- | The Kafka broker endpoints.<br/>**It's only used when the provider is `kafka`**. |
|
||||||
| `wal.max_batch_bytes` | String | `1MB` | The max size of a single producer batch.<br/>Warning: Kafka has a default limit of 1MB per message in a topic.<br/>**It's only used when the provider is `kafka`**. |
|
| `wal.max_batch_bytes` | String | `1MB` | The max size of a single producer batch.<br/>Warning: Kafka has a default limit of 1MB per message in a topic.<br/>**It's only used when the provider is `kafka`**. |
|
||||||
| `wal.consumer_wait_timeout` | String | `100ms` | The consumer wait timeout.<br/>**It's only used when the provider is `kafka`**. |
|
| `wal.consumer_wait_timeout` | String | `100ms` | The consumer wait timeout.<br/>**It's only used when the provider is `kafka`**. |
|
||||||
| `wal.backoff_init` | String | `500ms` | The initial backoff delay.<br/>**It's only used when the provider is `kafka`**. |
|
|
||||||
| `wal.backoff_max` | String | `10s` | The maximum backoff delay.<br/>**It's only used when the provider is `kafka`**. |
|
|
||||||
| `wal.backoff_base` | Integer | `2` | The exponential backoff rate, i.e. next backoff = base * current backoff.<br/>**It's only used when the provider is `kafka`**. |
|
|
||||||
| `wal.backoff_deadline` | String | `5mins` | The deadline of retries.<br/>**It's only used when the provider is `kafka`**. |
|
|
||||||
| `wal.create_index` | Bool | `true` | Whether to enable WAL index creation.<br/>**It's only used when the provider is `kafka`**. |
|
| `wal.create_index` | Bool | `true` | Whether to enable WAL index creation.<br/>**It's only used when the provider is `kafka`**. |
|
||||||
| `wal.dump_index_interval` | String | `60s` | The interval for dumping WAL indexes.<br/>**It's only used when the provider is `kafka`**. |
|
| `wal.dump_index_interval` | String | `60s` | The interval for dumping WAL indexes.<br/>**It's only used when the provider is `kafka`**. |
|
||||||
| `wal.overwrite_entry_start_id` | Bool | `false` | Ignore missing entries during read WAL.<br/>**It's only used when the provider is `kafka`**.<br/><br/>This option ensures that when Kafka messages are deleted, the system<br/>can still successfully replay memtable data without throwing an<br/>out-of-range error.<br/>However, enabling this option might lead to unexpected data loss,<br/>as the system will skip over missing entries instead of treating<br/>them as critical errors. |
|
| `wal.overwrite_entry_start_id` | Bool | `false` | Ignore missing entries during read WAL.<br/>**It's only used when the provider is `kafka`**.<br/><br/>This option ensures that when Kafka messages are deleted, the system<br/>can still successfully replay memtable data without throwing an<br/>out-of-range error.<br/>However, enabling this option might lead to unexpected data loss,<br/>as the system will skip over missing entries instead of treating<br/>them as critical errors. |
|
||||||
|
| `query` | -- | -- | The query engine options. |
|
||||||
|
| `query.parallelism` | Integer | `0` | Parallelism of the query engine.<br/>Default to 0, which means the number of CPU cores. |
|
||||||
| `storage` | -- | -- | The data storage options. |
|
| `storage` | -- | -- | The data storage options. |
|
||||||
| `storage.data_home` | String | `/tmp/greptimedb/` | The working home directory. |
|
| `storage.data_home` | String | `./greptimedb_data` | The working home directory. |
|
||||||
| `storage.type` | String | `File` | The storage type used to store the data.<br/>- `File`: the data is stored in the local file system.<br/>- `S3`: the data is stored in the S3 object storage.<br/>- `Gcs`: the data is stored in the Google Cloud Storage.<br/>- `Azblob`: the data is stored in the Azure Blob Storage.<br/>- `Oss`: the data is stored in the Aliyun OSS. |
|
| `storage.type` | String | `File` | The storage type used to store the data.<br/>- `File`: the data is stored in the local file system.<br/>- `S3`: the data is stored in the S3 object storage.<br/>- `Gcs`: the data is stored in the Google Cloud Storage.<br/>- `Azblob`: the data is stored in the Azure Blob Storage.<br/>- `Oss`: the data is stored in the Aliyun OSS. |
|
||||||
| `storage.cache_path` | String | Unset | Read cache configuration for object storage such as 'S3' etc, it's configured by default when using object storage. It is recommended to configure it when using object storage for better performance.<br/>A local file directory, defaults to `{data_home}`. An empty string means disabling. |
|
| `storage.cache_path` | String | Unset | Read cache configuration for object storage such as 'S3' etc, it's configured by default when using object storage. It is recommended to configure it when using object storage for better performance.<br/>A local file directory, defaults to `{data_home}`. An empty string means disabling. |
|
||||||
| `storage.cache_capacity` | String | Unset | The local file cache capacity in bytes. If your disk space is sufficient, it is recommended to set it larger. |
|
| `storage.cache_capacity` | String | Unset | The local file cache capacity in bytes. If your disk space is sufficient, it is recommended to set it larger. |
|
||||||
@@ -497,6 +503,7 @@
|
|||||||
| `region_engine.mito.index.metadata_cache_size` | String | `64MiB` | Cache size for inverted index metadata. |
|
| `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_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. |
|
| `region_engine.mito.index.content_cache_page_size` | String | `64KiB` | Page size for inverted index content cache. |
|
||||||
|
| `region_engine.mito.index.result_cache_size` | String | `128MiB` | Cache size for index result. |
|
||||||
| `region_engine.mito.inverted_index` | -- | -- | The options for inverted index in Mito engine. |
|
| `region_engine.mito.inverted_index` | -- | -- | The options for inverted index in Mito engine. |
|
||||||
| `region_engine.mito.inverted_index.create_on_flush` | String | `auto` | Whether to create the index on flush.<br/>- `auto`: automatically (default)<br/>- `disable`: never |
|
| `region_engine.mito.inverted_index.create_on_flush` | String | `auto` | Whether to create the index on flush.<br/>- `auto`: automatically (default)<br/>- `disable`: never |
|
||||||
| `region_engine.mito.inverted_index.create_on_compaction` | String | `auto` | Whether to create the index on compaction.<br/>- `auto`: automatically (default)<br/>- `disable`: never |
|
| `region_engine.mito.inverted_index.create_on_compaction` | String | `auto` | Whether to create the index on compaction.<br/>- `auto`: automatically (default)<br/>- `disable`: never |
|
||||||
@@ -522,7 +529,7 @@
|
|||||||
| `region_engine.metric` | -- | -- | Metric engine options. |
|
| `region_engine.metric` | -- | -- | Metric engine options. |
|
||||||
| `region_engine.metric.experimental_sparse_primary_key_encoding` | Bool | `false` | Whether to enable the experimental sparse primary key encoding. |
|
| `region_engine.metric.experimental_sparse_primary_key_encoding` | Bool | `false` | Whether to enable the experimental sparse primary key encoding. |
|
||||||
| `logging` | -- | -- | The logging options. |
|
| `logging` | -- | -- | The logging options. |
|
||||||
| `logging.dir` | String | `/tmp/greptimedb/logs` | The directory to store the log files. If set to empty, logs will not be written to files. |
|
| `logging.dir` | String | `./greptimedb_data/logs` | The directory to store the log files. If set to empty, logs will not be written to files. |
|
||||||
| `logging.level` | String | Unset | The log level. Can be `info`/`debug`/`warn`/`error`. |
|
| `logging.level` | String | Unset | The log level. Can be `info`/`debug`/`warn`/`error`. |
|
||||||
| `logging.enable_otlp_tracing` | Bool | `false` | Enable OTLP tracing. |
|
| `logging.enable_otlp_tracing` | Bool | `false` | Enable OTLP tracing. |
|
||||||
| `logging.otlp_endpoint` | String | `http://localhost:4317` | The OTLP tracing endpoint. |
|
| `logging.otlp_endpoint` | String | `http://localhost:4317` | The OTLP tracing endpoint. |
|
||||||
@@ -531,17 +538,11 @@
|
|||||||
| `logging.max_log_files` | Integer | `720` | The maximum amount of log files. |
|
| `logging.max_log_files` | Integer | `720` | The maximum amount of log files. |
|
||||||
| `logging.tracing_sample_ratio` | -- | -- | The percentage of tracing will be sampled and exported.<br/>Valid range `[0, 1]`, 1 means all traces are sampled, 0 means all traces are not sampled, the default value is 1.<br/>ratio > 1 are treated as 1. Fractions < 0 are treated as 0 |
|
| `logging.tracing_sample_ratio` | -- | -- | The percentage of tracing will be sampled and exported.<br/>Valid range `[0, 1]`, 1 means all traces are sampled, 0 means all traces are not sampled, the default value is 1.<br/>ratio > 1 are treated as 1. Fractions < 0 are treated as 0 |
|
||||||
| `logging.tracing_sample_ratio.default_ratio` | Float | `1.0` | -- |
|
| `logging.tracing_sample_ratio.default_ratio` | Float | `1.0` | -- |
|
||||||
| `logging.slow_query` | -- | -- | The slow query log options. |
|
| `export_metrics` | -- | -- | The datanode can export its metrics and send to Prometheus compatible service (e.g. `greptimedb` itself) from remote-write API.<br/>This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. |
|
||||||
| `logging.slow_query.enable` | Bool | `false` | Whether to enable slow query log. |
|
|
||||||
| `logging.slow_query.threshold` | String | Unset | The threshold of slow query. |
|
|
||||||
| `logging.slow_query.sample_ratio` | Float | Unset | The sampling ratio of slow query log. The value should be in the range of (0, 1]. |
|
|
||||||
| `export_metrics` | -- | -- | The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.<br/>This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. |
|
|
||||||
| `export_metrics.enable` | Bool | `false` | whether enable export metrics. |
|
| `export_metrics.enable` | Bool | `false` | whether enable export metrics. |
|
||||||
| `export_metrics.write_interval` | String | `30s` | The interval of export metrics. |
|
| `export_metrics.write_interval` | String | `30s` | The interval of export metrics. |
|
||||||
| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself<br/>You must create the database before enabling it. |
|
|
||||||
| `export_metrics.self_import.db` | String | Unset | -- |
|
|
||||||
| `export_metrics.remote_write` | -- | -- | -- |
|
| `export_metrics.remote_write` | -- | -- | -- |
|
||||||
| `export_metrics.remote_write.url` | String | `""` | The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`. |
|
| `export_metrics.remote_write.url` | String | `""` | The prometheus remote write endpoint that the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`. |
|
||||||
| `export_metrics.remote_write.headers` | InlineTable | -- | HTTP headers of Prometheus remote-write carry. |
|
| `export_metrics.remote_write.headers` | InlineTable | -- | HTTP headers of Prometheus remote-write carry. |
|
||||||
| `tracing` | -- | -- | The tracing options. Only effect when compiled with `tokio-console` feature. |
|
| `tracing` | -- | -- | The tracing options. Only effect when compiled with `tokio-console` feature. |
|
||||||
| `tracing.tokio_console_addr` | String | Unset | The tokio console address. |
|
| `tracing.tokio_console_addr` | String | Unset | The tokio console address. |
|
||||||
@@ -551,7 +552,6 @@
|
|||||||
|
|
||||||
| Key | Type | Default | Descriptions |
|
| Key | Type | Default | Descriptions |
|
||||||
| --- | -----| ------- | ----------- |
|
| --- | -----| ------- | ----------- |
|
||||||
| `mode` | String | `distributed` | The running mode of the flownode. It can be `standalone` or `distributed`. |
|
|
||||||
| `node_id` | Integer | Unset | The flownode identifier and should be unique in the cluster. |
|
| `node_id` | Integer | Unset | The flownode identifier and should be unique in the cluster. |
|
||||||
| `flow` | -- | -- | flow engine options. |
|
| `flow` | -- | -- | flow engine options. |
|
||||||
| `flow.num_workers` | Integer | `0` | The number of flow worker in flownode.<br/>Not setting(or set to 0) this value will use the number of CPU cores divided by 2. |
|
| `flow.num_workers` | Integer | `0` | The number of flow worker in flownode.<br/>Not setting(or set to 0) this value will use the number of CPU cores divided by 2. |
|
||||||
@@ -563,7 +563,7 @@
|
|||||||
| `grpc.max_send_message_size` | String | `512MB` | The maximum send message size for gRPC server. |
|
| `grpc.max_send_message_size` | String | `512MB` | The maximum send message size for gRPC server. |
|
||||||
| `http` | -- | -- | The HTTP server options. |
|
| `http` | -- | -- | The HTTP server options. |
|
||||||
| `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. |
|
| `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. |
|
||||||
| `http.timeout` | String | `30s` | HTTP request timeout. Set to 0 to disable timeout. |
|
| `http.timeout` | String | `0s` | HTTP request timeout. Set to 0 to disable timeout. |
|
||||||
| `http.body_limit` | String | `64MB` | HTTP request body limit.<br/>The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.<br/>Set to 0 to disable limit. |
|
| `http.body_limit` | String | `64MB` | HTTP request body limit.<br/>The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.<br/>Set to 0 to disable limit. |
|
||||||
| `meta_client` | -- | -- | The metasrv client options. |
|
| `meta_client` | -- | -- | The metasrv client options. |
|
||||||
| `meta_client.metasrv_addrs` | Array | -- | The addresses of the metasrv. |
|
| `meta_client.metasrv_addrs` | Array | -- | The addresses of the metasrv. |
|
||||||
@@ -579,7 +579,7 @@
|
|||||||
| `heartbeat.interval` | String | `3s` | Interval for sending heartbeat messages to the metasrv. |
|
| `heartbeat.interval` | String | `3s` | Interval for sending heartbeat messages to the metasrv. |
|
||||||
| `heartbeat.retry_interval` | String | `3s` | Interval for retrying to send heartbeat messages to the metasrv. |
|
| `heartbeat.retry_interval` | String | `3s` | Interval for retrying to send heartbeat messages to the metasrv. |
|
||||||
| `logging` | -- | -- | The logging options. |
|
| `logging` | -- | -- | The logging options. |
|
||||||
| `logging.dir` | String | `/tmp/greptimedb/logs` | The directory to store the log files. If set to empty, logs will not be written to files. |
|
| `logging.dir` | String | `./greptimedb_data/logs` | The directory to store the log files. If set to empty, logs will not be written to files. |
|
||||||
| `logging.level` | String | Unset | The log level. Can be `info`/`debug`/`warn`/`error`. |
|
| `logging.level` | String | Unset | The log level. Can be `info`/`debug`/`warn`/`error`. |
|
||||||
| `logging.enable_otlp_tracing` | Bool | `false` | Enable OTLP tracing. |
|
| `logging.enable_otlp_tracing` | Bool | `false` | Enable OTLP tracing. |
|
||||||
| `logging.otlp_endpoint` | String | `http://localhost:4317` | The OTLP tracing endpoint. |
|
| `logging.otlp_endpoint` | String | `http://localhost:4317` | The OTLP tracing endpoint. |
|
||||||
@@ -588,9 +588,5 @@
|
|||||||
| `logging.max_log_files` | Integer | `720` | The maximum amount of log files. |
|
| `logging.max_log_files` | Integer | `720` | The maximum amount of log files. |
|
||||||
| `logging.tracing_sample_ratio` | -- | -- | The percentage of tracing will be sampled and exported.<br/>Valid range `[0, 1]`, 1 means all traces are sampled, 0 means all traces are not sampled, the default value is 1.<br/>ratio > 1 are treated as 1. Fractions < 0 are treated as 0 |
|
| `logging.tracing_sample_ratio` | -- | -- | The percentage of tracing will be sampled and exported.<br/>Valid range `[0, 1]`, 1 means all traces are sampled, 0 means all traces are not sampled, the default value is 1.<br/>ratio > 1 are treated as 1. Fractions < 0 are treated as 0 |
|
||||||
| `logging.tracing_sample_ratio.default_ratio` | Float | `1.0` | -- |
|
| `logging.tracing_sample_ratio.default_ratio` | Float | `1.0` | -- |
|
||||||
| `logging.slow_query` | -- | -- | The slow query log options. |
|
|
||||||
| `logging.slow_query.enable` | Bool | `false` | Whether to enable slow query log. |
|
|
||||||
| `logging.slow_query.threshold` | String | Unset | The threshold of slow query. |
|
|
||||||
| `logging.slow_query.sample_ratio` | Float | Unset | The sampling ratio of slow query log. The value should be in the range of (0, 1]. |
|
|
||||||
| `tracing` | -- | -- | The tracing options. Only effect when compiled with `tokio-console` feature. |
|
| `tracing` | -- | -- | The tracing options. Only effect when compiled with `tokio-console` feature. |
|
||||||
| `tracing.tokio_console_addr` | String | Unset | The tokio console address. |
|
| `tracing.tokio_console_addr` | String | Unset | The tokio console address. |
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
## The running mode of the datanode. It can be `standalone` or `distributed`.
|
|
||||||
mode = "standalone"
|
|
||||||
|
|
||||||
## The datanode identifier and should be unique in the cluster.
|
## The datanode identifier and should be unique in the cluster.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
node_id = 42
|
node_id = 42
|
||||||
@@ -27,7 +24,7 @@ max_concurrent_queries = 0
|
|||||||
## The address to bind the HTTP server.
|
## The address to bind the HTTP server.
|
||||||
addr = "127.0.0.1:4000"
|
addr = "127.0.0.1:4000"
|
||||||
## HTTP request timeout. Set to 0 to disable timeout.
|
## HTTP request timeout. Set to 0 to disable timeout.
|
||||||
timeout = "30s"
|
timeout = "0s"
|
||||||
## HTTP request body limit.
|
## HTTP request body limit.
|
||||||
## The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
|
## The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
|
||||||
## Set to 0 to disable limit.
|
## Set to 0 to disable limit.
|
||||||
@@ -47,6 +44,13 @@ runtime_size = 8
|
|||||||
max_recv_message_size = "512MB"
|
max_recv_message_size = "512MB"
|
||||||
## The maximum send message size for gRPC server.
|
## The maximum send message size for gRPC server.
|
||||||
max_send_message_size = "512MB"
|
max_send_message_size = "512MB"
|
||||||
|
## Compression mode for datanode side Arrow IPC service. Available options:
|
||||||
|
## - `none`: disable all compression
|
||||||
|
## - `transport`: only enable gRPC transport compression (zstd)
|
||||||
|
## - `arrow_ipc`: only enable Arrow IPC compression (lz4)
|
||||||
|
## - `all`: enable all compression.
|
||||||
|
## Default to `none`
|
||||||
|
flight_compression = "arrow_ipc"
|
||||||
|
|
||||||
## gRPC server TLS options, see `mysql.tls` section.
|
## gRPC server TLS options, see `mysql.tls` section.
|
||||||
[grpc.tls]
|
[grpc.tls]
|
||||||
@@ -119,7 +123,7 @@ provider = "raft_engine"
|
|||||||
## The directory to store the WAL files.
|
## The directory to store the WAL files.
|
||||||
## **It's only used when the provider is `raft_engine`**.
|
## **It's only used when the provider is `raft_engine`**.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
dir = "/tmp/greptimedb/wal"
|
dir = "./greptimedb_data/wal"
|
||||||
|
|
||||||
## The size of the WAL segment file.
|
## The size of the WAL segment file.
|
||||||
## **It's only used when the provider is `raft_engine`**.
|
## **It's only used when the provider is `raft_engine`**.
|
||||||
@@ -169,22 +173,6 @@ max_batch_bytes = "1MB"
|
|||||||
## **It's only used when the provider is `kafka`**.
|
## **It's only used when the provider is `kafka`**.
|
||||||
consumer_wait_timeout = "100ms"
|
consumer_wait_timeout = "100ms"
|
||||||
|
|
||||||
## The initial backoff delay.
|
|
||||||
## **It's only used when the provider is `kafka`**.
|
|
||||||
backoff_init = "500ms"
|
|
||||||
|
|
||||||
## The maximum backoff delay.
|
|
||||||
## **It's only used when the provider is `kafka`**.
|
|
||||||
backoff_max = "10s"
|
|
||||||
|
|
||||||
## The exponential backoff rate, i.e. next backoff = base * current backoff.
|
|
||||||
## **It's only used when the provider is `kafka`**.
|
|
||||||
backoff_base = 2
|
|
||||||
|
|
||||||
## The deadline of retries.
|
|
||||||
## **It's only used when the provider is `kafka`**.
|
|
||||||
backoff_deadline = "5mins"
|
|
||||||
|
|
||||||
## Whether to enable WAL index creation.
|
## Whether to enable WAL index creation.
|
||||||
## **It's only used when the provider is `kafka`**.
|
## **It's only used when the provider is `kafka`**.
|
||||||
create_index = true
|
create_index = true
|
||||||
@@ -262,10 +250,16 @@ overwrite_entry_start_id = false
|
|||||||
# credential = "base64-credential"
|
# credential = "base64-credential"
|
||||||
# endpoint = "https://storage.googleapis.com"
|
# endpoint = "https://storage.googleapis.com"
|
||||||
|
|
||||||
|
## The query engine options.
|
||||||
|
[query]
|
||||||
|
## Parallelism of the query engine.
|
||||||
|
## Default to 0, which means the number of CPU cores.
|
||||||
|
parallelism = 0
|
||||||
|
|
||||||
## The data storage options.
|
## The data storage options.
|
||||||
[storage]
|
[storage]
|
||||||
## The working home directory.
|
## The working home directory.
|
||||||
data_home = "/tmp/greptimedb/"
|
data_home = "./greptimedb_data"
|
||||||
|
|
||||||
## The storage type used to store the data.
|
## The storage type used to store the data.
|
||||||
## - `File`: the data is stored in the local file system.
|
## - `File`: the data is stored in the local file system.
|
||||||
@@ -512,6 +506,9 @@ content_cache_size = "128MiB"
|
|||||||
## Page size for inverted index content cache.
|
## Page size for inverted index content cache.
|
||||||
content_cache_page_size = "64KiB"
|
content_cache_page_size = "64KiB"
|
||||||
|
|
||||||
|
## Cache size for index result.
|
||||||
|
result_cache_size = "128MiB"
|
||||||
|
|
||||||
## The options for inverted index in Mito engine.
|
## The options for inverted index in Mito engine.
|
||||||
[region_engine.mito.inverted_index]
|
[region_engine.mito.inverted_index]
|
||||||
|
|
||||||
@@ -618,7 +615,7 @@ experimental_sparse_primary_key_encoding = false
|
|||||||
## The logging options.
|
## The logging options.
|
||||||
[logging]
|
[logging]
|
||||||
## The directory to store the log files. If set to empty, logs will not be written to files.
|
## The directory to store the log files. If set to empty, logs will not be written to files.
|
||||||
dir = "/tmp/greptimedb/logs"
|
dir = "./greptimedb_data/logs"
|
||||||
|
|
||||||
## The log level. Can be `info`/`debug`/`warn`/`error`.
|
## The log level. Can be `info`/`debug`/`warn`/`error`.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
@@ -645,37 +642,16 @@ max_log_files = 720
|
|||||||
[logging.tracing_sample_ratio]
|
[logging.tracing_sample_ratio]
|
||||||
default_ratio = 1.0
|
default_ratio = 1.0
|
||||||
|
|
||||||
## The slow query log options.
|
## The datanode can export its metrics and send to Prometheus compatible service (e.g. `greptimedb` itself) from remote-write API.
|
||||||
[logging.slow_query]
|
|
||||||
## Whether to enable slow query log.
|
|
||||||
enable = false
|
|
||||||
|
|
||||||
## The threshold of slow query.
|
|
||||||
## @toml2docs:none-default
|
|
||||||
threshold = "10s"
|
|
||||||
|
|
||||||
## The sampling ratio of slow query log. The value should be in the range of (0, 1].
|
|
||||||
## @toml2docs:none-default
|
|
||||||
sample_ratio = 1.0
|
|
||||||
|
|
||||||
## The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.
|
|
||||||
## This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape.
|
## This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape.
|
||||||
[export_metrics]
|
[export_metrics]
|
||||||
|
|
||||||
## whether enable export metrics.
|
## whether enable export metrics.
|
||||||
enable = false
|
enable = false
|
||||||
|
|
||||||
## The interval of export metrics.
|
## The interval of export metrics.
|
||||||
write_interval = "30s"
|
write_interval = "30s"
|
||||||
|
|
||||||
## For `standalone` mode, `self_import` is recommend to collect metrics generated by itself
|
|
||||||
## You must create the database before enabling it.
|
|
||||||
[export_metrics.self_import]
|
|
||||||
## @toml2docs:none-default
|
|
||||||
db = "greptime_metrics"
|
|
||||||
|
|
||||||
[export_metrics.remote_write]
|
[export_metrics.remote_write]
|
||||||
## The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`.
|
## The prometheus remote write endpoint that the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`.
|
||||||
url = ""
|
url = ""
|
||||||
|
|
||||||
## HTTP headers of Prometheus remote-write carry.
|
## HTTP headers of Prometheus remote-write carry.
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
## The running mode of the flownode. It can be `standalone` or `distributed`.
|
|
||||||
mode = "distributed"
|
|
||||||
|
|
||||||
## The flownode identifier and should be unique in the cluster.
|
## The flownode identifier and should be unique in the cluster.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
node_id = 14
|
node_id = 14
|
||||||
@@ -30,7 +27,7 @@ max_send_message_size = "512MB"
|
|||||||
## The address to bind the HTTP server.
|
## The address to bind the HTTP server.
|
||||||
addr = "127.0.0.1:4000"
|
addr = "127.0.0.1:4000"
|
||||||
## HTTP request timeout. Set to 0 to disable timeout.
|
## HTTP request timeout. Set to 0 to disable timeout.
|
||||||
timeout = "30s"
|
timeout = "0s"
|
||||||
## HTTP request body limit.
|
## HTTP request body limit.
|
||||||
## The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
|
## The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
|
||||||
## Set to 0 to disable limit.
|
## Set to 0 to disable limit.
|
||||||
@@ -76,7 +73,7 @@ retry_interval = "3s"
|
|||||||
## The logging options.
|
## The logging options.
|
||||||
[logging]
|
[logging]
|
||||||
## The directory to store the log files. If set to empty, logs will not be written to files.
|
## The directory to store the log files. If set to empty, logs will not be written to files.
|
||||||
dir = "/tmp/greptimedb/logs"
|
dir = "./greptimedb_data/logs"
|
||||||
|
|
||||||
## The log level. Can be `info`/`debug`/`warn`/`error`.
|
## The log level. Can be `info`/`debug`/`warn`/`error`.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
@@ -103,22 +100,8 @@ max_log_files = 720
|
|||||||
[logging.tracing_sample_ratio]
|
[logging.tracing_sample_ratio]
|
||||||
default_ratio = 1.0
|
default_ratio = 1.0
|
||||||
|
|
||||||
## The slow query log options.
|
|
||||||
[logging.slow_query]
|
|
||||||
## Whether to enable slow query log.
|
|
||||||
enable = false
|
|
||||||
|
|
||||||
## The threshold of slow query.
|
|
||||||
## @toml2docs:none-default
|
|
||||||
threshold = "10s"
|
|
||||||
|
|
||||||
## The sampling ratio of slow query log. The value should be in the range of (0, 1].
|
|
||||||
## @toml2docs:none-default
|
|
||||||
sample_ratio = 1.0
|
|
||||||
|
|
||||||
## The tracing options. Only effect when compiled with `tokio-console` feature.
|
## The tracing options. Only effect when compiled with `tokio-console` feature.
|
||||||
#+ [tracing]
|
#+ [tracing]
|
||||||
## The tokio console address.
|
## The tokio console address.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
#+ tokio_console_addr = "127.0.0.1"
|
#+ tokio_console_addr = "127.0.0.1"
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ retry_interval = "3s"
|
|||||||
## The address to bind the HTTP server.
|
## The address to bind the HTTP server.
|
||||||
addr = "127.0.0.1:4000"
|
addr = "127.0.0.1:4000"
|
||||||
## HTTP request timeout. Set to 0 to disable timeout.
|
## HTTP request timeout. Set to 0 to disable timeout.
|
||||||
timeout = "30s"
|
timeout = "0s"
|
||||||
## HTTP request body limit.
|
## HTTP request body limit.
|
||||||
## The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
|
## The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
|
||||||
## Set to 0 to disable limit.
|
## Set to 0 to disable limit.
|
||||||
@@ -37,6 +37,12 @@ enable_cors = true
|
|||||||
## Customize allowed origins for HTTP CORS.
|
## Customize allowed origins for HTTP CORS.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
cors_allowed_origins = ["https://example.com"]
|
cors_allowed_origins = ["https://example.com"]
|
||||||
|
## Whether to enable validation for Prometheus remote write requests.
|
||||||
|
## Available options:
|
||||||
|
## - strict: deny invalid UTF-8 strings (default).
|
||||||
|
## - lossy: allow invalid UTF-8 strings, replace invalid characters with REPLACEMENT_CHARACTER(U+FFFD).
|
||||||
|
## - unchecked: do not valid strings.
|
||||||
|
prom_validation_mode = "strict"
|
||||||
|
|
||||||
## The gRPC server options.
|
## The gRPC server options.
|
||||||
[grpc]
|
[grpc]
|
||||||
@@ -48,6 +54,13 @@ bind_addr = "127.0.0.1:4001"
|
|||||||
server_addr = "127.0.0.1:4001"
|
server_addr = "127.0.0.1:4001"
|
||||||
## The number of server worker threads.
|
## The number of server worker threads.
|
||||||
runtime_size = 8
|
runtime_size = 8
|
||||||
|
## Compression mode for frontend side Arrow IPC service. Available options:
|
||||||
|
## - `none`: disable all compression
|
||||||
|
## - `transport`: only enable gRPC transport compression (zstd)
|
||||||
|
## - `arrow_ipc`: only enable Arrow IPC compression (lz4)
|
||||||
|
## - `all`: enable all compression.
|
||||||
|
## Default to `none`
|
||||||
|
flight_compression = "arrow_ipc"
|
||||||
|
|
||||||
## gRPC server TLS options, see `mysql.tls` section.
|
## gRPC server TLS options, see `mysql.tls` section.
|
||||||
[grpc.tls]
|
[grpc.tls]
|
||||||
@@ -179,6 +192,12 @@ metadata_cache_ttl = "10m"
|
|||||||
# TTI of the metadata cache.
|
# TTI of the metadata cache.
|
||||||
metadata_cache_tti = "5m"
|
metadata_cache_tti = "5m"
|
||||||
|
|
||||||
|
## The query engine options.
|
||||||
|
[query]
|
||||||
|
## Parallelism of the query engine.
|
||||||
|
## Default to 0, which means the number of CPU cores.
|
||||||
|
parallelism = 0
|
||||||
|
|
||||||
## Datanode options.
|
## Datanode options.
|
||||||
[datanode]
|
[datanode]
|
||||||
## Datanode client options.
|
## Datanode client options.
|
||||||
@@ -189,7 +208,7 @@ tcp_nodelay = true
|
|||||||
## The logging options.
|
## The logging options.
|
||||||
[logging]
|
[logging]
|
||||||
## The directory to store the log files. If set to empty, logs will not be written to files.
|
## The directory to store the log files. If set to empty, logs will not be written to files.
|
||||||
dir = "/tmp/greptimedb/logs"
|
dir = "./greptimedb_data/logs"
|
||||||
|
|
||||||
## The log level. Can be `info`/`debug`/`warn`/`error`.
|
## The log level. Can be `info`/`debug`/`warn`/`error`.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
@@ -217,36 +236,34 @@ max_log_files = 720
|
|||||||
default_ratio = 1.0
|
default_ratio = 1.0
|
||||||
|
|
||||||
## The slow query log options.
|
## The slow query log options.
|
||||||
[logging.slow_query]
|
[slow_query]
|
||||||
## Whether to enable slow query log.
|
## Whether to enable slow query log.
|
||||||
enable = false
|
enable = true
|
||||||
|
|
||||||
## The threshold of slow query.
|
## The record type of slow queries. It can be `system_table` or `log`.
|
||||||
## @toml2docs:none-default
|
## If `system_table` is selected, the slow queries will be recorded in a system table `greptime_private.slow_queries`.
|
||||||
threshold = "10s"
|
## If `log` is selected, the slow queries will be logged in a log file `greptimedb-slow-queries.*`.
|
||||||
|
record_type = "system_table"
|
||||||
|
|
||||||
## The sampling ratio of slow query log. The value should be in the range of (0, 1].
|
## The threshold of slow query. It can be human readable time string, for example: `10s`, `100ms`, `1s`.
|
||||||
## @toml2docs:none-default
|
threshold = "30s"
|
||||||
|
|
||||||
|
## The sampling ratio of slow query log. The value should be in the range of (0, 1]. For example, `0.1` means 10% of the slow queries will be logged and `1.0` means all slow queries will be logged.
|
||||||
sample_ratio = 1.0
|
sample_ratio = 1.0
|
||||||
|
|
||||||
## The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.
|
## The TTL of the `slow_queries` system table. Default is `30d` when `record_type` is `system_table`.
|
||||||
|
ttl = "30d"
|
||||||
|
|
||||||
|
## The frontend can export its metrics and send to Prometheus compatible service (e.g. `greptimedb` itself) from remote-write API.
|
||||||
## This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape.
|
## This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape.
|
||||||
[export_metrics]
|
[export_metrics]
|
||||||
|
|
||||||
## whether enable export metrics.
|
## whether enable export metrics.
|
||||||
enable = false
|
enable = false
|
||||||
|
|
||||||
## The interval of export metrics.
|
## The interval of export metrics.
|
||||||
write_interval = "30s"
|
write_interval = "30s"
|
||||||
|
|
||||||
## For `standalone` mode, `self_import` is recommend to collect metrics generated by itself
|
|
||||||
## You must create the database before enabling it.
|
|
||||||
[export_metrics.self_import]
|
|
||||||
## @toml2docs:none-default
|
|
||||||
db = "greptime_metrics"
|
|
||||||
|
|
||||||
[export_metrics.remote_write]
|
[export_metrics.remote_write]
|
||||||
## The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`.
|
## The prometheus remote write endpoint that the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`.
|
||||||
url = ""
|
url = ""
|
||||||
|
|
||||||
## HTTP headers of Prometheus remote-write carry.
|
## HTTP headers of Prometheus remote-write carry.
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
## The working home directory.
|
## The working home directory.
|
||||||
data_home = "/tmp/metasrv/"
|
data_home = "./greptimedb_data"
|
||||||
|
|
||||||
## The bind address of metasrv.
|
|
||||||
bind_addr = "127.0.0.1:3002"
|
|
||||||
|
|
||||||
## The communication server address for the frontend and datanode to connect to metasrv.
|
|
||||||
## If left empty or unset, the server will automatically use the IP address of the first network interface
|
|
||||||
## on the host, with the same port number as the one specified in `bind_addr`.
|
|
||||||
server_addr = "127.0.0.1:3002"
|
|
||||||
|
|
||||||
## Store server address default to etcd store.
|
## Store server address default to etcd store.
|
||||||
## For postgres store, the format is:
|
## For postgres store, the format is:
|
||||||
@@ -24,6 +16,7 @@ store_key_prefix = ""
|
|||||||
## - `etcd_store` (default value)
|
## - `etcd_store` (default value)
|
||||||
## - `memory_store`
|
## - `memory_store`
|
||||||
## - `postgres_store`
|
## - `postgres_store`
|
||||||
|
## - `mysql_store`
|
||||||
backend = "etcd_store"
|
backend = "etcd_store"
|
||||||
|
|
||||||
## Table name in RDS to store metadata. Effect when using a RDS kvbackend.
|
## Table name in RDS to store metadata. Effect when using a RDS kvbackend.
|
||||||
@@ -50,6 +43,10 @@ use_memory_store = false
|
|||||||
## - Using shared storage (e.g., s3).
|
## - Using shared storage (e.g., s3).
|
||||||
enable_region_failover = false
|
enable_region_failover = false
|
||||||
|
|
||||||
|
## Whether to allow region failover on local WAL.
|
||||||
|
## **This option is not recommended to be set to true, because it may lead to data loss during failover.**
|
||||||
|
allow_region_failover_on_local_wal = false
|
||||||
|
|
||||||
## Max allowed idle time before removing node info from metasrv memory.
|
## Max allowed idle time before removing node info from metasrv memory.
|
||||||
node_max_idle_time = "24hours"
|
node_max_idle_time = "24hours"
|
||||||
|
|
||||||
@@ -63,6 +60,32 @@ node_max_idle_time = "24hours"
|
|||||||
## The number of threads to execute the runtime for global write operations.
|
## The number of threads to execute the runtime for global write operations.
|
||||||
#+ compact_rt_size = 4
|
#+ compact_rt_size = 4
|
||||||
|
|
||||||
|
## The gRPC server options.
|
||||||
|
[grpc]
|
||||||
|
## The address to bind the gRPC server.
|
||||||
|
bind_addr = "127.0.0.1:3002"
|
||||||
|
## The communication server address for the frontend and datanode to connect to metasrv.
|
||||||
|
## If left empty or unset, the server will automatically use the IP address of the first network interface
|
||||||
|
## on the host, with the same port number as the one specified in `bind_addr`.
|
||||||
|
server_addr = "127.0.0.1:3002"
|
||||||
|
## The number of server worker threads.
|
||||||
|
runtime_size = 8
|
||||||
|
## The maximum receive message size for gRPC server.
|
||||||
|
max_recv_message_size = "512MB"
|
||||||
|
## The maximum send message size for gRPC server.
|
||||||
|
max_send_message_size = "512MB"
|
||||||
|
|
||||||
|
## The HTTP server options.
|
||||||
|
[http]
|
||||||
|
## The address to bind the HTTP server.
|
||||||
|
addr = "127.0.0.1:4000"
|
||||||
|
## HTTP request timeout. Set to 0 to disable timeout.
|
||||||
|
timeout = "0s"
|
||||||
|
## HTTP request body limit.
|
||||||
|
## The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
|
||||||
|
## Set to 0 to disable limit.
|
||||||
|
body_limit = "64MB"
|
||||||
|
|
||||||
## Procedure storage options.
|
## Procedure storage options.
|
||||||
[procedure]
|
[procedure]
|
||||||
|
|
||||||
@@ -79,6 +102,11 @@ retry_delay = "500ms"
|
|||||||
## Comments out the `max_metadata_value_size`, for don't split large value (no limit).
|
## Comments out the `max_metadata_value_size`, for don't split large value (no limit).
|
||||||
max_metadata_value_size = "1500KiB"
|
max_metadata_value_size = "1500KiB"
|
||||||
|
|
||||||
|
## Max running procedures.
|
||||||
|
## The maximum number of procedures that can be running at the same time.
|
||||||
|
## If the number of running procedures exceeds this limit, the procedure will be rejected.
|
||||||
|
max_running_procedures = 128
|
||||||
|
|
||||||
# Failure detectors options.
|
# Failure detectors options.
|
||||||
[failure_detector]
|
[failure_detector]
|
||||||
|
|
||||||
@@ -125,6 +153,22 @@ broker_endpoints = ["127.0.0.1:9092"]
|
|||||||
## Otherwise, use topics named `topic_name_prefix_[0..num_topics)`
|
## Otherwise, use topics named `topic_name_prefix_[0..num_topics)`
|
||||||
auto_create_topics = true
|
auto_create_topics = true
|
||||||
|
|
||||||
|
## Interval of automatically WAL pruning.
|
||||||
|
## Set to `0s` to disable automatically WAL pruning which delete unused remote WAL entries periodically.
|
||||||
|
auto_prune_interval = "0s"
|
||||||
|
|
||||||
|
## The threshold to trigger a flush operation of a region in automatically WAL pruning.
|
||||||
|
## Metasrv will send a flush request to flush the region when:
|
||||||
|
## `trigger_flush_threshold` + `prunable_entry_id` < `max_prunable_entry_id`
|
||||||
|
## where:
|
||||||
|
## - `prunable_entry_id` is the maximum entry id that can be pruned of the region.
|
||||||
|
## - `max_prunable_entry_id` is the maximum prunable entry id among all regions in the same topic.
|
||||||
|
## Set to `0` to disable the flush operation.
|
||||||
|
trigger_flush_threshold = 0
|
||||||
|
|
||||||
|
## Concurrent task limit for automatically WAL pruning.
|
||||||
|
auto_prune_parallelism = 10
|
||||||
|
|
||||||
## Number of topics.
|
## Number of topics.
|
||||||
num_topics = 64
|
num_topics = 64
|
||||||
|
|
||||||
@@ -144,17 +188,6 @@ replication_factor = 1
|
|||||||
|
|
||||||
## Above which a topic creation operation will be cancelled.
|
## Above which a topic creation operation will be cancelled.
|
||||||
create_topic_timeout = "30s"
|
create_topic_timeout = "30s"
|
||||||
## The initial backoff for kafka clients.
|
|
||||||
backoff_init = "500ms"
|
|
||||||
|
|
||||||
## The maximum backoff for kafka clients.
|
|
||||||
backoff_max = "10s"
|
|
||||||
|
|
||||||
## Exponential backoff rate, i.e. next backoff = base * current backoff.
|
|
||||||
backoff_base = 2
|
|
||||||
|
|
||||||
## Stop reconnecting if the total wait time reaches the deadline. If this config is missing, the reconnecting won't terminate.
|
|
||||||
backoff_deadline = "5mins"
|
|
||||||
|
|
||||||
# The Kafka SASL configuration.
|
# The Kafka SASL configuration.
|
||||||
# **It's only used when the provider is `kafka`**.
|
# **It's only used when the provider is `kafka`**.
|
||||||
@@ -177,7 +210,7 @@ backoff_deadline = "5mins"
|
|||||||
## The logging options.
|
## The logging options.
|
||||||
[logging]
|
[logging]
|
||||||
## The directory to store the log files. If set to empty, logs will not be written to files.
|
## The directory to store the log files. If set to empty, logs will not be written to files.
|
||||||
dir = "/tmp/greptimedb/logs"
|
dir = "./greptimedb_data/logs"
|
||||||
|
|
||||||
## The log level. Can be `info`/`debug`/`warn`/`error`.
|
## The log level. Can be `info`/`debug`/`warn`/`error`.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
@@ -204,37 +237,16 @@ max_log_files = 720
|
|||||||
[logging.tracing_sample_ratio]
|
[logging.tracing_sample_ratio]
|
||||||
default_ratio = 1.0
|
default_ratio = 1.0
|
||||||
|
|
||||||
## The slow query log options.
|
## The metasrv can export its metrics and send to Prometheus compatible service (e.g. `greptimedb` itself) from remote-write API.
|
||||||
[logging.slow_query]
|
|
||||||
## Whether to enable slow query log.
|
|
||||||
enable = false
|
|
||||||
|
|
||||||
## The threshold of slow query.
|
|
||||||
## @toml2docs:none-default
|
|
||||||
threshold = "10s"
|
|
||||||
|
|
||||||
## The sampling ratio of slow query log. The value should be in the range of (0, 1].
|
|
||||||
## @toml2docs:none-default
|
|
||||||
sample_ratio = 1.0
|
|
||||||
|
|
||||||
## The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.
|
|
||||||
## This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape.
|
## This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape.
|
||||||
[export_metrics]
|
[export_metrics]
|
||||||
|
|
||||||
## whether enable export metrics.
|
## whether enable export metrics.
|
||||||
enable = false
|
enable = false
|
||||||
|
|
||||||
## The interval of export metrics.
|
## The interval of export metrics.
|
||||||
write_interval = "30s"
|
write_interval = "30s"
|
||||||
|
|
||||||
## For `standalone` mode, `self_import` is recommend to collect metrics generated by itself
|
|
||||||
## You must create the database before enabling it.
|
|
||||||
[export_metrics.self_import]
|
|
||||||
## @toml2docs:none-default
|
|
||||||
db = "greptime_metrics"
|
|
||||||
|
|
||||||
[export_metrics.remote_write]
|
[export_metrics.remote_write]
|
||||||
## The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`.
|
## The prometheus remote write endpoint that the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`.
|
||||||
url = ""
|
url = ""
|
||||||
|
|
||||||
## HTTP headers of Prometheus remote-write carry.
|
## HTTP headers of Prometheus remote-write carry.
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
## The running mode of the datanode. It can be `standalone` or `distributed`.
|
|
||||||
mode = "standalone"
|
|
||||||
|
|
||||||
## The default timezone of the server.
|
## The default timezone of the server.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
default_timezone = "UTC"
|
default_timezone = "UTC"
|
||||||
@@ -34,7 +31,7 @@ max_concurrent_queries = 0
|
|||||||
## The address to bind the HTTP server.
|
## The address to bind the HTTP server.
|
||||||
addr = "127.0.0.1:4000"
|
addr = "127.0.0.1:4000"
|
||||||
## HTTP request timeout. Set to 0 to disable timeout.
|
## HTTP request timeout. Set to 0 to disable timeout.
|
||||||
timeout = "30s"
|
timeout = "0s"
|
||||||
## HTTP request body limit.
|
## HTTP request body limit.
|
||||||
## The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
|
## The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
|
||||||
## Set to 0 to disable limit.
|
## Set to 0 to disable limit.
|
||||||
@@ -46,6 +43,13 @@ enable_cors = true
|
|||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
cors_allowed_origins = ["https://example.com"]
|
cors_allowed_origins = ["https://example.com"]
|
||||||
|
|
||||||
|
## Whether to enable validation for Prometheus remote write requests.
|
||||||
|
## Available options:
|
||||||
|
## - strict: deny invalid UTF-8 strings (default).
|
||||||
|
## - lossy: allow invalid UTF-8 strings, replace invalid characters with REPLACEMENT_CHARACTER(U+FFFD).
|
||||||
|
## - unchecked: do not valid strings.
|
||||||
|
prom_validation_mode = "strict"
|
||||||
|
|
||||||
## The gRPC server options.
|
## The gRPC server options.
|
||||||
[grpc]
|
[grpc]
|
||||||
## The address to bind the gRPC server.
|
## The address to bind the gRPC server.
|
||||||
@@ -164,7 +168,7 @@ provider = "raft_engine"
|
|||||||
## The directory to store the WAL files.
|
## The directory to store the WAL files.
|
||||||
## **It's only used when the provider is `raft_engine`**.
|
## **It's only used when the provider is `raft_engine`**.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
dir = "/tmp/greptimedb/wal"
|
dir = "./greptimedb_data/wal"
|
||||||
|
|
||||||
## The size of the WAL segment file.
|
## The size of the WAL segment file.
|
||||||
## **It's only used when the provider is `raft_engine`**.
|
## **It's only used when the provider is `raft_engine`**.
|
||||||
@@ -242,22 +246,6 @@ max_batch_bytes = "1MB"
|
|||||||
## **It's only used when the provider is `kafka`**.
|
## **It's only used when the provider is `kafka`**.
|
||||||
consumer_wait_timeout = "100ms"
|
consumer_wait_timeout = "100ms"
|
||||||
|
|
||||||
## The initial backoff delay.
|
|
||||||
## **It's only used when the provider is `kafka`**.
|
|
||||||
backoff_init = "500ms"
|
|
||||||
|
|
||||||
## The maximum backoff delay.
|
|
||||||
## **It's only used when the provider is `kafka`**.
|
|
||||||
backoff_max = "10s"
|
|
||||||
|
|
||||||
## The exponential backoff rate, i.e. next backoff = base * current backoff.
|
|
||||||
## **It's only used when the provider is `kafka`**.
|
|
||||||
backoff_base = 2
|
|
||||||
|
|
||||||
## The deadline of retries.
|
|
||||||
## **It's only used when the provider is `kafka`**.
|
|
||||||
backoff_deadline = "5mins"
|
|
||||||
|
|
||||||
## Ignore missing entries during read WAL.
|
## Ignore missing entries during read WAL.
|
||||||
## **It's only used when the provider is `kafka`**.
|
## **It's only used when the provider is `kafka`**.
|
||||||
##
|
##
|
||||||
@@ -302,6 +290,10 @@ purge_interval = "1m"
|
|||||||
max_retry_times = 3
|
max_retry_times = 3
|
||||||
## Initial retry delay of procedures, increases exponentially
|
## Initial retry delay of procedures, increases exponentially
|
||||||
retry_delay = "500ms"
|
retry_delay = "500ms"
|
||||||
|
## Max running procedures.
|
||||||
|
## The maximum number of procedures that can be running at the same time.
|
||||||
|
## If the number of running procedures exceeds this limit, the procedure will be rejected.
|
||||||
|
max_running_procedures = 128
|
||||||
|
|
||||||
## flow engine options.
|
## flow engine options.
|
||||||
[flow]
|
[flow]
|
||||||
@@ -349,10 +341,16 @@ retry_delay = "500ms"
|
|||||||
# credential = "base64-credential"
|
# credential = "base64-credential"
|
||||||
# endpoint = "https://storage.googleapis.com"
|
# endpoint = "https://storage.googleapis.com"
|
||||||
|
|
||||||
|
## The query engine options.
|
||||||
|
[query]
|
||||||
|
## Parallelism of the query engine.
|
||||||
|
## Default to 0, which means the number of CPU cores.
|
||||||
|
parallelism = 0
|
||||||
|
|
||||||
## The data storage options.
|
## The data storage options.
|
||||||
[storage]
|
[storage]
|
||||||
## The working home directory.
|
## The working home directory.
|
||||||
data_home = "/tmp/greptimedb/"
|
data_home = "./greptimedb_data"
|
||||||
|
|
||||||
## The storage type used to store the data.
|
## The storage type used to store the data.
|
||||||
## - `File`: the data is stored in the local file system.
|
## - `File`: the data is stored in the local file system.
|
||||||
@@ -599,6 +597,9 @@ content_cache_size = "128MiB"
|
|||||||
## Page size for inverted index content cache.
|
## Page size for inverted index content cache.
|
||||||
content_cache_page_size = "64KiB"
|
content_cache_page_size = "64KiB"
|
||||||
|
|
||||||
|
## Cache size for index result.
|
||||||
|
result_cache_size = "128MiB"
|
||||||
|
|
||||||
## The options for inverted index in Mito engine.
|
## The options for inverted index in Mito engine.
|
||||||
[region_engine.mito.inverted_index]
|
[region_engine.mito.inverted_index]
|
||||||
|
|
||||||
@@ -705,7 +706,7 @@ experimental_sparse_primary_key_encoding = false
|
|||||||
## The logging options.
|
## The logging options.
|
||||||
[logging]
|
[logging]
|
||||||
## The directory to store the log files. If set to empty, logs will not be written to files.
|
## The directory to store the log files. If set to empty, logs will not be written to files.
|
||||||
dir = "/tmp/greptimedb/logs"
|
dir = "./greptimedb_data/logs"
|
||||||
|
|
||||||
## The log level. Can be `info`/`debug`/`warn`/`error`.
|
## The log level. Can be `info`/`debug`/`warn`/`error`.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
@@ -733,25 +734,27 @@ max_log_files = 720
|
|||||||
default_ratio = 1.0
|
default_ratio = 1.0
|
||||||
|
|
||||||
## The slow query log options.
|
## The slow query log options.
|
||||||
[logging.slow_query]
|
[slow_query]
|
||||||
## Whether to enable slow query log.
|
## Whether to enable slow query log.
|
||||||
enable = false
|
#+ enable = false
|
||||||
|
|
||||||
|
## The record type of slow queries. It can be `system_table` or `log`.
|
||||||
|
## @toml2docs:none-default
|
||||||
|
#+ record_type = "system_table"
|
||||||
|
|
||||||
## The threshold of slow query.
|
## The threshold of slow query.
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
threshold = "10s"
|
#+ threshold = "10s"
|
||||||
|
|
||||||
## The sampling ratio of slow query log. The value should be in the range of (0, 1].
|
## The sampling ratio of slow query log. The value should be in the range of (0, 1].
|
||||||
## @toml2docs:none-default
|
## @toml2docs:none-default
|
||||||
sample_ratio = 1.0
|
#+ sample_ratio = 1.0
|
||||||
|
|
||||||
## The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.
|
## The standalone can export its metrics and send to Prometheus compatible service (e.g. `greptimedb`) from remote-write API.
|
||||||
## This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape.
|
## This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape.
|
||||||
[export_metrics]
|
[export_metrics]
|
||||||
|
|
||||||
## whether enable export metrics.
|
## whether enable export metrics.
|
||||||
enable = false
|
enable = false
|
||||||
|
|
||||||
## The interval of export metrics.
|
## The interval of export metrics.
|
||||||
write_interval = "30s"
|
write_interval = "30s"
|
||||||
|
|
||||||
@@ -762,7 +765,7 @@ write_interval = "30s"
|
|||||||
db = "greptime_metrics"
|
db = "greptime_metrics"
|
||||||
|
|
||||||
[export_metrics.remote_write]
|
[export_metrics.remote_write]
|
||||||
## The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`.
|
## The prometheus remote write endpoint that the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=greptime_metrics`.
|
||||||
url = ""
|
url = ""
|
||||||
|
|
||||||
## HTTP headers of Prometheus remote-write carry.
|
## HTTP headers of Prometheus remote-write carry.
|
||||||
|
|||||||
@@ -1,75 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as core from "@actions/core";
|
|
||||||
import {obtainClient} from "@/common";
|
|
||||||
|
|
||||||
async function triggerWorkflow(workflowId: string, version: string) {
|
|
||||||
const docsClient = obtainClient("DOCS_REPO_TOKEN")
|
|
||||||
try {
|
|
||||||
await docsClient.rest.actions.createWorkflowDispatch({
|
|
||||||
owner: "GreptimeTeam",
|
|
||||||
repo: "docs",
|
|
||||||
workflow_id: workflowId,
|
|
||||||
ref: "main",
|
|
||||||
inputs: {
|
|
||||||
version,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
console.log(`Successfully triggered ${workflowId} workflow with version ${version}`);
|
|
||||||
} catch (error) {
|
|
||||||
core.setFailed(`Failed to trigger workflow: ${error.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function determineWorkflow(version: string): [string, string] {
|
|
||||||
// Check if it's a nightly version
|
|
||||||
if (version.includes('nightly')) {
|
|
||||||
return ['bump-nightly-version.yml', version];
|
|
||||||
}
|
|
||||||
|
|
||||||
const parts = version.split('.');
|
|
||||||
|
|
||||||
if (parts.length !== 3) {
|
|
||||||
throw new Error('Invalid version format');
|
|
||||||
}
|
|
||||||
|
|
||||||
// If patch version (last number) is 0, it's a major version
|
|
||||||
// Return only major.minor version
|
|
||||||
if (parts[2] === '0') {
|
|
||||||
return ['bump-version.yml', `${parts[0]}.${parts[1]}`];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise it's a patch version, use full version
|
|
||||||
return ['bump-patch-version.yml', version];
|
|
||||||
}
|
|
||||||
|
|
||||||
const version = process.env.VERSION;
|
|
||||||
if (!version) {
|
|
||||||
core.setFailed("VERSION environment variable is required");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove 'v' prefix if exists
|
|
||||||
const cleanVersion = version.startsWith('v') ? version.slice(1) : version;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const [workflowId, apiVersion] = determineWorkflow(cleanVersion);
|
|
||||||
triggerWorkflow(workflowId, apiVersion);
|
|
||||||
} catch (error) {
|
|
||||||
core.setFailed(`Error processing version: ${error.message}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
156
cyborg/bin/bump-versions.ts
Normal file
156
cyborg/bin/bump-versions.ts
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
import {obtainClient} from "@/common";
|
||||||
|
|
||||||
|
interface RepoConfig {
|
||||||
|
tokenEnv: string;
|
||||||
|
repo: string;
|
||||||
|
workflowLogic: (version: string) => [string, string] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const REPO_CONFIGS: Record<string, RepoConfig> = {
|
||||||
|
website: {
|
||||||
|
tokenEnv: "WEBSITE_REPO_TOKEN",
|
||||||
|
repo: "website",
|
||||||
|
workflowLogic: (version: string) => {
|
||||||
|
// Skip nightly versions for website
|
||||||
|
if (version.includes('nightly')) {
|
||||||
|
console.log('Nightly version detected for website, skipping workflow trigger.');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ['bump-patch-version.yml', version];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
demo: {
|
||||||
|
tokenEnv: "DEMO_REPO_TOKEN",
|
||||||
|
repo: "demo-scene",
|
||||||
|
workflowLogic: (version: string) => {
|
||||||
|
// Skip nightly versions for demo
|
||||||
|
if (version.includes('nightly')) {
|
||||||
|
console.log('Nightly version detected for demo, skipping workflow trigger.');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ['bump-patch-version.yml', version];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
docs: {
|
||||||
|
tokenEnv: "DOCS_REPO_TOKEN",
|
||||||
|
repo: "docs",
|
||||||
|
workflowLogic: (version: string) => {
|
||||||
|
// Check if it's a nightly version
|
||||||
|
if (version.includes('nightly')) {
|
||||||
|
return ['bump-nightly-version.yml', version];
|
||||||
|
}
|
||||||
|
|
||||||
|
const parts = version.split('.');
|
||||||
|
if (parts.length !== 3) {
|
||||||
|
throw new Error('Invalid version format');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If patch version (last number) is 0, it's a major version
|
||||||
|
// Return only major.minor version
|
||||||
|
if (parts[2] === '0') {
|
||||||
|
return ['bump-version.yml', `${parts[0]}.${parts[1]}`];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise it's a patch version, use full version
|
||||||
|
return ['bump-patch-version.yml', version];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function triggerWorkflow(repoConfig: RepoConfig, workflowId: string, version: string) {
|
||||||
|
const client = obtainClient(repoConfig.tokenEnv);
|
||||||
|
try {
|
||||||
|
await client.rest.actions.createWorkflowDispatch({
|
||||||
|
owner: "GreptimeTeam",
|
||||||
|
repo: repoConfig.repo,
|
||||||
|
workflow_id: workflowId,
|
||||||
|
ref: "main",
|
||||||
|
inputs: {
|
||||||
|
version,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
console.log(`Successfully triggered ${workflowId} workflow for ${repoConfig.repo} with version ${version}`);
|
||||||
|
} catch (error) {
|
||||||
|
core.setFailed(`Failed to trigger workflow for ${repoConfig.repo}: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processRepo(repoName: string, version: string) {
|
||||||
|
const repoConfig = REPO_CONFIGS[repoName];
|
||||||
|
if (!repoConfig) {
|
||||||
|
throw new Error(`Unknown repository: ${repoName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const workflowResult = repoConfig.workflowLogic(version);
|
||||||
|
if (workflowResult === null) {
|
||||||
|
// Skip this repo (e.g., nightly version for website)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [workflowId, apiVersion] = workflowResult;
|
||||||
|
await triggerWorkflow(repoConfig, workflowId, apiVersion);
|
||||||
|
} catch (error) {
|
||||||
|
core.setFailed(`Error processing ${repoName} with version ${version}: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const version = process.env.VERSION;
|
||||||
|
if (!version) {
|
||||||
|
core.setFailed("VERSION environment variable is required");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove 'v' prefix if exists
|
||||||
|
const cleanVersion = version.startsWith('v') ? version.slice(1) : version;
|
||||||
|
|
||||||
|
// Get target repositories from environment variable
|
||||||
|
// Default to both if not specified
|
||||||
|
const targetRepos = process.env.TARGET_REPOS?.split(',').map(repo => repo.trim()) || ['website', 'docs'];
|
||||||
|
|
||||||
|
console.log(`Processing version ${cleanVersion} for repositories: ${targetRepos.join(', ')}`);
|
||||||
|
|
||||||
|
const errors: string[] = [];
|
||||||
|
|
||||||
|
// Process each repository
|
||||||
|
for (const repo of targetRepos) {
|
||||||
|
try {
|
||||||
|
await processRepo(repo, cleanVersion);
|
||||||
|
} catch (error) {
|
||||||
|
errors.push(`${repo}: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors.length > 0) {
|
||||||
|
core.setFailed(`Failed to process some repositories: ${errors.join('; ')}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('All repositories processed successfully');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute main function
|
||||||
|
main().catch((error) => {
|
||||||
|
core.setFailed(`Unexpected error: ${error.message}`);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -25,7 +25,7 @@ services:
|
|||||||
- --initial-cluster-state=new
|
- --initial-cluster-state=new
|
||||||
- *etcd_initial_cluster_token
|
- *etcd_initial_cluster_token
|
||||||
volumes:
|
volumes:
|
||||||
- /tmp/greptimedb-cluster-docker-compose/etcd0:/var/lib/etcd
|
- ./greptimedb-cluster-docker-compose/etcd0:/var/lib/etcd
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "etcdctl", "--endpoints=http://etcd0:2379", "endpoint", "health" ]
|
test: [ "CMD", "etcdctl", "--endpoints=http://etcd0:2379", "endpoint", "health" ]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
@@ -68,12 +68,13 @@ services:
|
|||||||
- datanode
|
- datanode
|
||||||
- start
|
- start
|
||||||
- --node-id=0
|
- --node-id=0
|
||||||
|
- --data-home=/greptimedb_data
|
||||||
- --rpc-bind-addr=0.0.0.0:3001
|
- --rpc-bind-addr=0.0.0.0:3001
|
||||||
- --rpc-server-addr=datanode0:3001
|
- --rpc-server-addr=datanode0:3001
|
||||||
- --metasrv-addrs=metasrv:3002
|
- --metasrv-addrs=metasrv:3002
|
||||||
- --http-addr=0.0.0.0:5000
|
- --http-addr=0.0.0.0:5000
|
||||||
volumes:
|
volumes:
|
||||||
- /tmp/greptimedb-cluster-docker-compose/datanode0:/tmp/greptimedb
|
- ./greptimedb-cluster-docker-compose/datanode0:/greptimedb_data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "curl", "-fv", "http://datanode0:5000/health" ]
|
test: [ "CMD", "curl", "-fv", "http://datanode0:5000/health" ]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
|
|||||||
BIN
docs/architecture.png
Normal file
BIN
docs/architecture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 173 KiB |
@@ -11,6 +11,6 @@ And database will reply with something like:
|
|||||||
Log Level changed from Some("info") to "trace,flow=debug"%
|
Log Level changed from Some("info") to "trace,flow=debug"%
|
||||||
```
|
```
|
||||||
|
|
||||||
The data is a string in the format of `global_level,module1=level1,module2=level2,...` that follow the same rule of `RUST_LOG`.
|
The data is a string in the format of `global_level,module1=level1,module2=level2,...` that follows the same rule of `RUST_LOG`.
|
||||||
|
|
||||||
The module is the module name of the log, and the level is the log level. The log level can be one of the following: `trace`, `debug`, `info`, `warn`, `error`, `off`(case insensitive).
|
The module is the module name of the log, and the level is the log level. The log level can be one of the following: `trace`, `debug`, `info`, `warn`, `error`, `off`(case insensitive).
|
||||||
@@ -14,7 +14,7 @@ impl SqlQueryHandler for Instance {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Normally, when a SQL query arrives at GreptimeDB, the `do_query` method will be called. After some parsing work, the SQL
|
Normally, when a SQL query arrives at GreptimeDB, the `do_query` method will be called. After some parsing work, the SQL
|
||||||
will be feed into `StatementExecutor`:
|
will be fed into `StatementExecutor`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// in Frontend Instance:
|
// in Frontend Instance:
|
||||||
@@ -27,7 +27,7 @@ an example.
|
|||||||
|
|
||||||
Now, what if the statements should be handled differently for GreptimeDB Standalone and Cluster? You can see there's
|
Now, what if the statements should be handled differently for GreptimeDB Standalone and Cluster? You can see there's
|
||||||
a `SqlStatementExecutor` field in `StatementExecutor`. Each GreptimeDB Standalone and Cluster has its own implementation
|
a `SqlStatementExecutor` field in `StatementExecutor`. Each GreptimeDB Standalone and Cluster has its own implementation
|
||||||
of `SqlStatementExecutor`. If you are going to implement the statements differently in the two mode (
|
of `SqlStatementExecutor`. If you are going to implement the statements differently in the two modes (
|
||||||
like `CREATE TABLE`), you have to implement them in their own `SqlStatementExecutor`s.
|
like `CREATE TABLE`), you have to implement them in their own `SqlStatementExecutor`s.
|
||||||
|
|
||||||
Summarize as the diagram below:
|
Summarize as the diagram below:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Profile memory usage of GreptimeDB
|
# Profile memory usage of GreptimeDB
|
||||||
|
|
||||||
This crate provides an easy approach to dump memory profiling info.
|
This crate provides an easy approach to dump memory profiling info. A set of ready to use scripts is provided in [docs/how-to/memory-profile-scripts](./memory-profile-scripts/scripts).
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
### jemalloc
|
### jemalloc
|
||||||
@@ -44,6 +44,10 @@ Dump memory profiling data through HTTP API:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST localhost:4000/debug/prof/mem > greptime.hprof
|
curl -X POST localhost:4000/debug/prof/mem > greptime.hprof
|
||||||
|
# or output flamegraph directly
|
||||||
|
curl -X POST "localhost:4000/debug/prof/mem?output=flamegraph" > greptime.svg
|
||||||
|
# or output pprof format
|
||||||
|
curl -X POST "localhost:4000/debug/prof/mem?output=proto" > greptime.pprof
|
||||||
```
|
```
|
||||||
|
|
||||||
You can periodically dump profiling data and compare them to find the delta memory usage.
|
You can periodically dump profiling data and compare them to find the delta memory usage.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
Currently, our query engine is based on DataFusion, so all aggregate function is executed by DataFusion, through its UDAF interface. You can find DataFusion's UDAF example [here](https://github.com/apache/arrow-datafusion/blob/arrow2/datafusion-examples/examples/simple_udaf.rs). Basically, we provide the same way as DataFusion to write aggregate functions: both are centered in a struct called "Accumulator" to accumulates states along the way in aggregation.
|
Currently, our query engine is based on DataFusion, so all aggregate function is executed by DataFusion, through its UDAF interface. You can find DataFusion's UDAF example [here](https://github.com/apache/arrow-datafusion/blob/arrow2/datafusion-examples/examples/simple_udaf.rs). Basically, we provide the same way as DataFusion to write aggregate functions: both are centered in a struct called "Accumulator" to accumulates states along the way in aggregation.
|
||||||
|
|
||||||
However, DataFusion's UDAF implementation has a huge restriction, that it requires user to provide a concrete "Accumulator". Take `Median` aggregate function for example, to aggregate a `u32` datatype column, you have to write a `MedianU32`, and use `SELECT MEDIANU32(x)` in SQL. `MedianU32` cannot be used to aggregate a `i32` datatype column. Or, there's another way: you can use a special type that can hold all kinds of data (like our `Value` enum or Arrow's `ScalarValue`), and `match` all the way up to do aggregate calculations. It might work, though rather tedious. (But I think it's DataFusion's prefer way to write UDAF.)
|
However, DataFusion's UDAF implementation has a huge restriction, that it requires user to provide a concrete "Accumulator". Take `Median` aggregate function for example, to aggregate a `u32` datatype column, you have to write a `MedianU32`, and use `SELECT MEDIANU32(x)` in SQL. `MedianU32` cannot be used to aggregate a `i32` datatype column. Or, there's another way: you can use a special type that can hold all kinds of data (like our `Value` enum or Arrow's `ScalarValue`), and `match` all the way up to do aggregate calculations. It might work, though rather tedious. (But I think it's DataFusion's preferred way to write UDAF.)
|
||||||
|
|
||||||
So is there a way we can make an aggregate function that automatically match the input data's type? For example, a `Median` aggregator that can work on both `u32` column and `i32`? The answer is yes until we found a way to bypassing DataFusion's restriction, a restriction that DataFusion simply don't pass the input data's type when creating an Accumulator.
|
So is there a way we can make an aggregate function that automatically match the input data's type? For example, a `Median` aggregator that can work on both `u32` column and `i32`? The answer is yes until we find a way to bypass DataFusion's restriction, a restriction that DataFusion simply doesn't pass the input data's type when creating an Accumulator.
|
||||||
|
|
||||||
> There's an example in `my_sum_udaf_example.rs`, take that as quick start.
|
> There's an example in `my_sum_udaf_example.rs`, take that as quick start.
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ You must first define a struct that will be used to create your accumulator. For
|
|||||||
struct MySumAccumulatorCreator {}
|
struct MySumAccumulatorCreator {}
|
||||||
```
|
```
|
||||||
|
|
||||||
Attribute macro `#[as_aggr_func_creator]` and derive macro `#[derive(Debug, AggrFuncTypeStore)]` must both annotated on the struct. They work together to provide a storage of aggregate function's input data types, which are needed for creating generic accumulator later.
|
Attribute macro `#[as_aggr_func_creator]` and derive macro `#[derive(Debug, AggrFuncTypeStore)]` must both be annotated on the struct. They work together to provide a storage of aggregate function's input data types, which are needed for creating generic accumulator later.
|
||||||
|
|
||||||
> Note that the `as_aggr_func_creator` macro will add fields to the struct, so the struct cannot be defined as an empty struct without field like `struct Foo;`, neither as a new type like `struct Foo(bar)`.
|
> Note that the `as_aggr_func_creator` macro will add fields to the struct, so the struct cannot be defined as an empty struct without field like `struct Foo;`, neither as a new type like `struct Foo(bar)`.
|
||||||
|
|
||||||
@@ -32,11 +32,11 @@ pub trait AggregateFunctionCreator: Send + Sync + Debug {
|
|||||||
|
|
||||||
You can use input data's type in methods that return output type and state types (just invoke `input_types()`).
|
You can use input data's type in methods that return output type and state types (just invoke `input_types()`).
|
||||||
|
|
||||||
The output type is aggregate function's output data's type. For example, `SUM` aggregate function's output type is `u64` for a `u32` datatype column. The state types are accumulator's internal states' types. Take `AVG` aggregate function on a `i32` column as example, it's state types are `i64` (for sum) and `u64` (for count).
|
The output type is aggregate function's output data's type. For example, `SUM` aggregate function's output type is `u64` for a `u32` datatype column. The state types are accumulator's internal states' types. Take `AVG` aggregate function on a `i32` column as example, its state types are `i64` (for sum) and `u64` (for count).
|
||||||
|
|
||||||
The `creator` function is where you define how an accumulator (that will be used in DataFusion) is created. You define "how" to create the accumulator (instead of "what" to create), using the input data's type as arguments. With input datatype known, you can create accumulator generically.
|
The `creator` function is where you define how an accumulator (that will be used in DataFusion) is created. You define "how" to create the accumulator (instead of "what" to create), using the input data's type as arguments. With input datatype known, you can create accumulator generically.
|
||||||
|
|
||||||
# 2. Impl `Accumulator` trait for you accumulator.
|
# 2. Impl `Accumulator` trait for your accumulator.
|
||||||
|
|
||||||
The accumulator is where you store the aggregate calculation states and evaluate a result. You must impl `Accumulator` trait for it. The trait's definition is:
|
The accumulator is where you store the aggregate calculation states and evaluate a result. You must impl `Accumulator` trait for it. The trait's definition is:
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ pub trait Accumulator: Send + Sync + Debug {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The DataFusion basically execute aggregate like this:
|
The DataFusion basically executes aggregate like this:
|
||||||
|
|
||||||
1. Partitioning all input data for aggregate. Create an accumulator for each part.
|
1. Partitioning all input data for aggregate. Create an accumulator for each part.
|
||||||
2. Call `update_batch` on each accumulator with partitioned data, to let you update your aggregate calculation.
|
2. Call `update_batch` on each accumulator with partitioned data, to let you update your aggregate calculation.
|
||||||
@@ -63,10 +63,10 @@ Once you know the meaning of each method, you can easily write your accumulator.
|
|||||||
|
|
||||||
You can call `register_aggregate_function` method in query engine to register your aggregate function. To do that, you have to new an instance of struct `AggregateFunctionMeta`. The struct has three fields, first is the name of your aggregate function's name. The function name is case-sensitive due to DataFusion's restriction. We strongly recommend using lowercase for your name. If you have to use uppercase name, wrap your aggregate function with quotation marks. For example, if you define an aggregate function named "my_aggr", you can use "`SELECT MY_AGGR(x)`"; if you define "my_AGGR", you have to use "`SELECT "my_AGGR"(x)`".
|
You can call `register_aggregate_function` method in query engine to register your aggregate function. To do that, you have to new an instance of struct `AggregateFunctionMeta`. The struct has three fields, first is the name of your aggregate function's name. The function name is case-sensitive due to DataFusion's restriction. We strongly recommend using lowercase for your name. If you have to use uppercase name, wrap your aggregate function with quotation marks. For example, if you define an aggregate function named "my_aggr", you can use "`SELECT MY_AGGR(x)`"; if you define "my_AGGR", you have to use "`SELECT "my_AGGR"(x)`".
|
||||||
|
|
||||||
The second field is arg_counts ,the count of the arguments. Like accumulator `percentile`, calculating the p_number of the column. We need to input the value of column and the value of p to cacalate, and so the count of the arguments is two.
|
The second field is arg_counts ,the count of the arguments. Like accumulator `percentile`, calculating the p_number of the column. We need to input the value of column and the value of p to calculate, and so the count of the arguments is two.
|
||||||
|
|
||||||
The third field is a function about how to create your accumulator creator that you defined in step 1 above. Create creator, that's a bit intertwined, but it is how we make DataFusion use a newly created aggregate function each time it executes a SQL, preventing the stored input types from affecting each other. The key detail can be starting looking at our `DfContextProviderAdapter` struct's `get_aggregate_meta` method.
|
The third field is a function about how to create your accumulator creator that you defined in step 1 above. Create creator, that's a bit intertwined, but it is how we make DataFusion use a newly created aggregate function each time it executes a SQL, preventing the stored input types from affecting each other. The key detail can be starting looking at our `DfContextProviderAdapter` struct's `get_aggregate_meta` method.
|
||||||
|
|
||||||
# (Optional) 4. Make your aggregate function automatically registered.
|
# (Optional) 4. Make your aggregate function automatically registered.
|
||||||
|
|
||||||
If you've written a great aggregate function that want to let everyone use it, you can make it automatically registered to our query engine at start time. It's quick simple, just refer to the `AggregateFunctions::register` function in `common/function/src/scalars/aggregate/mod.rs`.
|
If you've written a great aggregate function that wants to let everyone use it, you can make it automatically register to our query engine at start time. It's quick and simple, just refer to the `AggregateFunctions::register` function in `common/function/src/scalars/aggregate/mod.rs`.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
This document introduces how to write fuzz tests in GreptimeDB.
|
This document introduces how to write fuzz tests in GreptimeDB.
|
||||||
|
|
||||||
## What is a fuzz test
|
## What is a fuzz test
|
||||||
Fuzz test is tool that leverage deterministic random generation to assist in finding bugs. The goal of fuzz tests is to identify inputs generated by the fuzzer that cause system panics, crashes, or unexpected behaviors to occur. And we are using the [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) to run our fuzz test targets.
|
Fuzz test is tool that leverages deterministic random generation to assist in finding bugs. The goal of fuzz tests is to identify inputs generated by the fuzzer that cause system panics, crashes, or unexpected behaviors to occur. And we are using the [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) to run our fuzz test targets.
|
||||||
|
|
||||||
## Why we need them
|
## Why we need them
|
||||||
- Find bugs by leveraging random generation
|
- Find bugs by leveraging random generation
|
||||||
|
|||||||
52
docs/how-to/memory-profile-scripts/scripts/README.md
Normal file
52
docs/how-to/memory-profile-scripts/scripts/README.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Memory Analysis Process
|
||||||
|
This section will guide you through the process of analyzing memory usage for greptimedb.
|
||||||
|
|
||||||
|
1. Get the `jeprof` tool script, see the next section("Getting the `jeprof` tool") for details.
|
||||||
|
|
||||||
|
2. After starting `greptimedb`(with env var `MALLOC_CONF=prof:true`), execute the `dump.sh` script with the PID of the `greptimedb` process as an argument. This continuously monitors memory usage and captures profiles when exceeding thresholds (e.g. +20MB within 10 minutes). Outputs `greptime-{timestamp}.gprof` files.
|
||||||
|
|
||||||
|
3. With 2-3 gprof files, run `gen_flamegraph.sh` in the same environment to generate flame graphs showing memory allocation call stacks.
|
||||||
|
|
||||||
|
4. **NOTE:** The `gen_flamegraph.sh` script requires `jeprof` and optionally `flamegraph.pl` to be in the current directory. If needed to gen flamegraph now, run the `get_flamegraph_tool.sh` script, which downloads the flame graph generation tool `flamegraph.pl` to the current directory.
|
||||||
|
The usage of `gen_flamegraph.sh` is:
|
||||||
|
|
||||||
|
`Usage: ./gen_flamegraph.sh <binary_path> <gprof_directory>`
|
||||||
|
where `<binary_path>` is the path to the greptimedb binary, `<gprof_directory>` is the directory containing the gprof files(the directory `dump.sh` is dumping profiles to).
|
||||||
|
Example call: `./gen_flamegraph.sh ./greptime .`
|
||||||
|
|
||||||
|
Generating the flame graph might take a few minutes. The generated flame graphs are located in the `<gprof_directory>/flamegraphs` directory. Or if no `flamegraph.pl` is found, it will only contain `.collapse` files which is also fine.
|
||||||
|
5. You can send the generated flame graphs(the entire folder of `<gprof_directory>/flamegraphs`) to developers for further analysis.
|
||||||
|
|
||||||
|
|
||||||
|
## Getting the `jeprof` tool
|
||||||
|
there are three ways to get `jeprof`, list in here from simple to complex, using any one of those methods is ok, as long as it's the same environment as the `greptimedb` will be running on:
|
||||||
|
1. If you are compiling greptimedb from source, then `jeprof` is already produced during compilation. After running `cargo build`, execute `find_compiled_jeprof.sh`. This will copy `jeprof` to the current directory.
|
||||||
|
2. Or, if you have the Rust toolchain installed locally, simply follow these commands:
|
||||||
|
```bash
|
||||||
|
cargo new get_jeprof
|
||||||
|
cd get_jeprof
|
||||||
|
```
|
||||||
|
Then add this line to `Cargo.toml`:
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
tikv-jemalloc-ctl = { version = "0.6", features = ["use_std", "stats"] }
|
||||||
|
```
|
||||||
|
then run:
|
||||||
|
```bash
|
||||||
|
cargo build
|
||||||
|
```
|
||||||
|
after that the `jeprof` tool is produced. Now run `find_compiled_jeprof.sh` in current directory, it will copy the `jeprof` tool to the current directory.
|
||||||
|
|
||||||
|
3. compile jemalloc from source
|
||||||
|
you can first clone this repo, and checkout to this commit:
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/tikv/jemalloc.git
|
||||||
|
cd jemalloc
|
||||||
|
git checkout e13ca993e8ccb9ba9847cc330696e02839f328f7
|
||||||
|
```
|
||||||
|
then run:
|
||||||
|
```bash
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
```
|
||||||
|
and `jeprof` is in `.bin/` directory. Copy it to the current directory.
|
||||||
78
docs/how-to/memory-profile-scripts/scripts/dump.sh
Executable file
78
docs/how-to/memory-profile-scripts/scripts/dump.sh
Executable file
@@ -0,0 +1,78 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Monitors greptime process memory usage every 10 minutes
|
||||||
|
# Triggers memory profile capture via `curl -X POST localhost:4000/debug/prof/mem > greptime-{timestamp}.gprof`
|
||||||
|
# when memory increases by more than 20MB since last check
|
||||||
|
# Generated profiles can be analyzed using flame graphs as described in `how-to-profile-memory.md`
|
||||||
|
# (jeprof is compiled with the database - see documentation)
|
||||||
|
# Alternative: Share binaries + profiles for analysis (Docker images preferred)
|
||||||
|
|
||||||
|
# Threshold in Kilobytes (20 MB)
|
||||||
|
threshold_kb=$((20 * 1024))
|
||||||
|
sleep_interval=$((10 * 60))
|
||||||
|
|
||||||
|
# Variable to store the last measured memory usage in KB
|
||||||
|
last_mem_kb=0
|
||||||
|
|
||||||
|
echo "Starting memory monitoring for 'greptime' process..."
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
|
||||||
|
# Check if PID is provided as an argument
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "$(date): PID must be provided as a command-line argument."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
pid="$1"
|
||||||
|
|
||||||
|
# Validate that the PID is a number
|
||||||
|
if ! [[ "$pid" =~ ^[0-9]+$ ]]; then
|
||||||
|
echo "$(date): Invalid PID: '$pid'. PID must be a number."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the current Resident Set Size (RSS) in Kilobytes
|
||||||
|
current_mem_kb=$(ps -o rss= -p "$pid")
|
||||||
|
|
||||||
|
# Check if ps command was successful and returned a number
|
||||||
|
if ! [[ "$current_mem_kb" =~ ^[0-9]+$ ]]; then
|
||||||
|
echo "$(date): Failed to get memory usage for PID $pid. Skipping check."
|
||||||
|
# Keep last_mem_kb to avoid false positives if the process briefly becomes unreadable.
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$(date): Current memory usage for PID $pid: ${current_mem_kb} KB"
|
||||||
|
|
||||||
|
# Compare with the last measurement
|
||||||
|
# if it's the first run, also do a baseline dump just to make sure we can dump
|
||||||
|
|
||||||
|
diff_kb=$((current_mem_kb - last_mem_kb))
|
||||||
|
echo "$(date): Memory usage change since last check: ${diff_kb} KB"
|
||||||
|
|
||||||
|
if [ "$diff_kb" -gt "$threshold_kb" ]; then
|
||||||
|
echo "$(date): Memory increase (${diff_kb} KB) exceeded threshold (${threshold_kb} KB). Dumping profile..."
|
||||||
|
timestamp=$(date +%Y%m%d%H%M%S)
|
||||||
|
profile_file="greptime-${timestamp}.gprof"
|
||||||
|
# Execute curl and capture output to file
|
||||||
|
if curl -sf -X POST localhost:4000/debug/prof/mem > "$profile_file"; then
|
||||||
|
echo "$(date): Memory profile saved to $profile_file"
|
||||||
|
else
|
||||||
|
echo "$(date): Failed to dump memory profile (curl exit code: $?)."
|
||||||
|
# Remove the potentially empty/failed profile file
|
||||||
|
rm -f "$profile_file"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$(date): Memory increase (${diff_kb} KB) is within the threshold (${threshold_kb} KB)."
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Update the last memory usage
|
||||||
|
last_mem_kb=$current_mem_kb
|
||||||
|
|
||||||
|
# Wait for 5 minutes
|
||||||
|
echo "$(date): Sleeping for $sleep_interval seconds..."
|
||||||
|
sleep $sleep_interval
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Memory monitoring script stopped." # This line might not be reached in normal operation
|
||||||
15
docs/how-to/memory-profile-scripts/scripts/find_compiled_jeprof.sh
Executable file
15
docs/how-to/memory-profile-scripts/scripts/find_compiled_jeprof.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Locates compiled jeprof binary (memory analysis tool) after cargo build
|
||||||
|
# Copies it to current directory from target/ build directories
|
||||||
|
|
||||||
|
JPROF_PATH=$(find . -name 'jeprof' -print -quit)
|
||||||
|
if [ -n "$JPROF_PATH" ]; then
|
||||||
|
echo "Found jeprof at $JPROF_PATH"
|
||||||
|
cp "$JPROF_PATH" .
|
||||||
|
chmod +x jeprof
|
||||||
|
echo "Copied jeprof to current directory and made it executable."
|
||||||
|
else
|
||||||
|
echo "jeprof not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
89
docs/how-to/memory-profile-scripts/scripts/gen_flamegraph.sh
Executable file
89
docs/how-to/memory-profile-scripts/scripts/gen_flamegraph.sh
Executable file
@@ -0,0 +1,89 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Generate flame graphs from a series of `.gprof` files
|
||||||
|
# First argument: Path to the binary executable
|
||||||
|
# Second argument: Path to directory containing gprof files
|
||||||
|
# Requires `jeprof` and `flamegraph.pl` in current directory
|
||||||
|
# What this script essentially does is:
|
||||||
|
# ./jeprof <binary> <gprof> --collapse | ./flamegraph.pl > <output>
|
||||||
|
# For differential analysis between consecutive profiles:
|
||||||
|
# ./jeprof <binary> --base <gprof1> <gprof2> --collapse | ./flamegraph.pl > <output_diff>
|
||||||
|
|
||||||
|
set -e # Exit immediately if a command exits with a non-zero status.
|
||||||
|
|
||||||
|
# Check for required tools
|
||||||
|
if [ ! -f "./jeprof" ]; then
|
||||||
|
echo "Error: jeprof not found in the current directory."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "./flamegraph.pl" ]; then
|
||||||
|
echo "Error: flamegraph.pl not found in the current directory."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check arguments
|
||||||
|
if [ "$#" -ne 2 ]; then
|
||||||
|
echo "Usage: $0 <binary_path> <gprof_directory>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
BINARY_PATH=$1
|
||||||
|
GPROF_DIR=$2
|
||||||
|
OUTPUT_DIR="${GPROF_DIR}/flamegraphs" # Store outputs in a subdirectory
|
||||||
|
|
||||||
|
if [ ! -f "$BINARY_PATH" ]; then
|
||||||
|
echo "Error: Binary file not found at $BINARY_PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$GPROF_DIR" ]; then
|
||||||
|
echo "Error: gprof directory not found at $GPROF_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
echo "Generating flamegraphs in $OUTPUT_DIR"
|
||||||
|
|
||||||
|
# Find and sort gprof files
|
||||||
|
# Use find + sort -V for natural sort of version numbers if present in filenames
|
||||||
|
# Use null-terminated strings for safety with find/xargs/sort
|
||||||
|
mapfile -d $'\0' gprof_files < <(find "$GPROF_DIR" -maxdepth 1 -name '*.gprof' -print0 | sort -zV)
|
||||||
|
|
||||||
|
if [ ${#gprof_files[@]} -eq 0 ]; then
|
||||||
|
echo "No .gprof files found in $GPROF_DIR"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
prev_gprof=""
|
||||||
|
|
||||||
|
# Generate flamegraphs
|
||||||
|
for gprof_file in "${gprof_files[@]}"; do
|
||||||
|
# Skip empty entries if any
|
||||||
|
if [ -z "$gprof_file" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
filename=$(basename "$gprof_file" .gprof)
|
||||||
|
output_collapse="${OUTPUT_DIR}/${filename}.collapse"
|
||||||
|
output_svg="${OUTPUT_DIR}/${filename}.svg"
|
||||||
|
echo "Generating collapse file for $gprof_file -> $output_collapse"
|
||||||
|
./jeprof "$BINARY_PATH" "$gprof_file" --collapse > "$output_collapse"
|
||||||
|
echo "Generating flamegraph for $gprof_file -> $output_svg"
|
||||||
|
./flamegraph.pl "$output_collapse" > "$output_svg" || true
|
||||||
|
|
||||||
|
# Generate diff flamegraph if not the first file
|
||||||
|
if [ -n "$prev_gprof" ]; then
|
||||||
|
prev_filename=$(basename "$prev_gprof" .gprof)
|
||||||
|
diff_output_collapse="${OUTPUT_DIR}/${prev_filename}_vs_${filename}_diff.collapse"
|
||||||
|
diff_output_svg="${OUTPUT_DIR}/${prev_filename}_vs_${filename}_diff.svg"
|
||||||
|
echo "Generating diff collapse file for $prev_gprof vs $gprof_file -> $diff_output_collapse"
|
||||||
|
./jeprof "$BINARY_PATH" --base "$prev_gprof" "$gprof_file" --collapse > "$diff_output_collapse"
|
||||||
|
echo "Generating diff flamegraph for $prev_gprof vs $gprof_file -> $diff_output_svg"
|
||||||
|
./flamegraph.pl "$diff_output_collapse" > "$diff_output_svg" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
prev_gprof="$gprof_file"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Flamegraph generation complete."
|
||||||
44
docs/how-to/memory-profile-scripts/scripts/gen_from_collapse.sh
Executable file
44
docs/how-to/memory-profile-scripts/scripts/gen_from_collapse.sh
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Generate flame graphs from .collapse files
|
||||||
|
# Argument: Path to directory containing collapse files
|
||||||
|
# Requires `flamegraph.pl` in current directory
|
||||||
|
|
||||||
|
# Check if flamegraph.pl exists
|
||||||
|
if [ ! -f "./flamegraph.pl" ]; then
|
||||||
|
echo "Error: flamegraph.pl not found in the current directory."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if directory argument is provided
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "Usage: $0 <collapse_directory>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
COLLAPSE_DIR=$1
|
||||||
|
|
||||||
|
# Check if the provided argument is a directory
|
||||||
|
if [ ! -d "$COLLAPSE_DIR" ]; then
|
||||||
|
echo "Error: '$COLLAPSE_DIR' is not a valid directory."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Generating flame graphs from collapse files in '$COLLAPSE_DIR'..."
|
||||||
|
|
||||||
|
# Find and process each .collapse file
|
||||||
|
find "$COLLAPSE_DIR" -maxdepth 1 -name "*.collapse" -print0 | while IFS= read -r -d $'\0' collapse_file; do
|
||||||
|
if [ -f "$collapse_file" ]; then
|
||||||
|
# Construct the output SVG filename
|
||||||
|
svg_file="${collapse_file%.collapse}.svg"
|
||||||
|
echo "Generating $svg_file from $collapse_file..."
|
||||||
|
./flamegraph.pl "$collapse_file" > "$svg_file"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error generating flame graph for $collapse_file"
|
||||||
|
else
|
||||||
|
echo "Successfully generated $svg_file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Flame graph generation complete."
|
||||||
6
docs/how-to/memory-profile-scripts/scripts/get_flamegraph_tool.sh
Executable file
6
docs/how-to/memory-profile-scripts/scripts/get_flamegraph_tool.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Download flamegraph.pl to current directory - this is the flame graph generation tool script
|
||||||
|
|
||||||
|
curl https://raw.githubusercontent.com/brendangregg/FlameGraph/master/flamegraph.pl > ./flamegraph.pl
|
||||||
|
chmod +x ./flamegraph.pl
|
||||||
77
docs/rfcs/2025-02-06-remote-wal-purge.md
Normal file
77
docs/rfcs/2025-02-06-remote-wal-purge.md
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
Feature Name: Remote WAL Purge
|
||||||
|
Tracking Issue: https://github.com/GreptimeTeam/greptimedb/issues/5474
|
||||||
|
Date: 2025-02-06
|
||||||
|
Author: "Yuhan Wang <profsyb@gmail.com>"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
|
||||||
|
This RFC proposes a method for purging remote WAL in the database.
|
||||||
|
|
||||||
|
# Motivation
|
||||||
|
|
||||||
|
Currently only local wal entries are purged when flushing, while remote wal does nothing.
|
||||||
|
|
||||||
|
# Details
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
Region0->>Kafka: Last entry id of the topic in use
|
||||||
|
Region0->>WALPruner: Heartbeat with last entry id
|
||||||
|
WALPruner->>+WALPruner: Time Loop
|
||||||
|
WALPruner->>+ProcedureManager: Submit purge procedure
|
||||||
|
ProcedureManager->>Region0: Flush request
|
||||||
|
ProcedureManager->>Kafka: Prune WAL entries
|
||||||
|
Region0->>Region0: Flush
|
||||||
|
```
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
### Before purge
|
||||||
|
|
||||||
|
Before purging remote WAL, metasrv needs to know:
|
||||||
|
|
||||||
|
1. `last_entry_id` of each region.
|
||||||
|
2. `kafka_topic_last_entry_id` which is the last entry id of the topic in use. Can be lazily updated and needed when region has empty memtable.
|
||||||
|
3. Kafka topics that each region uses.
|
||||||
|
|
||||||
|
The states are maintained through:
|
||||||
|
1. Heartbeat: Datanode sends `last_entry_id` to metasrv in heartbeat. As for regions with empty memtable, `last_entry_id` should equals to `kafka_topic_last_entry_id`.
|
||||||
|
2. Metasrv maintains a topic-region map to know which region uses which topic.
|
||||||
|
|
||||||
|
`kafka_topic_last_entry_id` will be maintained by the region itself. Region will update the value after `k` heartbeats if the memtable is empty.
|
||||||
|
|
||||||
|
### Purge procedure
|
||||||
|
|
||||||
|
We can better handle locks utilizing current procedure. It's quite similar to the region migration procedure.
|
||||||
|
|
||||||
|
After a period of time, metasrv will submit a purge procedure to ProcedureManager. The purge will apply to all topics.
|
||||||
|
|
||||||
|
The procedure is divided into following stages:
|
||||||
|
|
||||||
|
1. Preparation:
|
||||||
|
- Retrieve `last_entry_id` of each region kvbackend.
|
||||||
|
- Choose regions that have a relatively small `last_entry_id` as candidate regions, which means we need to send a flush request to these regions.
|
||||||
|
2. Communication:
|
||||||
|
- Send flush requests to candidate regions.
|
||||||
|
3. Purge:
|
||||||
|
- Choose proper entry id to delete for each topic. The entry should be the smallest `last_entry_id - 1` among all regions.
|
||||||
|
- Delete legacy entries in Kafka.
|
||||||
|
- Store the `last_purged_entry_id` in kvbackend. It should be locked to prevent other regions from replaying the purged entries.
|
||||||
|
|
||||||
|
### After purge
|
||||||
|
|
||||||
|
After purge, there may be some regions that have `last_entry_id` smaller than the entry we just deleted. It's legal since we only delete the entries that are not needed anymore.
|
||||||
|
|
||||||
|
When restarting a region, it should query the `last_purged_entry_id` from metasrv and replay from `min(last_entry_id, last_purged_entry_id)`.
|
||||||
|
|
||||||
|
### Error handling
|
||||||
|
|
||||||
|
No persisted states are needed since all states are maintained in kvbackend.
|
||||||
|
|
||||||
|
Retry when failed to retrieving metadata from kvbackend.
|
||||||
|
|
||||||
|
# Alternatives
|
||||||
|
|
||||||
|
Purge time can depend on the size of the WAL entries instead of a fixed period of time, which may be more efficient.
|
||||||
20
flake.lock
generated
20
flake.lock
generated
@@ -8,11 +8,11 @@
|
|||||||
"rust-analyzer-src": "rust-analyzer-src"
|
"rust-analyzer-src": "rust-analyzer-src"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737613896,
|
"lastModified": 1745735608,
|
||||||
"narHash": "sha256-ldqXIglq74C7yKMFUzrS9xMT/EVs26vZpOD68Sh7OcU=",
|
"narHash": "sha256-L0jzm815XBFfF2wCFmR+M1CF+beIEFj6SxlqVKF59Ec=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "fenix",
|
"repo": "fenix",
|
||||||
"rev": "303a062fdd8e89f233db05868468975d17855d80",
|
"rev": "c39a78eba6ed2a022cc3218db90d485077101496",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -41,16 +41,16 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737569578,
|
"lastModified": 1748162331,
|
||||||
"narHash": "sha256-6qY0pk2QmUtBT9Mywdvif0i/CLVgpCjMUn6g9vB+f3M=",
|
"narHash": "sha256-rqc2RKYTxP3tbjA+PB3VMRQNnjesrT0pEofXQTrMsS8=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "47addd76727f42d351590c905d9d1905ca895b82",
|
"rev": "7c43f080a7f28b2774f3b3f43234ca11661bf334",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "nixos-24.11",
|
"ref": "nixos-25.05",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
@@ -65,11 +65,11 @@
|
|||||||
"rust-analyzer-src": {
|
"rust-analyzer-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737581772,
|
"lastModified": 1745694049,
|
||||||
"narHash": "sha256-t1P2Pe3FAX9TlJsCZbmJ3wn+C4qr6aSMypAOu8WNsN0=",
|
"narHash": "sha256-fxvRYH/tS7hGQeg9zCVh5RBcSWT+JGJet7RA8Ss+rC0=",
|
||||||
"owner": "rust-lang",
|
"owner": "rust-lang",
|
||||||
"repo": "rust-analyzer",
|
"repo": "rust-analyzer",
|
||||||
"rev": "582af7ee9c8d84f5d534272fc7de9f292bd849be",
|
"rev": "d8887c0758bbd2d5f752d5bd405d4491e90e7ed6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
description = "Development environment flake";
|
description = "Development environment flake";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
|
||||||
fenix = {
|
fenix = {
|
||||||
url = "github:nix-community/fenix";
|
url = "github:nix-community/fenix";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
lib = nixpkgs.lib;
|
lib = nixpkgs.lib;
|
||||||
rustToolchain = fenix.packages.${system}.fromToolchainName {
|
rustToolchain = fenix.packages.${system}.fromToolchainName {
|
||||||
name = (lib.importTOML ./rust-toolchain.toml).toolchain.channel;
|
name = (lib.importTOML ./rust-toolchain.toml).toolchain.channel;
|
||||||
sha256 = "sha256-f/CVA1EC61EWbh0SjaRNhLL0Ypx2ObupbzigZp8NmL4=";
|
sha256 = "sha256-tJJr8oqX3YD+ohhPK7jlt/7kvKBnBqJVjYtoFr520d4=";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@@ -51,6 +51,7 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
|
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
|
||||||
|
NIX_HARDENING_ENABLE = "";
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,95 @@
|
|||||||
Grafana dashboard for GreptimeDB
|
# Grafana dashboards for GreptimeDB
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
GreptimeDB's official Grafana dashboard.
|
## Overview
|
||||||
|
|
||||||
Status notify: we are still working on this config. It's expected to change frequently in the recent days. Please feel free to submit your feedback and/or contribution to this dashboard 🤗
|
This repository contains Grafana dashboards for visualizing metrics and logs of GreptimeDB instances running in either cluster or standalone mode. **The Grafana version should be greater than 9.0**.
|
||||||
|
|
||||||
If you use Helm [chart](https://github.com/GreptimeTeam/helm-charts) to deploy GreptimeDB cluster, you can enable self-monitoring by setting the following values in your Helm chart:
|
We highly recommend using the self-monitoring feature provided by [GreptimeDB Operator](https://github.com/GrepTimeTeam/greptimedb-operator) to automatically collect metrics and logs from your GreptimeDB instances and store them in a dedicated GreptimeDB instance.
|
||||||
|
|
||||||
|
- **Metrics Dashboards**
|
||||||
|
|
||||||
|
- `dashboards/metrics/cluster/dashboard.json`: The Grafana dashboard for the GreptimeDB cluster. Read the [dashboard.md](./dashboards/metrics/cluster/dashboard.md) for more details.
|
||||||
|
|
||||||
|
- `dashboards/metrics/standalone/dashboard.json`: The Grafana dashboard for the standalone GreptimeDB instance. **It's generated from the `cluster/dashboard.json` by removing the instance filter through the `make dashboards` command**. Read the [dashboard.md](./dashboards/metrics/standalone/dashboard.md) for more details.
|
||||||
|
|
||||||
|
- **Logs Dashboard**
|
||||||
|
|
||||||
|
The `dashboards/logs/dashboard.json` provides a comprehensive Grafana dashboard for visualizing GreptimeDB logs. To utilize this dashboard effectively, you need to collect logs in JSON format from your GreptimeDB instances and store them in a dedicated GreptimeDB instance.
|
||||||
|
|
||||||
|
For proper integration, the logs table must adhere to the following schema design with the table name `_gt_logs`:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE IF NOT EXISTS `_gt_logs` (
|
||||||
|
`pod_ip` STRING NULL,
|
||||||
|
`namespace` STRING NULL,
|
||||||
|
`cluster` STRING NULL,
|
||||||
|
`file` STRING NULL,
|
||||||
|
`module_path` STRING NULL,
|
||||||
|
`level` STRING NULL,
|
||||||
|
`target` STRING NULL,
|
||||||
|
`role` STRING NULL,
|
||||||
|
`pod` STRING NULL SKIPPING INDEX WITH(granularity = '10240', type = 'BLOOM'),
|
||||||
|
`message` STRING NULL FULLTEXT INDEX WITH(analyzer = 'English', backend = 'bloom', case_sensitive = 'false'),
|
||||||
|
`err` STRING NULL FULLTEXT INDEX WITH(analyzer = 'English', backend = 'bloom', case_sensitive = 'false'),
|
||||||
|
`timestamp` TIMESTAMP(9) NOT NULL,
|
||||||
|
TIME INDEX (`timestamp`),
|
||||||
|
PRIMARY KEY (`level`, `target`, `role`)
|
||||||
|
)
|
||||||
|
ENGINE=mito
|
||||||
|
WITH (
|
||||||
|
append_mode = 'true'
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
As GreptimeDB evolves rapidly, metrics may change over time. We welcome your feedback and contributions to improve these dashboards 🤗
|
||||||
|
|
||||||
|
To modify the metrics dashboards, simply edit the `dashboards/metrics/cluster/dashboard.json` file and run the `make dashboards` command. This will automatically generate the updated `dashboards/metrics/standalone/dashboard.json` and other related files.
|
||||||
|
|
||||||
|
For easier dashboard maintenance, we utilize the [`dac`](https://github.com/zyy17/dac) tool to generate human-readable intermediate dashboards and documentation:
|
||||||
|
|
||||||
|
- `dashboards/metrics/cluster/dashboard.yaml`: The intermediate dashboard file for the GreptimeDB cluster.
|
||||||
|
- `dashboards/metrics/standalone/dashboard.yaml`: The intermediate dashboard file for standalone GreptimeDB instances.
|
||||||
|
|
||||||
|
## Data Sources
|
||||||
|
|
||||||
|
The following data sources are used to fetch metrics and logs:
|
||||||
|
|
||||||
|
- **`${metrics}`**: Prometheus data source for providing the GreptimeDB metrics.
|
||||||
|
- **`${logs}`**: MySQL data source for providing the GreptimeDB logs.
|
||||||
|
- **`${information_schema}`**: MySQL data source for providing the information schema of the current instance and used for the `overview` panel. It is the MySQL port of the current monitored instance.
|
||||||
|
|
||||||
|
## Instance Filters
|
||||||
|
|
||||||
|
To deploy the dashboards for multiple scenarios (K8s, bare metal, etc.), we prefer to use the `instance` label when filtering instances.
|
||||||
|
|
||||||
|
Additionally, we recommend including the `pod` label in the legend to make it easier to identify each instance, even though this field will be empty in bare metal scenarios.
|
||||||
|
|
||||||
|
For example, the following query is recommended:
|
||||||
|
|
||||||
|
```promql
|
||||||
|
sum(process_resident_memory_bytes{instance=~"$datanode"}) by (instance, pod)
|
||||||
|
```
|
||||||
|
|
||||||
|
And the legend will be like: `[{{instance}}]-[{{ pod }}]`.
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
### (Recommended) Helm Chart
|
||||||
|
|
||||||
|
If you use the [Helm Chart](https://github.com/GreptimeTeam/helm-charts) to deploy a GreptimeDB cluster, you can enable self-monitoring by setting the following values in your Helm chart:
|
||||||
|
|
||||||
- `monitoring.enabled=true`: Deploys a standalone GreptimeDB instance dedicated to monitoring the cluster;
|
- `monitoring.enabled=true`: Deploys a standalone GreptimeDB instance dedicated to monitoring the cluster;
|
||||||
- `grafana.enabled=true`: Deploys Grafana and automatically imports the monitoring dashboard;
|
- `grafana.enabled=true`: Deploys Grafana and automatically imports the monitoring dashboard;
|
||||||
|
|
||||||
The standalone GreptimeDB instance will collect metrics from your cluster and the dashboard will be available in the Grafana UI. For detailed deployment instructions, please refer to our [Kubernetes deployment guide](https://docs.greptime.com/nightly/user-guide/deployments/deploy-on-kubernetes/getting-started).
|
The standalone GreptimeDB instance will collect metrics from your cluster, and the dashboard will be available in the Grafana UI. For detailed deployment instructions, please refer to our [Kubernetes deployment guide](https://docs.greptime.com/nightly/user-guide/deployments/deploy-on-kubernetes/getting-started).
|
||||||
|
|
||||||
# How to use
|
### Self-host Prometheus and import dashboards manually
|
||||||
|
|
||||||
## `greptimedb.json`
|
1. **Configure Prometheus to scrape the cluster**
|
||||||
|
|
||||||
Open Grafana Dashboard page, choose `New` -> `Import`. And upload `greptimedb.json` file.
|
The following is an example configuration(**Please modify it according to your actual situation**):
|
||||||
|
|
||||||
## `greptimedb-cluster.json`
|
|
||||||
|
|
||||||
This cluster dashboard provides a comprehensive view of incoming requests, response statuses, and internal activities such as flush and compaction, with a layered structure from frontend to datanode. Designed with a focus on alert functionality, its primary aim is to highlight any anomalies in metrics, allowing users to quickly pinpoint the cause of errors.
|
|
||||||
|
|
||||||
We use Prometheus to scrape off metrics from nodes in GreptimeDB cluster, Grafana to visualize the diagram. Any compatible stack should work too.
|
|
||||||
|
|
||||||
__Note__: This dashboard is still in an early stage of development. Any issue or advice on improvement is welcomed.
|
|
||||||
|
|
||||||
### Configuration
|
|
||||||
|
|
||||||
Please ensure the following configuration before importing the dashboard into Grafana.
|
|
||||||
|
|
||||||
__1. Prometheus scrape config__
|
|
||||||
|
|
||||||
Configure Prometheus to scrape the cluster.
|
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
# example config
|
# example config
|
||||||
@@ -52,10 +109,14 @@ scrape_configs:
|
|||||||
- targets: ['<frontend-ip>:<port>']
|
- targets: ['<frontend-ip>:<port>']
|
||||||
```
|
```
|
||||||
|
|
||||||
__2. Grafana config__
|
2. **Configure the data sources in Grafana**
|
||||||
|
|
||||||
Create a Prometheus data source in Grafana before using this dashboard. We use `datasource` as a variable in Grafana dashboard so that multiple environments are supported.
|
You need to add two data sources in Grafana:
|
||||||
|
|
||||||
### Usage
|
- Prometheus: It is the Prometheus instance that scrapes the GreptimeDB metrics.
|
||||||
|
- Information Schema: It is the MySQL port of the current monitored instance. The dashboard will use this datasource to show the information schema of the current instance.
|
||||||
|
|
||||||
Use `datasource` or `instance` on the upper-left corner to filter data from certain node.
|
3. **Import the dashboards based on your deployment scenario**
|
||||||
|
|
||||||
|
- **Cluster**: Import the `dashboards/metrics/cluster/dashboard.json` dashboard.
|
||||||
|
- **Standalone**: Import the `dashboards/metrics/standalone/dashboard.json` dashboard.
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
BASEDIR=$(dirname "$0")
|
|
||||||
|
|
||||||
# Use jq to check for panels with empty or missing descriptions
|
|
||||||
invalid_panels=$(cat $BASEDIR/greptimedb-cluster.json | jq -r '
|
|
||||||
.panels[]
|
|
||||||
| select((.type == "stats" or .type == "timeseries") and (.description == "" or .description == null))
|
|
||||||
')
|
|
||||||
|
|
||||||
# Check if any invalid panels were found
|
|
||||||
if [[ -n "$invalid_panels" ]]; then
|
|
||||||
echo "Error: The following panels have empty or missing descriptions:"
|
|
||||||
echo "$invalid_panels"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "All panels with type 'stats' or 'timeseries' have valid descriptions."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
292
grafana/dashboards/logs/dashboard.json
Normal file
292
grafana/dashboards/logs/dashboard.json
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
{
|
||||||
|
"annotations": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"builtIn": 1,
|
||||||
|
"datasource": {
|
||||||
|
"type": "grafana",
|
||||||
|
"uid": "-- Grafana --"
|
||||||
|
},
|
||||||
|
"enable": true,
|
||||||
|
"hide": true,
|
||||||
|
"iconColor": "rgba(0, 211, 255, 1)",
|
||||||
|
"name": "Annotations & Alerts",
|
||||||
|
"type": "dashboard"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editable": true,
|
||||||
|
"fiscalYearStartMonth": 0,
|
||||||
|
"graphTooltip": 0,
|
||||||
|
"id": 12,
|
||||||
|
"links": [],
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"datasource": {
|
||||||
|
"default": false,
|
||||||
|
"type": "mysql",
|
||||||
|
"uid": "${datasource}"
|
||||||
|
},
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"h": 20,
|
||||||
|
"w": 24,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"id": 1,
|
||||||
|
"options": {
|
||||||
|
"dedupStrategy": "none",
|
||||||
|
"enableInfiniteScrolling": true,
|
||||||
|
"enableLogDetails": true,
|
||||||
|
"prettifyLogMessage": false,
|
||||||
|
"showCommonLabels": false,
|
||||||
|
"showLabels": false,
|
||||||
|
"showTime": true,
|
||||||
|
"sortOrder": "Descending",
|
||||||
|
"wrapLogMessage": false
|
||||||
|
},
|
||||||
|
"pluginVersion": "11.6.0",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"dataset": "greptime_private",
|
||||||
|
"datasource": {
|
||||||
|
"type": "mysql",
|
||||||
|
"uid": "${datasource}"
|
||||||
|
},
|
||||||
|
"editorMode": "code",
|
||||||
|
"format": "table",
|
||||||
|
"rawQuery": true,
|
||||||
|
"rawSql": "SELECT `timestamp`, CONCAT('[', `level`, ']', ' ', '<', `target`, '>', ' ', `message`),\n `role`,\n `pod`,\n `pod_ip`,\n `namespace`,\n `cluster`,\n `err`,\n `file`,\n `module_path`\nFROM\n `_gt_logs`\nWHERE\n (\n \"$level\" = \"'all'\"\n OR `level` IN ($level)\n ) \n AND (\n \"$role\" = \"'all'\"\n OR `role` IN ($role)\n )\n AND (\n \"$pod\" = \"\"\n OR `pod` = '$pod'\n )\n AND (\n \"$target\" = \"\"\n OR `target` = '$target'\n )\n AND (\n \"$search\" = \"\"\n OR matches_term(`message`, '$search')\n )\n AND (\n \"$exclude\" = \"\"\n OR NOT matches_term(`message`, '$exclude')\n )\n AND $__timeFilter(`timestamp`)\nORDER BY `timestamp` DESC\nLIMIT $limit;\n",
|
||||||
|
"refId": "A",
|
||||||
|
"sql": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"parameters": [],
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"groupBy": [
|
||||||
|
{
|
||||||
|
"property": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "groupBy"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"limit": 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Logs",
|
||||||
|
"type": "logs"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preload": false,
|
||||||
|
"refresh": "",
|
||||||
|
"schemaVersion": 41,
|
||||||
|
"tags": [],
|
||||||
|
"templating": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"current": {
|
||||||
|
"text": "logs",
|
||||||
|
"value": "P98F38F12DB221A8C"
|
||||||
|
},
|
||||||
|
"includeAll": false,
|
||||||
|
"name": "datasource",
|
||||||
|
"options": [],
|
||||||
|
"query": "mysql",
|
||||||
|
"refresh": 1,
|
||||||
|
"regex": "",
|
||||||
|
"type": "datasource"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allValue": "'all'",
|
||||||
|
"current": {
|
||||||
|
"text": [
|
||||||
|
"$__all"
|
||||||
|
],
|
||||||
|
"value": [
|
||||||
|
"$__all"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"includeAll": true,
|
||||||
|
"label": "level",
|
||||||
|
"multi": true,
|
||||||
|
"name": "level",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"selected": false,
|
||||||
|
"text": "INFO",
|
||||||
|
"value": "INFO"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selected": false,
|
||||||
|
"text": "ERROR",
|
||||||
|
"value": "ERROR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selected": false,
|
||||||
|
"text": "WARN",
|
||||||
|
"value": "WARN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selected": false,
|
||||||
|
"text": "DEBUG",
|
||||||
|
"value": "DEBUG"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selected": false,
|
||||||
|
"text": "TRACE",
|
||||||
|
"value": "TRACE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"query": "INFO,ERROR,WARN,DEBUG,TRACE",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allValue": "'all'",
|
||||||
|
"current": {
|
||||||
|
"text": [
|
||||||
|
"$__all"
|
||||||
|
],
|
||||||
|
"value": [
|
||||||
|
"$__all"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"includeAll": true,
|
||||||
|
"label": "role",
|
||||||
|
"multi": true,
|
||||||
|
"name": "role",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"selected": false,
|
||||||
|
"text": "datanode",
|
||||||
|
"value": "datanode"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selected": false,
|
||||||
|
"text": "frontend",
|
||||||
|
"value": "frontend"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selected": false,
|
||||||
|
"text": "meta",
|
||||||
|
"value": "meta"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"query": "datanode,frontend,meta",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"current": {
|
||||||
|
"text": "",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"label": "pod",
|
||||||
|
"name": "pod",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"selected": true,
|
||||||
|
"text": "",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"query": "",
|
||||||
|
"type": "textbox"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"current": {
|
||||||
|
"text": "",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"label": "target",
|
||||||
|
"name": "target",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"selected": true,
|
||||||
|
"text": "",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"query": "",
|
||||||
|
"type": "textbox"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"current": {
|
||||||
|
"text": "",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"label": "search",
|
||||||
|
"name": "search",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"selected": true,
|
||||||
|
"text": "",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"query": "",
|
||||||
|
"type": "textbox"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"current": {
|
||||||
|
"text": "",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"label": "exclude",
|
||||||
|
"name": "exclude",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"selected": true,
|
||||||
|
"text": "",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"query": "",
|
||||||
|
"type": "textbox"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"current": {
|
||||||
|
"text": "2000",
|
||||||
|
"value": "2000"
|
||||||
|
},
|
||||||
|
"includeAll": false,
|
||||||
|
"label": "limit",
|
||||||
|
"name": "limit",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"selected": true,
|
||||||
|
"text": "2000",
|
||||||
|
"value": "2000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selected": false,
|
||||||
|
"text": "5000",
|
||||||
|
"value": "5000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selected": false,
|
||||||
|
"text": "8000",
|
||||||
|
"value": "8000"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"query": "2000,5000,8000",
|
||||||
|
"type": "custom"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"from": "now-6h",
|
||||||
|
"to": "now"
|
||||||
|
},
|
||||||
|
"timepicker": {},
|
||||||
|
"timezone": "browser",
|
||||||
|
"title": "GreptimeDB Logs",
|
||||||
|
"uid": "edx5veo4rd3wge2",
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
8618
grafana/dashboards/metrics/cluster/dashboard.json
Normal file
8618
grafana/dashboards/metrics/cluster/dashboard.json
Normal file
File diff suppressed because it is too large
Load Diff
111
grafana/dashboards/metrics/cluster/dashboard.md
Normal file
111
grafana/dashboards/metrics/cluster/dashboard.md
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# Overview
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Uptime | `time() - process_start_time_seconds` | `stat` | The start time of GreptimeDB. | `prometheus` | `s` | `__auto` |
|
||||||
|
| Version | `SELECT pkg_version FROM information_schema.build_info` | `stat` | GreptimeDB version. | `mysql` | -- | -- |
|
||||||
|
| Total Ingestion Rate | `sum(rate(greptime_table_operator_ingest_rows[$__rate_interval]))` | `stat` | Total ingestion rate. | `prometheus` | `rowsps` | `__auto` |
|
||||||
|
| Total Storage Size | `select SUM(disk_size) from information_schema.region_statistics;` | `stat` | Total number of data file size. | `mysql` | `decbytes` | -- |
|
||||||
|
| Total Rows | `select SUM(region_rows) from information_schema.region_statistics;` | `stat` | Total number of data rows in the cluster. Calculated by sum of rows from each region. | `mysql` | `sishort` | -- |
|
||||||
|
| Deployment | `SELECT count(*) as datanode FROM information_schema.cluster_info WHERE peer_type = 'DATANODE';`<br/>`SELECT count(*) as frontend FROM information_schema.cluster_info WHERE peer_type = 'FRONTEND';`<br/>`SELECT count(*) as metasrv FROM information_schema.cluster_info WHERE peer_type = 'METASRV';`<br/>`SELECT count(*) as flownode FROM information_schema.cluster_info WHERE peer_type = 'FLOWNODE';` | `stat` | The deployment topology of GreptimeDB. | `mysql` | -- | -- |
|
||||||
|
| Database Resources | `SELECT COUNT(*) as databases FROM information_schema.schemata WHERE schema_name NOT IN ('greptime_private', 'information_schema')`<br/>`SELECT COUNT(*) as tables FROM information_schema.tables WHERE table_schema != 'information_schema'`<br/>`SELECT COUNT(region_id) as regions FROM information_schema.region_peers`<br/>`SELECT COUNT(*) as flows FROM information_schema.flows` | `stat` | The number of the key resources in GreptimeDB. | `mysql` | -- | -- |
|
||||||
|
| Data Size | `SELECT SUM(memtable_size) * 0.42825 as WAL FROM information_schema.region_statistics;`<br/>`SELECT SUM(index_size) as index FROM information_schema.region_statistics;`<br/>`SELECT SUM(manifest_size) as manifest FROM information_schema.region_statistics;` | `stat` | The data size of wal/index/manifest in the GreptimeDB. | `mysql` | `decbytes` | -- |
|
||||||
|
# Ingestion
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Total Ingestion Rate | `sum(rate(greptime_table_operator_ingest_rows{instance=~"$frontend"}[$__rate_interval]))` | `timeseries` | Total ingestion rate.<br/><br/>Here we listed 3 primary protocols:<br/><br/>- Prometheus remote write<br/>- Greptime's gRPC API (when using our ingest SDK)<br/>- Log ingestion http API<br/> | `prometheus` | `rowsps` | `ingestion` |
|
||||||
|
| Ingestion Rate by Type | `sum(rate(greptime_servers_http_logs_ingestion_counter[$__rate_interval]))`<br/>`sum(rate(greptime_servers_prometheus_remote_write_samples[$__rate_interval]))` | `timeseries` | Total ingestion rate.<br/><br/>Here we listed 3 primary protocols:<br/><br/>- Prometheus remote write<br/>- Greptime's gRPC API (when using our ingest SDK)<br/>- Log ingestion http API<br/> | `prometheus` | `rowsps` | `http-logs` |
|
||||||
|
# Queries
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Total Query Rate | `sum (rate(greptime_servers_mysql_query_elapsed_count{instance=~"$frontend"}[$__rate_interval]))`<br/>`sum (rate(greptime_servers_postgres_query_elapsed_count{instance=~"$frontend"}[$__rate_interval]))`<br/>`sum (rate(greptime_servers_http_promql_elapsed_counte{instance=~"$frontend"}[$__rate_interval]))` | `timeseries` | Total rate of query API calls by protocol. This metric is collected from frontends.<br/><br/>Here we listed 3 main protocols:<br/>- MySQL<br/>- Postgres<br/>- Prometheus API<br/><br/>Note that there are some other minor query APIs like /sql are not included | `prometheus` | `reqps` | `mysql` |
|
||||||
|
# Resources
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Datanode Memory per Instance | `sum(process_resident_memory_bytes{instance=~"$datanode"}) by (instance, pod)` | `timeseries` | Current memory usage by instance | `prometheus` | `decbytes` | `[{{instance}}]-[{{ pod }}]` |
|
||||||
|
| Datanode CPU Usage per Instance | `sum(rate(process_cpu_seconds_total{instance=~"$datanode"}[$__rate_interval]) * 1000) by (instance, pod)` | `timeseries` | Current cpu usage by instance | `prometheus` | `none` | `[{{ instance }}]-[{{ pod }}]` |
|
||||||
|
| Frontend Memory per Instance | `sum(process_resident_memory_bytes{instance=~"$frontend"}) by (instance, pod)` | `timeseries` | Current memory usage by instance | `prometheus` | `decbytes` | `[{{ instance }}]-[{{ pod }}]` |
|
||||||
|
| Frontend CPU Usage per Instance | `sum(rate(process_cpu_seconds_total{instance=~"$frontend"}[$__rate_interval]) * 1000) by (instance, pod)` | `timeseries` | Current cpu usage by instance | `prometheus` | `none` | `[{{ instance }}]-[{{ pod }}]-cpu` |
|
||||||
|
| Metasrv Memory per Instance | `sum(process_resident_memory_bytes{instance=~"$metasrv"}) by (instance, pod)` | `timeseries` | Current memory usage by instance | `prometheus` | `decbytes` | `[{{ instance }}]-[{{ pod }}]-resident` |
|
||||||
|
| Metasrv CPU Usage per Instance | `sum(rate(process_cpu_seconds_total{instance=~"$metasrv"}[$__rate_interval]) * 1000) by (instance, pod)` | `timeseries` | Current cpu usage by instance | `prometheus` | `none` | `[{{ instance }}]-[{{ pod }}]` |
|
||||||
|
| Flownode Memory per Instance | `sum(process_resident_memory_bytes{instance=~"$flownode"}) by (instance, pod)` | `timeseries` | Current memory usage by instance | `prometheus` | `decbytes` | `[{{ instance }}]-[{{ pod }}]` |
|
||||||
|
| Flownode CPU Usage per Instance | `sum(rate(process_cpu_seconds_total{instance=~"$flownode"}[$__rate_interval]) * 1000) by (instance, pod)` | `timeseries` | Current cpu usage by instance | `prometheus` | `none` | `[{{ instance }}]-[{{ pod }}]` |
|
||||||
|
# Frontend Requests
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| HTTP QPS per Instance | `sum by(instance, pod, path, method, code) (rate(greptime_servers_http_requests_elapsed_count{instance=~"$frontend",path!~"/health\|/metrics"}[$__rate_interval]))` | `timeseries` | HTTP QPS per Instance. | `prometheus` | `reqps` | `[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]` |
|
||||||
|
| HTTP P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, path, method, code) (rate(greptime_servers_http_requests_elapsed_bucket{instance=~"$frontend",path!~"/health\|/metrics"}[$__rate_interval])))` | `timeseries` | HTTP P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99` |
|
||||||
|
| gRPC QPS per Instance | `sum by(instance, pod, path, code) (rate(greptime_servers_grpc_requests_elapsed_count{instance=~"$frontend"}[$__rate_interval]))` | `timeseries` | gRPC QPS per Instance. | `prometheus` | `reqps` | `[{{instance}}]-[{{pod}}]-[{{path}}]-[{{code}}]` |
|
||||||
|
| gRPC P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, path, code) (rate(greptime_servers_grpc_requests_elapsed_bucket{instance=~"$frontend"}[$__rate_interval])))` | `timeseries` | gRPC P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99` |
|
||||||
|
| MySQL QPS per Instance | `sum by(pod, instance)(rate(greptime_servers_mysql_query_elapsed_count{instance=~"$frontend"}[$__rate_interval]))` | `timeseries` | MySQL QPS per Instance. | `prometheus` | `reqps` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| MySQL P99 per Instance | `histogram_quantile(0.99, sum by(pod, instance, le) (rate(greptime_servers_mysql_query_elapsed_bucket{instance=~"$frontend"}[$__rate_interval])))` | `timeseries` | MySQL P99 per Instance. | `prometheus` | `s` | `[{{ instance }}]-[{{ pod }}]-p99` |
|
||||||
|
| PostgreSQL QPS per Instance | `sum by(pod, instance)(rate(greptime_servers_postgres_query_elapsed_count{instance=~"$frontend"}[$__rate_interval]))` | `timeseries` | PostgreSQL QPS per Instance. | `prometheus` | `reqps` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| PostgreSQL P99 per Instance | `histogram_quantile(0.99, sum by(pod,instance,le) (rate(greptime_servers_postgres_query_elapsed_bucket{instance=~"$frontend"}[$__rate_interval])))` | `timeseries` | PostgreSQL P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-p99` |
|
||||||
|
# Frontend to Datanode
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Ingest Rows per Instance | `sum by(instance, pod)(rate(greptime_table_operator_ingest_rows{instance=~"$frontend"}[$__rate_interval]))` | `timeseries` | Ingestion rate by row as in each frontend | `prometheus` | `rowsps` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Region Call QPS per Instance | `sum by(instance, pod, request_type) (rate(greptime_grpc_region_request_count{instance=~"$frontend"}[$__rate_interval]))` | `timeseries` | Region Call QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{request_type}}]` |
|
||||||
|
| Region Call P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, request_type) (rate(greptime_grpc_region_request_bucket{instance=~"$frontend"}[$__rate_interval])))` | `timeseries` | Region Call P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{request_type}}]` |
|
||||||
|
| Frontend Handle Bulk Insert Elapsed Time | `sum by(instance, pod, stage) (rate(greptime_table_operator_handle_bulk_insert_sum[$__rate_interval]))/sum by(instance, pod, stage) (rate(greptime_table_operator_handle_bulk_insert_count[$__rate_interval]))`<br/>`histogram_quantile(0.99, sum by(instance, pod, stage, le) (rate(greptime_table_operator_handle_bulk_insert_bucket[$__rate_interval])))` | `timeseries` | Per-stage time for frontend to handle bulk insert requests | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-AVG` |
|
||||||
|
# Mito Engine
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Request OPS per Instance | `sum by(instance, pod, type) (rate(greptime_mito_handle_request_elapsed_count{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | Request QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{type}}]` |
|
||||||
|
| Request P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, type) (rate(greptime_mito_handle_request_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))` | `timeseries` | Request P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{type}}]` |
|
||||||
|
| Write Buffer per Instance | `greptime_mito_write_buffer_bytes{instance=~"$datanode"}` | `timeseries` | Write Buffer per Instance. | `prometheus` | `decbytes` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Write Rows per Instance | `sum by (instance, pod) (rate(greptime_mito_write_rows_total{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | Ingestion size by row counts. | `prometheus` | `rowsps` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Flush OPS per Instance | `sum by(instance, pod, reason) (rate(greptime_mito_flush_requests_total{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | Flush QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{reason}}]` |
|
||||||
|
| Write Stall per Instance | `sum by(instance, pod) (greptime_mito_write_stall_total{instance=~"$datanode"})` | `timeseries` | Write Stall per Instance. | `prometheus` | -- | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Read Stage OPS per Instance | `sum by(instance, pod) (rate(greptime_mito_read_stage_elapsed_count{instance=~"$datanode", stage="total"}[$__rate_interval]))` | `timeseries` | Read Stage OPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Read Stage P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_read_stage_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))` | `timeseries` | Read Stage P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]` |
|
||||||
|
| Write Stage P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_write_stage_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))` | `timeseries` | Write Stage P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]` |
|
||||||
|
| Compaction OPS per Instance | `sum by(instance, pod) (rate(greptime_mito_compaction_total_elapsed_count{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | Compaction OPS per Instance. | `prometheus` | `ops` | `[{{ instance }}]-[{{pod}}]` |
|
||||||
|
| Compaction Elapsed Time per Instance by Stage | `histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_compaction_stage_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))`<br/>`sum by(instance, pod, stage) (rate(greptime_mito_compaction_stage_elapsed_sum{instance=~"$datanode"}[$__rate_interval]))/sum by(instance, pod, stage) (rate(greptime_mito_compaction_stage_elapsed_count{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | Compaction latency by stage | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-p99` |
|
||||||
|
| Compaction P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le,stage) (rate(greptime_mito_compaction_total_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))` | `timeseries` | Compaction P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-compaction` |
|
||||||
|
| WAL write size | `histogram_quantile(0.95, sum by(le,instance, pod) (rate(raft_engine_write_size_bucket[$__rate_interval])))`<br/>`histogram_quantile(0.99, sum by(le,instance,pod) (rate(raft_engine_write_size_bucket[$__rate_interval])))`<br/>`sum by (instance, pod)(rate(raft_engine_write_size_sum[$__rate_interval]))` | `timeseries` | Write-ahead logs write size as bytes. This chart includes stats of p95 and p99 size by instance, total WAL write rate. | `prometheus` | `bytes` | `[{{instance}}]-[{{pod}}]-req-size-p95` |
|
||||||
|
| Cached Bytes per Instance | `greptime_mito_cache_bytes{instance=~"$datanode"}` | `timeseries` | Cached Bytes per Instance. | `prometheus` | `decbytes` | `[{{instance}}]-[{{pod}}]-[{{type}}]` |
|
||||||
|
| Inflight Compaction | `greptime_mito_inflight_compaction_count` | `timeseries` | Ongoing compaction task count | `prometheus` | `none` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| WAL sync duration seconds | `histogram_quantile(0.99, sum by(le, type, node, instance, pod) (rate(raft_engine_sync_log_duration_seconds_bucket[$__rate_interval])))` | `timeseries` | Raft engine (local disk) log store sync latency, p99 | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-p99` |
|
||||||
|
| Log Store op duration seconds | `histogram_quantile(0.99, sum by(le,logstore,optype,instance, pod) (rate(greptime_logstore_op_elapsed_bucket[$__rate_interval])))` | `timeseries` | Write-ahead log operations latency at p99 | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{logstore}}]-[{{optype}}]-p99` |
|
||||||
|
| Inflight Flush | `greptime_mito_inflight_flush_count` | `timeseries` | Ongoing flush task count | `prometheus` | `none` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Compaction Input/Output Bytes | `sum by(instance, pod) (greptime_mito_compaction_input_bytes)`<br/>`sum by(instance, pod) (greptime_mito_compaction_output_bytes)` | `timeseries` | Compaction oinput output bytes | `prometheus` | `bytes` | `[{{instance}}]-[{{pod}}]-input` |
|
||||||
|
| Region Worker Handle Bulk Insert Requests | `histogram_quantile(0.95, sum by(le,instance, stage, pod) (rate(greptime_region_worker_handle_write_bucket[$__rate_interval])))`<br/>`sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_sum[$__rate_interval]))/sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_count[$__rate_interval]))` | `timeseries` | Per-stage elapsed time for region worker to handle bulk insert region requests. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-P95` |
|
||||||
|
| Region Worker Convert Requests | `histogram_quantile(0.95, sum by(le, instance, stage, pod) (rate(greptime_datanode_convert_region_request_bucket[$__rate_interval])))`<br/>`sum by(le,instance, stage, pod) (rate(greptime_datanode_convert_region_request_sum[$__rate_interval]))/sum by(le,instance, stage, pod) (rate(greptime_datanode_convert_region_request_count[$__rate_interval]))` | `timeseries` | Per-stage elapsed time for region worker to decode requests. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-P95` |
|
||||||
|
# OpenDAL
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| QPS per Instance | `sum by(instance, pod, scheme, operation) (rate(opendal_operation_duration_seconds_count{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]` |
|
||||||
|
| Read QPS per Instance | `sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{instance=~"$datanode", operation="read"}[$__rate_interval]))` | `timeseries` | Read QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]` |
|
||||||
|
| Read P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{instance=~"$datanode",operation="read"}[$__rate_interval])))` | `timeseries` | Read P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-{{scheme}}` |
|
||||||
|
| Write QPS per Instance | `sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{instance=~"$datanode", operation="write"}[$__rate_interval]))` | `timeseries` | Write QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-{{scheme}}` |
|
||||||
|
| Write P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{instance=~"$datanode", operation="write"}[$__rate_interval])))` | `timeseries` | Write P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]` |
|
||||||
|
| List QPS per Instance | `sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{instance=~"$datanode", operation="list"}[$__rate_interval]))` | `timeseries` | List QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]` |
|
||||||
|
| List P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{instance=~"$datanode", operation="list"}[$__rate_interval])))` | `timeseries` | List P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]` |
|
||||||
|
| Other Requests per Instance | `sum by(instance, pod, scheme, operation) (rate(opendal_operation_duration_seconds_count{instance=~"$datanode",operation!~"read\|write\|list\|stat"}[$__rate_interval]))` | `timeseries` | Other Requests per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]` |
|
||||||
|
| Other Request P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, scheme, operation) (rate(opendal_operation_duration_seconds_bucket{instance=~"$datanode", operation!~"read\|write\|list"}[$__rate_interval])))` | `timeseries` | Other Request P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]` |
|
||||||
|
| Opendal traffic | `sum by(instance, pod, scheme, operation) (rate(opendal_operation_bytes_sum{instance=~"$datanode"}[$__rate_interval]))` | `timeseries` | Total traffic as in bytes by instance and operation | `prometheus` | `decbytes` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]` |
|
||||||
|
| OpenDAL errors per Instance | `sum by(instance, pod, scheme, operation, error) (rate(opendal_operation_errors_total{instance=~"$datanode", error!="NotFound"}[$__rate_interval]))` | `timeseries` | OpenDAL error counts per Instance. | `prometheus` | -- | `[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]-[{{error}}]` |
|
||||||
|
# Metasrv
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Region migration datanode | `greptime_meta_region_migration_stat{datanode_type="src"}`<br/>`greptime_meta_region_migration_stat{datanode_type="desc"}` | `status-history` | Counter of region migration by source and destination | `prometheus` | -- | `from-datanode-{{datanode_id}}` |
|
||||||
|
| Region migration error | `greptime_meta_region_migration_error` | `timeseries` | Counter of region migration error | `prometheus` | `none` | `{{pod}}-{{state}}-{{error_type}}` |
|
||||||
|
| Datanode load | `greptime_datanode_load` | `timeseries` | Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads. | `prometheus` | `binBps` | `Datanode-{{datanode_id}}-writeload` |
|
||||||
|
| Rate of SQL Executions (RDS) | `rate(greptime_meta_rds_pg_sql_execute_elapsed_ms_count[$__rate_interval])` | `timeseries` | Displays the rate of SQL executions processed by the Meta service using the RDS backend. | `prometheus` | `none` | `{{pod}} {{op}} {{type}} {{result}} ` |
|
||||||
|
| SQL Execution Latency (RDS) | `histogram_quantile(0.90, sum by(pod, op, type, result, le) (rate(greptime_meta_rds_pg_sql_execute_elapsed_ms_bucket[$__rate_interval])))` | `timeseries` | Measures the response time of SQL executions via the RDS backend. | `prometheus` | `ms` | `{{pod}} {{op}} {{type}} {{result}} p90` |
|
||||||
|
| Handler Execution Latency | `histogram_quantile(0.90, sum by(pod, le, name) (
|
||||||
|
rate(greptime_meta_handler_execute_bucket[$__rate_interval])
|
||||||
|
))` | `timeseries` | Shows latency of Meta handlers by pod and handler name, useful for monitoring handler performance and detecting latency spikes.<br/> | `prometheus` | `s` | `{{pod}} {{name}} p90` |
|
||||||
|
| Heartbeat Packet Size | `histogram_quantile(0.9, sum by(pod, le) (greptime_meta_heartbeat_stat_memory_size_bucket))` | `timeseries` | Shows p90 heartbeat message sizes, helping track network usage and identify anomalies in heartbeat payload.<br/> | `prometheus` | `bytes` | `{{pod}}` |
|
||||||
|
| Meta Heartbeat Receive Rate | `rate(greptime_meta_heartbeat_rate[$__rate_interval])` | `timeseries` | Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads. | `prometheus` | `s` | `{{pod}}` |
|
||||||
|
| Meta KV Ops Latency | `histogram_quantile(0.99, sum by(pod, le, op, target) (greptime_meta_kv_request_elapsed_bucket))` | `timeseries` | Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads. | `prometheus` | `s` | `{{pod}}-{{op}} p99` |
|
||||||
|
| Rate of meta KV Ops | `rate(greptime_meta_kv_request_elapsed_count[$__rate_interval])` | `timeseries` | Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads. | `prometheus` | `none` | `{{pod}}-{{op}} p99` |
|
||||||
|
| DDL Latency | `histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_tables_bucket))`<br/>`histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_table))`<br/>`histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_view))`<br/>`histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_flow))`<br/>`histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_drop_table))`<br/>`histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_alter_table))` | `timeseries` | Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads. | `prometheus` | `s` | `CreateLogicalTables-{{step}} p90` |
|
||||||
|
# Flownode
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Flow Ingest / Output Rate | `sum by(instance, pod, direction) (rate(greptime_flow_processed_rows[$__rate_interval]))` | `timeseries` | Flow Ingest / Output Rate. | `prometheus` | -- | `[{{pod}}]-[{{instance}}]-[{{direction}}]` |
|
||||||
|
| Flow Ingest Latency | `histogram_quantile(0.95, sum(rate(greptime_flow_insert_elapsed_bucket[$__rate_interval])) by (le, instance, pod))`<br/>`histogram_quantile(0.99, sum(rate(greptime_flow_insert_elapsed_bucket[$__rate_interval])) by (le, instance, pod))` | `timeseries` | Flow Ingest Latency. | `prometheus` | -- | `[{{instance}}]-[{{pod}}]-p95` |
|
||||||
|
| Flow Operation Latency | `histogram_quantile(0.95, sum(rate(greptime_flow_processing_time_bucket[$__rate_interval])) by (le,instance,pod,type))`<br/>`histogram_quantile(0.99, sum(rate(greptime_flow_processing_time_bucket[$__rate_interval])) by (le,instance,pod,type))` | `timeseries` | Flow Operation Latency. | `prometheus` | -- | `[{{instance}}]-[{{pod}}]-[{{type}}]-p95` |
|
||||||
|
| Flow Buffer Size per Instance | `greptime_flow_input_buf_size` | `timeseries` | Flow Buffer Size per Instance. | `prometheus` | -- | `[{{instance}}]-[{{pod}]` |
|
||||||
|
| Flow Processing Error per Instance | `sum by(instance,pod,code) (rate(greptime_flow_errors[$__rate_interval]))` | `timeseries` | Flow Processing Error per Instance. | `prometheus` | -- | `[{{instance}}]-[{{pod}}]-[{{code}}]` |
|
||||||
943
grafana/dashboards/metrics/cluster/dashboard.yaml
Normal file
943
grafana/dashboards/metrics/cluster/dashboard.yaml
Normal file
@@ -0,0 +1,943 @@
|
|||||||
|
groups:
|
||||||
|
- title: Overview
|
||||||
|
panels:
|
||||||
|
- title: Uptime
|
||||||
|
type: stat
|
||||||
|
description: The start time of GreptimeDB.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: time() - process_start_time_seconds
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: __auto
|
||||||
|
- title: Version
|
||||||
|
type: stat
|
||||||
|
description: GreptimeDB version.
|
||||||
|
queries:
|
||||||
|
- expr: SELECT pkg_version FROM information_schema.build_info
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Total Ingestion Rate
|
||||||
|
type: stat
|
||||||
|
description: Total ingestion rate.
|
||||||
|
unit: rowsps
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(greptime_table_operator_ingest_rows[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: __auto
|
||||||
|
- title: Total Storage Size
|
||||||
|
type: stat
|
||||||
|
description: Total number of data file size.
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: select SUM(disk_size) from information_schema.region_statistics;
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Total Rows
|
||||||
|
type: stat
|
||||||
|
description: Total number of data rows in the cluster. Calculated by sum of rows from each region.
|
||||||
|
unit: sishort
|
||||||
|
queries:
|
||||||
|
- expr: select SUM(region_rows) from information_schema.region_statistics;
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Deployment
|
||||||
|
type: stat
|
||||||
|
description: The deployment topology of GreptimeDB.
|
||||||
|
queries:
|
||||||
|
- expr: SELECT count(*) as datanode FROM information_schema.cluster_info WHERE peer_type = 'DATANODE';
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT count(*) as frontend FROM information_schema.cluster_info WHERE peer_type = 'FRONTEND';
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT count(*) as metasrv FROM information_schema.cluster_info WHERE peer_type = 'METASRV';
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT count(*) as flownode FROM information_schema.cluster_info WHERE peer_type = 'FLOWNODE';
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Database Resources
|
||||||
|
type: stat
|
||||||
|
description: The number of the key resources in GreptimeDB.
|
||||||
|
queries:
|
||||||
|
- expr: SELECT COUNT(*) as databases FROM information_schema.schemata WHERE schema_name NOT IN ('greptime_private', 'information_schema')
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT COUNT(*) as tables FROM information_schema.tables WHERE table_schema != 'information_schema'
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT COUNT(region_id) as regions FROM information_schema.region_peers
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT COUNT(*) as flows FROM information_schema.flows
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Data Size
|
||||||
|
type: stat
|
||||||
|
description: The data size of wal/index/manifest in the GreptimeDB.
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: SELECT SUM(memtable_size) * 0.42825 as WAL FROM information_schema.region_statistics;
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT SUM(index_size) as index FROM information_schema.region_statistics;
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT SUM(manifest_size) as manifest FROM information_schema.region_statistics;
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Ingestion
|
||||||
|
panels:
|
||||||
|
- title: Total Ingestion Rate
|
||||||
|
type: timeseries
|
||||||
|
description: |
|
||||||
|
Total ingestion rate.
|
||||||
|
|
||||||
|
Here we listed 3 primary protocols:
|
||||||
|
|
||||||
|
- Prometheus remote write
|
||||||
|
- Greptime's gRPC API (when using our ingest SDK)
|
||||||
|
- Log ingestion http API
|
||||||
|
unit: rowsps
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(greptime_table_operator_ingest_rows{instance=~"$frontend"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: ingestion
|
||||||
|
- title: Ingestion Rate by Type
|
||||||
|
type: timeseries
|
||||||
|
description: |
|
||||||
|
Total ingestion rate.
|
||||||
|
|
||||||
|
Here we listed 3 primary protocols:
|
||||||
|
|
||||||
|
- Prometheus remote write
|
||||||
|
- Greptime's gRPC API (when using our ingest SDK)
|
||||||
|
- Log ingestion http API
|
||||||
|
unit: rowsps
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(greptime_servers_http_logs_ingestion_counter[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: http-logs
|
||||||
|
- expr: sum(rate(greptime_servers_prometheus_remote_write_samples[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: prometheus-remote-write
|
||||||
|
- title: Queries
|
||||||
|
panels:
|
||||||
|
- title: Total Query Rate
|
||||||
|
type: timeseries
|
||||||
|
description: |-
|
||||||
|
Total rate of query API calls by protocol. This metric is collected from frontends.
|
||||||
|
|
||||||
|
Here we listed 3 main protocols:
|
||||||
|
- MySQL
|
||||||
|
- Postgres
|
||||||
|
- Prometheus API
|
||||||
|
|
||||||
|
Note that there are some other minor query APIs like /sql are not included
|
||||||
|
unit: reqps
|
||||||
|
queries:
|
||||||
|
- expr: sum (rate(greptime_servers_mysql_query_elapsed_count{instance=~"$frontend"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: mysql
|
||||||
|
- expr: sum (rate(greptime_servers_postgres_query_elapsed_count{instance=~"$frontend"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: pg
|
||||||
|
- expr: sum (rate(greptime_servers_http_promql_elapsed_counte{instance=~"$frontend"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: promql
|
||||||
|
- title: Resources
|
||||||
|
panels:
|
||||||
|
- title: Datanode Memory per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current memory usage by instance
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: sum(process_resident_memory_bytes{instance=~"$datanode"}) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{ pod }}]'
|
||||||
|
- title: Datanode CPU Usage per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current cpu usage by instance
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(process_cpu_seconds_total{instance=~"$datanode"}[$__rate_interval]) * 1000) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]'
|
||||||
|
- title: Frontend Memory per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current memory usage by instance
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: sum(process_resident_memory_bytes{instance=~"$frontend"}) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]'
|
||||||
|
- title: Frontend CPU Usage per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current cpu usage by instance
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(process_cpu_seconds_total{instance=~"$frontend"}[$__rate_interval]) * 1000) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]-cpu'
|
||||||
|
- title: Metasrv Memory per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current memory usage by instance
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: sum(process_resident_memory_bytes{instance=~"$metasrv"}) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]-resident'
|
||||||
|
- title: Metasrv CPU Usage per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current cpu usage by instance
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(process_cpu_seconds_total{instance=~"$metasrv"}[$__rate_interval]) * 1000) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]'
|
||||||
|
- title: Flownode Memory per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current memory usage by instance
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: sum(process_resident_memory_bytes{instance=~"$flownode"}) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]'
|
||||||
|
- title: Flownode CPU Usage per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current cpu usage by instance
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(process_cpu_seconds_total{instance=~"$flownode"}[$__rate_interval]) * 1000) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]'
|
||||||
|
- title: Frontend Requests
|
||||||
|
panels:
|
||||||
|
- title: HTTP QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: HTTP QPS per Instance.
|
||||||
|
unit: reqps
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, path, method, code) (rate(greptime_servers_http_requests_elapsed_count{instance=~"$frontend",path!~"/health|/metrics"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]'
|
||||||
|
- title: HTTP P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: HTTP P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, path, method, code) (rate(greptime_servers_http_requests_elapsed_bucket{instance=~"$frontend",path!~"/health|/metrics"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99'
|
||||||
|
- title: gRPC QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: gRPC QPS per Instance.
|
||||||
|
unit: reqps
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, path, code) (rate(greptime_servers_grpc_requests_elapsed_count{instance=~"$frontend"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{path}}]-[{{code}}]'
|
||||||
|
- title: gRPC P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: gRPC P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, path, code) (rate(greptime_servers_grpc_requests_elapsed_bucket{instance=~"$frontend"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99'
|
||||||
|
- title: MySQL QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: MySQL QPS per Instance.
|
||||||
|
unit: reqps
|
||||||
|
queries:
|
||||||
|
- expr: sum by(pod, instance)(rate(greptime_servers_mysql_query_elapsed_count{instance=~"$frontend"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: MySQL P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: MySQL P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(pod, instance, le) (rate(greptime_servers_mysql_query_elapsed_bucket{instance=~"$frontend"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]-p99'
|
||||||
|
- title: PostgreSQL QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: PostgreSQL QPS per Instance.
|
||||||
|
unit: reqps
|
||||||
|
queries:
|
||||||
|
- expr: sum by(pod, instance)(rate(greptime_servers_postgres_query_elapsed_count{instance=~"$frontend"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: PostgreSQL P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: PostgreSQL P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(pod,instance,le) (rate(greptime_servers_postgres_query_elapsed_bucket{instance=~"$frontend"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-p99'
|
||||||
|
- title: Frontend to Datanode
|
||||||
|
panels:
|
||||||
|
- title: Ingest Rows per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Ingestion rate by row as in each frontend
|
||||||
|
unit: rowsps
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod)(rate(greptime_table_operator_ingest_rows{instance=~"$frontend"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Region Call QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Region Call QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, request_type) (rate(greptime_grpc_region_request_count{instance=~"$frontend"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{request_type}}]'
|
||||||
|
- title: Region Call P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Region Call P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, request_type) (rate(greptime_grpc_region_request_bucket{instance=~"$frontend"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{request_type}}]'
|
||||||
|
- title: 'Frontend Handle Bulk Insert Elapsed Time '
|
||||||
|
type: timeseries
|
||||||
|
description: Per-stage time for frontend to handle bulk insert requests
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, stage) (rate(greptime_table_operator_handle_bulk_insert_sum[$__rate_interval]))/sum by(instance, pod, stage) (rate(greptime_table_operator_handle_bulk_insert_count[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-AVG'
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, stage, le) (rate(greptime_table_operator_handle_bulk_insert_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-P95'
|
||||||
|
- title: Mito Engine
|
||||||
|
panels:
|
||||||
|
- title: Request OPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Request QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, type) (rate(greptime_mito_handle_request_elapsed_count{instance=~"$datanode"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{type}}]'
|
||||||
|
- title: Request P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Request P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, type) (rate(greptime_mito_handle_request_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{type}}]'
|
||||||
|
- title: Write Buffer per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Write Buffer per Instance.
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: greptime_mito_write_buffer_bytes{instance=~"$datanode"}
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Write Rows per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Ingestion size by row counts.
|
||||||
|
unit: rowsps
|
||||||
|
queries:
|
||||||
|
- expr: sum by (instance, pod) (rate(greptime_mito_write_rows_total{instance=~"$datanode"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Flush OPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Flush QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, reason) (rate(greptime_mito_flush_requests_total{instance=~"$datanode"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{reason}}]'
|
||||||
|
- title: Write Stall per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Write Stall per Instance.
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod) (greptime_mito_write_stall_total{instance=~"$datanode"})
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Read Stage OPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Read Stage OPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod) (rate(greptime_mito_read_stage_elapsed_count{instance=~"$datanode", stage="total"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Read Stage P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Read Stage P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_read_stage_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]'
|
||||||
|
- title: Write Stage P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Write Stage P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_write_stage_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]'
|
||||||
|
- title: Compaction OPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Compaction OPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod) (rate(greptime_mito_compaction_total_elapsed_count{instance=~"$datanode"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{pod}}]'
|
||||||
|
- title: Compaction Elapsed Time per Instance by Stage
|
||||||
|
type: timeseries
|
||||||
|
description: Compaction latency by stage
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_compaction_stage_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-p99'
|
||||||
|
- expr: sum by(instance, pod, stage) (rate(greptime_mito_compaction_stage_elapsed_sum{instance=~"$datanode"}[$__rate_interval]))/sum by(instance, pod, stage) (rate(greptime_mito_compaction_stage_elapsed_count{instance=~"$datanode"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-avg'
|
||||||
|
- title: Compaction P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Compaction P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le,stage) (rate(greptime_mito_compaction_total_elapsed_bucket{instance=~"$datanode"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-compaction'
|
||||||
|
- title: WAL write size
|
||||||
|
type: timeseries
|
||||||
|
description: Write-ahead logs write size as bytes. This chart includes stats of p95 and p99 size by instance, total WAL write rate.
|
||||||
|
unit: bytes
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.95, sum by(le,instance, pod) (rate(raft_engine_write_size_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-req-size-p95'
|
||||||
|
- expr: histogram_quantile(0.99, sum by(le,instance,pod) (rate(raft_engine_write_size_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-req-size-p99'
|
||||||
|
- expr: sum by (instance, pod)(rate(raft_engine_write_size_sum[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-throughput'
|
||||||
|
- title: Cached Bytes per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Cached Bytes per Instance.
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: greptime_mito_cache_bytes{instance=~"$datanode"}
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{type}}]'
|
||||||
|
- title: Inflight Compaction
|
||||||
|
type: timeseries
|
||||||
|
description: Ongoing compaction task count
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: greptime_mito_inflight_compaction_count
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: WAL sync duration seconds
|
||||||
|
type: timeseries
|
||||||
|
description: Raft engine (local disk) log store sync latency, p99
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(le, type, node, instance, pod) (rate(raft_engine_sync_log_duration_seconds_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-p99'
|
||||||
|
- title: Log Store op duration seconds
|
||||||
|
type: timeseries
|
||||||
|
description: Write-ahead log operations latency at p99
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(le,logstore,optype,instance, pod) (rate(greptime_logstore_op_elapsed_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{logstore}}]-[{{optype}}]-p99'
|
||||||
|
- title: Inflight Flush
|
||||||
|
type: timeseries
|
||||||
|
description: Ongoing flush task count
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: greptime_mito_inflight_flush_count
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Compaction Input/Output Bytes
|
||||||
|
type: timeseries
|
||||||
|
description: Compaction oinput output bytes
|
||||||
|
unit: bytes
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod) (greptime_mito_compaction_input_bytes)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-input'
|
||||||
|
- expr: sum by(instance, pod) (greptime_mito_compaction_output_bytes)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-output'
|
||||||
|
- title: Region Worker Handle Bulk Insert Requests
|
||||||
|
type: timeseries
|
||||||
|
description: Per-stage elapsed time for region worker to handle bulk insert region requests.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.95, sum by(le,instance, stage, pod) (rate(greptime_region_worker_handle_write_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-P95'
|
||||||
|
- expr: sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_sum[$__rate_interval]))/sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_count[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-AVG'
|
||||||
|
- title: Region Worker Convert Requests
|
||||||
|
type: timeseries
|
||||||
|
description: Per-stage elapsed time for region worker to decode requests.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.95, sum by(le, instance, stage, pod) (rate(greptime_datanode_convert_region_request_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-P95'
|
||||||
|
- expr: sum by(le,instance, stage, pod) (rate(greptime_datanode_convert_region_request_sum[$__rate_interval]))/sum by(le,instance, stage, pod) (rate(greptime_datanode_convert_region_request_count[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-AVG'
|
||||||
|
- title: OpenDAL
|
||||||
|
panels:
|
||||||
|
- title: QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme, operation) (rate(opendal_operation_duration_seconds_count{instance=~"$datanode"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]'
|
||||||
|
- title: Read QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Read QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{instance=~"$datanode", operation="read"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]'
|
||||||
|
- title: Read P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Read P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{instance=~"$datanode",operation="read"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-{{scheme}}'
|
||||||
|
- title: Write QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Write QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{instance=~"$datanode", operation="write"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-{{scheme}}'
|
||||||
|
- title: Write P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Write P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{instance=~"$datanode", operation="write"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]'
|
||||||
|
- title: List QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: List QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{instance=~"$datanode", operation="list"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]'
|
||||||
|
- title: List P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: List P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{instance=~"$datanode", operation="list"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]'
|
||||||
|
- title: Other Requests per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Other Requests per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme, operation) (rate(opendal_operation_duration_seconds_count{instance=~"$datanode",operation!~"read|write|list|stat"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]'
|
||||||
|
- title: Other Request P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Other Request P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, scheme, operation) (rate(opendal_operation_duration_seconds_bucket{instance=~"$datanode", operation!~"read|write|list"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]'
|
||||||
|
- title: Opendal traffic
|
||||||
|
type: timeseries
|
||||||
|
description: Total traffic as in bytes by instance and operation
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme, operation) (rate(opendal_operation_bytes_sum{instance=~"$datanode"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]'
|
||||||
|
- title: OpenDAL errors per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: OpenDAL error counts per Instance.
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme, operation, error) (rate(opendal_operation_errors_total{instance=~"$datanode", error!="NotFound"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]-[{{error}}]'
|
||||||
|
- title: Metasrv
|
||||||
|
panels:
|
||||||
|
- title: Region migration datanode
|
||||||
|
type: status-history
|
||||||
|
description: Counter of region migration by source and destination
|
||||||
|
queries:
|
||||||
|
- expr: greptime_meta_region_migration_stat{datanode_type="src"}
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: from-datanode-{{datanode_id}}
|
||||||
|
- expr: greptime_meta_region_migration_stat{datanode_type="desc"}
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: to-datanode-{{datanode_id}}
|
||||||
|
- title: Region migration error
|
||||||
|
type: timeseries
|
||||||
|
description: Counter of region migration error
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: greptime_meta_region_migration_error
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}}-{{state}}-{{error_type}}'
|
||||||
|
- title: Datanode load
|
||||||
|
type: timeseries
|
||||||
|
description: Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads.
|
||||||
|
unit: binBps
|
||||||
|
queries:
|
||||||
|
- expr: greptime_datanode_load
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: Datanode-{{datanode_id}}-writeload
|
||||||
|
- title: Rate of SQL Executions (RDS)
|
||||||
|
type: timeseries
|
||||||
|
description: Displays the rate of SQL executions processed by the Meta service using the RDS backend.
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: rate(greptime_meta_rds_pg_sql_execute_elapsed_ms_count[$__rate_interval])
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}} {{op}} {{type}} {{result}} '
|
||||||
|
- title: SQL Execution Latency (RDS)
|
||||||
|
type: timeseries
|
||||||
|
description: 'Measures the response time of SQL executions via the RDS backend. '
|
||||||
|
unit: ms
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.90, sum by(pod, op, type, result, le) (rate(greptime_meta_rds_pg_sql_execute_elapsed_ms_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}} {{op}} {{type}} {{result}} p90'
|
||||||
|
- title: Handler Execution Latency
|
||||||
|
type: timeseries
|
||||||
|
description: |
|
||||||
|
Shows latency of Meta handlers by pod and handler name, useful for monitoring handler performance and detecting latency spikes.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: |-
|
||||||
|
histogram_quantile(0.90, sum by(pod, le, name) (
|
||||||
|
rate(greptime_meta_handler_execute_bucket[$__rate_interval])
|
||||||
|
))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}} {{name}} p90'
|
||||||
|
- title: Heartbeat Packet Size
|
||||||
|
type: timeseries
|
||||||
|
description: |
|
||||||
|
Shows p90 heartbeat message sizes, helping track network usage and identify anomalies in heartbeat payload.
|
||||||
|
unit: bytes
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.9, sum by(pod, le) (greptime_meta_heartbeat_stat_memory_size_bucket))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}}'
|
||||||
|
- title: Meta Heartbeat Receive Rate
|
||||||
|
type: timeseries
|
||||||
|
description: Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: rate(greptime_meta_heartbeat_rate[$__rate_interval])
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}}'
|
||||||
|
- title: Meta KV Ops Latency
|
||||||
|
type: timeseries
|
||||||
|
description: Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(pod, le, op, target) (greptime_meta_kv_request_elapsed_bucket))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}}-{{op}} p99'
|
||||||
|
- title: Rate of meta KV Ops
|
||||||
|
type: timeseries
|
||||||
|
description: Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads.
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: rate(greptime_meta_kv_request_elapsed_count[$__rate_interval])
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}}-{{op}} p99'
|
||||||
|
- title: DDL Latency
|
||||||
|
type: timeseries
|
||||||
|
description: Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_tables_bucket))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: CreateLogicalTables-{{step}} p90
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_table))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: CreateTable-{{step}} p90
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_view))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: CreateView-{{step}} p90
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_flow))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: CreateFlow-{{step}} p90
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_drop_table))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: DropTable-{{step}} p90
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_alter_table))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: AlterTable-{{step}} p90
|
||||||
|
- title: Flownode
|
||||||
|
panels:
|
||||||
|
- title: Flow Ingest / Output Rate
|
||||||
|
type: timeseries
|
||||||
|
description: Flow Ingest / Output Rate.
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, direction) (rate(greptime_flow_processed_rows[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{pod}}]-[{{instance}}]-[{{direction}}]'
|
||||||
|
- title: Flow Ingest Latency
|
||||||
|
type: timeseries
|
||||||
|
description: Flow Ingest Latency.
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.95, sum(rate(greptime_flow_insert_elapsed_bucket[$__rate_interval])) by (le, instance, pod))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-p95'
|
||||||
|
- expr: histogram_quantile(0.99, sum(rate(greptime_flow_insert_elapsed_bucket[$__rate_interval])) by (le, instance, pod))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-p99'
|
||||||
|
- title: Flow Operation Latency
|
||||||
|
type: timeseries
|
||||||
|
description: Flow Operation Latency.
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.95, sum(rate(greptime_flow_processing_time_bucket[$__rate_interval])) by (le,instance,pod,type))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{type}}]-p95'
|
||||||
|
- expr: histogram_quantile(0.99, sum(rate(greptime_flow_processing_time_bucket[$__rate_interval])) by (le,instance,pod,type))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{type}}]-p99'
|
||||||
|
- title: Flow Buffer Size per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Flow Buffer Size per Instance.
|
||||||
|
queries:
|
||||||
|
- expr: greptime_flow_input_buf_size
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}]'
|
||||||
|
- title: Flow Processing Error per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Flow Processing Error per Instance.
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance,pod,code) (rate(greptime_flow_errors[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{code}}]'
|
||||||
8618
grafana/dashboards/metrics/standalone/dashboard.json
Normal file
8618
grafana/dashboards/metrics/standalone/dashboard.json
Normal file
File diff suppressed because it is too large
Load Diff
111
grafana/dashboards/metrics/standalone/dashboard.md
Normal file
111
grafana/dashboards/metrics/standalone/dashboard.md
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# Overview
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Uptime | `time() - process_start_time_seconds` | `stat` | The start time of GreptimeDB. | `prometheus` | `s` | `__auto` |
|
||||||
|
| Version | `SELECT pkg_version FROM information_schema.build_info` | `stat` | GreptimeDB version. | `mysql` | -- | -- |
|
||||||
|
| Total Ingestion Rate | `sum(rate(greptime_table_operator_ingest_rows[$__rate_interval]))` | `stat` | Total ingestion rate. | `prometheus` | `rowsps` | `__auto` |
|
||||||
|
| Total Storage Size | `select SUM(disk_size) from information_schema.region_statistics;` | `stat` | Total number of data file size. | `mysql` | `decbytes` | -- |
|
||||||
|
| Total Rows | `select SUM(region_rows) from information_schema.region_statistics;` | `stat` | Total number of data rows in the cluster. Calculated by sum of rows from each region. | `mysql` | `sishort` | -- |
|
||||||
|
| Deployment | `SELECT count(*) as datanode FROM information_schema.cluster_info WHERE peer_type = 'DATANODE';`<br/>`SELECT count(*) as frontend FROM information_schema.cluster_info WHERE peer_type = 'FRONTEND';`<br/>`SELECT count(*) as metasrv FROM information_schema.cluster_info WHERE peer_type = 'METASRV';`<br/>`SELECT count(*) as flownode FROM information_schema.cluster_info WHERE peer_type = 'FLOWNODE';` | `stat` | The deployment topology of GreptimeDB. | `mysql` | -- | -- |
|
||||||
|
| Database Resources | `SELECT COUNT(*) as databases FROM information_schema.schemata WHERE schema_name NOT IN ('greptime_private', 'information_schema')`<br/>`SELECT COUNT(*) as tables FROM information_schema.tables WHERE table_schema != 'information_schema'`<br/>`SELECT COUNT(region_id) as regions FROM information_schema.region_peers`<br/>`SELECT COUNT(*) as flows FROM information_schema.flows` | `stat` | The number of the key resources in GreptimeDB. | `mysql` | -- | -- |
|
||||||
|
| Data Size | `SELECT SUM(memtable_size) * 0.42825 as WAL FROM information_schema.region_statistics;`<br/>`SELECT SUM(index_size) as index FROM information_schema.region_statistics;`<br/>`SELECT SUM(manifest_size) as manifest FROM information_schema.region_statistics;` | `stat` | The data size of wal/index/manifest in the GreptimeDB. | `mysql` | `decbytes` | -- |
|
||||||
|
# Ingestion
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Total Ingestion Rate | `sum(rate(greptime_table_operator_ingest_rows{}[$__rate_interval]))` | `timeseries` | Total ingestion rate.<br/><br/>Here we listed 3 primary protocols:<br/><br/>- Prometheus remote write<br/>- Greptime's gRPC API (when using our ingest SDK)<br/>- Log ingestion http API<br/> | `prometheus` | `rowsps` | `ingestion` |
|
||||||
|
| Ingestion Rate by Type | `sum(rate(greptime_servers_http_logs_ingestion_counter[$__rate_interval]))`<br/>`sum(rate(greptime_servers_prometheus_remote_write_samples[$__rate_interval]))` | `timeseries` | Total ingestion rate.<br/><br/>Here we listed 3 primary protocols:<br/><br/>- Prometheus remote write<br/>- Greptime's gRPC API (when using our ingest SDK)<br/>- Log ingestion http API<br/> | `prometheus` | `rowsps` | `http-logs` |
|
||||||
|
# Queries
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Total Query Rate | `sum (rate(greptime_servers_mysql_query_elapsed_count{}[$__rate_interval]))`<br/>`sum (rate(greptime_servers_postgres_query_elapsed_count{}[$__rate_interval]))`<br/>`sum (rate(greptime_servers_http_promql_elapsed_counte{}[$__rate_interval]))` | `timeseries` | Total rate of query API calls by protocol. This metric is collected from frontends.<br/><br/>Here we listed 3 main protocols:<br/>- MySQL<br/>- Postgres<br/>- Prometheus API<br/><br/>Note that there are some other minor query APIs like /sql are not included | `prometheus` | `reqps` | `mysql` |
|
||||||
|
# Resources
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Datanode Memory per Instance | `sum(process_resident_memory_bytes{}) by (instance, pod)` | `timeseries` | Current memory usage by instance | `prometheus` | `decbytes` | `[{{instance}}]-[{{ pod }}]` |
|
||||||
|
| Datanode CPU Usage per Instance | `sum(rate(process_cpu_seconds_total{}[$__rate_interval]) * 1000) by (instance, pod)` | `timeseries` | Current cpu usage by instance | `prometheus` | `none` | `[{{ instance }}]-[{{ pod }}]` |
|
||||||
|
| Frontend Memory per Instance | `sum(process_resident_memory_bytes{}) by (instance, pod)` | `timeseries` | Current memory usage by instance | `prometheus` | `decbytes` | `[{{ instance }}]-[{{ pod }}]` |
|
||||||
|
| Frontend CPU Usage per Instance | `sum(rate(process_cpu_seconds_total{}[$__rate_interval]) * 1000) by (instance, pod)` | `timeseries` | Current cpu usage by instance | `prometheus` | `none` | `[{{ instance }}]-[{{ pod }}]-cpu` |
|
||||||
|
| Metasrv Memory per Instance | `sum(process_resident_memory_bytes{}) by (instance, pod)` | `timeseries` | Current memory usage by instance | `prometheus` | `decbytes` | `[{{ instance }}]-[{{ pod }}]-resident` |
|
||||||
|
| Metasrv CPU Usage per Instance | `sum(rate(process_cpu_seconds_total{}[$__rate_interval]) * 1000) by (instance, pod)` | `timeseries` | Current cpu usage by instance | `prometheus` | `none` | `[{{ instance }}]-[{{ pod }}]` |
|
||||||
|
| Flownode Memory per Instance | `sum(process_resident_memory_bytes{}) by (instance, pod)` | `timeseries` | Current memory usage by instance | `prometheus` | `decbytes` | `[{{ instance }}]-[{{ pod }}]` |
|
||||||
|
| Flownode CPU Usage per Instance | `sum(rate(process_cpu_seconds_total{}[$__rate_interval]) * 1000) by (instance, pod)` | `timeseries` | Current cpu usage by instance | `prometheus` | `none` | `[{{ instance }}]-[{{ pod }}]` |
|
||||||
|
# Frontend Requests
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| HTTP QPS per Instance | `sum by(instance, pod, path, method, code) (rate(greptime_servers_http_requests_elapsed_count{path!~"/health\|/metrics"}[$__rate_interval]))` | `timeseries` | HTTP QPS per Instance. | `prometheus` | `reqps` | `[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]` |
|
||||||
|
| HTTP P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, path, method, code) (rate(greptime_servers_http_requests_elapsed_bucket{path!~"/health\|/metrics"}[$__rate_interval])))` | `timeseries` | HTTP P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99` |
|
||||||
|
| gRPC QPS per Instance | `sum by(instance, pod, path, code) (rate(greptime_servers_grpc_requests_elapsed_count{}[$__rate_interval]))` | `timeseries` | gRPC QPS per Instance. | `prometheus` | `reqps` | `[{{instance}}]-[{{pod}}]-[{{path}}]-[{{code}}]` |
|
||||||
|
| gRPC P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, path, code) (rate(greptime_servers_grpc_requests_elapsed_bucket{}[$__rate_interval])))` | `timeseries` | gRPC P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99` |
|
||||||
|
| MySQL QPS per Instance | `sum by(pod, instance)(rate(greptime_servers_mysql_query_elapsed_count{}[$__rate_interval]))` | `timeseries` | MySQL QPS per Instance. | `prometheus` | `reqps` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| MySQL P99 per Instance | `histogram_quantile(0.99, sum by(pod, instance, le) (rate(greptime_servers_mysql_query_elapsed_bucket{}[$__rate_interval])))` | `timeseries` | MySQL P99 per Instance. | `prometheus` | `s` | `[{{ instance }}]-[{{ pod }}]-p99` |
|
||||||
|
| PostgreSQL QPS per Instance | `sum by(pod, instance)(rate(greptime_servers_postgres_query_elapsed_count{}[$__rate_interval]))` | `timeseries` | PostgreSQL QPS per Instance. | `prometheus` | `reqps` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| PostgreSQL P99 per Instance | `histogram_quantile(0.99, sum by(pod,instance,le) (rate(greptime_servers_postgres_query_elapsed_bucket{}[$__rate_interval])))` | `timeseries` | PostgreSQL P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-p99` |
|
||||||
|
# Frontend to Datanode
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Ingest Rows per Instance | `sum by(instance, pod)(rate(greptime_table_operator_ingest_rows{}[$__rate_interval]))` | `timeseries` | Ingestion rate by row as in each frontend | `prometheus` | `rowsps` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Region Call QPS per Instance | `sum by(instance, pod, request_type) (rate(greptime_grpc_region_request_count{}[$__rate_interval]))` | `timeseries` | Region Call QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{request_type}}]` |
|
||||||
|
| Region Call P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, request_type) (rate(greptime_grpc_region_request_bucket{}[$__rate_interval])))` | `timeseries` | Region Call P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{request_type}}]` |
|
||||||
|
| Frontend Handle Bulk Insert Elapsed Time | `sum by(instance, pod, stage) (rate(greptime_table_operator_handle_bulk_insert_sum[$__rate_interval]))/sum by(instance, pod, stage) (rate(greptime_table_operator_handle_bulk_insert_count[$__rate_interval]))`<br/>`histogram_quantile(0.99, sum by(instance, pod, stage, le) (rate(greptime_table_operator_handle_bulk_insert_bucket[$__rate_interval])))` | `timeseries` | Per-stage time for frontend to handle bulk insert requests | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-AVG` |
|
||||||
|
# Mito Engine
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Request OPS per Instance | `sum by(instance, pod, type) (rate(greptime_mito_handle_request_elapsed_count{}[$__rate_interval]))` | `timeseries` | Request QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{type}}]` |
|
||||||
|
| Request P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, type) (rate(greptime_mito_handle_request_elapsed_bucket{}[$__rate_interval])))` | `timeseries` | Request P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{type}}]` |
|
||||||
|
| Write Buffer per Instance | `greptime_mito_write_buffer_bytes{}` | `timeseries` | Write Buffer per Instance. | `prometheus` | `decbytes` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Write Rows per Instance | `sum by (instance, pod) (rate(greptime_mito_write_rows_total{}[$__rate_interval]))` | `timeseries` | Ingestion size by row counts. | `prometheus` | `rowsps` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Flush OPS per Instance | `sum by(instance, pod, reason) (rate(greptime_mito_flush_requests_total{}[$__rate_interval]))` | `timeseries` | Flush QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{reason}}]` |
|
||||||
|
| Write Stall per Instance | `sum by(instance, pod) (greptime_mito_write_stall_total{})` | `timeseries` | Write Stall per Instance. | `prometheus` | -- | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Read Stage OPS per Instance | `sum by(instance, pod) (rate(greptime_mito_read_stage_elapsed_count{ stage="total"}[$__rate_interval]))` | `timeseries` | Read Stage OPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Read Stage P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_read_stage_elapsed_bucket{}[$__rate_interval])))` | `timeseries` | Read Stage P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]` |
|
||||||
|
| Write Stage P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_write_stage_elapsed_bucket{}[$__rate_interval])))` | `timeseries` | Write Stage P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]` |
|
||||||
|
| Compaction OPS per Instance | `sum by(instance, pod) (rate(greptime_mito_compaction_total_elapsed_count{}[$__rate_interval]))` | `timeseries` | Compaction OPS per Instance. | `prometheus` | `ops` | `[{{ instance }}]-[{{pod}}]` |
|
||||||
|
| Compaction Elapsed Time per Instance by Stage | `histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_compaction_stage_elapsed_bucket{}[$__rate_interval])))`<br/>`sum by(instance, pod, stage) (rate(greptime_mito_compaction_stage_elapsed_sum{}[$__rate_interval]))/sum by(instance, pod, stage) (rate(greptime_mito_compaction_stage_elapsed_count{}[$__rate_interval]))` | `timeseries` | Compaction latency by stage | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-p99` |
|
||||||
|
| Compaction P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le,stage) (rate(greptime_mito_compaction_total_elapsed_bucket{}[$__rate_interval])))` | `timeseries` | Compaction P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-compaction` |
|
||||||
|
| WAL write size | `histogram_quantile(0.95, sum by(le,instance, pod) (rate(raft_engine_write_size_bucket[$__rate_interval])))`<br/>`histogram_quantile(0.99, sum by(le,instance,pod) (rate(raft_engine_write_size_bucket[$__rate_interval])))`<br/>`sum by (instance, pod)(rate(raft_engine_write_size_sum[$__rate_interval]))` | `timeseries` | Write-ahead logs write size as bytes. This chart includes stats of p95 and p99 size by instance, total WAL write rate. | `prometheus` | `bytes` | `[{{instance}}]-[{{pod}}]-req-size-p95` |
|
||||||
|
| Cached Bytes per Instance | `greptime_mito_cache_bytes{}` | `timeseries` | Cached Bytes per Instance. | `prometheus` | `decbytes` | `[{{instance}}]-[{{pod}}]-[{{type}}]` |
|
||||||
|
| Inflight Compaction | `greptime_mito_inflight_compaction_count` | `timeseries` | Ongoing compaction task count | `prometheus` | `none` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| WAL sync duration seconds | `histogram_quantile(0.99, sum by(le, type, node, instance, pod) (rate(raft_engine_sync_log_duration_seconds_bucket[$__rate_interval])))` | `timeseries` | Raft engine (local disk) log store sync latency, p99 | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-p99` |
|
||||||
|
| Log Store op duration seconds | `histogram_quantile(0.99, sum by(le,logstore,optype,instance, pod) (rate(greptime_logstore_op_elapsed_bucket[$__rate_interval])))` | `timeseries` | Write-ahead log operations latency at p99 | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{logstore}}]-[{{optype}}]-p99` |
|
||||||
|
| Inflight Flush | `greptime_mito_inflight_flush_count` | `timeseries` | Ongoing flush task count | `prometheus` | `none` | `[{{instance}}]-[{{pod}}]` |
|
||||||
|
| Compaction Input/Output Bytes | `sum by(instance, pod) (greptime_mito_compaction_input_bytes)`<br/>`sum by(instance, pod) (greptime_mito_compaction_output_bytes)` | `timeseries` | Compaction oinput output bytes | `prometheus` | `bytes` | `[{{instance}}]-[{{pod}}]-input` |
|
||||||
|
| Region Worker Handle Bulk Insert Requests | `histogram_quantile(0.95, sum by(le,instance, stage, pod) (rate(greptime_region_worker_handle_write_bucket[$__rate_interval])))`<br/>`sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_sum[$__rate_interval]))/sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_count[$__rate_interval]))` | `timeseries` | Per-stage elapsed time for region worker to handle bulk insert region requests. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-P95` |
|
||||||
|
| Region Worker Convert Requests | `histogram_quantile(0.95, sum by(le, instance, stage, pod) (rate(greptime_datanode_convert_region_request_bucket[$__rate_interval])))`<br/>`sum by(le,instance, stage, pod) (rate(greptime_datanode_convert_region_request_sum[$__rate_interval]))/sum by(le,instance, stage, pod) (rate(greptime_datanode_convert_region_request_count[$__rate_interval]))` | `timeseries` | Per-stage elapsed time for region worker to decode requests. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{stage}}]-P95` |
|
||||||
|
# OpenDAL
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| QPS per Instance | `sum by(instance, pod, scheme, operation) (rate(opendal_operation_duration_seconds_count{}[$__rate_interval]))` | `timeseries` | QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]` |
|
||||||
|
| Read QPS per Instance | `sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{ operation="read"}[$__rate_interval]))` | `timeseries` | Read QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]` |
|
||||||
|
| Read P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{operation="read"}[$__rate_interval])))` | `timeseries` | Read P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-{{scheme}}` |
|
||||||
|
| Write QPS per Instance | `sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{ operation="write"}[$__rate_interval]))` | `timeseries` | Write QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-{{scheme}}` |
|
||||||
|
| Write P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{ operation="write"}[$__rate_interval])))` | `timeseries` | Write P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]` |
|
||||||
|
| List QPS per Instance | `sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{ operation="list"}[$__rate_interval]))` | `timeseries` | List QPS per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]` |
|
||||||
|
| List P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{ operation="list"}[$__rate_interval])))` | `timeseries` | List P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]` |
|
||||||
|
| Other Requests per Instance | `sum by(instance, pod, scheme, operation) (rate(opendal_operation_duration_seconds_count{operation!~"read\|write\|list\|stat"}[$__rate_interval]))` | `timeseries` | Other Requests per Instance. | `prometheus` | `ops` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]` |
|
||||||
|
| Other Request P99 per Instance | `histogram_quantile(0.99, sum by(instance, pod, le, scheme, operation) (rate(opendal_operation_duration_seconds_bucket{ operation!~"read\|write\|list"}[$__rate_interval])))` | `timeseries` | Other Request P99 per Instance. | `prometheus` | `s` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]` |
|
||||||
|
| Opendal traffic | `sum by(instance, pod, scheme, operation) (rate(opendal_operation_bytes_sum{}[$__rate_interval]))` | `timeseries` | Total traffic as in bytes by instance and operation | `prometheus` | `decbytes` | `[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]` |
|
||||||
|
| OpenDAL errors per Instance | `sum by(instance, pod, scheme, operation, error) (rate(opendal_operation_errors_total{ error!="NotFound"}[$__rate_interval]))` | `timeseries` | OpenDAL error counts per Instance. | `prometheus` | -- | `[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]-[{{error}}]` |
|
||||||
|
# Metasrv
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Region migration datanode | `greptime_meta_region_migration_stat{datanode_type="src"}`<br/>`greptime_meta_region_migration_stat{datanode_type="desc"}` | `status-history` | Counter of region migration by source and destination | `prometheus` | -- | `from-datanode-{{datanode_id}}` |
|
||||||
|
| Region migration error | `greptime_meta_region_migration_error` | `timeseries` | Counter of region migration error | `prometheus` | `none` | `{{pod}}-{{state}}-{{error_type}}` |
|
||||||
|
| Datanode load | `greptime_datanode_load` | `timeseries` | Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads. | `prometheus` | `binBps` | `Datanode-{{datanode_id}}-writeload` |
|
||||||
|
| Rate of SQL Executions (RDS) | `rate(greptime_meta_rds_pg_sql_execute_elapsed_ms_count[$__rate_interval])` | `timeseries` | Displays the rate of SQL executions processed by the Meta service using the RDS backend. | `prometheus` | `none` | `{{pod}} {{op}} {{type}} {{result}} ` |
|
||||||
|
| SQL Execution Latency (RDS) | `histogram_quantile(0.90, sum by(pod, op, type, result, le) (rate(greptime_meta_rds_pg_sql_execute_elapsed_ms_bucket[$__rate_interval])))` | `timeseries` | Measures the response time of SQL executions via the RDS backend. | `prometheus` | `ms` | `{{pod}} {{op}} {{type}} {{result}} p90` |
|
||||||
|
| Handler Execution Latency | `histogram_quantile(0.90, sum by(pod, le, name) (
|
||||||
|
rate(greptime_meta_handler_execute_bucket[$__rate_interval])
|
||||||
|
))` | `timeseries` | Shows latency of Meta handlers by pod and handler name, useful for monitoring handler performance and detecting latency spikes.<br/> | `prometheus` | `s` | `{{pod}} {{name}} p90` |
|
||||||
|
| Heartbeat Packet Size | `histogram_quantile(0.9, sum by(pod, le) (greptime_meta_heartbeat_stat_memory_size_bucket))` | `timeseries` | Shows p90 heartbeat message sizes, helping track network usage and identify anomalies in heartbeat payload.<br/> | `prometheus` | `bytes` | `{{pod}}` |
|
||||||
|
| Meta Heartbeat Receive Rate | `rate(greptime_meta_heartbeat_rate[$__rate_interval])` | `timeseries` | Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads. | `prometheus` | `s` | `{{pod}}` |
|
||||||
|
| Meta KV Ops Latency | `histogram_quantile(0.99, sum by(pod, le, op, target) (greptime_meta_kv_request_elapsed_bucket))` | `timeseries` | Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads. | `prometheus` | `s` | `{{pod}}-{{op}} p99` |
|
||||||
|
| Rate of meta KV Ops | `rate(greptime_meta_kv_request_elapsed_count[$__rate_interval])` | `timeseries` | Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads. | `prometheus` | `none` | `{{pod}}-{{op}} p99` |
|
||||||
|
| DDL Latency | `histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_tables_bucket))`<br/>`histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_table))`<br/>`histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_view))`<br/>`histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_flow))`<br/>`histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_drop_table))`<br/>`histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_alter_table))` | `timeseries` | Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads. | `prometheus` | `s` | `CreateLogicalTables-{{step}} p90` |
|
||||||
|
# Flownode
|
||||||
|
| Title | Query | Type | Description | Datasource | Unit | Legend Format |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Flow Ingest / Output Rate | `sum by(instance, pod, direction) (rate(greptime_flow_processed_rows[$__rate_interval]))` | `timeseries` | Flow Ingest / Output Rate. | `prometheus` | -- | `[{{pod}}]-[{{instance}}]-[{{direction}}]` |
|
||||||
|
| Flow Ingest Latency | `histogram_quantile(0.95, sum(rate(greptime_flow_insert_elapsed_bucket[$__rate_interval])) by (le, instance, pod))`<br/>`histogram_quantile(0.99, sum(rate(greptime_flow_insert_elapsed_bucket[$__rate_interval])) by (le, instance, pod))` | `timeseries` | Flow Ingest Latency. | `prometheus` | -- | `[{{instance}}]-[{{pod}}]-p95` |
|
||||||
|
| Flow Operation Latency | `histogram_quantile(0.95, sum(rate(greptime_flow_processing_time_bucket[$__rate_interval])) by (le,instance,pod,type))`<br/>`histogram_quantile(0.99, sum(rate(greptime_flow_processing_time_bucket[$__rate_interval])) by (le,instance,pod,type))` | `timeseries` | Flow Operation Latency. | `prometheus` | -- | `[{{instance}}]-[{{pod}}]-[{{type}}]-p95` |
|
||||||
|
| Flow Buffer Size per Instance | `greptime_flow_input_buf_size` | `timeseries` | Flow Buffer Size per Instance. | `prometheus` | -- | `[{{instance}}]-[{{pod}]` |
|
||||||
|
| Flow Processing Error per Instance | `sum by(instance,pod,code) (rate(greptime_flow_errors[$__rate_interval]))` | `timeseries` | Flow Processing Error per Instance. | `prometheus` | -- | `[{{instance}}]-[{{pod}}]-[{{code}}]` |
|
||||||
943
grafana/dashboards/metrics/standalone/dashboard.yaml
Normal file
943
grafana/dashboards/metrics/standalone/dashboard.yaml
Normal file
@@ -0,0 +1,943 @@
|
|||||||
|
groups:
|
||||||
|
- title: Overview
|
||||||
|
panels:
|
||||||
|
- title: Uptime
|
||||||
|
type: stat
|
||||||
|
description: The start time of GreptimeDB.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: time() - process_start_time_seconds
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: __auto
|
||||||
|
- title: Version
|
||||||
|
type: stat
|
||||||
|
description: GreptimeDB version.
|
||||||
|
queries:
|
||||||
|
- expr: SELECT pkg_version FROM information_schema.build_info
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Total Ingestion Rate
|
||||||
|
type: stat
|
||||||
|
description: Total ingestion rate.
|
||||||
|
unit: rowsps
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(greptime_table_operator_ingest_rows[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: __auto
|
||||||
|
- title: Total Storage Size
|
||||||
|
type: stat
|
||||||
|
description: Total number of data file size.
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: select SUM(disk_size) from information_schema.region_statistics;
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Total Rows
|
||||||
|
type: stat
|
||||||
|
description: Total number of data rows in the cluster. Calculated by sum of rows from each region.
|
||||||
|
unit: sishort
|
||||||
|
queries:
|
||||||
|
- expr: select SUM(region_rows) from information_schema.region_statistics;
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Deployment
|
||||||
|
type: stat
|
||||||
|
description: The deployment topology of GreptimeDB.
|
||||||
|
queries:
|
||||||
|
- expr: SELECT count(*) as datanode FROM information_schema.cluster_info WHERE peer_type = 'DATANODE';
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT count(*) as frontend FROM information_schema.cluster_info WHERE peer_type = 'FRONTEND';
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT count(*) as metasrv FROM information_schema.cluster_info WHERE peer_type = 'METASRV';
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT count(*) as flownode FROM information_schema.cluster_info WHERE peer_type = 'FLOWNODE';
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Database Resources
|
||||||
|
type: stat
|
||||||
|
description: The number of the key resources in GreptimeDB.
|
||||||
|
queries:
|
||||||
|
- expr: SELECT COUNT(*) as databases FROM information_schema.schemata WHERE schema_name NOT IN ('greptime_private', 'information_schema')
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT COUNT(*) as tables FROM information_schema.tables WHERE table_schema != 'information_schema'
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT COUNT(region_id) as regions FROM information_schema.region_peers
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT COUNT(*) as flows FROM information_schema.flows
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Data Size
|
||||||
|
type: stat
|
||||||
|
description: The data size of wal/index/manifest in the GreptimeDB.
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: SELECT SUM(memtable_size) * 0.42825 as WAL FROM information_schema.region_statistics;
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT SUM(index_size) as index FROM information_schema.region_statistics;
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- expr: SELECT SUM(manifest_size) as manifest FROM information_schema.region_statistics;
|
||||||
|
datasource:
|
||||||
|
type: mysql
|
||||||
|
uid: ${information_schema}
|
||||||
|
- title: Ingestion
|
||||||
|
panels:
|
||||||
|
- title: Total Ingestion Rate
|
||||||
|
type: timeseries
|
||||||
|
description: |
|
||||||
|
Total ingestion rate.
|
||||||
|
|
||||||
|
Here we listed 3 primary protocols:
|
||||||
|
|
||||||
|
- Prometheus remote write
|
||||||
|
- Greptime's gRPC API (when using our ingest SDK)
|
||||||
|
- Log ingestion http API
|
||||||
|
unit: rowsps
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(greptime_table_operator_ingest_rows{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: ingestion
|
||||||
|
- title: Ingestion Rate by Type
|
||||||
|
type: timeseries
|
||||||
|
description: |
|
||||||
|
Total ingestion rate.
|
||||||
|
|
||||||
|
Here we listed 3 primary protocols:
|
||||||
|
|
||||||
|
- Prometheus remote write
|
||||||
|
- Greptime's gRPC API (when using our ingest SDK)
|
||||||
|
- Log ingestion http API
|
||||||
|
unit: rowsps
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(greptime_servers_http_logs_ingestion_counter[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: http-logs
|
||||||
|
- expr: sum(rate(greptime_servers_prometheus_remote_write_samples[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: prometheus-remote-write
|
||||||
|
- title: Queries
|
||||||
|
panels:
|
||||||
|
- title: Total Query Rate
|
||||||
|
type: timeseries
|
||||||
|
description: |-
|
||||||
|
Total rate of query API calls by protocol. This metric is collected from frontends.
|
||||||
|
|
||||||
|
Here we listed 3 main protocols:
|
||||||
|
- MySQL
|
||||||
|
- Postgres
|
||||||
|
- Prometheus API
|
||||||
|
|
||||||
|
Note that there are some other minor query APIs like /sql are not included
|
||||||
|
unit: reqps
|
||||||
|
queries:
|
||||||
|
- expr: sum (rate(greptime_servers_mysql_query_elapsed_count{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: mysql
|
||||||
|
- expr: sum (rate(greptime_servers_postgres_query_elapsed_count{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: pg
|
||||||
|
- expr: sum (rate(greptime_servers_http_promql_elapsed_counte{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: promql
|
||||||
|
- title: Resources
|
||||||
|
panels:
|
||||||
|
- title: Datanode Memory per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current memory usage by instance
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: sum(process_resident_memory_bytes{}) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{ pod }}]'
|
||||||
|
- title: Datanode CPU Usage per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current cpu usage by instance
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(process_cpu_seconds_total{}[$__rate_interval]) * 1000) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]'
|
||||||
|
- title: Frontend Memory per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current memory usage by instance
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: sum(process_resident_memory_bytes{}) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]'
|
||||||
|
- title: Frontend CPU Usage per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current cpu usage by instance
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(process_cpu_seconds_total{}[$__rate_interval]) * 1000) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]-cpu'
|
||||||
|
- title: Metasrv Memory per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current memory usage by instance
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: sum(process_resident_memory_bytes{}) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]-resident'
|
||||||
|
- title: Metasrv CPU Usage per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current cpu usage by instance
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(process_cpu_seconds_total{}[$__rate_interval]) * 1000) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]'
|
||||||
|
- title: Flownode Memory per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current memory usage by instance
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: sum(process_resident_memory_bytes{}) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]'
|
||||||
|
- title: Flownode CPU Usage per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Current cpu usage by instance
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: sum(rate(process_cpu_seconds_total{}[$__rate_interval]) * 1000) by (instance, pod)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]'
|
||||||
|
- title: Frontend Requests
|
||||||
|
panels:
|
||||||
|
- title: HTTP QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: HTTP QPS per Instance.
|
||||||
|
unit: reqps
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, path, method, code) (rate(greptime_servers_http_requests_elapsed_count{path!~"/health|/metrics"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]'
|
||||||
|
- title: HTTP P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: HTTP P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, path, method, code) (rate(greptime_servers_http_requests_elapsed_bucket{path!~"/health|/metrics"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99'
|
||||||
|
- title: gRPC QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: gRPC QPS per Instance.
|
||||||
|
unit: reqps
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, path, code) (rate(greptime_servers_grpc_requests_elapsed_count{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{path}}]-[{{code}}]'
|
||||||
|
- title: gRPC P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: gRPC P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, path, code) (rate(greptime_servers_grpc_requests_elapsed_bucket{}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{path}}]-[{{method}}]-[{{code}}]-p99'
|
||||||
|
- title: MySQL QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: MySQL QPS per Instance.
|
||||||
|
unit: reqps
|
||||||
|
queries:
|
||||||
|
- expr: sum by(pod, instance)(rate(greptime_servers_mysql_query_elapsed_count{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: MySQL P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: MySQL P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(pod, instance, le) (rate(greptime_servers_mysql_query_elapsed_bucket{}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{ pod }}]-p99'
|
||||||
|
- title: PostgreSQL QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: PostgreSQL QPS per Instance.
|
||||||
|
unit: reqps
|
||||||
|
queries:
|
||||||
|
- expr: sum by(pod, instance)(rate(greptime_servers_postgres_query_elapsed_count{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: PostgreSQL P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: PostgreSQL P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(pod,instance,le) (rate(greptime_servers_postgres_query_elapsed_bucket{}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-p99'
|
||||||
|
- title: Frontend to Datanode
|
||||||
|
panels:
|
||||||
|
- title: Ingest Rows per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Ingestion rate by row as in each frontend
|
||||||
|
unit: rowsps
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod)(rate(greptime_table_operator_ingest_rows{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Region Call QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Region Call QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, request_type) (rate(greptime_grpc_region_request_count{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{request_type}}]'
|
||||||
|
- title: Region Call P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Region Call P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, request_type) (rate(greptime_grpc_region_request_bucket{}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{request_type}}]'
|
||||||
|
- title: 'Frontend Handle Bulk Insert Elapsed Time '
|
||||||
|
type: timeseries
|
||||||
|
description: Per-stage time for frontend to handle bulk insert requests
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, stage) (rate(greptime_table_operator_handle_bulk_insert_sum[$__rate_interval]))/sum by(instance, pod, stage) (rate(greptime_table_operator_handle_bulk_insert_count[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-AVG'
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, stage, le) (rate(greptime_table_operator_handle_bulk_insert_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-P95'
|
||||||
|
- title: Mito Engine
|
||||||
|
panels:
|
||||||
|
- title: Request OPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Request QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, type) (rate(greptime_mito_handle_request_elapsed_count{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{type}}]'
|
||||||
|
- title: Request P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Request P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, type) (rate(greptime_mito_handle_request_elapsed_bucket{}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{type}}]'
|
||||||
|
- title: Write Buffer per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Write Buffer per Instance.
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: greptime_mito_write_buffer_bytes{}
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Write Rows per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Ingestion size by row counts.
|
||||||
|
unit: rowsps
|
||||||
|
queries:
|
||||||
|
- expr: sum by (instance, pod) (rate(greptime_mito_write_rows_total{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Flush OPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Flush QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, reason) (rate(greptime_mito_flush_requests_total{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{reason}}]'
|
||||||
|
- title: Write Stall per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Write Stall per Instance.
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod) (greptime_mito_write_stall_total{})
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Read Stage OPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Read Stage OPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod) (rate(greptime_mito_read_stage_elapsed_count{ stage="total"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Read Stage P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Read Stage P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_read_stage_elapsed_bucket{}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]'
|
||||||
|
- title: Write Stage P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Write Stage P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_write_stage_elapsed_bucket{}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]'
|
||||||
|
- title: Compaction OPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Compaction OPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod) (rate(greptime_mito_compaction_total_elapsed_count{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{ instance }}]-[{{pod}}]'
|
||||||
|
- title: Compaction Elapsed Time per Instance by Stage
|
||||||
|
type: timeseries
|
||||||
|
description: Compaction latency by stage
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, stage) (rate(greptime_mito_compaction_stage_elapsed_bucket{}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-p99'
|
||||||
|
- expr: sum by(instance, pod, stage) (rate(greptime_mito_compaction_stage_elapsed_sum{}[$__rate_interval]))/sum by(instance, pod, stage) (rate(greptime_mito_compaction_stage_elapsed_count{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-avg'
|
||||||
|
- title: Compaction P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Compaction P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le,stage) (rate(greptime_mito_compaction_total_elapsed_bucket{}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-compaction'
|
||||||
|
- title: WAL write size
|
||||||
|
type: timeseries
|
||||||
|
description: Write-ahead logs write size as bytes. This chart includes stats of p95 and p99 size by instance, total WAL write rate.
|
||||||
|
unit: bytes
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.95, sum by(le,instance, pod) (rate(raft_engine_write_size_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-req-size-p95'
|
||||||
|
- expr: histogram_quantile(0.99, sum by(le,instance,pod) (rate(raft_engine_write_size_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-req-size-p99'
|
||||||
|
- expr: sum by (instance, pod)(rate(raft_engine_write_size_sum[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-throughput'
|
||||||
|
- title: Cached Bytes per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Cached Bytes per Instance.
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: greptime_mito_cache_bytes{}
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{type}}]'
|
||||||
|
- title: Inflight Compaction
|
||||||
|
type: timeseries
|
||||||
|
description: Ongoing compaction task count
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: greptime_mito_inflight_compaction_count
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: WAL sync duration seconds
|
||||||
|
type: timeseries
|
||||||
|
description: Raft engine (local disk) log store sync latency, p99
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(le, type, node, instance, pod) (rate(raft_engine_sync_log_duration_seconds_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-p99'
|
||||||
|
- title: Log Store op duration seconds
|
||||||
|
type: timeseries
|
||||||
|
description: Write-ahead log operations latency at p99
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(le,logstore,optype,instance, pod) (rate(greptime_logstore_op_elapsed_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{logstore}}]-[{{optype}}]-p99'
|
||||||
|
- title: Inflight Flush
|
||||||
|
type: timeseries
|
||||||
|
description: Ongoing flush task count
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: greptime_mito_inflight_flush_count
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]'
|
||||||
|
- title: Compaction Input/Output Bytes
|
||||||
|
type: timeseries
|
||||||
|
description: Compaction oinput output bytes
|
||||||
|
unit: bytes
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod) (greptime_mito_compaction_input_bytes)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-input'
|
||||||
|
- expr: sum by(instance, pod) (greptime_mito_compaction_output_bytes)
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-output'
|
||||||
|
- title: Region Worker Handle Bulk Insert Requests
|
||||||
|
type: timeseries
|
||||||
|
description: Per-stage elapsed time for region worker to handle bulk insert region requests.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.95, sum by(le,instance, stage, pod) (rate(greptime_region_worker_handle_write_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-P95'
|
||||||
|
- expr: sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_sum[$__rate_interval]))/sum by(instance, stage, pod) (rate(greptime_region_worker_handle_write_count[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-AVG'
|
||||||
|
- title: Region Worker Convert Requests
|
||||||
|
type: timeseries
|
||||||
|
description: Per-stage elapsed time for region worker to decode requests.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.95, sum by(le, instance, stage, pod) (rate(greptime_datanode_convert_region_request_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-P95'
|
||||||
|
- expr: sum by(le,instance, stage, pod) (rate(greptime_datanode_convert_region_request_sum[$__rate_interval]))/sum by(le,instance, stage, pod) (rate(greptime_datanode_convert_region_request_count[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{stage}}]-AVG'
|
||||||
|
- title: OpenDAL
|
||||||
|
panels:
|
||||||
|
- title: QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme, operation) (rate(opendal_operation_duration_seconds_count{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]'
|
||||||
|
- title: Read QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Read QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{ operation="read"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]'
|
||||||
|
- title: Read P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Read P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{operation="read"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-{{scheme}}'
|
||||||
|
- title: Write QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Write QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{ operation="write"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-{{scheme}}'
|
||||||
|
- title: Write P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Write P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{ operation="write"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]'
|
||||||
|
- title: List QPS per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: List QPS per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme) (rate(opendal_operation_duration_seconds_count{ operation="list"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]'
|
||||||
|
- title: List P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: List P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, scheme) (rate(opendal_operation_duration_seconds_bucket{ operation="list"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]'
|
||||||
|
- title: Other Requests per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Other Requests per Instance.
|
||||||
|
unit: ops
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme, operation) (rate(opendal_operation_duration_seconds_count{operation!~"read|write|list|stat"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]'
|
||||||
|
- title: Other Request P99 per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Other Request P99 per Instance.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(instance, pod, le, scheme, operation) (rate(opendal_operation_duration_seconds_bucket{ operation!~"read|write|list"}[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]'
|
||||||
|
- title: Opendal traffic
|
||||||
|
type: timeseries
|
||||||
|
description: Total traffic as in bytes by instance and operation
|
||||||
|
unit: decbytes
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme, operation) (rate(opendal_operation_bytes_sum{}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]'
|
||||||
|
- title: OpenDAL errors per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: OpenDAL error counts per Instance.
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, scheme, operation, error) (rate(opendal_operation_errors_total{ error!="NotFound"}[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{scheme}}]-[{{operation}}]-[{{error}}]'
|
||||||
|
- title: Metasrv
|
||||||
|
panels:
|
||||||
|
- title: Region migration datanode
|
||||||
|
type: status-history
|
||||||
|
description: Counter of region migration by source and destination
|
||||||
|
queries:
|
||||||
|
- expr: greptime_meta_region_migration_stat{datanode_type="src"}
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: from-datanode-{{datanode_id}}
|
||||||
|
- expr: greptime_meta_region_migration_stat{datanode_type="desc"}
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: to-datanode-{{datanode_id}}
|
||||||
|
- title: Region migration error
|
||||||
|
type: timeseries
|
||||||
|
description: Counter of region migration error
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: greptime_meta_region_migration_error
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}}-{{state}}-{{error_type}}'
|
||||||
|
- title: Datanode load
|
||||||
|
type: timeseries
|
||||||
|
description: Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads.
|
||||||
|
unit: binBps
|
||||||
|
queries:
|
||||||
|
- expr: greptime_datanode_load
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: Datanode-{{datanode_id}}-writeload
|
||||||
|
- title: Rate of SQL Executions (RDS)
|
||||||
|
type: timeseries
|
||||||
|
description: Displays the rate of SQL executions processed by the Meta service using the RDS backend.
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: rate(greptime_meta_rds_pg_sql_execute_elapsed_ms_count[$__rate_interval])
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}} {{op}} {{type}} {{result}} '
|
||||||
|
- title: SQL Execution Latency (RDS)
|
||||||
|
type: timeseries
|
||||||
|
description: 'Measures the response time of SQL executions via the RDS backend. '
|
||||||
|
unit: ms
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.90, sum by(pod, op, type, result, le) (rate(greptime_meta_rds_pg_sql_execute_elapsed_ms_bucket[$__rate_interval])))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}} {{op}} {{type}} {{result}} p90'
|
||||||
|
- title: Handler Execution Latency
|
||||||
|
type: timeseries
|
||||||
|
description: |
|
||||||
|
Shows latency of Meta handlers by pod and handler name, useful for monitoring handler performance and detecting latency spikes.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: |-
|
||||||
|
histogram_quantile(0.90, sum by(pod, le, name) (
|
||||||
|
rate(greptime_meta_handler_execute_bucket[$__rate_interval])
|
||||||
|
))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}} {{name}} p90'
|
||||||
|
- title: Heartbeat Packet Size
|
||||||
|
type: timeseries
|
||||||
|
description: |
|
||||||
|
Shows p90 heartbeat message sizes, helping track network usage and identify anomalies in heartbeat payload.
|
||||||
|
unit: bytes
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.9, sum by(pod, le) (greptime_meta_heartbeat_stat_memory_size_bucket))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}}'
|
||||||
|
- title: Meta Heartbeat Receive Rate
|
||||||
|
type: timeseries
|
||||||
|
description: Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: rate(greptime_meta_heartbeat_rate[$__rate_interval])
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}}'
|
||||||
|
- title: Meta KV Ops Latency
|
||||||
|
type: timeseries
|
||||||
|
description: Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.99, sum by(pod, le, op, target) (greptime_meta_kv_request_elapsed_bucket))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}}-{{op}} p99'
|
||||||
|
- title: Rate of meta KV Ops
|
||||||
|
type: timeseries
|
||||||
|
description: Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads.
|
||||||
|
unit: none
|
||||||
|
queries:
|
||||||
|
- expr: rate(greptime_meta_kv_request_elapsed_count[$__rate_interval])
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '{{pod}}-{{op}} p99'
|
||||||
|
- title: DDL Latency
|
||||||
|
type: timeseries
|
||||||
|
description: Gauge of load information of each datanode, collected via heartbeat between datanode and metasrv. This information is for metasrv to schedule workloads.
|
||||||
|
unit: s
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_tables_bucket))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: CreateLogicalTables-{{step}} p90
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_table))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: CreateTable-{{step}} p90
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_view))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: CreateView-{{step}} p90
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_create_flow))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: CreateFlow-{{step}} p90
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_drop_table))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: DropTable-{{step}} p90
|
||||||
|
- expr: histogram_quantile(0.9, sum by(le, pod, step) (greptime_meta_procedure_alter_table))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: AlterTable-{{step}} p90
|
||||||
|
- title: Flownode
|
||||||
|
panels:
|
||||||
|
- title: Flow Ingest / Output Rate
|
||||||
|
type: timeseries
|
||||||
|
description: Flow Ingest / Output Rate.
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance, pod, direction) (rate(greptime_flow_processed_rows[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{pod}}]-[{{instance}}]-[{{direction}}]'
|
||||||
|
- title: Flow Ingest Latency
|
||||||
|
type: timeseries
|
||||||
|
description: Flow Ingest Latency.
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.95, sum(rate(greptime_flow_insert_elapsed_bucket[$__rate_interval])) by (le, instance, pod))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-p95'
|
||||||
|
- expr: histogram_quantile(0.99, sum(rate(greptime_flow_insert_elapsed_bucket[$__rate_interval])) by (le, instance, pod))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-p99'
|
||||||
|
- title: Flow Operation Latency
|
||||||
|
type: timeseries
|
||||||
|
description: Flow Operation Latency.
|
||||||
|
queries:
|
||||||
|
- expr: histogram_quantile(0.95, sum(rate(greptime_flow_processing_time_bucket[$__rate_interval])) by (le,instance,pod,type))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{type}}]-p95'
|
||||||
|
- expr: histogram_quantile(0.99, sum(rate(greptime_flow_processing_time_bucket[$__rate_interval])) by (le,instance,pod,type))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{type}}]-p99'
|
||||||
|
- title: Flow Buffer Size per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Flow Buffer Size per Instance.
|
||||||
|
queries:
|
||||||
|
- expr: greptime_flow_input_buf_size
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}]'
|
||||||
|
- title: Flow Processing Error per Instance
|
||||||
|
type: timeseries
|
||||||
|
description: Flow Processing Error per Instance.
|
||||||
|
queries:
|
||||||
|
- expr: sum by(instance,pod,code) (rate(greptime_flow_errors[$__rate_interval]))
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: ${metrics}
|
||||||
|
legendFormat: '[{{instance}}]-[{{pod}}]-[{{code}}]'
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
54
grafana/scripts/check.sh
Executable file
54
grafana/scripts/check.sh
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
DASHBOARD_DIR=${1:-grafana/dashboards/metrics}
|
||||||
|
|
||||||
|
check_dashboard_description() {
|
||||||
|
for dashboard in $(find $DASHBOARD_DIR -name "*.json"); do
|
||||||
|
echo "Checking $dashboard description"
|
||||||
|
|
||||||
|
# Use jq to check for panels with empty or missing descriptions
|
||||||
|
invalid_panels=$(cat $dashboard | jq -r '
|
||||||
|
.panels[]
|
||||||
|
| select((.type == "stats" or .type == "timeseries") and (.description == "" or .description == null))')
|
||||||
|
|
||||||
|
# Check if any invalid panels were found
|
||||||
|
if [[ -n "$invalid_panels" ]]; then
|
||||||
|
echo "Error: The following panels have empty or missing descriptions:"
|
||||||
|
echo "$invalid_panels"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "All panels with type 'stats' or 'timeseries' have valid descriptions."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
check_dashboards_generation() {
|
||||||
|
./grafana/scripts/gen-dashboards.sh
|
||||||
|
|
||||||
|
if [[ -n "$(git diff --name-only grafana/dashboards/metrics)" ]]; then
|
||||||
|
echo "Error: The dashboards are not generated correctly. You should execute the `make dashboards` command."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_datasource() {
|
||||||
|
for dashboard in $(find $DASHBOARD_DIR -name "*.json"); do
|
||||||
|
echo "Checking $dashboard datasource"
|
||||||
|
jq -r '.panels[] | select(.type != "row") | .targets[] | [.datasource.type, .datasource.uid] | @tsv' $dashboard | while read -r type uid; do
|
||||||
|
# if the datasource is prometheus, check if the uid is ${metrics}
|
||||||
|
if [[ "$type" == "prometheus" && "$uid" != "\${metrics}" ]]; then
|
||||||
|
echo "Error: The datasource uid of $dashboard is not valid. It should be \${metrics}, got $uid"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# if the datasource is mysql, check if the uid is ${information_schema}
|
||||||
|
if [[ "$type" == "mysql" && "$uid" != "\${information_schema}" ]]; then
|
||||||
|
echo "Error: The datasource uid of $dashboard is not valid. It should be \${information_schema}, got $uid"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
check_dashboards_generation
|
||||||
|
check_dashboard_description
|
||||||
|
check_datasource
|
||||||
25
grafana/scripts/gen-dashboards.sh
Executable file
25
grafana/scripts/gen-dashboards.sh
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
CLUSTER_DASHBOARD_DIR=${1:-grafana/dashboards/metrics/cluster}
|
||||||
|
STANDALONE_DASHBOARD_DIR=${2:-grafana/dashboards/metrics/standalone}
|
||||||
|
DAC_IMAGE=ghcr.io/zyy17/dac:20250423-522bd35
|
||||||
|
|
||||||
|
remove_instance_filters() {
|
||||||
|
# Remove the instance filters for the standalone dashboards.
|
||||||
|
sed -E 's/instance=~\\"(\$datanode|\$frontend|\$metasrv|\$flownode)\\",?//g' "$CLUSTER_DASHBOARD_DIR/dashboard.json" > "$STANDALONE_DASHBOARD_DIR/dashboard.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_intermediate_dashboards_and_docs() {
|
||||||
|
docker run -v ${PWD}:/greptimedb --rm ${DAC_IMAGE} \
|
||||||
|
-i /greptimedb/$CLUSTER_DASHBOARD_DIR/dashboard.json \
|
||||||
|
-o /greptimedb/$CLUSTER_DASHBOARD_DIR/dashboard.yaml \
|
||||||
|
-m /greptimedb/$CLUSTER_DASHBOARD_DIR/dashboard.md
|
||||||
|
|
||||||
|
docker run -v ${PWD}:/greptimedb --rm ${DAC_IMAGE} \
|
||||||
|
-i /greptimedb/$STANDALONE_DASHBOARD_DIR/dashboard.json \
|
||||||
|
-o /greptimedb/$STANDALONE_DASHBOARD_DIR/dashboard.yaml \
|
||||||
|
-m /greptimedb/$STANDALONE_DASHBOARD_DIR/dashboard.md
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_instance_filters
|
||||||
|
generate_intermediate_dashboards_and_docs
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
BASEDIR=$(dirname "$0")
|
|
||||||
echo '| Title | Description | Expressions |
|
|
||||||
|---|---|---|'
|
|
||||||
|
|
||||||
cat $BASEDIR/greptimedb-cluster.json | jq -r '
|
|
||||||
.panels |
|
|
||||||
map(select(.type == "stat" or .type == "timeseries")) |
|
|
||||||
.[] | "| \(.title) | \(.description | gsub("\n"; "<br>")) | \(.targets | map(.expr // .rawSql | "`\(.|gsub("\n"; "<br>"))`") | join("<br>")) |"
|
|
||||||
'
|
|
||||||
@@ -26,6 +26,13 @@ excludes = [
|
|||||||
"src/common/base/src/secrets.rs",
|
"src/common/base/src/secrets.rs",
|
||||||
"src/servers/src/repeated_field.rs",
|
"src/servers/src/repeated_field.rs",
|
||||||
"src/servers/src/http/test_helpers.rs",
|
"src/servers/src/http/test_helpers.rs",
|
||||||
|
# enterprise
|
||||||
|
"src/common/meta/src/rpc/ddl/trigger.rs",
|
||||||
|
"src/operator/src/expr_helper/trigger.rs",
|
||||||
|
"src/sql/src/statements/create/trigger.rs",
|
||||||
|
"src/sql/src/statements/show/trigger.rs",
|
||||||
|
"src/sql/src/parsers/create_parser/trigger.rs",
|
||||||
|
"src/sql/src/parsers/show_parser/trigger.rs",
|
||||||
]
|
]
|
||||||
|
|
||||||
[properties]
|
[properties]
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2024-12-25"
|
channel = "nightly-2025-05-19"
|
||||||
|
|||||||
74
scripts/check-super-imports.py
Normal file
74
scripts/check-super-imports.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
from multiprocessing import Pool
|
||||||
|
|
||||||
|
|
||||||
|
def find_rust_files(directory):
|
||||||
|
rust_files = []
|
||||||
|
for root, _, files in os.walk(directory):
|
||||||
|
# Skip files with "test" in the path
|
||||||
|
if "test" in root.lower():
|
||||||
|
continue
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
# Skip files with "test" in the filename
|
||||||
|
if "test" in file.lower():
|
||||||
|
continue
|
||||||
|
|
||||||
|
if file.endswith(".rs"):
|
||||||
|
rust_files.append(os.path.join(root, file))
|
||||||
|
return rust_files
|
||||||
|
|
||||||
|
|
||||||
|
def check_file_for_super_import(file_path):
|
||||||
|
with open(file_path, "r") as file:
|
||||||
|
lines = file.readlines()
|
||||||
|
|
||||||
|
violations = []
|
||||||
|
for line_number, line in enumerate(lines, 1):
|
||||||
|
# Check for "use super::" without leading tab
|
||||||
|
if line.startswith("use super::"):
|
||||||
|
violations.append((line_number, line.strip()))
|
||||||
|
|
||||||
|
if violations:
|
||||||
|
return file_path, violations
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
rust_files = find_rust_files(".")
|
||||||
|
|
||||||
|
with Pool() as pool:
|
||||||
|
results = pool.map(check_file_for_super_import, rust_files)
|
||||||
|
|
||||||
|
# Filter out None results
|
||||||
|
violations = [result for result in results if result]
|
||||||
|
|
||||||
|
if violations:
|
||||||
|
print("Found 'use super::' without leading tab in the following files:")
|
||||||
|
counter = 1
|
||||||
|
for file_path, file_violations in violations:
|
||||||
|
for line_number, line in file_violations:
|
||||||
|
print(f"{counter:>5} {file_path}:{line_number} - {line}")
|
||||||
|
counter += 1
|
||||||
|
raise SystemExit(1)
|
||||||
|
else:
|
||||||
|
print("No 'use super::' without leading tab found. All files are compliant.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -514,6 +514,7 @@ fn query_request_type(request: &QueryRequest) -> &'static str {
|
|||||||
Some(Query::Sql(_)) => "query.sql",
|
Some(Query::Sql(_)) => "query.sql",
|
||||||
Some(Query::LogicalPlan(_)) => "query.logical_plan",
|
Some(Query::LogicalPlan(_)) => "query.logical_plan",
|
||||||
Some(Query::PromRangeQuery(_)) => "query.prom_range",
|
Some(Query::PromRangeQuery(_)) => "query.prom_range",
|
||||||
|
Some(Query::InsertIntoPlan(_)) => "query.insert_into_plan",
|
||||||
None => "query.empty",
|
None => "query.empty",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1049,7 +1050,7 @@ pub fn value_to_grpc_value(value: Value) -> GrpcValue {
|
|||||||
Value::Int64(v) => Some(ValueData::I64Value(v)),
|
Value::Int64(v) => Some(ValueData::I64Value(v)),
|
||||||
Value::Float32(v) => Some(ValueData::F32Value(*v)),
|
Value::Float32(v) => Some(ValueData::F32Value(*v)),
|
||||||
Value::Float64(v) => Some(ValueData::F64Value(*v)),
|
Value::Float64(v) => Some(ValueData::F64Value(*v)),
|
||||||
Value::String(v) => Some(ValueData::StringValue(v.as_utf8().to_string())),
|
Value::String(v) => Some(ValueData::StringValue(v.into_string())),
|
||||||
Value::Binary(v) => Some(ValueData::BinaryValue(v.to_vec())),
|
Value::Binary(v) => Some(ValueData::BinaryValue(v.to_vec())),
|
||||||
Value::Date(v) => Some(ValueData::DateValue(v.val())),
|
Value::Date(v) => Some(ValueData::DateValue(v.val())),
|
||||||
Value::Timestamp(v) => Some(match v.unit() {
|
Value::Timestamp(v) => Some(match v.unit() {
|
||||||
|
|||||||
@@ -15,10 +15,13 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use datatypes::schema::{
|
use datatypes::schema::{
|
||||||
ColumnDefaultConstraint, ColumnSchema, FulltextAnalyzer, FulltextOptions, SkippingIndexOptions,
|
ColumnDefaultConstraint, ColumnSchema, FulltextAnalyzer, FulltextBackend, FulltextOptions,
|
||||||
SkippingIndexType, COMMENT_KEY, FULLTEXT_KEY, INVERTED_INDEX_KEY, SKIPPING_INDEX_KEY,
|
SkippingIndexOptions, SkippingIndexType, COMMENT_KEY, FULLTEXT_KEY, INVERTED_INDEX_KEY,
|
||||||
|
SKIPPING_INDEX_KEY,
|
||||||
|
};
|
||||||
|
use greptime_proto::v1::{
|
||||||
|
Analyzer, FulltextBackend as PbFulltextBackend, SkippingIndexType as PbSkippingIndexType,
|
||||||
};
|
};
|
||||||
use greptime_proto::v1::{Analyzer, SkippingIndexType as PbSkippingIndexType};
|
|
||||||
use snafu::ResultExt;
|
use snafu::ResultExt;
|
||||||
|
|
||||||
use crate::error::{self, Result};
|
use crate::error::{self, Result};
|
||||||
@@ -142,13 +145,21 @@ pub fn options_from_inverted() -> ColumnOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to construct a `FulltextAnalyzer` from the given analyzer.
|
/// Tries to construct a `FulltextAnalyzer` from the given analyzer.
|
||||||
pub fn as_fulltext_option(analyzer: Analyzer) -> FulltextAnalyzer {
|
pub fn as_fulltext_option_analyzer(analyzer: Analyzer) -> FulltextAnalyzer {
|
||||||
match analyzer {
|
match analyzer {
|
||||||
Analyzer::English => FulltextAnalyzer::English,
|
Analyzer::English => FulltextAnalyzer::English,
|
||||||
Analyzer::Chinese => FulltextAnalyzer::Chinese,
|
Analyzer::Chinese => FulltextAnalyzer::Chinese,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tries to construct a `FulltextBackend` from the given backend.
|
||||||
|
pub fn as_fulltext_option_backend(backend: PbFulltextBackend) -> FulltextBackend {
|
||||||
|
match backend {
|
||||||
|
PbFulltextBackend::Bloom => FulltextBackend::Bloom,
|
||||||
|
PbFulltextBackend::Tantivy => FulltextBackend::Tantivy,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Tries to construct a `SkippingIndexType` from the given skipping index type.
|
/// Tries to construct a `SkippingIndexType` from the given skipping index type.
|
||||||
pub fn as_skipping_index_type(skipping_index_type: PbSkippingIndexType) -> SkippingIndexType {
|
pub fn as_skipping_index_type(skipping_index_type: PbSkippingIndexType) -> SkippingIndexType {
|
||||||
match skipping_index_type {
|
match skipping_index_type {
|
||||||
@@ -160,7 +171,7 @@ pub fn as_skipping_index_type(skipping_index_type: PbSkippingIndexType) -> Skipp
|
|||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use datatypes::data_type::ConcreteDataType;
|
use datatypes::data_type::ConcreteDataType;
|
||||||
use datatypes::schema::FulltextAnalyzer;
|
use datatypes::schema::{FulltextAnalyzer, FulltextBackend};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::v1::ColumnDataType;
|
use crate::v1::ColumnDataType;
|
||||||
@@ -219,13 +230,14 @@ mod tests {
|
|||||||
enable: true,
|
enable: true,
|
||||||
analyzer: FulltextAnalyzer::English,
|
analyzer: FulltextAnalyzer::English,
|
||||||
case_sensitive: false,
|
case_sensitive: false,
|
||||||
|
backend: FulltextBackend::Bloom,
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
schema.set_inverted_index(true);
|
schema.set_inverted_index(true);
|
||||||
let options = options_from_column_schema(&schema).unwrap();
|
let options = options_from_column_schema(&schema).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
options.options.get(FULLTEXT_GRPC_KEY).unwrap(),
|
options.options.get(FULLTEXT_GRPC_KEY).unwrap(),
|
||||||
"{\"enable\":true,\"analyzer\":\"English\",\"case-sensitive\":false}"
|
"{\"enable\":true,\"analyzer\":\"English\",\"case-sensitive\":false,\"backend\":\"bloom\"}"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
options.options.get(INVERTED_INDEX_GRPC_KEY).unwrap(),
|
options.options.get(INVERTED_INDEX_GRPC_KEY).unwrap(),
|
||||||
@@ -239,11 +251,12 @@ mod tests {
|
|||||||
enable: true,
|
enable: true,
|
||||||
analyzer: FulltextAnalyzer::English,
|
analyzer: FulltextAnalyzer::English,
|
||||||
case_sensitive: false,
|
case_sensitive: false,
|
||||||
|
backend: FulltextBackend::Bloom,
|
||||||
};
|
};
|
||||||
let options = options_from_fulltext(&fulltext).unwrap().unwrap();
|
let options = options_from_fulltext(&fulltext).unwrap().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
options.options.get(FULLTEXT_GRPC_KEY).unwrap(),
|
options.options.get(FULLTEXT_GRPC_KEY).unwrap(),
|
||||||
"{\"enable\":true,\"analyzer\":\"English\",\"case-sensitive\":false}"
|
"{\"enable\":true,\"analyzer\":\"English\",\"case-sensitive\":false,\"backend\":\"bloom\"}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub fn userinfo_by_name(username: Option<String>) -> UserInfoRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn user_provider_from_option(opt: &String) -> Result<UserProviderRef> {
|
pub fn user_provider_from_option(opt: &String) -> Result<UserProviderRef> {
|
||||||
let (name, content) = opt.split_once(':').context(InvalidConfigSnafu {
|
let (name, content) = opt.split_once(':').with_context(|| InvalidConfigSnafu {
|
||||||
value: opt.to_string(),
|
value: opt.to_string(),
|
||||||
msg: "UserProviderOption must be in format `<option>:<value>`",
|
msg: "UserProviderOption must be in format `<option>:<value>`",
|
||||||
})?;
|
})?;
|
||||||
@@ -57,6 +57,24 @@ pub fn user_provider_from_option(opt: &String) -> Result<UserProviderRef> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn static_user_provider_from_option(opt: &String) -> Result<StaticUserProvider> {
|
||||||
|
let (name, content) = opt.split_once(':').with_context(|| InvalidConfigSnafu {
|
||||||
|
value: opt.to_string(),
|
||||||
|
msg: "UserProviderOption must be in format `<option>:<value>`",
|
||||||
|
})?;
|
||||||
|
match name {
|
||||||
|
STATIC_USER_PROVIDER => {
|
||||||
|
let provider = StaticUserProvider::new(content)?;
|
||||||
|
Ok(provider)
|
||||||
|
}
|
||||||
|
_ => InvalidConfigSnafu {
|
||||||
|
value: name.to_string(),
|
||||||
|
msg: format!("Invalid UserProviderOption, expect only {STATIC_USER_PROVIDER}"),
|
||||||
|
}
|
||||||
|
.fail(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Username<'a> = &'a str;
|
type Username<'a> = &'a str;
|
||||||
type HostOrIp<'a> = &'a str;
|
type HostOrIp<'a> = &'a str;
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ pub enum Error {
|
|||||||
location: Location,
|
location: Location,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[snafu(display("Failed to convert to utf8"))]
|
||||||
|
FromUtf8 {
|
||||||
|
#[snafu(source)]
|
||||||
|
error: std::string::FromUtf8Error,
|
||||||
|
#[snafu(implicit)]
|
||||||
|
location: Location,
|
||||||
|
},
|
||||||
|
|
||||||
#[snafu(display("Authentication source failure"))]
|
#[snafu(display("Authentication source failure"))]
|
||||||
AuthBackend {
|
AuthBackend {
|
||||||
#[snafu(implicit)]
|
#[snafu(implicit)]
|
||||||
@@ -85,7 +93,7 @@ impl ErrorExt for Error {
|
|||||||
fn status_code(&self) -> StatusCode {
|
fn status_code(&self) -> StatusCode {
|
||||||
match self {
|
match self {
|
||||||
Error::InvalidConfig { .. } => StatusCode::InvalidArguments,
|
Error::InvalidConfig { .. } => StatusCode::InvalidArguments,
|
||||||
Error::IllegalParam { .. } => StatusCode::InvalidArguments,
|
Error::IllegalParam { .. } | Error::FromUtf8 { .. } => StatusCode::InvalidArguments,
|
||||||
Error::FileWatch { .. } => StatusCode::InvalidArguments,
|
Error::FileWatch { .. } => StatusCode::InvalidArguments,
|
||||||
Error::InternalState { .. } => StatusCode::Unexpected,
|
Error::InternalState { .. } => StatusCode::Unexpected,
|
||||||
Error::Io { .. } => StatusCode::StorageUnavailable,
|
Error::Io { .. } => StatusCode::StorageUnavailable,
|
||||||
|
|||||||
@@ -22,10 +22,12 @@ mod user_provider;
|
|||||||
pub mod tests;
|
pub mod tests;
|
||||||
|
|
||||||
pub use common::{
|
pub use common::{
|
||||||
auth_mysql, user_provider_from_option, userinfo_by_name, HashedPassword, Identity, Password,
|
auth_mysql, static_user_provider_from_option, user_provider_from_option, userinfo_by_name,
|
||||||
|
HashedPassword, Identity, Password,
|
||||||
};
|
};
|
||||||
pub use permission::{PermissionChecker, PermissionReq, PermissionResp};
|
pub use permission::{PermissionChecker, PermissionReq, PermissionResp};
|
||||||
pub use user_info::UserInfo;
|
pub use user_info::UserInfo;
|
||||||
|
pub use user_provider::static_user_provider::StaticUserProvider;
|
||||||
pub use user_provider::UserProvider;
|
pub use user_provider::UserProvider;
|
||||||
|
|
||||||
/// pub type alias
|
/// pub type alias
|
||||||
|
|||||||
@@ -15,15 +15,15 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use snafu::OptionExt;
|
use snafu::{OptionExt, ResultExt};
|
||||||
|
|
||||||
use crate::error::{InvalidConfigSnafu, Result};
|
use crate::error::{FromUtf8Snafu, InvalidConfigSnafu, Result};
|
||||||
use crate::user_provider::{authenticate_with_credential, load_credential_from_file};
|
use crate::user_provider::{authenticate_with_credential, load_credential_from_file};
|
||||||
use crate::{Identity, Password, UserInfoRef, UserProvider};
|
use crate::{Identity, Password, UserInfoRef, UserProvider};
|
||||||
|
|
||||||
pub(crate) const STATIC_USER_PROVIDER: &str = "static_user_provider";
|
pub(crate) const STATIC_USER_PROVIDER: &str = "static_user_provider";
|
||||||
|
|
||||||
pub(crate) struct StaticUserProvider {
|
pub struct StaticUserProvider {
|
||||||
users: HashMap<String, Vec<u8>>,
|
users: HashMap<String, Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,6 +60,18 @@ impl StaticUserProvider {
|
|||||||
.fail(),
|
.fail(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a random username/password pair
|
||||||
|
/// This is useful for invoking from other components in the cluster
|
||||||
|
pub fn get_one_user_pwd(&self) -> Result<(String, String)> {
|
||||||
|
let kv = self.users.iter().next().context(InvalidConfigSnafu {
|
||||||
|
value: "",
|
||||||
|
msg: "Expect at least one pair of username and password",
|
||||||
|
})?;
|
||||||
|
let username = kv.0;
|
||||||
|
let pwd = String::from_utf8(kv.1.clone()).context(FromUtf8Snafu)?;
|
||||||
|
Ok((username.clone(), pwd))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ mod information_memory_table;
|
|||||||
pub mod key_column_usage;
|
pub mod key_column_usage;
|
||||||
mod partitions;
|
mod partitions;
|
||||||
mod procedure_info;
|
mod procedure_info;
|
||||||
mod region_peers;
|
pub mod region_peers;
|
||||||
mod region_statistics;
|
mod region_statistics;
|
||||||
mod runtime_metrics;
|
mod runtime_metrics;
|
||||||
pub mod schemata;
|
pub mod schemata;
|
||||||
@@ -49,7 +49,6 @@ pub use table_names::*;
|
|||||||
use views::InformationSchemaViews;
|
use views::InformationSchemaViews;
|
||||||
|
|
||||||
use self::columns::InformationSchemaColumns;
|
use self::columns::InformationSchemaColumns;
|
||||||
use super::{SystemSchemaProviderInner, SystemTable, SystemTableRef};
|
|
||||||
use crate::error::{Error, Result};
|
use crate::error::{Error, Result};
|
||||||
use crate::system_schema::information_schema::cluster_info::InformationSchemaClusterInfo;
|
use crate::system_schema::information_schema::cluster_info::InformationSchemaClusterInfo;
|
||||||
use crate::system_schema::information_schema::flows::InformationSchemaFlows;
|
use crate::system_schema::information_schema::flows::InformationSchemaFlows;
|
||||||
@@ -63,7 +62,9 @@ use crate::system_schema::information_schema::table_constraints::InformationSche
|
|||||||
use crate::system_schema::information_schema::tables::InformationSchemaTables;
|
use crate::system_schema::information_schema::tables::InformationSchemaTables;
|
||||||
use crate::system_schema::memory_table::MemoryTable;
|
use crate::system_schema::memory_table::MemoryTable;
|
||||||
pub(crate) use crate::system_schema::predicate::Predicates;
|
pub(crate) use crate::system_schema::predicate::Predicates;
|
||||||
use crate::system_schema::SystemSchemaProvider;
|
use crate::system_schema::{
|
||||||
|
SystemSchemaProvider, SystemSchemaProviderInner, SystemTable, SystemTableRef,
|
||||||
|
};
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
|||||||
@@ -36,9 +36,8 @@ use datatypes::vectors::{
|
|||||||
use snafu::ResultExt;
|
use snafu::ResultExt;
|
||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
|
|
||||||
use super::CLUSTER_INFO;
|
|
||||||
use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result};
|
use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result};
|
||||||
use crate::system_schema::information_schema::{InformationTable, Predicates};
|
use crate::system_schema::information_schema::{InformationTable, Predicates, CLUSTER_INFO};
|
||||||
use crate::system_schema::utils;
|
use crate::system_schema::utils;
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ use snafu::{OptionExt, ResultExt};
|
|||||||
use sql::statements;
|
use sql::statements;
|
||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
|
|
||||||
use super::{InformationTable, COLUMNS};
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
||||||
};
|
};
|
||||||
use crate::information_schema::Predicates;
|
use crate::information_schema::Predicates;
|
||||||
|
use crate::system_schema::information_schema::{InformationTable, COLUMNS};
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -56,6 +56,8 @@ pub const TABLE_CATALOG: &str = "table_catalog";
|
|||||||
pub const TABLE_SCHEMA: &str = "table_schema";
|
pub const TABLE_SCHEMA: &str = "table_schema";
|
||||||
pub const TABLE_NAME: &str = "table_name";
|
pub const TABLE_NAME: &str = "table_name";
|
||||||
pub const COLUMN_NAME: &str = "column_name";
|
pub const COLUMN_NAME: &str = "column_name";
|
||||||
|
pub const REGION_ID: &str = "region_id";
|
||||||
|
pub const PEER_ID: &str = "peer_id";
|
||||||
const ORDINAL_POSITION: &str = "ordinal_position";
|
const ORDINAL_POSITION: &str = "ordinal_position";
|
||||||
const CHARACTER_MAXIMUM_LENGTH: &str = "character_maximum_length";
|
const CHARACTER_MAXIMUM_LENGTH: &str = "character_maximum_length";
|
||||||
const CHARACTER_OCTET_LENGTH: &str = "character_octet_length";
|
const CHARACTER_OCTET_LENGTH: &str = "character_octet_length";
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use common_catalog::consts::{METRIC_ENGINE, MITO_ENGINE};
|
|||||||
use datatypes::schema::{Schema, SchemaRef};
|
use datatypes::schema::{Schema, SchemaRef};
|
||||||
use datatypes::vectors::{Int64Vector, StringVector, VectorRef};
|
use datatypes::vectors::{Int64Vector, StringVector, VectorRef};
|
||||||
|
|
||||||
use super::table_names::*;
|
use crate::system_schema::information_schema::table_names::*;
|
||||||
use crate::system_schema::utils::tables::{
|
use crate::system_schema::utils::tables::{
|
||||||
bigint_column, string_column, string_columns, timestamp_micro_column,
|
bigint_column, string_column, string_columns, timestamp_micro_column,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,18 +24,17 @@ use datafusion::physical_plan::stream::RecordBatchStreamAdapter as DfRecordBatch
|
|||||||
use datafusion::physical_plan::streaming::PartitionStream as DfPartitionStream;
|
use datafusion::physical_plan::streaming::PartitionStream as DfPartitionStream;
|
||||||
use datafusion::physical_plan::SendableRecordBatchStream as DfSendableRecordBatchStream;
|
use datafusion::physical_plan::SendableRecordBatchStream as DfSendableRecordBatchStream;
|
||||||
use datatypes::prelude::{ConcreteDataType, MutableVector, ScalarVectorBuilder, VectorRef};
|
use datatypes::prelude::{ConcreteDataType, MutableVector, ScalarVectorBuilder, VectorRef};
|
||||||
use datatypes::schema::{ColumnSchema, Schema, SchemaRef};
|
use datatypes::schema::{ColumnSchema, FulltextBackend, Schema, SchemaRef};
|
||||||
use datatypes::value::Value;
|
use datatypes::value::Value;
|
||||||
use datatypes::vectors::{ConstantVector, StringVector, StringVectorBuilder, UInt32VectorBuilder};
|
use datatypes::vectors::{ConstantVector, StringVector, StringVectorBuilder, UInt32VectorBuilder};
|
||||||
use futures_util::TryStreamExt;
|
use futures_util::TryStreamExt;
|
||||||
use snafu::{OptionExt, ResultExt};
|
use snafu::{OptionExt, ResultExt};
|
||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
|
|
||||||
use super::KEY_COLUMN_USAGE;
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
||||||
};
|
};
|
||||||
use crate::system_schema::information_schema::{InformationTable, Predicates};
|
use crate::system_schema::information_schema::{InformationTable, Predicates, KEY_COLUMN_USAGE};
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
pub const CONSTRAINT_SCHEMA: &str = "constraint_schema";
|
pub const CONSTRAINT_SCHEMA: &str = "constraint_schema";
|
||||||
@@ -48,20 +47,38 @@ pub const TABLE_SCHEMA: &str = "table_schema";
|
|||||||
pub const TABLE_NAME: &str = "table_name";
|
pub const TABLE_NAME: &str = "table_name";
|
||||||
pub const COLUMN_NAME: &str = "column_name";
|
pub const COLUMN_NAME: &str = "column_name";
|
||||||
pub const ORDINAL_POSITION: &str = "ordinal_position";
|
pub const ORDINAL_POSITION: &str = "ordinal_position";
|
||||||
|
/// The type of the index.
|
||||||
|
pub const GREPTIME_INDEX_TYPE: &str = "greptime_index_type";
|
||||||
const INIT_CAPACITY: usize = 42;
|
const INIT_CAPACITY: usize = 42;
|
||||||
|
|
||||||
/// Primary key constraint name
|
|
||||||
pub(crate) const PRI_CONSTRAINT_NAME: &str = "PRIMARY";
|
|
||||||
/// Time index constraint name
|
/// Time index constraint name
|
||||||
pub(crate) const TIME_INDEX_CONSTRAINT_NAME: &str = "TIME INDEX";
|
pub(crate) const CONSTRAINT_NAME_TIME_INDEX: &str = "TIME INDEX";
|
||||||
|
|
||||||
|
/// Primary key constraint name
|
||||||
|
pub(crate) const CONSTRAINT_NAME_PRI: &str = "PRIMARY";
|
||||||
|
/// Primary key index type
|
||||||
|
pub(crate) const INDEX_TYPE_PRI: &str = "greptime-primary-key-v1";
|
||||||
|
|
||||||
/// Inverted index constraint name
|
/// Inverted index constraint name
|
||||||
pub(crate) const INVERTED_INDEX_CONSTRAINT_NAME: &str = "INVERTED INDEX";
|
pub(crate) const CONSTRAINT_NAME_INVERTED_INDEX: &str = "INVERTED INDEX";
|
||||||
|
/// Inverted index type
|
||||||
|
pub(crate) const INDEX_TYPE_INVERTED_INDEX: &str = "greptime-inverted-index-v1";
|
||||||
|
|
||||||
/// Fulltext index constraint name
|
/// Fulltext index constraint name
|
||||||
pub(crate) const FULLTEXT_INDEX_CONSTRAINT_NAME: &str = "FULLTEXT INDEX";
|
pub(crate) const CONSTRAINT_NAME_FULLTEXT_INDEX: &str = "FULLTEXT INDEX";
|
||||||
|
/// Fulltext index v1 type
|
||||||
|
pub(crate) const INDEX_TYPE_FULLTEXT_TANTIVY: &str = "greptime-fulltext-index-v1";
|
||||||
|
/// Fulltext index bloom type
|
||||||
|
pub(crate) const INDEX_TYPE_FULLTEXT_BLOOM: &str = "greptime-fulltext-index-bloom";
|
||||||
|
|
||||||
/// Skipping index constraint name
|
/// Skipping index constraint name
|
||||||
pub(crate) const SKIPPING_INDEX_CONSTRAINT_NAME: &str = "SKIPPING INDEX";
|
pub(crate) const CONSTRAINT_NAME_SKIPPING_INDEX: &str = "SKIPPING INDEX";
|
||||||
|
/// Skipping index type
|
||||||
|
pub(crate) const INDEX_TYPE_SKIPPING_INDEX: &str = "greptime-bloom-filter-v1";
|
||||||
|
|
||||||
/// The virtual table implementation for `information_schema.KEY_COLUMN_USAGE`.
|
/// The virtual table implementation for `information_schema.KEY_COLUMN_USAGE`.
|
||||||
|
///
|
||||||
|
/// Provides an extra column `greptime_index_type` for the index type of the key column.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct InformationSchemaKeyColumnUsage {
|
pub(super) struct InformationSchemaKeyColumnUsage {
|
||||||
schema: SchemaRef,
|
schema: SchemaRef,
|
||||||
@@ -121,6 +138,11 @@ impl InformationSchemaKeyColumnUsage {
|
|||||||
ConcreteDataType::string_datatype(),
|
ConcreteDataType::string_datatype(),
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
ColumnSchema::new(
|
||||||
|
GREPTIME_INDEX_TYPE,
|
||||||
|
ConcreteDataType::string_datatype(),
|
||||||
|
true,
|
||||||
|
),
|
||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +207,7 @@ struct InformationSchemaKeyColumnUsageBuilder {
|
|||||||
column_name: StringVectorBuilder,
|
column_name: StringVectorBuilder,
|
||||||
ordinal_position: UInt32VectorBuilder,
|
ordinal_position: UInt32VectorBuilder,
|
||||||
position_in_unique_constraint: UInt32VectorBuilder,
|
position_in_unique_constraint: UInt32VectorBuilder,
|
||||||
|
greptime_index_type: StringVectorBuilder,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InformationSchemaKeyColumnUsageBuilder {
|
impl InformationSchemaKeyColumnUsageBuilder {
|
||||||
@@ -207,6 +230,7 @@ impl InformationSchemaKeyColumnUsageBuilder {
|
|||||||
column_name: StringVectorBuilder::with_capacity(INIT_CAPACITY),
|
column_name: StringVectorBuilder::with_capacity(INIT_CAPACITY),
|
||||||
ordinal_position: UInt32VectorBuilder::with_capacity(INIT_CAPACITY),
|
ordinal_position: UInt32VectorBuilder::with_capacity(INIT_CAPACITY),
|
||||||
position_in_unique_constraint: UInt32VectorBuilder::with_capacity(INIT_CAPACITY),
|
position_in_unique_constraint: UInt32VectorBuilder::with_capacity(INIT_CAPACITY),
|
||||||
|
greptime_index_type: StringVectorBuilder::with_capacity(INIT_CAPACITY),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,34 +254,47 @@ impl InformationSchemaKeyColumnUsageBuilder {
|
|||||||
|
|
||||||
for (idx, column) in schema.column_schemas().iter().enumerate() {
|
for (idx, column) in schema.column_schemas().iter().enumerate() {
|
||||||
let mut constraints = vec![];
|
let mut constraints = vec![];
|
||||||
|
let mut greptime_index_type = vec![];
|
||||||
if column.is_time_index() {
|
if column.is_time_index() {
|
||||||
self.add_key_column_usage(
|
self.add_key_column_usage(
|
||||||
&predicates,
|
&predicates,
|
||||||
&schema_name,
|
&schema_name,
|
||||||
TIME_INDEX_CONSTRAINT_NAME,
|
CONSTRAINT_NAME_TIME_INDEX,
|
||||||
&catalog_name,
|
&catalog_name,
|
||||||
&schema_name,
|
&schema_name,
|
||||||
table_name,
|
table_name,
|
||||||
&column.name,
|
&column.name,
|
||||||
1, //always 1 for time index
|
1, //always 1 for time index
|
||||||
|
"",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO(dimbtp): foreign key constraint not supported yet
|
// TODO(dimbtp): foreign key constraint not supported yet
|
||||||
if keys.contains(&idx) {
|
if keys.contains(&idx) {
|
||||||
constraints.push(PRI_CONSTRAINT_NAME);
|
constraints.push(CONSTRAINT_NAME_PRI);
|
||||||
|
greptime_index_type.push(INDEX_TYPE_PRI);
|
||||||
}
|
}
|
||||||
if column.is_inverted_indexed() {
|
if column.is_inverted_indexed() {
|
||||||
constraints.push(INVERTED_INDEX_CONSTRAINT_NAME);
|
constraints.push(CONSTRAINT_NAME_INVERTED_INDEX);
|
||||||
|
greptime_index_type.push(INDEX_TYPE_INVERTED_INDEX);
|
||||||
|
}
|
||||||
|
if let Ok(Some(options)) = column.fulltext_options() {
|
||||||
|
if options.enable {
|
||||||
|
constraints.push(CONSTRAINT_NAME_FULLTEXT_INDEX);
|
||||||
|
let index_type = match options.backend {
|
||||||
|
FulltextBackend::Bloom => INDEX_TYPE_FULLTEXT_BLOOM,
|
||||||
|
FulltextBackend::Tantivy => INDEX_TYPE_FULLTEXT_TANTIVY,
|
||||||
|
};
|
||||||
|
greptime_index_type.push(index_type);
|
||||||
}
|
}
|
||||||
if column.is_fulltext_indexed() {
|
|
||||||
constraints.push(FULLTEXT_INDEX_CONSTRAINT_NAME);
|
|
||||||
}
|
}
|
||||||
if column.is_skipping_indexed() {
|
if column.is_skipping_indexed() {
|
||||||
constraints.push(SKIPPING_INDEX_CONSTRAINT_NAME);
|
constraints.push(CONSTRAINT_NAME_SKIPPING_INDEX);
|
||||||
|
greptime_index_type.push(INDEX_TYPE_SKIPPING_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !constraints.is_empty() {
|
if !constraints.is_empty() {
|
||||||
let aggregated_constraints = constraints.join(", ");
|
let aggregated_constraints = constraints.join(", ");
|
||||||
|
let aggregated_index_types = greptime_index_type.join(", ");
|
||||||
self.add_key_column_usage(
|
self.add_key_column_usage(
|
||||||
&predicates,
|
&predicates,
|
||||||
&schema_name,
|
&schema_name,
|
||||||
@@ -267,6 +304,7 @@ impl InformationSchemaKeyColumnUsageBuilder {
|
|||||||
table_name,
|
table_name,
|
||||||
&column.name,
|
&column.name,
|
||||||
idx as u32 + 1,
|
idx as u32 + 1,
|
||||||
|
&aggregated_index_types,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,6 +327,7 @@ impl InformationSchemaKeyColumnUsageBuilder {
|
|||||||
table_name: &str,
|
table_name: &str,
|
||||||
column_name: &str,
|
column_name: &str,
|
||||||
ordinal_position: u32,
|
ordinal_position: u32,
|
||||||
|
index_types: &str,
|
||||||
) {
|
) {
|
||||||
let row = [
|
let row = [
|
||||||
(CONSTRAINT_SCHEMA, &Value::from(constraint_schema)),
|
(CONSTRAINT_SCHEMA, &Value::from(constraint_schema)),
|
||||||
@@ -298,6 +337,7 @@ impl InformationSchemaKeyColumnUsageBuilder {
|
|||||||
(TABLE_NAME, &Value::from(table_name)),
|
(TABLE_NAME, &Value::from(table_name)),
|
||||||
(COLUMN_NAME, &Value::from(column_name)),
|
(COLUMN_NAME, &Value::from(column_name)),
|
||||||
(ORDINAL_POSITION, &Value::from(ordinal_position)),
|
(ORDINAL_POSITION, &Value::from(ordinal_position)),
|
||||||
|
(GREPTIME_INDEX_TYPE, &Value::from(index_types)),
|
||||||
];
|
];
|
||||||
|
|
||||||
if !predicates.eval(&row) {
|
if !predicates.eval(&row) {
|
||||||
@@ -314,6 +354,7 @@ impl InformationSchemaKeyColumnUsageBuilder {
|
|||||||
self.column_name.push(Some(column_name));
|
self.column_name.push(Some(column_name));
|
||||||
self.ordinal_position.push(Some(ordinal_position));
|
self.ordinal_position.push(Some(ordinal_position));
|
||||||
self.position_in_unique_constraint.push(None);
|
self.position_in_unique_constraint.push(None);
|
||||||
|
self.greptime_index_type.push(Some(index_types));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(&mut self) -> Result<RecordBatch> {
|
fn finish(&mut self) -> Result<RecordBatch> {
|
||||||
@@ -337,6 +378,7 @@ impl InformationSchemaKeyColumnUsageBuilder {
|
|||||||
null_string_vector.clone(),
|
null_string_vector.clone(),
|
||||||
null_string_vector.clone(),
|
null_string_vector.clone(),
|
||||||
null_string_vector,
|
null_string_vector,
|
||||||
|
Arc::new(self.greptime_index_type.finish()),
|
||||||
];
|
];
|
||||||
RecordBatch::new(self.schema.clone(), columns).context(CreateRecordBatchSnafu)
|
RecordBatch::new(self.schema.clone(), columns).context(CreateRecordBatchSnafu)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,13 +39,12 @@ use snafu::{OptionExt, ResultExt};
|
|||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
use table::metadata::{TableInfo, TableType};
|
use table::metadata::{TableInfo, TableType};
|
||||||
|
|
||||||
use super::PARTITIONS;
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CreateRecordBatchSnafu, FindPartitionsSnafu, InternalSnafu, PartitionManagerNotFoundSnafu,
|
CreateRecordBatchSnafu, FindPartitionsSnafu, InternalSnafu, PartitionManagerNotFoundSnafu,
|
||||||
Result, UpgradeWeakCatalogManagerRefSnafu,
|
Result, UpgradeWeakCatalogManagerRefSnafu,
|
||||||
};
|
};
|
||||||
use crate::kvbackend::KvBackendCatalogManager;
|
use crate::kvbackend::KvBackendCatalogManager;
|
||||||
use crate::system_schema::information_schema::{InformationTable, Predicates};
|
use crate::system_schema::information_schema::{InformationTable, Predicates, PARTITIONS};
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
const TABLE_CATALOG: &str = "table_catalog";
|
const TABLE_CATALOG: &str = "table_catalog";
|
||||||
|
|||||||
@@ -33,9 +33,8 @@ use datatypes::vectors::{StringVectorBuilder, TimestampMillisecondVectorBuilder}
|
|||||||
use snafu::ResultExt;
|
use snafu::ResultExt;
|
||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
|
|
||||||
use super::PROCEDURE_INFO;
|
|
||||||
use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result};
|
use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result};
|
||||||
use crate::system_schema::information_schema::{InformationTable, Predicates};
|
use crate::system_schema::information_schema::{InformationTable, Predicates, PROCEDURE_INFO};
|
||||||
use crate::system_schema::utils;
|
use crate::system_schema::utils;
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use common_error::ext::BoxedError;
|
|||||||
use common_meta::rpc::router::RegionRoute;
|
use common_meta::rpc::router::RegionRoute;
|
||||||
use common_recordbatch::adapter::RecordBatchStreamAdapter;
|
use common_recordbatch::adapter::RecordBatchStreamAdapter;
|
||||||
use common_recordbatch::{RecordBatch, SendableRecordBatchStream};
|
use common_recordbatch::{RecordBatch, SendableRecordBatchStream};
|
||||||
|
use datafusion::common::HashMap;
|
||||||
use datafusion::execution::TaskContext;
|
use datafusion::execution::TaskContext;
|
||||||
use datafusion::physical_plan::stream::RecordBatchStreamAdapter as DfRecordBatchStreamAdapter;
|
use datafusion::physical_plan::stream::RecordBatchStreamAdapter as DfRecordBatchStreamAdapter;
|
||||||
use datafusion::physical_plan::streaming::PartitionStream as DfPartitionStream;
|
use datafusion::physical_plan::streaming::PartitionStream as DfPartitionStream;
|
||||||
@@ -34,25 +35,30 @@ use snafu::{OptionExt, ResultExt};
|
|||||||
use store_api::storage::{RegionId, ScanRequest, TableId};
|
use store_api::storage::{RegionId, ScanRequest, TableId};
|
||||||
use table::metadata::TableType;
|
use table::metadata::TableType;
|
||||||
|
|
||||||
use super::REGION_PEERS;
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CreateRecordBatchSnafu, FindRegionRoutesSnafu, InternalSnafu, Result,
|
CreateRecordBatchSnafu, FindRegionRoutesSnafu, InternalSnafu, Result,
|
||||||
UpgradeWeakCatalogManagerRefSnafu,
|
UpgradeWeakCatalogManagerRefSnafu,
|
||||||
};
|
};
|
||||||
use crate::kvbackend::KvBackendCatalogManager;
|
use crate::kvbackend::KvBackendCatalogManager;
|
||||||
use crate::system_schema::information_schema::{InformationTable, Predicates};
|
use crate::system_schema::information_schema::{InformationTable, Predicates, REGION_PEERS};
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
const REGION_ID: &str = "region_id";
|
pub const TABLE_CATALOG: &str = "table_catalog";
|
||||||
const PEER_ID: &str = "peer_id";
|
pub const TABLE_SCHEMA: &str = "table_schema";
|
||||||
|
pub const TABLE_NAME: &str = "table_name";
|
||||||
|
pub const REGION_ID: &str = "region_id";
|
||||||
|
pub const PEER_ID: &str = "peer_id";
|
||||||
const PEER_ADDR: &str = "peer_addr";
|
const PEER_ADDR: &str = "peer_addr";
|
||||||
const IS_LEADER: &str = "is_leader";
|
pub const IS_LEADER: &str = "is_leader";
|
||||||
const STATUS: &str = "status";
|
const STATUS: &str = "status";
|
||||||
const DOWN_SECONDS: &str = "down_seconds";
|
const DOWN_SECONDS: &str = "down_seconds";
|
||||||
const INIT_CAPACITY: usize = 42;
|
const INIT_CAPACITY: usize = 42;
|
||||||
|
|
||||||
/// The `REGION_PEERS` table provides information about the region distribution and routes. Including fields:
|
/// The `REGION_PEERS` table provides information about the region distribution and routes. Including fields:
|
||||||
///
|
///
|
||||||
|
/// - `table_catalog`: the table catalog name
|
||||||
|
/// - `table_schema`: the table schema name
|
||||||
|
/// - `table_name`: the table name
|
||||||
/// - `region_id`: the region id
|
/// - `region_id`: the region id
|
||||||
/// - `peer_id`: the region storage datanode peer id
|
/// - `peer_id`: the region storage datanode peer id
|
||||||
/// - `peer_addr`: the region storage datanode gRPC peer address
|
/// - `peer_addr`: the region storage datanode gRPC peer address
|
||||||
@@ -77,6 +83,9 @@ impl InformationSchemaRegionPeers {
|
|||||||
|
|
||||||
pub(crate) fn schema() -> SchemaRef {
|
pub(crate) fn schema() -> SchemaRef {
|
||||||
Arc::new(Schema::new(vec![
|
Arc::new(Schema::new(vec![
|
||||||
|
ColumnSchema::new(TABLE_CATALOG, ConcreteDataType::string_datatype(), false),
|
||||||
|
ColumnSchema::new(TABLE_SCHEMA, ConcreteDataType::string_datatype(), false),
|
||||||
|
ColumnSchema::new(TABLE_NAME, ConcreteDataType::string_datatype(), false),
|
||||||
ColumnSchema::new(REGION_ID, ConcreteDataType::uint64_datatype(), false),
|
ColumnSchema::new(REGION_ID, ConcreteDataType::uint64_datatype(), false),
|
||||||
ColumnSchema::new(PEER_ID, ConcreteDataType::uint64_datatype(), true),
|
ColumnSchema::new(PEER_ID, ConcreteDataType::uint64_datatype(), true),
|
||||||
ColumnSchema::new(PEER_ADDR, ConcreteDataType::string_datatype(), true),
|
ColumnSchema::new(PEER_ADDR, ConcreteDataType::string_datatype(), true),
|
||||||
@@ -134,6 +143,9 @@ struct InformationSchemaRegionPeersBuilder {
|
|||||||
catalog_name: String,
|
catalog_name: String,
|
||||||
catalog_manager: Weak<dyn CatalogManager>,
|
catalog_manager: Weak<dyn CatalogManager>,
|
||||||
|
|
||||||
|
table_catalogs: StringVectorBuilder,
|
||||||
|
table_schemas: StringVectorBuilder,
|
||||||
|
table_names: StringVectorBuilder,
|
||||||
region_ids: UInt64VectorBuilder,
|
region_ids: UInt64VectorBuilder,
|
||||||
peer_ids: UInt64VectorBuilder,
|
peer_ids: UInt64VectorBuilder,
|
||||||
peer_addrs: StringVectorBuilder,
|
peer_addrs: StringVectorBuilder,
|
||||||
@@ -152,6 +164,9 @@ impl InformationSchemaRegionPeersBuilder {
|
|||||||
schema,
|
schema,
|
||||||
catalog_name,
|
catalog_name,
|
||||||
catalog_manager,
|
catalog_manager,
|
||||||
|
table_catalogs: StringVectorBuilder::with_capacity(INIT_CAPACITY),
|
||||||
|
table_schemas: StringVectorBuilder::with_capacity(INIT_CAPACITY),
|
||||||
|
table_names: StringVectorBuilder::with_capacity(INIT_CAPACITY),
|
||||||
region_ids: UInt64VectorBuilder::with_capacity(INIT_CAPACITY),
|
region_ids: UInt64VectorBuilder::with_capacity(INIT_CAPACITY),
|
||||||
peer_ids: UInt64VectorBuilder::with_capacity(INIT_CAPACITY),
|
peer_ids: UInt64VectorBuilder::with_capacity(INIT_CAPACITY),
|
||||||
peer_addrs: StringVectorBuilder::with_capacity(INIT_CAPACITY),
|
peer_addrs: StringVectorBuilder::with_capacity(INIT_CAPACITY),
|
||||||
@@ -177,24 +192,28 @@ impl InformationSchemaRegionPeersBuilder {
|
|||||||
let predicates = Predicates::from_scan_request(&request);
|
let predicates = Predicates::from_scan_request(&request);
|
||||||
|
|
||||||
for schema_name in catalog_manager.schema_names(&catalog_name, None).await? {
|
for schema_name in catalog_manager.schema_names(&catalog_name, None).await? {
|
||||||
let table_id_stream = catalog_manager
|
let table_stream = catalog_manager
|
||||||
.tables(&catalog_name, &schema_name, None)
|
.tables(&catalog_name, &schema_name, None)
|
||||||
.try_filter_map(|t| async move {
|
.try_filter_map(|t| async move {
|
||||||
let table_info = t.table_info();
|
let table_info = t.table_info();
|
||||||
if table_info.table_type == TableType::Temporary {
|
if table_info.table_type == TableType::Temporary {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(table_info.ident.table_id))
|
Ok(Some((
|
||||||
|
table_info.ident.table_id,
|
||||||
|
table_info.name.to_string(),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const BATCH_SIZE: usize = 128;
|
const BATCH_SIZE: usize = 128;
|
||||||
|
|
||||||
// Split table ids into chunks
|
// Split tables into chunks
|
||||||
let mut table_id_chunks = pin!(table_id_stream.ready_chunks(BATCH_SIZE));
|
let mut table_chunks = pin!(table_stream.ready_chunks(BATCH_SIZE));
|
||||||
|
|
||||||
while let Some(table_ids) = table_id_chunks.next().await {
|
while let Some(tables) = table_chunks.next().await {
|
||||||
let table_ids = table_ids.into_iter().collect::<Result<Vec<_>>>()?;
|
let tables = tables.into_iter().collect::<Result<HashMap<_, _>>>()?;
|
||||||
|
let table_ids = tables.keys().cloned().collect::<Vec<_>>();
|
||||||
|
|
||||||
let table_routes = if let Some(partition_manager) = &partition_manager {
|
let table_routes = if let Some(partition_manager) = &partition_manager {
|
||||||
partition_manager
|
partition_manager
|
||||||
@@ -206,7 +225,16 @@ impl InformationSchemaRegionPeersBuilder {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (table_id, routes) in table_routes {
|
for (table_id, routes) in table_routes {
|
||||||
self.add_region_peers(&predicates, table_id, &routes);
|
// Safety: table_id is guaranteed to be in the map
|
||||||
|
let table_name = tables.get(&table_id).unwrap();
|
||||||
|
self.add_region_peers(
|
||||||
|
&catalog_name,
|
||||||
|
&schema_name,
|
||||||
|
table_name,
|
||||||
|
&predicates,
|
||||||
|
table_id,
|
||||||
|
&routes,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,6 +244,9 @@ impl InformationSchemaRegionPeersBuilder {
|
|||||||
|
|
||||||
fn add_region_peers(
|
fn add_region_peers(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
table_catalog: &str,
|
||||||
|
table_schema: &str,
|
||||||
|
table_name: &str,
|
||||||
predicates: &Predicates,
|
predicates: &Predicates,
|
||||||
table_id: TableId,
|
table_id: TableId,
|
||||||
routes: &[RegionRoute],
|
routes: &[RegionRoute],
|
||||||
@@ -231,13 +262,20 @@ impl InformationSchemaRegionPeersBuilder {
|
|||||||
Some("ALIVE".to_string())
|
Some("ALIVE".to_string())
|
||||||
};
|
};
|
||||||
|
|
||||||
let row = [(REGION_ID, &Value::from(region_id))];
|
let row = [
|
||||||
|
(TABLE_CATALOG, &Value::from(table_catalog)),
|
||||||
|
(TABLE_SCHEMA, &Value::from(table_schema)),
|
||||||
|
(TABLE_NAME, &Value::from(table_name)),
|
||||||
|
(REGION_ID, &Value::from(region_id)),
|
||||||
|
];
|
||||||
|
|
||||||
if !predicates.eval(&row) {
|
if !predicates.eval(&row) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(dennis): adds followers.
|
self.table_catalogs.push(Some(table_catalog));
|
||||||
|
self.table_schemas.push(Some(table_schema));
|
||||||
|
self.table_names.push(Some(table_name));
|
||||||
self.region_ids.push(Some(region_id));
|
self.region_ids.push(Some(region_id));
|
||||||
self.peer_ids.push(peer_id);
|
self.peer_ids.push(peer_id);
|
||||||
self.peer_addrs.push(peer_addr.as_deref());
|
self.peer_addrs.push(peer_addr.as_deref());
|
||||||
@@ -245,11 +283,26 @@ impl InformationSchemaRegionPeersBuilder {
|
|||||||
self.statuses.push(state.as_deref());
|
self.statuses.push(state.as_deref());
|
||||||
self.down_seconds
|
self.down_seconds
|
||||||
.push(route.leader_down_millis().map(|m| m / 1000));
|
.push(route.leader_down_millis().map(|m| m / 1000));
|
||||||
|
|
||||||
|
for follower in &route.follower_peers {
|
||||||
|
self.table_catalogs.push(Some(table_catalog));
|
||||||
|
self.table_schemas.push(Some(table_schema));
|
||||||
|
self.table_names.push(Some(table_name));
|
||||||
|
self.region_ids.push(Some(region_id));
|
||||||
|
self.peer_ids.push(Some(follower.id));
|
||||||
|
self.peer_addrs.push(Some(follower.addr.as_str()));
|
||||||
|
self.is_leaders.push(Some("No"));
|
||||||
|
self.statuses.push(None);
|
||||||
|
self.down_seconds.push(None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(&mut self) -> Result<RecordBatch> {
|
fn finish(&mut self) -> Result<RecordBatch> {
|
||||||
let columns: Vec<VectorRef> = vec![
|
let columns: Vec<VectorRef> = vec![
|
||||||
|
Arc::new(self.table_catalogs.finish()),
|
||||||
|
Arc::new(self.table_schemas.finish()),
|
||||||
|
Arc::new(self.table_names.finish()),
|
||||||
Arc::new(self.region_ids.finish()),
|
Arc::new(self.region_ids.finish()),
|
||||||
Arc::new(self.peer_ids.finish()),
|
Arc::new(self.peer_ids.finish()),
|
||||||
Arc::new(self.peer_addrs.finish()),
|
Arc::new(self.peer_addrs.finish()),
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ use datatypes::vectors::{StringVectorBuilder, UInt32VectorBuilder, UInt64VectorB
|
|||||||
use snafu::ResultExt;
|
use snafu::ResultExt;
|
||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
|
|
||||||
use super::{InformationTable, REGION_STATISTICS};
|
|
||||||
use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result};
|
use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result};
|
||||||
use crate::information_schema::Predicates;
|
use crate::information_schema::Predicates;
|
||||||
|
use crate::system_schema::information_schema::{InformationTable, REGION_STATISTICS};
|
||||||
use crate::system_schema::utils;
|
use crate::system_schema::utils;
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ use itertools::Itertools;
|
|||||||
use snafu::ResultExt;
|
use snafu::ResultExt;
|
||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
|
|
||||||
use super::{InformationTable, RUNTIME_METRICS};
|
|
||||||
use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result};
|
use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result};
|
||||||
|
use crate::system_schema::information_schema::{InformationTable, RUNTIME_METRICS};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct InformationSchemaMetrics {
|
pub(super) struct InformationSchemaMetrics {
|
||||||
|
|||||||
@@ -31,12 +31,11 @@ use datatypes::vectors::StringVectorBuilder;
|
|||||||
use snafu::{OptionExt, ResultExt};
|
use snafu::{OptionExt, ResultExt};
|
||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
|
|
||||||
use super::SCHEMATA;
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CreateRecordBatchSnafu, InternalSnafu, Result, TableMetadataManagerSnafu,
|
CreateRecordBatchSnafu, InternalSnafu, Result, TableMetadataManagerSnafu,
|
||||||
UpgradeWeakCatalogManagerRefSnafu,
|
UpgradeWeakCatalogManagerRefSnafu,
|
||||||
};
|
};
|
||||||
use crate::system_schema::information_schema::{InformationTable, Predicates};
|
use crate::system_schema::information_schema::{InformationTable, Predicates, SCHEMATA};
|
||||||
use crate::system_schema::utils;
|
use crate::system_schema::utils;
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ use futures::TryStreamExt;
|
|||||||
use snafu::{OptionExt, ResultExt};
|
use snafu::{OptionExt, ResultExt};
|
||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
|
|
||||||
use super::{InformationTable, TABLE_CONSTRAINTS};
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
||||||
};
|
};
|
||||||
use crate::information_schema::key_column_usage::{
|
use crate::information_schema::key_column_usage::{
|
||||||
PRI_CONSTRAINT_NAME, TIME_INDEX_CONSTRAINT_NAME,
|
CONSTRAINT_NAME_PRI, CONSTRAINT_NAME_TIME_INDEX,
|
||||||
};
|
};
|
||||||
use crate::information_schema::Predicates;
|
use crate::information_schema::Predicates;
|
||||||
|
use crate::system_schema::information_schema::{InformationTable, TABLE_CONSTRAINTS};
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
/// The `TABLE_CONSTRAINTS` table describes which tables have constraints.
|
/// The `TABLE_CONSTRAINTS` table describes which tables have constraints.
|
||||||
@@ -188,7 +188,7 @@ impl InformationSchemaTableConstraintsBuilder {
|
|||||||
self.add_table_constraint(
|
self.add_table_constraint(
|
||||||
&predicates,
|
&predicates,
|
||||||
&schema_name,
|
&schema_name,
|
||||||
TIME_INDEX_CONSTRAINT_NAME,
|
CONSTRAINT_NAME_TIME_INDEX,
|
||||||
&schema_name,
|
&schema_name,
|
||||||
&table.table_info().name,
|
&table.table_info().name,
|
||||||
TIME_INDEX_CONSTRAINT_TYPE,
|
TIME_INDEX_CONSTRAINT_TYPE,
|
||||||
@@ -199,7 +199,7 @@ impl InformationSchemaTableConstraintsBuilder {
|
|||||||
self.add_table_constraint(
|
self.add_table_constraint(
|
||||||
&predicates,
|
&predicates,
|
||||||
&schema_name,
|
&schema_name,
|
||||||
PRI_CONSTRAINT_NAME,
|
CONSTRAINT_NAME_PRI,
|
||||||
&schema_name,
|
&schema_name,
|
||||||
&table.table_info().name,
|
&table.table_info().name,
|
||||||
PRI_KEY_CONSTRAINT_TYPE,
|
PRI_KEY_CONSTRAINT_TYPE,
|
||||||
|
|||||||
@@ -38,11 +38,10 @@ use snafu::{OptionExt, ResultExt};
|
|||||||
use store_api::storage::{RegionId, ScanRequest, TableId};
|
use store_api::storage::{RegionId, ScanRequest, TableId};
|
||||||
use table::metadata::{TableInfo, TableType};
|
use table::metadata::{TableInfo, TableType};
|
||||||
|
|
||||||
use super::TABLES;
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
||||||
};
|
};
|
||||||
use crate::system_schema::information_schema::{InformationTable, Predicates};
|
use crate::system_schema::information_schema::{InformationTable, Predicates, TABLES};
|
||||||
use crate::system_schema::utils;
|
use crate::system_schema::utils;
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
|
|||||||
@@ -32,13 +32,12 @@ use snafu::{OptionExt, ResultExt};
|
|||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
use table::metadata::TableType;
|
use table::metadata::TableType;
|
||||||
|
|
||||||
use super::VIEWS;
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CastManagerSnafu, CreateRecordBatchSnafu, GetViewCacheSnafu, InternalSnafu, Result,
|
CastManagerSnafu, CreateRecordBatchSnafu, GetViewCacheSnafu, InternalSnafu, Result,
|
||||||
UpgradeWeakCatalogManagerRefSnafu, ViewInfoNotFoundSnafu,
|
UpgradeWeakCatalogManagerRefSnafu, ViewInfoNotFoundSnafu,
|
||||||
};
|
};
|
||||||
use crate::kvbackend::KvBackendCatalogManager;
|
use crate::kvbackend::KvBackendCatalogManager;
|
||||||
use crate::system_schema::information_schema::{InformationTable, Predicates};
|
use crate::system_schema::information_schema::{InformationTable, Predicates, VIEWS};
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
const INIT_CAPACITY: usize = 42;
|
const INIT_CAPACITY: usize = 42;
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ use datatypes::vectors::VectorRef;
|
|||||||
use snafu::ResultExt;
|
use snafu::ResultExt;
|
||||||
use store_api::storage::{ScanRequest, TableId};
|
use store_api::storage::{ScanRequest, TableId};
|
||||||
|
|
||||||
use super::SystemTable;
|
|
||||||
use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result};
|
use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result};
|
||||||
|
use crate::system_schema::SystemTable;
|
||||||
|
|
||||||
/// A memory table with specified schema and columns.
|
/// A memory table with specified schema and columns.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ use table::TableRef;
|
|||||||
pub use table_names::*;
|
pub use table_names::*;
|
||||||
|
|
||||||
use self::pg_namespace::oid_map::{PGNamespaceOidMap, PGNamespaceOidMapRef};
|
use self::pg_namespace::oid_map::{PGNamespaceOidMap, PGNamespaceOidMapRef};
|
||||||
use super::memory_table::MemoryTable;
|
use crate::system_schema::memory_table::MemoryTable;
|
||||||
use super::utils::tables::u32_column;
|
use crate::system_schema::utils::tables::u32_column;
|
||||||
use super::{SystemSchemaProvider, SystemSchemaProviderInner, SystemTableRef};
|
use crate::system_schema::{SystemSchemaProvider, SystemSchemaProviderInner, SystemTableRef};
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ use std::sync::Arc;
|
|||||||
use datatypes::schema::{ColumnSchema, Schema, SchemaRef};
|
use datatypes::schema::{ColumnSchema, Schema, SchemaRef};
|
||||||
use datatypes::vectors::{Int16Vector, StringVector, UInt32Vector, VectorRef};
|
use datatypes::vectors::{Int16Vector, StringVector, UInt32Vector, VectorRef};
|
||||||
|
|
||||||
use super::oid_column;
|
|
||||||
use super::table_names::PG_TYPE;
|
|
||||||
use crate::memory_table_cols;
|
use crate::memory_table_cols;
|
||||||
|
use crate::system_schema::pg_catalog::oid_column;
|
||||||
|
use crate::system_schema::pg_catalog::table_names::PG_TYPE;
|
||||||
use crate::system_schema::utils::tables::{i16_column, string_column};
|
use crate::system_schema::utils::tables::{i16_column, string_column};
|
||||||
|
|
||||||
fn pg_type_schema_columns() -> (Vec<ColumnSchema>, Vec<VectorRef>) {
|
fn pg_type_schema_columns() -> (Vec<ColumnSchema>, Vec<VectorRef>) {
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ use snafu::{OptionExt, ResultExt};
|
|||||||
use store_api::storage::ScanRequest;
|
use store_api::storage::ScanRequest;
|
||||||
use table::metadata::TableType;
|
use table::metadata::TableType;
|
||||||
|
|
||||||
use super::pg_namespace::oid_map::PGNamespaceOidMapRef;
|
|
||||||
use super::{query_ctx, OID_COLUMN_NAME, PG_CLASS};
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
||||||
};
|
};
|
||||||
use crate::information_schema::Predicates;
|
use crate::information_schema::Predicates;
|
||||||
|
use crate::system_schema::pg_catalog::pg_namespace::oid_map::PGNamespaceOidMapRef;
|
||||||
|
use crate::system_schema::pg_catalog::{query_ctx, OID_COLUMN_NAME, PG_CLASS};
|
||||||
use crate::system_schema::utils::tables::{string_column, u32_column};
|
use crate::system_schema::utils::tables::{string_column, u32_column};
|
||||||
use crate::system_schema::SystemTable;
|
use crate::system_schema::SystemTable;
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ use datatypes::vectors::{StringVectorBuilder, UInt32VectorBuilder, VectorRef};
|
|||||||
use snafu::{OptionExt, ResultExt};
|
use snafu::{OptionExt, ResultExt};
|
||||||
use store_api::storage::ScanRequest;
|
use store_api::storage::ScanRequest;
|
||||||
|
|
||||||
use super::pg_namespace::oid_map::PGNamespaceOidMapRef;
|
|
||||||
use super::{query_ctx, OID_COLUMN_NAME, PG_DATABASE};
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
||||||
};
|
};
|
||||||
use crate::information_schema::Predicates;
|
use crate::information_schema::Predicates;
|
||||||
|
use crate::system_schema::pg_catalog::pg_namespace::oid_map::PGNamespaceOidMapRef;
|
||||||
|
use crate::system_schema::pg_catalog::{query_ctx, OID_COLUMN_NAME, PG_DATABASE};
|
||||||
use crate::system_schema::utils::tables::{string_column, u32_column};
|
use crate::system_schema::utils::tables::{string_column, u32_column};
|
||||||
use crate::system_schema::SystemTable;
|
use crate::system_schema::SystemTable;
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|||||||
@@ -35,11 +35,13 @@ use datatypes::vectors::{StringVectorBuilder, UInt32VectorBuilder, VectorRef};
|
|||||||
use snafu::{OptionExt, ResultExt};
|
use snafu::{OptionExt, ResultExt};
|
||||||
use store_api::storage::ScanRequest;
|
use store_api::storage::ScanRequest;
|
||||||
|
|
||||||
use super::{query_ctx, PGNamespaceOidMapRef, OID_COLUMN_NAME, PG_NAMESPACE};
|
|
||||||
use crate::error::{
|
use crate::error::{
|
||||||
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
CreateRecordBatchSnafu, InternalSnafu, Result, UpgradeWeakCatalogManagerRefSnafu,
|
||||||
};
|
};
|
||||||
use crate::information_schema::Predicates;
|
use crate::information_schema::Predicates;
|
||||||
|
use crate::system_schema::pg_catalog::{
|
||||||
|
query_ctx, PGNamespaceOidMapRef, OID_COLUMN_NAME, PG_NAMESPACE,
|
||||||
|
};
|
||||||
use crate::system_schema::utils::tables::{string_column, u32_column};
|
use crate::system_schema::utils::tables::{string_column, u32_column};
|
||||||
use crate::system_schema::SystemTable;
|
use crate::system_schema::SystemTable;
|
||||||
use crate::CatalogManager;
|
use crate::CatalogManager;
|
||||||
|
|||||||
@@ -84,12 +84,6 @@ mod tests {
|
|||||||
let key1 = "3178510";
|
let key1 = "3178510";
|
||||||
let key2 = "4215648";
|
let key2 = "4215648";
|
||||||
|
|
||||||
// have collision
|
|
||||||
assert_eq!(
|
|
||||||
oid_map.hasher.hash_one(key1) as u32,
|
|
||||||
oid_map.hasher.hash_one(key2) as u32
|
|
||||||
);
|
|
||||||
|
|
||||||
// insert them into oid_map
|
// insert them into oid_map
|
||||||
let oid1 = oid_map.get_oid(key1);
|
let oid1 = oid_map.get_oid(key1);
|
||||||
let oid2 = oid_map.get_oid(key2);
|
let oid2 = oid_map.get_oid(key2);
|
||||||
|
|||||||
@@ -437,10 +437,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn column(name: &str) -> Expr {
|
fn column(name: &str) -> Expr {
|
||||||
Expr::Column(Column {
|
Expr::Column(Column::from_name(name))
|
||||||
relation: None,
|
|
||||||
name: name.to_string(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn string_literal(v: &str) -> Expr {
|
fn string_literal(v: &str) -> Expr {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use session::context::QueryContextRef;
|
|||||||
use snafu::{ensure, OptionExt, ResultExt};
|
use snafu::{ensure, OptionExt, ResultExt};
|
||||||
use table::metadata::TableType;
|
use table::metadata::TableType;
|
||||||
use table::table::adapter::DfTableProviderAdapter;
|
use table::table::adapter::DfTableProviderAdapter;
|
||||||
mod dummy_catalog;
|
pub mod dummy_catalog;
|
||||||
use dummy_catalog::DummyCatalogList;
|
use dummy_catalog::DummyCatalogList;
|
||||||
use table::TableRef;
|
use table::TableRef;
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,12 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
pg_kvbackend = ["common-meta/pg_kvbackend"]
|
default = [
|
||||||
mysql_kvbackend = ["common-meta/mysql_kvbackend"]
|
"pg_kvbackend",
|
||||||
|
"mysql_kvbackend",
|
||||||
|
]
|
||||||
|
pg_kvbackend = ["common-meta/pg_kvbackend", "meta-srv/pg_kvbackend"]
|
||||||
|
mysql_kvbackend = ["common-meta/mysql_kvbackend", "meta-srv/mysql_kvbackend"]
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
@@ -43,15 +47,12 @@ etcd-client.workspace = true
|
|||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
humantime.workspace = true
|
humantime.workspace = true
|
||||||
meta-client.workspace = true
|
meta-client.workspace = true
|
||||||
|
meta-srv.workspace = true
|
||||||
nu-ansi-term = "0.46"
|
nu-ansi-term = "0.46"
|
||||||
opendal = { version = "0.51.1", features = [
|
object-store.workspace = true
|
||||||
"services-fs",
|
|
||||||
"services-s3",
|
|
||||||
] }
|
|
||||||
query.workspace = true
|
query.workspace = true
|
||||||
rand.workspace = true
|
rand.workspace = true
|
||||||
reqwest.workspace = true
|
reqwest.workspace = true
|
||||||
rustyline = "10.1"
|
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
servers.workspace = true
|
servers.workspace = true
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ where
|
|||||||
info!("{desc}, average operation cost: {cost:.2} ms");
|
info!("{desc}, average operation cost: {cost:.2} ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Command to benchmark table metadata operations.
|
||||||
#[derive(Debug, Default, Parser)]
|
#[derive(Debug, Default, Parser)]
|
||||||
pub struct BenchTableMetadataCommand {
|
pub struct BenchTableMetadataCommand {
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
@@ -177,7 +178,7 @@ fn create_table_info(table_id: TableId, table_name: TableName) -> RawTableInfo {
|
|||||||
|
|
||||||
fn create_region_routes(regions: Vec<RegionNumber>) -> Vec<RegionRoute> {
|
fn create_region_routes(regions: Vec<RegionNumber>) -> Vec<RegionRoute> {
|
||||||
let mut region_routes = Vec::with_capacity(100);
|
let mut region_routes = Vec::with_capacity(100);
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
for region_id in regions.into_iter().map(u64::from) {
|
for region_id in regions.into_iter().map(u64::from) {
|
||||||
region_routes.push(RegionRoute {
|
region_routes.push(RegionRoute {
|
||||||
@@ -188,7 +189,7 @@ fn create_region_routes(regions: Vec<RegionNumber>) -> Vec<RegionRoute> {
|
|||||||
attrs: BTreeMap::new(),
|
attrs: BTreeMap::new(),
|
||||||
},
|
},
|
||||||
leader_peer: Some(Peer {
|
leader_peer: Some(Peer {
|
||||||
id: rng.gen_range(0..10),
|
id: rng.random_range(0..10),
|
||||||
addr: String::new(),
|
addr: String::new(),
|
||||||
}),
|
}),
|
||||||
follower_peers: vec![],
|
follower_peers: vec![],
|
||||||
|
|||||||
@@ -1,154 +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 crate::error::{Error, InvalidReplCommandSnafu, Result};
|
|
||||||
|
|
||||||
/// Represents the parsed command from the user (which may be over many lines)
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub(crate) enum ReplCommand {
|
|
||||||
Help,
|
|
||||||
UseDatabase { db_name: String },
|
|
||||||
Sql { sql: String },
|
|
||||||
Exit,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<&str> for ReplCommand {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn try_from(input: &str) -> Result<Self> {
|
|
||||||
let input = input.trim();
|
|
||||||
if input.is_empty() {
|
|
||||||
return InvalidReplCommandSnafu {
|
|
||||||
reason: "No command specified".to_string(),
|
|
||||||
}
|
|
||||||
.fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If line ends with ';', it must be treated as a complete input.
|
|
||||||
// However, the opposite is not true.
|
|
||||||
let input_is_completed = input.ends_with(';');
|
|
||||||
|
|
||||||
let input = input.strip_suffix(';').map(|x| x.trim()).unwrap_or(input);
|
|
||||||
let lowercase = input.to_lowercase();
|
|
||||||
match lowercase.as_str() {
|
|
||||||
"help" => Ok(Self::Help),
|
|
||||||
"exit" | "quit" => Ok(Self::Exit),
|
|
||||||
_ => match input.split_once(' ') {
|
|
||||||
Some((maybe_use, database)) if maybe_use.to_lowercase() == "use" => {
|
|
||||||
Ok(Self::UseDatabase {
|
|
||||||
db_name: database.trim().to_string(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// Any valid SQL must contains at least one whitespace.
|
|
||||||
Some(_) if input_is_completed => Ok(Self::Sql {
|
|
||||||
sql: input.to_string(),
|
|
||||||
}),
|
|
||||||
_ => InvalidReplCommandSnafu {
|
|
||||||
reason: format!("unknown command '{input}', maybe input is not completed"),
|
|
||||||
}
|
|
||||||
.fail(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ReplCommand {
|
|
||||||
pub fn help() -> &'static str {
|
|
||||||
r#"
|
|
||||||
Available commands (case insensitive):
|
|
||||||
- 'help': print this help
|
|
||||||
- 'exit' or 'quit': exit the REPL
|
|
||||||
- 'use <your database name>': switch to another database/schema context
|
|
||||||
- Other typed in text will be treated as SQL.
|
|
||||||
You can enter new line while typing, just remember to end it with ';'.
|
|
||||||
"#
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use crate::error::Error::InvalidReplCommand;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_from_str() {
|
|
||||||
fn test_ok(s: &str, expected: ReplCommand) {
|
|
||||||
let actual: ReplCommand = s.try_into().unwrap();
|
|
||||||
assert_eq!(expected, actual, "'{}'", s);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_err(s: &str) {
|
|
||||||
let result: Result<ReplCommand> = s.try_into();
|
|
||||||
assert!(matches!(result, Err(InvalidReplCommand { .. })))
|
|
||||||
}
|
|
||||||
|
|
||||||
test_err("");
|
|
||||||
test_err(" ");
|
|
||||||
test_err("\t");
|
|
||||||
|
|
||||||
test_ok("help", ReplCommand::Help);
|
|
||||||
test_ok("help", ReplCommand::Help);
|
|
||||||
test_ok(" help", ReplCommand::Help);
|
|
||||||
test_ok(" help ", ReplCommand::Help);
|
|
||||||
test_ok(" HELP ", ReplCommand::Help);
|
|
||||||
test_ok(" Help; ", ReplCommand::Help);
|
|
||||||
test_ok(" help ; ", ReplCommand::Help);
|
|
||||||
|
|
||||||
test_ok("exit", ReplCommand::Exit);
|
|
||||||
test_ok("exit;", ReplCommand::Exit);
|
|
||||||
test_ok("exit ;", ReplCommand::Exit);
|
|
||||||
test_ok("EXIT", ReplCommand::Exit);
|
|
||||||
|
|
||||||
test_ok("quit", ReplCommand::Exit);
|
|
||||||
test_ok("quit;", ReplCommand::Exit);
|
|
||||||
test_ok("quit ;", ReplCommand::Exit);
|
|
||||||
test_ok("QUIT", ReplCommand::Exit);
|
|
||||||
|
|
||||||
test_ok(
|
|
||||||
"use Foo",
|
|
||||||
ReplCommand::UseDatabase {
|
|
||||||
db_name: "Foo".to_string(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
test_ok(
|
|
||||||
" use Foo ; ",
|
|
||||||
ReplCommand::UseDatabase {
|
|
||||||
db_name: "Foo".to_string(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
// ensure that database name is case sensitive
|
|
||||||
test_ok(
|
|
||||||
" use FOO ; ",
|
|
||||||
ReplCommand::UseDatabase {
|
|
||||||
db_name: "FOO".to_string(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// ensure that we aren't messing with capitalization
|
|
||||||
test_ok(
|
|
||||||
"SELECT * from foo;",
|
|
||||||
ReplCommand::Sql {
|
|
||||||
sql: "SELECT * from foo".to_string(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
// Input line (that don't belong to any other cases above) must ends with ';' to make it a valid SQL.
|
|
||||||
test_err("insert blah");
|
|
||||||
test_ok(
|
|
||||||
"insert blah;",
|
|
||||||
ReplCommand::Sql {
|
|
||||||
sql: "insert blah".to_string(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,7 @@ use std::any::Any;
|
|||||||
use common_error::ext::{BoxedError, ErrorExt};
|
use common_error::ext::{BoxedError, ErrorExt};
|
||||||
use common_error::status_code::StatusCode;
|
use common_error::status_code::StatusCode;
|
||||||
use common_macro::stack_trace_debug;
|
use common_macro::stack_trace_debug;
|
||||||
use rustyline::error::ReadlineError;
|
use object_store::Error as ObjectStoreError;
|
||||||
use snafu::{Location, Snafu};
|
use snafu::{Location, Snafu};
|
||||||
|
|
||||||
#[derive(Snafu)]
|
#[derive(Snafu)]
|
||||||
@@ -102,55 +102,6 @@ pub enum Error {
|
|||||||
error: reqwest::Error,
|
error: reqwest::Error,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[snafu(display("Invalid REPL command: {reason}"))]
|
|
||||||
InvalidReplCommand { reason: String },
|
|
||||||
|
|
||||||
#[snafu(display("Cannot create REPL"))]
|
|
||||||
ReplCreation {
|
|
||||||
#[snafu(source)]
|
|
||||||
error: ReadlineError,
|
|
||||||
#[snafu(implicit)]
|
|
||||||
location: Location,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[snafu(display("Error reading command"))]
|
|
||||||
Readline {
|
|
||||||
#[snafu(source)]
|
|
||||||
error: ReadlineError,
|
|
||||||
#[snafu(implicit)]
|
|
||||||
location: Location,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[snafu(display("Failed to request database, sql: {sql}"))]
|
|
||||||
RequestDatabase {
|
|
||||||
sql: String,
|
|
||||||
#[snafu(source)]
|
|
||||||
source: client::Error,
|
|
||||||
#[snafu(implicit)]
|
|
||||||
location: Location,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[snafu(display("Failed to collect RecordBatches"))]
|
|
||||||
CollectRecordBatches {
|
|
||||||
#[snafu(implicit)]
|
|
||||||
location: Location,
|
|
||||||
source: common_recordbatch::error::Error,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[snafu(display("Failed to pretty print Recordbatches"))]
|
|
||||||
PrettyPrintRecordBatches {
|
|
||||||
#[snafu(implicit)]
|
|
||||||
location: Location,
|
|
||||||
source: common_recordbatch::error::Error,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[snafu(display("Failed to start Meta client"))]
|
|
||||||
StartMetaClient {
|
|
||||||
#[snafu(implicit)]
|
|
||||||
location: Location,
|
|
||||||
source: meta_client::error::Error,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[snafu(display("Failed to parse SQL: {}", sql))]
|
#[snafu(display("Failed to parse SQL: {}", sql))]
|
||||||
ParseSql {
|
ParseSql {
|
||||||
sql: String,
|
sql: String,
|
||||||
@@ -166,13 +117,6 @@ pub enum Error {
|
|||||||
source: query::error::Error,
|
source: query::error::Error,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[snafu(display("Failed to encode logical plan in substrait"))]
|
|
||||||
SubstraitEncodeLogicalPlan {
|
|
||||||
#[snafu(implicit)]
|
|
||||||
location: Location,
|
|
||||||
source: substrait::error::Error,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[snafu(display("Failed to load layered config"))]
|
#[snafu(display("Failed to load layered config"))]
|
||||||
LoadLayeredConfig {
|
LoadLayeredConfig {
|
||||||
#[snafu(source(from(common_config::error::Error, Box::new)))]
|
#[snafu(source(from(common_config::error::Error, Box::new)))]
|
||||||
@@ -282,7 +226,7 @@ pub enum Error {
|
|||||||
#[snafu(implicit)]
|
#[snafu(implicit)]
|
||||||
location: Location,
|
location: Location,
|
||||||
#[snafu(source)]
|
#[snafu(source)]
|
||||||
error: opendal::Error,
|
error: ObjectStoreError,
|
||||||
},
|
},
|
||||||
#[snafu(display("S3 config need be set"))]
|
#[snafu(display("S3 config need be set"))]
|
||||||
S3ConfigNotSet {
|
S3ConfigNotSet {
|
||||||
@@ -294,6 +238,24 @@ pub enum Error {
|
|||||||
#[snafu(implicit)]
|
#[snafu(implicit)]
|
||||||
location: Location,
|
location: Location,
|
||||||
},
|
},
|
||||||
|
#[snafu(display("KV backend not set: {}", backend))]
|
||||||
|
KvBackendNotSet {
|
||||||
|
backend: String,
|
||||||
|
#[snafu(implicit)]
|
||||||
|
location: Location,
|
||||||
|
},
|
||||||
|
#[snafu(display("Unsupported memory backend"))]
|
||||||
|
UnsupportedMemoryBackend {
|
||||||
|
#[snafu(implicit)]
|
||||||
|
location: Location,
|
||||||
|
},
|
||||||
|
|
||||||
|
#[snafu(display("File path invalid: {}", msg))]
|
||||||
|
InvalidFilePath {
|
||||||
|
msg: String,
|
||||||
|
#[snafu(implicit)]
|
||||||
|
location: Location,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
@@ -308,27 +270,21 @@ impl ErrorExt for Error {
|
|||||||
Error::MissingConfig { .. }
|
Error::MissingConfig { .. }
|
||||||
| Error::LoadLayeredConfig { .. }
|
| Error::LoadLayeredConfig { .. }
|
||||||
| Error::IllegalConfig { .. }
|
| Error::IllegalConfig { .. }
|
||||||
| Error::InvalidReplCommand { .. }
|
|
||||||
| Error::InitTimezone { .. }
|
| Error::InitTimezone { .. }
|
||||||
| Error::ConnectEtcd { .. }
|
| Error::ConnectEtcd { .. }
|
||||||
| Error::CreateDir { .. }
|
| Error::CreateDir { .. }
|
||||||
| Error::EmptyResult { .. }
|
| Error::EmptyResult { .. }
|
||||||
|
| Error::InvalidFilePath { .. }
|
||||||
|
| Error::UnsupportedMemoryBackend { .. }
|
||||||
| Error::ParseProxyOpts { .. } => StatusCode::InvalidArguments,
|
| Error::ParseProxyOpts { .. } => StatusCode::InvalidArguments,
|
||||||
|
|
||||||
Error::StartProcedureManager { source, .. }
|
Error::StartProcedureManager { source, .. }
|
||||||
| Error::StopProcedureManager { source, .. } => source.status_code(),
|
| Error::StopProcedureManager { source, .. } => source.status_code(),
|
||||||
Error::StartWalOptionsAllocator { source, .. } => source.status_code(),
|
Error::StartWalOptionsAllocator { source, .. } => source.status_code(),
|
||||||
Error::ReplCreation { .. } | Error::Readline { .. } | Error::HttpQuerySql { .. } => {
|
Error::HttpQuerySql { .. } => StatusCode::Internal,
|
||||||
StatusCode::Internal
|
|
||||||
}
|
|
||||||
Error::RequestDatabase { source, .. } => source.status_code(),
|
|
||||||
Error::CollectRecordBatches { source, .. }
|
|
||||||
| Error::PrettyPrintRecordBatches { source, .. } => source.status_code(),
|
|
||||||
Error::StartMetaClient { source, .. } => source.status_code(),
|
|
||||||
Error::ParseSql { source, .. } | Error::PlanStatement { source, .. } => {
|
Error::ParseSql { source, .. } | Error::PlanStatement { source, .. } => {
|
||||||
source.status_code()
|
source.status_code()
|
||||||
}
|
}
|
||||||
Error::SubstraitEncodeLogicalPlan { source, .. } => source.status_code(),
|
|
||||||
|
|
||||||
Error::SerdeJson { .. }
|
Error::SerdeJson { .. }
|
||||||
| Error::FileIo { .. }
|
| Error::FileIo { .. }
|
||||||
@@ -338,8 +294,9 @@ impl ErrorExt for Error {
|
|||||||
|
|
||||||
Error::Other { source, .. } => source.status_code(),
|
Error::Other { source, .. } => source.status_code(),
|
||||||
Error::OpenDal { .. } => StatusCode::Internal,
|
Error::OpenDal { .. } => StatusCode::Internal,
|
||||||
Error::S3ConfigNotSet { .. } => StatusCode::InvalidArguments,
|
Error::S3ConfigNotSet { .. }
|
||||||
Error::OutputDirNotSet { .. } => StatusCode::InvalidArguments,
|
| Error::OutputDirNotSet { .. }
|
||||||
|
| Error::KvBackendNotSet { .. } => StatusCode::InvalidArguments,
|
||||||
|
|
||||||
Error::BuildRuntime { source, .. } => source.status_code(),
|
Error::BuildRuntime { source, .. } => source.status_code(),
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user