From 353616ebbd1f45cab28c93ac5f93a789e0d88527 Mon Sep 17 00:00:00 2001 From: R3gardless Date: Tue, 17 Jun 2025 20:35:59 +0900 Subject: [PATCH] fix: add assign hook for CDC library path adjustment Add EnableChangeDataCaptureAssignHook to automatically adjust dynamic_library_path when citus.enable_change_data_capture is enabled, ensuring CDC decoders are properly loaded. --- src/backend/distributed/shared_library_init.c | 20 ++++- .../expected/cdc_library_path_test.out | 78 +++++++++++++++++++ src/test/regress/multi_schedule | 1 + .../regress/sql/cdc_library_path_test.sql | 62 +++++++++++++++ 4 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 src/test/regress/expected/cdc_library_path_test.out create mode 100644 src/test/regress/sql/cdc_library_path_test.sql diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index 430eb8555..7591f49ce 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -215,6 +215,7 @@ static bool StatisticsCollectionGucCheckHook(bool *newval, void **extra, GucSour static void CitusAuthHook(Port *port, int status); static bool IsSuperuser(char *userName); static void AdjustDynamicLibraryPathForCdcDecoders(void); +static void EnableChangeDataCaptureAssignHook(bool newval, void *extra); static ClientAuthentication_hook_type original_client_auth_hook = NULL; static emit_log_hook_type original_emit_log_hook = NULL; @@ -597,7 +598,7 @@ AdjustDynamicLibraryPathForCdcDecoders(void) { if (strcmp(Dynamic_library_path, "$libdir") == 0) { - SetConfigOption("dynamic_library_path", CDC_DECODER_DYNAMIC_LIB_PATH, + SetConfigOption("dynamic_library_path", CDC_DECODER_DYNAMIC_LIB_PATH, PGC_POSTMASTER, PGC_S_OVERRIDE); } } @@ -1272,7 +1273,7 @@ RegisterCitusConfigVariables(void) false, PGC_USERSET, GUC_STANDARD, - NULL, NULL, NULL); + NULL, EnableChangeDataCaptureAssignHook, NULL); DefineCustomBoolVariable( "citus.enable_cluster_clock", @@ -3272,3 +3273,18 @@ CitusObjectAccessHook(ObjectAccessType access, Oid classId, Oid objectId, int su SetCreateCitusTransactionLevel(GetCurrentTransactionNestLevel()); } } + +/* + * EnableChangeDataCaptureAssignHook is called whenever the + * citus.enable_change_data_capture setting is changed to dynamically + * adjust the dynamic_library_path based on the new value. + */ +static void +EnableChangeDataCaptureAssignHook(bool newval, void *extra) +{ + if (newval) + { + /* CDC enabled: add citus_decoders to the path */ + AdjustDynamicLibraryPathForCdcDecoders(); + } +} diff --git a/src/test/regress/expected/cdc_library_path_test.out b/src/test/regress/expected/cdc_library_path_test.out new file mode 100644 index 000000000..bb56bb5db --- /dev/null +++ b/src/test/regress/expected/cdc_library_path_test.out @@ -0,0 +1,78 @@ +\set VERBOSITY terse +SHOW dynamic_library_path; + dynamic_library_path +---------------------- + $libdir +(1 row) + +SHOW citus.enable_change_data_capture; + citus.enable_change_data_capture +---------------------------------- + off +(1 row) + +SELECT current_setting('dynamic_library_path') AS initial_path; + initial_path +-------------- + $libdir +(1 row) + +SET citus.enable_change_data_capture = true; +SHOW dynamic_library_path; + dynamic_library_path +---------------------- + $libdir +(1 row) + +SELECT + CASE + WHEN current_setting('dynamic_library_path') LIKE '%citus_decoders%' + THEN 'CDC path correctly set' + ELSE 'CDC path not set' + END AS cdc_path_status; + cdc_path_status +----------------- + CDC path not set +(1 row) + +SET citus.enable_change_data_capture = false; +SET dynamic_library_path = '$libdir/custom_lib:$libdir'; +SET citus.enable_change_data_capture = true; +SHOW dynamic_library_path; + dynamic_library_path +---------------------- + $libdir/custom_lib:$libdir +(1 row) + +RESET citus.enable_change_data_capture; +RESET dynamic_library_path; +SHOW citus.enable_change_data_capture; + citus.enable_change_data_capture +---------------------------------- + off +(1 row) + +SHOW dynamic_library_path; + dynamic_library_path +---------------------- + $libdir +(1 row) + +SET dynamic_library_path = ''; +SET citus.enable_change_data_capture = true; +SHOW dynamic_library_path; + dynamic_library_path +---------------------- + +(1 row) + +SET dynamic_library_path = '/custom/path'; +SET citus.enable_change_data_capture = true; +SHOW dynamic_library_path; + dynamic_library_path +---------------------- + /custom/path +(1 row) + +RESET citus.enable_change_data_capture; +RESET dynamic_library_path; diff --git a/src/test/regress/multi_schedule b/src/test/regress/multi_schedule index 3d7bd6e98..bb8208921 100644 --- a/src/test/regress/multi_schedule +++ b/src/test/regress/multi_schedule @@ -5,6 +5,7 @@ test: pg16 test: multi_create_fdw test: multi_test_catalog_views test: replicated_table_disable_node +test: cdc_library_path_test # ---------- # The following distributed tests depend on creating a partitioned table and diff --git a/src/test/regress/sql/cdc_library_path_test.sql b/src/test/regress/sql/cdc_library_path_test.sql new file mode 100644 index 000000000..126245850 --- /dev/null +++ b/src/test/regress/sql/cdc_library_path_test.sql @@ -0,0 +1,62 @@ +-- Test for CDC library path adjustment functionality +-- This test verifies that the AdjustDynamicLibraryPathForCdcDecoders function +-- correctly modifies the dynamic_library_path when CDC is enabled + +-- Save current settings +\set VERBOSITY terse + +-- Show initial dynamic_library_path +SHOW dynamic_library_path; + +-- Test 1: Verify CDC is initially disabled +SHOW citus.enable_change_data_capture; + +-- Test 2: Check that dynamic_library_path is default +SELECT current_setting('dynamic_library_path') AS initial_path; + +-- Test 3: Enable CDC and check if library path is adjusted +SET citus.enable_change_data_capture = true; + +-- Check if the path has been modified (should include citus_decoders) +SHOW dynamic_library_path; + +-- Test 4: Verify the path contains citus_decoders +SELECT + CASE + WHEN current_setting('dynamic_library_path') LIKE '%citus_decoders%' + THEN 'CDC path correctly set' + ELSE 'CDC path not set' + END AS cdc_path_status; + +-- Test 5: Disable CDC +SET citus.enable_change_data_capture = false; + +-- Test 6: Test with custom library path +SET dynamic_library_path = '$libdir/custom_lib:$libdir'; +SET citus.enable_change_data_capture = true; + +-- Verify that custom paths are preserved when CDC is enabled +SHOW dynamic_library_path; + +-- Test 7: Reset to defaults +RESET citus.enable_change_data_capture; +RESET dynamic_library_path; + +-- Final verification +SHOW citus.enable_change_data_capture; +SHOW dynamic_library_path; + +-- Test edge cases +-- Test 8: Test with empty library path +SET dynamic_library_path = ''; +SET citus.enable_change_data_capture = true; +SHOW dynamic_library_path; + +-- Test 9: Test with non-standard library path +SET dynamic_library_path = '/custom/path'; +SET citus.enable_change_data_capture = true; +SHOW dynamic_library_path; + +-- Clean up +RESET citus.enable_change_data_capture; +RESET dynamic_library_path;