|
22 | 22 | import org.apache.flink.cdc.common.schema.Schema; |
23 | 23 | import org.apache.flink.cdc.connectors.hudi.sink.event.CreateTableOperatorEvent; |
24 | 24 | import org.apache.flink.cdc.connectors.hudi.sink.event.EnhancedWriteMetadataEvent; |
| 25 | +import org.apache.flink.cdc.connectors.hudi.sink.event.SchemaChangeOperatorEvent; |
25 | 26 | import org.apache.flink.cdc.connectors.hudi.sink.util.RowDataUtils; |
26 | 27 | import org.apache.flink.configuration.Configuration; |
27 | 28 | import org.apache.flink.runtime.jobgraph.OperatorID; |
@@ -453,6 +454,8 @@ public void handleEventFromOperator( |
453 | 454 | () -> { |
454 | 455 | if (operatorEvent instanceof CreateTableOperatorEvent) { |
455 | 456 | handleCreateTableEvent((CreateTableOperatorEvent) operatorEvent); |
| 457 | + } else if (operatorEvent instanceof SchemaChangeOperatorEvent) { |
| 458 | + handleSchemaChangeEvent((SchemaChangeOperatorEvent) operatorEvent); |
456 | 459 | } else if (operatorEvent instanceof EnhancedWriteMetadataEvent) { |
457 | 460 | handleEnhancedWriteMetadataEvent( |
458 | 461 | (EnhancedWriteMetadataEvent) operatorEvent); |
@@ -507,6 +510,71 @@ private void handleCreateTableEvent(CreateTableOperatorEvent createTableOperator |
507 | 510 | }); |
508 | 511 | } |
509 | 512 |
|
| 513 | + /** |
| 514 | + * Handles schema change events from the sink functions. Updates the cached schema and recreates |
| 515 | + * the write client to ensure it uses the new schema. |
| 516 | + * |
| 517 | + * @param event The schema change event containing the table ID and new schema |
| 518 | + */ |
| 519 | + private void handleSchemaChangeEvent(SchemaChangeOperatorEvent event) { |
| 520 | + TableId tableId = event.getTableId(); |
| 521 | + Schema newSchema = event.getNewSchema(); |
| 522 | + |
| 523 | + LOG.info( |
| 524 | + "Received schema change event for table {}: {} columns", |
| 525 | + tableId, |
| 526 | + newSchema.getColumnCount()); |
| 527 | + |
| 528 | + // Update the cached schema |
| 529 | + tableSchemas.put(tableId, newSchema); |
| 530 | + LOG.info("Updated coordinator's schema cache for table: {}", tableId); |
| 531 | + |
| 532 | + // Get the existing table context |
| 533 | + TableContext oldContext = tableContexts.get(tableId); |
| 534 | + if (oldContext == null) { |
| 535 | + LOG.warn( |
| 536 | + "Received schema change for unknown table: {}. Skipping write client update.", |
| 537 | + tableId); |
| 538 | + return; |
| 539 | + } |
| 540 | + |
| 541 | + try { |
| 542 | + // Close the old write client |
| 543 | + if (oldContext.writeClient != null) { |
| 544 | + oldContext.writeClient.close(); |
| 545 | + LOG.info("Closed old write client for table: {}", tableId); |
| 546 | + } |
| 547 | + |
| 548 | + // Create new configuration with updated schema |
| 549 | + Configuration tableConfig = createTableSpecificConfig(tableId); |
| 550 | + |
| 551 | + // Create new write client with updated schema |
| 552 | + HoodieFlinkWriteClient<?> newWriteClient = |
| 553 | + FlinkWriteClients.createWriteClient(tableConfig); |
| 554 | + LOG.info("Created new write client with updated schema for table: {}", tableId); |
| 555 | + |
| 556 | + // Update the table context with the new write client |
| 557 | + // Keep the same eventBuffers, tableState, and tablePath |
| 558 | + TableContext newContext = |
| 559 | + new TableContext( |
| 560 | + newWriteClient, |
| 561 | + oldContext.eventBuffers, |
| 562 | + oldContext.tableState, |
| 563 | + oldContext.tablePath); |
| 564 | + tableContexts.put(tableId, newContext); |
| 565 | + |
| 566 | + LOG.info("Successfully updated write client for table {} after schema change", tableId); |
| 567 | + } catch (Exception e) { |
| 568 | + LOG.error("Failed to update write client for table {} after schema change", tableId, e); |
| 569 | + context.failJob( |
| 570 | + new HoodieException( |
| 571 | + "Failed to update write client for table " |
| 572 | + + tableId |
| 573 | + + " after schema change", |
| 574 | + e)); |
| 575 | + } |
| 576 | + } |
| 577 | + |
510 | 578 | private void handleEnhancedWriteMetadataEvent(EnhancedWriteMetadataEvent enhancedEvent) { |
511 | 579 | String tablePath = enhancedEvent.getTablePath(); |
512 | 580 | WriteMetadataEvent event = enhancedEvent.getOriginalEvent(); |
|
0 commit comments