Compare commits

...

260 Commits

Author SHA1 Message Date
Zhen Ye
3439c3eb45
fix: interleave the go and cpp log (#46005)
issue: #45640
pr: #46004

Signed-off-by: chyezh <chyezh@outlook.com>
2025-12-03 14:27:12 +08:00
sre-ci-robot
7109b2062a
test: e2e tests support to run on gcp and aws on 2.6 branch [p0] (#45980)
pr: #45621

---------

Signed-off-by: Zhikun Yao <zhikun.yao@zilliz.com>
Co-authored-by: zhikunyao <zhikun.yao@zilliz.com>
2025-12-03 11:01:10 +08:00
nico
7b6aa2175f
test: update sdk version (#46002)
pr: #45809

Signed-off-by: nico <cheng.yuan@zilliz.com>
2025-12-02 19:05:11 +08:00
wei liu
1e89b8b94a
enhance: [2.6] Upgrade pulsar-client-go to v0.17.0(#46007) (#46013)
issue: #46006
pr: #46007

Upgrade apache/pulsar-client-go from v0.15.1 to v0.17.0 to fix send
buffer race condition (apache/pulsar-client-go#1394)

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
2025-12-02 18:47:10 +08:00
wei liu
c258d03a01
fix: [2.6] Enable leader checker to sync segment distribution to RO nodes (#45949) (#45991)
issue: #45865
pr: #45949

- Modified leader_checker.go to include all nodes (RO + RW) instead of
only RW nodes, preventing channel balance from stucking on RO nodes
- Added debug logging in segment_checker.go when no shard leader found
- Enhanced target_observer.go with detailed logging for delegator check
failures to improve debugging visibility
- Fixed integration tests:
- Temporarily disabled partial result counter assertion in
partial_result_on_node_down_test.go pending concurrent issue fix
- Increased transfer channel timeout from 10s to 20s in
manual_rolling_upgrade_test.go to avoid flaky test caused by target
update interval (10s)

---------

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
2025-12-02 17:47:10 +08:00
congqixia
99eccffe03
enhance: [2.6] Bump Go SDK pkg dependency fixing code checker (#45992)
Follow up for #45971

Update the `milvus/pkg/v2` dependency in both root and client modules to
align with the latest v2.6.7 release, and improve Makefile lint-fix
target logging.

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-12-02 13:09:10 +08:00
Zhen Ye
b71a123d25
fix: write ahead buffer unittest failure (#45979)
issue: #45977 
pr: #45978

Signed-off-by: chyezh <chyezh@outlook.com>
2025-12-02 11:39:09 +08:00
zhuwenxing
ce762358af
test: [cp2.6]unify schema retrieval to use get_schema() method in chaos checker (#45986)
master pr: https://github.com/milvus-io/milvus/pull/45985



Replace direct self.schema access and describe_collection() calls with
get_schema() method to ensure consistent schema handling with complete
struct_fields information. Also fix FlushChecker error handling and
change schema log level from info to debug.

Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
2025-12-02 10:51:10 +08:00
congqixia
af64f2acba
enhance: Bump milvus & proto version to v2.6.7 (#45971)
Bump milvus & proto version

Also bump golang.org/x/crypto to v0.45.0 fixing CVE-2025-47914

Related to #45976

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-12-01 20:03:10 +08:00
zhuwenxing
9b0e5cf032
test: [cp2.6]refactor connection method to prioritize uri/token and add query limit (#45948)
master pr: #45901

Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
2025-12-01 19:55:10 +08:00
Zhen Ye
e9d920a785
enhance: support proxy DML forward (#45922)
issue: #45812
pr: #45921

- 2.6 proxy will try to forward DWL to 2.5 proxy if streaming service is
not ready

Signed-off-by: chyezh <chyezh@outlook.com>
2025-12-01 19:39:10 +08:00
Zhen Ye
9942454811
enhance: remove watch at session liveness check (#45974)
issue: #45724
pr: #45968

---------

Signed-off-by: chyezh <chyezh@outlook.com>
2025-12-01 19:29:10 +08:00
zhagnlu
731178a97f
enhance: remove some meta cache for json shredding (#45889)
pr: #45888

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-12-01 15:55:09 +08:00
zhagnlu
8ee392a682
enhance: make estimate json stats size more accurate (#45876)
pr: #45875

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-12-01 15:49:09 +08:00
zhuwenxing
511516a61b
test: [cp2.6]add dynamicfield.enabled property alter in chaos checker (#45950)
pr: #45625

Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
2025-12-01 15:45:10 +08:00
zhuwenxing
9ac5d66dc6
test: [cp 2.6]fix apikey setting in restful v2 testcases (#45940)
master pr: #45396

Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
2025-12-01 15:43:15 +08:00
junjiejiangjjj
2989fbc666
fix: [2.6] Sum AllSearchCount from multiple search results (#45904)
https://github.com/milvus-io/milvus/issues/45842
pr: https://github.com/milvus-io/milvus/pull/45914

Signed-off-by: junjie.jiang <junjie.jiang@zilliz.com>
2025-12-01 14:45:10 +08:00
congqixia
17ac58a731
fix: [2.6] always call handleNodeUp in rewatchNodes for proper stopping balance (#45963)
Cherry-pick from master
pr: #45961 
Related to #45960

When QueryCoord restarts or reconnects to etcd, the rewatchNodes
function previously skipped handleNodeUp for QueryNodes in stopping
state. This caused stopping balance to fail because necessary components
were not initialized:
- Task scheduler executor was not added
- Dist handler was not started
- Node was not registered in resource manager

This fix ensures handleNodeUp is always called for new nodes regardless
of their stopping state, followed by handleNodeStopping if the node is
stopping. This allows the graceful shutdown process to correctly migrate
segments and channels away from stopping nodes.

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-12-01 14:03:09 +08:00
Buqian Zheng
5b77d45a27
fix: [2.6] term expr to correctly handle in of string in json (#45956)
issue: https://github.com/milvus-io/milvus/issues/45887
pr: https://github.com/milvus-io/milvus/pull/45955

---------

Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
2025-11-29 21:55:09 +08:00
sparknack
45bda55716
enhance: [2.6] always use buffered io for high load priority (#45958)
issue: #43040
pr: #45900

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-29 20:53:08 +08:00
Xiaofan
b8e28d227d
enhance: [2.6]Upgrade etcd to 3.5.23 (#45953)
upgrade the etcd client and dependency to 2.5.23
related: #45947
pr: #44666
issue: #44614

Signed-off-by: xiaofanluan <xiaofan.luan@zilliz.com>
2025-11-29 16:38:09 +08:00
sparknack
52aa31324c
fix: [2.6] milvus-common update (#45930)
issue: #41435
pr: #45929

fix some usage tracking bugs in caching layer.

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-29 09:39:06 +08:00
sparknack
e0fe0d7169
enhance: [2.6] check both eviction and warmup when estimate segment loading size (#45891)
issue: #44857
pr: #45222

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-29 02:19:09 +08:00
sparknack
7afa1e7ce4
enhance: [2.6] mmap once for each group chunk (#45893)
issue: #45486
pr: #45487

This commit refactors the chunk writing system by introducing a
two-phase
approach: size calculation followed by writing to a target. This enables
efficient group chunk creation where multiple fields share a single mmap
region, significantly reducing the number of mmap system calls and VMAs.

- Optimize `mmap` usage: single `mmap` per group chunk instead of per
field
- Split ChunkWriter into two phases:
  - `calculate_size()`: Pre-compute required memory without allocation
  - `write_to_target()`: Write data to a provided ChunkTarget
- Implement `ChunkMmapGuard` for unified mmap region lifecycle
management
  - Handles `munmap` and file cleanup via RAII
  - Shared via `std::shared_ptr` across multiple chunks in a group



---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-28 23:55:09 +08:00
sparknack
5d3e4dd038
enhance: [2.6] add cancellation checking in each operator and expr (#45894)
issue: #45353
pr: #45354

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-28 19:41:08 +08:00
wei liu
b2ef076597
fix: [2.6] prevent panic in standby mixcoord during shutdown #45859 (#45898)
issue: #45728
pr: #45730
When mixcoord is in standby mode and shutdown is triggered, the
ProcessActiveStandBy goroutine may panic if context cancellation occurs.
This happens because the error handling didn't check for
context.Canceled errors before panicking.

Changes:
- Add context cancellation check in mix_coord Register() before panic
- Check s.ctx.Err() == context.Canceled and gracefully exit
- Remove unused ForceActiveStandby() function from session_util

This ensures standby mixcoord can shutdown gracefully without panic when
context is cancelled during the standby process.

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
2025-11-28 19:33:09 +08:00
Spade A
5ba7c4ed35
fix: fix false negative panic on missing fields [2.6] (#45903)
pr: https://github.com/milvus-io/milvus/pull/45902
issue: https://github.com/milvus-io/milvus/issues/45834

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-11-28 18:53:08 +08:00
Feilong Hou
eaed10538d
test: add e2e test cases for Timestamptz (#45800)
Issue: #44518, #45756
pr: #44871, #45128, #45770, #45524,  #44794, #45014

---------

Signed-off-by: Eric Hou <eric.hou@zilliz.com>
Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
Co-authored-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: zhuwenxing <wenxing.zhu@zilliz.com>
2025-11-28 18:01:09 +08:00
zhenshan.cao
b948c62413
feat: Add /livez for Liveness Probes (#45454) (#45481)
issue: https://github.com/milvus-io/milvus/issues/45443
pr: https://github.com/milvus-io/milvus/pull/45454

Signed-off-by: zhenshan.cao <zhenshan.cao@zilliz.com>
2025-11-28 18:00:00 +08:00
Zhen Ye
3e96bcc979
enhance: support async write syncer for milvus logging (#45806)
issue: #45640
pr: #45805

- log may be dropped if the underlying file system is busy.
- use async write syncer to avoid the log operation block the milvus
major system.
- remove some log dependency from the until function to avoid
dependency-loop.

---------

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-28 17:55:08 +08:00
yihao.dai
20592fb236
enhance: [2.6] Skip redundant failure marking for completed import jobs (#45768)
Skip redundant failure marking for completed import jobs when the
collection is dropped or import jobs are timeout.

issue: https://github.com/milvus-io/milvus/issues/45766

pr: https://github.com/milvus-io/milvus/pull/45767

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
2025-11-28 17:47:08 +08:00
Buqian Zheng
adf2be6506
enhance: batch cp optimizations to 2.6 (#45869)
issue: #44452
pr: #45829
pr: #45328
pr: #45307
pr: #45008
pr: #44634

---------

Signed-off-by: zhagnlu <lu.zhang@zilliz.com>
Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
Co-authored-by: zhagnlu <lu.zhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-11-28 17:43:11 +08:00
cai.zhang
07727e7f25
fix: [2.6] Ensure the proxy's shard-leader cache remains stable for coord down test (#45909)
issue: #45847 
master pr: #45908 

After a collection is successfully loaded, the shard-leader state on the
QC may still not be marked as serviceable. It becomes serviceable only
after the scheduled distribution update runs, which will also invalidate
the shard-leader cache on the proxy. Therefore, even if queries are
already executable, the shard-leader mapping on the proxy may still
change afterward.

Try to ensure—as much as possible—that the proxy’s shard-leader cache
remains stable before killing the mixcoord.

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-28 17:29:08 +08:00
Zhen Ye
da601d2a3c
fix: remove the streamingnode checking when loading segment (#45860)
issue: #43117
pr: #45859

If we enable checking when loading segments, all segment should always
be loaded by streamingnode but not 2.5 querynode, make some search and
query failure when upgrading. Otherwise, some search and query result
will be wrong when upgrading. We choose to disable this checking for now
to promise available search and query when upgrading.

also see pr: #43346

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-28 11:23:08 +08:00
congqixia
18493d5cf5
fix: [2.6] Add EmptySessionWatcher to prevent panic in IndexNodeBinding mode (#45912)
Cherry-pick from master
pr: #45911
Related to #45910

When IndexNodeBinding mode is enabled, DataCoord skips session watching
for datanodes but the dnSessionWatcher field remains nil. This causes a
panic when other code attempts to access the watcher.

This fix introduces an EmptySessionWatcher as a placeholder for the
IndexNodeBinding mode scenario. The empty watcher implements the
SessionWatcher interface with no-op methods, preventing nil pointer
dereferences while maintaining the expected interface contract.

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-28 10:21:08 +08:00
tinswzy
1403bfdc68
enhance: [2.6] improve WAL retention strategy (#45784)
pr: #45350
issue: #44369

Signed-off-by: tinswzy <zhenyuan.wei@zilliz.com>
2025-11-28 10:07:08 +08:00
Zhen Ye
d20b332e63
fix: executor/scheduler should be latest replica meta but not replica copy (#45878)
issue: #45865
pr: #45877

---------

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-28 08:49:08 +08:00
zhenshan.cao
4cdeea5ddd
enhance: timestamptz support groupby (#45763)
issue: https://github.com/milvus-io/milvus/issues/45761
pr: https://github.com/milvus-io/milvus/pull/45762

Signed-off-by: zhenshan.cao <zhenshan.cao@zilliz.com>
2025-11-27 20:01:08 +08:00
zhagnlu
49c6a5382c
enhance: support mmap for jsonstats shared key index (#45861)
pr: #44914

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-11-27 16:07:08 +08:00
cai.zhang
58e4673081
fix:[2.6]Reduce qc check node in replica interval for test (#45838)
issue: #45791 
master pr: #45837

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-27 15:09:09 +08:00
Chun Han
195022a8f0
enhance: remove useless code(#30376) (#45713)
related: #30376
pr: https://github.com/milvus-io/milvus/pull/45685

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-11-27 13:59:08 +08:00
Zhen Ye
507fe62027
fix: LastConfirmedMessageID may be wrong if high concurrent writing (#45874)
issue: #45872
pr: #45873

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-27 12:03:07 +08:00
cai.zhang
1a2c21205d
fix: [2.6] Increase the random suffix of the import test collection name (#45855)
issue: #45853 
master pr: #45854

---------

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-27 10:09:07 +08:00
Xiaofan
cbb79dae8c
enhance: [2.6] add robust handle etcd servercrash (#45633)
issue: #45303
pr: #45304
fix milvus pod may restart when etcd pod start

---------

Signed-off-by: xiaofanluan <xiaofan.luan@zilliz.com>
2025-11-27 07:45:08 +08:00
Xiaofan
607c9ef40c
fix: [2.6]listImport and getImportProgress should follow import access (#45862)
issue: #45709
pr: #45822

Signed-off-by: xiaofanluan <xiaofan.luan@zilliz.com>
2025-11-27 02:11:10 +08:00
zhagnlu
fafec35bdc
fix:fix undefined behavior for dump snapshot (#45612)
pr: #45611

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-11-26 20:17:12 +08:00
jac
59e1b0b5b7
test: update pymilvus to 2.6.4rc13 for milvus2.6 (#45836)
Signed-off-by: silas.jiang <silas.jiang@zilliz.com>
Co-authored-by: silas.jiang <silas.jiang@zilliz.com>
2025-11-26 15:47:09 +08:00
Buqian Zheng
ce302c1555
enhance: [2.6] add vector reserve to improve memory allocation in segcore (#45759)
This commit optimizes std::vector usage across segcore by adding
reserve() calls where the size is known in advance, reducing memory
reallocations during push_back operations.

Changes:

TimestampIndex.cpp: Reserve space for prefix_sums and timestamp_barriers
SegmentGrowingImpl.cpp: Reserve space for binlog info vectors
ChunkedSegmentSealedImpl.cpp: Reserve space for futures and field data
vectors
storagev2translator/GroupChunkTranslator.cpp: Reserve space for metadata
vectors
This improves performance by avoiding multiple memory reallocations when
the vector size is predictable.

issue: https://github.com/milvus-io/milvus/issues/45679
pr: https://github.com/milvus-io/milvus/pull/45757

Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
2025-11-26 10:33:09 +08:00
cai.zhang
feffbf90d2
fix: [2.6]Search before kill coord to ensure proxy init shard leader cache (#45849)
issue: #45847 
master pr: #45848

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-26 04:05:11 +08:00
Bingyi Sun
a5008ea509
fix: Replace json.doc() calls with json.dom_doc() in JsonContainsExpr (#45786)
issue: https://github.com/milvus-io/milvus/issues/45783
pr: https://github.com/milvus-io/milvus/pull/45573

Signed-off-by: sunby <sunbingyi1992@gmail.com>
2025-11-25 20:15:07 +08:00
XuanYang-cn
eef2d5b1a8
fix: [cp26]Move Init and Remove EZ logic out of metatable (#45828)
This will avoid endless retry CreateDatabase/DropDatabase when
cipherPlugin fails in the new DDL framework.

See also: #45826
pr: #45827

---------

Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-11-25 20:11:07 +08:00
XuanYang-cn
4cc6e015d4
enhance: [cp26]Enable to merge sort one segment (#45652) (#45686)
Remove the log stack when setting isCompacting

pr: #45652

Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-11-25 19:55:07 +08:00
Buqian Zheng
1f2645dea0
fix: [2.6] Remove debug logging from JsonFlatIndex (#45818)
issue: https://github.com/milvus-io/milvus/issues/44452
pr: #44807

Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
2025-11-25 19:47:07 +08:00
groot
1e5c49a463
fix: [2.6] Fix a bug that bulkimport cannot handle empty struct list (#45692)
issue: https://github.com/milvus-io/milvus/issues/42148
pr: https://github.com/milvus-io/milvus/pull/45693

Signed-off-by: yhmo <yihua.mo@zilliz.com>
2025-11-25 18:21:07 +08:00
yanliang567
428526aa22
test: [cp2.6] Update hybrid search tests to milvus client style (#45810)
related issue: https://github.com/milvus-io/milvus/issues/45326
releted pr: #45772 

1. also cp more async tests to 2.6

---------

Signed-off-by: yanliang567 <yanliang.qiao@zilliz.com>
2025-11-25 14:25:07 +08:00
aoiasd
b92f17b138
fix: [2.6] segcore collection schema update not concurrent safe. (#45618)
relate: https://github.com/milvus-io/milvus/issues/45345
pr: https://github.com/milvus-io/milvus/pull/45337

Signed-off-by: aoiasd <zhicheng.yue@zilliz.com>
2025-11-25 10:33:06 +08:00
Buqian Zheng
3394ac86f6
enhance: [2.6] add ScalarFieldProto& overload to avoid unnecessary copies (#45742)
1. Array.h: Add output_data(ScalarFieldProto&) overload for both Array
and ArrayView classes
2. Use std::string_view instead of std::string for VARCHAR and GEOMETRY
types to avoid extra string copies
3. Call Reserve(length_) before writing to proto objects to reduce
memory reallocations

a simple test shows those optimizations improve the Array of Varchar
bulk_subscript performance by 20%

issue: https://github.com/milvus-io/milvus/issues/45679
pr: https://github.com/milvus-io/milvus/pull/45743

Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
2025-11-24 22:19:06 +08:00
Zhen Ye
f49951e900
fix: keep memory state consistent when recovering broadcast task from proto (#45788)
issue: #45782
pr: #45787

- because the zero value of the repeated field and bytes field in proto
is ignored or treated as empty value but not nil pointer, so we need to
fix the recovery info of the broadcast task from proto to keep the
consistency of memory state.

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-24 20:21:06 +08:00
XuanYang-cn
0a89b23240
fix: [cp26]Use base64 to encode not utf-8 bytes (#45656)
See also: #45654
pr: #45655

Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-11-24 20:11:07 +08:00
aoiasd
37b163613b
enhance: [2.6] remove resource type from file resource config (#45103) (#45727)
File resource type was useless till now, remove it before new release. 
relate: https://github.com/milvus-io/milvus/issues/43687
pr: https://github.com/milvus-io/milvus/pull/45103

Signed-off-by: aoiasd <zhicheng.yue@zilliz.com>
2025-11-24 11:37:06 +08:00
XuanYang-cn
276a8628d2
test: Increase PyMilvus version to 2.6.4rc12 for 2.6 branch (#45776)
Automated daily bump from pymilvus 2.6 branch. Updates
tests/python_client/requirements.txt.

Signed-off-by: XuanYang-cn <xuan.yang@zilliz.com>
2025-11-24 10:25:06 +08:00
Zhen Ye
22a7ac0ec6
fix: use remote wal when local wal shutdown (#45754)
issue: #45750
pr: #45753

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-22 21:57:05 +08:00
sre-ci-robot
1a37f6d56b
[automated] Bump milvus version to v2.6.6 (#45765)
Bump milvus version to v2.6.6
Signed-off-by: sre-ci-robot sre-ci-robot@users.noreply.github.com

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-21 16:45:05 +08:00
qixuan
171f218328
test:[cp2.6] add field case about dynamic and compaction (#45749)
master pr: #45694 
releated issue: #42126

Signed-off-by: qixuan <673771573@qq.com>
2025-11-21 14:21:05 +08:00
zhenshan.cao
476c7a181c
fix: Partial update panic with TIMESTAMPTZ (#45741)
issue: https://github.com/milvus-io/milvus/issues/45729
pr: https://github.com/milvus-io/milvus/pull/45740

Signed-off-by: zhenshan.cao <zhenshan.cao@zilliz.com>
2025-11-20 21:19:58 +08:00
Zhen Ye
9a34fb61fa
fix: use 2.6.6 for milvus DDL upgrading (#45739)
issue: #43897
pr: #45738

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-20 19:26:54 +08:00
Zhen Ye
92f4b48a3c
fix: use latest timetick to expire cache (#45699)
issue: #45697
pr: #45717

- also remove the  too frequent metric collection of tokenizer.

---------

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-20 18:32:52 +08:00
congqixia
151ade0215
enhance: Bump milvus & proto version to v2.6.6 (#45657)
Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-20 18:27:05 +08:00
Zhen Ye
a48f7ae170
fix: streamingnode should exit when initializing failure (#45732)
issue: #45721
pr: #45731

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-20 18:24:19 +08:00
liliu-z
bc3b1bf61c
enhance: Fix CVE-2025-63811 (#45658)
Fix CVE-2025-63811
pr: #45659

Signed-off-by: Li Liu <li.liu@zilliz.com>
2025-11-20 17:20:02 +08:00
wei liu
efd9367c1f
enhance: [2.6] Remove large segment ID arrays from QueryNode logs (#45720)
issue: #45718
pr: #45719
Logging complete segment ID arrays caused excessive log volume (3-6 TB
for 200k segments). Remove arrays from logger fields and keep only
segment counts for observability.

Changes:
- Remove requestSegments/preparedSegments arrays from Load logger
- Remove segmentIDs from BM25 stats logs
- Remove entries structure from sync distribution log

This reduces log volume by 99.99% for large-scale operations.

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
2025-11-20 17:18:30 +08:00
Bingyi Sun
1ebb31e868
enhance: skip test_milvus_client_search_json_path_index_default (#45605)
To prevent this issue from blocking other PRs, we are temporarily
disabling this test. A proper fix will be implemented before the 2.6.6
release.

pr: https://github.com/milvus-io/milvus/pull/45604
issue: https://github.com/milvus-io/milvus/issues/45511

---------

Signed-off-by: sunby <sunbingyi1992@gmail.com>
2025-11-20 16:53:09 +08:00
congqixia
29c9132e55
fix: [2.6] protect tbb concurrent_map emplace to avoid race condition deadlock (#45682)
Cherry-pick from master
pr: #45681
Related to #44974

The emplace() operation on tbb::concurrent_hash_map was not protected,
allowing other threads to erase entries between the emplace attempt and
the subsequent lookup.

Solution:
1. Add shared_lock protection around the emplace() operation to prevent
concurrent erasure during insertion
2. Instead of returning nullptr when the key is not found on retry,
recursively call Get(key) to retry the entire operation
3. Fix typo: "earsed" -> "erased"

This ensures that concurrent Get() operations are properly synchronized
and will eventually succeed even under high contention.

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-20 14:23:12 +08:00
Buqian Zheng
3741fcdd78
enhance: updated multiple places where the expr copies the input values in every loop (#45712)
pr: https://github.com/milvus-io/milvus/pull/45680
issue: https://github.com/milvus-io/milvus/issues/45679

Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
2025-11-20 14:17:07 +08:00
Zhen Ye
78c479ce9b
fix: panic when streaming coord shutdown but query coord still work (#45696)
issue: #44984
pr: #45695

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-20 12:05:09 +08:00
Bingyi Sun
e4a85ab92e
enhance: optimize term expr performance (#45671)
issue: https://github.com/milvus-io/milvus/issues/45641
pr: https://github.com/milvus-io/milvus/pull/45491

Signed-off-by: sunby <sunbingyi1992@gmail.com>
2025-11-19 19:43:06 +08:00
Gao
08ae6b5fcc
enhance: [2.6]prefetch vector chunks for sealed non-indexed segments (#45666)
pr: https://github.com/milvus-io/milvus/pull/45665

Signed-off-by: chasingegg <chao.gao@zilliz.com>
2025-11-19 18:41:07 +08:00
cai.zhang
6878de25ff
fix: [2.6] Set task init when worker doesn't have task (#45676)
issue: #45674 
master pr: #45675

---------

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-19 18:19:07 +08:00
wei liu
ccc993bbb3
fix: Prevent deadlock in runComponent when Prepare fails (#45609) (#45647)
issue: #45608
pr: #45609
When component.Prepare() fails (e.g., net listener creation error), the
sign channel was never closed, causing runComponent to block
indefinitely at <-sign. This resulted in the entire process hanging
after logging the error message.

Changes:
- Move close(sign) to defer statement in runComponent goroutine
- Ensures sign channel is always closed regardless of success/failure
- Allows proper error propagation through future.Await() mechanism

---------

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
2025-11-19 16:43:09 +08:00
Zhen Ye
f288f698e3
fix: panic when double close channel of ack broadcast (#45662)
issue: #45635
pr: #45661

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-19 14:35:08 +08:00
foxspy
3203119153
enhance: [2.6] update knowhere version (#45565)
issue: #42937

Signed-off-by: xianliang.li <xianliang.li@zilliz.com>
2025-11-19 10:56:44 +08:00
zhenshan.cao
442bd23583
fix: correct default value backfill during AddField (#45644)
issue: https://github.com/milvus-io/milvus/issues/44585
pr: https://github.com/milvus-io/milvus/pull/45634

Signed-off-by: zhenshan.cao <zhenshan.cao@zilliz.com>
2025-11-19 10:03:04 +08:00
Zhen Ye
bafa5bd4c9
fix: compact the assignment history of channel to decrease the size of assignment recovery info (#45607)
issue: #45210
pr: #45606

If the underlying WAL is failed to open, the recovery info size of
streaming coord streamingcoord-meta/pchannel will increase fast until
reaching the etcd limitation.
So make a compaction by serverID at assignment history to decrease the
streamingcoord-meta/pchannel size.

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-18 13:13:39 +08:00
congqixia
15a6a995f6
fix: [2.6] update EnableDynamicField and SchemaVersion during collection modification (#45616)
Cherry-pick from master
pr: #45615
Related to #45614

This commit fixes a bug where certain collection attributes were not
properly updated during collection modification, causing metadata errors
after cluster restart and collection reload failures.

When altering a collection, the `EnableDynamicField` and `SchemaVersion`
attributes were not being persisted to the catalog. This caused
inconsistencies between the in-memory collection metadata and the
persisted state, leading to:
- Dynamic field validation failures after restart
- Collection loading errors
- Metadata state mismatches

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-18 10:49:39 +08:00
congqixia
7be311320c
fix: [2.6] Handle default values correctly during compaction for added fields (#45619)
Cherry-pick from master
pr: #45572
Related to #45543

When a field with a default value is added to a collection, the default
value becomes null after compaction instead of retaining the expected
default value.

**Root Cause**
The `appendValueAt` function in `internal/storage/arrow_util.go`
incorrectly checked if the entire arrow.Array was nil before handling
default values. This meant that default values were only applied when
the array itself was nil, not when individual field values were null
(which is the correct condition).

**Changes**
1. **Early nil check**: Added a guard at the function entry to detect
nil arrow.Array and return an error immediately, as this is an
unexpected condition that should not occur during normal operation.

2. **Refactored default value handling**: Removed the per-type nil array
checks and moved default value logic to handle individual null values
within the array (when `IsNull(idx)` returns true).

3. **Applied to all types**: Updated the logic consistently across all
builder types:
   - BooleanBuilder
   - Int8Builder, Int16Builder, Int32Builder, Int64Builder
   - Float32Builder
   - StringBuilder
   - BinaryBuilder (added default value support for internal $meta json)
   - ListBuilder (removed unnecessary nil check)

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-18 10:13:39 +08:00
sparknack
aa5cd951a1
enhance: expr: [2.6] only prefetch chunks once (#45555)
issue: https://github.com/milvus-io/milvus/issues/43611
pr: #45554

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-17 14:56:27 +08:00
wei liu
c33d6a0f49
enhance: Add nullable support for Geometry and Timestamptz types (#44846) (#45522)
issue: #44800
pr: #44846
This commit enhances the upsert and validation logic to properly handle
nullable Geometry (WKT/WKB) and Timestamptz data types:

- Add ToCompressedFormatNullable support for TimestamptzData,
GeometryWktData, and GeometryData to filter out null values during data
compression
- Implement GenNullableFieldData for Timestamptz and Geometry types to
generate nullable field data structures
- Update FillWithNullValue to handle both GeometryData and
GeometryWktData with null value filling logic
- Add UpdateFieldData support for Timestamptz, GeometryData, and
GeometryWktData field updates
- Comprehensive unit tests covering all new data type handling scenarios

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
2025-11-14 18:53:38 +08:00
wei liu
15cf0c5147
enhance: increase session TTL from 10s to 30s (#45228) (#45517)
issue: #45227
pr: #45228
Increase the default session TTL to 30 seconds to tolerate etcd failover
time. This prevents session expiration during etcd cluster failover,
improving system stability.

When etcd undergoes failover (leader election or node restart), the
previous 10s TTL was too short to survive the failover window, causing
unnecessary session expiration and component restarts. The new 30s TTL
provides sufficient buffer for etcd to complete failover while
maintaining session liveness.

Changes:
- Update DefaultSessionTTL constant from 10 to 30
- Update SessionTTL ParamItem DefaultValue from "10" to "30"

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
2025-11-14 18:07:39 +08:00
Zhen Ye
601687d8d2
enhance: add more metrics for DDL framework (#45559)
issue: #43897
pr: #45558

---------

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-14 16:03:38 +08:00
Spade A
679d248c59
fix: remove validateFieldName in dropIndex [2.6] (#45462)
issue: https://github.com/milvus-io/milvus/issues/45459
pr: https://github.com/milvus-io/milvus/pull/45460

---------

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-11-14 15:33:38 +08:00
cai.zhang
9b76d75e0a
fix: [2.6] Ignore compaction task when from segment is not healthy (#45535)
issue: #45533 

master pr: #45534

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-14 15:31:38 +08:00
XuanYang-cn
898e129326
fix: [cp26]Set schema properties before broadcast alter collection (#45529)
This causes collection schema properties is empty in datacoord caches,
thus making compaction, indexing, unable to get properties from schema.

See also: #45053, #45159
pr: #45502

Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-11-14 14:23:37 +08:00
XuanYang-cn
d25c4053b8
fix: [cp26]store database event if the key is invalid (#45348) (#45530)
See also: #45136, #45124
pr: #45348

Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-11-14 12:05:38 +08:00
Feilong Hou
df05e7c12c
test: fix partial update chaos checker (#45550)
Issue: #45489 
pr: #45492

---------

Signed-off-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Eric Hou <eric.hou@zilliz.com>
2025-11-13 18:51:39 +08:00
Gao
88ce11a361
enhance: update maxConnections config version (#45547)
issue: #45344 
pr: #45546

Signed-off-by: chasingegg <chao.gao@zilliz.com>
2025-11-13 18:39:38 +08:00
groot
9191c8dcfd
fix: [2.6] Fix bulkimport bug for Struct field (#45536)
issue: https://github.com/milvus-io/milvus/issues/45006
pr: https://github.com/milvus-io/milvus/pull/45474

Signed-off-by: yhmo <yihua.mo@zilliz.com>
2025-11-13 18:13:38 +08:00
Chun Han
a12444e3ca
fix: failed to get raw data for hybrid index(#45318) (#45408)
related: #45318
pr: https://github.com/milvus-io/milvus/pull/45411

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-11-13 17:09:37 +08:00
aoiasd
e4adb9fc56
enhance: [2.6] skip check source id (#45519)
pr: https://github.com/milvus-io/milvus/pull/45377
relate:https://github.com/milvus-io/milvus/issues/45381

Signed-off-by: aoiasd <zhicheng.yue@zilliz.com>
2025-11-13 17:03:38 +08:00
Gao
df5da9c2b5
enhance: [2.6] support max_connection config for remote storage (#45364)
issue: #45344 
pr: #45225

Signed-off-by: chasingegg <chao.gao@zilliz.com>
2025-11-13 15:41:37 +08:00
cai.zhang
eee6ed91ca
fix: [2.6] Retain collection early to prevent it from being released before query completion. (#45415)
issue: #45314 

master pr: #45413

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-13 12:37:38 +08:00
aoiasd
719b71c3f2
enhance: [2.6] prevent panic by adding null pointer check when clearing InsertRecord _pk2offset_ (#45442)
pr:https://github.com/milvus-io/milvus/pull/45281

Signed-off-by: aoiasd <zhicheng.yue@zilliz.com>
2025-11-13 10:55:37 +08:00
Zhen Ye
8ca120b841
fix: use the right resource key lock for ddl and use new ddl in transfer replica (#45509)
issue: #45452
pr: #45506

- alias/rename related DDL should use database level exclusive lock
- alias cannot use as the resource key of lock, use collection name
instead
- transfer replica should use WAL-based framework

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-12 20:13:38 +08:00
Spade A
a78b6e51b0
fix: fix index compatibility after upgrade [2.6] (#45374)
pr: https://github.com/milvus-io/milvus/pull/45373
issue: https://github.com/milvus-io/milvus/issues/45380

---------

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-11-12 19:55:37 +08:00
yihao.dai
b1255dba6f
fix: [2.6] Fix channel not available error and release collection blocking (#45429)
1. Ensure replica creation is idempotent.
2. Prevent currentTarget update when replica is missing.
3. Move the wait-for-release logic into the DDL framework's callback,
and add a timeout to prevent it from blocking the DDL callback
indefinitely.

issue: https://github.com/milvus-io/milvus/issues/45301,
https://github.com/milvus-io/milvus/issues/45274,
https://github.com/milvus-io/milvus/issues/45295

pr: https://github.com/milvus-io/milvus/pull/45428

---------

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
2025-11-12 18:57:37 +08:00
XuanYang-cn
245e96645f
feat: [cp26]Add new config and enable to dynamic update configs (#45363)
This PR changes the config layout according to the latest design, and
adds two external credential configs for aws kms

See also: #45169
pr: #45170

Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-11-12 18:11:41 +08:00
Zhen Ye
24a0782cb5
fix: remove collection meta when drop partition (#45497)
issue: #45476
pr: #45493

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-12 10:15:36 +08:00
cai.zhang
49e3059719
fix: Fix target segment marked dropped for save stats result twice (#45479)
issue: #45477 

master pr: #45478

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-11 23:41:37 +08:00
Zhen Ye
1cfb9f6881
fix: wrong update timetick of collection info (#45471)
issue: #45397, #45403, #45463
pr: #45461
also pick pr: #45447

- fix alter collection with alias failed with collection not found
- fix the Nightly E2E failures.
- fix the wrong update timetick of altering collection to fix the
related load failure.

---------

Signed-off-by: sijie-ni-0214 <sijie.ni@zilliz.com>
Signed-off-by: chyezh <chyezh@outlook.com>
Co-authored-by: sijie-ni-0214 <sijie.ni@zilliz.com>
2025-11-11 22:07:37 +08:00
zhenshan.cao
2f6940253d
fix: Add tzdata dependency to enable IANA Time Zone ID recognition (#45495)
Also Set timezone to UTC and ensure tzdata support (#45483)

issue: https://github.com/milvus-io/milvus/issues/45473
pr: https://github.com/milvus-io/milvus/pull/45475
https://github.com/milvus-io/milvus/pull/45483

Signed-off-by: zhenshan.cao <zhenshan.cao@zilliz.com>
2025-11-11 20:45:37 +08:00
congqixia
9ff5731c7d
fix: [2.6] Support JSON default values in FillFieldData (#45455) (#45470)
Cherry-pick from master
pr: #45455
Related to #45445

Previously, FillFieldData for JSON fields would assert and fail when a
default_value was provided, blocking index creation for JSON fields with
default values (including dynamic fields like $meta).

This change enables JSON default value support by:
- Removing the assertion that blocked default values
- Parsing bytes_data into Json objects when default_value is present
- Properly filling data_ array and setting valid_data_ bitset to true
- Maintaining null behavior when no default_value is provided

Impact:
- Fixes index creation failure for JSON fields with default values
- Resolves upgrade issues from 2.5 to 2.6.5 where dynamic fields with
default values couldn't be indexed
- Index builds that were stuck in InProgress state can now complete

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-11 18:21:37 +08:00
congqixia
7d13bdcf4c
fix: [2.6] correct field data offset calculation in rerank functions for bulk search (#45444) (#45482)
Cherry-pick from master
pr: #45444
Related to #45338

When using bulk vector search in hybrid search with rerank functions,
the output field values for different queries were all equal to the
values returned by the first query, instead of the correct values
belonging to each document ID. The document IDs were correct, but the
entity field values were wrong.

In rerank functions (RRF, weighted, decay, model), when processing
multiple queries in a batch, the `idLocations` stored only the relative
offset within each result set (`idx`), not accounting for the absolute
position within the entire batch. This caused `FillFieldData` to
retrieve field data from the wrong positions, always using offsets
relative to the first query.

This fix ensures that when processing bulk searches with rerank
functions, each result correctly retrieves its corresponding field data
based on the absolute offset within the entire batch, resolving the
issue where all queries returned the first query's field values.

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-11 18:15:37 +08:00
sparknack
aaa8f4335d
enhance: [2.6] some optimization of scalar field fetching in tiered storage scenarios (#45361)
issue: #43611
pr: #45360

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-11 17:27:40 +08:00
cai.zhang
8b16216e01
fix: [2.6]Fix filter geometry for growing with mmap (#45465)
issue: #45450
master pr: #45464

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-11 15:41:40 +08:00
Chun Han
85c8cca094
feat: milvus support huawei cloud iam verification(#45298) (#45312)
related: #45298
pr: https://github.com/milvus-io/milvus/pull/45457

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-11-11 15:11:36 +08:00
Spade A
7cee398df1
fix: nextFieldID does not consider STRUCT [2.6] (#45438)
issue: https://github.com/milvus-io/milvus/issues/45362
pr: https://github.com/milvus-io/milvus/pull/45437

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-11-11 11:29:35 +08:00
aoiasd
2637854a12
enhance: [2.6] fix typo of analyzer params (#45434)
pr: https://github.com/milvus-io/milvus/pull/45299

Signed-off-by: aoiasd <zhicheng.yue@zilliz.com>
2025-11-11 10:33:36 +08:00
Gao
1398a069d3
enhance: override index_type while creating segment index (#45417)
issue: #44752
pr: #45416

---------

Signed-off-by: chasingegg <chao.gao@zilliz.com>
2025-11-11 09:45:36 +08:00
zhuwenxing
7380684b9e
test: [2.6]add struct array mmap testcases (#45453)
master pr: https://github.com/milvus-io/milvus/pull/45309

Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
2025-11-10 19:49:36 +08:00
Chun Han
94563fb4f2
fix: Group value is nil(#45418) (#45419)
related: #45418 
pr: https://github.com/milvus-io/milvus/pull/45422

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-11-10 16:17:38 +08:00
yihao.dai
58f4afd3f0
enhance: [2.6] Add RBAC support for UpdateReplicateConfiguration (#45236)
issue: https://github.com/milvus-io/milvus/issues/44123

pr: https://github.com/milvus-io/milvus/pull/45123

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
2025-11-08 17:43:34 +08:00
XuanYang-cn
7c37e444a2
fix: [cp26]Accurate size estimation for sliced arrow arrays in compaction (#45352)
Sliced arrow arrays "incorrectly" returned the original array's size via
SizeInBytes(), causing inaccurate memory estimates during compaction.

This resulted in segments closing prematurely in mergeSplit mode -
expected 500MB compactions produced 4x100+MB segments instead.

Fixed by calculating actual byte size of sliced arrays, ensuring proper
segment sizing and more accurate memory usage tracking.

See also: #45293
pr: #45294

Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-11-07 18:07:35 +08:00
yihao.dai
0bfb5f6012
fix: [2.6] Fix data race in replicate stream client (#45347)
issue: https://github.com/milvus-io/milvus/issues/44123

pr: https://github.com/milvus-io/milvus/pull/45346

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
2025-11-07 16:43:35 +08:00
XuanYang-cn
750af91c5a
test: Increase PyMilvus version to 2.6.4rc3 for 2.6 branch (#45386)
Automated daily bump from pymilvus 2.6 branch. Updates
tests/python_client/requirements.txt.

Signed-off-by: XuanYang-cn <xuan.yang@zilliz.com>
2025-11-07 15:23:38 +08:00
cai.zhang
12e3fb7655
fix: [2.6]Skip building text index for newly added columns (#45317)
issue: #45315 
master pr: #45316

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-07 15:21:42 +08:00
XuanYang-cn
f3e5a53fc5
fix: [2.6]Accidentally ignored sealed segments in L0 Compaction (#45341)
When there're no growing segments in the collection, L0 Compaction will
try to choose all L0 segments that hits all L1/L2 segments.

However, if there's Sealed Segment still under flushing in DataNode at
the same time L0 Compaction selects satisfied L1/L2 segments, L0
Compaction will ignore this Segment because it's not in "FlushState",
which is wrong, causing missing deletes on the Sealed Segment.

This quick solution here is to fail this L0 compaction task once
selected a Sealed segment.

See also: #45339
pr: #45340

---------

Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-11-07 11:49:34 +08:00
congqixia
b856b396da
enhance: [2.6] Bump go version to 1.24.9 (#45369)
Cherry-pick from master
pr: #45359 
Fixing CVE-2025-58187

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-07 11:23:34 +08:00
cai.zhang
b33c58807a
enhance: [2.6] [test] Move R-Tree index tests into the implementation package (#45356)
master pr: #45355

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-07 10:05:35 +08:00
zhagnlu
27d737bbaf
enhance: disable jsonshredding for default config (#45349)
#42533

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-11-06 19:21:30 +08:00
congqixia
2c50d7e1f8
fix: [2.6] Move FinishLoad before text index creation to ensure raw data availability (#45335)
Cherry-pick from master
pr: #45334
Related to #45333

Fix segment loading failure when adding fields with text match enabled.
The issue occurred because text indexes were being loaded before
FinishLoad() was called, meaning raw data was not properly available
when text index creation attempted to access it, resulting in "failed to
create text index, neither raw data nor index are found" errors.

Solution is to move the FinishLoad() call to execute after raw data
loading but before text index loading. This ensures that:
1. Raw data is properly loaded and available in memory
2. Text indexes can access the raw data they need during creation
3. The segment is in the correct state before any index operations

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-06 17:11:34 +08:00
XuanYang-cn
19fe1423d6
test: Increase PyMilvus version to 2.6.4rc2 for 2.6 branch (#45272)
Automated daily bump from pymilvus 2.6 branch. Updates
tests/python_client/requirements.txt.

Signed-off-by: XuanYang-cn <xuan.yang@zilliz.com>
2025-11-06 16:53:38 +08:00
zhagnlu
d91470e59e
fix: not use json_shredding for json path is null (#45311)
pr: #45310

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-11-06 11:49:33 +08:00
zhenshan.cao
a42d3248e1
fix: cherry pick fixes related to timestamptz (#45321)
pr: https://github.com/milvus-io/milvus/pull/45111
https://github.com/milvus-io/milvus/pull/45287
issue: https://github.com/milvus-io/milvus/issues/44527
https://github.com/milvus-io/milvus/issues/44537
https://github.com/milvus-io/milvus/issues/44538
https://github.com/milvus-io/milvus/issues/44585
https://github.com/milvus-io/milvus/issues/44622
https://github.com/milvus-io/milvus/issues/44585

---------

Signed-off-by: zhenshan.cao <zhenshan.cao@zilliz.com>
2025-11-06 11:05:34 +08:00
sparknack
fb1b16186a
enhance: [2.6] unify the aligned buffer for both buffered and direct I/O (#45325)
issue: https://github.com/milvus-io/milvus/issues/43040
pr: https://github.com/milvus-io/milvus/pull/45323

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-06 10:59:33 +08:00
yihao.dai
c19fa9f5c3
fix: [2.6] Fix load segment failed due to get disk usage error (#45300)
When getting disk usage, files or directories may be removed
concurrently due to segment release. This PR ignores “file or directory
does not exist” errors in such cases.

issue: https://github.com/milvus-io/milvus/issues/45239

pr: https://github.com/milvus-io/milvus/pull/45255

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
2025-11-06 10:35:34 +08:00
congqixia
9a26b11614
fix: [2.6] Support JSON default value in compaction (#45331)
Cherry-pick from master
pr: #45330
Related to #45329

Fix compaction failure when handling newly added dynamic fields with
storage v1 binlogs. The issue occurred because the
`GenerateEmptyArrayFromSchema` function did not support JSON data type
default values, causing "Unexpected default value" errors during
compaction.

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-06 10:21:34 +08:00
cai.zhang
3df5f89cb0
fix: [2.6] Compute the correct batch size for the geometry index of the growing segment (#45261)
issue: #44648 
master pr: #45253

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-05 15:51:33 +08:00
foxspy
e1ea30b04c
enhance: [2.6] update knowhere version (#45271)
issue: #42937 
pr: #45270

Signed-off-by: xianliang.li <xianliang.li@zilliz.com>
2025-11-05 11:11:33 +08:00
zhagnlu
8942bb7594
enhance: rename jsonstats related user config params (#45252)
pr: #45254

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-11-05 10:35:32 +08:00
Zhen Ye
40806f9162
fix: ddl framework bug patch (#45292)
issue: #45080, #45274, #45285
pr: #45290

- LoadCollection doesn't ignore the ignorable request, for false field
array.
- CreatIndex doesn't ignore the ignorable request, for wrong index.
- index meta is not thread safe.
- lost parameter check of DDL.
- DDL Ack scheduler may get stuck and DDL is block until next incoming
DDL.

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-05 00:29:34 +08:00
Gao
844fa8c999
enhance: [2.6] make knowhere thread pool config refreshable (#45191)
pr: #45190

---------

Signed-off-by: chasingegg <chao.gao@zilliz.com>
2025-11-04 20:43:34 +08:00
Spade A
282798371d
fix: alter collection failed with MMAP setting for STRUCT [2.6] (#45240)
pr: https://github.com/milvus-io/milvus/pull/45173
issue: https://github.com/milvus-io/milvus/issues/45001
ref: https://github.com/milvus-io/milvus/issues/42148

---------

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
Signed-off-by: SpadeA-Tang <tangchenjie1210@gmail.com>
2025-11-04 20:25:37 +08:00
Zhen Ye
122d024df4
enhance: cherry pick patch of new DDL framework and CDC 3 (#45280)
issue: #43897, #44123
pr: #45266
also pick pr: #45237, #45264,#45244,#45275

fix: kafka should auto reset the offset from earliest to read (#45237)

issue: #44172, #45210, #44851,#45244

kafka will auto reset the offset to "latest" if the offset is
Out-of-range. the recovery of milvus wal cannot read any message from
that. So once the offset is out-of-range, kafka should read from eariest
to read the latest uncleared data.


https://kafka.apache.org/documentation/#consumerconfigs_auto.offset.reset

enhance: support alter collection/database with WAL-based DDL framework
(#45266)

issue: #43897

- Alter collection/database is implemented by WAL-based DDL framework
now.
- Support AlterCollection/AlterDatabase in wal now.
- Alter operation can be synced by new CDC now.
- Refactor some UT for alter DDL.

fix: milvus role cannot stop at initializing state (#45244)

issue: #45243

fix: support upgrading from 2.6.x -> 2.6.5 (#45264)

issue: #43897

---------

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-04 20:21:37 +08:00
congqixia
9d7ef929e1
fix: [2.6] Initialize timestamp range in composite binlog writer (#45283)
Related to #45282

Initialize `tsFrom` and `tsTo` fields in the composite binlog record
writer constructor to prevent timestamp range information loss in stats
tasks.

The composite binlog writer now properly initializes the timestamp range
fields, ensuring that:
1. The first timestamp update will correctly set the minimum (`tsFrom`)
2. The first timestamp update will correctly set the maximum (`tsTo`)
3. All subsequent data writes will maintain accurate timestamp range
tracking

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-04 19:47:34 +08:00
zhuwenxing
af766513f6
test: add struct array testcases (#44973)
/kind improvement

master pr: https://github.com/milvus-io/milvus/pull/44940
https://github.com/milvus-io/milvus/pull/45146

---------

Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
2025-11-04 17:45:34 +08:00
cai.zhang
852b801e90
fix: [2.6] Skip create tmp dir for growing R-Tree index (#45257)
issue: #45181 

master pr: #45256

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-04 17:43:33 +08:00
congqixia
d490a5b4bf
enhance: [2.6] set schema version when creating new collection (#45263) (#45269)
Cherry pick from master
pr: #45263
Related to #43028

Initialize the schema version field when creating a new collection
instance in QueryNode. The schema version is extracted from loadMetaInfo
and assigned to the collection, ensuring proper schema version tracking
and consistency across the distributed system.

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-11-04 17:05:34 +08:00
sparknack
efaa538238
fix:[2.6] avoid potential race conditions when updating the executor (#45232)
issue: #43040 
pr: #45230

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-04 16:11:33 +08:00
groot
f21d7ce05b
enhance: Support JSONL/NDJSON files for bulkinsert (#44602) (#44717)
issue: https://github.com/milvus-io/milvus/issues/44567
pr: https://github.com/milvus-io/milvus/pull/44602

Signed-off-by: yhmo <yihua.mo@zilliz.com>
2025-11-04 16:01:33 +08:00
yihao.dai
b8257facf2
enhance: [2.6] Wait for replicate stream client to finish (#45260)
Make channel replicator stop more gracefully.

issue: https://github.com/milvus-io/milvus/issues/44123

pr: https://github.com/milvus-io/milvus/pull/45259

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
2025-11-04 14:23:33 +08:00
Spade A
bc47935600
feat: impl StructArray -- support diskann index [2.6] (#45234)
pr: https://github.com/milvus-io/milvus/pull/45223
issue: https://github.com/milvus-io/milvus/issues/42148

---------

Signed-off-by: SpadeA-Tang <tangchenjie1210@gmail.com>
Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-11-04 12:13:34 +08:00
Spade A
f26ce204ce
fix: allow "[" and "]" in index name [2.6] (#45194)
pr: https://github.com/milvus-io/milvus/pull/45193
issue: https://github.com/milvus-io/milvus/issues/42148

---------

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
Signed-off-by: SpadeA-Tang <tangchenjie1210@gmail.com>
2025-11-04 12:11:34 +08:00
zhagnlu
cb2bc2b41b
fix: fix bug for shredding json when empty but not null json (#45214)
pr: #45221

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-11-04 11:13:34 +08:00
cai.zhang
4bc2dc86a0
enhance: [2.6]Make GeometryCache an optional configuration (#45196)
issue: #45187 
master pr: #45192

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-04 09:51:33 +08:00
Zhen Ye
02e2170601
enhance: cherry pick patch of new DDL framework and CDC 2 (#45241)
issue: #43897, #44123
pr: #45224
also pick pr: #45216,#45154,#45033,#45145,#45092,#45058,#45029

enhance: Close channel replicator more gracefully (#45029)

issue: https://github.com/milvus-io/milvus/issues/44123

enhance: Show create time for import job (#45058)

issue: https://github.com/milvus-io/milvus/issues/45056

fix: wal state may be unconsistent after recovering from crash (#45092)

issue: #45088, #45086

- Message on control channel should trigger the checkpoint update.
- LastConfrimedMessageID should be recovered from the minimum of
checkpoint or the LastConfirmedMessageID of uncommitted txn.
- Add more log info for wal debugging.

fix: make ack of broadcaster cannot canceled by client (#45145)

issue: #45141

- make ack of broadcaster cannot canceled by rpc.
- make clone for assignment snapshot of wal balancer.
- add server id for GetReplicateCheckpoint to avoid failure.

enhance: support collection and index with WAL-based DDL framework
(#45033)

issue: #43897

- Part of collection/index related DDL is implemented by WAL-based DDL
framework now.
- Support following message type in wal, CreateCollection,
DropCollection, CreatePartition, DropPartition, CreateIndex, AlterIndex,
DropIndex.
- Part of collection/index related DDL can be synced by new CDC now.
- Refactor some UT for collection/index DDL.
- Add Tombstone scheduler to manage the tombstone GC for collection or
partition meta.
- Move the vchannel allocation into streaming pchannel manager.

enhance: support load/release collection/partition with WAL-based DDL
framework (#45154)

issue: #43897

- Load/Release collection/partition is implemented by WAL-based DDL
framework now.
- Support AlterLoadConfig/DropLoadConfig in wal now.
- Load/Release operation can be synced by new CDC now.
- Refactor some UT for load/release DDL.

enhance: Don't start cdc by default (#45216)

issue: https://github.com/milvus-io/milvus/issues/44123


fix: unrecoverable when replicate from old (#45224)

issue: #44962

---------

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
Signed-off-by: chyezh <chyezh@outlook.com>
Co-authored-by: yihao.dai <yihao.dai@zilliz.com>
2025-11-04 01:35:33 +08:00
yihao.dai
cefdd25ef7
enhance: [2.6] Don't start cdc by default (#45217)
issue: https://github.com/milvus-io/milvus/issues/44123

pr: https://github.com/milvus-io/milvus/pull/45216

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
2025-11-03 20:51:33 +08:00
cai.zhang
7451d89a22
enhance: [2.6]Add log to debug index task (#45199)
master pr: #45198

---------

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-11-03 20:03:34 +08:00
Spade A
902eea8e2c
feat: implement ngram tokenizer with token_chars and custom_token_chars [2.6] (#45046)
pr: https://github.com/milvus-io/milvus/pull/45040
issue: https://github.com/milvus-io/milvus/issues/45039

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-11-03 18:11:34 +08:00
zhuwenxing
1be0dcf51e
test: add geometry datatype testcases (#45097)
master pr: https://github.com/milvus-io/milvus/pull/44646

/kind improvement

Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
2025-11-03 17:21:38 +08:00
zhuwenxing
d095fb9bd3
test: [2.6]add json dumps for json string data (#45219)
master pr: https://github.com/milvus-io/milvus/pull/45189

Signed-off-by: zhuwenxing <wenxing.zhu@zilliz.com>
2025-11-03 16:07:33 +08:00
Zhen Ye
318db122b8
enhance: cherry pick patch of new DDL framework and CDC (#45025)
issue: #43897, #44123
pr: #44898
related pr: #44607 #44642 #44792 #44809 #44564 #44560 #44735 #44822
#44865 #44850 #44942 #44874 #44963 #44886 #44898

enhance: remove redundant channel manager from datacoord (#44532)

issue: #41611

- After enabling streaming arch, channel manager of data coord is a
redundant component.


fix: Fix CDC OOM due to high buffer size (#44607)

Fix CDC OOM by:
1. free msg buffer manually.
2. limit max msg buffer size.
3. reduce scanner msg hander buffer size.

issue: https://github.com/milvus-io/milvus/issues/44123

fix: remove wrong start timetick to avoid filtering DML whose timetick
is less than it. (#44691)

issue: #41611

- introduced by #44532

enhance: support remove cluster from replicate topology (#44642)

issue: #44558, #44123
- Update config(A->C) to A and C, config(B) to B on replicate topology
(A->B,A->C) can remove the B from replicate topology
- Fix some metric error of CDC

fix: check if qn is sqn with label and streamingnode list (#44792)

issue: #44014

- On standalone, the query node inside need to load segment and watch
channel, so the querynode is not a embeded querynode in streamingnode
without `LabelStreamingNodeEmbeddedQueryNode`. The channel dist manager
can not confirm a standalone node is a embededStreamingNode.

Bug is introduced by #44099

enhance: Make GetReplicateInfo API work at the pchannel level (#44809)

issue: https://github.com/milvus-io/milvus/issues/44123

enhance: Speed up CDC scheduling (#44564)

Make CDC watch etcd replicate pchannel meta instead of listing them
periodically.

issue: https://github.com/milvus-io/milvus/issues/44123


enhance: refactor update replicate config operation using
wal-broadcast-based DDL/DCL framework (#44560)

issue: #43897

- UpdateReplicateConfig operation will broadcast AlterReplicateConfig
message into all pchannels with cluster-exclusive-lock.
- Begin txn message will use commit message timetick now (to avoid
timetick rollback when CDC with txn message).
- If current cluster is secondary, the UpdateReplicateConfig will wait
until the replicate configuration is consistent with the config
replicated from primary.


enhance: support rbac with WAL-based DDL framework (#44735)

issue: #43897

- RBAC(Roles/Users/Privileges/Privilege Groups) is implemented by
WAL-based DDL framework now.
- Support following message type in wal `AlterUser`, `DropUser`,
`AlterRole`, `DropRole`, `AlterUserRole`, `DropUserRole`,
`AlterPrivilege`, `DropPrivilege`, `AlterPrivilegeGroup`,
`DropPrivilegeGroup`, `RestoreRBAC`.
- RBAC can be synced by new CDC now.
- Refactor some UT for RBAC.


enhance: support database with WAL-based DDL framework (#44822)

issue: #43897

- Database related DDL is implemented by WAL-based DDL framework now.
- Support following message type in wal CreateDatabase, AlterDatabase,
DropDatabase.
- Database DDL can be synced by new CDC now.
- Refactor some UT for Database DDL.

enhance: support alias with WAL-based DDL framework (#44865)

issue: #43897

- Alias related DDL is implemented by WAL-based DDL framework now.
- Support following message type in wal AlterAlias, DropAlias.
- Alias DDL can be synced by new CDC now.
- Refactor some UT for Alias DDL.

enhance: Disable import for replicating cluster (#44850)

1. Import in replicating cluster is not supported yet, so disable it for
now.
2. Remove GetReplicateConfiguration wal API

issue: https://github.com/milvus-io/milvus/issues/44123


fix: use short debug string to avoid newline in debug logs (#44925)

issue: #44924

fix: rerank before requery if reranker didn't use field data (#44942)

issue: #44918


enhance: support resource group with WAL-based DDL framework (#44874)

issue: #43897

- Resource group related DDL is implemented by WAL-based DDL framework
now.
- Support following message type in wal AlterResourceGroup,
DropResourceGroup.
- Resource group DDL can be synced by new CDC now.
- Refactor some UT for resource group DDL.


fix: Fix Fix replication txn data loss during chaos (#44963)

Only confirm CommitMsg for txn messages to prevent data loss.

issue: https://github.com/milvus-io/milvus/issues/44962,
https://github.com/milvus-io/milvus/issues/44123

fix: wrong execution order of DDL/DCL on secondary (#44886)

issue: #44697, #44696

- The DDL executing order of secondary keep same with order of control
channel timetick now.
- filtering the control channel operation on shard manager of
streamingnode to avoid wrong vchannel of create segment.
- fix that the immutable txn message lost replicate header.


fix: Fix primary-secondary replication switch blocking (#44898)

1. Fix primary-secondary replication switchover blocking by delete
replicate pchannel meta using modRevision.
2. Stop channel replicator(scanner) when cluster role changes to prevent
continued message consumption and replication.
3. Close Milvus client to prevent goroutine leak.
4. Create Milvus client once for a channel replicator.
5. Simplify CDC controller and resources.

issue: https://github.com/milvus-io/milvus/issues/44123

---------

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
Signed-off-by: chyezh <chyezh@outlook.com>
Co-authored-by: yihao.dai <yihao.dai@zilliz.com>
2025-11-03 15:39:33 +08:00
Zhen Ye
022241cc14
fix: append operation can be only canceled by the wal itself but not the rpc (#45079)
issue: #45077
pr: #45078

We need to promise the state of wal consistent with the memory state of
streamingnode. So we don't allow the append operation can be cancelled
by the append caller to avoid leave a inconsistent state of alive wal.
The wal append operation can only be cancelled when the wal is shutting
down.

Signed-off-by: chyezh <chyezh@outlook.com>
2025-11-03 15:07:36 +08:00
XuanYang-cn
debb00c83d
test: Increase PyMilvus version to 2.6.3rc16 for 2.6 branch (#45096)
Automated daily bump from pymilvus 2.6 branch. Updates
tests/python_client/requirements.txt.

---------

Signed-off-by: XuanYang-cn <xuan.yang@zilliz.com>
Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-11-03 10:25:32 +08:00
tinswzy
d7134a6cc9
fix: [2.6] resolve wp GCP Cloud Storage access issue with AK/SK (#45144)
cherry-pick from master

pr: #45120
related issue: #43638 

Resolve issue accessing GCP Cloud Storage with ak/sk , related wp
[pr:11c0834c4](11c0834c4f)
upgrade wp v0.1.11

Signed-off-by: tinswzy <zhenyuan.wei@zilliz.com>
2025-11-03 09:59:32 +08:00
zhikunyao
4bc8737c60
test: update helm to 5.0.6 for e2e (#45205)
pr: #45204

Signed-off-by: Zhikun Yao <zhikun.yao@zilliz.com>
2025-10-31 18:54:09 +08:00
cai.zhang
e70ee327f1
fix: [2.6] Fix import null geometry data (#45162)
issue: #44787 

master pr: #45161

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-10-31 13:42:08 +08:00
congqixia
f3175d2964
fix: [2.6] add null check for packed_writer_ in JsonStatsParquetWriter::Close() (#45158) (#45176)
Cherry-pick from master
pr: #45158

Related to #45157

Fix a bug where DataNode panics when building json stats index throws an
exception before the writer is initialized. The destructor would call
Close() on an uninitialized packed_writer_ pointer, causing a null
pointer dereference.

Changes:
- Add null check for packed_writer_ before calling Flush() and Close()
- Prevents null pointer dereference in edge cases
- Ignore close status as this is a cleanup operation

This ensures safe cleanup even when initialization fails due to
exceptions.

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-31 10:04:10 +08:00
cqy123456
7878293c46
fix: fail to mmap emb_list_meta in embedding list (#45126)
issue: https://github.com/milvus-io/milvus/issues/44965
related pr: https://github.com/milvus-io/milvus/pull/45127

Signed-off-by: cqy123456 <qianya.cheng@zilliz.com>
2025-10-30 17:04:08 +08:00
congqixia
7f10c98321
fix: [2.6] update QueryNode NumEntities metrics when collection has no segments (#45147) (#45160)
Cherry-pick from master
pr: #45147 

Related to #44509

Fix a bug where QueryNodeNumEntities metrics were not updated for
collections with zero segments, causing stale metrics when all segments
are flushed or compacted.

The previous implementation used separate loops: one to update size
metrics for all collections, and another to update num entities metrics
only for collections present in the grouped segments map. Collections
with no segments were skipped in the second loop, leaving their
NumEntities metrics stale.

Changes:
- Consolidate size and num entities metric updates into single loop
- Iterate over all collections instead of grouped segments
- Get collection metadata from manager instead of segment instances
- Correctly set NumEntities to 0 for collections with no segments
- Apply the same fix to both growing and sealed segment processing
- Add nil check for collection metadata before processing

This ensures all collection metrics are updated consistently, even when
segment count drops to zero.

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-30 14:08:09 +08:00
wei liu
a0373a348a
enhance: [2.6] remove max vector field number limit (#45156)
issue: #45150
pr: #45151

Removed the maximum limit constraint (value range [1, 10]) for vector
fields in a collection to support more flexible schema design.

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
2025-10-30 14:06:15 +08:00
yihao.dai
607fa69624
fix: [2.6] Prevent retry when importing invalid UTF-8 strings (#45068)
Convert invalid UTF-8 string the hex in failure reason.

issue: https://github.com/milvus-io/milvus/issues/45066

pr: https://github.com/milvus-io/milvus/pull/45067

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
2025-10-29 20:43:46 +08:00
wei liu
71bd07bcf7
fix: Handle empty FieldsData in reduce/rerank for requery scenario (#44917) (#45137)
issue: #44909
pr: #44917

When requery optimization is enabled, search results contain IDs but
empty FieldsData. During reduce/rerank operations, if the first shard
has empty FieldsData while others have data, PrepareResultFieldData
initializes an empty array, causing AppendFieldData to panic when
accessing array indices.

Changes:
- Find first non-empty FieldsData as template in 3 functions:
reduceAdvanceGroupBy, reduceSearchResultDataWithGroupBy,
reduceSearchResultDataNoGroupBy
- Add length check before 2 AppendFieldData calls in reduce functions to
prevent panic
- Improve newRerankOutputs to find first non-empty fieldData using
len(FieldsData) check instead of GetSizeOfIDs
- Add length check in appendResult before AppendFieldData
- Add comprehensive unit tests for empty and partial empty FieldsData
scenarios in both reduce and rerank functions

This fix handles both pure requery (all empty) and mixed scenarios (some
empty, some with data) without breaking normal search flow. The key
improvement is checking FieldsData length directly rather than IDs, as
requery may have IDs but empty FieldsData.

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
2025-10-29 20:12:13 +08:00
yihao.dai
a3006b7116
fix: [2.6] Fix panic when gracefully stopping cdc (#45095)
issue: https://github.com/milvus-io/milvus/issues/45093,
https://github.com/milvus-io/milvus/issues/44123

pr: https://github.com/milvus-io/milvus/pull/45094

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
2025-10-28 17:14:13 +08:00
tinswzy
76b2d67c6a
fix: [2.6] auth token contamination, OSS/COS support, redundant sync err logs (#45106)
Cherry-pick from master

pr: #44964 , related issue #44892 fix invalid auth token cause by
context contamination

pr: #44879   enable WP support aliyun oss/tencent cos

pr: #44934 , related issue #44713  fix redundant wp sync error logs

---------

Signed-off-by: tinswzy <zhenyuan.wei@zilliz.com>
2025-10-28 15:06:12 +08:00
congqixia
d84348b7a2
fix: [2.6] Handle all-null data in StringIndexSort to prevent load timeout(#45100) (#45104)
Cherry-pick from master
pr: #45100

Related to #45081

StringIndexSort now properly handles collections with all-null string
fields by:
- Removing the error thrown when unique_count is 0 in ParseBinaryData
- Adding alignment and padding support in mmap serialization (similar to
ScalarIndexSort)
- Separating data_size_ from mmap_size_ to correctly parse data without
reading padding

This fixes load collection timeout failures when all string field data
is null, particularly affecting STL_SORT and TRIE index types.

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-28 12:10:11 +08:00
zhagnlu
1df958f444
fix: disable build old version jsonstats from request (#45102)
pr: #45101

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-10-28 11:14:11 +08:00
cai.zhang
882cffaa96
fix: Fix bug for importing Geometry data (#45090)
issue: https://github.com/milvus-io/milvus/issues/44787 ,
https://github.com/milvus-io/milvus/issues/45012
master pr: #45089

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-10-28 11:12:20 +08:00
yihao.dai
60a802d3c8
enhance: [2.6] Show create time for import job (#45059)
issue: https://github.com/milvus-io/milvus/issues/45056

pr: https://github.com/milvus-io/milvus/pull/45058

---------

Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
2025-10-27 14:20:19 +08:00
congqixia
71d75a1f9b
enhance: [2.6] Optimize ScalarIndexSort bitmap initialization for range queries (#45085) (#45087)
Cherry-pick from master
pr: #45085

Optimize bitmap initialization in ScalarIndexSort range queries by using
adaptive strategy based on result density. When more than 50% of
elements match the range condition, initialize bitmap with all true
values and clear non-matching elements. Otherwise, use the original
approach of initializing with false and setting matching elements. Also
defer bitmap allocation until after early return checks to avoid
unnecessary memory allocation.

This optimization reduces bit operations for high-selectivity queries
while maintaining the same performance for low-selectivity queries.

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-27 14:10:07 +08:00
Spade A
a98aad0034
fix: fix parquet import bug in STRUCT [2.6] (#45071)
pr: https://github.com/milvus-io/milvus/pull/45028
issue: https://github.com/milvus-io/milvus/issues/45006
ref: https://github.com/milvus-io/milvus/issues/42148

---------

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-10-24 18:16:06 +08:00
cai.zhang
f9a49c60e4
fix: [2.6] Added GetMetrics back to IndexNodeServer to ensure compatibility (#45074)
issue: #45070 
master pr: #45073

---------

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-10-24 17:32:06 +08:00
Chun Han
a9d845b99e
feat: support run analyzer(#44803) (#45032)
related: https://github.com/milvus-io/milvus/issues/44803
pr: https://github.com/milvus-io/milvus/pull/44805

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-10-24 15:36:05 +08:00
congqixia
98c19386e3
fix: [2.6] Update milvus-storage to fix duplicate AWS SDK initialization (#45063)
Cherry-pick from master
pr: #45062
Update milvus-storage version from aa189ad to e5f5b4c to include the fix
for duplicate AWS SDK initialization that was causing init conflicts.

This update removes the redundant arrow::fs::InitializeS3() call that
was resulting in duplicate Aws::InitAPI() initialization. The duplicate
initialization was causing AWS SDK to ignore custom configurations,
particularly affecting GCP Workload Identity authentication.

Changes in milvus-storage e5f5b4c:
- Remove redundant arrow::fs::InitializeS3() call
- Keep only the extended S3 initialization with custom AWS SDK options
- Ensure GCP IAM authentication via custom HTTP client factory works
correctly

Relates to #44745
Reference: milvus-io/milvus-storage#285

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-24 11:42:05 +08:00
Spade A
95b0fb5a9b
enhance: enable STL_SORT to support VARCHAR [2.6] (#45050)
issue: https://github.com/milvus-io/milvus/issues/44399
pr: https://github.com/milvus-io/milvus/pull/44401

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-10-24 10:52:05 +08:00
Feilong Hou
77578e08ed
test: change test_milvus_client_search_json_path_index_all_expressions to L1 (#44985)
Issue: #44989  
On branch 2.6
 Changes to be committed:
	modified:   milvus_client/test_milvus_client_query.py

pr: #44986

Signed-off-by: Eric Hou <eric.hou@zilliz.com>
Co-authored-by: Eric Hou <eric.hou@zilliz.com>
2025-10-24 10:44:04 +08:00
Spade A
974d369019
fix: fix alter collection failed for STRUCT sub-fields [2.6] (#45042)
pr: https://github.com/milvus-io/milvus/pull/45041
issue: https://github.com/milvus-io/milvus/issues/45001
ref: https://github.com/milvus-io/milvus/issues/42148

---------

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-10-24 10:38:05 +08:00
Spade A
9b075d7706
fix: collection level MMAP does not take effect for STRUCT [2.6] (#44997)
pr: https://github.com/milvus-io/milvus/pull/44996
issue: https://github.com/milvus-io/milvus/issues/42148

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-10-24 10:36:13 +08:00
congqixia
c3932022c9
fix: [2.6] prevent data race in querycoord collection notifier update (#45037) (#45051)
Cherry-pick from master
pr: #45037
Fixes #45035

This commit addresses a data race issue where refreshCollection was
updating the collection notifier without proper lock protection.

Changes:
- Add UpdateCollection method to CollectionManager with proper locking
- Introduce CollectionOperator pattern for thread-safe collection
updates
- Make setRefreshNotifier private and use it through the operator
pattern
- Update refreshCollection to use the new UpdateCollection method
- Handle collection not found error gracefully in refreshCollection

The CollectionOperator pattern ensures all collection modifications go
through the CollectionManager's lock, preventing concurrent access
issues.

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-23 19:34:13 +08:00
congqixia
a592cfc8b4
enhance: [2.6] extract shard client logic into dedicated package (#45018) (#45031)
Cherry-pick from master
pr: #45018 #45030
Related to #44761

Refactor proxy shard client management by creating a new
internal/proxy/shardclient package. This improves code organization and
modularity by:

- Moving load balancing logic (LookAsideBalancer, RoundRobinBalancer) to
shardclient package
- Extracting shard client manager and related interfaces into separate
package
- Relocating shard leader management and client lifecycle code
- Adding package documentation (README.md, OWNERS)
- Updating proxy code to use the new shardclient package interfaces

This change makes the shard client functionality more maintainable and
better encapsulated, reducing coupling in the proxy layer.

Also consolidates the proxy package's mockery generation to use a
centralized `.mockery.yaml` configuration file, aligning with the
pattern used by other packages like querycoordv2.

Changes
- **Makefile**: Replace multiple individual mockery commands with a
single config-based invocation for `generate-mockery-proxy` target
- **internal/proxy/.mockery.yaml**: Add mockery configuration defining
all mock interfaces for proxy and proxy/shardclient packages
- **Mock files**: Regenerate mocks using the new configuration:
  - `mock_cache.go`: Clean up by removing unused interface methods
  (credential, shard cache, policy methods)
  - `shardclient/mock_lb_balancer.go`: Update type comments
  (nodeInfo → NodeInfo)
  - `shardclient/mock_lb_policy.go`: Update formatting
  - `shardclient/mock_shardclient_manager.go`: Fix parameter naming
  consistency (nodeInfo1 → nodeInfo)
- **task_search_test.go**: Remove obsolete mock expectations for
deprecated cache methods

Benefits
- Centralized mockery configuration for easier maintenance
- Consistent with other packages (querycoordv2, etc.)
- Cleaner mock interfaces by removing unused methods
- Better type consistency in generated mocks

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-22 16:06:06 +08:00
congqixia
b3e525609c
fix: [2.6] Handle JSON field default values in storage layer (#44999) (#45009)
Cherry-pick from master
pr: #44999
Related to #44995
Added missing case for JSON data type in GetDefaultValue function to
properly retrieve default values for JSON fields. This prevents crashes
when enabling dynamic fields with default values during concurrent
insert operations.

Changes:
- Added JSON data type case in GetDefaultValue to return BytesData
- Added comprehensive tests for fillMissingFields covering JSON and
other data types with default values
- Added tests for nullable fields, required fields validation, and edge
cases

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-22 10:18:03 +08:00
congqixia
6677260b0f
enhance: [2.6] Refactor privilege management by extracting privilege cache into separate package (#44762) (#45002)
Cherry-pick from master
pr: #44762

Related to #44761

This commit refactors the privilege management system in the proxy
component by:

1. **Separation of Concerns**: Extracts privilege-related functionality
from MetaCache into a dedicated `internal/proxy/privilege` package,
improving code organization and maintainability.

2. **New Package Structure**: Creates `internal/proxy/privilege/` with:
   - `cache.go`: Core privilege cache implementation (PrivilegeCache)
   - `result_cache.go`: Privilege enforcement result caching
   - `model.go`: Casbin model and policy enforcement functions
   - `meta_cache_adapter.go`: Casbin adapter for MetaCache integration
   - Corresponding test files and mock implementations

3. **MetaCache Simplification**: Removes privilege and credential
management methods from MetaCache interface and implementation:
   - Removed: GetCredentialInfo, RemoveCredential, UpdateCredential
- Removed: GetPrivilegeInfo, GetUserRole, RefreshPolicyInfo,
InitPolicyInfo
   - Deleted: meta_cache_adapter.go, privilege_cache.go and their tests

4. **Updated References**: Updates all callsites to use the new
privilegeCache global:
- Authentication interceptor now uses privilegeCache for password
verification
- Credential cache operations (InvalidateCredentialCache,
UpdateCredentialCache, UpdateCredential) now use privilegeCache
- Policy refresh operations (RefreshPolicyInfoCache) now use
privilegeCache
- Privilege interceptor uses new privilege.GetEnforcer() and privilege
result cache

5. **Improved API**: Renames cache functions for clarity:
   - GetPrivilegeCache → GetResultCache
   - SetPrivilegeCache → SetResultCache
   - CleanPrivilegeCache → CleanResultCache

This refactoring makes the codebase more modular, separates privilege
management concerns from general metadata caching, and provides a
clearer API for privilege enforcement operations.

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-22 10:14:04 +08:00
cai.zhang
62cffb0105
fix: [2.6] Double check to avoid iter has been earsed by other thread (#45015)
issue: #44974 
master pr: #45013

---------

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-10-22 10:02:03 +08:00
zhagnlu
dcb6d5b709
fix:fix ut of not equal for null (#45003)
pr: #44959

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-10-21 18:28:03 +08:00
cai.zhang
1f1fdcb1fe
fix: [2.6]Fix bug for gis function to filter geometry (#44967)
issue: #44961
master pr: #44966 

This PR fixes 3 geometry related bugs:
1. Implement ToString interface for GisFunctionFilter.
2. Ignore GisFunctionFilter MoveCursor for growing segment.
3. Don't skip null geometry for building R-Tree index, should be record
in null_offsets.

---------

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-10-21 17:00:13 +08:00
sre-ci-robot
c22a2853b5
[automated] Bump milvus version to v2.6.4 (#45005)
Bump milvus version to v2.6.4
Signed-off-by: sre-ci-robot sre-ci-robot@users.noreply.github.com

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-21 15:10:04 +08:00
congqixia
5bca28764b
fix: [2.6][skip e2e]use eventual assertion for pending message check in replicate stream test (#44972) (#44987)
Cherry-pick from master
pr: #44972
Related to #44620

The test was flaky because pendingMessages.Len() assertion happened
before async message processing completed. Changed to assert.Eventually
to wait up to 1 second for the pending queue to drain, fixing the race
condition where actual was 1 but expected was 0.

Fixes TestReplicateStreamClient_Reconnect flakiness.

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-21 10:44:05 +08:00
zhagnlu
9b9a303a09
fix:fix valid ut test of TestUnaryRangeJsonNullable (#44990)
#44959

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-10-21 10:38:59 +08:00
Spade A
9cb6c0be2f
fix: fix "at most one distinct index is allowed per field" in STRUCT index [2.6] (#44970)
master: https://github.com/milvus-io/milvus/pull/44969
issue: https://github.com/milvus-io/milvus/issues/42148

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-10-21 10:38:29 +08:00
cai.zhang
09880e8e6c
fix: [2.6]Ensure fulfill promise when CreateArrowFileSystem throw an exception (#44976)
issue: #44974 

master pr: #44975

---------

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-10-21 10:14:03 +08:00
Buqian Zheng
6476b1dbcf
enhance: [2.6]enable default json stats (#44811)
issue: https://github.com/milvus-io/milvus/issues/44132
pr: #44810

Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
2025-10-20 18:58:09 +08:00
congqixia
4312bfd030
enhance: Bump milvus & proto version to v2.6.4 (#44977)
Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-20 18:56:03 +08:00
XuanYang-cn
41dfbba33a
fix: Disk encryption config missing (#44820) (#44839)
pr: #44820
See also: #44823

Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-10-20 18:52:03 +08:00
wei liu
613b6a716e
fix: [2.6] Fix deactivate balance checker also stops stopping balance (#44836)
issue: #43858
pr: #44834
Fix the issue introduced in PR #43992 where deactivating the balance
checker incorrectly stops stopping balance operations.

Changes:
- Move IsActive() check after stopping balance logic
- Only skip normal balance when checker is inactive
- Allow stopping balance to proceed regardless of checker state

This ensures stopping balance can execute even when the balance checker
is deactivated.

---------

Signed-off-by: Wei Liu <wei.liu@zilliz.com>
2025-10-20 18:48:03 +08:00
zhagnlu
26c3983d93
fix: fix not equal not include None (#44960)
#44959

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-10-20 18:25:52 +08:00
aoiasd
fd22dc281a
enhance: [2.6] update some annotations (#44953)
relate: https://github.com/milvus-io/milvus/issues/43114
pr: https://github.com/milvus-io/milvus/pull/44769

---------

Signed-off-by: aoiasd <zhicheng.yue@zilliz.com>
2025-10-20 15:42:08 +08:00
Zhen Ye
c835f4b0dc
fix: rerank before requery if reranker didn't use field data (#44943)
issue: #44918
pr: #44942

---------

Signed-off-by: chyezh <chyezh@outlook.com>
2025-10-20 15:38:03 +08:00
nico
d6de935b88
test: update cases for binary vectors support HNSW and timezone[2.6] (#44931)
pr: #44928

Signed-off-by: nico <cheng.yuan@zilliz.com>
2025-10-20 14:52:03 +08:00
congqixia
b737011048
fix: [2.6] support JSON default value in CreateArrowScalarFromDefaultValue(#44912) (#44952)
Cherry-pick from master
pr: #44912
Related to #44897

Add missing JSON data type handling in CreateArrowScalarFromDefaultValue
to fix query failures when dynamic fields are enabled. JSON default
values are now properly converted to arrow::BinaryScalar using
bytes_data().

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-20 10:46:03 +08:00
zhikunyao
dc2c4d0f7f
enhance: remove gcc from build dockerfile to fix cve 2.6 (#44882)
pr: #44881

Signed-off-by: Zhikun Yao <zhikun.yao@zilliz.com>
2025-10-20 10:42:03 +08:00
Spade A
94c3f114eb
fix: reject GEOMETRY and TIMESTAMPTZ in STRUCT [2.6] (#44938)
issue: https://github.com/milvus-io/milvus/issues/44930
pr: https://github.com/milvus-io/milvus/pull/44937

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-10-20 10:34:03 +08:00
Zhen Ye
1ff0d5d47d
fix: use short debug string to avoid newline in debug logs (#44929)
issue: #44924
pr: #44925

Signed-off-by: chyezh <chyezh@outlook.com>
2025-10-20 10:32:03 +08:00
Bingyi Sun
82c019181e
fix: Fix exists expr for json flat index (#44951)
issue: https://github.com/milvus-io/milvus/issues/44915
pr: https://github.com/milvus-io/milvus/pull/44910

Signed-off-by: sunby <sunbingyi1992@gmail.com>
2025-10-19 19:52:02 +08:00
sparknack
64b76b723f
enhance: [2.6] add a disk quota for the loaded binlog size to prevent load failures of querynode (#44932)
issue: #41435 
pr: #44893

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-19 19:46:07 +08:00
zhagnlu
ce8187d28e
fix:remove duplicated '/' in jsonstats path (#44945)
pr: #44939

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-10-19 12:10:02 +08:00
cai.zhang
642a77a497
fix: [2.6] Fix return EOF when geometry enable null (#44913)
issue: #44648
master pr: #44911 

If the value is `null` during insertion, it will be omitted instead of
being filled with nil. Therefore, when performing checks, there’s no
need to retrieve data based on the valid offset.

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-10-17 17:16:08 +08:00
cai.zhang
2dea67cc20
fix: [2.6]Fix the geometry return POINT(0 0) when growing mmap is enabled (#44890)
issue: #44802 
master pr: #44889 

After a Geometry object is serialized into WKB, the resulting binary may
contain '\0' bytes.
When growing mmap is enabled, the append data logic uses strcpy, which
stops copying at the first '\0' bytes.
This causes only part of the WKB---typically the portion up to the
geometry type field to be copied, leading to corrupted data.
As a result, during parsing, all POINT geometries are incorrectly
interperted as POINT(0 0).

To fix this issue, memcpy will be used instead of strcpy.

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-10-17 17:14:23 +08:00
cai.zhang
dd62691438
enhance: [2.6]Support import geometry data by json/csv (#44827)
issue: #44787 
master pr: #44826

---------

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-10-17 17:12:17 +08:00
zhagnlu
8e8b551b6f
fix:unified json exists path semantic (#44926)
pr: #44916

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-10-17 15:52:02 +08:00
Spade A
c6d951adb8
feat: impl StructArray -- ban non-float-vector for now [2.6] (#44876)
ref https://github.com/milvus-io/milvus/issues/42148
pr: https://github.com/milvus-io/milvus/pull/44875

---------

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-10-17 15:26:02 +08:00
Spade A
cfd748f50d
fix: empty internal InsertMsg caues panic[2.6] (#44906)
issue: https://github.com/milvus-io/milvus/issues/44901
pr: https://github.com/milvus-io/milvus/pull/44903

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
2025-10-17 10:32:01 +08:00
congqixia
2b5c2f7303
fix: [2.6] ensure deterministic search result ordering when scores are equal (#44870) (#44884)
Cherry-pick from master
pr: #44870

Related to #44819
This fix addresses an issue(#44819) where the offset parameter did not
work correctly during searches when multiple results had identical
scores. The problem occurred because results with equal scores were not
consistently ordered, leading to unpredictable pagination behavior.

The solution adds a new sorting step (SortEqualScoresByPks) in the
reduce phase that sorts results with identical scores by their primary
keys in ascending order. This ensures deterministic ordering and enables
proper offset functionality.

Changes:
- Add SortEqualScoresByPks() to sort results with equal scores by PK
- Add SortEqualScoresOneNQ() to handle per-query sorting logic
- Invoke sorting step after FillPrimaryKey() in Reduce() workflow

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-16 19:34:08 +08:00
foxspy
8cb49595e7
fix: [2.6] update aisaq params (#44862)
issue: #44860 
pr: #44861

Signed-off-by: xianliang.li <xianliang.li@zilliz.com>
2025-10-15 18:19:45 +08:00
cqy123456
b43dcdf9aa
enhance: [2.6]embedding_list support mmap in MemVectorIndex (#44832)
issue: https://github.com/milvus-io/milvus/issues/44702
related pr: https://github.com/milvus-io/milvus/pull/44764

Signed-off-by: cqy123456 <qianya.cheng@zilliz.com>
2025-10-15 16:18:00 +08:00
yanliang567
bb4446e5af
test:[cp 2.6] add test for allow insert auto id (#44837)
related issue: https://github.com/milvus-io/milvus/issues/44425
pr: #44801

split insert.py into a few files: upsert.py, insert.py,
partial_upsert.py ...
add test for allow insert auto id

---------

Signed-off-by: yanliang567 <yanliang.qiao@zilliz.com>
2025-10-15 11:38:00 +08:00
sparknack
88b731d1f0
fix: milvus-common update (#44799)
issue: #44501 
pr: #44798

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-15 11:26:00 +08:00
sparknack
54fe82756a
enhance: [2.6] add cachinglayer management for TextMatchIndex (#44768)
issue: #41435, #44502
pr: #44741, #44806

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-15 11:09:59 +08:00
Bingyi Sun
cd272e8c94
enhance: optimize the performace of bitmap reverse lookup (#44804) (#44838)
pr: https://github.com/milvus-io/milvus/pull/44804

Signed-off-by: sunby <sunbingyi1992@gmail.com>
2025-10-15 10:38:00 +08:00
Spade A
661b803d12
feat: impl StructArray -- support more types of vector in STRUCT [2.6] (#44845)
ref: https://github.com/milvus-io/milvus/issues/42148
pr: https://github.com/milvus-io/milvus/pull/44736

---------

Signed-off-by: SpadeA <tangchenjie1210@gmail.com>
Signed-off-by: SpadeA-Tang <tangchenjie1210@gmail.com>
2025-10-15 10:34:00 +08:00
cqy123456
57f0d028bc
fix:[2.6]remove the limit of deduplicate case when disable autoindex (#44824)
issue: https://github.com/milvus-io/milvus/issues/44702
related pr: https://github.com/milvus-io/milvus/pull/44825

Signed-off-by: cqy123456 <qianya.cheng@zilliz.com>
2025-10-14 17:02:00 +08:00
nico
abdf993efd
enhance: [skip e2e]Enable nightly test for the 2.6 branch (#44829)
Signed-off-by: nico <cheng.yuan@zilliz.com>
2025-10-14 16:58:08 +08:00
congqixia
8ed2717c3f
fix: [2.6] avoid concurrent Reset/Add operations on DataCoord metrics (#44789) (#44815)
Cherry-pick from master
pr: #44789

This commit addresses issue #44788 where the
`datacoord_stored_binlog_size` metric could become inaccurate when
multiple concurrent `GetMetrics` calls arrived at DataCoord.

### Problem

The original implementation called `Reset()` followed by `Add()`
operations on Prometheus metrics within the `GetQuotaInfo()` method.
When multiple goroutines invoked this method concurrently, race
conditions occurred:
- Thread 1: Reset() → Add(value1)
- Thread 2: Reset() → Add(value2)
- Result: Metrics could be reset multiple times and values added in an
interleaved fashion, leading to inaccurate and inflated metric values

### Solution

Changed the approach from `Reset() + Add()` to aggregating metric values
in local maps first, then using `Set()` to update metrics atomically:

1. Collect segment size data into local maps:
   - `storedBinlogSize`: tracks size per collection per segment state
   - `binlogFileSize`: tracks total file count per collection
   - `coll2DbName`: maps collection IDs to database names

2. After aggregation is complete, use `Set()` (instead of `Add()`) to
update metrics in a single operation per label combination

This ensures that concurrent `GetMetrics` calls don't interfere with
each other, as each invocation works with its own local state and only
updates the final metric value atomically.

---------

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-14 16:48:05 +08:00
Buqian Zheng
3d0ad8b65d
fix [2.6]: disable using shredding for json_path contains digital (#44808)
issue: #44132
pr: #44724

Signed-off-by: zhagnlu <lu.zhang@zilliz.com>
Co-authored-by: zhagnlu <lu.zhang@zilliz.com>
2025-10-14 10:25:59 +08:00
zhagnlu
984f50e978
fix:fix json_contains(path, int) bug (#44818)
cherry-pick from pr: #44814

Signed-off-by: luzhang <luzhang@zilliz.com>
Co-authored-by: luzhang <luzhang@zilliz.com>
2025-10-14 00:22:00 +08:00
sparknack
e23f923c21
fix: cachinglayer: [2.6] avoid eviction during json handling (#44813)
issue: #44797 
pr: #44812

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-13 22:10:00 +08:00
foxspy
40f0aef6b8
enhance: [2.6] update knowhere version (#44765)
issue: #42937 
/kind branch-feature
/set-milestone 2.6.4

Signed-off-by: xianliang.li <xianliang.li@zilliz.com>
2025-10-13 19:21:58 +08:00
aoiasd
92996cba9d
fix:[2.6] expr filter return wrong result when skipped (#44779)
relate: https://github.com/milvus-io/milvus/issues/44777
pr: https://github.com/milvus-io/milvus/pull/44778
Should return res with false if skipped. But now return vaild[0], it
almost be true.

Signed-off-by: aoiasd <zhicheng.yue@zilliz.com>
2025-10-13 19:15:59 +08:00
Zhen Ye
ddd4dcc942
fix: check if qn is sqn with label and streamingnode list (#44793)
issue: #44014
pr: #44792

- On standalone, the query node inside need to load segment and watch
channel, so the querynode is not a embeded querynode in streamingnode
without LabelStreamingNodeEmbeddedQueryNode. The channel dist manager
can not confirm a standalone node is a embededStreamingNode.

Bug is introduced by https://github.com/milvus-io/milvus/pull/44099

Signed-off-by: chyezh <chyezh@outlook.com>
2025-10-13 16:39:59 +08:00
XuanYang-cn
71a0203ce2
test: Increase PyMilvus version to 2.6.3rc9 for 2.6 branch (#44795)
Automated daily bump from pymilvus 2.6 branch. Updates
tests/python_client/requirements.txt.

Signed-off-by: XuanYang-cn <xuan.yang@zilliz.com>
2025-10-13 15:55:58 +08:00
sparknack
c72a19d174
enhance: remove logical usage checks during segment loading (#44770)
issue: #41435 
pr: #44743

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-13 14:23:58 +08:00
aoiasd
6ff30e8f9e
fix: [2.6] BM25 with boost return result not ordered (#44759)
relate: https://github.com/milvus-io/milvus/issues/44758
pr: https://github.com/milvus-io/milvus/pull/44744
Wrong code which should be (result.seg_offsets_[i] >= 0 &&
result.seg_offsets_[j] < 0), but was (result.seg_offsets_[j] >= 0 &&
result.seg_offsets_[j] < 0) now.
But because all placeholder which was offset -1, will fill with worst
distance value.
For IP, L2 or COSIN, it will be +inf or -inf. So sort distance was
enough.
But when use BM25, it will be NAN. Will case sort out of ordered.

Signed-off-by: aoiasd <zhicheng.yue@zilliz.com>
2025-10-13 11:57:57 +08:00
congqixia
781df9d0b3
enhance: [2.6] Add accesslog field for template value length info (#44723) (#44783)
Cherry-pick from master
pr: #44723
Related to #36672

Add accesslog field displaying value length for search/query request may
help developers debug related issues

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-13 10:21:58 +08:00
foxspy
d1d32eb1f9
enhance: [2.6]overwriting current index type during index build stage (#44754)
issue: #44753 
pr: #44753

Signed-off-by: xianliang.li <xianliang.li@zilliz.com>
2025-10-11 21:03:58 +08:00
foxspy
363d214500
enhance: [2.6]add load params for vector index (#44749)
issue: #44746 
pr: #44747

Signed-off-by: xianliang.li <xianliang.li@zilliz.com>
2025-10-11 21:02:05 +08:00
congqixia
0a908c2e52
enhance: [GoSDK] Bump milvusclient version to v2.6.1 (#44775)
Bump go milvus client version to v2.6.1

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-11 19:25:57 +08:00
XuanYang-cn
69a5ff5518
enhance: [cp26]Unify compaction executor task state management (#44722)
Remove stopTask.
Replace multiple task tracking maps with single unified taskState map.
Fix slot tracking, improve state transitions, and add comprehensive test

See also: #44714
pr: #44721

---------

Signed-off-by: yangxuan <xuan.yang@zilliz.com>
2025-10-11 18:30:08 +08:00
cai.zhang
9af220e211
fix: [2.6] Fix bug for nullable geometry (#44767)
issue: #44648 
master pr: #44732

Signed-off-by: Cai Zhang <cai.zhang@zilliz.com>
2025-10-11 17:51:56 +08:00
congqixia
e469e89d83
enhance: [2.6] Bump go version to 1.24.6 with image builder (#44763)
Cherry-pick from master
pr: #44739 #44757
Fixing CVE-2025-47907

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-11 16:35:57 +08:00
zhenshan.cao
fc6fe6e3bd
enhance: Add refine logs for task scheduler in QueryCoord (#44577) (#44725)
issue: https://github.com/milvus-io/milvus/issues/43968
pr: https://github.com/milvus-io/milvus/pull/44577

---------

Signed-off-by: zhenshan.cao <zhenshan.cao@zilliz.com>
Signed-off-by: Wei Liu <wei.liu@zilliz.com>
Co-authored-by: wei liu <wei.liu@zilliz.com>
2025-10-11 15:35:57 +08:00
Bingyi Sun
0ca9a76ab8
fix: Fix bulk import with autoid (#44604) (#44694)
issue: #44424
pr: #44604

Signed-off-by: sunby <sunbingyi1992@gmail.com>
2025-10-11 10:23:58 +08:00
congqixia
07bca45376
fix: [2.6] Pass fs via FileManagerContext when loading index (#44734)
Cherry-pick from master
pr: #44733
Related to #44615

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-11 09:57:57 +08:00
congqixia
a85b06d965
fix: [2.6] Use eventually & fix task id appear in both executing&completed (#44698) (#44715)
Cherry-pick from master
pr: #44698
Related to #44620

This PR:
- Use eventually instead of `time.Sleep` in accesslog writer unit test
- Make sure compaction task results have only one state from executor
API

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-10 14:29:57 +08:00
congqixia
615544ee71
enhance: [2.6][GoSDK] Bump pkg version to v2.6.3 (#44712)
Cherry-pick from master
pr: #44619 
Related to #31293

Bump pkg dependency version to v2.6.3

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-10 11:01:56 +08:00
Zhen Ye
ce0a0b964e
fix: remove wrong start timetick to avoid filtering DML whose timetick is less than it. (#44692)
issue: #41611
pr: #44691

- introduced by #44532

Signed-off-by: chyezh <chyezh@outlook.com>
2025-10-10 10:13:57 +08:00
congqixia
81ce0a3efe
enhance: [2.6] Make accesslog.$consistency_level represent actual value used (#44706) (#44711)
Cherry-pick from master
pr: #44706 
Related to #44703

This PR:
- Add `SetActualConsistencyLevel` to `info.AccessInfo` interface and
related util method processing it
- Make `$consistency_level` returning actual value if set

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-10 10:11:56 +08:00
congqixia
fb62c77bf7
enhance: [2.6][backlog] Fix unittest and remove fs fallback logic (#44615) (#44686)
Cherry-pick from master
pr: #44615
Related to #44535

This PR:
- Fix the unittest creating `DiskFileManagerImpl` without `filesystem`
- Add comments for methods need `fs_`
- Remove fallback creation and add assertion for nullptr fs

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-10 10:01:55 +08:00
sre-ci-robot
778da323bd
[automated] Bump milvus version to v2.6.3 (#44656)
Bump milvus version to v2.6.3
Signed-off-by: sre-ci-robot sre-ci-robot@users.noreply.github.com

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-10 09:19:57 +08:00
liliu-z
b08fba5074
enhance: Upgrade Knohwere Version to fix GPU Compilation issue (#44707)
pr: #44704

Signed-off-by: Li Liu <li.liu@zilliz.com>
2025-10-10 09:06:04 +08:00
congqixia
98530564b5
fix: [2.6] Make aws credential provider singleton (#44687) (#44705)
Cherry-pick from master
pr: #44687
Related to #44647

This patch make milvus-storage using singleton credential provider in
case of data race when concurrent index build task recieved.

See also milvus-io/milvus-storage#44647

---------

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-09 19:39:56 +08:00
Zhen Ye
ea4c2227da
enhance: remove redundant channel manager from datacoord (#44679)
issue: #41611
pr: #44532

- After enabling streaming arch, channel manager of data coord is a
redundant component.

---------

Signed-off-by: chyezh <chyezh@outlook.com>
2025-10-09 11:11:56 +08:00
congqixia
6c0a234ad6
enhance: [2.6] Use relative path in proto following convention (#44650) (#44653)
Cherry-pick from master
pr: #44650
Previous pr #44163

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
2025-10-09 10:01:57 +08:00
PjJinchen
8797703c09
feat: [2.6] support Ali rerank(#44364) (#44660)
Cherry-pick from master
pr: https://github.com/milvus-io/milvus/pull/44364
issue: https://github.com/milvus-io/milvus/issues/44363

---------

Signed-off-by: PjJinchen <6268414+pj1987111@users.noreply.github.com>
2025-10-02 15:31:22 +08:00
992 changed files with 66796 additions and 46123 deletions

8
.env
View File

@ -5,11 +5,11 @@ IMAGE_ARCH=amd64
OS_NAME=ubuntu22.04
# for services.builder.image in docker-compose.yml
DATE_VERSION=20250915-2b2a11a
LATEST_DATE_VERSION=20250915-2b2a11a
DATE_VERSION=20251011-78b266a
LATEST_DATE_VERSION=20251011-78b266a
# for services.gpubuilder.image in docker-compose.yml
GPU_DATE_VERSION=20250915-2b2a11a
LATEST_GPU_DATE_VERSION=20250915-2b2a11a
GPU_DATE_VERSION=20251011-78b266a
LATEST_GPU_DATE_VERSION=20251011-78b266a
# for other services in docker-compose.yml
MINIO_ADDRESS=minio:9000

View File

@ -61,7 +61,8 @@ jobs:
- name: Setup Go environment
uses: actions/setup-go@v4
with:
go-version: '1.24.4'
go-version: '1.24.9'
cache: false
- name: Download Caches
uses: ./.github/actions/macos-cache-restore
- name: Code Check

3
.gitignore vendored
View File

@ -117,3 +117,6 @@ WARP.md
# Antlr
.antlr
# Gocache
**/.gocache/

View File

@ -111,6 +111,8 @@ linters-settings:
desc: "not allowed, gogo protobuf is deprecated"
- pkg: "github.com/golang/protobuf/proto"
desc: "not allowed, protobuf v1 is deprecated, use google.golang.org/protobuf/proto instead"
- pkg: "github.com/pingcap/log"
desc: "not allowed, use github.com/milvus-io/milvus/pkg/v2/log"
forbidigo:
forbid:
- '^time\.Tick$'

View File

@ -191,9 +191,11 @@ lint-fix: getdeps
@$(INSTALL_PATH)/gci write pkg/ --skip-generated -s standard -s default -s "prefix(github.com/milvus-io)" --custom-order
@$(INSTALL_PATH)/gci write client/ --skip-generated -s standard -s default -s "prefix(github.com/milvus-io)" --custom-order
@$(INSTALL_PATH)/gci write tests/ --skip-generated -s standard -s default -s "prefix(github.com/milvus-io)" --custom-order
@echo "Running golangci-lint auto-fix"
@echo "Running golangci-lint auto-fix for core"
@source $(PWD)/scripts/setenv.sh && GO111MODULE=on $(INSTALL_PATH)/golangci-lint run --fix --timeout=30m --config $(PWD)/.golangci.yml;
@echo "Running golangci-lint auto-fix for pkg"
@source $(PWD)/scripts/setenv.sh && cd pkg && GO111MODULE=on $(INSTALL_PATH)/golangci-lint run --fix --timeout=30m --config $(PWD)/.golangci.yml
@echo "Running golangci-lint auto-fix for client"
@source $(PWD)/scripts/setenv.sh && cd client && GO111MODULE=on $(INSTALL_PATH)/golangci-lint run --fix --timeout=30m --config $(PWD)/client/.golangci.yml
#TODO: Check code specifications by golangci-lint
@ -386,6 +388,21 @@ run-test-cpp:
@echo $(PWD)/scripts/run_cpp_unittest.sh arg=${filter}
@(env bash $(PWD)/scripts/run_cpp_unittest.sh arg=${filter})
# tool for benchmark
exprparser-tool:
@echo "Building exprparser helper ..."
@source $(PWD)/scripts/setenv.sh && \
mkdir -p $(INSTALL_PATH) && go env -w CGO_ENABLED="1" && \
GO111MODULE=on $(GO) build -pgo=$(PGO_PATH)/default.pgo -ldflags="-r $${RPATH}" -o $(INSTALL_PATH)/exprparser $(PWD)/cmd/tools/exprparser/main.go 1>/dev/null
# Build unittest with external scalar-benchmark enabled
scalar-bench: generated-proto exprparser-tool
@echo "Building Milvus cpp unittest with scalar-benchmark ... "
@(export CMAKE_EXTRA_ARGS="-DENABLE_SCALAR_BENCH=ON"; env bash $(PWD)/scripts/core_build.sh -t ${mode} -a ${use_asan} -u -n ${use_disk_index} -y ${use_dynamic_simd} ${AZURE_OPTION} -x ${index_engine} -o ${use_opendal} -f $(tantivy_features))
scalar-bench-ui:
@echo "Starting scalar-benchmark ui ... "
@(cd cmake_build/unittest/scalar-benchmark-src/ui && ./serve_ui_dev.sh)
# Run code coverage.
codecov: codecov-go codecov-cpp
@ -478,12 +495,7 @@ generate-mockery-rootcoord: getdeps
$(INSTALL_PATH)/mockery --name=IMetaTable --dir=$(PWD)/internal/rootcoord --output=$(PWD)/internal/rootcoord/mocks --filename=meta_table.go --with-expecter --outpkg=mockrootcoord
generate-mockery-proxy: getdeps
$(INSTALL_PATH)/mockery --name=Cache --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_cache.go --structname=MockCache --with-expecter --outpkg=proxy --inpackage
$(INSTALL_PATH)/mockery --name=timestampAllocatorInterface --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_tso_test.go --structname=mockTimestampAllocator --with-expecter --outpkg=proxy --inpackage
$(INSTALL_PATH)/mockery --name=LBPolicy --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_lb_policy.go --structname=MockLBPolicy --with-expecter --outpkg=proxy --inpackage
$(INSTALL_PATH)/mockery --name=LBBalancer --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_lb_balancer.go --structname=MockLBBalancer --with-expecter --outpkg=proxy --inpackage
$(INSTALL_PATH)/mockery --name=shardClientMgr --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_shardclient_manager.go --structname=MockShardClientManager --with-expecter --outpkg=proxy --inpackage
$(INSTALL_PATH)/mockery --name=channelsMgr --dir=$(PWD)/internal/proxy --output=$(PWD)/internal/proxy --filename=mock_channels_manager.go --structname=MockChannelsMgr --with-expecter --outpkg=proxy --inpackage
$(INSTALL_PATH)/mockery --config $(PWD)/internal/proxy/.mockery.yaml
generate-mockery-querycoord: getdeps
$(INSTALL_PATH)/mockery --config $(PWD)/internal/querycoordv2/.mockery.yaml
@ -523,6 +535,7 @@ generate-mockery-utils: getdeps
# tso.Allocator
$(INSTALL_PATH)/mockery --name=Allocator --dir=internal/tso --output=internal/tso/mocks --filename=allocator.go --with-expecter --structname=Allocator --outpkg=mocktso
$(INSTALL_PATH)/mockery --name=SessionInterface --dir=$(PWD)/internal/util/sessionutil --output=$(PWD)/internal/util/sessionutil --filename=mock_session.go --with-expecter --structname=MockSession --inpackage
$(INSTALL_PATH)/mockery --name=SessionWatcher --dir=$(PWD)/internal/util/sessionutil --output=$(PWD)/internal/util/sessionutil --filename=mock_session_watcher.go --with-expecter --structname=MockSessionWatcher --inpackage
$(INSTALL_PATH)/mockery --name=GrpcClient --dir=$(PWD)/internal/util/grpcclient --output=$(PWD)/internal/mocks --filename=mock_grpc_client.go --with-expecter --structname=MockGrpcClient
# proxy_client_manager.go
$(INSTALL_PATH)/mockery --name=ProxyClientManagerInterface --dir=$(PWD)/internal/util/proxyutil --output=$(PWD)/internal/util/proxyutil --filename=mock_proxy_client_manager.go --with-expecter --structname=MockProxyClientManager --inpackage

View File

@ -8,7 +8,7 @@ Homepage: https://github.com/milvus-io/milvus
Package: milvus
Architecture: any-amd64
Depends: ${shlibs:Depends}, ${misc:Depends}
Depends: ${shlibs:Depends}, ${misc:Depends}, tzdata
Description: An open-source vector dstabase for unstructured data.
Milvus was created in 2019 with a singular goal: store, index, and manage massive embedding vectors generated by deep neural networks and other machine learning (ML) models.

View File

@ -15,14 +15,14 @@ ARG TARGETARCH
RUN dnf install -y wget g++ gcc gdb libatomic libstdc++-static ninja-build git make zip unzip tar which \
autoconf automake python3 python3-pip perl-FindBin texinfo \
pkg-config libuuid-devel libaio perl-IPC-Cmd libasan openblas-devel && \
pkg-config libuuid-devel libaio perl-IPC-Cmd libasan openblas-devel tzdata && \
rm -rf /var/cache/yum/*
ENV GOPATH /go
ENV GOROOT /usr/local/go
ENV GO111MODULE on
ENV PATH $GOPATH/bin:$GOROOT/bin:$PATH
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
mkdir -p "$GOPATH/src" "$GOPATH/bin" && \
go clean --modcache && \
chmod -R 777 "$GOPATH" && chmod -R a+w $(go env GOTOOLDIR)

View File

@ -17,7 +17,7 @@ ARG TARGETARCH
RUN dnf install -y make cmake automake gcc gcc-c++ curl zip unzip tar git which \
libaio libuuid-devel wget python3 python3-pip \
pkg-config perl-IPC-Cmd perl-Digest-SHA libatomic libtool
pkg-config perl-IPC-Cmd perl-Digest-SHA libatomic libtool tzdata
# install openblas-devel texinfo ninja
RUN dnf -y update && \
@ -27,7 +27,7 @@ RUN dnf -y update && \
RUN pip3 install conan==1.64.1
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go
RUN curl https://sh.rustup.rs -sSf | \
sh -s -- --default-toolchain=1.89 -y

View File

@ -17,6 +17,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget curl ca-ce
g++ gcc gdb gdbserver ninja-build git make ccache libssl-dev zlib1g-dev zip unzip \
clang-format-12 clang-tidy-12 lcov libtool m4 autoconf automake python3 python3-pip \
pkg-config uuid-dev libaio-dev libopenblas-dev && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
echo "Etc/UTC" > /etc/timezone && \
apt-get remove --purge -y && \
rm -rf /var/lib/apt/lists/*
@ -30,7 +33,7 @@ ENV GOPATH /go
ENV GOROOT /usr/local/go
ENV GO111MODULE on
ENV PATH $GOPATH/bin:$GOROOT/bin:$PATH
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
mkdir -p "$GOPATH/src" "$GOPATH/bin" && \
go clean --modcache && \
chmod -R 777 "$GOPATH" && chmod -R a+w $(go env GOTOOLDIR)

View File

@ -17,6 +17,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget curl ca-ce
g++ gcc gdb gdbserver ninja-build git make ccache libssl-dev zlib1g-dev zip unzip \
clang-format-12 clang-tidy-12 lcov libtool m4 autoconf automake python3 python3-pip \
pkg-config uuid-dev libaio-dev libopenblas-dev && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
echo "Etc/UTC" > /etc/timezone && \
apt-get remove --purge -y && \
rm -rf /var/lib/apt/lists/*
@ -36,7 +39,7 @@ ENV GOPATH /go
ENV GOROOT /usr/local/go
ENV GO111MODULE on
ENV PATH $GOPATH/bin:$GOROOT/bin:$PATH
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
mkdir -p "$GOPATH/src" "$GOPATH/bin" && \
go clean --modcache && \
chmod -R 777 "$GOPATH" && chmod -R a+w $(go env GOTOOLDIR)

View File

@ -19,6 +19,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget curl ca-ce
g++ gcc gfortran git make ccache libssl-dev zlib1g-dev zip unzip \
clang-format-12 clang-tidy-12 lcov libtool m4 autoconf automake python3 python3-pip \
pkg-config uuid-dev libaio-dev libgoogle-perftools-dev libopenblas-dev && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
echo "Etc/UTC" > /etc/timezone && \
apt-get remove --purge -y && \
rm -rf /var/lib/apt/lists/*
@ -41,7 +44,7 @@ ENV GOPATH /go
ENV GOROOT /usr/local/go
ENV GO111MODULE on
ENV PATH $GOPATH/bin:$GOROOT/bin:$PATH
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go && \
mkdir -p "$GOPATH/src" "$GOPATH/bin" && \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ${GOROOT}/bin v1.46.2 && \
# export GO111MODULE=on && go get github.com/quasilyte/go-ruleguard/cmd/ruleguard@v0.2.1 && \

View File

@ -8,12 +8,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget curl ca-ce
g++ gcc gfortran git make ccache libssl-dev zlib1g-dev zip unzip \
clang-format-12 clang-tidy-12 lcov libtool m4 autoconf automake python3 python3-pip \
pkg-config uuid-dev libaio-dev libgoogle-perftools-dev libopenblas-dev && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
echo "Etc/UTC" > /etc/timezone && \
apt-get remove --purge -y && \
rm -rf /var/lib/apt/lists/*
# Install go
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.4.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go
RUN mkdir -p /usr/local/go && wget -qO- "https://go.dev/dl/go1.24.9.linux-$TARGETARCH.tar.gz" | tar --strip-components=1 -xz -C /usr/local/go
# Install conan
RUN pip3 install conan==1.64.1
# Install rust

View File

@ -14,7 +14,7 @@ FROM amazonlinux:2023
ARG TARGETARCH
ARG MILVUS_ASAN_LIB
RUN yum install -y wget libgomp libaio libatomic openblas-devel gcc gcc-c++ && \
RUN yum install -y wget libgomp libaio libatomic openblas-devel tzdata && \
rm -rf /var/cache/yum/*
# Add Tini

View File

@ -21,6 +21,9 @@ ENV TZ=UTC
RUN apt-get update && \
apt-get install -y --no-install-recommends curl libtbb-dev gfortran netcat iputils-ping ca-certificates liblapack3 libzstd-dev uuid-dev libaio-dev libboost-program-options-dev libboost-filesystem-dev && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
echo "Etc/UTC" > /etc/timezone && \
apt-get remove --purge -y && \
rm -rf /var/lib/apt/lists/*

View File

@ -8,6 +8,9 @@ RUN apt-get update && \
sed -i 's/http:/https:/g' /etc/apt/sources.list && \
apt-get update && \
apt-get install -y --no-install-recommends curl libaio-dev libgomp1 libopenblas-dev && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
echo "Etc/UTC" > /etc/timezone && \
apt-get remove --purge -y && \
rm -rf /var/lib/apt/lists/*

View File

@ -15,7 +15,7 @@ FROM rockylinux/rockylinux:8
ARG TARGETARCH
ARG MILVUS_ASAN_LIB
RUN dnf install -y wget libgomp libaio libatomic gcc gcc-c++
RUN dnf install -y wget libgomp libaio libatomic tzdata
# install openblas-devel
RUN dnf -y install dnf-plugins-core && \

View File

@ -19,7 +19,10 @@ RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates && \
sed -i 's/http:/https:/g' /etc/apt/sources.list && \
apt-get update && \
apt-get install -y --no-install-recommends curl libaio-dev libgomp1 libopenblas-dev gcc g++ && \
apt-get install -y --no-install-recommends curl libaio-dev libgomp1 libopenblas-dev && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
echo "Etc/UTC" > /etc/timezone && \
apt-get remove --purge -y && \
rm -rf /var/lib/apt/lists/*

View File

@ -19,7 +19,10 @@ RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates && \
sed -i 's/http:/https:/g' /etc/apt/sources.list && \
apt-get update && \
apt-get install -y --no-install-recommends curl libaio-dev libgomp1 libopenblas-dev gcc g++ && \
apt-get install -y --no-install-recommends curl libaio-dev libgomp1 libopenblas-dev && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && \
ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
echo "Etc/UTC" > /etc/timezone && \
apt-get remove --purge -y && \
rm -rf /var/lib/apt/lists/*

View File

@ -11,7 +11,7 @@ Version: %{version}
Release: %{release}
Summary: Milvus V2 RPM
License: Apache License 2.0
Requires(preun): libstdc++ libgomp tbb-devel
Requires(preun): libstdc++ libgomp tbb-devel tzdata
# tbb-devel actually provides it, but not defined
Provides: libtbb.so()(64bit)
BuildArch: x86_64

View File

@ -1,5 +1,7 @@
#!/usr/bin/env groovy
// DEPRECATED: This job is deprecated, it is replaced by nightly2 job
// When scheduling a job that gets automatically triggered by changes,
// you need to include a [cronjob] tag within the commit message.
String cron_timezone = 'TZ=Asia/Shanghai'

View File

@ -3,12 +3,12 @@
def pod = libraryResource 'io/milvus/pod/tekton-4am.yaml'
String cron_timezone = 'TZ=Asia/Shanghai'
String cron_string = BRANCH_NAME == 'master' ? '50 4 * * * ' : ''
String cron_string = BRANCH_NAME == '2.6' ? '50 1 * * * ' : ''
// Make timeout 4 hours so that we can run two nightly during the ci
int total_timeout_minutes = 7 * 60
def milvus_helm_chart_version = '5.0.0'
def milvus_helm_chart_version = '5.0.6'
pipeline {
triggers {

View File

@ -4,7 +4,7 @@ int total_timeout_minutes = 60 * 5
int e2e_timeout_seconds = 120 * 60
def imageTag=''
int case_timeout_seconds = 20 * 60
def chart_version='5.0.0'
def chart_version='5.0.6'
pipeline {
options {
timestamps()

View File

@ -2,7 +2,7 @@
def pod = libraryResource 'io/milvus/pod/tekton-4am.yaml'
def milvus_helm_chart_version = '5.0.0'
def milvus_helm_chart_version = '5.0.6'
pipeline {
options {

View File

@ -1,7 +1,7 @@
@Library('jenkins-shared-library@tekton') _
def pod = libraryResource 'io/milvus/pod/tekton-4am.yaml'
def milvus_helm_chart_version = '5.0.0'
def milvus_helm_chart_version = '5.0.6'
pipeline {
options {

View File

@ -4,7 +4,7 @@ int total_timeout_minutes = 60 * 5
int e2e_timeout_seconds = 70 * 60
def imageTag=''
int case_timeout_seconds = 10 * 60
def chart_version='5.0.0'
def chart_version='5.0.6'
pipeline {
options {
timestamps()

View File

@ -1,5 +1,7 @@
@Library('jenkins-shared-library@tekton') _
// DEPRECATED: This job is deprecated, it is replaced by ci-v2/ut-cpp job
def pod = libraryResource 'io/milvus/pod/tekton-4am.yaml'
def milvus_helm_chart_version = '4.2.56'

View File

@ -10,7 +10,7 @@ Go MilvusClient for [Milvus](https://github.com/milvus-io/milvus). To contribute
### Prerequisites
Go 1.24.4 or higher
Go 1.24.9 or higher
### Install Milvus Go SDK

View File

@ -18,5 +18,5 @@ package common
const (
// SDKVersion const value for current version
SDKVersion = `2.6.0`
SDKVersion = `2.6.1`
)

View File

@ -1,22 +1,20 @@
module github.com/milvus-io/milvus/client/v2
go 1.24.4
go 1.24.9
require (
github.com/blang/semver/v4 v4.0.0
github.com/cockroachdb/errors v1.9.1
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3
github.com/milvus-io/milvus/pkg/v2 v2.0.0-20250319085209-5a6b4e56d59e
github.com/quasilyte/go-ruleguard/dsl v0.3.22
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7
github.com/milvus-io/milvus/pkg/v2 v2.6.7-0.20251201120310-af64f2acba38
github.com/quasilyte/go-ruleguard/dsl v0.3.23
github.com/samber/lo v1.27.0
github.com/stretchr/testify v1.10.0
github.com/stretchr/testify v1.11.1
github.com/tidwall/gjson v1.17.1
go.opentelemetry.io/otel v1.28.0
go.uber.org/atomic v1.11.0
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
google.golang.org/grpc v1.65.0
google.golang.org/protobuf v1.34.2
google.golang.org/grpc v1.71.0
google.golang.org/protobuf v1.36.5
)
require (
@ -29,10 +27,11 @@ require (
github.com/containerd/cgroups/v3 v3.0.3 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/getsentry/sentry-go v0.12.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
@ -42,29 +41,31 @@ require (
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/runtime-spec v1.0.2 // indirect
github.com/panjf2000/ants/v2 v2.11.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/shirou/gopsutil/v3 v3.22.9 // indirect
github.com/prometheus/client_golang v1.20.5 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/soheilhy/cmux v0.1.5 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
@ -73,13 +74,14 @@ require (
github.com/stretchr/objx v0.5.2 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/tklauser/numcpus v0.4.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
github.com/twpayne/go-geom v1.6.1 // indirect
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.etcd.io/etcd/api/v3 v3.5.5 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
@ -88,29 +90,32 @@ require (
go.etcd.io/etcd/pkg/v3 v3.5.5 // indirect
go.etcd.io/etcd/raft/v3 v3.5.5 // indirect
go.etcd.io/etcd/server/v3 v3.5.5 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.uber.org/automaxprocs v1.5.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.36.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/time v0.10.0 // indirect
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apimachinery v0.28.6 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
k8s.io/apimachinery v0.32.3 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

View File

@ -13,15 +13,19 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY=
github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -88,14 +92,15 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
@ -117,6 +122,8 @@ github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD
github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk=
@ -159,8 +166,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4=
github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc=
github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@ -215,8 +222,9 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
@ -248,6 +256,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
@ -265,8 +275,8 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/Kgo2/7xNSUuC5G28VR8ljfrLKU2G4IjU=
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12/go.mod h1:TBzl5BIHNXfS9+C35ZyJaklL7mLDbgUkcgXzSLa8Tk0=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
@ -283,6 +293,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -295,6 +307,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
@ -313,15 +327,13 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3 h1:w7IBrU25KULWNlHKoKwx6ruTsDAmzrWknotIc6A4ys4=
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/milvus-io/milvus/pkg/v2 v2.0.0-20250319085209-5a6b4e56d59e h1:VCr43pG4efacDbM4au70fh8/5hNTftoWzm1iEumvDWM=
github.com/milvus-io/milvus/pkg/v2 v2.0.0-20250319085209-5a6b4e56d59e/go.mod h1:37AWzxVs2NS4QUJrkcbeLUwi+4Av0h5mEdjLI62EANU=
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7 h1:RJtZbkS5zKNIXxsqjGBUZc2SbnI4MGq+TfOfc8tJsuM=
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/milvus-io/milvus/pkg/v2 v2.6.7-0.20251201120310-af64f2acba38 h1:75pdNz8Ln9jdBxlkUQRJu+P8tz4q+G48XAybS3O30FQ=
github.com/milvus-io/milvus/pkg/v2 v2.6.7-0.20251201120310-af64f2acba38/go.mod h1:ak5nlCCbtImG4/WWcI/csU5ht6EyF/9QQ/tmivMzF4c=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@ -338,6 +350,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
@ -363,8 +377,9 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
@ -375,39 +390,41 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=
github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/quasilyte/go-ruleguard/dsl v0.3.23 h1:lxjt5B6ZCiBeeNO8/oQsegE6fLeCzuMRoVWSkXC4uvY=
github.com/quasilyte/go-ruleguard/dsl v0.3.23/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/remeh/sizedwaitgroup v1.0.0 h1:VNGGFwNo/R5+MJBf6yrsr110p0m4/OX4S3DCy7Kyl5E=
github.com/remeh/sizedwaitgroup v1.0.0/go.mod h1:3j2R4OIe/SeS6YDhICBy22RWjJC5eNCJ1V+9+NVNYlo=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
@ -417,8 +434,12 @@ github.com/samber/lo v1.27.0/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+R
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA=
github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A=
github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4=
github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@ -449,6 +470,7 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@ -458,8 +480,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
github.com/thoas/go-funk v0.9.1/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
@ -469,13 +492,15 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/twpayne/go-geom v1.6.1 h1:iLE+Opv0Ihm/ABIcvQFGIiFBXd76oBIar9drAwHFhR4=
github.com/twpayne/go-geom v1.6.1/go.mod h1:Kr+Nly6BswFsKM5sd31YaoWS5PeDDH2NftJTK7Gd028=
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
@ -503,8 +528,8 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
@ -524,26 +549,30 @@ go.etcd.io/etcd/server/v3 v3.5.5 h1:jNjYm/9s+f9A9r6+SC4RvNaz6AqixpOvhrFdT0PvIj0=
go.etcd.io/etcd/server/v3 v3.5.5/go.mod h1:rZ95vDw/jrvsbj9XpTqPrTAB9/kzchVdhRirySPkUBc=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0/go.mod h1:E5NNboN0UqSAki0Atn9kVwaN7I+l25gGxDqBueo/74E=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0=
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI=
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk=
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
@ -577,8 +606,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -632,8 +661,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -647,8 +676,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -691,12 +720,13 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -705,14 +735,14 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -768,12 +798,12 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d h1:PksQg4dV6Sem3/HkBX+Ltq8T0ke0PKIRBNBatoDTVls=
google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:s7iA721uChleev562UJO2OYB0PPT9CMFjV+Ce7VJH5M=
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc=
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE=
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE=
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e h1:YA5lmSs3zc/5w+xsRcHqpETkaYyK63ivEPzNTcUUlSA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@ -788,8 +818,8 @@ google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -802,8 +832,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -819,8 +849,9 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
@ -843,9 +874,9 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
k8s.io/apimachinery v0.28.6 h1:RsTeR4z6S07srPg6XYrwXpTJVMXsjPXn0ODakMytSW0=
k8s.io/apimachinery v0.28.6/go.mod h1:QFNX/kCl/EMT2WTSz8k4WLCv2XnkOLMaL8GAVRMdpsA=
k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

View File

@ -86,6 +86,65 @@ func (_c *MilvusServiceServer_AddCollectionField_Call) RunAndReturn(run func(con
return _c
}
// AddCollectionFunction provides a mock function with given fields: _a0, _a1
func (_m *MilvusServiceServer) AddCollectionFunction(_a0 context.Context, _a1 *milvuspb.AddCollectionFunctionRequest) (*commonpb.Status, error) {
ret := _m.Called(_a0, _a1)
if len(ret) == 0 {
panic("no return value specified for AddCollectionFunction")
}
var r0 *commonpb.Status
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AddCollectionFunctionRequest) (*commonpb.Status, error)); ok {
return rf(_a0, _a1)
}
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AddCollectionFunctionRequest) *commonpb.Status); ok {
r0 = rf(_a0, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*commonpb.Status)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.AddCollectionFunctionRequest) error); ok {
r1 = rf(_a0, _a1)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MilvusServiceServer_AddCollectionFunction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddCollectionFunction'
type MilvusServiceServer_AddCollectionFunction_Call struct {
*mock.Call
}
// AddCollectionFunction is a helper method to define mock.On call
// - _a0 context.Context
// - _a1 *milvuspb.AddCollectionFunctionRequest
func (_e *MilvusServiceServer_Expecter) AddCollectionFunction(_a0 interface{}, _a1 interface{}) *MilvusServiceServer_AddCollectionFunction_Call {
return &MilvusServiceServer_AddCollectionFunction_Call{Call: _e.mock.On("AddCollectionFunction", _a0, _a1)}
}
func (_c *MilvusServiceServer_AddCollectionFunction_Call) Run(run func(_a0 context.Context, _a1 *milvuspb.AddCollectionFunctionRequest)) *MilvusServiceServer_AddCollectionFunction_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*milvuspb.AddCollectionFunctionRequest))
})
return _c
}
func (_c *MilvusServiceServer_AddCollectionFunction_Call) Return(_a0 *commonpb.Status, _a1 error) *MilvusServiceServer_AddCollectionFunction_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MilvusServiceServer_AddCollectionFunction_Call) RunAndReturn(run func(context.Context, *milvuspb.AddCollectionFunctionRequest) (*commonpb.Status, error)) *MilvusServiceServer_AddCollectionFunction_Call {
_c.Call.Return(run)
return _c
}
// AddFileResource provides a mock function with given fields: _a0, _a1
func (_m *MilvusServiceServer) AddFileResource(_a0 context.Context, _a1 *milvuspb.AddFileResourceRequest) (*commonpb.Status, error) {
ret := _m.Called(_a0, _a1)
@ -440,6 +499,65 @@ func (_c *MilvusServiceServer_AlterCollectionField_Call) RunAndReturn(run func(c
return _c
}
// AlterCollectionFunction provides a mock function with given fields: _a0, _a1
func (_m *MilvusServiceServer) AlterCollectionFunction(_a0 context.Context, _a1 *milvuspb.AlterCollectionFunctionRequest) (*commonpb.Status, error) {
ret := _m.Called(_a0, _a1)
if len(ret) == 0 {
panic("no return value specified for AlterCollectionFunction")
}
var r0 *commonpb.Status
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AlterCollectionFunctionRequest) (*commonpb.Status, error)); ok {
return rf(_a0, _a1)
}
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AlterCollectionFunctionRequest) *commonpb.Status); ok {
r0 = rf(_a0, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*commonpb.Status)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.AlterCollectionFunctionRequest) error); ok {
r1 = rf(_a0, _a1)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MilvusServiceServer_AlterCollectionFunction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AlterCollectionFunction'
type MilvusServiceServer_AlterCollectionFunction_Call struct {
*mock.Call
}
// AlterCollectionFunction is a helper method to define mock.On call
// - _a0 context.Context
// - _a1 *milvuspb.AlterCollectionFunctionRequest
func (_e *MilvusServiceServer_Expecter) AlterCollectionFunction(_a0 interface{}, _a1 interface{}) *MilvusServiceServer_AlterCollectionFunction_Call {
return &MilvusServiceServer_AlterCollectionFunction_Call{Call: _e.mock.On("AlterCollectionFunction", _a0, _a1)}
}
func (_c *MilvusServiceServer_AlterCollectionFunction_Call) Run(run func(_a0 context.Context, _a1 *milvuspb.AlterCollectionFunctionRequest)) *MilvusServiceServer_AlterCollectionFunction_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*milvuspb.AlterCollectionFunctionRequest))
})
return _c
}
func (_c *MilvusServiceServer_AlterCollectionFunction_Call) Return(_a0 *commonpb.Status, _a1 error) *MilvusServiceServer_AlterCollectionFunction_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MilvusServiceServer_AlterCollectionFunction_Call) RunAndReturn(run func(context.Context, *milvuspb.AlterCollectionFunctionRequest) (*commonpb.Status, error)) *MilvusServiceServer_AlterCollectionFunction_Call {
_c.Call.Return(run)
return _c
}
// AlterDatabase provides a mock function with given fields: _a0, _a1
func (_m *MilvusServiceServer) AlterDatabase(_a0 context.Context, _a1 *milvuspb.AlterDatabaseRequest) (*commonpb.Status, error) {
ret := _m.Called(_a0, _a1)
@ -2138,6 +2256,65 @@ func (_c *MilvusServiceServer_DropCollection_Call) RunAndReturn(run func(context
return _c
}
// DropCollectionFunction provides a mock function with given fields: _a0, _a1
func (_m *MilvusServiceServer) DropCollectionFunction(_a0 context.Context, _a1 *milvuspb.DropCollectionFunctionRequest) (*commonpb.Status, error) {
ret := _m.Called(_a0, _a1)
if len(ret) == 0 {
panic("no return value specified for DropCollectionFunction")
}
var r0 *commonpb.Status
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.DropCollectionFunctionRequest) (*commonpb.Status, error)); ok {
return rf(_a0, _a1)
}
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.DropCollectionFunctionRequest) *commonpb.Status); ok {
r0 = rf(_a0, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*commonpb.Status)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.DropCollectionFunctionRequest) error); ok {
r1 = rf(_a0, _a1)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MilvusServiceServer_DropCollectionFunction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DropCollectionFunction'
type MilvusServiceServer_DropCollectionFunction_Call struct {
*mock.Call
}
// DropCollectionFunction is a helper method to define mock.On call
// - _a0 context.Context
// - _a1 *milvuspb.DropCollectionFunctionRequest
func (_e *MilvusServiceServer_Expecter) DropCollectionFunction(_a0 interface{}, _a1 interface{}) *MilvusServiceServer_DropCollectionFunction_Call {
return &MilvusServiceServer_DropCollectionFunction_Call{Call: _e.mock.On("DropCollectionFunction", _a0, _a1)}
}
func (_c *MilvusServiceServer_DropCollectionFunction_Call) Run(run func(_a0 context.Context, _a1 *milvuspb.DropCollectionFunctionRequest)) *MilvusServiceServer_DropCollectionFunction_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*milvuspb.DropCollectionFunctionRequest))
})
return _c
}
func (_c *MilvusServiceServer_DropCollectionFunction_Call) Return(_a0 *commonpb.Status, _a1 error) *MilvusServiceServer_DropCollectionFunction_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MilvusServiceServer_DropCollectionFunction_Call) RunAndReturn(run func(context.Context, *milvuspb.DropCollectionFunctionRequest) (*commonpb.Status, error)) *MilvusServiceServer_DropCollectionFunction_Call {
_c.Call.Return(run)
return _c
}
// DropDatabase provides a mock function with given fields: _a0, _a1
func (_m *MilvusServiceServer) DropDatabase(_a0 context.Context, _a1 *milvuspb.DropDatabaseRequest) (*commonpb.Status, error) {
ret := _m.Called(_a0, _a1)

View File

@ -26,10 +26,7 @@ func (c *Client) UpdateReplicateConfiguration(ctx context.Context, config *commo
}
// GetReplicateInfo gets replicate information from the Milvus cluster
func (c *Client) GetReplicateInfo(ctx context.Context, sourceClusterID string, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error) {
req := &milvuspb.GetReplicateInfoRequest{
SourceClusterId: sourceClusterID,
}
func (c *Client) GetReplicateInfo(ctx context.Context, req *milvuspb.GetReplicateInfoRequest, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error) {
var resp *milvuspb.GetReplicateInfoResponse
err := c.callService(func(milvusService milvuspb.MilvusServiceClient) error {
var err error

View File

@ -21,6 +21,7 @@ import (
"context"
"log"
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
"github.com/milvus-io/milvus/client/v2/milvusclient"
)
@ -81,13 +82,16 @@ func ExampleClient_GetReplicateInfo() {
}
// Get replicate information for a specific source cluster
resp, err := cli.GetReplicateInfo(ctx, "source-cluster")
resp, err := cli.GetReplicateInfo(ctx, &milvuspb.GetReplicateInfoRequest{
SourceClusterId: "source-cluster",
TargetPchannel: "source-channel-dml_0",
})
if err != nil {
log.Printf("Failed to get replicate information: %v", err)
return
}
log.Printf("Replicate information retrieved successfully, checkpoint count: %d", len(resp.GetCheckpoints()))
log.Printf("Replicate information retrieved successfully, checkpoint: %v", resp.GetCheckpoint())
}
func ExampleClient_CreateReplicateStream() {

View File

@ -216,7 +216,7 @@ func (c *mck) connectEctd() {
var err error
log := log.Ctx(context.TODO())
if c.etcdIP != "" {
etcdCli, err = etcd.GetRemoteEtcdClient([]string{c.etcdIP})
etcdCli, err = etcd.GetRemoteEtcdClient([]string{c.etcdIP}, c.params.EtcdCfg.ClientOptions()...)
} else {
etcdCli, err = etcd.CreateEtcdClient(
c.params.EtcdCfg.UseEmbedEtcd.GetAsBool(),
@ -228,7 +228,8 @@ func (c *mck) connectEctd() {
c.params.EtcdCfg.EtcdTLSCert.GetValue(),
c.params.EtcdCfg.EtcdTLSKey.GetValue(),
c.params.EtcdCfg.EtcdTLSCACert.GetValue(),
c.params.EtcdCfg.EtcdTLSMinVersion.GetValue())
c.params.EtcdCfg.EtcdTLSMinVersion.GetValue(),
c.params.EtcdCfg.ClientOptions()...)
}
if err != nil {
log.Fatal("failed to connect to etcd", zap.Error(err))

View File

@ -21,7 +21,6 @@ import (
"github.com/milvus-io/milvus/cmd/roles"
"github.com/milvus-io/milvus/internal/util/sessionutil"
"github.com/milvus-io/milvus/internal/util/streamingutil"
"github.com/milvus-io/milvus/pkg/v2/log"
"github.com/milvus-io/milvus/pkg/v2/util/etcd"
"github.com/milvus-io/milvus/pkg/v2/util/hardware"
@ -138,7 +137,7 @@ func GetMilvusRoles(args []string, flags *flag.FlagSet) *roles.MilvusRoles {
case typeutil.DataNodeRole:
role.EnableDataNode = true
case typeutil.StreamingNodeRole:
streamingutil.EnableEmbededQueryNode()
sessionutil.EnableEmbededQueryNodeLabel()
role.EnableStreamingNode = true
role.EnableQueryNode = true
case typeutil.StandaloneRole, typeutil.EmbeddedRole:
@ -149,9 +148,9 @@ func GetMilvusRoles(args []string, flags *flag.FlagSet) *roles.MilvusRoles {
role.EnableStreamingNode = true
role.Local = true
role.Embedded = serverType == typeutil.EmbeddedRole
sessionutil.EnableStandaloneLabel()
case typeutil.MixCoordRole:
role.EnableMixCoord = true
case typeutil.MixtureRole:
role.EnableRootCoord = enableRootCoord
role.EnableQueryCoord = enableQueryCoord
@ -162,7 +161,7 @@ func GetMilvusRoles(args []string, flags *flag.FlagSet) *roles.MilvusRoles {
role.EnableStreamingNode = enableStreamingNode
if enableStreamingNode && !enableQueryNode {
role.EnableQueryNode = true
streamingutil.EnableEmbededQueryNode()
sessionutil.EnableEmbededQueryNodeLabel()
}
case typeutil.CDCRole:

View File

@ -21,12 +21,14 @@ import (
"fmt"
"os"
"os/signal"
"reflect"
"runtime/debug"
"strings"
"sync"
"syscall"
"time"
"github.com/cockroachdb/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/samber/lo"
@ -50,10 +52,10 @@ import (
rocksmqimpl "github.com/milvus-io/milvus/pkg/v2/mq/mqimpl/rocksmq/server"
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
"github.com/milvus-io/milvus/pkg/v2/tracer"
"github.com/milvus-io/milvus/pkg/v2/util/conc"
"github.com/milvus-io/milvus/pkg/v2/util/etcd"
"github.com/milvus-io/milvus/pkg/v2/util/expr"
"github.com/milvus-io/milvus/pkg/v2/util/gc"
"github.com/milvus-io/milvus/pkg/v2/util/generic"
"github.com/milvus-io/milvus/pkg/v2/util/logutil"
"github.com/milvus-io/milvus/pkg/v2/util/metricsinfo"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
@ -109,35 +111,40 @@ func runComponent[T component](ctx context.Context,
runWg *sync.WaitGroup,
creator func(context.Context, dependency.Factory) (T, error),
metricRegister func(*prometheus.Registry),
) component {
var role T
) *conc.Future[component] {
sign := make(chan struct{})
go func() {
factory := dependency.NewFactory(localMsg)
var err error
role, err = creator(ctx, factory)
future := conc.Go(func() (component, error) {
// Wrap the creation and preparation phase to enable concurrent component startup
prepareFunc := func() (component, error) {
defer close(sign)
factory := dependency.NewFactory(localMsg)
var err error
role, err := creator(ctx, factory)
if err != nil {
return nil, errors.Wrap(err, "create component failed")
}
if err := role.Prepare(); err != nil {
return nil, errors.Wrap(err, "prepare component failed")
}
healthz.Register(role)
metricRegister(Registry.GoRegistry)
return role, nil
}
role, err := prepareFunc()
if err != nil {
panic(err)
return nil, err
}
if err := role.Prepare(); err != nil {
panic(err)
}
close(sign)
// Run() executes after sign is closed, allowing components to start concurrently
if err := role.Run(); err != nil {
panic(err)
return nil, errors.Wrap(err, "run component failed")
}
runWg.Done()
}()
return role, nil
})
<-sign
healthz.Register(role)
metricRegister(Registry.GoRegistry)
if generic.IsZero(role) {
return nil
}
return role
return future
}
// MilvusRoles decides which components are brought up with Milvus.
@ -177,18 +184,15 @@ func (mr *MilvusRoles) printLDPreLoad() {
}
}
func (mr *MilvusRoles) runProxy(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
wg.Add(1)
func (mr *MilvusRoles) runProxy(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
return runComponent(ctx, localMsg, wg, components.NewProxy, metrics.RegisterProxy)
}
func (mr *MilvusRoles) runMixCoord(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
wg.Add(1)
func (mr *MilvusRoles) runMixCoord(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
return runComponent(ctx, localMsg, wg, components.NewMixCoord, metrics.RegisterMixCoord)
}
func (mr *MilvusRoles) runQueryNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
wg.Add(1)
func (mr *MilvusRoles) runQueryNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
// clear local storage
queryDataLocalPath := pathutil.GetPath(pathutil.RootCachePath, 0)
if !paramtable.Get().CommonCfg.EnablePosixMode.GetAsBool() {
@ -199,21 +203,73 @@ func (mr *MilvusRoles) runQueryNode(ctx context.Context, localMsg bool, wg *sync
return runComponent(ctx, localMsg, wg, components.NewQueryNode, metrics.RegisterQueryNode)
}
func (mr *MilvusRoles) runStreamingNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
wg.Add(1)
func (mr *MilvusRoles) runStreamingNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
return runComponent(ctx, localMsg, wg, components.NewStreamingNode, metrics.RegisterStreamingNode)
}
func (mr *MilvusRoles) runDataNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
wg.Add(1)
func (mr *MilvusRoles) runDataNode(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
return runComponent(ctx, localMsg, wg, components.NewDataNode, metrics.RegisterDataNode)
}
func (mr *MilvusRoles) runCDC(ctx context.Context, localMsg bool, wg *sync.WaitGroup) component {
wg.Add(1)
func (mr *MilvusRoles) runCDC(ctx context.Context, localMsg bool, wg *sync.WaitGroup) *conc.Future[component] {
return runComponent(ctx, localMsg, wg, components.NewCDC, metrics.RegisterCDC)
}
func (mr *MilvusRoles) waitForAllComponentsReady(cancel context.CancelFunc, componentFutureMap map[string]*conc.Future[component]) (map[string]component, error) {
roles := make([]string, 0, len(componentFutureMap))
futures := make([]*conc.Future[component], 0, len(componentFutureMap))
for role, future := range componentFutureMap {
roles = append(roles, role)
futures = append(futures, future)
}
selectCases := make([]reflect.SelectCase, 1+len(componentFutureMap))
selectCases[0] = reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(mr.closed),
}
for i, future := range futures {
selectCases[i+1] = reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(future.Inner()),
}
}
componentMap := make(map[string]component, len(componentFutureMap))
readyCount := 0
var gerr error
for {
index, _, _ := reflect.Select(selectCases)
if index == 0 {
cancel()
log.Warn("components are not ready before closing, wait for the start of components to be canceled...")
} else {
role := roles[index-1]
component, err := futures[index-1].Await()
readyCount++
if err != nil {
if gerr == nil {
gerr = errors.Wrapf(err, "component %s is not ready before closing", role)
cancel()
}
log.Warn("component is not ready before closing", zap.String("role", role), zap.Error(err))
} else {
componentMap[role] = component
log.Info("component is ready", zap.String("role", role))
}
}
selectCases[index] = reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(nil),
}
if readyCount == len(componentFutureMap) {
break
}
}
if gerr != nil {
return nil, errors.Wrap(gerr, "failed to wait for all components ready")
}
return componentMap, nil
}
func (mr *MilvusRoles) setupLogger() {
params := paramtable.Get()
logConfig := log.Config{
@ -227,6 +283,13 @@ func (mr *MilvusRoles) setupLogger() {
MaxDays: params.LogCfg.MaxAge.GetAsInt(),
MaxBackups: params.LogCfg.MaxBackups.GetAsInt(),
},
AsyncWriteEnable: params.LogCfg.AsyncWriteEnable.GetAsBool(),
AsyncWriteFlushInterval: params.LogCfg.AsyncWriteFlushInterval.GetAsDurationByParse(),
AsyncWriteDroppedTimeout: params.LogCfg.AsyncWriteDroppedTimeout.GetAsDurationByParse(),
AsyncWriteStopTimeout: params.LogCfg.AsyncWriteStopTimeout.GetAsDurationByParse(),
AsyncWritePendingLength: params.LogCfg.AsyncWritePendingLength.GetAsInt(),
AsyncWriteBufferSize: int(params.LogCfg.AsyncWriteBufferSize.GetAsSize()),
AsyncWriteMaxBytesPerLog: int(params.LogCfg.AsyncWriteMaxBytesPerLog.GetAsSize()),
}
id := paramtable.GetNodeID()
roleName := paramtable.GetRole()
@ -238,6 +301,7 @@ func (mr *MilvusRoles) setupLogger() {
}
logutil.SetupLogger(&logConfig)
params.Watch(params.LogCfg.Level.Key, config.NewHandler("log.level", func(event *config.Event) {
if !event.HasUpdated || event.EventType == config.DeleteType {
return
@ -361,14 +425,6 @@ func (mr *MilvusRoles) Run() {
// init tracer before run any component
tracer.Init()
// Initialize streaming service if enabled.
if mr.ServerType == typeutil.StandaloneRole || !mr.EnableDataNode {
// only datanode does not init streaming service
streaming.Init()
defer streaming.Release()
}
enableComponents := []bool{
mr.EnableProxy,
mr.EnableQueryNode,
@ -388,6 +444,8 @@ func (mr *MilvusRoles) Run() {
expr.Init()
expr.Register("param", paramtable.Get())
mr.setupLogger()
defer log.Cleanup()
http.ServeHTTP()
setupPrometheusHTTPServer(Registry)
@ -403,51 +461,61 @@ func (mr *MilvusRoles) Run() {
}
}
// Initialize streaming service if enabled.
if mr.ServerType == typeutil.StandaloneRole || !mr.EnableDataNode {
// only datanode does not init streaming service
streaming.Init()
defer streaming.Release()
}
var wg sync.WaitGroup
local := mr.Local
componentMap := make(map[string]component)
var mixCoord component
var proxy, dataNode, queryNode, streamingNode, cdc component
componentFutureMap := make(map[string]*conc.Future[component])
if (mr.EnableRootCoord && mr.EnableDataCoord && mr.EnableQueryCoord) || mr.EnableMixCoord {
paramtable.SetLocalComponentEnabled(typeutil.MixCoordRole)
mixCoord = mr.runMixCoord(ctx, local, &wg)
componentMap[typeutil.MixCoordRole] = mixCoord
mixCoord := mr.runMixCoord(ctx, local, &wg)
componentFutureMap[typeutil.MixCoordRole] = mixCoord
}
if mr.EnableQueryNode {
paramtable.SetLocalComponentEnabled(typeutil.QueryNodeRole)
queryNode = mr.runQueryNode(ctx, local, &wg)
componentMap[typeutil.QueryNodeRole] = queryNode
queryNode := mr.runQueryNode(ctx, local, &wg)
componentFutureMap[typeutil.QueryNodeRole] = queryNode
}
if mr.EnableDataNode {
paramtable.SetLocalComponentEnabled(typeutil.DataNodeRole)
dataNode = mr.runDataNode(ctx, local, &wg)
componentMap[typeutil.DataNodeRole] = dataNode
dataNode := mr.runDataNode(ctx, local, &wg)
componentFutureMap[typeutil.DataNodeRole] = dataNode
}
if mr.EnableProxy {
paramtable.SetLocalComponentEnabled(typeutil.ProxyRole)
proxy = mr.runProxy(ctx, local, &wg)
componentMap[typeutil.ProxyRole] = proxy
proxy := mr.runProxy(ctx, local, &wg)
componentFutureMap[typeutil.ProxyRole] = proxy
}
if mr.EnableStreamingNode {
// Before initializing the local streaming node, make sure the local registry is ready.
paramtable.SetLocalComponentEnabled(typeutil.StreamingNodeRole)
streamingNode = mr.runStreamingNode(ctx, local, &wg)
componentMap[typeutil.StreamingNodeRole] = streamingNode
streamingNode := mr.runStreamingNode(ctx, local, &wg)
componentFutureMap[typeutil.StreamingNodeRole] = streamingNode
}
if mr.EnableCDC {
paramtable.SetLocalComponentEnabled(typeutil.CDCRole)
cdc = mr.runCDC(ctx, local, &wg)
componentMap[typeutil.CDCRole] = cdc
cdc := mr.runCDC(ctx, local, &wg)
componentFutureMap[typeutil.CDCRole] = cdc
}
wg.Wait()
componentMap, err := mr.waitForAllComponentsReady(cancel, componentFutureMap)
if err != nil {
log.Warn("Failed to wait for all components ready", zap.Error(err))
return
}
log.Info("All components are ready", zap.Strings("roles", lo.Keys(componentMap)))
http.RegisterStopComponent(func(role string) error {
if len(role) == 0 || componentMap[role] == nil {
@ -505,6 +573,13 @@ func (mr *MilvusRoles) Run() {
<-mr.closed
mixCoord := componentMap[typeutil.MixCoordRole]
streamingNode := componentMap[typeutil.StreamingNodeRole]
queryNode := componentMap[typeutil.QueryNodeRole]
dataNode := componentMap[typeutil.DataNodeRole]
cdc := componentMap[typeutil.CDCRole]
proxy := componentMap[typeutil.ProxyRole]
// stop coordinators first
coordinators := []component{mixCoord}
for idx, coord := range coordinators {

View File

@ -0,0 +1,115 @@
package main
import (
"bufio"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"os"
"strings"
"google.golang.org/protobuf/proto"
schemapb "github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
"github.com/milvus-io/milvus/internal/parser/planparserv2"
_ "github.com/milvus-io/milvus/pkg/v2/proto/planpb"
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
)
type parseRequest struct {
ID string `json:"id"`
Op string `json:"op"`
SchemaB64 string `json:"schema_b64"`
Expr string `json:"expr"`
Options struct {
IsCount bool `json:"is_count"`
Limit int64 `json:"limit"`
} `json:"options"`
}
type parseResponse struct {
ID string `json:"id"`
OK bool `json:"ok"`
PlanB64 string `json:"plan_b64,omitempty"`
Error string `json:"error,omitempty"`
}
func handle(line string) parseResponse {
line = strings.TrimSpace(line)
if line == "" {
return parseResponse{ID: "", OK: false, Error: "empty line"}
}
var req parseRequest
if err := json.Unmarshal([]byte(line), &req); err != nil {
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("invalid json: %v", err)}
}
if req.Op != "parse_expr" {
return parseResponse{ID: req.ID, OK: false, Error: "unsupported op"}
}
if req.SchemaB64 == "" {
return parseResponse{ID: req.ID, OK: false, Error: "missing schema_b64"}
}
if req.Expr == "" {
return parseResponse{ID: req.ID, OK: false, Error: "missing expr"}
}
schemaBytes, err := base64.StdEncoding.DecodeString(req.SchemaB64)
if err != nil {
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("decode schema_b64 failed: %v", err)}
}
var schema schemapb.CollectionSchema
if err := proto.Unmarshal(schemaBytes, &schema); err != nil {
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("unmarshal schema failed: %v", err)}
}
helper, err := typeutil.CreateSchemaHelper(&schema)
if err != nil {
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("schema helper error: %v", err)}
}
planNode, err := planparserv2.CreateRetrievePlan(helper, req.Expr, nil)
if err != nil {
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("parse error: %v", err)}
}
// Apply options if provided
if q := planNode.GetQuery(); q != nil {
q.IsCount = req.Options.IsCount
if req.Options.Limit > 0 {
q.Limit = req.Options.Limit
}
}
planBytes, err := proto.Marshal(planNode)
if err != nil {
return parseResponse{ID: req.ID, OK: false, Error: fmt.Sprintf("marshal plan failed: %v", err)}
}
return parseResponse{ID: req.ID, OK: true, PlanB64: base64.StdEncoding.EncodeToString(planBytes)}
}
func writeResp(w *bufio.Writer, resp parseResponse) {
b, _ := json.Marshal(resp)
_, _ = w.Write(b)
_ = w.WriteByte('\n')
_ = w.Flush()
}
func main() {
in := bufio.NewScanner(os.Stdin)
buf := make([]byte, 0, 1024*1024)
in.Buffer(buf, 16*1024*1024)
w := bufio.NewWriter(os.Stdout)
for {
if !in.Scan() {
if err := in.Err(); err != nil && err != io.EOF {
writeResp(w, parseResponse{ID: "", OK: false, Error: fmt.Sprintf("scan error: %v", err)})
}
break
}
resp := handle(in.Text())
writeResp(w, resp)
}
}

View File

@ -32,7 +32,8 @@ func newEtcdBasedBackend(cfg *configs.MilvusConfig) (*etcdBasedBackend, error) {
cfg.EtcdCfg.EtcdTLSCert.GetValue(),
cfg.EtcdCfg.EtcdTLSKey.GetValue(),
cfg.EtcdCfg.EtcdTLSCACert.GetValue(),
cfg.EtcdCfg.EtcdTLSMinVersion.GetValue())
cfg.EtcdCfg.EtcdTLSMinVersion.GetValue(),
cfg.EtcdCfg.ClientOptions()...)
if err != nil {
return nil, err
}

View File

@ -49,12 +49,12 @@ func (r *Runner) watchByPrefix(prefix string) {
_, revision, err := r.session.GetSessions(prefix)
fn := func() { r.Stop() }
console.AbnormalExitIf(err, r.backupFinished.Load(), console.AddCallbacks(fn))
eventCh := r.session.WatchServices(prefix, revision, nil)
watcher := r.session.WatchServices(prefix, revision, nil)
for {
select {
case <-r.ctx.Done():
return
case event := <-eventCh:
case event := <-watcher.EventChannel():
msg := fmt.Sprintf("session up/down, exit migration, event type: %s, session: %s", event.EventType.String(), event.Session.String())
console.AbnormalExit(r.backupFinished.Load(), msg, console.AddCallbacks(fn))
}
@ -79,7 +79,8 @@ func (r *Runner) initEtcdCli() {
r.cfg.EtcdCfg.EtcdTLSCert.GetValue(),
r.cfg.EtcdCfg.EtcdTLSKey.GetValue(),
r.cfg.EtcdCfg.EtcdTLSCACert.GetValue(),
r.cfg.EtcdCfg.EtcdTLSMinVersion.GetValue())
r.cfg.EtcdCfg.EtcdTLSMinVersion.GetValue(),
r.cfg.EtcdCfg.ClientOptions()...)
console.AbnormalExitIf(err, r.backupFinished.Load())
r.etcdCli = cli
}
@ -164,7 +165,6 @@ func (r *Runner) CheckSessions() error {
func (r *Runner) RegisterSession() error {
r.session.Register()
r.session.LivenessCheck(r.ctx, func() {})
return nil
}
@ -245,7 +245,7 @@ func (r *Runner) waitUntilSessionExpired() {
}
func (r *Runner) Stop() {
r.session.Revoke(time.Second)
r.session.Stop()
r.waitUntilSessionExpired()
r.cancel()
r.wg.Wait()

View File

@ -19,6 +19,7 @@ import (
// Therefore, we need to read configs from 2.3.x and modify meta data if necessary.
type MmapMigration struct {
rootcoordMeta rootcoord.IMetaTable
rootCoordCatalog metastore.RootCoordCatalog
tsoAllocator tso.Allocator
datacoordCatalog metastore.DataCoordCatalog
}
@ -58,8 +59,7 @@ func (m *MmapMigration) MigrateRootCoordCollection(ctx context.Context) {
newColl.Properties = updateOrAddMmapKey(newColl.Properties, common.MmapEnabledKey, "true")
fmt.Printf("migrate collection %v, %s\n", collection.CollectionID, collection.Name)
if err := m.rootcoordMeta.AlterCollection(ctx, collection, newColl, ts, false); err != nil {
if err := m.rootCoordCatalog.AlterCollection(ctx, collection, newColl, metastore.MODIFY, ts, false); err != nil {
panic(err)
}
}
@ -100,9 +100,10 @@ func (m *MmapMigration) MigrateIndexCoordCollection(ctx context.Context) {
}
}
func NewMmapMigration(rootcoordMeta rootcoord.IMetaTable, tsoAllocator tso.Allocator, datacoordCatalog metastore.DataCoordCatalog) *MmapMigration {
func NewMmapMigration(rootcoordMeta rootcoord.IMetaTable, tsoAllocator tso.Allocator, datacoordCatalog metastore.DataCoordCatalog, rootCoordCatalog metastore.RootCoordCatalog) *MmapMigration {
return &MmapMigration{
rootcoordMeta: rootcoordMeta,
rootCoordCatalog: rootCoordCatalog,
tsoAllocator: tsoAllocator,
datacoordCatalog: datacoordCatalog,
}

View File

@ -42,9 +42,9 @@ func main() {
}
fmt.Printf("MmapDirPath: %s\n", paramtable.Get().QueryNodeCfg.MmapDirPath.GetValue())
allocator := prepareTsoAllocator()
rootCoordMeta := prepareRootCoordMeta(context.Background(), allocator)
rootCoordMeta, rootCoordCatalog := prepareRootCoordMeta(context.Background(), allocator)
dataCoordCatalog := prepareDataCoordCatalog()
m := mmap.NewMmapMigration(rootCoordMeta, allocator, dataCoordCatalog)
m := mmap.NewMmapMigration(rootCoordMeta, allocator, dataCoordCatalog, rootCoordCatalog)
m.Migrate(context.Background())
}
@ -75,7 +75,8 @@ func prepareTsoAllocator() tso.Allocator {
etcdConfig.EtcdTLSCert.GetValue(),
etcdConfig.EtcdTLSKey.GetValue(),
etcdConfig.EtcdTLSCACert.GetValue(),
etcdConfig.EtcdTLSMinVersion.GetValue())
etcdConfig.EtcdTLSMinVersion.GetValue(),
etcdConfig.ClientOptions()...)
if err != nil {
panic(err)
}
@ -109,7 +110,8 @@ func metaKVCreator() (kv.MetaKv, error) {
etcdConfig.EtcdTLSCert.GetValue(),
etcdConfig.EtcdTLSKey.GetValue(),
etcdConfig.EtcdTLSCACert.GetValue(),
etcdConfig.EtcdTLSMinVersion.GetValue())
etcdConfig.EtcdTLSMinVersion.GetValue(),
etcdConfig.ClientOptions()...)
if err != nil {
panic(err)
}
@ -117,7 +119,7 @@ func metaKVCreator() (kv.MetaKv, error) {
etcdkv.WithRequestTimeout(paramtable.Get().ServiceParam.EtcdCfg.RequestTimeout.GetAsDuration(time.Millisecond))), nil
}
func prepareRootCoordMeta(ctx context.Context, allocator tso.Allocator) rootcoord.IMetaTable {
func prepareRootCoordMeta(ctx context.Context, allocator tso.Allocator) (rootcoord.IMetaTable, metastore.RootCoordCatalog) {
var catalog metastore.RootCoordCatalog
var err error
@ -158,7 +160,7 @@ func prepareRootCoordMeta(ctx context.Context, allocator tso.Allocator) rootcoor
panic(err)
}
return meta
return meta, catalog
}
func prepareDataCoordCatalog() metastore.DataCoordCatalog {

View File

@ -53,6 +53,8 @@ etcd:
# We recommend using version 1.2 and above.
tlsMinVersion: 1.3
requestTimeout: 10000 # Etcd operation timeout in milliseconds
dialKeepAliveTime: 3000 # Interval in milliseconds for gRPC dial keepalive pings sent to etcd endpoints.
dialKeepAliveTimeout: 2000 # Timeout in milliseconds waiting for keepalive responses before marking the connection as unhealthy.
use:
embed: false # Whether to enable embedded Etcd (an in-process EtcdServer).
data:
@ -211,6 +213,8 @@ woodpecker:
segmentReadPolicy:
maxBatchSize: 16M # Maximum size of a batch in bytes.
maxFetchThreads: 32 # Maximum number of threads to fetch data.
retentionPolicy:
ttl: 72h # Time to live for truncated segments in seconds, default is 72h
storage:
type: minio # The Type of the storage provider. Valid values: [minio, local]
rootPath: default # The root path of the storage provider. If set to 'default', uses localStorage.path as base directory and creates a woodpecker subdirectory. Otherwise, specifies a custom woodpecker data storage directory.
@ -242,8 +246,7 @@ pulsar:
# If these options is non-zero, the wal data in pulsar is fully protected by retention policy,
# so admin of pulsar should give enough retention time to avoid the wal message lost.
# If these options is zero, no subscription will be created, so pulsar cluster must close the backlog protection, otherwise the milvus can not recovered if backlog exceed.
# Moreover, if these option is zero, Milvus use a truncation subscriber to protect the wal data in pulsar if user disable the subscriptionExpirationTimeMinutes.
# The retention policy of pulsar can set shorter to save the storage space in this case.
# If this option is zero or negative, it will be ignored and the default value (100m) will be used.
backlogAutoClearBytes: 100m
# If you want to enable kafka, needs to comment the pulsar configs
@ -310,7 +313,7 @@ proxy:
bufSize: 512 # The maximum number of messages can be buffered in the timeTick message stream of the proxy when producing messages.
maxNameLength: 255 # The maximum length of the name or alias that can be created in Milvus, including the collection name, collection alias, partition name, and field name.
maxFieldNum: 64 # The maximum number of field can be created when creating in a collection. It is strongly DISCOURAGED to set maxFieldNum >= 64.
maxVectorFieldNum: 4 # The maximum number of vector fields that can be specified in a collection. Value range: [1, 10].
maxVectorFieldNum: 4 # The maximum number of vector fields that can be specified in a collection
maxShardNum: 16 # The maximum number of shards can be created when creating in a collection.
maxDimension: 32768 # The maximum number of dimensions of a vector can have when creating in a collection.
# Whether to produce gin logs.\n
@ -465,6 +468,7 @@ queryNode:
memExpansionRate: 1.15 # extra memory needed by building interim index
buildParallelRate: 0.5 # the ratio of building interim index parallel matched with cpu num
multipleChunkedEnable: true # Deprecated. Enable multiple chunked search
enableGeometryCache: false # Enable geometry cache for geometry data
tieredStorage:
warmup:
# options: sync, disable.
@ -488,20 +492,6 @@ queryNode:
# Enable eviction for Tiered Storage. Defaults to false.
# Note that if eviction is enabled, cache data loaded during sync warmup is also subject to eviction.
evictionEnabled: false
# This ratio estimates how much evictable memory can be cached.
# The higher the ratio, the more physical memory is reserved for evictable memory,
# resulting in fewer evictions but fewer segments can be loaded.
# Conversely, a lower ratio results in more evictions but allows more segments to be loaded.
# This parameter is only valid when eviction is enabled.
# It defaults to 0.3 (meaning about 30% of evictable in-memory data can be cached), with a valid range of [0.0, 1.0].
evictableMemoryCacheRatio: 0.3
# This ratio estimates how much evictable disk space can be cached.
# The higher the ratio, the more physical disk space is reserved for evictable disk usage,
# resulting in fewer evictions but fewer segments can be loaded.
# Conversely, a lower ratio results in more evictions but allows more segments to be loaded.
# This parameter is only valid when eviction is enabled.
# It defaults to 0.3 (meaning about 30% of evictable on-disk data can be cached), with a valid range of [0.0, 1.0].
evictableDiskCacheRatio: 0.3
# Enable background eviction for Tiered Storage. Defaults to false.
# Background eviction is used to do periodic eviction in a separate thread.
# And it will only work when both 'evictionEnabled' and 'backgroundEvictionEnabled' are set to 'true'.
@ -524,7 +514,7 @@ queryNode:
vectorIndex: false # Enable mmap for loading vector index
scalarField: false # Enable mmap for loading scalar data
scalarIndex: false # Enable mmap for loading scalar index
jsonStats: true # Enable mmap for loading json stats
jsonShredding: true # Enable mmap for loading json stats
# Enable memory mapping (mmap) to optimize the handling of growing raw data.
# By activating this feature, the memory overhead associated with newly added or modified data will be significantly minimized.
# However, this optimization may come at the cost of a slight decrease in query latency for the affected data segments.
@ -742,11 +732,11 @@ dataCoord:
indexTaskSlotUsage: 64 # slot usage of index task per 512mb
statsTaskSlotUsage: 8 # slot usage of stats task per 512mb
analyzeTaskSlotUsage: 65535 # slot usage of analyze task
jsonStatsTriggerCount: 10 # jsonkey stats task count per trigger
jsonStatsTriggerInterval: 10 # jsonkey task interval per trigger
jsonStatsMaxShreddingColumns: 1024 # the max number of columns to shred
jsonStatsShreddingRatioThreshold: 0.3 # the ratio threshold to shred
jsonStatsWriteBatchSize: 819200 # the batch size to write
jsonShreddingTriggerCount: 10 # jsonkey stats task count per trigger
jsonShreddingTriggerInterval: 10 # jsonkey task interval per trigger
jsonShreddingMaxColumns: 1024 # the max number of columns to shred
jsonShreddingRatioThreshold: 0.3 # the ratio threshold to shred
jsonShreddingWriteBatchSize: 81920 # the batch size to write
ip: # TCP/IP address of dataCoord. If not specified, use the first unicastable address
port: 13333 # TCP port of dataCoord
grpc:
@ -945,7 +935,7 @@ common:
# Currently, only QueryNode uses 'common.diskWrite*' parameters. Support for other components will be added in the future.
# The options include 'direct' and 'buffered'. The default value is 'buffered'.
diskWriteMode: buffered
# Disk write buffer size in KB, only used when disk write mode is 'direct', default is 64KB.
# Disk write buffer size in KB, used for both 'direct' and 'buffered' modes, default is 64KB.
# Current valid range is [4, 65536]. If the value is not aligned to 4KB, it will be rounded up to the nearest multiple of 4KB.
diskWriteBufferSizeKb: 64
# This parameter controls the number of writer threads used for disk write operations. The valid range is [0, hardware_concurrency].
@ -983,7 +973,7 @@ common:
readwrite:
privileges: ListDatabases,SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups,ListPrivilegeGroups,FlushAll,TransferNode,TransferReplica,UpdateResourceGroups # Cluster level readwrite privileges
admin:
privileges: ListDatabases,SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups,ListPrivilegeGroups,FlushAll,TransferNode,TransferReplica,UpdateResourceGroups,BackupRBAC,RestoreRBAC,CreateDatabase,DropDatabase,CreateOwnership,DropOwnership,ManageOwnership,CreateResourceGroup,DropResourceGroup,UpdateUser,RenameCollection,CreatePrivilegeGroup,DropPrivilegeGroup,OperatePrivilegeGroup # Cluster level admin privileges
privileges: ListDatabases,SelectOwnership,SelectUser,DescribeResourceGroup,ListResourceGroups,ListPrivilegeGroups,FlushAll,TransferNode,TransferReplica,UpdateResourceGroups,BackupRBAC,RestoreRBAC,CreateDatabase,DropDatabase,CreateOwnership,DropOwnership,ManageOwnership,CreateResourceGroup,DropResourceGroup,UpdateUser,RenameCollection,CreatePrivilegeGroup,DropPrivilegeGroup,OperatePrivilegeGroup,UpdateReplicateConfiguration # Cluster level admin privileges
database:
readonly:
privileges: ShowCollections,DescribeDatabase # Database level readonly privileges
@ -1001,7 +991,7 @@ common:
internaltlsEnabled: false
tlsMode: 0
session:
ttl: 10 # ttl value when session granting a lease to register service
ttl: 15 # ttl value when session granting a lease to register service
retryTimes: 30 # retry times when session sending etcd requests
locks:
metrics:
@ -1036,11 +1026,11 @@ common:
sync:
taskPoolReleaseTimeoutSeconds: 60 # The maximum time to wait for the task to finish and release resources in the pool
enabledOptimizeExpr: true # Indicates whether to enable optimize expr
enabledJSONKeyStats: false # Indicates sealedsegment whether to enable JSON key stats
enabledGrowingSegmentJSONKeyStats: false # Indicates growingsegment whether to enable JSON key stats
enabledJSONShredding: false # Indicates sealedsegment whether to enable JSON key stats
enabledGrowingSegmentJSONShredding: false # Indicates growingsegment whether to enable JSON key stats
enableConfigParamTypeCheck: true # Indicates whether to enable config param type check
enablePosixMode: false # Specifies whether to run in POSIX mode for enhanced file system compatibility
UsingJSONStatsForQuery: true # Indicates whether to use json stats when query
usingJSONShreddingForQuery: true # Indicates whether to use json stats when query
clusterID: 0 # cluster id
# QuotaConfig, configurations of Milvus quota and limits.
@ -1223,6 +1213,7 @@ quotaAndLimits:
diskProtection:
enabled: true # When the total file size of object storage is greater than `diskQuota`, all dml requests would be rejected;
diskQuota: -1 # MB, (0, +inf), default no limit
loadedDiskQuota: -1 # MB, (0, +inf), default no limit
diskQuotaPerDB: -1 # MB, (0, +inf), default no limit
diskQuotaPerCollection: -1 # MB, (0, +inf), default no limit
diskQuotaPerPartition: -1 # MB, (0, +inf), default no limit
@ -1325,7 +1316,7 @@ streaming:
# it also determine the depth of depth first search method that is used to find the best balance result, 3 by default
rebalanceMaxStep: 3
walBroadcaster:
concurrencyRatio: 1 # The concurrency ratio based on number of CPU for wal broadcaster, 1 by default.
concurrencyRatio: 4 # The concurrency ratio based on number of CPU for wal broadcaster, 4 by default.
txn:
defaultKeepaliveTimeout: 10s # The default keepalive timeout for wal txn, 10s by default
walWriteAheadBuffer:
@ -1376,23 +1367,17 @@ streaming:
# When the wal is on-closing, the recovery module will try to persist the recovery info for wal to make next recovery operation more fast.
# If that persist operation exceeds this timeout, the wal recovery module will close right now.
gracefulCloseTimeout: 3s
walTruncate:
# The interval of sampling wal checkpoint when truncate, 30m by default.
# Every time the checkpoint is persisted, the checkpoint will be sampled and used to be a candidate of truncate checkpoint.
# More samples, more frequent truncate, more memory usage.
sampleInterval: 30m
# The retention interval of wal truncate, 72h by default.
# If the sampled checkpoint is older than this interval, it will be used to truncate wal checkpoint.
# Greater the interval, more wal storage usage, more redundant data in wal.
# Because current query path doesn't promise the read operation not happen before the truncate point,
# retention interval should be greater than the dataCoord.segment.maxLife to avoid the message lost at query path.
# If the wal is pulsar, the pulsar should close the subscription expiration to avoid the message lost.
# because the wal truncate operation is implemented by pulsar consumer.
retentionInterval: 72h
# Any configuration related to the knowhere vector search engine
knowhere:
enable: true # When enable this configuration, the index parameters defined following will be automatically populated as index parameters, without requiring user input.
AISAQ:
build:
max_degree: 56 # Maximum degree of the Vamana graph
pq_code_budget_gb_ratio: 0.125 # Size limit on the PQ code (compared with raw data)
search_list_size: 100 # Size of the candidate list during building graph
search:
beam_width_ratio: 4 # Ratio between the maximum number of IO requests per search iteration and CPU number
DISKANN:
build:
max_degree: 56 # Maximum degree of the Vamana graph

View File

@ -30,7 +30,7 @@ $ ./minio server /minio
To start Milvus standalone, you need a Milvus binary file. Currently you can get the latest version of Milvus binary file through the Milvus docker image. (We will upload Milvus binary files in the future)
```shell
$ docker run -d --name milvus milvusdb/milvus:v2.6.1 /bin/bash
$ docker run -d --name milvus milvusdb/milvus:v2.6.6 /bin/bash
$ docker cp milvus:/milvus .
```

View File

@ -33,7 +33,7 @@ dependencies_network= host
nodes_network= host
; Setup varibale to controll what image version of Milvus to use.
image= milvusdb/milvus:v2.6.1
image= milvusdb/milvus:v2.6.6
; Setup static IP addresses of the docker hosts as variable for container environment variable config.
; Before running the playbook, below 4 IP addresses need to be replaced with the IP of your host VM

View File

@ -38,7 +38,7 @@ services:
standalone:
container_name: milvus-standalone
image: milvusdb/milvus:v2.6.1-gpu
image: milvusdb/milvus:v2.6.6-gpu
command: ["milvus", "run", "standalone"]
security_opt:
- seccomp:unconfined

View File

@ -38,7 +38,7 @@ services:
standalone:
container_name: milvus-standalone
image: milvusdb/milvus:v2.6.1
image: milvusdb/milvus:v2.6.6
command: ["milvus", "run", "standalone"]
security_opt:
- seccomp:unconfined

77
go.mod
View File

@ -1,6 +1,6 @@
module github.com/milvus-io/milvus
go 1.24.4
go 1.24.9
require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
@ -19,16 +19,16 @@ require (
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.2
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/klauspost/compress v1.17.9
github.com/klauspost/compress v1.18.0
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7
github.com/minio/minio-go/v7 v7.0.73
github.com/panjf2000/ants/v2 v2.11.3 // indirect
github.com/pingcap/log v1.1.1-0.20221015072633-39906604fb81
github.com/pingcap/log v1.1.1-0.20221015072633-39906604fb81 // indirect
github.com/prometheus/client_golang v1.20.5
github.com/prometheus/client_model v0.6.1
github.com/prometheus/common v0.55.0
github.com/quasilyte/go-ruleguard/dsl v0.3.22
github.com/quasilyte/go-ruleguard/dsl v0.3.23
github.com/samber/lo v1.27.0
github.com/sbinet/npyio v0.6.0
github.com/soheilhy/cmux v0.1.5
@ -37,28 +37,28 @@ require (
github.com/stretchr/testify v1.11.1
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.865 // indirect
github.com/tikv/client-go/v2 v2.0.4
go.etcd.io/etcd/api/v3 v3.5.5
go.etcd.io/etcd/client/v3 v3.5.5
go.etcd.io/etcd/server/v3 v3.5.5
go.etcd.io/etcd/api/v3 v3.5.23
go.etcd.io/etcd/client/v3 v3.5.23
go.etcd.io/etcd/server/v3 v3.5.23
go.opentelemetry.io/otel v1.34.0
go.opentelemetry.io/otel/trace v1.34.0
go.uber.org/atomic v1.11.0
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.41.0
golang.org/x/crypto v0.45.0
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
golang.org/x/net v0.43.0
golang.org/x/net v0.47.0
golang.org/x/oauth2 v0.28.0
golang.org/x/sync v0.16.0
golang.org/x/text v0.28.0
google.golang.org/grpc v1.71.0
golang.org/x/sync v0.18.0
golang.org/x/text v0.31.0
google.golang.org/grpc v1.71.1
google.golang.org/grpc/examples v0.0.0-20220617181431-3e7b97febc7f
)
require (
cloud.google.com/go/storage v1.50.0
github.com/antlr4-go/antlr/v4 v4.13.1
github.com/apache/pulsar-client-go v0.15.1
github.com/apache/pulsar-client-go v0.17.0
github.com/aws/aws-sdk-go-v2 v1.36.3
github.com/aws/aws-sdk-go-v2/config v1.29.9
github.com/aws/aws-sdk-go-v2/credentials v1.17.62
@ -74,10 +74,10 @@ require (
github.com/jolestar/go-commons-pool/v2 v2.1.2
github.com/magiconair/properties v1.8.7
github.com/milvus-io/milvus/client/v2 v2.0.0-00010101000000-000000000000
github.com/milvus-io/milvus/pkg/v2 v2.5.7
github.com/milvus-io/milvus/pkg/v2 v2.6.7-0.20251201120310-af64f2acba38
github.com/pkg/errors v0.9.1
github.com/remeh/sizedwaitgroup v1.0.0
github.com/shirou/gopsutil/v4 v4.24.10
github.com/shirou/gopsutil/v4 v4.25.10
github.com/tidwall/gjson v1.17.1
github.com/twpayne/go-geom v1.6.1
github.com/valyala/fastjson v1.6.4
@ -153,11 +153,12 @@ require (
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dvsekhvalnov/jose2go v1.6.0 // indirect
github.com/ebitengine/purego v0.8.1 // indirect
github.com/dvsekhvalnov/jose2go v1.7.0 // indirect
github.com/ebitengine/purego v0.9.0 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/expr-lang/expr v1.15.7 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
@ -172,12 +173,15 @@ require (
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/goccy/go-yaml v1.11.0 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/godbus/dbus/v5 v5.0.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/flatbuffers v24.3.25+incompatible // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/s2a-go v0.1.9 // indirect
@ -189,12 +193,13 @@ require (
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/hamba/avro/v2 v2.26.0 // indirect
github.com/hamba/avro/v2 v2.29.0 // indirect
github.com/hashicorp/go-syslog v1.0.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.174 // indirect
github.com/ianlancetaylor/cgosymbolizer v0.0.0-20221217025313-27d3c9f66b6a // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect
github.com/klauspost/asmfmt v1.3.2 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/kr/pretty v0.3.1 // indirect
@ -225,7 +230,7 @@ require (
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
@ -248,8 +253,9 @@ require (
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/tklauser/numcpus v0.10.0 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/twmb/murmur3 v1.1.6 // indirect
@ -260,12 +266,13 @@ require (
github.com/x448/float16 v0.8.4 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zilliztech/woodpecker v0.1.6 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
go.etcd.io/etcd/client/v2 v2.305.5 // indirect
go.etcd.io/etcd/pkg/v3 v3.5.5 // indirect
go.etcd.io/etcd/raft/v3 v3.5.5 // indirect
github.com/zilliztech/woodpecker v0.1.12 // indirect
go.etcd.io/bbolt v1.3.12 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.23 // indirect
go.etcd.io/etcd/client/v2 v2.305.23 // indirect
go.etcd.io/etcd/pkg/v3 v3.5.23 // indirect
go.etcd.io/etcd/raft/v3 v3.5.23 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
@ -280,11 +287,12 @@ require (
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.uber.org/automaxprocs v1.5.3 // indirect
golang.org/x/arch v0.11.0 // indirect
golang.org/x/mod v0.26.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/term v0.34.0 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect
golang.org/x/term v0.37.0 // indirect
golang.org/x/time v0.10.0 // indirect
golang.org/x/tools v0.35.0 // indirect
golang.org/x/tools v0.38.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
gonum.org/v1/gonum v0.15.0 // indirect
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
@ -310,7 +318,6 @@ replace (
github.com/bketelsen/crypt => github.com/bketelsen/crypt v0.0.4 // Fix security alert for core-os/etcd
github.com/expr-lang/expr => github.com/SimFG/expr v0.0.0-20250513112851-9b981e8400b9
github.com/go-kit/kit => github.com/go-kit/kit v0.1.0
github.com/golang-jwt/jwt => github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/greatroar/blobloom => github.com/milvus-io/blobloom v0.0.0-20240603110411-471ae49f3b93
github.com/ianlancetaylor/cgosymbolizer => github.com/milvus-io/cgosymbolizer v0.0.0-20250318084424-114f4050c3a6
github.com/milvus-io/milvus/pkg/v2 => ./pkg

183
go.sum
View File

@ -144,8 +144,8 @@ github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQY
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
github.com/apache/pulsar-client-go v0.15.1 h1:/BtkKA0WnGLDRJe1GJGhhRcpfxZ85IBHHOktmbz6fME=
github.com/apache/pulsar-client-go v0.15.1/go.mod h1:ow9PhLoGUY6ncrKOtjnWeJycFnTKOwrIV39j3kNV54M=
github.com/apache/pulsar-client-go v0.17.0 h1:FLyfsW6FfGHZPjDapu6Y+Thp/9JQNGJS3dms+18bdpA=
github.com/apache/pulsar-client-go v0.17.0/go.mod h1:sGZ3k5Knrf38skZh6YMoK8bibNH4aIq6wx7McQu8IAE=
github.com/apache/thrift v0.20.0 h1:631+KvYbsBZxmuJjYwhezVsrfc/TbqtZV4QcxOX1fOI=
github.com/apache/thrift v0.20.0/go.mod h1:hOk1BQqcp2OLzGsyVXdfMk7YFlMxK3aoEVhjD06QhB8=
github.com/ardielle/ardielle-go v1.5.2 h1:TilHTpHIQJ27R1Tl/iITBzMwiUGSlVfiVhwDNGM3Zj4=
@ -217,12 +217,10 @@ github.com/casbin/casbin/v2 v2.44.2 h1:mlWtgbX872r707frOq+REaHzfvsl+qQw0Eq+ekzJ7
github.com/casbin/casbin/v2 v2.44.2/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
github.com/casbin/json-adapter/v2 v2.0.0 h1:nOCN3TK1CJKSNQQ/MnakbU9/cUcNR3N0AxBDnEBLSDI=
github.com/casbin/json-adapter/v2 v2.0.0/go.mod h1:LvsfPXXr8CD0ZFucAxawcY9Xb0FtLk3mozJ1qcSTUD4=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
@ -240,7 +238,6 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
@ -263,8 +260,6 @@ github.com/confluentinc/confluent-kafka-go v1.9.1 h1:L3aW6KvTyrq/+BOMnDm9xJylhAE
github.com/confluentinc/confluent-kafka-go v1.9.1/go.mod h1:ptXNqsuDfYbAE/LBW6pnwWZElUoWxHoV8E43DCrliyo=
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
github.com/containerd/containerd v1.7.27 h1:yFyEyojddO3MIGVER2xJLWoCIn+Up4GaHFquP7hsFII=
github.com/containerd/containerd v1.7.27/go.mod h1:xZmPnl75Vc+BLGt4MIfu6bp+fy03gdHAn9bz+FreFR0=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
@ -303,8 +298,8 @@ github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4w
github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v28.0.0+incompatible h1:Olh0KS820sJ7nPsBKChVhk5pzqcwDR15fumfAd/p9hM=
github.com/docker/docker v28.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@ -317,10 +312,10 @@ github.com/dubbogo/jsonparser v1.0.1/go.mod h1:tYAtpctvSP/tWw4MeelsowSPgXQRVHHWb
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY=
github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU=
github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/BE=
github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo=
github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU=
github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k=
github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@ -328,7 +323,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
@ -350,6 +344,7 @@ github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+ne
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
@ -432,11 +427,16 @@ github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.9.8/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXKkTfoE=
github.com/goccy/go-yaml v1.11.0 h1:n7Z+zx8S9f9KgzG6KtQKf+kwqXZlLNR2F6018Dgau54=
github.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng=
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@ -454,6 +454,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
@ -465,7 +467,6 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
@ -497,12 +498,12 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI=
@ -588,8 +589,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9K
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=
github.com/hamba/avro v1.5.6/go.mod h1:3vNT0RLXXpFm2Tb/5KC71ZRJlOroggq1Rcitb6k4Fr8=
github.com/hamba/avro/v2 v2.26.0 h1:IaT5l6W3zh7K67sMrT2+RreJyDTllBGVJm4+Hedk9qE=
github.com/hamba/avro/v2 v2.26.0/go.mod h1:I8glyswHnpED3Nlx2ZdUe+4LJnCOOyiCzLMno9i/Uu0=
github.com/hamba/avro/v2 v2.29.0 h1:fkqoWEPxfygZxrkktgSHEpd0j/P7RKTBTDbcEeMdVEY=
github.com/hamba/avro/v2 v2.29.0/go.mod h1:Pk3T+x74uJoJOFmHrdJ8PRdgSEL/kEKteJ31NytCKxI=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -619,6 +620,8 @@ github.com/heetch/avro v0.3.1/go.mod h1:4xn38Oz/+hiEUTpbVfGVLfvOg0yKLlRP7Q9+gJJI
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.174 h1:FBlx7E5rl8doUTbizt+DXR0zU05Mu2oEYvc/2GMB7pc=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.174/go.mod h1:M+yna96Fx9o5GbIUnF3OvVvQGjgfVSyeJbV9Yb1z/wI=
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@ -653,8 +656,9 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/Kgo2/7xNSUuC5G28VR8ljfrLKU2G4IjU=
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12/go.mod h1:TBzl5BIHNXfS9+C35ZyJaklL7mLDbgUkcgXzSLa8Tk0=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@ -706,8 +710,9 @@ github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
@ -794,8 +799,8 @@ github.com/milvus-io/cgosymbolizer v0.0.0-20250318084424-114f4050c3a6 h1:YHMFI6L
github.com/milvus-io/cgosymbolizer v0.0.0-20250318084424-114f4050c3a6/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg=
github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b h1:TfeY0NxYxZzUfIfYe5qYDBzt4ZYRqzUjTR6CvUzjat8=
github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b/go.mod h1:iwW+9cWfIzzDseEBCCeDSN5SD16Tidvy8cwQ7ZY8Qj4=
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3 h1:w7IBrU25KULWNlHKoKwx6ruTsDAmzrWknotIc6A4ys4=
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.3/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7 h1:RJtZbkS5zKNIXxsqjGBUZc2SbnI4MGq+TfOfc8tJsuM=
github.com/milvus-io/milvus-proto/go-api/v2 v2.6.7/go.mod h1:/6UT4zZl6awVeXLeE7UGDWZvXj3IWkRsh3mqsn0DiAs=
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs=
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI=
@ -834,6 +839,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
@ -914,8 +920,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@ -925,7 +932,6 @@ github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@ -953,8 +959,8 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=
github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/quasilyte/go-ruleguard/dsl v0.3.23 h1:lxjt5B6ZCiBeeNO8/oQsegE6fLeCzuMRoVWSkXC4uvY=
github.com/quasilyte/go-ruleguard/dsl v0.3.23/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remeh/sizedwaitgroup v1.0.0 h1:VNGGFwNo/R5+MJBf6yrsr110p0m4/OX4S3DCy7Kyl5E=
@ -993,12 +999,13 @@ github.com/shirou/gopsutil v3.20.11+incompatible h1:LJr4ZQK4mPpIV5gOa4jCOKOGb4ty
github.com/shirou/gopsutil v3.20.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4=
github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
github.com/shirou/gopsutil/v4 v4.24.10 h1:7VOzPtfw/5YDU+jLEoBwXwxJbQetULywoSV4RYY7HkM=
github.com/shirou/gopsutil/v4 v4.24.10/go.mod h1:s4D/wg+ag4rG0WO7AiTj2BeYCRhym0vM7DHbZRxnIT8=
github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA=
github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/httpfs v0.0.0-20181222201310-74dc9339e414/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
@ -1034,7 +1041,6 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
@ -1092,10 +1098,14 @@ github.com/tikv/client-go/v2 v2.0.4 h1:cPtMXTExqjzk8L40qhrgB/mXiBXKP5LRU0vwjtI2X
github.com/tikv/client-go/v2 v2.0.4/go.mod h1:v52O5zDtv2BBus4lm5yrSQhxGW4Z4RaXWfg0U1Kuyqo=
github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 h1:ckPpxKcl75mO2N6a4cJXiZH43hvcHPpqc9dh1TmH1nc=
github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07/go.mod h1:CipBxPfxPUME+BImx9MUYXCnAVLS3VJUr3mnSJwh40A=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
@ -1128,6 +1138,9 @@ github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
@ -1137,6 +1150,7 @@ github.com/xiaofan-luan/pulsarctl v0.5.1 h1:2V+IWFarElzcln5WBbU3VNu3zC8Q7RS6rMpV
github.com/xiaofan-luan/pulsarctl v0.5.1/go.mod h1:kfeG1rRglz+QDSxyBB21H2Q4hMnzfirW32bs8yx/Q0Q=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
@ -1145,6 +1159,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
@ -1152,35 +1167,37 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
github.com/zilliztech/woodpecker v0.1.6 h1:3Ml1UJtiJXVPy01E5/qbVZHIPadL4RjJgg+e0Nj2LDw=
github.com/zilliztech/woodpecker v0.1.6/go.mod h1:xA7jPkUnnr5S4+LmQghrc/1hNU2kiU8KWZ93Uup2jks=
github.com/zilliztech/woodpecker v0.1.12 h1:GWq95o9FvwP/EvjedbDJlBwQPo/ZC9NxOmoSpeboznk=
github.com/zilliztech/woodpecker v0.1.12/go.mod h1:xA7jPkUnnr5S4+LmQghrc/1hNU2kiU8KWZ93Uup2jks=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.etcd.io/bbolt v1.3.12 h1:UAxZAIuJqzFwByP19gZC3zd5robK3FOangrGS+Fdczg=
go.etcd.io/bbolt v1.3.12/go.mod h1:Gi2toLZr1jFkuReJm+yEPn7H8wk6ooptePtHYCbCS1g=
go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r74ymPoSWa3Sw=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/api/v3 v3.5.5 h1:BX4JIbQ7hl7+jL+g+2j5UAr0o1bctCm6/Ct+ArBGkf0=
go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8=
go.etcd.io/etcd/api/v3 v3.5.23 h1:tQi/RaO6peOhmf0c11miU3RQIYPZmiL3UzG9V+f8g6k=
go.etcd.io/etcd/api/v3 v3.5.23/go.mod h1:QP4ZLWROP49Kk/vPLhudxYQcF4ndhMQ1gvJE4rCTAgc=
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/pkg/v3 v3.5.5 h1:9S0JUVvmrVl7wCF39iTQthdaaNIiAaQbmK75ogO6GU8=
go.etcd.io/etcd/client/pkg/v3 v3.5.5/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ=
go.etcd.io/etcd/client/pkg/v3 v3.5.23 h1:RzwVV28JgOwGl5TUjA47s9IWxl5qQjM2VqSh8wjFFLM=
go.etcd.io/etcd/client/pkg/v3 v3.5.23/go.mod h1:IdIjxGUGNy+8HWeVlbBXDqmPqe+n8GsVGVYnccAEZ5o=
go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU=
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
go.etcd.io/etcd/client/v2 v2.305.5 h1:DktRP60//JJpnPC0VBymAN/7V71GHMdjDCBt4ZPXDjI=
go.etcd.io/etcd/client/v2 v2.305.5/go.mod h1:zQjKllfqfBVyVStbt4FaosoX2iYd8fV/GRy/PbowgP4=
go.etcd.io/etcd/client/v2 v2.305.23 h1:lo6nsSHjp3tGsRLrzmM+neVSahXxbhxnfoatEdB6nao=
go.etcd.io/etcd/client/v2 v2.305.23/go.mod h1:Up9T9+5M3MMcCj/V0nDfadBERNMxIYf1tdycva1dXM4=
go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8=
go.etcd.io/etcd/client/v3 v3.5.5 h1:q++2WTJbUgpQu4B6hCuT7VkdwaTP7Qz6Daak3WzbrlI=
go.etcd.io/etcd/client/v3 v3.5.5/go.mod h1:aApjR4WGlSumpnJ2kloS75h6aHUmAyaPLjHMxpc7E7c=
go.etcd.io/etcd/client/v3 v3.5.23 h1:WN7sypGG326sFP5jLkFqD3anf/k6NNlV5Hy/UxvTPvc=
go.etcd.io/etcd/client/v3 v3.5.23/go.mod h1:XTf1oMQi4ZzpXGFoPgvAqbY9JFmTFQqWI1SF4g+hV6o=
go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0/go.mod h1:tV31atvwzcybuqejDoY3oaNRTtlD2l/Ot78Pc9w7DMY=
go.etcd.io/etcd/pkg/v3 v3.5.5 h1:Ablg7T7OkR+AeeeU32kdVhw/AGDsitkKPl7aW73ssjU=
go.etcd.io/etcd/pkg/v3 v3.5.5/go.mod h1:6ksYFxttiUGzC2uxyqiyOEvhAiD0tuIqSZkX3TyPdaE=
go.etcd.io/etcd/pkg/v3 v3.5.23 h1:q2skPu7VFC7oerL3MrFqImVACjAFWPlZMjHU0zll9x4=
go.etcd.io/etcd/pkg/v3 v3.5.23/go.mod h1:zUWlm5U4HgvDg+0PUWb8TgMF7ZrUiQA8aQq7FxE0WHo=
go.etcd.io/etcd/raft/v3 v3.5.0-alpha.0/go.mod h1:FAwse6Zlm5v4tEWZaTjmNhe17Int4Oxbu7+2r0DiD3w=
go.etcd.io/etcd/raft/v3 v3.5.5 h1:Ibz6XyZ60OYyRopu73lLM/P+qco3YtlZMOhnXNS051I=
go.etcd.io/etcd/raft/v3 v3.5.5/go.mod h1:76TA48q03g1y1VpTue92jZLr9lIHKUNcYdZOOGyx8rI=
go.etcd.io/etcd/raft/v3 v3.5.23 h1:NhCdh4xz1VsrqHd2c+h6SLvhE95B1Hs7K+ESaAs6LLQ=
go.etcd.io/etcd/raft/v3 v3.5.23/go.mod h1:NJz9BGkhGvru47lIc1wL0QHsg5yvHTy6tUpEqM69ERM=
go.etcd.io/etcd/server/v3 v3.5.0-alpha.0/go.mod h1:tsKetYpt980ZTpzl/gb+UOJj9RkIyCb1u4wjzMg90BQ=
go.etcd.io/etcd/server/v3 v3.5.5 h1:jNjYm/9s+f9A9r6+SC4RvNaz6AqixpOvhrFdT0PvIj0=
go.etcd.io/etcd/server/v3 v3.5.5/go.mod h1:rZ95vDw/jrvsbj9XpTqPrTAB9/kzchVdhRirySPkUBc=
go.etcd.io/etcd/server/v3 v3.5.23 h1:2g1hz32pp1TYMI7xUyifR8gXOlUnTBCfixV+uJ8BqRU=
go.etcd.io/etcd/server/v3 v3.5.23/go.mod h1:sZwt/lLSwYQ/S5aAbzSQX2xNw1WA0Fo5noUCVxVYB4g=
go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk=
go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@ -1192,20 +1209,16 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao=
go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0/go.mod h1:E5NNboN0UqSAki0Atn9kVwaN7I+l25gGxDqBueo/74E=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/exporters/jaeger v1.13.0 h1:VAMoGujbVV8Q0JNM/cEbhzUIWWBxnEqH45HP9iBKN04=
go.opentelemetry.io/otel/exporters/jaeger v1.13.0/go.mod h1:fHwbmle6mBFJA1p2ZIhilvffCdq/dM5UTIiCOmEjS+w=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.20.0 h1:CsBiKCiQPdSjS+MlRiqeTI9JDDpSuk0Hb6QTRfwer8k=
@ -1216,16 +1229,13 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.20.0 h1:4s9HxB4azeeQkhY
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.20.0/go.mod h1:djVA3TUJ2fSdMX0JE5XxFBOaZzprElJoP7fD4vnV2SU=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@ -1272,13 +1282,14 @@ golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1328,8 +1339,9 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.0.0-20180406214816-61147c48b25b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1369,6 +1381,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@ -1381,8 +1394,9 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1408,8 +1422,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180807162357-acbc56fc7007/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1457,7 +1472,6 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -1487,7 +1501,10 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -1495,11 +1512,14 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU=
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1509,14 +1529,15 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -1586,8 +1607,9 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1710,14 +1732,11 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc/examples v0.0.0-20220617181431-3e7b97febc7f h1:rqzndB2lIQGivcXdTuY3Y9NBvr70X+y77woofSRluec=
google.golang.org/grpc/examples v0.0.0-20220617181431-3e7b97febc7f/go.mod h1:gxndsbNG1n4TZcHGgsYEfVGnTxqfEdfiDv6/DADXX9o=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=

View File

@ -14,6 +14,9 @@ packages:
Broadcast:
Local:
Scanner:
github.com/milvus-io/milvus/internal/rootcoord/tombstone:
interfaces:
TombstoneSweeper:
github.com/milvus-io/milvus/internal/streamingcoord/server/balancer:
interfaces:
Balancer:

View File

@ -49,12 +49,12 @@ func startEmbedEtcdServer() (*embed.Etcd, error) {
if err != nil {
return nil, err
}
config.LCUrls = []url.URL{*u}
config.ListenClientUrls = []url.URL{*u}
u, err = url.Parse("http://localhost:0")
if err != nil {
return nil, err
}
config.LPUrls = []url.URL{*u}
config.ListenPeerUrls = []url.URL{*u}
return embed.StartEtcd(config)
}

View File

@ -1,4 +1,4 @@
// Code generated by mockery v2.32.4. DO NOT EDIT.
// Code generated by mockery v2.53.3. DO NOT EDIT.
package allocator
@ -21,6 +21,10 @@ func (_m *MockGlobalIDAllocator) EXPECT() *MockGlobalIDAllocator_Expecter {
func (_m *MockGlobalIDAllocator) Alloc(count uint32) (int64, int64, error) {
ret := _m.Called(count)
if len(ret) == 0 {
panic("no return value specified for Alloc")
}
var r0 int64
var r1 int64
var r2 error
@ -76,10 +80,14 @@ func (_c *MockGlobalIDAllocator_Alloc_Call) RunAndReturn(run func(uint32) (int64
return _c
}
// AllocOne provides a mock function with given fields:
// AllocOne provides a mock function with no fields
func (_m *MockGlobalIDAllocator) AllocOne() (int64, error) {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for AllocOne")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func() (int64, error)); ok {
@ -127,10 +135,14 @@ func (_c *MockGlobalIDAllocator_AllocOne_Call) RunAndReturn(run func() (int64, e
return _c
}
// Initialize provides a mock function with given fields:
// Initialize provides a mock function with no fields
func (_m *MockGlobalIDAllocator) Initialize() error {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Initialize")
}
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()

View File

@ -19,6 +19,3 @@ packages:
github.com/milvus-io/milvus/internal/cdc/replication/replicatemanager:
interfaces:
ChannelReplicator:
github.com/milvus-io/milvus/internal/cdc/controller:
interfaces:
Controller:

View File

@ -1,51 +0,0 @@
// Licensed to the LF AI & Data foundation under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cluster
import (
"context"
"go.uber.org/zap"
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
"github.com/milvus-io/milvus/client/v2/milvusclient"
"github.com/milvus-io/milvus/pkg/v2/log"
)
type ClusterClient interface {
CreateMilvusClient(ctx context.Context, cluster *commonpb.MilvusCluster) (MilvusClient, error)
}
var _ ClusterClient = (*clusterClient)(nil)
type clusterClient struct{}
func NewClusterClient() ClusterClient {
return &clusterClient{}
}
func (c *clusterClient) CreateMilvusClient(ctx context.Context, cluster *commonpb.MilvusCluster) (MilvusClient, error) {
cli, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: cluster.GetConnectionParam().GetUri(),
APIKey: cluster.GetConnectionParam().GetToken(),
})
if err != nil {
log.Warn("failed to create milvus client", zap.Error(err))
return nil, err
}
return cli, nil
}

View File

@ -19,16 +19,32 @@ package cluster
import (
"context"
"github.com/cockroachdb/errors"
"google.golang.org/grpc"
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
"github.com/milvus-io/milvus/client/v2/milvusclient"
)
type MilvusClient interface {
// GetReplicateInfo gets the replicate information from the milvus cluster.
GetReplicateInfo(ctx context.Context, sourceClusterID string, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)
GetReplicateInfo(ctx context.Context, req *milvuspb.GetReplicateInfoRequest, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)
// CreateReplicateStream creates a replicate stream to the milvus cluster.
CreateReplicateStream(ctx context.Context, opts ...grpc.CallOption) (milvuspb.MilvusService_CreateReplicateStreamClient, error)
// Close closes the milvus client.
Close(ctx context.Context) error
}
type CreateMilvusClientFunc func(ctx context.Context, cluster *commonpb.MilvusCluster) (MilvusClient, error)
func NewMilvusClient(ctx context.Context, cluster *commonpb.MilvusCluster) (MilvusClient, error) {
cli, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: cluster.GetConnectionParam().GetUri(),
APIKey: cluster.GetConnectionParam().GetToken(),
})
if err != nil {
return nil, errors.Wrap(err, "failed to create milvus client")
}
return cli, nil
}

View File

@ -1,97 +0,0 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package cluster
import (
context "context"
commonpb "github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
mock "github.com/stretchr/testify/mock"
)
// MockClusterClient is an autogenerated mock type for the ClusterClient type
type MockClusterClient struct {
mock.Mock
}
type MockClusterClient_Expecter struct {
mock *mock.Mock
}
func (_m *MockClusterClient) EXPECT() *MockClusterClient_Expecter {
return &MockClusterClient_Expecter{mock: &_m.Mock}
}
// CreateMilvusClient provides a mock function with given fields: ctx, _a1
func (_m *MockClusterClient) CreateMilvusClient(ctx context.Context, _a1 *commonpb.MilvusCluster) (MilvusClient, error) {
ret := _m.Called(ctx, _a1)
if len(ret) == 0 {
panic("no return value specified for CreateMilvusClient")
}
var r0 MilvusClient
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *commonpb.MilvusCluster) (MilvusClient, error)); ok {
return rf(ctx, _a1)
}
if rf, ok := ret.Get(0).(func(context.Context, *commonpb.MilvusCluster) MilvusClient); ok {
r0 = rf(ctx, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(MilvusClient)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *commonpb.MilvusCluster) error); ok {
r1 = rf(ctx, _a1)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockClusterClient_CreateMilvusClient_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateMilvusClient'
type MockClusterClient_CreateMilvusClient_Call struct {
*mock.Call
}
// CreateMilvusClient is a helper method to define mock.On call
// - ctx context.Context
// - _a1 *commonpb.MilvusCluster
func (_e *MockClusterClient_Expecter) CreateMilvusClient(ctx interface{}, _a1 interface{}) *MockClusterClient_CreateMilvusClient_Call {
return &MockClusterClient_CreateMilvusClient_Call{Call: _e.mock.On("CreateMilvusClient", ctx, _a1)}
}
func (_c *MockClusterClient_CreateMilvusClient_Call) Run(run func(ctx context.Context, _a1 *commonpb.MilvusCluster)) *MockClusterClient_CreateMilvusClient_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*commonpb.MilvusCluster))
})
return _c
}
func (_c *MockClusterClient_CreateMilvusClient_Call) Return(_a0 MilvusClient, _a1 error) *MockClusterClient_CreateMilvusClient_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockClusterClient_CreateMilvusClient_Call) RunAndReturn(run func(context.Context, *commonpb.MilvusCluster) (MilvusClient, error)) *MockClusterClient_CreateMilvusClient_Call {
_c.Call.Return(run)
return _c
}
// NewMockClusterClient creates a new instance of MockClusterClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockClusterClient(t interface {
mock.TestingT
Cleanup(func())
}) *MockClusterClient {
mock := &MockClusterClient{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -144,14 +144,14 @@ func (_c *MockMilvusClient_CreateReplicateStream_Call) RunAndReturn(run func(con
return _c
}
// GetReplicateInfo provides a mock function with given fields: ctx, sourceClusterID, opts
func (_m *MockMilvusClient) GetReplicateInfo(ctx context.Context, sourceClusterID string, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error) {
// GetReplicateInfo provides a mock function with given fields: ctx, req, opts
func (_m *MockMilvusClient) GetReplicateInfo(ctx context.Context, req *milvuspb.GetReplicateInfoRequest, opts ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, sourceClusterID)
_ca = append(_ca, ctx, req)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
@ -161,19 +161,19 @@ func (_m *MockMilvusClient) GetReplicateInfo(ctx context.Context, sourceClusterI
var r0 *milvuspb.GetReplicateInfoResponse
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)); ok {
return rf(ctx, sourceClusterID, opts...)
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.GetReplicateInfoRequest, ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)); ok {
return rf(ctx, req, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, string, ...grpc.CallOption) *milvuspb.GetReplicateInfoResponse); ok {
r0 = rf(ctx, sourceClusterID, opts...)
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.GetReplicateInfoRequest, ...grpc.CallOption) *milvuspb.GetReplicateInfoResponse); ok {
r0 = rf(ctx, req, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*milvuspb.GetReplicateInfoResponse)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, ...grpc.CallOption) error); ok {
r1 = rf(ctx, sourceClusterID, opts...)
if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.GetReplicateInfoRequest, ...grpc.CallOption) error); ok {
r1 = rf(ctx, req, opts...)
} else {
r1 = ret.Error(1)
}
@ -188,14 +188,14 @@ type MockMilvusClient_GetReplicateInfo_Call struct {
// GetReplicateInfo is a helper method to define mock.On call
// - ctx context.Context
// - sourceClusterID string
// - req *milvuspb.GetReplicateInfoRequest
// - opts ...grpc.CallOption
func (_e *MockMilvusClient_Expecter) GetReplicateInfo(ctx interface{}, sourceClusterID interface{}, opts ...interface{}) *MockMilvusClient_GetReplicateInfo_Call {
func (_e *MockMilvusClient_Expecter) GetReplicateInfo(ctx interface{}, req interface{}, opts ...interface{}) *MockMilvusClient_GetReplicateInfo_Call {
return &MockMilvusClient_GetReplicateInfo_Call{Call: _e.mock.On("GetReplicateInfo",
append([]interface{}{ctx, sourceClusterID}, opts...)...)}
append([]interface{}{ctx, req}, opts...)...)}
}
func (_c *MockMilvusClient_GetReplicateInfo_Call) Run(run func(ctx context.Context, sourceClusterID string, opts ...grpc.CallOption)) *MockMilvusClient_GetReplicateInfo_Call {
func (_c *MockMilvusClient_GetReplicateInfo_Call) Run(run func(ctx context.Context, req *milvuspb.GetReplicateInfoRequest, opts ...grpc.CallOption)) *MockMilvusClient_GetReplicateInfo_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
@ -203,7 +203,7 @@ func (_c *MockMilvusClient_GetReplicateInfo_Call) Run(run func(ctx context.Conte
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(string), variadicArgs...)
run(args[0].(context.Context), args[1].(*milvuspb.GetReplicateInfoRequest), variadicArgs...)
})
return _c
}
@ -213,7 +213,7 @@ func (_c *MockMilvusClient_GetReplicateInfo_Call) Return(_a0 *milvuspb.GetReplic
return _c
}
func (_c *MockMilvusClient_GetReplicateInfo_Call) RunAndReturn(run func(context.Context, string, ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)) *MockMilvusClient_GetReplicateInfo_Call {
func (_c *MockMilvusClient_GetReplicateInfo_Call) RunAndReturn(run func(context.Context, *milvuspb.GetReplicateInfoRequest, ...grpc.CallOption) (*milvuspb.GetReplicateInfoResponse, error)) *MockMilvusClient_GetReplicateInfo_Call {
_c.Call.Return(run)
return _c
}

View File

@ -16,9 +16,159 @@
package controller
import (
"context"
"path"
"strings"
"sync"
"go.etcd.io/etcd/api/v3/mvccpb"
clientv3 "go.etcd.io/etcd/client/v3"
"go.uber.org/zap"
"github.com/milvus-io/milvus/internal/cdc/meta"
"github.com/milvus-io/milvus/internal/cdc/resource"
"github.com/milvus-io/milvus/internal/metastore/kv/streamingcoord"
"github.com/milvus-io/milvus/pkg/v2/log"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
)
// Controller controls and schedules the CDC process.
// It will periodically update the replications by the replicate configuration.
type Controller interface {
Start()
Start() error
Stop()
}
type controller struct {
ctx context.Context
cancel context.CancelFunc
wg sync.WaitGroup
prefix string
}
func NewController() *controller {
ctx, cancel := context.WithCancel(context.Background())
return &controller{
ctx: ctx,
cancel: cancel,
prefix: path.Join(
paramtable.Get().EtcdCfg.MetaRootPath.GetValue(),
streamingcoord.ReplicatePChannelMetaPrefix,
),
}
}
func (c *controller) Start() error {
c.startWatchLoop()
return nil
}
func (c *controller) recoverReplicatePChannelMeta(channels []*meta.ReplicateChannel) {
currentClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
for _, channelMeta := range channels {
if !strings.Contains(channelMeta.Value.GetSourceChannelName(), currentClusterID) {
// current cluster is not source cluster, skip create replicator
continue
}
log.Info("recover replicate pchannel meta",
zap.String("key", channelMeta.Key),
zap.Int64("revision", channelMeta.ModRevision),
)
channel := &meta.ReplicateChannel{
Key: channelMeta.Key,
Value: channelMeta.Value,
ModRevision: channelMeta.ModRevision,
}
resource.Resource().ReplicateManagerClient().CreateReplicator(channel)
}
resource.Resource().ReplicateManagerClient().RemoveOutdatedReplicators(channels)
}
func (c *controller) watchEvents(revision int64) clientv3.WatchChan {
eventCh := resource.Resource().ETCD().Watch(
c.ctx,
c.prefix,
clientv3.WithPrefix(),
clientv3.WithPrevKV(),
clientv3.WithRev(revision),
)
log.Ctx(c.ctx).Info("succeed to watch replicate pchannel meta events",
zap.Int64("revision", revision), zap.String("prefix", c.prefix))
return eventCh
}
func (c *controller) startWatchLoop() {
c.wg.Add(1)
go func() {
defer c.wg.Done()
for {
m, err := meta.ListReplicatePChannels(c.ctx, resource.Resource().ETCD(), c.prefix)
if err != nil && c.ctx.Err() == nil {
log.Ctx(c.ctx).Warn("failed to list replicate pchannels", zap.Error(err))
continue
}
c.recoverReplicatePChannelMeta(m.Channels)
eventCh := c.watchEvents(m.Revision + 1)
err = c.watchLoop(eventCh)
if err == nil {
break
}
}
}()
}
func (c *controller) watchLoop(eventCh clientv3.WatchChan) error {
for {
select {
case <-c.ctx.Done():
return nil
case event, ok := <-eventCh:
if !ok {
panic("etcd event channel closed")
}
if err := event.Err(); err != nil {
log.Warn("etcd event error", zap.Error(err))
return err
}
for _, e := range event.Events {
switch e.Type {
case mvccpb.PUT:
log.Info("handle replicate pchannel PUT event",
zap.String("key", string(e.Kv.Key)),
zap.Int64("modRevision", e.Kv.ModRevision),
)
currentClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
replicate := meta.MustParseReplicateChannelFromEvent(e)
if !strings.Contains(replicate.GetSourceChannelName(), currentClusterID) {
// current cluster is not source cluster, skip create replicator
continue
}
channel := &meta.ReplicateChannel{
Key: string(e.Kv.Key),
Value: replicate,
ModRevision: e.Kv.ModRevision,
}
resource.Resource().ReplicateManagerClient().CreateReplicator(channel)
case mvccpb.DELETE:
log.Info("handle replicate pchannel DELETE event",
zap.String("key", string(e.Kv.Key)),
zap.Int64("prevModRevision", e.PrevKv.ModRevision),
)
key := string(e.Kv.Key)
revision := e.PrevKv.ModRevision
resource.Resource().ReplicateManagerClient().RemoveReplicator(key, revision)
}
}
}
}
}
func (c *controller) Stop() {
log.Ctx(c.ctx).Info("stop CDC controller...")
c.cancel()
c.wg.Wait()
resource.Resource().ReplicateManagerClient().Close()
log.Ctx(c.ctx).Info("CDC controller stopped")
}

View File

@ -0,0 +1,104 @@
// Licensed to the LF AI & Data foundation under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package controller
import (
"testing"
"time"
"github.com/stretchr/testify/mock"
"go.etcd.io/etcd/api/v3/mvccpb"
clientv3 "go.etcd.io/etcd/client/v3"
"google.golang.org/protobuf/proto"
"github.com/milvus-io/milvus/internal/cdc/meta"
"github.com/milvus-io/milvus/internal/cdc/replication"
"github.com/milvus-io/milvus/internal/cdc/resource"
"github.com/milvus-io/milvus/internal/metastore/kv/streamingcoord"
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
)
func TestController_StartAndStop_WithEvents(t *testing.T) {
mockReplicateManagerClient := replication.NewMockReplicateManagerClient(t)
mockReplicateManagerClient.EXPECT().Close().Return()
// Create test data
replicateMeta := &streamingpb.ReplicatePChannelMeta{
SourceChannelName: "by-dev-test-source-channel",
TargetChannelName: "by-dev-test-target-channel",
}
metaBytes, _ := proto.Marshal(replicateMeta)
// Create mock events
putEvent := &clientv3.Event{
Type: mvccpb.PUT,
Kv: &mvccpb.KeyValue{
Key: []byte(streamingcoord.BuildReplicatePChannelMetaKey(replicateMeta)),
Value: metaBytes,
},
}
deleteEvent := &clientv3.Event{
Type: mvccpb.DELETE,
Kv: &mvccpb.KeyValue{
Key: []byte(streamingcoord.BuildReplicatePChannelMetaKey(replicateMeta)),
},
PrevKv: &mvccpb.KeyValue{
Value: metaBytes,
},
}
eventCh := make(chan clientv3.WatchResponse, 2)
// Send events
go func() {
eventCh <- clientv3.WatchResponse{
Events: []*clientv3.Event{putEvent},
}
eventCh <- clientv3.WatchResponse{
Events: []*clientv3.Event{deleteEvent},
}
}()
notifyCh := make(chan struct{}, 2)
mockReplicateManagerClient.EXPECT().CreateReplicator(mock.Anything).RunAndReturn(func(replicate *meta.ReplicateChannel) {
notifyCh <- struct{}{}
})
mockReplicateManagerClient.EXPECT().RemoveReplicator(mock.Anything, mock.Anything).RunAndReturn(func(key string, modRevision int64) {
notifyCh <- struct{}{}
})
resource.InitForTest(t,
resource.OptReplicateManagerClient(mockReplicateManagerClient),
)
ctrl := NewController()
go ctrl.watchLoop(eventCh)
// Wait for put event to be processed
select {
case <-notifyCh:
case <-time.After(10 * time.Second):
t.Fatal("timeout waiting for put event")
}
// Wait for delete event to be processed
select {
case <-notifyCh:
case <-time.After(10 * time.Second):
t.Fatal("timeout waiting for delete event")
}
ctrl.Stop()
}

View File

@ -1,87 +0,0 @@
// Licensed to the LF AI & Data foundation under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package controllerimpl
import (
"context"
"sync"
"time"
"go.uber.org/zap"
"github.com/milvus-io/milvus/internal/cdc/resource"
"github.com/milvus-io/milvus/pkg/v2/log"
)
const checkInterval = 10 * time.Second
type controller struct {
ctx context.Context
wg sync.WaitGroup
stopOnce sync.Once
stopChan chan struct{}
}
func NewController() *controller {
return &controller{
ctx: context.Background(),
stopChan: make(chan struct{}),
}
}
func (c *controller) Start() {
log.Ctx(c.ctx).Info("CDC controller started")
c.wg.Add(1)
go func() {
defer c.wg.Done()
timer := time.NewTicker(checkInterval)
defer timer.Stop()
for {
select {
case <-c.stopChan:
return
case <-timer.C:
c.run()
}
}
}()
}
func (c *controller) Stop() {
c.stopOnce.Do(func() {
log.Ctx(c.ctx).Info("CDC controller stopping...")
close(c.stopChan)
c.wg.Wait()
resource.Resource().ReplicateManagerClient().Close()
log.Ctx(c.ctx).Info("CDC controller stopped")
})
}
func (c *controller) run() {
targetReplicatePChannels, err := resource.Resource().ReplicationCatalog().ListReplicatePChannels(c.ctx)
if err != nil {
log.Ctx(c.ctx).Error("failed to get replicate pchannels", zap.Error(err))
return
}
// create replicators for all replicate pchannels
for _, replicatePChannel := range targetReplicatePChannels {
resource.Resource().ReplicateManagerClient().CreateReplicator(replicatePChannel)
}
// remove out of target replicators
resource.Resource().ReplicateManagerClient().RemoveOutOfTargetReplicators(targetReplicatePChannels)
}

View File

@ -1,87 +0,0 @@
// Licensed to the LF AI & Data foundation under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package controllerimpl
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/milvus-io/milvus/internal/cdc/replication"
"github.com/milvus-io/milvus/internal/cdc/resource"
"github.com/milvus-io/milvus/internal/mocks/mock_metastore"
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
)
func TestController_StartAndStop(t *testing.T) {
mockReplicateManagerClient := replication.NewMockReplicateManagerClient(t)
mockReplicateManagerClient.EXPECT().Close().Return()
resource.InitForTest(t,
resource.OptReplicateManagerClient(mockReplicateManagerClient),
)
ctrl := NewController()
assert.NotPanics(t, func() {
ctrl.Start()
})
assert.NotPanics(t, func() {
ctrl.Stop()
})
}
func TestController_Run(t *testing.T) {
mockReplicateManagerClient := replication.NewMockReplicateManagerClient(t)
mockReplicateManagerClient.EXPECT().Close().Return()
replicatePChannels := []*streamingpb.ReplicatePChannelMeta{
{
SourceChannelName: "test-source-channel-1",
TargetChannelName: "test-target-channel-1",
},
}
mockReplicationCatalog := mock_metastore.NewMockReplicationCatalog(t)
mockReplicationCatalog.EXPECT().ListReplicatePChannels(mock.Anything).Return(replicatePChannels, nil)
mockReplicateManagerClient.EXPECT().CreateReplicator(replicatePChannels[0]).Return()
mockReplicateManagerClient.EXPECT().RemoveOutOfTargetReplicators(replicatePChannels).Return()
resource.InitForTest(t,
resource.OptReplicateManagerClient(mockReplicateManagerClient),
resource.OptReplicationCatalog(mockReplicationCatalog),
)
ctrl := NewController()
ctrl.Start()
defer ctrl.Stop()
ctrl.run()
}
func TestController_RunError(t *testing.T) {
mockReplicateManagerClient := replication.NewMockReplicateManagerClient(t)
mockReplicateManagerClient.EXPECT().Close().Return()
mockReplicationCatalog := mock_metastore.NewMockReplicationCatalog(t)
mockReplicationCatalog.EXPECT().ListReplicatePChannels(mock.Anything).Return(nil, assert.AnError)
resource.InitForTest(t,
resource.OptReplicateManagerClient(mockReplicateManagerClient),
resource.OptReplicationCatalog(mockReplicationCatalog),
)
ctrl := NewController()
ctrl.Start()
defer ctrl.Stop()
ctrl.run()
}

View File

@ -1,96 +0,0 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
package controller
import mock "github.com/stretchr/testify/mock"
// MockController is an autogenerated mock type for the Controller type
type MockController struct {
mock.Mock
}
type MockController_Expecter struct {
mock *mock.Mock
}
func (_m *MockController) EXPECT() *MockController_Expecter {
return &MockController_Expecter{mock: &_m.Mock}
}
// Start provides a mock function with no fields
func (_m *MockController) Start() {
_m.Called()
}
// MockController_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start'
type MockController_Start_Call struct {
*mock.Call
}
// Start is a helper method to define mock.On call
func (_e *MockController_Expecter) Start() *MockController_Start_Call {
return &MockController_Start_Call{Call: _e.mock.On("Start")}
}
func (_c *MockController_Start_Call) Run(run func()) *MockController_Start_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockController_Start_Call) Return() *MockController_Start_Call {
_c.Call.Return()
return _c
}
func (_c *MockController_Start_Call) RunAndReturn(run func()) *MockController_Start_Call {
_c.Run(run)
return _c
}
// Stop provides a mock function with no fields
func (_m *MockController) Stop() {
_m.Called()
}
// MockController_Stop_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Stop'
type MockController_Stop_Call struct {
*mock.Call
}
// Stop is a helper method to define mock.On call
func (_e *MockController_Expecter) Stop() *MockController_Stop_Call {
return &MockController_Stop_Call{Call: _e.mock.On("Stop")}
}
func (_c *MockController_Stop_Call) Run(run func()) *MockController_Stop_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockController_Stop_Call) Return() *MockController_Stop_Call {
_c.Call.Return()
return _c
}
func (_c *MockController_Stop_Call) RunAndReturn(run func()) *MockController_Stop_Call {
_c.Run(run)
return _c
}
// NewMockController creates a new instance of MockController. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockController(t interface {
mock.TestingT
Cleanup(func())
}) *MockController {
mock := &MockController{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -0,0 +1,111 @@
package meta
import (
"context"
"fmt"
"time"
"github.com/cockroachdb/errors"
clientv3 "go.etcd.io/etcd/client/v3"
"google.golang.org/protobuf/proto"
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
)
const requestTimeout = 30 * time.Second
type ReplicateChannel struct {
Key string
Value *streamingpb.ReplicatePChannelMeta
ModRevision int64
}
type ReplicateChannels struct {
Channels []*ReplicateChannel
Revision int64
}
// ListReplicatePChannels lists the replicate pchannels metadata from metastore.
func ListReplicatePChannels(ctx context.Context, etcdCli *clientv3.Client, prefix string) (*ReplicateChannels, error) {
resp, err := listByPrefix(ctx, etcdCli, prefix)
if err != nil {
return nil, err
}
keys := make([]string, 0, resp.Count)
values := make([]string, 0, resp.Count)
revisions := make([]int64, 0, resp.Count)
for _, kv := range resp.Kvs {
keys = append(keys, string(kv.Key))
values = append(values, string(kv.Value))
revisions = append(revisions, kv.ModRevision)
}
channels := make([]*ReplicateChannel, 0, len(values))
for k, value := range values {
meta := &streamingpb.ReplicatePChannelMeta{}
err = proto.Unmarshal([]byte(value), meta)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal replicate pchannel meta %s failed", keys[k])
}
channel := &ReplicateChannel{
Key: keys[k],
Value: meta,
ModRevision: revisions[k],
}
channels = append(channels, channel)
}
return &ReplicateChannels{
Channels: channels,
Revision: resp.Header.Revision,
}, nil
}
// RemoveReplicatePChannelWithRevision removes the replicate pchannel from metastore.
// Remove the task of CDC replication task of current cluster, should be called when a CDC replication task is finished.
// Because CDC removes the replicate pchannel meta asynchronously, there may be ordering conflicts
// during primary-secondary switches. For example:
// 1. Init: A -> B, Save key
// 2. Switch: B -> A, Delete key asynchronously
// 3. Switch again: A -> B, Save key
// Expected meta op order: [Save, Delete, Save]
// Actual meta op may be: [Save, Save, Delete]
// To avoid ordering conflicts, we need to pass the keys revision
// and only remove the KV when the revision matches.
func RemoveReplicatePChannelWithRevision(ctx context.Context, etcdCli *clientv3.Client, key string, revision int64) (bool, error) {
result, err := removeWithCmps(ctx, etcdCli, key, clientv3.Compare(clientv3.ModRevision(key), "=", revision))
return result, err
}
func MustParseReplicateChannelFromEvent(e *clientv3.Event) *streamingpb.ReplicatePChannelMeta {
meta := &streamingpb.ReplicatePChannelMeta{}
err := proto.Unmarshal(e.Kv.Value, meta)
if err != nil {
panic(fmt.Sprintf("failed to unmarshal replicate pchannel meta: %v", err))
}
return meta
}
// listByPrefix gets the key-value pairs with the given prefix.
func listByPrefix(ctx context.Context, etcdCli *clientv3.Client, prefix string) (*clientv3.GetResponse, error) {
ctx1, cancel := context.WithTimeout(ctx, requestTimeout)
defer cancel()
opts := []clientv3.OpOption{
clientv3.WithPrefix(),
clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend),
}
return etcdCli.Get(ctx1, prefix, opts...)
}
// removeWithCmps removes the key with given cmps.
func removeWithCmps(ctx context.Context, etcdCli *clientv3.Client, key string, cmps ...clientv3.Cmp) (bool, error) {
ctx, cancel := context.WithTimeout(ctx, requestTimeout)
defer cancel()
delOp := clientv3.OpDelete(key)
txn := etcdCli.Txn(ctx).If(cmps...).Then(delOp)
resp, err := txn.Commit()
if err != nil {
return false, err
}
return resp.Succeeded, nil
}

View File

@ -3,7 +3,7 @@
package replication
import (
streamingpb "github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
meta "github.com/milvus-io/milvus/internal/cdc/meta"
mock "github.com/stretchr/testify/mock"
)
@ -52,9 +52,9 @@ func (_c *MockReplicateManagerClient_Close_Call) RunAndReturn(run func()) *MockR
return _c
}
// CreateReplicator provides a mock function with given fields: replicateInfo
func (_m *MockReplicateManagerClient) CreateReplicator(replicateInfo *streamingpb.ReplicatePChannelMeta) {
_m.Called(replicateInfo)
// CreateReplicator provides a mock function with given fields: channel
func (_m *MockReplicateManagerClient) CreateReplicator(channel *meta.ReplicateChannel) {
_m.Called(channel)
}
// MockReplicateManagerClient_CreateReplicator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateReplicator'
@ -63,14 +63,14 @@ type MockReplicateManagerClient_CreateReplicator_Call struct {
}
// CreateReplicator is a helper method to define mock.On call
// - replicateInfo *streamingpb.ReplicatePChannelMeta
func (_e *MockReplicateManagerClient_Expecter) CreateReplicator(replicateInfo interface{}) *MockReplicateManagerClient_CreateReplicator_Call {
return &MockReplicateManagerClient_CreateReplicator_Call{Call: _e.mock.On("CreateReplicator", replicateInfo)}
// - channel *meta.ReplicateChannel
func (_e *MockReplicateManagerClient_Expecter) CreateReplicator(channel interface{}) *MockReplicateManagerClient_CreateReplicator_Call {
return &MockReplicateManagerClient_CreateReplicator_Call{Call: _e.mock.On("CreateReplicator", channel)}
}
func (_c *MockReplicateManagerClient_CreateReplicator_Call) Run(run func(replicateInfo *streamingpb.ReplicatePChannelMeta)) *MockReplicateManagerClient_CreateReplicator_Call {
func (_c *MockReplicateManagerClient_CreateReplicator_Call) Run(run func(channel *meta.ReplicateChannel)) *MockReplicateManagerClient_CreateReplicator_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*streamingpb.ReplicatePChannelMeta))
run(args[0].(*meta.ReplicateChannel))
})
return _c
}
@ -80,40 +80,74 @@ func (_c *MockReplicateManagerClient_CreateReplicator_Call) Return() *MockReplic
return _c
}
func (_c *MockReplicateManagerClient_CreateReplicator_Call) RunAndReturn(run func(*streamingpb.ReplicatePChannelMeta)) *MockReplicateManagerClient_CreateReplicator_Call {
func (_c *MockReplicateManagerClient_CreateReplicator_Call) RunAndReturn(run func(*meta.ReplicateChannel)) *MockReplicateManagerClient_CreateReplicator_Call {
_c.Run(run)
return _c
}
// RemoveOutOfTargetReplicators provides a mock function with given fields: targetReplicatePChannels
func (_m *MockReplicateManagerClient) RemoveOutOfTargetReplicators(targetReplicatePChannels []*streamingpb.ReplicatePChannelMeta) {
_m.Called(targetReplicatePChannels)
// RemoveOutdatedReplicators provides a mock function with given fields: aliveChannels
func (_m *MockReplicateManagerClient) RemoveOutdatedReplicators(aliveChannels []*meta.ReplicateChannel) {
_m.Called(aliveChannels)
}
// MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveOutOfTargetReplicators'
type MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call struct {
// MockReplicateManagerClient_RemoveOutdatedReplicators_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveOutdatedReplicators'
type MockReplicateManagerClient_RemoveOutdatedReplicators_Call struct {
*mock.Call
}
// RemoveOutOfTargetReplicators is a helper method to define mock.On call
// - targetReplicatePChannels []*streamingpb.ReplicatePChannelMeta
func (_e *MockReplicateManagerClient_Expecter) RemoveOutOfTargetReplicators(targetReplicatePChannels interface{}) *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call {
return &MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call{Call: _e.mock.On("RemoveOutOfTargetReplicators", targetReplicatePChannels)}
// RemoveOutdatedReplicators is a helper method to define mock.On call
// - aliveChannels []*meta.ReplicateChannel
func (_e *MockReplicateManagerClient_Expecter) RemoveOutdatedReplicators(aliveChannels interface{}) *MockReplicateManagerClient_RemoveOutdatedReplicators_Call {
return &MockReplicateManagerClient_RemoveOutdatedReplicators_Call{Call: _e.mock.On("RemoveOutdatedReplicators", aliveChannels)}
}
func (_c *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call) Run(run func(targetReplicatePChannels []*streamingpb.ReplicatePChannelMeta)) *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call {
func (_c *MockReplicateManagerClient_RemoveOutdatedReplicators_Call) Run(run func(aliveChannels []*meta.ReplicateChannel)) *MockReplicateManagerClient_RemoveOutdatedReplicators_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].([]*streamingpb.ReplicatePChannelMeta))
run(args[0].([]*meta.ReplicateChannel))
})
return _c
}
func (_c *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call) Return() *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call {
func (_c *MockReplicateManagerClient_RemoveOutdatedReplicators_Call) Return() *MockReplicateManagerClient_RemoveOutdatedReplicators_Call {
_c.Call.Return()
return _c
}
func (_c *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call) RunAndReturn(run func([]*streamingpb.ReplicatePChannelMeta)) *MockReplicateManagerClient_RemoveOutOfTargetReplicators_Call {
func (_c *MockReplicateManagerClient_RemoveOutdatedReplicators_Call) RunAndReturn(run func([]*meta.ReplicateChannel)) *MockReplicateManagerClient_RemoveOutdatedReplicators_Call {
_c.Run(run)
return _c
}
// RemoveReplicator provides a mock function with given fields: key, modRevision
func (_m *MockReplicateManagerClient) RemoveReplicator(key string, modRevision int64) {
_m.Called(key, modRevision)
}
// MockReplicateManagerClient_RemoveReplicator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveReplicator'
type MockReplicateManagerClient_RemoveReplicator_Call struct {
*mock.Call
}
// RemoveReplicator is a helper method to define mock.On call
// - key string
// - modRevision int64
func (_e *MockReplicateManagerClient_Expecter) RemoveReplicator(key interface{}, modRevision interface{}) *MockReplicateManagerClient_RemoveReplicator_Call {
return &MockReplicateManagerClient_RemoveReplicator_Call{Call: _e.mock.On("RemoveReplicator", key, modRevision)}
}
func (_c *MockReplicateManagerClient_RemoveReplicator_Call) Run(run func(key string, modRevision int64)) *MockReplicateManagerClient_RemoveReplicator_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(int64))
})
return _c
}
func (_c *MockReplicateManagerClient_RemoveReplicator_Call) Return() *MockReplicateManagerClient_RemoveReplicator_Call {
_c.Call.Return()
return _c
}
func (_c *MockReplicateManagerClient_RemoveReplicator_Call) RunAndReturn(run func(string, int64)) *MockReplicateManagerClient_RemoveReplicator_Call {
_c.Run(run)
return _c
}

View File

@ -16,15 +16,18 @@
package replication
import "github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
import "github.com/milvus-io/milvus/internal/cdc/meta"
// ReplicateManagerClient is the client that manages the replicate configuration.
type ReplicateManagerClient interface {
// CreateReplicator creates a new replicator for the replicate pchannel.
CreateReplicator(replicateInfo *streamingpb.ReplicatePChannelMeta)
CreateReplicator(channel *meta.ReplicateChannel)
// RemoveOutOfTargetReplicators removes replicators that are not in the target replicate pchannels.
RemoveOutOfTargetReplicators(targetReplicatePChannels []*streamingpb.ReplicatePChannelMeta)
// RemoveReplicator removes a replicator for the replicate pchannel.
RemoveReplicator(key string, modRevision int64)
// RemoveOutdatedReplicators removes the outdated replicators.
RemoveOutdatedReplicators(aliveChannels []*meta.ReplicateChannel)
// Close closes the replicate manager client.
Close()

View File

@ -21,162 +21,181 @@ import (
"fmt"
"time"
"github.com/cockroachdb/errors"
"go.uber.org/zap"
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
"github.com/milvus-io/milvus/internal/cdc/cluster"
"github.com/milvus-io/milvus/internal/cdc/meta"
"github.com/milvus-io/milvus/internal/cdc/replication/replicatestream"
"github.com/milvus-io/milvus/internal/cdc/resource"
"github.com/milvus-io/milvus/internal/cdc/util"
"github.com/milvus-io/milvus/internal/distributed/streaming"
"github.com/milvus-io/milvus/internal/streamingnode/server/wal/utility"
"github.com/milvus-io/milvus/pkg/v2/log"
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message/adaptor"
"github.com/milvus-io/milvus/pkg/v2/streaming/util/options"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
"github.com/milvus-io/milvus/pkg/v2/util/syncutil"
)
const scannerHandlerChanSize = 64
// Replicator is the client that replicates the message to the channel in the target cluster.
type Replicator interface {
// StartReplicate starts the replicate for the channel.
StartReplicate()
// StartReplication starts the replicate for the channel.
StartReplication()
// StopReplicate stops the replicate loop
// StopReplication stops the replicate loop
// and wait for the loop to exit.
StopReplicate()
// GetState returns the current state of the replicator.
GetState() typeutil.LifetimeState
StopReplication()
}
var _ Replicator = (*channelReplicator)(nil)
// channelReplicator is the implementation of ChannelReplicator.
type channelReplicator struct {
replicateInfo *streamingpb.ReplicatePChannelMeta
channel *meta.ReplicateChannel
createRscFunc replicatestream.CreateReplicateStreamClientFunc
createMcFunc cluster.CreateMilvusClientFunc
targetClient cluster.MilvusClient
streamClient replicatestream.ReplicateStreamClient
msgScanner streaming.Scanner
msgChan adaptor.ChanMessageHandler
ctx context.Context
cancel context.CancelFunc
lifetime *typeutil.Lifetime
asyncNotifier *syncutil.AsyncTaskNotifier[struct{}]
}
// NewChannelReplicator creates a new ChannelReplicator.
func NewChannelReplicator(replicateMeta *streamingpb.ReplicatePChannelMeta) Replicator {
ctx, cancel := context.WithCancel(context.Background())
func NewChannelReplicator(channel *meta.ReplicateChannel) Replicator {
createRscFunc := replicatestream.NewReplicateStreamClient
return &channelReplicator{
replicateInfo: replicateMeta,
channel: channel,
createRscFunc: createRscFunc,
ctx: ctx,
cancel: cancel,
lifetime: typeutil.NewLifetime(),
createMcFunc: cluster.NewMilvusClient,
asyncNotifier: syncutil.NewAsyncTaskNotifier[struct{}](),
}
}
func (r *channelReplicator) StartReplicate() {
logger := log.With(
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
)
if !r.lifetime.Add(typeutil.LifetimeStateWorking) {
logger.Warn("replicate channel already started")
return
}
func (r *channelReplicator) StartReplication() {
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("modRevision", r.channel.ModRevision))
logger.Info("start replicate channel")
go func() {
defer r.lifetime.Done()
for {
err := r.replicateLoop()
if err != nil {
logger.Warn("replicate channel failed", zap.Error(err))
time.Sleep(10 * time.Second)
continue
defer func() {
if r.streamClient != nil {
r.streamClient.Close()
}
if r.msgScanner != nil {
r.msgScanner.Close()
}
if r.targetClient != nil {
r.targetClient.Close(r.asyncNotifier.Context())
}
r.asyncNotifier.Finish(struct{}{})
}()
INIT_LOOP:
for {
select {
case <-r.asyncNotifier.Context().Done():
return
default:
err := r.init()
if err != nil {
logger.Warn("initialize replicator failed", zap.Error(err))
continue
}
break INIT_LOOP
}
break
}
logger.Info("stop replicate channel")
r.startConsumeLoop()
}()
}
// replicateLoop starts the replicate loop.
func (r *channelReplicator) replicateLoop() error {
logger := log.With(
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
)
cp, err := r.getReplicateCheckpoint()
if err != nil {
return err
func (r *channelReplicator) init() error {
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("modRevision", r.channel.ModRevision))
// init target client
if r.targetClient == nil {
dialCtx, dialCancel := context.WithTimeout(r.asyncNotifier.Context(), 30*time.Second)
defer dialCancel()
milvusClient, err := r.createMcFunc(dialCtx, r.channel.Value.GetTargetCluster())
if err != nil {
return err
}
r.targetClient = milvusClient
logger.Info("target client initialized")
}
ch := make(adaptor.ChanMessageHandler, scannerHandlerChanSize)
scanner := streaming.WAL().Read(r.ctx, streaming.ReadOption{
PChannel: r.replicateInfo.GetSourceChannelName(),
DeliverPolicy: options.DeliverPolicyStartFrom(cp.MessageID),
DeliverFilters: []options.DeliverFilter{options.DeliverFilterTimeTickGT(cp.TimeTick)},
MessageHandler: ch,
})
defer scanner.Close()
// init msg scanner
if r.msgScanner == nil {
cp, err := r.getReplicateCheckpoint()
if err != nil {
return err
}
ch := make(adaptor.ChanMessageHandler)
scanner := streaming.WAL().Read(r.asyncNotifier.Context(), streaming.ReadOption{
PChannel: r.channel.Value.GetSourceChannelName(),
DeliverPolicy: options.DeliverPolicyStartFrom(cp.MessageID),
DeliverFilters: []options.DeliverFilter{options.DeliverFilterTimeTickGT(cp.TimeTick)},
MessageHandler: ch,
})
r.msgScanner = scanner
r.msgChan = ch
logger.Info("scanner initialized", zap.Any("checkpoint", cp))
}
// init replicate stream client
if r.streamClient == nil {
r.streamClient = r.createRscFunc(r.asyncNotifier.Context(), r.targetClient, r.channel)
logger.Info("stream client initialized")
}
return nil
}
rsc := r.createRscFunc(r.ctx, r.replicateInfo)
defer rsc.Close()
logger.Info("start replicate channel loop", zap.Any("startFrom", cp))
// startConsumeLoop starts the replicate loop.
func (r *channelReplicator) startConsumeLoop() {
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("modRevision", r.channel.ModRevision))
logger.Info("start consume loop")
for {
select {
case <-r.ctx.Done():
logger.Info("replicate channel stopped")
return nil
case msg := <-ch:
// TODO: Should be done at streamingnode.
if msg.MessageType().IsSelfControlled() {
if msg.MessageType() != message.MessageTypeTimeTick {
logger.Debug("skip self-controlled message", log.FieldMessage(msg))
case <-r.asyncNotifier.Context().Done():
logger.Info("consume loop stopped")
return
case msg := <-r.msgChan:
err := r.streamClient.Replicate(msg)
if err != nil {
if !errors.Is(err, replicatestream.ErrReplicateIgnored) {
panic(fmt.Sprintf("replicate message failed due to unrecoverable error: %v", err))
}
continue
}
err := rsc.Replicate(msg)
if err != nil {
panic(fmt.Sprintf("replicate message failed due to unrecoverable error: %v", err))
}
logger.Debug("replicate message success", log.FieldMessage(msg))
if msg.MessageType() == message.MessageTypeAlterReplicateConfig {
if util.IsReplicationRemovedByAlterReplicateConfigMessage(msg, r.channel.Value) {
logger.Info("replication removed, stop consume loop")
r.streamClient.BlockUntilFinish()
return
}
}
}
}
}
func (r *channelReplicator) getReplicateCheckpoint() (*utility.ReplicateCheckpoint, error) {
logger := log.With(
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
)
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("modRevision", r.channel.ModRevision))
ctx, cancel := context.WithTimeout(r.ctx, 30*time.Second)
ctx, cancel := context.WithTimeout(r.asyncNotifier.Context(), 30*time.Second)
defer cancel()
milvusClient, err := resource.Resource().ClusterClient().CreateMilvusClient(ctx, r.replicateInfo.GetTargetCluster())
if err != nil {
return nil, err
}
defer milvusClient.Close(ctx)
sourceClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
replicateInfo, err := milvusClient.GetReplicateInfo(ctx, sourceClusterID)
req := &milvuspb.GetReplicateInfoRequest{
SourceClusterId: sourceClusterID,
TargetPchannel: r.channel.Value.GetTargetChannelName(),
}
replicateInfo, err := r.targetClient.GetReplicateInfo(ctx, req)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "failed to get replicate info")
}
var checkpoint *commonpb.ReplicateCheckpoint
for _, cp := range replicateInfo.GetCheckpoints() {
if cp.GetPchannel() == r.replicateInfo.GetSourceChannelName() {
checkpoint = cp
break
}
}
checkpoint := replicateInfo.GetCheckpoint()
if checkpoint == nil || checkpoint.MessageId == nil {
initializedCheckpoint := utility.NewReplicateCheckpointFromProto(r.replicateInfo.InitializedCheckpoint)
initializedCheckpoint := utility.NewReplicateCheckpointFromProto(r.channel.Value.InitializedCheckpoint)
logger.Info("channel not found in replicate info, will start from the beginning",
zap.Stringer("messageID", initializedCheckpoint.MessageID),
zap.Uint64("timeTick", initializedCheckpoint.TimeTick),
@ -192,12 +211,7 @@ func (r *channelReplicator) getReplicateCheckpoint() (*utility.ReplicateCheckpoi
return cp, nil
}
func (r *channelReplicator) StopReplicate() {
r.lifetime.SetState(typeutil.LifetimeStateStopped)
r.cancel()
r.lifetime.Wait()
}
func (r *channelReplicator) GetState() typeutil.LifetimeState {
return r.lifetime.GetState()
func (r *channelReplicator) StopReplication() {
r.asyncNotifier.Cancel()
r.asyncNotifier.BlockUntilFinish()
}

View File

@ -19,6 +19,7 @@ package replicatemanager
import (
"context"
"testing"
"time"
"github.com/apache/pulsar-client-go/pulsar"
"github.com/stretchr/testify/assert"
@ -27,13 +28,12 @@ import (
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
"github.com/milvus-io/milvus/internal/cdc/cluster"
"github.com/milvus-io/milvus/internal/cdc/meta"
"github.com/milvus-io/milvus/internal/cdc/replication/replicatestream"
"github.com/milvus-io/milvus/internal/cdc/resource"
"github.com/milvus-io/milvus/internal/distributed/streaming"
"github.com/milvus-io/milvus/internal/mocks/distributed/mock_streaming"
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
pulsar2 "github.com/milvus-io/milvus/pkg/v2/streaming/walimpls/impls/pulsar"
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
)
func newMockPulsarMessageID() *commonpb.MessageID {
@ -49,22 +49,13 @@ func TestChannelReplicator_StartReplicateChannel(t *testing.T) {
mockMilvusClient := cluster.NewMockMilvusClient(t)
mockMilvusClient.EXPECT().GetReplicateInfo(mock.Anything, mock.Anything).
Return(&milvuspb.GetReplicateInfoResponse{
Checkpoints: []*commonpb.ReplicateCheckpoint{
{
Pchannel: "test-source-channel",
MessageId: newMockPulsarMessageID(),
},
Checkpoint: &commonpb.ReplicateCheckpoint{
Pchannel: "test-source-channel",
MessageId: newMockPulsarMessageID(),
},
}, nil)
mockMilvusClient.EXPECT().Close(mock.Anything).Return(nil)
mockClusterClient := cluster.NewMockClusterClient(t)
mockClusterClient.EXPECT().CreateMilvusClient(mock.Anything, mock.Anything).
Return(mockMilvusClient, nil)
resource.InitForTest(t,
resource.OptClusterClient(mockClusterClient),
)
scanner := mock_streaming.NewMockScanner(t)
scanner.EXPECT().Close().Return()
wal := mock_streaming.NewMockWALAccesser(t)
@ -74,23 +65,31 @@ func TestChannelReplicator_StartReplicateChannel(t *testing.T) {
rs := replicatestream.NewMockReplicateStreamClient(t)
rs.EXPECT().Close().Return()
cluster := &commonpb.MilvusCluster{ClusterId: "test-cluster"}
mc := &commonpb.MilvusCluster{ClusterId: "test-cluster"}
replicateInfo := &streamingpb.ReplicatePChannelMeta{
SourceChannelName: "test-source-channel",
TargetChannelName: "test-target-channel",
TargetCluster: cluster,
TargetCluster: mc,
}
replicator := NewChannelReplicator(replicateInfo)
replicator := NewChannelReplicator(&meta.ReplicateChannel{
Value: replicateInfo,
ModRevision: 0,
})
assert.NotNil(t, replicator)
replicator.(*channelReplicator).createRscFunc = func(ctx context.Context,
replicateInfo *streamingpb.ReplicatePChannelMeta,
c cluster.MilvusClient,
rm *meta.ReplicateChannel,
) replicatestream.ReplicateStreamClient {
return rs
}
assert.NotNil(t, replicator)
replicator.(*channelReplicator).createMcFunc = func(ctx context.Context,
cluster *commonpb.MilvusCluster,
) (cluster.MilvusClient, error) {
return mockMilvusClient, nil
}
replicator.StartReplicate()
replicator.StopReplicate()
state := replicator.GetState()
assert.Equal(t, typeutil.LifetimeStateStopped, state)
replicator.StartReplication()
time.Sleep(200 * time.Millisecond)
replicator.StopReplication()
}

View File

@ -18,74 +18,103 @@ package replicatemanager
import (
"context"
"fmt"
"strings"
"sync"
"github.com/samber/lo"
"go.uber.org/zap"
"github.com/milvus-io/milvus/internal/metastore/kv/streamingcoord"
"github.com/milvus-io/milvus/internal/cdc/meta"
"github.com/milvus-io/milvus/pkg/v2/log"
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
)
// replicateManager is the implementation of ReplicateManagerClient.
type replicateManager struct {
ctx context.Context
mu sync.Mutex
// replicators is a map of replicate pchannel name to ChannelReplicator.
replicators map[string]Replicator
replicatorPChannels map[string]*streamingpb.ReplicatePChannelMeta
replicators map[string]Replicator
replicatorChannels map[string]*meta.ReplicateChannel
}
func NewReplicateManager() *replicateManager {
return &replicateManager{
ctx: context.Background(),
replicators: make(map[string]Replicator),
replicatorPChannels: make(map[string]*streamingpb.ReplicatePChannelMeta),
ctx: context.Background(),
replicators: make(map[string]Replicator),
replicatorChannels: make(map[string]*meta.ReplicateChannel),
}
}
func (r *replicateManager) CreateReplicator(replicateInfo *streamingpb.ReplicatePChannelMeta) {
logger := log.With(
zap.String("sourceChannel", replicateInfo.GetSourceChannelName()),
zap.String("targetChannel", replicateInfo.GetTargetChannelName()),
)
func buildReplicatorKey(metaKey string, modRevision int64) string {
return fmt.Sprintf("%s/_v%d", metaKey, modRevision)
}
func (r *replicateManager) CreateReplicator(channel *meta.ReplicateChannel) {
r.mu.Lock()
defer r.mu.Unlock()
logger := log.With(zap.String("key", channel.Key), zap.Int64("modRevision", channel.ModRevision))
repKey := buildReplicatorKey(channel.Key, channel.ModRevision)
currentClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
if !strings.Contains(replicateInfo.GetSourceChannelName(), currentClusterID) {
// current cluster is not source cluster, skip create replicator
if !strings.Contains(channel.Value.GetSourceChannelName(), currentClusterID) {
return
}
replicatorKey := streamingcoord.BuildReplicatePChannelMetaKey(replicateInfo)
_, ok := r.replicators[replicatorKey]
_, ok := r.replicators[repKey]
if ok {
logger.Debug("replicator already exists, skip create replicator")
return
}
replicator := NewChannelReplicator(replicateInfo)
replicator.StartReplicate()
r.replicators[replicatorKey] = replicator
r.replicatorPChannels[replicatorKey] = replicateInfo
replicator := NewChannelReplicator(channel)
replicator.StartReplication()
r.replicators[repKey] = replicator
r.replicatorChannels[repKey] = channel
logger.Info("created replicator for replicate pchannel")
}
func (r *replicateManager) RemoveOutOfTargetReplicators(targetReplicatePChannels []*streamingpb.ReplicatePChannelMeta) {
targets := lo.KeyBy(targetReplicatePChannels, streamingcoord.BuildReplicatePChannelMetaKey)
for replicatorKey, replicator := range r.replicators {
if pchannelMeta, ok := targets[replicatorKey]; !ok {
replicator.StopReplicate()
delete(r.replicators, replicatorKey)
delete(r.replicatorPChannels, replicatorKey)
log.Info("removed replicator due to out of target",
zap.String("sourceChannel", pchannelMeta.GetSourceChannelName()),
zap.String("targetChannel", pchannelMeta.GetTargetChannelName()),
)
func (r *replicateManager) RemoveReplicator(key string, modRevision int64) {
r.mu.Lock()
defer r.mu.Unlock()
r.removeReplicatorInternal(key, modRevision)
}
func (r *replicateManager) removeReplicatorInternal(key string, modRevision int64) {
logger := log.With(zap.String("key", key), zap.Int64("modRevision", modRevision))
repKey := buildReplicatorKey(key, modRevision)
replicator, ok := r.replicators[repKey]
if !ok {
logger.Info("replicator not found, skip remove")
return
}
replicator.StopReplication()
delete(r.replicators, repKey)
delete(r.replicatorChannels, repKey)
logger.Info("removed replicator for replicate pchannel")
}
func (r *replicateManager) RemoveOutdatedReplicators(aliveChannels []*meta.ReplicateChannel) {
r.mu.Lock()
defer r.mu.Unlock()
alivesMap := make(map[string]struct{})
for _, channel := range aliveChannels {
repKey := buildReplicatorKey(channel.Key, channel.ModRevision)
alivesMap[repKey] = struct{}{}
}
for repKey := range r.replicators {
if _, ok := alivesMap[repKey]; !ok {
channel := r.replicatorChannels[repKey]
r.removeReplicatorInternal(channel.Key, channel.ModRevision)
}
}
}
func (r *replicateManager) Close() {
r.mu.Lock()
defer r.mu.Unlock()
for _, replicator := range r.replicators {
replicator.StopReplicate()
replicator.StopReplication()
}
r.replicators = make(map[string]Replicator)
r.replicatorChannels = make(map[string]*meta.ReplicateChannel)
}

View File

@ -24,8 +24,7 @@ import (
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
"github.com/milvus-io/milvus/internal/cdc/cluster"
"github.com/milvus-io/milvus/internal/cdc/resource"
"github.com/milvus-io/milvus/internal/metastore/kv/streamingcoord"
"github.com/milvus-io/milvus/internal/cdc/meta"
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
)
@ -39,13 +38,6 @@ func TestReplicateManager_CreateReplicator(t *testing.T) {
Return(nil, assert.AnError).Maybe()
mockMilvusClient.EXPECT().Close(mock.Anything).Return(nil).Maybe()
mockClusterClient := cluster.NewMockClusterClient(t)
mockClusterClient.EXPECT().CreateMilvusClient(mock.Anything, mock.Anything).
Return(mockMilvusClient, nil).Maybe()
resource.InitForTest(t,
resource.OptClusterClient(mockClusterClient),
)
manager := NewReplicateManager()
// Test creating first replicator
@ -56,13 +48,18 @@ func TestReplicateManager_CreateReplicator(t *testing.T) {
ClusterId: "test-cluster-1",
},
}
key := "test-replicate-key-1"
replicateMeta := &meta.ReplicateChannel{
Key: key,
Value: replicateInfo,
ModRevision: 0,
}
manager.CreateReplicator(replicateInfo)
manager.CreateReplicator(replicateMeta)
// Verify replicator was created
assert.Equal(t, 1, len(manager.replicators))
key := streamingcoord.BuildReplicatePChannelMetaKey(replicateInfo)
replicator, exists := manager.replicators[key]
replicator, exists := manager.replicators[buildReplicatorKey(key, 0)]
assert.True(t, exists)
assert.NotNil(t, replicator)
@ -74,18 +71,23 @@ func TestReplicateManager_CreateReplicator(t *testing.T) {
ClusterId: "test-cluster-2",
},
}
key2 := "test-replicate-key-2"
replicateMeta2 := &meta.ReplicateChannel{
Key: key2,
Value: replicateInfo2,
ModRevision: 0,
}
manager.CreateReplicator(replicateInfo2)
manager.CreateReplicator(replicateMeta2)
// Verify second replicator was created
assert.Equal(t, 2, len(manager.replicators))
key2 := streamingcoord.BuildReplicatePChannelMetaKey(replicateInfo2)
replicator2, exists := manager.replicators[key2]
replicator2, exists := manager.replicators[buildReplicatorKey(key2, 0)]
assert.True(t, exists)
assert.NotNil(t, replicator2)
// Verify first replicator still exists
replicator1, exists := manager.replicators[key]
replicator1, exists := manager.replicators[buildReplicatorKey(key, 0)]
assert.True(t, exists)
assert.NotNil(t, replicator1)
}

View File

@ -19,9 +19,11 @@ package replicatestream
import (
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/milvus-io/milvus/pkg/v2/metrics"
streamingpb "github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
message "github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
"github.com/milvus-io/milvus/pkg/v2/util/timerecord"
"github.com/milvus-io/milvus/pkg/v2/util/tsoutil"
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
@ -31,9 +33,11 @@ type ReplicateMetrics interface {
StartReplicate(msg message.ImmutableMessage)
OnSent(msg message.ImmutableMessage)
OnConfirmed(msg message.ImmutableMessage)
OnNoIncomingMessages()
OnInitiate()
OnConnect()
OnDisconnect()
OnReconnect()
OnClose()
}
type msgMetrics struct {
@ -96,10 +100,18 @@ func (m *replicateMetrics) OnConfirmed(msg message.ImmutableMessage) {
).Set(float64(lag.Milliseconds()))
}
func (m *replicateMetrics) OnConnect() {
// OnNoIncomingMessages is called when there are no incoming messages.
func (m *replicateMetrics) OnNoIncomingMessages() {
metrics.CDCReplicateLag.WithLabelValues(
m.replicateInfo.GetSourceChannelName(),
m.replicateInfo.GetTargetChannelName(),
).Set(0)
}
func (m *replicateMetrics) OnInitiate() {
metrics.CDCStreamRPCConnections.WithLabelValues(
m.replicateInfo.GetTargetCluster().GetClusterId(),
metrics.CDCStatusConnected,
metrics.CDCStatusDisconnected,
).Inc()
}
@ -115,7 +127,7 @@ func (m *replicateMetrics) OnDisconnect() {
).Inc()
}
func (m *replicateMetrics) OnReconnect() {
func (m *replicateMetrics) OnConnect() {
targetClusterID := m.replicateInfo.GetTargetCluster().GetClusterId()
metrics.CDCStreamRPCConnections.WithLabelValues(
targetClusterID,
@ -130,3 +142,9 @@ func (m *replicateMetrics) OnReconnect() {
targetClusterID,
).Inc()
}
func (m *replicateMetrics) OnClose() {
metrics.CDCStreamRPCConnections.DeletePartialMatch(prometheus.Labels{
metrics.CDCLabelTargetCluster: m.replicateInfo.GetTargetCluster().GetClusterId(),
})
}

View File

@ -20,6 +20,38 @@ func (_m *MockReplicateStreamClient) EXPECT() *MockReplicateStreamClient_Expecte
return &MockReplicateStreamClient_Expecter{mock: &_m.Mock}
}
// BlockUntilFinish provides a mock function with no fields
func (_m *MockReplicateStreamClient) BlockUntilFinish() {
_m.Called()
}
// MockReplicateStreamClient_BlockUntilFinish_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BlockUntilFinish'
type MockReplicateStreamClient_BlockUntilFinish_Call struct {
*mock.Call
}
// BlockUntilFinish is a helper method to define mock.On call
func (_e *MockReplicateStreamClient_Expecter) BlockUntilFinish() *MockReplicateStreamClient_BlockUntilFinish_Call {
return &MockReplicateStreamClient_BlockUntilFinish_Call{Call: _e.mock.On("BlockUntilFinish")}
}
func (_c *MockReplicateStreamClient_BlockUntilFinish_Call) Run(run func()) *MockReplicateStreamClient_BlockUntilFinish_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockReplicateStreamClient_BlockUntilFinish_Call) Return() *MockReplicateStreamClient_BlockUntilFinish_Call {
_c.Call.Return()
return _c
}
func (_c *MockReplicateStreamClient_BlockUntilFinish_Call) RunAndReturn(run func()) *MockReplicateStreamClient_BlockUntilFinish_Call {
_c.Run(run)
return _c
}
// Close provides a mock function with no fields
func (_m *MockReplicateStreamClient) Close() {
_m.Called()

View File

@ -62,18 +62,28 @@ type msgQueue struct {
notEmpty *sync.Cond
notFull *sync.Cond
buf []message.ImmutableMessage
readIdx int
cap int
closed bool
buf []message.ImmutableMessage
bufBytes int
readIdx int
cap int
maxSize int
closed bool
}
type MsgQueueOptions struct {
Capacity int
MaxSize int
}
// NewMsgQueue creates a queue with a fixed capacity (>0).
func NewMsgQueue(capacity int) *msgQueue {
if capacity <= 0 {
func NewMsgQueue(options MsgQueueOptions) *msgQueue {
if options.Capacity <= 0 {
panic("capacity must be > 0")
}
q := &msgQueue{cap: capacity}
if options.MaxSize <= 0 {
panic("max size must be > 0")
}
q := &msgQueue{cap: options.Capacity, maxSize: options.MaxSize}
q.notEmpty = sync.NewCond(&q.mu)
q.notFull = sync.NewCond(&q.mu)
return q
@ -92,7 +102,7 @@ func (q *msgQueue) Enqueue(ctx context.Context, msg message.ImmutableMessage) er
q.mu.Lock()
defer q.mu.Unlock()
for len(q.buf) >= q.cap {
for len(q.buf) >= q.cap || q.bufBytes >= q.maxSize {
if ctx.Err() != nil {
return context.Canceled
}
@ -110,6 +120,7 @@ func (q *msgQueue) Enqueue(ctx context.Context, msg message.ImmutableMessage) er
// }
q.buf = append(q.buf, msg)
q.bufBytes += msg.EstimateSize()
// New data is available for readers.
q.notEmpty.Signal()
@ -176,6 +187,11 @@ func (q *msgQueue) CleanupConfirmedMessages(lastConfirmedTimeTick uint64) []mess
copy(cleanedMessages, q.buf[:cut])
// Drop the prefix [0:cut)
// Release memory of [0:cut) by zeroing references before reslicing
for i := 0; i < cut; i++ {
q.bufBytes -= q.buf[i].EstimateSize()
q.buf[i] = nil
}
q.buf = q.buf[cut:]
// Adjust read cursor relative to the new slice
q.readIdx -= cut

View File

@ -29,7 +29,7 @@ import (
func TestMsgQueue_BasicOperations(t *testing.T) {
// Test basic queue operations
queue := NewMsgQueue(3)
queue := NewMsgQueue(MsgQueueOptions{Capacity: 3, MaxSize: 1000})
assert.Equal(t, 3, queue.Cap())
assert.Equal(t, 0, queue.Len())
@ -37,6 +37,7 @@ func TestMsgQueue_BasicOperations(t *testing.T) {
ctx := context.Background()
msg1 := mock_message.NewMockImmutableMessage(t)
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
msg1.EXPECT().EstimateSize().Return(100).Maybe()
err := queue.Enqueue(ctx, msg1)
assert.NoError(t, err)
@ -51,14 +52,16 @@ func TestMsgQueue_BasicOperations(t *testing.T) {
func TestMsgQueue_EnqueueBlocking(t *testing.T) {
// Test enqueue blocking when queue is full
queue := NewMsgQueue(2)
queue := NewMsgQueue(MsgQueueOptions{Capacity: 2, MaxSize: 1000})
ctx := context.Background()
// Fill the queue
msg1 := mock_message.NewMockImmutableMessage(t)
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
msg1.EXPECT().EstimateSize().Return(100).Maybe()
msg2 := mock_message.NewMockImmutableMessage(t)
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
msg2.EXPECT().EstimateSize().Return(100).Maybe()
err := queue.Enqueue(ctx, msg1)
assert.NoError(t, err)
@ -69,6 +72,7 @@ func TestMsgQueue_EnqueueBlocking(t *testing.T) {
// Try to enqueue when full - should block
msg3 := mock_message.NewMockImmutableMessage(t)
msg3.EXPECT().TimeTick().Return(uint64(300)).Maybe()
msg3.EXPECT().EstimateSize().Return(100).Maybe()
// Use a context with timeout to test blocking
ctxWithTimeout, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
@ -82,7 +86,7 @@ func TestMsgQueue_EnqueueBlocking(t *testing.T) {
func TestMsgQueue_DequeueBlocking(t *testing.T) {
// Test dequeue blocking when queue is empty
queue := NewMsgQueue(2)
queue := NewMsgQueue(MsgQueueOptions{Capacity: 2, MaxSize: 1000})
ctx := context.Background()
// Try to dequeue from empty queue - should block
@ -97,14 +101,16 @@ func TestMsgQueue_DequeueBlocking(t *testing.T) {
func TestMsgQueue_SeekToHead(t *testing.T) {
// Test seek to head functionality
queue := NewMsgQueue(3)
queue := NewMsgQueue(MsgQueueOptions{Capacity: 3, MaxSize: 1000})
ctx := context.Background()
// Add messages
msg1 := mock_message.NewMockImmutableMessage(t)
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
msg1.EXPECT().EstimateSize().Return(100).Maybe()
msg2 := mock_message.NewMockImmutableMessage(t)
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
msg2.EXPECT().EstimateSize().Return(100).Maybe()
err := queue.Enqueue(ctx, msg1)
assert.NoError(t, err)
@ -127,16 +133,19 @@ func TestMsgQueue_SeekToHead(t *testing.T) {
func TestMsgQueue_CleanupConfirmedMessages(t *testing.T) {
// Test cleanup functionality
queue := NewMsgQueue(5)
queue := NewMsgQueue(MsgQueueOptions{Capacity: 5, MaxSize: 1000})
ctx := context.Background()
// Add messages with different timeticks
msg1 := mock_message.NewMockImmutableMessage(t)
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
msg1.EXPECT().EstimateSize().Return(100).Maybe()
msg2 := mock_message.NewMockImmutableMessage(t)
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
msg2.EXPECT().EstimateSize().Return(100).Maybe()
msg3 := mock_message.NewMockImmutableMessage(t)
msg3.EXPECT().TimeTick().Return(uint64(300)).Maybe()
msg3.EXPECT().EstimateSize().Return(100).Maybe()
err := queue.Enqueue(ctx, msg1)
assert.NoError(t, err)
@ -162,16 +171,19 @@ func TestMsgQueue_CleanupConfirmedMessages(t *testing.T) {
func TestMsgQueue_CleanupWithReadCursor(t *testing.T) {
// Test cleanup when read cursor is advanced
queue := NewMsgQueue(5)
queue := NewMsgQueue(MsgQueueOptions{Capacity: 5, MaxSize: 1000})
ctx := context.Background()
// Add messages
msg1 := mock_message.NewMockImmutableMessage(t)
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
msg1.EXPECT().EstimateSize().Return(100).Maybe()
msg2 := mock_message.NewMockImmutableMessage(t)
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
msg2.EXPECT().EstimateSize().Return(100).Maybe()
msg3 := mock_message.NewMockImmutableMessage(t)
msg3.EXPECT().TimeTick().Return(uint64(300)).Maybe()
msg3.EXPECT().EstimateSize().Return(100).Maybe()
err := queue.Enqueue(ctx, msg1)
assert.NoError(t, err)
@ -184,30 +196,30 @@ func TestMsgQueue_CleanupWithReadCursor(t *testing.T) {
dequeuedMsg, err := queue.ReadNext(ctx)
assert.NoError(t, err)
assert.Equal(t, msg1, dequeuedMsg)
assert.Equal(t, 1, queue.readIdx)
// Cleanup messages with timetick <= 150
cleanedMessages := queue.CleanupConfirmedMessages(150)
assert.Equal(t, 2, queue.Len()) // msg1 removed, msg2 and msg3 remain
assert.Equal(t, 0, queue.readIdx) // read cursor adjusted
assert.Equal(t, 2, queue.Len()) // msg1 removed, msg2 and msg3 remain
assert.Equal(t, 1, len(cleanedMessages))
assert.Equal(t, msg1, cleanedMessages[0])
}
func TestMsgQueue_ContextCancellation(t *testing.T) {
// Test context cancellation
queue := NewMsgQueue(1)
queue := NewMsgQueue(MsgQueueOptions{Capacity: 1, MaxSize: 1000})
ctx, cancel := context.WithCancel(context.Background())
// Fill the queue
msg1 := mock_message.NewMockImmutableMessage(t)
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
msg1.EXPECT().EstimateSize().Return(100).Maybe()
err := queue.Enqueue(ctx, msg1)
assert.NoError(t, err)
// Try to enqueue when full
msg2 := mock_message.NewMockImmutableMessage(t)
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
msg2.EXPECT().EstimateSize().Return(100).Maybe()
// Cancel context before enqueue
cancel()
@ -219,22 +231,30 @@ func TestMsgQueue_ContextCancellation(t *testing.T) {
func TestMsgQueue_NewMsgQueueValidation(t *testing.T) {
// Test constructor validation
assert.Panics(t, func() {
NewMsgQueue(0)
NewMsgQueue(MsgQueueOptions{Capacity: 0, MaxSize: 1000})
})
assert.Panics(t, func() {
NewMsgQueue(-1)
NewMsgQueue(MsgQueueOptions{Capacity: -1, MaxSize: 1000})
})
assert.Panics(t, func() {
NewMsgQueue(MsgQueueOptions{Capacity: 1, MaxSize: 0})
})
assert.Panics(t, func() {
NewMsgQueue(MsgQueueOptions{Capacity: 1, MaxSize: -1})
})
// Valid capacity
queue := NewMsgQueue(1)
queue := NewMsgQueue(MsgQueueOptions{Capacity: 1, MaxSize: 1000})
assert.NotNil(t, queue)
assert.Equal(t, 1, queue.Cap())
}
func TestMsgQueue_ConcurrentOperations(t *testing.T) {
// Test concurrent enqueue and dequeue operations
queue := NewMsgQueue(10)
queue := NewMsgQueue(MsgQueueOptions{Capacity: 10, MaxSize: 10000})
ctx := context.Background()
numMessages := 100
@ -246,6 +266,7 @@ func TestMsgQueue_ConcurrentOperations(t *testing.T) {
for i := 0; i < numMessages; i++ {
msg := mock_message.NewMockImmutableMessage(t)
msg.EXPECT().TimeTick().Return(uint64(i)).Maybe()
msg.EXPECT().EstimateSize().Return(100).Maybe()
err := queue.Enqueue(ctx, msg)
assert.NoError(t, err)
}
@ -270,7 +291,7 @@ func TestMsgQueue_ConcurrentOperations(t *testing.T) {
func TestMsgQueue_EdgeCases(t *testing.T) {
// Test edge cases
queue := NewMsgQueue(1)
queue := NewMsgQueue(MsgQueueOptions{Capacity: 1, MaxSize: 1000})
// Test with nil message (if allowed by interface)
// This depends on the actual message.ImmutableMessage interface implementation
@ -283,5 +304,90 @@ func TestMsgQueue_EdgeCases(t *testing.T) {
// Test seek to head on empty queue
queue.SeekToHead()
assert.Equal(t, 0, queue.readIdx)
// Note: readIdx is not accessible from outside the package
}
func TestMsgQueue_SizeBasedCapacity(t *testing.T) {
// Test size-based capacity control
queue := NewMsgQueue(MsgQueueOptions{Capacity: 10, MaxSize: 100})
ctx := context.Background()
// Add messages that exceed size limit but not count limit
msg1 := mock_message.NewMockImmutableMessage(t)
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
msg1.EXPECT().EstimateSize().Return(100).Maybe()
msg2 := mock_message.NewMockImmutableMessage(t)
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
msg2.EXPECT().EstimateSize().Return(50).Maybe()
err := queue.Enqueue(ctx, msg1)
assert.NoError(t, err)
assert.Equal(t, 1, queue.Len())
// Try to enqueue second message - should block due to size limit (100 >= 100)
ctxWithTimeout, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
defer cancel()
err = queue.Enqueue(ctxWithTimeout, msg2)
assert.Error(t, err)
assert.Equal(t, context.Canceled, err)
}
func TestMsgQueue_SizeBasedCapacityWithCleanup(t *testing.T) {
// Test size-based capacity with cleanup
queue := NewMsgQueue(MsgQueueOptions{Capacity: 10, MaxSize: 300})
ctx := context.Background()
// Add messages
msg1 := mock_message.NewMockImmutableMessage(t)
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
msg1.EXPECT().EstimateSize().Return(200).Maybe()
msg2 := mock_message.NewMockImmutableMessage(t)
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
msg2.EXPECT().EstimateSize().Return(200).Maybe()
err := queue.Enqueue(ctx, msg1)
assert.NoError(t, err)
// Cleanup first message to free space
cleanedMessages := queue.CleanupConfirmedMessages(100)
assert.Equal(t, 1, len(cleanedMessages))
assert.Equal(t, msg1, cleanedMessages[0])
// Now should be able to enqueue second message (200 < 300)
err = queue.Enqueue(ctx, msg2)
assert.NoError(t, err)
assert.Equal(t, 1, queue.Len())
}
func TestMsgQueue_MixedCapacityLimits(t *testing.T) {
// Test both count and size limits
queue := NewMsgQueue(MsgQueueOptions{Capacity: 2, MaxSize: 1000})
ctx := context.Background()
// Add messages that hit count limit first
msg1 := mock_message.NewMockImmutableMessage(t)
msg1.EXPECT().TimeTick().Return(uint64(100)).Maybe()
msg1.EXPECT().EstimateSize().Return(100).Maybe()
msg2 := mock_message.NewMockImmutableMessage(t)
msg2.EXPECT().TimeTick().Return(uint64(200)).Maybe()
msg2.EXPECT().EstimateSize().Return(100).Maybe()
err := queue.Enqueue(ctx, msg1)
assert.NoError(t, err)
err = queue.Enqueue(ctx, msg2)
assert.NoError(t, err)
assert.Equal(t, 2, queue.Len())
// Try to enqueue third message - should block due to count limit
msg3 := mock_message.NewMockImmutableMessage(t)
msg3.EXPECT().TimeTick().Return(uint64(300)).Maybe()
msg3.EXPECT().EstimateSize().Return(100).Maybe()
ctxWithTimeout, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
defer cancel()
err = queue.Enqueue(ctxWithTimeout, msg3)
assert.Error(t, err)
assert.Equal(t, context.Canceled, err)
}

View File

@ -19,20 +19,29 @@ package replicatestream
import (
context "context"
streamingpb "github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
"github.com/cockroachdb/errors"
"github.com/milvus-io/milvus/internal/cdc/cluster"
"github.com/milvus-io/milvus/internal/cdc/meta"
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
)
var ErrReplicateIgnored = errors.New("ignored replicate message")
// ReplicateStreamClient is the client that replicates the message to the given cluster.
type ReplicateStreamClient interface {
// Replicate replicates the message to the target cluster.
// Replicate opeartion doesn't promise the message is delivered to the target cluster.
// It will cache the message in memory and retry until the message is delivered to the target cluster or the client is closed.
// Once the error is returned, the replicate operation will be unrecoverable.
// return ErrReplicateIgnored if the message should not be replicated.
Replicate(msg message.ImmutableMessage) error
// Stop stops the replicate operation.
// BlockUntilFinish blocks until the replicate stream client is finished.
BlockUntilFinish()
// Close closes the replicate stream client.
Close()
}
type CreateReplicateStreamClientFunc func(ctx context.Context, replicateInfo *streamingpb.ReplicatePChannelMeta) ReplicateStreamClient
type CreateReplicateStreamClientFunc func(ctx context.Context, c cluster.MilvusClient, rm *meta.ReplicateChannel) ReplicateStreamClient

View File

@ -22,27 +22,35 @@ import (
"time"
"github.com/cenkalti/backoff/v4"
"github.com/cockroachdb/errors"
"go.uber.org/zap"
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
"github.com/milvus-io/milvus/internal/cdc/cluster"
"github.com/milvus-io/milvus/internal/cdc/meta"
"github.com/milvus-io/milvus/internal/cdc/resource"
"github.com/milvus-io/milvus/internal/cdc/util"
"github.com/milvus-io/milvus/internal/util/streamingutil/service/contextutil"
"github.com/milvus-io/milvus/pkg/v2/log"
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
"github.com/milvus-io/milvus/pkg/v2/util/replicateutil"
)
const pendingMessageQueueLength = 128
const (
// TODO: sheep, make these parameters configurable
pendingMessageQueueLength = 128
pendingMessageQueueMaxSize = 128 * 1024 * 1024
)
var ErrReplicationRemoved = errors.New("replication removed")
// replicateStreamClient is the implementation of ReplicateStreamClient.
type replicateStreamClient struct {
replicateInfo *streamingpb.ReplicatePChannelMeta
clusterID string
targetClient cluster.MilvusClient
client milvuspb.MilvusService_CreateReplicateStreamClient
channel *meta.ReplicateChannel
pendingMessages MsgQueue
metrics ReplicateMetrics
@ -52,34 +60,37 @@ type replicateStreamClient struct {
}
// NewReplicateStreamClient creates a new ReplicateStreamClient.
func NewReplicateStreamClient(ctx context.Context, replicateInfo *streamingpb.ReplicatePChannelMeta) ReplicateStreamClient {
func NewReplicateStreamClient(ctx context.Context, c cluster.MilvusClient, channel *meta.ReplicateChannel) ReplicateStreamClient {
ctx1, cancel := context.WithCancel(ctx)
ctx1 = contextutil.WithClusterID(ctx1, replicateInfo.GetTargetCluster().GetClusterId())
ctx1 = contextutil.WithClusterID(ctx1, channel.Value.GetTargetCluster().GetClusterId())
options := MsgQueueOptions{
Capacity: pendingMessageQueueLength,
MaxSize: pendingMessageQueueMaxSize,
}
pendingMessages := NewMsgQueue(options)
rs := &replicateStreamClient{
clusterID: paramtable.Get().CommonCfg.ClusterPrefix.GetValue(),
replicateInfo: replicateInfo,
pendingMessages: NewMsgQueue(pendingMessageQueueLength),
metrics: NewReplicateMetrics(replicateInfo),
targetClient: c,
channel: channel,
pendingMessages: pendingMessages,
metrics: NewReplicateMetrics(channel.Value),
ctx: ctx1,
cancel: cancel,
finishedCh: make(chan struct{}),
}
rs.metrics.OnConnect()
rs.metrics.OnInitiate()
go rs.startInternal()
return rs
}
func (r *replicateStreamClient) startInternal() {
logger := log.With(
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
)
defer func() {
r.metrics.OnDisconnect()
logger.Info("replicate stream client closed")
log.Info("replicate stream client closed",
zap.String("key", r.channel.Key),
zap.Int64("revision", r.channel.ModRevision))
r.metrics.OnClose()
close(r.finishedCh)
}()
@ -87,52 +98,67 @@ func (r *replicateStreamClient) startInternal() {
backoff.InitialInterval = 100 * time.Millisecond
backoff.MaxInterval = 10 * time.Second
backoff.MaxElapsedTime = 0
backoff.Reset()
for {
// Create a local context for this connection that can be canceled
// when we need to stop the send/recv loops
connCtx, connCancel := context.WithCancel(r.ctx)
milvusClient, err := resource.Resource().ClusterClient().CreateMilvusClient(connCtx, r.replicateInfo.GetTargetCluster())
if err != nil {
logger.Warn("create milvus client failed, retry...", zap.Error(err))
time.Sleep(backoff.NextBackOff())
continue
}
client, err := milvusClient.CreateReplicateStream(connCtx)
if err != nil {
logger.Warn("create milvus replicate stream failed, retry...", zap.Error(err))
time.Sleep(backoff.NextBackOff())
continue
}
logger.Info("replicate stream client service started")
// reset client and pending messages
r.client = client
r.pendingMessages.SeekToHead()
sendCh := r.startSendLoop(connCtx)
recvCh := r.startRecvLoop(connCtx)
select {
case <-r.ctx.Done():
case <-sendCh:
case <-recvCh:
}
connCancel() // Cancel the connection context
<-sendCh
<-recvCh // wait for send/recv loops to exit
if r.ctx.Err() != nil {
logger.Info("close replicate stream client by ctx done")
restart := r.startReplicating(backoff)
if !restart {
return
} else {
logger.Warn("restart replicate stream client")
r.metrics.OnDisconnect()
time.Sleep(backoff.NextBackOff())
}
time.Sleep(backoff.NextBackOff())
}
}
func (r *replicateStreamClient) startReplicating(backoff backoff.BackOff) (needRestart bool) {
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("revision", r.channel.ModRevision))
if r.ctx.Err() != nil {
logger.Info("close replicate stream client due to ctx done")
return false
}
// Create a local context for this connection that can be canceled
// when we need to stop the send/recv loops
connCtx, connCancel := context.WithCancel(r.ctx)
defer connCancel()
client, err := r.targetClient.CreateReplicateStream(connCtx)
if err != nil {
logger.Warn("create milvus replicate stream failed, retry...", zap.Error(err))
return true
}
defer client.CloseSend()
logger.Info("replicate stream client service started")
r.metrics.OnConnect()
backoff.Reset()
// reset client and pending messages
r.client = client
r.pendingMessages.SeekToHead()
sendCh := r.startSendLoop(connCtx)
recvCh := r.startRecvLoop(connCtx)
var chErr error
select {
case <-r.ctx.Done():
case chErr = <-sendCh:
case chErr = <-recvCh:
}
connCancel() // Cancel the connection context
<-sendCh
<-recvCh // wait for send/recv loops to exit
if r.ctx.Err() != nil {
logger.Info("close replicate stream client due to ctx done")
return false
} else if errors.Is(chErr, ErrReplicationRemoved) {
logger.Info("close replicate stream client due to replication removed")
return false
} else {
logger.Warn("restart replicate stream client due to unexpected error", zap.Error(chErr))
r.metrics.OnDisconnect()
return true
}
}
@ -142,42 +168,48 @@ func (r *replicateStreamClient) Replicate(msg message.ImmutableMessage) error {
case <-r.ctx.Done():
return nil
default:
// TODO: Should be done at streamingnode, but after move it into streamingnode, the metric need to be adjusted.
if msg.MessageType().IsSelfControlled() {
if r.pendingMessages.Len() == 0 {
// if there is no pending messages, there's no lag between source and target.
r.metrics.OnNoIncomingMessages()
}
return ErrReplicateIgnored
}
r.metrics.StartReplicate(msg)
r.pendingMessages.Enqueue(r.ctx, msg)
return nil
}
}
func (r *replicateStreamClient) startSendLoop(ctx context.Context) <-chan struct{} {
ch := make(chan struct{})
func (r *replicateStreamClient) startSendLoop(ctx context.Context) <-chan error {
ch := make(chan error)
go func() {
_ = r.sendLoop(ctx)
err := r.sendLoop(ctx)
ch <- err
close(ch)
}()
return ch
}
func (r *replicateStreamClient) startRecvLoop(ctx context.Context) <-chan struct{} {
ch := make(chan struct{})
func (r *replicateStreamClient) startRecvLoop(ctx context.Context) <-chan error {
ch := make(chan error)
go func() {
_ = r.recvLoop(ctx)
err := r.recvLoop(ctx)
ch <- err
close(ch)
}()
return ch
}
func (r *replicateStreamClient) sendLoop(ctx context.Context) (err error) {
logger := log.With(
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
)
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("revision", r.channel.ModRevision))
defer func() {
if err != nil {
logger.Warn("send loop closed by unexpected error", zap.Error(err))
} else {
logger.Info("send loop closed")
}
r.client.CloseSend()
}()
for {
select {
@ -225,10 +257,7 @@ func (r *replicateStreamClient) sendLoop(ctx context.Context) (err error) {
func (r *replicateStreamClient) sendMessage(msg message.ImmutableMessage) (err error) {
defer func() {
logger := log.With(
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
)
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("revision", r.channel.ModRevision))
if err != nil {
logger.Warn("send message failed", zap.Error(err), log.FieldMessage(msg))
} else {
@ -253,15 +282,12 @@ func (r *replicateStreamClient) sendMessage(msg message.ImmutableMessage) (err e
}
func (r *replicateStreamClient) recvLoop(ctx context.Context) (err error) {
logger := log.With(
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
)
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("revision", r.channel.ModRevision))
defer func() {
if err != nil {
if err != nil && !errors.Is(err, ErrReplicationRemoved) {
logger.Warn("recv loop closed by unexpected error", zap.Error(err))
} else {
logger.Info("recv loop closed")
logger.Info("recv loop closed", zap.Error(err))
}
}()
for {
@ -278,46 +304,56 @@ func (r *replicateStreamClient) recvLoop(ctx context.Context) (err error) {
if lastConfirmedMessageInfo != nil {
messages := r.pendingMessages.CleanupConfirmedMessages(lastConfirmedMessageInfo.GetConfirmedTimeTick())
for _, msg := range messages {
r.metrics.OnConfirmed(msg)
if msg.MessageType() == message.MessageTypeAlterReplicateConfig {
roleChanged := r.handleAlterReplicateConfigMessage(msg)
if roleChanged {
// Role changed, return and stop replicate.
return nil
replicationRemoved := r.handleAlterReplicateConfigMessage(msg)
if replicationRemoved {
// Replication removed, return and stop replicate.
return ErrReplicationRemoved
}
}
r.metrics.OnConfirmed(msg)
}
}
}
}
}
func (r *replicateStreamClient) handleAlterReplicateConfigMessage(msg message.ImmutableMessage) (roleChanged bool) {
logger := log.With(
zap.String("sourceChannel", r.replicateInfo.GetSourceChannelName()),
zap.String("targetChannel", r.replicateInfo.GetTargetChannelName()),
)
func (r *replicateStreamClient) handleAlterReplicateConfigMessage(msg message.ImmutableMessage) (replicationRemoved bool) {
logger := log.With(zap.String("key", r.channel.Key), zap.Int64("revision", r.channel.ModRevision))
logger.Info("handle AlterReplicateConfigMessage", log.FieldMessage(msg))
prcMsg := message.MustAsImmutableAlterReplicateConfigMessageV2(msg)
replicateConfig := prcMsg.Header().ReplicateConfiguration
currentClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
currentCluster := replicateutil.MustNewConfigHelper(currentClusterID, replicateConfig).GetCurrentCluster()
_, err := currentCluster.GetTargetChannel(r.replicateInfo.GetSourceChannelName(),
r.replicateInfo.GetTargetCluster().GetClusterId())
if err != nil {
replicationRemoved = util.IsReplicationRemovedByAlterReplicateConfigMessage(msg, r.channel.Value)
if replicationRemoved {
// Cannot find the target channel, it means that the `current->target` topology edge is removed,
// so we need to remove the replicate pchannel and stop replicate.
err := resource.Resource().ReplicationCatalog().RemoveReplicatePChannel(r.ctx, r.replicateInfo)
etcdCli := resource.Resource().ETCD()
ok, err := meta.RemoveReplicatePChannelWithRevision(r.ctx, etcdCli, r.channel.Key, r.channel.ModRevision)
if err != nil {
panic(fmt.Sprintf("failed to remove replicate pchannel: %v", err))
logger.Warn("failed to remove replicate pchannel", zap.Error(err))
// When performing delete operation on etcd, the context may be canceled by the delete event
// in cdc controller and then return `context.Canceled` error.
// Since the delete event is generated after the delete operation is committed in etcd,
// the delete is guaranteed to have succeeded on the server side.
// So we can ignore the context canceled error here.
if !errors.Is(err, context.Canceled) {
panic(fmt.Sprintf("failed to remove replicate pchannel: %v", err))
}
}
if ok {
logger.Info("handle AlterReplicateConfigMessage done, replicate pchannel removed")
} else {
logger.Info("handle AlterReplicateConfigMessage done, revision not match, replicate pchannel not removed")
}
logger.Info("handle AlterReplicateConfigMessage done, replicate pchannel removed")
return true
}
logger.Info("target channel found, skip handle AlterReplicateConfigMessage")
return false
}
func (r *replicateStreamClient) BlockUntilFinish() {
<-r.finishedCh
}
func (r *replicateStreamClient) Close() {
r.cancel()
<-r.finishedCh

View File

@ -19,6 +19,7 @@ package replicatestream
import (
"context"
"strconv"
"sync"
"testing"
"time"
@ -30,7 +31,7 @@ import (
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
milvuspb "github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
"github.com/milvus-io/milvus/internal/cdc/cluster"
"github.com/milvus-io/milvus/internal/cdc/resource"
"github.com/milvus-io/milvus/internal/cdc/meta"
"github.com/milvus-io/milvus/internal/distributed/streaming"
"github.com/milvus-io/milvus/internal/mocks/distributed/mock_streaming"
mock_message "github.com/milvus-io/milvus/pkg/v2/mocks/streaming/util/mock_message"
@ -55,23 +56,22 @@ func TestReplicateStreamClient_Replicate(t *testing.T) {
mockMilvusClient := cluster.NewMockMilvusClient(t)
mockMilvusClient.EXPECT().CreateReplicateStream(mock.Anything).Return(mockStreamClient, nil)
mockClusterClient := cluster.NewMockClusterClient(t)
mockClusterClient.EXPECT().CreateMilvusClient(mock.Anything, mock.Anything).
Return(mockMilvusClient, nil)
resource.InitForTest(t,
resource.OptClusterClient(mockClusterClient),
)
wal := mock_streaming.NewMockWALAccesser(t)
streaming.SetWALForTest(wal)
replicateInfo := &streamingpb.ReplicatePChannelMeta{
repMeta := &streamingpb.ReplicatePChannelMeta{
SourceChannelName: "test-source-channel",
TargetChannelName: "test-target-channel",
TargetCluster: targetCluster,
}
replicateClient := NewReplicateStreamClient(ctx, replicateInfo)
key := "test-replicate-key"
channel := &meta.ReplicateChannel{
Key: key,
Value: repMeta,
ModRevision: 0,
}
replicateClient := NewReplicateStreamClient(ctx, mockMilvusClient, channel)
defer replicateClient.Close()
// Test Replicate method
const msgCount = pendingMessageQueueLength * 10
@ -101,8 +101,10 @@ func TestReplicateStreamClient_Replicate(t *testing.T) {
mockStreamClient.ExpectRecv()
}
assert.Equal(t, msgCount, mockStreamClient.GetRecvCount())
assert.Equal(t, 0, replicateClient.(*replicateStreamClient).pendingMessages.Len())
replicateClient.Close()
assert.Eventually(t, func() bool {
return replicateClient.(*replicateStreamClient).pendingMessages.Len() == 0
}, time.Second, 100*time.Millisecond)
mockStreamClient.Close()
}
func TestReplicateStreamClient_Replicate_ContextCanceled(t *testing.T) {
@ -121,23 +123,21 @@ func TestReplicateStreamClient_Replicate_ContextCanceled(t *testing.T) {
mockMilvusClient.EXPECT().CreateReplicateStream(mock.Anything).Return(mockStreamClient, nil).Maybe()
mockMilvusClient.EXPECT().Close(mock.Anything).Return(nil).Maybe()
mockClusterClient := cluster.NewMockClusterClient(t)
mockClusterClient.EXPECT().CreateMilvusClient(mock.Anything, mock.Anything).
Return(mockMilvusClient, nil).Maybe()
resource.InitForTest(t,
resource.OptClusterClient(mockClusterClient),
)
wal := mock_streaming.NewMockWALAccesser(t)
streaming.SetWALForTest(wal)
replicateInfo := &streamingpb.ReplicatePChannelMeta{
key := "test-replicate-key"
repMeta := &streamingpb.ReplicatePChannelMeta{
SourceChannelName: "test-source-channel",
TargetChannelName: "test-target-channel",
TargetCluster: targetCluster,
}
client := NewReplicateStreamClient(ctx, replicateInfo)
channel := &meta.ReplicateChannel{
Key: key,
Value: repMeta,
ModRevision: 0,
}
client := NewReplicateStreamClient(ctx, mockMilvusClient, channel)
defer client.Close()
// Cancel context
@ -172,24 +172,23 @@ func TestReplicateStreamClient_Reconnect(t *testing.T) {
return mockStreamClient, nil
}).Times(reconnectTimes) // expect to be called reconnectTimes times
mockClusterClient := cluster.NewMockClusterClient(t)
mockClusterClient.EXPECT().CreateMilvusClient(mock.Anything, mock.Anything).
Return(mockMilvusClient, nil)
resource.InitForTest(t,
resource.OptClusterClient(mockClusterClient),
)
wal := mock_streaming.NewMockWALAccesser(t)
streaming.SetWALForTest(wal)
// Create client which will start internal retry loop
replicateInfo := &streamingpb.ReplicatePChannelMeta{
key := "test-replicate-key"
repMeta := &streamingpb.ReplicatePChannelMeta{
SourceChannelName: "test-source-channel",
TargetChannelName: "test-target-channel",
TargetCluster: targetCluster,
}
replicateClient := NewReplicateStreamClient(ctx, replicateInfo)
channel := &meta.ReplicateChannel{
Key: key,
Value: repMeta,
ModRevision: 0,
}
replicateClient := NewReplicateStreamClient(ctx, mockMilvusClient, channel)
defer replicateClient.Close()
// Replicate after reconnected
const msgCount = 100
@ -218,8 +217,10 @@ func TestReplicateStreamClient_Reconnect(t *testing.T) {
mockStreamClient.ExpectRecv()
}
assert.Equal(t, msgCount, mockStreamClient.GetRecvCount())
assert.Equal(t, 0, replicateClient.(*replicateStreamClient).pendingMessages.Len())
replicateClient.Close()
assert.Eventually(t, func() bool {
return replicateClient.(*replicateStreamClient).pendingMessages.Len() == 0
}, time.Second, 100*time.Millisecond)
mockStreamClient.Close()
}
// mockReplicateStreamClient implements the milvuspb.MilvusService_CreateReplicateStreamClient interface
@ -234,7 +235,8 @@ type mockReplicateStreamClient struct {
t *testing.T
timeout time.Duration
closeCh chan struct{}
closeOnce sync.Once
closeCh chan struct{}
}
func newMockReplicateStreamClient(t *testing.T) *mockReplicateStreamClient {
@ -244,6 +246,7 @@ func newMockReplicateStreamClient(t *testing.T) *mockReplicateStreamClient {
t: t,
timeout: 10 * time.Second,
closeCh: make(chan struct{}, 1),
closeOnce: sync.Once{},
}
}
@ -313,10 +316,18 @@ func (m *mockReplicateStreamClient) Trailer() metadata.MD {
}
func (m *mockReplicateStreamClient) CloseSend() error {
close(m.closeCh)
m.closeOnce.Do(func() {
close(m.closeCh)
})
return nil
}
func (m *mockReplicateStreamClient) Context() context.Context {
return context.Background()
}
func (m *mockReplicateStreamClient) Close() {
m.closeOnce.Do(func() {
close(m.closeCh)
})
}

View File

@ -19,12 +19,9 @@ package resource
import (
"reflect"
"github.com/milvus-io/milvus/internal/cdc/cluster"
"github.com/milvus-io/milvus/internal/cdc/controller"
clientv3 "go.etcd.io/etcd/client/v3"
"github.com/milvus-io/milvus/internal/cdc/replication"
"github.com/milvus-io/milvus/internal/metastore"
"github.com/milvus-io/milvus/internal/metastore/kv/streamingcoord"
"github.com/milvus-io/milvus/pkg/v2/kv"
)
var r *resourceImpl // singleton resource instance
@ -32,10 +29,10 @@ var r *resourceImpl // singleton resource instance
// optResourceInit is the option to initialize the resource.
type optResourceInit func(r *resourceImpl)
// OptMetaKV provides the meta kv to the resource.
func OptMetaKV(metaKV kv.MetaKv) optResourceInit {
// OptETCD provides the etcd client to the resource.
func OptETCD(etcd *clientv3.Client) optResourceInit {
return func(r *resourceImpl) {
r.metaKV = metaKV
r.etcdClient = etcd
}
}
@ -46,27 +43,6 @@ func OptReplicateManagerClient(replicateManagerClient replication.ReplicateManag
}
}
// OptReplicationCatalog provides the replication catalog to the resource.
func OptReplicationCatalog(catalog metastore.ReplicationCatalog) optResourceInit {
return func(r *resourceImpl) {
r.catalog = catalog
}
}
// OptClusterClient provides the cluster client to the resource.
func OptClusterClient(clusterClient cluster.ClusterClient) optResourceInit {
return func(r *resourceImpl) {
r.clusterClient = clusterClient
}
}
// OptController provides the controller to the resource.
func OptController(controller controller.Controller) optResourceInit {
return func(r *resourceImpl) {
r.controller = controller
}
}
// Done finish all initialization of resources.
func Init(opts ...optResourceInit) {
newR := &resourceImpl{}
@ -74,14 +50,8 @@ func Init(opts ...optResourceInit) {
opt(newR)
}
newR.catalog = streamingcoord.NewReplicationCatalog(newR.MetaKV())
newR.clusterClient = cluster.NewClusterClient()
assertNotNil(newR.MetaKV())
assertNotNil(newR.ReplicationCatalog())
assertNotNil(newR.ClusterClient())
assertNotNil(newR.ETCD())
assertNotNil(newR.ReplicateManagerClient())
assertNotNil(newR.Controller())
r = newR
}
@ -96,26 +66,13 @@ func Resource() *resourceImpl {
// resourceImpl is a basic resource dependency for streamingnode server.
// All utility on it is concurrent-safe and singleton.
type resourceImpl struct {
metaKV kv.MetaKv
catalog metastore.ReplicationCatalog
clusterClient cluster.ClusterClient
etcdClient *clientv3.Client
replicateManagerClient replication.ReplicateManagerClient
controller controller.Controller
}
// MetaKV returns the meta kv.
func (r *resourceImpl) MetaKV() kv.MetaKv {
return r.metaKV
}
// ReplicationCatalog returns the replication catalog.
func (r *resourceImpl) ReplicationCatalog() metastore.ReplicationCatalog {
return r.catalog
}
// ClusterClient returns the cluster client.
func (r *resourceImpl) ClusterClient() cluster.ClusterClient {
return r.clusterClient
// ETCD returns the etcd client.
func (r *resourceImpl) ETCD() *clientv3.Client {
return r.etcdClient
}
// ReplicateManagerClient returns the replicate manager client.
@ -123,11 +80,6 @@ func (r *resourceImpl) ReplicateManagerClient() replication.ReplicateManagerClie
return r.replicateManagerClient
}
// Controller returns the controller.
func (r *resourceImpl) Controller() controller.Controller {
return r.controller
}
// assertNotNil panics if the resource is nil.
func assertNotNil(v interface{}) {
iv := reflect.ValueOf(v)

View File

@ -6,11 +6,9 @@ package resource
import (
"testing"
"github.com/milvus-io/milvus/internal/cdc/cluster"
"github.com/milvus-io/milvus/internal/cdc/controller"
clientv3 "go.etcd.io/etcd/client/v3"
"github.com/milvus-io/milvus/internal/cdc/replication"
"github.com/milvus-io/milvus/internal/mocks/mock_metastore"
"github.com/milvus-io/milvus/pkg/v2/mocks/mock_kv"
)
// InitForTest initializes the singleton of resources for test.
@ -19,19 +17,10 @@ func InitForTest(t *testing.T, opts ...optResourceInit) {
for _, opt := range opts {
opt(r)
}
if r.metaKV == nil {
r.metaKV = mock_kv.NewMockMetaKv(t)
}
if r.catalog == nil {
r.catalog = mock_metastore.NewMockReplicationCatalog(t)
}
if r.clusterClient == nil {
r.clusterClient = cluster.NewMockClusterClient(t)
if r.etcdClient == nil {
r.etcdClient = &clientv3.Client{}
}
if r.replicateManagerClient == nil {
r.replicateManagerClient = replication.NewMockReplicateManagerClient(t)
}
if r.controller == nil {
r.controller = controller.NewMockController(t)
}
}

View File

@ -19,37 +19,39 @@ package cdc
import (
"context"
"github.com/milvus-io/milvus/internal/cdc/resource"
"go.uber.org/zap"
"github.com/milvus-io/milvus/internal/cdc/controller"
"github.com/milvus-io/milvus/pkg/v2/log"
)
type CDCServer struct {
ctx context.Context
ctx context.Context
controller controller.Controller
}
// NewCDCServer will return a CDCServer.
func NewCDCServer(ctx context.Context) *CDCServer {
return &CDCServer{
ctx: ctx,
ctx: ctx,
controller: controller.NewController(),
}
}
// Init initializes the CDCServer.
func (svr *CDCServer) Init() error {
log.Ctx(svr.ctx).Info("CDCServer init successfully")
return nil
}
// Start starts CDCServer.
func (svr *CDCServer) Start() error {
resource.Resource().Controller().Start()
err := svr.controller.Start()
if err != nil {
log.Ctx(svr.ctx).Error("start CDC controller failed", zap.Error(err))
return err
}
log.Ctx(svr.ctx).Info("CDCServer start successfully")
return nil
}
// Stop stops CDCServer.
func (svr *CDCServer) Stop() error {
resource.Resource().Controller().Stop()
svr.controller.Stop()
log.Ctx(svr.ctx).Info("CDCServer stop successfully")
return nil
}

23
internal/cdc/util/util.go Normal file
View File

@ -0,0 +1,23 @@
package util
import (
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
"github.com/milvus-io/milvus/pkg/v2/util/replicateutil"
)
func IsReplicationRemovedByAlterReplicateConfigMessage(msg message.ImmutableMessage, replicateInfo *streamingpb.ReplicatePChannelMeta) (replicationRemoved bool) {
prcMsg := message.MustAsImmutableAlterReplicateConfigMessageV2(msg)
replicateConfig := prcMsg.Header().ReplicateConfiguration
currentClusterID := paramtable.Get().CommonCfg.ClusterPrefix.GetValue()
currentCluster := replicateutil.MustNewConfigHelper(currentClusterID, replicateConfig).GetCurrentCluster()
_, err := currentCluster.GetTargetChannel(replicateInfo.GetSourceChannelName(),
replicateInfo.GetTargetCluster().GetClusterId())
if err != nil {
// Cannot find the target channel, it means that the `current->target` topology edge is removed,
// it means that the replication is removed.
return true
}
return false
}

View File

@ -113,14 +113,14 @@ func (s *mixCoordImpl) Register() error {
afterRegister := func() {
metrics.NumNodes.WithLabelValues(fmt.Sprint(paramtable.GetNodeID()), typeutil.MixCoordRole).Inc()
log.Info("MixCoord Register Finished")
s.session.LivenessCheck(s.ctx, func() {
log.Error("MixCoord disconnected from etcd, process will exit", zap.Int64("serverID", s.session.GetServerID()))
os.Exit(1)
})
}
if s.enableActiveStandBy {
go func() {
if err := s.session.ProcessActiveStandBy(s.activateFunc); err != nil {
if s.ctx.Err() == context.Canceled {
log.Info("standby process canceled due to server shutdown")
return
}
log.Error("failed to activate standby server", zap.Error(err))
panic(err)
}

View File

@ -9,7 +9,6 @@ import (
"sync"
"github.com/cockroachdb/errors"
"github.com/pingcap/log"
"github.com/samber/lo"
"go.uber.org/zap"
@ -18,6 +17,7 @@ import (
"github.com/milvus-io/milvus/internal/distributed/streaming"
management "github.com/milvus-io/milvus/internal/http"
"github.com/milvus-io/milvus/internal/json"
"github.com/milvus-io/milvus/pkg/v2/log"
"github.com/milvus-io/milvus/pkg/v2/proto/datapb"
"github.com/milvus-io/milvus/pkg/v2/proto/querypb"
"github.com/milvus-io/milvus/pkg/v2/util/commonpbutil"

View File

@ -67,6 +67,7 @@ type StreamingNodeManager struct {
cond *syncutil.ContextCond
latestAssignments map[string]types.PChannelInfoAssigned // The latest assignments info got from streaming coord balance module.
nodeChangedNotifier *syncutil.VersionedNotifier // used to notify that node in streaming node manager has been changed.
previousNodeIDs typeutil.UniqueSet // used to store the previous node ids.
}
// GetBalancer returns the balancer of the streaming node manager.
@ -78,6 +79,15 @@ func (s *StreamingNodeManager) GetBalancer() balancer.Balancer {
return b
}
// AllocVirtualChannels allocates virtual channels for a collection.
func (s *StreamingNodeManager) AllocVirtualChannels(ctx context.Context, param balancer.AllocVChannelParam) ([]string, error) {
balancer, err := balance.GetWithContext(ctx)
if err != nil {
return nil, err
}
return balancer.AllocVirtualChannels(ctx, param)
}
// GetLatestWALLocated returns the server id of the node that the wal of the vChannel is located.
// Return -1 and error if the vchannel is not found or context is canceled.
func (s *StreamingNodeManager) GetLatestWALLocated(ctx context.Context, vchannel string) (int64, error) {
@ -142,12 +152,15 @@ func (s *StreamingNodeManager) GetStreamingQueryNodeIDs() typeutil.UniqueSet {
}
streamingNodes, err := balancer.GetAllStreamingNodes(context.Background())
if err != nil {
panic(err)
// when the streaming coord is on shutdown, the balancer will return an error,
// causing panic, so we need to return the previous node ids.
return s.previousNodeIDs
}
streamingNodeIDs := typeutil.NewUniqueSet()
for _, streamingNode := range streamingNodes {
streamingNodeIDs.Insert(streamingNode.ServerID)
}
s.previousNodeIDs = streamingNodeIDs
return streamingNodeIDs
}

View File

@ -189,6 +189,7 @@ test_run() {
std::string root_path = "/tmp/test-kmeans-clustering/";
auto storage_config = gen_local_storage_config(root_path);
auto cm = storage::CreateChunkManager(storage_config);
auto fs = storage::InitArrowFileSystem(storage_config);
std::vector<T> data_gen(nb * dim);
for (int64_t i = 0; i < nb * dim; ++i) {
@ -216,7 +217,7 @@ test_run() {
auto log_path = get_binlog_path(0);
auto cm_w = ChunkManagerWrapper(cm);
cm_w.Write(log_path, serialized_bytes.data(), serialized_bytes.size());
storage::FileManagerContext ctx(field_meta, index_meta, cm);
storage::FileManagerContext ctx(field_meta, index_meta, cm, fs);
std::map<int64_t, std::vector<std::string>> remote_files;
std::map<int64_t, int64_t> num_rows;

View File

@ -21,6 +21,7 @@
#include "types.h"
#include "index/Utils.h"
#include "index/Meta.h"
#include "storage/StorageV2FSCache.h"
#include "storage/Util.h"
#include "pb/clustering.pb.h"
#include "monitor/scope_metric.h"
@ -48,6 +49,8 @@ get_storage_config(const milvus::proto::clustering::StorageConfig& config) {
storage_config.requestTimeoutMs = config.request_timeout_ms();
storage_config.gcp_credential_json =
std::string(config.gcpcredentialjson());
storage_config.max_connections = config.max_connections();
return storage_config;
}
@ -78,9 +81,30 @@ Analyze(CAnalyze* res_analyze,
get_storage_config(analyze_info->storage_config());
auto chunk_manager =
milvus::storage::CreateChunkManager(storage_config);
auto fs = milvus::storage::StorageV2FSCache::Instance().Get({
storage_config.address,
storage_config.bucket_name,
storage_config.access_key_id,
storage_config.access_key_value,
storage_config.root_path,
storage_config.storage_type,
storage_config.cloud_provider,
storage_config.iam_endpoint,
storage_config.log_level,
storage_config.region,
storage_config.useSSL,
storage_config.sslCACert,
storage_config.useIAM,
storage_config.useVirtualHost,
storage_config.requestTimeoutMs,
false,
storage_config.gcp_credential_json,
false,
storage_config.max_connections,
});
milvus::storage::FileManagerContext fileManagerContext(
field_meta, index_meta, chunk_manager);
field_meta, index_meta, chunk_manager, fs);
if (field_type != DataType::VECTOR_FLOAT) {
throw SegcoreError(

View File

@ -296,11 +296,12 @@ class Array {
return offsets_ptr_.get();
}
ScalarFieldProto
output_data() const {
ScalarFieldProto data_array;
void
output_data(ScalarFieldProto& data_array) const {
switch (element_type_) {
case DataType::BOOL: {
data_array.mutable_bool_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<bool>(j);
data_array.mutable_bool_data()->add_data(element);
@ -310,6 +311,7 @@ class Array {
case DataType::INT8:
case DataType::INT16:
case DataType::INT32: {
data_array.mutable_int_data()->mutable_data()->Reserve(length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<int>(j);
data_array.mutable_int_data()->add_data(element);
@ -317,6 +319,8 @@ class Array {
break;
}
case DataType::INT64: {
data_array.mutable_long_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<int64_t>(j);
data_array.mutable_long_data()->add_data(element);
@ -325,13 +329,18 @@ class Array {
}
case DataType::STRING:
case DataType::VARCHAR: {
data_array.mutable_string_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<std::string>(j);
data_array.mutable_string_data()->add_data(element);
auto element = get_data<std::string_view>(j);
data_array.mutable_string_data()->add_data(element.data(),
element.size());
}
break;
}
case DataType::FLOAT: {
data_array.mutable_float_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<float>(j);
data_array.mutable_float_data()->add_data(element);
@ -339,6 +348,8 @@ class Array {
break;
}
case DataType::DOUBLE: {
data_array.mutable_double_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<double>(j);
data_array.mutable_double_data()->add_data(element);
@ -346,9 +357,12 @@ class Array {
break;
}
case DataType::GEOMETRY: {
data_array.mutable_geometry_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<std::string>(j);
data_array.mutable_geometry_data()->add_data(element);
auto element = get_data<std::string_view>(j);
data_array.mutable_geometry_data()->add_data(
element.data(), element.size());
}
break;
}
@ -356,6 +370,12 @@ class Array {
// empty array
}
}
}
ScalarFieldProto
output_data() const {
ScalarFieldProto data_array;
output_data(data_array);
return data_array;
}
@ -541,11 +561,12 @@ class ArrayView {
return reinterpret_cast<T*>(data_)[index];
}
ScalarFieldProto
output_data() const {
ScalarFieldProto data_array;
void
output_data(ScalarFieldProto& data_array) const {
switch (element_type_) {
case DataType::BOOL: {
data_array.mutable_bool_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<bool>(j);
data_array.mutable_bool_data()->add_data(element);
@ -555,6 +576,7 @@ class ArrayView {
case DataType::INT8:
case DataType::INT16:
case DataType::INT32: {
data_array.mutable_int_data()->mutable_data()->Reserve(length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<int>(j);
data_array.mutable_int_data()->add_data(element);
@ -562,6 +584,8 @@ class ArrayView {
break;
}
case DataType::INT64: {
data_array.mutable_long_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<int64_t>(j);
data_array.mutable_long_data()->add_data(element);
@ -570,13 +594,18 @@ class ArrayView {
}
case DataType::STRING:
case DataType::VARCHAR: {
data_array.mutable_string_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<std::string>(j);
data_array.mutable_string_data()->add_data(element);
auto element = get_data<std::string_view>(j);
data_array.mutable_string_data()->add_data(element.data(),
element.size());
}
break;
}
case DataType::FLOAT: {
data_array.mutable_float_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<float>(j);
data_array.mutable_float_data()->add_data(element);
@ -584,6 +613,8 @@ class ArrayView {
break;
}
case DataType::DOUBLE: {
data_array.mutable_double_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<double>(j);
data_array.mutable_double_data()->add_data(element);
@ -591,9 +622,12 @@ class ArrayView {
break;
}
case DataType::GEOMETRY: {
data_array.mutable_geometry_data()->mutable_data()->Reserve(
length_);
for (int j = 0; j < length_; ++j) {
auto element = get_data<std::string>(j);
data_array.mutable_geometry_data()->add_data(element);
auto element = get_data<std::string_view>(j);
data_array.mutable_geometry_data()->add_data(
element.data(), element.size());
}
break;
}
@ -601,6 +635,12 @@ class ArrayView {
// empty array
}
}
}
ScalarFieldProto
output_data() const {
ScalarFieldProto data_array;
output_data(data_array);
return data_array;
}

View File

@ -38,6 +38,39 @@ namespace milvus {
constexpr uint64_t MMAP_STRING_PADDING = 1;
constexpr uint64_t MMAP_GEOMETRY_PADDING = 1;
constexpr uint64_t MMAP_ARRAY_PADDING = 1;
// Shared mmap region manager for group chunks
class ChunkMmapGuard {
public:
ChunkMmapGuard(char* mmap_ptr, size_t mmap_size, std::string file_path)
: mmap_ptr_(mmap_ptr), mmap_size_(mmap_size), file_path_(file_path) {
}
~ChunkMmapGuard() {
if (mmap_ptr_ != nullptr) {
munmap(mmap_ptr_, mmap_size_);
}
if (!file_path_.empty()) {
unlink(file_path_.c_str());
}
}
char*
get_ptr() const {
return mmap_ptr_;
}
bool
is_file_backed() const {
return !file_path_.empty();
}
private:
char* mmap_ptr_;
size_t mmap_size_;
const std::string file_path_;
};
class Chunk {
public:
Chunk() = default;
@ -45,12 +78,12 @@ class Chunk {
char* data,
uint64_t size,
bool nullable,
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
: data_(data),
row_nums_(row_nums),
size_(size),
nullable_(nullable),
mmap_file_raii_(std::move(mmap_file_raii)) {
chunk_mmap_guard_(chunk_mmap_guard) {
if (nullable) {
valid_.reserve(row_nums);
for (int i = 0; i < row_nums; i++) {
@ -59,7 +92,7 @@ class Chunk {
}
}
virtual ~Chunk() {
munmap(data_, size_);
// The ChunkMmapGuard will handle the unmapping and unlinking of the file if it is file backed
}
uint64_t
@ -69,7 +102,7 @@ class Chunk {
cachinglayer::ResourceUsage
CellByteSize() const {
if (mmap_file_raii_) {
if (chunk_mmap_guard_ && chunk_mmap_guard_->is_file_backed()) {
return cachinglayer::ResourceUsage(0, static_cast<int64_t>(size_));
}
return cachinglayer::ResourceUsage(static_cast<int64_t>(size_), 0);
@ -109,7 +142,7 @@ class Chunk {
FixedVector<bool>
valid_; // parse null bitmap to valid_ to be compatible with SpanBase
std::unique_ptr<MmapFileRAII> mmap_file_raii_;
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard_{nullptr};
};
// for fixed size data, includes fixed size array
@ -121,8 +154,8 @@ class FixedWidthChunk : public Chunk {
uint64_t size,
uint64_t element_size,
bool nullable,
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
: Chunk(row_nums, data, size, nullable, std::move(mmap_file_raii)),
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
: Chunk(row_nums, data, size, nullable, chunk_mmap_guard),
dim_(dim),
element_size_(element_size) {
auto null_bitmap_bytes_num = nullable_ ? (row_nums_ + 7) / 8 : 0;
@ -181,8 +214,8 @@ class StringChunk : public Chunk {
char* data,
uint64_t size,
bool nullable,
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
: Chunk(row_nums, data, size, nullable, std::move(mmap_file_raii)) {
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
: Chunk(row_nums, data, size, nullable, chunk_mmap_guard) {
auto null_bitmap_bytes_num = nullable_ ? (row_nums_ + 7) / 8 : 0;
offsets_ = reinterpret_cast<uint32_t*>(data + null_bitmap_bytes_num);
}
@ -314,8 +347,8 @@ class ArrayChunk : public Chunk {
uint64_t size,
milvus::DataType element_type,
bool nullable,
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
: Chunk(row_nums, data, size, nullable, std::move(mmap_file_raii)),
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
: Chunk(row_nums, data, size, nullable, chunk_mmap_guard),
element_type_(element_type) {
auto null_bitmap_bytes_num = 0;
if (nullable) {
@ -431,18 +464,18 @@ class VectorArrayChunk : public Chunk {
char* data,
uint64_t size,
milvus::DataType element_type,
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
: Chunk(row_nums, data, size, false, std::move(mmap_file_raii)),
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
: Chunk(row_nums, data, size, false, chunk_mmap_guard),
dim_(dim),
element_type_(element_type) {
offsets_lens_ = reinterpret_cast<uint32_t*>(data);
auto offset = 0;
lims_.reserve(row_nums_ + 1);
lims_.push_back(offset);
offsets_.reserve(row_nums_ + 1);
offsets_.push_back(offset);
for (int64_t i = 0; i < row_nums_; i++) {
offset += offsets_lens_[i * 2 + 1];
lims_.push_back(offset);
offsets_.push_back(offset);
}
}
@ -507,30 +540,27 @@ class VectorArrayChunk : public Chunk {
}
const size_t*
Lims() const {
return lims_.data();
Offsets() const {
return offsets_.data();
}
private:
int64_t dim_;
uint32_t* offsets_lens_;
milvus::DataType element_type_;
// The name 'Lims' is consistent with knowhere::DataSet::SetLims which describes the number of vectors
// in each vector array (embedding list). This is needed as vectors are flattened in the chunk.
std::vector<size_t> lims_;
std::vector<size_t> offsets_;
};
class SparseFloatVectorChunk : public Chunk {
public:
SparseFloatVectorChunk(
int32_t row_nums,
char* data,
uint64_t size,
bool nullable,
std::unique_ptr<MmapFileRAII> mmap_file_raii = nullptr)
: Chunk(row_nums, data, size, nullable, std::move(mmap_file_raii)) {
SparseFloatVectorChunk(int32_t row_nums,
char* data,
uint64_t size,
bool nullable,
std::shared_ptr<ChunkMmapGuard> chunk_mmap_guard)
: Chunk(row_nums, data, size, nullable, chunk_mmap_guard) {
vec_.resize(row_nums);
auto null_bitmap_bytes_num = (row_nums + 7) / 8;
auto null_bitmap_bytes_num = nullable ? (row_nums + 7) / 8 : 0;
auto offsets_ptr =
reinterpret_cast<uint64_t*>(data + null_bitmap_bytes_num);
for (int i = 0; i < row_nums; i++) {

View File

@ -27,9 +27,9 @@ MemChunkTarget::write(const void* data, size_t size) {
size_ += size;
}
std::pair<char*, size_t>
MemChunkTarget::get() {
return {data_, cap_};
char*
MemChunkTarget::release() {
return data_;
}
size_t
@ -39,6 +39,11 @@ MemChunkTarget::tell() {
void
MmapChunkTarget::flush() {
if (cap_ > size_) {
std::string padding(cap_ - size_, 0);
file_writer_->Write(padding.data(), cap_ - size_);
size_ = cap_;
}
file_writer_->Finish();
}
@ -48,17 +53,17 @@ MmapChunkTarget::write(const void* data, size_t size) {
size_ += size;
}
std::pair<char*, size_t>
MmapChunkTarget::get() {
char*
MmapChunkTarget::release() {
flush();
auto file = File::Open(file_path_, O_RDWR);
auto m = mmap(nullptr, size_, PROT_READ, MAP_SHARED, file.Descriptor(), 0);
auto m = mmap(nullptr, cap_, PROT_READ, MAP_SHARED, file.Descriptor(), 0);
AssertInfo(m != MAP_FAILED,
"failed to map: {}, map_size={}",
strerror(errno),
size_);
return {static_cast<char*>(m), size_};
cap_);
return static_cast<char*>(m);
}
size_t

View File

@ -23,46 +23,66 @@
namespace milvus {
class ChunkTarget {
public:
virtual void
write(const void* data, size_t size) = 0;
virtual std::pair<char*, size_t>
get() = 0;
static constexpr size_t ALIGNED_SIZE = 4096; // 4KB
virtual ~ChunkTarget() = default;
/**
* @brief write data to the target at the current position
* @param data the data to write
* @param size the size of the data to write
*/
virtual void
write(const void* data, size_t size) = 0;
/**
* @brief release the data pointer to the caller
* @note no write() should be called after release()
* @return the data pointer
*/
virtual char*
release() = 0;
/**
* @brief get the current position of the target
* @return the current position
*/
virtual size_t
tell() = 0;
};
class MmapChunkTarget : public ChunkTarget {
public:
explicit MmapChunkTarget(std::string file_path)
: file_path_(std::move(file_path)) {
file_writer_ = std::make_unique<storage::FileWriter>(file_path_);
explicit MmapChunkTarget(std::string file_path,
size_t cap,
storage::io::Priority io_prio)
: file_path_(std::move(file_path)), cap_(cap) {
file_writer_ =
std::make_unique<storage::FileWriter>(file_path_, io_prio);
}
void
flush();
void
write(const void* data, size_t size) override;
std::pair<char*, size_t>
get() override;
char*
release() override;
size_t
tell() override;
private:
void
flush();
std::unique_ptr<storage::FileWriter> file_writer_{nullptr};
std::string file_path_{};
size_t size_ = 0;
size_t cap_{0};
size_t size_{0};
};
class MemChunkTarget : public ChunkTarget {
public:
MemChunkTarget(size_t cap) : cap_(cap) {
explicit MemChunkTarget(size_t cap) : cap_(cap) {
auto m = mmap(nullptr,
cap,
PROT_READ | PROT_WRITE,
@ -79,8 +99,8 @@ class MemChunkTarget : public ChunkTarget {
void
write(const void* data, size_t size) override;
std::pair<char*, size_t>
get() override;
char*
release() override;
size_t
tell() override;

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,6 @@
#include <cstddef>
#include <cstdint>
#include <memory>
#include <numeric>
#include <utility>
#include <vector>
#include "arrow/array/array_primitive.h"
@ -21,37 +20,26 @@
#include "common/ChunkTarget.h"
#include "arrow/record_batch.h"
#include "common/Chunk.h"
#include "common/EasyAssert.h"
#include "common/FieldDataInterface.h"
#include "storage/FileWriter.h"
#include "common/Geometry.h"
namespace milvus {
class ChunkWriterBase {
public:
explicit ChunkWriterBase(bool nullable) : nullable_(nullable) {
}
ChunkWriterBase(std::string file_path, bool nullable)
: file_path_(std::move(file_path)), nullable_(nullable) {
}
virtual std::pair<size_t, size_t>
calculate_size(const arrow::ArrayVector& data) = 0;
virtual void
write(const arrow::ArrayVector& data) = 0;
virtual std::unique_ptr<Chunk>
finish() = 0;
std::pair<char*, size_t>
get_data() {
return target_->get();
}
write_to_target(const arrow::ArrayVector& array_vec,
const std::shared_ptr<ChunkTarget>& target) = 0;
protected:
void
write_null_bit_maps(
const std::vector<std::tuple<const uint8_t*, int64_t, int64_t>>&
null_bitmaps) {
null_bitmaps,
const std::shared_ptr<ChunkTarget>& target) {
if (nullable_) {
// merge all null bitmaps in case of multiple chunk null bitmap dislocation
// say [0xFF, 0x00] with size [7, 8] cannot be treated as [0xFF, 0x00] after merged but
@ -81,15 +69,13 @@ class ChunkWriterBase {
}
size_total_bit += size_bits;
}
target_->write(merged_null_bitmap.data(), (size_total_bit + 7) / 8);
target->write(merged_null_bitmap.data(), (size_total_bit + 7) / 8);
}
}
protected:
int row_nums_ = 0;
std::string file_path_{""};
size_t row_nums_ = 0;
bool nullable_ = false;
std::shared_ptr<ChunkTarget> target_;
};
template <typename ArrowType, typename T>
@ -98,30 +84,25 @@ class ChunkWriter final : public ChunkWriterBase {
ChunkWriter(int dim, bool nullable) : ChunkWriterBase(nullable), dim_(dim) {
}
ChunkWriter(int dim, std::string file_path, bool nullable)
: ChunkWriterBase(std::move(file_path), nullable), dim_(dim){};
void
write(const arrow::ArrayVector& array_vec) override {
auto size = 0;
auto row_nums = 0;
std::pair<size_t, size_t>
calculate_size(const arrow::ArrayVector& array_vec) override {
size_t size = 0;
size_t row_nums = 0;
for (const auto& data : array_vec) {
row_nums += data->length();
auto array = std::static_pointer_cast<ArrowType>(data);
if (nullable_) {
auto null_bitmap_n = (data->length() + 7) / 8;
size += null_bitmap_n;
}
size += array->length() * dim_ * sizeof(T);
}
row_nums_ = row_nums;
if (!file_path_.empty()) {
target_ = std::make_shared<MmapChunkTarget>(file_path_);
} else {
target_ = std::make_shared<MemChunkTarget>(size);
if (nullable_) {
size += (row_nums + 7) / 8;
}
row_nums_ = row_nums;
return {size, row_nums};
}
void
write_to_target(const arrow::ArrayVector& array_vec,
const std::shared_ptr<ChunkTarget>& target) override {
// Chunk layout:
// 1. Null bitmap (if nullable_=true): Indicates which values are null
// 2. Data values: Contiguous storage of data elements in the order:
@ -134,55 +115,25 @@ class ChunkWriter final : public ChunkWriterBase {
null_bitmaps.emplace_back(
data->null_bitmap_data(), data->length(), data->offset());
}
write_null_bit_maps(null_bitmaps);
write_null_bit_maps(null_bitmaps, target);
}
for (const auto& data : array_vec) {
auto array = std::static_pointer_cast<ArrowType>(data);
auto data_ptr = array->raw_values();
target_->write(data_ptr, array->length() * dim_ * sizeof(T));
target->write(data_ptr, array->length() * dim_ * sizeof(T));
}
}
std::unique_ptr<Chunk>
finish() override {
auto [data, size] = target_->get();
auto mmap_file_raii = file_path_.empty()
? nullptr
: std::make_unique<MmapFileRAII>(file_path_);
return std::make_unique<FixedWidthChunk>(row_nums_,
dim_,
data,
size,
sizeof(T),
nullable_,
std::move(mmap_file_raii));
}
private:
int dim_;
const int64_t dim_;
};
template <>
inline void
ChunkWriter<arrow::BooleanArray, bool>::write(
const arrow::ArrayVector& array_vec) {
auto size = 0;
auto row_nums = 0;
for (const auto& data : array_vec) {
row_nums += data->length();
auto array = std::dynamic_pointer_cast<arrow::BooleanArray>(data);
size += array->length() * dim_;
size += (data->length() + 7) / 8;
}
row_nums_ = row_nums;
if (!file_path_.empty()) {
target_ = std::make_shared<MmapChunkTarget>(file_path_);
} else {
target_ = std::make_shared<MemChunkTarget>(size);
}
ChunkWriter<arrow::BooleanArray, bool>::write_to_target(
const arrow::ArrayVector& array_vec,
const std::shared_ptr<ChunkTarget>& target) {
if (nullable_) {
// tuple <data, size, offset>
std::vector<std::tuple<const uint8_t*, int64_t, int64_t>> null_bitmaps;
@ -190,14 +141,14 @@ ChunkWriter<arrow::BooleanArray, bool>::write(
null_bitmaps.emplace_back(
data->null_bitmap_data(), data->length(), data->offset());
}
write_null_bit_maps(null_bitmaps);
write_null_bit_maps(null_bitmaps, target);
}
for (const auto& data : array_vec) {
auto array = std::dynamic_pointer_cast<arrow::BooleanArray>(data);
for (int i = 0; i < array->length(); i++) {
auto value = array->Value(i);
target_->write(&value, sizeof(bool));
target->write(&value, sizeof(bool));
}
}
}
@ -206,32 +157,39 @@ class StringChunkWriter : public ChunkWriterBase {
public:
using ChunkWriterBase::ChunkWriterBase;
void
write(const arrow::ArrayVector& array_vec) override;
std::pair<size_t, size_t>
calculate_size(const arrow::ArrayVector& array_vec) override;
std::unique_ptr<Chunk>
finish() override;
void
write_to_target(const arrow::ArrayVector& array_vec,
const std::shared_ptr<ChunkTarget>& target) override;
private:
std::vector<std::string_view> strs_;
};
class JSONChunkWriter : public ChunkWriterBase {
public:
using ChunkWriterBase::ChunkWriterBase;
void
write(const arrow::ArrayVector& array_vec) override;
std::pair<size_t, size_t>
calculate_size(const arrow::ArrayVector& array_vec) override;
std::unique_ptr<Chunk>
finish() override;
void
write_to_target(const arrow::ArrayVector& array_vec,
const std::shared_ptr<ChunkTarget>& target) override;
};
class GeometryChunkWriter : public ChunkWriterBase {
public:
using ChunkWriterBase::ChunkWriterBase;
void
write(const arrow::ArrayVector& array_vec) override;
std::unique_ptr<Chunk>
finish() override;
std::pair<size_t, size_t>
calculate_size(const arrow::ArrayVector& array_vec) override;
void
write_to_target(const arrow::ArrayVector& array_vec,
const std::shared_ptr<ChunkTarget>& target) override;
};
class ArrayChunkWriter : public ChunkWriterBase {
@ -239,18 +197,13 @@ class ArrayChunkWriter : public ChunkWriterBase {
ArrayChunkWriter(const milvus::DataType element_type, bool nullable)
: ChunkWriterBase(nullable), element_type_(element_type) {
}
ArrayChunkWriter(const milvus::DataType element_type,
std::string file_path,
bool nullable)
: ChunkWriterBase(std::move(file_path), nullable),
element_type_(element_type) {
}
std::pair<size_t, size_t>
calculate_size(const arrow::ArrayVector& array_vec) override;
void
write(const arrow::ArrayVector& array_vec) override;
std::unique_ptr<Chunk>
finish() override;
write_to_target(const arrow::ArrayVector& array_vec,
const std::shared_ptr<ChunkTarget>& target) override;
private:
const milvus::DataType element_type_;
@ -258,49 +211,48 @@ class ArrayChunkWriter : public ChunkWriterBase {
class VectorArrayChunkWriter : public ChunkWriterBase {
public:
VectorArrayChunkWriter(int64_t dim,
const milvus::DataType element_type,
std::string file_path = "")
: ChunkWriterBase(std::move(file_path), false),
element_type_(element_type),
dim_(dim) {
VectorArrayChunkWriter(int64_t dim, const milvus::DataType element_type)
: ChunkWriterBase(false), element_type_(element_type), dim_(dim) {
}
void
write(const arrow::ArrayVector& array_vec) override;
std::pair<size_t, size_t>
calculate_size(const arrow::ArrayVector& array_vec) override;
std::unique_ptr<Chunk>
finish() override;
void
write_to_target(const arrow::ArrayVector& array_vec,
const std::shared_ptr<ChunkTarget>& target) override;
private:
void
writeFloatVectorArray(const arrow::ArrayVector& array_vec);
size_t
calculateTotalSize(const arrow::ArrayVector& array_vec);
const milvus::DataType element_type_;
int64_t dim_;
const int64_t dim_;
};
class SparseFloatVectorChunkWriter : public ChunkWriterBase {
public:
using ChunkWriterBase::ChunkWriterBase;
std::pair<size_t, size_t>
calculate_size(const arrow::ArrayVector& array_vec) override;
void
write(const arrow::ArrayVector& array_vec) override;
std::unique_ptr<Chunk>
finish() override;
write_to_target(const arrow::ArrayVector& array_vec,
const std::shared_ptr<ChunkTarget>& target) override;
};
std::unique_ptr<Chunk>
create_chunk(const FieldMeta& field_meta, const arrow::ArrayVector& array_vec);
std::unique_ptr<Chunk>
create_chunk(const FieldMeta& field_meta,
const arrow::ArrayVector& array_vec,
const std::string& file_path);
const std::string& file_path = "",
proto::common::LoadPriority load_priority =
proto::common::LoadPriority::HIGH);
std::unordered_map<FieldId, std::shared_ptr<Chunk>>
create_group_chunk(const std::vector<FieldId>& field_ids,
const std::vector<FieldMeta>& field_metas,
const std::vector<arrow::ArrayVector>& array_vec,
const std::string& file_path = "",
proto::common::LoadPriority load_priority =
proto::common::LoadPriority::HIGH);
arrow::ArrayVector
read_single_column_batches(std::shared_ptr<arrow::RecordBatchReader> reader);

View File

@ -123,3 +123,6 @@ const int64_t DEFAULT_SHORT_COLUMN_GROUP_ID = 0;
// VectorArray related, used for fetch metadata from Arrow schema
const std::string ELEMENT_TYPE_KEY_FOR_ARROW = "elementType";
// EPSILON value for comparing float numbers
const float EPSILON = 0.0000000119;

View File

@ -25,6 +25,7 @@
#include "common/Exception.h"
#include "common/FieldDataInterface.h"
#include "common/Json.h"
#include "index/Utils.h"
#include "simdjson/padded_string.h"
namespace milvus {
@ -348,46 +349,47 @@ FieldDataImpl<Type, is_type_entire_row>::FillFieldData(
std::vector<VectorArray> values(element_count);
switch (element_type) {
case DataType::VECTOR_FLOAT: {
auto float_array =
std::dynamic_pointer_cast<arrow::FloatArray>(
case DataType::VECTOR_FLOAT:
case DataType::VECTOR_BINARY:
case DataType::VECTOR_FLOAT16:
case DataType::VECTOR_BFLOAT16:
case DataType::VECTOR_INT8: {
// All vector types use FixedSizeBinaryArray and have the same serialization logic
auto binary_array =
std::dynamic_pointer_cast<arrow::FixedSizeBinaryArray>(
values_array);
AssertInfo(
float_array != nullptr,
"Expected FloatArray for VECTOR_FLOAT element type");
AssertInfo(binary_array != nullptr,
"Expected FixedSizeBinaryArray for VectorArray "
"element");
// Calculate bytes per vector using the unified function
auto bytes_per_vec =
milvus::vector_bytes_per_element(element_type, dim);
for (size_t index = 0; index < element_count; ++index) {
int64_t start_offset = list_array->value_offset(index);
int64_t end_offset =
list_array->value_offset(index + 1);
int64_t num_floats = end_offset - start_offset;
AssertInfo(num_floats % dim == 0,
"Invalid data: number of floats ({}) not "
"divisible by "
"dimension ({})",
num_floats,
dim);
int64_t num_vectors = end_offset - start_offset;
int num_vectors = num_floats / dim;
const float* data_ptr =
float_array->raw_values() + start_offset;
values[index] =
VectorArray(static_cast<const void*>(data_ptr),
num_vectors,
dim,
element_type);
auto data_size = num_vectors * bytes_per_vec;
auto data_ptr = std::make_unique<uint8_t[]>(data_size);
for (int64_t i = 0; i < num_vectors; i++) {
const uint8_t* binary_data =
binary_array->GetValue(start_offset + i);
uint8_t* dest = data_ptr.get() + i * bytes_per_vec;
std::memcpy(dest, binary_data, bytes_per_vec);
}
values[index] = VectorArray(
static_cast<const void*>(data_ptr.get()),
num_vectors,
dim,
element_type);
}
break;
}
case DataType::VECTOR_BINARY:
case DataType::VECTOR_FLOAT16:
case DataType::VECTOR_BFLOAT16:
case DataType::VECTOR_INT8:
ThrowInfo(
NotImplemented,
"Element type {} in VectorArray not implemented yet",
GetDataTypeName(element_type));
break;
default:
ThrowInfo(DataTypeInvalid,
"Unsupported element type {} in VectorArray",

View File

@ -40,9 +40,6 @@
#include "common/TypeTraits.h"
namespace milvus {
using DataType = milvus::DataType;
class FieldDataBase {
public:
explicit FieldDataBase(DataType data_type, bool nullable)
@ -727,21 +724,32 @@ class FieldDataJsonImpl : public FieldDataImpl<Json, true> {
void
FillFieldData(const std::optional<DefaultValueType> default_value,
ssize_t element_count) override {
// todo: add json default_value
AssertInfo(!default_value.has_value(),
"json type not support default_value");
if (element_count == 0) {
return;
}
null_count_ = element_count;
std::lock_guard lck(tell_mutex_);
if (length_ + element_count > get_num_rows()) {
resize_field_data(length_ + element_count);
}
bitset::detail::ElementWiseBitsetPolicy<uint8_t>::op_fill(
valid_data_.data(), length_, element_count, false);
if (default_value.has_value()) {
AssertInfo(default_value->has_bytes_data(),
"json type default_value shall be bytes data");
auto data = default_value->bytes_data();
Json default_json = Json(data.data(), data.size());
std::fill(data_.data() + length_,
data_.data() + length_ + element_count,
default_json);
bitset::detail::ElementWiseBitsetPolicy<uint8_t>::op_fill(
valid_data_.data(), length_, element_count, true);
} else {
null_count_ = element_count;
bitset::detail::ElementWiseBitsetPolicy<uint8_t>::op_fill(
valid_data_.data(), length_, element_count, false);
}
length_ += element_count;
}

View File

@ -68,6 +68,65 @@ FieldMeta::get_analyzer_params() const {
return ParseTokenizerParams(params);
}
milvus::proto::schema::FieldSchema
FieldMeta::ToProto() const {
milvus::proto::schema::FieldSchema proto;
proto.set_fieldid(id_.get());
proto.set_name(name_.get());
proto.set_data_type(ToProtoDataType(type_));
proto.set_nullable(nullable_);
if (has_default_value()) {
*proto.mutable_default_value() = *default_value_;
}
if (element_type_ != DataType::NONE) {
proto.set_element_type(ToProtoDataType(element_type_));
}
auto add_type_param = [&proto](const std::string& key,
const std::string& value) {
auto* param = proto.add_type_params();
param->set_key(key);
param->set_value(value);
};
auto add_index_param = [&proto](const std::string& key,
const std::string& value) {
auto* param = proto.add_index_params();
param->set_key(key);
param->set_value(value);
};
if (type_ == DataType::VECTOR_ARRAY) {
add_type_param("dim", std::to_string(get_dim()));
if (auto metric = get_metric_type(); metric.has_value()) {
add_index_param("metric_type", metric.value());
}
} else if (IsVectorDataType(type_)) {
if (!IsSparseFloatVectorDataType(type_)) {
add_type_param("dim", std::to_string(get_dim()));
}
if (auto metric = get_metric_type(); metric.has_value()) {
add_index_param("metric_type", metric.value());
}
} else if (IsStringDataType(type_)) {
std::map<std::string, std::string> params;
if (string_info_.has_value()) {
params = string_info_->params;
}
params[MAX_LENGTH] = std::to_string(get_max_len());
params["enable_match"] = enable_match() ? "true" : "false";
params["enable_analyzer"] = enable_analyzer() ? "true" : "false";
for (const auto& [key, value] : params) {
add_type_param(key, value);
}
} else if (IsArrayDataType(type_)) {
// element_type already populated above
}
return proto;
}
FieldMeta
FieldMeta::ParseFrom(const milvus::proto::schema::FieldSchema& schema_proto) {
auto field_id = FieldId(schema_proto.fieldid());

View File

@ -16,6 +16,7 @@
#pragma once
#include <map>
#include <optional>
#include <stdexcept>
#include <string>
@ -251,6 +252,9 @@ class FieldMeta {
return default_value_;
}
milvus::proto::schema::FieldSchema
ToProto() const;
size_t
get_sizeof() const {
AssertInfo(!IsSparseFloatVectorDataType(type_),

View File

@ -114,7 +114,7 @@ class SimpleGeometryCacheManager {
SimpleGeometryCacheManager() = default;
SimpleGeometryCache&
GetCache(int64_t segment_id, FieldId field_id) {
GetOrCreateCache(int64_t segment_id, FieldId field_id) {
std::lock_guard<std::mutex> lock(mutex_);
auto key = MakeCacheKey(segment_id, field_id);
auto it = caches_.find(key);
@ -128,6 +128,17 @@ class SimpleGeometryCacheManager {
return *cache_ptr;
}
SimpleGeometryCache*
GetCache(int64_t segment_id, FieldId field_id) {
std::lock_guard<std::mutex> lock(mutex_);
auto key = MakeCacheKey(segment_id, field_id);
auto it = caches_.find(key);
if (it != caches_.end()) {
return it->second.get();
}
return nullptr;
}
void
RemoveCache(GEOSContextHandle_t ctx, int64_t segment_id, FieldId field_id) {
std::lock_guard<std::mutex> lock(mutex_);
@ -184,26 +195,4 @@ class SimpleGeometryCacheManager {
} // namespace exec
// Convenient global functions for direct access to geometry cache
inline const Geometry*
GetGeometryByOffset(int64_t segment_id, FieldId field_id, size_t offset) {
auto& cache = exec::SimpleGeometryCacheManager::Instance().GetCache(
segment_id, field_id);
return cache.GetByOffset(offset);
}
inline void
RemoveGeometryCache(GEOSContextHandle_t ctx,
int64_t segment_id,
FieldId field_id) {
exec::SimpleGeometryCacheManager::Instance().RemoveCache(
ctx, segment_id, field_id);
}
inline void
RemoveSegmentGeometryCaches(GEOSContextHandle_t ctx, int64_t segment_id) {
exec::SimpleGeometryCacheManager::Instance().RemoveSegmentCaches(
ctx, segment_id);
}
} // namespace milvus

View File

@ -98,4 +98,9 @@ class GroupChunk {
std::unordered_map<FieldId, std::shared_ptr<Chunk>> chunks_;
};
enum class GroupChunkType : uint8_t {
DEFAULT = 0,
JSON_KEY_STATS = 1,
};
} // namespace milvus

View File

@ -94,8 +94,8 @@ Schema::ConvertToArrowSchema() const {
std::shared_ptr<arrow::DataType> arrow_data_type = nullptr;
auto data_type = meta.get_data_type();
if (data_type == DataType::VECTOR_ARRAY) {
arrow_data_type =
GetArrowDataTypeForVectorArray(meta.get_element_type());
arrow_data_type = GetArrowDataTypeForVectorArray(
meta.get_element_type(), meta.get_dim());
} else {
arrow_data_type = GetArrowDataType(data_type, dim);
}
@ -111,6 +111,29 @@ Schema::ConvertToArrowSchema() const {
return arrow::schema(arrow_fields);
}
proto::schema::CollectionSchema
Schema::ToProto() const {
proto::schema::CollectionSchema schema_proto;
schema_proto.set_enable_dynamic_field(dynamic_field_id_opt_.has_value());
for (const auto& field_id : field_ids_) {
const auto& meta = fields_.at(field_id);
auto* field_proto = schema_proto.add_fields();
*field_proto = meta.ToProto();
if (primary_field_id_opt_.has_value() &&
field_id == primary_field_id_opt_.value()) {
field_proto->set_is_primary_key(true);
}
if (dynamic_field_id_opt_.has_value() &&
field_id == dynamic_field_id_opt_.value()) {
field_proto->set_is_dynamic(true);
}
}
return schema_proto;
}
std::unique_ptr<std::vector<FieldMeta>>
Schema::AbsentFields(Schema& old_schema) const {
std::vector<FieldMeta> result;

View File

@ -16,6 +16,7 @@
#pragma once
#include <atomic>
#include <cstdint>
#include <memory>
#include <optional>
@ -126,6 +127,31 @@ class Schema {
return field_id;
}
// string type
FieldId
AddDebugVarcharField(const FieldName& name,
DataType data_type,
int64_t max_length,
bool nullable,
bool enable_match,
bool enable_analyzer,
std::map<std::string, std::string>& params,
std::optional<DefaultValueType> default_value) {
auto field_id = FieldId(debug_id);
debug_id++;
auto field_meta = FieldMeta(name,
field_id,
data_type,
max_length,
nullable,
enable_match,
enable_analyzer,
params,
std::move(default_value));
this->AddField(std::move(field_meta));
return field_id;
}
// scalar type
void
AddField(const FieldName& name,
@ -293,6 +319,9 @@ class Schema {
const ArrowSchemaPtr
ConvertToArrowSchema() const;
proto::schema::CollectionSchema
ToProto() const;
void
UpdateLoadFields(const std::vector<int64_t>& field_ids) {
load_fields_.clear();
@ -358,5 +387,5 @@ class Schema {
};
using SchemaPtr = std::shared_ptr<Schema>;
using SafeSchemaPtr = std::atomic<SchemaPtr*>;
} // namespace milvus

View File

@ -156,6 +156,67 @@ GetDataTypeSize(DataType data_type, int dim = 1) {
}
}
// Convert internal DataType to proto schema DataType
inline proto::schema::DataType
ToProtoDataType(DataType data_type) {
switch (data_type) {
case DataType::NONE:
return proto::schema::DataType::None;
case DataType::BOOL:
return proto::schema::DataType::Bool;
case DataType::INT8:
return proto::schema::DataType::Int8;
case DataType::INT16:
return proto::schema::DataType::Int16;
case DataType::INT32:
return proto::schema::DataType::Int32;
case DataType::INT64:
return proto::schema::DataType::Int64;
case DataType::FLOAT:
return proto::schema::DataType::Float;
case DataType::DOUBLE:
return proto::schema::DataType::Double;
case DataType::STRING:
return proto::schema::DataType::String;
case DataType::VARCHAR:
return proto::schema::DataType::VarChar;
case DataType::ARRAY:
return proto::schema::DataType::Array;
case DataType::JSON:
return proto::schema::DataType::JSON;
case DataType::TEXT:
return proto::schema::DataType::Text;
case DataType::TIMESTAMPTZ:
return proto::schema::DataType::Timestamptz;
case DataType::VECTOR_BINARY:
return proto::schema::DataType::BinaryVector;
case DataType::VECTOR_FLOAT:
return proto::schema::DataType::FloatVector;
case DataType::VECTOR_FLOAT16:
return proto::schema::DataType::Float16Vector;
case DataType::VECTOR_BFLOAT16:
return proto::schema::DataType::BFloat16Vector;
case DataType::VECTOR_SPARSE_U32_F32:
return proto::schema::DataType::SparseFloatVector;
case DataType::VECTOR_INT8:
return proto::schema::DataType::Int8Vector;
case DataType::VECTOR_ARRAY:
return proto::schema::DataType::ArrayOfVector;
// Internal-only or unsupported mappings
case DataType::ROW:
default:
ThrowInfo(
DataTypeInvalid,
fmt::format(
"failed to convert to proto data type, invalid type {}",
data_type));
}
}
inline std::shared_ptr<arrow::DataType>
GetArrowDataType(DataType data_type, int dim = 1) {
switch (data_type) {
@ -205,10 +266,23 @@ GetArrowDataType(DataType data_type, int dim = 1) {
}
inline std::shared_ptr<arrow::DataType>
GetArrowDataTypeForVectorArray(DataType elem_type) {
GetArrowDataTypeForVectorArray(DataType elem_type, int dim) {
if (dim <= 0) {
ThrowInfo(DataTypeInvalid, "dim must be provided for VectorArray");
}
// VectorArray stores vectors as FixedSizeBinaryArray
// We must have dim to create the correct fixed_size_binary type
switch (elem_type) {
case DataType::VECTOR_FLOAT:
return arrow::list(arrow::float32());
return arrow::list(arrow::fixed_size_binary(dim * sizeof(float)));
case DataType::VECTOR_BINARY:
return arrow::list(arrow::fixed_size_binary((dim + 7) / 8));
case DataType::VECTOR_FLOAT16:
return arrow::list(arrow::fixed_size_binary(dim * 2));
case DataType::VECTOR_BFLOAT16:
return arrow::list(arrow::fixed_size_binary(dim * 2));
case DataType::VECTOR_INT8:
return arrow::list(arrow::fixed_size_binary(dim));
default: {
ThrowInfo(DataTypeInvalid,
fmt::format("failed to get arrow type for vector array, "
@ -384,6 +458,7 @@ IsPrimitiveType(proto::schema::DataType type) {
case proto::schema::DataType::Double:
case proto::schema::DataType::String:
case proto::schema::DataType::VarChar:
case proto::schema::DataType::Timestamptz:
return true;
default:
return false;
@ -534,7 +609,10 @@ IsFloatVectorMetricType(const MetricType& metric_type) {
metric_type == knowhere::metric::IP ||
metric_type == knowhere::metric::COSINE ||
metric_type == knowhere::metric::BM25 ||
metric_type == knowhere::metric::MAX_SIM;
metric_type == knowhere::metric::MAX_SIM ||
metric_type == knowhere::metric::MAX_SIM_COSINE ||
metric_type == knowhere::metric::MAX_SIM_IP ||
metric_type == knowhere::metric::MAX_SIM_L2;
}
inline bool
@ -543,14 +621,20 @@ IsBinaryVectorMetricType(const MetricType& metric_type) {
metric_type == knowhere::metric::JACCARD ||
metric_type == knowhere::metric::SUPERSTRUCTURE ||
metric_type == knowhere::metric::SUBSTRUCTURE ||
metric_type == knowhere::metric::MHJACCARD;
metric_type == knowhere::metric::MHJACCARD ||
metric_type == knowhere::metric::MAX_SIM_HAMMING ||
metric_type == knowhere::metric::MAX_SIM_JACCARD;
}
inline bool
IsIntVectorMetricType(const MetricType& metric_type) {
return metric_type == knowhere::metric::L2 ||
metric_type == knowhere::metric::IP ||
metric_type == knowhere::metric::COSINE;
metric_type == knowhere::metric::COSINE ||
metric_type == knowhere::metric::MAX_SIM ||
metric_type == knowhere::metric::MAX_SIM_COSINE ||
metric_type == knowhere::metric::MAX_SIM_IP ||
metric_type == knowhere::metric::MAX_SIM_L2;
}
// Plus 1 because we can't use greater(>) symbol
@ -746,6 +830,30 @@ FromValCase(milvus::proto::plan::GenericValue::ValCase val_case) {
return DataType::NONE;
}
}
// Calculate bytes per vector element for different vector types
// Used by VectorArray and storage utilities
inline size_t
vector_bytes_per_element(const DataType data_type, int64_t dim) {
switch (data_type) {
case DataType::VECTOR_BINARY:
// Binary vector stores bits, so dim represents bit count
// Need (dim + 7) / 8 bytes to store dim bits
return (dim + 7) / 8;
case DataType::VECTOR_FLOAT:
return dim * sizeof(float);
case DataType::VECTOR_FLOAT16:
return dim * sizeof(float16);
case DataType::VECTOR_BFLOAT16:
return dim * sizeof(bfloat16);
case DataType::VECTOR_INT8:
return dim * sizeof(int8);
default:
ThrowInfo(UnexpectedError,
fmt::format("invalid data type: {}", data_type));
}
}
} // namespace milvus
template <>
struct fmt::formatter<milvus::DataType> : formatter<string_view> {
@ -935,6 +1043,9 @@ struct fmt::formatter<milvus::proto::schema::DataType>
case milvus::proto::schema::DataType::Geometry:
name = "Geometry";
break;
case milvus::proto::schema::DataType::Timestamptz:
name = "Timestamptz";
break;
case milvus::proto::schema::DataType::Text:
name = "Text";
break;

Some files were not shown because too many files have changed in this diff Show More