Merge branch '3.0' of https://github.com/taosdata/TDengine into fix/TD-21899
This commit is contained in:
commit
8a21d7f307
|
@ -2,7 +2,7 @@
|
|||
# taosadapter
|
||||
ExternalProject_Add(taosadapter
|
||||
GIT_REPOSITORY https://github.com/taosdata/taosadapter.git
|
||||
GIT_TAG 213f8b3
|
||||
GIT_TAG 3e08996
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosadapter"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# taos-tools
|
||||
ExternalProject_Add(taos-tools
|
||||
GIT_REPOSITORY https://github.com/taosdata/taos-tools.git
|
||||
GIT_TAG 0cd564a
|
||||
GIT_TAG 181bcac
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -58,7 +58,7 @@ database_option: {
|
|||
- WAL_FSYNC_PERIOD: specifies the interval (in milliseconds) at which data is written from the WAL to disk. This parameter takes effect only when the WAL parameter is set to 2. The default value is 3000. Enter a value between 0 and 180000. The value 0 indicates that incoming data is immediately written to disk.
|
||||
- MAXROWS: specifies the maximum number of rows recorded in a block. The default value is 4096.
|
||||
- MINROWS: specifies the minimum number of rows recorded in a block. The default value is 100.
|
||||
- KEEP: specifies the time for which data is retained. Enter a value between 1 and 365000. The default value is 3650. The value of the KEEP parameter must be greater than or equal to the value of the DURATION parameter. TDengine automatically deletes data that is older than the value of the KEEP parameter. You can use m (minutes), h (hours), and d (days) as the unit, for example KEEP 100h or KEEP 10d. If you do not include a unit, d is used by default.
|
||||
- KEEP: specifies the time for which data is retained. Enter a value between 1 and 365000. The default value is 3650. The value of the KEEP parameter must be greater than or equal to the value of the DURATION parameter. TDengine automatically deletes data that is older than the value of the KEEP parameter. You can use m (minutes), h (hours), and d (days) as the unit, for example KEEP 100h or KEEP 10d. If you do not include a unit, d is used by default. The Enterprise Edition supports [Tiered Storage](https://docs.tdengine.com/tdinternal/arch/#tiered-storage) function, thus multiple KEEP values (comma separated and up to 3 values supported, and meet keep 0 <= keep 1 <= keep 2, e.g. KEEP 100h,100d,3650d) are supported; the Community Edition does not support Tiered Storage function (although multiple keep values are configured, they do not take effect, only the maximum keep value is used as KEEP).
|
||||
- PAGES: specifies the number of pages in the metadata storage engine cache on each vnode. Enter a value greater than or equal to 64. The default value is 256. The space occupied by metadata storage on each vnode is equal to the product of the values of the PAGESIZE and PAGES parameters. The space occupied by default is 1 MB.
|
||||
- PAGESIZE: specifies the size (in KB) of each page in the metadata storage engine cache on each vnode. The default value is 4. Enter a value between 1 and 16384.
|
||||
- PRECISION: specifies the precision at which a database records timestamps. Enter ms for milliseconds, us for microseconds, or ns for nanoseconds. The default value is ms.
|
||||
|
|
|
@ -363,7 +363,7 @@ Shows information about all vgroups in the system or about the vgroups for a spe
|
|||
## SHOW VNODES
|
||||
|
||||
```sql
|
||||
SHOW VNODES [dnode_name];
|
||||
SHOW VNODES {dnode_id | dnode_endpoint};
|
||||
```
|
||||
|
||||
Shows information about all vnodes in the system or about the vnodes for a specified dnode.
|
||||
|
|
|
@ -323,6 +323,7 @@ The charset that takes effect is UTF-8.
|
|||
| Applicable | Server Only |
|
||||
| Meaning | All data files are stored in this directory |
|
||||
| Default Value | /var/lib/taos |
|
||||
| Note | The [Tiered Storage](https://docs.tdengine.com/tdinternal/arch/#tiered-storage) function needs to be used in conjunction with the [KEEP](https://docs.tdengine.com/taos-sql/database/#parameters) parameter |
|
||||
|
||||
### tempDir
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/taosdata/driver-go/v3 v3.1.0/go.mod h1:H2vo/At+rOPY1aMzUV9P49SVX7NlXb3LAbKw+MCLrmU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
@ -1,8 +1,11 @@
|
|||
import pandas
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy import create_engine, text
|
||||
|
||||
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(df.index)
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import pandas
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy import create_engine, text
|
||||
|
||||
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(df.index)
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
# ANCHOR: connect
|
||||
from taosrest import connect, TaosRestConnection, TaosRestCursor
|
||||
|
||||
conn: TaosRestConnection = connect(url="http://localhost:6041",
|
||||
user="root",
|
||||
password="taosdata",
|
||||
timeout=30)
|
||||
conn = connect(url="http://localhost:6041",
|
||||
user="root",
|
||||
password="taosdata",
|
||||
timeout=30)
|
||||
|
||||
# ANCHOR_END: connect
|
||||
# ANCHOR: basic
|
||||
# create STable
|
||||
cursor: TaosRestCursor = conn.cursor()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DROP DATABASE IF EXISTS 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
|
||||
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)
|
||||
|
@ -28,7 +29,7 @@ print("queried row count:", cursor.rowcount)
|
|||
# get column names from cursor
|
||||
column_names = [meta[0] for meta in cursor.description]
|
||||
# get rows
|
||||
data: list[tuple] = cursor.fetchall()
|
||||
data = cursor.fetchall()
|
||||
print(column_names)
|
||||
for row in data:
|
||||
print(row)
|
||||
|
|
|
@ -8,7 +8,7 @@ conn.execute("CREATE DATABASE test")
|
|||
# change database. same as execute "USE db"
|
||||
conn.select_db("test")
|
||||
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)
|
||||
# output:
|
||||
# affected_row 3
|
||||
|
@ -16,10 +16,10 @@ print("affected_row", affected_row)
|
|||
|
||||
# ANCHOR: query
|
||||
# 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
|
||||
fields: taos.field.TaosFields = result.fields
|
||||
fields = result.fields
|
||||
for field in fields:
|
||||
print(field) # {name: ts, type: 9, bytes: 8}
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
# install dependencies:
|
||||
# recommend python >= 3.8
|
||||
# pip3 install faster-fifo
|
||||
#
|
||||
|
||||
import logging
|
||||
import math
|
||||
import multiprocessing
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
from multiprocessing import Process
|
||||
from faster_fifo import Queue
|
||||
from multiprocessing import Process, Queue
|
||||
from mockdatasource import MockDataSource
|
||||
from queue import Empty
|
||||
from typing import List
|
||||
|
@ -22,8 +21,7 @@ TABLE_COUNT = 1000
|
|||
QUEUE_SIZE = 1000000
|
||||
MAX_BATCH_SIZE = 3000
|
||||
|
||||
read_processes = []
|
||||
write_processes = []
|
||||
_DONE_MESSAGE = '__DONE__'
|
||||
|
||||
|
||||
def get_connection():
|
||||
|
@ -44,41 +42,64 @@ def get_connection():
|
|||
|
||||
# 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
|
||||
data_source = MockDataSource(f"tb{task_id}", table_count_per_task)
|
||||
data_source = MockDataSource(f"tb{task_id}", table_count_per_task, infinity)
|
||||
try:
|
||||
for batch in data_source:
|
||||
if isinstance(batch, tuple):
|
||||
batch = [batch]
|
||||
for table_id, rows in batch:
|
||||
# hash data to different queue
|
||||
i = table_id % len(task_queues)
|
||||
# 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:
|
||||
pass
|
||||
finally:
|
||||
logging.info('read task over')
|
||||
|
||||
|
||||
# ANCHOR_END: read
|
||||
|
||||
|
||||
# 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
|
||||
log = logging.getLogger(f"WriteTask-{task_id}")
|
||||
writer = SQLWriter(get_connection)
|
||||
lines = None
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
# get as many as possible
|
||||
lines = queue.get_many(block=False, max_messages_to_get=MAX_BATCH_SIZE)
|
||||
over = False
|
||||
lines = []
|
||||
for _ in range(MAX_BATCH_SIZE):
|
||||
try:
|
||||
line = queue.get_nowait()
|
||||
if line == _DONE_MESSAGE:
|
||||
over = True
|
||||
break
|
||||
if line:
|
||||
lines.append(line)
|
||||
except Empty:
|
||||
time.sleep(0.1)
|
||||
if len(lines) > 0:
|
||||
writer.process_lines(lines)
|
||||
except Empty:
|
||||
time.sleep(0.01)
|
||||
if over:
|
||||
done_queue.put(_DONE_MESSAGE)
|
||||
break
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
except BaseException as e:
|
||||
log.debug(f"lines={lines}")
|
||||
raise e
|
||||
finally:
|
||||
writer.close()
|
||||
log.debug('write task over')
|
||||
|
||||
|
||||
# ANCHOR_END: write
|
||||
|
@ -103,47 +124,64 @@ def set_global_config():
|
|||
|
||||
|
||||
# ANCHOR: monitor
|
||||
def run_monitor_process():
|
||||
def run_monitor_process(done_queue: Queue):
|
||||
log = logging.getLogger("DataBaseMonitor")
|
||||
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)")
|
||||
conn = None
|
||||
try:
|
||||
conn = get_connection()
|
||||
|
||||
def get_count():
|
||||
res = conn.query("SELECT count(*) FROM test.meters")
|
||||
rows = res.fetch_all()
|
||||
return rows[0][0] if rows else 0
|
||||
def get_count():
|
||||
res = conn.query("SELECT count(*) FROM test.meters")
|
||||
rows = res.fetch_all()
|
||||
return rows[0][0] if rows else 0
|
||||
|
||||
last_count = 0
|
||||
while True:
|
||||
time.sleep(10)
|
||||
count = get_count()
|
||||
log.info(f"count={count} speed={(count - last_count) / 10}")
|
||||
last_count = count
|
||||
last_count = 0
|
||||
while True:
|
||||
try:
|
||||
done = done_queue.get_nowait()
|
||||
if done == _DONE_MESSAGE:
|
||||
break
|
||||
except Empty:
|
||||
pass
|
||||
time.sleep(10)
|
||||
count = get_count()
|
||||
log.info(f"count={count} speed={(count - last_count) / 10}")
|
||||
last_count = count
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
# ANCHOR_END: monitor
|
||||
# ANCHOR: main
|
||||
def main():
|
||||
def main(infinity):
|
||||
set_global_config()
|
||||
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}")
|
||||
|
||||
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()
|
||||
time.sleep(3) # waiting for database ready.
|
||||
logging.debug(f"monitor task started with pid {monitor_process.pid}")
|
||||
|
||||
task_queues: List[Queue] = []
|
||||
write_processes = []
|
||||
read_processes = []
|
||||
|
||||
# create task queues
|
||||
for i in range(WRITE_TASK_COUNT):
|
||||
queue = Queue(max_size_bytes=QUEUE_SIZE)
|
||||
queue = Queue()
|
||||
task_queues.append(queue)
|
||||
|
||||
# create write processes
|
||||
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()
|
||||
logging.debug(f"WriteTask-{i} started with pid {p.pid}")
|
||||
write_processes.append(p)
|
||||
|
@ -151,13 +189,19 @@ def main():
|
|||
# create read processes
|
||||
for i in range(READ_TASK_COUNT):
|
||||
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()
|
||||
logging.debug(f"ReadTask-{i} started with pid {p.pid}")
|
||||
read_processes.append(p)
|
||||
|
||||
try:
|
||||
monitor_process.join()
|
||||
for p in read_processes:
|
||||
p.join()
|
||||
for p in write_processes:
|
||||
p.join()
|
||||
time.sleep(1)
|
||||
return
|
||||
except KeyboardInterrupt:
|
||||
monitor_process.terminate()
|
||||
[p.terminate() for p in read_processes]
|
||||
|
@ -176,5 +220,6 @@ def assign_queues(read_task_id, task_queues):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
multiprocessing.set_start_method('spawn')
|
||||
main(False)
|
||||
# ANCHOR_END: main
|
||||
|
|
|
@ -26,7 +26,8 @@ class Consumer(object):
|
|||
'bath_consume': True,
|
||||
'batch_size': 1000,
|
||||
'async_model': True,
|
||||
'workers': 10
|
||||
'workers': 10,
|
||||
'testing': False
|
||||
}
|
||||
|
||||
LOCATIONS = ['California.SanFrancisco', 'California.LosAngles', 'California.SanDiego', 'California.SanJose',
|
||||
|
@ -46,11 +47,12 @@ class Consumer(object):
|
|||
def __init__(self, **configs):
|
||||
self.config: dict = self.DEFAULT_CONFIGS
|
||||
self.config.update(configs)
|
||||
self.consumer = KafkaConsumer(
|
||||
self.config.get('kafka_topic'), # topic
|
||||
bootstrap_servers=self.config.get('kafka_brokers'),
|
||||
group_id=self.config.get('kafka_group_id'),
|
||||
)
|
||||
if not self.config.get('testing'):
|
||||
self.consumer = KafkaConsumer(
|
||||
self.config.get('kafka_topic'), # topic
|
||||
bootstrap_servers=self.config.get('kafka_brokers'),
|
||||
group_id=self.config.get('kafka_group_id'),
|
||||
)
|
||||
self.taos = taos.connect(
|
||||
host=self.config.get('taos_host'),
|
||||
user=self.config.get('taos_user'),
|
||||
|
@ -60,7 +62,7 @@ class Consumer(object):
|
|||
)
|
||||
if self.config.get('async_model'):
|
||||
self.pool = ThreadPoolExecutor(max_workers=self.config.get('workers'))
|
||||
self.tasks: list[Future] = []
|
||||
self.tasks = []
|
||||
# tags and table mapping # key: {location}_{groupId} value:
|
||||
self.tag_table_mapping = {}
|
||||
i = 0
|
||||
|
@ -115,14 +117,14 @@ class Consumer(object):
|
|||
if self.taos is not None:
|
||||
self.taos.close()
|
||||
|
||||
def _run(self, f: Callable[[ConsumerRecord], bool]):
|
||||
def _run(self, f):
|
||||
for message in self.consumer:
|
||||
if self.config.get('async_model'):
|
||||
self.pool.submit(f(message))
|
||||
else:
|
||||
f(message)
|
||||
|
||||
def _run_batch(self, f: Callable[[list[list[ConsumerRecord]]], None]):
|
||||
def _run_batch(self, f):
|
||||
while True:
|
||||
messages = self.consumer.poll(timeout_ms=500, max_records=self.config.get('batch_size'))
|
||||
if messages:
|
||||
|
@ -140,7 +142,7 @@ class Consumer(object):
|
|||
logging.info('## insert sql %s', sql)
|
||||
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)
|
||||
if len(sql) == 0: # decode error, skip
|
||||
return
|
||||
|
@ -162,7 +164,7 @@ class Consumer(object):
|
|||
table_name = self._get_table_name(location=location, group_id=group_id)
|
||||
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 = []
|
||||
for partition_messages in messages:
|
||||
for message in partition_messages:
|
||||
|
@ -186,7 +188,54 @@ def _get_location_and_group(key: str) -> (str, int):
|
|||
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__':
|
||||
consumer = Consumer(async_model=True)
|
||||
consumer = Consumer(async_model=True, testing=True)
|
||||
# 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"
|
||||
]
|
||||
|
||||
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_count = table_count
|
||||
self.max_rows = 10000000
|
||||
self.current_ts = round(time.time() * 1000) - self.max_rows * 100
|
||||
# [(tableId, tableName, values),]
|
||||
self.data = self._init_data()
|
||||
self.infinity = infinity
|
||||
|
||||
def _init_data(self):
|
||||
lines = self.samples * (self.table_count // 5 + 1)
|
||||
|
@ -28,14 +29,19 @@ class MockDataSource:
|
|||
|
||||
def __iter__(self):
|
||||
self.row = 0
|
||||
return self
|
||||
if not self.infinity:
|
||||
return iter(self._iter_data())
|
||||
else:
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
"""
|
||||
next 1000 rows for each table.
|
||||
return: {tableId:[row,...]}
|
||||
"""
|
||||
# generate 1000 timestamps
|
||||
return self._iter_data()
|
||||
|
||||
def _iter_data(self):
|
||||
ts = []
|
||||
for _ in range(1000):
|
||||
self.current_ts += 100
|
||||
|
@ -47,3 +53,9 @@ class MockDataSource:
|
|||
rows = [table_name + ',' + t + ',' + values for t in ts]
|
||||
result.append((table_id, rows))
|
||||
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._conn = get_connection_func()
|
||||
self._max_sql_length = self.get_max_sql_length()
|
||||
self._conn.execute("create database if not exists test")
|
||||
self._conn.execute("USE test")
|
||||
|
||||
def get_max_sql_length(self):
|
||||
|
@ -20,7 +21,7 @@ class SQLWriter:
|
|||
return int(r[1])
|
||||
return 1024 * 1024
|
||||
|
||||
def process_lines(self, lines: str):
|
||||
def process_lines(self, lines: [str]):
|
||||
"""
|
||||
:param lines: [[tbName,ts,current,voltage,phase,location,groupId]]
|
||||
"""
|
||||
|
@ -60,6 +61,7 @@ class SQLWriter:
|
|||
buf.append(q)
|
||||
sql_len += len(q)
|
||||
sql += " ".join(buf)
|
||||
self.create_tables()
|
||||
self.execute_sql(sql)
|
||||
self._tb_values.clear()
|
||||
|
||||
|
@ -88,3 +90,22 @@ class SQLWriter:
|
|||
except BaseException as e:
|
||||
self.log.error("Execute SQL: %s", sql)
|
||||
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)")
|
||||
|
|
|
@ -19,8 +19,14 @@ def init_tmq_env(db, topic):
|
|||
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
|
||||
init_tmq_env("tmq_test", "tmq_test_topic") # init env
|
||||
consumer = Consumer(
|
||||
{
|
||||
"group.id": "tg2",
|
||||
|
@ -33,9 +39,9 @@ if __name__ == '__main__':
|
|||
|
||||
try:
|
||||
while True:
|
||||
res = consumer.poll(100)
|
||||
res = consumer.poll(1)
|
||||
if not res:
|
||||
continue
|
||||
break
|
||||
err = res.error()
|
||||
if err is not None:
|
||||
raise err
|
||||
|
@ -46,3 +52,4 @@ if __name__ == '__main__':
|
|||
finally:
|
||||
consumer.unsubscribe()
|
||||
consumer.close()
|
||||
cleanup("tmq_test", "tmq_test_topic")
|
||||
|
|
|
@ -58,7 +58,7 @@ database_option: {
|
|||
- WAL_FSYNC_PERIOD:当 WAL 参数设置为 2 时,落盘的周期。默认为 3000,单位毫秒。最小为 0,表示每次写入立即落盘;最大为 180000,即三分钟。
|
||||
- MAXROWS:文件块中记录的最大条数,默认为 4096 条。
|
||||
- MINROWS:文件块中记录的最小条数,默认为 100 条。
|
||||
- KEEP:表示数据文件保存的天数,缺省值为 3650,取值范围 [1, 365000],且必须大于或等于 DURATION 参数值。数据库会自动删除保存时间超过 KEEP 值的数据。KEEP 可以使用加单位的表示形式,如 KEEP 100h、KEEP 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。也可以不写单位,如 KEEP 50,此时默认单位为天。
|
||||
- KEEP:表示数据文件保存的天数,缺省值为 3650,取值范围 [1, 365000],且必须大于或等于 DURATION 参数值。数据库会自动删除保存时间超过 KEEP 值的数据。KEEP 可以使用加单位的表示形式,如 KEEP 100h、KEEP 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。也可以不写单位,如 KEEP 50,此时默认单位为天。企业版支持[多级存储](https://docs.taosdata.com/tdinternal/arch/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8)功能, 因此, 可以设置多个保存时间(多个以英文逗号分隔,最多 3 个,满足 keep 0 <= keep 1 <= keep 2,如 KEEP 100h,100d,3650d); 社区版不支持多级存储功能(即使配置了多个保存时间, 也不会生效, KEEP 会取最大的保存时间)。
|
||||
- PAGES:一个 VNODE 中元数据存储引擎的缓存页个数,默认为 256,最小 64。一个 VNODE 元数据存储占用 PAGESIZE \* PAGES,默认情况下为 1MB 内存。
|
||||
- PAGESIZE:一个 VNODE 中元数据存储引擎的页大小,单位为 KB,默认为 4 KB。范围为 1 到 16384,即 1 KB 到 16 MB。
|
||||
- PRECISION:数据库的时间戳精度。ms 表示毫秒,us 表示微秒,ns 表示纳秒,默认 ms 毫秒。
|
||||
|
|
|
@ -306,7 +306,7 @@ SHOW [db_name.]VGROUPS;
|
|||
## SHOW VNODES
|
||||
|
||||
```sql
|
||||
SHOW VNODES [dnode_name];
|
||||
SHOW VNODES {dnode_id | dnode_endpoint};
|
||||
```
|
||||
|
||||
显示当前系统中所有 VNODE 或某个 DNODE 的 VNODE 的信息。
|
||||
|
|
|
@ -323,6 +323,7 @@ charset 的有效值是 UTF-8。
|
|||
| 适用范围 | 仅服务端适用 |
|
||||
| 含义 | 数据文件目录,所有的数据文件都将写入该目录 |
|
||||
| 缺省值 | /var/lib/taos |
|
||||
| 补充说明 | [多级存储](https://docs.taosdata.com/tdinternal/arch/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8) 功能需要与 [KEEP](https://docs.taosdata.com/taos-sql/database/#%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E) 参数配合使用 |
|
||||
|
||||
### tempDir
|
||||
|
||||
|
|
|
@ -146,9 +146,9 @@ extern void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max,
|
|||
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind);
|
||||
void tColDataSortMerge(SArray *colDataArr);
|
||||
|
||||
//for raw block
|
||||
int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t bytes,
|
||||
int32_t nRows, char* lengthOrbitmap, char *data);
|
||||
// for raw block
|
||||
int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t bytes, int32_t nRows, char *lengthOrbitmap,
|
||||
char *data);
|
||||
// for encode/decode
|
||||
int32_t tPutColData(uint8_t *pBuf, SColData *pColData);
|
||||
int32_t tGetColData(uint8_t *pBuf, SColData *pColData);
|
||||
|
@ -261,7 +261,13 @@ struct STag {
|
|||
|
||||
// STSchema ================================
|
||||
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version);
|
||||
void tDestroyTSchema(STSchema *pTSchema);
|
||||
#define tDestroyTSchema(pTSchema) \
|
||||
do { \
|
||||
if (pTSchema) { \
|
||||
taosMemoryFree(pTSchema); \
|
||||
pTSchema = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -914,6 +914,7 @@ typedef struct {
|
|||
int32_t numOfRetensions;
|
||||
SArray* pRetensions;
|
||||
int8_t schemaless;
|
||||
int16_t sstTrigger;
|
||||
} SDbCfgRsp;
|
||||
|
||||
int32_t tSerializeSDbCfgRsp(void* buf, int32_t bufLen, const SDbCfgRsp* pRsp);
|
||||
|
|
|
@ -370,7 +370,8 @@ int32_t tDecodeSStreamTask(SDecoder* pDecoder, SStreamTask* pTask);
|
|||
void tFreeSStreamTask(SStreamTask* pTask);
|
||||
|
||||
static FORCE_INLINE int32_t streamTaskInput(SStreamTask* pTask, SStreamQueueItem* pItem) {
|
||||
if (pItem->type == STREAM_INPUT__DATA_SUBMIT) {
|
||||
int8_t type = pItem->type;
|
||||
if (type == STREAM_INPUT__DATA_SUBMIT) {
|
||||
SStreamDataSubmit2* pSubmitClone = streamSubmitRefClone((SStreamDataSubmit2*)pItem);
|
||||
if (pSubmitClone == NULL) {
|
||||
qDebug("task %d %p submit enqueue failed since out of memory", pTask->taskId, pTask);
|
||||
|
@ -382,19 +383,19 @@ static FORCE_INLINE int32_t streamTaskInput(SStreamTask* pTask, SStreamQueueItem
|
|||
pSubmitClone->submit.msgStr, pSubmitClone->submit.msgLen, pSubmitClone->submit.ver);
|
||||
taosWriteQitem(pTask->inputQueue->queue, pSubmitClone);
|
||||
// qStreamInput(pTask->exec.executor, pSubmitClone);
|
||||
} else if (pItem->type == STREAM_INPUT__DATA_BLOCK || pItem->type == STREAM_INPUT__DATA_RETRIEVE ||
|
||||
pItem->type == STREAM_INPUT__REF_DATA_BLOCK) {
|
||||
} else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE ||
|
||||
type == STREAM_INPUT__REF_DATA_BLOCK) {
|
||||
taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
// qStreamInput(pTask->exec.executor, pItem);
|
||||
} else if (pItem->type == STREAM_INPUT__CHECKPOINT) {
|
||||
} else if (type == STREAM_INPUT__CHECKPOINT) {
|
||||
taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
// qStreamInput(pTask->exec.executor, pItem);
|
||||
} else if (pItem->type == STREAM_INPUT__GET_RES) {
|
||||
} else if (type == STREAM_INPUT__GET_RES) {
|
||||
taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
// qStreamInput(pTask->exec.executor, pItem);
|
||||
}
|
||||
|
||||
if (pItem->type != STREAM_INPUT__GET_RES && pItem->type != STREAM_INPUT__CHECKPOINT && pTask->triggerParam != 0) {
|
||||
if (type != STREAM_INPUT__GET_RES && type != STREAM_INPUT__CHECKPOINT && pTask->triggerParam != 0) {
|
||||
atomic_val_compare_exchange_8(&pTask->triggerStatus, TASK_TRIGGER_STATUS__INACTIVE, TASK_TRIGGER_STATUS__ACTIVE);
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ typedef struct SSyncLogStore {
|
|||
SyncIndex (*syncLogLastIndex)(struct SSyncLogStore* pLogStore);
|
||||
SyncTerm (*syncLogLastTerm)(struct SSyncLogStore* pLogStore);
|
||||
|
||||
int32_t (*syncLogAppendEntry)(struct SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry);
|
||||
int32_t (*syncLogAppendEntry)(struct SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry, bool forcSync);
|
||||
int32_t (*syncLogGetEntry)(struct SSyncLogStore* pLogStore, SyncIndex index, SSyncRaftEntry** ppEntry);
|
||||
int32_t (*syncLogTruncate)(struct SSyncLogStore* pLogStore, SyncIndex fromIndex);
|
||||
|
||||
|
|
|
@ -201,6 +201,7 @@ int32_t walFetchHead(SWalReader *pRead, int64_t ver, SWalCkHead *pHead);
|
|||
int32_t walFetchBody(SWalReader *pRead, SWalCkHead **ppHead);
|
||||
int32_t walSkipFetchBody(SWalReader *pRead, const SWalCkHead *pHead);
|
||||
|
||||
SWalRef *walRefFirstVer(SWal *, SWalRef *);
|
||||
SWalRef *walRefCommittedVer(SWal *);
|
||||
|
||||
SWalRef *walOpenRef(SWal *);
|
||||
|
|
|
@ -746,7 +746,7 @@ function is_version_compatible() {
|
|||
deb_erase() {
|
||||
confirm=""
|
||||
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
|
||||
if [ "yes" == "$confirm" ]; then
|
||||
${csudo}dpkg --remove tdengine ||:
|
||||
|
@ -760,7 +760,7 @@ deb_erase() {
|
|||
rpm_erase() {
|
||||
confirm=""
|
||||
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
|
||||
if [ "yes" == "$confirm" ]; then
|
||||
${csudo}rpm -e tdengine ||:
|
||||
|
|
|
@ -400,45 +400,6 @@ void destroyRequest(SRequestObj *pRequest) {
|
|||
removeRequest(pRequest->self);
|
||||
}
|
||||
|
||||
void taosClientCrash(int signum, void *sigInfo, void *context) {
|
||||
taosIgnSignal(SIGTERM);
|
||||
taosIgnSignal(SIGHUP);
|
||||
taosIgnSignal(SIGINT);
|
||||
taosIgnSignal(SIGBREAK);
|
||||
|
||||
#if !defined(WINDOWS)
|
||||
taosIgnSignal(SIGBUS);
|
||||
#endif
|
||||
taosIgnSignal(SIGABRT);
|
||||
taosIgnSignal(SIGFPE);
|
||||
taosIgnSignal(SIGSEGV);
|
||||
|
||||
char *pMsg = NULL;
|
||||
const char *flags = "UTL FATAL ";
|
||||
ELogLevel level = DEBUG_FATAL;
|
||||
int32_t dflag = 255;
|
||||
int64_t msgLen= -1;
|
||||
|
||||
if (tsEnableCrashReport) {
|
||||
if (taosGenCrashJsonMsg(signum, &pMsg, lastClusterId, appInfo.startTime)) {
|
||||
taosPrintLog(flags, level, dflag, "failed to generate crash json msg");
|
||||
goto _return;
|
||||
} else {
|
||||
msgLen = strlen(pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
_return:
|
||||
|
||||
taosLogCrashInfo("taos", pMsg, msgLen, signum, sigInfo);
|
||||
|
||||
#ifdef _TD_DARWIN_64
|
||||
exit(signum);
|
||||
#elif defined(WINDOWS)
|
||||
exit(signum);
|
||||
#endif
|
||||
}
|
||||
|
||||
void crashReportThreadFuncUnexpectedStopped(void) { atomic_store_32(&clientStop, -1); }
|
||||
|
||||
static void *tscCrashReportThreadFp(void *param) {
|
||||
|
@ -535,15 +496,26 @@ void tscStopCrashReport() {
|
|||
}
|
||||
}
|
||||
|
||||
static void tscSetSignalHandle() {
|
||||
#if !defined(WINDOWS)
|
||||
taosSetSignal(SIGBUS, taosClientCrash);
|
||||
#endif
|
||||
taosSetSignal(SIGABRT, taosClientCrash);
|
||||
taosSetSignal(SIGFPE, taosClientCrash);
|
||||
taosSetSignal(SIGSEGV, taosClientCrash);
|
||||
|
||||
void tscWriteCrashInfo(int signum, void *sigInfo, void *context) {
|
||||
char *pMsg = NULL;
|
||||
const char *flags = "UTL FATAL ";
|
||||
ELogLevel level = DEBUG_FATAL;
|
||||
int32_t dflag = 255;
|
||||
int64_t msgLen= -1;
|
||||
|
||||
if (tsEnableCrashReport) {
|
||||
if (taosGenCrashJsonMsg(signum, &pMsg, lastClusterId, appInfo.startTime)) {
|
||||
taosPrintLog(flags, level, dflag, "failed to generate crash json msg");
|
||||
} else {
|
||||
msgLen = strlen(pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
taosLogCrashInfo("taos", pMsg, msgLen, signum, sigInfo);
|
||||
}
|
||||
|
||||
|
||||
void taos_init_imp(void) {
|
||||
// In the APIs of other program language, taos_cleanup is not available yet.
|
||||
// So, to make sure taos_cleanup will be invoked to clean up the allocated resource to suppress the valgrind warning.
|
||||
|
@ -567,8 +539,6 @@ void taos_init_imp(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
tscSetSignalHandle();
|
||||
|
||||
initQueryModuleMsgHandle();
|
||||
|
||||
if (taosConvInit() != 0) {
|
||||
|
|
|
@ -1239,7 +1239,7 @@ STscObj* taosConnectImpl(const char* user, const char* auth, const char* db, __t
|
|||
|
||||
int64_t transporterId = 0;
|
||||
asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &transporterId, body);
|
||||
|
||||
|
||||
tsem_wait(&pRequest->body.rspSem);
|
||||
if (pRequest->code != TSDB_CODE_SUCCESS) {
|
||||
const char* errorMsg =
|
||||
|
|
|
@ -528,9 +528,8 @@ void taos_stop_query(TAOS_RES *res) {
|
|||
SRequestObj *pRequest = (SRequestObj *)res;
|
||||
pRequest->killed = true;
|
||||
|
||||
int32_t numOfFields = taos_num_fields(pRequest);
|
||||
// It is not a query, no need to stop.
|
||||
if (numOfFields == 0) {
|
||||
if (NULL == pRequest->pQuery || QUERY_EXEC_MODE_SCHEDULE != pRequest->pQuery->execMode) {
|
||||
tscDebug("request 0x%" PRIx64 " no need to be killed since not query", pRequest->requestId);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ static char* buildAlterSTableJson(void* alterData, int32_t alterDataLen) {
|
|||
}
|
||||
string = cJSON_PrintUnformatted(json);
|
||||
|
||||
end:
|
||||
end:
|
||||
cJSON_Delete(json);
|
||||
tFreeSMAltertbReq(&req);
|
||||
return string;
|
||||
|
@ -200,7 +200,7 @@ static char* processCreateStb(SMqMetaRsp* metaRsp) {
|
|||
}
|
||||
string = buildCreateTableJson(&req.schemaRow, &req.schemaTag, req.name, req.suid, TSDB_SUPER_TABLE);
|
||||
|
||||
_err:
|
||||
_err:
|
||||
tDecoderClear(&coder);
|
||||
return string;
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ static char* processAlterStb(SMqMetaRsp* metaRsp) {
|
|||
}
|
||||
string = buildAlterSTableJson(req.alterOriData, req.alterOriDataLen);
|
||||
|
||||
_err:
|
||||
_err:
|
||||
tDecoderClear(&coder);
|
||||
return string;
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ static void buildChildElement(cJSON* json, SVCreateTbReq* pCreateReq) {
|
|||
cJSON_AddItemToArray(tags, tag);
|
||||
}
|
||||
|
||||
end:
|
||||
end:
|
||||
cJSON_AddItemToObject(json, "tags", tags);
|
||||
taosArrayDestroy(pTagVals);
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ static char* processCreateTable(SMqMetaRsp* metaRsp) {
|
|||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
_exit:
|
||||
for (int32_t iReq = 0; iReq < req.nReqs; iReq++) {
|
||||
pCreateReq = req.pReqs + iReq;
|
||||
taosMemoryFreeClear(pCreateReq->comment);
|
||||
|
@ -373,7 +373,7 @@ static char* processCreateTable(SMqMetaRsp* metaRsp) {
|
|||
}
|
||||
|
||||
static char* processAutoCreateTable(STaosxRsp* rsp) {
|
||||
if(rsp->createTableNum <= 0){
|
||||
if (rsp->createTableNum <= 0) {
|
||||
uError("WriteRaw:processAutoCreateTable rsp->createTableNum <= 0");
|
||||
goto _exit;
|
||||
}
|
||||
|
@ -392,14 +392,14 @@ static char* processAutoCreateTable(STaosxRsp* rsp) {
|
|||
goto _exit;
|
||||
}
|
||||
|
||||
if(pCreateReq[iReq].type != TSDB_CHILD_TABLE){
|
||||
if (pCreateReq[iReq].type != TSDB_CHILD_TABLE) {
|
||||
uError("WriteRaw:processAutoCreateTable pCreateReq[iReq].type != TSDB_CHILD_TABLE");
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
string = buildCreateCTableJson(pCreateReq, rsp->createTableNum);
|
||||
|
||||
_exit:
|
||||
_exit:
|
||||
for (int i = 0; i < rsp->createTableNum; i++) {
|
||||
tDecoderClear(&decoder[i]);
|
||||
taosMemoryFreeClear(pCreateReq[i].comment);
|
||||
|
@ -500,7 +500,7 @@ static char* processAlterTable(SMqMetaRsp* metaRsp) {
|
|||
char* buf = NULL;
|
||||
|
||||
if (vAlterTbReq.tagType == TSDB_DATA_TYPE_JSON) {
|
||||
if(!tTagIsJson(vAlterTbReq.pTagVal)){
|
||||
if (!tTagIsJson(vAlterTbReq.pTagVal)) {
|
||||
uError("processAlterTable isJson false");
|
||||
goto _exit;
|
||||
}
|
||||
|
@ -524,7 +524,7 @@ static char* processAlterTable(SMqMetaRsp* metaRsp) {
|
|||
}
|
||||
string = cJSON_PrintUnformatted(json);
|
||||
|
||||
_exit:
|
||||
_exit:
|
||||
cJSON_Delete(json);
|
||||
tDecoderClear(&decoder);
|
||||
return string;
|
||||
|
@ -557,12 +557,12 @@ static char* processDropSTable(SMqMetaRsp* metaRsp) {
|
|||
|
||||
string = cJSON_PrintUnformatted(json);
|
||||
|
||||
_exit:
|
||||
_exit:
|
||||
cJSON_Delete(json);
|
||||
tDecoderClear(&decoder);
|
||||
return string;
|
||||
}
|
||||
static char* processDeleteTable(SMqMetaRsp* metaRsp){
|
||||
static char* processDeleteTable(SMqMetaRsp* metaRsp) {
|
||||
SDeleteRes req = {0};
|
||||
SDecoder coder = {0};
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
@ -596,7 +596,7 @@ static char* processDeleteTable(SMqMetaRsp* metaRsp){
|
|||
|
||||
string = cJSON_PrintUnformatted(json);
|
||||
|
||||
_exit:
|
||||
_exit:
|
||||
cJSON_Delete(json);
|
||||
tDecoderClear(&coder);
|
||||
return string;
|
||||
|
@ -638,7 +638,7 @@ static char* processDropTable(SMqMetaRsp* metaRsp) {
|
|||
|
||||
string = cJSON_PrintUnformatted(json);
|
||||
|
||||
_exit:
|
||||
_exit:
|
||||
cJSON_Delete(json);
|
||||
tDecoderClear(&decoder);
|
||||
return string;
|
||||
|
@ -726,7 +726,7 @@ static int32_t taosCreateStb(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
code = pRequest->code;
|
||||
taosMemoryFree(pCmdMsg.pMsg);
|
||||
|
||||
end:
|
||||
end:
|
||||
destroyRequest(pRequest);
|
||||
tFreeSMCreateStbReq(&pReq);
|
||||
tDecoderClear(&coder);
|
||||
|
@ -796,7 +796,7 @@ static int32_t taosDropStb(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
code = pRequest->code;
|
||||
taosMemoryFree(pCmdMsg.pMsg);
|
||||
|
||||
end:
|
||||
end:
|
||||
destroyRequest(pRequest);
|
||||
tDecoderClear(&coder);
|
||||
return code;
|
||||
|
@ -857,9 +857,9 @@ static int32_t taosCreateTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
taosHashSetFreeFp(pVgroupHashmap, destroyCreateTbReqBatch);
|
||||
|
||||
SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter,
|
||||
.requestId = pRequest->requestId,
|
||||
.requestObjRefId = pRequest->self,
|
||||
.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
|
||||
.requestId = pRequest->requestId,
|
||||
.requestObjRefId = pRequest->self,
|
||||
.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
|
||||
|
||||
pRequest->tableList = taosArrayInit(req.nReqs, sizeof(SName));
|
||||
// loop to create table
|
||||
|
@ -939,7 +939,7 @@ static int32_t taosCreateTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
|
||||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
end:
|
||||
for (int32_t iReq = 0; iReq < req.nReqs; iReq++) {
|
||||
pCreateReq = req.pReqs + iReq;
|
||||
taosMemoryFreeClear(pCreateReq->comment);
|
||||
|
@ -1009,9 +1009,9 @@ static int32_t taosDropTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
taosHashSetFreeFp(pVgroupHashmap, destroyDropTbReqBatch);
|
||||
|
||||
SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter,
|
||||
.requestId = pRequest->requestId,
|
||||
.requestObjRefId = pRequest->self,
|
||||
.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
|
||||
.requestId = pRequest->requestId,
|
||||
.requestObjRefId = pRequest->self,
|
||||
.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
|
||||
pRequest->tableList = taosArrayInit(req.nReqs, sizeof(SName));
|
||||
// loop to create table
|
||||
for (int32_t iReq = 0; iReq < req.nReqs; iReq++) {
|
||||
|
@ -1063,7 +1063,7 @@ static int32_t taosDropTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
}
|
||||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
end:
|
||||
taosHashCleanup(pVgroupHashmap);
|
||||
destroyRequest(pRequest);
|
||||
tDecoderClear(&coder);
|
||||
|
@ -1131,7 +1131,7 @@ static int32_t taosDeleteData(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
}
|
||||
taos_free_result(res);
|
||||
|
||||
end:
|
||||
end:
|
||||
tDecoderClear(&coder);
|
||||
return code;
|
||||
}
|
||||
|
@ -1178,9 +1178,9 @@ static int32_t taosAlterTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
}
|
||||
|
||||
SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter,
|
||||
.requestId = pRequest->requestId,
|
||||
.requestObjRefId = pRequest->self,
|
||||
.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
|
||||
.requestId = pRequest->requestId,
|
||||
.requestObjRefId = pRequest->self,
|
||||
.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
|
||||
|
||||
SVgroupInfo pInfo = {0};
|
||||
SName pName = {0};
|
||||
|
@ -1239,7 +1239,7 @@ static int32_t taosAlterTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
code = handleAlterTbExecRes(pRes->res, pCatalog);
|
||||
}
|
||||
}
|
||||
end:
|
||||
end:
|
||||
taosArrayDestroy(pArray);
|
||||
if (pVgData) taosMemoryFreeClear(pVgData->pData);
|
||||
taosMemoryFreeClear(pVgData);
|
||||
|
@ -1402,7 +1402,7 @@ int taos_write_raw_block(TAOS* taos, int rows, char* pData, const char* tbname)
|
|||
launchQueryImpl(pRequest, pQuery, true, NULL);
|
||||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
end:
|
||||
taosMemoryFreeClear(pTableMeta);
|
||||
qDestroyQuery(pQuery);
|
||||
destroyRequest(pRequest);
|
||||
|
@ -1532,7 +1532,7 @@ static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, int32_t dataLen) {
|
|||
launchQueryImpl(pRequest, pQuery, true, NULL);
|
||||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
end:
|
||||
tDeleteSMqDataRsp(&rspObj.rsp);
|
||||
tDecoderClear(&decoder);
|
||||
qDestroyQuery(pQuery);
|
||||
|
@ -1631,7 +1631,7 @@ static int32_t tmqWriteRawMetaDataImpl(TAOS* taos, void* data, int32_t dataLen)
|
|||
goto end;
|
||||
}
|
||||
|
||||
if(pCreateReq.type != TSDB_CHILD_TABLE){
|
||||
if (pCreateReq.type != TSDB_CHILD_TABLE) {
|
||||
uError("WriteRaw:pCreateReq.type != TSDB_CHILD_TABLE. table name: %s", tbName);
|
||||
code = TSDB_CODE_TSC_INVALID_VALUE;
|
||||
goto end;
|
||||
|
|
|
@ -1532,10 +1532,6 @@ STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
|
|||
return pTSchema;
|
||||
}
|
||||
|
||||
void tDestroyTSchema(STSchema *pTSchema) {
|
||||
if (pTSchema) taosMemoryFree(pTSchema);
|
||||
}
|
||||
|
||||
// SColData ========================================
|
||||
void tColDataDestroy(void *ph) {
|
||||
SColData *pColData = (SColData *)ph;
|
||||
|
|
|
@ -2821,8 +2821,8 @@ int32_t tSerializeSDbCfgRsp(void *buf, int32_t bufLen, const SDbCfgRsp *pRsp) {
|
|||
if (tEncodeI8(&encoder, pRetension->keepUnit) < 0) return -1;
|
||||
}
|
||||
if (tEncodeI8(&encoder, pRsp->schemaless) < 0) return -1;
|
||||
if (tEncodeI16(&encoder, pRsp->sstTrigger) < 0) return -1;
|
||||
tEndEncode(&encoder);
|
||||
|
||||
int32_t tlen = encoder.pos;
|
||||
tEncoderClear(&encoder);
|
||||
return tlen;
|
||||
|
@ -2873,6 +2873,7 @@ int32_t tDeserializeSDbCfgRsp(void *buf, int32_t bufLen, SDbCfgRsp *pRsp) {
|
|||
}
|
||||
}
|
||||
if (tDecodeI8(&decoder, &pRsp->schemaless) < 0) return -1;
|
||||
if (tDecodeI16(&decoder, &pRsp->sstTrigger) < 0) return -1;
|
||||
tEndDecode(&decoder);
|
||||
|
||||
tDecoderClear(&decoder);
|
||||
|
|
|
@ -889,7 +889,7 @@ static int32_t mndProcessGetDbCfgReq(SRpcMsg *pReq) {
|
|||
cfgRsp.numOfRetensions = pDb->cfg.numOfRetensions;
|
||||
cfgRsp.pRetensions = pDb->cfg.pRetensions;
|
||||
cfgRsp.schemaless = pDb->cfg.schemaless;
|
||||
|
||||
cfgRsp.sstTrigger = pDb->cfg.sstTrigger;
|
||||
int32_t contLen = tSerializeSDbCfgRsp(NULL, 0, &cfgRsp);
|
||||
void *pRsp = rpcMallocCont(contLen);
|
||||
if (pRsp == NULL) {
|
||||
|
|
|
@ -153,6 +153,8 @@ typedef struct SMTbCursor SMTbCursor;
|
|||
SMTbCursor *metaOpenTbCursor(SMeta *pMeta);
|
||||
void metaCloseTbCursor(SMTbCursor *pTbCur);
|
||||
int32_t metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType);
|
||||
int32_t metaTbCursorPrev(SMTbCursor *pTbCur);
|
||||
|
||||
#endif
|
||||
|
||||
// tsdb
|
||||
|
|
|
@ -206,6 +206,7 @@ int32_t tsdbCmprColData(SColData *pColData, int8_t cmprAlg, SBlockCol *pBlockCol
|
|||
uint8_t **ppBuf);
|
||||
int32_t tsdbDecmprColData(uint8_t *pIn, SBlockCol *pBlockCol, int8_t cmprAlg, int32_t nVal, SColData *pColData,
|
||||
uint8_t **ppBuf);
|
||||
int32_t tRowInfoCmprFn(const void *p1, const void *p2);
|
||||
// tsdbMemTable ==============================================================================================
|
||||
// SMemTable
|
||||
int32_t tsdbMemTableCreate(STsdb *pTsdb, SMemTable **ppMemTable);
|
||||
|
|
|
@ -252,7 +252,7 @@ int32_t tsdbSnapReaderClose(STsdbSnapReader** ppReader);
|
|||
int32_t tsdbSnapRead(STsdbSnapReader* pReader, uint8_t** ppData);
|
||||
// STsdbSnapWriter ========================================
|
||||
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 tsdbSnapWriterClose(STsdbSnapWriter** ppWriter, int8_t rollback);
|
||||
// STqSnapshotReader ==
|
||||
|
|
|
@ -310,7 +310,7 @@ void metaCloseTbCursor(SMTbCursor *pTbCur) {
|
|||
}
|
||||
}
|
||||
|
||||
int metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType) {
|
||||
int32_t metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType) {
|
||||
int ret;
|
||||
void *pBuf;
|
||||
STbCfg tbCfg;
|
||||
|
@ -334,6 +334,30 @@ int metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t metaTbCursorPrev(SMTbCursor *pTbCur) {
|
||||
int ret;
|
||||
void *pBuf;
|
||||
STbCfg tbCfg;
|
||||
|
||||
for (;;) {
|
||||
ret = tdbTbcPrev(pTbCur->pDbc, &pTbCur->pKey, &pTbCur->kLen, &pTbCur->pVal, &pTbCur->vLen);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tDecoderClear(&pTbCur->mr.coder);
|
||||
|
||||
metaGetTableEntryByVersion(&pTbCur->mr, ((SUidIdxVal *)pTbCur->pVal)[0].version, *(tb_uid_t *)pTbCur->pKey);
|
||||
if (pTbCur->mr.me.type == TSDB_SUPER_TABLE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, int lock) {
|
||||
void *pData = NULL;
|
||||
int nData = 0;
|
||||
|
@ -682,9 +706,8 @@ int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sv
|
|||
}
|
||||
}
|
||||
|
||||
if (sver <= 0) {
|
||||
metaError("meta/query: incorrect sver: %" PRId32 ".", sver);
|
||||
code = TSDB_CODE_FAILED;
|
||||
if (ASSERTS(sver > 0, __FILE__, __LINE__, "failed to get table schema version: %d", sver)) {
|
||||
code = TSDB_CODE_NOT_FOUND;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
|
|
|
@ -446,10 +446,10 @@ int32_t rsmaSnapWrite(SRSmaSnapWriter* pWriter, uint8_t* pData, uint32_t nData)
|
|||
// rsma1/rsma2
|
||||
if (pHdr->type == SNAP_DATA_RSMA1) {
|
||||
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) {
|
||||
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) {
|
||||
code = rsmaSnapWriteQTaskInfo(pWriter, pData, nData);
|
||||
} else {
|
||||
|
|
|
@ -520,7 +520,12 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
tqOffsetResetToData(&fetchOffsetNew, 0, 0);
|
||||
}
|
||||
} 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) {
|
||||
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
|
|
|
@ -56,7 +56,7 @@ int32_t tqOffsetSnapRead(STqOffsetReader* pReader, uint8_t** ppData) {
|
|||
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
taosMemoryFree(fname);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t sz = 0;
|
||||
|
|
|
@ -268,7 +268,10 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32
|
|||
}
|
||||
|
||||
taosThreadMutexLock(&pr->readerMutex);
|
||||
tsdbTakeReadSnap((STsdbReader*)pr, tsdbCacheQueryReseek, &pr->pReadSnap);
|
||||
code = tsdbTakeReadSnap((STsdbReader*)pr, tsdbCacheQueryReseek, &pr->pReadSnap);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _end;
|
||||
}
|
||||
pr->pDataFReader = NULL;
|
||||
pr->pDataFReaderLast = NULL;
|
||||
|
||||
|
@ -279,7 +282,7 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32
|
|||
|
||||
code = doExtractCacheRow(pr, lruCache, pKeyInfo->uid, &pRow, &h);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
if (h == NULL) {
|
||||
|
@ -352,7 +355,7 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32
|
|||
STableKeyInfo* pKeyInfo = &pr->pTableList[i];
|
||||
code = doExtractCacheRow(pr, lruCache, pKeyInfo->uid, &pRow, &h);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
if (h == NULL) {
|
||||
|
|
|
@ -458,9 +458,8 @@ static int32_t tsdbMergeFileSet(STsdb *pTsdb, SDFileSet *pSetOld, SDFileSet *pSe
|
|||
taosMemoryFree(pHeadF);
|
||||
}
|
||||
} else {
|
||||
nRef = pHeadF->nRef;
|
||||
*pHeadF = *pSetNew->pHeadF;
|
||||
pHeadF->nRef = nRef;
|
||||
ASSERT(pHeadF->offset == pSetNew->pHeadF->offset);
|
||||
ASSERT(pHeadF->size == pSetNew->pHeadF->size);
|
||||
}
|
||||
|
||||
// data
|
||||
|
@ -481,9 +480,7 @@ static int32_t tsdbMergeFileSet(STsdb *pTsdb, SDFileSet *pSetOld, SDFileSet *pSe
|
|||
taosMemoryFree(pDataF);
|
||||
}
|
||||
} else {
|
||||
nRef = pDataF->nRef;
|
||||
*pDataF = *pSetNew->pDataF;
|
||||
pDataF->nRef = nRef;
|
||||
pDataF->size = pSetNew->pDataF->size;
|
||||
}
|
||||
|
||||
// sma
|
||||
|
@ -504,9 +501,7 @@ static int32_t tsdbMergeFileSet(STsdb *pTsdb, SDFileSet *pSetOld, SDFileSet *pSe
|
|||
taosMemoryFree(pSmaF);
|
||||
}
|
||||
} else {
|
||||
nRef = pSmaF->nRef;
|
||||
*pSmaF = *pSetNew->pSmaF;
|
||||
pSmaF->nRef = nRef;
|
||||
pSmaF->size = pSetNew->pSmaF->size;
|
||||
}
|
||||
|
||||
// stt
|
||||
|
|
|
@ -573,6 +573,68 @@ static SSDataBlock* createResBlock(SQueryTableDataCond* pCond, int32_t capacity)
|
|||
return pResBlock;
|
||||
}
|
||||
|
||||
static int32_t tsdbInitReaderLock(STsdbReader* pReader) {
|
||||
int32_t code = -1;
|
||||
qTrace("tsdb/read: %p, pre-init read mutex: %p, code: %d", pReader, &pReader->readerMutex, code);
|
||||
|
||||
code = taosThreadMutexInit(&pReader->readerMutex, NULL);
|
||||
|
||||
qTrace("tsdb/read: %p, post-init read mutex: %p, code: %d", pReader, &pReader->readerMutex, code);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbUninitReaderLock(STsdbReader* pReader) {
|
||||
int32_t code = -1;
|
||||
qTrace("tsdb/read: %p, pre-uninit read mutex: %p, code: %d", pReader, &pReader->readerMutex, code);
|
||||
|
||||
code = taosThreadMutexDestroy(&pReader->readerMutex);
|
||||
|
||||
qTrace("tsdb/read: %p, post-uninit read mutex: %p, code: %d", pReader, &pReader->readerMutex, code);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbAcquireReader(STsdbReader* pReader) {
|
||||
int32_t code = -1;
|
||||
qTrace("tsdb/read: %p, pre-take read mutex: %p, code: %d", pReader, &pReader->readerMutex, code);
|
||||
|
||||
code = taosThreadMutexLock(&pReader->readerMutex);
|
||||
|
||||
qTrace("tsdb/read: %p, post-take read mutex: %p, code: %d", pReader, &pReader->readerMutex, code);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbTryAcquireReader(STsdbReader* pReader) {
|
||||
int32_t code = -1;
|
||||
qTrace("tsdb/read: %p, pre-trytake read mutex: %p, code: %d", pReader, &pReader->readerMutex, code);
|
||||
|
||||
code = taosThreadMutexTryLock(&pReader->readerMutex);
|
||||
|
||||
qTrace("tsdb/read: %p, post-trytake read mutex: %p, code: %d", pReader, &pReader->readerMutex, code);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbReleaseReader(STsdbReader* pReader) {
|
||||
int32_t code = -1;
|
||||
qTrace("tsdb/read: %p, pre-untake read mutex: %p, code: %d", pReader, &pReader->readerMutex, code);
|
||||
|
||||
code = taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
|
||||
qTrace("tsdb/read: %p, post-untake read mutex: %p, code: %d", pReader, &pReader->readerMutex, code);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void tsdbReleaseDataBlock(STsdbReader* pReader) {
|
||||
SReaderStatus* pStatus = &pReader->status;
|
||||
if (!pStatus->composedDataBlock) {
|
||||
tsdbReleaseReader(pReader);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t tsdbReaderCreate(SVnode* pVnode, SQueryTableDataCond* pCond, STsdbReader** ppReader, int32_t capacity,
|
||||
SSDataBlock* pResBlock, const char* idstr) {
|
||||
int32_t code = 0;
|
||||
|
@ -636,7 +698,7 @@ static int32_t tsdbReaderCreate(SVnode* pVnode, SQueryTableDataCond* pCond, STsd
|
|||
|
||||
setColumnIdSlotList(&pReader->suppInfo, pCond->colList, pCond->pSlotList, pCond->numOfCols);
|
||||
|
||||
taosThreadMutexInit(&pReader->readerMutex, NULL);
|
||||
tsdbInitReaderLock(pReader);
|
||||
|
||||
*ppReader = pReader;
|
||||
return code;
|
||||
|
@ -1776,12 +1838,15 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
}
|
||||
|
||||
if (minKey == k.ts) {
|
||||
STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
|
||||
if (pSchema == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
if (init) {
|
||||
tsdbRowMerge(&merge, pRow);
|
||||
tsdbRowMergerAdd(&merge, pRow, pSchema);
|
||||
} else {
|
||||
init = true;
|
||||
STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
|
||||
int32_t code = tsdbRowMergerInit(&merge, pRow, pSchema);
|
||||
int32_t code = tsdbRowMergerInit(&merge, pRow, pSchema);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -2882,7 +2947,7 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
|||
|
||||
if (pResBlock->info.rows > 0) {
|
||||
tsdbDebug("%p uid:%" PRIu64 ", composed data block created, brange:%" PRIu64 "-%" PRIu64
|
||||
" rows:%d, elapsed time:%.2f ms %s",
|
||||
" 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);
|
||||
}
|
||||
|
@ -2932,7 +2997,7 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
|||
|
||||
if (pResBlock->info.rows > 0) {
|
||||
tsdbDebug("%p uid:%" PRIu64 ", composed data block created, brange:%" PRIu64 "-%" PRIu64
|
||||
" rows:%d, elapsed time:%.2f ms %s",
|
||||
" 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);
|
||||
}
|
||||
|
@ -4013,8 +4078,9 @@ void tsdbReaderClose(STsdbReader* pReader) {
|
|||
|
||||
qTrace("tsdb/reader: %p, untake snapshot", pReader);
|
||||
tsdbUntakeReadSnap(pReader, pReader->pReadSnap, true);
|
||||
pReader->pReadSnap = NULL;
|
||||
|
||||
taosThreadMutexDestroy(&pReader->readerMutex);
|
||||
tsdbUninitReaderLock(pReader);
|
||||
|
||||
taosMemoryFree(pReader->status.uidCheckInfo.tableUidList);
|
||||
SIOCostSummary* pCost = &pReader->cost;
|
||||
|
@ -4096,6 +4162,28 @@ int32_t tsdbReaderSuspend(STsdbReader* pReader) {
|
|||
// pInfo->lastKey = ts;
|
||||
}
|
||||
} else {
|
||||
// resetDataBlockScanInfo excluding lastKey
|
||||
STableBlockScanInfo** p = NULL;
|
||||
|
||||
while ((p = taosHashIterate(pStatus->pTableMap, p)) != NULL) {
|
||||
STableBlockScanInfo* pInfo = *(STableBlockScanInfo**)p;
|
||||
|
||||
pInfo->iterInit = false;
|
||||
pInfo->iter.hasVal = false;
|
||||
pInfo->iiter.hasVal = false;
|
||||
|
||||
if (pInfo->iter.iter != NULL) {
|
||||
pInfo->iter.iter = tsdbTbDataIterDestroy(pInfo->iter.iter);
|
||||
}
|
||||
|
||||
if (pInfo->iiter.iter != NULL) {
|
||||
pInfo->iiter.iter = tsdbTbDataIterDestroy(pInfo->iiter.iter);
|
||||
}
|
||||
|
||||
pInfo->delSkyline = taosArrayDestroy(pInfo->delSkyline);
|
||||
// pInfo->lastKey = ts;
|
||||
}
|
||||
|
||||
pBlockScanInfo = pStatus->pTableIter == NULL ? NULL : *pStatus->pTableIter;
|
||||
if (pBlockScanInfo) {
|
||||
// save lastKey to restore memory iterator
|
||||
|
@ -4104,7 +4192,8 @@ int32_t tsdbReaderSuspend(STsdbReader* pReader) {
|
|||
|
||||
// reset current current table's data block scan info,
|
||||
pBlockScanInfo->iterInit = false;
|
||||
// pBlockScanInfo->iiter.hasVal = false;
|
||||
pBlockScanInfo->iter.hasVal = false;
|
||||
pBlockScanInfo->iiter.hasVal = false;
|
||||
if (pBlockScanInfo->iter.iter != NULL) {
|
||||
pBlockScanInfo->iter.iter = tsdbTbDataIterDestroy(pBlockScanInfo->iter.iter);
|
||||
}
|
||||
|
@ -4138,16 +4227,16 @@ static int32_t tsdbSetQueryReseek(void* pQHandle) {
|
|||
int32_t code = 0;
|
||||
STsdbReader* pReader = pQHandle;
|
||||
|
||||
code = taosThreadMutexTryLock(&pReader->readerMutex);
|
||||
code = tsdbTryAcquireReader(pReader);
|
||||
if (code == 0) {
|
||||
if (pReader->suspended) {
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
return code;
|
||||
}
|
||||
|
||||
tsdbReaderSuspend(pReader);
|
||||
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
|
||||
return code;
|
||||
} else if (code == EBUSY) {
|
||||
|
@ -4248,8 +4337,9 @@ bool tsdbNextDataBlock(STsdbReader* pReader) {
|
|||
|
||||
SReaderStatus* pStatus = &pReader->status;
|
||||
|
||||
qTrace("tsdb/read: %p, take read mutex", pReader);
|
||||
taosThreadMutexLock(&pReader->readerMutex);
|
||||
int32_t code = tsdbAcquireReader(pReader);
|
||||
qTrace("tsdb/read: %p, take read mutex, code: %d", pReader, code);
|
||||
|
||||
if (pReader->suspended) {
|
||||
tsdbReaderResume(pReader);
|
||||
}
|
||||
|
@ -4261,7 +4351,7 @@ bool tsdbNextDataBlock(STsdbReader* pReader) {
|
|||
pStatus = &pReader->innerReader[0]->status;
|
||||
if (pStatus->composedDataBlock) {
|
||||
qTrace("tsdb/read: %p, unlock read mutex", pReader);
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -4284,7 +4374,7 @@ bool tsdbNextDataBlock(STsdbReader* pReader) {
|
|||
if (ret) {
|
||||
if (pStatus->composedDataBlock) {
|
||||
qTrace("tsdb/read: %p, unlock read mutex", pReader);
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -4304,7 +4394,7 @@ bool tsdbNextDataBlock(STsdbReader* pReader) {
|
|||
pStatus = &pReader->innerReader[1]->status;
|
||||
if (pStatus->composedDataBlock) {
|
||||
qTrace("tsdb/read: %p, unlock read mutex", pReader);
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
}
|
||||
|
||||
return ret1;
|
||||
|
@ -4312,7 +4402,7 @@ bool tsdbNextDataBlock(STsdbReader* pReader) {
|
|||
}
|
||||
|
||||
qTrace("tsdb/read: %p, unlock read mutex", pReader);
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -4471,13 +4561,6 @@ static SSDataBlock* doRetrieveDataBlock(STsdbReader* pReader) {
|
|||
return pReader->pResBlock;
|
||||
}
|
||||
|
||||
void tsdbReleaseDataBlock(STsdbReader* pReader) {
|
||||
// SReaderStatus* pStatus = &pReader->status;
|
||||
// if (!pStatus->composedDataBlock) {
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
//}
|
||||
}
|
||||
|
||||
SSDataBlock* tsdbRetrieveDataBlock(STsdbReader* pReader, SArray* pIdList) {
|
||||
STsdbReader* pTReader = pReader;
|
||||
if (pReader->type == TIMEWINDOW_RANGE_EXTERNAL) {
|
||||
|
@ -4496,7 +4579,7 @@ SSDataBlock* tsdbRetrieveDataBlock(STsdbReader* pReader, SArray* pIdList) {
|
|||
SSDataBlock* ret = doRetrieveDataBlock(pTReader);
|
||||
|
||||
qTrace("tsdb/read-retrieve: %p, unlock read mutex", pReader);
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -4505,7 +4588,7 @@ int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
|
|||
SReaderStatus* pStatus = &pReader->status;
|
||||
|
||||
qTrace("tsdb/reader-reset: %p, take read mutex", pReader);
|
||||
taosThreadMutexLock(&pReader->readerMutex);
|
||||
tsdbAcquireReader(pReader);
|
||||
|
||||
if (pReader->suspended) {
|
||||
tsdbReaderResume(pReader);
|
||||
|
@ -4514,7 +4597,7 @@ int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
|
|||
if (isEmptyQueryTimeWindow(&pReader->window) || pReader->pReadSnap == NULL) {
|
||||
tsdbDebug("tsdb reader reset return %p", pReader->pReadSnap);
|
||||
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -4552,7 +4635,7 @@ int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
|
|||
tsdbError("%p reset reader failed, numOfTables:%d, query range:%" PRId64 " - %" PRId64 " in query %s", pReader,
|
||||
numOfTables, pReader->window.skey, pReader->window.ekey, pReader->idStr);
|
||||
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -4563,7 +4646,7 @@ int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
|
|||
pReader, pReader->suid, numOfTables, pCond->twindows.skey, pReader->window.skey, pReader->window.ekey,
|
||||
pReader->idStr);
|
||||
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -4648,7 +4731,7 @@ int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
|
|||
int64_t rows = 0;
|
||||
|
||||
SReaderStatus* pStatus = &pReader->status;
|
||||
taosThreadMutexLock(&pReader->readerMutex);
|
||||
tsdbAcquireReader(pReader);
|
||||
if (pReader->suspended) {
|
||||
tsdbReaderResume(pReader);
|
||||
}
|
||||
|
@ -4678,7 +4761,7 @@ int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
|
|||
pStatus->pTableIter = taosHashIterate(pStatus->pTableMap, pStatus->pTableIter);
|
||||
}
|
||||
|
||||
taosThreadMutexUnlock(&pReader->readerMutex);
|
||||
tsdbReleaseReader(pReader);
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -732,6 +732,7 @@ int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema)
|
|||
tsdbRowGetColVal(pRow, pTSchema, jCol++, pColVal);
|
||||
|
||||
if (key.version > pMerger->version) {
|
||||
#if 0
|
||||
if (!COL_VAL_IS_NONE(pColVal)) {
|
||||
if ((!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
SColVal *tColVal = taosArrayGet(pMerger->pArray, iCol);
|
||||
|
@ -747,6 +748,28 @@ int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema)
|
|||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!COL_VAL_IS_NONE(pColVal)) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
|
||||
if (!COL_VAL_IS_NULL(pColVal)) {
|
||||
code = tRealloc(&pTColVal->value.pData, pColVal->value.nData);
|
||||
if (code) return code;
|
||||
|
||||
pTColVal->value.nData = pColVal->value.nData;
|
||||
if (pTColVal->value.nData) {
|
||||
memcpy(pTColVal->value.pData, pColVal->value.pData, pTColVal->value.nData);
|
||||
}
|
||||
pTColVal->flag = 0;
|
||||
} else {
|
||||
tFree(pTColVal->value.pData);
|
||||
pTColVal->value.pData = NULL;
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
}
|
||||
} else {
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
}
|
||||
}
|
||||
} else if (key.version < pMerger->version) {
|
||||
SColVal *tColVal = (SColVal *)taosArrayGet(pMerger->pArray, iCol);
|
||||
if (COL_VAL_IS_NONE(tColVal) && !COL_VAL_IS_NONE(pColVal)) {
|
||||
|
@ -1110,6 +1133,7 @@ _exit:
|
|||
void tBlockDataReset(SBlockData *pBlockData) {
|
||||
pBlockData->suid = 0;
|
||||
pBlockData->uid = 0;
|
||||
pBlockData->nRow = 0;
|
||||
}
|
||||
|
||||
void tBlockDataClear(SBlockData *pBlockData) {
|
||||
|
|
|
@ -455,7 +455,7 @@ int32_t vnodeSnapWrite(SVSnapWriter *pWriter, uint8_t *pData, uint32_t nData) {
|
|||
if (code) goto _err;
|
||||
}
|
||||
|
||||
code = tsdbSnapWrite(pWriter->pTsdbSnapWriter, pData, nData);
|
||||
code = tsdbSnapWrite(pWriter->pTsdbSnapWriter, pHdr);
|
||||
if (code) goto _err;
|
||||
} break;
|
||||
case SNAP_DATA_TQ_HANDLE: {
|
||||
|
|
|
@ -805,6 +805,7 @@ int32_t ctgMakeVgArray(SDBVgInfo* dbInfo);
|
|||
int32_t ctgAcquireVgMetaFromCache(SCatalog *pCtg, const char *dbFName, const char *tbName, SCtgDBCache **pDb, SCtgTbCache **pTb);
|
||||
int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCtgTbCache **pTb, STableMeta **pTableMeta, char* dbFName);
|
||||
void ctgReleaseVgMetaToCache(SCatalog *pCtg, SCtgDBCache *dbCache, SCtgTbCache *pCache);
|
||||
void ctgReleaseTbMetaToCache(SCatalog *pCtg, SCtgDBCache *dbCache, SCtgTbCache *pCache);
|
||||
|
||||
extern SCatalogMgmt gCtgMgmt;
|
||||
extern SCtgDebug gCTGDebug;
|
||||
|
|
|
@ -598,10 +598,16 @@ int32_t ctgGetCachedTbVgMeta(SCatalog* pCtg, const SName* pTableName, SVgroupInf
|
|||
|
||||
CTG_ERR_JRET(ctgGetVgInfoFromHashValue(pCtg, dbCache->vgCache.vgInfo, pTableName, pVgroup));
|
||||
|
||||
ctgRUnlockVgInfo(dbCache);
|
||||
|
||||
SCtgTbMetaCtx ctx = {0};
|
||||
ctx.pName = (SName*)pTableName;
|
||||
ctx.flag = CTG_FLAG_UNKNOWN_STB;
|
||||
CTG_ERR_JRET(ctgCopyTbMeta(pCtg, &ctx, &dbCache, &tbCache, pTableMeta, db));
|
||||
code = ctgCopyTbMeta(pCtg, &ctx, &dbCache, &tbCache, pTableMeta, db);
|
||||
|
||||
ctgReleaseTbMetaToCache(pCtg, dbCache, tbCache);
|
||||
|
||||
CTG_RET(code);
|
||||
|
||||
_return:
|
||||
|
||||
|
|
|
@ -999,6 +999,7 @@ int32_t ctgHandleGetTbMetaRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBuf
|
|||
CTG_ERR_JRET(ctgGetTbMetaFromVnode(pCtg, pConn, pName, &vgInfo, NULL, tReq));
|
||||
|
||||
ctgReleaseVgInfoToCache(pCtg, dbCache);
|
||||
dbCache = NULL;
|
||||
} else {
|
||||
SBuildUseDBInput input = {0};
|
||||
|
||||
|
@ -1168,6 +1169,7 @@ int32_t ctgHandleGetTbMetasRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBu
|
|||
CTG_ERR_JRET(ctgGetTbMetaFromVnode(pCtg, pConn, pName, &vgInfo, NULL, tReq));
|
||||
|
||||
ctgReleaseVgInfoToCache(pCtg, dbCache);
|
||||
dbCache = NULL;
|
||||
} else {
|
||||
SBuildUseDBInput input = {0};
|
||||
|
||||
|
|
|
@ -2118,7 +2118,7 @@ int32_t ctgOpUpdateEpset(SCtgCacheOperation *operation) {
|
|||
|
||||
_return:
|
||||
|
||||
if (dbCache) {
|
||||
if (code == TSDB_CODE_SUCCESS && dbCache) {
|
||||
ctgWUnlockVgInfo(dbCache);
|
||||
}
|
||||
|
||||
|
|
|
@ -281,10 +281,10 @@ static void setCreateDBResultIntoDataBlock(SSDataBlock* pBlock, char* dbFName, S
|
|||
len += sprintf(
|
||||
buf2 + VARSTR_HEADER_SIZE,
|
||||
"CREATE DATABASE `%s` BUFFER %d CACHESIZE %d CACHEMODEL '%s' COMP %d DURATION %dm "
|
||||
"WAL_FSYNC_PERIOD %d MAXROWS %d MINROWS %d KEEP %dm,%dm,%dm PAGES %d PAGESIZE %d PRECISION '%s' REPLICA %d "
|
||||
"WAL_FSYNC_PERIOD %d MAXROWS %d MINROWS %d STT_TRIGGER %d KEEP %dm,%dm,%dm PAGES %d PAGESIZE %d PRECISION '%s' REPLICA %d "
|
||||
"WAL_LEVEL %d VGROUPS %d SINGLE_STABLE %d",
|
||||
dbFName, pCfg->buffer, pCfg->cacheSize, cacheModelStr(pCfg->cacheLast), pCfg->compression, pCfg->daysPerFile,
|
||||
pCfg->walFsyncPeriod, pCfg->maxRows, pCfg->minRows, pCfg->daysToKeep0, pCfg->daysToKeep1, pCfg->daysToKeep2,
|
||||
pCfg->walFsyncPeriod, pCfg->maxRows, pCfg->minRows, pCfg->sstTrigger, pCfg->daysToKeep0, pCfg->daysToKeep1, pCfg->daysToKeep2,
|
||||
pCfg->pages, pCfg->pageSize, prec, pCfg->replications, pCfg->walLevel, pCfg->numOfVgroups,
|
||||
1 == pCfg->numOfStables);
|
||||
|
||||
|
|
|
@ -24,12 +24,16 @@
|
|||
static TdThreadOnce initPoolOnce = PTHREAD_ONCE_INIT;
|
||||
int32_t exchangeObjRefPool = -1;
|
||||
|
||||
static void initRefPool() { exchangeObjRefPool = taosOpenRef(1024, doDestroyExchangeOperatorInfo); }
|
||||
static void cleanupRefPool() {
|
||||
int32_t ref = atomic_val_compare_exchange_32(&exchangeObjRefPool, exchangeObjRefPool, 0);
|
||||
taosCloseRef(ref);
|
||||
}
|
||||
|
||||
static void initRefPool() {
|
||||
exchangeObjRefPool = taosOpenRef(1024, doDestroyExchangeOperatorInfo);
|
||||
atexit(cleanupRefPool);
|
||||
}
|
||||
|
||||
static int32_t doSetSMABlock(SOperatorInfo* pOperator, void* input, size_t numOfBlocks, int32_t type, char* id) {
|
||||
ASSERT(pOperator != NULL);
|
||||
if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
|
||||
|
@ -448,7 +452,6 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId,
|
|||
SExecTaskInfo** pTask = (SExecTaskInfo**)pTaskInfo;
|
||||
|
||||
taosThreadOnce(&initPoolOnce, initRefPool);
|
||||
atexit(cleanupRefPool);
|
||||
|
||||
qDebug("start to create subplan task, TID:0x%" PRIx64 " QID:0x%" PRIx64, taskId, pSubplan->id.queryId);
|
||||
|
||||
|
|
|
@ -593,8 +593,11 @@ void* getCurrentDataGroupInfo(const SPartitionOperatorInfo* pInfo, SDataGroupInf
|
|||
|
||||
int32_t pageId = 0;
|
||||
pPage = getNewBufPage(pInfo->pBuf, &pageId);
|
||||
taosArrayPush(p->pPageList, &pageId);
|
||||
if (pPage == NULL) {
|
||||
return pPage;
|
||||
}
|
||||
|
||||
taosArrayPush(p->pPageList, &pageId);
|
||||
*(int32_t*)pPage = 0;
|
||||
} else {
|
||||
int32_t* curId = taosArrayGetLast(p->pPageList);
|
||||
|
@ -612,6 +615,11 @@ void* getCurrentDataGroupInfo(const SPartitionOperatorInfo* pInfo, SDataGroupInf
|
|||
// add a new page for current group
|
||||
int32_t pageId = 0;
|
||||
pPage = getNewBufPage(pInfo->pBuf, &pageId);
|
||||
if (pPage == NULL) {
|
||||
qError("failed to get new buffer, code:%s", tstrerror(terrno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
taosArrayPush(p->pPageList, &pageId);
|
||||
memset(pPage, 0, getBufPageSize(pInfo->pBuf));
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ typedef struct SSysTableScanInfo {
|
|||
int64_t numOfBlocks; // extract basic running information.
|
||||
SLoadRemoteDataInfo loadInfo;
|
||||
|
||||
int32_t tbnameSlotId;
|
||||
int32_t tbnameSlotId;
|
||||
} SSysTableScanInfo;
|
||||
|
||||
typedef struct {
|
||||
|
@ -81,10 +81,10 @@ typedef struct MergeIndex {
|
|||
} MergeIndex;
|
||||
|
||||
typedef struct SBlockDistInfo {
|
||||
SSDataBlock* pResBlock;
|
||||
STsdbReader* pHandle;
|
||||
SReadHandle readHandle;
|
||||
uint64_t uid; // table uid
|
||||
SSDataBlock* pResBlock;
|
||||
STsdbReader* pHandle;
|
||||
SReadHandle readHandle;
|
||||
uint64_t uid; // table uid
|
||||
} SBlockDistInfo;
|
||||
|
||||
static int32_t sysChkFilter__Comm(SNode* pNode);
|
||||
|
@ -129,20 +129,20 @@ static char* SYSTABLE_IDX_COLUMN[] = {"table_name", "db_name", "create_time"
|
|||
|
||||
static char* SYSTABLE_SPECIAL_COL[] = {"db_name", "vgroup_id"};
|
||||
|
||||
static int32_t buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capacity);
|
||||
static SSDataBlock* buildInfoSchemaTableMetaBlock(char* tableName);
|
||||
static void destroySysScanOperator(void* param);
|
||||
static int32_t loadSysTableCallback(void* param, SDataBuf* pMsg, int32_t code);
|
||||
static SSDataBlock* doFilterResult(SSDataBlock* pDataBlock, SFilterInfo* pFilterInfo);
|
||||
static int32_t buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capacity);
|
||||
static SSDataBlock* buildInfoSchemaTableMetaBlock(char* tableName);
|
||||
static void destroySysScanOperator(void* param);
|
||||
static int32_t loadSysTableCallback(void* param, SDataBuf* pMsg, int32_t code);
|
||||
static SSDataBlock* doFilterResult(SSDataBlock* pDataBlock, SFilterInfo* pFilterInfo);
|
||||
static __optSysFilter optSysGetFilterFunc(int32_t ctype, bool* reverse);
|
||||
|
||||
static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo, SMetaReader* smrSuperTable,
|
||||
SMetaReader* smrChildTable, const char* dbname, const char* tableName,
|
||||
int32_t* pNumOfRows, const SSDataBlock* dataBlock);
|
||||
|
||||
static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname,
|
||||
int32_t* pNumOfRows, const SSDataBlock* dataBlock,
|
||||
char* tName, SSchemaWrapper* schemaRow, char* tableType);
|
||||
static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname, int32_t* pNumOfRows,
|
||||
const SSDataBlock* dataBlock, char* tName, SSchemaWrapper* schemaRow,
|
||||
char* tableType);
|
||||
|
||||
static void relocateAndFilterSysTagsScanResult(SSysTableScanInfo* pInfo, int32_t numOfRows, SSDataBlock* dataBlock,
|
||||
SFilterInfo* pFilterInfo);
|
||||
|
@ -204,11 +204,11 @@ int32_t sysFilte__TableName(void* arg, SNode* pNode, SArray* result) {
|
|||
if (func == NULL) return -1;
|
||||
|
||||
SMetaFltParam param = {.suid = 0,
|
||||
.cid = 0,
|
||||
.type = TSDB_DATA_TYPE_VARCHAR,
|
||||
.val = pVal->datum.p,
|
||||
.reverse = reverse,
|
||||
.filterFunc = func};
|
||||
.cid = 0,
|
||||
.type = TSDB_DATA_TYPE_VARCHAR,
|
||||
.val = pVal->datum.p,
|
||||
.reverse = reverse,
|
||||
.filterFunc = func};
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -223,11 +223,11 @@ int32_t sysFilte__CreateTime(void* arg, SNode* pNode, SArray* result) {
|
|||
if (func == NULL) return -1;
|
||||
|
||||
SMetaFltParam param = {.suid = 0,
|
||||
.cid = 0,
|
||||
.type = TSDB_DATA_TYPE_BIGINT,
|
||||
.val = &pVal->datum.i,
|
||||
.reverse = reverse,
|
||||
.filterFunc = func};
|
||||
.cid = 0,
|
||||
.type = TSDB_DATA_TYPE_BIGINT,
|
||||
.val = &pVal->datum.i,
|
||||
.reverse = reverse,
|
||||
.filterFunc = func};
|
||||
|
||||
int32_t ret = metaFilterCreateTime(pMeta, ¶m, result);
|
||||
return ret;
|
||||
|
@ -355,9 +355,9 @@ static int32_t optSysMergeRslt(SArray* mRslt, SArray* rslt);
|
|||
static SSDataBlock* sysTableScanFromMNode(SOperatorInfo* pOperator, SSysTableScanInfo* pInfo, const char* name,
|
||||
SExecTaskInfo* pTaskInfo);
|
||||
void extractTbnameSlotId(SSysTableScanInfo* pInfo, const SScanPhysiNode* pScanNode);
|
||||
static SSDataBlock* sysTableScanFillTbName(SOperatorInfo* pOperator, const SSysTableScanInfo* pInfo,
|
||||
const char* name, SSDataBlock* pBlock);
|
||||
__optSysFilter optSysGetFilterFunc(int32_t ctype, bool* reverse) {
|
||||
static SSDataBlock* sysTableScanFillTbName(SOperatorInfo* pOperator, const SSysTableScanInfo* pInfo, const char* name,
|
||||
SSDataBlock* pBlock);
|
||||
__optSysFilter optSysGetFilterFunc(int32_t ctype, bool* reverse) {
|
||||
if (ctype == OP_TYPE_LOWER_EQUAL || ctype == OP_TYPE_LOWER_THAN) {
|
||||
*reverse = true;
|
||||
}
|
||||
|
@ -479,13 +479,13 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
|
|||
}
|
||||
}
|
||||
|
||||
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
SSchemaWrapper *schemaRow = NULL;
|
||||
if(smrTable.me.type == TSDB_SUPER_TABLE){
|
||||
schemaRow = &smrTable.me.stbEntry.schemaRow;
|
||||
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
SSchemaWrapper* schemaRow = NULL;
|
||||
if (smrTable.me.type == TSDB_SUPER_TABLE) {
|
||||
schemaRow = &smrTable.me.stbEntry.schemaRow;
|
||||
STR_TO_VARSTR(typeName, "CHILD_TABLE");
|
||||
}else if(smrTable.me.type == TSDB_NORMAL_TABLE){
|
||||
schemaRow = &smrTable.me.ntbEntry.schemaRow;
|
||||
} else if (smrTable.me.type == TSDB_NORMAL_TABLE) {
|
||||
schemaRow = &smrTable.me.ntbEntry.schemaRow;
|
||||
STR_TO_VARSTR(typeName, "NORMAL_TABLE");
|
||||
}
|
||||
|
||||
|
@ -507,50 +507,50 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
|
|||
pInfo->pCur = metaOpenTbCursor(pInfo->readHandle.meta);
|
||||
}
|
||||
|
||||
SHashObj *stableSchema = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
||||
SHashObj* stableSchema = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
||||
taosHashSetFreeFp(stableSchema, tDeleteSSchemaWrapperForHash);
|
||||
while ((ret = metaTbCursorNext(pInfo->pCur, TSDB_TABLE_MAX)) == 0) {
|
||||
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
|
||||
SSchemaWrapper *schemaRow = NULL;
|
||||
SSchemaWrapper* schemaRow = NULL;
|
||||
|
||||
if(pInfo->pCur->mr.me.type == TSDB_SUPER_TABLE){
|
||||
if (pInfo->pCur->mr.me.type == TSDB_SUPER_TABLE) {
|
||||
qDebug("sysTableScanUserCols cursor get super table");
|
||||
void *schema = taosHashGet(stableSchema, &pInfo->pCur->mr.me.uid, sizeof(int64_t));
|
||||
if(schema == NULL){
|
||||
SSchemaWrapper *schemaWrapper = tCloneSSchemaWrapper(&pInfo->pCur->mr.me.stbEntry.schemaRow);
|
||||
void* schema = taosHashGet(stableSchema, &pInfo->pCur->mr.me.uid, sizeof(int64_t));
|
||||
if (schema == NULL) {
|
||||
SSchemaWrapper* schemaWrapper = tCloneSSchemaWrapper(&pInfo->pCur->mr.me.stbEntry.schemaRow);
|
||||
taosHashPut(stableSchema, &pInfo->pCur->mr.me.uid, sizeof(int64_t), &schemaWrapper, POINTER_BYTES);
|
||||
}
|
||||
continue;
|
||||
}else if (pInfo->pCur->mr.me.type == TSDB_CHILD_TABLE) {
|
||||
} else if (pInfo->pCur->mr.me.type == TSDB_CHILD_TABLE) {
|
||||
qDebug("sysTableScanUserCols cursor get child table");
|
||||
STR_TO_VARSTR(typeName, "CHILD_TABLE");
|
||||
STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
|
||||
|
||||
int64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
|
||||
void *schema = taosHashGet(stableSchema, &pInfo->pCur->mr.me.ctbEntry.suid, sizeof(int64_t));
|
||||
if(schema != NULL){
|
||||
schemaRow = *(SSchemaWrapper **)schema;
|
||||
}else{
|
||||
void* schema = taosHashGet(stableSchema, &pInfo->pCur->mr.me.ctbEntry.suid, sizeof(int64_t));
|
||||
if (schema != NULL) {
|
||||
schemaRow = *(SSchemaWrapper**)schema;
|
||||
} else {
|
||||
tDecoderClear(&pInfo->pCur->mr.coder);
|
||||
int code = metaGetTableEntryByUid(&pInfo->pCur->mr, suid);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
// terrno has been set by metaGetTableEntryByName, therefore, return directly
|
||||
qError("sysTableScanUserCols get meta by suid:%"PRId64 " error, code:%d", suid, code);
|
||||
qError("sysTableScanUserCols get meta by suid:%" PRId64 " error, code:%d", suid, code);
|
||||
blockDataDestroy(dataBlock);
|
||||
pInfo->loadInfo.totalRows = 0;
|
||||
taosHashCleanup(stableSchema);
|
||||
return NULL;
|
||||
}
|
||||
schemaRow = &pInfo->pCur->mr.me.stbEntry.schemaRow;
|
||||
schemaRow = &pInfo->pCur->mr.me.stbEntry.schemaRow;
|
||||
}
|
||||
}else if(pInfo->pCur->mr.me.type == TSDB_NORMAL_TABLE){
|
||||
} else if (pInfo->pCur->mr.me.type == TSDB_NORMAL_TABLE) {
|
||||
qDebug("sysTableScanUserCols cursor get normal table");
|
||||
schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
|
||||
schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
|
||||
STR_TO_VARSTR(typeName, "NORMAL_TABLE");
|
||||
STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
|
||||
}else{
|
||||
} else {
|
||||
qDebug("sysTableScanUserCols cursor get invalid table");
|
||||
continue;
|
||||
}
|
||||
|
@ -665,6 +665,7 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
|
|||
pInfo->pCur = metaOpenTbCursor(pInfo->readHandle.meta);
|
||||
}
|
||||
|
||||
bool blockFull = false;
|
||||
while ((ret = metaTbCursorNext(pInfo->pCur, TSDB_SUPER_TABLE)) == 0) {
|
||||
if (pInfo->pCur->mr.me.type != TSDB_CHILD_TABLE) {
|
||||
continue;
|
||||
|
@ -686,17 +687,25 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
|
|||
T_LONG_JMP(pTaskInfo->env, terrno);
|
||||
}
|
||||
|
||||
sysTableUserTagsFillOneTableTags(pInfo, &smrSuperTable, &pInfo->pCur->mr, dbname, tableName, &numOfRows, dataBlock);
|
||||
if ((smrSuperTable.me.stbEntry.schemaTag.nCols + numOfRows) > pOperator->resultInfo.capacity) {
|
||||
metaTbCursorPrev(pInfo->pCur);
|
||||
blockFull = true;
|
||||
} else {
|
||||
sysTableUserTagsFillOneTableTags(pInfo, &smrSuperTable, &pInfo->pCur->mr, dbname, tableName, &numOfRows,
|
||||
dataBlock);
|
||||
}
|
||||
|
||||
metaReaderClear(&smrSuperTable);
|
||||
|
||||
if (numOfRows >= pOperator->resultInfo.capacity) {
|
||||
if (blockFull || numOfRows >= pOperator->resultInfo.capacity) {
|
||||
relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo);
|
||||
numOfRows = 0;
|
||||
|
||||
if (pInfo->pRes->info.rows > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
blockFull = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -902,10 +911,10 @@ static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo,
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname,
|
||||
int32_t* pNumOfRows, const SSDataBlock* dataBlock, char* tName,
|
||||
SSchemaWrapper* schemaRow, char* tableType) {
|
||||
if(schemaRow == NULL){
|
||||
static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname, int32_t* pNumOfRows,
|
||||
const SSDataBlock* dataBlock, char* tName, SSchemaWrapper* schemaRow,
|
||||
char* tableType) {
|
||||
if (schemaRow == NULL) {
|
||||
qError("sysTableUserColsFillOneTableCols schemaRow is NULL");
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -941,9 +950,8 @@ static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo,
|
|||
colTypeLen += sprintf(varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)(schemaRow->pSchema[i].bytes - VARSTR_HEADER_SIZE));
|
||||
} else if (colType == TSDB_DATA_TYPE_NCHAR) {
|
||||
colTypeLen += sprintf(
|
||||
varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)((schemaRow->pSchema[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
|
||||
colTypeLen += sprintf(varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)((schemaRow->pSchema[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
|
||||
}
|
||||
varDataSetLen(colTypeStr, colTypeLen);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*)colTypeStr, false);
|
||||
|
@ -1550,9 +1558,9 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
|||
if (pInfo->showRewrite) {
|
||||
getDBNameFromCondition(pInfo->pCondition, dbName);
|
||||
sprintf(pInfo->req.db, "%d.%s", pInfo->accountId, dbName);
|
||||
}else if(strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0){
|
||||
} else if (strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0) {
|
||||
getDBNameFromCondition(pInfo->pCondition, dbName);
|
||||
if(dbName[0]) sprintf(pInfo->req.db, "%d.%s", pInfo->accountId, dbName);
|
||||
if (dbName[0]) sprintf(pInfo->req.db, "%d.%s", pInfo->accountId, dbName);
|
||||
sysTableIsCondOnOneTable(pInfo->pCondition, pInfo->req.filterTb);
|
||||
}
|
||||
|
||||
|
@ -1573,12 +1581,12 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
|||
return sysTableScanFillTbName(pOperator, pInfo, name, pBlock);
|
||||
}
|
||||
|
||||
static SSDataBlock* sysTableScanFillTbName(SOperatorInfo* pOperator, const SSysTableScanInfo* pInfo,
|
||||
const char* name, SSDataBlock* pBlock) {
|
||||
static SSDataBlock* sysTableScanFillTbName(SOperatorInfo* pOperator, const SSysTableScanInfo* pInfo, const char* name,
|
||||
SSDataBlock* pBlock) {
|
||||
if (pBlock != NULL) {
|
||||
if (pInfo->tbnameSlotId != -1) {
|
||||
SColumnInfoData* pColumnInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, pInfo->tbnameSlotId);
|
||||
char varTbName[TSDB_TABLE_FNAME_LEN - 1 + VARSTR_HEADER_SIZE] = {0};
|
||||
char varTbName[TSDB_TABLE_FNAME_LEN - 1 + VARSTR_HEADER_SIZE] = {0};
|
||||
memcpy(varDataVal(varTbName), name, strlen(name));
|
||||
varDataSetLen(varTbName, strlen(name));
|
||||
for (int i = 0; i < pBlock->info.rows; ++i) {
|
||||
|
@ -1669,7 +1677,7 @@ static SSDataBlock* sysTableScanFromMNode(SOperatorInfo* pOperator, SSysTableSca
|
|||
|
||||
SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode* pScanPhyNode,
|
||||
const char* pUser, SExecTaskInfo* pTaskInfo) {
|
||||
int32_t code = TDB_CODE_SUCCESS;
|
||||
int32_t code = TDB_CODE_SUCCESS;
|
||||
SSysTableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SSysTableScanInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
|
@ -1717,10 +1725,11 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScan
|
|||
setOperatorInfo(pOperator, "SysTableScanOperator", QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN, false, OP_NOT_OPENED,
|
||||
pInfo, pTaskInfo);
|
||||
pOperator->exprSupp.numOfExprs = taosArrayGetSize(pInfo->pRes->pDataBlock);
|
||||
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doSysTableScan, NULL, destroySysScanOperator, optrDefaultBufFn, NULL);
|
||||
pOperator->fpSet =
|
||||
createOperatorFpSet(optrDummyOpenFn, doSysTableScan, NULL, destroySysScanOperator, optrDefaultBufFn, NULL);
|
||||
return pOperator;
|
||||
|
||||
_error:
|
||||
_error:
|
||||
if (pInfo != NULL) {
|
||||
destroySysScanOperator(pInfo);
|
||||
}
|
||||
|
@ -1757,7 +1766,7 @@ void destroySysScanOperator(void* param) {
|
|||
const char* name = tNameGetTableName(&pInfo->name);
|
||||
if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0 ||
|
||||
strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0 ||
|
||||
strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0|| pInfo->pCur != NULL) {
|
||||
strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0 || pInfo->pCur != NULL) {
|
||||
metaCloseTbCursor(pInfo->pCur);
|
||||
pInfo->pCur = NULL;
|
||||
}
|
||||
|
@ -2165,7 +2174,7 @@ static SSDataBlock* doBlockInfoScan(SOperatorInfo* pOperator) {
|
|||
// make the valgrind happy that all memory buffer has been initialized already.
|
||||
if (slotId != 0) {
|
||||
SColumnInfoData* p1 = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
int64_t v = 0;
|
||||
int64_t v = 0;
|
||||
colDataAppendInt64(p1, 0, &v);
|
||||
}
|
||||
|
||||
|
@ -2175,10 +2184,10 @@ static SSDataBlock* doBlockInfoScan(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
static void destroyBlockDistScanOperatorInfo(void* param) {
|
||||
SBlockDistInfo* pDistInfo = (SBlockDistInfo*)param;
|
||||
blockDataDestroy(pDistInfo->pResBlock);
|
||||
tsdbReaderClose(pDistInfo->pHandle);
|
||||
taosMemoryFreeClear(param);
|
||||
SBlockDistInfo* pDistInfo = (SBlockDistInfo*)param;
|
||||
blockDataDestroy(pDistInfo->pResBlock);
|
||||
tsdbReaderClose(pDistInfo->pHandle);
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
static int32_t initTableblockDistQueryCond(uint64_t uid, SQueryTableDataCond* pCond) {
|
||||
|
@ -2250,8 +2259,8 @@ SOperatorInfo* createDataBlockInfoScanOperator(SReadHandle* readHandle, SBlockDi
|
|||
|
||||
setOperatorInfo(pOperator, "DataBlockDistScanOperator", QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN, false,
|
||||
OP_NOT_OPENED, pInfo, pTaskInfo);
|
||||
pOperator->fpSet =
|
||||
createOperatorFpSet(optrDummyOpenFn, doBlockInfoScan, NULL, destroyBlockDistScanOperatorInfo, optrDefaultBufFn, NULL);
|
||||
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doBlockInfoScan, NULL, destroyBlockDistScanOperatorInfo,
|
||||
optrDefaultBufFn, NULL);
|
||||
return pOperator;
|
||||
|
||||
_error:
|
||||
|
|
|
@ -3053,14 +3053,12 @@ static int32_t doSaveTupleData(SSerializeDataHandle* pHandle, const void* pBuf,
|
|||
if (pHandle->currentPage == -1) {
|
||||
pPage = getNewBufPage(pHandle->pBuf, &pHandle->currentPage);
|
||||
if (pPage == NULL) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
return terrno;
|
||||
}
|
||||
pPage->num = sizeof(SFilePage);
|
||||
} else {
|
||||
pPage = getBufPage(pHandle->pBuf, pHandle->currentPage);
|
||||
if (pPage == NULL) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
return terrno;
|
||||
}
|
||||
if (pPage->num + length > getBufPageSize(pHandle->pBuf)) {
|
||||
|
@ -3068,7 +3066,6 @@ static int32_t doSaveTupleData(SSerializeDataHandle* pHandle, const void* pBuf,
|
|||
releaseBufPage(pHandle->pBuf, pPage);
|
||||
pPage = getNewBufPage(pHandle->pBuf, &pHandle->currentPage);
|
||||
if (pPage == NULL) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
return terrno;
|
||||
}
|
||||
pPage->num = sizeof(SFilePage);
|
||||
|
@ -3115,7 +3112,6 @@ static int32_t doUpdateTupleData(SSerializeDataHandle* pHandle, const void* pBuf
|
|||
if (pHandle->pBuf != NULL) {
|
||||
SFilePage* pPage = getBufPage(pHandle->pBuf, pPos->pageId);
|
||||
if (pPage == NULL) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
return terrno;
|
||||
}
|
||||
memcpy(pPage->data + pPos->offset, pBuf, length);
|
||||
|
|
|
@ -50,8 +50,8 @@ static SFilePage *loadDataFromFilePage(tMemBucket *pMemBucket, int32_t slotIdx)
|
|||
if (pg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(buffer->data + offset, pg->data, (size_t)(pg->num * pMemBucket->bytes));
|
||||
|
||||
memcpy(buffer->data + offset, pg->data, (size_t)(pg->num * pMemBucket->bytes));
|
||||
offset += (int32_t)(pg->num * pMemBucket->bytes);
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ int32_t findOnlyResult(tMemBucket *pMemBucket, double *result) {
|
|||
int32_t *pageId = taosArrayGet(list, 0);
|
||||
SFilePage *pPage = getBufPage(pMemBucket->pBuffer, *pageId);
|
||||
if (pPage == NULL) {
|
||||
return TSDB_CODE_NO_AVAIL_DISK;
|
||||
return terrno;
|
||||
}
|
||||
ASSERT(pPage->num == 1);
|
||||
|
||||
|
@ -283,7 +283,7 @@ tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int32_t ret = createDiskbasedBuf(&pBucket->pBuffer, pBucket->bufPageSize, pBucket->bufPageSize * 512, "1", tsTempDir);
|
||||
int32_t ret = createDiskbasedBuf(&pBucket->pBuffer, pBucket->bufPageSize, pBucket->bufPageSize * 1024, "1", tsTempDir);
|
||||
if (ret != 0) {
|
||||
tMemBucketDestroy(pBucket);
|
||||
return NULL;
|
||||
|
@ -395,7 +395,7 @@ int32_t tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size) {
|
|||
|
||||
pSlot->info.data = getNewBufPage(pBucket->pBuffer, &pageId);
|
||||
if (pSlot->info.data == NULL) {
|
||||
return TSDB_CODE_NO_AVAIL_DISK;
|
||||
return terrno;
|
||||
}
|
||||
pSlot->info.pageId = pageId;
|
||||
taosArrayPush(pPageIdList, &pageId);
|
||||
|
@ -489,8 +489,9 @@ int32_t getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction
|
|||
// data in buffer and file are merged together to be processed.
|
||||
SFilePage *buffer = loadDataFromFilePage(pMemBucket, i);
|
||||
if (buffer == NULL) {
|
||||
return TSDB_CODE_NO_AVAIL_DISK;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
int32_t currentIdx = count - num;
|
||||
|
||||
char *thisVal = buffer->data + pMemBucket->bytes * currentIdx;
|
||||
|
@ -536,7 +537,7 @@ int32_t getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction
|
|||
int32_t *pageId = taosArrayGet(list, f);
|
||||
SFilePage *pg = getBufPage(pMemBucket->pBuffer, *pageId);
|
||||
if (pg == NULL) {
|
||||
return TSDB_CODE_NO_AVAIL_DISK;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
int32_t code = tMemBucketPut(pMemBucket, pg->data, (int32_t)pg->num);
|
||||
|
|
|
@ -228,9 +228,14 @@ typedef struct SQWorkerMgmt {
|
|||
case QW_PHASE_POST_FETCH: \
|
||||
ctx->inFetch = 0; \
|
||||
break; \
|
||||
default: \
|
||||
case QW_PHASE_PRE_QUERY: \
|
||||
case QW_PHASE_POST_QUERY: \
|
||||
case QW_PHASE_PRE_CQUERY: \
|
||||
case QW_PHASE_POST_CQUERY: \
|
||||
atomic_store_8(&(ctx)->phase, _value); \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -550,7 +550,9 @@ _return:
|
|||
if (ctx) {
|
||||
QW_UPDATE_RSP_CODE(ctx, code);
|
||||
|
||||
QW_SET_PHASE(ctx, phase);
|
||||
if (QW_PHASE_POST_CQUERY != phase) {
|
||||
QW_SET_PHASE(ctx, phase);
|
||||
}
|
||||
|
||||
QW_UNLOCK(QW_WRITE, &ctx->lock);
|
||||
qwReleaseTaskCtx(mgmt, ctx);
|
||||
|
@ -757,7 +759,7 @@ int32_t qwProcessCQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg) {
|
|||
QW_LOCK(QW_WRITE, &ctx->lock);
|
||||
if (qComplete || (queryStop && (0 == atomic_load_8((int8_t *)&ctx->queryContinue))) || code) {
|
||||
// Note: query is not running anymore
|
||||
QW_SET_PHASE(ctx, 0);
|
||||
QW_SET_PHASE(ctx, QW_PHASE_POST_CQUERY);
|
||||
QW_UNLOCK(QW_WRITE, &ctx->lock);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -207,6 +207,7 @@ void streamMetaRemoveTask(SStreamMeta* pMeta, int32_t taskId) {
|
|||
if (ppTask) {
|
||||
SStreamTask* pTask = *ppTask;
|
||||
taosHashRemove(pMeta->pTasks, &taskId, sizeof(int32_t));
|
||||
tdbTbDelete(pMeta->pTaskDb, &taskId, sizeof(int32_t), pMeta->txn);
|
||||
/*if (pTask->timer) {
|
||||
* taosTmrStop(pTask->timer);*/
|
||||
/*pTask->timer = NULL;*/
|
||||
|
|
|
@ -89,45 +89,6 @@
|
|||
// /\ 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* pEntry = taosMemoryMalloc(pMsg->dataLen);
|
||||
if (pEntry == NULL) {
|
||||
|
@ -232,256 +193,3 @@ _IGNORE:
|
|||
rpcFreeCont(rpcRsp.pCont);
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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]
|
||||
// /\ 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) {
|
||||
// I am leader, I agree
|
||||
|
@ -210,83 +68,7 @@ static inline int64_t syncNodeAbs64(int64_t a, int64_t b) {
|
|||
return c;
|
||||
}
|
||||
|
||||
int32_t syncNodeDynamicQuorum(const SSyncNode* pSyncNode) {
|
||||
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;
|
||||
}
|
||||
*/
|
||||
int32_t syncNodeDynamicQuorum(const SSyncNode* pSyncNode) { return pSyncNode->quorum; }
|
||||
|
||||
bool syncNodeAgreedUpon(SSyncNode* pNode, SyncIndex index) {
|
||||
int count = 0;
|
||||
|
|
|
@ -43,7 +43,10 @@ static int32_t syncNodeRequestVotePeers(SSyncNode* pNode) {
|
|||
for (int i = 0; i < pNode->peersNum; ++i) {
|
||||
SRpcMsg rpcMsg = {0};
|
||||
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;
|
||||
pMsg->srcId = pNode->myRaftId;
|
||||
|
@ -51,13 +54,18 @@ static int32_t syncNodeRequestVotePeers(SSyncNode* pNode) {
|
|||
pMsg->term = pNode->raftStore.currentTerm;
|
||||
|
||||
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());
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = syncNodeSendMsgById(&pNode->peersId[i], pNode, &rpcMsg);
|
||||
ASSERT(ret == 0);
|
||||
if (ret < 0) {
|
||||
sError("vgId:%d, failed to send msg to peerId:%" PRId64, pNode->vgId, pNode->peersId[i].addr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncNodeElect(SSyncNode* pSyncNode) {
|
||||
|
|
|
@ -292,8 +292,6 @@ int32_t syncBeginSnapshot(int64_t rid, int64_t lastApplyIndex) {
|
|||
goto _DEL_WAL;
|
||||
|
||||
} else {
|
||||
lastApplyIndex -= SYNC_VNODE_LOG_RETENTION;
|
||||
|
||||
SyncIndex beginIndex = pSyncNode->pLogStore->syncLogBeginIndex(pSyncNode->pLogStore);
|
||||
SyncIndex endIndex = pSyncNode->pLogStore->syncLogEndIndex(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) {
|
||||
// multi replicas
|
||||
|
||||
lastApplyIndex = TMAX(lastApplyIndex - SYNC_VNODE_LOG_RETENTION, beginIndex - 1);
|
||||
|
||||
if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
||||
pSyncNode->minMatchIndex = syncMinMatchIndex(pSyncNode);
|
||||
|
||||
|
@ -586,78 +586,6 @@ SSyncState syncGetState(int64_t rid) {
|
|||
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) {
|
||||
ASSERT(pSyncNode->raftCfg.configIndexCount >= 1);
|
||||
SyncIndex lastIndex = (pSyncNode->raftCfg.configIndexArr)[0];
|
||||
|
@ -1042,9 +970,12 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) {
|
|||
pSyncNode->commitIndex = commitIndex;
|
||||
sInfo("vgId:%d, sync node commitIndex initialized as %" PRId64, pSyncNode->vgId, pSyncNode->commitIndex);
|
||||
|
||||
// restore log store on need
|
||||
if (syncNodeLogStoreRestoreOnNeed(pSyncNode) < 0) {
|
||||
sError("vgId:%d, failed to restore log store since %s.", pSyncNode->vgId, terrstr());
|
||||
goto _error;
|
||||
}
|
||||
|
||||
// timer ms init
|
||||
pSyncNode->pingBaseLine = PING_TIMER_MS;
|
||||
pSyncNode->electBaseLine = tsElectInterval;
|
||||
|
@ -1107,10 +1038,16 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) {
|
|||
pSyncNode->changing = false;
|
||||
|
||||
// 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
|
||||
syncNodePeerStateInit(pSyncNode);
|
||||
if (syncNodePeerStateInit(pSyncNode) < 0) {
|
||||
sError("vgId:%d, failed to init peer stat since %s.", pSyncNode->vgId, terrstr());
|
||||
goto _error;
|
||||
}
|
||||
|
||||
//
|
||||
// min match index
|
||||
|
@ -1205,27 +1142,10 @@ int32_t syncNodeStart(SSyncNode* pSyncNode) {
|
|||
|
||||
int32_t ret = 0;
|
||||
ret = syncNodeStartPingTimer(pSyncNode);
|
||||
ASSERT(ret == 0);
|
||||
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");
|
||||
if (ret != 0) {
|
||||
sError("vgId:%d, failed to start ping timer since %s", pSyncNode->vgId, terrstr());
|
||||
}
|
||||
|
||||
int32_t ret = 0;
|
||||
ret = syncNodeStartPingTimer(pSyncNode);
|
||||
ASSERT(ret == 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodeStartStandBy(SSyncNode* pSyncNode) {
|
||||
|
@ -1236,11 +1156,16 @@ int32_t syncNodeStartStandBy(SSyncNode* pSyncNode) {
|
|||
// reset elect timer, long enough
|
||||
int32_t electMS = TIMER_MAX_MS;
|
||||
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);
|
||||
ASSERT(ret == 0);
|
||||
if (ret < 0) {
|
||||
sError("vgId:%d, failed to start ping timer since %s", pSyncNode->vgId, terrstr());
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1829,12 +1754,6 @@ void syncNodeBecomeLeader(SSyncNode* pSyncNode, const char* debugStr) {
|
|||
pSyncNode->leaderCache = pSyncNode->myRaftId;
|
||||
|
||||
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;
|
||||
SyncTerm lastTerm;
|
||||
int32_t code = syncNodeGetLastIndexTerm(pSyncNode, &lastIndex, &lastTerm);
|
||||
|
@ -1896,7 +1815,11 @@ void syncNodeBecomeLeader(SSyncNode* pSyncNode, const char* debugStr) {
|
|||
|
||||
void syncNodeCandidate2Leader(SSyncNode* pSyncNode) {
|
||||
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");
|
||||
|
||||
sNTrace(pSyncNode, "state change syncNodeCandidate2Leader");
|
||||
|
@ -1912,20 +1835,6 @@ void syncNodeCandidate2Leader(SSyncNode* pSyncNode) {
|
|||
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); }
|
||||
|
||||
int32_t syncNodePeerStateInit(SSyncNode* pSyncNode) {
|
||||
|
@ -1971,7 +1880,8 @@ void syncNodeCandidate2Follower(SSyncNode* pSyncNode) {
|
|||
// need assert
|
||||
void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId) {
|
||||
ASSERT(term == pSyncNode->raftStore.currentTerm);
|
||||
ASSERT(!raftStoreHasVoted(pSyncNode));
|
||||
bool voted = raftStoreHasVoted(pSyncNode);
|
||||
ASSERT(!voted);
|
||||
|
||||
raftStoreVote(pSyncNode, pRaftId);
|
||||
}
|
||||
|
@ -2488,7 +2398,7 @@ static int32_t syncNodeAppendNoopOld(SSyncNode* ths) {
|
|||
LRUHandle* h = NULL;
|
||||
|
||||
if (ths->state == TAOS_SYNC_STATE_LEADER) {
|
||||
int32_t code = ths->pLogStore->syncLogAppendEntry(ths->pLogStore, pEntry);
|
||||
int32_t code = ths->pLogStore->syncLogAppendEntry(ths->pLogStore, pEntry, false);
|
||||
if (code != 0) {
|
||||
sError("append noop error");
|
||||
return -1;
|
||||
|
@ -2649,24 +2559,6 @@ int32_t syncNodeOnLocalCmd(SSyncNode* ths, const SRpcMsg* pRpcMsg) {
|
|||
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
|
||||
// ClientRequest(i, v) ==
|
||||
// /\ state[i] = Leader
|
||||
|
@ -2711,96 +2603,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);
|
||||
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) {
|
||||
switch (state) {
|
||||
case TAOS_SYNC_STATE_FOLLOWER:
|
||||
|
@ -2905,129 +2707,6 @@ bool syncNodeIsOptimizedOneReplica(SSyncNode* ths, SRpcMsg* pMsg) {
|
|||
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) {
|
||||
for (int32_t i = 0; i < ths->replicaNum; ++i) {
|
||||
if (syncUtilSameId(&((ths->replicasId)[i]), pRaftId)) {
|
||||
|
|
|
@ -364,7 +364,11 @@ _out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncLogStorePersist(SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry) {
|
||||
static inline bool syncLogStoreNeedFlush(SSyncRaftEntry* pEntry, int32_t replicaNum) {
|
||||
return (replicaNum > 1) && (pEntry->originalRpcType == TDMT_VND_COMMIT);
|
||||
}
|
||||
|
||||
int32_t syncLogStorePersist(SSyncLogStore* pLogStore, SSyncNode* pNode, SSyncRaftEntry* pEntry) {
|
||||
ASSERT(pEntry->index >= 0);
|
||||
SyncIndex lastVer = pLogStore->syncLogLastIndex(pLogStore);
|
||||
if (lastVer >= pEntry->index && pLogStore->syncLogTruncate(pLogStore, pEntry->index) < 0) {
|
||||
|
@ -374,7 +378,8 @@ int32_t syncLogStorePersist(SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry) {
|
|||
lastVer = pLogStore->syncLogLastIndex(pLogStore);
|
||||
ASSERT(pEntry->index == lastVer + 1);
|
||||
|
||||
if (pLogStore->syncLogAppendEntry(pLogStore, pEntry) < 0) {
|
||||
bool doFsync = syncLogStoreNeedFlush(pEntry, pNode->replicaNum);
|
||||
if (pLogStore->syncLogAppendEntry(pLogStore, pEntry, doFsync) < 0) {
|
||||
sError("failed to append sync log entry since %s. index:%" PRId64 ", term:%" PRId64 "", terrstr(), pEntry->index,
|
||||
pEntry->term);
|
||||
return -1;
|
||||
|
@ -436,7 +441,7 @@ int64_t syncLogBufferProceed(SSyncLogBuffer* pBuf, SSyncNode* pNode, SyncTerm* p
|
|||
(void)syncNodeReplicateWithoutLock(pNode);
|
||||
|
||||
// persist
|
||||
if (syncLogStorePersist(pLogStore, pEntry) < 0) {
|
||||
if (syncLogStorePersist(pLogStore, pNode, pEntry) < 0) {
|
||||
sError("vgId:%d, failed to persist sync log entry from buffer since %s. index:%" PRId64, pNode->vgId, terrstr(),
|
||||
pEntry->index);
|
||||
goto _out;
|
||||
|
@ -940,8 +945,11 @@ int32_t syncNodeLogReplMgrInit(SSyncNode* pNode) {
|
|||
for (int i = 0; i < TSDB_MAX_REPLICA; i++) {
|
||||
ASSERT(pNode->logReplMgrs[i] == NULL);
|
||||
pNode->logReplMgrs[i] = syncLogReplMgrCreate();
|
||||
if (pNode->logReplMgrs[i] == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
pNode->logReplMgrs[i]->peerId = i;
|
||||
ASSERTS(pNode->logReplMgrs[i] != NULL, "Out of memory.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
// public function
|
||||
static int32_t raftLogRestoreFromSnapshot(struct SSyncLogStore* pLogStore, SyncIndex snapshotIndex);
|
||||
static int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry);
|
||||
static int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry, bool forceSync);
|
||||
static int32_t raftLogTruncate(struct SSyncLogStore* pLogStore, SyncIndex fromIndex);
|
||||
static bool raftLogExist(struct SSyncLogStore* pLogStore, SyncIndex index);
|
||||
static int32_t raftLogUpdateCommitIndex(SSyncLogStore* pLogStore, SyncIndex index);
|
||||
|
@ -192,9 +192,7 @@ SyncTerm raftLogLastTerm(struct SSyncLogStore* pLogStore) {
|
|||
return SYNC_TERM_INVALID;
|
||||
}
|
||||
|
||||
static inline bool raftLogForceSync(SSyncRaftEntry* pEntry) { return (pEntry->originalRpcType == TDMT_VND_COMMIT); }
|
||||
|
||||
static int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry) {
|
||||
static int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry, bool forceSync) {
|
||||
SSyncLogStoreData* pData = pLogStore->data;
|
||||
SWal* pWal = pData->pWal;
|
||||
|
||||
|
@ -221,7 +219,6 @@ static int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncRaftEntr
|
|||
|
||||
ASSERT(pEntry->index == index);
|
||||
|
||||
bool forceSync = raftLogForceSync(pEntry);
|
||||
walFsync(pWal, forceSync);
|
||||
|
||||
sNTrace(pData->pSyncNode, "write index:%" PRId64 ", type:%s, origin type:%s, elapsed:%" PRId64, pEntry->index,
|
||||
|
|
|
@ -48,92 +48,6 @@
|
|||
|
||||
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) {
|
||||
SSyncLogBuffer* pBuf = pNode->pLogBuf;
|
||||
taosThreadMutexLock(&pBuf->mutex);
|
||||
|
@ -156,25 +70,6 @@ int32_t syncNodeReplicateWithoutLock(SSyncNode* pNode) {
|
|||
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) {
|
||||
SyncAppendEntries* pMsg = pRpcMsg->pCont;
|
||||
pMsg->destId = *destRaftId;
|
||||
|
@ -182,39 +77,6 @@ int32_t syncNodeSendAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftI
|
|||
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 ret = 0;
|
||||
SyncAppendEntries* pMsg = pRpcMsg->pCont;
|
||||
|
|
|
@ -322,6 +322,35 @@ bool walLogEntriesComplete(const SWal* pWal) {
|
|||
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) {
|
||||
// load log files, get first/snapshot/last version info
|
||||
const char* logPattern = "^[0-9]+.log$";
|
||||
|
@ -396,6 +425,8 @@ int walCheckAndRepairMeta(SWal* pWal) {
|
|||
}
|
||||
updateMeta = true;
|
||||
|
||||
(void)walTrimIdxFile(pWal, fileIdx);
|
||||
|
||||
int64_t lastVer = walScanLogGetLastVer(pWal, fileIdx);
|
||||
if (lastVer < 0) {
|
||||
if (terrno != TSDB_CODE_WAL_LOG_NOT_EXIST) {
|
||||
|
@ -558,6 +589,7 @@ int walCheckAndRepairIdxFile(SWal* pWal, int32_t fileIdx) {
|
|||
goto _err;
|
||||
}
|
||||
|
||||
int64_t count = 0;
|
||||
while (idxEntry.ver < pFileInfo->lastVer) {
|
||||
/*A(idxEntry.ver == ckHead.head.version);*/
|
||||
|
||||
|
@ -569,11 +601,11 @@ int walCheckAndRepairIdxFile(SWal* pWal, int32_t fileIdx) {
|
|||
idxEntry.offset, fLogNameStr);
|
||||
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) {
|
||||
wError("vgId:%d, failed to append file since %s. file:%s", pWal->cfg.vgId, terrstr(), fnameStr);
|
||||
goto _err;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
if (taosFsyncFile(pIdxFile) < 0) {
|
||||
|
@ -581,6 +613,11 @@ int walCheckAndRepairIdxFile(SWal* pWal, int32_t fileIdx) {
|
|||
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(&pIdxFile);
|
||||
return 0;
|
||||
|
|
|
@ -77,6 +77,31 @@ void walUnrefVer(SWalRef *pRef) {
|
|||
}
|
||||
#endif
|
||||
|
||||
SWalRef *walRefFirstVer(SWal *pWal, SWalRef *pRef) {
|
||||
if (pRef == NULL) {
|
||||
pRef = walOpenRef(pWal);
|
||||
if (pRef == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
taosThreadMutexLock(&pWal->mutex);
|
||||
|
||||
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) {
|
||||
|
@ -87,6 +112,8 @@ SWalRef *walRefCommittedVer(SWal *pWal) {
|
|||
|
||||
int64_t ver = walGetCommittedVer(pWal);
|
||||
|
||||
wDebug("vgId:%d, wal ref version %" PRId64 " for committed", pWal->cfg.vgId, ver);
|
||||
|
||||
pRef->refVer = ver;
|
||||
// bsearch in fileSet
|
||||
SWalFileInfo tmpInfo;
|
||||
|
|
|
@ -41,7 +41,7 @@ target_link_libraries(
|
|||
)
|
||||
if(TD_WINDOWS)
|
||||
target_link_libraries(
|
||||
os PUBLIC ws2_32 iconv msvcregex wcwidth winmm crashdump dbghelp
|
||||
os PUBLIC ws2_32 iconv msvcregex wcwidth winmm crashdump dbghelp version
|
||||
)
|
||||
elseif(TD_DARWIN_64)
|
||||
find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation)
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
#define ALLOW_FORBID_FUNC
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include <stdlib.h>
|
||||
#include "os.h"
|
||||
|
||||
#ifdef WINDOWS
|
||||
void swapStr(char* j, char* J, int width) {
|
||||
|
@ -32,7 +32,17 @@ void swapStr(char* j, char* J, int width) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// todo refactor: 1) move away; 2) use merge sort instead; 3) qsort is not a stable sort actually.
|
||||
void taosSort(void* arr, int64_t sz, int64_t width, __compar_fn_t compar) {
|
||||
qsort(arr, sz, width, compar);
|
||||
int32_t qsortHelper(const void* p1, const void* p2, const void* param) {
|
||||
__compar_fn_t comparFn = param;
|
||||
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
|
||||
}
|
||||
|
|
|
@ -280,11 +280,46 @@ int32_t taosGetEmail(char *email, int32_t maxLen) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef WINDOWS
|
||||
bool getWinVersionReleaseName(char *releaseName, int32_t maxLen) {
|
||||
TCHAR szFileName[MAX_PATH];
|
||||
DWORD dwHandle;
|
||||
DWORD dwLen;
|
||||
LPVOID lpData;
|
||||
UINT uLen;
|
||||
VS_FIXEDFILEINFO *pFileInfo;
|
||||
|
||||
GetWindowsDirectory(szFileName, MAX_PATH);
|
||||
wsprintf(szFileName, L"%s%s", szFileName, L"\\explorer.exe");
|
||||
dwLen = GetFileVersionInfoSize(szFileName, &dwHandle);
|
||||
if (dwLen == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lpData = malloc(dwLen);
|
||||
if (lpData == NULL) return false;
|
||||
if (!GetFileVersionInfo(szFileName, dwHandle, dwLen, lpData)) {
|
||||
free(lpData);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!VerQueryValue(lpData, L"\\", (LPVOID *)&pFileInfo, &uLen)) {
|
||||
free(lpData);
|
||||
return false;
|
||||
}
|
||||
|
||||
snprintf(releaseName, maxLen, "Windows %d.%d", HIWORD(pFileInfo->dwProductVersionMS),
|
||||
LOWORD(pFileInfo->dwProductVersionMS));
|
||||
free(lpData);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t taosGetOsReleaseName(char *releaseName, int32_t maxLen) {
|
||||
#ifdef WINDOWS
|
||||
snprintf(releaseName, maxLen, "Windows");
|
||||
if (!getWinVersionReleaseName(releaseName, maxLen)) {
|
||||
snprintf(releaseName, maxLen, "Windows");
|
||||
}
|
||||
return 0;
|
||||
#elif defined(_TD_DARWIN_64)
|
||||
char osversion[32];
|
||||
|
@ -840,7 +875,11 @@ int32_t taosGetSystemUUID(char *uid, int32_t uidlen) {
|
|||
uuid_generate(uuid);
|
||||
// it's caller's responsibility to make enough space for `uid`, that's 36-char + 1-null
|
||||
uuid_unparse_lower(uuid, buf);
|
||||
memcpy(uid, buf, uidlen);
|
||||
int n = snprintf(uid, uidlen, "%.*s", (int)sizeof(buf), buf); // though less performance, much safer
|
||||
if (n >= uidlen) {
|
||||
// target buffer is too small
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
int len = 0;
|
||||
|
|
|
@ -34,6 +34,12 @@ TEST(osTest, osSystem) {
|
|||
ELogLevel level = DEBUG_FATAL;
|
||||
int32_t dflag = 255; // tsLogEmbedded ? 255 : uDebugFlag
|
||||
taosPrintTrace(flags, level, dflag, 0);
|
||||
|
||||
const int sysLen = 64;
|
||||
char osSysName[sysLen];
|
||||
int ret = taosGetOsReleaseName(osSysName, sysLen);
|
||||
printf("os systeme name:%s\n", osSysName);
|
||||
ASSERT_EQ(ret, 0);
|
||||
}
|
||||
|
||||
void fileOperateOnFree(void *param) {
|
||||
|
|
|
@ -41,12 +41,6 @@ static void median(void *src, int64_t size, int64_t s, int64_t e, const void *pa
|
|||
|
||||
ASSERT(comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, s), 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,
|
||||
|
@ -278,14 +272,4 @@ void taosheapsort(void *base, int32_t size, int32_t len, const void *parcompar,
|
|||
}
|
||||
|
||||
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);
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -20,7 +20,10 @@
|
|||
// todo refactor API
|
||||
|
||||
SArray* taosArrayInit(size_t size, size_t elemSize) {
|
||||
assert(elemSize > 0);
|
||||
if (elemSize == 0) {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size < TARRAY_MIN_SIZE) {
|
||||
size = TARRAY_MIN_SIZE;
|
||||
|
@ -96,8 +99,6 @@ void* taosArrayAddBatch(SArray* pArray, const void* pData, int32_t nEles) {
|
|||
}
|
||||
|
||||
void taosArrayRemoveDuplicate(SArray* pArray, __compar_fn_t comparFn, void (*fp)(void*)) {
|
||||
assert(pArray);
|
||||
|
||||
size_t size = pArray->size;
|
||||
if (size <= 1) {
|
||||
return;
|
||||
|
@ -136,8 +137,6 @@ void taosArrayRemoveDuplicate(SArray* pArray, __compar_fn_t comparFn, void (*fp)
|
|||
}
|
||||
|
||||
void taosArrayRemoveDuplicateP(SArray* pArray, __compar_fn_t comparFn, void (*fp)(void*)) {
|
||||
assert(pArray);
|
||||
|
||||
size_t size = pArray->size;
|
||||
if (size <= 1) {
|
||||
return;
|
||||
|
@ -197,11 +196,10 @@ void* taosArrayReserve(SArray* pArray, int32_t num) {
|
|||
}
|
||||
|
||||
void* taosArrayPop(SArray* pArray) {
|
||||
assert(pArray != NULL);
|
||||
|
||||
if (pArray->size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pArray->size -= 1;
|
||||
return TARRAY_GET_ELEM(pArray, pArray->size);
|
||||
}
|
||||
|
@ -210,16 +208,21 @@ void* taosArrayGet(const SArray* pArray, size_t index) {
|
|||
if (NULL == pArray) {
|
||||
return NULL;
|
||||
}
|
||||
assert(index < pArray->size);
|
||||
|
||||
if (index >= pArray->size) {
|
||||
uError("index is out of range, current:%"PRIzu" max:%d", index, pArray->capacity);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return TARRAY_GET_ELEM(pArray, index);
|
||||
}
|
||||
|
||||
void* taosArrayGetP(const SArray* pArray, size_t index) {
|
||||
assert(index < pArray->size);
|
||||
|
||||
void* d = TARRAY_GET_ELEM(pArray, index);
|
||||
|
||||
return *(void**)d;
|
||||
void** p = taosArrayGet(pArray, index);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return *p;
|
||||
}
|
||||
|
||||
void* taosArrayGetLast(const SArray* pArray) { return TARRAY_GET_ELEM(pArray, pArray->size - 1); }
|
||||
|
@ -312,9 +315,12 @@ void taosArrayRemoveBatch(SArray* pArray, size_t index, size_t num, FDelete fp)
|
|||
}
|
||||
|
||||
SArray* taosArrayFromList(const void* src, size_t size, size_t elemSize) {
|
||||
assert(src != NULL && elemSize > 0);
|
||||
SArray* pDst = taosArrayInit(size, elemSize);
|
||||
if (elemSize <= 0) {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SArray* pDst = taosArrayInit(size, elemSize);
|
||||
memcpy(pDst->pData, src, elemSize * size);
|
||||
pDst->size = size;
|
||||
|
||||
|
@ -322,8 +328,6 @@ SArray* taosArrayFromList(const void* src, size_t size, size_t elemSize) {
|
|||
}
|
||||
|
||||
SArray* taosArrayDup(const SArray* pSrc, __array_item_dup_fn_t fn) {
|
||||
assert(pSrc != NULL);
|
||||
|
||||
if (pSrc->size == 0) { // empty array list
|
||||
return taosArrayInit(8, pSrc->elemSize);
|
||||
}
|
||||
|
@ -415,14 +419,10 @@ void taosArrayDestroyEx(SArray* pArray, FDelete fp) {
|
|||
}
|
||||
|
||||
void taosArraySort(SArray* pArray, __compar_fn_t compar) {
|
||||
ASSERT(pArray != NULL && compar != NULL);
|
||||
taosSort(pArray->pData, pArray->size, pArray->elemSize, compar);
|
||||
}
|
||||
|
||||
void* taosArraySearch(const SArray* pArray, const void* key, __compar_fn_t comparFn, int32_t flags) {
|
||||
assert(pArray != NULL && comparFn != NULL);
|
||||
assert(key != NULL);
|
||||
|
||||
return taosbsearch(key, pArray->pData, pArray->size, pArray->elemSize, comparFn, flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -897,6 +897,7 @@ void taosLogCrashInfo(char* nodeType, char* pMsg, int64_t msgLen, int signum, vo
|
|||
|
||||
pFile = taosOpenFile(filepath, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_APPEND);
|
||||
if (pFile == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
taosPrintLog(flags, level, dflag, "failed to open file:%s since %s", filepath, terrstr());
|
||||
goto _return;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
#include "thash.h"
|
||||
#include "tlog.h"
|
||||
|
||||
#define GET_DATA_PAYLOAD(_p) ((char*)(_p)->pData + POINTER_BYTES)
|
||||
#define GET_PAYLOAD_DATA(_p) ((char*)(_p)->pData + POINTER_BYTES)
|
||||
#define BUF_PAGE_IN_MEM(_p) ((_p)->pData != NULL)
|
||||
#define CLEAR_BUF_PAGE_IN_MEM_FLAG(_p) ((_p)->pData = NULL)
|
||||
#define HAS_DATA_IN_DISK(_p) ((_p)->offset >= 0)
|
||||
#define NO_IN_MEM_AVAILABLE_PAGES(_b) (listNEles((_b)->lruList) >= (_b)->inMemPages)
|
||||
|
||||
typedef struct SPageDiskInfo {
|
||||
|
@ -14,7 +17,7 @@ typedef struct SPageDiskInfo {
|
|||
} SPageDiskInfo, SFreeListItem;
|
||||
|
||||
struct SPageInfo {
|
||||
SListNode* pn; // point to list node struct
|
||||
SListNode* pn; // point to list node struct. it is NULL when the page is evicted from the in-memory buffer
|
||||
void* pData;
|
||||
int64_t offset;
|
||||
int32_t pageId;
|
||||
|
@ -89,7 +92,7 @@ static char* doDecompressData(void* data, int32_t srcSize, int32_t* dst, SDiskba
|
|||
return data;
|
||||
}
|
||||
|
||||
static uint64_t allocatePositionInFile(SDiskbasedBuf* pBuf, size_t size) {
|
||||
static uint64_t allocateNewPositionInFile(SDiskbasedBuf* pBuf, size_t size) {
|
||||
if (pBuf->pFree == NULL) {
|
||||
return pBuf->nextPos;
|
||||
} else {
|
||||
|
@ -112,10 +115,6 @@ static uint64_t allocatePositionInFile(SDiskbasedBuf* pBuf, size_t size) {
|
|||
}
|
||||
}
|
||||
|
||||
static void setPageNotInBuf(SPageInfo* pPageInfo) { pPageInfo->pData = NULL; }
|
||||
|
||||
static FORCE_INLINE size_t getAllocPageSize(int32_t pageSize) { return pageSize + POINTER_BYTES + sizeof(SFilePage); }
|
||||
|
||||
/**
|
||||
* +--------------------------+-------------------+--------------+
|
||||
* | PTR to SPageInfo (8bytes)| Payload (PageSize)| 2 Extra Bytes|
|
||||
|
@ -124,23 +123,31 @@ static FORCE_INLINE size_t getAllocPageSize(int32_t pageSize) { return pageSize
|
|||
* @param pg
|
||||
* @return
|
||||
*/
|
||||
static char* doFlushPageToDisk(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
||||
ASSERT(!pg->used && pg->pData != NULL);
|
||||
|
||||
static FORCE_INLINE size_t getAllocPageSize(int32_t pageSize) { return pageSize + POINTER_BYTES + sizeof(SFilePage); }
|
||||
|
||||
static char* doFlushBufPage(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
||||
if (pg->pData == NULL || pg->used) {
|
||||
uError("invalid params in paged buffer process when flushing buf to disk, %s", pBuf->id);
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t size = pBuf->pageSize;
|
||||
char* t = NULL;
|
||||
if (pg->offset == -1 || pg->dirty) {
|
||||
void* payload = GET_DATA_PAYLOAD(pg);
|
||||
if ((!HAS_DATA_IN_DISK(pg)) || pg->dirty) {
|
||||
void* payload = GET_PAYLOAD_DATA(pg);
|
||||
t = doCompressData(payload, pBuf->pageSize, &size, pBuf);
|
||||
ASSERTS(size >= 0, "size is negative");
|
||||
if (size < 0) {
|
||||
uError("failed to compress data when flushing data to disk, %s", pBuf->id);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// this page is flushed to disk for the first time
|
||||
if (pg->dirty) {
|
||||
if (pg->offset == -1) {
|
||||
ASSERTS(pg->dirty == true, "pg->dirty is false");
|
||||
|
||||
pg->offset = allocatePositionInFile(pBuf, size);
|
||||
if (!HAS_DATA_IN_DISK(pg)) {
|
||||
pg->offset = allocateNewPositionInFile(pBuf, size);
|
||||
pBuf->nextPos += size;
|
||||
|
||||
int32_t ret = taosLSeekFile(pBuf->pFile, pg->offset, SEEK_SET);
|
||||
|
@ -155,6 +162,7 @@ static char* doFlushPageToDisk(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// extend the file size
|
||||
if (pBuf->fileSize < pg->offset + size) {
|
||||
pBuf->fileSize = pg->offset + size;
|
||||
}
|
||||
|
@ -169,7 +177,7 @@ static char* doFlushPageToDisk(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
|||
taosArrayPush(pBuf->pFree, &dinfo);
|
||||
|
||||
// 2. allocate new position, and update the info
|
||||
pg->offset = allocatePositionInFile(pBuf, size);
|
||||
pg->offset = allocateNewPositionInFile(pBuf, size);
|
||||
pBuf->nextPos += size;
|
||||
}
|
||||
|
||||
|
@ -197,20 +205,19 @@ static char* doFlushPageToDisk(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
|||
size = pg->length;
|
||||
}
|
||||
|
||||
ASSERT(size > 0 || (pg->offset == -1 && pg->length == -1));
|
||||
|
||||
char* pDataBuf = pg->pData;
|
||||
memset(pDataBuf, 0, getAllocPageSize(pBuf->pageSize));
|
||||
|
||||
#ifdef BUF_PAGE_DEBUG
|
||||
uDebug("page_flush %p, pageId:%d, offset:%d", pDataBuf, pg->pageId, pg->offset);
|
||||
#endif
|
||||
|
||||
pg->length = size; // on disk size
|
||||
return pDataBuf;
|
||||
}
|
||||
|
||||
static char* flushPageToDisk(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
||||
static char* flushBufPage(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
||||
int32_t ret = TSDB_CODE_SUCCESS;
|
||||
ASSERT(((int64_t)pBuf->numOfPages * pBuf->pageSize) == pBuf->totalBufSize && pBuf->numOfPages >= pBuf->inMemPages);
|
||||
|
||||
if (pBuf->pFile == NULL) {
|
||||
if ((ret = createDiskFile(pBuf)) != TSDB_CODE_SUCCESS) {
|
||||
|
@ -219,22 +226,27 @@ static char* flushPageToDisk(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
|||
}
|
||||
}
|
||||
|
||||
char* p = doFlushPageToDisk(pBuf, pg);
|
||||
setPageNotInBuf(pg);
|
||||
pg->dirty = false;
|
||||
char* p = doFlushBufPage(pBuf, pg);
|
||||
CLEAR_BUF_PAGE_IN_MEM_FLAG(pg);
|
||||
|
||||
pg->dirty = false;
|
||||
return p;
|
||||
}
|
||||
|
||||
// load file block data in disk
|
||||
static int32_t loadPageFromDisk(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
||||
if (pg->offset < 0 || pg->length <= 0) {
|
||||
uError("failed to load buf page from disk, offset:%"PRId64", length:%d, %s", pg->offset, pg->length, pBuf->id);
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
int32_t ret = taosLSeekFile(pBuf->pFile, pg->offset, SEEK_SET);
|
||||
if (ret == -1) {
|
||||
ret = TAOS_SYSTEM_ERROR(errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* pPage = (void*)GET_DATA_PAYLOAD(pg);
|
||||
void* pPage = (void*)GET_PAYLOAD_DATA(pg);
|
||||
ret = (int32_t)taosReadFile(pBuf->pFile, pPage, pg->length);
|
||||
if (ret != pg->length) {
|
||||
ret = TAOS_SYSTEM_ERROR(errno);
|
||||
|
@ -249,10 +261,14 @@ static int32_t loadPageFromDisk(SDiskbasedBuf* pBuf, SPageInfo* pg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SPageInfo* registerPage(SDiskbasedBuf* pBuf, int32_t pageId) {
|
||||
static SPageInfo* registerNewPageInfo(SDiskbasedBuf* pBuf, int32_t pageId) {
|
||||
pBuf->numOfPages += 1;
|
||||
|
||||
SPageInfo* ppi = taosMemoryMalloc(sizeof(SPageInfo));
|
||||
if (ppi == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ppi->pageId = pageId;
|
||||
ppi->pData = NULL;
|
||||
|
@ -272,46 +288,33 @@ static SListNode* getEldestUnrefedPage(SDiskbasedBuf* pBuf) {
|
|||
SListNode* pn = NULL;
|
||||
while ((pn = tdListNext(&iter)) != NULL) {
|
||||
SPageInfo* pageInfo = *(SPageInfo**)pn->data;
|
||||
ASSERT(pageInfo->pageId >= 0 && pageInfo->pn == pn);
|
||||
|
||||
SPageInfo* p = *(SPageInfo**)(pageInfo->pData);
|
||||
ASSERT(pageInfo->pageId >= 0 && pageInfo->pn == pn && p == pageInfo);
|
||||
|
||||
if (!pageInfo->used) {
|
||||
// printf("%d is chosen\n", pageInfo->pageId);
|
||||
break;
|
||||
} else {
|
||||
// printf("page %d is used, dirty:%d\n", pageInfo->pageId, pageInfo->dirty);
|
||||
}
|
||||
}
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
static char* evacOneDataPage(SDiskbasedBuf* pBuf) {
|
||||
char* bufPage = NULL;
|
||||
static char* evictBufPage(SDiskbasedBuf* pBuf) {
|
||||
SListNode* pn = getEldestUnrefedPage(pBuf);
|
||||
terrno = 0;
|
||||
|
||||
// all pages are referenced by user, try to allocate new space
|
||||
if (pn == NULL) {
|
||||
int32_t prev = pBuf->inMemPages;
|
||||
|
||||
// increase by 50% of previous mem pages
|
||||
pBuf->inMemPages = (int32_t)(pBuf->inMemPages * 1.5f);
|
||||
|
||||
// qWarn("%p in memory buf page not sufficient, expand from %d to %d, page size:%d", pBuf, prev,
|
||||
// pBuf->inMemPages, pBuf->pageSize);
|
||||
} else {
|
||||
tdListPopNode(pBuf->lruList, pn);
|
||||
|
||||
SPageInfo* d = *(SPageInfo**)pn->data;
|
||||
ASSERTS(d->pn == pn, "d->pn not equal pn");
|
||||
|
||||
d->pn = NULL;
|
||||
taosMemoryFreeClear(pn);
|
||||
|
||||
bufPage = flushPageToDisk(pBuf, d);
|
||||
if (pn == NULL) { // no available buffer pages now, return.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bufPage;
|
||||
terrno = 0;
|
||||
tdListPopNode(pBuf->lruList, pn);
|
||||
|
||||
SPageInfo* d = *(SPageInfo**)pn->data;
|
||||
|
||||
d->pn = NULL;
|
||||
taosMemoryFreeClear(pn);
|
||||
|
||||
return flushBufPage(pBuf, d);
|
||||
}
|
||||
|
||||
static void lruListPushFront(SList* pList, SPageInfo* pi) {
|
||||
|
@ -338,13 +341,12 @@ int32_t createDiskbasedBuf(SDiskbasedBuf** pBuf, int32_t pagesize, int32_t inMem
|
|||
|
||||
SDiskbasedBuf* pPBuf = *pBuf;
|
||||
if (pPBuf == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pPBuf->pageSize = pagesize;
|
||||
pPBuf->numOfPages = 0; // all pages are in buffer in the first place
|
||||
pPBuf->totalBufSize = 0;
|
||||
pPBuf->inMemPages = inMemBufSize / pagesize; // maximum allowed pages, it is a soft limit.
|
||||
pPBuf->allocateId = -1;
|
||||
pPBuf->pFile = NULL;
|
||||
pPBuf->id = strdup(id);
|
||||
|
@ -353,33 +355,69 @@ int32_t createDiskbasedBuf(SDiskbasedBuf** pBuf, int32_t pagesize, int32_t inMem
|
|||
pPBuf->freePgList = tdListNew(POINTER_BYTES);
|
||||
|
||||
// at least more than 2 pages must be in memory
|
||||
ASSERT(inMemBufSize >= pagesize * 2);
|
||||
if (inMemBufSize < pagesize * 2) {
|
||||
inMemBufSize = pagesize * 2;
|
||||
}
|
||||
|
||||
pPBuf->inMemPages = inMemBufSize / pagesize; // maximum allowed pages, it is a soft limit.
|
||||
pPBuf->lruList = tdListNew(POINTER_BYTES);
|
||||
if (pPBuf->lruList == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
// init id hash table
|
||||
_hash_fn_t fn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT);
|
||||
pPBuf->pIdList = taosArrayInit(4, POINTER_BYTES);
|
||||
if (pPBuf->pIdList == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pPBuf->assistBuf = taosMemoryMalloc(pPBuf->pageSize + 2); // EXTRA BYTES
|
||||
pPBuf->all = taosHashInit(10, fn, true, false);
|
||||
pPBuf->prefix = (char*) dir;
|
||||
if (pPBuf->assistBuf == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pPBuf->all = taosHashInit(10, fn, true, false);
|
||||
if (pPBuf->all == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pPBuf->prefix = (char*) dir;
|
||||
pPBuf->emptyDummyIdList = taosArrayInit(1, sizeof(int32_t));
|
||||
|
||||
// qDebug("QInfo:0x%"PRIx64" create resBuf for output, page size:%d, inmem buf pages:%d, file:%s", qId,
|
||||
// pPBuf->pageSize,
|
||||
// pPBuf->inMemPages, pPBuf->path);
|
||||
// pPBuf->pageSize, pPBuf->inMemPages, pPBuf->path);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_error:
|
||||
destroyDiskbasedBuf(pPBuf);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
static char* doExtractPage(SDiskbasedBuf* pBuf) {
|
||||
char* availablePage = NULL;
|
||||
if (NO_IN_MEM_AVAILABLE_PAGES(pBuf)) {
|
||||
availablePage = evictBufPage(pBuf);
|
||||
if (availablePage == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
uWarn("no available buf pages, current:%d, max:%d", listNEles(pBuf->lruList), pBuf->inMemPages)
|
||||
}
|
||||
} else {
|
||||
availablePage = taosMemoryCalloc(1, getAllocPageSize(pBuf->pageSize)); // add extract bytes in case of zipped buffer increased.
|
||||
if (availablePage == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return availablePage;
|
||||
}
|
||||
|
||||
void* getNewBufPage(SDiskbasedBuf* pBuf, int32_t* pageId) {
|
||||
pBuf->statis.getPages += 1;
|
||||
|
||||
char* availablePage = NULL;
|
||||
if (NO_IN_MEM_AVAILABLE_PAGES(pBuf)) {
|
||||
availablePage = evacOneDataPage(pBuf);
|
||||
char* availablePage = doExtractPage(pBuf);
|
||||
if (availablePage == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SPageInfo* pi = NULL;
|
||||
|
@ -394,7 +432,10 @@ void* getNewBufPage(SDiskbasedBuf* pBuf, int32_t* pageId) {
|
|||
*pageId = (++pBuf->allocateId);
|
||||
|
||||
// register page id info
|
||||
pi = registerPage(pBuf, *pageId);
|
||||
pi = registerNewPageInfo(pBuf, *pageId);
|
||||
if (pi == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// add to hash map
|
||||
taosHashPut(pBuf->all, pageId, sizeof(int32_t), &pi, POINTER_BYTES);
|
||||
|
@ -402,63 +443,62 @@ void* getNewBufPage(SDiskbasedBuf* pBuf, int32_t* pageId) {
|
|||
}
|
||||
|
||||
// add to LRU list
|
||||
ASSERT(listNEles(pBuf->lruList) < pBuf->inMemPages && pBuf->inMemPages > 0);
|
||||
lruListPushFront(pBuf->lruList, pi);
|
||||
|
||||
// allocate buf
|
||||
if (availablePage == NULL) {
|
||||
pi->pData =
|
||||
taosMemoryCalloc(1, getAllocPageSize(pBuf->pageSize)); // add extract bytes in case of zipped buffer increased.
|
||||
} else {
|
||||
pi->pData = availablePage;
|
||||
}
|
||||
pi->pData = availablePage;
|
||||
|
||||
((void**)pi->pData)[0] = pi;
|
||||
#ifdef BUF_PAGE_DEBUG
|
||||
uDebug("page_getNewBufPage , pi->pData:%p, pageId:%d, offset:%" PRId64, pi->pData, pi->pageId, pi->offset);
|
||||
#endif
|
||||
return (void*)(GET_DATA_PAYLOAD(pi));
|
||||
|
||||
return (void*)(GET_PAYLOAD_DATA(pi));
|
||||
}
|
||||
|
||||
void* getBufPage(SDiskbasedBuf* pBuf, int32_t id) {
|
||||
ASSERT(pBuf != NULL && id >= 0);
|
||||
if (id < 0) {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
uError("invalid page id:%d, %s", id, pBuf->id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pBuf->statis.getPages += 1;
|
||||
|
||||
SPageInfo** pi = taosHashGet(pBuf->all, &id, sizeof(int32_t));
|
||||
ASSERT(pi != NULL && *pi != NULL);
|
||||
if (pi == NULL || *pi == NULL) {
|
||||
uError("failed to locate the buffer page:%d, %s", id, pBuf->id);
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((*pi)->pData != NULL) { // it is in memory
|
||||
if (BUF_PAGE_IN_MEM(*pi)) { // it is in memory
|
||||
// no need to update the LRU list if only one page exists
|
||||
if (pBuf->numOfPages == 1) {
|
||||
(*pi)->used = true;
|
||||
return (void*)(GET_DATA_PAYLOAD(*pi));
|
||||
return (void*)(GET_PAYLOAD_DATA(*pi));
|
||||
}
|
||||
|
||||
SPageInfo** pInfo = (SPageInfo**)((*pi)->pn->data);
|
||||
ASSERT(*pInfo == *pi);
|
||||
if (*pInfo != *pi) {
|
||||
uError("inconsistently data in paged buffer, pInfo:%p, pi:%p, %s", *pInfo, *pi, pBuf->id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lruListMoveToFront(pBuf->lruList, (*pi));
|
||||
(*pi)->used = true;
|
||||
|
||||
#ifdef BUF_PAGE_DEBUG
|
||||
uDebug("page_getBufPage1 pageId:%d, offset:%" PRId64, (*pi)->pageId, (*pi)->offset);
|
||||
#endif
|
||||
return (void*)(GET_DATA_PAYLOAD(*pi));
|
||||
return (void*)(GET_PAYLOAD_DATA(*pi));
|
||||
} else { // not in memory
|
||||
ASSERT((*pi)->pData == NULL && (*pi)->pn == NULL &&
|
||||
ASSERT((!BUF_PAGE_IN_MEM(*pi)) && (*pi)->pn == NULL &&
|
||||
(((*pi)->length >= 0 && (*pi)->offset >= 0) || ((*pi)->length == -1 && (*pi)->offset == -1)));
|
||||
|
||||
char* availablePage = NULL;
|
||||
if (NO_IN_MEM_AVAILABLE_PAGES(pBuf)) {
|
||||
availablePage = evacOneDataPage(pBuf);
|
||||
if (availablePage == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
(*pi)->pData = doExtractPage(pBuf);
|
||||
|
||||
if (availablePage == NULL) {
|
||||
(*pi)->pData = taosMemoryCalloc(1, getAllocPageSize(pBuf->pageSize));
|
||||
} else {
|
||||
(*pi)->pData = availablePage;
|
||||
// failed to evict buffer page, return with error code.
|
||||
if ((*pi)->pData == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// set the ptr to the new SPageInfo
|
||||
|
@ -468,23 +508,25 @@ void* getBufPage(SDiskbasedBuf* pBuf, int32_t id) {
|
|||
(*pi)->used = true;
|
||||
|
||||
// some data has been flushed to disk, and needs to be loaded into buffer again.
|
||||
if ((*pi)->length > 0 && (*pi)->offset >= 0) {
|
||||
if (HAS_DATA_IN_DISK(*pi)) {
|
||||
int32_t code = loadPageFromDisk(pBuf, *pi);
|
||||
if (code != 0) {
|
||||
terrno = code;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#ifdef BUF_PAGE_DEBUG
|
||||
uDebug("page_getBufPage2 pageId:%d, offset:%" PRId64, (*pi)->pageId, (*pi)->offset);
|
||||
#endif
|
||||
return (void*)(GET_DATA_PAYLOAD(*pi));
|
||||
return (void*)(GET_PAYLOAD_DATA(*pi));
|
||||
}
|
||||
}
|
||||
|
||||
void releaseBufPage(SDiskbasedBuf* pBuf, void* page) {
|
||||
if (ASSERTS(pBuf != NULL && page != NULL, "pBuf or page is NULL")) {
|
||||
if (page == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SPageInfo* ppi = getPageInfoFromPayload(page);
|
||||
releaseBufPageInfo(pBuf, ppi);
|
||||
}
|
||||
|
@ -493,7 +535,13 @@ void releaseBufPageInfo(SDiskbasedBuf* pBuf, SPageInfo* pi) {
|
|||
#ifdef BUF_PAGE_DEBUG
|
||||
uDebug("page_releaseBufPageInfo pageId:%d, used:%d, offset:%" PRId64, pi->pageId, pi->used, pi->offset);
|
||||
#endif
|
||||
if (ASSERTS(pi->pData != NULL, "pi->pData is NULL")) {
|
||||
|
||||
if (pi == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pi->pData == NULL) {
|
||||
uError("pi->pData (page data) is null");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -504,7 +552,6 @@ void releaseBufPageInfo(SDiskbasedBuf* pBuf, SPageInfo* pi) {
|
|||
size_t getTotalBufSize(const SDiskbasedBuf* pBuf) { return (size_t)pBuf->totalBufSize; }
|
||||
|
||||
SArray* getDataBufPagesIdList(SDiskbasedBuf* pBuf) {
|
||||
ASSERT(pBuf != NULL);
|
||||
return pBuf->pIdList;
|
||||
}
|
||||
|
||||
|
@ -582,7 +629,6 @@ SPageInfo* getLastPageInfo(SArray* pList) {
|
|||
}
|
||||
|
||||
int32_t getPageId(const SPageInfo* pPgInfo) {
|
||||
ASSERT(pPgInfo != NULL);
|
||||
return pPgInfo->pageId;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
import sys
|
||||
from util.log import *
|
||||
from util.cases import *
|
||||
from util.sql import *
|
||||
from util.dnodes import tdDnodes
|
||||
from math import inf
|
||||
|
||||
class TDTestCase:
|
||||
def caseDescription(self):
|
||||
'''
|
||||
case1<shenglian zhou>: [TD-11204]Difference improvement that can ignore negative
|
||||
'''
|
||||
return
|
||||
|
||||
def init(self, conn, logSql, replicaVer=1):
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor(), False)
|
||||
self._conn = conn
|
||||
|
||||
def restartTaosd(self, index=1, dbname="db"):
|
||||
tdDnodes.stop(index)
|
||||
tdDnodes.startWithoutSleep(index)
|
||||
tdSql.execute(f"use scd")
|
||||
|
||||
def run(self):
|
||||
print("running {}".format(__file__))
|
||||
tdSql.execute("drop database if exists scd")
|
||||
tdSql.execute("create database if not exists scd")
|
||||
tdSql.execute('use scd')
|
||||
tdSql.execute('create table stb1 (ts timestamp, c1 bool, c2 tinyint, c3 smallint, c4 int, c5 bigint, c6 float, c7 double, c8 binary(10), c9 nchar(10), c10 tinyint unsigned, c11 smallint unsigned, c12 int unsigned, c13 bigint unsigned) TAGS(t1 int, t2 binary(10), t3 double);')
|
||||
|
||||
tdSql.execute("create table tb1 using stb1 tags(1,'1',1.0);")
|
||||
|
||||
tdSql.execute("create table tb2 using stb1 tags(2,'2',2.0);")
|
||||
|
||||
tdSql.execute("create table tb3 using stb1 tags(3,'3',3.0);")
|
||||
|
||||
tdSql.execute('create database scd2 stt_trigger 3;')
|
||||
|
||||
tdSql.execute('create database scd4 stt_trigger 13;')
|
||||
|
||||
tdSql.query('show create database scd;')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 'scd')
|
||||
tdSql.checkData(0, 1, "CREATE DATABASE `scd` BUFFER 256 CACHESIZE 1 CACHEMODEL 'none' COMP 2 DURATION 14400m WAL_FSYNC_PERIOD 3000 MAXROWS 4096 MINROWS 100 STT_TRIGGER 1 KEEP 5256000m,5256000m,5256000m PAGES 256 PAGESIZE 4 PRECISION 'ms' REPLICA 1 WAL_LEVEL 1 VGROUPS 2 SINGLE_STABLE 0")
|
||||
|
||||
tdSql.query('show create database scd2;')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 'scd2')
|
||||
tdSql.checkData(0, 1, "CREATE DATABASE `scd2` BUFFER 256 CACHESIZE 1 CACHEMODEL 'none' COMP 2 DURATION 14400m WAL_FSYNC_PERIOD 3000 MAXROWS 4096 MINROWS 100 STT_TRIGGER 3 KEEP 5256000m,5256000m,5256000m PAGES 256 PAGESIZE 4 PRECISION 'ms' REPLICA 1 WAL_LEVEL 1 VGROUPS 2 SINGLE_STABLE 0")
|
||||
|
||||
tdSql.query('show create database scd4')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 'scd4')
|
||||
tdSql.checkData(0, 1, "CREATE DATABASE `scd4` BUFFER 256 CACHESIZE 1 CACHEMODEL 'none' COMP 2 DURATION 14400m WAL_FSYNC_PERIOD 3000 MAXROWS 4096 MINROWS 100 STT_TRIGGER 13 KEEP 5256000m,5256000m,5256000m PAGES 256 PAGESIZE 4 PRECISION 'ms' REPLICA 1 WAL_LEVEL 1 VGROUPS 2 SINGLE_STABLE 0")
|
||||
|
||||
|
||||
self.restartTaosd(1, dbname='scd')
|
||||
|
||||
tdSql.query('show create database scd;')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 'scd')
|
||||
tdSql.checkData(0, 1, "CREATE DATABASE `scd` BUFFER 256 CACHESIZE 1 CACHEMODEL 'none' COMP 2 DURATION 14400m WAL_FSYNC_PERIOD 3000 MAXROWS 4096 MINROWS 100 STT_TRIGGER 1 KEEP 5256000m,5256000m,5256000m PAGES 256 PAGESIZE 4 PRECISION 'ms' REPLICA 1 WAL_LEVEL 1 VGROUPS 2 SINGLE_STABLE 0")
|
||||
|
||||
tdSql.query('show create database scd2;')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 'scd2')
|
||||
tdSql.checkData(0, 1, "CREATE DATABASE `scd2` BUFFER 256 CACHESIZE 1 CACHEMODEL 'none' COMP 2 DURATION 14400m WAL_FSYNC_PERIOD 3000 MAXROWS 4096 MINROWS 100 STT_TRIGGER 3 KEEP 5256000m,5256000m,5256000m PAGES 256 PAGESIZE 4 PRECISION 'ms' REPLICA 1 WAL_LEVEL 1 VGROUPS 2 SINGLE_STABLE 0")
|
||||
|
||||
tdSql.query('show create database scd4')
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 'scd4')
|
||||
tdSql.checkData(0, 1, "CREATE DATABASE `scd4` BUFFER 256 CACHESIZE 1 CACHEMODEL 'none' COMP 2 DURATION 14400m WAL_FSYNC_PERIOD 3000 MAXROWS 4096 MINROWS 100 STT_TRIGGER 13 KEEP 5256000m,5256000m,5256000m PAGES 256 PAGESIZE 4 PRECISION 'ms' REPLICA 1 WAL_LEVEL 1 VGROUPS 2 SINGLE_STABLE 0")
|
||||
|
||||
|
||||
tdSql.execute('drop database scd')
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -16,13 +16,7 @@
|
|||
"databases": [{
|
||||
"dbinfo": {
|
||||
"name": "db",
|
||||
"drop": "yes",
|
||||
"replica": 1,
|
||||
"precision": "ms",
|
||||
"keep": 36500,
|
||||
"minRows": 100,
|
||||
"maxRows": 4096,
|
||||
"comp":2
|
||||
"drop": "yes"
|
||||
},
|
||||
"super_tables": [{
|
||||
"name": "stb1",
|
||||
|
@ -37,7 +31,7 @@
|
|||
"line_protocol": "json",
|
||||
"childtable_limit": 0,
|
||||
"childtable_offset": 0,
|
||||
"insert_rows": 10,
|
||||
"insert_rows": 20,
|
||||
"insert_interval": 0,
|
||||
"interlace_rows": 0,
|
||||
"disorder_ratio": 0,
|
||||
|
@ -62,7 +56,7 @@
|
|||
"line_protocol": "json",
|
||||
"childtable_limit": 0,
|
||||
"childtable_offset": 0,
|
||||
"insert_rows": 10,
|
||||
"insert_rows": 20,
|
||||
"insert_interval": 0,
|
||||
"interlace_rows": 0,
|
||||
"disorder_ratio": 0,
|
||||
|
@ -87,7 +81,7 @@
|
|||
"line_protocol": "json",
|
||||
"childtable_limit": 0,
|
||||
"childtable_offset": 0,
|
||||
"insert_rows": 10,
|
||||
"insert_rows": 20,
|
||||
"insert_interval": 0,
|
||||
"interlace_rows": 0,
|
||||
"disorder_ratio": 0,
|
||||
|
@ -112,7 +106,7 @@
|
|||
"line_protocol": "json",
|
||||
"childtable_limit": 0,
|
||||
"childtable_offset": 0,
|
||||
"insert_rows": 10,
|
||||
"insert_rows": 20,
|
||||
"insert_interval": 0,
|
||||
"interlace_rows": 0,
|
||||
"disorder_ratio": 0,
|
||||
|
@ -137,7 +131,7 @@
|
|||
"line_protocol": "json",
|
||||
"childtable_limit": 0,
|
||||
"childtable_offset": 0,
|
||||
"insert_rows": 10,
|
||||
"insert_rows": 20,
|
||||
"insert_interval": 0,
|
||||
"interlace_rows": 0,
|
||||
"disorder_ratio": 0,
|
||||
|
@ -162,7 +156,7 @@
|
|||
"line_protocol": "json",
|
||||
"childtable_limit": 0,
|
||||
"childtable_offset": 0,
|
||||
"insert_rows": 10,
|
||||
"insert_rows": 20,
|
||||
"insert_interval": 0,
|
||||
"interlace_rows": 0,
|
||||
"disorder_ratio": 0,
|
||||
|
@ -187,7 +181,7 @@
|
|||
"line_protocol": "json",
|
||||
"childtable_limit": 0,
|
||||
"childtable_offset": 0,
|
||||
"insert_rows": 10,
|
||||
"insert_rows": 20,
|
||||
"insert_interval": 0,
|
||||
"interlace_rows": 0,
|
||||
"disorder_ratio": 0,
|
||||
|
@ -212,7 +206,7 @@
|
|||
"line_protocol": "json",
|
||||
"childtable_limit": 0,
|
||||
"childtable_offset": 0,
|
||||
"insert_rows": 10,
|
||||
"insert_rows": 20,
|
||||
"insert_interval": 0,
|
||||
"interlace_rows": 0,
|
||||
"disorder_ratio": 0,
|
||||
|
@ -237,7 +231,7 @@
|
|||
"line_protocol": "json",
|
||||
"childtable_limit": 0,
|
||||
"childtable_offset": 0,
|
||||
"insert_rows": 10,
|
||||
"insert_rows": 20,
|
||||
"insert_interval": 0,
|
||||
"interlace_rows": 0,
|
||||
"disorder_ratio": 0,
|
||||
|
|
|
@ -19,32 +19,38 @@ from util.dnodes import *
|
|||
|
||||
class TDTestCase:
|
||||
def caseDescription(self):
|
||||
'''
|
||||
"""
|
||||
[TD-11510] taosBenchmark test cases
|
||||
'''
|
||||
return
|
||||
"""
|
||||
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdSql.init(conn.cursor(), logSql)
|
||||
|
||||
def getPath(self, tool="taosBenchmark"):
|
||||
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if ("community" in selfPath):
|
||||
projPath = selfPath[:selfPath.find("community")]
|
||||
if "community" in selfPath:
|
||||
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:
|
||||
projPath = selfPath[:selfPath.find("tests")]
|
||||
tdLog.info("cannot found %s in path: %s, use system's" % (tool, selfPath))
|
||||
projPath = "/usr/local/taos/bin/"
|
||||
|
||||
paths = []
|
||||
for root, dirs, files in os.walk(projPath):
|
||||
if ((tool) in files):
|
||||
for root, dummy, files in os.walk(projPath):
|
||||
if (tool) in files:
|
||||
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))
|
||||
break
|
||||
if (len(paths) == 0):
|
||||
if len(paths) == 0:
|
||||
tdLog.exit("taosBenchmark not found!")
|
||||
return
|
||||
else:
|
||||
|
@ -52,49 +58,63 @@ class TDTestCase:
|
|||
return paths[0]
|
||||
|
||||
def run(self):
|
||||
tdSql.query("select client_version()")
|
||||
client_ver = "".join(tdSql.queryResult[0])
|
||||
major_ver = client_ver.split(".")[0]
|
||||
|
||||
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)
|
||||
os.system("%s" % cmd)
|
||||
tdSql.execute("reset query cache")
|
||||
tdSql.query("describe db.stb1")
|
||||
tdSql.checkData(1, 1, "BOOL")
|
||||
tdSql.query("describe db.stb2")
|
||||
tdSql.checkData(1, 1, "TINYINT")
|
||||
tdSql.checkData(1, 1, "DOUBLE")
|
||||
tdSql.query("describe db.stb3")
|
||||
tdSql.checkData(1, 1, "SMALLINT")
|
||||
tdSql.checkData(1, 1, "DOUBLE")
|
||||
tdSql.query("describe db.stb4")
|
||||
tdSql.checkData(1, 1, "INT")
|
||||
tdSql.checkData(1, 1, "DOUBLE")
|
||||
tdSql.query("describe db.stb5")
|
||||
tdSql.checkData(1, 1, "BIGINT")
|
||||
tdSql.checkData(1, 1, "DOUBLE")
|
||||
tdSql.query("describe db.stb6")
|
||||
tdSql.checkData(1, 1, "FLOAT")
|
||||
tdSql.checkData(1, 1, "DOUBLE")
|
||||
tdSql.query("describe db.stb7")
|
||||
tdSql.checkData(1, 1, "DOUBLE")
|
||||
tdSql.query("describe db.stb8")
|
||||
tdSql.checkData(1, 1, "VARCHAR")
|
||||
tdSql.checkData(1, 2, 16)
|
||||
if major_ver == "3":
|
||||
tdSql.checkData(1, 1, "VARCHAR")
|
||||
tdSql.checkData(1, 2, 16)
|
||||
else:
|
||||
tdSql.checkData(1, 1, "NCHAR")
|
||||
tdSql.checkData(1, 2, 8)
|
||||
|
||||
tdSql.query("describe db.stb9")
|
||||
tdSql.checkData(1, 1, "NCHAR")
|
||||
tdSql.checkData(1, 2, 16)
|
||||
if major_ver == "3":
|
||||
tdSql.checkData(1, 1, "VARCHAR")
|
||||
tdSql.checkData(1, 2, 16)
|
||||
else:
|
||||
tdSql.checkData(1, 1, "NCHAR")
|
||||
tdSql.checkData(1, 2, 8)
|
||||
|
||||
tdSql.query("select count(*) from db.stb1")
|
||||
tdSql.checkData(0, 0, 80)
|
||||
tdSql.checkData(0, 0, 160)
|
||||
tdSql.query("select count(*) from db.stb2")
|
||||
tdSql.checkData(0, 0, 80)
|
||||
tdSql.checkData(0, 0, 160)
|
||||
tdSql.query("select count(*) from db.stb3")
|
||||
tdSql.checkData(0, 0, 80)
|
||||
tdSql.checkData(0, 0, 160)
|
||||
tdSql.query("select count(*) from db.stb4")
|
||||
tdSql.checkData(0, 0, 80)
|
||||
tdSql.checkData(0, 0, 160)
|
||||
tdSql.query("select count(*) from db.stb5")
|
||||
tdSql.checkData(0, 0, 80)
|
||||
tdSql.checkData(0, 0, 160)
|
||||
tdSql.query("select count(*) from db.stb6")
|
||||
tdSql.checkData(0, 0, 80)
|
||||
tdSql.checkData(0, 0, 160)
|
||||
tdSql.query("select count(*) from db.stb7")
|
||||
tdSql.checkData(0, 0, 80)
|
||||
tdSql.checkData(0, 0, 160)
|
||||
tdSql.query("select count(*) from db.stb8")
|
||||
tdSql.checkData(0, 0, 80)
|
||||
tdSql.checkData(0, 0, 160)
|
||||
tdSql.query("select count(*) from db.stb9")
|
||||
tdSql.checkData(0, 0, 80)
|
||||
tdSql.checkData(0, 0, 160)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
|
|
@ -23,7 +23,7 @@ python3 bind_param_example.py
|
|||
|
||||
# 4
|
||||
taos -s "drop database power"
|
||||
python3 multi_bind_example.py
|
||||
python3 multi_bind_example.py
|
||||
|
||||
# 5
|
||||
python3 query_example.py
|
||||
|
@ -44,4 +44,43 @@ taos -s "drop database test"
|
|||
python3 json_protocol_example.py
|
||||
|
||||
# 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
|
||||
|
|
|
@ -1060,6 +1060,7 @@
|
|||
|
||||
#develop test
|
||||
,,n,develop-test,python3 ./test.py -f 2-query/table_count_scan.py
|
||||
,,n,develop-test,python3 ./test.py -f 2-query/show_create_db.py
|
||||
,,n,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/auto_create_table_json.py
|
||||
,,n,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/custom_col_tag.py
|
||||
,,n,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/default_json.py
|
||||
|
|
|
@ -55,7 +55,7 @@ fi
|
|||
date
|
||||
docker run \
|
||||
-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
|
||||
echo "delete ${WORKDIR}/debugNoSan"
|
||||
|
@ -70,7 +70,7 @@ mv ${REP_REAL_PATH}/debug ${WORKDIR}/debugNoSan
|
|||
date
|
||||
docker run \
|
||||
-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
|
||||
|
||||
|
|
|
@ -2828,7 +2828,7 @@ void runAll(TAOS *taos) {
|
|||
printf("%s Begin\n", gCaseCtrl.caseCatalog);
|
||||
runCaseList(taos);
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
strcpy(gCaseCtrl.caseCatalog, "Micro DB precision Test");
|
||||
printf("%s Begin\n", gCaseCtrl.caseCatalog);
|
||||
gCaseCtrl.precision = TIME_PRECISION_MICRO;
|
||||
|
|
|
@ -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.ctb8 values(now, 8, "8")
|
||||
sql insert into db.ctb9 values(now, 9, "9")
|
||||
sql flush database db;
|
||||
|
||||
print =============== step3: create dnodes
|
||||
sql create dnode $hostname port 7300
|
||||
|
|
|
@ -86,4 +86,23 @@ if $data00 != @ins_tags@ then
|
|||
return -1
|
||||
endi
|
||||
|
||||
sql create stable stb(ts timestamp, f int) tags(t1 int, t2 int, t3 int, t4 int, t5 int);
|
||||
|
||||
$i = 0
|
||||
$tbNum = 1000
|
||||
$tbPrefix = stb_tb
|
||||
while $i < $tbNum
|
||||
$tb = $tbPrefix . $i
|
||||
sql create table $tb using stb tags( $i , $i , $i , $i , $i )
|
||||
|
||||
$i = $i + 1
|
||||
endw
|
||||
|
||||
sql select tag_value from information_schema.ins_tags where stable_name='stb';
|
||||
if $rows != 5000 then
|
||||
print $rows
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
#system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
|
|
@ -81,8 +81,60 @@ if $data01 != 10 then
|
|||
endi
|
||||
|
||||
#===================================================================
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
print =============== wait maxdelay 15+2 seconds for results after reboot
|
||||
sleep 17000
|
||||
|
||||
#==================== reboot to trigger commit data to file
|
||||
print =============== select * from retention level 2 from memory after reboot
|
||||
sql select * from ct1;
|
||||
print $data00 $data01
|
||||
if $rows > 2 then
|
||||
print retention level 2 file rows $rows > 2
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
if $data01 != 1 then
|
||||
if $data01 != 10 then
|
||||
print =============> $data01
|
||||
print retention level 2 file result $data01 != 1 or 10
|
||||
return -1
|
||||
endi
|
||||
endi
|
||||
|
||||
print =============== select * from retention level 1 from memory after reboot
|
||||
sql select * from ct1 where ts > now-8d;
|
||||
print $data00 $data01
|
||||
if $rows > 2 then
|
||||
print retention level 1 file rows $rows > 2
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 1 then
|
||||
if $data01 != 10 then
|
||||
print retention level 1 file result $data01 != 1 or 10
|
||||
return -1
|
||||
endi
|
||||
endi
|
||||
|
||||
print =============== select * from retention level 0 from memory after reboot
|
||||
sql select * from ct1 where ts > now-3d;
|
||||
print $data00 $data01
|
||||
print $data10 $data11
|
||||
print $data20 $data21
|
||||
|
||||
if $rows < 1 then
|
||||
print retention level 0 file rows $rows < 1
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 10 then
|
||||
print retention level 0 file result $data01 != 10
|
||||
return -1
|
||||
endi
|
||||
|
||||
#==================== flush database to trigger commit data to file
|
||||
sql flush database d0;
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
|
|
|
@ -82,9 +82,62 @@ if $data01 != 10 then
|
|||
endi
|
||||
|
||||
#===================================================================
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
print =============== wait maxdelay 5+2 seconds for results after reboot
|
||||
sleep 7000
|
||||
|
||||
print =============== select * from retention level 2 from memory after reboot
|
||||
sql select * from ct1;
|
||||
print $data00 $data01 $data02
|
||||
print $data10 $data11 $data12
|
||||
if $rows > 2 then
|
||||
print retention level 2 file rows $rows > 2
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
#==================== reboot to trigger commit data to file
|
||||
if $data01 != 100 then
|
||||
if $data01 != 10 then
|
||||
print retention level 2 file result $data01 != 100 or 10
|
||||
return -1
|
||||
endi
|
||||
endi
|
||||
|
||||
print =============== select * from retention level 1 from memory after reboot
|
||||
sql select * from ct1 where ts > now-8d;
|
||||
print $data00 $data01 $data02
|
||||
print $data10 $data11 $data12
|
||||
if $rows > 2 then
|
||||
print retention level 1 file rows $rows > 2
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 100 then
|
||||
if $data01 != 10 then
|
||||
print retention level 1 file result $data01 != 100 or 10
|
||||
return -1
|
||||
endi
|
||||
endi
|
||||
|
||||
print =============== select * from retention level 0 from memory after reboot
|
||||
sql select * from ct1 where ts > now-3d;
|
||||
print $data00 $data01 $data02
|
||||
print $data10 $data11 $data12
|
||||
print $data20 $data21 $data22
|
||||
|
||||
if $rows < 1 then
|
||||
print retention level 0 file rows $rows < 1
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 10 then
|
||||
print retention level 0 file result $data01 != 10
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
#==================== flush database to trigger commit data to file
|
||||
sql flush database d0;
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
|
|
|
@ -136,7 +136,76 @@ system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
|||
system sh/exec.sh -n dnode1 -s start
|
||||
sleep 50
|
||||
|
||||
print =============== select * from ct1 from memory after reboot
|
||||
sql select * from ct1;
|
||||
print $data00 $data01 $data02 $data03
|
||||
print $data10 $data11 $data12 $data13
|
||||
print $data20 $data21 $data22 $data23
|
||||
print $data30 $data31 $data32 $data33
|
||||
print $data40 $data41 $data42 $data43
|
||||
if $rows != 5 then
|
||||
print rows $rows != 5
|
||||
return -1
|
||||
endi
|
||||
|
||||
print =============== select * from stb from memory in designated vgroup after reboot
|
||||
sql select _wstart, _wend, min(c1),max(c2),max(c1) from stb interval(5m,10s) sliding(5m);
|
||||
print $data00 $data01 $data02 $data03 $data04
|
||||
print $data10 $data11 $data12 $data13 $data14
|
||||
if $rows != 1 then
|
||||
print rows $rows != 1
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != -13 then
|
||||
print data02 $data02 != -13
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 20.00000 then
|
||||
print data03 $data03 != 20.00000
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data04 != 20 then
|
||||
print data04 $data04 != 20
|
||||
return -1
|
||||
endi
|
||||
|
||||
print =============== select * from stb from memory in common vgroups after reboot
|
||||
sql select _wstart, _wend, min(c1),max(c2),max(c1),max(c3) from stb interval(5m,10s) sliding(5m);
|
||||
print $data00 $data01 $data02 $data03 $data04 $data05
|
||||
if $rows != 1 then
|
||||
print rows $rows != 1
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != -13 then
|
||||
print data02 $data02 != -13
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 20.00000 then
|
||||
print data03 $data03 != 20.00000
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data04 != 20 then
|
||||
print data04 $data04 != 20
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data05 != 30.000000000 then
|
||||
print data05 $data05 != 30.000000000
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
#==================== flush database to trigger commit data to file
|
||||
sql flush database d1;
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sleep 50
|
||||
print =============== select * from ct1 from file
|
||||
sql select * from ct1;
|
||||
print $data00 $data01 $data02 $data03
|
||||
|
|
|
@ -206,7 +206,7 @@ class TDTestCase:
|
|||
paraDict['rowsPerTbl'] = self.rowsPerTbl
|
||||
consumerId = 1
|
||||
if self.snapshot == 0:
|
||||
expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (2))
|
||||
expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (1/2))
|
||||
elif self.snapshot == 1:
|
||||
expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (1))
|
||||
|
||||
|
|
|
@ -213,9 +213,9 @@ class TDTestCase:
|
|||
paraDict['rowsPerTbl'] = self.rowsPerTbl
|
||||
consumerId = 1
|
||||
if self.snapshot == 0:
|
||||
expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (2 + 1/2*1/2*2 + 1/2*1/2))
|
||||
expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (1/2) * (1/2*3))
|
||||
elif self.snapshot == 1:
|
||||
expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (2 + 1/2*1/2))
|
||||
expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (1 + 1/2))
|
||||
|
||||
topicList = topicFromStb1
|
||||
ifcheckdata = 1
|
||||
|
|
|
@ -148,5 +148,6 @@ void shellRunSingleCommandWebsocketImp(char *command);
|
|||
|
||||
// shellMain.c
|
||||
extern SShellObj shell;
|
||||
extern void tscWriteCrashInfo(int signum, void *sigInfo, void *context);
|
||||
|
||||
#endif /*_TD_SHELL_INT_H_*/
|
||||
|
|
|
@ -1137,10 +1137,8 @@ int32_t shellExecute() {
|
|||
|
||||
taosSetSignal(SIGTERM, shellQueryInterruptHandler);
|
||||
taosSetSignal(SIGHUP, shellQueryInterruptHandler);
|
||||
taosSetSignal(SIGABRT, shellQueryInterruptHandler);
|
||||
|
||||
taosSetSignal(SIGINT, shellQueryInterruptHandler);
|
||||
|
||||
|
||||
#ifdef WEBSOCKET
|
||||
if (!shell.args.restful && !shell.args.cloud) {
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,29 @@
|
|||
|
||||
SShellObj shell = {0};
|
||||
|
||||
|
||||
void shellCrashHandler(int signum, void *sigInfo, void *context) {
|
||||
taosIgnSignal(SIGTERM);
|
||||
taosIgnSignal(SIGHUP);
|
||||
taosIgnSignal(SIGINT);
|
||||
taosIgnSignal(SIGBREAK);
|
||||
|
||||
#if !defined(WINDOWS)
|
||||
taosIgnSignal(SIGBUS);
|
||||
#endif
|
||||
taosIgnSignal(SIGABRT);
|
||||
taosIgnSignal(SIGFPE);
|
||||
taosIgnSignal(SIGSEGV);
|
||||
|
||||
tscWriteCrashInfo(signum, sigInfo, context);
|
||||
|
||||
#ifdef _TD_DARWIN_64
|
||||
exit(signum);
|
||||
#elif defined(WINDOWS)
|
||||
exit(signum);
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
shell.exit = false;
|
||||
#ifdef WEBSOCKET
|
||||
|
@ -26,6 +49,13 @@ int main(int argc, char *argv[]) {
|
|||
shell.args.cloud = true;
|
||||
#endif
|
||||
|
||||
#if !defined(WINDOWS)
|
||||
taosSetSignal(SIGBUS, shellCrashHandler);
|
||||
#endif
|
||||
taosSetSignal(SIGABRT, shellCrashHandler);
|
||||
taosSetSignal(SIGFPE, shellCrashHandler);
|
||||
taosSetSignal(SIGSEGV, shellCrashHandler);
|
||||
|
||||
if (shellCheckIntSize() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue