List Tablet Details for a YCQL Table From the Command Line

YugabyteDB automatically splits YCQL user tables into multiple shards, called tablets, using a hash based strategy.

You can see the tablets for a table via the admin UI for YB-Master, which is available at http://<<YB-Master IP>>:7000.

We can scrape the information provided from the admin UI and get the details for a particular table.

I’ve encapsulated the logic in a shell script.

				
					#!/bin/bash
shopt -s expand_aliases

# Script:      list_tablets_ycql.sh
# Description: This script will list tablet details for a given YCQL table by scraping data from
#              the YB Master Admin UI.

# Created:     12/01/2022
# Last update: 12/04/2022

# Edits:
#   12/03/2022 Added a connection an request timeout of 3600 seconds to YCQL calls
#   12/04/2022 Added a check if ycqlsh access is set up properly
#   12/04/2022 Set CONSISTENCY ONE for ycql sessions running COUNTs to enable follower reads
#   12/04/2022 Fixed Raft Config output to include all nodes

# Call Spec:
#   ./list_tablets_ycql.sh <<Keyspace Name>> <<Table Name>> <<YB Master Node IP>> <<Database Username>> <<Password>>
#   The password parameter is optional. If ommitted, the user will be prompted for a password for each YCQL call.

# Example Use:
#   ./list_tablets_ycql.sh test test 172.152.101.162 cassandra password

# Reference:   https://docs.yugabyte.com/preview/reference/configuration/yb-master/#admin-ui

# Defaults
YCQL_TIMEOUT=600

# Verify input parameters

# Check if table keyspace name was provided
if [ -z "$1" ]
then
  echo "Please provide a keyspace name"
  exit 0
else
  YB_KEYSPACE=$1
fi

# Check if table name was provided
if [ -z "$2" ]
then
  echo "Please provide a table name"
  exit 0
else
  YB_TABLE_NAME=$2
fi

# Check if IP or hostname was provided
if [ -z "$3" ]
then
  echo "Please provide an IP or hostname for a YB Master node"
  exit 0
else
  YB_IP=$3
fi

# Check if database user name was provided
if [ -z "$4" ]
then
  echo "Please provide a database username"
  exit 0
else
  YB_USER=$4
fi

# Set up the YCQLSH alias below per your environment
YB_PATH='/home/yugabyte/yb-software/yugabyte-2.17.1.1186-b4-centos-x86_64/bin/ycqlsh'

# Check if ycqlsh access is set up properly
if ! command -v $YB_PATH &> /dev/null
then
    echo "ycqlsh could not be found"
    exit
fi

# If database password was provided, use it in building ycqlsh alias and variable
if [ -z "$5" ]
then
  alias y="$YB_PATH $YB_IP -u $YB_USER --connect-timeout=$YCQL_TIMEOUT"
  y1="$YB_PATH $YB_IP -u $YB_USER --connect-timeout=$YCQL_TIMEOUT"
else
  alias y="$YB_PATH $YB_IP -u $YB_USER -p $5 --connect-timeout=$YCQL_TIMEOUT --request-timeout=$YCQL_TIMEOUT"
  y1="$YB_PATH $YB_IP -u $YB_USER -p $5 --connect-timeout=$YCQL_TIMEOUT --request-timeout=$YCQL_TIMEOUT"
fi

# Check if table exists
tc=`y -e "SELECT COUNT(*) FROM system_schema.tables WHERE keyspace_name = '$YB_KEYSPACE' AND table_name = '$YB_TABLE_NAME';" | awk 'FNR==4{print $1}'`

if [ $tc -gt 0 ]
then
  # Get the PK HASH columns for the table.
  table_id=`curl -s http://$YB_IP:7000/tables | sed -e 's/<[^>]*>/|/g' | awk -F\| -v YB_KEYSPACE=$YB_KEYSPACE -v YB_TABLE_NAME=$YB_TABLE_NAME '{if ($3==YB_KEYSPACE && $6==YB_TABLE_NAME && $15=="") print $13}'`
  pk=`curl -s http://$YB_IP:7000/table?id=$table_id | grep "NOT NULL PARTITION KEY" | sed -e 's/<[^>]*>/|/g' | awk -F\| '{print $3}' | paste -d ',' -s`

if [ -z "$pk" ]
then
  echo "The table \"$1.$2\" does not have a HASH sharded primary key defined."
  exit 1
fi

# Get the number of nodes in the cluster
nc=`y -e "SELECT COUNT(*) FROM system.peers;" | awk 'FNR==4{print $1}'`
nc=$((nc+1))

# Scrap the YB Master UI for Tablet data and print to it to the screen
curl -s http://$YB_IP:9000/tablets | grep -A $nc $table_id | sed -e 's/<[^>]*>/|/g' | sed 's/\([|]\)\1\+/\1/g' | sed 's:^.\(.*\).$:\1:' | sed -z 's/\n|LEADER:/|LEADER:/g' | sed -z 's/\n|FOLLOWER:/ FOLLOWER:/g' | sed '/^$/d' | awk -F\| -v pk="$pk" -v y1="$y1" -v k="$YB_KEYSPACE" -v tn="$YB_TABLE_NAME" 'BEGIN{print "Tablet ID|Partition|State|Hidden|Row Count|Num SST Files|On-disk size|RaftConfig"}; {p=index($5,","); cmd=y1" -e \"CONSISTENCY ONE; SELECT COUNT("pk") FROM "k"."tn" WHERE partition_hash("pk") >= \""strtonum( "0x" substr($5, p-4, 4))"\" AND partition_hash("pk") <= \""strtonum( "0x" substr($5, p+4, 4))"\";\" | sed -n 5p"; cmd | getline rc; close(cmd); print $4"|"$5"|"$6"|"$7"|"strtonum(rc)"|"$8"|"$9" / "$10" / "$11" / "$12" / "$13"|"$14;}' | column -t -s"|"

else
  echo "The table \"$1.$2\" does not exist."
fi

exit 0
				
			

Example:

				
					[yugabyte@ip-172-152-101-162 ~]$ alias c
alias c='ycqlsh 172.152.101.162 -u cassandra -p Yugabyte123! --connect-timeout=3600 --request-timeout=3600 -r'

[yugabyte@ip-172-152-101-162 ~]$ time c -e "SELECT COUNT(*) FROM test.test;"

 count
----------
 10000000

(1 rows)

real	0m12.829s
user	0m0.183s
sys	0m0.028s

[yugabyte@ip-172-152-101-162 ~]$ time ./list_tablets_ycql.sh test test 172.152.101.162 cassandra Yugabyte123!
Tablet ID                         Partition                     State    Hidden  Row Count  Num SST Files  On-disk size                                                                                                          RaftConfig
2e37ea5013cc4b4bab0107d3950f762d  hash_split: [0x0000, 0x5554]  RUNNING  false   3334342    4              Total: 194.85M / Consensus Metadata: 1.5K / WAL Files: 128.00M / SST Files: 66.85M / SST Files Uncompressed: 174.19M  LEADER: 172.152.101.162 FOLLOWER: 172.161.52.255 FOLLOWER: 172.150.43.0
54f9402a2a1c4001ae47d553086c4425  hash_split: [0x5555, 0xAAA9]  RUNNING  false   3334859    4              Total: 194.87M / Consensus Metadata: 1.5K / WAL Files: 128.00M / SST Files: 66.87M / SST Files Uncompressed: 174.22M  LEADER: 172.152.101.162 FOLLOWER: 172.161.52.255 FOLLOWER: 172.150.43.0
b5dc1b9693ef4914932e986e50d29528  hash_split: [0xAAAA, 0xFFFF]  RUNNING  false   3330799    4              Total: 194.86M / Consensus Metadata: 1.5K / WAL Files: 128.00M / SST Files: 66.85M / SST Files Uncompressed: 174.17M  LEADER: 172.152.101.162 FOLLOWER: 172.161.52.255 FOLLOWER: 172.150.43.0

real	0m15.514s
user	0m0.868s
sys	0m0.158s
				
			

Have Fun!