MySQL 数据库的备份与恢复
1.1 备份数据的意义
1.2 备份单个数据库参数使用
mysqldump -uroot -p123456 -S /data/3306/mysql.sock oldboy >/opt/oldboy_$(date +%F).sql
[root@db02 oldboy]# egrep -v "#|\*|--|^$" /opt/oldboy_2016-06-22.sql
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
`age` tinyint(2) NOT NULL DEFAULT '0',
`dept` varchar(16) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_name` (`name`),
KEY `index_age` (`name`(8)),
KEY `ind_name_dept` (`name`,`dept`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOCK TABLES `student` WRITE;
UNLOCK TABLES;
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
LOCK TABLES `test` WRITE;
INSERT INTO `test` VALUES (1,'oldboy'),(2,'oldgirl'),(3,'inca'),(4,'zuma'),(5,'kaka');
UNLOCK TABLES;
参数 | 说明 | |
-A | 备份所有数据库 | |
-B | 增加创建数据库和连接数据库的语句 | |
-t | 只备份数据 | |
-d | 只备份库表结构 | |
-T | 分离库表和数据成不同的文件,数据是文本,非SQL语句 | |
-x | 锁表 禁止写入数据 | |
-F | 刷新binlog日志,生成新的文件,将来增量恢复使用 |
1.3 常用命令介绍
mysqldump
-uroot -p123456 -S /data/3306/mysql.sock -B oldboy >/opt/oldboy_B_$(date
+%F).sql
[root@db02
oldboy]# mysql -uroot -p123456 -S /data/3306/mysql.sock
</opt/oldboy_2016-06-22.sql
小结:如果不加-B 恢复的时候需要提前创建好数据库并指定
–skip-disable-keys –skip-add-locks
mysqldump -uroot -p123456 -S /data/3306/mysql.sock -B oldboy --compact >/opt/123.sql
mysqldump -uroot -p123456 -S /data/3306/mysql.sock -B oldboy|gzip>/opt/123.sql.gz
-rw-r--r-- 1 root root 899 Jun 22 17:34 123.sql.gz
-rw-r--r-- 1 root root 1014 Jun 22 17:27 123.sql
以上参数小结
- 备份数据使用-B参数,会在备份数据中增加建库的语句。
- 备份数据使用-B参数,后面可以直接接多个库名
- 用gzip对备份的数据压缩,可以提高效率
- debug时可以用–compact减少输出,但不用于生产
- 指定字符集备份用–default-character-set=latin1(一般不用此字符集)
mysqldump的工作原理?
mysqldump -uroot -p123456 -S /data/3306/mysql.sock -B oldboy wordpress >/opt/123.sql
提示:使用mysqldump是把数据库的数据导出通过sql语句的形式存储,这种备份方式成称为逻辑备份,效率不是很高,一般50G以内的数据。
其他的备份方式:物理备份cp、tar(停库),xtrabackup
1.4 如果做分库分表
mysqldump -uroot -p123456 -B oldboy
mysqldump -uroot -p123456 -B oldboy_gbk
分库的备份语法:
[root@db02 oldboy]# mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show databases;"|egrep -v "Database|_schema|mysql"
cyh
oldboy
oldboy123
oldboy_gbk
wordpress
执行命令,进行批量备份
mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show databases;"|egrep -v "Database|_schema|mysql"|sed -r 's#^(.*)#mysqldump -uroot -p123456 -S /data/3306/mysql.sock -B \1 >/tmp/\1.sql.gz#g'|bash
查看最后结果
[root@db02 tmp]# ll
total 20
-rw-r--r-- 1 root root 0 Jun 21 11:55 bak.sql
-rw-r--r-- 1 root root 1382 Jun 22 17:55 cyh.sql.gz
-rw-r--r-- 1 root root 1406 Jun 22 17:55 oldboy123.sql.gz
-rw-r--r-- 1 root root 1409 Jun 22 17:55 oldboy_gbk.sql.gz
-rw-r--r-- 1 root root 2808 Jun 22 17:55 oldboy.sql.gz
-rw-r--r-- 1 root root 1406 Jun 22 17:55 wordpress.sql.gz
mysqldump -uroot -p123456 -S /data/3306/mysql.sock oldboy test >/opt/test.sql
mysqldump -uroot -p123456 -S /data/3306/mysql.sock oldboy test cyh>/opt/test.sql
mysqldump -uroot -p123456 -S /data/3306/mysql.sock oldboy test -d >/opt/test.sql
mysqldump -uroot -p123456 -S /data/3306/mysql.sock oldboy test -t>/opt/test.sql
利用mysqldump -d 参数只备份表的结构,例:备份oldboy所有表结构
mysqldump -uroot -p123546 -B -d oldboy >/opt/t.sql
mysqldump -uroot -p123456 oldboy student –compact –tab=/tmp/
cat /tmp/student.txt
oldboy
oldgirl
inca
zuma
mysqldump用于定时对某一时刻的数据的全备,例如:00点进行备份back.sql.gz
增量备份:当有数据写入到数据库时,还会同时把更新的SQL语句写入到对应的文件里这个就叫做binlog文件
mysqldump -uroot -p123456 -S /data/3306/mysql.sock oldboy test -F --compact
-F 在/data/3306就会记录mysql-bin.000005 按照循序设置,刷新binglog日志,在备份之后立刻刷新binlog日志
- binlog是记录数据库更新的SQL语句,二进制文件
- mysqldump永不定时对某一时刻数据的全备,例如:00点进行备份bak.sql.gz
- 增量备份:当有数据写入到数据库时,还会同时把更新的SQL语句写入到对应的文件里
- 这个文件就叫做binlog文件
- 00点时刻备份的bak.sql.gz 数据还原到数据库,这个时候恢复到了00点
- 00点-10:00数据,就要从binlog里恢复
- -F 刷新binlog日志,生成新文件,将来恢复从这个文件开始。
- –maser-data在备份语句里添加CHANGE MASTER语句及binlog文件位置点信息
- 值为1=可执行的CHANGE MASTER语句
- 值为2=注释的–CHANGE MASTER语句
- –master-data除了增量恢复确定临界点外,做主从复制时作用更大。
1.5 生产场景不同引擎mysqldump备份命令
mysqldump -uroot -poldboy123 -A -B -F -R --master-data=2 -x --events|gzip >/opt/all.sql.gz
提示:-F 也可以不用,与--master-data有些重复
mysqldump -uroot —poldboy123 -A -B -F -R --master-data=2 --events --single-transaction|gzip >/opt/all.sql.gz
提示:-F 也可以不用,与--master-data
Mysql>system ls -l /opt/ 可以跳出mysql查看命令
Mysql>source /opt/oldboy_B.sql 直接接路径就可以恢复
source数据恢复和字符集关联很大,如果字符集不正确会导致恢复的数据乱码
UTF8数据库,那么恢复的文件格式需要为"UTF8-没有签名"格式,txt右击另存为设置
1.6 MySQL恢复命令
gzip -d /opt/mysql.sql.gz
mysql -uroot -poldboy </opt/mysql.sql
不删除源备份文件:
gzip -cd 01.sql.gz >2.sql
gunzip<b_bak.sql.gz>/opt/mysql.sql
mysql -uroot -poldboy </opt/mysql.sql
或者
gunzip <b_bak.sql.gz|mysql -uroot -poldboy123
1.7 实现和MySQL非交互式对话
1.7.1 利用mysql -e 参数查看mysql数据
[root@www ~]# mysql -uroot -p -e "show databases;"
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbs |
| mysql |
| performance_schema |
| test |
| wordpress |
+--------------------+
[root@www ~]# mysql -uroot -p -e "show full processlist;"
Enter password:
+-----+------+-----------+------+---------+------+-------+-----------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-----+------+-----------+------+---------+------+-------+-----------------------+
| 797 | root | localhost | NULL | Query | 0 | NULL | show full processlist |
+-----+------+-----------+------+---------+------+-------+-----------------------+
mysql> show processlist;
mysql>kill 89; 可以使用kill 杀死进程
[mysqld]
interactive_timeout = 120 <==此参数设置后wait_timout自动失效
wait_timeout = 120
1.8 不重启数据库修改数据库参数
shell>mysql -uroot -poldboy -e "show variables;"|grep key_buffer
key_buffer_size 16384
shell>mysql -uroot -poldboy -e "set global key_buffer_size = 1024*32;"
shell>mysql -uroot -poldboy -e "show variables;"|grep key_buffer
key_buffer_size 32768
shell>sed -n '32p' /etc/my.cnf
key_buffer_size = 16K
shell>sed -i 's#key_buffer_size = 16K#key_buffer_size = 32K#g' /etc/my.cnf
查看数据库参数是否生效
mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show variables\G"
[root@db02 opt]# mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show variables like '%server_id%';"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 1 |
+---------------+-------+
查看my配置文件有没有在数据库中生效
[root@db02 opt]# mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show variables like '%log_bin%';"
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| log_bin | ON |
| log_bin_trust_function_creators | OFF |
| sql_log_bin | ON |
+---------------------------------+-------+
[root@db02 opt]# mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show variables like '%slow_%';"
+---------------------+-------------------------------+
| Variable_name | Value |
+---------------------+-------------------------------+
| log_slow_queries | OFF |
| slow_launch_time | 2 |
| slow_query_log | OFF |
| slow_query_log_file | /data/3306/data/db02-slow.log |
+---------------------+-------------------------------+
[root@db02 opt]# mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show variables like '%key_buffer%';"
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| key_buffer_size | 16777216 |
+-----------------+----------+
修改索引缓冲区的大小
set global key_buffer_size = 1024*1024*32;
root@oldboy 11:03:59->show variables like '%key_buffer%';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| key_buffer_size | 33554432 |
+-----------------+----------+
1 row in set (0.00 sec)
show processlist; #查看数据库正在执行的SQL语句,可能无法看全完整SQL语句
show full prcesslist #查看正在执行的完整SQL语句,完整显示
set global key_buffer_size = 1024*1024*32 #不重启数据库调整数据库参数,直接生效,重启后失效、
show variables; #查看数据库的配置参数信息,例如:my.cnf里参数的生效情况
kill ID #杀掉SQL线程的命令,ID为线程号
show session status #查看当前会话的数据库状态信息
show global status; #查看整个数据库运行状态信息,很重要。要分析并做好监控
show status; #mysql运行状态
- show engine innodb status; #显示InnoDB 引擎的性能状态(早起版本show innodb status)
root@oldboy 11:22:46->show global status like '%select%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| Com_insert_select | 0 |
| Com_replace_select | 0 |
| Com_select | 264 |
| Select_full_join | 0 |
| Select_full_range_join | 0 |
| Select_range | 7 |
| Select_range_check | 0 |
| Select_scan | 287 |
+------------------------+-------+
8 rows in set (0.00 sec)
[root@db02 opt]# mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show status ;"|grep -E "select|insert"
Com_insert 0
Com_insert_select 0
Com_replace_select 0
Com_select 1
Delayed_insert_threads 0
Innodb_rows_inserted 117
Qcache_inserts 58
[root@db02 opt]# mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show status ;"|grep -E "select|insert"
Com_insert 0
Com_insert_select 0
Com_replace_select 0
Com_select 1
Delayed_insert_threads 0
Innodb_rows_inserted 117
Qcache_inserts 58
show gengine innodb status\G
MySQL工具mysqlbinlog
2.1 mysql的binlog日志是什么?
多实例路径:/data/3306/
mysql-bin.00001
mysql-bin.00002
mysql-bin.00003
mysql-bin.00004
mysql-bin.00005
grep log-bin my.cnf
log-bin = /data/3306/mysql-bin
2.2 mysqlbinlog工具解析binlog日志实践
shell>mysqlbinglog -d oldboy mysql-bin.00001 -r oldboy.sql
- 提示:-r代表>输出内容 -d 指定库文件
# at 2154
#160630 7:45:07 server id 1 end_log_pos 2253 Query thread_id=11 exec_time=0 error_code=0
SET TIMESTAMP=1467243907/*!*/;
create database qqqqqqq41233
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
按照位置截取:确定
# at 2154
#160630 7:45:07
mysqlbinlog mysql-bin.000001 --start-position=2156 --stop-position=3000 -r pos.sql
其中,--start-posistion可以在配置文件中不存在,那时候取值将会取最接近2156的值
按照时间截图:模糊,不准
mysqlbinlog mysql-bin.00001 --start-datetime='2016-10-16 17:14:15' --stop-datetime='2014-10-16 17:15:15' -r time.sql
指定开始时间,不指定结束时间,将从开始时间一直到最后
mysqlbinlog mysql-bin.000001 --start-datetime='2016-10-16 17:14:15' -r time.sql
指定结束时间,不指定开始时间,将从开始一直到指定的结束时间
mysqlbinlog mysql-bin.000002 --stop-datetime='2016-10-16 17:14:15' -r time.sql
mysqlbinlog命令
mysqlbinlog --base64-ouput=decode-rows-v mysql-bin.00001
mysqlbinlog --base64-ouput="decode-rows" --verbose-mysql-bin.00001
2.3 错误日志(error log)介绍与调整
法1:在配置文件中调整方法,当然可以在启动时加入启动参数
[mysqld_safe]
log-error=/data/3306/mysql_oldboy3306.err
法2:启动MySQL命令里加入:
mysqld_safe --default-file=/data/3306/my.cnf --log-error=/data/3306/mysql_oldboy.err &
root@oldboy 10:09:14->show variables like '%log_error%';
+---------------+---------------------------------+
| Variable_name | Value |
+---------------+---------------------------------+
| log_error | /data/3306/mysql_oldboy3306.err |
+---------------+---------------------------------+
1 row in set (0.04 sec)
mysqld_safe --default-file=/data/3306/my.cnf --log-error=/data/3306/mysql_oldboy.err &
root@oldboy 10:09:14->show variables like '%log_error%';
+---------------+---------------------------------+
| Variable_name | Value |
+---------------+---------------------------------+
| log_error | /data/3306/mysql_oldboy3306.err |
+---------------+---------------------------------+
1 row in set (0.04 sec)
新装MySQL服务,无法启动排查思路
步骤———————————-
[root@db02 3306]# cat mysql_oldboy3306.err
160616 16:46:07 mysqld_safe Starting mysqld daemon with databases from /data/3306/data
[root@db02 3306]# chown -R mysql *
[root@db02 3306]# id mysql
uid=502(mysql) gid=502(mysql) groups=502(mysql)
[root@db02 3306]#/data/3306/mysql start
[root@db02 3306]#lsof -i:3306
2.4 查询日志(也可以叫做访问日志)
[root@db02 ~]grep gene /data/3306/my.cnf
general_log = on
general_log_file = /data/3306/data/MySQL_oldboy.log
long_query_time=超过指定时间查询(看公司要求,通常2秒)
log-slow-queries= 日志路径
log_queries_not_using_indexes=不使用索引
[root@db02 oldboy]# egrep "quer" /data/3306/my.cnf|tail -3
long_query_time = 1
log-slow-queries = /data/3306/slow.log
log_queries_not_using_indexes
2.6 慢查询日志切割
shell>cat /server/scripts/cut_slow_log.sh
cd /data/3306/ &&\
/bin/mv slow.log slow.log.$(date +%F)&&\
mysqladmin -uroot -poldboy123 -S /data/3306/mysql.sock flush-log
shell>tail -2 /var/spool/cron/root
#cut mysql slow log
00 00 * * * /bin/sh /server/scripts/cur_slow_log.sh >/dev/null 2>&1
使用explain优化SQL语句(select语句)的基础流程;
1.抓慢查询SQL语句方法:
2.explain语句检查索引执行情况
3.分析慢查询的工具mysqlsla(每天早上发邮件)
shell>mv /data/3306/slow.log /opt/$(date +%F)_slow.log
shell>mysqladmin -uroot -poldboy -S /data/3306/mysql.sock flush-logs
mysqlsla分析:http://blog.itpub.net/7607759/viewspace-692828
2.7 二进制日志(binary log)介绍与调整
root@oldboy 11:13:37->show variables like '%log_bin%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| log_bin 记录binlog开关 | ON |
| log_bin_trust_function_creators | OFF |
| sql_log_bin 临时不记录binlog开关(增量恢复)| ON
+---------------------------------+-------+
3 rows in set (0.01 sec)
[root@db02 3306]# grep log-bin /data/3306/my.cnf
log-bin = /data/3306/mysql-bin
二进制日志log-bin作用;
2.8 增量备份
(1)按天全备情况
(2)按周全备情况
企业场景全量和增量的频率是怎么做的呢?
MySQL备份常见方法
MySQL的mysqldump备份什么时候排上用场?
2.9 什么情况下需要增量恢复?
3.0 MySQL增量恢复必备条件
3.1 开启MySQL log-bin 日志功能
shell>grep log-bin /data/3306/my.cnf
log-bin = /data/3306/mysql-bin
3.2 模拟每天00点备份数据,早上10.00领导删除数据,10.10发现问题并进行解决
- [root@db02 3306]#date -s "00:00:00"
[root@db02 3306]# mysqldump -uroot -p123456 -S /data/3306/mysql.sock -B -F -R -x --master-data=2 oldboy|gzip >/opt/rh/oldboy-$(date +%F).sql.gz
[root@db02 3306]#date -s "10:00:00"
mysql>drop database test;
[root@db02 rh]# gzip -d oldboy-2015-12-22.sql.gz
[root@db02 rh]# grep CHANGE oldboy-2015-12-22.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000007', MASTER_LOG_POS=107;
[root@db02 rh]# cp /data/3306/mysql-bin.000007 .
[root@db02 rh]# ls -l
total 8
-rw-r----- 1 root root 792 Dec 22 10:10 mysql-bin.000007
-rw-r--r-- 1 root root 3010 Dec 22 00:00 oldboy-2015-12-22.sql
[root@db02 rh]# mysqlbinlog -d oldboy oldboy-2015-12-22.sql
-d oldboy oldboy-2015-12-22.sql*或者后面接上bin。
[root@db02 rh]# mysqlbinlog -d oldboy mysql-bin.000007 >007.sql
[root@db02 rh]#vim 007.sql
因为是使用drop删除,日志里面记录了,所以我们使用vim将里面的drop删除
[root@db02 rh]# mysql -uroot -p123456 -S /data/3306/mysql.sock <oldboy-2015-12-22.sql
[root@db02 rh]# mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| cyh |
| mysql |
| oldboy |
| oldboy123 |
| oldboy_gbk |
| performance_schema |
| wordpress |
+--------------------+
表示已经恢复到我们00点之前的数据
[root@db02 rh]# mysql -uroot -p123456 -S /data/3306/mysql.sock -e "select * from oldboy.test;"
+----+--------+
| id | name |
+----+--------+
| 1 | gongli |
| 2 | gongli |
| 3 | gongli |
| 4 | gongli |
| 5 | gongli |
+----+--------+
恢复增量数据
[root@db02 rh]# mysql -uroot -p123456 -S
/data/3306/mysql.sock 007.sql
企业案例:
625某电商网站数据库宕机故障解决实录(上)
http://oldboy.blog.51cto.com/2561410/1431161
http://oldboy.blog.51cto.com/2561410/1431172