Merge branch 'main' into enh/stream_buffer_param
This commit is contained in:
commit
ae4ad7d851
|
@ -2,7 +2,7 @@
|
||||||
# taosadapter
|
# taosadapter
|
||||||
ExternalProject_Add(taosadapter
|
ExternalProject_Add(taosadapter
|
||||||
GIT_REPOSITORY https://github.com/taosdata/taosadapter.git
|
GIT_REPOSITORY https://github.com/taosdata/taosadapter.git
|
||||||
GIT_TAG 213f8b3
|
GIT_TAG db6c843
|
||||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosadapter"
|
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosadapter"
|
||||||
BINARY_DIR ""
|
BINARY_DIR ""
|
||||||
#BUILD_IN_SOURCE TRUE
|
#BUILD_IN_SOURCE TRUE
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# taos-tools
|
# taos-tools
|
||||||
ExternalProject_Add(taos-tools
|
ExternalProject_Add(taos-tools
|
||||||
GIT_REPOSITORY https://github.com/taosdata/taos-tools.git
|
GIT_REPOSITORY https://github.com/taosdata/taos-tools.git
|
||||||
GIT_TAG 7d24ed5
|
GIT_TAG 6a2d9fc
|
||||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
|
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
|
||||||
BINARY_DIR ""
|
BINARY_DIR ""
|
||||||
#BUILD_IN_SOURCE TRUE
|
#BUILD_IN_SOURCE TRUE
|
||||||
|
|
|
@ -872,9 +872,9 @@ INTERP(expr)
|
||||||
- `INTERP` is used to get the value that matches the specified time slice from a column. If no such value exists an interpolation value will be returned based on `FILL` parameter.
|
- `INTERP` is used to get the value that matches the specified time slice from a column. If no such value exists an interpolation value will be returned based on `FILL` parameter.
|
||||||
- The input data of `INTERP` is the value of the specified column and a `where` clause can be used to filter the original data. If no `where` condition is specified then all original data is the input.
|
- The input data of `INTERP` is the value of the specified column and a `where` clause can be used to filter the original data. If no `where` condition is specified then all original data is the input.
|
||||||
- `INTERP` must be used along with `RANGE`, `EVERY`, `FILL` keywords.
|
- `INTERP` must be used along with `RANGE`, `EVERY`, `FILL` keywords.
|
||||||
- The output time range of `INTERP` is specified by `RANGE(timestamp1,timestamp2)` parameter, with timestamp1<=timestamp2. timestamp1 is the starting point of the output time range and must be specified. timestamp2 is the ending point of the output time range and must be specified.
|
- The output time range of `INTERP` is specified by `RANGE(timestamp1,timestamp2)` parameter, with timestamp1 < timestamp2. timestamp1 is the starting point of the output time range and must be specified. timestamp2 is the ending point of the output time range and must be specified.
|
||||||
- The number of rows in the result set of `INTERP` is determined by the parameter `EVERY`. Starting from timestamp1, one interpolation is performed for every time interval specified `EVERY` parameter. The parameter `EVERY` must be an integer, with no quotes, with a time unit of: b(nanosecond), u(microsecond), a(millisecond)), s(second), m(minute), h(hour), d(day), or w(week). For example, `EVERY(500a)` will interpolate every 500 milliseconds.
|
- The number of rows in the result set of `INTERP` is determined by the parameter `EVERY(time_unit)`. Starting from timestamp1, one interpolation is performed for every time interval specified `time_unit` parameter. The parameter `time_unit` must be an integer, with no quotes, with a time unit of: a(millisecond)), s(second), m(minute), h(hour), d(day), or w(week). For example, `EVERY(500a)` will interpolate every 500 milliseconds.
|
||||||
- Interpolation is performed based on `FILL` parameter.
|
- Interpolation is performed based on `FILL` parameter. For more information about FILL clause, see [FILL Clause](./distinguished/#fill-clause).
|
||||||
- `INTERP` can only be used to interpolate in single timeline. So it must be used with `partition by tbname` when it's used on a STable.
|
- `INTERP` can only be used to interpolate in single timeline. So it must be used with `partition by tbname` when it's used on a STable.
|
||||||
- Pseudo column `_irowts` can be used along with `INTERP` to return the timestamps associated with interpolation points(support after version 3.0.1.4).
|
- Pseudo column `_irowts` can be used along with `INTERP` to return the timestamps associated with interpolation points(support after version 3.0.1.4).
|
||||||
|
|
||||||
|
|
|
@ -2,5 +2,5 @@ module goexample
|
||||||
|
|
||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require github.com/taosdata/driver-go/v3 3.0
|
require github.com/taosdata/driver-go/v3 v3.1.0
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import pandas
|
import pandas
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine, text
|
||||||
|
|
||||||
engine = create_engine("taos://root:taosdata@localhost:6030/power")
|
engine = create_engine("taos://root:taosdata@localhost:6030/power")
|
||||||
df = pandas.read_sql("SELECT * FROM meters", engine)
|
conn = engine.connect()
|
||||||
|
df = pandas.read_sql(text("SELECT * FROM power.meters"), conn)
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
# print index
|
# print index
|
||||||
print(df.index)
|
print(df.index)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import pandas
|
import pandas
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine, text
|
||||||
|
|
||||||
engine = create_engine("taosrest://root:taosdata@localhost:6041")
|
engine = create_engine("taosrest://root:taosdata@localhost:6041")
|
||||||
df: pandas.DataFrame = pandas.read_sql("SELECT * FROM power.meters", engine)
|
conn = engine.connect()
|
||||||
|
df: pandas.DataFrame = pandas.read_sql(text("SELECT * FROM power.meters"), conn)
|
||||||
|
conn.close()
|
||||||
|
|
||||||
# print index
|
# print index
|
||||||
print(df.index)
|
print(df.index)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# ANCHOR: connect
|
# ANCHOR: connect
|
||||||
from taosrest import connect, TaosRestConnection, TaosRestCursor
|
from taosrest import connect, TaosRestConnection, TaosRestCursor
|
||||||
|
|
||||||
conn: TaosRestConnection = connect(url="http://localhost:6041",
|
conn = connect(url="http://localhost:6041",
|
||||||
user="root",
|
user="root",
|
||||||
password="taosdata",
|
password="taosdata",
|
||||||
timeout=30)
|
timeout=30)
|
||||||
|
@ -9,16 +9,17 @@ conn: TaosRestConnection = connect(url="http://localhost:6041",
|
||||||
# ANCHOR_END: connect
|
# ANCHOR_END: connect
|
||||||
# ANCHOR: basic
|
# ANCHOR: basic
|
||||||
# create STable
|
# create STable
|
||||||
cursor: TaosRestCursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute("DROP DATABASE IF EXISTS power")
|
cursor.execute("DROP DATABASE IF EXISTS power")
|
||||||
cursor.execute("CREATE DATABASE power")
|
cursor.execute("CREATE DATABASE power")
|
||||||
cursor.execute("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)")
|
cursor.execute(
|
||||||
|
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)")
|
||||||
|
|
||||||
# insert data
|
# insert data
|
||||||
cursor.execute("""INSERT INTO power.d1001 USING power.meters TAGS(California.SanFrancisco, 2) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
|
cursor.execute("""INSERT INTO power.d1001 USING power.meters TAGS('California.SanFrancisco', 2) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
|
||||||
power.d1002 USING power.meters TAGS(California.SanFrancisco, 3) VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
|
power.d1002 USING power.meters TAGS('California.SanFrancisco', 3) VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
|
||||||
power.d1003 USING power.meters TAGS(California.LosAngeles, 2) VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
|
power.d1003 USING power.meters TAGS('California.LosAngeles', 2) VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
|
||||||
power.d1004 USING power.meters TAGS(California.LosAngeles, 3) VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)""")
|
power.d1004 USING power.meters TAGS('California.LosAngeles', 3) VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)""")
|
||||||
print("inserted row count:", cursor.rowcount)
|
print("inserted row count:", cursor.rowcount)
|
||||||
|
|
||||||
# query data
|
# query data
|
||||||
|
@ -28,7 +29,7 @@ print("queried row count:", cursor.rowcount)
|
||||||
# get column names from cursor
|
# get column names from cursor
|
||||||
column_names = [meta[0] for meta in cursor.description]
|
column_names = [meta[0] for meta in cursor.description]
|
||||||
# get rows
|
# get rows
|
||||||
data: list[tuple] = cursor.fetchall()
|
data = cursor.fetchall()
|
||||||
print(column_names)
|
print(column_names)
|
||||||
for row in data:
|
for row in data:
|
||||||
print(row)
|
print(row)
|
||||||
|
|
|
@ -8,7 +8,7 @@ conn.execute("CREATE DATABASE test")
|
||||||
# change database. same as execute "USE db"
|
# change database. same as execute "USE db"
|
||||||
conn.select_db("test")
|
conn.select_db("test")
|
||||||
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||||
affected_row: int = conn.execute("INSERT INTO t1 USING weather TAGS(1) VALUES (now, 23.5) (now+1m, 23.5) (now+2m 24.4)")
|
affected_row = conn.execute("INSERT INTO t1 USING weather TAGS(1) VALUES (now, 23.5) (now+1m, 23.5) (now+2m, 24.4)")
|
||||||
print("affected_row", affected_row)
|
print("affected_row", affected_row)
|
||||||
# output:
|
# output:
|
||||||
# affected_row 3
|
# affected_row 3
|
||||||
|
@ -16,10 +16,10 @@ print("affected_row", affected_row)
|
||||||
|
|
||||||
# ANCHOR: query
|
# ANCHOR: query
|
||||||
# Execute a sql and get its result set. It's useful for SELECT statement
|
# Execute a sql and get its result set. It's useful for SELECT statement
|
||||||
result: taos.TaosResult = conn.query("SELECT * from weather")
|
result = conn.query("SELECT * from weather")
|
||||||
|
|
||||||
# Get fields from result
|
# Get fields from result
|
||||||
fields: taos.field.TaosFields = result.fields
|
fields = result.fields
|
||||||
for field in fields:
|
for field in fields:
|
||||||
print(field) # {name: ts, type: 9, bytes: 8}
|
print(field) # {name: ts, type: 9, bytes: 8}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
# install dependencies:
|
# install dependencies:
|
||||||
# recommend python >= 3.8
|
# recommend python >= 3.8
|
||||||
# pip3 install faster-fifo
|
|
||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
|
import multiprocessing
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
from multiprocessing import Process
|
from multiprocessing import Process, Queue
|
||||||
from faster_fifo import Queue
|
|
||||||
from mockdatasource import MockDataSource
|
from mockdatasource import MockDataSource
|
||||||
from queue import Empty
|
from queue import Empty
|
||||||
from typing import List
|
from typing import List
|
||||||
|
@ -22,8 +21,7 @@ TABLE_COUNT = 1000
|
||||||
QUEUE_SIZE = 1000000
|
QUEUE_SIZE = 1000000
|
||||||
MAX_BATCH_SIZE = 3000
|
MAX_BATCH_SIZE = 3000
|
||||||
|
|
||||||
read_processes = []
|
_DONE_MESSAGE = '__DONE__'
|
||||||
write_processes = []
|
|
||||||
|
|
||||||
|
|
||||||
def get_connection():
|
def get_connection():
|
||||||
|
@ -44,41 +42,64 @@ def get_connection():
|
||||||
|
|
||||||
# ANCHOR: read
|
# ANCHOR: read
|
||||||
|
|
||||||
def run_read_task(task_id: int, task_queues: List[Queue]):
|
def run_read_task(task_id: int, task_queues: List[Queue], infinity):
|
||||||
table_count_per_task = TABLE_COUNT // READ_TASK_COUNT
|
table_count_per_task = TABLE_COUNT // READ_TASK_COUNT
|
||||||
data_source = MockDataSource(f"tb{task_id}", table_count_per_task)
|
data_source = MockDataSource(f"tb{task_id}", table_count_per_task, infinity)
|
||||||
try:
|
try:
|
||||||
for batch in data_source:
|
for batch in data_source:
|
||||||
|
if isinstance(batch, tuple):
|
||||||
|
batch = [batch]
|
||||||
for table_id, rows in batch:
|
for table_id, rows in batch:
|
||||||
# hash data to different queue
|
# hash data to different queue
|
||||||
i = table_id % len(task_queues)
|
i = table_id % len(task_queues)
|
||||||
# block putting forever when the queue is full
|
# block putting forever when the queue is full
|
||||||
task_queues[i].put_many(rows, block=True, timeout=-1)
|
for row in rows:
|
||||||
|
task_queues[i].put(row)
|
||||||
|
if not infinity:
|
||||||
|
for queue in task_queues:
|
||||||
|
queue.put(_DONE_MESSAGE)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
|
finally:
|
||||||
|
logging.info('read task over')
|
||||||
|
|
||||||
|
|
||||||
# ANCHOR_END: read
|
# ANCHOR_END: read
|
||||||
|
|
||||||
|
|
||||||
# ANCHOR: write
|
# ANCHOR: write
|
||||||
def run_write_task(task_id: int, queue: Queue):
|
def run_write_task(task_id: int, queue: Queue, done_queue: Queue):
|
||||||
from sql_writer import SQLWriter
|
from sql_writer import SQLWriter
|
||||||
log = logging.getLogger(f"WriteTask-{task_id}")
|
log = logging.getLogger(f"WriteTask-{task_id}")
|
||||||
writer = SQLWriter(get_connection)
|
writer = SQLWriter(get_connection)
|
||||||
lines = None
|
lines = None
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
|
over = False
|
||||||
|
lines = []
|
||||||
|
for _ in range(MAX_BATCH_SIZE):
|
||||||
try:
|
try:
|
||||||
# get as many as possible
|
line = queue.get_nowait()
|
||||||
lines = queue.get_many(block=False, max_messages_to_get=MAX_BATCH_SIZE)
|
if line == _DONE_MESSAGE:
|
||||||
writer.process_lines(lines)
|
over = True
|
||||||
|
break
|
||||||
|
if line:
|
||||||
|
lines.append(line)
|
||||||
except Empty:
|
except Empty:
|
||||||
time.sleep(0.01)
|
time.sleep(0.1)
|
||||||
|
if len(lines) > 0:
|
||||||
|
writer.process_lines(lines)
|
||||||
|
if over:
|
||||||
|
done_queue.put(_DONE_MESSAGE)
|
||||||
|
break
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
log.debug(f"lines={lines}")
|
log.debug(f"lines={lines}")
|
||||||
raise e
|
raise e
|
||||||
|
finally:
|
||||||
|
writer.close()
|
||||||
|
log.debug('write task over')
|
||||||
|
|
||||||
|
|
||||||
# ANCHOR_END: write
|
# ANCHOR_END: write
|
||||||
|
@ -103,13 +124,11 @@ def set_global_config():
|
||||||
|
|
||||||
|
|
||||||
# ANCHOR: monitor
|
# ANCHOR: monitor
|
||||||
def run_monitor_process():
|
def run_monitor_process(done_queue: Queue):
|
||||||
log = logging.getLogger("DataBaseMonitor")
|
log = logging.getLogger("DataBaseMonitor")
|
||||||
|
conn = None
|
||||||
|
try:
|
||||||
conn = get_connection()
|
conn = get_connection()
|
||||||
conn.execute("DROP DATABASE IF EXISTS test")
|
|
||||||
conn.execute("CREATE DATABASE test")
|
|
||||||
conn.execute("CREATE STABLE test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) "
|
|
||||||
"TAGS (location BINARY(64), groupId INT)")
|
|
||||||
|
|
||||||
def get_count():
|
def get_count():
|
||||||
res = conn.query("SELECT count(*) FROM test.meters")
|
res = conn.query("SELECT count(*) FROM test.meters")
|
||||||
|
@ -118,32 +137,51 @@ def run_monitor_process():
|
||||||
|
|
||||||
last_count = 0
|
last_count = 0
|
||||||
while True:
|
while True:
|
||||||
|
try:
|
||||||
|
done = done_queue.get_nowait()
|
||||||
|
if done == _DONE_MESSAGE:
|
||||||
|
break
|
||||||
|
except Empty:
|
||||||
|
pass
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
count = get_count()
|
count = get_count()
|
||||||
log.info(f"count={count} speed={(count - last_count) / 10}")
|
log.info(f"count={count} speed={(count - last_count) / 10}")
|
||||||
last_count = count
|
last_count = count
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
# ANCHOR_END: monitor
|
# ANCHOR_END: monitor
|
||||||
# ANCHOR: main
|
# ANCHOR: main
|
||||||
def main():
|
def main(infinity):
|
||||||
set_global_config()
|
set_global_config()
|
||||||
logging.info(f"READ_TASK_COUNT={READ_TASK_COUNT}, WRITE_TASK_COUNT={WRITE_TASK_COUNT}, "
|
logging.info(f"READ_TASK_COUNT={READ_TASK_COUNT}, WRITE_TASK_COUNT={WRITE_TASK_COUNT}, "
|
||||||
f"TABLE_COUNT={TABLE_COUNT}, QUEUE_SIZE={QUEUE_SIZE}, MAX_BATCH_SIZE={MAX_BATCH_SIZE}")
|
f"TABLE_COUNT={TABLE_COUNT}, QUEUE_SIZE={QUEUE_SIZE}, MAX_BATCH_SIZE={MAX_BATCH_SIZE}")
|
||||||
|
|
||||||
monitor_process = Process(target=run_monitor_process)
|
conn = get_connection()
|
||||||
|
conn.execute("DROP DATABASE IF EXISTS test")
|
||||||
|
conn.execute("CREATE DATABASE IF NOT EXISTS test")
|
||||||
|
conn.execute("CREATE STABLE IF NOT EXISTS test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) "
|
||||||
|
"TAGS (location BINARY(64), groupId INT)")
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
done_queue = Queue()
|
||||||
|
monitor_process = Process(target=run_monitor_process, args=(done_queue,))
|
||||||
monitor_process.start()
|
monitor_process.start()
|
||||||
time.sleep(3) # waiting for database ready.
|
logging.debug(f"monitor task started with pid {monitor_process.pid}")
|
||||||
|
|
||||||
task_queues: List[Queue] = []
|
task_queues: List[Queue] = []
|
||||||
|
write_processes = []
|
||||||
|
read_processes = []
|
||||||
|
|
||||||
# create task queues
|
# create task queues
|
||||||
for i in range(WRITE_TASK_COUNT):
|
for i in range(WRITE_TASK_COUNT):
|
||||||
queue = Queue(max_size_bytes=QUEUE_SIZE)
|
queue = Queue()
|
||||||
task_queues.append(queue)
|
task_queues.append(queue)
|
||||||
|
|
||||||
# create write processes
|
# create write processes
|
||||||
for i in range(WRITE_TASK_COUNT):
|
for i in range(WRITE_TASK_COUNT):
|
||||||
p = Process(target=run_write_task, args=(i, task_queues[i]))
|
p = Process(target=run_write_task, args=(i, task_queues[i], done_queue))
|
||||||
p.start()
|
p.start()
|
||||||
logging.debug(f"WriteTask-{i} started with pid {p.pid}")
|
logging.debug(f"WriteTask-{i} started with pid {p.pid}")
|
||||||
write_processes.append(p)
|
write_processes.append(p)
|
||||||
|
@ -151,13 +189,19 @@ def main():
|
||||||
# create read processes
|
# create read processes
|
||||||
for i in range(READ_TASK_COUNT):
|
for i in range(READ_TASK_COUNT):
|
||||||
queues = assign_queues(i, task_queues)
|
queues = assign_queues(i, task_queues)
|
||||||
p = Process(target=run_read_task, args=(i, queues))
|
p = Process(target=run_read_task, args=(i, queues, infinity))
|
||||||
p.start()
|
p.start()
|
||||||
logging.debug(f"ReadTask-{i} started with pid {p.pid}")
|
logging.debug(f"ReadTask-{i} started with pid {p.pid}")
|
||||||
read_processes.append(p)
|
read_processes.append(p)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
monitor_process.join()
|
monitor_process.join()
|
||||||
|
for p in read_processes:
|
||||||
|
p.join()
|
||||||
|
for p in write_processes:
|
||||||
|
p.join()
|
||||||
|
time.sleep(1)
|
||||||
|
return
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
monitor_process.terminate()
|
monitor_process.terminate()
|
||||||
[p.terminate() for p in read_processes]
|
[p.terminate() for p in read_processes]
|
||||||
|
@ -176,5 +220,6 @@ def assign_queues(read_task_id, task_queues):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
multiprocessing.set_start_method('spawn')
|
||||||
|
main(False)
|
||||||
# ANCHOR_END: main
|
# ANCHOR_END: main
|
||||||
|
|
|
@ -26,7 +26,8 @@ class Consumer(object):
|
||||||
'bath_consume': True,
|
'bath_consume': True,
|
||||||
'batch_size': 1000,
|
'batch_size': 1000,
|
||||||
'async_model': True,
|
'async_model': True,
|
||||||
'workers': 10
|
'workers': 10,
|
||||||
|
'testing': False
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCATIONS = ['California.SanFrancisco', 'California.LosAngles', 'California.SanDiego', 'California.SanJose',
|
LOCATIONS = ['California.SanFrancisco', 'California.LosAngles', 'California.SanDiego', 'California.SanJose',
|
||||||
|
@ -46,6 +47,7 @@ class Consumer(object):
|
||||||
def __init__(self, **configs):
|
def __init__(self, **configs):
|
||||||
self.config: dict = self.DEFAULT_CONFIGS
|
self.config: dict = self.DEFAULT_CONFIGS
|
||||||
self.config.update(configs)
|
self.config.update(configs)
|
||||||
|
if not self.config.get('testing'):
|
||||||
self.consumer = KafkaConsumer(
|
self.consumer = KafkaConsumer(
|
||||||
self.config.get('kafka_topic'), # topic
|
self.config.get('kafka_topic'), # topic
|
||||||
bootstrap_servers=self.config.get('kafka_brokers'),
|
bootstrap_servers=self.config.get('kafka_brokers'),
|
||||||
|
@ -60,7 +62,7 @@ class Consumer(object):
|
||||||
)
|
)
|
||||||
if self.config.get('async_model'):
|
if self.config.get('async_model'):
|
||||||
self.pool = ThreadPoolExecutor(max_workers=self.config.get('workers'))
|
self.pool = ThreadPoolExecutor(max_workers=self.config.get('workers'))
|
||||||
self.tasks: list[Future] = []
|
self.tasks = []
|
||||||
# tags and table mapping # key: {location}_{groupId} value:
|
# tags and table mapping # key: {location}_{groupId} value:
|
||||||
self.tag_table_mapping = {}
|
self.tag_table_mapping = {}
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -115,14 +117,14 @@ class Consumer(object):
|
||||||
if self.taos is not None:
|
if self.taos is not None:
|
||||||
self.taos.close()
|
self.taos.close()
|
||||||
|
|
||||||
def _run(self, f: Callable[[ConsumerRecord], bool]):
|
def _run(self, f):
|
||||||
for message in self.consumer:
|
for message in self.consumer:
|
||||||
if self.config.get('async_model'):
|
if self.config.get('async_model'):
|
||||||
self.pool.submit(f(message))
|
self.pool.submit(f(message))
|
||||||
else:
|
else:
|
||||||
f(message)
|
f(message)
|
||||||
|
|
||||||
def _run_batch(self, f: Callable[[list[list[ConsumerRecord]]], None]):
|
def _run_batch(self, f):
|
||||||
while True:
|
while True:
|
||||||
messages = self.consumer.poll(timeout_ms=500, max_records=self.config.get('batch_size'))
|
messages = self.consumer.poll(timeout_ms=500, max_records=self.config.get('batch_size'))
|
||||||
if messages:
|
if messages:
|
||||||
|
@ -140,7 +142,7 @@ class Consumer(object):
|
||||||
logging.info('## insert sql %s', sql)
|
logging.info('## insert sql %s', sql)
|
||||||
return self.taos.execute(sql=sql) == 1
|
return self.taos.execute(sql=sql) == 1
|
||||||
|
|
||||||
def _to_taos_batch(self, messages: list[list[ConsumerRecord]]):
|
def _to_taos_batch(self, messages):
|
||||||
sql = self._build_sql_batch(messages=messages)
|
sql = self._build_sql_batch(messages=messages)
|
||||||
if len(sql) == 0: # decode error, skip
|
if len(sql) == 0: # decode error, skip
|
||||||
return
|
return
|
||||||
|
@ -162,7 +164,7 @@ class Consumer(object):
|
||||||
table_name = self._get_table_name(location=location, group_id=group_id)
|
table_name = self._get_table_name(location=location, group_id=group_id)
|
||||||
return self.INSERT_PART_SQL.format(table_name, ts, current, voltage, phase)
|
return self.INSERT_PART_SQL.format(table_name, ts, current, voltage, phase)
|
||||||
|
|
||||||
def _build_sql_batch(self, messages: list[list[ConsumerRecord]]) -> str:
|
def _build_sql_batch(self, messages) -> str:
|
||||||
sql_list = []
|
sql_list = []
|
||||||
for partition_messages in messages:
|
for partition_messages in messages:
|
||||||
for message in partition_messages:
|
for message in partition_messages:
|
||||||
|
@ -186,7 +188,55 @@ def _get_location_and_group(key: str) -> (str, int):
|
||||||
return fields[0], fields[1]
|
return fields[0], fields[1]
|
||||||
|
|
||||||
|
|
||||||
|
def test_to_taos(consumer: Consumer):
|
||||||
|
msg = {
|
||||||
|
'location': 'California.SanFrancisco',
|
||||||
|
'groupId': 1,
|
||||||
|
'ts': '2022-12-06 15:13:38.643',
|
||||||
|
'current': 3.41,
|
||||||
|
'voltage': 105,
|
||||||
|
'phase': 0.02027,
|
||||||
|
}
|
||||||
|
record = ConsumerRecord(checksum=None, headers=None, offset=1, key=None, value=json.dumps(msg), partition=1,
|
||||||
|
topic='test', serialized_key_size=None, serialized_header_size=None,
|
||||||
|
serialized_value_size=None, timestamp=time.time(), timestamp_type=None)
|
||||||
|
assert consumer._to_taos(message=record)
|
||||||
|
|
||||||
|
|
||||||
|
def test_to_taos_batch(consumer: Consumer):
|
||||||
|
records = [
|
||||||
|
[
|
||||||
|
ConsumerRecord(checksum=None, headers=None, offset=1, key=None,
|
||||||
|
value=json.dumps({'location': 'California.SanFrancisco',
|
||||||
|
'groupId': 1,
|
||||||
|
'ts': '2022-12-06 15:13:38.643',
|
||||||
|
'current': 3.41,
|
||||||
|
'voltage': 105,
|
||||||
|
'phase': 0.02027, }),
|
||||||
|
partition=1, topic='test', serialized_key_size=None, serialized_header_size=None,
|
||||||
|
serialized_value_size=None, timestamp=time.time(), timestamp_type=None),
|
||||||
|
ConsumerRecord(checksum=None, headers=None, offset=1, key=None,
|
||||||
|
value=json.dumps({'location': 'California.LosAngles',
|
||||||
|
'groupId': 2,
|
||||||
|
'ts': '2022-12-06 15:13:39.643',
|
||||||
|
'current': 3.41,
|
||||||
|
'voltage': 102,
|
||||||
|
'phase': 0.02027, }),
|
||||||
|
partition=1, topic='test', serialized_key_size=None, serialized_header_size=None,
|
||||||
|
serialized_value_size=None, timestamp=time.time(), timestamp_type=None),
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
consumer._to_taos_batch(messages=records)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
consumer = Consumer(async_model=True)
|
consumer = Consumer(async_model=True, testing=True)
|
||||||
|
# init env
|
||||||
consumer.init_env()
|
consumer.init_env()
|
||||||
consumer.consume()
|
# consumer.consume()
|
||||||
|
# test build sql
|
||||||
|
# test build sql batch
|
||||||
|
test_to_taos(consumer)
|
||||||
|
test_to_taos_batch(consumer)
|
||||||
|
|
|
@ -10,13 +10,14 @@ class MockDataSource:
|
||||||
"9.4,118,0.141,California.SanFrancisco,4"
|
"9.4,118,0.141,California.SanFrancisco,4"
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, tb_name_prefix, table_count):
|
def __init__(self, tb_name_prefix, table_count, infinity=True):
|
||||||
self.table_name_prefix = tb_name_prefix + "_"
|
self.table_name_prefix = tb_name_prefix + "_"
|
||||||
self.table_count = table_count
|
self.table_count = table_count
|
||||||
self.max_rows = 10000000
|
self.max_rows = 10000000
|
||||||
self.current_ts = round(time.time() * 1000) - self.max_rows * 100
|
self.current_ts = round(time.time() * 1000) - self.max_rows * 100
|
||||||
# [(tableId, tableName, values),]
|
# [(tableId, tableName, values),]
|
||||||
self.data = self._init_data()
|
self.data = self._init_data()
|
||||||
|
self.infinity = infinity
|
||||||
|
|
||||||
def _init_data(self):
|
def _init_data(self):
|
||||||
lines = self.samples * (self.table_count // 5 + 1)
|
lines = self.samples * (self.table_count // 5 + 1)
|
||||||
|
@ -28,6 +29,9 @@ class MockDataSource:
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
self.row = 0
|
self.row = 0
|
||||||
|
if not self.infinity:
|
||||||
|
return iter(self._iter_data())
|
||||||
|
else:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __next__(self):
|
def __next__(self):
|
||||||
|
@ -35,7 +39,9 @@ class MockDataSource:
|
||||||
next 1000 rows for each table.
|
next 1000 rows for each table.
|
||||||
return: {tableId:[row,...]}
|
return: {tableId:[row,...]}
|
||||||
"""
|
"""
|
||||||
# generate 1000 timestamps
|
return self._iter_data()
|
||||||
|
|
||||||
|
def _iter_data(self):
|
||||||
ts = []
|
ts = []
|
||||||
for _ in range(1000):
|
for _ in range(1000):
|
||||||
self.current_ts += 100
|
self.current_ts += 100
|
||||||
|
@ -47,3 +53,10 @@ class MockDataSource:
|
||||||
rows = [table_name + ',' + t + ',' + values for t in ts]
|
rows = [table_name + ',' + t + ',' + values for t in ts]
|
||||||
result.append((table_id, rows))
|
result.append((table_id, rows))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
datasource = MockDataSource('t', 10, False)
|
||||||
|
for data in datasource:
|
||||||
|
print(data)
|
||||||
|
|
|
@ -10,6 +10,7 @@ class SQLWriter:
|
||||||
self._tb_tags = {}
|
self._tb_tags = {}
|
||||||
self._conn = get_connection_func()
|
self._conn = get_connection_func()
|
||||||
self._max_sql_length = self.get_max_sql_length()
|
self._max_sql_length = self.get_max_sql_length()
|
||||||
|
self._conn.execute("create database if not exists test")
|
||||||
self._conn.execute("USE test")
|
self._conn.execute("USE test")
|
||||||
|
|
||||||
def get_max_sql_length(self):
|
def get_max_sql_length(self):
|
||||||
|
@ -20,7 +21,7 @@ class SQLWriter:
|
||||||
return int(r[1])
|
return int(r[1])
|
||||||
return 1024 * 1024
|
return 1024 * 1024
|
||||||
|
|
||||||
def process_lines(self, lines: str):
|
def process_lines(self, lines: [str]):
|
||||||
"""
|
"""
|
||||||
:param lines: [[tbName,ts,current,voltage,phase,location,groupId]]
|
:param lines: [[tbName,ts,current,voltage,phase,location,groupId]]
|
||||||
"""
|
"""
|
||||||
|
@ -60,6 +61,7 @@ class SQLWriter:
|
||||||
buf.append(q)
|
buf.append(q)
|
||||||
sql_len += len(q)
|
sql_len += len(q)
|
||||||
sql += " ".join(buf)
|
sql += " ".join(buf)
|
||||||
|
self.create_tables()
|
||||||
self.execute_sql(sql)
|
self.execute_sql(sql)
|
||||||
self._tb_values.clear()
|
self._tb_values.clear()
|
||||||
|
|
||||||
|
@ -88,3 +90,23 @@ class SQLWriter:
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
self.log.error("Execute SQL: %s", sql)
|
self.log.error("Execute SQL: %s", sql)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self._conn:
|
||||||
|
self._conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
def get_connection_func():
|
||||||
|
conn = taos.connect()
|
||||||
|
return conn
|
||||||
|
|
||||||
|
|
||||||
|
writer = SQLWriter(get_connection_func=get_connection_func)
|
||||||
|
writer.execute_sql(
|
||||||
|
"create stable if not exists meters (ts timestamp, current float, voltage int, phase float) "
|
||||||
|
"tags (location binary(64), groupId int)")
|
||||||
|
writer.execute_sql(
|
||||||
|
"INSERT INTO d21001 USING meters TAGS ('California.SanFrancisco', 2) "
|
||||||
|
"VALUES ('2021-07-13 14:06:32.272', 10.2, 219, 0.32)")
|
||||||
|
|
|
@ -1,58 +1,55 @@
|
||||||
|
from taos.tmq import Consumer
|
||||||
import taos
|
import taos
|
||||||
from taos.tmq import *
|
|
||||||
|
|
||||||
|
|
||||||
|
def init_tmq_env(db, topic):
|
||||||
conn = taos.connect()
|
conn = taos.connect()
|
||||||
|
conn.execute("drop topic if exists {}".format(topic))
|
||||||
print("init")
|
conn.execute("drop database if exists {}".format(db))
|
||||||
conn.execute("drop topic if exists topic_ctb_column")
|
conn.execute("create database if not exists {}".format(db))
|
||||||
conn.execute("drop database if exists py_tmq")
|
conn.select_db(db)
|
||||||
conn.execute("create database if not exists py_tmq vgroups 2")
|
|
||||||
conn.select_db("py_tmq")
|
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"create stable if not exists stb1 (ts timestamp, c1 int, c2 float, c3 binary(10)) tags(t1 int)"
|
"create stable if not exists stb1 (ts timestamp, c1 int, c2 float, c3 varchar(16)) tags(t1 int, t3 varchar(16))")
|
||||||
|
conn.execute("create table if not exists tb1 using stb1 tags(1, 't1')")
|
||||||
|
conn.execute("create table if not exists tb2 using stb1 tags(2, 't2')")
|
||||||
|
conn.execute("create table if not exists tb3 using stb1 tags(3, 't3')")
|
||||||
|
conn.execute("create topic if not exists {} as select ts, c1, c2, c3 from stb1".format(topic))
|
||||||
|
conn.execute("insert into tb1 values (now, 1, 1.0, 'tmq test')")
|
||||||
|
conn.execute("insert into tb2 values (now, 2, 2.0, 'tmq test')")
|
||||||
|
conn.execute("insert into tb3 values (now, 3, 3.0, 'tmq test')")
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup(db, topic):
|
||||||
|
conn = taos.connect()
|
||||||
|
conn.execute("drop topic if exists {}".format(topic))
|
||||||
|
conn.execute("drop database if exists {}".format(db))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
init_tmq_env("tmq_test", "tmq_test_topic") # init env
|
||||||
|
consumer = Consumer(
|
||||||
|
{
|
||||||
|
"group.id": "tg2",
|
||||||
|
"td.connect.user": "root",
|
||||||
|
"td.connect.pass": "taosdata",
|
||||||
|
"enable.auto.commit": "true",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
conn.execute("create table if not exists tb1 using stb1 tags(1)")
|
consumer.subscribe(["tmq_test_topic"])
|
||||||
conn.execute("create table if not exists tb2 using stb1 tags(2)")
|
|
||||||
conn.execute("create table if not exists tb3 using stb1 tags(3)")
|
|
||||||
|
|
||||||
print("create topic")
|
try:
|
||||||
conn.execute(
|
while True:
|
||||||
"create topic if not exists topic_ctb_column as select ts, c1, c2, c3 from stb1"
|
res = consumer.poll(1)
|
||||||
)
|
if not res:
|
||||||
|
break
|
||||||
|
err = res.error()
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
val = res.value()
|
||||||
|
|
||||||
print("build consumer")
|
for block in val:
|
||||||
conf = TaosTmqConf()
|
print(block.fetchall())
|
||||||
conf.set("group.id", "tg2")
|
finally:
|
||||||
conf.set("td.connect.user", "root")
|
consumer.unsubscribe()
|
||||||
conf.set("td.connect.pass", "taosdata")
|
consumer.close()
|
||||||
conf.set("enable.auto.commit", "true")
|
cleanup("tmq_test", "tmq_test_topic")
|
||||||
|
|
||||||
|
|
||||||
def tmq_commit_cb_print(tmq, resp, offset, param=None):
|
|
||||||
print(f"commit: {resp}, tmq: {tmq}, offset: {offset}, param: {param}")
|
|
||||||
|
|
||||||
|
|
||||||
conf.set_auto_commit_cb(tmq_commit_cb_print, None)
|
|
||||||
tmq = conf.new_consumer()
|
|
||||||
|
|
||||||
print("build topic list")
|
|
||||||
|
|
||||||
topic_list = TaosTmqList()
|
|
||||||
topic_list.append("topic_ctb_column")
|
|
||||||
|
|
||||||
print("basic consume loop")
|
|
||||||
tmq.subscribe(topic_list)
|
|
||||||
|
|
||||||
sub_list = tmq.subscription()
|
|
||||||
|
|
||||||
print("subscribed topics: ", sub_list)
|
|
||||||
|
|
||||||
while 1:
|
|
||||||
res = tmq.poll(1000)
|
|
||||||
if res:
|
|
||||||
topic = res.get_topic_name()
|
|
||||||
vg = res.get_vgroup_id()
|
|
||||||
db = res.get_db_name()
|
|
||||||
print(f"topic: {topic}\nvgroup id: {vg}\ndb: {db}")
|
|
||||||
for row in res:
|
|
||||||
print(row)
|
|
|
@ -875,9 +875,9 @@ INTERP(expr)
|
||||||
- INTERP 用于在指定时间断面获取指定列的记录值,如果该时间断面不存在符合条件的行数据,那么会根据 FILL 参数的设定进行插值。
|
- INTERP 用于在指定时间断面获取指定列的记录值,如果该时间断面不存在符合条件的行数据,那么会根据 FILL 参数的设定进行插值。
|
||||||
- INTERP 的输入数据为指定列的数据,可以通过条件语句(where 子句)来对原始列数据进行过滤,如果没有指定过滤条件则输入为全部数据。
|
- INTERP 的输入数据为指定列的数据,可以通过条件语句(where 子句)来对原始列数据进行过滤,如果没有指定过滤条件则输入为全部数据。
|
||||||
- INTERP 需要同时与 RANGE,EVERY 和 FILL 关键字一起使用。
|
- INTERP 需要同时与 RANGE,EVERY 和 FILL 关键字一起使用。
|
||||||
- INTERP 的输出时间范围根据 RANGE(timestamp1,timestamp2)字段来指定,需满足 timestamp1<=timestamp2。其中 timestamp1(必选值)为输出时间范围的起始值,即如果 timestamp1 时刻符合插值条件则 timestamp1 为输出的第一条记录,timestamp2(必选值)为输出时间范围的结束值,即输出的最后一条记录的 timestamp 不能大于 timestamp2。
|
- INTERP 的输出时间范围根据 RANGE(timestamp1,timestamp2)字段来指定,需满足 timestamp1 < timestamp2。其中 timestamp1(必选值)为输出时间范围的起始值,即如果 timestamp1 时刻符合插值条件则 timestamp1 为输出的第一条记录,timestamp2(必选值)为输出时间范围的结束值,即输出的最后一条记录的 timestamp 不能大于 timestamp2。
|
||||||
- INTERP 根据 EVERY 字段来确定输出时间范围内的结果条数,即从 timestamp1 开始每隔固定长度的时间(EVERY 值)进行插值。
|
- INTERP 根据 EVERY(time_unit) 字段来确定输出时间范围内的结果条数,即从 timestamp1 开始每隔固定长度的时间(time_unit 值)进行插值,time_unit 可取值时间单位:1a(毫秒),1s(秒),1m(分),1h(小时),1d(天),1w(周)。例如 EVERY(500a) 将对于指定数据每500毫秒间隔进行一次插值.
|
||||||
- INTERP 根据 FILL 字段来决定在每个符合输出条件的时刻如何进行插值。
|
- INTERP 根据 FILL 字段来决定在每个符合输出条件的时刻如何进行插值。关于 FILL 子句如何使用请参考 [FILL 子句](./distinguished/#fill-子句)
|
||||||
- INTERP 只能在一个时间序列内进行插值,因此当作用于超级表时必须跟 partition by tbname 一起使用。
|
- INTERP 只能在一个时间序列内进行插值,因此当作用于超级表时必须跟 partition by tbname 一起使用。
|
||||||
- INTERP 可以与伪列 _irowts 一起使用,返回插值点所对应的时间戳(3.0.1.4版本以后支持)。
|
- INTERP 可以与伪列 _irowts 一起使用,返回插值点所对应的时间戳(3.0.1.4版本以后支持)。
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ extern int32_t tMsgDict[];
|
||||||
#define TMSG_INFO(TYPE) \
|
#define TMSG_INFO(TYPE) \
|
||||||
((TYPE) < TDMT_DND_MAX_MSG || (TYPE) < TDMT_MND_MAX_MSG || (TYPE) < TDMT_VND_MAX_MSG || (TYPE) < TDMT_SCH_MAX_MSG || \
|
((TYPE) < TDMT_DND_MAX_MSG || (TYPE) < TDMT_MND_MAX_MSG || (TYPE) < TDMT_VND_MAX_MSG || (TYPE) < TDMT_SCH_MAX_MSG || \
|
||||||
(TYPE) < TDMT_STREAM_MAX_MSG || (TYPE) < TDMT_MON_MAX_MSG || (TYPE) < TDMT_SYNC_MAX_MSG) || \
|
(TYPE) < TDMT_STREAM_MAX_MSG || (TYPE) < TDMT_MON_MAX_MSG || (TYPE) < TDMT_SYNC_MAX_MSG) || \
|
||||||
(TYPE) < TDMT_VND_STREAM_MSG || (TYPE) < TDMT_VND_TMQ_MSG \
|
(TYPE) < TDMT_VND_STREAM_MSG || (TYPE) < TDMT_VND_TMQ_MSG || (TYPE) < TDMT_VND_TMQ_MAX_MSG \
|
||||||
? tMsgInfo[tMsgDict[TMSG_SEG_CODE(TYPE)] + TMSG_SEG_SEQ(TYPE)] \
|
? tMsgInfo[tMsgDict[TMSG_SEG_CODE(TYPE)] + TMSG_SEG_SEQ(TYPE)] \
|
||||||
: 0
|
: 0
|
||||||
|
|
||||||
|
|
|
@ -218,6 +218,7 @@ bool fmIsKeepOrderFunc(int32_t funcId);
|
||||||
bool fmIsCumulativeFunc(int32_t funcId);
|
bool fmIsCumulativeFunc(int32_t funcId);
|
||||||
bool fmIsInterpPseudoColumnFunc(int32_t funcId);
|
bool fmIsInterpPseudoColumnFunc(int32_t funcId);
|
||||||
bool fmIsGroupKeyFunc(int32_t funcId);
|
bool fmIsGroupKeyFunc(int32_t funcId);
|
||||||
|
bool fmIsBlockDistFunc(int32_t funcId);
|
||||||
|
|
||||||
void getLastCacheDataType(SDataType* pType);
|
void getLastCacheDataType(SDataType* pType);
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,8 @@ int32_t qCreateSName(SName* pName, const char* pTableName, int32_t acctId, char*
|
||||||
void* smlInitHandle(SQuery* pQuery);
|
void* smlInitHandle(SQuery* pQuery);
|
||||||
void smlDestroyHandle(void* pHandle);
|
void smlDestroyHandle(void* pHandle);
|
||||||
int32_t smlBindData(void* handle, SArray* tags, SArray* colsSchema, SArray* cols, bool format, STableMeta* pTableMeta,
|
int32_t smlBindData(void* handle, SArray* tags, SArray* colsSchema, SArray* cols, bool format, STableMeta* pTableMeta,
|
||||||
char* tableName, const char* sTableName, int32_t sTableNameLen, int32_t ttl, char* msgBuf, int16_t msgBufLen);
|
char* tableName, const char* sTableName, int32_t sTableNameLen, int32_t ttl, char* msgBuf,
|
||||||
|
int16_t msgBufLen);
|
||||||
int32_t smlBuildOutput(void* handle, SHashObj* pVgHash);
|
int32_t smlBuildOutput(void* handle, SHashObj* pVgHash);
|
||||||
|
|
||||||
int32_t rewriteToVnodeModifyOpStmt(SQuery* pQuery, SArray* pBufArray);
|
int32_t rewriteToVnodeModifyOpStmt(SQuery* pQuery, SArray* pBufArray);
|
||||||
|
|
|
@ -201,6 +201,7 @@ int32_t walFetchHead(SWalReader *pRead, int64_t ver, SWalCkHead *pHead);
|
||||||
int32_t walFetchBody(SWalReader *pRead, SWalCkHead **ppHead);
|
int32_t walFetchBody(SWalReader *pRead, SWalCkHead **ppHead);
|
||||||
int32_t walSkipFetchBody(SWalReader *pRead, const SWalCkHead *pHead);
|
int32_t walSkipFetchBody(SWalReader *pRead, const SWalCkHead *pHead);
|
||||||
|
|
||||||
|
SWalRef *walRefFirstVer(SWal *, SWalRef *);
|
||||||
SWalRef *walRefCommittedVer(SWal *);
|
SWalRef *walRefCommittedVer(SWal *);
|
||||||
|
|
||||||
SWalRef *walOpenRef(SWal *);
|
SWalRef *walOpenRef(SWal *);
|
||||||
|
|
|
@ -355,6 +355,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_MND_STREAM_MUST_BE_DELETED TAOS_DEF_ERROR_CODE(0, 0x03F3)
|
#define TSDB_CODE_MND_STREAM_MUST_BE_DELETED TAOS_DEF_ERROR_CODE(0, 0x03F3)
|
||||||
#define TSDB_CODE_MND_STREAM_TASK_DROPPED TAOS_DEF_ERROR_CODE(0, 0x03F4)
|
#define TSDB_CODE_MND_STREAM_TASK_DROPPED TAOS_DEF_ERROR_CODE(0, 0x03F4)
|
||||||
#define TSDB_CODE_MND_MULTI_REPLICA_SOURCE_DB TAOS_DEF_ERROR_CODE(0, 0x03F5)
|
#define TSDB_CODE_MND_MULTI_REPLICA_SOURCE_DB TAOS_DEF_ERROR_CODE(0, 0x03F5)
|
||||||
|
#define TSDB_CODE_MND_TOO_MANY_STREAMS TAOS_DEF_ERROR_CODE(0, 0x03F6)
|
||||||
|
|
||||||
// mnode-sma
|
// mnode-sma
|
||||||
#define TSDB_CODE_MND_SMA_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0480)
|
#define TSDB_CODE_MND_SMA_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0480)
|
||||||
|
|
|
@ -210,8 +210,8 @@ function install_bin() {
|
||||||
[ -x ${install_main_dir}/bin/${serverName} ] && ${csudo}ln -s ${install_main_dir}/bin/${serverName} ${bin_link_dir}/${serverName} || :
|
[ -x ${install_main_dir}/bin/${serverName} ] && ${csudo}ln -s ${install_main_dir}/bin/${serverName} ${bin_link_dir}/${serverName} || :
|
||||||
[ -x ${install_main_dir}/bin/${udfdName} ] && ${csudo}ln -s ${install_main_dir}/bin/${udfdName} ${bin_link_dir}/${udfdName} || :
|
[ -x ${install_main_dir}/bin/${udfdName} ] && ${csudo}ln -s ${install_main_dir}/bin/${udfdName} ${bin_link_dir}/${udfdName} || :
|
||||||
[ -x ${install_main_dir}/bin/${adapterName} ] && ${csudo}ln -s ${install_main_dir}/bin/${adapterName} ${bin_link_dir}/${adapterName} || :
|
[ -x ${install_main_dir}/bin/${adapterName} ] && ${csudo}ln -s ${install_main_dir}/bin/${adapterName} ${bin_link_dir}/${adapterName} || :
|
||||||
[ -x ${install_main_dir}/bin/${benchmarkName} ] && ${csudo}ln -s ${install_main_dir}/bin/${benchmarkName} ${bin_link_dir}/${demoName} || :
|
[ -x ${install_main_dir}/bin/${benchmarkName} ] && ${csudo}ln -sf ${install_main_dir}/bin/${benchmarkName} ${bin_link_dir}/${demoName} || :
|
||||||
[ -x ${install_main_dir}/bin/${benchmarkName} ] && ${csudo}ln -s ${install_main_dir}/bin/${benchmarkName} ${bin_link_dir}/${benchmarkName} || :
|
[ -x ${install_main_dir}/bin/${benchmarkName} ] && ${csudo}ln -sf ${install_main_dir}/bin/${benchmarkName} ${bin_link_dir}/${benchmarkName} || :
|
||||||
[ -x ${install_main_dir}/bin/${dumpName} ] && ${csudo}ln -s ${install_main_dir}/bin/${dumpName} ${bin_link_dir}/${dumpName} || :
|
[ -x ${install_main_dir}/bin/${dumpName} ] && ${csudo}ln -s ${install_main_dir}/bin/${dumpName} ${bin_link_dir}/${dumpName} || :
|
||||||
[ -x ${install_main_dir}/bin/${xname} ] && ${csudo}ln -s ${install_main_dir}/bin/${xname} ${bin_link_dir}/${xname} || :
|
[ -x ${install_main_dir}/bin/${xname} ] && ${csudo}ln -s ${install_main_dir}/bin/${xname} ${bin_link_dir}/${xname} || :
|
||||||
[ -x ${install_main_dir}/bin/TDinsight.sh ] && ${csudo}ln -s ${install_main_dir}/bin/TDinsight.sh ${bin_link_dir}/TDinsight.sh || :
|
[ -x ${install_main_dir}/bin/TDinsight.sh ] && ${csudo}ln -s ${install_main_dir}/bin/TDinsight.sh ${bin_link_dir}/TDinsight.sh || :
|
||||||
|
@ -746,7 +746,7 @@ function is_version_compatible() {
|
||||||
deb_erase() {
|
deb_erase() {
|
||||||
confirm=""
|
confirm=""
|
||||||
while [ "" == "${confirm}" ]; do
|
while [ "" == "${confirm}" ]; do
|
||||||
echo -e -n "${RED}Exist tdengine deb detected, do you want to remove it? [yes|no] ${NC}:"
|
echo -e -n "${RED}Existing TDengine deb is detected, do you want to remove it? [yes|no] ${NC}:"
|
||||||
read confirm
|
read confirm
|
||||||
if [ "yes" == "$confirm" ]; then
|
if [ "yes" == "$confirm" ]; then
|
||||||
${csudo}dpkg --remove tdengine ||:
|
${csudo}dpkg --remove tdengine ||:
|
||||||
|
@ -760,7 +760,7 @@ deb_erase() {
|
||||||
rpm_erase() {
|
rpm_erase() {
|
||||||
confirm=""
|
confirm=""
|
||||||
while [ "" == "${confirm}" ]; do
|
while [ "" == "${confirm}" ]; do
|
||||||
echo -e -n "${RED}Exist tdengine rpm detected, do you want to remove it? [yes|no] ${NC}:"
|
echo -e -n "${RED}Existing TDengine rpm is detected, do you want to remove it? [yes|no] ${NC}:"
|
||||||
read confirm
|
read confirm
|
||||||
if [ "yes" == "$confirm" ]; then
|
if [ "yes" == "$confirm" ]; then
|
||||||
${csudo}rpm -e tdengine ||:
|
${csudo}rpm -e tdengine ||:
|
||||||
|
@ -787,7 +787,7 @@ function updateProduct() {
|
||||||
if echo $osinfo | grep -qwi "centos"; then
|
if echo $osinfo | grep -qwi "centos"; then
|
||||||
rpm -q tdengine 2>&1 > /dev/null && rpm_erase tdengine ||:
|
rpm -q tdengine 2>&1 > /dev/null && rpm_erase tdengine ||:
|
||||||
elif echo $osinfo | grep -qwi "ubuntu"; then
|
elif echo $osinfo | grep -qwi "ubuntu"; then
|
||||||
dpkg -l tdengine 2>&1 > /dev/null && deb_erase tdengine ||:
|
dpkg -l tdengine 2>&1 | grep ii > /dev/null && deb_erase tdengine ||:
|
||||||
fi
|
fi
|
||||||
|
|
||||||
tar -zxf ${tarName}
|
tar -zxf ${tarName}
|
||||||
|
|
|
@ -138,6 +138,12 @@ STscObj* taos_connect_internal(const char* ip, const char* user, const char* pas
|
||||||
p->mgmtEp = epSet;
|
p->mgmtEp = epSet;
|
||||||
taosThreadMutexInit(&p->qnodeMutex, NULL);
|
taosThreadMutexInit(&p->qnodeMutex, NULL);
|
||||||
p->pTransporter = openTransporter(user, secretEncrypt, tsNumOfCores / 2);
|
p->pTransporter = openTransporter(user, secretEncrypt, tsNumOfCores / 2);
|
||||||
|
if (p->pTransporter == NULL) {
|
||||||
|
taosThreadMutexUnlock(&appInfo.mutex);
|
||||||
|
taosMemoryFreeClear(key);
|
||||||
|
taosMemoryFree(p);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
p->pAppHbMgr = appHbMgrInit(p, key);
|
p->pAppHbMgr = appHbMgrInit(p, key);
|
||||||
if (NULL == p->pAppHbMgr) {
|
if (NULL == p->pAppHbMgr) {
|
||||||
destroyAppInst(p);
|
destroyAppInst(p);
|
||||||
|
@ -1402,8 +1408,6 @@ int32_t doProcessMsgFromServer(void* param) {
|
||||||
tscError("0x%" PRIx64 " rsp msg:%s, code:%s rspLen:%d, elapsed time:%d ms, reqId:0x%" PRIx64, pRequest->self,
|
tscError("0x%" PRIx64 " rsp msg:%s, code:%s rspLen:%d, elapsed time:%d ms, reqId:0x%" PRIx64, pRequest->self,
|
||||||
TMSG_INFO(pMsg->msgType), tstrerror(pMsg->code), pMsg->contLen, elapsed / 1000, pRequest->requestId);
|
TMSG_INFO(pMsg->msgType), tstrerror(pMsg->code), pMsg->contLen, elapsed / 1000, pRequest->requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosReleaseRef(clientReqRefPool, pSendInfo->requestObjRefId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1423,6 +1427,11 @@ int32_t doProcessMsgFromServer(void* param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pSendInfo->fp(pSendInfo->param, &buf, pMsg->code);
|
pSendInfo->fp(pSendInfo->param, &buf, pMsg->code);
|
||||||
|
|
||||||
|
if (pTscObj) {
|
||||||
|
taosReleaseRef(clientReqRefPool, pSendInfo->requestObjRefId);
|
||||||
|
}
|
||||||
|
|
||||||
rpcFreeCont(pMsg->pCont);
|
rpcFreeCont(pMsg->pCont);
|
||||||
destroySendMsgInfo(pSendInfo);
|
destroySendMsgInfo(pSendInfo);
|
||||||
|
|
||||||
|
@ -1460,6 +1469,7 @@ void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
|
||||||
tscError("failed to sched msg to tsc, tsc ready to quit");
|
tscError("failed to sched msg to tsc, tsc ready to quit");
|
||||||
rpcFreeCont(pMsg->pCont);
|
rpcFreeCont(pMsg->pCont);
|
||||||
taosMemoryFree(arg->pEpset);
|
taosMemoryFree(arg->pEpset);
|
||||||
|
destroySendMsgInfo(pMsg->info.ahandle);
|
||||||
taosMemoryFree(arg);
|
taosMemoryFree(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,8 @@ int32_t stmtRestoreQueryFields(STscStmt* pStmt) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, SName* tbName, const char* sTableName, bool autoCreateTbl) {
|
int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, SName* tbName, const char* sTableName,
|
||||||
|
bool autoCreateTbl) {
|
||||||
STscStmt* pStmt = (STscStmt*)stmt;
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||||
tNameExtractFullName(tbName, tbFName);
|
tNameExtractFullName(tbName, tbFName);
|
||||||
|
|
|
@ -1891,9 +1891,6 @@ int32_t tmq_consumer_close(tmq_t* tmq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tmq_list_destroy(lst);
|
tmq_list_destroy(lst);
|
||||||
|
|
||||||
/*return rsp;*/
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
taosRemoveRef(tmqMgmt.rsetId, tmq->refId);
|
taosRemoveRef(tmqMgmt.rsetId, tmq->refId);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1431,6 +1431,7 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
||||||
pBlock->info.rows = 0;
|
pBlock->info.rows = 0;
|
||||||
pBlock->info.capacity = 0;
|
pBlock->info.capacity = 0;
|
||||||
pBlock->info.rowSize = 0;
|
pBlock->info.rowSize = 0;
|
||||||
|
pBlock->info.id = pDataBlock->info.id;
|
||||||
|
|
||||||
size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
|
size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
|
||||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
|
|
@ -167,6 +167,7 @@ SArray *mmGetMsgHandles() {
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_CREATE_STB_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_CREATE_STB_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_STB_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_STB_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_STB_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_STB_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
|
if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TTL_TABLE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_CREATE_SMA_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_CREATE_SMA_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_SMA_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_SMA_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_SUBSCRIBE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_SUBSCRIBE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
|
|
|
@ -49,7 +49,7 @@ static void mmProcessRpcMsg(SQueueInfo *pInfo, SRpcMsg *pMsg) {
|
||||||
pMsg->info.node = pMgmt->pMnode;
|
pMsg->info.node = pMgmt->pMnode;
|
||||||
|
|
||||||
const STraceId *trace = &pMsg->info.traceId;
|
const STraceId *trace = &pMsg->info.traceId;
|
||||||
dGTrace("msg:%p, get from mnode queue", pMsg);
|
dGTrace("msg:%p, get from mnode queue, type:%s", pMsg, TMSG_INFO(pMsg->msgType));
|
||||||
|
|
||||||
int32_t code = mndProcessRpcMsg(pMsg);
|
int32_t code = mndProcessRpcMsg(pMsg);
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,6 @@ int32_t vmOpenVnode(SVnodeMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl) {
|
||||||
void vmCloseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) {
|
void vmCloseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) {
|
||||||
char path[TSDB_FILENAME_LEN] = {0};
|
char path[TSDB_FILENAME_LEN] = {0};
|
||||||
|
|
||||||
vnodeProposeCommitOnNeed(pVnode->pImpl);
|
|
||||||
|
|
||||||
taosThreadRwlockWrlock(&pMgmt->lock);
|
taosThreadRwlockWrlock(&pMgmt->lock);
|
||||||
taosHashRemove(pMgmt->hash, &pVnode->vgId, sizeof(int32_t));
|
taosHashRemove(pMgmt->hash, &pVnode->vgId, sizeof(int32_t));
|
||||||
taosThreadRwlockUnlock(&pMgmt->lock);
|
taosThreadRwlockUnlock(&pMgmt->lock);
|
||||||
|
|
|
@ -81,7 +81,7 @@ int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans);
|
||||||
int32_t mndTransProcessRsp(SRpcMsg *pRsp);
|
int32_t mndTransProcessRsp(SRpcMsg *pRsp);
|
||||||
void mndTransPullup(SMnode *pMnode);
|
void mndTransPullup(SMnode *pMnode);
|
||||||
int32_t mndKillTrans(SMnode *pMnode, STrans *pTrans);
|
int32_t mndKillTrans(SMnode *pMnode, STrans *pTrans);
|
||||||
void mndTransExecute(SMnode *pMnode, STrans *pTrans);
|
void mndTransExecute(SMnode *pMnode, STrans *pTrans, bool isLeader);
|
||||||
int32_t mndSetRpcInfoForDbTrans(SMnode *pMnode, SRpcMsg *pMsg, EOperType oper, const char *dbname);
|
int32_t mndSetRpcInfoForDbTrans(SMnode *pMnode, SRpcMsg *pMsg, EOperType oper, const char *dbname);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -836,10 +836,13 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
|
||||||
|
|
||||||
char *addedTopic = strdup(taosArrayGetP(pNewConsumer->rebNewTopics, 0));
|
char *addedTopic = strdup(taosArrayGetP(pNewConsumer->rebNewTopics, 0));
|
||||||
// not exist in current topic
|
// not exist in current topic
|
||||||
|
bool existing = false;
|
||||||
#if 1
|
#if 1
|
||||||
for (int32_t i = 0; i < taosArrayGetSize(pOldConsumer->currentTopics); i++) {
|
for (int32_t i = 0; i < taosArrayGetSize(pOldConsumer->currentTopics); i++) {
|
||||||
char *topic = taosArrayGetP(pOldConsumer->currentTopics, i);
|
char *topic = taosArrayGetP(pOldConsumer->currentTopics, i);
|
||||||
ASSERT(strcmp(topic, addedTopic) != 0);
|
if (strcmp(topic, addedTopic) == 0) {
|
||||||
|
existing = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -854,8 +857,10 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
|
||||||
}
|
}
|
||||||
|
|
||||||
// add to current topic
|
// add to current topic
|
||||||
|
if (!existing) {
|
||||||
taosArrayPush(pOldConsumer->currentTopics, &addedTopic);
|
taosArrayPush(pOldConsumer->currentTopics, &addedTopic);
|
||||||
taosArraySort(pOldConsumer->currentTopics, taosArrayCompareString);
|
taosArraySort(pOldConsumer->currentTopics, taosArrayCompareString);
|
||||||
|
}
|
||||||
|
|
||||||
// set status
|
// set status
|
||||||
if (taosArrayGetSize(pOldConsumer->rebNewTopics) == 0 && taosArrayGetSize(pOldConsumer->rebRemovedTopics) == 0) {
|
if (taosArrayGetSize(pOldConsumer->rebNewTopics) == 0 && taosArrayGetSize(pOldConsumer->rebRemovedTopics) == 0) {
|
||||||
|
|
|
@ -41,6 +41,7 @@ static int32_t mndProcessTtlTimer(SRpcMsg *pReq);
|
||||||
static int32_t mndProcessCreateStbReq(SRpcMsg *pReq);
|
static int32_t mndProcessCreateStbReq(SRpcMsg *pReq);
|
||||||
static int32_t mndProcessAlterStbReq(SRpcMsg *pReq);
|
static int32_t mndProcessAlterStbReq(SRpcMsg *pReq);
|
||||||
static int32_t mndProcessDropStbReq(SRpcMsg *pReq);
|
static int32_t mndProcessDropStbReq(SRpcMsg *pReq);
|
||||||
|
static int32_t mndProcessDropTtltbReq(SRpcMsg *pReq);
|
||||||
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq);
|
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq);
|
||||||
static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
||||||
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter);
|
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter);
|
||||||
|
@ -64,6 +65,7 @@ int32_t mndInitStb(SMnode *pMnode) {
|
||||||
mndSetMsgHandle(pMnode, TDMT_MND_ALTER_STB, mndProcessAlterStbReq);
|
mndSetMsgHandle(pMnode, TDMT_MND_ALTER_STB, mndProcessAlterStbReq);
|
||||||
mndSetMsgHandle(pMnode, TDMT_MND_DROP_STB, mndProcessDropStbReq);
|
mndSetMsgHandle(pMnode, TDMT_MND_DROP_STB, mndProcessDropStbReq);
|
||||||
mndSetMsgHandle(pMnode, TDMT_VND_CREATE_STB_RSP, mndTransProcessRsp);
|
mndSetMsgHandle(pMnode, TDMT_VND_CREATE_STB_RSP, mndTransProcessRsp);
|
||||||
|
mndSetMsgHandle(pMnode, TDMT_VND_DROP_TTL_TABLE_RSP, mndProcessDropTtltbReq);
|
||||||
mndSetMsgHandle(pMnode, TDMT_VND_ALTER_STB_RSP, mndTransProcessRsp);
|
mndSetMsgHandle(pMnode, TDMT_VND_ALTER_STB_RSP, mndTransProcessRsp);
|
||||||
mndSetMsgHandle(pMnode, TDMT_VND_DROP_STB_RSP, mndTransProcessRsp);
|
mndSetMsgHandle(pMnode, TDMT_VND_DROP_STB_RSP, mndTransProcessRsp);
|
||||||
mndSetMsgHandle(pMnode, TDMT_MND_TABLE_META, mndProcessTableMetaReq);
|
mndSetMsgHandle(pMnode, TDMT_MND_TABLE_META, mndProcessTableMetaReq);
|
||||||
|
@ -2176,6 +2178,10 @@ static int32_t mndCheckDropStbForStream(SMnode *pMnode, const char *stbFullName,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t mndProcessDropTtltbReq(SRpcMsg *pRsp) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t mndProcessDropStbReq(SRpcMsg *pReq) {
|
static int32_t mndProcessDropStbReq(SRpcMsg *pReq) {
|
||||||
SMnode *pMnode = pReq->info.node;
|
SMnode *pMnode = pReq->info.node;
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#define MND_STREAM_VER_NUMBER 2
|
#define MND_STREAM_VER_NUMBER 2
|
||||||
#define MND_STREAM_RESERVE_SIZE 64
|
#define MND_STREAM_RESERVE_SIZE 64
|
||||||
|
|
||||||
|
#define MND_STREAM_MAX_NUM 10
|
||||||
|
|
||||||
static int32_t mndStreamActionInsert(SSdb *pSdb, SStreamObj *pStream);
|
static int32_t mndStreamActionInsert(SSdb *pSdb, SStreamObj *pStream);
|
||||||
static int32_t mndStreamActionDelete(SSdb *pSdb, SStreamObj *pStream);
|
static int32_t mndStreamActionDelete(SSdb *pSdb, SStreamObj *pStream);
|
||||||
static int32_t mndStreamActionUpdate(SSdb *pSdb, SStreamObj *pStream, SStreamObj *pNewStream);
|
static int32_t mndStreamActionUpdate(SSdb *pSdb, SStreamObj *pStream, SStreamObj *pNewStream);
|
||||||
|
@ -627,6 +629,35 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int32_t numOfStream = 0;
|
||||||
|
|
||||||
|
SStreamObj *pStream = NULL;
|
||||||
|
void *pIter = NULL;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
pIter = sdbFetch(pMnode->pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||||
|
if (pIter == NULL) {
|
||||||
|
if (numOfStream > MND_STREAM_MAX_NUM) {
|
||||||
|
mError("too many streams, no more than 10 for each database");
|
||||||
|
terrno = TSDB_CODE_MND_TOO_MANY_STREAMS;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pStream->sourceDbUid == streamObj.sourceDbUid) {
|
||||||
|
++numOfStream;
|
||||||
|
}
|
||||||
|
sdbRelease(pMnode->pSdb, pStream);
|
||||||
|
if (numOfStream > MND_STREAM_MAX_NUM) {
|
||||||
|
mError("too many streams, no more than 10 for each database");
|
||||||
|
terrno = TSDB_CODE_MND_TOO_MANY_STREAMS;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pDb = mndAcquireDb(pMnode, streamObj.sourceDb);
|
pDb = mndAcquireDb(pMnode, streamObj.sourceDb);
|
||||||
if (pDb->cfg.replications != 1) {
|
if (pDb->cfg.replications != 1) {
|
||||||
mError("stream source db must have only 1 replica, but %s has %d", pDb->name, pDb->cfg.replications);
|
mError("stream source db must have only 1 replica, but %s has %d", pDb->name, pDb->cfg.replications);
|
||||||
|
|
|
@ -85,7 +85,11 @@ int32_t mndProcessWriteMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFsmCbMeta
|
||||||
pRaw, pMgmt->transSec, pMgmt->transSeq);
|
pRaw, pMgmt->transSec, pMgmt->transSeq);
|
||||||
|
|
||||||
if (pMeta->code == 0) {
|
if (pMeta->code == 0) {
|
||||||
sdbWriteWithoutFree(pMnode->pSdb, pRaw);
|
int32_t code = sdbWriteWithoutFree(pMnode->pSdb, pRaw);
|
||||||
|
if (code != 0) {
|
||||||
|
mError("trans:%d, failed to write to sdb since %s", transId, terrstr());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
sdbSetApplyInfo(pMnode->pSdb, pMeta->index, pMeta->term, pMeta->lastConfigIndex);
|
sdbSetApplyInfo(pMnode->pSdb, pMeta->index, pMeta->term, pMeta->lastConfigIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,8 +114,9 @@ int32_t mndProcessWriteMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFsmCbMeta
|
||||||
taosThreadMutexUnlock(&pMgmt->lock);
|
taosThreadMutexUnlock(&pMgmt->lock);
|
||||||
STrans *pTrans = mndAcquireTrans(pMnode, transId);
|
STrans *pTrans = mndAcquireTrans(pMnode, transId);
|
||||||
if (pTrans != NULL) {
|
if (pTrans != NULL) {
|
||||||
mInfo("trans:%d, execute in mnode which not leader or sync timeout", transId);
|
mInfo("trans:%d, execute in mnode which not leader or sync timeout, createTime:%" PRId64 " saved trans:%d",
|
||||||
mndTransExecute(pMnode, pTrans);
|
transId, pTrans->createdTime, pMgmt->transId);
|
||||||
|
mndTransExecute(pMnode, pTrans, false);
|
||||||
mndReleaseTrans(pMnode, pTrans);
|
mndReleaseTrans(pMnode, pTrans);
|
||||||
// sdbWriteFile(pMnode->pSdb, SDB_WRITE_DELTA);
|
// sdbWriteFile(pMnode->pSdb, SDB_WRITE_DELTA);
|
||||||
} else {
|
} else {
|
||||||
|
@ -368,7 +373,7 @@ int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw, int32_t transId) {
|
||||||
taosThreadMutexLock(&pMgmt->lock);
|
taosThreadMutexLock(&pMgmt->lock);
|
||||||
pMgmt->errCode = 0;
|
pMgmt->errCode = 0;
|
||||||
|
|
||||||
if (pMgmt->transId != 0) {
|
if (pMgmt->transId != 0 /* && pMgmt->transId != transId*/) {
|
||||||
mError("trans:%d, can't be proposed since trans:%d already waiting for confirm", transId, pMgmt->transId);
|
mError("trans:%d, can't be proposed since trans:%d already waiting for confirm", transId, pMgmt->transId);
|
||||||
taosThreadMutexUnlock(&pMgmt->lock);
|
taosThreadMutexUnlock(&pMgmt->lock);
|
||||||
rpcFreeCont(req.pCont);
|
rpcFreeCont(req.pCont);
|
||||||
|
|
|
@ -572,8 +572,20 @@ static void mndTransUpdateActions(SArray *pOldArray, SArray *pNewArray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *pOld, STrans *pNew) {
|
static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *pOld, STrans *pNew) {
|
||||||
mTrace("trans:%d, perform update action, old row:%p stage:%s, new row:%p stage:%s", pOld->id, pOld,
|
mTrace("trans:%d, perform update action, old row:%p stage:%s create:%" PRId64 ", new row:%p stage:%s create:%" PRId64,
|
||||||
mndTransStr(pOld->stage), pNew, mndTransStr(pNew->stage));
|
pOld->id, pOld, mndTransStr(pOld->stage), pOld->createdTime, pNew, mndTransStr(pNew->stage),
|
||||||
|
pNew->createdTime);
|
||||||
|
|
||||||
|
if (pOld->createdTime != pNew->createdTime) {
|
||||||
|
mError("trans:%d, failed to perform update action since createTime not match, old row:%p stage:%s create:%" PRId64
|
||||||
|
", new row:%p stage:%s create:%" PRId64,
|
||||||
|
pOld->id, pOld, mndTransStr(pOld->stage), pOld->createdTime, pNew, mndTransStr(pNew->stage),
|
||||||
|
pNew->createdTime);
|
||||||
|
// only occured while sync timeout
|
||||||
|
terrno = TSDB_CODE_MND_TRNAS_SYNC_TIMEOUT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
mndTransUpdateActions(pOld->redoActions, pNew->redoActions);
|
mndTransUpdateActions(pOld->redoActions, pNew->redoActions);
|
||||||
mndTransUpdateActions(pOld->undoActions, pNew->undoActions);
|
mndTransUpdateActions(pOld->undoActions, pNew->undoActions);
|
||||||
mndTransUpdateActions(pOld->commitActions, pNew->commitActions);
|
mndTransUpdateActions(pOld->commitActions, pNew->commitActions);
|
||||||
|
@ -779,16 +791,18 @@ static int32_t mndTransSync(SMnode *pMnode, STrans *pTrans) {
|
||||||
}
|
}
|
||||||
(void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
|
(void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
|
||||||
|
|
||||||
mInfo("trans:%d, sync to other mnodes, stage:%s", pTrans->id, mndTransStr(pTrans->stage));
|
mInfo("trans:%d, sync to other mnodes, stage:%s createTime:%" PRId64, pTrans->id, mndTransStr(pTrans->stage),
|
||||||
|
pTrans->createdTime);
|
||||||
int32_t code = mndSyncPropose(pMnode, pRaw, pTrans->id);
|
int32_t code = mndSyncPropose(pMnode, pRaw, pTrans->id);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
mError("trans:%d, failed to sync, errno:%s code:%s", pTrans->id, terrstr(), tstrerror(code));
|
mError("trans:%d, failed to sync, errno:%s code:%s createTime:%" PRId64 " saved trans:%d", pTrans->id, terrstr(),
|
||||||
|
tstrerror(code), pTrans->createdTime, pMnode->syncMgmt.transId);
|
||||||
sdbFreeRaw(pRaw);
|
sdbFreeRaw(pRaw);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdbFreeRaw(pRaw);
|
sdbFreeRaw(pRaw);
|
||||||
mInfo("trans:%d, sync finished", pTrans->id);
|
mInfo("trans:%d, sync finished, createTime:%" PRId64, pTrans->id, pTrans->createdTime);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,7 +905,7 @@ int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) {
|
||||||
pTrans->rpcRsp = NULL;
|
pTrans->rpcRsp = NULL;
|
||||||
pTrans->rpcRspLen = 0;
|
pTrans->rpcRspLen = 0;
|
||||||
|
|
||||||
mndTransExecute(pMnode, pNew);
|
mndTransExecute(pMnode, pNew, true);
|
||||||
mndReleaseTrans(pMnode, pNew);
|
mndReleaseTrans(pMnode, pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1054,7 +1068,7 @@ int32_t mndTransProcessRsp(SRpcMsg *pRsp) {
|
||||||
|
|
||||||
mInfo("trans:%d, %s:%d response is received, code:0x%x, accept:0x%x retry:0x%x", transId, mndTransStr(pAction->stage),
|
mInfo("trans:%d, %s:%d response is received, code:0x%x, accept:0x%x retry:0x%x", transId, mndTransStr(pAction->stage),
|
||||||
action, pRsp->code, pAction->acceptableCode, pAction->retryCode);
|
action, pRsp->code, pAction->acceptableCode, pAction->retryCode);
|
||||||
mndTransExecute(pMnode, pTrans);
|
mndTransExecute(pMnode, pTrans, true);
|
||||||
|
|
||||||
_OVER:
|
_OVER:
|
||||||
mndReleaseTrans(pMnode, pTrans);
|
mndReleaseTrans(pMnode, pTrans);
|
||||||
|
@ -1483,15 +1497,17 @@ static bool mndTransPerfromFinishedStage(SMnode *pMnode, STrans *pTrans) {
|
||||||
mError("trans:%d, failed to write sdb since %s", pTrans->id, terrstr());
|
mError("trans:%d, failed to write sdb since %s", pTrans->id, terrstr());
|
||||||
}
|
}
|
||||||
|
|
||||||
mInfo("trans:%d, execute finished, code:0x%x, failedTimes:%d", pTrans->id, pTrans->code, pTrans->failedTimes);
|
mInfo("trans:%d, execute finished, code:0x%x, failedTimes:%d createTime:%" PRId64, pTrans->id, pTrans->code,
|
||||||
|
pTrans->failedTimes, pTrans->createdTime);
|
||||||
return continueExec;
|
return continueExec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mndTransExecute(SMnode *pMnode, STrans *pTrans) {
|
void mndTransExecute(SMnode *pMnode, STrans *pTrans, bool isLeader) {
|
||||||
bool continueExec = true;
|
bool continueExec = true;
|
||||||
|
|
||||||
while (continueExec) {
|
while (continueExec) {
|
||||||
mInfo("trans:%d, continue to execute, stage:%s", pTrans->id, mndTransStr(pTrans->stage));
|
mInfo("trans:%d, continue to execute, stage:%s createTime:%" PRId64 " leader:%d", pTrans->id,
|
||||||
|
mndTransStr(pTrans->stage), pTrans->createdTime, isLeader);
|
||||||
pTrans->lastExecTime = taosGetTimestampMs();
|
pTrans->lastExecTime = taosGetTimestampMs();
|
||||||
switch (pTrans->stage) {
|
switch (pTrans->stage) {
|
||||||
case TRN_STAGE_PREPARE:
|
case TRN_STAGE_PREPARE:
|
||||||
|
@ -1501,13 +1517,23 @@ void mndTransExecute(SMnode *pMnode, STrans *pTrans) {
|
||||||
continueExec = mndTransPerformRedoActionStage(pMnode, pTrans);
|
continueExec = mndTransPerformRedoActionStage(pMnode, pTrans);
|
||||||
break;
|
break;
|
||||||
case TRN_STAGE_COMMIT:
|
case TRN_STAGE_COMMIT:
|
||||||
|
if (isLeader) {
|
||||||
continueExec = mndTransPerformCommitStage(pMnode, pTrans);
|
continueExec = mndTransPerformCommitStage(pMnode, pTrans);
|
||||||
|
} else {
|
||||||
|
mInfo("trans:%d, can not commit since not leader", pTrans->id);
|
||||||
|
continueExec = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TRN_STAGE_COMMIT_ACTION:
|
case TRN_STAGE_COMMIT_ACTION:
|
||||||
continueExec = mndTransPerformCommitActionStage(pMnode, pTrans);
|
continueExec = mndTransPerformCommitActionStage(pMnode, pTrans);
|
||||||
break;
|
break;
|
||||||
case TRN_STAGE_ROLLBACK:
|
case TRN_STAGE_ROLLBACK:
|
||||||
|
if (isLeader) {
|
||||||
continueExec = mndTransPerformRollbackStage(pMnode, pTrans);
|
continueExec = mndTransPerformRollbackStage(pMnode, pTrans);
|
||||||
|
} else {
|
||||||
|
mInfo("trans:%d, can not rollback since not leader", pTrans->id);
|
||||||
|
continueExec = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TRN_STAGE_UNDO_ACTION:
|
case TRN_STAGE_UNDO_ACTION:
|
||||||
continueExec = mndTransPerformUndoActionStage(pMnode, pTrans);
|
continueExec = mndTransPerformUndoActionStage(pMnode, pTrans);
|
||||||
|
@ -1550,7 +1576,7 @@ int32_t mndKillTrans(SMnode *pMnode, STrans *pTrans) {
|
||||||
pAction->errCode = 0;
|
pAction->errCode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mndTransExecute(pMnode, pTrans);
|
mndTransExecute(pMnode, pTrans, true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1608,7 +1634,7 @@ void mndTransPullup(SMnode *pMnode) {
|
||||||
int32_t *pTransId = taosArrayGet(pArray, i);
|
int32_t *pTransId = taosArrayGet(pArray, i);
|
||||||
STrans *pTrans = mndAcquireTrans(pMnode, *pTransId);
|
STrans *pTrans = mndAcquireTrans(pMnode, *pTransId);
|
||||||
if (pTrans != NULL) {
|
if (pTrans != NULL) {
|
||||||
mndTransExecute(pMnode, pTrans);
|
mndTransExecute(pMnode, pTrans, true);
|
||||||
}
|
}
|
||||||
mndReleaseTrans(pMnode, pTrans);
|
mndReleaseTrans(pMnode, pTrans);
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,8 @@ int32_t sndExpandTask(SSnode *pSnode, SStreamTask *pTask, int64_t ver) {
|
||||||
pTask->exec.executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &mgHandle);
|
pTask->exec.executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &mgHandle);
|
||||||
ASSERT(pTask->exec.executor);
|
ASSERT(pTask->exec.executor);
|
||||||
|
|
||||||
|
streamSetupTrigger(pTask);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,6 +202,7 @@ int32_t tsdbCmprColData(SColData *pColData, int8_t cmprAlg, SBlockCol *pBlockCol
|
||||||
uint8_t **ppBuf);
|
uint8_t **ppBuf);
|
||||||
int32_t tsdbDecmprColData(uint8_t *pIn, SBlockCol *pBlockCol, int8_t cmprAlg, int32_t nVal, SColData *pColData,
|
int32_t tsdbDecmprColData(uint8_t *pIn, SBlockCol *pBlockCol, int8_t cmprAlg, int32_t nVal, SColData *pColData,
|
||||||
uint8_t **ppBuf);
|
uint8_t **ppBuf);
|
||||||
|
int32_t tRowInfoCmprFn(const void *p1, const void *p2);
|
||||||
// tsdbMemTable ==============================================================================================
|
// tsdbMemTable ==============================================================================================
|
||||||
// SMemTable
|
// SMemTable
|
||||||
int32_t tsdbMemTableCreate(STsdb *pTsdb, SMemTable **ppMemTable);
|
int32_t tsdbMemTableCreate(STsdb *pTsdb, SMemTable **ppMemTable);
|
||||||
|
@ -320,6 +321,8 @@ struct STsdb {
|
||||||
STsdbFS fs;
|
STsdbFS fs;
|
||||||
SLRUCache *lruCache;
|
SLRUCache *lruCache;
|
||||||
TdThreadMutex lruMutex;
|
TdThreadMutex lruMutex;
|
||||||
|
SLRUCache *biCache;
|
||||||
|
TdThreadMutex biMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TSDBKEY {
|
struct TSDBKEY {
|
||||||
|
@ -745,6 +748,9 @@ int32_t tsdbCacheGetLastH(SLRUCache *pCache, tb_uid_t uid, SCacheRowsReader *pr,
|
||||||
int32_t tsdbCacheGetLastrowH(SLRUCache *pCache, tb_uid_t uid, SCacheRowsReader *pr, LRUHandle **h);
|
int32_t tsdbCacheGetLastrowH(SLRUCache *pCache, tb_uid_t uid, SCacheRowsReader *pr, LRUHandle **h);
|
||||||
int32_t tsdbCacheRelease(SLRUCache *pCache, LRUHandle *h);
|
int32_t tsdbCacheRelease(SLRUCache *pCache, LRUHandle *h);
|
||||||
|
|
||||||
|
int32_t tsdbCacheGetBlockIdx(SLRUCache *pCache, SDataFReader *pFileReader, LRUHandle **handle);
|
||||||
|
int32_t tsdbBICacheRelease(SLRUCache *pCache, LRUHandle *h);
|
||||||
|
|
||||||
int32_t tsdbCacheDeleteLastrow(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey);
|
int32_t tsdbCacheDeleteLastrow(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey);
|
||||||
int32_t tsdbCacheDeleteLast(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey);
|
int32_t tsdbCacheDeleteLast(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey);
|
||||||
int32_t tsdbCacheDelete(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey);
|
int32_t tsdbCacheDelete(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey);
|
||||||
|
|
|
@ -247,7 +247,7 @@ int32_t tsdbSnapReaderClose(STsdbSnapReader** ppReader);
|
||||||
int32_t tsdbSnapRead(STsdbSnapReader* pReader, uint8_t** ppData);
|
int32_t tsdbSnapRead(STsdbSnapReader* pReader, uint8_t** ppData);
|
||||||
// STsdbSnapWriter ========================================
|
// STsdbSnapWriter ========================================
|
||||||
int32_t tsdbSnapWriterOpen(STsdb* pTsdb, int64_t sver, int64_t ever, STsdbSnapWriter** ppWriter);
|
int32_t tsdbSnapWriterOpen(STsdb* pTsdb, int64_t sver, int64_t ever, STsdbSnapWriter** ppWriter);
|
||||||
int32_t tsdbSnapWrite(STsdbSnapWriter* pWriter, uint8_t* pData, uint32_t nData);
|
int32_t tsdbSnapWrite(STsdbSnapWriter* pWriter, SSnapDataHdr* pHdr);
|
||||||
int32_t tsdbSnapWriterPrepareClose(STsdbSnapWriter* pWriter);
|
int32_t tsdbSnapWriterPrepareClose(STsdbSnapWriter* pWriter);
|
||||||
int32_t tsdbSnapWriterClose(STsdbSnapWriter** ppWriter, int8_t rollback);
|
int32_t tsdbSnapWriterClose(STsdbSnapWriter** ppWriter, int8_t rollback);
|
||||||
// STqSnapshotReader ==
|
// STqSnapshotReader ==
|
||||||
|
|
|
@ -56,4 +56,7 @@ int metaPrepareAsyncCommit(SMeta *pMeta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// abort the meta txn
|
// abort the meta txn
|
||||||
int metaAbort(SMeta *pMeta) { return tdbAbort(pMeta->pEnv, pMeta->txn); }
|
int metaAbort(SMeta *pMeta) {
|
||||||
|
if (!pMeta->txn) return 0;
|
||||||
|
return tdbAbort(pMeta->pEnv, pMeta->txn);
|
||||||
|
}
|
||||||
|
|
|
@ -203,7 +203,7 @@ _err:
|
||||||
|
|
||||||
int metaClose(SMeta *pMeta) {
|
int metaClose(SMeta *pMeta) {
|
||||||
if (pMeta) {
|
if (pMeta) {
|
||||||
if (pMeta->pEnv) tdbAbort(pMeta->pEnv, pMeta->txn);
|
if (pMeta->pEnv) metaAbort(pMeta);
|
||||||
if (pMeta->pCache) metaCacheClose(pMeta);
|
if (pMeta->pCache) metaCacheClose(pMeta);
|
||||||
if (pMeta->pIdx) metaCloseIdx(pMeta);
|
if (pMeta->pIdx) metaCloseIdx(pMeta);
|
||||||
if (pMeta->pStreamDb) tdbTbClose(pMeta->pStreamDb);
|
if (pMeta->pStreamDb) tdbTbClose(pMeta->pStreamDb);
|
||||||
|
|
|
@ -423,10 +423,10 @@ int32_t rsmaSnapWrite(SRSmaSnapWriter* pWriter, uint8_t* pData, uint32_t nData)
|
||||||
// rsma1/rsma2
|
// rsma1/rsma2
|
||||||
if (pHdr->type == SNAP_DATA_RSMA1) {
|
if (pHdr->type == SNAP_DATA_RSMA1) {
|
||||||
pHdr->type = SNAP_DATA_TSDB;
|
pHdr->type = SNAP_DATA_TSDB;
|
||||||
code = tsdbSnapWrite(pWriter->pDataWriter[0], pData, nData);
|
code = tsdbSnapWrite(pWriter->pDataWriter[0], pHdr);
|
||||||
} else if (pHdr->type == SNAP_DATA_RSMA2) {
|
} else if (pHdr->type == SNAP_DATA_RSMA2) {
|
||||||
pHdr->type = SNAP_DATA_TSDB;
|
pHdr->type = SNAP_DATA_TSDB;
|
||||||
code = tsdbSnapWrite(pWriter->pDataWriter[1], pData, nData);
|
code = tsdbSnapWrite(pWriter->pDataWriter[1], pHdr);
|
||||||
} else if (pHdr->type == SNAP_DATA_QTASK) {
|
} else if (pHdr->type == SNAP_DATA_QTASK) {
|
||||||
code = rsmaSnapWriteQTaskInfo(pWriter, pData, nData);
|
code = rsmaSnapWriteQTaskInfo(pWriter, pData, nData);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -521,7 +521,12 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||||
tqOffsetResetToData(&fetchOffsetNew, 0, 0);
|
tqOffsetResetToData(&fetchOffsetNew, 0, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tqOffsetResetToLog(&fetchOffsetNew, walGetFirstVer(pTq->pVnode->pWal));
|
pHandle->pRef = walRefFirstVer(pTq->pVnode->pWal, pHandle->pRef);
|
||||||
|
if (pHandle->pRef == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tqOffsetResetToLog(&fetchOffsetNew, pHandle->pRef->refVer - 1);
|
||||||
}
|
}
|
||||||
} else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) {
|
} else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) {
|
||||||
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||||
|
@ -719,6 +724,8 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||||
int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen) {
|
int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen) {
|
||||||
SMqVDeleteReq* pReq = (SMqVDeleteReq*)msg;
|
SMqVDeleteReq* pReq = (SMqVDeleteReq*)msg;
|
||||||
|
|
||||||
|
tqDebug("vgId:%d, delete sub: %s", pTq->pVnode->config.vgId, pReq->subKey);
|
||||||
|
|
||||||
taosWLockLatch(&pTq->pushLock);
|
taosWLockLatch(&pTq->pushLock);
|
||||||
int32_t code = taosHashRemove(pTq->pPushMgr, pReq->subKey, strlen(pReq->subKey));
|
int32_t code = taosHashRemove(pTq->pPushMgr, pReq->subKey, strlen(pReq->subKey));
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
|
|
|
@ -15,6 +15,34 @@
|
||||||
|
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
|
|
||||||
|
static int32_t tsdbOpenBICache(STsdb *pTsdb) {
|
||||||
|
int32_t code = 0;
|
||||||
|
SLRUCache *pCache = taosLRUCacheInit(5 * 1024 * 1024, -1, .5);
|
||||||
|
if (pCache == NULL) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosLRUCacheSetStrictCapacity(pCache, false);
|
||||||
|
|
||||||
|
taosThreadMutexInit(&pTsdb->biMutex, NULL);
|
||||||
|
|
||||||
|
_err:
|
||||||
|
pTsdb->biCache = pCache;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tsdbCloseBICache(STsdb *pTsdb) {
|
||||||
|
SLRUCache *pCache = pTsdb->biCache;
|
||||||
|
if (pCache) {
|
||||||
|
taosLRUCacheEraseUnrefEntries(pCache);
|
||||||
|
|
||||||
|
taosLRUCacheCleanup(pCache);
|
||||||
|
|
||||||
|
taosThreadMutexDestroy(&pTsdb->biMutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tsdbOpenCache(STsdb *pTsdb) {
|
int32_t tsdbOpenCache(STsdb *pTsdb) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
SLRUCache *pCache = NULL;
|
SLRUCache *pCache = NULL;
|
||||||
|
@ -26,6 +54,12 @@ int32_t tsdbOpenCache(STsdb *pTsdb) {
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code = tsdbOpenBICache(pTsdb);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
taosLRUCacheSetStrictCapacity(pCache, false);
|
taosLRUCacheSetStrictCapacity(pCache, false);
|
||||||
|
|
||||||
taosThreadMutexInit(&pTsdb->lruMutex, NULL);
|
taosThreadMutexInit(&pTsdb->lruMutex, NULL);
|
||||||
|
@ -44,6 +78,8 @@ void tsdbCloseCache(STsdb *pTsdb) {
|
||||||
|
|
||||||
taosThreadMutexDestroy(&pTsdb->lruMutex);
|
taosThreadMutexDestroy(&pTsdb->lruMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tsdbCloseBICache(pTsdb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getTableCacheKey(tb_uid_t uid, int cacheType, char *key, int *len) {
|
static void getTableCacheKey(tb_uid_t uid, int cacheType, char *key, int *len) {
|
||||||
|
@ -1475,3 +1511,84 @@ size_t tsdbCacheGetUsage(SVnode *pVnode) {
|
||||||
|
|
||||||
return usage;
|
return usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void getBICacheKey(int32_t fid, int64_t commitID, char *key, int *len) {
|
||||||
|
struct {
|
||||||
|
int32_t fid;
|
||||||
|
int64_t commitID;
|
||||||
|
} biKey = {0};
|
||||||
|
|
||||||
|
biKey.fid = fid;
|
||||||
|
biKey.commitID = commitID;
|
||||||
|
|
||||||
|
*len = sizeof(biKey);
|
||||||
|
memcpy(key, &biKey, *len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t tsdbCacheLoadBlockIdx(SDataFReader *pFileReader, SArray **aBlockIdx) {
|
||||||
|
SArray *pArray = taosArrayInit(8, sizeof(SBlockIdx));
|
||||||
|
int32_t code = tsdbReadBlockIdx(pFileReader, pArray);
|
||||||
|
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosArrayDestroy(pArray);
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aBlockIdx = pArray;
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deleteBICache(const void *key, size_t keyLen, void *value) {
|
||||||
|
SArray *pArray = (SArray *)value;
|
||||||
|
|
||||||
|
taosArrayDestroy(pArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tsdbCacheGetBlockIdx(SLRUCache *pCache, SDataFReader *pFileReader, LRUHandle **handle) {
|
||||||
|
int32_t code = 0;
|
||||||
|
char key[128] = {0};
|
||||||
|
int keyLen = 0;
|
||||||
|
|
||||||
|
getBICacheKey(pFileReader->pSet->fid, pFileReader->pSet->pHeadF->commitID, key, &keyLen);
|
||||||
|
LRUHandle *h = taosLRUCacheLookup(pCache, key, keyLen);
|
||||||
|
if (!h) {
|
||||||
|
STsdb *pTsdb = pFileReader->pTsdb;
|
||||||
|
taosThreadMutexLock(&pTsdb->biMutex);
|
||||||
|
|
||||||
|
h = taosLRUCacheLookup(pCache, key, keyLen);
|
||||||
|
if (!h) {
|
||||||
|
SArray *pArray = NULL;
|
||||||
|
code = tsdbCacheLoadBlockIdx(pFileReader, &pArray);
|
||||||
|
// if table's empty or error, return code of -1
|
||||||
|
if (code != TSDB_CODE_SUCCESS || pArray == NULL) {
|
||||||
|
taosThreadMutexUnlock(&pTsdb->biMutex);
|
||||||
|
|
||||||
|
*handle = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t charge = pArray->capacity * pArray->elemSize + sizeof(*pArray);
|
||||||
|
_taos_lru_deleter_t deleter = deleteBICache;
|
||||||
|
LRUStatus status = taosLRUCacheInsert(pCache, key, keyLen, pArray, charge, deleter, &h, TAOS_LRU_PRIORITY_LOW);
|
||||||
|
if (status != TAOS_LRU_STATUS_OK) {
|
||||||
|
code = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
taosThreadMutexUnlock(&pTsdb->biMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
*handle = h;
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tsdbBICacheRelease(SLRUCache *pCache, LRUHandle *h) {
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
taosLRUCacheRelease(pCache, h, false);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
|
@ -79,6 +79,9 @@ typedef struct SIOCostSummary {
|
||||||
int64_t composedBlocks;
|
int64_t composedBlocks;
|
||||||
double buildComposedBlockTime;
|
double buildComposedBlockTime;
|
||||||
double createScanInfoList;
|
double createScanInfoList;
|
||||||
|
// double getTbFromMemTime;
|
||||||
|
// double getTbFromIMemTime;
|
||||||
|
double initDelSkylineIterTime;
|
||||||
} SIOCostSummary;
|
} SIOCostSummary;
|
||||||
|
|
||||||
typedef struct SBlockLoadSuppInfo {
|
typedef struct SBlockLoadSuppInfo {
|
||||||
|
@ -215,10 +218,12 @@ static int32_t doBuildDataBlock(STsdbReader* pReader);
|
||||||
static TSDBKEY getCurrentKeyInBuf(STableBlockScanInfo* pScanInfo, STsdbReader* pReader);
|
static TSDBKEY getCurrentKeyInBuf(STableBlockScanInfo* pScanInfo, STsdbReader* pReader);
|
||||||
static bool hasDataInFileBlock(const SBlockData* pBlockData, const SFileBlockDumpInfo* pDumpInfo);
|
static bool hasDataInFileBlock(const SBlockData* pBlockData, const SFileBlockDumpInfo* pDumpInfo);
|
||||||
static void initBlockDumpInfo(STsdbReader* pReader, SDataBlockIter* pBlockIter);
|
static void initBlockDumpInfo(STsdbReader* pReader, SDataBlockIter* pBlockIter);
|
||||||
|
static int32_t getInitialDelIndex(const SArray* pDelSkyline, int32_t order);
|
||||||
|
|
||||||
static bool outOfTimeWindow(int64_t ts, STimeWindow* pWindow) { return (ts > pWindow->ekey) || (ts < pWindow->skey); }
|
static bool outOfTimeWindow(int64_t ts, STimeWindow* pWindow) { return (ts > pWindow->ekey) || (ts < pWindow->skey); }
|
||||||
|
|
||||||
static int32_t setColumnIdSlotList(SBlockLoadSuppInfo* pSupInfo, SColumnInfo* pCols, const int32_t* pSlotIdList, int32_t numOfCols) {
|
static int32_t setColumnIdSlotList(SBlockLoadSuppInfo* pSupInfo, SColumnInfo* pCols, const int32_t* pSlotIdList,
|
||||||
|
int32_t numOfCols) {
|
||||||
pSupInfo->smaValid = true;
|
pSupInfo->smaValid = true;
|
||||||
pSupInfo->numOfCols = numOfCols;
|
pSupInfo->numOfCols = numOfCols;
|
||||||
pSupInfo->colId = taosMemoryMalloc(numOfCols * (sizeof(int16_t) * 2 + POINTER_BYTES));
|
pSupInfo->colId = taosMemoryMalloc(numOfCols * (sizeof(int16_t) * 2 + POINTER_BYTES));
|
||||||
|
@ -311,7 +316,8 @@ static void* getPosInBlockInfoBuf(SBlockInfoBuf* pBuf, int32_t index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: speedup the whole processing by preparing the buffer for STableBlockScanInfo in batch model
|
// NOTE: speedup the whole processing by preparing the buffer for STableBlockScanInfo in batch model
|
||||||
static SHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf* pBuf, const STableKeyInfo* idList, int32_t numOfTables) {
|
static SHashObj* createDataBlockScanInfo(STsdbReader* pTsdbReader, SBlockInfoBuf* pBuf, const STableKeyInfo* idList,
|
||||||
|
int32_t numOfTables) {
|
||||||
// allocate buffer in order to load data blocks from file
|
// allocate buffer in order to load data blocks from file
|
||||||
// todo use simple hash instead, optimize the memory consumption
|
// todo use simple hash instead, optimize the memory consumption
|
||||||
SHashObj* pTableMap =
|
SHashObj* pTableMap =
|
||||||
|
@ -397,9 +403,7 @@ static void destroyAllBlockScanInfo(SHashObj* pTableMap) {
|
||||||
taosHashCleanup(pTableMap);
|
taosHashCleanup(pTableMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isEmptyQueryTimeWindow(STimeWindow* pWindow) {
|
static bool isEmptyQueryTimeWindow(STimeWindow* pWindow) { return pWindow->skey > pWindow->ekey; }
|
||||||
return pWindow->skey > pWindow->ekey;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the query time window according to the data time to live(TTL) information, in order to avoid to return
|
// Update the query time window according to the data time to live(TTL) information, in order to avoid to return
|
||||||
// the expired data to client, even it is queried already.
|
// the expired data to client, even it is queried already.
|
||||||
|
@ -643,17 +647,21 @@ _end:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doLoadBlockIndex(STsdbReader* pReader, SDataFReader* pFileReader, SArray* pIndexList) {
|
static int32_t doLoadBlockIndex(STsdbReader* pReader, SDataFReader* pFileReader, SArray* pIndexList) {
|
||||||
SArray* aBlockIdx = taosArrayInit(8, sizeof(SBlockIdx));
|
// SArray* aBlockIdx = taosArrayInit(8, sizeof(SBlockIdx));
|
||||||
|
|
||||||
int64_t st = taosGetTimestampUs();
|
int64_t st = taosGetTimestampUs();
|
||||||
int32_t code = tsdbReadBlockIdx(pFileReader, aBlockIdx);
|
// int32_t code = tsdbReadBlockIdx(pFileReader, aBlockIdx);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
LRUHandle* handle = NULL;
|
||||||
|
int32_t code = tsdbCacheGetBlockIdx(pFileReader->pTsdb->biCache, pFileReader, &handle);
|
||||||
|
if (code != TSDB_CODE_SUCCESS || handle == NULL) {
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SArray* aBlockIdx = (SArray*)taosLRUCacheValue(pFileReader->pTsdb->biCache, handle);
|
||||||
size_t num = taosArrayGetSize(aBlockIdx);
|
size_t num = taosArrayGetSize(aBlockIdx);
|
||||||
if (num == 0) {
|
if (num == 0) {
|
||||||
taosArrayDestroy(aBlockIdx);
|
tsdbBICacheRelease(pFileReader->pTsdb->biCache, handle);
|
||||||
|
// taosArrayDestroy(aBlockIdx);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,7 +697,8 @@ static int32_t doLoadBlockIndex(STsdbReader* pReader, SDataFReader* pFileReader,
|
||||||
pReader->cost.headFileLoadTime += (et1 - st) / 1000.0;
|
pReader->cost.headFileLoadTime += (et1 - st) / 1000.0;
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
taosArrayDestroy(aBlockIdx);
|
// taosArrayDestroy(aBlockIdx);
|
||||||
|
tsdbBICacheRelease(pFileReader->pTsdb->biCache, handle);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -768,7 +777,6 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN
|
||||||
numOfTables, pBlockNum->numOfBlocks, numOfQTable, pBlockNum->numOfLastFiles, sizeInDisk / 1000.0, el,
|
numOfTables, pBlockNum->numOfBlocks, numOfQTable, pBlockNum->numOfLastFiles, sizeInDisk / 1000.0, el,
|
||||||
pReader->idStr);
|
pReader->idStr);
|
||||||
|
|
||||||
|
|
||||||
pReader->cost.numOfBlocks += total;
|
pReader->cost.numOfBlocks += total;
|
||||||
pReader->cost.headFileLoadTime += el;
|
pReader->cost.headFileLoadTime += el;
|
||||||
|
|
||||||
|
@ -925,8 +933,7 @@ static void copyNumericCols(const SColData* pData, SFileBlockDumpInfo* pDumpInfo
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
case TSDB_DATA_TYPE_BIGINT:
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
case TSDB_DATA_TYPE_UBIGINT:
|
case TSDB_DATA_TYPE_UBIGINT: {
|
||||||
{
|
|
||||||
int32_t mid = dumpedRows >> 1u;
|
int32_t mid = dumpedRows >> 1u;
|
||||||
int64_t* pts = (int64_t*)pColData->pData;
|
int64_t* pts = (int64_t*)pColData->pData;
|
||||||
for (int32_t j = 0; j < mid; ++j) {
|
for (int32_t j = 0; j < mid; ++j) {
|
||||||
|
@ -1112,9 +1119,9 @@ static int32_t copyBlockDataToSDataBlock(STsdbReader* pReader, STableBlockScanIn
|
||||||
|
|
||||||
int32_t unDumpedRows = asc ? pBlock->nRow - pDumpInfo->rowIndex : pDumpInfo->rowIndex + 1;
|
int32_t unDumpedRows = asc ? pBlock->nRow - pDumpInfo->rowIndex : pDumpInfo->rowIndex + 1;
|
||||||
tsdbDebug("%p copy file block to sdatablock, global index:%d, table index:%d, brange:%" PRId64 "-%" PRId64
|
tsdbDebug("%p copy file block to sdatablock, global index:%d, table index:%d, brange:%" PRId64 "-%" PRId64
|
||||||
", rows:%d, remain:%d, minVer:%" PRId64 ", maxVer:%" PRId64 ", elapsed time:%.2f ms, %s",
|
", rows:%d, remain:%d, minVer:%" PRId64 ", maxVer:%" PRId64 ", uid:%" PRIu64 " elapsed time:%.2f ms, %s",
|
||||||
pReader, pBlockIter->index, pBlockInfo->tbBlockIdx, pBlock->minKey.ts, pBlock->maxKey.ts, dumpedRows,
|
pReader, pBlockIter->index, pBlockInfo->tbBlockIdx, pBlock->minKey.ts, pBlock->maxKey.ts, dumpedRows,
|
||||||
unDumpedRows, pBlock->minVer, pBlock->maxVer, elapsedTime, pReader->idStr);
|
unDumpedRows, pBlock->minVer, pBlock->maxVer, pBlockInfo->uid, elapsedTime, pReader->idStr);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1551,8 +1558,7 @@ static bool fileBlockShouldLoad(STsdbReader* pReader, SFileDataBlockInfo* pBlock
|
||||||
|
|
||||||
// log the reason why load the datablock for profile
|
// log the reason why load the datablock for profile
|
||||||
if (loadDataBlock) {
|
if (loadDataBlock) {
|
||||||
tsdbDebug("%p uid:%" PRIu64
|
tsdbDebug("%p uid:%" PRIu64 " need to load the datablock, overlapneighbor:%d, hasDup:%d, partiallyRequired:%d, "
|
||||||
" need to load the datablock, overlapwithneighborblock:%d, hasDup:%d, partiallyRequired:%d, "
|
|
||||||
"overlapWithKey:%d, greaterThanBuf:%d, overlapWithDel:%d, overlapWithlastBlock:%d, %s",
|
"overlapWithKey:%d, greaterThanBuf:%d, overlapWithDel:%d, overlapWithlastBlock:%d, %s",
|
||||||
pReader, pBlockInfo->uid, info.overlapWithNeighborBlock, info.hasDupTs, info.partiallyRequired,
|
pReader, pBlockInfo->uid, info.overlapWithNeighborBlock, info.hasDupTs, info.partiallyRequired,
|
||||||
info.overlapWithKeyInBuf, info.moreThanCapcity, info.overlapWithDelInfo, info.overlapWithLastBlock,
|
info.overlapWithKeyInBuf, info.moreThanCapcity, info.overlapWithDelInfo, info.overlapWithLastBlock,
|
||||||
|
@ -2177,6 +2183,7 @@ static int32_t initMemDataIterator(STableBlockScanInfo* pBlockScanInfo, STsdbRea
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t backward = (!ASCENDING_TRAVERSE(pReader->order));
|
int32_t backward = (!ASCENDING_TRAVERSE(pReader->order));
|
||||||
|
int64_t st = 0;
|
||||||
|
|
||||||
STbData* d = NULL;
|
STbData* d = NULL;
|
||||||
if (pReader->pReadSnap->pMem != NULL) {
|
if (pReader->pReadSnap->pMem != NULL) {
|
||||||
|
@ -2186,17 +2193,17 @@ static int32_t initMemDataIterator(STableBlockScanInfo* pBlockScanInfo, STsdbRea
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
pBlockScanInfo->iter.hasVal = (tsdbTbDataIterGet(pBlockScanInfo->iter.iter) != NULL);
|
pBlockScanInfo->iter.hasVal = (tsdbTbDataIterGet(pBlockScanInfo->iter.iter) != NULL);
|
||||||
|
|
||||||
tsdbDebug("%p uid:%" PRId64 ", check data in mem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
|
tsdbDebug("%p uid:%" PRIu64 ", check data in mem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
|
||||||
"-%" PRId64 " %s",
|
"-%" PRId64 " %s",
|
||||||
pReader, pBlockScanInfo->uid, startKey.ts, pReader->order, d->minKey, d->maxKey, pReader->idStr);
|
pReader, pBlockScanInfo->uid, startKey.ts, pReader->order, d->minKey, d->maxKey, pReader->idStr);
|
||||||
} else {
|
} else {
|
||||||
tsdbError("%p uid:%" PRId64 ", failed to create iterator for imem, code:%s, %s", pReader, pBlockScanInfo->uid,
|
tsdbError("%p uid:%" PRIu64 ", failed to create iterator for imem, code:%s, %s", pReader, pBlockScanInfo->uid,
|
||||||
tstrerror(code), pReader->idStr);
|
tstrerror(code), pReader->idStr);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tsdbDebug("%p uid:%" PRId64 ", no data in mem, %s", pReader, pBlockScanInfo->uid, pReader->idStr);
|
tsdbDebug("%p uid:%" PRIu64 ", no data in mem, %s", pReader, pBlockScanInfo->uid, pReader->idStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
STbData* di = NULL;
|
STbData* di = NULL;
|
||||||
|
@ -2207,20 +2214,22 @@ static int32_t initMemDataIterator(STableBlockScanInfo* pBlockScanInfo, STsdbRea
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
pBlockScanInfo->iiter.hasVal = (tsdbTbDataIterGet(pBlockScanInfo->iiter.iter) != NULL);
|
pBlockScanInfo->iiter.hasVal = (tsdbTbDataIterGet(pBlockScanInfo->iiter.iter) != NULL);
|
||||||
|
|
||||||
tsdbDebug("%p uid:%" PRId64 ", check data in imem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
|
tsdbDebug("%p uid:%" PRIu64 ", check data in imem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
|
||||||
"-%" PRId64 " %s",
|
"-%" PRId64 " %s",
|
||||||
pReader, pBlockScanInfo->uid, startKey.ts, pReader->order, di->minKey, di->maxKey, pReader->idStr);
|
pReader, pBlockScanInfo->uid, startKey.ts, pReader->order, di->minKey, di->maxKey, pReader->idStr);
|
||||||
} else {
|
} else {
|
||||||
tsdbError("%p uid:%" PRId64 ", failed to create iterator for mem, code:%s, %s", pReader, pBlockScanInfo->uid,
|
tsdbError("%p uid:%" PRIu64 ", failed to create iterator for mem, code:%s, %s", pReader, pBlockScanInfo->uid,
|
||||||
tstrerror(code), pReader->idStr);
|
tstrerror(code), pReader->idStr);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tsdbDebug("%p uid:%" PRId64 ", no data in imem, %s", pReader, pBlockScanInfo->uid, pReader->idStr);
|
tsdbDebug("%p uid:%" PRIu64 ", no data in imem, %s", pReader, pBlockScanInfo->uid, pReader->idStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
st = taosGetTimestampUs();
|
||||||
initDelSkylineIterator(pBlockScanInfo, pReader, d, di);
|
initDelSkylineIterator(pBlockScanInfo, pReader, d, di);
|
||||||
|
pReader->cost.initDelSkylineIterTime += (taosGetTimestampUs() - st) / 1000.0;
|
||||||
|
|
||||||
pBlockScanInfo->iterInit = true;
|
pBlockScanInfo->iterInit = true;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -2526,6 +2535,14 @@ _end:
|
||||||
|
|
||||||
void setComposedBlockFlag(STsdbReader* pReader, bool composed) { pReader->status.composedDataBlock = composed; }
|
void setComposedBlockFlag(STsdbReader* pReader, bool composed) { pReader->status.composedDataBlock = composed; }
|
||||||
|
|
||||||
|
int32_t getInitialDelIndex(const SArray* pDelSkyline, int32_t order) {
|
||||||
|
if (pDelSkyline == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ASCENDING_TRAVERSE(order) ? 0 : taosArrayGetSize(pDelSkyline) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader, STbData* pMemTbData,
|
int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader, STbData* pMemTbData,
|
||||||
STbData* piMemTbData) {
|
STbData* piMemTbData) {
|
||||||
if (pBlockScanInfo->delSkyline != NULL) {
|
if (pBlockScanInfo->delSkyline != NULL) {
|
||||||
|
@ -2543,7 +2560,6 @@ int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader*
|
||||||
if (pIdx != NULL) {
|
if (pIdx != NULL) {
|
||||||
code = tsdbReadDelData(pReader->pDelFReader, pIdx, pDelData);
|
code = tsdbReadDelData(pReader->pDelFReader, pIdx, pDelData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
@ -2572,11 +2588,13 @@ int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader*
|
||||||
}
|
}
|
||||||
|
|
||||||
taosArrayDestroy(pDelData);
|
taosArrayDestroy(pDelData);
|
||||||
pBlockScanInfo->iter.index =
|
int32_t index = getInitialDelIndex(pBlockScanInfo->delSkyline, pReader->order);
|
||||||
ASCENDING_TRAVERSE(pReader->order) ? 0 : taosArrayGetSize(pBlockScanInfo->delSkyline) - 1;
|
|
||||||
pBlockScanInfo->iiter.index = pBlockScanInfo->iter.index;
|
pBlockScanInfo->iter.index = index;
|
||||||
pBlockScanInfo->fileDelIndex = pBlockScanInfo->iter.index;
|
pBlockScanInfo->iiter.index = index;
|
||||||
pBlockScanInfo->lastBlockDelIndex = pBlockScanInfo->iter.index;
|
pBlockScanInfo->fileDelIndex = index;
|
||||||
|
pBlockScanInfo->lastBlockDelIndex = index;
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
|
||||||
_err:
|
_err:
|
||||||
|
@ -2585,22 +2603,40 @@ _err:
|
||||||
}
|
}
|
||||||
|
|
||||||
TSDBKEY getCurrentKeyInBuf(STableBlockScanInfo* pScanInfo, STsdbReader* pReader) {
|
TSDBKEY getCurrentKeyInBuf(STableBlockScanInfo* pScanInfo, STsdbReader* pReader) {
|
||||||
TSDBKEY key = {.ts = TSKEY_INITIAL_VAL};
|
bool asc = ASCENDING_TRAVERSE(pReader->order);
|
||||||
|
// TSKEY initialVal = asc? TSKEY_MIN:TSKEY_MAX;
|
||||||
|
|
||||||
|
TSDBKEY key = {.ts = TSKEY_INITIAL_VAL}, ikey = {.ts = TSKEY_INITIAL_VAL};
|
||||||
|
|
||||||
|
bool hasKey = false, hasIKey = false;
|
||||||
TSDBROW* pRow = getValidMemRow(&pScanInfo->iter, pScanInfo->delSkyline, pReader);
|
TSDBROW* pRow = getValidMemRow(&pScanInfo->iter, pScanInfo->delSkyline, pReader);
|
||||||
if (pRow != NULL) {
|
if (pRow != NULL) {
|
||||||
|
hasKey = true;
|
||||||
key = TSDBROW_KEY(pRow);
|
key = TSDBROW_KEY(pRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
pRow = getValidMemRow(&pScanInfo->iiter, pScanInfo->delSkyline, pReader);
|
TSDBROW* pIRow = getValidMemRow(&pScanInfo->iiter, pScanInfo->delSkyline, pReader);
|
||||||
if (pRow != NULL) {
|
if (pIRow != NULL) {
|
||||||
TSDBKEY k = TSDBROW_KEY(pRow);
|
hasIKey = true;
|
||||||
if (key.ts > k.ts) {
|
ikey = TSDBROW_KEY(pIRow);
|
||||||
key = k;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasKey) {
|
||||||
|
if (hasIKey) { // has data in mem & imem
|
||||||
|
if (asc) {
|
||||||
|
return key.ts <= ikey.ts ? key : ikey;
|
||||||
|
} else {
|
||||||
|
return key.ts <= ikey.ts ? ikey: key;
|
||||||
|
}
|
||||||
|
} else { // no data in imem
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// no data in mem & imem, return the initial value
|
||||||
|
// only imem has data, return ikey
|
||||||
|
return ikey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t moveToNextFile(STsdbReader* pReader, SBlockNumber* pBlockNum) {
|
static int32_t moveToNextFile(STsdbReader* pReader, SBlockNumber* pBlockNum) {
|
||||||
SReaderStatus* pStatus = &pReader->status;
|
SReaderStatus* pStatus = &pReader->status;
|
||||||
|
@ -2641,7 +2677,6 @@ static int32_t moveToNextFile(STsdbReader* pReader, SBlockNumber* pBlockNum) {
|
||||||
taosArrayDestroy(pIndexList);
|
taosArrayDestroy(pIndexList);
|
||||||
|
|
||||||
if (pReader->pReadSnap != NULL) {
|
if (pReader->pReadSnap != NULL) {
|
||||||
|
|
||||||
SDelFile* pDelFile = pReader->pReadSnap->fs.pDelFile;
|
SDelFile* pDelFile = pReader->pReadSnap->fs.pDelFile;
|
||||||
if (pReader->pDelFReader == NULL && pDelFile != NULL) {
|
if (pReader->pDelFReader == NULL && pDelFile != NULL) {
|
||||||
int32_t code = tsdbDelFReaderOpen(&pReader->pDelFReader, pDelFile, pReader->pTsdb);
|
int32_t code = tsdbDelFReaderOpen(&pReader->pDelFReader, pDelFile, pReader->pTsdb);
|
||||||
|
@ -2676,7 +2711,7 @@ static int32_t uidComparFunc(const void* p1, const void* p2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void extractOrderedTableUidList(SUidOrderCheckInfo* pOrderCheckInfo, SReaderStatus* pStatus) {
|
static void extractOrderedTableUidList(SUidOrderCheckInfo* pOrderCheckInfo, SReaderStatus* pStatus, int32_t order) {
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
int32_t total = taosHashGetSize(pStatus->pTableMap);
|
int32_t total = taosHashGetSize(pStatus->pTableMap);
|
||||||
|
|
||||||
|
@ -2690,7 +2725,21 @@ static void extractOrderedTableUidList(SUidOrderCheckInfo* pOrderCheckInfo, SRea
|
||||||
taosSort(pOrderCheckInfo->tableUidList, total, sizeof(uint64_t), uidComparFunc);
|
taosSort(pOrderCheckInfo->tableUidList, total, sizeof(uint64_t), uidComparFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t initOrderCheckInfo(SUidOrderCheckInfo* pOrderCheckInfo, SReaderStatus* pStatus) {
|
// reset the last del file index
|
||||||
|
static void resetScanBlockLastBlockDelIndex(SReaderStatus* pStatus, int32_t order) {
|
||||||
|
void* p = taosHashIterate(pStatus->pTableMap, NULL);
|
||||||
|
while (p != NULL) {
|
||||||
|
STableBlockScanInfo* pScanInfo = *(STableBlockScanInfo**)p;
|
||||||
|
|
||||||
|
// reset the last del file index
|
||||||
|
pScanInfo->lastBlockDelIndex = getInitialDelIndex(pScanInfo->delSkyline, order);
|
||||||
|
p = taosHashIterate(pStatus->pTableMap, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t initOrderCheckInfo(SUidOrderCheckInfo* pOrderCheckInfo, STsdbReader* pReader) {
|
||||||
|
SReaderStatus* pStatus = &pReader->status;
|
||||||
|
|
||||||
int32_t total = taosHashGetSize(pStatus->pTableMap);
|
int32_t total = taosHashGetSize(pStatus->pTableMap);
|
||||||
if (total == 0) {
|
if (total == 0) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -2703,7 +2752,7 @@ static int32_t initOrderCheckInfo(SUidOrderCheckInfo* pOrderCheckInfo, SReaderSt
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
extractOrderedTableUidList(pOrderCheckInfo, pStatus);
|
extractOrderedTableUidList(pOrderCheckInfo, pStatus, pReader->order);
|
||||||
uint64_t uid = pOrderCheckInfo->tableUidList[0];
|
uint64_t uid = pOrderCheckInfo->tableUidList[0];
|
||||||
pStatus->pTableIter = taosHashGet(pStatus->pTableMap, &uid, sizeof(uid));
|
pStatus->pTableIter = taosHashGet(pStatus->pTableMap, &uid, sizeof(uid));
|
||||||
} else {
|
} else {
|
||||||
|
@ -2720,7 +2769,7 @@ static int32_t initOrderCheckInfo(SUidOrderCheckInfo* pOrderCheckInfo, SReaderSt
|
||||||
}
|
}
|
||||||
|
|
||||||
pOrderCheckInfo->tableUidList = p;
|
pOrderCheckInfo->tableUidList = p;
|
||||||
extractOrderedTableUidList(pOrderCheckInfo, pStatus);
|
extractOrderedTableUidList(pOrderCheckInfo, pStatus, pReader->order);
|
||||||
|
|
||||||
uid = pOrderCheckInfo->tableUidList[0];
|
uid = pOrderCheckInfo->tableUidList[0];
|
||||||
pStatus->pTableIter = taosHashGet(pStatus->pTableMap, &uid, sizeof(uid));
|
pStatus->pTableIter = taosHashGet(pStatus->pTableMap, &uid, sizeof(uid));
|
||||||
|
@ -2740,11 +2789,7 @@ static bool moveToNextTable(SUidOrderCheckInfo* pOrderedCheckInfo, SReaderStatus
|
||||||
|
|
||||||
uint64_t uid = pOrderedCheckInfo->tableUidList[pOrderedCheckInfo->currentIndex];
|
uint64_t uid = pOrderedCheckInfo->tableUidList[pOrderedCheckInfo->currentIndex];
|
||||||
pStatus->pTableIter = taosHashGet(pStatus->pTableMap, &uid, sizeof(uid));
|
pStatus->pTableIter = taosHashGet(pStatus->pTableMap, &uid, sizeof(uid));
|
||||||
if (pStatus->pTableIter == NULL) {
|
return (pStatus->pTableIter != NULL);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doLoadLastBlockSequentially(STsdbReader* pReader) {
|
static int32_t doLoadLastBlockSequentially(STsdbReader* pReader) {
|
||||||
|
@ -2752,7 +2797,7 @@ static int32_t doLoadLastBlockSequentially(STsdbReader* pReader) {
|
||||||
SLastBlockReader* pLastBlockReader = pStatus->fileIter.pLastBlockReader;
|
SLastBlockReader* pLastBlockReader = pStatus->fileIter.pLastBlockReader;
|
||||||
|
|
||||||
SUidOrderCheckInfo* pOrderedCheckInfo = &pStatus->uidCheckInfo;
|
SUidOrderCheckInfo* pOrderedCheckInfo = &pStatus->uidCheckInfo;
|
||||||
int32_t code = initOrderCheckInfo(pOrderedCheckInfo, pStatus);
|
int32_t code = initOrderCheckInfo(pOrderedCheckInfo, pReader);
|
||||||
if (code != TSDB_CODE_SUCCESS || (taosHashGetSize(pStatus->pTableMap) == 0)) {
|
if (code != TSDB_CODE_SUCCESS || (taosHashGetSize(pStatus->pTableMap) == 0)) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -2817,59 +2862,21 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
||||||
SFileDataBlockInfo* pBlockInfo = getCurrentBlockInfo(pBlockIter);
|
SFileDataBlockInfo* pBlockInfo = getCurrentBlockInfo(pBlockIter);
|
||||||
SLastBlockReader* pLastBlockReader = pReader->status.fileIter.pLastBlockReader;
|
SLastBlockReader* pLastBlockReader = pReader->status.fileIter.pLastBlockReader;
|
||||||
|
|
||||||
if (pBlockInfo != NULL) {
|
ASSERT(pBlockInfo != NULL);
|
||||||
pScanInfo =
|
|
||||||
*(STableBlockScanInfo**)taosHashGet(pReader->status.pTableMap, &pBlockInfo->uid, sizeof(pBlockInfo->uid));
|
|
||||||
} else {
|
|
||||||
pScanInfo = *pReader->status.pTableIter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
pScanInfo = *(STableBlockScanInfo**)taosHashGet(pReader->status.pTableMap, &pBlockInfo->uid, sizeof(pBlockInfo->uid));
|
||||||
if (pScanInfo == NULL) {
|
if (pScanInfo == NULL) {
|
||||||
tsdbError("failed to get table scan-info, %s", pReader->idStr);
|
tsdbError("failed to get table scan-info, %s", pReader->idStr);
|
||||||
code = TSDB_CODE_INVALID_PARA;
|
code = TSDB_CODE_INVALID_PARA;
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pBlockInfo != NULL) {
|
|
||||||
pBlock = getCurrentBlock(pBlockIter);
|
pBlock = getCurrentBlock(pBlockIter);
|
||||||
}
|
|
||||||
|
|
||||||
initLastBlockReader(pLastBlockReader, pScanInfo, pReader);
|
initLastBlockReader(pLastBlockReader, pScanInfo, pReader);
|
||||||
TSDBKEY keyInBuf = getCurrentKeyInBuf(pScanInfo, pReader);
|
TSDBKEY keyInBuf = getCurrentKeyInBuf(pScanInfo, pReader);
|
||||||
|
|
||||||
if (pBlockInfo == NULL) { // build data block from last data file
|
if (fileBlockShouldLoad(pReader, pBlockInfo, pBlock, pScanInfo, keyInBuf, pLastBlockReader)) {
|
||||||
SBlockData* pBData = &pReader->status.fileBlockData;
|
|
||||||
tBlockDataReset(pBData);
|
|
||||||
|
|
||||||
SSDataBlock* pResBlock = pReader->pResBlock;
|
|
||||||
tsdbDebug("load data in last block firstly, due to desc scan data, %s", pReader->idStr);
|
|
||||||
|
|
||||||
int64_t st = taosGetTimestampUs();
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
bool hasBlockLData = hasDataInLastBlock(pLastBlockReader);
|
|
||||||
|
|
||||||
// no data in last block and block, no need to proceed.
|
|
||||||
if (hasBlockLData == false) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
buildComposedDataBlockImpl(pReader, pScanInfo, &pReader->status.fileBlockData, pLastBlockReader);
|
|
||||||
if (pResBlock->info.rows >= pReader->capacity) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double el = (taosGetTimestampUs() - st) / 1000.0;
|
|
||||||
updateComposedBlockInfo(pReader, el, pScanInfo);
|
|
||||||
|
|
||||||
if (pResBlock->info.rows > 0) {
|
|
||||||
tsdbDebug("%p uid:%" PRIu64 ", composed data block created, brange:%" PRIu64 "-%" PRIu64
|
|
||||||
" rows:%d, elapsed time:%.2f ms %s",
|
|
||||||
pReader, pResBlock->info.id.uid, pResBlock->info.window.skey, pResBlock->info.window.ekey,
|
|
||||||
pResBlock->info.rows, el, pReader->idStr);
|
|
||||||
}
|
|
||||||
} else if (fileBlockShouldLoad(pReader, pBlockInfo, pBlock, pScanInfo, keyInBuf, pLastBlockReader)) {
|
|
||||||
code = doLoadFileBlockData(pReader, pBlockIter, &pStatus->fileBlockData, pScanInfo->uid);
|
code = doLoadFileBlockData(pReader, pBlockIter, &pStatus->fileBlockData, pScanInfo->uid);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
|
@ -2929,6 +2936,11 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
||||||
|
|
||||||
// update the last key for the corresponding table
|
// update the last key for the corresponding table
|
||||||
pScanInfo->lastKey = ASCENDING_TRAVERSE(pReader->order) ? pInfo->window.ekey : pInfo->window.skey;
|
pScanInfo->lastKey = ASCENDING_TRAVERSE(pReader->order) ? pInfo->window.ekey : pInfo->window.skey;
|
||||||
|
tsdbDebug("%p uid:%" PRIu64
|
||||||
|
" clean file block retrieved from file, global index:%d, "
|
||||||
|
"table index:%d, rows:%d, brange:%" PRId64 "-%" PRId64 ", %s",
|
||||||
|
pReader, pScanInfo->uid, pBlockIter->index, pBlockInfo->tbBlockIdx, pBlock->nRow, pBlock->minKey.ts,
|
||||||
|
pBlock->maxKey.ts, pReader->idStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3040,6 +3052,7 @@ static int32_t buildBlockFromFiles(STsdbReader* pReader) {
|
||||||
|
|
||||||
// this file does not have data files, let's start check the last block file if exists
|
// this file does not have data files, let's start check the last block file if exists
|
||||||
if (pBlockIter->numOfBlocks == 0) {
|
if (pBlockIter->numOfBlocks == 0) {
|
||||||
|
resetScanBlockLastBlockDelIndex(&pReader->status, pReader->order);
|
||||||
goto _begin;
|
goto _begin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3071,6 +3084,7 @@ static int32_t buildBlockFromFiles(STsdbReader* pReader) {
|
||||||
// data blocks in current file are exhausted, let's try the next file now
|
// data blocks in current file are exhausted, let's try the next file now
|
||||||
tBlockDataReset(&pReader->status.fileBlockData);
|
tBlockDataReset(&pReader->status.fileBlockData);
|
||||||
resetDataBlockIterator(pBlockIter, pReader->order);
|
resetDataBlockIterator(pBlockIter, pReader->order);
|
||||||
|
resetScanBlockLastBlockDelIndex(&pReader->status, pReader->order);
|
||||||
goto _begin;
|
goto _begin;
|
||||||
} else {
|
} else {
|
||||||
code = initForFirstBlockInFile(pReader, pBlockIter);
|
code = initForFirstBlockInFile(pReader, pBlockIter);
|
||||||
|
@ -3082,6 +3096,7 @@ static int32_t buildBlockFromFiles(STsdbReader* pReader) {
|
||||||
|
|
||||||
// this file does not have blocks, let's start check the last block file
|
// this file does not have blocks, let's start check the last block file
|
||||||
if (pBlockIter->numOfBlocks == 0) {
|
if (pBlockIter->numOfBlocks == 0) {
|
||||||
|
resetScanBlockLastBlockDelIndex(&pReader->status, pReader->order);
|
||||||
goto _begin;
|
goto _begin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3177,7 +3192,8 @@ bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32
|
||||||
return false;
|
return false;
|
||||||
} else if (pKey->ts == last->ts) {
|
} else if (pKey->ts == last->ts) {
|
||||||
TSDBKEY* prev = taosArrayGet(pDelList, num - 2);
|
TSDBKEY* prev = taosArrayGet(pDelList, num - 2);
|
||||||
return (prev->version >= pKey->version && prev->version <= pVerRange->maxVer && prev->version >= pVerRange->minVer);
|
return (prev->version >= pKey->version && prev->version <= pVerRange->maxVer &&
|
||||||
|
prev->version >= pVerRange->minVer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TSDBKEY* pCurrent = taosArrayGet(pDelList, *index);
|
TSDBKEY* pCurrent = taosArrayGet(pDelList, *index);
|
||||||
|
@ -4000,16 +4016,16 @@ void tsdbReaderClose(STsdbReader* pReader) {
|
||||||
taosMemoryFree(pLReader);
|
taosMemoryFree(pLReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
tsdbDebug("%p :io-cost summary: head-file:%" PRIu64 ", head-file time:%.2f ms, SMA:%" PRId64
|
tsdbDebug(
|
||||||
|
"%p :io-cost summary: head-file:%" PRIu64 ", head-file time:%.2f ms, SMA:%" PRId64
|
||||||
" SMA-time:%.2f ms, fileBlocks:%" PRId64
|
" SMA-time:%.2f ms, fileBlocks:%" PRId64
|
||||||
", fileBlocks-load-time:%.2f ms, "
|
", fileBlocks-load-time:%.2f ms, "
|
||||||
"build in-memory-block-time:%.2f ms, lastBlocks:%" PRId64
|
"build in-memory-block-time:%.2f ms, lastBlocks:%" PRId64 ", lastBlocks-time:%.2f ms, composed-blocks:%" PRId64
|
||||||
", lastBlocks-time:%.2f ms, composed-blocks:%" PRId64
|
", composed-blocks-time:%.2fms, STableBlockScanInfo size:%.2f Kb, createTime:%.2f ms,initDelSkylineIterTime:%.2f ms, %s",
|
||||||
", composed-blocks-time:%.2fms, STableBlockScanInfo size:%.2f Kb, creatTime:%.2f ms, %s",
|
pReader, pCost->headFileLoad, pCost->headFileLoadTime, pCost->smaDataLoad, pCost->smaLoadTime, pCost->numOfBlocks,
|
||||||
pReader, pCost->headFileLoad, pCost->headFileLoadTime, pCost->smaDataLoad, pCost->smaLoadTime,
|
pCost->blockLoadTime, pCost->buildmemBlock, pCost->lastBlockLoad, pCost->lastBlockLoadTime, pCost->composedBlocks,
|
||||||
pCost->numOfBlocks, pCost->blockLoadTime, pCost->buildmemBlock, pCost->lastBlockLoad,
|
pCost->buildComposedBlockTime, numOfTables * sizeof(STableBlockScanInfo) / 1000.0, pCost->createScanInfoList,
|
||||||
pCost->lastBlockLoadTime, pCost->composedBlocks, pCost->buildComposedBlockTime,
|
pCost->initDelSkylineIterTime, pReader->idStr);
|
||||||
numOfTables * sizeof(STableBlockScanInfo) / 1000.0, pCost->createScanInfoList, pReader->idStr);
|
|
||||||
|
|
||||||
taosMemoryFree(pReader->idStr);
|
taosMemoryFree(pReader->idStr);
|
||||||
taosMemoryFree(pReader->pSchema);
|
taosMemoryFree(pReader->pSchema);
|
||||||
|
@ -4115,9 +4131,7 @@ void tsdbRetrieveDataBlockInfo(const STsdbReader* pReader, int32_t* rows, uint64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void doFillNullColSMA(SBlockLoadSuppInfo* pSup, int32_t numOfRows, int32_t numOfCols, SColumnDataAgg* pTsAgg) {
|
||||||
static void doFillNullColSMA(SBlockLoadSuppInfo* pSup, int32_t numOfRows, int32_t numOfCols,
|
|
||||||
SColumnDataAgg* pTsAgg) {
|
|
||||||
// do fill all null column value SMA info
|
// do fill all null column value SMA info
|
||||||
int32_t i = 0, j = 0;
|
int32_t i = 0, j = 0;
|
||||||
int32_t size = (int32_t)taosArrayGetSize(pSup->pColAgg);
|
int32_t size = (int32_t)taosArrayGetSize(pSup->pColAgg);
|
||||||
|
@ -4402,7 +4416,7 @@ int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
|
||||||
STableBlockScanInfo* pBlockScanInfo = *(STableBlockScanInfo**)pStatus->pTableIter;
|
STableBlockScanInfo* pBlockScanInfo = *(STableBlockScanInfo**)pStatus->pTableIter;
|
||||||
|
|
||||||
STbData* d = NULL;
|
STbData* d = NULL;
|
||||||
if (pReader->pTsdb->mem != NULL) {
|
if (pReader->pReadSnap->pMem != NULL) {
|
||||||
d = tsdbGetTbDataFromMemTable(pReader->pReadSnap->pMem, pReader->suid, pBlockScanInfo->uid);
|
d = tsdbGetTbDataFromMemTable(pReader->pReadSnap->pMem, pReader->suid, pBlockScanInfo->uid);
|
||||||
if (d != NULL) {
|
if (d != NULL) {
|
||||||
rows += tsdbGetNRowsInTbData(d);
|
rows += tsdbGetNRowsInTbData(d);
|
||||||
|
@ -4410,7 +4424,7 @@ int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
STbData* di = NULL;
|
STbData* di = NULL;
|
||||||
if (pReader->pTsdb->imem != NULL) {
|
if (pReader->pReadSnap->pIMem != NULL) {
|
||||||
di = tsdbGetTbDataFromMemTable(pReader->pReadSnap->pIMem, pReader->suid, pBlockScanInfo->uid);
|
di = tsdbGetTbDataFromMemTable(pReader->pReadSnap->pIMem, pReader->suid, pBlockScanInfo->uid);
|
||||||
if (di != NULL) {
|
if (di != NULL) {
|
||||||
rows += tsdbGetNRowsInTbData(di);
|
rows += tsdbGetNRowsInTbData(di);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -929,8 +929,9 @@ int32_t tRowMergerGetRow(SRowMerger *pMerger, STSRow **ppRow) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// delete skyline ======================================================
|
// delete skyline ======================================================
|
||||||
static int32_t tsdbMergeSkyline(SArray *aSkyline1, SArray *aSkyline2, SArray *aSkyline) {
|
static int32_t tsdbMergeSkyline2(SArray *aSkyline1, SArray *aSkyline2, SArray *aSkyline) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
int32_t i1 = 0;
|
int32_t i1 = 0;
|
||||||
int32_t n1 = taosArrayGetSize(aSkyline1);
|
int32_t n1 = taosArrayGetSize(aSkyline1);
|
||||||
|
@ -996,7 +997,141 @@ static int32_t tsdbMergeSkyline(SArray *aSkyline1, SArray *aSkyline2, SArray *aS
|
||||||
_exit:
|
_exit:
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// delete skyline ======================================================
|
||||||
|
static int32_t tsdbMergeSkyline(SArray *pSkyline1, SArray *pSkyline2, SArray *pSkyline) {
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t i1 = 0;
|
||||||
|
int32_t n1 = taosArrayGetSize(pSkyline1);
|
||||||
|
int32_t i2 = 0;
|
||||||
|
int32_t n2 = taosArrayGetSize(pSkyline2);
|
||||||
|
TSDBKEY *pKey1;
|
||||||
|
TSDBKEY *pKey2;
|
||||||
|
int64_t version1 = 0;
|
||||||
|
int64_t version2 = 0;
|
||||||
|
|
||||||
|
ASSERT(n1 > 0 && n2 > 0);
|
||||||
|
|
||||||
|
taosArrayClear(pSkyline);
|
||||||
|
TSDBKEY **pItem = TARRAY_GET_ELEM(pSkyline, 0);
|
||||||
|
|
||||||
|
while (i1 < n1 && i2 < n2) {
|
||||||
|
pKey1 = (TSDBKEY *)taosArrayGetP(pSkyline1, i1);
|
||||||
|
pKey2 = (TSDBKEY *)taosArrayGetP(pSkyline2, i2);
|
||||||
|
|
||||||
|
if (pKey1->ts < pKey2->ts) {
|
||||||
|
version1 = pKey1->version;
|
||||||
|
*pItem = pKey1;
|
||||||
|
i1++;
|
||||||
|
} else if (pKey1->ts > pKey2->ts) {
|
||||||
|
version2 = pKey2->version;
|
||||||
|
*pItem = pKey2;
|
||||||
|
i2++;
|
||||||
|
} else {
|
||||||
|
version1 = pKey1->version;
|
||||||
|
version2 = pKey2->version;
|
||||||
|
*pItem = pKey1;
|
||||||
|
i1++;
|
||||||
|
i2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*pItem)->version = TMAX(version1, version2);
|
||||||
|
pItem++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i1 < n1) {
|
||||||
|
pKey1 = (TSDBKEY *)taosArrayGetP(pSkyline1, i1);
|
||||||
|
*pItem = pKey1;
|
||||||
|
pItem++;
|
||||||
|
i1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i2 < n2) {
|
||||||
|
pKey2 = (TSDBKEY *)taosArrayGetP(pSkyline2, i2);
|
||||||
|
*pItem = pKey2;
|
||||||
|
pItem++;
|
||||||
|
i2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArraySetSize(pSkyline, TARRAY_ELEM_IDX(pSkyline, pItem));
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t tsdbBuildDeleteSkylineImpl(SArray *aSkyline, int32_t sidx, int32_t eidx, SArray *pSkyline) {
|
||||||
|
int32_t code = 0;
|
||||||
|
SDelData *pDelData;
|
||||||
|
int32_t midx;
|
||||||
|
|
||||||
|
taosArrayClear(pSkyline);
|
||||||
|
if (sidx == eidx) {
|
||||||
|
TSDBKEY *pItem1 = taosArrayGet(aSkyline, sidx * 2);
|
||||||
|
TSDBKEY *pItem2 = taosArrayGet(aSkyline, sidx * 2 + 1);
|
||||||
|
taosArrayPush(pSkyline, &pItem1);
|
||||||
|
taosArrayPush(pSkyline, &pItem2);
|
||||||
|
} else {
|
||||||
|
SArray *pSkyline1 = NULL;
|
||||||
|
SArray *pSkyline2 = NULL;
|
||||||
|
midx = (sidx + eidx) / 2;
|
||||||
|
|
||||||
|
pSkyline1 = taosArrayInit((midx - sidx + 1) * 2, POINTER_BYTES);
|
||||||
|
pSkyline2 = taosArrayInit((eidx - midx) * 2, POINTER_BYTES);
|
||||||
|
if (pSkyline1 == NULL || pSkyline1 == NULL) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
goto _clear;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = tsdbBuildDeleteSkylineImpl(aSkyline, sidx, midx, pSkyline1);
|
||||||
|
if (code) goto _clear;
|
||||||
|
|
||||||
|
code = tsdbBuildDeleteSkylineImpl(aSkyline, midx + 1, eidx, pSkyline2);
|
||||||
|
if (code) goto _clear;
|
||||||
|
|
||||||
|
code = tsdbMergeSkyline(pSkyline1, pSkyline2, pSkyline);
|
||||||
|
|
||||||
|
_clear:
|
||||||
|
taosArrayDestroy(pSkyline1);
|
||||||
|
taosArrayDestroy(pSkyline2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t tsdbBuildDeleteSkyline(SArray *aDelData, int32_t sidx, int32_t eidx, SArray *aSkyline) {
|
int32_t tsdbBuildDeleteSkyline(SArray *aDelData, int32_t sidx, int32_t eidx, SArray *aSkyline) {
|
||||||
|
SDelData *pDelData;
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t dataNum = eidx - sidx + 1;
|
||||||
|
SArray *aTmpSkyline = taosArrayInit(dataNum * 2, sizeof(TSDBKEY));
|
||||||
|
SArray *pSkyline = taosArrayInit(dataNum * 2, POINTER_BYTES);
|
||||||
|
|
||||||
|
for (int32_t i = sidx; i <= eidx; ++i) {
|
||||||
|
pDelData = (SDelData *)taosArrayGet(aDelData, i);
|
||||||
|
taosArrayPush(aTmpSkyline, &(TSDBKEY){.ts = pDelData->sKey, .version = pDelData->version});
|
||||||
|
taosArrayPush(aTmpSkyline, &(TSDBKEY){.ts = pDelData->eKey, .version = 0});
|
||||||
|
}
|
||||||
|
|
||||||
|
code = tsdbBuildDeleteSkylineImpl(aTmpSkyline, sidx, eidx, pSkyline);
|
||||||
|
if (code) goto _clear;
|
||||||
|
|
||||||
|
int32_t skylineNum = taosArrayGetSize(pSkyline);
|
||||||
|
for (int32_t i = 0; i < skylineNum; ++i) {
|
||||||
|
TSDBKEY *p = taosArrayGetP(pSkyline, i);
|
||||||
|
taosArrayPush(aSkyline, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
_clear:
|
||||||
|
taosArrayDestroy(aTmpSkyline);
|
||||||
|
taosArrayDestroy(pSkyline);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int32_t tsdbBuildDeleteSkyline2(SArray *aDelData, int32_t sidx, int32_t eidx, SArray *aSkyline) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
SDelData *pDelData;
|
SDelData *pDelData;
|
||||||
int32_t midx;
|
int32_t midx;
|
||||||
|
@ -1033,6 +1168,7 @@ int32_t tsdbBuildDeleteSkyline(SArray *aDelData, int32_t sidx, int32_t eidx, SAr
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// SBlockData ======================================================
|
// SBlockData ======================================================
|
||||||
int32_t tBlockDataCreate(SBlockData *pBlockData) {
|
int32_t tBlockDataCreate(SBlockData *pBlockData) {
|
||||||
|
|
|
@ -455,7 +455,7 @@ int32_t vnodeSnapWrite(SVSnapWriter *pWriter, uint8_t *pData, uint32_t nData) {
|
||||||
if (code) goto _err;
|
if (code) goto _err;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = tsdbSnapWrite(pWriter->pTsdbSnapWriter, pData, nData);
|
code = tsdbSnapWrite(pWriter->pTsdbSnapWriter, pHdr);
|
||||||
if (code) goto _err;
|
if (code) goto _err;
|
||||||
} break;
|
} break;
|
||||||
case SNAP_DATA_TQ_HANDLE: {
|
case SNAP_DATA_TQ_HANDLE: {
|
||||||
|
|
|
@ -704,9 +704,10 @@ void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SG
|
||||||
SDiskbasedBuf* pBuf);
|
SDiskbasedBuf* pBuf);
|
||||||
|
|
||||||
bool hasLimitOffsetInfo(SLimitInfo* pLimitInfo);
|
bool hasLimitOffsetInfo(SLimitInfo* pLimitInfo);
|
||||||
|
bool hasSlimitOffsetInfo(SLimitInfo* pLimitInfo);
|
||||||
void initLimitInfo(const SNode* pLimit, const SNode* pSLimit, SLimitInfo* pLimitInfo);
|
void initLimitInfo(const SNode* pLimit, const SNode* pSLimit, SLimitInfo* pLimitInfo);
|
||||||
void resetLimitInfoForNextGroup(SLimitInfo* pLimitInfo);
|
void resetLimitInfoForNextGroup(SLimitInfo* pLimitInfo);
|
||||||
bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo, SOperatorInfo* pOperator);
|
bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo);
|
||||||
|
|
||||||
void applyAggFunctionOnPartialTuples(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, SColumnInfoData* pTimeWindowData,
|
void applyAggFunctionOnPartialTuples(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, SColumnInfoData* pTimeWindowData,
|
||||||
int32_t offset, int32_t forwardStep, int32_t numOfTotal, int32_t numOfOutput);
|
int32_t offset, int32_t forwardStep, int32_t numOfTotal, int32_t numOfOutput);
|
||||||
|
|
|
@ -218,10 +218,7 @@ static SSDataBlock* loadRemoteData(SOperatorInfo* pOperator) {
|
||||||
if (status == PROJECT_RETRIEVE_CONTINUE) {
|
if (status == PROJECT_RETRIEVE_CONTINUE) {
|
||||||
continue;
|
continue;
|
||||||
} else if (status == PROJECT_RETRIEVE_DONE) {
|
} else if (status == PROJECT_RETRIEVE_DONE) {
|
||||||
size_t rows = pBlock->info.rows;
|
if (pBlock->info.rows == 0) {
|
||||||
pExchangeInfo->limitInfo.numOfOutputRows += rows;
|
|
||||||
|
|
||||||
if (rows == 0) {
|
|
||||||
setOperatorCompleted(pOperator);
|
setOperatorCompleted(pOperator);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -707,6 +704,8 @@ int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t handleLimitOffset(SOperatorInfo* pOperator, SLimitInfo* pLimitInfo, SSDataBlock* pBlock, bool holdDataInBuf) {
|
int32_t handleLimitOffset(SOperatorInfo* pOperator, SLimitInfo* pLimitInfo, SSDataBlock* pBlock, bool holdDataInBuf) {
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
|
||||||
if (pLimitInfo->remainGroupOffset > 0) {
|
if (pLimitInfo->remainGroupOffset > 0) {
|
||||||
if (pLimitInfo->currentGroupId == 0) { // it is the first group
|
if (pLimitInfo->currentGroupId == 0) { // it is the first group
|
||||||
pLimitInfo->currentGroupId = pBlock->info.id.groupId;
|
pLimitInfo->currentGroupId = pBlock->info.id.groupId;
|
||||||
|
@ -750,36 +749,20 @@ int32_t handleLimitOffset(SOperatorInfo* pOperator, SLimitInfo* pLimitInfo, SSDa
|
||||||
// set current group id
|
// set current group id
|
||||||
pLimitInfo->currentGroupId = pBlock->info.id.groupId;
|
pLimitInfo->currentGroupId = pBlock->info.id.groupId;
|
||||||
|
|
||||||
if (pLimitInfo->remainOffset >= pBlock->info.rows) {
|
bool limitReached = applyLimitOffset(pLimitInfo, pBlock, pTaskInfo);
|
||||||
pLimitInfo->remainOffset -= pBlock->info.rows;
|
|
||||||
blockDataCleanup(pBlock);
|
|
||||||
return PROJECT_RETRIEVE_CONTINUE;
|
|
||||||
} else if (pLimitInfo->remainOffset < pBlock->info.rows && pLimitInfo->remainOffset > 0) {
|
|
||||||
blockDataTrimFirstNRows(pBlock, pLimitInfo->remainOffset);
|
|
||||||
pLimitInfo->remainOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for the limitation in each group
|
|
||||||
if (pLimitInfo->limit.limit >= 0 && pLimitInfo->numOfOutputRows + pBlock->info.rows >= pLimitInfo->limit.limit) {
|
|
||||||
int32_t keepRows = (int32_t)(pLimitInfo->limit.limit - pLimitInfo->numOfOutputRows);
|
|
||||||
blockDataKeepFirstNRows(pBlock, keepRows);
|
|
||||||
if (pLimitInfo->slimit.limit > 0 && pLimitInfo->slimit.limit <= pLimitInfo->numOfOutputGroups) {
|
|
||||||
setOperatorCompleted(pOperator);
|
|
||||||
} else {
|
|
||||||
// current group limitation is reached, and future blocks of this group need to be discarded.
|
|
||||||
if (pBlock->info.rows == 0) {
|
if (pBlock->info.rows == 0) {
|
||||||
return PROJECT_RETRIEVE_CONTINUE;
|
return PROJECT_RETRIEVE_CONTINUE;
|
||||||
}
|
} else {
|
||||||
}
|
if (limitReached && (pLimitInfo->slimit.limit > 0 && pLimitInfo->slimit.limit <= pLimitInfo->numOfOutputGroups)) {
|
||||||
|
setOperatorCompleted(pOperator);
|
||||||
return PROJECT_RETRIEVE_DONE;
|
return PROJECT_RETRIEVE_DONE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// todo optimize performance
|
// todo optimize performance
|
||||||
// If there are slimit/soffset value exists, multi-round result can not be packed into one group, since the
|
// If there are slimit/soffset value exists, multi-round result can not be packed into one group, since the
|
||||||
// they may not belong to the same group the limit/offset value is not valid in this case.
|
// they may not belong to the same group the limit/offset value is not valid in this case.
|
||||||
if ((!holdDataInBuf) || (pBlock->info.rows >= pOperator->resultInfo.threshold) || pLimitInfo->slimit.offset != -1 ||
|
if ((!holdDataInBuf) || (pBlock->info.rows >= pOperator->resultInfo.threshold) || hasSlimitOffsetInfo(pLimitInfo)) {
|
||||||
pLimitInfo->slimit.limit != -1) {
|
|
||||||
return PROJECT_RETRIEVE_DONE;
|
return PROJECT_RETRIEVE_DONE;
|
||||||
} else { // not full enough, continue to accumulate the output data in the buffer.
|
} else { // not full enough, continue to accumulate the output data in the buffer.
|
||||||
return PROJECT_RETRIEVE_CONTINUE;
|
return PROJECT_RETRIEVE_CONTINUE;
|
||||||
|
|
|
@ -1749,6 +1749,10 @@ bool hasLimitOffsetInfo(SLimitInfo* pLimitInfo) {
|
||||||
pLimitInfo->slimit.offset != -1);
|
pLimitInfo->slimit.offset != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasSlimitOffsetInfo(SLimitInfo* pLimitInfo) {
|
||||||
|
return (pLimitInfo->slimit.limit != -1 || pLimitInfo->slimit.offset != -1);
|
||||||
|
}
|
||||||
|
|
||||||
void initLimitInfo(const SNode* pLimit, const SNode* pSLimit, SLimitInfo* pLimitInfo) {
|
void initLimitInfo(const SNode* pLimit, const SNode* pSLimit, SLimitInfo* pLimitInfo) {
|
||||||
SLimit limit = {.limit = getLimit(pLimit), .offset = getOffset(pLimit)};
|
SLimit limit = {.limit = getLimit(pLimit), .offset = getOffset(pLimit)};
|
||||||
SLimit slimit = {.limit = getLimit(pSLimit), .offset = getOffset(pSLimit)};
|
SLimit slimit = {.limit = getLimit(pSLimit), .offset = getOffset(pSLimit)};
|
||||||
|
|
|
@ -829,6 +829,8 @@ SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartition
|
||||||
SPartitionOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SPartitionOperatorInfo));
|
SPartitionOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SPartitionOperatorInfo));
|
||||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
if (pInfo == NULL || pOperator == NULL) {
|
if (pInfo == NULL || pOperator == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
pTaskInfo->code = terrno;
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,6 +843,8 @@ SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartition
|
||||||
SExprInfo* pExprInfo1 = createExprInfo(pPartNode->pExprs, NULL, &num);
|
SExprInfo* pExprInfo1 = createExprInfo(pPartNode->pExprs, NULL, &num);
|
||||||
int32_t code = initExprSupp(&pInfo->scalarSup, pExprInfo1, num);
|
int32_t code = initExprSupp(&pInfo->scalarSup, pExprInfo1, num);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
terrno = code;
|
||||||
|
pTaskInfo->code = terrno;
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -848,6 +852,8 @@ SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartition
|
||||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||||
pInfo->pGroupSet = taosHashInit(100, hashFn, false, HASH_NO_LOCK);
|
pInfo->pGroupSet = taosHashInit(100, hashFn, false, HASH_NO_LOCK);
|
||||||
if (pInfo->pGroupSet == NULL) {
|
if (pInfo->pGroupSet == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
pTaskInfo->code = terrno;
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,6 +872,8 @@ SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartition
|
||||||
|
|
||||||
int32_t code = createDiskbasedBuf(&pInfo->pBuf, defaultPgsz, defaultBufsz, pTaskInfo->id.str, tsTempDir);
|
int32_t code = createDiskbasedBuf(&pInfo->pBuf, defaultPgsz, defaultBufsz, pTaskInfo->id.str, tsTempDir);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
terrno = code;
|
||||||
|
pTaskInfo->code = code;
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,6 +881,8 @@ SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartition
|
||||||
pInfo->columnOffset = setupColumnOffset(pInfo->binfo.pRes, pInfo->rowCapacity);
|
pInfo->columnOffset = setupColumnOffset(pInfo->binfo.pRes, pInfo->rowCapacity);
|
||||||
code = initGroupOptrInfo(&pInfo->pGroupColVals, &pInfo->groupKeyLen, &pInfo->keyBuf, pInfo->pGroupCols);
|
code = initGroupOptrInfo(&pInfo->pGroupColVals, &pInfo->groupKeyLen, &pInfo->keyBuf, pInfo->pGroupCols);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
terrno = code;
|
||||||
|
pTaskInfo->code = code;
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,10 +895,15 @@ SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartition
|
||||||
createOperatorFpSet(optrDummyOpenFn, hashPartition, NULL, destroyPartitionOperatorInfo, optrDefaultBufFn, NULL);
|
createOperatorFpSet(optrDummyOpenFn, hashPartition, NULL, destroyPartitionOperatorInfo, optrDefaultBufFn, NULL);
|
||||||
|
|
||||||
code = appendDownstream(pOperator, &downstream, 1);
|
code = appendDownstream(pOperator, &downstream, 1);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
terrno = code;
|
||||||
|
pTaskInfo->code = code;
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
return pOperator;
|
return pOperator;
|
||||||
|
|
||||||
_error:
|
_error:
|
||||||
pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
if (pInfo != NULL) {
|
if (pInfo != NULL) {
|
||||||
destroyPartitionOperatorInfo(pInfo);
|
destroyPartitionOperatorInfo(pInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,16 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhys
|
||||||
|
|
||||||
pInfo->binfo.pRes = pResBlock;
|
pInfo->binfo.pRes = pResBlock;
|
||||||
pInfo->pFinalRes = createOneDataBlock(pResBlock, false);
|
pInfo->pFinalRes = createOneDataBlock(pResBlock, false);
|
||||||
pInfo->mergeDataBlocks = (pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM) ? false : pProjPhyNode->mergeDataBlock;
|
|
||||||
|
if (pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
|
||||||
|
pInfo->mergeDataBlocks = false;
|
||||||
|
} else {
|
||||||
|
if (!pProjPhyNode->ignoreGroupId) {
|
||||||
|
pInfo->mergeDataBlocks = false;
|
||||||
|
} else {
|
||||||
|
pInfo->mergeDataBlocks = pProjPhyNode->mergeDataBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t numOfRows = 4096;
|
int32_t numOfRows = 4096;
|
||||||
size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
|
size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
|
||||||
|
@ -181,40 +190,20 @@ static int32_t setInfoForNewGroup(SSDataBlock* pBlock, SLimitInfo* pLimitInfo, S
|
||||||
return PROJECT_RETRIEVE_DONE;
|
return PROJECT_RETRIEVE_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo refactor
|
||||||
static int32_t doIngroupLimitOffset(SLimitInfo* pLimitInfo, uint64_t groupId, SSDataBlock* pBlock,
|
static int32_t doIngroupLimitOffset(SLimitInfo* pLimitInfo, uint64_t groupId, SSDataBlock* pBlock,
|
||||||
SOperatorInfo* pOperator) {
|
SOperatorInfo* pOperator) {
|
||||||
// set current group id
|
// set current group id
|
||||||
pLimitInfo->currentGroupId = groupId;
|
pLimitInfo->currentGroupId = groupId;
|
||||||
|
bool limitReached = applyLimitOffset(pLimitInfo, pBlock, pOperator->pTaskInfo);
|
||||||
if (pLimitInfo->remainOffset >= pBlock->info.rows) {
|
if (pBlock->info.rows == 0) {
|
||||||
pLimitInfo->remainOffset -= pBlock->info.rows;
|
|
||||||
blockDataCleanup(pBlock);
|
|
||||||
return PROJECT_RETRIEVE_CONTINUE;
|
return PROJECT_RETRIEVE_CONTINUE;
|
||||||
} else if (pLimitInfo->remainOffset < pBlock->info.rows && pLimitInfo->remainOffset > 0) {
|
|
||||||
blockDataTrimFirstNRows(pBlock, pLimitInfo->remainOffset);
|
|
||||||
pLimitInfo->remainOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for the limitation in each group
|
|
||||||
if (pLimitInfo->limit.limit >= 0 && pLimitInfo->numOfOutputRows + pBlock->info.rows >= pLimitInfo->limit.limit) {
|
|
||||||
int32_t keepRows = (int32_t)(pLimitInfo->limit.limit - pLimitInfo->numOfOutputRows);
|
|
||||||
blockDataKeepFirstNRows(pBlock, keepRows);
|
|
||||||
|
|
||||||
// TODO: optimize it later when partition by + limit
|
|
||||||
// all retrieved requirement has been fulfilled, let's finish this
|
|
||||||
if ((pLimitInfo->slimit.limit == -1 && pLimitInfo->currentGroupId == 0) ||
|
|
||||||
(pLimitInfo->slimit.limit > 0 && pLimitInfo->slimit.limit <= pLimitInfo->numOfOutputGroups)) {
|
|
||||||
setOperatorCompleted(pOperator);
|
|
||||||
} else {
|
} else {
|
||||||
// Even current group is done, there may be many vgroups remain existed, and we need to continue to retrieve data
|
if (limitReached && (pLimitInfo->slimit.limit > 0 && pLimitInfo->slimit.limit <= pLimitInfo->numOfOutputGroups)) {
|
||||||
// from next group. So let's continue this retrieve process
|
setOperatorCompleted(pOperator);
|
||||||
if (keepRows == 0) {
|
|
||||||
return PROJECT_RETRIEVE_CONTINUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pLimitInfo->numOfOutputRows += pBlock->info.rows;
|
|
||||||
return PROJECT_RETRIEVE_DONE;
|
return PROJECT_RETRIEVE_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -256,12 +256,11 @@ static void doSetTagColumnData(STableScanBase* pTableScanInfo, SSDataBlock* pBlo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo handle the slimit info
|
bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo) {
|
||||||
bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo, SOperatorInfo* pOperator) {
|
|
||||||
SLimit* pLimit = &pLimitInfo->limit;
|
SLimit* pLimit = &pLimitInfo->limit;
|
||||||
const char* id = GET_TASKID(pTaskInfo);
|
const char* id = GET_TASKID(pTaskInfo);
|
||||||
|
|
||||||
if (pLimit->offset > 0 && pLimitInfo->remainOffset > 0) {
|
if (pLimitInfo->remainOffset > 0) {
|
||||||
if (pLimitInfo->remainOffset >= pBlock->info.rows) {
|
if (pLimitInfo->remainOffset >= pBlock->info.rows) {
|
||||||
pLimitInfo->remainOffset -= pBlock->info.rows;
|
pLimitInfo->remainOffset -= pBlock->info.rows;
|
||||||
blockDataEmpty(pBlock);
|
blockDataEmpty(pBlock);
|
||||||
|
@ -276,12 +275,14 @@ bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo
|
||||||
if (pLimit->limit != -1 && pLimit->limit <= (pLimitInfo->numOfOutputRows + pBlock->info.rows)) {
|
if (pLimit->limit != -1 && pLimit->limit <= (pLimitInfo->numOfOutputRows + pBlock->info.rows)) {
|
||||||
// limit the output rows
|
// limit the output rows
|
||||||
int32_t keep = (int32_t)(pLimit->limit - pLimitInfo->numOfOutputRows);
|
int32_t keep = (int32_t)(pLimit->limit - pLimitInfo->numOfOutputRows);
|
||||||
|
|
||||||
blockDataKeepFirstNRows(pBlock, keep);
|
blockDataKeepFirstNRows(pBlock, keep);
|
||||||
|
|
||||||
|
pLimitInfo->numOfOutputRows += pBlock->info.rows;
|
||||||
qDebug("output limit %" PRId64 " has reached, %s", pLimit->limit, id);
|
qDebug("output limit %" PRId64 " has reached, %s", pLimit->limit, id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pLimitInfo->numOfOutputRows += pBlock->info.rows;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,8 +311,8 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanBase* pTableSca
|
||||||
pCost->totalRows += pBlock->info.rows;
|
pCost->totalRows += pBlock->info.rows;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
} else if (*status == FUNC_DATA_REQUIRED_NOT_LOAD) {
|
} else if (*status == FUNC_DATA_REQUIRED_NOT_LOAD) {
|
||||||
qDebug("%s data block skipped, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
|
qDebug("%s data block skipped, brange:%" PRId64 "-%" PRId64 ", rows:%d, uid:%"PRIu64, GET_TASKID(pTaskInfo),
|
||||||
pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
|
pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, pBlockInfo->id.uid);
|
||||||
doSetTagColumnData(pTableScanInfo, pBlock, pTaskInfo, 1);
|
doSetTagColumnData(pTableScanInfo, pBlock, pTaskInfo, 1);
|
||||||
pCost->skipBlocks += 1;
|
pCost->skipBlocks += 1;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -393,13 +394,12 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanBase* pTableSca
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool limitReached = applyLimitOffset(&pTableScanInfo->limitInfo, pBlock, pTaskInfo, pOperator);
|
bool limitReached = applyLimitOffset(&pTableScanInfo->limitInfo, pBlock, pTaskInfo);
|
||||||
if (limitReached) { // set operator flag is done
|
if (limitReached) { // set operator flag is done
|
||||||
setOperatorCompleted(pOperator);
|
setOperatorCompleted(pOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
pCost->totalRows += pBlock->info.rows;
|
pCost->totalRows += pBlock->info.rows;
|
||||||
pTableScanInfo->limitInfo.numOfOutputRows = pCost->totalRows;
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,6 +446,16 @@ static STableCachedVal* createTableCacheVal(const SMetaReader* pMetaReader) {
|
||||||
// const void *key, size_t keyLen, void *value
|
// const void *key, size_t keyLen, void *value
|
||||||
static void freeCachedMetaItem(const void* key, size_t keyLen, void* value) { freeTableCachedVal(value); }
|
static void freeCachedMetaItem(const void* key, size_t keyLen, void* value) { freeTableCachedVal(value); }
|
||||||
|
|
||||||
|
|
||||||
|
static void doSetNullValue(SSDataBlock* pBlock, const SExprInfo* pExpr, int32_t numOfExpr) {
|
||||||
|
for (int32_t j = 0; j < numOfExpr; ++j) {
|
||||||
|
int32_t dstSlotId = pExpr[j].base.resSchema.slotId;
|
||||||
|
|
||||||
|
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotId);
|
||||||
|
colDataAppendNNULL(pColInfoData, 0, pBlock->info.rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t addTagPseudoColumnData(SReadHandle* pHandle, const SExprInfo* pExpr, int32_t numOfExpr, SSDataBlock* pBlock,
|
int32_t addTagPseudoColumnData(SReadHandle* pHandle, const SExprInfo* pExpr, int32_t numOfExpr, SSDataBlock* pBlock,
|
||||||
int32_t rows, const char* idStr, STableMetaCacheInfo* pCache) {
|
int32_t rows, const char* idStr, STableMetaCacheInfo* pCache) {
|
||||||
// currently only the tbname pseudo column
|
// currently only the tbname pseudo column
|
||||||
|
@ -465,14 +475,22 @@ int32_t addTagPseudoColumnData(SReadHandle* pHandle, const SExprInfo* pExpr, int
|
||||||
SMetaReader mr = {0};
|
SMetaReader mr = {0};
|
||||||
LRUHandle* h = NULL;
|
LRUHandle* h = NULL;
|
||||||
|
|
||||||
|
// todo refactor: extract method
|
||||||
|
// the handling of the null data should be packed in the extracted method
|
||||||
|
|
||||||
// 1. check if it is existed in meta cache
|
// 1. check if it is existed in meta cache
|
||||||
if (pCache == NULL) {
|
if (pCache == NULL) {
|
||||||
metaReaderInit(&mr, pHandle->meta, 0);
|
metaReaderInit(&mr, pHandle->meta, 0);
|
||||||
code = metaGetTableEntryByUidCache(&mr, pBlock->info.id.uid);
|
code = metaGetTableEntryByUidCache(&mr, pBlock->info.id.uid);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
|
||||||
|
// when encounter the TSDB_CODE_PAR_TABLE_NOT_EXIST error, we proceed.
|
||||||
if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
|
if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
|
||||||
qWarn("failed to get table meta, table may have been dropped, uid:0x%" PRIx64 ", code:%s, %s",
|
qWarn("failed to get table meta, table may have been dropped, uid:0x%" PRIx64 ", code:%s, %s",
|
||||||
pBlock->info.id.uid, tstrerror(terrno), idStr);
|
pBlock->info.id.uid, tstrerror(terrno), idStr);
|
||||||
|
|
||||||
|
// append null value before return to caller, since the caller will ignore this error code and proceed
|
||||||
|
doSetNullValue(pBlock, pExpr, numOfExpr);
|
||||||
} else {
|
} else {
|
||||||
qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", pBlock->info.id.uid, tstrerror(terrno),
|
qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", pBlock->info.id.uid, tstrerror(terrno),
|
||||||
idStr);
|
idStr);
|
||||||
|
@ -498,6 +516,8 @@ int32_t addTagPseudoColumnData(SReadHandle* pHandle, const SExprInfo* pExpr, int
|
||||||
if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
|
if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
|
||||||
qWarn("failed to get table meta, table may have been dropped, uid:0x%" PRIx64 ", code:%s, %s",
|
qWarn("failed to get table meta, table may have been dropped, uid:0x%" PRIx64 ", code:%s, %s",
|
||||||
pBlock->info.id.uid, tstrerror(terrno), idStr);
|
pBlock->info.id.uid, tstrerror(terrno), idStr);
|
||||||
|
// append null value before return to caller, since the caller will ignore this error code and proceed
|
||||||
|
doSetNullValue(pBlock, pExpr, numOfExpr);
|
||||||
} else {
|
} else {
|
||||||
qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", pBlock->info.id.uid, tstrerror(terrno),
|
qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", pBlock->info.id.uid, tstrerror(terrno),
|
||||||
idStr);
|
idStr);
|
||||||
|
@ -617,6 +637,10 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) {
|
||||||
T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
|
T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// process this data block based on the probabilities
|
// process this data block based on the probabilities
|
||||||
bool processThisBlock = processBlockWithProbability(&pTableScanInfo->sample);
|
bool processThisBlock = processBlockWithProbability(&pTableScanInfo->sample);
|
||||||
if (!processThisBlock) {
|
if (!processThisBlock) {
|
||||||
|
@ -628,9 +652,8 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
uint32_t status = 0;
|
uint32_t status = 0;
|
||||||
int32_t code = loadDataBlock(pOperator, &pTableScanInfo->base, pBlock, &status);
|
int32_t code = loadDataBlock(pOperator, &pTableScanInfo->base, pBlock, &status);
|
||||||
// int32_t code = loadDataBlockOnDemand(pOperator->pRuntimeEnv, pTableScanInfo, pBlock, &status);
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
T_LONG_JMP(pOperator->pTaskInfo->env, code);
|
T_LONG_JMP(pTaskInfo->env, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
// current block is filter out according to filter condition, continue load the next block
|
// current block is filter out according to filter condition, continue load the next block
|
||||||
|
@ -2540,7 +2563,7 @@ static SSDataBlock* getTableDataBlockImpl(void* param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t status = 0;
|
uint32_t status = 0;
|
||||||
loadDataBlock(pOperator, &pInfo->base, pBlock, &status);
|
code = loadDataBlock(pOperator, &pInfo->base, pBlock, &status);
|
||||||
// code = loadDataBlockFromOneTable(pOperator, pTableScanInfo, pBlock, &status);
|
// code = loadDataBlockFromOneTable(pOperator, pTableScanInfo, pBlock, &status);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
T_LONG_JMP(pTaskInfo->env, code);
|
T_LONG_JMP(pTaskInfo->env, code);
|
||||||
|
@ -2714,12 +2737,13 @@ SSDataBlock* getSortedTableMergeScanBlockData(SSortHandle* pHandle, SSDataBlock*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
applyLimitOffset(&pInfo->limitInfo, pResBlock, pTaskInfo, pOperator);
|
bool limitReached = applyLimitOffset(&pInfo->limitInfo, pResBlock, pTaskInfo);
|
||||||
pInfo->limitInfo.numOfOutputRows += pResBlock->info.rows;
|
|
||||||
|
|
||||||
qDebug("%s get sorted row block, rows:%d, limit:%"PRId64, GET_TASKID(pTaskInfo), pResBlock->info.rows,
|
qDebug("%s get sorted row block, rows:%d, limit:%"PRId64, GET_TASKID(pTaskInfo), pResBlock->info.rows,
|
||||||
pInfo->limitInfo.numOfOutputRows);
|
pInfo->limitInfo.numOfOutputRows);
|
||||||
|
|
||||||
|
if (limitReached) {
|
||||||
|
resetLimitInfoForNextGroup(&pInfo->limitInfo);
|
||||||
|
}
|
||||||
return (pResBlock->info.rows > 0) ? pResBlock : NULL;
|
return (pResBlock->info.rows > 0) ? pResBlock : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,6 +222,7 @@ SSDataBlock* doSort(SOperatorInfo* pOperator) {
|
||||||
T_LONG_JMP(pTaskInfo->env, code);
|
T_LONG_JMP(pTaskInfo->env, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// multi-group case not handle here
|
||||||
SSDataBlock* pBlock = NULL;
|
SSDataBlock* pBlock = NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
pBlock = getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity,
|
pBlock = getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity,
|
||||||
|
@ -236,28 +237,14 @@ SSDataBlock* doSort(SOperatorInfo* pOperator) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo add the limit/offset info
|
// there are bugs?
|
||||||
if (pInfo->limitInfo.remainOffset > 0) {
|
bool limitReached = applyLimitOffset(&pInfo->limitInfo, pBlock, pTaskInfo);
|
||||||
if (pInfo->limitInfo.remainOffset >= blockDataGetNumOfRows(pBlock)) {
|
if (limitReached) {
|
||||||
pInfo->limitInfo.remainOffset -= pBlock->info.rows;
|
resetLimitInfoForNextGroup(&pInfo->limitInfo);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blockDataTrimFirstNRows(pBlock, pInfo->limitInfo.remainOffset);
|
pOperator->resultInfo.totalRows += pBlock->info.rows;
|
||||||
pInfo->limitInfo.remainOffset = 0;
|
if (pBlock->info.rows > 0) {
|
||||||
}
|
|
||||||
|
|
||||||
if (pInfo->limitInfo.limit.limit > 0 &&
|
|
||||||
pInfo->limitInfo.limit.limit <= pInfo->limitInfo.numOfOutputRows + blockDataGetNumOfRows(pBlock)) {
|
|
||||||
int32_t remain = pInfo->limitInfo.limit.limit - pInfo->limitInfo.numOfOutputRows;
|
|
||||||
blockDataKeepFirstNRows(pBlock, remain);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t numOfRows = blockDataGetNumOfRows(pBlock);
|
|
||||||
pInfo->limitInfo.numOfOutputRows += numOfRows;
|
|
||||||
pOperator->resultInfo.totalRows += numOfRows;
|
|
||||||
|
|
||||||
if (numOfRows > 0) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -557,7 +544,6 @@ typedef struct SMultiwayMergeOperatorInfo {
|
||||||
SSDataBlock* pIntermediateBlock; // to hold the intermediate result
|
SSDataBlock* pIntermediateBlock; // to hold the intermediate result
|
||||||
int64_t startTs; // sort start time
|
int64_t startTs; // sort start time
|
||||||
bool groupSort;
|
bool groupSort;
|
||||||
bool hasGroupId;
|
|
||||||
uint64_t groupId;
|
uint64_t groupId;
|
||||||
STupleHandle* prefetchedTuple;
|
STupleHandle* prefetchedTuple;
|
||||||
} SMultiwayMergeOperatorInfo;
|
} SMultiwayMergeOperatorInfo;
|
||||||
|
@ -604,7 +590,9 @@ int32_t openMultiwayMergeOperator(SOperatorInfo* pOperator) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doGetSortedBlockData(SMultiwayMergeOperatorInfo* pInfo, SSortHandle* pHandle, int32_t capacity, SSDataBlock* p) {
|
static void doGetSortedBlockData(SMultiwayMergeOperatorInfo* pInfo, SSortHandle* pHandle, int32_t capacity,
|
||||||
|
SSDataBlock* p, bool* newgroup) {
|
||||||
|
*newgroup = false;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
STupleHandle* pTupleHandle = NULL;
|
STupleHandle* pTupleHandle = NULL;
|
||||||
|
@ -613,8 +601,12 @@ static void doGetSortedBlockData(SMultiwayMergeOperatorInfo* pInfo, SSortHandle*
|
||||||
pTupleHandle = tsortNextTuple(pHandle);
|
pTupleHandle = tsortNextTuple(pHandle);
|
||||||
} else {
|
} else {
|
||||||
pTupleHandle = pInfo->prefetchedTuple;
|
pTupleHandle = pInfo->prefetchedTuple;
|
||||||
pInfo->groupId = tsortGetGroupId(pTupleHandle);
|
|
||||||
pInfo->prefetchedTuple = NULL;
|
pInfo->prefetchedTuple = NULL;
|
||||||
|
uint64_t gid = tsortGetGroupId(pTupleHandle);
|
||||||
|
if (gid != pInfo->groupId) {
|
||||||
|
*newgroup = true;
|
||||||
|
pInfo->groupId = gid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pTupleHandle = tsortNextTuple(pHandle);
|
pTupleHandle = tsortNextTuple(pHandle);
|
||||||
|
@ -627,12 +619,10 @@ static void doGetSortedBlockData(SMultiwayMergeOperatorInfo* pInfo, SSortHandle*
|
||||||
|
|
||||||
if (pInfo->groupSort) {
|
if (pInfo->groupSort) {
|
||||||
uint64_t tupleGroupId = tsortGetGroupId(pTupleHandle);
|
uint64_t tupleGroupId = tsortGetGroupId(pTupleHandle);
|
||||||
if (!pInfo->hasGroupId) {
|
if (pInfo->groupId == 0 || pInfo->groupId == tupleGroupId) {
|
||||||
|
appendOneRowToDataBlock(p, pTupleHandle);
|
||||||
|
p->info.id.groupId = tupleGroupId;
|
||||||
pInfo->groupId = tupleGroupId;
|
pInfo->groupId = tupleGroupId;
|
||||||
pInfo->hasGroupId = true;
|
|
||||||
appendOneRowToDataBlock(p, pTupleHandle);
|
|
||||||
} else if (pInfo->groupId == tupleGroupId) {
|
|
||||||
appendOneRowToDataBlock(p, pTupleHandle);
|
|
||||||
} else {
|
} else {
|
||||||
pInfo->prefetchedTuple = pTupleHandle;
|
pInfo->prefetchedTuple = pTupleHandle;
|
||||||
break;
|
break;
|
||||||
|
@ -645,11 +635,6 @@ static void doGetSortedBlockData(SMultiwayMergeOperatorInfo* pInfo, SSortHandle*
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pInfo->groupSort) {
|
|
||||||
pInfo->hasGroupId = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, SArray* pColMatchInfo,
|
SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, SArray* pColMatchInfo,
|
||||||
|
@ -673,14 +658,19 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData
|
||||||
}
|
}
|
||||||
|
|
||||||
SSDataBlock* p = pInfo->pIntermediateBlock;
|
SSDataBlock* p = pInfo->pIntermediateBlock;
|
||||||
|
bool newgroup = false;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
doGetSortedBlockData(pInfo, pHandle, capacity, p);
|
doGetSortedBlockData(pInfo, pHandle, capacity, p, &newgroup);
|
||||||
if (p->info.rows == 0) {
|
if (p->info.rows == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool limitReached = applyLimitOffset(&pInfo->limitInfo, p, pTaskInfo, pOperator);
|
if (newgroup) {
|
||||||
|
resetLimitInfoForNextGroup(&pInfo->limitInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool limitReached = applyLimitOffset(&pInfo->limitInfo, p, pTaskInfo);
|
||||||
if (limitReached) {
|
if (limitReached) {
|
||||||
resetLimitInfoForNextGroup(&pInfo->limitInfo);
|
resetLimitInfoForNextGroup(&pInfo->limitInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -447,32 +447,6 @@ struct SFillInfo* taosCreateFillInfo(TSKEY skey, int32_t numOfFillCols, int32_t
|
||||||
|
|
||||||
taosResetFillInfo(pFillInfo, skey);
|
taosResetFillInfo(pFillInfo, skey);
|
||||||
|
|
||||||
switch (fillType) {
|
|
||||||
case FILL_MODE_NONE:
|
|
||||||
pFillInfo->type = TSDB_FILL_NONE;
|
|
||||||
break;
|
|
||||||
case FILL_MODE_PREV:
|
|
||||||
pFillInfo->type = TSDB_FILL_PREV;
|
|
||||||
break;
|
|
||||||
case FILL_MODE_NULL:
|
|
||||||
pFillInfo->type = TSDB_FILL_NULL;
|
|
||||||
break;
|
|
||||||
case FILL_MODE_LINEAR:
|
|
||||||
pFillInfo->type = TSDB_FILL_LINEAR;
|
|
||||||
break;
|
|
||||||
case FILL_MODE_NEXT:
|
|
||||||
pFillInfo->type = TSDB_FILL_NEXT;
|
|
||||||
break;
|
|
||||||
case FILL_MODE_VALUE:
|
|
||||||
pFillInfo->type = TSDB_FILL_SET_VALUE;
|
|
||||||
break;
|
|
||||||
default: {
|
|
||||||
taosMemoryFree(pFillInfo);
|
|
||||||
terrno = TSDB_CODE_INVALID_PARA;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pFillInfo->type = fillType;
|
pFillInfo->type = fillType;
|
||||||
pFillInfo->pFillCol = pCol;
|
pFillInfo->pFillCol = pCol;
|
||||||
pFillInfo->numOfCols = numOfFillCols + numOfNotFillCols;
|
pFillInfo->numOfCols = numOfFillCols + numOfNotFillCols;
|
||||||
|
|
|
@ -433,6 +433,11 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pSliceInfo->scalarSup.pExprInfo != NULL) {
|
||||||
|
SExprSupp* pExprSup = &pSliceInfo->scalarSup;
|
||||||
|
projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t code = initKeeperInfo(pSliceInfo, pBlock);
|
int32_t code = initKeeperInfo(pSliceInfo, pBlock);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
T_LONG_JMP(pTaskInfo->env, code);
|
T_LONG_JMP(pTaskInfo->env, code);
|
||||||
|
@ -531,6 +536,8 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) {
|
||||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision);
|
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL);
|
||||||
|
|
||||||
// restore the value
|
// restore the value
|
||||||
setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
|
setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
|
||||||
if (pResBlock->info.rows == 0) {
|
if (pResBlock->info.rows == 0) {
|
||||||
|
@ -566,6 +573,11 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code = filterInitFromNode((SNode*)pInterpPhyNode->node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
pInfo->tsCol = extractColumnFromColumnNode((SColumnNode*)pInterpPhyNode->pTimeSeries);
|
pInfo->tsCol = extractColumnFromColumnNode((SColumnNode*)pInterpPhyNode->pTimeSeries);
|
||||||
pInfo->fillType = convertFillType(pInterpPhyNode->fillMode);
|
pInfo->fillType = convertFillType(pInterpPhyNode->fillMode);
|
||||||
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||||
|
@ -622,6 +634,7 @@ void destroyTimeSliceOperatorInfo(void* param) {
|
||||||
taosMemoryFree(pKey->end.val);
|
taosMemoryFree(pKey->end.val);
|
||||||
}
|
}
|
||||||
taosArrayDestroy(pInfo->pLinearInfo);
|
taosArrayDestroy(pInfo->pLinearInfo);
|
||||||
|
cleanupExprSupp(&pInfo->scalarSup);
|
||||||
|
|
||||||
taosMemoryFree(pInfo->pFillColInfo);
|
taosMemoryFree(pInfo->pFillColInfo);
|
||||||
taosMemoryFreeClear(param);
|
taosMemoryFreeClear(param);
|
||||||
|
|
|
@ -2477,7 +2477,19 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* p
|
||||||
pInfo->delKey = key;
|
pInfo->delKey = key;
|
||||||
}
|
}
|
||||||
int32_t prevEndPos = (forwardRows - 1) * step + startPos;
|
int32_t prevEndPos = (forwardRows - 1) * step + startPos;
|
||||||
ASSERT(pSDataBlock->info.window.skey > 0 && pSDataBlock->info.window.ekey > 0);
|
if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) {
|
||||||
|
qError("table uid %" PRIu64 " data block timestamp range may not be calculated! minKey %" PRId64
|
||||||
|
",maxKey %" PRId64,
|
||||||
|
pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey);
|
||||||
|
blockDataUpdateTsWindow(pSDataBlock, 0);
|
||||||
|
|
||||||
|
// timestamp of the data is incorrect
|
||||||
|
if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) {
|
||||||
|
qError("table uid %" PRIu64 " data block timestamp is out of range! minKey %" PRId64 ",maxKey %" PRId64,
|
||||||
|
pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_FINAL_OP(pInfo)) {
|
if (IS_FINAL_OP(pInfo)) {
|
||||||
startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos);
|
startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2534,7 +2546,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
||||||
} else {
|
} else {
|
||||||
deleteIntervalDiscBuf(pInfo->pState, pInfo->pPullDataMap, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark,
|
deleteIntervalDiscBuf(pInfo->pState, pInfo->pPullDataMap, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark,
|
||||||
&pInfo->interval, &pInfo->delKey);
|
&pInfo->interval, &pInfo->delKey);
|
||||||
// streamStateCommit(pTaskInfo->streamInfo.pState);
|
streamStateCommit(pTaskInfo->streamInfo.pState);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -4734,7 +4746,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
||||||
deleteIntervalDiscBuf(pInfo->pState, NULL, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark, &pInfo->interval,
|
deleteIntervalDiscBuf(pInfo->pState, NULL, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark, &pInfo->interval,
|
||||||
&pInfo->delKey);
|
&pInfo->delKey);
|
||||||
setOperatorCompleted(pOperator);
|
setOperatorCompleted(pOperator);
|
||||||
// streamStateCommit(pTaskInfo->streamInfo.pState);
|
streamStateCommit(pTaskInfo->streamInfo.pState);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,8 +190,9 @@ static int32_t doAddToBuf(SSDataBlock* pDataBlock, SSortHandle* pHandle) {
|
||||||
qError("Add to buf failed since %s", terrstr(terrno));
|
qError("Add to buf failed since %s", terrstr(terrno));
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = createDiskbasedBuf(&pHandle->pBuf, pHandle->pageSize, pHandle->numOfPages * pHandle->pageSize,
|
int32_t code = createDiskbasedBuf(&pHandle->pBuf, pHandle->pageSize, pHandle->numOfPages * pHandle->pageSize,
|
||||||
"doAddToBuf", tsTempDir);
|
"sortExternalBuf", tsTempDir);
|
||||||
dBufSetPrintInfo(pHandle->pBuf);
|
dBufSetPrintInfo(pHandle->pBuf);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
|
@ -635,6 +636,7 @@ int32_t getProperSortPageSize(size_t rowSize, uint32_t numOfCols) {
|
||||||
|
|
||||||
static int32_t createInitialSources(SSortHandle* pHandle) {
|
static int32_t createInitialSources(SSortHandle* pHandle) {
|
||||||
size_t sortBufSize = pHandle->numOfPages * pHandle->pageSize;
|
size_t sortBufSize = pHandle->numOfPages * pHandle->pageSize;
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
if (pHandle->type == SORT_SINGLESOURCE_SORT) {
|
if (pHandle->type == SORT_SINGLESOURCE_SORT) {
|
||||||
SSortSource** pSource = taosArrayGet(pHandle->pOrderedSource, 0);
|
SSortSource** pSource = taosArrayGet(pHandle->pOrderedSource, 0);
|
||||||
|
@ -663,8 +665,8 @@ static int32_t createInitialSources(SSortHandle* pHandle) {
|
||||||
pHandle->beforeFp(pBlock, pHandle->param);
|
pHandle->beforeFp(pBlock, pHandle->param);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = blockDataMerge(pHandle->pDataBlock, pBlock);
|
code = blockDataMerge(pHandle->pDataBlock, pBlock);
|
||||||
if (code != 0) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
if (source->param && !source->onlyRef) {
|
if (source->param && !source->onlyRef) {
|
||||||
taosMemoryFree(source->param);
|
taosMemoryFree(source->param);
|
||||||
}
|
}
|
||||||
|
@ -689,6 +691,7 @@ static int32_t createInitialSources(SSortHandle* pHandle) {
|
||||||
blockDataDestroy(source->src.pBlock);
|
blockDataDestroy(source->src.pBlock);
|
||||||
source->src.pBlock = NULL;
|
source->src.pBlock = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
taosMemoryFree(source);
|
taosMemoryFree(source);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -696,13 +699,17 @@ static int32_t createInitialSources(SSortHandle* pHandle) {
|
||||||
int64_t el = taosGetTimestampUs() - p;
|
int64_t el = taosGetTimestampUs() - p;
|
||||||
pHandle->sortElapsed += el;
|
pHandle->sortElapsed += el;
|
||||||
|
|
||||||
doAddToBuf(pHandle->pDataBlock, pHandle);
|
code = doAddToBuf(pHandle->pDataBlock, pHandle);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source->param && !source->onlyRef) {
|
if (source->param && !source->onlyRef) {
|
||||||
taosMemoryFree(source->param);
|
taosMemoryFree(source->param);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosMemoryFree(source);
|
taosMemoryFree(source);
|
||||||
|
|
||||||
if (pHandle->pDataBlock != NULL && pHandle->pDataBlock->info.rows > 0) {
|
if (pHandle->pDataBlock != NULL && pHandle->pDataBlock->info.rows > 0) {
|
||||||
|
@ -711,7 +718,7 @@ static int32_t createInitialSources(SSortHandle* pHandle) {
|
||||||
// Perform the in-memory sort and then flush data in the buffer into disk.
|
// Perform the in-memory sort and then flush data in the buffer into disk.
|
||||||
int64_t p = taosGetTimestampUs();
|
int64_t p = taosGetTimestampUs();
|
||||||
|
|
||||||
int32_t code = blockDataSort(pHandle->pDataBlock, pHandle->pSortInfo);
|
code = blockDataSort(pHandle->pDataBlock, pHandle->pSortInfo);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -729,12 +736,12 @@ static int32_t createInitialSources(SSortHandle* pHandle) {
|
||||||
pHandle->tupleHandle.pBlock = pHandle->pDataBlock;
|
pHandle->tupleHandle.pBlock = pHandle->pDataBlock;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
doAddToBuf(pHandle->pDataBlock, pHandle);
|
code = doAddToBuf(pHandle->pDataBlock, pHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tsortOpen(SSortHandle* pHandle) {
|
int32_t tsortOpen(SSortHandle* pHandle) {
|
||||||
|
|
|
@ -714,26 +714,18 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc, int32_t* nElems)
|
||||||
pBuf->type = type;
|
pBuf->type = type;
|
||||||
|
|
||||||
if (IS_NULL_TYPE(type)) {
|
if (IS_NULL_TYPE(type)) {
|
||||||
numOfElems = 0;
|
|
||||||
goto _over;
|
goto _over;
|
||||||
}
|
}
|
||||||
|
|
||||||
// data in current data block are qualified to the query
|
// data in current data block are qualified to the query
|
||||||
if (pInput->colDataSMAIsSet) {
|
if (pInput->colDataSMAIsSet) {
|
||||||
numOfElems = pInput->numOfRows - pAgg->numOfNull;
|
numOfElems = pInput->numOfRows - pAgg->numOfNull;
|
||||||
|
|
||||||
if (numOfElems == 0) {
|
if (numOfElems == 0) {
|
||||||
goto _over;
|
goto _over;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* tval = NULL;
|
|
||||||
int16_t index = 0;
|
int16_t index = 0;
|
||||||
|
void* tval = (isMinFunc) ? &pInput->pColumnDataAgg[0]->min : &pInput->pColumnDataAgg[0]->max;
|
||||||
if (isMinFunc) {
|
|
||||||
tval = &pInput->pColumnDataAgg[0]->min;
|
|
||||||
} else {
|
|
||||||
tval = &pInput->pColumnDataAgg[0]->max;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pBuf->assign) {
|
if (!pBuf->assign) {
|
||||||
if (type == TSDB_DATA_TYPE_FLOAT) {
|
if (type == TSDB_DATA_TYPE_FLOAT) {
|
||||||
|
@ -824,8 +816,9 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc, int32_t* nElems)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
numOfElems = 1;
|
||||||
pBuf->assign = true;
|
pBuf->assign = true;
|
||||||
return TSDB_CODE_SUCCESS;
|
goto _over;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t start = pInput->startRowIndex;
|
int32_t start = pInput->startRowIndex;
|
||||||
|
|
|
@ -262,6 +262,13 @@ bool fmIsGroupKeyFunc(int32_t funcId) {
|
||||||
return FUNCTION_TYPE_GROUP_KEY == funcMgtBuiltins[funcId].type;
|
return FUNCTION_TYPE_GROUP_KEY == funcMgtBuiltins[funcId].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fmIsBlockDistFunc(int32_t funcId) {
|
||||||
|
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return FUNCTION_TYPE_BLOCK_DIST == funcMgtBuiltins[funcId].type;
|
||||||
|
}
|
||||||
|
|
||||||
void fmFuncMgtDestroy() {
|
void fmFuncMgtDestroy() {
|
||||||
void* m = gFunMgtService.pFuncNameHashTable;
|
void* m = gFunMgtService.pFuncNameHashTable;
|
||||||
if (m != NULL && atomic_val_compare_exchange_ptr((void**)&gFunMgtService.pFuncNameHashTable, m, 0) == m) {
|
if (m != NULL && atomic_val_compare_exchange_ptr((void**)&gFunMgtService.pFuncNameHashTable, m, 0) == m) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct SToken;
|
||||||
#define NEXT_TOKEN(pSql, sToken) \
|
#define NEXT_TOKEN(pSql, sToken) \
|
||||||
do { \
|
do { \
|
||||||
int32_t index = 0; \
|
int32_t index = 0; \
|
||||||
sToken = tStrGetToken(pSql, &index, false); \
|
sToken = tStrGetToken(pSql, &index, false, NULL); \
|
||||||
pSql += index; \
|
pSql += index; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ uint32_t tGetToken(const char *z, uint32_t *tokenType);
|
||||||
* @param isPrevOptr
|
* @param isPrevOptr
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
SToken tStrGetToken(const char *str, int32_t *i, bool isPrevOptr);
|
SToken tStrGetToken(const char *str, int32_t *i, bool isPrevOptr, bool *pIgnoreComma);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if it is a keyword or not
|
* check if it is a keyword or not
|
||||||
|
|
|
@ -21,13 +21,20 @@
|
||||||
#define NEXT_TOKEN_WITH_PREV(pSql, token) \
|
#define NEXT_TOKEN_WITH_PREV(pSql, token) \
|
||||||
do { \
|
do { \
|
||||||
int32_t index = 0; \
|
int32_t index = 0; \
|
||||||
token = tStrGetToken(pSql, &index, true); \
|
token = tStrGetToken(pSql, &index, true, NULL); \
|
||||||
|
pSql += index; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define NEXT_TOKEN_WITH_PREV_EXT(pSql, token, pIgnoreComma) \
|
||||||
|
do { \
|
||||||
|
int32_t index = 0; \
|
||||||
|
token = tStrGetToken(pSql, &index, true, pIgnoreComma); \
|
||||||
pSql += index; \
|
pSql += index; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define NEXT_TOKEN_KEEP_SQL(pSql, token, index) \
|
#define NEXT_TOKEN_KEEP_SQL(pSql, token, index) \
|
||||||
do { \
|
do { \
|
||||||
token = tStrGetToken(pSql, &index, false); \
|
token = tStrGetToken(pSql, &index, false, NULL); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define NEXT_VALID_TOKEN(pSql, token) \
|
#define NEXT_VALID_TOKEN(pSql, token) \
|
||||||
|
@ -302,12 +309,12 @@ static int parseTime(const char** end, SToken* pToken, int16_t timePrec, int64_t
|
||||||
* e.g., now+12a, now-5h
|
* e.g., now+12a, now-5h
|
||||||
*/
|
*/
|
||||||
index = 0;
|
index = 0;
|
||||||
SToken token = tStrGetToken(pTokenEnd, &index, false);
|
SToken token = tStrGetToken(pTokenEnd, &index, false, NULL);
|
||||||
pTokenEnd += index;
|
pTokenEnd += index;
|
||||||
|
|
||||||
if (token.type == TK_NK_MINUS || token.type == TK_NK_PLUS) {
|
if (token.type == TK_NK_MINUS || token.type == TK_NK_PLUS) {
|
||||||
index = 0;
|
index = 0;
|
||||||
SToken valueToken = tStrGetToken(pTokenEnd, &index, false);
|
SToken valueToken = tStrGetToken(pTokenEnd, &index, false, NULL);
|
||||||
pTokenEnd += index;
|
pTokenEnd += index;
|
||||||
|
|
||||||
if (valueToken.n < 2) {
|
if (valueToken.n < 2) {
|
||||||
|
@ -1240,30 +1247,35 @@ static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataB
|
||||||
int32_t code = tdSRowResetBuf(pBuilder, row);
|
int32_t code = tdSRowResetBuf(pBuilder, row);
|
||||||
// 1. set the parsed value from sql string
|
// 1. set the parsed value from sql string
|
||||||
for (int i = 0; i < pCols->numOfBound && TSDB_CODE_SUCCESS == code; ++i) {
|
for (int i = 0; i < pCols->numOfBound && TSDB_CODE_SUCCESS == code; ++i) {
|
||||||
NEXT_TOKEN_WITH_PREV(*pSql, *pToken);
|
const char* pOrigSql = *pSql;
|
||||||
SSchema* pSchema = &pSchemas[pCols->boundColumns[i]];
|
bool ignoreComma = false;
|
||||||
|
NEXT_TOKEN_WITH_PREV_EXT(*pSql, *pToken, &ignoreComma);
|
||||||
|
if (ignoreComma) {
|
||||||
|
code = buildSyntaxErrMsg(&pCxt->msg, "invalid data or symbol", pOrigSql);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (pToken->type == TK_NK_QUESTION) {
|
if (pToken->type == TK_NK_QUESTION) {
|
||||||
isParseBindParam = true;
|
isParseBindParam = true;
|
||||||
if (NULL == pCxt->pComCxt->pStmtCb) {
|
if (NULL == pCxt->pComCxt->pStmtCb) {
|
||||||
code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z);
|
code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
} else {
|
||||||
}
|
if (TK_NK_RP == pToken->type) {
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && TK_NK_RP == pToken->type) {
|
|
||||||
code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
|
code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && isParseBindParam) {
|
if (isParseBindParam) {
|
||||||
code = buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and values");
|
code = buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and values");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
param.schema = &pSchemas[pCols->boundColumns[i]];
|
||||||
param.schema = pSchema;
|
|
||||||
insGetSTSRowAppendInfo(pBuilder->rowType, pCols, i, ¶m.toffset, ¶m.colIdx);
|
insGetSTSRowAppendInfo(pBuilder->rowType, pCols, i, ¶m.toffset, ¶m.colIdx);
|
||||||
code = parseValueToken(pCxt, pSql, pToken, pSchema, getTableInfo(pDataBuf->pTableMeta).precision, insMemRowAppend,
|
code = parseValueToken(pCxt, pSql, pToken, param.schema, getTableInfo(pDataBuf->pTableMeta).precision,
|
||||||
¶m);
|
insMemRowAppend, ¶m);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && i < pCols->numOfBound - 1) {
|
if (TSDB_CODE_SUCCESS == code && i < pCols->numOfBound - 1) {
|
||||||
|
@ -1760,6 +1772,9 @@ static int32_t getTableSchemaFromMetaData(SInsertParseContext* pCxt, const SMeta
|
||||||
if (TSDB_CODE_SUCCESS == code && !isStb && TSDB_SUPER_TABLE == pStmt->pTableMeta->tableType) {
|
if (TSDB_CODE_SUCCESS == code && !isStb && TSDB_SUPER_TABLE == pStmt->pTableMeta->tableType) {
|
||||||
code = buildInvalidOperationMsg(&pCxt->msg, "insert data into super table is not supported");
|
code = buildInvalidOperationMsg(&pCxt->msg, "insert data into super table is not supported");
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && isStb) {
|
||||||
|
code = storeTableMeta(pCxt, pStmt);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = getTableVgroupFromMetaData(pMetaData->pTableHash, pStmt, isStb);
|
code = getTableVgroupFromMetaData(pMetaData->pTableHash, pStmt, isStb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,8 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch
|
||||||
}
|
}
|
||||||
|
|
||||||
SVCreateTbReq tbReq = {0};
|
SVCreateTbReq tbReq = {0};
|
||||||
insBuildCreateTbReq(&tbReq, tName, pTag, suid, sTableName, tagName, pDataBlock->pTableMeta->tableInfo.numOfTags, TSDB_DEFAULT_TABLE_TTL);
|
insBuildCreateTbReq(&tbReq, tName, pTag, suid, sTableName, tagName, pDataBlock->pTableMeta->tableInfo.numOfTags,
|
||||||
|
TSDB_DEFAULT_TABLE_TTL);
|
||||||
code = insBuildCreateTbMsg(pDataBlock, &tbReq);
|
code = insBuildCreateTbMsg(pDataBlock, &tbReq);
|
||||||
tdDestroySVCreateTbReq(&tbReq);
|
tdDestroySVCreateTbReq(&tbReq);
|
||||||
|
|
||||||
|
|
|
@ -620,7 +620,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr) {
|
SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr, bool* pIgnoreComma) {
|
||||||
SToken t0 = {0};
|
SToken t0 = {0};
|
||||||
|
|
||||||
// here we reach the end of sql string, null-terminated string
|
// here we reach the end of sql string, null-terminated string
|
||||||
|
@ -641,6 +641,10 @@ SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr) {
|
||||||
return t0;
|
return t0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NULL != pIgnoreComma && t == ',') {
|
||||||
|
*pIgnoreComma = true;
|
||||||
|
}
|
||||||
|
|
||||||
t = str[++(*i)];
|
t = str[++(*i)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1553,11 +1553,34 @@ static int32_t translateRepeatScanFunc(STranslateContext* pCxt, SFunctionNode* p
|
||||||
// select percentile() without from clause is also valid
|
// select percentile() without from clause is also valid
|
||||||
if ((NULL != pTable && (QUERY_NODE_REAL_TABLE != nodeType(pTable) ||
|
if ((NULL != pTable && (QUERY_NODE_REAL_TABLE != nodeType(pTable) ||
|
||||||
(TSDB_CHILD_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType &&
|
(TSDB_CHILD_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType &&
|
||||||
TSDB_NORMAL_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType))) ||
|
TSDB_NORMAL_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType)))) {
|
||||||
NULL != pSelect->pPartitionByList) {
|
|
||||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE,
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE,
|
||||||
"%s is only supported in single table query", pFunc->functionName);
|
"%s is only supported in single table query", pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
if (NULL != pSelect->pPartitionByList) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||||
|
"%s function is not supported in partition query", pFunc->functionName);
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t translateBlockDistFunc(STranslateContext* pCtx, SFunctionNode* pFunc) {
|
||||||
|
if (!fmIsBlockDistFunc(pFunc->funcId)) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
if (!isSelectStmt(pCtx->pCurrStmt)) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCtx->msgBuf, TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE,
|
||||||
|
"%s is only supported in single table query", pFunc->functionName);
|
||||||
|
}
|
||||||
|
SSelectStmt* pSelect = (SSelectStmt*)pCtx->pCurrStmt;
|
||||||
|
SNode* pTable = pSelect->pFromTable;
|
||||||
|
if (NULL != pTable && (QUERY_NODE_REAL_TABLE != nodeType(pTable) ||
|
||||||
|
(TSDB_SUPER_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType &&
|
||||||
|
TSDB_CHILD_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType &&
|
||||||
|
TSDB_NORMAL_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType))) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCtx->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||||
|
"%s is only supported on super table, child table or normal table", pFunc->functionName);
|
||||||
|
}
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1720,7 +1743,7 @@ static int32_t rewriteSystemInfoFunc(STranslateContext* pCxt, SNode** pNode) {
|
||||||
return TSDB_CODE_PAR_INTERNAL_ERROR;
|
return TSDB_CODE_PAR_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t translateNoramlFunction(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
static int32_t translateNormalFunction(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||||
int32_t code = translateAggFunc(pCxt, pFunc);
|
int32_t code = translateAggFunc(pCxt, pFunc);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateScanPseudoColumnFunc(pCxt, pFunc);
|
code = translateScanPseudoColumnFunc(pCxt, pFunc);
|
||||||
|
@ -1752,6 +1775,9 @@ static int32_t translateNoramlFunction(STranslateContext* pCxt, SFunctionNode* p
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateTimelineFunc(pCxt, pFunc);
|
code = translateTimelineFunc(pCxt, pFunc);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = translateBlockDistFunc(pCxt, pFunc);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
setFuncClassification(pCxt->pCurrStmt, pFunc);
|
setFuncClassification(pCxt->pCurrStmt, pFunc);
|
||||||
}
|
}
|
||||||
|
@ -1812,7 +1838,7 @@ static int32_t translateFunctionImpl(STranslateContext* pCxt, SFunctionNode** pF
|
||||||
if (fmIsClientPseudoColumnFunc((*pFunc)->funcId)) {
|
if (fmIsClientPseudoColumnFunc((*pFunc)->funcId)) {
|
||||||
return rewriteClientPseudoColumnFunc(pCxt, (SNode**)pFunc);
|
return rewriteClientPseudoColumnFunc(pCxt, (SNode**)pFunc);
|
||||||
}
|
}
|
||||||
return translateNoramlFunction(pCxt, *pFunc);
|
return translateNormalFunction(pCxt, *pFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode** pFunc) {
|
static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode** pFunc) {
|
||||||
|
@ -2978,7 +3004,7 @@ static int32_t checkFill(STranslateContext* pCxt, SFillNode* pFill, SValueNode*
|
||||||
intervalRange = pInterval->datum.i;
|
intervalRange = pInterval->datum.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((timeRange == 0) || (timeRange / intervalRange) >= MAX_INTERVAL_TIME_WINDOW) {
|
if ((timeRange / intervalRange) >= MAX_INTERVAL_TIME_WINDOW) {
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE);
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ bool qIsInsertValuesSql(const char* pStr, size_t length) {
|
||||||
const char* pSql = pStr;
|
const char* pSql = pStr;
|
||||||
|
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
SToken t = tStrGetToken((char*)pStr, &index, false);
|
SToken t = tStrGetToken((char*)pStr, &index, false, NULL);
|
||||||
if (TK_INSERT != t.type && TK_IMPORT != t.type) {
|
if (TK_INSERT != t.type && TK_IMPORT != t.type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ bool qIsInsertValuesSql(const char* pStr, size_t length) {
|
||||||
do {
|
do {
|
||||||
pStr += index;
|
pStr += index;
|
||||||
index = 0;
|
index = 0;
|
||||||
t = tStrGetToken((char*)pStr, &index, false);
|
t = tStrGetToken((char*)pStr, &index, false, NULL);
|
||||||
if (TK_USING == t.type || TK_VALUES == t.type || TK_FILE == t.type) {
|
if (TK_USING == t.type || TK_VALUES == t.type || TK_FILE == t.type) {
|
||||||
return true;
|
return true;
|
||||||
} else if (TK_SELECT == t.type) {
|
} else if (TK_SELECT == t.type) {
|
||||||
|
|
|
@ -1016,7 +1016,7 @@ static int32_t createProjectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSel
|
||||||
|
|
||||||
TSWAP(pProject->node.pLimit, pSelect->pLimit);
|
TSWAP(pProject->node.pLimit, pSelect->pLimit);
|
||||||
TSWAP(pProject->node.pSlimit, pSelect->pSlimit);
|
TSWAP(pProject->node.pSlimit, pSelect->pSlimit);
|
||||||
pProject->ignoreGroupId = (NULL == pSelect->pPartitionByList);
|
pProject->ignoreGroupId = pSelect->isSubquery ? true : (NULL == pSelect->pPartitionByList);
|
||||||
pProject->node.groupAction =
|
pProject->node.groupAction =
|
||||||
(!pSelect->isSubquery && pCxt->pPlanCxt->streamQuery) ? GROUP_ACTION_KEEP : GROUP_ACTION_CLEAR;
|
(!pSelect->isSubquery && pCxt->pPlanCxt->streamQuery) ? GROUP_ACTION_KEEP : GROUP_ACTION_CLEAR;
|
||||||
pProject->node.requireDataOrder = DATA_ORDER_LEVEL_NONE;
|
pProject->node.requireDataOrder = DATA_ORDER_LEVEL_NONE;
|
||||||
|
|
|
@ -348,7 +348,8 @@ static bool stbSplIsPartTableAgg(SAggLogicNode* pAgg) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (NULL != pAgg->pGroupKeys) {
|
if (NULL != pAgg->pGroupKeys) {
|
||||||
return stbSplHasPartTbname(pAgg->pGroupKeys) && stbSplNotSystemScan((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0));
|
return stbSplHasPartTbname(pAgg->pGroupKeys) &&
|
||||||
|
stbSplNotSystemScan((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0));
|
||||||
}
|
}
|
||||||
return stbSplHasPartTbname(stbSplGetPartKeys((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0)));
|
return stbSplHasPartTbname(stbSplGetPartKeys((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0)));
|
||||||
}
|
}
|
||||||
|
@ -559,6 +560,8 @@ static int32_t stbSplCreateMergeNode(SSplitContext* pCxt, SLogicSubplan* pSubpla
|
||||||
if (NULL == pMerge->node.pLimit) {
|
if (NULL == pMerge->node.pLimit) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
((SLimitNode*)pSplitNode->pLimit)->limit += ((SLimitNode*)pSplitNode->pLimit)->offset;
|
||||||
|
((SLimitNode*)pSplitNode->pLimit)->offset = 0;
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
if (NULL == pSubplan) {
|
if (NULL == pSubplan) {
|
||||||
|
@ -1025,21 +1028,29 @@ static int32_t stbSplSplitSortNode(SSplitContext* pCxt, SStableSplitInfo* pInfo)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t stbSplSplitScanNodeWithoutPartTags(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
static int32_t stbSplGetSplitNodeForScan(SStableSplitInfo* pInfo, SLogicNode** pSplitNode) {
|
||||||
SLogicNode* pSplitNode = pInfo->pSplitNode;
|
*pSplitNode = pInfo->pSplitNode;
|
||||||
if (NULL != pInfo->pSplitNode->pParent && QUERY_NODE_LOGIC_PLAN_PROJECT == nodeType(pInfo->pSplitNode->pParent) &&
|
if (NULL != pInfo->pSplitNode->pParent && QUERY_NODE_LOGIC_PLAN_PROJECT == nodeType(pInfo->pSplitNode->pParent) &&
|
||||||
NULL == pInfo->pSplitNode->pParent->pLimit && NULL == pInfo->pSplitNode->pParent->pSlimit) {
|
NULL == pInfo->pSplitNode->pParent->pLimit && NULL == pInfo->pSplitNode->pParent->pSlimit) {
|
||||||
pSplitNode = pInfo->pSplitNode->pParent;
|
*pSplitNode = pInfo->pSplitNode->pParent;
|
||||||
if (NULL != pInfo->pSplitNode->pLimit) {
|
if (NULL != pInfo->pSplitNode->pLimit) {
|
||||||
pSplitNode->pLimit = nodesCloneNode(pInfo->pSplitNode->pLimit);
|
(*pSplitNode)->pLimit = nodesCloneNode(pInfo->pSplitNode->pLimit);
|
||||||
if (NULL == pSplitNode->pLimit) {
|
if (NULL == (*pSplitNode)->pLimit) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
((SLimitNode*)pInfo->pSplitNode->pLimit)->limit += ((SLimitNode*)pInfo->pSplitNode->pLimit)->offset;
|
((SLimitNode*)pInfo->pSplitNode->pLimit)->limit += ((SLimitNode*)pInfo->pSplitNode->pLimit)->offset;
|
||||||
((SLimitNode*)pInfo->pSplitNode->pLimit)->offset = 0;
|
((SLimitNode*)pInfo->pSplitNode->pLimit)->offset = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int32_t code = splCreateExchangeNodeForSubplan(pCxt, pInfo->pSubplan, pSplitNode, SUBPLAN_TYPE_MERGE);
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t stbSplSplitScanNodeWithoutPartTags(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||||
|
SLogicNode* pSplitNode = NULL;
|
||||||
|
int32_t code = stbSplGetSplitNodeForScan(pInfo, &pSplitNode);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = splCreateExchangeNodeForSubplan(pCxt, pInfo->pSubplan, pSplitNode, SUBPLAN_TYPE_MERGE);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren,
|
code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren,
|
||||||
(SNode*)splCreateScanSubplan(pCxt, pSplitNode, SPLIT_FLAG_STABLE_SPLIT));
|
(SNode*)splCreateScanSubplan(pCxt, pSplitNode, SPLIT_FLAG_STABLE_SPLIT));
|
||||||
|
@ -1049,12 +1060,11 @@ static int32_t stbSplSplitScanNodeWithoutPartTags(SSplitContext* pCxt, SStableSp
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t stbSplSplitScanNodeWithPartTags(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
static int32_t stbSplSplitScanNodeWithPartTags(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||||
SLogicNode* pSplitNode = pInfo->pSplitNode;
|
SLogicNode* pSplitNode = NULL;
|
||||||
if (NULL != pInfo->pSplitNode->pParent && QUERY_NODE_LOGIC_PLAN_PROJECT == nodeType(pInfo->pSplitNode->pParent) &&
|
int32_t code = stbSplGetSplitNodeForScan(pInfo, &pSplitNode);
|
||||||
NULL == pInfo->pSplitNode->pParent->pLimit && NULL == pInfo->pSplitNode->pParent->pSlimit) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
pSplitNode = pInfo->pSplitNode->pParent;
|
code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pSplitNode, NULL, pSplitNode, true);
|
||||||
}
|
}
|
||||||
int32_t code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pSplitNode, NULL, pSplitNode, true);
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren,
|
code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren,
|
||||||
(SNode*)splCreateScanSubplan(pCxt, pSplitNode, SPLIT_FLAG_STABLE_SPLIT));
|
(SNode*)splCreateScanSubplan(pCxt, pSplitNode, SPLIT_FLAG_STABLE_SPLIT));
|
||||||
|
|
|
@ -194,6 +194,8 @@ typedef struct SQWorker {
|
||||||
SMsgCb msgCb;
|
SMsgCb msgCb;
|
||||||
SQWStat stat;
|
SQWStat stat;
|
||||||
int32_t *destroyed;
|
int32_t *destroyed;
|
||||||
|
|
||||||
|
int8_t nodeStopped;
|
||||||
} SQWorker;
|
} SQWorker;
|
||||||
|
|
||||||
typedef struct SQWorkerMgmt {
|
typedef struct SQWorkerMgmt {
|
||||||
|
|
|
@ -213,9 +213,15 @@ int32_t qwAcquireTaskCtx(QW_FPARAMS_DEF, SQWTaskCtx **ctx) {
|
||||||
QW_SET_QTID(id, qId, tId, eId);
|
QW_SET_QTID(id, qId, tId, eId);
|
||||||
|
|
||||||
*ctx = taosHashAcquire(mgmt->ctxHash, id, sizeof(id));
|
*ctx = taosHashAcquire(mgmt->ctxHash, id, sizeof(id));
|
||||||
|
int8_t nodeStopped = atomic_load_8(&mgmt->nodeStopped);
|
||||||
if (NULL == (*ctx)) {
|
if (NULL == (*ctx)) {
|
||||||
|
if (!nodeStopped) {
|
||||||
QW_TASK_DLOG_E("task ctx not exist, may be dropped");
|
QW_TASK_DLOG_E("task ctx not exist, may be dropped");
|
||||||
QW_ERR_RET(TSDB_CODE_QRY_TASK_CTX_NOT_EXIST);
|
QW_ERR_RET(TSDB_CODE_QRY_TASK_CTX_NOT_EXIST);
|
||||||
|
} else {
|
||||||
|
QW_TASK_DLOG_E("node stopped");
|
||||||
|
QW_ERR_RET(TSDB_CODE_VND_STOPPED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -226,9 +232,16 @@ int32_t qwGetTaskCtx(QW_FPARAMS_DEF, SQWTaskCtx **ctx) {
|
||||||
QW_SET_QTID(id, qId, tId, eId);
|
QW_SET_QTID(id, qId, tId, eId);
|
||||||
|
|
||||||
*ctx = taosHashGet(mgmt->ctxHash, id, sizeof(id));
|
*ctx = taosHashGet(mgmt->ctxHash, id, sizeof(id));
|
||||||
|
int8_t nodeStopped = atomic_load_8(&mgmt->nodeStopped);
|
||||||
|
|
||||||
if (NULL == (*ctx)) {
|
if (NULL == (*ctx)) {
|
||||||
|
if (!nodeStopped) {
|
||||||
QW_TASK_DLOG_E("task ctx not exist, may be dropped");
|
QW_TASK_DLOG_E("task ctx not exist, may be dropped");
|
||||||
QW_ERR_RET(TSDB_CODE_QRY_TASK_CTX_NOT_EXIST);
|
QW_ERR_RET(TSDB_CODE_QRY_TASK_CTX_NOT_EXIST);
|
||||||
|
} else {
|
||||||
|
QW_TASK_DLOG_E("node stopped");
|
||||||
|
QW_ERR_RET(TSDB_CODE_VND_STOPPED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
|
@ -517,7 +517,7 @@ int32_t qwHandlePostPhaseEvents(QW_FPARAMS_DEF, int8_t phase, SQWPhaseInput *inp
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QW_EVENT_RECEIVED(ctx, QW_EVENT_DROP)) {
|
if (QW_EVENT_RECEIVED(ctx, QW_EVENT_DROP)) {
|
||||||
if (QW_PHASE_POST_FETCH != phase || qwTaskNotInExec(ctx)) {
|
if (QW_PHASE_POST_FETCH != phase || ((!QW_QUERY_RUNNING(ctx)) && qwTaskNotInExec(ctx))) {
|
||||||
QW_ERR_JRET(qwDropTask(QW_FPARAMS()));
|
QW_ERR_JRET(qwDropTask(QW_FPARAMS()));
|
||||||
QW_ERR_JRET(ctx->rspCode);
|
QW_ERR_JRET(ctx->rspCode);
|
||||||
}
|
}
|
||||||
|
@ -1188,6 +1188,9 @@ void qWorkerStopAllTasks(void *qWorkerMgmt) {
|
||||||
uint64_t qId, tId, sId;
|
uint64_t qId, tId, sId;
|
||||||
int32_t eId;
|
int32_t eId;
|
||||||
int64_t rId = 0;
|
int64_t rId = 0;
|
||||||
|
|
||||||
|
atomic_store_8(&mgmt->nodeStopped, 1);
|
||||||
|
|
||||||
void *pIter = taosHashIterate(mgmt->ctxHash, NULL);
|
void *pIter = taosHashIterate(mgmt->ctxHash, NULL);
|
||||||
while (pIter) {
|
while (pIter) {
|
||||||
SQWTaskCtx *ctx = (SQWTaskCtx *)pIter;
|
SQWTaskCtx *ctx = (SQWTaskCtx *)pIter;
|
||||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
||||||
|
|
||||||
#define SYNC_SNAPSHOT_SEQ_INVALID -2
|
#define SYNC_SNAPSHOT_SEQ_INVALID -2
|
||||||
#define SYNC_SNAPSHOT_SEQ_FORCE_CLOSE -3
|
#define SYNC_SNAPSHOT_SEQ_FORCE_CLOSE -3
|
||||||
#define SYNC_SNAPSHOT_SEQ_PRE_SNAPSHOT -1
|
#define SYNC_SNAPSHOT_SEQ_PREP_SNAPSHOT -1
|
||||||
#define SYNC_SNAPSHOT_SEQ_BEGIN 0
|
#define SYNC_SNAPSHOT_SEQ_BEGIN 0
|
||||||
#define SYNC_SNAPSHOT_SEQ_END 0x7FFFFFFF
|
#define SYNC_SNAPSHOT_SEQ_END 0x7FFFFFFF
|
||||||
|
|
||||||
|
|
|
@ -89,45 +89,6 @@
|
||||||
// /\ UNCHANGED <<candidateVars, leaderVars>>
|
// /\ UNCHANGED <<candidateVars, leaderVars>>
|
||||||
//
|
//
|
||||||
|
|
||||||
int32_t syncNodeFollowerCommit(SSyncNode* ths, SyncIndex newCommitIndex) {
|
|
||||||
ASSERT(false && "deprecated");
|
|
||||||
if (ths->state != TAOS_SYNC_STATE_FOLLOWER) {
|
|
||||||
sNTrace(ths, "can not do follower commit");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maybe update commit index, leader notice me
|
|
||||||
if (newCommitIndex > ths->commitIndex) {
|
|
||||||
// has commit entry in local
|
|
||||||
if (newCommitIndex <= ths->pLogStore->syncLogLastIndex(ths->pLogStore)) {
|
|
||||||
// advance commit index to sanpshot first
|
|
||||||
SSnapshot snapshot;
|
|
||||||
ths->pFsm->FpGetSnapshotInfo(ths->pFsm, &snapshot);
|
|
||||||
if (snapshot.lastApplyIndex >= 0 && snapshot.lastApplyIndex > ths->commitIndex) {
|
|
||||||
SyncIndex commitBegin = ths->commitIndex;
|
|
||||||
SyncIndex commitEnd = snapshot.lastApplyIndex;
|
|
||||||
ths->commitIndex = snapshot.lastApplyIndex;
|
|
||||||
sNTrace(ths, "commit by snapshot from index:%" PRId64 " to index:%" PRId64, commitBegin, commitEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
SyncIndex beginIndex = ths->commitIndex + 1;
|
|
||||||
SyncIndex endIndex = newCommitIndex;
|
|
||||||
|
|
||||||
// update commit index
|
|
||||||
ths->commitIndex = newCommitIndex;
|
|
||||||
|
|
||||||
// call back Wal
|
|
||||||
int32_t code = ths->pLogStore->syncLogUpdateCommitIndex(ths->pLogStore, ths->commitIndex);
|
|
||||||
ASSERT(code == 0);
|
|
||||||
|
|
||||||
code = syncNodeDoCommit(ths, beginIndex, endIndex, ths->state);
|
|
||||||
ASSERT(code == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSyncRaftEntry* syncBuildRaftEntryFromAppendEntries(const SyncAppendEntries* pMsg) {
|
SSyncRaftEntry* syncBuildRaftEntryFromAppendEntries(const SyncAppendEntries* pMsg) {
|
||||||
SSyncRaftEntry* pEntry = taosMemoryMalloc(pMsg->dataLen);
|
SSyncRaftEntry* pEntry = taosMemoryMalloc(pMsg->dataLen);
|
||||||
if (pEntry == NULL) {
|
if (pEntry == NULL) {
|
||||||
|
@ -232,256 +193,3 @@ _IGNORE:
|
||||||
rpcFreeCont(rpcRsp.pCont);
|
rpcFreeCont(rpcRsp.pCont);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncNodeOnAppendEntriesOld(SSyncNode* ths, const SRpcMsg* pRpcMsg) {
|
|
||||||
SyncAppendEntries* pMsg = pRpcMsg->pCont;
|
|
||||||
SRpcMsg rpcRsp = {0};
|
|
||||||
|
|
||||||
// if already drop replica, do not process
|
|
||||||
if (!syncNodeInRaftGroup(ths, &(pMsg->srcId))) {
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, "not in my config");
|
|
||||||
goto _IGNORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare response msg
|
|
||||||
int32_t code = syncBuildAppendEntriesReply(&rpcRsp, ths->vgId);
|
|
||||||
if (code != 0) {
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, "build rsp error");
|
|
||||||
goto _IGNORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
SyncAppendEntriesReply* pReply = rpcRsp.pCont;
|
|
||||||
pReply->srcId = ths->myRaftId;
|
|
||||||
pReply->destId = pMsg->srcId;
|
|
||||||
pReply->term = ths->raftStore.currentTerm;
|
|
||||||
pReply->success = false;
|
|
||||||
// pReply->matchIndex = ths->pLogStore->syncLogLastIndex(ths->pLogStore);
|
|
||||||
pReply->matchIndex = SYNC_INDEX_INVALID;
|
|
||||||
pReply->lastSendIndex = pMsg->prevLogIndex + 1;
|
|
||||||
pReply->startTime = ths->startTime;
|
|
||||||
|
|
||||||
if (pMsg->term < ths->raftStore.currentTerm) {
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, "reject, small term");
|
|
||||||
goto _SEND_RESPONSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pMsg->term > ths->raftStore.currentTerm) {
|
|
||||||
pReply->term = pMsg->term;
|
|
||||||
}
|
|
||||||
|
|
||||||
syncNodeStepDown(ths, pMsg->term);
|
|
||||||
syncNodeResetElectTimer(ths);
|
|
||||||
|
|
||||||
SyncIndex startIndex = ths->pLogStore->syncLogBeginIndex(ths->pLogStore);
|
|
||||||
SyncIndex lastIndex = ths->pLogStore->syncLogLastIndex(ths->pLogStore);
|
|
||||||
|
|
||||||
if (pMsg->prevLogIndex > lastIndex) {
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, "reject, index not match");
|
|
||||||
goto _SEND_RESPONSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pMsg->prevLogIndex >= startIndex) {
|
|
||||||
SyncTerm myPreLogTerm = syncNodeGetPreTerm(ths, pMsg->prevLogIndex + 1);
|
|
||||||
// ASSERT(myPreLogTerm != SYNC_TERM_INVALID);
|
|
||||||
if (myPreLogTerm == SYNC_TERM_INVALID) {
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, "reject, pre-term invalid");
|
|
||||||
goto _SEND_RESPONSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (myPreLogTerm != pMsg->prevLogTerm) {
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, "reject, pre-term not match");
|
|
||||||
goto _SEND_RESPONSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// accept
|
|
||||||
pReply->success = true;
|
|
||||||
bool hasAppendEntries = pMsg->dataLen > 0;
|
|
||||||
if (hasAppendEntries) {
|
|
||||||
SSyncRaftEntry* pAppendEntry = syncEntryBuildFromAppendEntries(pMsg);
|
|
||||||
ASSERT(pAppendEntry != NULL);
|
|
||||||
|
|
||||||
SyncIndex appendIndex = pMsg->prevLogIndex + 1;
|
|
||||||
|
|
||||||
LRUHandle* hLocal = NULL;
|
|
||||||
LRUHandle* hAppend = NULL;
|
|
||||||
|
|
||||||
int32_t code = 0;
|
|
||||||
SSyncRaftEntry* pLocalEntry = NULL;
|
|
||||||
SLRUCache* pCache = ths->pLogStore->pCache;
|
|
||||||
hLocal = taosLRUCacheLookup(pCache, &appendIndex, sizeof(appendIndex));
|
|
||||||
if (hLocal) {
|
|
||||||
pLocalEntry = (SSyncRaftEntry*)taosLRUCacheValue(pCache, hLocal);
|
|
||||||
code = 0;
|
|
||||||
|
|
||||||
ths->pLogStore->cacheHit++;
|
|
||||||
sNTrace(ths, "hit cache index:%" PRId64 ", bytes:%u, %p", appendIndex, pLocalEntry->bytes, pLocalEntry);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ths->pLogStore->cacheMiss++;
|
|
||||||
sNTrace(ths, "miss cache index:%" PRId64, appendIndex);
|
|
||||||
|
|
||||||
code = ths->pLogStore->syncLogGetEntry(ths->pLogStore, appendIndex, &pLocalEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code == 0) {
|
|
||||||
// get local entry success
|
|
||||||
|
|
||||||
if (pLocalEntry->term == pAppendEntry->term) {
|
|
||||||
// do nothing
|
|
||||||
sNTrace(ths, "log match, do nothing, index:%" PRId64, appendIndex);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// truncate
|
|
||||||
code = ths->pLogStore->syncLogTruncate(ths->pLogStore, appendIndex);
|
|
||||||
if (code != 0) {
|
|
||||||
char logBuf[128];
|
|
||||||
snprintf(logBuf, sizeof(logBuf), "ignore, truncate error, append-index:%" PRId64, appendIndex);
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, logBuf);
|
|
||||||
|
|
||||||
if (hLocal) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, hLocal, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pLocalEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hAppend) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, hAppend, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pAppendEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto _IGNORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(pAppendEntry->index == appendIndex);
|
|
||||||
|
|
||||||
// append
|
|
||||||
code = ths->pLogStore->syncLogAppendEntry(ths->pLogStore, pAppendEntry, false);
|
|
||||||
if (code != 0) {
|
|
||||||
char logBuf[128];
|
|
||||||
snprintf(logBuf, sizeof(logBuf), "ignore, append error, append-index:%" PRId64, appendIndex);
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, logBuf);
|
|
||||||
|
|
||||||
if (hLocal) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, hLocal, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pLocalEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hAppend) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, hAppend, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pAppendEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto _IGNORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
syncCacheEntry(ths->pLogStore, pAppendEntry, &hAppend);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (terrno == TSDB_CODE_WAL_LOG_NOT_EXIST) {
|
|
||||||
// log not exist
|
|
||||||
|
|
||||||
// truncate
|
|
||||||
code = ths->pLogStore->syncLogTruncate(ths->pLogStore, appendIndex);
|
|
||||||
if (code != 0) {
|
|
||||||
char logBuf[128];
|
|
||||||
snprintf(logBuf, sizeof(logBuf), "ignore, log not exist, truncate error, append-index:%" PRId64, appendIndex);
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, logBuf);
|
|
||||||
|
|
||||||
syncEntryDestroy(pLocalEntry);
|
|
||||||
syncEntryDestroy(pAppendEntry);
|
|
||||||
goto _IGNORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// append
|
|
||||||
code = ths->pLogStore->syncLogAppendEntry(ths->pLogStore, pAppendEntry, false);
|
|
||||||
if (code != 0) {
|
|
||||||
char logBuf[128];
|
|
||||||
snprintf(logBuf, sizeof(logBuf), "ignore, log not exist, append error, append-index:%" PRId64, appendIndex);
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, logBuf);
|
|
||||||
|
|
||||||
if (hLocal) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, hLocal, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pLocalEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hAppend) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, hAppend, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pAppendEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto _IGNORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
syncCacheEntry(ths->pLogStore, pAppendEntry, &hAppend);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// get local entry success
|
|
||||||
char logBuf[128];
|
|
||||||
snprintf(logBuf, sizeof(logBuf), "ignore, get local entry error, append-index:%" PRId64 " err:%d", appendIndex,
|
|
||||||
terrno);
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, logBuf);
|
|
||||||
|
|
||||||
if (hLocal) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, hLocal, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pLocalEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hAppend) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, hAppend, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pAppendEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto _IGNORE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update match index
|
|
||||||
pReply->matchIndex = pAppendEntry->index;
|
|
||||||
|
|
||||||
if (hLocal) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, hLocal, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pLocalEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hAppend) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, hAppend, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pAppendEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// no append entries, do nothing
|
|
||||||
// maybe has extra entries, no harm
|
|
||||||
|
|
||||||
// update match index
|
|
||||||
pReply->matchIndex = pMsg->prevLogIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maybe update commit index, leader notice me
|
|
||||||
syncNodeFollowerCommit(ths, pMsg->commitIndex);
|
|
||||||
|
|
||||||
syncLogRecvAppendEntries(ths, pMsg, "accept");
|
|
||||||
goto _SEND_RESPONSE;
|
|
||||||
|
|
||||||
_IGNORE:
|
|
||||||
rpcFreeCont(rpcRsp.pCont);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
_SEND_RESPONSE:
|
|
||||||
// msg event log
|
|
||||||
syncLogSendAppendEntriesReply(ths, pReply, "");
|
|
||||||
|
|
||||||
// send response
|
|
||||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcRsp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -89,63 +89,3 @@ int32_t syncNodeOnAppendEntriesReply(SSyncNode* ths, const SRpcMsg* pRpcMsg) {
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncNodeOnAppendEntriesReplyOld(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {
|
|
||||||
int32_t ret = 0;
|
|
||||||
|
|
||||||
// if already drop replica, do not process
|
|
||||||
if (!syncNodeInRaftGroup(ths, &(pMsg->srcId))) {
|
|
||||||
syncLogRecvAppendEntriesReply(ths, pMsg, "not in my config");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// drop stale response
|
|
||||||
if (pMsg->term < ths->raftStore.currentTerm) {
|
|
||||||
syncLogRecvAppendEntriesReply(ths, pMsg, "drop stale response");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ths->state == TAOS_SYNC_STATE_LEADER) {
|
|
||||||
if (pMsg->term > ths->raftStore.currentTerm) {
|
|
||||||
syncLogRecvAppendEntriesReply(ths, pMsg, "error term");
|
|
||||||
syncNodeStepDown(ths, pMsg->term);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(pMsg->term == ths->raftStore.currentTerm);
|
|
||||||
|
|
||||||
if (pMsg->success) {
|
|
||||||
SyncIndex oldMatchIndex = syncIndexMgrGetIndex(ths->pMatchIndex, &(pMsg->srcId));
|
|
||||||
if (pMsg->matchIndex > oldMatchIndex) {
|
|
||||||
syncIndexMgrSetIndex(ths->pMatchIndex, &(pMsg->srcId), pMsg->matchIndex);
|
|
||||||
syncMaybeAdvanceCommitIndex(ths);
|
|
||||||
|
|
||||||
// maybe update minMatchIndex
|
|
||||||
ths->minMatchIndex = syncMinMatchIndex(ths);
|
|
||||||
}
|
|
||||||
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), pMsg->matchIndex + 1);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
SyncIndex nextIndex = syncIndexMgrGetIndex(ths->pNextIndex, &(pMsg->srcId));
|
|
||||||
if (nextIndex > SYNC_INDEX_BEGIN) {
|
|
||||||
--nextIndex;
|
|
||||||
}
|
|
||||||
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), nextIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// send next append entries
|
|
||||||
SPeerState* pState = syncNodeGetPeerState(ths, &(pMsg->srcId));
|
|
||||||
ASSERT(pState != NULL);
|
|
||||||
|
|
||||||
if (pMsg->lastSendIndex == pState->lastSendIndex) {
|
|
||||||
int64_t timeNow = taosGetTimestampMs();
|
|
||||||
int64_t elapsed = timeNow - pState->lastSendTime;
|
|
||||||
sNTrace(ths, "sync-append-entries rtt elapsed:%" PRId64 ", index:%" PRId64, elapsed, pState->lastSendIndex);
|
|
||||||
|
|
||||||
syncNodeReplicateOne(ths, &(pMsg->srcId), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
syncLogRecvAppendEntriesReply(ths, pMsg, "process");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -43,148 +43,6 @@
|
||||||
// IN commitIndex' = [commitIndex EXCEPT ![i] = newCommitIndex]
|
// IN commitIndex' = [commitIndex EXCEPT ![i] = newCommitIndex]
|
||||||
// /\ UNCHANGED <<messages, serverVars, candidateVars, leaderVars, log>>
|
// /\ UNCHANGED <<messages, serverVars, candidateVars, leaderVars, log>>
|
||||||
//
|
//
|
||||||
void syncOneReplicaAdvance(SSyncNode* pSyncNode) {
|
|
||||||
ASSERT(false && "deprecated");
|
|
||||||
if (pSyncNode == NULL) {
|
|
||||||
sError("pSyncNode is NULL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pSyncNode->state != TAOS_SYNC_STATE_LEADER) {
|
|
||||||
sNError(pSyncNode, "not leader, can not advance commit index");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pSyncNode->replicaNum != 1) {
|
|
||||||
sNError(pSyncNode, "not one replica, can not advance commit index");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// advance commit index to snapshot first
|
|
||||||
SSnapshot snapshot;
|
|
||||||
pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot);
|
|
||||||
if (snapshot.lastApplyIndex > 0 && snapshot.lastApplyIndex > pSyncNode->commitIndex) {
|
|
||||||
SyncIndex commitBegin = pSyncNode->commitIndex;
|
|
||||||
SyncIndex commitEnd = snapshot.lastApplyIndex;
|
|
||||||
pSyncNode->commitIndex = snapshot.lastApplyIndex;
|
|
||||||
sNTrace(pSyncNode, "commit by snapshot from index:%" PRId64 " to index:%" PRId64, commitBegin, commitEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// advance commit index as large as possible
|
|
||||||
SyncIndex lastIndex = syncNodeGetLastIndex(pSyncNode);
|
|
||||||
if (lastIndex > pSyncNode->commitIndex) {
|
|
||||||
sNTrace(pSyncNode, "commit by wal from index:%" PRId64 " to index:%" PRId64, pSyncNode->commitIndex + 1, lastIndex);
|
|
||||||
pSyncNode->commitIndex = lastIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// call back Wal
|
|
||||||
SyncIndex walCommitVer = logStoreWalCommitVer(pSyncNode->pLogStore);
|
|
||||||
if (pSyncNode->commitIndex > walCommitVer) {
|
|
||||||
pSyncNode->pLogStore->syncLogUpdateCommitIndex(pSyncNode->pLogStore, pSyncNode->commitIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void syncMaybeAdvanceCommitIndex(SSyncNode* pSyncNode) {
|
|
||||||
ASSERTS(false, "deprecated");
|
|
||||||
if (pSyncNode == NULL) {
|
|
||||||
sError("pSyncNode is NULL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pSyncNode->state != TAOS_SYNC_STATE_LEADER) {
|
|
||||||
sNError(pSyncNode, "not leader, can not advance commit index");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// advance commit index to sanpshot first
|
|
||||||
SSnapshot snapshot;
|
|
||||||
pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot);
|
|
||||||
if (snapshot.lastApplyIndex > 0 && snapshot.lastApplyIndex > pSyncNode->commitIndex) {
|
|
||||||
SyncIndex commitBegin = pSyncNode->commitIndex;
|
|
||||||
SyncIndex commitEnd = snapshot.lastApplyIndex;
|
|
||||||
pSyncNode->commitIndex = snapshot.lastApplyIndex;
|
|
||||||
sNTrace(pSyncNode, "commit by snapshot from index:%" PRId64 " to index:%" PRId64, commitBegin, commitEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update commit index
|
|
||||||
SyncIndex newCommitIndex = pSyncNode->commitIndex;
|
|
||||||
for (SyncIndex index = syncNodeGetLastIndex(pSyncNode); index > pSyncNode->commitIndex; --index) {
|
|
||||||
bool agree = syncAgree(pSyncNode, index);
|
|
||||||
|
|
||||||
if (agree) {
|
|
||||||
// term
|
|
||||||
SSyncRaftEntry* pEntry = NULL;
|
|
||||||
SLRUCache* pCache = pSyncNode->pLogStore->pCache;
|
|
||||||
LRUHandle* h = taosLRUCacheLookup(pCache, &index, sizeof(index));
|
|
||||||
if (h) {
|
|
||||||
pEntry = (SSyncRaftEntry*)taosLRUCacheValue(pCache, h);
|
|
||||||
|
|
||||||
pSyncNode->pLogStore->cacheHit++;
|
|
||||||
sNTrace(pSyncNode, "hit cache index:%" PRId64 ", bytes:%u, %p", index, pEntry->bytes, pEntry);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
pSyncNode->pLogStore->cacheMiss++;
|
|
||||||
sNTrace(pSyncNode, "miss cache index:%" PRId64, index);
|
|
||||||
|
|
||||||
int32_t code = pSyncNode->pLogStore->syncLogGetEntry(pSyncNode->pLogStore, index, &pEntry);
|
|
||||||
if (code != 0) {
|
|
||||||
sNError(pSyncNode, "advance commit index error, read wal index:%" PRId64, index);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// cannot commit, even if quorum agree. need check term!
|
|
||||||
if (pEntry->term <= pSyncNode->raftStore.currentTerm) {
|
|
||||||
// update commit index
|
|
||||||
newCommitIndex = index;
|
|
||||||
|
|
||||||
if (h) {
|
|
||||||
taosLRUCacheRelease(pCache, h, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
sNTrace(pSyncNode, "can not commit due to term not equal, index:%" PRId64 ", term:%" PRIu64, pEntry->index,
|
|
||||||
pEntry->term);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h) {
|
|
||||||
taosLRUCacheRelease(pCache, h, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// advance commit index as large as possible
|
|
||||||
SyncIndex walCommitVer = logStoreWalCommitVer(pSyncNode->pLogStore);
|
|
||||||
if (walCommitVer > newCommitIndex) {
|
|
||||||
newCommitIndex = walCommitVer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maybe execute fsm
|
|
||||||
if (newCommitIndex > pSyncNode->commitIndex) {
|
|
||||||
SyncIndex beginIndex = pSyncNode->commitIndex + 1;
|
|
||||||
SyncIndex endIndex = newCommitIndex;
|
|
||||||
|
|
||||||
// update commit index
|
|
||||||
pSyncNode->commitIndex = newCommitIndex;
|
|
||||||
|
|
||||||
// call back Wal
|
|
||||||
pSyncNode->pLogStore->syncLogUpdateCommitIndex(pSyncNode->pLogStore, pSyncNode->commitIndex);
|
|
||||||
|
|
||||||
// execute fsm
|
|
||||||
if (pSyncNode != NULL && pSyncNode->pFsm != NULL) {
|
|
||||||
int32_t code = syncNodeDoCommit(pSyncNode, beginIndex, endIndex, pSyncNode->state);
|
|
||||||
if (code != 0) {
|
|
||||||
sNError(pSyncNode, "advance commit index error, do commit begin:%" PRId64 ", end:%" PRId64, beginIndex,
|
|
||||||
endIndex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool syncAgreeIndex(SSyncNode* pSyncNode, SRaftId* pRaftId, SyncIndex index) {
|
bool syncAgreeIndex(SSyncNode* pSyncNode, SRaftId* pRaftId, SyncIndex index) {
|
||||||
// I am leader, I agree
|
// I am leader, I agree
|
||||||
|
@ -210,83 +68,7 @@ static inline int64_t syncNodeAbs64(int64_t a, int64_t b) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncNodeDynamicQuorum(const SSyncNode* pSyncNode) {
|
int32_t syncNodeDynamicQuorum(const SSyncNode* pSyncNode) { return pSyncNode->quorum; }
|
||||||
return pSyncNode->quorum;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
int32_t quorum = 1; // self
|
|
||||||
|
|
||||||
int64_t timeNow = taosGetTimestampMs();
|
|
||||||
for (int i = 0; i < pSyncNode->peersNum; ++i) {
|
|
||||||
int64_t peerStartTime = syncIndexMgrGetStartTime(pSyncNode->pNextIndex, &(pSyncNode->peersId)[i]);
|
|
||||||
int64_t peerRecvTime = syncIndexMgrGetRecvTime(pSyncNode->pNextIndex, &(pSyncNode->peersId)[i]);
|
|
||||||
SyncIndex peerMatchIndex = syncIndexMgrGetIndex(pSyncNode->pMatchIndex, &(pSyncNode->peersId)[i]);
|
|
||||||
|
|
||||||
int64_t recvTimeDiff = TABS(peerRecvTime - timeNow);
|
|
||||||
int64_t startTimeDiff = TABS(peerStartTime - pSyncNode->startTime);
|
|
||||||
int64_t logDiff = TABS(peerMatchIndex - syncNodeGetLastIndex(pSyncNode));
|
|
||||||
|
|
||||||
/*
|
|
||||||
int64_t recvTimeDiff = syncNodeAbs64(peerRecvTime, timeNow);
|
|
||||||
int64_t startTimeDiff = syncNodeAbs64(peerStartTime, pSyncNode->startTime);
|
|
||||||
int64_t logDiff = syncNodeAbs64(peerMatchIndex, syncNodeGetLastIndex(pSyncNode));
|
|
||||||
*/
|
|
||||||
|
|
||||||
int32_t addQuorum = 0;
|
|
||||||
|
|
||||||
if (recvTimeDiff < SYNC_MAX_RECV_TIME_RANGE_MS) {
|
|
||||||
if (startTimeDiff < SYNC_MAX_START_TIME_RANGE_MS) {
|
|
||||||
addQuorum = 1;
|
|
||||||
} else {
|
|
||||||
if (logDiff < SYNC_ADD_QUORUM_COUNT) {
|
|
||||||
addQuorum = 1;
|
|
||||||
} else {
|
|
||||||
addQuorum = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addQuorum = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (recvTimeDiff < SYNC_MAX_RECV_TIME_RANGE_MS) {
|
|
||||||
addQuorum = 1;
|
|
||||||
} else {
|
|
||||||
addQuorum = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startTimeDiff > SYNC_MAX_START_TIME_RANGE_MS) {
|
|
||||||
addQuorum = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
quorum += addQuorum;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(quorum <= pSyncNode->replicaNum);
|
|
||||||
|
|
||||||
if (quorum < pSyncNode->quorum) {
|
|
||||||
quorum = pSyncNode->quorum;
|
|
||||||
}
|
|
||||||
|
|
||||||
return quorum;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
bool syncAgree(SSyncNode* pSyncNode, SyncIndex index) {
|
|
||||||
int agreeCount = 0;
|
|
||||||
for (int i = 0; i < pSyncNode->replicaNum; ++i) {
|
|
||||||
if (syncAgreeIndex(pSyncNode, &(pSyncNode->replicasId[i]), index)) {
|
|
||||||
++agreeCount;
|
|
||||||
}
|
|
||||||
if (agreeCount >= syncNodeDynamicQuorum(pSyncNode)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool syncNodeAgreedUpon(SSyncNode* pNode, SyncIndex index) {
|
bool syncNodeAgreedUpon(SSyncNode* pNode, SyncIndex index) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
|
@ -43,7 +43,10 @@ static int32_t syncNodeRequestVotePeers(SSyncNode* pNode) {
|
||||||
for (int i = 0; i < pNode->peersNum; ++i) {
|
for (int i = 0; i < pNode->peersNum; ++i) {
|
||||||
SRpcMsg rpcMsg = {0};
|
SRpcMsg rpcMsg = {0};
|
||||||
ret = syncBuildRequestVote(&rpcMsg, pNode->vgId);
|
ret = syncBuildRequestVote(&rpcMsg, pNode->vgId);
|
||||||
ASSERT(ret == 0);
|
if (ret < 0) {
|
||||||
|
sError("vgId:%d, failed to build request-vote msg since %s", pNode->vgId, terrstr());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
SyncRequestVote* pMsg = rpcMsg.pCont;
|
SyncRequestVote* pMsg = rpcMsg.pCont;
|
||||||
pMsg->srcId = pNode->myRaftId;
|
pMsg->srcId = pNode->myRaftId;
|
||||||
|
@ -51,13 +54,18 @@ static int32_t syncNodeRequestVotePeers(SSyncNode* pNode) {
|
||||||
pMsg->term = pNode->raftStore.currentTerm;
|
pMsg->term = pNode->raftStore.currentTerm;
|
||||||
|
|
||||||
ret = syncNodeGetLastIndexTerm(pNode, &pMsg->lastLogIndex, &pMsg->lastLogTerm);
|
ret = syncNodeGetLastIndexTerm(pNode, &pMsg->lastLogIndex, &pMsg->lastLogTerm);
|
||||||
ASSERT(ret == 0);
|
if (ret < 0) {
|
||||||
|
sError("vgId:%d, failed to get index and term of last log since %s", pNode->vgId, terrstr());
|
||||||
ret = syncNodeSendMsgById(&pNode->peersId[i], pNode, &rpcMsg);
|
continue;
|
||||||
ASSERT(ret == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
ret = syncNodeSendMsgById(&pNode->peersId[i], pNode, &rpcMsg);
|
||||||
|
if (ret < 0) {
|
||||||
|
sError("vgId:%d, failed to send msg to peerId:%" PRId64, pNode->vgId, pNode->peersId[i].addr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncNodeElect(SSyncNode* pSyncNode) {
|
int32_t syncNodeElect(SSyncNode* pSyncNode) {
|
||||||
|
|
|
@ -292,8 +292,6 @@ int32_t syncBeginSnapshot(int64_t rid, int64_t lastApplyIndex) {
|
||||||
goto _DEL_WAL;
|
goto _DEL_WAL;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
lastApplyIndex -= SYNC_VNODE_LOG_RETENTION;
|
|
||||||
|
|
||||||
SyncIndex beginIndex = pSyncNode->pLogStore->syncLogBeginIndex(pSyncNode->pLogStore);
|
SyncIndex beginIndex = pSyncNode->pLogStore->syncLogBeginIndex(pSyncNode->pLogStore);
|
||||||
SyncIndex endIndex = pSyncNode->pLogStore->syncLogEndIndex(pSyncNode->pLogStore);
|
SyncIndex endIndex = pSyncNode->pLogStore->syncLogEndIndex(pSyncNode->pLogStore);
|
||||||
bool isEmpty = pSyncNode->pLogStore->syncLogIsEmpty(pSyncNode->pLogStore);
|
bool isEmpty = pSyncNode->pLogStore->syncLogIsEmpty(pSyncNode->pLogStore);
|
||||||
|
@ -308,6 +306,8 @@ int32_t syncBeginSnapshot(int64_t rid, int64_t lastApplyIndex) {
|
||||||
if (pSyncNode->replicaNum > 1) {
|
if (pSyncNode->replicaNum > 1) {
|
||||||
// multi replicas
|
// multi replicas
|
||||||
|
|
||||||
|
lastApplyIndex = TMAX(lastApplyIndex - SYNC_VNODE_LOG_RETENTION, beginIndex - 1);
|
||||||
|
|
||||||
if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
||||||
pSyncNode->minMatchIndex = syncMinMatchIndex(pSyncNode);
|
pSyncNode->minMatchIndex = syncMinMatchIndex(pSyncNode);
|
||||||
|
|
||||||
|
@ -586,78 +586,6 @@ SSyncState syncGetState(int64_t rid) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
int32_t syncGetSnapshotByIndex(int64_t rid, SyncIndex index, SSnapshot* pSnapshot) {
|
|
||||||
if (index < SYNC_INDEX_BEGIN) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSyncNode* pSyncNode = syncNodeAcquire(rid);
|
|
||||||
if (pSyncNode == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ASSERT(rid == pSyncNode->rid);
|
|
||||||
|
|
||||||
SSyncRaftEntry* pEntry = NULL;
|
|
||||||
int32_t code = pSyncNode->pLogStore->syncLogGetEntry(pSyncNode->pLogStore, index, &pEntry);
|
|
||||||
if (code != 0) {
|
|
||||||
if (pEntry != NULL) {
|
|
||||||
syncEntryDestroy(pEntry);
|
|
||||||
}
|
|
||||||
syncNodeRelease(pSyncNode);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ASSERT(pEntry != NULL);
|
|
||||||
|
|
||||||
pSnapshot->data = NULL;
|
|
||||||
pSnapshot->lastApplyIndex = index;
|
|
||||||
pSnapshot->lastApplyTerm = pEntry->term;
|
|
||||||
pSnapshot->lastConfigIndex = syncNodeGetSnapshotConfigIndex(pSyncNode, index);
|
|
||||||
|
|
||||||
syncEntryDestroy(pEntry);
|
|
||||||
syncNodeRelease(pSyncNode);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t syncGetSnapshotMeta(int64_t rid, struct SSnapshotMeta* sMeta) {
|
|
||||||
SSyncNode* pSyncNode = syncNodeAcquire(rid);
|
|
||||||
if (pSyncNode == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ASSERT(rid == pSyncNode->rid);
|
|
||||||
sMeta->lastConfigIndex = pSyncNode->raftCfg.lastConfigIndex;
|
|
||||||
|
|
||||||
sTrace("vgId:%d, get snapshot meta, lastConfigIndex:%" PRId64, pSyncNode->vgId, pSyncNode->raftCfg.lastConfigIndex);
|
|
||||||
|
|
||||||
syncNodeRelease(pSyncNode);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t syncGetSnapshotMetaByIndex(int64_t rid, SyncIndex snapshotIndex, struct SSnapshotMeta* sMeta) {
|
|
||||||
SSyncNode* pSyncNode = syncNodeAcquire(rid);
|
|
||||||
if (pSyncNode == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ASSERT(rid == pSyncNode->rid);
|
|
||||||
|
|
||||||
ASSERT(pSyncNode->raftCfg.configIndexCount >= 1);
|
|
||||||
SyncIndex lastIndex = (pSyncNode->raftCfg.configIndexArr)[0];
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pSyncNode->raftCfg.configIndexCount; ++i) {
|
|
||||||
if ((pSyncNode->raftCfg.configIndexArr)[i] > lastIndex &&
|
|
||||||
(pSyncNode->raftCfg.configIndexArr)[i] <= snapshotIndex) {
|
|
||||||
lastIndex = (pSyncNode->raftCfg.configIndexArr)[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sMeta->lastConfigIndex = lastIndex;
|
|
||||||
sTrace("vgId:%d, get snapshot meta by index:%" PRId64 " lcindex:%" PRId64, pSyncNode->vgId, snapshotIndex,
|
|
||||||
sMeta->lastConfigIndex);
|
|
||||||
|
|
||||||
syncNodeRelease(pSyncNode);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SyncIndex syncNodeGetSnapshotConfigIndex(SSyncNode* pSyncNode, SyncIndex snapshotLastApplyIndex) {
|
SyncIndex syncNodeGetSnapshotConfigIndex(SSyncNode* pSyncNode, SyncIndex snapshotLastApplyIndex) {
|
||||||
ASSERT(pSyncNode->raftCfg.configIndexCount >= 1);
|
ASSERT(pSyncNode->raftCfg.configIndexCount >= 1);
|
||||||
SyncIndex lastIndex = (pSyncNode->raftCfg.configIndexArr)[0];
|
SyncIndex lastIndex = (pSyncNode->raftCfg.configIndexArr)[0];
|
||||||
|
@ -1031,9 +959,12 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) {
|
||||||
pSyncNode->commitIndex = commitIndex;
|
pSyncNode->commitIndex = commitIndex;
|
||||||
sInfo("vgId:%d, sync node commitIndex initialized as %" PRId64, pSyncNode->vgId, pSyncNode->commitIndex);
|
sInfo("vgId:%d, sync node commitIndex initialized as %" PRId64, pSyncNode->vgId, pSyncNode->commitIndex);
|
||||||
|
|
||||||
|
// restore log store on need
|
||||||
if (syncNodeLogStoreRestoreOnNeed(pSyncNode) < 0) {
|
if (syncNodeLogStoreRestoreOnNeed(pSyncNode) < 0) {
|
||||||
|
sError("vgId:%d, failed to restore log store since %s.", pSyncNode->vgId, terrstr());
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// timer ms init
|
// timer ms init
|
||||||
pSyncNode->pingBaseLine = PING_TIMER_MS;
|
pSyncNode->pingBaseLine = PING_TIMER_MS;
|
||||||
pSyncNode->electBaseLine = tsElectInterval;
|
pSyncNode->electBaseLine = tsElectInterval;
|
||||||
|
@ -1096,10 +1027,16 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) {
|
||||||
pSyncNode->changing = false;
|
pSyncNode->changing = false;
|
||||||
|
|
||||||
// replication mgr
|
// replication mgr
|
||||||
syncNodeLogReplMgrInit(pSyncNode);
|
if (syncNodeLogReplMgrInit(pSyncNode) < 0) {
|
||||||
|
sError("vgId:%d, failed to init repl mgr since %s.", pSyncNode->vgId, terrstr());
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
// peer state
|
// peer state
|
||||||
syncNodePeerStateInit(pSyncNode);
|
if (syncNodePeerStateInit(pSyncNode) < 0) {
|
||||||
|
sError("vgId:%d, failed to init peer stat since %s.", pSyncNode->vgId, terrstr());
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// min match index
|
// min match index
|
||||||
|
@ -1194,29 +1131,12 @@ int32_t syncNodeStart(SSyncNode* pSyncNode) {
|
||||||
|
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
ret = syncNodeStartPingTimer(pSyncNode);
|
ret = syncNodeStartPingTimer(pSyncNode);
|
||||||
ASSERT(ret == 0);
|
if (ret != 0) {
|
||||||
|
sError("vgId:%d, failed to start ping timer since %s", pSyncNode->vgId, terrstr());
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncNodeStartOld(SSyncNode* pSyncNode) {
|
|
||||||
// start raft
|
|
||||||
if (pSyncNode->replicaNum == 1) {
|
|
||||||
raftStoreNextTerm(pSyncNode);
|
|
||||||
syncNodeBecomeLeader(pSyncNode, "one replica start");
|
|
||||||
|
|
||||||
// Raft 3.6.2 Committing entries from previous terms
|
|
||||||
syncNodeAppendNoop(pSyncNode);
|
|
||||||
syncMaybeAdvanceCommitIndex(pSyncNode);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
syncNodeBecomeFollower(pSyncNode, "first start");
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ret = 0;
|
|
||||||
ret = syncNodeStartPingTimer(pSyncNode);
|
|
||||||
ASSERT(ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t syncNodeStartStandBy(SSyncNode* pSyncNode) {
|
int32_t syncNodeStartStandBy(SSyncNode* pSyncNode) {
|
||||||
// state change
|
// state change
|
||||||
pSyncNode->state = TAOS_SYNC_STATE_FOLLOWER;
|
pSyncNode->state = TAOS_SYNC_STATE_FOLLOWER;
|
||||||
|
@ -1225,11 +1145,16 @@ int32_t syncNodeStartStandBy(SSyncNode* pSyncNode) {
|
||||||
// reset elect timer, long enough
|
// reset elect timer, long enough
|
||||||
int32_t electMS = TIMER_MAX_MS;
|
int32_t electMS = TIMER_MAX_MS;
|
||||||
int32_t ret = syncNodeRestartElectTimer(pSyncNode, electMS);
|
int32_t ret = syncNodeRestartElectTimer(pSyncNode, electMS);
|
||||||
ASSERT(ret == 0);
|
if (ret < 0) {
|
||||||
|
sError("vgId:%d, failed to restart elect timer since %s", pSyncNode->vgId, terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
ret = syncNodeStartPingTimer(pSyncNode);
|
ret = syncNodeStartPingTimer(pSyncNode);
|
||||||
ASSERT(ret == 0);
|
if (ret < 0) {
|
||||||
|
sError("vgId:%d, failed to start ping timer since %s", pSyncNode->vgId, terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1818,12 +1743,6 @@ void syncNodeBecomeLeader(SSyncNode* pSyncNode, const char* debugStr) {
|
||||||
pSyncNode->leaderCache = pSyncNode->myRaftId;
|
pSyncNode->leaderCache = pSyncNode->myRaftId;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pSyncNode->pNextIndex->replicaNum; ++i) {
|
for (int32_t i = 0; i < pSyncNode->pNextIndex->replicaNum; ++i) {
|
||||||
// maybe overwrite myself, no harm
|
|
||||||
// just do it!
|
|
||||||
|
|
||||||
// pSyncNode->pNextIndex->index[i] = pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore) + 1;
|
|
||||||
|
|
||||||
// maybe wal is deleted
|
|
||||||
SyncIndex lastIndex;
|
SyncIndex lastIndex;
|
||||||
SyncTerm lastTerm;
|
SyncTerm lastTerm;
|
||||||
int32_t code = syncNodeGetLastIndexTerm(pSyncNode, &lastIndex, &lastTerm);
|
int32_t code = syncNodeGetLastIndexTerm(pSyncNode, &lastIndex, &lastTerm);
|
||||||
|
@ -1885,7 +1804,11 @@ void syncNodeBecomeLeader(SSyncNode* pSyncNode, const char* debugStr) {
|
||||||
|
|
||||||
void syncNodeCandidate2Leader(SSyncNode* pSyncNode) {
|
void syncNodeCandidate2Leader(SSyncNode* pSyncNode) {
|
||||||
ASSERT(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE);
|
ASSERT(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE);
|
||||||
ASSERT(voteGrantedMajority(pSyncNode->pVotesGranted));
|
bool granted = voteGrantedMajority(pSyncNode->pVotesGranted);
|
||||||
|
if (!granted) {
|
||||||
|
sError("vgId:%d, not granted by majority.", pSyncNode->vgId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
syncNodeBecomeLeader(pSyncNode, "candidate to leader");
|
syncNodeBecomeLeader(pSyncNode, "candidate to leader");
|
||||||
|
|
||||||
sNTrace(pSyncNode, "state change syncNodeCandidate2Leader");
|
sNTrace(pSyncNode, "state change syncNodeCandidate2Leader");
|
||||||
|
@ -1901,20 +1824,6 @@ void syncNodeCandidate2Leader(SSyncNode* pSyncNode) {
|
||||||
pSyncNode->vgId, pSyncNode->raftStore.currentTerm, pSyncNode->commitIndex, lastIndex);
|
pSyncNode->vgId, pSyncNode->raftStore.currentTerm, pSyncNode->commitIndex, lastIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncNodeCandidate2LeaderOld(SSyncNode* pSyncNode) {
|
|
||||||
ASSERT(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE);
|
|
||||||
ASSERT(voteGrantedMajority(pSyncNode->pVotesGranted));
|
|
||||||
syncNodeBecomeLeader(pSyncNode, "candidate to leader");
|
|
||||||
|
|
||||||
// Raft 3.6.2 Committing entries from previous terms
|
|
||||||
syncNodeAppendNoop(pSyncNode);
|
|
||||||
syncMaybeAdvanceCommitIndex(pSyncNode);
|
|
||||||
|
|
||||||
if (pSyncNode->replicaNum > 1) {
|
|
||||||
syncNodeReplicate(pSyncNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool syncNodeIsMnode(SSyncNode* pSyncNode) { return (pSyncNode->vgId == 1); }
|
bool syncNodeIsMnode(SSyncNode* pSyncNode) { return (pSyncNode->vgId == 1); }
|
||||||
|
|
||||||
int32_t syncNodePeerStateInit(SSyncNode* pSyncNode) {
|
int32_t syncNodePeerStateInit(SSyncNode* pSyncNode) {
|
||||||
|
@ -1960,7 +1869,8 @@ void syncNodeCandidate2Follower(SSyncNode* pSyncNode) {
|
||||||
// need assert
|
// need assert
|
||||||
void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId) {
|
void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId) {
|
||||||
ASSERT(term == pSyncNode->raftStore.currentTerm);
|
ASSERT(term == pSyncNode->raftStore.currentTerm);
|
||||||
ASSERT(!raftStoreHasVoted(pSyncNode));
|
bool voted = raftStoreHasVoted(pSyncNode);
|
||||||
|
ASSERT(!voted);
|
||||||
|
|
||||||
raftStoreVote(pSyncNode, pRaftId);
|
raftStoreVote(pSyncNode, pRaftId);
|
||||||
}
|
}
|
||||||
|
@ -2638,24 +2548,6 @@ int32_t syncNodeOnLocalCmd(SSyncNode* ths, const SRpcMsg* pRpcMsg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncNodeOnLocalCmdOld(SSyncNode* ths, const SRpcMsg* pRpcMsg) {
|
|
||||||
ASSERT(false && "deprecated");
|
|
||||||
SyncLocalCmd* pMsg = pRpcMsg->pCont;
|
|
||||||
syncLogRecvLocalCmd(ths, pMsg, "");
|
|
||||||
|
|
||||||
if (pMsg->cmd == SYNC_LOCAL_CMD_STEP_DOWN) {
|
|
||||||
syncNodeStepDown(ths, pMsg->currentTerm);
|
|
||||||
|
|
||||||
} else if (pMsg->cmd == SYNC_LOCAL_CMD_FOLLOWER_CMT) {
|
|
||||||
syncNodeFollowerCommit(ths, pMsg->commitIndex);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
sError("error local cmd");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TLA+ Spec
|
// TLA+ Spec
|
||||||
// ClientRequest(i, v) ==
|
// ClientRequest(i, v) ==
|
||||||
// /\ state[i] = Leader
|
// /\ state[i] = Leader
|
||||||
|
@ -2700,96 +2592,6 @@ int32_t syncNodeOnClientRequest(SSyncNode* ths, SRpcMsg* pMsg, SyncIndex* pRetIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncNodeOnClientRequestOld(SSyncNode* ths, SRpcMsg* pMsg, SyncIndex* pRetIndex) {
|
|
||||||
sNTrace(ths, "on client request");
|
|
||||||
|
|
||||||
int32_t ret = 0;
|
|
||||||
int32_t code = 0;
|
|
||||||
|
|
||||||
SyncIndex index = ths->pLogStore->syncLogWriteIndex(ths->pLogStore);
|
|
||||||
SyncTerm term = ths->raftStore.currentTerm;
|
|
||||||
SSyncRaftEntry* pEntry;
|
|
||||||
|
|
||||||
if (pMsg->msgType == TDMT_SYNC_CLIENT_REQUEST) {
|
|
||||||
pEntry = syncEntryBuildFromClientRequest(pMsg->pCont, term, index);
|
|
||||||
} else {
|
|
||||||
pEntry = syncEntryBuildFromRpcMsg(pMsg, term, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
LRUHandle* h = NULL;
|
|
||||||
|
|
||||||
if (ths->state == TAOS_SYNC_STATE_LEADER) {
|
|
||||||
// append entry
|
|
||||||
code = ths->pLogStore->syncLogAppendEntry(ths->pLogStore, pEntry, false);
|
|
||||||
if (code != 0) {
|
|
||||||
if (ths->replicaNum == 1) {
|
|
||||||
if (h) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, h, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// del resp mgr, call FpCommitCb
|
|
||||||
SFsmCbMeta cbMeta = {
|
|
||||||
.index = pEntry->index,
|
|
||||||
.lastConfigIndex = SYNC_INDEX_INVALID,
|
|
||||||
.isWeak = pEntry->isWeak,
|
|
||||||
.code = -1,
|
|
||||||
.state = ths->state,
|
|
||||||
.seqNum = pEntry->seqNum,
|
|
||||||
.term = pEntry->term,
|
|
||||||
.currentTerm = ths->raftStore.currentTerm,
|
|
||||||
.flag = 0,
|
|
||||||
};
|
|
||||||
ths->pFsm->FpCommitCb(ths->pFsm, pMsg, &cbMeta);
|
|
||||||
|
|
||||||
if (h) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, h, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
syncCacheEntry(ths->pLogStore, pEntry, &h);
|
|
||||||
|
|
||||||
// if mulit replica, start replicate right now
|
|
||||||
if (ths->replicaNum > 1) {
|
|
||||||
syncNodeReplicate(ths);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if only myself, maybe commit right now
|
|
||||||
if (ths->replicaNum == 1) {
|
|
||||||
if (syncNodeIsMnode(ths)) {
|
|
||||||
syncMaybeAdvanceCommitIndex(ths);
|
|
||||||
} else {
|
|
||||||
syncOneReplicaAdvance(ths);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pRetIndex != NULL) {
|
|
||||||
if (ret == 0 && pEntry != NULL) {
|
|
||||||
*pRetIndex = pEntry->index;
|
|
||||||
} else {
|
|
||||||
*pRetIndex = SYNC_INDEX_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h) {
|
|
||||||
taosLRUCacheRelease(ths->pLogStore->pCache, h, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* syncStr(ESyncState state) {
|
const char* syncStr(ESyncState state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case TAOS_SYNC_STATE_FOLLOWER:
|
case TAOS_SYNC_STATE_FOLLOWER:
|
||||||
|
@ -2894,129 +2696,6 @@ bool syncNodeIsOptimizedOneReplica(SSyncNode* ths, SRpcMsg* pMsg) {
|
||||||
return (ths->replicaNum == 1 && syncUtilUserCommit(pMsg->msgType) && ths->vgId != 1);
|
return (ths->replicaNum == 1 && syncUtilUserCommit(pMsg->msgType) && ths->vgId != 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncNodeDoCommit(SSyncNode* ths, SyncIndex beginIndex, SyncIndex endIndex, uint64_t flag) {
|
|
||||||
ASSERT(false);
|
|
||||||
if (beginIndex > endIndex) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ths == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ths->pFsm != NULL && ths->pFsm->FpGetSnapshotInfo != NULL) {
|
|
||||||
// advance commit index to sanpshot first
|
|
||||||
SSnapshot snapshot = {0};
|
|
||||||
ths->pFsm->FpGetSnapshotInfo(ths->pFsm, &snapshot);
|
|
||||||
if (snapshot.lastApplyIndex >= 0 && snapshot.lastApplyIndex >= beginIndex) {
|
|
||||||
sNTrace(ths, "commit by snapshot from index:%" PRId64 " to index:%" PRId64, beginIndex, snapshot.lastApplyIndex);
|
|
||||||
|
|
||||||
// update begin index
|
|
||||||
beginIndex = snapshot.lastApplyIndex + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t code = 0;
|
|
||||||
ESyncState state = flag;
|
|
||||||
|
|
||||||
sNTrace(ths, "commit by wal from index:%" PRId64 " to index:%" PRId64, beginIndex, endIndex);
|
|
||||||
|
|
||||||
// execute fsm
|
|
||||||
if (ths->pFsm != NULL) {
|
|
||||||
for (SyncIndex i = beginIndex; i <= endIndex; ++i) {
|
|
||||||
if (i != SYNC_INDEX_INVALID) {
|
|
||||||
SSyncRaftEntry* pEntry;
|
|
||||||
SLRUCache* pCache = ths->pLogStore->pCache;
|
|
||||||
LRUHandle* h = taosLRUCacheLookup(pCache, &i, sizeof(i));
|
|
||||||
if (h) {
|
|
||||||
pEntry = (SSyncRaftEntry*)taosLRUCacheValue(pCache, h);
|
|
||||||
|
|
||||||
ths->pLogStore->cacheHit++;
|
|
||||||
sNTrace(ths, "hit cache index:%" PRId64 ", bytes:%u, %p", i, pEntry->bytes, pEntry);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ths->pLogStore->cacheMiss++;
|
|
||||||
sNTrace(ths, "miss cache index:%" PRId64, i);
|
|
||||||
|
|
||||||
code = ths->pLogStore->syncLogGetEntry(ths->pLogStore, i, &pEntry);
|
|
||||||
// ASSERT(code == 0);
|
|
||||||
// ASSERT(pEntry != NULL);
|
|
||||||
if (code != 0 || pEntry == NULL) {
|
|
||||||
sNError(ths, "get log entry error");
|
|
||||||
sFatal("vgId:%d, get log entry %" PRId64 " error when commit since %s", ths->vgId, i, terrstr());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SRpcMsg rpcMsg = {0};
|
|
||||||
syncEntry2OriginalRpc(pEntry, &rpcMsg);
|
|
||||||
|
|
||||||
sTrace("do commit index:%" PRId64 ", type:%s", i, TMSG_INFO(pEntry->msgType));
|
|
||||||
|
|
||||||
// user commit
|
|
||||||
if ((ths->pFsm->FpCommitCb != NULL) && syncUtilUserCommit(pEntry->originalRpcType)) {
|
|
||||||
bool internalExecute = true;
|
|
||||||
if ((ths->replicaNum == 1) && ths->restoreFinish && ths->vgId != 1) {
|
|
||||||
internalExecute = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sNTrace(ths, "user commit index:%" PRId64 ", internal:%d, type:%s", i, internalExecute,
|
|
||||||
TMSG_INFO(pEntry->msgType));
|
|
||||||
|
|
||||||
// execute fsm in apply thread, or execute outside syncPropose
|
|
||||||
if (internalExecute) {
|
|
||||||
SFsmCbMeta cbMeta = {
|
|
||||||
.index = pEntry->index,
|
|
||||||
.lastConfigIndex = syncNodeGetSnapshotConfigIndex(ths, pEntry->index),
|
|
||||||
.isWeak = pEntry->isWeak,
|
|
||||||
.code = 0,
|
|
||||||
.state = ths->state,
|
|
||||||
.seqNum = pEntry->seqNum,
|
|
||||||
.term = pEntry->term,
|
|
||||||
.currentTerm = ths->raftStore.currentTerm,
|
|
||||||
.flag = flag,
|
|
||||||
};
|
|
||||||
|
|
||||||
syncRespMgrGetAndDel(ths->pSyncRespMgr, cbMeta.seqNum, &rpcMsg.info);
|
|
||||||
ths->pFsm->FpCommitCb(ths->pFsm, &rpcMsg, &cbMeta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// execute in pre-commit
|
|
||||||
// leader transfer
|
|
||||||
if (pEntry->originalRpcType == TDMT_SYNC_LEADER_TRANSFER) {
|
|
||||||
code = syncDoLeaderTransfer(ths, &rpcMsg, pEntry);
|
|
||||||
ASSERT(code == 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// restore finish
|
|
||||||
// if only snapshot, a noop entry will be append, so syncLogLastIndex is always ok
|
|
||||||
if (pEntry->index == ths->pLogStore->syncLogLastIndex(ths->pLogStore)) {
|
|
||||||
if (ths->restoreFinish == false) {
|
|
||||||
if (ths->pFsm->FpRestoreFinishCb != NULL) {
|
|
||||||
ths->pFsm->FpRestoreFinishCb(ths->pFsm);
|
|
||||||
}
|
|
||||||
ths->restoreFinish = true;
|
|
||||||
|
|
||||||
int64_t restoreDelay = taosGetTimestampMs() - ths->leaderTime;
|
|
||||||
sNTrace(ths, "restore finish, index:%" PRId64 ", elapsed:%" PRId64 " ms", pEntry->index, restoreDelay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rpcFreeCont(rpcMsg.pCont);
|
|
||||||
if (h) {
|
|
||||||
taosLRUCacheRelease(pCache, h, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool syncNodeInRaftGroup(SSyncNode* ths, SRaftId* pRaftId) {
|
bool syncNodeInRaftGroup(SSyncNode* ths, SRaftId* pRaftId) {
|
||||||
for (int32_t i = 0; i < ths->replicaNum; ++i) {
|
for (int32_t i = 0; i < ths->replicaNum; ++i) {
|
||||||
if (syncUtilSameId(&((ths->replicasId)[i]), pRaftId)) {
|
if (syncUtilSameId(&((ths->replicasId)[i]), pRaftId)) {
|
||||||
|
|
|
@ -830,7 +830,7 @@ int32_t syncLogReplMgrReplicateProbe(SSyncLogReplMgr* pMgr, SSyncNode* pNode, Sy
|
||||||
pMgr->endIndex = index + 1;
|
pMgr->endIndex = index + 1;
|
||||||
|
|
||||||
SSyncLogBuffer* pBuf = pNode->pLogBuf;
|
SSyncLogBuffer* pBuf = pNode->pLogBuf;
|
||||||
sInfo("vgId:%d, probe peer:%" PRIx64 " with msg of index:%" PRId64 " term: %" PRId64 ". mgr (rs:%d): [%" PRId64
|
sTrace("vgId:%d, probe peer:%" PRIx64 " with msg of index:%" PRId64 " term:%" PRId64 ". mgr (rs:%d): [%" PRId64
|
||||||
" %" PRId64 ", %" PRId64 "), buffer: [%" PRId64 " %" PRId64 " %" PRId64 ", %" PRId64 ")",
|
" %" PRId64 ", %" PRId64 "), buffer: [%" PRId64 " %" PRId64 " %" PRId64 ", %" PRId64 ")",
|
||||||
pNode->vgId, pDestId->addr, index, term, pMgr->restored, pMgr->startIndex, pMgr->matchIndex, pMgr->endIndex,
|
pNode->vgId, pDestId->addr, index, term, pMgr->restored, pMgr->startIndex, pMgr->matchIndex, pMgr->endIndex,
|
||||||
pBuf->startIndex, pBuf->commitIndex, pBuf->matchIndex, pBuf->endIndex);
|
pBuf->startIndex, pBuf->commitIndex, pBuf->matchIndex, pBuf->endIndex);
|
||||||
|
@ -945,8 +945,11 @@ int32_t syncNodeLogReplMgrInit(SSyncNode* pNode) {
|
||||||
for (int i = 0; i < TSDB_MAX_REPLICA; i++) {
|
for (int i = 0; i < TSDB_MAX_REPLICA; i++) {
|
||||||
ASSERT(pNode->logReplMgrs[i] == NULL);
|
ASSERT(pNode->logReplMgrs[i] == NULL);
|
||||||
pNode->logReplMgrs[i] = syncLogReplMgrCreate();
|
pNode->logReplMgrs[i] = syncLogReplMgrCreate();
|
||||||
|
if (pNode->logReplMgrs[i] == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
pNode->logReplMgrs[i]->peerId = i;
|
pNode->logReplMgrs[i]->peerId = i;
|
||||||
ASSERTS(pNode->logReplMgrs[i] != NULL, "Out of memory.");
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,92 +48,6 @@
|
||||||
|
|
||||||
int32_t syncNodeMaybeSendAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, SRpcMsg* pRpcMsg);
|
int32_t syncNodeMaybeSendAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, SRpcMsg* pRpcMsg);
|
||||||
|
|
||||||
int32_t syncNodeReplicateOne(SSyncNode* pSyncNode, SRaftId* pDestId, bool snapshot) {
|
|
||||||
ASSERT(false && "deprecated");
|
|
||||||
// next index
|
|
||||||
SyncIndex nextIndex = syncIndexMgrGetIndex(pSyncNode->pNextIndex, pDestId);
|
|
||||||
|
|
||||||
if (snapshot) {
|
|
||||||
// maybe start snapshot
|
|
||||||
SyncIndex logStartIndex = pSyncNode->pLogStore->syncLogBeginIndex(pSyncNode->pLogStore);
|
|
||||||
SyncIndex logEndIndex = pSyncNode->pLogStore->syncLogEndIndex(pSyncNode->pLogStore);
|
|
||||||
if (nextIndex < logStartIndex || nextIndex - 1 > logEndIndex) {
|
|
||||||
sNTrace(pSyncNode, "maybe start snapshot for next-index:%" PRId64 ", start:%" PRId64 ", end:%" PRId64, nextIndex,
|
|
||||||
logStartIndex, logEndIndex);
|
|
||||||
// start snapshot
|
|
||||||
int32_t code = syncNodeStartSnapshot(pSyncNode, pDestId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pre index, pre term
|
|
||||||
SyncIndex preLogIndex = syncNodeGetPreIndex(pSyncNode, nextIndex);
|
|
||||||
SyncTerm preLogTerm = syncNodeGetPreTerm(pSyncNode, nextIndex);
|
|
||||||
|
|
||||||
// prepare entry
|
|
||||||
SRpcMsg rpcMsg = {0};
|
|
||||||
SyncAppendEntries* pMsg = NULL;
|
|
||||||
|
|
||||||
SSyncRaftEntry* pEntry = NULL;
|
|
||||||
SLRUCache* pCache = pSyncNode->pLogStore->pCache;
|
|
||||||
LRUHandle* h = taosLRUCacheLookup(pCache, &nextIndex, sizeof(nextIndex));
|
|
||||||
int32_t code = 0;
|
|
||||||
if (h) {
|
|
||||||
pEntry = (SSyncRaftEntry*)taosLRUCacheValue(pCache, h);
|
|
||||||
code = 0;
|
|
||||||
|
|
||||||
pSyncNode->pLogStore->cacheHit++;
|
|
||||||
sNTrace(pSyncNode, "hit cache index:%" PRId64 ", bytes:%u, %p", nextIndex, pEntry->bytes, pEntry);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
pSyncNode->pLogStore->cacheMiss++;
|
|
||||||
sNTrace(pSyncNode, "miss cache index:%" PRId64, nextIndex);
|
|
||||||
|
|
||||||
code = pSyncNode->pLogStore->syncLogGetEntry(pSyncNode->pLogStore, nextIndex, &pEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code == 0) {
|
|
||||||
ASSERT(pEntry != NULL);
|
|
||||||
|
|
||||||
code = syncBuildAppendEntries(&rpcMsg, (int32_t)(pEntry->bytes), pSyncNode->vgId);
|
|
||||||
ASSERT(code == 0);
|
|
||||||
|
|
||||||
pMsg = rpcMsg.pCont;
|
|
||||||
memcpy(pMsg->data, pEntry, pEntry->bytes);
|
|
||||||
} else {
|
|
||||||
if (terrno == TSDB_CODE_WAL_LOG_NOT_EXIST) {
|
|
||||||
// no entry in log
|
|
||||||
code = syncBuildAppendEntries(&rpcMsg, 0, pSyncNode->vgId);
|
|
||||||
ASSERT(code == 0);
|
|
||||||
|
|
||||||
pMsg = rpcMsg.pCont;
|
|
||||||
} else {
|
|
||||||
sNError(pSyncNode, "replicate to dnode:%d error, next-index:%" PRId64, DID(pDestId), nextIndex);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h) {
|
|
||||||
taosLRUCacheRelease(pCache, h, false);
|
|
||||||
} else {
|
|
||||||
syncEntryDestroy(pEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare msg
|
|
||||||
ASSERT(pMsg != NULL);
|
|
||||||
pMsg->srcId = pSyncNode->myRaftId;
|
|
||||||
pMsg->destId = *pDestId;
|
|
||||||
pMsg->term = pSyncNode->raftStore.currentTerm;
|
|
||||||
pMsg->prevLogIndex = preLogIndex;
|
|
||||||
pMsg->prevLogTerm = preLogTerm;
|
|
||||||
pMsg->commitIndex = pSyncNode->commitIndex;
|
|
||||||
pMsg->privateTerm = 0;
|
|
||||||
// pMsg->privateTerm = syncIndexMgrGetTerm(pSyncNode->pNextIndex, pDestId);
|
|
||||||
|
|
||||||
// send msg
|
|
||||||
syncNodeMaybeSendAppendEntries(pSyncNode, pDestId, &rpcMsg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t syncNodeReplicate(SSyncNode* pNode) {
|
int32_t syncNodeReplicate(SSyncNode* pNode) {
|
||||||
SSyncLogBuffer* pBuf = pNode->pLogBuf;
|
SSyncLogBuffer* pBuf = pNode->pLogBuf;
|
||||||
taosThreadMutexLock(&pBuf->mutex);
|
taosThreadMutexLock(&pBuf->mutex);
|
||||||
|
@ -156,25 +70,6 @@ int32_t syncNodeReplicateWithoutLock(SSyncNode* pNode) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncNodeReplicateOld(SSyncNode* pSyncNode) {
|
|
||||||
if (pSyncNode->state != TAOS_SYNC_STATE_LEADER) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sNTrace(pSyncNode, "do replicate");
|
|
||||||
|
|
||||||
int32_t ret = 0;
|
|
||||||
for (int i = 0; i < pSyncNode->peersNum; ++i) {
|
|
||||||
SRaftId* pDestId = &(pSyncNode->peersId[i]);
|
|
||||||
ret = syncNodeReplicateOne(pSyncNode, pDestId, true);
|
|
||||||
if (ret != 0) {
|
|
||||||
sError("vgId:%d, do append entries error for dnode:%d", pSyncNode->vgId, DID(pDestId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t syncNodeSendAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, SRpcMsg* pRpcMsg) {
|
int32_t syncNodeSendAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, SRpcMsg* pRpcMsg) {
|
||||||
SyncAppendEntries* pMsg = pRpcMsg->pCont;
|
SyncAppendEntries* pMsg = pRpcMsg->pCont;
|
||||||
pMsg->destId = *destRaftId;
|
pMsg->destId = *destRaftId;
|
||||||
|
@ -182,39 +77,6 @@ int32_t syncNodeSendAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftI
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t syncNodeSendAppendEntriesOld(SSyncNode* pSyncNode, const SRaftId* destRaftId, SRpcMsg* pRpcMsg) {
|
|
||||||
int32_t ret = 0;
|
|
||||||
SyncAppendEntries* pMsg = pRpcMsg->pCont;
|
|
||||||
if (pMsg == NULL) {
|
|
||||||
sError("vgId:%d, sync-append-entries msg is NULL", pSyncNode->vgId);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SPeerState* pState = syncNodeGetPeerState(pSyncNode, destRaftId);
|
|
||||||
if (pState == NULL) {
|
|
||||||
sError("vgId:%d, replica maybe dropped", pSyncNode->vgId);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// save index, otherwise pMsg will be free by rpc
|
|
||||||
SyncIndex saveLastSendIndex = pState->lastSendIndex;
|
|
||||||
bool update = false;
|
|
||||||
if (pMsg->dataLen > 0) {
|
|
||||||
saveLastSendIndex = pMsg->prevLogIndex + 1;
|
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
syncLogSendAppendEntries(pSyncNode, pMsg, "");
|
|
||||||
syncNodeSendMsgById(destRaftId, pSyncNode, pRpcMsg);
|
|
||||||
|
|
||||||
if (update) {
|
|
||||||
pState->lastSendIndex = saveLastSendIndex;
|
|
||||||
pState->lastSendTime = taosGetTimestampMs();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t syncNodeMaybeSendAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, SRpcMsg* pRpcMsg) {
|
int32_t syncNodeMaybeSendAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, SRpcMsg* pRpcMsg) {
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
SyncAppendEntries* pMsg = pRpcMsg->pCont;
|
SyncAppendEntries* pMsg = pRpcMsg->pCont;
|
||||||
|
|
|
@ -112,7 +112,7 @@ int32_t snapshotSenderStart(SSyncSnapshotSender *pSender) {
|
||||||
pMsg->lastConfigIndex = pSender->snapshot.lastConfigIndex;
|
pMsg->lastConfigIndex = pSender->snapshot.lastConfigIndex;
|
||||||
pMsg->lastConfig = pSender->lastConfig;
|
pMsg->lastConfig = pSender->lastConfig;
|
||||||
pMsg->startTime = pSender->startTime;
|
pMsg->startTime = pSender->startTime;
|
||||||
pMsg->seq = SYNC_SNAPSHOT_SEQ_PRE_SNAPSHOT;
|
pMsg->seq = SYNC_SNAPSHOT_SEQ_PREP_SNAPSHOT;
|
||||||
|
|
||||||
// event log
|
// event log
|
||||||
syncLogSendSyncSnapshotSend(pSender->pSyncNode, pMsg, "snapshot sender start");
|
syncLogSendSyncSnapshotSend(pSender->pSyncNode, pMsg, "snapshot sender start");
|
||||||
|
@ -379,7 +379,7 @@ void snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncSnapshotSend *p
|
||||||
}
|
}
|
||||||
|
|
||||||
pReceiver->start = true;
|
pReceiver->start = true;
|
||||||
pReceiver->ack = SYNC_SNAPSHOT_SEQ_PRE_SNAPSHOT;
|
pReceiver->ack = SYNC_SNAPSHOT_SEQ_PREP_SNAPSHOT;
|
||||||
pReceiver->term = pReceiver->pSyncNode->raftStore.currentTerm;
|
pReceiver->term = pReceiver->pSyncNode->raftStore.currentTerm;
|
||||||
pReceiver->fromId = pPreMsg->srcId;
|
pReceiver->fromId = pPreMsg->srcId;
|
||||||
pReceiver->startTime = pPreMsg->startTime;
|
pReceiver->startTime = pPreMsg->startTime;
|
||||||
|
@ -510,16 +510,8 @@ SyncIndex syncNodeGetSnapBeginIndex(SSyncNode *ths) {
|
||||||
SSyncLogStoreData *pData = ths->pLogStore->data;
|
SSyncLogStoreData *pData = ths->pLogStore->data;
|
||||||
SWal *pWal = pData->pWal;
|
SWal *pWal = pData->pWal;
|
||||||
|
|
||||||
bool isEmpty = ths->pLogStore->syncLogIsEmpty(ths->pLogStore);
|
|
||||||
int64_t walCommitVer = walGetCommittedVer(pWal);
|
int64_t walCommitVer = walGetCommittedVer(pWal);
|
||||||
|
snapStart = TMAX(ths->commitIndex, walCommitVer) + 1;
|
||||||
if (!isEmpty && ths->commitIndex != walCommitVer) {
|
|
||||||
sNError(ths, "commit not same, wal-commit:%" PRId64 ", commit:%" PRId64 ", ignore", walCommitVer,
|
|
||||||
ths->commitIndex);
|
|
||||||
snapStart = walCommitVer + 1;
|
|
||||||
} else {
|
|
||||||
snapStart = ths->commitIndex + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sNInfo(ths, "snapshot begin index is %" PRId64, snapStart);
|
sNInfo(ths, "snapshot begin index is %" PRId64, snapStart);
|
||||||
}
|
}
|
||||||
|
@ -527,7 +519,7 @@ SyncIndex syncNodeGetSnapBeginIndex(SSyncNode *ths) {
|
||||||
return snapStart;
|
return snapStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t syncNodeOnSnapshotPre(SSyncNode *pSyncNode, SyncSnapshotSend *pMsg) {
|
static int32_t syncNodeOnSnapshotPrep(SSyncNode *pSyncNode, SyncSnapshotSend *pMsg) {
|
||||||
SSyncSnapshotReceiver *pReceiver = pSyncNode->pNewNodeReceiver;
|
SSyncSnapshotReceiver *pReceiver = pSyncNode->pNewNodeReceiver;
|
||||||
int64_t timeNow = taosGetTimestampMs();
|
int64_t timeNow = taosGetTimestampMs();
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
|
@ -565,7 +557,7 @@ _START_RECEIVER:
|
||||||
} else {
|
} else {
|
||||||
// waiting for clock match
|
// waiting for clock match
|
||||||
while (timeNow < pMsg->startTime) {
|
while (timeNow < pMsg->startTime) {
|
||||||
sRInfo(pReceiver, "snapshot receiver pre waitting for true time, now:%" PRId64 ", stime:%" PRId64, timeNow,
|
sRInfo(pReceiver, "snapshot receiver pre waitting for true time, now:%" PRId64 ", startTime:%" PRId64, timeNow,
|
||||||
pMsg->startTime);
|
pMsg->startTime);
|
||||||
taosMsleep(10);
|
taosMsleep(10);
|
||||||
timeNow = taosGetTimestampMs();
|
timeNow = taosGetTimestampMs();
|
||||||
|
@ -765,7 +757,7 @@ static int32_t syncNodeOnSnapshotEnd(SSyncNode *pSyncNode, SyncSnapshotSend *pMs
|
||||||
|
|
||||||
// receiver on message
|
// receiver on message
|
||||||
//
|
//
|
||||||
// condition 1, recv SYNC_SNAPSHOT_SEQ_PRE_SNAPSHOT
|
// condition 1, recv SYNC_SNAPSHOT_SEQ_PREP_SNAPSHOT
|
||||||
// if receiver already start
|
// if receiver already start
|
||||||
// if sender.start-time > receiver.start-time, restart receiver(reply snapshot start)
|
// if sender.start-time > receiver.start-time, restart receiver(reply snapshot start)
|
||||||
// if sender.start-time = receiver.start-time, maybe duplicate msg
|
// if sender.start-time = receiver.start-time, maybe duplicate msg
|
||||||
|
@ -809,9 +801,9 @@ int32_t syncNodeOnSnapshot(SSyncNode *pSyncNode, const SRpcMsg *pRpcMsg) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
if (pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER) {
|
if (pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER) {
|
||||||
if (pMsg->term == pSyncNode->raftStore.currentTerm) {
|
if (pMsg->term == pSyncNode->raftStore.currentTerm) {
|
||||||
if (pMsg->seq == SYNC_SNAPSHOT_SEQ_PRE_SNAPSHOT) {
|
if (pMsg->seq == SYNC_SNAPSHOT_SEQ_PREP_SNAPSHOT) {
|
||||||
syncLogRecvSyncSnapshotSend(pSyncNode, pMsg, "process seq pre-snapshot");
|
syncLogRecvSyncSnapshotSend(pSyncNode, pMsg, "process seq pre-snapshot");
|
||||||
code = syncNodeOnSnapshotPre(pSyncNode, pMsg);
|
code = syncNodeOnSnapshotPrep(pSyncNode, pMsg);
|
||||||
} else if (pMsg->seq == SYNC_SNAPSHOT_SEQ_BEGIN) {
|
} else if (pMsg->seq == SYNC_SNAPSHOT_SEQ_BEGIN) {
|
||||||
syncLogRecvSyncSnapshotSend(pSyncNode, pMsg, "process seq begin");
|
syncLogRecvSyncSnapshotSend(pSyncNode, pMsg, "process seq begin");
|
||||||
code = syncNodeOnSnapshotBegin(pSyncNode, pMsg);
|
code = syncNodeOnSnapshotBegin(pSyncNode, pMsg);
|
||||||
|
@ -848,7 +840,7 @@ int32_t syncNodeOnSnapshot(SSyncNode *pSyncNode, const SRpcMsg *pRpcMsg) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t syncNodeOnSnapshotPreRsp(SSyncNode *pSyncNode, SSyncSnapshotSender *pSender, SyncSnapshotRsp *pMsg) {
|
static int32_t syncNodeOnSnapshotPrepRsp(SSyncNode *pSyncNode, SSyncSnapshotSender *pSender, SyncSnapshotRsp *pMsg) {
|
||||||
SSnapshot snapshot = {0};
|
SSnapshot snapshot = {0};
|
||||||
pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot);
|
pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot);
|
||||||
|
|
||||||
|
@ -945,8 +937,8 @@ int32_t syncNodeOnSnapshotRsp(SSyncNode *pSyncNode, const SRpcMsg *pRpcMsg) {
|
||||||
|
|
||||||
if (pMsg->startTime != pSender->startTime) {
|
if (pMsg->startTime != pSender->startTime) {
|
||||||
syncLogRecvSyncSnapshotRsp(pSyncNode, pMsg, "snapshot sender and receiver time not match");
|
syncLogRecvSyncSnapshotRsp(pSyncNode, pMsg, "snapshot sender and receiver time not match");
|
||||||
sSError(pSender, "sender:%" PRId64 " receiver:%" PRId64 " time not match, code:0x%x", pMsg->startTime,
|
sSError(pSender, "sender:%" PRId64 " receiver:%" PRId64 " time not match, error:%s 0x%x", pMsg->startTime,
|
||||||
pSender->startTime, pMsg->code);
|
pSender->startTime, tstrerror(pMsg->code), pMsg->code);
|
||||||
terrno = TSDB_CODE_SYN_INTERNAL_ERROR;
|
terrno = TSDB_CODE_SYN_INTERNAL_ERROR;
|
||||||
goto _ERROR;
|
goto _ERROR;
|
||||||
}
|
}
|
||||||
|
@ -961,15 +953,15 @@ int32_t syncNodeOnSnapshotRsp(SSyncNode *pSyncNode, const SRpcMsg *pRpcMsg) {
|
||||||
|
|
||||||
if (pMsg->code != 0) {
|
if (pMsg->code != 0) {
|
||||||
syncLogRecvSyncSnapshotRsp(pSyncNode, pMsg, "receive error code");
|
syncLogRecvSyncSnapshotRsp(pSyncNode, pMsg, "receive error code");
|
||||||
sSError(pSender, "snapshot sender receive error code:0x%x and stop sender", pMsg->code);
|
sSError(pSender, "snapshot sender receive error:%s 0x%x and stop sender", tstrerror(pMsg->code), pMsg->code);
|
||||||
terrno = pMsg->code;
|
terrno = pMsg->code;
|
||||||
goto _ERROR;
|
goto _ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare <begin, end>, send begin msg
|
// prepare <begin, end>, send begin msg
|
||||||
if (pMsg->ack == SYNC_SNAPSHOT_SEQ_PRE_SNAPSHOT) {
|
if (pMsg->ack == SYNC_SNAPSHOT_SEQ_PREP_SNAPSHOT) {
|
||||||
syncLogRecvSyncSnapshotRsp(pSyncNode, pMsg, "process seq pre-snapshot");
|
syncLogRecvSyncSnapshotRsp(pSyncNode, pMsg, "process seq pre-snapshot");
|
||||||
return syncNodeOnSnapshotPreRsp(pSyncNode, pSender, pMsg);
|
return syncNodeOnSnapshotPrepRsp(pSyncNode, pSender, pMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSender->pReader == NULL || pSender->finish) {
|
if (pSender->pReader == NULL || pSender->finish) {
|
||||||
|
|
|
@ -141,20 +141,15 @@ static void syncLogReplMgrStates2Str(SSyncNode* pSyncNode, char* buf, int32_t bu
|
||||||
}
|
}
|
||||||
|
|
||||||
static void syncPeerState2Str(SSyncNode* pSyncNode, char* buf, int32_t bufLen) {
|
static void syncPeerState2Str(SSyncNode* pSyncNode, char* buf, int32_t bufLen) {
|
||||||
int32_t len = 1;
|
int32_t len = 0;
|
||||||
|
len += snprintf(buf + len, bufLen - len, "%s", "{");
|
||||||
for (int32_t i = 0; i < pSyncNode->replicaNum; ++i) {
|
for (int32_t i = 0; i < pSyncNode->replicaNum; ++i) {
|
||||||
SPeerState* pState = syncNodeGetPeerState(pSyncNode, &(pSyncNode->replicasId[i]));
|
SPeerState* pState = syncNodeGetPeerState(pSyncNode, &(pSyncNode->replicasId[i]));
|
||||||
if (pState == NULL) break;
|
if (pState == NULL) break;
|
||||||
|
len += snprintf(buf + len, bufLen - len, "%d:%" PRId64 " %" PRId64 "%s", i, pState->lastSendIndex,
|
||||||
if (i < pSyncNode->replicaNum - 1) {
|
pState->lastSendTime, (i < pSyncNode->replicaNum - 1) ? ", " : "");
|
||||||
len += snprintf(buf + len, bufLen - len, "%d:%" PRId64 " %" PRId64 ", ", i, pState->lastSendIndex,
|
|
||||||
pState->lastSendTime);
|
|
||||||
} else {
|
|
||||||
len += snprintf(buf + len, bufLen - len, "%d:%" PRId64 " %" PRId64 "}", i, pState->lastSendIndex,
|
|
||||||
pState->lastSendTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
len += snprintf(buf + len, bufLen - len, "%s", "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncPrintNodeLog(const char* flags, ELogLevel level, int32_t dflag, SSyncNode* pNode, const char* format, ...) {
|
void syncPrintNodeLog(const char* flags, ELogLevel level, int32_t dflag, SSyncNode* pNode, const char* format, ...) {
|
||||||
|
@ -245,7 +240,7 @@ void syncPrintSnapshotSenderLog(const char* flags, ELogLevel level, int32_t dfla
|
||||||
char cfgStr[1024] = "";
|
char cfgStr[1024] = "";
|
||||||
syncCfg2SimpleStr(&pNode->raftCfg.cfg, cfgStr, sizeof(cfgStr));
|
syncCfg2SimpleStr(&pNode->raftCfg.cfg, cfgStr, sizeof(cfgStr));
|
||||||
|
|
||||||
char peerStr[1024] = "{";
|
char peerStr[1024] = "";
|
||||||
syncPeerState2Str(pNode, peerStr, sizeof(peerStr));
|
syncPeerState2Str(pNode, peerStr, sizeof(peerStr));
|
||||||
|
|
||||||
char eventLog[512]; // {0};
|
char eventLog[512]; // {0};
|
||||||
|
@ -255,20 +250,21 @@ void syncPrintSnapshotSenderLog(const char* flags, ELogLevel level, int32_t dfla
|
||||||
va_end(argpointer);
|
va_end(argpointer);
|
||||||
|
|
||||||
taosPrintLog(flags, level, dflag,
|
taosPrintLog(flags, level, dflag,
|
||||||
"vgId:%d, %s, sync:%s, {%p s-param:%" PRId64 " e-param:%" PRId64 " laindex:%" PRId64 " laterm:%" PRIu64
|
"vgId:%d, %s, sync:%s, snap-sender:{%p start:%" PRId64 " end:%" PRId64 " last-index:%" PRId64
|
||||||
" lcindex:%" PRId64
|
" last-term:%" PRIu64 " last-cfg:%" PRId64
|
||||||
" seq:%d ack:%d finish:%d replica-index:%d dnode:%d}"
|
", seq:%d ack:%d finish:%d, as:%d dnode:%d}"
|
||||||
", tm:%" PRIu64 ", cmt:%" PRId64 ", fst:%" PRId64 ", lst:%" PRId64 ", min:%" PRId64 ", snap:%" PRId64
|
", term:%" PRIu64 ", commit-index:%" PRId64 ", firstver:%" PRId64 ", lastver:%" PRId64
|
||||||
", snap-tm:%" PRIu64 ", sby:%d, stgy:%d, bch:%d, r-num:%d, lcfg:%" PRId64
|
", min-match:%" PRId64 ", snap:{last-index:%" PRId64 ", term:%" PRIu64
|
||||||
", chging:%d, rsto:%d, dquorum:%d, elt:%" PRId64 ", hb:%" PRId64 ", %s, %s",
|
"}, standby:%d, batch-sz:%d, replicas:%d, last-cfg:%" PRId64
|
||||||
|
", chging:%d, restore:%d, quorum:%d, lc-timer:{elect:%" PRId64 ", hb:%" PRId64 "}, peer:%s, cfg:%s",
|
||||||
pNode->vgId, eventLog, syncStr(pNode->state), pSender, pSender->snapshotParam.start,
|
pNode->vgId, eventLog, syncStr(pNode->state), pSender, pSender->snapshotParam.start,
|
||||||
pSender->snapshotParam.end, pSender->snapshot.lastApplyIndex, pSender->snapshot.lastApplyTerm,
|
pSender->snapshotParam.end, pSender->snapshot.lastApplyIndex, pSender->snapshot.lastApplyTerm,
|
||||||
pSender->snapshot.lastConfigIndex, pSender->seq, pSender->ack, pSender->finish, pSender->replicaIndex,
|
pSender->snapshot.lastConfigIndex, pSender->seq, pSender->ack, pSender->finish, pSender->replicaIndex,
|
||||||
DID(&pNode->replicasId[pSender->replicaIndex]), pNode->raftStore.currentTerm, pNode->commitIndex,
|
DID(&pNode->replicasId[pSender->replicaIndex]), pNode->raftStore.currentTerm, pNode->commitIndex,
|
||||||
logBeginIndex, logLastIndex, pNode->minMatchIndex, snapshot.lastApplyIndex, snapshot.lastApplyTerm,
|
logBeginIndex, logLastIndex, pNode->minMatchIndex, snapshot.lastApplyIndex, snapshot.lastApplyTerm,
|
||||||
pNode->raftCfg.isStandBy, pNode->raftCfg.snapshotStrategy, pNode->raftCfg.batchSize, pNode->replicaNum,
|
pNode->raftCfg.isStandBy, pNode->raftCfg.batchSize, pNode->replicaNum, pNode->raftCfg.lastConfigIndex,
|
||||||
pNode->raftCfg.lastConfigIndex, pNode->changing, pNode->restoreFinish, syncNodeDynamicQuorum(pNode),
|
pNode->changing, pNode->restoreFinish, syncNodeDynamicQuorum(pNode), pNode->electTimerLogicClock,
|
||||||
pNode->electTimerLogicClock, pNode->heartbeatTimerLogicClockUser, peerStr, cfgStr);
|
pNode->heartbeatTimerLogicClockUser, peerStr, cfgStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncPrintSnapshotReceiverLog(const char* flags, ELogLevel level, int32_t dflag, SSyncSnapshotReceiver* pReceiver,
|
void syncPrintSnapshotReceiverLog(const char* flags, ELogLevel level, int32_t dflag, SSyncSnapshotReceiver* pReceiver,
|
||||||
|
@ -291,7 +287,7 @@ void syncPrintSnapshotReceiverLog(const char* flags, ELogLevel level, int32_t df
|
||||||
char cfgStr[1024] = "";
|
char cfgStr[1024] = "";
|
||||||
syncCfg2SimpleStr(&pNode->raftCfg.cfg, cfgStr, sizeof(cfgStr));
|
syncCfg2SimpleStr(&pNode->raftCfg.cfg, cfgStr, sizeof(cfgStr));
|
||||||
|
|
||||||
char peerStr[1024] = "{";
|
char peerStr[1024] = "";
|
||||||
syncPeerState2Str(pNode, peerStr, sizeof(peerStr));
|
syncPeerState2Str(pNode, peerStr, sizeof(peerStr));
|
||||||
|
|
||||||
char eventLog[512]; // {0};
|
char eventLog[512]; // {0};
|
||||||
|
@ -300,22 +296,22 @@ void syncPrintSnapshotReceiverLog(const char* flags, ELogLevel level, int32_t df
|
||||||
int32_t writeLen = vsnprintf(eventLog, sizeof(eventLog), format, argpointer);
|
int32_t writeLen = vsnprintf(eventLog, sizeof(eventLog), format, argpointer);
|
||||||
va_end(argpointer);
|
va_end(argpointer);
|
||||||
|
|
||||||
taosPrintLog(flags, level, dflag,
|
taosPrintLog(
|
||||||
|
flags, level, dflag,
|
||||||
"vgId:%d, %s, sync:%s,"
|
"vgId:%d, %s, sync:%s,"
|
||||||
" {%p start:%d ack:%d term:%" PRIu64 " start-time:%" PRId64 " from dnode:%d s-param:%" PRId64
|
" snap-receiver:{%p started:%d acked:%d term:%" PRIu64 " start-time:%" PRId64 " from-dnode:%d, start:%" PRId64
|
||||||
" e-param:%" PRId64 " laindex:%" PRId64 " laterm:%" PRIu64 " lcindex:%" PRId64
|
" end:%" PRId64 " last-index:%" PRId64 " last-term:%" PRIu64 " last-cfg:%" PRId64
|
||||||
"}"
|
"}"
|
||||||
", tm:%" PRIu64 ", cmt:%" PRId64 ", fst:%" PRId64 ", lst:%" PRId64 ", min:%" PRId64 ", snap:%" PRId64
|
", term:%" PRIu64 ", commit-index:%" PRId64 ", firstver:%" PRId64 ", lastver:%" PRId64 ", min-match:%" PRId64
|
||||||
", snap-tm:%" PRIu64 ", sby:%d, stgy:%d, bch:%d, r-num:%d, lcfg:%" PRId64
|
", snap:{last-index:%" PRId64 ", last-term:%" PRIu64 "}, standby:%d, batch-sz:%d, replicas:%d, last-cfg:%" PRId64
|
||||||
", chging:%d, rsto:%d, dquorum:%d, elt:%" PRId64 ", hb:%" PRId64 ", %s, %s",
|
", chging:%d, restore:%d, quorum:%d, lc-timers:{elect:%" PRId64 ", hb:%" PRId64 "}, peer:%s, cfg:%s",
|
||||||
pNode->vgId, eventLog, syncStr(pNode->state), pReceiver, pReceiver->start, pReceiver->ack,
|
pNode->vgId, eventLog, syncStr(pNode->state), pReceiver, pReceiver->start, pReceiver->ack, pReceiver->term,
|
||||||
pReceiver->term, pReceiver->startTime, DID(&pReceiver->fromId), pReceiver->snapshotParam.start,
|
pReceiver->startTime, DID(&pReceiver->fromId), pReceiver->snapshotParam.start, pReceiver->snapshotParam.end,
|
||||||
pReceiver->snapshotParam.end, pReceiver->snapshot.lastApplyIndex, pReceiver->snapshot.lastApplyTerm,
|
pReceiver->snapshot.lastApplyIndex, pReceiver->snapshot.lastApplyTerm, pReceiver->snapshot.lastConfigIndex,
|
||||||
pReceiver->snapshot.lastConfigIndex, pNode->raftStore.currentTerm, pNode->commitIndex, logBeginIndex,
|
pNode->raftStore.currentTerm, pNode->commitIndex, logBeginIndex, logLastIndex, pNode->minMatchIndex,
|
||||||
logLastIndex, pNode->minMatchIndex, snapshot.lastApplyIndex, snapshot.lastApplyTerm,
|
snapshot.lastApplyIndex, snapshot.lastApplyTerm, pNode->raftCfg.isStandBy, pNode->raftCfg.batchSize,
|
||||||
pNode->raftCfg.isStandBy, pNode->raftCfg.snapshotStrategy, pNode->raftCfg.batchSize, pNode->replicaNum,
|
pNode->replicaNum, pNode->raftCfg.lastConfigIndex, pNode->changing, pNode->restoreFinish,
|
||||||
pNode->raftCfg.lastConfigIndex, pNode->changing, pNode->restoreFinish, syncNodeDynamicQuorum(pNode),
|
syncNodeDynamicQuorum(pNode), pNode->electTimerLogicClock, pNode->heartbeatTimerLogicClockUser, peerStr, cfgStr);
|
||||||
pNode->electTimerLogicClock, pNode->heartbeatTimerLogicClockUser, peerStr, cfgStr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncLogRecvTimer(SSyncNode* pSyncNode, const SyncTimeout* pMsg, const char* s) {
|
void syncLogRecvTimer(SSyncNode* pSyncNode, const SyncTimeout* pMsg, const char* s) {
|
||||||
|
@ -351,13 +347,13 @@ void syncLogSendHeartbeat(SSyncNode* pSyncNode, const SyncHeartbeat* pMsg, bool
|
||||||
int64_t execTime) {
|
int64_t execTime) {
|
||||||
if (printX) {
|
if (printX) {
|
||||||
sNTrace(pSyncNode,
|
sNTrace(pSyncNode,
|
||||||
"send sync-heartbeat to dnode:%d {term:%" PRId64 ", cmt:%" PRId64 ", min-match:%" PRId64 ", ts:%" PRId64
|
"send sync-heartbeat to dnode:%d {term:%" PRId64 ", commit-index:%" PRId64 ", min-match:%" PRId64
|
||||||
"}, x",
|
", ts:%" PRId64 "}, x",
|
||||||
DID(&pMsg->destId), pMsg->term, pMsg->commitIndex, pMsg->minMatchIndex, pMsg->timeStamp);
|
DID(&pMsg->destId), pMsg->term, pMsg->commitIndex, pMsg->minMatchIndex, pMsg->timeStamp);
|
||||||
} else {
|
} else {
|
||||||
sNTrace(pSyncNode,
|
sNTrace(pSyncNode,
|
||||||
"send sync-heartbeat to dnode:%d {term:%" PRId64 ", cmt:%" PRId64 ", min-match:%" PRId64 ", ts:%" PRId64
|
"send sync-heartbeat to dnode:%d {term:%" PRId64 ", commit-index:%" PRId64 ", min-match:%" PRId64
|
||||||
"}, timer-elapsed:%" PRId64 ", next-exec:%" PRId64,
|
", ts:%" PRId64 "}, timer-elapsed:%" PRId64 ", next-exec:%" PRId64,
|
||||||
DID(&pMsg->destId), pMsg->term, pMsg->commitIndex, pMsg->minMatchIndex, pMsg->timeStamp, timerElapsed,
|
DID(&pMsg->destId), pMsg->term, pMsg->commitIndex, pMsg->minMatchIndex, pMsg->timeStamp, timerElapsed,
|
||||||
execTime);
|
execTime);
|
||||||
}
|
}
|
||||||
|
@ -368,14 +364,14 @@ void syncLogRecvHeartbeat(SSyncNode* pSyncNode, const SyncHeartbeat* pMsg, int64
|
||||||
pSyncNode->hbSlowNum++;
|
pSyncNode->hbSlowNum++;
|
||||||
|
|
||||||
sNInfo(pSyncNode,
|
sNInfo(pSyncNode,
|
||||||
"recv sync-heartbeat from dnode:%d slow {term:%" PRId64 ", cmt:%" PRId64 ", min-match:%" PRId64
|
"recv sync-heartbeat from dnode:%d slow {term:%" PRId64 ", commit-index:%" PRId64 ", min-match:%" PRId64
|
||||||
", ts:%" PRId64 "}, %s, net elapsed:%" PRId64,
|
", ts:%" PRId64 "}, %s, net elapsed:%" PRId64,
|
||||||
DID(&pMsg->srcId), pMsg->term, pMsg->commitIndex, pMsg->minMatchIndex, pMsg->timeStamp, s, timeDiff);
|
DID(&pMsg->srcId), pMsg->term, pMsg->commitIndex, pMsg->minMatchIndex, pMsg->timeStamp, s, timeDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
sNTrace(pSyncNode,
|
sNTrace(pSyncNode,
|
||||||
"recv sync-heartbeat from dnode:%d {term:%" PRId64 ", cmt:%" PRId64 ", min-match:%" PRId64 ", ts:%" PRId64
|
"recv sync-heartbeat from dnode:%d {term:%" PRId64 ", commit-index:%" PRId64 ", min-match:%" PRId64
|
||||||
"}, %s, net elapsed:%" PRId64,
|
", ts:%" PRId64 "}, %s, net elapsed:%" PRId64,
|
||||||
DID(&pMsg->srcId), pMsg->term, pMsg->commitIndex, pMsg->minMatchIndex, pMsg->timeStamp, s, timeDiff);
|
DID(&pMsg->srcId), pMsg->term, pMsg->commitIndex, pMsg->minMatchIndex, pMsg->timeStamp, s, timeDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,67 +396,64 @@ void syncLogRecvHeartbeatReply(SSyncNode* pSyncNode, const SyncHeartbeatReply* p
|
||||||
|
|
||||||
void syncLogSendSyncSnapshotSend(SSyncNode* pSyncNode, const SyncSnapshotSend* pMsg, const char* s) {
|
void syncLogSendSyncSnapshotSend(SSyncNode* pSyncNode, const SyncSnapshotSend* pMsg, const char* s) {
|
||||||
sNDebug(pSyncNode,
|
sNDebug(pSyncNode,
|
||||||
"send sync-snapshot-send to dnode:%d, %s, seq:%d, term:%" PRId64 ", begin:%" PRId64 ", end:%" PRId64
|
"send sync-snapshot-send to dnode:%d, %s, seq:%d, term:%" PRId64 ", begin-index:%" PRId64
|
||||||
", lterm:%" PRId64 ", stime:%" PRId64,
|
", last-index:%" PRId64 ", last-term:%" PRId64 ", start-time:%" PRId64,
|
||||||
DID(&pMsg->destId), s, pMsg->seq, pMsg->term, pMsg->beginIndex, pMsg->lastIndex, pMsg->lastTerm,
|
DID(&pMsg->destId), s, pMsg->seq, pMsg->term, pMsg->beginIndex, pMsg->lastIndex, pMsg->lastTerm,
|
||||||
pMsg->startTime);
|
pMsg->startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncLogRecvSyncSnapshotSend(SSyncNode* pSyncNode, const SyncSnapshotSend* pMsg, const char* s) {
|
void syncLogRecvSyncSnapshotSend(SSyncNode* pSyncNode, const SyncSnapshotSend* pMsg, const char* s) {
|
||||||
sNDebug(pSyncNode,
|
sNDebug(pSyncNode,
|
||||||
"recv sync-snapshot-send from dnode:%d, %s, seq:%d, term:%" PRId64 ", begin:%" PRId64 ", lst:%" PRId64
|
"recv sync-snapshot-send from dnode:%d, %s, seq:%d, term:%" PRId64 ", begin-index:%" PRId64
|
||||||
", lterm:%" PRId64 ", stime:%" PRId64 ", len:%u",
|
", last-index:%" PRId64 ", last-term:%" PRId64 ", start-time:%" PRId64 ", data-len:%u",
|
||||||
DID(&pMsg->srcId), s, pMsg->seq, pMsg->term, pMsg->beginIndex, pMsg->lastIndex, pMsg->lastTerm,
|
DID(&pMsg->srcId), s, pMsg->seq, pMsg->term, pMsg->beginIndex, pMsg->lastIndex, pMsg->lastTerm,
|
||||||
pMsg->startTime, pMsg->dataLen);
|
pMsg->startTime, pMsg->dataLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncLogSendSyncSnapshotRsp(SSyncNode* pSyncNode, const SyncSnapshotRsp* pMsg, const char* s) {
|
void syncLogSendSyncSnapshotRsp(SSyncNode* pSyncNode, const SyncSnapshotRsp* pMsg, const char* s) {
|
||||||
sNDebug(pSyncNode,
|
sNDebug(pSyncNode,
|
||||||
"send sync-snapshot-rsp to dnode:%d, %s, ack:%d, term:%" PRId64 ", begin:%" PRId64 ", lst:%" PRId64
|
"send sync-snapshot-rsp to dnode:%d, %s, acked:%d, term:%" PRId64 ", begin-index:%" PRId64
|
||||||
", lterm:%" PRId64 ", stime:%" PRId64,
|
", last-index:%" PRId64 ", last-term:%" PRId64 ", start-time:%" PRId64,
|
||||||
DID(&pMsg->destId), s, pMsg->ack, pMsg->term, pMsg->snapBeginIndex, pMsg->lastIndex, pMsg->lastTerm,
|
DID(&pMsg->destId), s, pMsg->ack, pMsg->term, pMsg->snapBeginIndex, pMsg->lastIndex, pMsg->lastTerm,
|
||||||
pMsg->startTime);
|
pMsg->startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncLogRecvSyncSnapshotRsp(SSyncNode* pSyncNode, const SyncSnapshotRsp* pMsg, const char* s) {
|
void syncLogRecvSyncSnapshotRsp(SSyncNode* pSyncNode, const SyncSnapshotRsp* pMsg, const char* s) {
|
||||||
sNDebug(pSyncNode,
|
sNDebug(pSyncNode,
|
||||||
"recv sync-snapshot-rsp from dnode:%d, %s, ack:%d, term:%" PRId64 ", begin:%" PRId64 ", lst:%" PRId64
|
"recv sync-snapshot-rsp from dnode:%d, %s, ack:%d, term:%" PRId64 ", begin-index:%" PRId64
|
||||||
", lterm:%" PRId64 ", stime:%" PRId64,
|
", last-index:%" PRId64 ", last-term:%" PRId64 ", start-time:%" PRId64,
|
||||||
DID(&pMsg->srcId), s, pMsg->ack, pMsg->term, pMsg->snapBeginIndex, pMsg->lastIndex, pMsg->lastTerm,
|
DID(&pMsg->srcId), s, pMsg->ack, pMsg->term, pMsg->snapBeginIndex, pMsg->lastIndex, pMsg->lastTerm,
|
||||||
pMsg->startTime);
|
pMsg->startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncLogRecvAppendEntries(SSyncNode* pSyncNode, const SyncAppendEntries* pMsg, const char* s) {
|
void syncLogRecvAppendEntries(SSyncNode* pSyncNode, const SyncAppendEntries* pMsg, const char* s) {
|
||||||
sNTrace(pSyncNode,
|
sNTrace(pSyncNode,
|
||||||
"recv sync-append-entries from dnode:%d {term:%" PRId64 ", pre-index:%" PRId64 ", pre-term:%" PRId64
|
"recv sync-append-entries from dnode:%d {term:%" PRId64 ", prev-log:{index:%" PRId64 ", term:%" PRId64
|
||||||
", cmt:%" PRId64 ", pterm:%" PRId64 ", datalen:%d}, %s",
|
"}, commit-index:%" PRId64 ", datalen:%d}, %s",
|
||||||
DID(&pMsg->srcId), pMsg->term, pMsg->prevLogIndex, pMsg->prevLogTerm, pMsg->commitIndex, pMsg->privateTerm,
|
DID(&pMsg->srcId), pMsg->term, pMsg->prevLogIndex, pMsg->prevLogTerm, pMsg->commitIndex, pMsg->dataLen, s);
|
||||||
pMsg->dataLen, s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncLogSendAppendEntries(SSyncNode* pSyncNode, const SyncAppendEntries* pMsg, const char* s) {
|
void syncLogSendAppendEntries(SSyncNode* pSyncNode, const SyncAppendEntries* pMsg, const char* s) {
|
||||||
sNTrace(pSyncNode,
|
sNTrace(pSyncNode,
|
||||||
"send sync-append-entries to dnode:%d, {term:%" PRId64 ", pre-index:%" PRId64 ", pre-term:%" PRId64
|
"send sync-append-entries to dnode:%d, {term:%" PRId64 ", prev-log:{index:%" PRId64 ", term:%" PRId64
|
||||||
", lsend-index:%" PRId64 ", cmt:%" PRId64 ", datalen:%d}, %s",
|
"}, index:%" PRId64 ", commit-index:%" PRId64 ", datalen:%d}, %s",
|
||||||
DID(&pMsg->destId), pMsg->term, pMsg->prevLogIndex, pMsg->prevLogTerm, (pMsg->prevLogIndex + 1),
|
DID(&pMsg->destId), pMsg->term, pMsg->prevLogIndex, pMsg->prevLogTerm, (pMsg->prevLogIndex + 1),
|
||||||
pMsg->commitIndex, pMsg->dataLen, s);
|
pMsg->commitIndex, pMsg->dataLen, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncLogRecvRequestVote(SSyncNode* pSyncNode, const SyncRequestVote* pMsg, int32_t voteGranted, const char* s) {
|
void syncLogRecvRequestVote(SSyncNode* pSyncNode, const SyncRequestVote* pMsg, int32_t voteGranted,
|
||||||
if (voteGranted == -1) {
|
const char* errmsg) {
|
||||||
|
char statusMsg[64];
|
||||||
|
snprintf(statusMsg, sizeof(statusMsg), "granted:%d", voteGranted);
|
||||||
sNInfo(pSyncNode,
|
sNInfo(pSyncNode,
|
||||||
"recv sync-request-vote from dnode:%d, {term:%" PRId64 ", lindex:%" PRId64 ", lterm:%" PRId64 "}, %s",
|
"recv sync-request-vote from dnode:%d, {term:%" PRId64 ", last-index:%" PRId64 ", last-term:%" PRId64 "}, %s",
|
||||||
DID(&pMsg->srcId), pMsg->term, pMsg->lastLogIndex, pMsg->lastLogTerm, s);
|
DID(&pMsg->srcId), pMsg->term, pMsg->lastLogIndex, pMsg->lastLogTerm,
|
||||||
} else {
|
(voteGranted != -1) ? statusMsg : errmsg);
|
||||||
sNInfo(pSyncNode,
|
|
||||||
"recv sync-request-vote from dnode:%d, {term:%" PRId64 ", lindex:%" PRId64 ", lterm:%" PRId64
|
|
||||||
"}, granted:%d",
|
|
||||||
DID(&pMsg->srcId), pMsg->term, pMsg->lastLogIndex, pMsg->lastLogTerm, voteGranted);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncLogSendRequestVote(SSyncNode* pNode, const SyncRequestVote* pMsg, const char* s) {
|
void syncLogSendRequestVote(SSyncNode* pNode, const SyncRequestVote* pMsg, const char* s) {
|
||||||
sNInfo(pNode, "send sync-request-vote to dnode:%d {term:%" PRId64 ", lindex:%" PRId64 ", lterm:%" PRId64 "}, %s",
|
sNInfo(pNode,
|
||||||
|
"send sync-request-vote to dnode:%d {term:%" PRId64 ", last-index:%" PRId64 ", last-term:%" PRId64 "}, %s",
|
||||||
DID(&pMsg->destId), pMsg->term, pMsg->lastLogIndex, pMsg->lastLogTerm, s);
|
DID(&pMsg->destId), pMsg->term, pMsg->lastLogIndex, pMsg->lastLogTerm, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -457,6 +457,11 @@ int tdbPagerAbort(SPager *pPager, TXN *pTxn) {
|
||||||
SPgno journalSize = 0;
|
SPgno journalSize = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (pTxn->jfd == 0) {
|
||||||
|
// txn is commited
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// sync the journal file
|
// sync the journal file
|
||||||
ret = tdbOsFSync(pTxn->jfd);
|
ret = tdbOsFSync(pTxn->jfd);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
|
@ -671,7 +671,7 @@ static SCliConn* cliCreateConn(SCliThrd* pThrd) {
|
||||||
conn->stream = (uv_stream_t*)taosMemoryMalloc(sizeof(uv_tcp_t));
|
conn->stream = (uv_stream_t*)taosMemoryMalloc(sizeof(uv_tcp_t));
|
||||||
uv_tcp_init(pThrd->loop, (uv_tcp_t*)(conn->stream));
|
uv_tcp_init(pThrd->loop, (uv_tcp_t*)(conn->stream));
|
||||||
conn->stream->data = conn;
|
conn->stream->data = conn;
|
||||||
transSetConnOption((uv_tcp_t*)conn->stream);
|
// transSetConnOption((uv_tcp_t*)conn->stream);
|
||||||
|
|
||||||
uv_timer_t* timer = taosArrayGetSize(pThrd->timerList) > 0 ? *(uv_timer_t**)taosArrayPop(pThrd->timerList) : NULL;
|
uv_timer_t* timer = taosArrayGetSize(pThrd->timerList) > 0 ? *(uv_timer_t**)taosArrayPop(pThrd->timerList) : NULL;
|
||||||
if (timer == NULL) {
|
if (timer == NULL) {
|
||||||
|
@ -778,7 +778,7 @@ static void cliSendCb(uv_write_t* req, int status) {
|
||||||
SCliMsg* pMsg = !transQueueEmpty(&pConn->cliMsgs) ? transQueueGet(&pConn->cliMsgs, 0) : NULL;
|
SCliMsg* pMsg = !transQueueEmpty(&pConn->cliMsgs) ? transQueueGet(&pConn->cliMsgs, 0) : NULL;
|
||||||
if (pMsg != NULL) {
|
if (pMsg != NULL) {
|
||||||
int64_t cost = taosGetTimestampUs() - pMsg->st;
|
int64_t cost = taosGetTimestampUs() - pMsg->st;
|
||||||
if (cost > 1000) {
|
if (cost > 1000 * 20) {
|
||||||
tWarn("%s conn %p send cost:%dus, send exception", CONN_GET_INST_LABEL(pConn), pConn, (int)cost);
|
tWarn("%s conn %p send cost:%dus, send exception", CONN_GET_INST_LABEL(pConn), pConn, (int)cost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -800,9 +800,12 @@ static void cliSendCb(uv_write_t* req, int status) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void cliSend(SCliConn* pConn) {
|
void cliSend(SCliConn* pConn) {
|
||||||
bool empty = transQueueEmpty(&pConn->cliMsgs);
|
SCliThrd* pThrd = pConn->hostThrd;
|
||||||
ASSERTS(empty == false, "trans-cli get invalid msg");
|
STrans* pTransInst = pThrd->pTransInst;
|
||||||
if (empty == true) {
|
|
||||||
|
if (transQueueEmpty(&pConn->cliMsgs)) {
|
||||||
|
tError("%s conn %p not msg to send", pTransInst->label, pConn);
|
||||||
|
cliHandleExcept(pConn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,9 +815,6 @@ void cliSend(SCliConn* pConn) {
|
||||||
|
|
||||||
STransConnCtx* pCtx = pCliMsg->ctx;
|
STransConnCtx* pCtx = pCliMsg->ctx;
|
||||||
|
|
||||||
SCliThrd* pThrd = pConn->hostThrd;
|
|
||||||
STrans* pTransInst = pThrd->pTransInst;
|
|
||||||
|
|
||||||
STransMsg* pMsg = (STransMsg*)(&pCliMsg->msg);
|
STransMsg* pMsg = (STransMsg*)(&pCliMsg->msg);
|
||||||
if (pMsg->pCont == 0) {
|
if (pMsg->pCont == 0) {
|
||||||
pMsg->pCont = (void*)rpcMallocCont(0);
|
pMsg->pCont = (void*)rpcMallocCont(0);
|
||||||
|
@ -1045,6 +1045,12 @@ static FORCE_INLINE uint32_t cliGetIpFromFqdnCache(SHashObj* cache, char* fqdn)
|
||||||
uint32_t* v = taosHashGet(cache, fqdn, strlen(fqdn));
|
uint32_t* v = taosHashGet(cache, fqdn, strlen(fqdn));
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
addr = taosGetIpv4FromFqdn(fqdn);
|
addr = taosGetIpv4FromFqdn(fqdn);
|
||||||
|
if (addr == 0xffffffff) {
|
||||||
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
tError("failed to get ip from fqdn:%s since %s", fqdn, terrstr());
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
taosHashPut(cache, fqdn, strlen(fqdn), &addr, sizeof(addr));
|
taosHashPut(cache, fqdn, strlen(fqdn), &addr, sizeof(addr));
|
||||||
} else {
|
} else {
|
||||||
addr = *v;
|
addr = *v;
|
||||||
|
@ -1061,9 +1067,10 @@ void cliHandleReq(SCliMsg* pMsg, SCliThrd* pThrd) {
|
||||||
STransConnCtx* pCtx = pMsg->ctx;
|
STransConnCtx* pCtx = pMsg->ctx;
|
||||||
|
|
||||||
cliMayCvtFqdnToIp(&pCtx->epSet, &pThrd->cvtAddr);
|
cliMayCvtFqdnToIp(&pCtx->epSet, &pThrd->cvtAddr);
|
||||||
|
STraceId* trace = &pMsg->msg.info.traceId;
|
||||||
|
|
||||||
if (!EPSET_IS_VALID(&pCtx->epSet)) {
|
if (!EPSET_IS_VALID(&pCtx->epSet)) {
|
||||||
tError("invalid epset");
|
tGError("%s, msg %s sent with invalid epset", pTransInst->label, TMSG_INFO(pMsg->msg.msgType));
|
||||||
destroyCmsg(pMsg);
|
destroyCmsg(pMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1116,15 +1123,45 @@ void cliHandleReq(SCliMsg* pMsg, SCliThrd* pThrd) {
|
||||||
conn->ip = strdup(EPSET_GET_INUSE_IP(&pCtx->epSet));
|
conn->ip = strdup(EPSET_GET_INUSE_IP(&pCtx->epSet));
|
||||||
conn->port = EPSET_GET_INUSE_PORT(&pCtx->epSet);
|
conn->port = EPSET_GET_INUSE_PORT(&pCtx->epSet);
|
||||||
|
|
||||||
|
uint32_t ipaddr = cliGetIpFromFqdnCache(pThrd->fqdn2ipCache, conn->ip);
|
||||||
|
if (ipaddr == 0xffffffff) {
|
||||||
|
uv_timer_stop(conn->timer);
|
||||||
|
conn->timer->data = NULL;
|
||||||
|
taosArrayPush(pThrd->timerList, &conn->timer);
|
||||||
|
conn->timer = NULL;
|
||||||
|
|
||||||
|
cliHandleExcept(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_addr.s_addr = cliGetIpFromFqdnCache(pThrd->fqdn2ipCache, conn->ip);
|
addr.sin_addr.s_addr = ipaddr;
|
||||||
addr.sin_port = (uint16_t)htons((uint16_t)conn->port);
|
addr.sin_port = (uint16_t)htons((uint16_t)conn->port);
|
||||||
|
|
||||||
STraceId* trace = &(pMsg->msg.info.traceId);
|
|
||||||
tGTrace("%s conn %p try to connect to %s:%d", pTransInst->label, conn, conn->ip, conn->port);
|
tGTrace("%s conn %p try to connect to %s:%d", pTransInst->label, conn, conn->ip, conn->port);
|
||||||
|
int32_t fd = taosCreateSocketWithTimeout(TRANS_CONN_TIMEOUT * 4);
|
||||||
|
if (fd == -1) {
|
||||||
|
tGError("%s conn %p failed to create socket, reason:%s", transLabel(pTransInst), conn,
|
||||||
|
tstrerror(TAOS_SYSTEM_ERROR(errno)));
|
||||||
|
cliHandleExcept(conn);
|
||||||
|
errno = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int ret = uv_tcp_open((uv_tcp_t*)conn->stream, fd);
|
||||||
|
if (ret != 0) {
|
||||||
|
tGError("%s conn %p failed to set stream, reason:%s", transLabel(pTransInst), conn, uv_err_name(ret));
|
||||||
|
cliHandleExcept(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ret = transSetConnOption((uv_tcp_t*)conn->stream);
|
||||||
|
if (ret != 0) {
|
||||||
|
tGError("%s conn %p failed to set socket opt, reason:%s", transLabel(pTransInst), conn, uv_err_name(ret));
|
||||||
|
cliHandleExcept(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int ret = uv_tcp_connect(&conn->connReq, (uv_tcp_t*)(conn->stream), (const struct sockaddr*)&addr, cliConnCb);
|
ret = uv_tcp_connect(&conn->connReq, (uv_tcp_t*)(conn->stream), (const struct sockaddr*)&addr, cliConnCb);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
tGError("%s conn %p failed to connect to %s:%d, reason:%s", pTransInst->label, conn, conn->ip, conn->port,
|
tGError("%s conn %p failed to connect to %s:%d, reason:%s", pTransInst->label, conn, conn->ip, conn->port,
|
||||||
uv_err_name(ret));
|
uv_err_name(ret));
|
||||||
|
@ -1139,7 +1176,6 @@ void cliHandleReq(SCliMsg* pMsg, SCliThrd* pThrd) {
|
||||||
}
|
}
|
||||||
uv_timer_start(conn->timer, cliConnTimeout, TRANS_CONN_TIMEOUT, 0);
|
uv_timer_start(conn->timer, cliConnTimeout, TRANS_CONN_TIMEOUT, 0);
|
||||||
}
|
}
|
||||||
STraceId* trace = &pMsg->msg.info.traceId;
|
|
||||||
tGTrace("%s conn %p ready", pTransInst->label, conn);
|
tGTrace("%s conn %p ready", pTransInst->label, conn);
|
||||||
}
|
}
|
||||||
static void cliAsyncCb(uv_async_t* handle) {
|
static void cliAsyncCb(uv_async_t* handle) {
|
||||||
|
@ -1275,6 +1311,10 @@ void* transInitClient(uint32_t ip, uint32_t port, char* label, int numOfThreads,
|
||||||
|
|
||||||
for (int i = 0; i < cli->numOfThreads; i++) {
|
for (int i = 0; i < cli->numOfThreads; i++) {
|
||||||
SCliThrd* pThrd = createThrdObj(shandle);
|
SCliThrd* pThrd = createThrdObj(shandle);
|
||||||
|
if (pThrd == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int err = taosThreadCreate(&pThrd->thread, NULL, cliWorkThread, (void*)(pThrd));
|
int err = taosThreadCreate(&pThrd->thread, NULL, cliWorkThread, (void*)(pThrd));
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
tDebug("success to create tranport-cli thread:%d", i);
|
tDebug("success to create tranport-cli thread:%d", i);
|
||||||
|
@ -1332,9 +1372,23 @@ static SCliThrd* createThrdObj(void* trans) {
|
||||||
taosThreadMutexInit(&pThrd->msgMtx, NULL);
|
taosThreadMutexInit(&pThrd->msgMtx, NULL);
|
||||||
|
|
||||||
pThrd->loop = (uv_loop_t*)taosMemoryMalloc(sizeof(uv_loop_t));
|
pThrd->loop = (uv_loop_t*)taosMemoryMalloc(sizeof(uv_loop_t));
|
||||||
uv_loop_init(pThrd->loop);
|
int err = uv_loop_init(pThrd->loop);
|
||||||
|
if (err != 0) {
|
||||||
|
tError("failed to init uv_loop, reason:%s", uv_err_name(err));
|
||||||
|
taosMemoryFree(pThrd->loop);
|
||||||
|
taosThreadMutexDestroy(&pThrd->msgMtx);
|
||||||
|
taosMemoryFree(pThrd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
pThrd->asyncPool = transAsyncPoolCreate(pThrd->loop, 8, pThrd, cliAsyncCb);
|
pThrd->asyncPool = transAsyncPoolCreate(pThrd->loop, 8, pThrd, cliAsyncCb);
|
||||||
|
if (pThrd->asyncPool == NULL) {
|
||||||
|
tError("failed to init async pool");
|
||||||
|
uv_loop_close(pThrd->loop);
|
||||||
|
taosMemoryFree(pThrd->loop);
|
||||||
|
taosThreadMutexDestroy(&pThrd->msgMtx);
|
||||||
|
taosMemoryFree(pThrd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pThrd->prepare = taosMemoryCalloc(1, sizeof(uv_prepare_t));
|
pThrd->prepare = taosMemoryCalloc(1, sizeof(uv_prepare_t));
|
||||||
uv_prepare_init(pThrd->loop, pThrd->prepare);
|
uv_prepare_init(pThrd->loop, pThrd->prepare);
|
||||||
|
|
|
@ -205,6 +205,10 @@ bool transReadComplete(SConnBuffer* connBuf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int transSetConnOption(uv_tcp_t* stream) {
|
int transSetConnOption(uv_tcp_t* stream) {
|
||||||
|
#if defined(WINDOWS) || defined(DARWIN)
|
||||||
|
#else
|
||||||
|
uv_tcp_keepalive(stream, 1, 20);
|
||||||
|
#endif
|
||||||
return uv_tcp_nodelay(stream, 1);
|
return uv_tcp_nodelay(stream, 1);
|
||||||
// int ret = uv_tcp_keepalive(stream, 5, 60);
|
// int ret = uv_tcp_keepalive(stream, 5, 60);
|
||||||
}
|
}
|
||||||
|
@ -214,24 +218,37 @@ SAsyncPool* transAsyncPoolCreate(uv_loop_t* loop, int sz, void* arg, AsyncCB cb)
|
||||||
pool->nAsync = sz;
|
pool->nAsync = sz;
|
||||||
pool->asyncs = taosMemoryCalloc(1, sizeof(uv_async_t) * pool->nAsync);
|
pool->asyncs = taosMemoryCalloc(1, sizeof(uv_async_t) * pool->nAsync);
|
||||||
|
|
||||||
for (int i = 0; i < pool->nAsync; i++) {
|
int i = 0, err = 0;
|
||||||
|
for (i = 0; i < pool->nAsync; i++) {
|
||||||
|
uv_async_t* async = &(pool->asyncs[i]);
|
||||||
|
|
||||||
SAsyncItem* item = taosMemoryCalloc(1, sizeof(SAsyncItem));
|
SAsyncItem* item = taosMemoryCalloc(1, sizeof(SAsyncItem));
|
||||||
item->pThrd = arg;
|
item->pThrd = arg;
|
||||||
QUEUE_INIT(&item->qmsg);
|
QUEUE_INIT(&item->qmsg);
|
||||||
taosThreadMutexInit(&item->mtx, NULL);
|
taosThreadMutexInit(&item->mtx, NULL);
|
||||||
|
|
||||||
uv_async_t* async = &(pool->asyncs[i]);
|
|
||||||
uv_async_init(loop, async, cb);
|
|
||||||
async->data = item;
|
async->data = item;
|
||||||
|
err = uv_async_init(loop, async, cb);
|
||||||
|
if (err != 0) {
|
||||||
|
tError("failed to init async, reason:%s", uv_err_name(err));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != pool->nAsync) {
|
||||||
|
transAsyncPoolDestroy(pool);
|
||||||
|
pool = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
void transAsyncPoolDestroy(SAsyncPool* pool) {
|
void transAsyncPoolDestroy(SAsyncPool* pool) {
|
||||||
for (int i = 0; i < pool->nAsync; i++) {
|
for (int i = 0; i < pool->nAsync; i++) {
|
||||||
uv_async_t* async = &(pool->asyncs[i]);
|
uv_async_t* async = &(pool->asyncs[i]);
|
||||||
|
|
||||||
SAsyncItem* item = async->data;
|
SAsyncItem* item = async->data;
|
||||||
|
if (item == NULL) continue;
|
||||||
|
|
||||||
taosThreadMutexDestroy(&item->mtx);
|
taosThreadMutexDestroy(&item->mtx);
|
||||||
taosMemoryFree(item);
|
taosMemoryFree(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,6 +325,35 @@ bool walLogEntriesComplete(const SWal* pWal) {
|
||||||
return complete;
|
return complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int walTrimIdxFile(SWal* pWal, int32_t fileIdx) {
|
||||||
|
SWalFileInfo* pFileInfo = taosArrayGet(pWal->fileInfoSet, fileIdx);
|
||||||
|
ASSERT(pFileInfo != NULL);
|
||||||
|
char fnameStr[WAL_FILE_LEN];
|
||||||
|
walBuildIdxName(pWal, pFileInfo->firstVer, fnameStr);
|
||||||
|
|
||||||
|
int64_t fileSize = 0;
|
||||||
|
taosStatFile(fnameStr, &fileSize, NULL);
|
||||||
|
int64_t records = TMAX(0, pFileInfo->lastVer - pFileInfo->firstVer + 1);
|
||||||
|
int64_t lastEndOffset = records * sizeof(SWalIdxEntry);
|
||||||
|
|
||||||
|
if (fileSize <= lastEndOffset) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TdFilePtr pFile = taosOpenFile(fnameStr, TD_FILE_READ | TD_FILE_WRITE);
|
||||||
|
if (pFile == NULL) {
|
||||||
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wInfo("vgId:%d, trim idx file. file: %s, size: %" PRId64 ", offset: %" PRId64, pWal->cfg.vgId, fnameStr, fileSize,
|
||||||
|
lastEndOffset);
|
||||||
|
|
||||||
|
taosFtruncateFile(pFile, lastEndOffset);
|
||||||
|
taosCloseFile(&pFile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int walCheckAndRepairMeta(SWal* pWal) {
|
int walCheckAndRepairMeta(SWal* pWal) {
|
||||||
// load log files, get first/snapshot/last version info
|
// load log files, get first/snapshot/last version info
|
||||||
const char* logPattern = "^[0-9]+.log$";
|
const char* logPattern = "^[0-9]+.log$";
|
||||||
|
@ -402,6 +431,8 @@ int walCheckAndRepairMeta(SWal* pWal) {
|
||||||
}
|
}
|
||||||
updateMeta = true;
|
updateMeta = true;
|
||||||
|
|
||||||
|
(void)walTrimIdxFile(pWal, fileIdx);
|
||||||
|
|
||||||
int64_t lastVer = walScanLogGetLastVer(pWal, fileIdx);
|
int64_t lastVer = walScanLogGetLastVer(pWal, fileIdx);
|
||||||
if (lastVer < 0) {
|
if (lastVer < 0) {
|
||||||
if (terrno != TSDB_CODE_WAL_LOG_NOT_EXIST) {
|
if (terrno != TSDB_CODE_WAL_LOG_NOT_EXIST) {
|
||||||
|
@ -567,6 +598,7 @@ int walCheckAndRepairIdxFile(SWal* pWal, int32_t fileIdx) {
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t count = 0;
|
||||||
while (idxEntry.ver < pFileInfo->lastVer) {
|
while (idxEntry.ver < pFileInfo->lastVer) {
|
||||||
ASSERT(idxEntry.ver == ckHead.head.version);
|
ASSERT(idxEntry.ver == ckHead.head.version);
|
||||||
|
|
||||||
|
@ -578,11 +610,11 @@ int walCheckAndRepairIdxFile(SWal* pWal, int32_t fileIdx) {
|
||||||
idxEntry.offset, fLogNameStr);
|
idxEntry.offset, fLogNameStr);
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
wWarn("vgId:%d, wal idx append new entry %" PRId64 " %" PRId64, pWal->cfg.vgId, idxEntry.ver, idxEntry.offset);
|
|
||||||
if (taosWriteFile(pIdxFile, &idxEntry, sizeof(SWalIdxEntry)) < 0) {
|
if (taosWriteFile(pIdxFile, &idxEntry, sizeof(SWalIdxEntry)) < 0) {
|
||||||
wError("vgId:%d, failed to append file since %s. file:%s", pWal->cfg.vgId, terrstr(), fnameStr);
|
wError("vgId:%d, failed to append file since %s. file:%s", pWal->cfg.vgId, terrstr(), fnameStr);
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (taosFsyncFile(pIdxFile) < 0) {
|
if (taosFsyncFile(pIdxFile) < 0) {
|
||||||
|
@ -590,6 +622,11 @@ int walCheckAndRepairIdxFile(SWal* pWal, int32_t fileIdx) {
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
wInfo("vgId:%d, rebuilt %" PRId64 " wal idx entries until lastVer: %" PRId64, pWal->cfg.vgId, count,
|
||||||
|
pFileInfo->lastVer);
|
||||||
|
}
|
||||||
|
|
||||||
(void)taosCloseFile(&pLogFile);
|
(void)taosCloseFile(&pLogFile);
|
||||||
(void)taosCloseFile(&pIdxFile);
|
(void)taosCloseFile(&pIdxFile);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -77,14 +77,41 @@ void walUnrefVer(SWalRef *pRef) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SWalRef *walRefCommittedVer(SWal *pWal) {
|
SWalRef *walRefFirstVer(SWal *pWal, SWalRef *pRef) {
|
||||||
SWalRef *pRef = walOpenRef(pWal);
|
if (pRef == NULL) {
|
||||||
|
pRef = walOpenRef(pWal);
|
||||||
if (pRef == NULL) {
|
if (pRef == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
taosThreadMutexLock(&pWal->mutex);
|
taosThreadMutexLock(&pWal->mutex);
|
||||||
|
|
||||||
int64_t ver = walGetCommittedVer(pWal);
|
int64_t ver = walGetFirstVer(pWal);
|
||||||
|
|
||||||
|
wDebug("vgId:%d, wal ref version %" PRId64 " for first", pWal->cfg.vgId, ver);
|
||||||
|
|
||||||
|
pRef->refVer = ver;
|
||||||
|
// bsearch in fileSet
|
||||||
|
SWalFileInfo tmpInfo;
|
||||||
|
tmpInfo.firstVer = ver;
|
||||||
|
SWalFileInfo *pRet = taosArraySearch(pWal->fileInfoSet, &tmpInfo, compareWalFileInfo, TD_LE);
|
||||||
|
ASSERT(pRet != NULL);
|
||||||
|
pRef->refFile = pRet->firstVer;
|
||||||
|
|
||||||
|
taosThreadMutexUnlock(&pWal->mutex);
|
||||||
|
return pRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWalRef *walRefCommittedVer(SWal *pWal) {
|
||||||
|
SWalRef *pRef = walOpenRef(pWal);
|
||||||
|
if (pRef == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
taosThreadMutexLock(&pWal->mutex);
|
||||||
|
|
||||||
|
int64_t ver = walGetCommittedVer(pWal);
|
||||||
|
|
||||||
|
wDebug("vgId:%d, wal ref version %" PRId64 " for committed", pWal->cfg.vgId, ver);
|
||||||
|
|
||||||
pRef->refVer = ver;
|
pRef->refVer = ver;
|
||||||
// bsearch in fileSet
|
// bsearch in fileSet
|
||||||
|
|
|
@ -32,7 +32,18 @@ void swapStr(char* j, char* J, int width) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// todo refactor: 1) move away; 2) use merge sort instead; 3) qsort is not a stable sort actually.
|
int qsortHelper(const void* p1, const void* p2, const void* param) {
|
||||||
void taosSort(void* arr, int64_t sz, int64_t width, __compar_fn_t compar) {
|
__compar_fn_t comparFn = param;
|
||||||
qsort(arr, sz, width, compar);
|
return comparFn(p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo refactor: 1) move away; 2) use merge sort instead; 3) qsort is not a stable sort actually.
|
||||||
|
void taosSort(void* base, int64_t sz, int64_t width, __compar_fn_t compar) {
|
||||||
|
#ifdef _ALPINE
|
||||||
|
void* param = compar;
|
||||||
|
taosqsort(base, width, sz, param, qsortHelper);
|
||||||
|
#else
|
||||||
|
qsort(base, sz, width, compar);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -944,7 +944,7 @@ uint32_t taosGetIpv4FromFqdn(const char *fqdn) {
|
||||||
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
if (iResult != 0) {
|
if (iResult != 0) {
|
||||||
// printf("WSAStartup failed: %d\n", iResult);
|
// printf("WSAStartup failed: %d\n", iResult);
|
||||||
return 1;
|
return 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
struct addrinfo hints = {0};
|
struct addrinfo hints = {0};
|
||||||
|
@ -1071,11 +1071,12 @@ int32_t taosCreateSocketWithTimeout(uint32_t timeout) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#elif defined(_TD_DARWIN_64)
|
#elif defined(_TD_DARWIN_64)
|
||||||
uint32_t conn_timeout_ms = timeout * 1000;
|
// invalid config
|
||||||
if (0 != setsockopt(fd, IPPROTO_TCP, TCP_CONNECTIONTIMEOUT, (char *)&conn_timeout_ms, sizeof(conn_timeout_ms))) {
|
// uint32_t conn_timeout_ms = timeout * 1000;
|
||||||
taosCloseSocketNoCheck1(fd);
|
// if (0 != setsockopt(fd, IPPROTO_TCP, TCP_CONNECTIONTIMEOUT, (char *)&conn_timeout_ms, sizeof(conn_timeout_ms))) {
|
||||||
return -1;
|
// taosCloseSocketNoCheck1(fd);
|
||||||
}
|
// return -1;
|
||||||
|
//}
|
||||||
#else // Linux like systems
|
#else // Linux like systems
|
||||||
uint32_t conn_timeout_ms = timeout * 1000;
|
uint32_t conn_timeout_ms = timeout * 1000;
|
||||||
if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, (char *)&conn_timeout_ms, sizeof(conn_timeout_ms))) {
|
if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, (char *)&conn_timeout_ms, sizeof(conn_timeout_ms))) {
|
||||||
|
|
|
@ -33,6 +33,11 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
//#define TM_YEAR_BASE 1970 //origin
|
//#define TM_YEAR_BASE 1970 //origin
|
||||||
#define TM_YEAR_BASE 1900 // slguan
|
#define TM_YEAR_BASE 1900 // slguan
|
||||||
|
|
||||||
|
// This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
|
||||||
|
// until 00:00:00 January 1, 1970
|
||||||
|
static const uint64_t TIMEEPOCH = ((uint64_t)116444736000000000ULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We do not implement alternate representations. However, we always
|
* We do not implement alternate representations. However, we always
|
||||||
* check whether a given modifier is allowed for a certain conversion.
|
* check whether a given modifier is allowed for a certain conversion.
|
||||||
|
@ -341,15 +346,17 @@ char *taosStrpTime(const char *buf, const char *fmt, struct tm *tm) {
|
||||||
|
|
||||||
int32_t taosGetTimeOfDay(struct timeval *tv) {
|
int32_t taosGetTimeOfDay(struct timeval *tv) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
time_t t;
|
LARGE_INTEGER t;
|
||||||
t = taosGetTimestampSec();
|
FILETIME f;
|
||||||
SYSTEMTIME st;
|
|
||||||
GetLocalTime(&st);
|
|
||||||
|
|
||||||
tv->tv_sec = (long)t;
|
GetSystemTimeAsFileTime(&f);
|
||||||
tv->tv_usec = st.wMilliseconds * 1000;
|
t.QuadPart = f.dwHighDateTime;
|
||||||
|
t.QuadPart <<= 32;
|
||||||
|
t.QuadPart |= f.dwLowDateTime;
|
||||||
|
|
||||||
return 0;
|
t.QuadPart -= TIMEEPOCH;
|
||||||
|
tv->tv_sec = t.QuadPart / 10000000;
|
||||||
|
tv->tv_usec = (t.QuadPart % 10000000) / 10;
|
||||||
#else
|
#else
|
||||||
return gettimeofday(tv, NULL);
|
return gettimeofday(tv, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
@ -550,37 +557,13 @@ int32_t taosClockGetTime(int clock_id, struct timespec *pTS) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
LARGE_INTEGER t;
|
LARGE_INTEGER t;
|
||||||
FILETIME f;
|
FILETIME f;
|
||||||
static FILETIME ff;
|
|
||||||
static SYSTEMTIME ss;
|
|
||||||
static LARGE_INTEGER offset;
|
|
||||||
|
|
||||||
static int8_t offsetInit = 0;
|
|
||||||
static volatile bool offsetInitFinished = false;
|
|
||||||
int8_t old = atomic_val_compare_exchange_8(&offsetInit, 0, 1);
|
|
||||||
if (0 == old) {
|
|
||||||
ss.wYear = 1970;
|
|
||||||
ss.wMonth = 1;
|
|
||||||
ss.wDay = 1;
|
|
||||||
ss.wHour = 0;
|
|
||||||
ss.wMinute = 0;
|
|
||||||
ss.wSecond = 0;
|
|
||||||
ss.wMilliseconds = 0;
|
|
||||||
SystemTimeToFileTime(&ss, &ff);
|
|
||||||
offset.QuadPart = ff.dwHighDateTime;
|
|
||||||
offset.QuadPart <<= 32;
|
|
||||||
offset.QuadPart |= ff.dwLowDateTime;
|
|
||||||
offsetInitFinished = true;
|
|
||||||
} else {
|
|
||||||
while (!offsetInitFinished)
|
|
||||||
; // Ensure initialization is completed.
|
|
||||||
}
|
|
||||||
|
|
||||||
GetSystemTimeAsFileTime(&f);
|
GetSystemTimeAsFileTime(&f);
|
||||||
t.QuadPart = f.dwHighDateTime;
|
t.QuadPart = f.dwHighDateTime;
|
||||||
t.QuadPart <<= 32;
|
t.QuadPart <<= 32;
|
||||||
t.QuadPart |= f.dwLowDateTime;
|
t.QuadPart |= f.dwLowDateTime;
|
||||||
|
|
||||||
t.QuadPart -= offset.QuadPart;
|
t.QuadPart -= TIMEEPOCH;
|
||||||
pTS->tv_sec = t.QuadPart / 10000000;
|
pTS->tv_sec = t.QuadPart / 10000000;
|
||||||
pTS->tv_nsec = (t.QuadPart % 10000000) * 100;
|
pTS->tv_nsec = (t.QuadPart % 10000000) * 100;
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
@ -28,32 +28,26 @@ static void median(void *src, int64_t size, int64_t s, int64_t e, const void *pa
|
||||||
void *buf) {
|
void *buf) {
|
||||||
int32_t mid = ((int32_t)(e - s) >> 1u) + (int32_t)s;
|
int32_t mid = ((int32_t)(e - s) >> 1u) + (int32_t)s;
|
||||||
|
|
||||||
if (comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, s), param) == 1) {
|
if (comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, s), param) > 0) {
|
||||||
doswap(elePtrAt(src, size, mid), elePtrAt(src, size, s), size, buf);
|
doswap(elePtrAt(src, size, mid), elePtrAt(src, size, s), size, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, e), param) == 1) {
|
if (comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, e), param) > 0) {
|
||||||
doswap(elePtrAt(src, size, mid), elePtrAt(src, size, s), size, buf);
|
doswap(elePtrAt(src, size, mid), elePtrAt(src, size, s), size, buf);
|
||||||
doswap(elePtrAt(src, size, mid), elePtrAt(src, size, e), size, buf);
|
doswap(elePtrAt(src, size, mid), elePtrAt(src, size, e), size, buf);
|
||||||
} else if (comparFn(elePtrAt(src, size, s), elePtrAt(src, size, e), param) == 1) {
|
} else if (comparFn(elePtrAt(src, size, s), elePtrAt(src, size, e), param) > 0) {
|
||||||
doswap(elePtrAt(src, size, s), elePtrAt(src, size, e), size, buf);
|
doswap(elePtrAt(src, size, s), elePtrAt(src, size, e), size, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, s), param) <= 0 &&
|
ASSERT(comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, s), param) <= 0 &&
|
||||||
comparFn(elePtrAt(src, size, s), elePtrAt(src, size, e), param) <= 0);
|
comparFn(elePtrAt(src, size, s), elePtrAt(src, size, e), param) <= 0);
|
||||||
|
|
||||||
#ifdef _DEBUG_VIEW
|
|
||||||
// tTagsPrints(src[s], pOrderDesc->pColumnModel, &pOrderDesc->orderIdx);
|
|
||||||
// tTagsPrints(src[mid], pOrderDesc->pColumnModel, &pOrderDesc->orderIdx);
|
|
||||||
// tTagsPrints(src[e], pOrderDesc->pColumnModel, &pOrderDesc->orderIdx);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tInsertSort(void *src, int64_t size, int32_t s, int32_t e, const void *param, __ext_compar_fn_t comparFn,
|
static void tInsertSort(void *src, int64_t size, int32_t s, int32_t e, const void *param, __ext_compar_fn_t comparFn,
|
||||||
void *buf) {
|
void *buf) {
|
||||||
for (int32_t i = s + 1; i <= e; ++i) {
|
for (int32_t i = s + 1; i <= e; ++i) {
|
||||||
for (int32_t j = i; j > s; --j) {
|
for (int32_t j = i; j > s; --j) {
|
||||||
if (comparFn(elePtrAt(src, size, j), elePtrAt(src, size, j - 1), param) == -1) {
|
if (comparFn(elePtrAt(src, size, j), elePtrAt(src, size, j - 1), param) < 0) {
|
||||||
doswap(elePtrAt(src, size, j), elePtrAt(src, size, j - 1), size, buf);
|
doswap(elePtrAt(src, size, j), elePtrAt(src, size, j - 1), size, buf);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -278,14 +272,4 @@ void taosheapsort(void *base, int32_t size, int32_t len, const void *parcompar,
|
||||||
}
|
}
|
||||||
|
|
||||||
taosMemoryFree(buf);
|
taosMemoryFree(buf);
|
||||||
/*
|
|
||||||
char *buf = taosMemoryCalloc(1, size);
|
|
||||||
|
|
||||||
for (i = len - 1; i > 0; i--) {
|
|
||||||
doswap(elePtrAt(base, size, 0), elePtrAt(base, size, i));
|
|
||||||
taosheapadjust(base, size, 0, i - 1, parcompar, compar, parswap, swap, maxroot);
|
|
||||||
}
|
|
||||||
|
|
||||||
taosMemoryFreeClear(buf);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,6 +287,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_STREAM_NOT_EXIST, "Stream not exist")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_OPTION, "Invalid stream option")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_OPTION, "Invalid stream option")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_STREAM_MUST_BE_DELETED, "Stream must be dropped first")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_STREAM_MUST_BE_DELETED, "Stream must be dropped first")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_MULTI_REPLICA_SOURCE_DB, "Stream temporarily does not support source db having replica > 1")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_MULTI_REPLICA_SOURCE_DB, "Stream temporarily does not support source db having replica > 1")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_STREAMS, "Too many streams")
|
||||||
|
|
||||||
// mnode-sma
|
// mnode-sma
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SMA_ALREADY_EXIST, "SMA already exists")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SMA_ALREADY_EXIST, "SMA already exists")
|
||||||
|
|
|
@ -126,6 +126,30 @@ static uint64_t allocateNewPositionInFile(SDiskbasedBuf* pBuf, size_t size) {
|
||||||
|
|
||||||
static FORCE_INLINE size_t getAllocPageSize(int32_t pageSize) { return pageSize + POINTER_BYTES + sizeof(SFilePage); }
|
static FORCE_INLINE size_t getAllocPageSize(int32_t pageSize) { return pageSize + POINTER_BYTES + sizeof(SFilePage); }
|
||||||
|
|
||||||
|
static int32_t doFlushBufPageImpl(SDiskbasedBuf* pBuf, int64_t offset, const char* pData, int32_t size) {
|
||||||
|
int32_t ret = taosLSeekFile(pBuf->pFile, offset, SEEK_SET);
|
||||||
|
if (ret == -1) {
|
||||||
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (int32_t)taosWriteFile(pBuf->pFile, pData, size);
|
||||||
|
if (ret != size) {
|
||||||
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extend the file
|
||||||
|
if (pBuf->fileSize < offset + size) {
|
||||||
|
pBuf->fileSize = offset + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
pBuf->statis.flushBytes += size;
|
||||||
|
pBuf->statis.flushPages += 1;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static char* doFlushBufPage(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
static char* doFlushBufPage(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
||||||
if (pg->pData == NULL || pg->used) {
|
if (pg->pData == NULL || pg->used) {
|
||||||
uError("invalid params in paged buffer process when flushing buf to disk, %s", pBuf->id);
|
uError("invalid params in paged buffer process when flushing buf to disk, %s", pBuf->id);
|
||||||
|
@ -134,6 +158,8 @@ static char* doFlushBufPage(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t size = pBuf->pageSize;
|
int32_t size = pBuf->pageSize;
|
||||||
|
int64_t offset = pg->offset;
|
||||||
|
|
||||||
char* t = NULL;
|
char* t = NULL;
|
||||||
if ((!HAS_DATA_IN_DISK(pg)) || pg->dirty) {
|
if ((!HAS_DATA_IN_DISK(pg)) || pg->dirty) {
|
||||||
void* payload = GET_PAYLOAD_DATA(pg);
|
void* payload = GET_PAYLOAD_DATA(pg);
|
||||||
|
@ -147,59 +173,29 @@ static char* doFlushBufPage(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
||||||
// this page is flushed to disk for the first time
|
// this page is flushed to disk for the first time
|
||||||
if (pg->dirty) {
|
if (pg->dirty) {
|
||||||
if (!HAS_DATA_IN_DISK(pg)) {
|
if (!HAS_DATA_IN_DISK(pg)) {
|
||||||
pg->offset = allocateNewPositionInFile(pBuf, size);
|
offset = allocateNewPositionInFile(pBuf, size);
|
||||||
pBuf->nextPos += size;
|
pBuf->nextPos += size;
|
||||||
|
|
||||||
int32_t ret = taosLSeekFile(pBuf->pFile, pg->offset, SEEK_SET);
|
int32_t code = doFlushBufPageImpl(pBuf, offset, t, size);
|
||||||
if (ret == -1) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (int32_t)taosWriteFile(pBuf->pFile, t, size);
|
|
||||||
if (ret != size) {
|
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// extend the file size
|
|
||||||
if (pBuf->fileSize < pg->offset + size) {
|
|
||||||
pBuf->fileSize = pg->offset + size;
|
|
||||||
}
|
|
||||||
|
|
||||||
pBuf->statis.flushBytes += size;
|
|
||||||
pBuf->statis.flushPages += 1;
|
|
||||||
} else {
|
} else {
|
||||||
// length becomes greater, current space is not enough, allocate new place, otherwise, do nothing
|
// length becomes greater, current space is not enough, allocate new place, otherwise, do nothing
|
||||||
if (pg->length < size) {
|
if (pg->length < size) {
|
||||||
// 1. add current space to free list
|
// 1. add current space to free list
|
||||||
SPageDiskInfo dinfo = {.length = pg->length, .offset = pg->offset};
|
SPageDiskInfo dinfo = {.length = pg->length, .offset = offset};
|
||||||
taosArrayPush(pBuf->pFree, &dinfo);
|
taosArrayPush(pBuf->pFree, &dinfo);
|
||||||
|
|
||||||
// 2. allocate new position, and update the info
|
// 2. allocate new position, and update the info
|
||||||
pg->offset = allocateNewPositionInFile(pBuf, size);
|
offset = allocateNewPositionInFile(pBuf, size);
|
||||||
pBuf->nextPos += size;
|
pBuf->nextPos += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. write to disk.
|
int32_t code = doFlushBufPageImpl(pBuf, offset, t, size);
|
||||||
int32_t ret = taosLSeekFile(pBuf->pFile, pg->offset, SEEK_SET);
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
if (ret == -1) {
|
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (int32_t)taosWriteFile(pBuf->pFile, t, size);
|
|
||||||
if (ret != size) {
|
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pBuf->fileSize < pg->offset + size) {
|
|
||||||
pBuf->fileSize = pg->offset + size;
|
|
||||||
}
|
|
||||||
|
|
||||||
pBuf->statis.flushBytes += size;
|
|
||||||
pBuf->statis.flushPages += 1;
|
|
||||||
}
|
}
|
||||||
} else { // NOTE: the size may be -1, the this recycle page has not been flushed to disk yet.
|
} else { // NOTE: the size may be -1, the this recycle page has not been flushed to disk yet.
|
||||||
size = pg->length;
|
size = pg->length;
|
||||||
|
@ -209,9 +205,10 @@ static char* doFlushBufPage(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
||||||
memset(pDataBuf, 0, getAllocPageSize(pBuf->pageSize));
|
memset(pDataBuf, 0, getAllocPageSize(pBuf->pageSize));
|
||||||
|
|
||||||
#ifdef BUF_PAGE_DEBUG
|
#ifdef BUF_PAGE_DEBUG
|
||||||
uDebug("page_flush %p, pageId:%d, offset:%d", pDataBuf, pg->pageId, pg->offset);
|
uDebug("page_flush %p, pageId:%d, offset:%d", pDataBuf, pg->pageId, offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pg->offset = offset;
|
||||||
pg->length = size; // on disk size
|
pg->length = size; // on disk size
|
||||||
return pDataBuf;
|
return pDataBuf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
FROM python:3.8
|
||||||
|
RUN pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
RUN pip3 install pandas psutil fabric2 requests faker simplejson toml pexpect tzlocal distro
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y psmisc sudo tree libjansson-dev libsnappy-dev liblzma-dev libz-dev zlib1g pkg-config build-essential valgrind \
|
||||||
|
vim libjemalloc-dev openssh-server screen sshpass net-tools dirmngr gnupg apt-transport-https ca-certificates software-properties-common r-base iputils-ping
|
||||||
|
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
|
||||||
|
RUN add-apt-repository 'deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/'
|
||||||
|
RUN apt install -y r-base
|
||||||
|
ADD go1.17.6.linux-amd64.tar.gz /usr/local/
|
||||||
|
ADD jdk-8u144-linux-x64.tar.gz /usr/local/
|
||||||
|
ADD apache-maven-3.8.4-bin.tar.gz /usr/local/
|
||||||
|
RUN apt-get install wget -y \
|
||||||
|
&& wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
|
||||||
|
&& dpkg -i packages-microsoft-prod.deb \
|
||||||
|
&& rm packages-microsoft-prod.deb \
|
||||||
|
&& apt-get update && apt-get install -y dotnet-sdk-5.0 && apt-get install -y dotnet-sdk-6.0
|
||||||
|
ADD node-v12.20.0-linux-x64.tar.gz /usr/local/
|
||||||
|
RUN sh -c "rm -f /etc/localtime;ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime;echo \"Asia/Shanghai\" >/etc/timezone"
|
||||||
|
COPY id_rsa /root/.ssh/id_rsa
|
||||||
|
COPY .m2 /root/.m2
|
||||||
|
COPY .nuget /root/.nuget
|
||||||
|
COPY .dotnet /root/.dotnet
|
||||||
|
COPY .cargo /root/.cargo
|
||||||
|
COPY go /root/go
|
||||||
|
ADD cmake-3.21.5-linux-x86_64.tar.gz /usr/local/
|
||||||
|
RUN echo " export RUSTUP_DIST_SERVER=\"https://rsproxy.cn\" " >> /root/.bashrc
|
||||||
|
RUN echo " export RUSTUP_UPDATE_ROOT=\"https://rsproxy.cn/rustup\" " >> /root/.bashrc
|
||||||
|
RUN curl https://sh.rustup.rs -o /tmp/rustup-init.sh
|
||||||
|
RUN sh /tmp/rustup-init.sh -y
|
||||||
|
ENV PATH /usr/local/go/bin:/usr/local/node-v12.20.0-linux-x64/bin:/usr/local/apache-maven-3.8.4/bin:/usr/local/jdk1.8.0_144/bin:/usr/local/cmake-3.21.5-linux-x86_64/bin:/root/.cargo/bin:$PATH
|
||||||
|
ENV JAVA_HOME /usr/local/jdk1.8.0_144
|
||||||
|
RUN go env -w GOPROXY=https://goproxy.cn
|
||||||
|
RUN echo "StrictHostKeyChecking no" >>/etc/ssh/ssh_config
|
||||||
|
RUN npm config -g set unsafe-perm
|
||||||
|
RUN npm config -g set registry https://registry.npm.taobao.org
|
||||||
|
COPY .npm /root/.npm
|
||||||
|
RUN R CMD javareconf JAVA_HOME=${JAVA_HOME} JAVA=${JAVA_HOME}/bin/java JAVAC=${JAVA_HOME}/bin/javac JAVAH=${JAVA_HOME}/bin/javah JAR=${JAVA_HOME}/bin/jar
|
||||||
|
RUN echo "install.packages(\"RJDBC\", repos=\"http://cran.us.r-project.org\")"|R --no-save
|
||||||
|
COPY .gitconfig /root/.gitconfig
|
||||||
|
RUN mkdir -p /run/sshd
|
||||||
|
COPY id_rsa.pub /root/.ssh/id_rsa.pub
|
||||||
|
COPY id_rsa.pub /root/.ssh/authorized_keys
|
||||||
|
RUN pip3 uninstall -y taostest
|
||||||
|
COPY repository/TDinternal /home/TDinternal
|
||||||
|
COPY repository/taos-connector-python /home/taos-connector-python
|
||||||
|
RUN sh -c "cd /home/taos-connector-python; pip3 install ."
|
||||||
|
COPY setup.sh /home/setup.sh
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
docker build --no-cache -t taos_test:v1.0 .
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
script_dir=`dirname $0`
|
||||||
|
cd $script_dir
|
||||||
|
script_dir=`pwd`
|
||||||
|
cd $script_dir/repository/taos-connector-python
|
||||||
|
git pull
|
||||||
|
|
||||||
|
cd $script_dir/repository/TDinternal
|
||||||
|
git clean -fxd
|
||||||
|
git pull
|
||||||
|
|
||||||
|
cd $script_dir/repository/TDinternal/community
|
||||||
|
git clean -fxd
|
||||||
|
git checkout main
|
||||||
|
git pull origin main
|
||||||
|
git submodule update --init --recursive
|
||||||
|
|
||||||
|
cd $script_dir
|
||||||
|
cp $script_dir/repository/TDinternal/community/tests/ci/build_image.sh .
|
||||||
|
cp $script_dir/repository/TDinternal/community/tests/ci/daily_build_image.sh .
|
||||||
|
|
||||||
|
./build_image.sh || exit 1
|
||||||
|
docker image prune -f
|
||||||
|
ips="\
|
||||||
|
192.168.1.47 \
|
||||||
|
192.168.1.48 \
|
||||||
|
192.168.1.49 \
|
||||||
|
192.168.1.52 \
|
||||||
|
192.168.0.215 \
|
||||||
|
192.168.0.217 \
|
||||||
|
192.168.0.219 \
|
||||||
|
"
|
||||||
|
|
||||||
|
image=taos_image.tar
|
||||||
|
|
||||||
|
docker save taos_test:v1.0 -o $image
|
||||||
|
|
||||||
|
for ip in $ips; do
|
||||||
|
echo "scp $image root@$ip:/home/ &"
|
||||||
|
scp $image root@$ip:/home/ &
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
|
||||||
|
for ip in $ips; do
|
||||||
|
echo "ssh root@$ip docker load -i /home/$image &"
|
||||||
|
ssh root@$ip docker load -i /home/$image &
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
|
||||||
|
for ip in $ips; do
|
||||||
|
echo "ssh root@$ip rm -f /home/$image &"
|
||||||
|
ssh root@$ip rm -f /home/$image &
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
|
||||||
|
rm -rf taos_image.tar
|
||||||
|
|
|
@ -19,32 +19,38 @@ from util.dnodes import *
|
||||||
|
|
||||||
class TDTestCase:
|
class TDTestCase:
|
||||||
def caseDescription(self):
|
def caseDescription(self):
|
||||||
'''
|
"""
|
||||||
[TD-11510] taosBenchmark test cases
|
[TD-11510] taosBenchmark test cases
|
||||||
'''
|
"""
|
||||||
return
|
|
||||||
|
|
||||||
def init(self, conn, logSql, replicaVar=1):
|
def init(self, conn, logSql, replicaVar=1):
|
||||||
self.replicaVar = int(replicaVar)
|
|
||||||
tdLog.debug("start to execute %s" % __file__)
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
self.replicaVar = int(replicaVar)
|
||||||
tdSql.init(conn.cursor(), logSql)
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
def getPath(self, tool="taosBenchmark"):
|
def getPath(self, tool="taosBenchmark"):
|
||||||
selfPath = os.path.dirname(os.path.realpath(__file__))
|
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
if ("community" in selfPath):
|
if "community" in selfPath:
|
||||||
projPath = selfPath[: selfPath.find("community")]
|
projPath = selfPath[: selfPath.find("community")]
|
||||||
|
elif "src" in selfPath:
|
||||||
|
projPath = selfPath[: selfPath.find("src")]
|
||||||
|
elif "/tools/" in selfPath:
|
||||||
|
projPath = selfPath[: selfPath.find("/tools/")]
|
||||||
|
elif "/tests/" in selfPath:
|
||||||
|
projPath = selfPath[: selfPath.find("/tests/")]
|
||||||
else:
|
else:
|
||||||
projPath = selfPath[:selfPath.find("tests")]
|
tdLog.info("cannot found %s in path: %s, use system's" % (tool, selfPath))
|
||||||
|
projPath = "/usr/local/taos/bin/"
|
||||||
|
|
||||||
paths = []
|
paths = []
|
||||||
for root, dirs, files in os.walk(projPath):
|
for root, dummy, files in os.walk(projPath):
|
||||||
if ((tool) in files):
|
if (tool) in files:
|
||||||
rootRealPath = os.path.dirname(os.path.realpath(root))
|
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||||
if ("packaging" not in rootRealPath):
|
if "packaging" not in rootRealPath:
|
||||||
paths.append(os.path.join(root, tool))
|
paths.append(os.path.join(root, tool))
|
||||||
break
|
break
|
||||||
if (len(paths) == 0):
|
if len(paths) == 0:
|
||||||
tdLog.exit("taosBenchmark not found!")
|
tdLog.exit("taosBenchmark not found!")
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
@ -52,6 +58,10 @@ class TDTestCase:
|
||||||
return paths[0]
|
return paths[0]
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
tdSql.query("select client_version()")
|
||||||
|
client_ver = "".join(tdSql.queryResult[0])
|
||||||
|
major_ver = client_ver.split(".")[0]
|
||||||
|
|
||||||
binPath = self.getPath()
|
binPath = self.getPath()
|
||||||
cmd = "%s -f ./5-taos-tools/taosbenchmark/json/sml_json_alltypes.json" % binPath
|
cmd = "%s -f ./5-taos-tools/taosbenchmark/json/sml_json_alltypes.json" % binPath
|
||||||
tdLog.info("%s" % cmd)
|
tdLog.info("%s" % cmd)
|
||||||
|
@ -60,23 +70,33 @@ class TDTestCase:
|
||||||
tdSql.query("describe db.stb1")
|
tdSql.query("describe db.stb1")
|
||||||
tdSql.checkData(1, 1, "BOOL")
|
tdSql.checkData(1, 1, "BOOL")
|
||||||
tdSql.query("describe db.stb2")
|
tdSql.query("describe db.stb2")
|
||||||
tdSql.checkData(1, 1, "TINYINT")
|
tdSql.checkData(1, 1, "DOUBLE")
|
||||||
tdSql.query("describe db.stb3")
|
tdSql.query("describe db.stb3")
|
||||||
tdSql.checkData(1, 1, "SMALLINT")
|
tdSql.checkData(1, 1, "DOUBLE")
|
||||||
tdSql.query("describe db.stb4")
|
tdSql.query("describe db.stb4")
|
||||||
tdSql.checkData(1, 1, "INT")
|
tdSql.checkData(1, 1, "DOUBLE")
|
||||||
tdSql.query("describe db.stb5")
|
tdSql.query("describe db.stb5")
|
||||||
tdSql.checkData(1, 1, "BIGINT")
|
tdSql.checkData(1, 1, "DOUBLE")
|
||||||
tdSql.query("describe db.stb6")
|
tdSql.query("describe db.stb6")
|
||||||
tdSql.checkData(1, 1, "FLOAT")
|
tdSql.checkData(1, 1, "DOUBLE")
|
||||||
tdSql.query("describe db.stb7")
|
tdSql.query("describe db.stb7")
|
||||||
tdSql.checkData(1, 1, "DOUBLE")
|
tdSql.checkData(1, 1, "DOUBLE")
|
||||||
tdSql.query("describe db.stb8")
|
tdSql.query("describe db.stb8")
|
||||||
tdSql.checkData(1, 1, "VARCHAR")
|
if major_ver == "3":
|
||||||
tdSql.checkData(1, 2, 16)
|
|
||||||
tdSql.query("describe db.stb9")
|
|
||||||
tdSql.checkData(1, 1, "NCHAR")
|
tdSql.checkData(1, 1, "NCHAR")
|
||||||
tdSql.checkData(1, 2, 16)
|
tdSql.checkData(1, 2, 16)
|
||||||
|
else:
|
||||||
|
tdSql.checkData(1, 1, "NCHAR")
|
||||||
|
tdSql.checkData(1, 2, 8)
|
||||||
|
|
||||||
|
tdSql.query("describe db.stb9")
|
||||||
|
if major_ver == "3":
|
||||||
|
tdSql.checkData(1, 1, "NCHAR")
|
||||||
|
tdSql.checkData(1, 2, 16)
|
||||||
|
else:
|
||||||
|
tdSql.checkData(1, 1, "NCHAR")
|
||||||
|
tdSql.checkData(1, 2, 8)
|
||||||
|
|
||||||
tdSql.query("select count(*) from db.stb1")
|
tdSql.query("select count(*) from db.stb1")
|
||||||
tdSql.checkData(0, 0, 160)
|
tdSql.checkData(0, 0, 160)
|
||||||
tdSql.query("select count(*) from db.stb2")
|
tdSql.query("select count(*) from db.stb2")
|
||||||
|
|
|
@ -44,4 +44,43 @@ taos -s "drop database test"
|
||||||
python3 json_protocol_example.py
|
python3 json_protocol_example.py
|
||||||
|
|
||||||
# 10
|
# 10
|
||||||
# python3 subscribe_demo.py
|
pip install SQLAlchemy
|
||||||
|
pip install pandas
|
||||||
|
taosBenchmark -y -d power -t 10 -n 10
|
||||||
|
python3 conn_native_pandas.py
|
||||||
|
python3 conn_rest_pandas.py
|
||||||
|
taos -s "drop database if exists power"
|
||||||
|
|
||||||
|
# 11
|
||||||
|
taos -s "create database if not exists test"
|
||||||
|
python3 connect_native_reference.py
|
||||||
|
|
||||||
|
# 12
|
||||||
|
python3 connect_rest_examples.py
|
||||||
|
|
||||||
|
# 13
|
||||||
|
python3 handle_exception.py
|
||||||
|
|
||||||
|
# 14
|
||||||
|
taosBenchmark -y -d power -t 2 -n 10
|
||||||
|
python3 rest_client_example.py
|
||||||
|
taos -s "drop database if exists power"
|
||||||
|
|
||||||
|
# 15
|
||||||
|
python3 result_set_examples.py
|
||||||
|
|
||||||
|
# 16
|
||||||
|
python3 tmq_example.py
|
||||||
|
|
||||||
|
# 17
|
||||||
|
python3 sql_writer.py
|
||||||
|
|
||||||
|
# 18
|
||||||
|
python3 mockdatasource.py
|
||||||
|
|
||||||
|
# 19
|
||||||
|
python3 fast_write_example.py
|
||||||
|
|
||||||
|
# 20
|
||||||
|
pip3 install kafka-python
|
||||||
|
python3 kafka_example.py
|
||||||
|
|
|
@ -55,7 +55,7 @@ fi
|
||||||
date
|
date
|
||||||
docker run \
|
docker run \
|
||||||
-v $REP_MOUNT_PARAM \
|
-v $REP_MOUNT_PARAM \
|
||||||
--rm --ulimit core=-1 taos_test:v1.0 sh -c "cd $REP_DIR;rm -rf debug;mkdir -p debug;cd debug;cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true -DBUILD_TEST=true -DWEBSOCKET=true;make -j || exit 1"
|
--rm --ulimit core=-1 taos_test:v1.0 sh -c "cd $REP_DIR;rm -rf debug;mkdir -p debug;cd debug;cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true -DBUILD_TEST=true -DWEBSOCKET=true -DBUILD_TAOSX=true;make -j || exit 1"
|
||||||
|
|
||||||
if [[ -d ${WORKDIR}/debugNoSan ]] ;then
|
if [[ -d ${WORKDIR}/debugNoSan ]] ;then
|
||||||
echo "delete ${WORKDIR}/debugNoSan"
|
echo "delete ${WORKDIR}/debugNoSan"
|
||||||
|
@ -70,7 +70,7 @@ mv ${REP_REAL_PATH}/debug ${WORKDIR}/debugNoSan
|
||||||
date
|
date
|
||||||
docker run \
|
docker run \
|
||||||
-v $REP_MOUNT_PARAM \
|
-v $REP_MOUNT_PARAM \
|
||||||
--rm --ulimit core=-1 taos_test:v1.0 sh -c "cd $REP_DIR;rm -rf debug;mkdir -p debug;cd debug;cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true -DBUILD_TEST=true -DWEBSOCKET=true -DBUILD_SANITIZER=1 -DTOOLS_SANITIZE=true -DTOOLS_BUILD_TYPE=Debug;make -j || exit 1 "
|
--rm --ulimit core=-1 taos_test:v1.0 sh -c "cd $REP_DIR;rm -rf debug;mkdir -p debug;cd debug;cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true -DBUILD_TEST=true -DWEBSOCKET=true -DBUILD_SANITIZER=1 -DTOOLS_SANITIZE=true -DTOOLS_BUILD_TYPE=Debug -DBUILD_TAOSX=true;make -j || exit 1 "
|
||||||
|
|
||||||
mv ${REP_REAL_PATH}/debug ${WORKDIR}/debugSan
|
mv ${REP_REAL_PATH}/debug ${WORKDIR}/debugSan
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,10 @@ print ============== TD-5998
|
||||||
sql_error select _block_dist() from (select * from $nt)
|
sql_error select _block_dist() from (select * from $nt)
|
||||||
sql_error select _block_dist() from (select * from $mt)
|
sql_error select _block_dist() from (select * from $mt)
|
||||||
|
|
||||||
|
print ============== TD-22140 & TD-22165
|
||||||
|
sql_error show table distributed information_schema.ins_databases
|
||||||
|
sql_error show table distributed performance_schema.perf_apps
|
||||||
|
|
||||||
print =============== clear
|
print =============== clear
|
||||||
sql drop database $db
|
sql drop database $db
|
||||||
sql select * from information_schema.ins_databases
|
sql select * from information_schema.ins_databases
|
||||||
|
|
|
@ -79,6 +79,7 @@ sql insert into db.ctb6 values(now, 6, "6")
|
||||||
sql insert into db.ctb7 values(now, 7, "7")
|
sql insert into db.ctb7 values(now, 7, "7")
|
||||||
sql insert into db.ctb8 values(now, 8, "8")
|
sql insert into db.ctb8 values(now, 8, "8")
|
||||||
sql insert into db.ctb9 values(now, 9, "9")
|
sql insert into db.ctb9 values(now, 9, "9")
|
||||||
|
sql flush database db;
|
||||||
|
|
||||||
print =============== step3: create dnodes
|
print =============== step3: create dnodes
|
||||||
sql create dnode $hostname port 7300
|
sql create dnode $hostname port 7300
|
||||||
|
|
|
@ -72,4 +72,33 @@ sql_error select interp(*) from nt5931 where ts=now
|
||||||
sql_error select interp(*) from st5931 where ts=now
|
sql_error select interp(*) from st5931 where ts=now
|
||||||
sql_error select interp(*) from ct5931 where ts=now
|
sql_error select interp(*) from ct5931 where ts=now
|
||||||
|
|
||||||
|
sql create stable sta (ts timestamp, f1 double, f2 binary(200)) tags(t1 int);
|
||||||
|
sql create table tba1 using sta tags(1);
|
||||||
|
sql insert into tba1 values ('2022-04-26 15:15:01', -3.0, "a");
|
||||||
|
sql insert into tba1 values ('2022-04-26 15:15:05', 3.0, "b");
|
||||||
|
sql select a from (select interp(f1) as a from tba1 where ts >= '2022-04-26 15:15:01' and ts <= '2022-04-26 15:15:05' range('2022-04-26 15:15:01','2022-04-26 15:15:05') every(1s) fill(linear)) where a > 0;
|
||||||
|
if $rows != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data00 != 1.500000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data10 != 3.000000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql select a from (select interp(f1+1) as a from tba1 where ts >= '2022-04-26 15:15:01' and ts <= '2022-04-26 15:15:05' range('2022-04-26 15:15:01','2022-04-26 15:15:05') every(1s) fill(linear)) where a > 0;
|
||||||
|
if $rows != 3 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data00 != 1.000000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data10 != 2.500000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data20 != 4.000000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue