• mysql 基于GTID方式的bin-log日志恢复数据


    1.

    如果想通过 mysql 的 binlog 恢复数据,首先要开启 binlog 。这里搭建一个测试的环境,了解一下 mysql binlog 是如何恢复数据库的。原理比较简单,binlog 会存储mysql中变化的数据,比如你创建了一个数据库,写入了一些数据,这些都会存储在 mysql 的 binlog 中。

    需要恢复的时候就找到,两个位置,一个起始位置,一个结束的位置。结束的位置,一半是数据被破坏或者删除前的位置。mysql 8 默认已经开启了 binlog

    1. mysql> show variables like '%log_bin%';
    2. +---------------------------------+---------------------------------+
    3. | Variable_name | Value |
    4. +---------------------------------+---------------------------------+
    5. | log_bin | ON |
    6. | log_bin_basename | /var/lib/mysql/master-bin |
    7. | log_bin_index | /var/lib/mysql/master-bin.index |
    8. | log_bin_trust_function_creators | OFF |
    9. | log_bin_use_v1_row_events | OFF |
    10. | sql_log_bin | ON |
    11. +---------------------------------+---------------------------------+
    12. 6 rows in set (0.01 sec)

    2 . 执行重置(reset master)后 ,可以看到之前的 binlog 文件已经被删除了,产生一个新的 binlog 文件。

    可以查看一下这个文件的内容

    1. mysql> show master logs;
    2. +-------------------+-----------+
    3. | Log_name | File_size |
    4. +-------------------+-----------+
    5. | master-bin.000001 | 962 |
    6. | master-bin.000002 | 242 |
    7. | master-bin.000003 | 242 |
    8. | master-bin.000004 | 242 |
    9. | master-bin.000005 | 401 |
    10. | master-bin.000006 | 194 |
    11. +-------------------+-----------+
    12. 6 rows in set (0.00 sec)
    1. mysql> show master logs;
    2. +-------------------+-----------+
    3. | Log_name | File_size |
    4. +-------------------+-----------+
    5. | master-bin.000001 | 962 |
    6. | master-bin.000002 | 242 |
    7. | master-bin.000003 | 242 |
    8. | master-bin.000004 | 242 |
    9. | master-bin.000005 | 401 |
    10. | master-bin.000006 | 194 |
    11. +-------------------+-----------+
    12. 6 rows in set (0.00 sec)
    13. mysql> reset master;
    14. Query OK, 0 rows affected (0.01 sec)
    15. mysql> show master logs;
    16. +-------------------+-----------+
    17. | Log_name | File_size |
    18. +-------------------+-----------+
    19. | master-bin.000001 | 154 |
    20. +-------------------+-----------+
    21. 1 row in set (0.00 sec)

     可以查看一下这个文件的内容

    1. [root@localhost mysql]# ls -al
    2. -rw-r----- 1 mysql mysql 154 88 16:07 master-bin.000001
    3. -rw-r----- 1 mysql mysql 20 88 16:07 master-bin.index
    1. [root@localhost mysql]# mysqlbinlog master-bin.000001
    2. /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
    3. /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
    4. DELIMITER /*!*/;
    5. # at 4
    6. #220808 16:07:41 server id 1 end_log_pos 123 CRC32 0xadec6205 Start: binlog v 4, server v 5.7.35-log created 220808 16:07:41 at startup
    7. # Warning: this binlog is either in use or was not closed properly.
    8. ROLLBACK/*!*/;
    9. BINLOG '
    10. TcTwYg8BAAAAdwAAAHsAAAABAAQANS43LjM1LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    11. AAAAAAAAAAAAAAAAAABNxPBiEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    12. AQVi7K0=
    13. '/*!*/;
    14. # at 123
    15. #220808 16:07:41 server id 1 end_log_pos 154 CRC32 0x5c15c4eb Previous-GTIDs
    16. # [empty]
    17. SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    18. DELIMITER ;
    19. # End of log file
    20. /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    21. /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

    这个时候,我们添加一些数据

    1. mysql> create database test;
    2. Query OK, 1 row affected (0.00 sec)
    3. mysql> use test;
    4. Database changed
    5. mysql> create table jettech01(id int,name char);
    6. Query OK, 0 rows affected (0.01 sec)
    7. mysql> insert into jettech01 value(3,'c');
    8. Query OK, 1 row affected (0.00 sec)
    9. mysql> flush privileges;
    10. Query OK, 0 rows affected (0.00 sec)
    11. mysql> select * from jettech01;
    12. +------+------+
    13. | id | name |
    14. +------+------+
    15. | 3 | c |
    16. +------+------+
    17. 1 row in set (0.00 sec)

    这个时候,不小心删除了,数据库 test

    1. mysql> drop database test;
    2. Query OK, 1 row affected (0.01 sec)

    binlog 大小没变还是没删除之前的数据都在里面 

    1. [root@localhost mysql]# ls -al
    2. -rw-r----- 1 mysql mysql 913 88 16:10 master-bin.000001
    3. -rw-r----- 1 mysql mysql 20 88 16:09 master-bin.index

    3 现在就需要解决一个实际问题,怎么恢复这个数据库

    首先为了防止干扰,执行 flush logs ,产生一个新binlog 文件

    1. mysql> show master logs;
    2. +-------------------+-----------+
    3. | Log_name | File_size |
    4. +-------------------+-----------+
    5. | master-bin.000001 | 1070 |
    6. +-------------------+-----------+
    7. 1 row in set (0.00 sec)
    8. mysql> show master status;
    9. +-------------------+----------+--------------+-------------------------------------------------+-------------------+
    10. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    11. +-------------------+----------+--------------+-------------------------------------------------+-------------------+
    12. | master-bin.000001 | 1070 | test,test1 | mysql,performance_schema,information_schema,sys | |
    13. +-------------------+----------+--------------+-------------------------------------------------+-------------------+
    14. 1 row in set (0.00 sec)
    15. mysql> flush logs;
    16. Query OK, 0 rows affected (0.01 sec)
    17. mysql> show master status;
    18. +-------------------+----------+--------------+-------------------------------------------------+-------------------+
    19. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    20. +-------------------+----------+--------------+-------------------------------------------------+-------------------+
    21. | master-bin.000002 | 154 | test,test1 | mysql,performance_schema,information_schema,sys | |
    22. +-------------------+----------+--------------+-------------------------------------------------+-------------------+
    23. 1 row in set (0.00 sec)

    系统文件: 

    1. [root@localhost mysql]# cat master-bin.index
    2. ./master-bin.000001
    3. ./master-bin.000002
    4. [root@localhost mysql]# ls -al master-bin.*
    5. -rw-r----- 1 mysql mysql 1118 88 16:12 master-bin.000001
    6. -rw-r----- 1 mysql mysql 154 88 16:12 master-bin.000002
    7. -rw-r----- 1 mysql mysql 40 88 16:12 master-bin.index

    4.恢复数据,首先要找到数据在哪里被删除了。

    1. [root@localhost mysql]# mysqlbinlog master-bin.000001 | grep -n "drop database"
    2. 76:drop database test

    可以看到在 76 行的地方有个 删除语句。终可以找到两个地方

    1. 数据需要恢复的起始位置
    2. 数据需要恢复的结束位置

    这里起始的位置就找 创建数据库的位置,结束的位置就找 删除数据库的位置。

    1. # at 219
    2. #220808 16:09:45 server id 1 end_log_pos 313 CRC32 0x781d4308 Query thread_id=6 exec_time=0 error_code=0
    3. SET TIMESTAMP=1659946185/*!*/;
    4. SET @@session.pseudo_thread_id=6/*!*/;
    5. SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    6. SET @@session.sql_mode=1436549152/*!*/;
    7. SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    8. /*!\C utf8 *//*!*/;
    9. SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
    10. SET @@session.lc_time_names=0/*!*/;
    11. SET @@session.collation_database=DEFAULT/*!*/;
    12. create database test
    13. /*!*/;
    14. 36 # at 313
    15. 37 #220808 16:09:54 server id 1 end_log_pos 378 CRC32 0xed8705a1 Anonymous_GTID last_committed=1 sequence_number=2 rbr_only=no
    16. 38 SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    17. 39 # at 378
    18. 40 #220808 16:09:54 server id 1 end_log_pos 492 CRC32 0x372bd559 Query thread_id=6 exec_time=0 error_code=0
    19. 41 use `test`/*!*/;
    20. 42 SET TIMESTAMP=1659946194/*!*/;
    21. 43 create table jettech01(id int,name char)
    22. 44 /*!*/;
    23. 45 # at 492
    24. 46 #220808 16:09:59 server id 1 end_log_pos 557 CRC32 0xf2b51311 Anonymous_GTID last_committed=2 sequence_number=3 rbr_only=yes
    25. 47 /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    26. 48 SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    27. 49 # at 557
    28. 50 #220808 16:09:59 server id 1 end_log_pos 629 CRC32 0x5755f64f Query thread_id=6 exec_time=0 error_code=0
    29. 51 SET TIMESTAMP=1659946199/*!*/;
    30. 52 BEGIN
    31. 53 /*!*/;
    32. 54 # at 629
    33. 55 #220808 16:09:59 server id 1 end_log_pos 684 CRC32 0xc59d8d91 Table_map: `test`.`jettech01` mapped to number 113
    34. 56 # at 684
    35. 57 #220808 16:09:59 server id 1 end_log_pos 726 CRC32 0x9b8b6300 Write_rows: table id 113 flags: STMT_END_F
    36. 58
    37. 59 BINLOG '
    38. 60 18TwYhMBAAAANwAAAKwCAAAAAHEAAAAAAAEABHRlc3QACWpldHRlY2gwMQACA/4C/gEDkY2dxQ==
    39. 61 18TwYh4BAAAAKgAAANYCAAAAAHEAAAAAAAEAAgAC//wDAAAAAWMAY4ub
    40. 62 '/*!*/;
    41. 63 # at 726
    42. 64 #220808 16:09:59 server id 1 end_log_pos 757 CRC32 0x86c37763 Xid = 399
    43. 65 COMMIT/*!*/;
    44. 66 # at 757
    45. 67 #220808 16:10:10 server id 1 end_log_pos 822 CRC32 0xda41b64a Anonymous_GTID last_committed=3 sequence_number=4 rbr_only=no
    46. 68 SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    47. 69 # at 822
    48. 70 #220808 16:10:10 server id 1 end_log_pos 913 CRC32 0xc428bae4 Query thread_id=6 exec_time=0 error_code=0
    49. 71 SET TIMESTAMP=1659946210/*!*/;
    50. 72 SET @@session.time_zone='SYSTEM'/*!*/;
    51. 73 flush privileges
    52. 74 /*!*/;
    53. 75 # at 913
    54. 76 #220808 16:11:05 server id 1 end_log_pos 978 CRC32 0x4ee77a13 Anonymous_GTID last_committed=4 sequence_number=5 rbr_only=no
    55. 77 SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    56. 78 # at 978
    57. 79 #220808 16:11:05 server id 1 end_log_pos 1070 CRC32 0x0ec87860 Query thread_id=6 exec_time=0 error_code=0
    58. 80 SET TIMESTAMP=1659946265/*!*/;
    59. 81 drop database test
    60. 82 /*!*/;
    61. 83 # at 1070

    start_position:219

    end_position:978

    恢复数据报错:

    1. [root@localhost mysql]# mysqlbinlog -vv  master-bin.000001 --start-position=219 --stop-position=978 | mysql -uroot -p
    2. Enter password: 
    3. ERROR 1782 (HY000) at line 23: @@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON.

    解决方案 

    MySQL :: MySQL 5.7 Reference Manual :: 16.1.4.3 Disabling GTID Transactions Online

    1. mysql> show global variables like 'gtid_mode';
    2. +---------------+-------+
    3. | Variable_name | Value |
    4. +---------------+-------+
    5. | gtid_mode | ON |
    6. +---------------+-------+
    7. 1 row in set (0.01 sec)
    8. mysql> set @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
    9. Query OK, 0 rows affected (0.00 sec)
    10. mysql> set @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
    11. Query OK, 0 rows affected (0.00 sec)
    12. mysql> show global variables like 'gtid_mode';
    13. +---------------+----------------+
    14. | Variable_name | Value |
    15. +---------------+----------------+
    16. | gtid_mode | OFF_PERMISSIVE |
    17. +---------------+----------------+
    18. 1 row in set (0.00 sec)

    注:更改 GTID_MODE 状态顺序为 ON<->ON_PERMISSIVE<->OFF_PERMISSIVE<->OFF ,需要按照顺序依次改变。

    再次执行就不会报错了:

    1. [root@localhost mysql]# mysqlbinlog -vv master-bin.000001 --start-position=219 --stop-position=978 | mysql -uroot -p
    2. Enter password:
    3. [root@localhost mysql]

    检查数据 

    1. mysql> show databases;
    2. +--------------------+
    3. | Database |
    4. +--------------------+
    5. | information_schema |
    6. | mysql |
    7. | performance_schema |
    8. | sys |
    9. | test |
    10. +--------------------+
    11. 5 rows in set (0.00 sec)
    12. mysql> select * from test.jettech01;
    13. +------+------+
    14. | id | name |
    15. +------+------+
    16. | 3 | c |
    17. +------+------+
    18. 1 row in set (0.00 sec)

     在恢复回去GTID_MODE 

    1. mysql> set @@GLOBAL.GTID_MODE = ON;
    2. ERROR 1788 (HY000): The value of @@GLOBAL.GTID_MODE can only be changed one step at a time: OFF <-> OFF_PERMISSIVE <-> ON_PERMISSIVE <-> ON. Also note that this value must be stepped up or down simultaneously on all servers. See the Manual for instructions.
    3. mysql> set @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
    4. Query OK, 0 rows affected (0.00 sec)
    5. mysql> set @@GLOBAL.GTID_MODE = ON;
    6. Query OK, 0 rows affected (0.00 sec)
    7. mysql> show global variables like 'gtid_mode';
    8. +---------------+-------+
    9. | Variable_name | Value |
    10. +---------------+-------+
    11. | gtid_mode | ON |
    12. +---------------+-------+
    13. 1 row in set (0.01 sec)

  • 相关阅读:
    YOLOV8改进:TripletAttention | 即插即用的轻量级注意力机制
    MES系统物料管理的五大功能,建议收藏
    语言模型和词向量的发展史及其原理
    十分钟“手撕”七大排序
    Javaweb项目中文件的上传与下载
    window11安装JDK1.8【jdk-8u121】
    集合类ArrayList的扩容机制详解
    如何在Linux系统安装Nginx
    java专题练习(抢红包)
    第2-3-5章 删除附件的接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss
  • 原文地址:https://blog.csdn.net/Michaelwubo/article/details/126229721