KlustronDB Table Redistribution Function and Usage
KlustronDB Table Redistribution Function and Usage
Note:
Unless otherwise specified, the version numbers in the text can be replaced with the version numbers of any released version. For all released versions, see: Release_notes
Overview
Demonstrated the table redistribution functionality of KlustronDB through command line tools and XPanel, guiding customers on how to convert regular tables into partitioned tables. Simulated a case of table redistribution in an online application scenario, tested the impact of table redistribution on the online application, and verified data integrity.
In real business scenarios, it often happens that as business needs and the amount of data in a table change, the way the table was originally created may no longer be suitable. For example, in the sales_order table used in this article, at the initial stage of creation, because the business volume was not large, a non-partitioned table was created. However, as the company's business develops, the number of records in the table increases, so it needs to be converted into a partitioned table to facilitate future data archiving and speed up application access.
The specific environmental information is as follows:
| Node Type | IP | Port |
|---|---|---|
| Kluscomp instance | 192.168.40.152 | 47002 |
| Shard1 Primary | 192.168.40.152 | 57003 |
| Shard2 Primary | 192.168.26.153 | 57005 |
| XPanel | 192.168.40.151 | 18080 |
01 Environment Preparation
Log in to the Kluscomp instance through the PG client and create users and databases.
psql -h 192.168.40.152 -p 47001 postgres
create user kunlun_test with password 'kunlun';
create database test_db with owner kunlun_test encoding utf8 template template0;
\q
psql -h 192.168.40.152 -p 47001 -U kunlun_test test_db
Create the sales_order table and load data through a stored procedure
create table sales_order
(
order_number INT NOT NULL AUTO_INCREMENT,
customer_number INT NOT NULL,
product_code INT NOT NULL,
order_date DATETIME NOT NULL,
entry_date DATETIME NOT NULL,
order_amount DECIMAL(18,2) NOT NULL,
primary key(order_number,order_date)
) ;
create or replace procedure generate_order_data()
AS $$
DECLARE
v_customer_number integer;
v_product_code integer;
v_order_date date;
v_amount integer;
start_date date := to_date('2021-01-01','yyyy-mm-dd');
i integer :=1;
BEGIN
while i<=10000 loop
v_customer_number := FLOOR(1+RANDOM()*6);
v_product_code := FLOOR(1+RANDOM()*500);
v_order_date := to_date('2021-01-01','yyyy-mm-dd') + CAST(FLOOR(RANDOM()*365) AS INT);
v_amount := FLOOR(1000+RANDOM()*9000);
INSERT INTO sales_order VALUES (i,v_customer_number,v_product_code,v_order_date,v_order_date,v_amount);
commit;
i := i+1;
end loop;
END; $$
LANGUAGE plpgsql;
set statement_timeout=0;
call generate_order_data();
test_db=> select count(*) from sales_order;
count
-------
10000
(1 row)
Create the target table sales_order_new, partitioned by the range of order time.
create table sales_order_new
(
order_number INT NOT NULL AUTO_INCREMENT,
customer_number INT NOT NULL,
product_code INT NOT NULL,
order_date DATETIME NOT NULL,
entry_date DATETIME NOT NULL,
order_amount DECIMAL(18,2) NOT NULL,
primary key(order_number,order_date)
) partition by range(order_date);
create table sales_order_p0 partition of sales_order_new
for values from ('2021-01-01') to ('2021-05-01');
create table sales_order_p1 partition of sales_order_new
for values from ('2021-05-01') to ('2021-09-01');
create table sales_order_p2 partition of sales_order_new
for values from ('2021-09-01') to ('2022-01-01');
02 Prepare a Python program kinsert.py to simulate an insertion application that runs continuously on the sales_order table.
import psycopg2.extras
import time
conn = psycopg2.connect(database='test_db',user='kunlun_test',
password='kunlun',host='192.168.40.152',port='47001')
cursor = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
# insert sales_order table
insert_sql = '''INSERT INTO sales_order VALUES (%s,
FLOOR(1+RANDOM()*6), FLOOR(1+RANDOM()*3),
to_date('2021-01-01','yyyy-mm-dd') + CAST(FLOOR(RANDOM()*365) AS INT),
to_date('2021-01-01','yyyy-mm-dd') + CAST(FLOOR(RANDOM()*365) AS INT),
FLOOR(1000+RANDOM()*9000));
;'''
#print("Press Enter to continue.")
input('Press any key and Enter to continue ~!')
i = 10001
while (i < 20001) :
cursor.execute(insert_sql,[i])
conn.commit()
print("order_number:",i," is inserted.")
i = i+1
cursor.close()
conn.close()
The application simulation starts inserting from order_number 10001. After the program runs, it will wait for input before executing the actual insertion logic. After starting to redistribute tasks in the XPanel interface, the program immediately resumes running.
[klbase@server-0 ~]$ python kinsert.py
Press any key and Enter to continue ~!
03 Perform table redistribution operations on the XPanel interface
On the 'Cluster List Information' page, click 'Settings'

Click 'Table Redistribution' in the left sidebar

Select the 'target table cluster,' 'source table,' 'target table,' and the strategy for deleting the source table. If the strategy is set to 'automatic,' the source table will be retained by default for 7 days; if set to 'manual,' the user deletes the source table themselves.
_
Click 'Submit'. Meanwhile, switch to the terminal running the Python program kinsert.py and press Enter to continue inserting records.
[klbase@server-0 ~]$ python kinsert.py
Press any key and Enter to continue ~!
order_number: 10001 is inserted.
order_number: 10002 is inserted.
order_number: 10003 is inserted.
order_number: 10004 is inserted.
order_number: 10005 is inserted.
order_number: 10006 is inserted.
order_number: 10007 is inserted.
order_number: 10008 is inserted.
order_number: 10009 is inserted.
order_number: 10010 is inserted.
order_number: 10011 is inserted.
order_number: 10012 is inserted.
order_number: 10013 is inserted.
order_number: 10014 is inserted.
order_number: 10015 is inserted.
order_number: 10016 is inserted.
Wait a moment and an insert error will occur, at which time the source table sales_order has been renamed.
order_number: 10281 is inserted.
order_number: 10282 is inserted.
order_number: 10283 is inserted.
order_number: 10284 is inserted.
order_number: 10285 is inserted.
order_number: 10286 is inserted.
order_number: 10287 is inserted.
order_number: 10288 is inserted.
order_number: 10289 is inserted.
order_number: 10290 is inserted.
order_number: 10291 is inserted.
order_number: 10292 is inserted.
order_number: 10293 is inserted.
order_number: 10294 is inserted.
order_number: 10295 is inserted.
order_number: 10296 is inserted.
order_number: 10297 is inserted.
Traceback (most recent call last):
File "kinsert.py", line 22, in <module>
cursor.execute(insert_sql,[i])
File "/usr/local/lib64/python3.6/site-packages/psycopg2/extras.py", line 236, in execute
return super().execute(query, vars)
psycopg2.errors.UndefinedTable: relation "sales_order" does not exist
LINE 1: INSERT INTO sales_order VALUES (10298,
At this time, the order_number inserted by the online application is 10297. When the table redistribution is executed, sales_order will be renamed, so the application fails to insert at this time.
_
03 Check the status of the target table and source table
Return to the PG client to check the status of the target table and the source table. It was found that the source table had become a partitioned table, and the target table was renamed to __sales_order$$tb_repartition_13 according to the 'delete source table' policy.
The naming rule is: _[source table name]$$tb_repartition[task number]. After 7 days, the system will automatically delete the table __sales_order$$tb_repartition_13.
_
_
Query the data in sales_order, the amount of data exactly matches the insertion point before the application error. After starting table redistribution, the online application still inserted 297 records.
test_db=> select count(*) from sales_order;
count
-------
10297
(1 row)
