mysql数据恢复,binlog详解
程序员文章站
2022-06-23 14:50:28
"个人博客:mysql数据恢复,binlog详解" binlog日志恢复数据,是挽救错误操作和数据损坏一根救命稻草,所以认识和使用binglog对于技术人员还是很有必要的 binlog一般用于 主从复制 中 master节点开启binlog把二进制日志传递给slave节点达到主从数据一致 第二点自然 ......
个人博客:mysql数据恢复,binlog详解
binlog日志恢复数据,是挽救错误操作和数据损坏一根救命稻草,所以认识和使用binglog对于技术人员还是很有必要的
binlog一般用于
- 主从复制 中 master节点开启binlog把二进制日志传递给slave节点达到主从数据一致
- 第二点自然是用于数据恢复了,使用mysqlbinlog工具来恢复数据
因为我自己的网站遇到过mysql表被我误删操作,drop table后当时我还是挺淡定的,虽然我不清楚我能不能把数据拯救回来,对于个人网站而言可能都没有主从,也没有把mysql的各项配置设置完美,这种情形下最担心的当然是binlog是否开启了,如果没有开启binlog并且也没有做数据备份,我感觉基本上就gg了
因为我mysql是通过docker容器安装的,所以具体 my.cnf 配置文件的放在哪也忘记了
- 使用 find / -name my.cnf 找到文件在哪
root@0d5861775029:/# find / -name my.cnf find: '/proc/1/map_files': operation not permitted find: '/proc/182/map_files': operation not permitted find: '/proc/187/map_files': operation not permitted find: '/proc/1601/map_files': operation not permitted find: '/proc/1731/map_files': operation not permitted find: '/proc/1741/map_files': operation not permitted /etc/alternatives/my.cnf /etc/mysql/my.cnf /var/lib/dpkg/alternatives/my.cnf root@0d5861775029:/#
- 查看my.cnf配置找到binlog以及mysql数据存储的位置
# # the mysql server configuration file. # # for explanations see # http://dev.mysql.com/doc/mysql/en/server-system-variables.html [mysqld] pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql secure-file-priv= null # disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # custom config should go here !includedir /etc/mysql/conf.d/
- 可以看到mysql数据存储的目录是 datadir = /var/lib/mysql 目录中
root@0d5861775029:/etc/mysql# cd /var/lib/mysql/ root@0d5861775029:/var/lib/mysql# ls #innodb_temp binlog.index client-key.pem ib_logfile1 mysql.ibd server-cert.pem undo_002 auto.cnf ca-key.pem db_blog ibdata1 performance_schema server-key.pem binlog.000001 ca.pem ib_buffer_pool ibtmp1 private_key.pem sys binlog.000002 client-cert.pem ib_logfile0 mysql public_key.pem undo_001
上面的前戏都看完了,这其实并非binlog具体使用,而是我个人发现数据目录方式 接下来我将详细介绍binlog的使用
一、开启binlog日志
- 查看binlog是否开启
- on 表示已经开启
- 查看更多内容可以这样
show variables like 'log_%';
mysql> show variables like 'log_bin'; +---------------+-------+ | variable_name | value | +---------------+-------+ | log_bin | on | +---------------+-------+ 1 row in set (0.00 sec)
mysql> show variables like 'log_%'; +----------------------------------------+----------------------------------------+ | variable_name | value | +----------------------------------------+----------------------------------------+ | log_bin | on | | log_bin_basename | /var/lib/mysql/binlog | | log_bin_index | /var/lib/mysql/binlog.index | | log_bin_trust_function_creators | off | | log_bin_use_v1_row_events | off | | log_error | stderr | | log_error_services | log_filter_internal; log_sink_internal | | log_error_suppression_list | | | log_error_verbosity | 2 | | log_output | file | | log_queries_not_using_indexes | off | | log_slave_updates | on | | log_slow_admin_statements | off | | log_slow_extra | off | | log_slow_slave_statements | off | | log_statements_unsafe_for_binlog | on | | log_throttle_queries_not_using_indexes | 0 | | log_timestamps | utc | +----------------------------------------+----------------------------------------+ 18 rows in set (0.00 sec)
- 编辑my.cnf开启binlog
在[mysqld] 区块 设置/添加 log-bin=mysql-bin 确认是打开状态(值 mysql-bin 是日志的基本名或前缀名);
然后重启mysql
二、查看binlog日志操作命令
- 查看所有binlog日志列表
mysql> show logs; error 1064 (42000): you have an error in your sql syntax; check the manual that corresponds to your mysql server version for the right syntax to use near 'logs' at line 1 mysql> show master logs; +---------------+-----------+-----------+ | log_name | file_size | encrypted | +---------------+-----------+-----------+ | binlog.000001 | 3091158 | no | | binlog.000002 | 141156437 | no | +---------------+-----------+-----------+ 2 rows in set (0.17 sec)
- 查看master状态,也就是最新一个binlog日志编号名称和最后一个操作事件pos结束位置
mysql> show master status; +---------------+-----------+--------------+------------------+-------------------+ | file | position | binlog_do_db | binlog_ignore_db | executed_gtid_set | +---------------+-----------+--------------+------------------+-------------------+ | binlog.000002 | 141156437 | | | | +---------------+-----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
- 刷新log日志,将会产生一个新编号的binlog日志文件
mysql> flush logs;
- 重置(清空)所有binlog日志
mysql> reset master;
三、查看binlog日志内容
-
使用mysqlbinlog命令查看
因为binlog是二进制文件,普通文件查看器都无法打开,必须使用自带的mysqlbinlog命令查看
- mysqlbinlog binlog.000002 使用mysqlbinlog不好观察
- 在mysql中查看binlog日志
mysql> show binlog events [in 'log_name'] [from pos] [limit [offset,] row_count]; 选项解析: in 'log_name' 指定要查询的binlog文件名(不指定就是第一个binlog文件) from pos 指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算) limit [offset,] 偏移量(不指定就是0) row_count 查询总条数(不指定就是所有行) 截取部分查询结果: *************************** 20. row *************************** log_name: mysql-bin.000021 ----------------------------------------------> 查询的binlog日志文件名 pos: 11197 ----------------------------------------------------------> pos起始点: event_type: query ----------------------------------------------------------> 事件类型:query server_id: 1 --------------------------------------------------------------> 标识是由哪台服务器执行的 end_log_pos: 11308 ----------------------------------------------------------> pos结束点:11308(即:下行的pos起始点) info: use `zyyshop`; insert into `team2` values (0,345,'asdf8er5') ---> 执行的sql语句 *************************** 21. row *************************** log_name: mysql-bin.000021 pos: 11308 ----------------------------------------------------------> pos起始点:11308(即:上行的pos结束点) event_type: query server_id: 1 end_log_pos: 11417 info: use `zyyshop`; /*!40000 alter table `team2` enable keys */ *************************** 22. row *************************** log_name: mysql-bin.000021 pos: 11417 event_type: query server_id: 1 end_log_pos: 11510 info: use `zyyshop`; drop table if exists `type`
- 指定查询 binlog.000002 日志
mysql> show binlog events in 'binlog.000002' limit 10; +---------------+------+----------------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | log_name | pos | event_type | server_id | end_log_pos | info | +---------------+------+----------------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | binlog.000002 | 4 | format_desc | 1 | 124 | server ver: 8.0.16, binlog ver: 4 | | binlog.000002 | 124 | previous_gtids | 1 | 155 | | | binlog.000002 | 155 | anonymous_gtid | 1 | 234 | set @@session.gtid_next= 'anonymous' | | binlog.000002 | 234 | query | 1 | 482 | create user 'schwarzeni'@'localhost' identified with 'caching_sha2_password' as '$a$005$h{;gmzb@[}k1i\nbcce80ezg8j3o0qddyocc1oxbkshlqyzmov/c4rgp69' /* xid=7 */ | | binlog.000002 | 482 | anonymous_gtid | 1 | 561 | set @@session.gtid_next= 'anonymous' | | binlog.000002 | 561 | query | 1 | 801 | create user 'cuishifeng'@'%' identified with 'caching_sha2_password' as '$a$005$f8zs\zhy(9]hptcan83yctnmhs/lqsa2dercx.zvgd4inryicpj75ma' /* xid=8 */ | | binlog.000002 | 801 | anonymous_gtid | 1 | 878 | set @@session.gtid_next= 'anonymous' | | binlog.000002 | 878 | query | 1 | 968 | flush privileges | | binlog.000002 | 968 | anonymous_gtid | 1 | 1047 | set @@session.gtid_next= 'anonymous' | | binlog.000002 | 1047 | query | 1 | 1256 | alter user 'cuishifeng'@'%' identified with 'mysql_native_password' as '*10320381f36be49a18f09b06a4bc005223975101' /* xid=12 */ | +---------------+------+----------------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 10 rows in set (0.00 sec)
- 指定查询 binlog.000002 这个文件,从pos点:968开始查起
mysql> show binlog events in 'binlog.000002' from 968 limit 10; +---------------+------+----------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------+ | log_name | pos | event_type | server_id | end_log_pos | info | +---------------+------+----------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------+ | binlog.000002 | 968 | anonymous_gtid | 1 | 1047 | set @@session.gtid_next= 'anonymous' | | binlog.000002 | 1047 | query | 1 | 1256 | alter user 'cuishifeng'@'%' identified with 'mysql_native_password' as '*10320381f36be49a18f09b06a4bc005223975101' /* xid=12 */ | | binlog.000002 | 1256 | anonymous_gtid | 1 | 1333 | set @@session.gtid_next= 'anonymous' | | binlog.000002 | 1333 | query | 1 | 1423 | flush privileges | | binlog.000002 | 1423 | anonymous_gtid | 1 | 1500 | set @@session.gtid_next= 'anonymous' | | binlog.000002 | 1500 | query | 1 | 1646 | grant all privileges on *.* to 'cuishifeng'@'%' /* xid=70 */ | | binlog.000002 | 1646 | anonymous_gtid | 1 | 1723 | set @@session.gtid_next= 'anonymous' | | binlog.000002 | 1723 | query | 1 | 1813 | flush privileges | | binlog.000002 | 1813 | anonymous_gtid | 1 | 1890 | set @@session.gtid_next= 'anonymous' | | binlog.000002 | 1890 | query | 1 | 1968 | flush tables | +---------------+------+----------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------+ 10 rows in set (0.00 sec)
从日志中可以看出执行的mysql命令 并且有起始位置,对于恢复数据非常有用
- 查询第一个(最早)的binlog日志
mysql> show binlog events;
四、现在从binlog日志恢复数据
- 常用命令
恢复语法格式: # mysqlbinlog mysql-bin.0000xx | mysql -u用户名 -p密码 数据库名 常用选项: --start-position=953 起始pos点 --stop-position=1437 结束pos点 --start-datetime="2013-11-29 13:18:54" 起始时间点 --stop-datetime="2013-11-29 13:21:53" 结束时间点 --database=zyyshop 指定只恢复zyyshop数据库(一台主机上往往有多个数据库,只限本地log日志) 不常用选项: -u --user=name connect to the remote server as username.连接到远程主机的用户名 -p --password[=name] password to connect to remote server.连接到远程主机的密码 -h --host=name get the binlog from server.从远程主机上获取binlog日志 --read-from-remote-server read binary logs from a mysql server.从某个mysql服务器上读取binlog日志 小结:实际是将读出的binlog日志内容,通过管道符传递给mysql命令。这些命令、文件尽量写成绝对路径;
日志恢复 相当于执行当时ddl语句,如果日志恢复的语句例如你库中存在某个表 日志又执行创建这个表 肯定是走不通的 所以最好指定具体位置恢复
- 查看binlog日志 确定从哪恢复
mysql> show binlog events in 'mysql-bin.000023'; 以下为末尾片段: +------------------+------+------------+-----------+-------------+------------------------------------------------------------+ | log_name | pos | event_type | server_id | end_log_pos | info | +------------------+------+------------+-----------+-------------+------------------------------------------------------------+ | mysql-bin.000023 | 922 | xid | 1 | 953 | commit /* xid=3820 */ | | mysql-bin.000023 | 953 | query | 1 | 1038 | begin | | mysql-bin.000023 | 1038 | query | 1 | 1164 | use `zyyshop`; update zyyshop.tt set name='李四' where id=4| | mysql-bin.000023 | 1164 | xid | 1 | 1195 | commit /* xid=3822 */ | | mysql-bin.000023 | 1195 | query | 1 | 1280 | begin | | mysql-bin.000023 | 1280 | query | 1 | 1406 | use `zyyshop`; update zyyshop.tt set name='小二' where id=2| | mysql-bin.000023 | 1406 | xid | 1 | 1437 | commit /* xid=3823 */ | | mysql-bin.000023 | 1437 | query | 1 | 1538 | drop database zyyshop | +------------------+------+------------+-----------+-------------+------------------------------------------------------------+ 通过分析,造成数据库破坏的pos点区间是介于 1437--1538 之间,只要恢复到1437前就可。
mysqlbinlog --start-position=953 --stop-position=1538 --database=zyyshop binlog.000002 | mysql -uroot -p123456 -v zyyshop
- 指定时间恢复
- 知道自己在哪个时间段误操作了
mysql> drop table tt; @ --start-datetime="2013-11-29 13:18:54" 起始时间点 @ --stop-datetime="2013-11-29 13:21:53" 结束时间点 # mysqlbinlog --start-datetime="2013-11-29 13:18:54" --stop-datetime="2013-11-29 13:21:53" --database=zyyshop binlog.000002 | mysql -uroot -p123456 -v zyyshop
希望这篇文章能够帮助误删操作的朋友顺利恢复数据
上一篇: 手机号码正则表达式