はじめに
MySQL Database Service (略 MDS) には、ちょっと前に、Inbound Replication 機能が追加されました。これは、オンプレミスなどで稼働している MySQL を レプリケーションの Source(Master) にして、MDS へ非同期レプリケーションが出来る機能です。今回の記事では、Inbound Replication の設定手順を紹介します。
次の Document を参考にしています
https://docs.oracle.com/en-us/iaas/mysql-database/doc/replication.html
用語について
MySQL のレプリケーションで、データ同期元を Source と呼びます。データ同期先を Replica と呼びます。ちょっと前まで、Master, Slave と呼ばれていましたが、用語変更されました。今回の記事では、新しい定義で書いていきます。
制限事項
Document に書かれている通り、Inbound Replication は次の制限事項があるのでご注意ください
- 行ベースレプリケーションのみサポート
- GTIDベースのレプリケーションのみサポート
- マルチソースレプリケーションは非サポート
- レプリケーションフィルターは非サポート
- Source(Master) の
mysql
スキーマはレプリケーション対象外。また、mysql
スキーマで変更をしてしまうと、レプリケーションが停止してしまう
Source : MySQL のインストール
データ同期元の Source を CentOS 7 上で適当に作ります。この辺を参考に。
https://qiita.com/sugimount/items/bf44904db8201d377536
8.0.23 をインストール
========================================================================================================================
Package Arch Version Repository Size
========================================================================================================================
Installing:
mysql-community-libs x86_64 8.0.23-1.el7 mysql80-community 4.6 M
replacing mariadb-libs.x86_64 1:5.5.68-1.el7
mysql-community-libs-compat x86_64 8.0.23-1.el7 mysql80-community 1.2 M
replacing mariadb-libs.x86_64 1:5.5.68-1.el7
mysql-community-server x86_64 8.0.23-1.el7 mysql80-community 518 M
Installing for dependencies:
mysql-community-client x86_64 8.0.23-1.el7 mysql80-community 48 M
mysql-community-client-plugins x86_64 8.0.23-1.el7 mysql80-community 237 k
mysql-community-common x86_64 8.0.23-1.el7 mysql80-community 621 k
Transaction Summary
========================================================================================================================
Source : テストデータ作成
作った Source の MySQL にテストデータを作成します
sugitest
スキーマ作成
mysql> create database sugitest;
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sugitest |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql>
sample
テーブルの作成
use sugitest;
CREATE TABLE sample(
id INT(11) NOT NULL AUTO_INCREMENT,
value INT(5) NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
INSERT INTO sample(value) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
Source : GTID Mode を有効
8.0.23 の Default では、gtid_mode が OFF になっている。Replication のために、ON へ変更
mysql> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | OFF |
| gtid_executed | |
| gtid_executed_compression_period | 0 |
| gtid_mode | OFF |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+-----------+
9 rows in set (0.01 sec)
mysql>
編集
sudo vim /etc/my.cnf
追記
[mysqld]
...
省略
...
log-bin
server-id=100
log-slave-updates
gtid-mode=ON
enforce-gtid-consistency=true
再起動
sudo systemctl restart mysqld
有効化されている
mysql> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed | |
| gtid_executed_compression_period | 0 |
| gtid_mode | ON |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+-----------+
9 rows in set (0.00 sec)
mysql>
Source : レプリケーションユーザーの設定
ユーザー作成
CREATE USER rpluser001@'%' IDENTIFIED BY 'Rpl001#!' REQUIRE SSL;
REPLICATION SLAVE の権限付与
GRANT REPLICATION SLAVE on *.* to rpluser001@'%';
Source : Dump ファイルを Export
MySQL Shell を使って、Dump ファイルを作成します。
https://docs.oracle.com/en-us/iaas/mysql-database/doc/importing-and-exporting-databases.html#GUID-63396585-3ECA-4202-86D7-94C6DE08CCCD
このあたりを参考に、MySQL Shell を Insall
https://qiita.com/sugimount/items/bf44904db8201d377536#mysql-shell-install
Export用ユーザー作成
CREATE USER sugi01@'%' IDENTIFIED BY 'mIfoO8_fai12#-gai897fao';
grant all on *.* to sugi01@'%';
MySQL Shell で接続
mysqlsh sugi01@10.0.0.63
接続例
[opc@mysql-client01 ~]$ mysqlsh sugi01@10.0.0.63
Please provide the password for 'sugi01@10.0.0.63': ***********************
Save password for 'sugi01@10.0.0.63'? [Y]es/[N]o/Ne[v]er (default No):
MySQL Shell 8.0.23
Copyright (c) 2016, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.
Type '\help' or '\?' for help; '\quit' to exit.
Creating a session to 'sugi01@10.0.0.63'
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 25 (X protocol)
Server version: 8.0.23 MySQL Community Server - GPL
No default schema selected; type \use <schema> to set one.
MySQL 10.0.0.63:33060+ ssl JS >
ここのバケットにDumpする
util.dumpInstance
で、Source MySQL の全体の Dump を取得
util.dumpInstance("SourceInstanceDump", {osBucketName: "mysqldump", osNamespace: "orasejapan", threads: 4, ocimds: true, compatibility: ["strip_restricted_grants"]})
ちなみに、自分の環境ではハマりポイントがありました。次のエラーが発生ました。
JS > util.dumpInstance("SourceInstanceDump", {osBucketName: "mysqldump", osNamespace: "orasejapan", threads: 4, ocimds: true, compatibility: ["strip_restricted_grants"]})
Util.dumpInstance: Cannot load "~/.oci/oci_api_key.pem" private key associated with OCI configuration profile named "DEFAULT". (RuntimeError)
原因は /home/opc/.oci/config
ファイルの中の書き方でした。key_file
の書き方がチルダ(~) が含まれているとエラーでした。
[opc@mysql-client01 .oci]$ cat config
[DEFAULT]
key_file=~/.oci/oci_api_key.pem
region=ap-tokyo-1
絶対パスで指定すると正常に動作しました。もし同じエラーの場合は注意してください。
[opc@mysql-client01 .oci]$ cat config
[DEFAULT]
key_file=/home/opc/.oci/oci_api_key.pem
region=ap-tokyo-1
実行例
MySQL 10.0.0.63:33060+ ssl JS > util.dumpInstance("SourceInstanceDump", {osBucketName: "mysqldump", osNamespace: "orasejapan", threads: 4, ocimds: true, compatibility: ["strip_restricted_grants"]})
Acquiring global read lock
Global read lock acquired
Gathering information - done
All transactions have been started
Locking instance for backup
Global read lock has been released
Checking for compatibility with MySQL Database Service 8.0.23
NOTE: User 'root'@'localhost' had restricted privileges (AUDIT_ADMIN, BACKUP_ADMIN, BINLOG_ADMIN, BINLOG_ENCRYPTION_ADMIN, CLONE_ADMIN, CREATE TABLESPACE, ENCRYPTION_KEY_ADMIN, FILE, FLUSH_OPTIMIZER_COSTS, FLUSH_STATUS, FLUSH_TABLES, FLUSH_USER_RESOURCES, GROUP_REPLICATION_ADMIN, INNODB_REDO_LOG_ARCHIVE, INNODB_REDO_LOG_ENABLE, PERSIST_RO_VARIABLES_ADMIN, PROXY, RELOAD, REPLICATION_SLAVE_ADMIN, ROLE_ADMIN, SERVICE_CONNECTION_ADMIN, SESSION_VARIABLES_ADMIN, SET_USER_ID, SHOW_ROUTINE, SHUTDOWN, SUPER, SYSTEM_USER, SYSTEM_VARIABLES_ADMIN, TABLE_ENCRYPTION_ADMIN) removed
NOTE: User 'sugi01'@'%' had restricted privileges (AUDIT_ADMIN, BACKUP_ADMIN, BINLOG_ADMIN, BINLOG_ENCRYPTION_ADMIN, CLONE_ADMIN, CREATE TABLESPACE, ENCRYPTION_KEY_ADMIN, FILE, FLUSH_OPTIMIZER_COSTS, FLUSH_STATUS, FLUSH_TABLES, FLUSH_USER_RESOURCES, GROUP_REPLICATION_ADMIN, INNODB_REDO_LOG_ARCHIVE, INNODB_REDO_LOG_ENABLE, PERSIST_RO_VARIABLES_ADMIN, RELOAD, REPLICATION_SLAVE_ADMIN, ROLE_ADMIN, SERVICE_CONNECTION_ADMIN, SESSION_VARIABLES_ADMIN, SET_USER_ID, SHOW_ROUTINE, SHUTDOWN, SUPER, SYSTEM_USER, SYSTEM_VARIABLES_ADMIN, TABLE_ENCRYPTION_ADMIN) removed
NOTE: Database sugitest had unsupported ENCRYPTION option commented out
Compatibility issues with MySQL Database Service 8.0.23 were found and repaired. Please review the changes made before loading them.
Writing global DDL files
Writing users DDL
Preparing data dump for table `sugitest`.`sample`
Writing DDL for schema `sugitest`
Data dump for table `sugitest`.`sample` will be chunked using column `id`
Running data dump using 4 threads.
NOTE: Progress information uses estimated values and may not be accurate.
Writing DDL for table `sugitest`.`sample`
Data dump for table `sugitest`.`sample` will be written to 1 file
1 thds dumping - 100% (10 rows / ~10 rows), 7.00 rows/s, 32.00 B/s uncompressed, 0.00 B/s compressed
Duration: 00:00:01s
Schemas dumped: 1
Tables dumped: 1
Uncompressed data size: 42 bytes
Compressed data size: 0 bytes
Compression ratio: 42.0
Rows written: 10
Bytes written: 0 bytes
Average uncompressed throughput: 32.59 B/s
Average compressed throughput: 0.00 B/s
MySQL 10.0.0.63:33060+ ssl JS >
こんな具合に Bucket に DumpFile が出力されている
Replica : Dumpfile を Import
Replica である MDS に Dumpfile を Import します
MySQL Shell で接続
mysqlsh admin@replica01.mysqlsubnet01.vcn.oraclevcn.com
実行例
[opc@mysql-client01 ~]$ mysqlsh admin@replica01.mysqlsubnet01.vcn.oraclevcn.com
Please provide the password for 'admin@replica01.mysqlsubnet01.vcn.oraclevcn.com': ***********************
Save password for 'admin@replica01.mysqlsubnet01.vcn.oraclevcn.com'? [Y]es/[N]o/Ne[v]er (default No):
MySQL Shell 8.0.23
Copyright (c) 2016, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.
Type '\help' or '\?' for help; '\quit' to exit.
Creating a session to 'admin@replica01.mysqlsubnet01.vcn.oraclevcn.com'
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 275
Server version: 8.0.23-cloud MySQL Enterprise - Cloud
No default schema selected; type \use <schema> to set one.
MySQL replica01.mysqlsubnet01.vcn.oraclevcn.com:3306 ssl JS >
Dumpfile を Import
util.loadDump("SourceInstanceDump", {osBucketName: "mysqldump", osNamespace: "orasejapan", threads: 4})
実行例
MySQL replica01.mysqlsubnet01.vcn.oraclevcn.com:3306 ssl JS > util.loadDump("SourceInstanceDump", {osBucketName: "mysqldump", osNamespace: "orasejapan", threads: 4})
Loading DDL and Data from OCI ObjectStorage bucket=mysqldump, prefix='SourceInstanceDump' using 4 threads.
Opening dump...
Target is MySQL 8.0.23-cloud (MySQL Database Service). Dump was produced from MySQL 8.0.23
Fetching dump data from remote location...
Fetching 1 table metadata files for schema `sugitest`...
Checking for pre-existing objects...
Executing common preamble SQL
Executing DDL script for schema `sugitest`
[Worker000] Executing DDL script for `sugitest`.`sample`
[Worker001] sugitest@sample@@0.tsv.zst: Records: 10 Deleted: 0 Skipped: 0 Warnings: 0
Executing common postamble SQL
1 chunks (10 rows, 42 bytes) for 1 tables in 1 schemas were loaded in 1 sec (avg throughput 42.00 B/s)
0 warnings were reported during the load.
MySQL replica01.mysqlsubnet01.vcn.oraclevcn.com:3306 ssl JS >
GTID ベースのレプリケーションでは、どこまでトランザクションをレプリケーションしたかを、GTID で管理しています。MySQL Shell のユーティリティでは、Replica 側で、GTID 関連の設定が必要です。
Object Storage 内の json メタデータから、gtidExecuted
を取得してメモします。
Object Storage の@.json
ファイルをダウンロードします。
この @.json
ファイルの中身は以下。この中の gtidExecuted
をメモっておく
{
"dumper": "mysqlsh Ver 8.0.23 for Linux on x86_64 - for MySQL 8.0.23 (MySQL Community Server (GPL))",
"version": "1.0.2",
"origin": "dumpInstance",
"schemas": [
"sugitest"
],
"basenames": {
"sugitest": "sugitest"
},
"users": [
"'root'@'localhost'",
"'rpluser001'@'%'",
"'rpluser002'@'%'",
"'sugi01'@'%'",
"'test2'@'%'"
],
"defaultCharacterSet": "utf8mb4",
"tzUtc": true,
"bytesPerChunk": 64000000,
"user": "sugi01",
"hostname": "mysql-client01",
"server": "mysql-source01",
"serverVersion": "8.0.23",
"gtidExecuted": "0e1a6a53-5cac-11eb-8d54-02001701e97e:1-3",
"gtidExecutedInconsistent": false,
"consistent": true,
"mdsCompatibility": true,
"begin": "2021-01-23 07:10:44"
}
メモった値を使って、gtid_purged を行います。Replica に MySQL Client (MySQL Shell じゃないよ) を使って接続します。次にメモった値を使ってコマンドを発行します
mysql> call sys.set_gtid_purged("0e1a6a53-5cac-11eb-8d54-02001701e97e:1-3");
Query OK, 0 rows affected (0.00 sec)
mysql>
確認
mysql> select @@gtid_purged;
+------------------------------------------+
| @@gtid_purged |
+------------------------------------------+
| 0e1a6a53-5cac-11eb-8d54-02001701e97e:1-3 |
+------------------------------------------+
1 row in set (0.00 sec)
mysql>
memo : エラーになったとき
mysql> call sys.set_gtid_purged("0e1a6a53-5cac-11eb-8d54-02001701e97e:1-10");
ERROR 3546 (HY000): @@GLOBAL.GTID_PURGED cannot be changed: the added gtid set must not overlap with @@GLOBAL.GTID_EXECUTED
memo : 次の gtid_purged が空白じゃないとエラーになる
mysql> show global variables like 'GTID%';
+----------------------------------+------------------------------------------------------------------------------------+
| Variable_name | Value |
+----------------------------------+------------------------------------------------------------------------------------+
| gtid_executed | 0e1a6a53-5cac-11eb-8d54-02001701e97e:1-5,
cbcefcc6-5cb0-11eb-8761-020017004a1e:1-7 |
| gtid_executed_compression_period | 0 |
| gtid_mode | ON |
| gtid_owned | |
| gtid_purged | 0e1a6a53-5cac-11eb-8d54-02001701e97e:1-3 |
+----------------------------------+------------------------------------------------------------------------------------+
5 rows in set (0.01 sec)
mysql>
Replica : Channel の作成
OCI Console 上で、Create Channel を行います
各種パラメータを入れます。Source で作成したレプリケーション用のユーザー名とパスワードを指定します
rpluser001
Rpl001#!
Create
Creating
ステータスが NEEDS ATTENTION になった場合、レプリケーションに何らかの問題が発生しています
次の URL で「NEEDS ATTENTION」で検索すると、詳細情報が見えます
https://docs.oracle.com/en-us/iaas/mysql-database/doc/replication.html#GUID-CB1AC60B-AA87-4D7C-9D75-191449F89663
一個上の画面に戻ると、エラーメッセージが確認出来ます。自分の環境の場合は、Source のセキュリティーグループで 3306 を開けていなかったため、次のエラーが出ていました。
エラー原因を改善したあとに、Resume を押すと再開できます。
ACTIVE になります。これで Inbound Replication を使った非同期レプリケーションが完成です。
レプリケーション確認
レプリケーションされているか確認するために、Source にテストデータを入れてみます
mysql -h 10.0.0.63 -u sugi01 -p
現在のデータ
mysql> select * from sugitest.sample;
+----+-------+
| id | value |
+----+-------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
| 8 | 8 |
| 9 | 9 |
| 10 | 10 |
+----+-------+
10 rows in set (0.00 sec)
mysql>
Source にデータを Insert します
INSERT INTO sugitest.sample(value) VALUES (11);
replica 先
mysql -h replica01.mysqlsubnet01.vcn.oraclevcn.com -u admin -p
レプリケートされている
mysql> select * from sugitest.sample;
+----+-------+
| id | value |
+----+-------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
| 8 | 8 |
| 9 | 9 |
| 10 | 10 |
| 11 | 11 |
+----+-------+
11 rows in set (0.00 sec)
mysql>
memo : わかったこと
- MDS1個につき、Channel は1個まで (マルチソースレプリケーションが現状出来ないので、問題なし)
-
-
mysql
スキーマ内で CREATE TABLE しても、レプリケーションされない。また、これが影響してレプリケーションが中断されるので注意 (Document で書かれているので、mysql スキーマ内で作業するのは止めよう)
-
参考URL
Inbound Replication
https://docs.oracle.com/en-us/iaas/mysql-database/doc/replication.html
MySQL Database Serviceへ移行してみよう
https://www.s-style.co.jp/blog/2021/01/7076/