目前已經完成了mysql的主備模式的搭建。mysql
mysql> show global variables like "%binlog_format%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
複製代碼
執行一條語句sql
delete from t /*comment*/ where a>=4 and t_modified<='2018-11-10' limit 1;
複製代碼
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000005 | 2847 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> show binlog events in 'master.000005';
複製代碼
查看binogshell
| mysql-bin.000005 | 2627 | Query | 1 | 2714 | BEGIN |
| mysql-bin.000005 | 2714 | Table_map | 1 | 2768 | table_id: 118 (testKeep.t) |
| mysql-bin.000005 | 2768 | Write_rows | 1 | 2816 | table_id: 118 flags: STMT_END_F |
| mysql-bin.000005 | 2816 | Xid | 1 | 2847 | COMMIT /* xid=1507 */ |
| mysql-bin.000005 | 2847 | Anonymous_Gtid | 1 | 2926 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
複製代碼
爲何要切換爲MIXED模式?數據庫
row模式很是費空間,statement模式由於執行索引不必定相同可能會致使主備不一致問題,由此產生了row格式。因此線上 MySQL 設置的 binlog 格式是 statement 的話,那基本上就能夠認爲這是一個不合理的設置。你至少應該把 binlog 的格式設置爲 mixed。bash
如何切換markdown
vi /etc/my.cnf # 根據自身狀況調整位置
log-bin=mysql-bin
binlog_format=MIXED
mysql> show global variables like "%binlog_format%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+
1 row in set (0.01 sec)
複製代碼
並且因爲擁有statement模式的特點,咱們在數據恢復上能夠很方便函數
咱們用測試數據庫testKeep分別測試增、刪、改的恢復方法性能
mysql> select * from t;
+----+------+---------------------+
| id | a | t_modified |
+----+------+---------------------+
| 1 | 1 | 2018-11-13 00:00:00 |
| 2 | 2 | 2018-11-12 00:00:00 |
| 3 | 3 | 2018-11-11 00:00:00 |
| 4 | 4 | 2018-11-10 00:00:00 |
| 7 | 7 | 2018-11-15 00:00:00 |
+----+------+---------------------+
5 rows in set (0.00 sec)
複製代碼
增:測試
mysql> insert into t values(8,8,'2021-6-4');
Query OK, 1 row affected (0.00 sec)
複製代碼
mysql> show binlog events in 'mysql-bin.000007';
+------------------+-----+----------------+-----------+-------------+------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+------------------------------------------------------+
| mysql-bin.000007 | 4 | Format_desc | 1 | 125 | Server ver: 8.0.25, Binlog ver: 4 |
| mysql-bin.000007 | 125 | Previous_gtids | 1 | 156 | |
| mysql-bin.000007 | 156 | Anonymous_Gtid | 1 | 235 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000007 | 235 | Query | 1 | 333 | BEGIN |
| mysql-bin.000007 | 333 | Query | 1 | 462 | use `testKeep`; insert into t values(8,8,'2021-6-4') |
| mysql-bin.000007 | 462 | Xid | 1 | 493 | COMMIT /* xid=58 */ |
+------------------+-----+----------------+-----------+-------------+------------------------------------------------------+
6 rows in set (0.00 sec)
複製代碼
咱們發現,日誌行數比之前ROW 少特別多,並且完整的記錄了sql語句,能夠根據sql語句對誤增的數據直接刪除。ui
改
mysql> update t set a = 99 where id = 8;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
複製代碼
mysql> show binlog events in 'mysql-bin.000007';
+------------------+-----+----------------+-----------+-------------+------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+------------------------------------------------------+
| mysql-bin.000007 | 4 | Format_desc | 1 | 125 | Server ver: 8.0.25, Binlog ver: 4 |
| mysql-bin.000007 | 125 | Previous_gtids | 1 | 156 | |
| mysql-bin.000007 | 156 | Anonymous_Gtid | 1 | 235 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000007 | 235 | Query | 1 | 333 | BEGIN |
| mysql-bin.000007 | 333 | Query | 1 | 462 | use `testKeep`; insert into t values(8,8,'2021-6-4') |
| mysql-bin.000007 | 462 | Xid | 1 | 493 | COMMIT /* xid=58 */ |
| mysql-bin.000007 | 493 | Anonymous_Gtid | 1 | 572 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000007 | 572 | Query | 1 | 671 | BEGIN |
| mysql-bin.000007 | 671 | Query | 1 | 797 | use `testKeep`; update t set a = 99 where id = 8 |
| mysql-bin.000007 | 797 | Xid | 1 | 828 | COMMIT /* xid=69 */ |
+------------------+-----+----------------+-----------+-------------+------------------------------------------------------+
10 rows in set (0.00 sec)
複製代碼
它會修改事件先後的區別,能夠根據這些區別而還原數據
刪
mysql> delete from t where id = 8;
Query OK, 1 row affected (0.01 sec)
複製代碼
mysql> show binlog events in 'mysql-bin.000007';
+------------------+------+----------------+-----------+-------------+------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+------+----------------+-----------+-------------+------------------------------------------------------+
| mysql-bin.000007 | 4 | Format_desc | 1 | 125 | Server ver: 8.0.25, Binlog ver: 4 |
| mysql-bin.000007 | 125 | Previous_gtids | 1 | 156 | |
| mysql-bin.000007 | 156 | Anonymous_Gtid | 1 | 235 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000007 | 235 | Query | 1 | 333 | BEGIN |
| mysql-bin.000007 | 333 | Query | 1 | 462 | use `testKeep`; insert into t values(8,8,'2021-6-4') |
| mysql-bin.000007 | 462 | Xid | 1 | 493 | COMMIT /* xid=58 */ |
| mysql-bin.000007 | 493 | Anonymous_Gtid | 1 | 572 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000007 | 572 | Query | 1 | 671 | BEGIN |
| mysql-bin.000007 | 671 | Query | 1 | 797 | use `testKeep`; update t set a = 99 where id = 8 |
| mysql-bin.000007 | 797 | Xid | 1 | 828 | COMMIT /* xid=69 */ |
| mysql-bin.000007 | 828 | Anonymous_Gtid | 1 | 907 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000007 | 907 | Query | 1 | 997 | BEGIN |
| mysql-bin.000007 | 997 | Query | 1 | 1108 | use `testKeep`; delete from t where id = 8 |
| mysql-bin.000007 | 1108 | Xid | 1 | 1139 | COMMIT /* xid=88 */ |
+------------------+------+----------------+-----------+-------------+------------------------------------------------------+
14 rows in set (0.00 sec)
複製代碼
很明顯咱們查出了 這條sql被建立以後發生的全部事情,被新增過,修改過,後來又被刪除了。
從節點開啓只讀模式
set global read_only是全局級別的,置爲1以後root用戶還能夠寫,其餘用戶不能寫
mysql> set global read_only=1;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like '%read_only%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_read_only | OFF |
| read_only | ON |
| super_read_only | OFF |
| transaction_read_only | OFF |
+-----------------------+-------+
複製代碼
#創建只讀帳戶並分配權限
CREATE USER '{帳戶名稱}'@'%' IDENTIFIED BY '{帳戶密碼}';
grant SELECT on *.* to '{帳戶名稱}'@'%';
複製代碼
切換到只讀用戶,並進行測試
mysql> select count(*) from t;
+----------+
| count(*) |
+----------+
| 6 |
+----------+
1 row in set (0.00 sec)
mysql> insert into t values(15,15,'2021-6-4');
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
mysql> delete from t where id = 2;
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
mysql> update t set a = 99 where id = 2;
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
複製代碼
結果顯示能夠查,不能夠增刪改。
成文時間比較長(老存貨了),已經找不到參考文獻。