データベースの削除も古いスローガンであり、データベースの運用・保守中に誤ってデータを削除したり、開発したコードにバグがあったりすると、誤ってデータが削除されることがあります。ただし、誤った削除を回復または防止するためのソリューションは多数あります。たとえば、SQL管理システムは、実行するSQLを最初に管理者に送信して確認し、次に管理者がミラーデータベースをバックアップし、ミラー上でSQLを実行して実行します。画像を復元します。このように、チェックのレイヤーを通過することにより、誤操作の可能性を大幅に減らすことができます。
さらに、binlogログを使用して誤操作からデータを回復することもできるため、オンラインで実行されているすべてのデータベースでbinlogログ機能が有効になります。このセクションで紹介する遅延ノードもあります。レプリケーションクラスターでは、遅延ノードを設定できます。このノードのデータ同期時間は、他のノードが誤動作している場合、遅延がある場合、クラスター内の他のノードよりも遅くなります。ノードのデータは、影響を受けることなく、遅延ノードから回復できます。
しかし、既存のデータベースがすべてPXCクラスターである場合、このソリューションはレプリケーションクラスターなしで使用できますか? PXCクラスターとレプリケーションクラスターは相互に排他的ではありません。PXCクラスター内のノードをマスターとして設定し、遅延ノードをスレーブに追加して、これら2つのノードがデータ同期用のレプリケーションクラスターを形成するようにすることもできます。それでおしまい。次のように:
このセクションでは、この異種クラスターの下に遅延ノードを構築する方法を簡単に示します。ここでは、PXCクラスターと遅延ノードとして使用されるデータベースを事前に準備しました。
ここでは、PXCクラスター内の PXC-Node3
がマスターとして使用され、 DelayNode
とマスタースレーブを形成し、 DelayNode
は当然遅延ノードとして機能します。
PXCクラスターとレプリケーションクラスターの構築については、以下の記事を参照できますが、スペースが限られているため、ここでは説明しません。
次に、実践的な練習を開始します。まず、次の2つのノードで[MySQL](https://cloud.tencent.com/product/cdb?from=10680)サービスを停止する必要があります。
systemctl stop mysqld
マスターノードとスレーブノードの構成ファイルでGTIDを有効にする必要があります。有効にしないと、遅延ノードを使用してデータを取得できません。マスターノードに追加される構成は次のとおりです。
[ root@PXC-Node3 ~]# vim /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
[ mysqld]...
# ノードのIDを設定します
server_id=3
# binlogを開く
log_bin=mysql_bin
# GTIDをオンにします
gtid_mode=ON
enforce_gtid_consistency=1
ノードから追加する必要のある構成は次のとおりです。
[ root@delay-node ~]# vim /etc/my.cnf
[ mysqld]...
server_id=102
log_bin=mysql_bin
# スレーブノードはリレーをオンにする必要があります_log
relay_log=relay_bin
gtid_mode=ON
enforce_gtid_consistency=1
構成ファイルの構成が完了したら、次の2つのノードを開始します。
systemctl start mysqld
次に、スレーブとマスター間のマスターとスレーブの関係を構成し、マスターのMySQLコマンドラインターミナルに入り、次のステートメントを使用して、マスターが現在使用しているバイナリログと現在の実行バイナリログの場所を照会します。
mysql> flush logs;--ログを更新
mysql> show master status;+----------------------+----------+--------------+------------------+-------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |+----------------------+----------+--------------+------------------+-------------------+| PXC-Node3-bin.000003|154||||+----------------------+----------+--------------+------------------+-------------------+1 row inset(0.00 sec)
上記の実行結果を記録した後、スレーブのMySQLコマンドラインターミナルに入り、それぞれ次のステートメントを実行します。
mysql> stop slave;--マスターとスレーブの同期を停止します
mysql> change master to master_log_file='PXC-Node3-bin.000003', master_log_pos=154, master_host='192.168.190.134', master_port=3306, master_user='admin', master_password='Abc_123456';--マスターノードの接続情報と、マスターバイナリログからコピーを開始する場所を構成します
mysql> start slave;--マスタースレーブ同期を開始します
master_auto_position = 1
パラメータを使用できます。マスターとスレーブの関係を構成した後、 show slave status \ G;
ステートメントを使用してマスターとスレーブの同期ステータスを表示します。Slave_IO_Running
と Slave_SQL_Running
の値は両方とも Yes
であり、マスターとスレーブの同期ステータスが正常であることを示します。
マスターとスレーブの関係の構成が完了したら、マスターとスレーブのデータ同期が正常かどうかをテストします。次のように、マスターでいくつかのSQLステートメントを実行します。
mysql> create database test_db;
mysql> use test_db;
mysql> CREATE TABLE `student`(`id`int(11) NOT NULL,`name`varchar(20) NOT NULL,
PRIMARY KEY(`id`));
mysql> INSERT INTO `test_db`.`student`(`id`,`name`)VALUES(1,'Jack');
実行が完了したら、スレーブで通常の同期があるかどうかを確認します。
mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || sys || test_db |+--------------------+5 rows inset(0.00 sec)
mysql> use test_db;
mysql> select *from student;+----+------+| id | name |+----+------+|1| Jack |+----+------+1 row inset(0.00 sec)
mysql>
マスターノードとスレーブノードがデータを正常に同期できることを確認した後、スレーブノードの同期遅延を設定できます。スレーブノードで次のステートメントを実行します。
mysql> stop slave;
mysql> change master to master_delay=1200;--同期遅延を1200秒に設定します
mysql> start slave;
同様に、マスターとスレーブの関係を再構成した後、マスターとスレーブの同期ステータスが正常であることを確認する必要があります。
次に、遅延ノードの機能を示します。最初にマスターノードに移動し、 student
テーブルのデータを削除して、偶発的な削除をシミュレートします。
mysql> use test_db;
mysql>deletefrom student;--学生テーブルのすべてのデータを削除します
mysql> select *from student;--マスターでデータを照会することはできません
Empty set(0.00 sec)
mysql>
現時点では、同期が遅れているため、削除されたデータは引き続きスレーブノードで正常にクエリできます。
mysql> use test_db;
mysql> select *from student;+----+------+| id | name |+----+------+|1| Jack |+----+------+1 row inset(0.00 sec)
mysql>
今度はGTIDが再生されます。スレーブノードに削除操作のGTIDをスキップさせてから、マスターにスレーブからデータを復元させる必要があります。そうしないと、スレーブがGTIDを同期すると、スレーブノードのデータも削除されます。同期前にマスターデータを復元しても、マスターとスレーブのデータが一致しないという問題が発生します。
GTIDはbinlogに記録されます。誤って削除がマスターで実行されるため、最初に show master logs;
ステートメントを使用して、マスターノードのbinlogログ名を照会します。
次に、binlogファイルで偶発的な削除の記録とそのGTIDを見つける必要があります。binlogファイルのシリアル番号が増加しているため、最新の操作は通常、シリアル番号が最大のbinlogファイルに記録されます。したがって、 show binlog events in'PXC-Node3-bin.000003 ';
ステートメントを実行し、結果セットから誤った削除操作のレコードとそのGTIDを見つけます。以下に示すように:
マスターノードで誤って削除した操作のGTIDを見つけたら、GTIDをコピーします。次に、スレーブノードで次のステートメントを実行します。
mysql> stop slave;--マスターとスレーブの同期を停止します
mysql>set gtid_next='d36eaafb-c653-ee15-4458-5d6bc793bd7a:4';--GTIDをスキップするように設定します
mysql> begin; commit;--トランザクションを開いてコミットします。つまり、スレーブをシミュレートしてGTIDを同期します。その後の同期は実行されないため、スキップの効果が得られます。
mysql>set gtid_next='automatic';--gtid設定を復元する
mysql> change master to master_delay=0;--同期遅延を0に設定すると、同期のためにGTIDがすぐにスキップされます。
mysql> start slave;
上記の操作を完了した後も、この時点でスレーブに誤って削除されたデータが残っています。
そして、マスターの student
テーブルはまだ空です:
上記の操作が完了したら、同期遅延設定を復元します。
mysql> stop slave;
mysql> change master to master_delay=1200;--同期遅延を1200秒に設定します
mysql> start slave;
スレーブノードに誤った削除操作のGTIDをスキップさせた後、マスターノードのデータの復元を開始できます。最初に、マスターノードが配置されているPXCクラスターでのビジネスシステムの読み取りおよび書き込み操作を停止して、復元プロセス中のデータの混乱を回避します。次に、スレーブノードのデータをエクスポートします。
マスターノードに一時データベースを作成します。これは、事故を回避するために、一時データベースのデータの正確性を確認した後、データをビジネスデータベースにインポートするためのものです。
create database temp_db;
次に、データをインポートします。
マスターノードのデータテーブルの名前を変更します。
rename table test_db.student to test_db.student_bak;
一時データベースのデータテーブルをビジネスデータベースに移行します。
rename table temp_db.student to test_db.student;
この時点で、マスターノードで誤って削除されたデータは正常に復元されます。
前述のように、遅延ノードの解決に加えて、binlogログを使用してデータを回復することもできます。データを回復するこの方法は、通常、ログフラッシュバックと呼ばれます。このスキームがここで導入される理由は、遅延ノードスキームには特定の制限があるためです。遅延フェーズで問題が検出および解決されないと、マスタースレーブデータが同期された後、スレーブノードを使用して達成することはできません。誤った削除の回復。
ログフラッシュバックソリューションは、遅延ノードソリューションよりも単純であり、追加のノードは必要なく、現在のノードを使用してデータを回復できます。ただし、このソリューションは万能ではありません。たとえば、binlogログには、「テーブルの削除」や「テーブルの切り捨て」などの操作によって削除されたデータが記録されないため、ログから復元することはできません。ただし、これら2つのプログラムは競合せず、同時に使用してデータ回復の可能性を高めることができます。
ログフラッシュバックの前提は、binlogログをオンにしてから、いくつかのフラッシュバックツールを使用してbinlogログをSQLに解析し、SQLの delete
ステートメントを insert
ステートメントに変換するか、誤って削除されたデータの insert
を見つけることです。 ステートメント。最後に、これらの
insert`ステートメントがデータベースで再度実行されるため、データの回復が実現されます。
多くのフラッシュバックツールがあります。この記事では、[binlog2sql](https://github.com/danfengcao/binlog2sql)を使用します。これは、Pythonに基づいてDianpingによって作成されたオープンソースのMySQLログフラッシュバックツールです。
ツールのインストール手順は次のとおりです。
# フロントツールをインストールする
[ root@PXC-Node3 ~]# yum install -y epel-release
[ root@PXC-Node3 ~]# yum install -y git python3-pip
# binlog2sqlのソースコードライブラリのクローンを作成し、ソースディレクトリに入ります
[ root@PXC-Node3 ~]# git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql
# binlog2sqlが依存するPythonライブラリをインストールします
[ root@PXC-Node3 ~/binlog2sql]# pip3 install -r requirements.txt
binlog2sqlは row
形式のbinlogに基づいて解析されるため、MySQL構成ファイルで次のパラメーターを構成します。
[ mysqld]...
binlog_format = row
binlog_row_image = full
ここに次のデータを含む製品テーブルがあります。
delete
ステートメントを使用してテーブル内のデータを削除し、偶発的な削除をシミュレートします。
deletefrom flash.goods;
次に、誤って削除した後に新しく追加されたデータをシミュレートするために、いくつかのデータを挿入します。
INSERT INTO `flash`.`goods`(`id`,`name`,`desc`,`status`)VALUES(6,'林檎','xxxx','1');
INSERT INTO `flash`.`goods`(`id`,`name`,`desc`,`status`)VALUES(7,'バナナ','xxxx','1');
回復前の準備:
アイテムテーブルが復元されるため、アイテムテーブル内のすべてのレコードがクリアされます。
deletefrom flash.goods;
前述のように、最近の操作は通常、シリアル番号が最大のbinlogファイルに記録されるため、データベース内のbinlogファイル名を照会する必要があります。
次に、binlog2sqlを使用して、指定されたbinlogログを解析します。具体的なコマンドは次のとおりです。
[ root@PXC-Node3 ~/binlog2sql]# python3 binlog2sql/binlog2sql.py -uadmin -p'Abc_123456'-dflash -tgoods --start-file='PXC-Node3-bin.000003'>/home/PXC-Node3-bin.000003.sql
binlog2sql / binlog2sql.py
:実行されたPythonファイル- u
:データベースへの接続に使用されるアカウント- p
:データベースアカウントのパスワード- d
:論理ライブラリの名前を指定します- t
:データテーブルの名前を指定します- - start-file
:解析するbinlogのファイル名を指定します / home / PXC-Node3-bin.000003.sql
:分析によって生成されたSQLを書き込むファイルを指定します次に、解析されたSQLコンテンツを確認します: cat / home / PXC-Node3-bin.000003.sql
。次の図に示すように、便利な部分のスクリーンショットを次に示します。delete
ステートメントと insert
ステートメントに復元するデータが含まれていることがわかります。
次のステップは、これらのステートメントを取得することです。 delete
ステートメントを insert
ステートメントに変換するか、 insert
部分のSQLステートメントをデータベースに直接コピーして実行します。ここに insert
ステートメントを直接コピーします。
INSERT INTO `flash`.`goods`(`id`,`name`,`desc`,`status`)VALUES(1,'ケーキ','食べて良い','1'); #start 3170 end 3363 time 2020-01-2718:00:11
INSERT INTO `flash`.`goods`(`id`,`name`,`desc`,`status`)VALUES(2,'レモンティー','マリファナの喫煙を冷やす','1'); #start 3459 end 3664 time 2020-01-2718:00:56
INSERT INTO `flash`.`goods`(`id`,`name`,`desc`,`status`)VALUES(3,'豆乳','おいしい','0'); #start 3760 end 3953 time 2020-01-2718:01:10
INSERT INTO `flash`.`goods`(`id`,`name`,`desc`,`status`)VALUES(4,'うわとう','4人で1ドル','1'); #start 4049 end 4254 time 2020-01-2718:01:37
INSERT INTO `flash`.`goods`(`id`,`name`,`desc`,`status`)VALUES(5,'チキンレッグ','あなたがとても美しいチキン','0'); #start 4350 end 4549 time 2020-01-2718:02:08
INSERT INTO `flash`.`goods`(`id`,`name`,`desc`,`status`)VALUES(6,'林檎','xxxx','1'); #start 5052 end 5243 time 2020-01-2718:06:24
INSERT INTO `flash`.`goods`(`id`,`name`,`desc`,`status`)VALUES(7,'バナナ','xxxx','1'); #start 5339 end 5530 time 2020-01-2718:06:24
上記のSQLを実行すると、productテーブルで削除されたデータが正常に復元されたことがわかります。
Recommended Posts