How to Implement Both Put and Delete Operations in a Batch in TiKV

Note:
This topic has been translated from a Chinese forum by GPT and might contain errors.

Original topic: 请问tikv中如何实现一个batch中既有put操作,又有delete操作

| username: 我家有个臭皮崽

As the topic suggests, how can I implement a batch operation in TiKV that includes both put and delete operations?
Currently, the only solution I can think of is using batchPut along with TTL operations, but how do I set the expiration time for the keys to be deleted?

| username: 有猫万事足 | Original post link

I’m not sure if the client you are using is in Go.

This issue clearly mentions that there is an interface called BatchPutTTL.

Another problem is that TTL only supports rawkv. It cannot support transactions.

| username: redgame | Original post link

The person above is right.

| username: ljluestc | Original post link

In TiKV, you can use the RawKV interface to perform Put and Delete operations. Here is a simple example demonstrating how to perform Put and Delete operations in a Batch operation:

package main

import (
	"context"
	"fmt"
	"github.com/tikv/client-go/config"
	"github.com/tikv/client-go/rawkv"
)

func main() {
	// Create RawKV client
	cli, err := rawkv.NewClient(context.Background(), []string{"127.0.0.1:2379"}, config.Security{})
	if err != nil {
		fmt.Printf("Failed to create TiKV client: %v\n", err)
		return
	}
	defer cli.Close()

	batch := cli.NewWriteBatch()

	// Add Put operation
	batch.Put([]byte("key1"), []byte("value1"))

	// Add Delete operation
	batch.Delete([]byte("key2"))

	// Commit Batch operation
	err = batch.Write()
	if err != nil {
		fmt.Printf("Failed to write batch: %v\n", err)
		return
	}

	fmt.Println("Batch operation completed successfully")
}
| username: 我家有个臭皮崽 | Original post link

I am using the C++ client.

| username: 我家有个臭皮崽 | Original post link

Thanks, I’ll check the Go implementation.

| username: 我家有个臭皮崽 | Original post link

You answered about setting a batch TTL for all keys. What I want to know is how to set an expiration TTL for a single key, equivalent to the effect of delete.

| username: 我家有个臭皮崽 | Original post link

These two operations in the batch are atomic, right?

| username: 有猫万事足 | Original post link

I don’t quite understand.
Do you mean that you want to batch put, but one or several keys in this batch are the ones you don’t want?
Or even the unwanted key is not in the batch you are putting?
Because you are not using transactional KV access, you have to complete batch put + delete in one call, is that what you mean?

| username: 我家有个臭皮崽 | Original post link

What I mean is that a WriteBatch contains both put and delete operations, similar to this operation in RocksDB:

// Create a WriteBatch
rocksdb::WriteBatch batch;

batch.Put(“key1”, “value1”);
batch.Delete(“key2”);
status = db->Write(rocksdb::WriteOptions(), &batch);
But all the keys are in one region.

| username: 有猫万事足 | Original post link

The batch here feels similar to a transaction.

It seems that the above example meets your requirements.

| username: 我家有个臭皮崽 | Original post link

Well, it should be this. Another question, can the transaction interface and RawKv interface be called simultaneously? That is, can a project have both RawClient and transaction Client? Will this have any impact?

| username: 有猫万事足 | Original post link

No, a bold warning directly.

| username: 我家有个臭皮崽 | Original post link

Alright… We mainly use RawKv :cry:

| username: 有猫万事足 | Original post link

However, this document hasn’t been updated for a long time, and the statements in the TiKV configuration are different.

* Data is divided into ranges based on usage, supporting the coexistence of a single TiDB cluster, transactional KV, and RawKV applications.

I understand that by configuring api-version=2 here, it can achieve coexistence whether TiDB uses TiKV for storage or clients access through txn or raw mode.
Of course, I haven’t actually tried this configuration.
Let’s wait and see if any other experts can provide an explanation.

| username: 我家有个臭皮崽 | Original post link

Then let’s not mix them for now. Actually, as I initially asked, if we can only choose RawKv, the BatchPut of RawKv is atomic, and all key-values in BatchPut can have a TTL. If we can set the TTL of the key we want to delete to -1 (expired), it can actually achieve the effect of using a transactional batch; for example:

batchPut{
“key1” : “value1”, ttl = 0;
“key2” : “”, ttl = -1;
}

Something like this, but I found out that TTL is uint64 :joy:

| username: 有猫万事足 | Original post link

That’s not all; the key point is that TiKV’s TTL is disabled by default. Enabling it requires setting api-version=2. There’s also a long section of red warning text. :joy:
It seems quite difficult to manage without upgrading.
The application team will have to find a solution.

| username: 我家有个臭皮崽 | Original post link

I can only upgrade :smiling_face_with_tear: