Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move create database to procedure #3591

Closed
WenyXu opened this issue Mar 27, 2024 · 6 comments · Fixed by #3626
Closed

move create database to procedure #3591

WenyXu opened this issue Mar 27, 2024 · 6 comments · Fixed by #3626
Assignees
Labels
good first issue Good for newcomers

Comments

@WenyXu
Copy link
Member

WenyXu commented Mar 27, 2024

What type of enhancement is this?

Refactor, Tech debt reduction

What does the enhancement do?

We introduced multiple-level locks in the procedure, and all DDL operations should acquire all related locks during the execution. After implementing #3516, we should refactor the database creation into a procedure.

Implementation challenges

No response

@tisonkun
Copy link
Collaborator

Would you add some refer impl like how other procedure are implemented?

@WenyXu
Copy link
Member Author

WenyXu commented Mar 27, 2024

Would you add some refer impl like how other procedure are implemented?

Yes, a typical procedure looks like this:

#[async_trait]
impl Procedure for CreateTableProcedure {
fn type_name(&self) -> &str {
Self::TYPE_NAME
}
async fn execute(&mut self, _ctx: &ProcedureContext) -> ProcedureResult<Status> {
let state = &self.creator.data.state;
let _timer = metrics::METRIC_META_PROCEDURE_CREATE_TABLE
.with_label_values(&[state.as_ref()])
.start_timer();
match state {
CreateTableState::Prepare => self.on_prepare().await,
CreateTableState::DatanodeCreateRegions => self.on_datanode_create_regions().await,
CreateTableState::CreateMetadata => self.on_create_metadata().await,
}
.map_err(handle_retry_error)
}
fn dump(&self) -> ProcedureResult<String> {
serde_json::to_string(&self.creator.data).context(ToJsonSnafu)
}
fn lock_key(&self) -> LockKey {
let table_ref = &self.creator.data.table_ref();
LockKey::new(vec![
CatalogLock::Read(table_ref.catalog).into(),
SchemaLock::read(table_ref.catalog, table_ref.schema).into(),
TableNameLock::new(table_ref.catalog, table_ref.schema, table_ref.table).into(),
])
}
}

And more procedures can be found here

@CookiePieWw
Copy link
Collaborator

Hi @WenyXu , I'd like to give it a try.

@WenyXu
Copy link
Member Author

WenyXu commented Mar 27, 2024

Hi @WenyXu , I'd like to give it a try.

Have fun

@CookiePieWw
Copy link
Collaborator

I've made some efforts in the past few days. Since It's my first time diving into greptimedb, I think it would be better to make it clear before taking actions. Here are my findings and confusions:

  • Currently, the create database statement is simply executed inside create_database method in StatementExecutor. The target is to refactor it as other ddl ops, which executes as follows (here I take drop database as an example):

    • Do some checks and then forward the params to drop_database_procedure method
    • Packaging the params as a task. The packaging methods are implemented in src/common/meta/src/rpc/ddl.rs
    • Submit the task to execute. The submission methods are implemented in src/common/meta/src/ddl_manager.rs and src/common/meta/src/ddl.rs
    • The execution methods take place under src/common/meta/src/ddl, thus a file named create_database.rs should be added to implement the CreateDatabaseProcedure
  • I've noticed that there are lots of methods and traits related to rpc like PbDropDatabaseTask, which lead me to greptimedb-proto finally. Is it proper to simply place a todo somewhere and leave it alone?

  • I've read about the implemention of CreateTableProcedure. It seems the procedure executes in 3 stages with several concepts I'm not familiar yet (regions, memory allocation, etc.). Should I have a more complicated design for the procedure, or simply copy the original one into the execute method and acquire some locks in lock_key? Besides, it seems the from_json and dump methods are related to rpc as well.

Would you mind giving me some advice @WenyXu ? Thanks a lot.

@WenyXu
Copy link
Member Author

WenyXu commented Mar 30, 2024

I've made some efforts in the past few days. Since It's my first time diving into greptimedb, I think it would be better to make it clear before taking actions. Here are my findings and confusions:

  • Currently, the create database statement is simply executed inside create_database method in StatementExecutor. The target is to refactor it as other ddl ops, which executes as follows (here I take drop database as an example):

    • Do some checks and then forward the params to drop_database_procedure method
    • Packaging the params as a task. The packaging methods are implemented in src/common/meta/src/rpc/ddl.rs
    • Submit the task to execute. The submission methods are implemented in src/common/meta/src/ddl_manager.rs and src/common/meta/src/ddl.rs
    • The execution methods take place under src/common/meta/src/ddl, thus a file named create_database.rs should be added to implement the CreateDatabaseProcedure
  • I've noticed that there are lots of methods and traits related to rpc like PbDropDatabaseTask, which lead me to greptimedb-proto finally. Is it proper to simply place a todo somewhere and leave it alone?

  • I've read about the implemention of CreateTableProcedure. It seems the procedure executes in 3 stages with several concepts I'm not familiar yet (regions, memory allocation, etc.). Should I have a more complicated design for the procedure, or simply copy the original one into the execute method and acquire some locks in lock_key? Besides, it seems the from_json and dump methods are related to rpc as well.

Would you mind giving me some advice @WenyXu ? Thanks a lot.

Is it proper to simply place a todo somewhere and leave it alone?

Nope, we should define the protobuf in the greeting-proto firstly.

I've read about the implemention of CreateTableProcedure. It seems the procedure executes in 3 stages with several concepts I'm not familiar yet (regions, memory allocation, etc.). ….

Don’t worry, creating database only requires to create the metadata. Check current logical of the database creation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants