milvus-io / milvus

A cloud-native vector database, storage for next generation AI applications
https://milvus.io
Apache License 2.0
30.14k stars 2.89k forks source link

[Bug]: alias name is leaky if dropping a collection that has a alias #36963

Open yanliang567 opened 1 week ago

yanliang567 commented 1 week ago

Is there an existing issue for this?

Environment

- Milvus version: master-20241015-f3b6792a and 2.4
- Deployment mode(standalone or cluster): standlaone
- MQ type(rocksmq, pulsar or kafka):    
- SDK version(e.g. pymilvus v2.0.0rc2): pymilvus 2.4.8

Current Behavior

via birdwatcher, we can see the alias still exists while the alias linked the collection was dropped.

Expected Behavior

if dropping a collection, drop the collection and the related aliases as well. as a workaround, users have to manually drop the alias name, and recreate a alias with the same alias name.

Steps To Reproduce

1. create collection C
2. create a alias A and link to collection C
3. drop the collection C     (after this step, there is no way to list or get the alias name again)
4. create a collection with name C again
5. create a alias A and link to the C

Milvus Log

No response

Anything else?

run the test below:

 @pytest.mark.tags(CaseLabel.L0)
    def test_alias_reuse_alias_name_from_dropped_collection(self):
        """
        target: test dropping a collection which has a alias
        method:
                1.create a collection
                2.create an alias for the collection
                3.drop the collection
                4.create a new collection
                5.create an alias with the same alias name for the new collection
            expected: in step 5, create alias with the same name for the new collection succ
        """
        self._connect()
        c_name = cf.gen_unique_str("collection")
        collection_w = self.init_collection_wrap(name=c_name, schema=default_schema,
                                                 check_task=CheckTasks.check_collection_property,
                                                 check_items={exp_name: c_name, exp_schema: default_schema})
        alias_name = cf.gen_unique_str(prefix)
        self.utility_wrap.create_alias(collection_w.name, alias_name)
        res = self.utility_wrap.list_aliases(c_name)[0]
        assert len(res) == 1

        # dropping collection that has an alias shall drop the alias as well
        collection_w.drop()
        collection_w = self.init_collection_wrap(name=c_name, schema=default_schema,
                                                 check_task=CheckTasks.check_collection_property,
                                                 check_items={exp_name: c_name, exp_schema: default_schema})
        res2 = self.utility_wrap.list_aliases(c_name)[0]
        assert len(res2) == 0
        # the same alias name can be reused for another collection
        self.utility_wrap.create_alias(collection_w.name, alias_name)
        res2 = self.utility_wrap.list_aliases(c_name)[0]
        assert len(res2) == 1
yanliang567 commented 1 week ago

another test for this case:

@pytest.mark.tags(CaseLabel.L0)
    def test_alias_rename_collection_to_alias_name(self):
        """
        target: test renaming a collection to a alias name
        method:
                1.create a collection
                2.create an alias for the collection
                3.rename the collection to the alias name
        """
        self._connect()
        c_name = cf.gen_unique_str("collection")
        collection_w = self.init_collection_wrap(name=c_name, schema=default_schema,
                                                 check_task=CheckTasks.check_collection_property,
                                                 check_items={exp_name: c_name, exp_schema: default_schema})
        alias_name = cf.gen_unique_str(prefix)
        self.utility_wrap.create_alias(collection_w.name, alias_name)
        error = {ct.err_code: 999,
                 ct.err_msg: f"duplicated new collection name default:{alias_name} with other collection name or alias"}
        self.utility_wrap.rename_collection(collection_w.name, alias_name,
                                            check_task=CheckTasks.err_res, check_items=error)

        collection_w.drop()
        collection_w = self.init_collection_wrap(name=c_name, schema=default_schema,
                                                 check_task=CheckTasks.check_collection_property,
                                                 check_items={exp_name: c_name, exp_schema: default_schema})
        error = {ct.err_code: 999,
                 ct.err_msg: f"this is not expected, any collection name or alias name shall be unique"}
        self.utility_wrap.rename_collection(collection_w.name, alias_name,
                                            check_task=CheckTasks.err_res, check_items=error)