從 Aurora 同步到 EC2 上的 MySQL

Percona 這篇「How to Set Up Replication Between AWS Aurora and an External MySQL Instance」講怎麼設定 Amazon Aurora,把資料同步到外部的 MySQL instance。

其中最重要的應該是你需要透過 snapshot 建出 consistent backup,然後用這份資料去接 Aurora 的 master server:

Create a snapshot and restore it (create a new instance from a snapshot). This is only needed to make a consistent copy with mysqldump. As Aurora does not allow “super” privileges, running mysqldump --master-data is not possible. The snapshot is the only way to get a consistent backup with the specific binary log position.

能拉出來後續就能做很多事情...

Amazon Aurora (PostgreSQL) 也支援 Read Replica 了

Amazon Aurora (PostgreSQL) 支援 Read Replica 了:「Announcing Amazon Aurora PostgreSQL Read Replica for Amazon RDS for PostgreSQL」。

馬上想到的用途是量爆增時,如果當初有作 R/W split (讀寫分離) 就可以直接用錢撐住,不過官方給的範例是降低 RDS 轉移到 Aurora 的 downtime,這點就有點微妙...:

You can now create an Amazon Aurora PostgreSQL read replica for an Amazon RDS for PostgreSQL instance, allowing you to continuously replicate to Amazon Aurora PostgreSQL. This helps you minimize downtime when migrating a live workload from Amazon RDS for PostgreSQL to Amazon Aurora PostgreSQL, by keeping the instances in sync until you're ready to move your applications and users to Amazon Aurora PostgreSQL.

所以這次算是陸陸續續把功能補上來,在 Amazon Aurora (MySQL) 有的一般性功能,這邊就跟著先實作...

Amazon DynamoDB 跨區 Replication 以及備份

Amazon DynamoDB 實做了全球性的 replication,以及備份功能:「Amazon DynamoDB Update – Global Tables and On-Demand Backup」。

跨區 replication 的功能讓每個 region 都可以存取當地機房的 DynamoDB:

Global Tables – You can now create tables that are automatically replicated across two or more AWS Regions, with full support for multi-master writes, with a couple of clicks. This gives you the ability to build fast, massively scaled applications for a global user base without having to manage the replication process.

這有點類似 GoogleCloud Spanner 在前陣子也推出全球性服務,但 DynamoDB 提供的比較偏向 NoSQL 而不是 RDBMS。

另外一個限制是跨區同步是 async,會有 replication lag 的問題:

Updates are propagated to other Regions asynchronously via DynamoDB Streams and are typically complete within one second (you can track this using the new ReplicationLatency and PendingReplicationCount metrics).

不過如果是這樣的機制,conflict 的問題不知道怎麼解決... 文章裡面沒看到。

然後目前支援的區域還是有限:

Global Tables are available in the US East (Ohio), US East (N. Virginia), US West (Oregon), EU (Ireland), and EU (Frankfurt) Regions today, with more Regions in the works for 2018.

另外一個是備份與還原機制,有這樣的功能對很多計畫方便不少:

On-Demand Backup – You can now create full backups of your DynamoDB tables with a single click, and with zero impact on performance or availability. Your application remains online and runs at full speed. Backups are suitable for long-term retention and archival, and can help you to comply with regulatory requirements.

而備份還原機制是陸陸續續開放的,區域也有限:

We are rolling this new feature out on an account-by-account basis as quickly as possible, with initial availability in the US East (Northern Virginia), US East (Ohio), US West (Oregon), and EU (Ireland) Regions.

大型 WordPress 站台會用到的 LudicrousDB (以及 HyperDB)

最近收到 HyperDB 的 mailing list 信件 (開頭是「[HyperDB] How can I set up HyperDB with latest version.」這封),有人提到 HyperDB 很久沒更新了... 結果在信理看到有人回了「stuttter/ludicrousdb」這個專案:

LudicrousDB is an advanced database interface for WordPress that supports replication, failover, load balancing, & partitioning

兩個專案都是抽換掉 WordPress 在處理 database 的 library,然後希望自己控制 master/slave 的讀寫分離以及各機房之間的處理 (還有 replication lag),而不要靠 ProxySQL 這類工具來做 (以時間來看,當初他們發展這些工具時,ProxySQL 這類的方案也還不夠成熟,大家都不會想要選這個方向...)。

先記錄下來,如果之後有遇到時可以當作是一個選項...

在 MOPCON 2017 的 Unconference「MySQL to NoSQL & Search Engine」

把投影片傳到 Speaker Deck 上了:「MySQL to NoSQL & Search Engine」。

這是在介紹 noplay/python-mysql-replication 這個軟體,我在示範時用的 python script 有增加 blocking 參數讓他保持一直讀取 MySQL replication stream:

from pymysqlreplication import BinLogStreamReader

mysql_settings = {'host': '127.0.0.1', 'port': 3306, 'user': 'root', 'passwd': ''}

stream = BinLogStreamReader(connection_settings = mysql_settings, server_id=100, blocking=True)

for binlogevent in stream:
    binlogevent.dump()

stream.close()

利用這樣的工具可以做很多事情,像是當 post 表格更新時自動更新 search engine,並且清空 memcached 內的資料。這可以避免使用 library 時有可能會漏掉忘記做 (因為有些程式不用 library 處理),可靠度比較高。

另外一方面 replication protocol 本身就有考慮重連的問題,重新接上時是可以從上一次處理完的資料繼續處理 (只要不要隔太久),這讓寫應用的人不需要用太複雜的方式確保他不會漏掉。

PostgreSQL 10 發表

PostgreSQL 10 發表,有不少重要的功能 (進步):「PostgreSQL 10 Released」。

首先提到的是 Logical Replication:

Logical Replication - A publish/subscribe framework for distributing data

以往內建的 replication 是 block level change (同步哪個 block 改變的內容),對於版本不同的 PostgreSQL 就會痛。所以在 10 之前,想要處理 PostgreSQL 版本不同的問題都會使用第三方套件 (一種常見的情境就是資料庫的版本升級)。在 10 內建支援 Logical Replication 後就不需要掛其他套件了:

Logical replication extends the current replication features of PostgreSQL with the ability to send modifications on a per-database and per-table level to different PostgreSQL databases. Users can now fine-tune the data replicated to various database clusters and will have the ability to perform zero-downtime upgrades to future major PostgreSQL versions.

於是就可以達到 zero-downtime upgrade,這對於商業維運考量是個很重要的進展。

另外一個是 Improved Query Parallelism (在 9.6 就有,現在又再改善了),針對可平行化的 CPU-bounded SQL query 可以利用多 CPU 大幅加速,這點也是目前在 MySQL 上還沒看到的:

PostgreSQL 10 provides better support for parallelized queries by allowing more parts of the query execution process to be parallelized. Improvements include additional types of data scans that are parallelized as well as optimizations when the data is recombined, such as pre-sorting. These enhancements allow results to be returned more quickly.

上面提到這兩點其實對於某些需求是相輔相成的。

因為很多報表分析是可平行化的 CPU-bounded SQL query,但以前在 RDBMS 都不能被平行運算,於是很多單位就會想要倒出來到其他類型的資料庫運算 (以現在比較紅的產品,像是 Amazon RedshiftAmazon Athena,或是 BigQuery,甚至是丟進 ELK 裡)。但你用 PostgreSQL 又會痛在沒辦法很方便的把資料同步拉出來... (於是就會稍微妥協,用 cron job 每天倒資料)

現在 10 的這兩個功能剛好從兩個面向解決:一個是對於剛開使用 PostgreSQL 的人,他們可以繼續只用 PostgreSQL 撐久一點,因為報表需求的 SQL query 快很多;另外一方面也讓目前用 cron job 每天倒資料的人有了同步的選擇 (用 replication 同步到其他系統上)。

再來是 Quorum Commit for Synchronous Replication 這個功能,把分散式架構中需要「正確性」的底層技術做起來:

PostgreSQL 10 introduces quorum commit for synchronous replication, which allows for flexibility in how a primary database receives acknowledgement that changes were successfully written to remote replicas. An administrator can now specify that if any number of replicas has acknowledged that a change to the database has been made, then the data can be considered safely written.

整體來說,PostgreSQL 10 有非常多進步,而且這些進步對於商業營運考量都很有幫助...

MySQL 上 Replication 的方案

Percona 的人整理了一篇關於 Replication 的方案 (以及 NDB,不過這邊就先偷偷跳過去...),雖然標題寫的是 High Availability:「The MySQL High Availability Landscape in 2017 (The Elders)」。

先講他給的另外兩個方案,一個是 Shared Storage,另外一個是 NDB。

其中 Shared Storage 其實在儲存空間端還是有單點失效的問題,而 NDB 的特性跟 InnoDB 不同,有很多概念要重新學... 如果就這三個比較,常見的還是第一個提到的 Replication。

其實把 Replication 用熟的話已經可以解決不少問題了 (不論是早期的 MMM,或是 MHA)。而且因為技術已經發展很久了,大家幾乎都很熟特性 (以及 bug XD),網路上可以找到不少資料,甚至 Percona 也都能夠支援 (當你願意付錢的時候 XDDD)。

Oracle 的人講 MySQL 5.7 最新出的 Group Replication

不愧是 Oracle 的 MySQL Community Manager,把對手的 Galera Cluster 講的一無是處 XDDD:「Group Replication is GA with MySQL 5.7.17 – comparison with Galera」。

然後下面 comment 的地方 Mark Callaghan (@Facebook) 出來提 Galera Cluster 架構中 arbitrator 的好處,另外 Sergei Petrunia (@MariaDB) 也出來糾正抹黑對手的 FUD (講 Galera Cluster 的 protocol 是 "proprietary"),不知道還會不會其他人跳進來...

另外文章裡面看起來也怪怪的,像是 Group Replication 在 InnoDB 上的作法真的能解決他說的問題嗎... conflict 把有問題的 transaction 砍掉不是很合理嗎?設計個 high priority transaction 是怎樣...

來繼續觀望看看就好,Galera Cluster 的成熟度還是很高的... 也許等到其他幾家也決定把 Group Replication 放進支援再說吧。

MongoDB 的 replica-set 設定

Percona 的人寫了一份文件,以 MySQL DBA 的角度說明兩者在 replication 上的差異,然後示範怎麼在單機上架起三個 MongoDB 並且設定 replica-set:「First MongoDB replica-set Configuration for MySQL DBAs」。

這邊文章拿的是 Percona Server for MongoDB,不過應該也還行,並竟是拿 MongoDB 3.2 改的,而不是完全重寫,所以裡面的步驟拿到原版的 MongoDB 上應該也行...

可以拿 Docker 或是在 AWS 開一台 t2.medium 測試玩看看...

MySQL GTID Replication 的惡搞修復

Percona 的「Database Daily Ops Series: GTID Replication」這篇在講當 MySQL 的 GTID Replication 爛掉時可能的修法,算是頗惡搞的方法,修好後還是要跑 pt-table-checksum 確認兩邊的資料是否一致,如果有狀況的話還是得拿出 pt-table-sync 同步。

第一招是用 pt-slave-restart,跳過會造成問題 SQL,讓他強制同步 (唔):

This passes the master’s UUID and it skips all global transactions breaking replication on a specific slave server[.]

第二招是 mysqlslavetrx,也是類似的作法,只是拿的是 MySQL 官方的工具來惡搞...

第三招是 Inject a Fake Transaction,其實就是手動自己做 XDDD

所以不管是哪招,做完後還是要記得跑 pt-table-{checksum,sync} 收尾,不然還是會爛掉...