{"id":30069,"date":"2025-10-27T04:33:45","date_gmt":"2025-10-27T11:33:45","guid":{"rendered":"https:\/\/www.pingcap.com\/?p=30069"},"modified":"2025-12-03T16:39:23","modified_gmt":"2025-12-04T00:39:23","slug":"replicate-tidb-mirrored-database-microsoft-fabric-ticdc","status":"publish","type":"post","link":"https:\/\/www.pingcap.com\/ko\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/","title":{"rendered":"How to Replicate TiDB to a Mirrored Database in Microsoft Fabric with TiCDC"},"content":{"rendered":"<p>TiDB is an open-source distributed SQL database built for cloud-native, data-intensive, and AI-driven applications. It is MySQL compatible and features horizontal scalability, strong consistency, and high availability. By leveraging a <a href=\"https:\/\/docs.pingcap.com\/tidb\/stable\/ticdc-overview\/\">TiCDC<\/a> replication solution for Open Mirroring, TiDB seamlessly integrates with Microsoft Fabric. This unlocks continuous, real-time data synchronization from any TiDB deployment environment into Microsoft Fabric OneLake, making your data instantly available for AI and <a href=\"https:\/\/www.pingcap.com\/ko\/article\/real-time-data-analytics-with-distributed-database\/\">analytics<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"575\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25002102\/image-1024x575.png\" alt=\"\" class=\"wp-image-30070\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25002102\/image-1024x575.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002102\/image-300x168.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002102\/image-768x431.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002102\/image-1536x862.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002102\/image.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>Open Mirroring is designed to enable Data ISVs and customers to extend Mirroring in Microsoft Fabric based on the open Delta Lake table format. This capability enables TiDB to write change data directly into a Mirrored Database in Microsoft Fabric based on the open mirroring public APIs. To learn more about Open Mirroring in Microsoft Fabric, please visit <a href=\"https:\/\/aka.ms\/mirroring\/intro-open-mirroring\">Open Mirroring in Microsoft Fabric.<\/a><\/p>\n\n\n\n<p>In this post, we will detail the implementation of this open source integration solution and demonstrate how to configure each component, providing a detailed, step-by-step walkthrough.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"0-prerequisites\"><span class=\"ez-toc-section\" id=\"Prerequisites\"><\/span>Prerequisites<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Deploy a TiCDC cluster to connect to your TiDB cluster, regardless of its deployment pattern (TiDB Cloud or Self-Managed) or location (in any public cloud or on-premises). Alternatively, you can use the <a href=\"https:\/\/labs.tidb.io\/labs\/dba_303_lab_ff10\">sandbox environment<\/a> provided by TiDB Labs for evaluation purposes.<\/li>\n\n\n\n<li>A Microsoft Azure account with Fabric subscription and familiarity with Azure services, specifically Entra ID, Storage service Blobs container, Function App and Event Grid.<\/li>\n\n\n\n<li>Basics of using Python and Python virtual environments.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"1-architecture-overview\"><span class=\"ez-toc-section\" id=\"Architecture_Overview\"><\/span>Architecture Overview<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Simply put, the TiCDC cluster captures incremental data changes generated by the TiDB cluster in real time as CSV files and writes them into Azure Object Storage (Blob). By having Azure Function App subscribe to the change events from Blob via Event Grid, it can invoke the open Mirroring APIs to write incremental data into the Fabric Mirrored Database in real time and integrate it into OneLake.<\/p>\n\n\n\n<p>In this way, the only transform is performed by Azure Function to convert the changes from TiCDC output to OneLake ingestion format, in real-time. Fabric\u2019s built-in tools for business intelligence, artificial intelligence, and data science can then be used directly.&nbsp;<\/p>\n\n\n\n<p>To understand the solution&#8217;s architecture, this section provides a high-level overview of its key components. When you&#8217;re ready to build it, follow the detailed, step-by-step instructions in the section &#8220;A Step-by-Step Example to Table Replication: From TiDB to Microsoft Fabric.&#8221;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"2-ticdc-cluster\">TiCDC Cluster<\/h3>\n\n\n\n<p>TiCDC is a tool used to capture transactional incremental data from TiDB, sort the captured data, and export row-based incremental data to downstream sinks. Similar to TiDB, the TiCDC cluster supports high-availability deployment. Multi-node, cross-AZ topologies are common in production environments.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"494\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25002129\/image-1-1024x494.png\" alt=\"\" class=\"wp-image-30071\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25002129\/image-1-1024x494.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002129\/image-1-300x145.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002129\/image-1-768x371.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002129\/image-1-1536x741.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002129\/image-1.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>TiCDC\u2019s HA is achieved through TiDB\u2019s Placement Driver (PD). The replication process consists of the following steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Multiple TiCDC processes pull data changes from Row Storage nodes.<\/li>\n\n\n\n<li>TiCDC sorts and merges the data changes.<\/li>\n\n\n\n<li>TiCDC replicates the data changes to downstream systems through replication tasks (changefeeds).<\/li>\n<\/ul>\n\n\n\n<p>For all captured changes, TiCDC outputs them at least once. When the TiDB row storage or TiCDC cluster encounters a failure, TiCDC might send the same incremental change repeatedly.<\/p>\n\n\n\n<p>Azure Blob Container object storage is the TiCDC downstream for the integration solution.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"3-azure-blob-container-function-app-and-event-grid\">Azure Blob Container, Function App, and Event Grid<\/h3>\n\n\n\n<p>The arrival of changed data in the Blob container triggers an Azure Function App via Event Grid. Within the function, the following two key tasks are executed:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Transforms the TiCDC event payload into the acceptable format specified by the OneLake mirrored database.<\/li>\n\n\n\n<li>Ingest the transformed change data into the Landing Zone of the mirrored database.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"325\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25002723\/image-2-1024x325.png\" alt=\"\" class=\"wp-image-30072\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25002723\/image-2-1024x325.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002723\/image-2-300x95.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002723\/image-2-768x244.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002723\/image-2.png 1116w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"4-landing-zone-for-the-mirrored-database\">Landing Zone for the Mirrored Database<\/h3>\n\n\n\n<p>For every mirrored database, there&#8217;s a unique storage location in OneLake for metadata and delta tables. Open mirroring provides a landing zone folder for the Function app to create a metadata file and push incremental data into OneLake. Mirroring monitors these files in the landing zone and reads the folder for new tables and data added.<\/p>\n\n\n\n<p>Once the data lands in the Mirrored Database, open mirroring simplifies the handling of complex data changes, ensuring that all mirrored data is continuously up-to-date and ready for analysis.<\/p>\n\n\n\n<p>To streamline your workflow with Mirrored Database Landing Zones, our solution offers Python utilities that manage all necessary Fabric mirroring API interactions, ensuring compliance with <a href=\"https:\/\/learn.microsoft.com\/en-us\/fabric\/mirroring\/open-mirroring-landing-zone-format\">Landing Zone requirements and file formats<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"5-python-utilities-\">Python Utilities&nbsp;<\/h3>\n\n\n\n<p>To simplify the open-source integration, we provide two helper Python scripts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/pingcap-inc\/tidb-course-labs\/blob\/main\/solution\/microsoft-fabric-mirrored-database\/openmirroring_admin.py\">Admin tool template<\/a>: Designed for replication administrators, this tool offers a high-level API interface for managing tables within the mirrored database. We have adapted the original Microsoft version to ensure compatibility with TiCDC&#8217;s CSV file format.<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/pingcap-inc\/tidb-course-labs\/blob\/main\/solution\/microsoft-fabric-mirrored-database\/function_app.py\">Azure function template<\/a>: This is a semi-complete core script for the Azure Function App, provided as a starter template. You can directly incorporate it into your own Azure Function and customize it to work with your specific business logic.<\/li>\n<\/ul>\n\n\n\n<p>Detailed usage instructions for both of these tools will be provided in the step-by-step guide below.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6-a-step-by-step-example-to-table-replication-from-tidb-to-microsoft-fabric\"><span class=\"ez-toc-section\" id=\"A_Step-by-Step_Example_to_Table_Replication_From_TiDB_to_Microsoft_Fabric\"><\/span>A Step-by-Step Example to Table Replication: From TiDB to Microsoft Fabric<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"7-note\">Note<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>For this demonstration, to ensure a clean separation from your existing environment, we will create a new resource group and storage account dedicated to this example workload. While not the only method, this is the simplest way to enforce permission separation.<\/li>\n\n\n\n<li>The TiDB version we use in this detailed example is TiDB 8.5.1.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"8-step-1-create-a-mirrored-database-in-microsoft-fabric\">Step 1. Create a Mirrored Database in Microsoft Fabric<\/h3>\n\n\n\n<p>The Mirrored Database in Microsoft Fabric can either be created using a <a href=\"https:\/\/learn.microsoft.com\/en-us\/fabric\/mirroring\/mirrored-database-rest-api\">publicly available Rest API<\/a> or through the Microsoft Fabric portal. This blog guides you through the steps via Microsoft Fabric portal:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sign in to the Microsoft Fabric portal.<\/li>\n\n\n\n<li>Create a new workspace. In our example, the workspace name is <strong>integration-demo<\/strong>.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"212\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25002851\/image-3.png\" alt=\"\" class=\"wp-image-30073\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25002851\/image-3.png 940w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002851\/image-3-300x68.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/25002851\/image-3-768x173.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In the workspace, click \u201c+ New item\u201d, choose the <strong>Mirrored database<\/strong> item.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"596\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25003011\/image-4-1024x596.png\" alt=\"\" class=\"wp-image-30074\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25003011\/image-4-1024x596.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/25003011\/image-4-300x175.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/25003011\/image-4-768x447.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/25003011\/image-4.png 1124w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Give it a name. In our example, the mirrored database name is <strong>bs_mirror1<\/strong>. Click \u201cCreate\u201d and wait for the creation to complete, do not navigate away.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"518\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25003102\/image-5.png\" alt=\"\" class=\"wp-image-30075\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25003102\/image-5.png 960w, https:\/\/static.pingcap.com\/files\/2025\/10\/25003102\/image-5-300x162.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/25003102\/image-5-768x414.png 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>After the Mirrored Database is created and replication automatically begins, you will see this interface. You should copy and save the Landing Zone URL for future use. For subsequent steps, we will use the placeholder &lt;landing_zone_url&gt; to represent the Landing Zone URL.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"503\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25003155\/image-6-1024x503.png\" alt=\"\" class=\"wp-image-30076\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/25003155\/image-6-1024x503.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/25003155\/image-6-300x147.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/25003155\/image-6-768x377.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/25003155\/image-6-1536x755.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/25003155\/image-6.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>You have created an empty Mirrored Database in Microsoft Fabric, and by default, it has already started replication. Your database will wait for the data files to be ingested into the Landing Zone.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"9-step-2-create-a-dedicated-azure-resource-group-for-the-example-replication-workload\">Step 2. Create a Dedicated Azure Resource Group for the Example Replication Workload<\/h3>\n\n\n\n<p>This step is optional but recommended. As we will create multiple Azure resources, placing them in a single resource group will simplify IAM (Identity and Access Management) permission control. This approach adheres to security best practices by isolating the example workload&#8217;s access from your existing environment.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sign in to the Microsoft Azure Portal.<\/li>\n\n\n\n<li>Navigate to <strong>Resource groups<\/strong>. Create a new resource group named <strong>bgl-pilot-rg<\/strong>. You also need to assign Subscription and Region to the resource group. In our example, the TiDB cluster is deployed in Oregon US, so we\u2019ll choose <strong>(US) West US 2<\/strong> when possible for every new resource we create along the way<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"764\" height=\"396\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/26060118\/Screenshot-2025-10-26-at-6.28.49-PM.png\" alt=\"\" class=\"wp-image-30077\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/26060118\/Screenshot-2025-10-26-at-6.28.49-PM.png 764w, https:\/\/static.pingcap.com\/files\/2025\/10\/26060118\/Screenshot-2025-10-26-at-6.28.49-PM-300x155.png 300w\" sizes=\"auto, (max-width: 764px) 100vw, 764px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>All new Azure resources created in other steps will be placed into the resource group <strong>bgl-pilot-rg<\/strong>.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"790\" height=\"588\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/26060254\/image-7.png\" alt=\"\" class=\"wp-image-30078\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/26060254\/image-7.png 790w, https:\/\/static.pingcap.com\/files\/2025\/10\/26060254\/image-7-300x223.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/26060254\/image-7-768x572.png 768w\" sizes=\"auto, (max-width: 790px) 100vw, 790px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"10-step-3-create-a-new-storage-account-and-a-blob-container-for-ticdc-sink-destination\">Step 3. Create a New Storage Account and a Blob Container for TiCDC Sink Destination <\/h3>\n\n\n\n<p>TiCDC replicates change data by capturing it from TiDB&#8217;s row storage and feeding it in real-time to an Azure Blob Storage container. This blob container functions as an intermediate staging area, caching the incremental transactional data for further processing.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sign in to the Microsoft Azure Portal.<\/li>\n\n\n\n<li>Navigate to <strong>Storage accounts<\/strong>. You need to <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/storage\/common\/storage-account-create?tabs=azure-portal\">create a storage account<\/a> and put it into resource group <strong>bgl-pilot-rg<\/strong>. Note your storage account name. For subsequent steps, we will use the placeholder &lt;storage_account_name&gt; to represent the name of your storage account.<\/li>\n\n\n\n<li>In your storage account, create a new blob container named <strong>tidb-demo-cdc<\/strong> for our example.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"797\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27010105\/image-9-1024x797.png\" alt=\"\" class=\"wp-image-30087\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27010105\/image-9-1024x797.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010105\/image-9-300x233.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010105\/image-9-768x598.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010105\/image-9-1536x1195.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010105\/image-9.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"11-step-4-prepare-microsoft-entra-id-for-the-replication-workload\">Step 4. Prepare Microsoft Entra ID for the Replication Workload<\/h3>\n\n\n\n<p>The replication workload needs access permissions to Azure Data Lake and other required resources in Azure. In this step, we will first create a Registered App for replication workload authentication.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sign in to the Microsoft Azure Portal.<\/li>\n\n\n\n<li>Navigate to <strong>App registrations<\/strong>. Click \u201c+ New registration\u201d, keep all the defaults, and click \u201cCreate\u201d. In our case, it is named <strong>fabric-app<\/strong>.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"627\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27010239\/image-10-1024x627.png\" alt=\"\" class=\"wp-image-30088\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27010239\/image-10-1024x627.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010239\/image-10-300x184.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010239\/image-10-768x470.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010239\/image-10.png 1404w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Click on <strong>fabric-app<\/strong> and navigate to its Overview page. Then, complete the following three tasks:\n<ul class=\"wp-block-list\">\n<li>Note down the Application (client) ID. We will refer to this as &lt;fabric_app_client_id&gt; in subsequent steps.<\/li>\n\n\n\n<li>Note down the Directory (tenant) ID. We will refer to this as &lt;fabric_app_client_tenant&gt; in subsequent steps.<\/li>\n\n\n\n<li>Generate a client secret for Client credentials and note down the secret value. We will refer to this as &lt;fabric_app_client_secret&gt; in subsequent steps.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"237\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27010437\/image-11-1024x237.png\" alt=\"\" class=\"wp-image-30089\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27010437\/image-11-1024x237.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010437\/image-11-300x69.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010437\/image-11-768x178.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010437\/image-11-1536x355.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27010437\/image-11.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>Add the registered App fabric-app to an Entra ID group. In our case the group name is <strong>sa-general-python-app-test-group<\/strong>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Navigate to Microsoft Entra ID.<\/li>\n\n\n\n<li>Create a group, and assign <strong>fabric-app<\/strong> as its member.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"559\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011139\/image-12-1024x559.png\" alt=\"\" class=\"wp-image-30090\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011139\/image-12-1024x559.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011139\/image-12-300x164.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011139\/image-12-768x419.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011139\/image-12-1536x838.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011139\/image-12.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>Grant required permissions to <strong>fabric-app<\/strong> for replication workload authorization.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Grant permissions to <strong>sa-general-python-app-test-group<\/strong> from Azure portal. Navigate to <strong>Resource groups<\/strong>, click <strong>bgl-pilot-rg<\/strong>, click <strong>Access control (IAM)<\/strong>, click \u201c+ Add\u201d and then <strong>Add role assignment<\/strong>. The following roles are recommended:<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"648\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011304\/image-13-1024x648.png\" alt=\"\" class=\"wp-image-30091\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011304\/image-13-1024x648.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011304\/image-13-300x190.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011304\/image-13-768x486.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011304\/image-13-1536x972.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011304\/image-13.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Grant permissions to <strong>fabric-app<\/strong> from Azure portal. Navigate to <strong>App registrations<\/strong> and click <strong>fabric-app<\/strong> under <strong>API permissions<\/strong>. The following permissions are recommended:<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"515\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011503\/image-14-1024x515.png\" alt=\"\" class=\"wp-image-30092\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011503\/image-14-1024x515.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011503\/image-14-300x151.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011503\/image-14-768x386.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011503\/image-14-1536x772.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011503\/image-14.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Next, sign in to the Microsoft Fabric portal.<\/li>\n\n\n\n<li>Navigate to workspace <strong>integration-demo,<\/strong> and click <strong>Manage access<\/strong>.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"616\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011516\/image-15-1024x616.png\" alt=\"\" class=\"wp-image-30093\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011516\/image-15-1024x616.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011516\/image-15-300x181.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011516\/image-15-768x462.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011516\/image-15-1536x924.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011516\/image-15.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Grant the <strong>Contributor<\/strong> permission to <strong>sa-general-python-app-test-group<\/strong>.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"656\" height=\"592\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011556\/image-16.png\" alt=\"\" class=\"wp-image-30094\" style=\"width:840px;height:auto\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011556\/image-16.png 656w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011556\/image-16-300x271.png 300w\" sizes=\"auto, (max-width: 656px) 100vw, 656px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"12-step-5-create-a-table-in-mirrored-database\">Step 5. Create a Table in Mirrored Database<\/h3>\n\n\n\n<p>In our example, we will replicate a book table in real-time from TiDB to Fabric OneLake.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"821\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011656\/image-17-1024x821.png\" alt=\"\" class=\"wp-image-30095\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011656\/image-17-1024x821.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011656\/image-17-300x241.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011656\/image-17-768x616.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011656\/image-17.png 1090w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>We need to create a mirrored delta table in the mirrored database. The following tasks are recommended to be executed in a Python virtual environment with Python 3.11.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Download the Python admin tool template, which provides a high-level API for managing mirrored databases. In this walkthrough, we download the solution version of the Admin Tool Template, which includes pre-defined metadata for the&nbsp; books table.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>wget https:\/\/raw.githubusercontent.com\/pingcap-inc\/tidb-course-labs\/refs\/heads\/main\/solution\/microsoft-fabric-mirrored-database\/openmirroring_admin_solution.py\n\nwget https:\/\/raw.githubusercontent.com\/pingcap-inc\/tidb-course-labs\/refs\/heads\/main\/solution\/microsoft-fabric-mirrored-database\/requirements.txt<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Modify the Python script <strong>openmirroring_admin_solution.py<\/strong> around line# 430, replace the following placeholders with the actual values you copied from Step 1 and Step 4.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"848\" height=\"130\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011852\/image-18.png\" alt=\"\" class=\"wp-image-30096\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011852\/image-18.png 848w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011852\/image-18-300x46.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011852\/image-18-768x118.png 768w\" sizes=\"auto, (max-width: 848px) 100vw, 848px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Install the dependencies in your Python virtual environment.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install -r requirements.txt&nbsp;<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create an empty table <strong>books_mirror1<\/strong> in the mirrored database.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>python openmirroring_admin_solution.py --create-table --table-name books_mirror1&nbsp;<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sign in to Microsoft Fabric portal.<\/li>\n\n\n\n<li>Navigate to the <strong>integration-demo<\/strong> workspace, open the <strong>bs_mirror1<\/strong> mirrored database, and expand the &#8220;Uploaded files&#8221; section. Verify that a _metadata.json file is present. OneLake will use this metadata to create a delta table asynchronously.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"852\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011958\/image-19-1024x852.png\" alt=\"\" class=\"wp-image-30097\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27011958\/image-19-1024x852.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011958\/image-19-300x250.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011958\/image-19-768x639.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27011958\/image-19.png 1522w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>Now that the <strong>books<\/strong> table definition is in place as <strong>books_mirror1<\/strong> within the mirrored database, any data with anticipated structure uploaded to the Landing Zone will be automatically imported into OneLake. The table definition is defined by variable target_table_metadata in <strong>openmirroring_admin_solution.py<\/strong>. In a real world scenario you can add your own metadata like so or externalize them at your will.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"13-step-6-deploy-an-event-trigger-as-the-changefeed-listener\">Step 6. Deploy an Event Trigger as the Changefeed Listener<\/h3>\n\n\n\n<p>In this step, we will establish the Changefeed listener between the Blob container <strong>tidb-demo-cdc<\/strong> and the Mirrored Database <strong>bs_mirror1<\/strong> Landing Zone. It is achieved by implementing an Azure Function App deployed on the top of Azure Event Grid.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"564\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012136\/image-20-1024x564.png\" alt=\"\" class=\"wp-image-30098\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012136\/image-20-1024x564.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012136\/image-20-300x165.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012136\/image-20-768x423.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012136\/image-20-1536x846.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012136\/image-20.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>Follow this <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/azure-functions\/functions-event-grid-blob-trigger?pivots=programming-language-python\">tutorial<\/a> to develop and deploy the event-driven Azure Function App while keeping the following information in mind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The Azure Function App name should be <strong>table-books-cdc-trigger<\/strong>.<\/li>\n\n\n\n<li>The Blob container path is <strong>tidb-demo-cdc<\/strong>.<\/li>\n\n\n\n<li>Create all resources under the resource group <strong>bgl-pilot-rg<\/strong>.<\/li>\n\n\n\n<li>TiCDC uploads change data as CSV files. When configuring the trigger, ensure its filtering rule targets files with the .csv extension. For our example, the full path for the uploaded change data blob will be tidb-demo-cdc\/&lt;tidb-cluster-name&gt;\/bookshop\/books\/&lt;start-tso-sequence&gt;\/&lt;yyyy-mm-dd&gt;\/CDCnnnnnnnnnnnnnnnnnnnn.csv.<\/li>\n\n\n\n<li>In the Python script <strong>function_app.py<\/strong>, the function name for the trigger should be <strong>event_grid_blob_trigger<\/strong>. For example, you will see the following view in your VS Code editor:<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"63\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012235\/image-21-1024x63.png\" alt=\"\" class=\"wp-image-30099\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012235\/image-21-1024x63.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012235\/image-21-300x19.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012235\/image-21-768x48.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012235\/image-21-1536x95.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012235\/image-21.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>Once you complete all the steps, download the solution <strong>function_app.py<\/strong> Python script to replace the one in your VS Code workspace.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Download the Python Azure Function template and the requirements.txt with the ability to extract the change data of <strong>books<\/strong> table and upload them to Landing Zone.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>wget https:\/\/raw.githubusercontent.com\/pingcap-inc\/tidb-course-labs\/refs\/heads\/main\/solution\/microsoft-fabric-mirrored-database\/function_app.py<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>wget https:\/\/raw.githubusercontent.com\/pingcap-inc\/tidb-course-labs\/refs\/heads\/main\/solution\/microsoft-fabric-mirrored-database\/requirements.txt<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Replace the <strong>function_app.py<\/strong> \uadf8\ub9ac\uace0 <strong>requirements.txt<\/strong> in your VS Code workspace with the downloaded files.<\/li>\n\n\n\n<li>Modify the Python script <strong>function_app.py<\/strong> around line# 12, replace the following placeholders with the actual values you copied from Steps 1 and 4.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"796\" height=\"136\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012426\/image-22.png\" alt=\"\" class=\"wp-image-30100\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012426\/image-22.png 796w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012426\/image-22-300x51.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012426\/image-22-768x131.png 768w\" sizes=\"auto, (max-width: 796px) 100vw, 796px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Next, modify the Python script <strong>function_app.py<\/strong> around line# 403, replacing the placeholder for &lt;connection_name&gt; to the actual connection name. You can find your value in your&nbsp; local_settings.json file. It is similar to xxxxxx_STORAGE.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"396\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012514\/image-23-1024x396.png\" alt=\"\" class=\"wp-image-30101\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012514\/image-23-1024x396.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012514\/image-23-300x116.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012514\/image-23-768x297.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012514\/image-23-1536x594.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012514\/image-23.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"564\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012529\/image-24-1024x564.png\" alt=\"\" class=\"wp-image-30102\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012529\/image-24-1024x564.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012529\/image-24-300x165.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012529\/image-24-768x423.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012529\/image-24.png 1272w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Re-deploy the modified function to Azure Function App.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"14-step-7-prepare-your-tidb-and-ticdc-cluster\">Step 7. Prepare Your TiDB and TiCDC Cluster<\/h3>\n\n\n\n<p>TiCDC (TiDB Change Data Capture) is a core component of TiDB that captures row-level data changes from a TiDB cluster and outputs them to a downstream platform in real-time. TiCDC can be enabled on both TiDB Cloud and TiDB Self-Managed cluster.&nbsp;<\/p>\n\n\n\n<p>This step is only required for self-managed TiDB deployments. If you are using TiDB Cloud, you can skip it, as TiCDC is fully managed by the cloud service. The following instructions explain how to deploy a TiCDC cluster for a self-managed TiDB cluster.<\/p>\n\n\n\n<p>For high availability (HA), our example deploys the TiCDC cluster across three availability zones, matching our TiDB cluster configuration. You can adapt this to your needs; while a single node is functional, multiple nodes across zones are recommended for production. Please note that your existing TiDB cluster can be located on-premises or in any cloud environment, such as AWS, GCP, or Azure.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"973\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012706\/image-25-1024x973.png\" alt=\"\" class=\"wp-image-30103\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012706\/image-25-1024x973.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012706\/image-25-300x285.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012706\/image-25-768x730.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012706\/image-25.png 1094w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Tip for New TiDB Users<\/strong><\/h4>\n\n\n\n<p>If you are new to TiDB and TiCDC, the tasks in this step may seem complex. We recommend using the <a href=\"https:\/\/labs.tidb.io\/labs\/dba_303_lab_ff10\">sandbox environment (2 hours per instance) provided by TiDB Labs<\/a>. Simply choose the Oregon region and start the lab, complete the guided Module 1 to provision a working TiDB cluster with TiCDC enabled, and then directly proceed to Step 6 &#8211; Prepare the Sample Schema.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"547\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012810\/image-26-1024x547.png\" alt=\"\" class=\"wp-image-30104\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012810\/image-26-1024x547.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012810\/image-26-300x160.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012810\/image-26-768x410.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012810\/image-26-1536x821.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012810\/image-26.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prepare three additional nodes for the TiCDC cluster alongside your TiDB cluster. See the node requirements <a href=\"https:\/\/docs.pingcap.com\/tidb\/stable\/ticdc-deployment-topology\/\">\uc5ec\uae30<\/a>. In our example, the private IP addresses for these nodes are 10.90.3.31, 10.90.3.17, and 10.90.3.40.<\/li>\n\n\n\n<li>Compose a yaml configuration for your TiCDC cluster, for example: <strong>example.yaml<\/strong><\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"490\" height=\"370\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012857\/image-27.png\" alt=\"\" class=\"wp-image-30105\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27012857\/image-27.png 490w, https:\/\/static.pingcap.com\/files\/2025\/10\/27012857\/image-27-300x227.png 300w\" sizes=\"auto, (max-width: 490px) 100vw, 490px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Deploy the TiCDC cluster by executing the following tiup cluster scale-out command from your TiUP control machine. For a detailed explanation of the command&#8217;s parameters, please refer to the <a href=\"https:\/\/docs.pingcap.com\/tidb\/stable\/tiup-component-cluster-scale-out\/\">documentation<\/a>.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>tiup cluster scale-out &lt;tidb_cluster_name&gt; --user &lt;tidb_deploy_user&gt; -i &lt;auth_private_key&gt; example.yaml -y<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>To verify the TiCDC cluster is running, execute the following command from your TiUP control machine. Replace &lt;pd_private_address&gt; with the private address of any Placement Driver (PD) node in your cluster. In our example the address is 10.90.3.21.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>tiup ctl:v8.5.1 cdc capture list --pd=http:\/\/&lt;pd_private_address&gt;:2379\n<\/code><\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"188\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27013241\/unnamed.png\" alt=\"\" class=\"wp-image-30107\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27013241\/unnamed.png 512w, https:\/\/static.pingcap.com\/files\/2025\/10\/27013241\/unnamed-300x110.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>Now that you have the source TiDB and TiCDC cluster ready, we will prepare the data in the next step. Also note that TiCDC runs even with an unconfigured changefeed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"15-step-8-prepare-the-example-schema\">Step 8. Prepare the Example Schema<\/h3>\n\n\n\n<p><strong>Tip for New TiDB Users<\/strong>: If you are using the <a href=\"https:\/\/labs.tidb.io\/labs\/dba_303_lab_ff10\">sandbox environment provided by TiDB Labs<\/a>, please do NOT follow Module 2. Follow this step instead.<\/p>\n\n\n\n<p>We will demonstrate the replication using a books table within a bookshop database. This step involves creating this schema and table in your TiDB cluster.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Download the schema creation SQL script.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>wget https:\/\/raw.githubusercontent.com\/pingcap-inc\/tidb-course-labs\/refs\/heads\/main\/solution\/microsoft-fabric-mirrored-database\/bookshop_demo.sql<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Connect to your TiDB cluster and execute the SQL script. For a detailed explanation of how to connect to the TiDB SQL layer by using mysql client, please refer to the <a href=\"https:\/\/docs.pingcap.com\/tidb\/stable\/dev-guide-connect-to-tidb\/\">documentation<\/a>.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql&gt; SOURCE bookshop_demo.sql<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Confirm that there are 100 rows in table <strong>bookshop.books<\/strong>.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"858\" height=\"294\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27013432\/image-28.png\" alt=\"\" class=\"wp-image-30108\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27013432\/image-28.png 858w, https:\/\/static.pingcap.com\/files\/2025\/10\/27013432\/image-28-300x103.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27013432\/image-28-768x263.png 768w\" sizes=\"auto, (max-width: 858px) 100vw, 858px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"16-step-9-upload-the-initial-table-data-to-landing-zone\">Step 9. Upload the Initial Table Data to Landing Zone<\/h3>\n\n\n\n<p>In this step, we use Dumpling to dump the entire books table from TiDB as a CSV file, and upload it to the Mirrored Database Landing Zone. Then, Fabric will push the data into OneLake automatically.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"485\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27013511\/image-29-1024x485.png\" alt=\"\" class=\"wp-image-30109\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27013511\/image-29-1024x485.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27013511\/image-29-300x142.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27013511\/image-29-768x364.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27013511\/image-29-1536x728.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27013511\/image-29.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Export the entire bookshop.books table to a CSV file. Our example executes this task on the TiUP control machine, but you can also run it from a different machine. For details on using Dumpling, please refer to its <a href=\"https:\/\/docs.pingcap.com\/tidb\/stable\/dumpling-overview\/\">documentation<\/a>. In the following command, ${HOST_TIDB_SERVER_IP} represents the IP address of one of your TiDB server instances you can connect to.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>tiup dumpling:v8.5.1 -uroot -P4000 -h ${HOST_TIDB_SERVER_IP} --filetype csv --csv-null-value \"N\/A\" -t 1 -o \/tmp\/books -T bookshop.books<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Verify that the exported files are located in the \/tmp\/books\/ directory.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>ls -l \/tmp\/books\/<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Upload the <strong>bookshop.books.000000000.csv<\/strong> to <strong>bs_mirror1<\/strong> Landing Zone by using the Python script you downloaded in Step 5. (If you run Dumpling on a different machine from the one used in Step 5, you may need to copy the CSV file to that machine first.)<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>python openmirroring_admin_solution.py --upload-data-file --table-name books_mirror1 --local-file-path \/tmp\/books\/bookshop.books.000000000.csv<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In the Microsoft Fabric portal, navigate to the integration-demo workspace and open the bs_mirror1 mirrored database. Verify the results as shown in the highlighted area of the following screenshot:<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"678\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27014330\/image-30-1024x678.png\" alt=\"\" class=\"wp-image-30111\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27014330\/image-30-1024x678.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27014330\/image-30-300x199.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27014330\/image-30-768x508.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27014330\/image-30-1536x1017.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27014330\/image-30.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>Now the mirrored database has the same data in the source database, but the real-time changefeed is not active yet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"17-step-10-start-the-ticdc-changefeed-for-incremental-replication\">Step 10. Start the TiCDC Changefeed for Incremental Replication<\/h3>\n\n\n\n<p>In this step, we will create a changefeed on TiCDC to instruct it to capture all the transactional changes on table bookshop.books and send the changes to Blob container <strong>tidb-demo-cdc, <\/strong>We have already deployed an event listener Azure function on this changefeed. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"420\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27014452\/image-31-1024x420.png\" alt=\"\" class=\"wp-image-30112\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27014452\/image-31-1024x420.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27014452\/image-31-300x123.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27014452\/image-31-768x315.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27014452\/image-31-1536x630.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27014452\/image-31.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sign in to the Microsoft Azure portal, navigate to your storage account, and enable and retrieve the storage account key. For detailed instructions, please refer to this <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/storage\/common\/storage-account-keys-manage?tabs=azure-portal\">documentation<\/a>.<\/li>\n\n\n\n<li>On the TiUP control machine, compose a changefeed configuration file &#8211; books.toml<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;filter]\n\nrules = &#91;\"bookshop.books\"]\n\n&#91;sink]\n\nprotocol = \"csv\"\n\nenable-partition-separator = false\n\n&#91;sink.csv]\n\nnull = \"N\/A\"<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Execute the following command to enable the changefeed. Replace the placeholders with the actual values of your storage account name and storage account key. ${HOST_PD1_PRIVATE_IP} represents the private IP address of any Placement Driver (PD) node in your cluster.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>export ACCOUNT_NAME=\"&lt;storage_account_name&gt;\"\n\nexport ACCOUNT_KEY='&lt;storage_account_key&gt;'\n\nexport CONTAINER_NAME=\"tidb-demo-cdc\"\n\ntiup cdc:v8.5.1 cli changefeed create --pd=http:\/\/${HOST_PD1_PRIVATE_IP}:2379 \\ --sink-uri=\"azure:\/\/${CONTAINER_NAME}\/tidb-test?safe-mode=true&amp;account-name=${ACCOUNT_NAME}&amp;account-key=${ACCOUNT_KEY}\" \\\n\n&nbsp;&nbsp;--changefeed-id=\"replication-task-1\" \\\n\n&nbsp;&nbsp;--sort-engine=\"unified\" \\\n\n&nbsp;&nbsp;--config=books.toml<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use the following command to verify an activated changefeed, along with the expected output:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>tiup cdc:v8.5.1 cli changefeed query \\\n\n--pd=http:\/\/${HOST_PD1_PRIVATE_IP}:2379 \\\n\n--changefeed-id=replication-task-1<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"18-step-11-apply-changes-in-tidb-and-verify-results-in-microsoft-fabric-mirrored-database\">Step 11. Apply Changes in TiDB and Verify Results in Microsoft Fabric Mirrored Database<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Connect to TiDB and make one update on the <strong>bookshop.books<\/strong> table.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>UPDATE bookshop.books SET price = price*0.9 WHERE id=1;<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Navigate to the Fabric portal. You will see that a CSV file has been automatically uploaded to the Landing Zone. Note that the &#8220;Rows replicated&#8221; count will still show 100 and will not immediately update to 101.<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"481\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27030508\/image-32-1024x481.png\" alt=\"\" class=\"wp-image-30113\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27030508\/image-32-1024x481.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27030508\/image-32-300x141.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27030508\/image-32-768x360.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27030508\/image-32-1536x721.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27030508\/image-32.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>After a short wait, when &#8220;Rows replicated&#8221; changes to 101, check the row with id = 1. The price in OneLake should be 0.9 times the value from the bookshop.books.000000000.csv file.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"463\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27030904\/image-33-1024x463.png\" alt=\"\" class=\"wp-image-30114\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27030904\/image-33-1024x463.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27030904\/image-33-300x136.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27030904\/image-33-768x347.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27030904\/image-33-1536x694.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27030904\/image-33.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"525\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031226\/image-34-1024x525.png\" alt=\"\" class=\"wp-image-30115\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031226\/image-34-1024x525.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031226\/image-34-300x154.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031226\/image-34-768x394.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031226\/image-34-1536x787.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031226\/image-34.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Connect to TiDB and make one insert on the <strong>bookshop.books<\/strong> table.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>INSERT INTO bookshop.books VALUES (NULL,'Introduction to TiDB', 'Education &amp; Reference', NOW(), 100, 20.0);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Verify Results in Microsoft Fabric<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Navigate to the Fabric portal. You will see that a CSV file has been automatically uploaded to the Landing Zone again, and the file name was incremented sequentially. Note that the &#8220;Rows replicated&#8221; count will still show 101 and will soon update to 102.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"489\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031406\/image-35-1024x489.png\" alt=\"\" class=\"wp-image-30116\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031406\/image-35-1024x489.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031406\/image-35-300x143.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031406\/image-35-768x367.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031406\/image-35-1536x733.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031406\/image-35.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"525\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031422\/image-36-1024x525.png\" alt=\"\" class=\"wp-image-30117\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031422\/image-36-1024x525.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031422\/image-36-300x154.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031422\/image-36-768x394.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031422\/image-36-1536x787.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031422\/image-36.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Connect to TiDB and delete 5 rows from <strong>bookshop.books<\/strong> table.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>DELETE FROM bookshop.books WHERE id IN (1,2,3,4,5);<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Navigate to the Fabric portal. You will see the result similar to the following screenshot: <br><\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"388\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031456\/image-37-1024x388.png\" alt=\"\" class=\"wp-image-30118\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031456\/image-37-1024x388.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031456\/image-37-300x114.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031456\/image-37-768x291.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031456\/image-37-1536x582.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031456\/image-37.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sign in to Microsoft Azure and navigate to the Blob container named tidb-demo-cdc to examine the staged changefeed CSV files. Note that your TSO and datetime folder names will differ from this example. Pay close attention to the CSV file naming conventions, which differ from the files in the Landing Zone in two key ways:<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li>They are prefixed with &#8220;CDC&#8221;.<\/li>\n\n\n\n<li>Their sequence numbers are one less than the corresponding files in the Landing Zone. This is because the first file in the Landing Zone represents a full data import, while these files contain only incremental changes.<\/li>\n<\/ol>\n\n\n\n<p>For example: The file CDC00000000000000000003.csv here corresponds to 00000000000000000003.csv in the Landing Zone.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"311\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031529\/image-38-1024x311.png\" alt=\"\" class=\"wp-image-30119\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031529\/image-38-1024x311.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031529\/image-38-300x91.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031529\/image-38-768x233.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031529\/image-38-1536x467.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031529\/image-38.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>From the SQL analytics endpoint, you can use T-SQL to verify there are 96 rows in your mirrored database.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"483\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031554\/image-39-1024x483.png\" alt=\"\" class=\"wp-image-30120\" srcset=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27031554\/image-39-1024x483.png 1024w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031554\/image-39-300x142.png 300w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031554\/image-39-768x362.png 768w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031554\/image-39-1536x725.png 1536w, https:\/\/static.pingcap.com\/files\/2025\/10\/27031554\/image-39.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-center\"><\/p>\n\n\n\n<p>Now that your operational data is replicating into OneLake in real-time, you can use all the features described in this <a href=\"https:\/\/learn.microsoft.com\/en-us\/fabric\/onelake\/\">document<\/a> to analyze it immediately.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"19-best-practices\"><span class=\"ez-toc-section\" id=\"Best_Practices\"><\/span>Best Practices<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Between Steps 9 and 10, the bookshop.books table remains unchanged, indicating a period of read-only activity or a pause in transactions. To eliminate this downtime and allow the application to continue processing transactions, you must use the &#8211;start-ts option when creating the changefeed in Step 10. Set the &#8211;start-ts value to the TSO (Timestamp Oracle) captured at the beginning of the Dumpling export in Step 9. This TSO (the value of Pos) can be found in this file&nbsp; \/tmp\/books\/metadata from Step 9.<\/li>\n\n\n\n<li>Based on your business requirements, you can configure different retention policies for the mirrored database landing zone and the Blobs container.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"20-conclusion\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>This blog post demonstrated an integration solution for real-time data replication from TiDB to Microsoft Fabric using TiCDC and Open Mirroring. By following the detailed steps, users can seamlessly integrate their TiDB data into OneLake, leveraging Fabric&#8217;s powerful analytics and AI capabilities. This integration ensures data freshness and consistency, empowering businesses with timely insights for informed decision-making. If you want to know more about the data stream capture and replication capabilities of TiDB, please visit our <a href=\"https:\/\/docs.pingcap.com\/tidb\/stable\/ticdc-deployment-topology\/\">TiCDC documentation<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>TiDB is an open-source distributed SQL database built for cloud-native, data-intensive, and AI-driven applications. It is MySQL compatible and features horizontal scalability, strong consistency, and high availability. By leveraging a TiCDC replication solution for Open Mirroring, TiDB seamlessly integrates with Microsoft Fabric. This unlocks continuous, real-time data synchronization from any TiDB deployment environment into Microsoft [&hellip;]<\/p>\n","protected":false},"author":236,"featured_media":30123,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ub_ctt_via":"","footnotes":""},"categories":[6],"tags":[],"class_list":["post-30069","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-engineering"],"acf":[],"featured_image_src":"https:\/\/static.pingcap.com\/files\/2025\/10\/27043237\/20251027-170225.png","author_info":{"display_name":"Guanglei Bao","author_link":"https:\/\/www.pingcap.com\/ko\/blog\/author\/bao-gl\/"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Replicate TiDB to a Mirrored Database in Microsoft Fabric<\/title>\n<meta name=\"description\" content=\"Replicate TiDB to a Mirrored Database in Microsoft Fabric in real-time with TiCDC and Open Mirroring for seamless data sync and analytics.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.pingcap.com\/ko\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Replicate TiDB to a Mirrored Database in Microsoft Fabric\" \/>\n<meta property=\"og:description\" content=\"Replicate TiDB to a Mirrored Database in Microsoft Fabric in real-time with TiCDC and Open Mirroring for seamless data sync and analytics.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.pingcap.com\/ko\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/\" \/>\n<meta property=\"og:site_name\" content=\"TiDB\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/facebook.com\/pingcap2015\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-27T11:33:45+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-12-04T00:39:23+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27043308\/20251027-170247.png\" \/>\n\t<meta property=\"og:image:width\" content=\"3200\" \/>\n\t<meta property=\"og:image:height\" content=\"1800\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Guanglei Bao\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@PingCAP\" \/>\n<meta name=\"twitter:site\" content=\"@PingCAP\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Guanglei Bao\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"19\ubd84\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/\"},\"author\":{\"name\":\"Guanglei Bao\",\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/person\/b7cfeaa633d1893ad56abb26bda171b3\"},\"headline\":\"How to Replicate TiDB to a Mirrored Database in Microsoft Fabric with TiCDC\",\"datePublished\":\"2025-10-27T11:33:45+00:00\",\"dateModified\":\"2025-12-04T00:39:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/\"},\"wordCount\":3465,\"publisher\":{\"@id\":\"https:\/\/www.pingcap.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/static.pingcap.com\/files\/2025\/10\/27043237\/20251027-170225.png\",\"articleSection\":[\"Engineering\"],\"inLanguage\":\"ko-KR\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/\",\"url\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/\",\"name\":\"How to Replicate TiDB to a Mirrored Database in Microsoft Fabric\",\"isPartOf\":{\"@id\":\"https:\/\/www.pingcap.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/static.pingcap.com\/files\/2025\/10\/27043237\/20251027-170225.png\",\"datePublished\":\"2025-10-27T11:33:45+00:00\",\"dateModified\":\"2025-12-04T00:39:23+00:00\",\"description\":\"Replicate TiDB to a Mirrored Database in Microsoft Fabric in real-time with TiCDC and Open Mirroring for seamless data sync and analytics.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#primaryimage\",\"url\":\"https:\/\/static.pingcap.com\/files\/2025\/10\/27043237\/20251027-170225.png\",\"contentUrl\":\"https:\/\/static.pingcap.com\/files\/2025\/10\/27043237\/20251027-170225.png\",\"width\":3600,\"height\":1200},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.pingcap.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Replicate TiDB to a Mirrored Database in Microsoft Fabric with TiCDC\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.pingcap.com\/#website\",\"url\":\"https:\/\/www.pingcap.com\/\",\"name\":\"TiDB\",\"description\":\"TiDB | SQL at Scale\",\"publisher\":{\"@id\":\"https:\/\/www.pingcap.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.pingcap.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ko-KR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.pingcap.com\/#organization\",\"name\":\"PingCAP\",\"url\":\"https:\/\/www.pingcap.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png\",\"contentUrl\":\"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png\",\"width\":811,\"height\":232,\"caption\":\"PingCAP\"},\"image\":{\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/facebook.com\/pingcap2015\",\"https:\/\/x.com\/PingCAP\",\"https:\/\/linkedin.com\/company\/pingcap\",\"https:\/\/youtube.com\/channel\/UCuq4puT32DzHKT5rU1IZpIA\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/person\/b7cfeaa633d1893ad56abb26bda171b3\",\"name\":\"Guanglei Bao\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.pingcap.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/static.pingcap.com\/files\/2023\/06\/20023309\/bao-gl-150x150.jpeg\",\"contentUrl\":\"https:\/\/static.pingcap.com\/files\/2023\/06\/20023309\/bao-gl-150x150.jpeg\",\"caption\":\"Guanglei Bao\"},\"description\":\"Principal Solutions Architect\",\"url\":\"https:\/\/www.pingcap.com\/ko\/blog\/author\/bao-gl\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Replicate TiDB to a Mirrored Database in Microsoft Fabric","description":"Replicate TiDB to a Mirrored Database in Microsoft Fabric in real-time with TiCDC and Open Mirroring for seamless data sync and analytics.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.pingcap.com\/ko\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/","og_locale":"ko_KR","og_type":"article","og_title":"How to Replicate TiDB to a Mirrored Database in Microsoft Fabric","og_description":"Replicate TiDB to a Mirrored Database in Microsoft Fabric in real-time with TiCDC and Open Mirroring for seamless data sync and analytics.","og_url":"https:\/\/www.pingcap.com\/ko\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/","og_site_name":"TiDB","article_publisher":"https:\/\/facebook.com\/pingcap2015","article_published_time":"2025-10-27T11:33:45+00:00","article_modified_time":"2025-12-04T00:39:23+00:00","og_image":[{"width":3200,"height":1800,"url":"https:\/\/static.pingcap.com\/files\/2025\/10\/27043308\/20251027-170247.png","type":"image\/png"}],"author":"Guanglei Bao","twitter_card":"summary_large_image","twitter_creator":"@PingCAP","twitter_site":"@PingCAP","twitter_misc":{"Written by":"Guanglei Bao","Est. reading time":"19\ubd84"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#article","isPartOf":{"@id":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/"},"author":{"name":"Guanglei Bao","@id":"https:\/\/www.pingcap.com\/#\/schema\/person\/b7cfeaa633d1893ad56abb26bda171b3"},"headline":"How to Replicate TiDB to a Mirrored Database in Microsoft Fabric with TiCDC","datePublished":"2025-10-27T11:33:45+00:00","dateModified":"2025-12-04T00:39:23+00:00","mainEntityOfPage":{"@id":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/"},"wordCount":3465,"publisher":{"@id":"https:\/\/www.pingcap.com\/#organization"},"image":{"@id":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#primaryimage"},"thumbnailUrl":"https:\/\/static.pingcap.com\/files\/2025\/10\/27043237\/20251027-170225.png","articleSection":["Engineering"],"inLanguage":"ko-KR"},{"@type":"WebPage","@id":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/","url":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/","name":"How to Replicate TiDB to a Mirrored Database in Microsoft Fabric","isPartOf":{"@id":"https:\/\/www.pingcap.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#primaryimage"},"image":{"@id":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#primaryimage"},"thumbnailUrl":"https:\/\/static.pingcap.com\/files\/2025\/10\/27043237\/20251027-170225.png","datePublished":"2025-10-27T11:33:45+00:00","dateModified":"2025-12-04T00:39:23+00:00","description":"Replicate TiDB to a Mirrored Database in Microsoft Fabric in real-time with TiCDC and Open Mirroring for seamless data sync and analytics.","breadcrumb":{"@id":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/"]}]},{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#primaryimage","url":"https:\/\/static.pingcap.com\/files\/2025\/10\/27043237\/20251027-170225.png","contentUrl":"https:\/\/static.pingcap.com\/files\/2025\/10\/27043237\/20251027-170225.png","width":3600,"height":1200},{"@type":"BreadcrumbList","@id":"https:\/\/www.pingcap.com\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.pingcap.com\/"},{"@type":"ListItem","position":2,"name":"How to Replicate TiDB to a Mirrored Database in Microsoft Fabric with TiCDC"}]},{"@type":"WebSite","@id":"https:\/\/www.pingcap.com\/#website","url":"https:\/\/www.pingcap.com\/","name":"\ud2f0DB","description":"TiDB | SQL at Scale","publisher":{"@id":"https:\/\/www.pingcap.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.pingcap.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ko-KR"},{"@type":"Organization","@id":"https:\/\/www.pingcap.com\/#organization","name":"PingCAP","url":"https:\/\/www.pingcap.com\/","logo":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/","url":"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png","contentUrl":"https:\/\/static.pingcap.com\/files\/2021\/11\/pingcap-logo.png","width":811,"height":232,"caption":"PingCAP"},"image":{"@id":"https:\/\/www.pingcap.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/facebook.com\/pingcap2015","https:\/\/x.com\/PingCAP","https:\/\/linkedin.com\/company\/pingcap","https:\/\/youtube.com\/channel\/UCuq4puT32DzHKT5rU1IZpIA"]},{"@type":"Person","@id":"https:\/\/www.pingcap.com\/#\/schema\/person\/b7cfeaa633d1893ad56abb26bda171b3","name":"Guanglei Bao","image":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.pingcap.com\/#\/schema\/person\/image\/","url":"https:\/\/static.pingcap.com\/files\/2023\/06\/20023309\/bao-gl-150x150.jpeg","contentUrl":"https:\/\/static.pingcap.com\/files\/2023\/06\/20023309\/bao-gl-150x150.jpeg","caption":"Guanglei Bao"},"description":"Principal Solutions Architect","url":"https:\/\/www.pingcap.com\/ko\/blog\/author\/bao-gl\/"}]}},"grav_blocks":false,"card_markup":"<a class=\"card-resource bg-white\" href=\"https:\/\/www.pingcap.com\/ko\/blog\/replicate-tidb-mirrored-database-microsoft-fabric-ticdc\/\"><div class=\"card-resource__image-container\"><img class=\"card-resource__image\" alt=\"20251027-170225\" src=\"https:\/\/static.pingcap.com\/files\/2025\/10\/27043237\/20251027-170225.png\" loading=\"lazy\" width=3600 height=1200 \/><\/div><div class=\"card-resource__content-container\"><div class=\"card-resource__content-head\"><div class=\"card-resource__category\">Engineering<\/div><\/div><h5 class=\"card-resource__title\">How to Replicate TiDB to a Mirrored Database in Microsoft Fabric with TiCDC<\/h5><\/div><\/a>","_links":{"self":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/posts\/30069","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/users\/236"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/comments?post=30069"}],"version-history":[{"count":15,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/posts\/30069\/revisions"}],"predecessor-version":[{"id":30850,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/posts\/30069\/revisions\/30850"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/media\/30123"}],"wp:attachment":[{"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/media?parent=30069"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/categories?post=30069"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pingcap.com\/ko\/wp-json\/wp\/v2\/tags?post=30069"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}