github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/docs/RFCS/20230320_ddl_block_related_table.md (about)

     1  # Proposal: Make DDL only block related table
     2  
     3  - Author(s): [asddongmen](https://github.com/asddongmen)
     4  - Last updated: 2023-03-20
     5  
     6  ## Abstract
     7  
     8  This proposal introduces a solution to make DDL events in TiCDC only blocks related table syncnization progress, which can effectively reducing the checkpoint lag caused by DDL synchronization.
     9  Table of contents:
    10  
    11  - [Background](#Background)
    12  - [Implementation](#Implementation)
    13  
    14  ## Background
    15  
    16  ![ddl_handle_logic](../media/ddl_block_related_table_1.png)
    17  
    18  As shown in the figure above, TiCDC currently blocks the synchronization progress of all tables in all processors through the `barrierTs` mechanism before synchronizing DDL. The DDL is executed once the `checkpoinTs` have reached the `barrierTs`, after which the `barrierTs` is advanced to resume synchronization.
    19  
    20  In this implementation, if a large number of DDL events occur in a short period of time, the checkpoint lag of the `changefeed` may increase. Especially in the scenario where a table in the `changefeed` is executing a time consuming DDL, while other tables need to synchronize a large number of row changes.
    21  
    22  ## Implementation
    23  
    24  To reduce the impact of DDL synchronization on `changefeed` synchronizing, we hope that `changefeed` will only block the progress of related tables when executing DDL events.
    25  
    26  To achieve DDL only blocking related tables, the key is to decouple `ddlBarrierTs` from the global `barrierTs` and narrow the scope of `ddlBarrierTs` from the `changefeed` level to the table level.
    27  
    28  To decouple `ddlBarrierTs` and simplify the relevant logic of DDL processing in the current `changefeed` code, we need to introduce a new structure `ddlManager`. Its main functions are:
    29  
    30  - Cache unexecuted DDL events.
    31  - Calculate `ddlBarrierTs` and return a `map` of `tableID` -> `tableBarrierTs` to the caller.
    32  - Maintain and update `schemaStorage` for `scheduler` to get current table information.
    33  
    34  After introducing `ddlManager`, the interaction sequence diagram of the components involved in DDL synchronization is as follows:
    35  
    36  ![ddl_manager_logic](../media/ddl_block_related_table_2.png)
    37  
    38  First, when the DDL event sent by the upstream reaches `ddlManager`, it applies to the `schemaStorage` in memory and updates the current table information. Then, it caches the DDL in the `pendingDDLs` field, calculates the `tableBarrier` of the tables that need to execute DDL, and returns the `globalBarrierTs` of the tables that do not need to execute DDL to the `owner`.
    39  
    40  The `owner` broadcasts the `barrier` to the `processor`, and the `processor` blocks the synchronization progress of the relevant tables based on the `barrier`. The logic of executing the DDL later is the same as the original implementation.
    41  
    42  It is worth noting that some DDLs involve multiple tables, and some DDLs do not have corresponding tables in `changefeed` before they are executed, so it is not possible to use `tableBarrier` to block the progress of related tables. In order to limit the scope of the proposal within a certain range and avoid overly complex designs, this proposal suggests that such DDLs should be handled in the same way as the original implementation, that is, blocking the synchronization progress of the entire `changefeed`.