<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Multi-Source on Tarragon</title><link>https://tarrragon.github.io/blog/tags/multi-source/</link><description>Recent content in Multi-Source on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 22 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/multi-source/index.xml" rel="self" type="application/rss+xml"/><item><title>MySQL Multi-source Replication</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/mysql/multi-source-replication/</link><pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/mysql/multi-source-replication/</guid><description>&lt;p>MySQL multi-source replication 的核心責任是讓一個 replica 從多個 source 接收資料。這種拓撲常用於資料整併、分庫匯總、migration staging、報表集中或多個 bounded context 的 read consolidation。&lt;/p>
&lt;p>本文的判讀錨點是：multi-source replication 是 consolidation pattern，而非 multi-primary conflict resolution。每個 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/replication-channel/" data-link-title="Replication Channel" data-link-desc="說明多來源複製中，每個來源對應的獨立複製通道如何成為隔離單位">replication channel&lt;/a> 要有獨立 source、schema scope、lag、error handling 與 ownership。&lt;/p>
&lt;h2 id="use-cases">Use Cases&lt;/h2>
&lt;p>Use cases 的核心責任是確認 multi-source 解決的是整併需求。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>情境&lt;/th>
 &lt;th>適合條件&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Reporting replica&lt;/td>
 &lt;td>多個 source 匯入同一 read-only target&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Migration staging&lt;/td>
 &lt;td>新平台先接多個 source binlog&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Regional fan-in&lt;/td>
 &lt;td>多區 local DB 匯總到中心&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Shard consolidation&lt;/td>
 &lt;td>多 shard 同 schema 匯入 reporting DB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Audit / CDC sink&lt;/td>
 &lt;td>變更集中供後續 pipeline 使用&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Multi-source target 通常應 read-only。若 target 同時接受 application write，就要設計 conflict 與 ownership，複雜度會大幅提高。&lt;/p>
&lt;h2 id="channel-design">Channel Design&lt;/h2>
&lt;p>Channel design 的核心責任是把每個 source 隔離成可觀測單位。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>設計項&lt;/th>
 &lt;th>審查問題&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Channel name&lt;/td>
 &lt;td>是否能看出 source / owner / purpose&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Schema scope&lt;/td>
 &lt;td>不同 source 是否寫入不同 schema / table&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GTID&lt;/td>
 &lt;td>GTID domain / collision policy&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Filter&lt;/td>
 &lt;td>replicate-do / ignore 規則是否可審查&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Credential&lt;/td>
 &lt;td>每個 channel 是否獨立 secret&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Lag alert&lt;/td>
 &lt;td>channel-level lag 與 error&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Channel 命名要可讀。Incident 時看到 channel 名稱，就要知道哪個 source、哪個 team、哪個用途與是否可暫停。&lt;/p>
&lt;h2 id="conflict-boundary">Conflict Boundary&lt;/h2>
&lt;p>Conflict boundary 的核心責任是避免多個 source 寫同一份邏輯資料。Multi-source 沒有自動解決業務 conflict 的能力。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Conflict 類型&lt;/th>
 &lt;th>控制方式&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Primary key collision&lt;/td>
 &lt;td>shard key prefix、schema isolation&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Duplicate natural key&lt;/td>
 &lt;td>source namespace、dedupe layer&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Out-of-order update&lt;/td>
 &lt;td>source ownership、event timestamp&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Delete collision&lt;/td>
 &lt;td>tombstone policy&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DDL drift&lt;/td>
 &lt;td>migration coordination&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>最安全的 pattern 是每個 source 寫自己的 schema 或帶 source namespace 的 table。若多 source 寫同一 table，必須先設計 key space 與 conflict policy。&lt;/p>
&lt;h2 id="monitoring">Monitoring&lt;/h2>
&lt;p>Monitoring 的核心責任是讓每個 channel 的狀態可見。&lt;/p></description><content:encoded><![CDATA[<p>MySQL multi-source replication 的核心責任是讓一個 replica 從多個 source 接收資料。這種拓撲常用於資料整併、分庫匯總、migration staging、報表集中或多個 bounded context 的 read consolidation。</p>
<p>本文的判讀錨點是：multi-source replication 是 consolidation pattern，而非 multi-primary conflict resolution。每個 <a href="/blog/backend/knowledge-cards/replication-channel/" data-link-title="Replication Channel" data-link-desc="說明多來源複製中，每個來源對應的獨立複製通道如何成為隔離單位">replication channel</a> 要有獨立 source、schema scope、lag、error handling 與 ownership。</p>
<h2 id="use-cases">Use Cases</h2>
<p>Use cases 的核心責任是確認 multi-source 解決的是整併需求。</p>
<table>
  <thead>
      <tr>
          <th>情境</th>
          <th>適合條件</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Reporting replica</td>
          <td>多個 source 匯入同一 read-only target</td>
      </tr>
      <tr>
          <td>Migration staging</td>
          <td>新平台先接多個 source binlog</td>
      </tr>
      <tr>
          <td>Regional fan-in</td>
          <td>多區 local DB 匯總到中心</td>
      </tr>
      <tr>
          <td>Shard consolidation</td>
          <td>多 shard 同 schema 匯入 reporting DB</td>
      </tr>
      <tr>
          <td>Audit / CDC sink</td>
          <td>變更集中供後續 pipeline 使用</td>
      </tr>
  </tbody>
</table>
<p>Multi-source target 通常應 read-only。若 target 同時接受 application write，就要設計 conflict 與 ownership，複雜度會大幅提高。</p>
<h2 id="channel-design">Channel Design</h2>
<p>Channel design 的核心責任是把每個 source 隔離成可觀測單位。</p>
<table>
  <thead>
      <tr>
          <th>設計項</th>
          <th>審查問題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Channel name</td>
          <td>是否能看出 source / owner / purpose</td>
      </tr>
      <tr>
          <td>Schema scope</td>
          <td>不同 source 是否寫入不同 schema / table</td>
      </tr>
      <tr>
          <td>GTID</td>
          <td>GTID domain / collision policy</td>
      </tr>
      <tr>
          <td>Filter</td>
          <td>replicate-do / ignore 規則是否可審查</td>
      </tr>
      <tr>
          <td>Credential</td>
          <td>每個 channel 是否獨立 secret</td>
      </tr>
      <tr>
          <td>Lag alert</td>
          <td>channel-level lag 與 error</td>
      </tr>
  </tbody>
</table>
<p>Channel 命名要可讀。Incident 時看到 channel 名稱，就要知道哪個 source、哪個 team、哪個用途與是否可暫停。</p>
<h2 id="conflict-boundary">Conflict Boundary</h2>
<p>Conflict boundary 的核心責任是避免多個 source 寫同一份邏輯資料。Multi-source 沒有自動解決業務 conflict 的能力。</p>
<table>
  <thead>
      <tr>
          <th>Conflict 類型</th>
          <th>控制方式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Primary key collision</td>
          <td>shard key prefix、schema isolation</td>
      </tr>
      <tr>
          <td>Duplicate natural key</td>
          <td>source namespace、dedupe layer</td>
      </tr>
      <tr>
          <td>Out-of-order update</td>
          <td>source ownership、event timestamp</td>
      </tr>
      <tr>
          <td>Delete collision</td>
          <td>tombstone policy</td>
      </tr>
      <tr>
          <td>DDL drift</td>
          <td>migration coordination</td>
      </tr>
  </tbody>
</table>
<p>最安全的 pattern 是每個 source 寫自己的 schema 或帶 source namespace 的 table。若多 source 寫同一 table，必須先設計 key space 與 conflict policy。</p>
<h2 id="monitoring">Monitoring</h2>
<p>Monitoring 的核心責任是讓每個 channel 的狀態可見。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">SHOW</span><span class="w"> </span><span class="n">REPLICA</span><span class="w"> </span><span class="n">STATUS</span><span class="w"> </span><span class="k">FOR</span><span class="w"> </span><span class="n">CHANNEL</span><span class="w"> </span><span class="s1">&#39;source_a&#39;</span><span class="err">\</span><span class="k">G</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="k">SHOW</span><span class="w"> </span><span class="n">REPLICA</span><span class="w"> </span><span class="n">STATUS</span><span class="w"> </span><span class="k">FOR</span><span class="w"> </span><span class="n">CHANNEL</span><span class="w"> </span><span class="s1">&#39;source_b&#39;</span><span class="err">\</span><span class="k">G</span></span></span></code></pre></div><p>要觀測：</p>
<ol>
<li>IO thread / SQL thread status。</li>
<li>Seconds behind source。</li>
<li>Last IO error / SQL error。</li>
<li>Relay log growth。</li>
<li>GTID executed / retrieved。</li>
<li>Channel credential expiry。</li>
</ol>
<p>Lag 要分 channel 告警。總體 replica 健康不足以定位哪個 source 卡住。</p>
<h2 id="migration-pattern">Migration Pattern</h2>
<p>Migration pattern 的核心責任是把 multi-source 用在可回退的搬遷。</p>
<table>
  <thead>
      <tr>
          <th>Phase</th>
          <th>Evidence</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source audit</td>
          <td>schema、GTID、binlog format</td>
      </tr>
      <tr>
          <td>Target setup</td>
          <td>channel、filter、credential</td>
      </tr>
      <tr>
          <td>Backfill</td>
          <td>dump / load、checksum</td>
      </tr>
      <tr>
          <td>Catch-up</td>
          <td>channel lag、error</td>
      </tr>
      <tr>
          <td>Read test</td>
          <td>report query、row count</td>
      </tr>
      <tr>
          <td>Cutover</td>
          <td>read endpoint switch</td>
      </tr>
      <tr>
          <td>Cleanup</td>
          <td>stop channel、retention、secret</td>
      </tr>
  </tbody>
</table>
<p>Migration target 若只是 reporting，cutover 風險較低；若要成為 new primary，還要處理 write freeze、conflict、application route 與 rollback。</p>
<h2 id="failure-modes">Failure Modes</h2>
<p>Failure modes 的核心責任是把 multi-source 事故分 channel 處理。</p>
<table>
  <thead>
      <tr>
          <th>Failure mode</th>
          <th>判讀訊號</th>
          <th>修正方向</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Single channel lag</td>
          <td>某 source 延遲</td>
          <td>查 source load、network、SQL error</td>
      </tr>
      <tr>
          <td>DDL drift</td>
          <td>replication SQL error</td>
          <td>migration coordination</td>
      </tr>
      <tr>
          <td>Key collision</td>
          <td>duplicate key error</td>
          <td>namespace / key rewrite</td>
      </tr>
      <tr>
          <td>Relay log growth</td>
          <td>target apply 慢</td>
          <td>調整 parallel apply、拆 workload</td>
      </tr>
      <tr>
          <td>Credential expired</td>
          <td>IO thread stopped</td>
          <td>rotate secret、resume channel</td>
      </tr>
  </tbody>
</table>
<p>Channel failure 要避免全局操作。只停問題 channel，保留其他 channel，能降低 blast radius。</p>
<h2 id="下一步路由">下一步路由</h2>
<p>Multi-source replication 完成後，基本拓撲讀 <a href="../replication-topology/">Replication Topology</a>；failover 讀 <a href="../orchestrator-failover/">Orchestrator Failover</a>；CDC 與 binlog 讀 <a href="../binlog-cdc/">Binlog CDC</a>。</p>
]]></content:encoded></item></channel></rss>