数据库的备份与恢复

时间:2024-04-16 18:03:44

第1章 MySQL数据库的备份

1.1 备份数据的意义

第一个是保护公司的数据

第二个是网站7*24小时提供服务

1.2 MySQL备份常见两种方式:

1.2.1 逻辑备份

常用工具:mysqldump

就是以SQL语句的形式,将数据导出成文件(SQL语句)

优点:简单、方便、可靠

          导出的数据可以跨平台、跨版本、可以跨软件

缺点:速度慢、效率不是特别高

mysqldump是mysql官方自带的逻辑备份工具,还能实现分表分库备份。

企业场景:

    1、适合数据量不是特别大的场景,打包前50G以内的数据库数据。

    2、跨版本、系统升级时候是用mysqldump迁移数据。

 

1.2.2 物理备份

简单讲直接对MySQL数据文件拷贝备份,例如cp,tar

优点:速度快、效率高

缺点:不容易跨平台、跨版本、跨软件、甚至不能分库分表备份。

     如果普通的系统拷贝命令就需要停机备份。

常用工具或方法:

a.linux备份工具(cp,tar),锁表或者停库。

b.开源的热备(基于innodb)工具xtrabackup(课后作业)、不能分表分库。超过50G可选方案

企业应用场景:

1、xtrabackup物理备份工具:全备和增量。

2、超过50G数据量的优选方案。

3、物理备份方案:从库停止SQL线程,cp或打包。

1.2.3 物理备份和逻辑备份的对比

 

1.3 全量与增量如何结合备份

1.3.1 按天备份

 

1.3.2 按天备份的特点

 

1.3.3 按周备份

 

1.3.4 按周备份的特点

 

 

1.3.5 全备

 

1.3.6 备份最牛逼的层次,就是永远用不上备份

不管是逻辑备份还是物理备份,备份的数据什么时候需要用?

1、恢复数据到测试库的时候。

2、人为通过SQL语句将数据删除的时候。

3、做数据库主从复制的时候。

其他场景几乎都不要使用备份恢复,而是直接使用主从复制功能,将业务切换到从库。

1.4 使用mysqldump进行数据库备份实践

MySQL数据库自带了一个优秀的备份命令,就是mysqldump,它的基本使用如下:

语法:mysqldump -u用户名 -p密码 参数 数据库名 >备份的文件名.sql

特别说明:为了防止密码外泄,我们已经将密码写入配置文件了,具体配置见之前整理的不用密码登录。

1.4.1 不带参数备份单个数据库

不加参数备份名字为oldboy的库

a.查看备份前的数据

mysql> use oldboy

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> show tables;

+------------------+

| Tables_in_oldboy |

+------------------+

| student          |

| test             |

+------------------+

2 rows in set (0.00 sec)

c.命令行执行备份

[root@db02 ~]# mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock oldboy >/opt/oldboy.sql

Warning: Using a password on the command line interface can be insecure.

b.删除oldboy

mysql> drop database oldboy;

Query OK, 2 rows affected (0.04 sec)

d.恢复

mysql> source /opt/oldboy.sql

mysql> show databases;  可以看到没有回复成功

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| performance_schema |

| test               |

+--------------------+

4 rows in set (0.00 sec)

mysql> create database oldboy;  单独创建oldboy数据库

Query OK, 1 row affected (0.00 sec)

mysql> use oldboy    进入oldboy库

mysql> source /opt/oldboy.sql   恢复数据

mysql> show tables;      成功

+------------------+

| Tables_in_oldboy |

+------------------+

| student          |

+------------------+

1 row in set (0.00 sec)

提示:mysqldump备份的内容就是曾经执行过的sql语句,所不同的是恢复效率,mysqldump把数据写成了一个inster语句,另外多了两行锁表和解锁的操作。

1.4.2 加-B参数备份实践

1.4.2.1  备份时加-B参数

[root@db02 ~]# mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock -B oldboy >/opt/oldboy_B_.sql

[root@db02 ~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock </opt/oldboy_B_.sql   恢复时候直接恢复

1.4.2.2  不加-B 恢复

[root@db02 ~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock </opt/oldboy.sql

Warning: Using a password on the command line interface can be insecure.

ERROR 1046 (3D000) at line 22: No database selected

[root@db02 ~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock -e "create database oldboy;"

Warning: Using a password on the command line interface can be insecure.

root@db02 ~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock oldboy</opt/oldboy.sql

Warning: Using a password on the command line interface can be insecure.

1.4.2.3  加-B 与不加-B 文件的区别

[root@db02 ~]# mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock oldboy >/opt/oldboy.sql

[root@db02 ~]# mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock -B oldboy >/opt/oldboy_B_.sql

[root@db02 ~]# vimdiff /opt/oldboy_B_.sql /opt/oldboy.sql

2 files to edit

 

+ +-- 12 lines: -- MySQL dump 10.13  Distrib 5.6|+ +-- 12 lines: -- MySQL dump 10.13  Distrib 5.

  /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECK|  /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHEC

  /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN|  /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIG

  /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MOD|  /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MO

  /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_N|  /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_

                                                | 

  --                                            |  --

  -- Current Database: `oldboy`                 |  ---------------------------------------------

  --                                            |  ---------------------------------------------

                                                |  ---------------------------------------------

  CREATE DATABASE /*!32312 IF NOT EXISTS*/ `oldb|  ---------------------------------------------

                                                |  ---------------------------------------------

  USE `oldboy`;                                 |  ---------------------------------------------

                                                |  ---------------------------------------------

  --                                            |  ---------------------------------------------

  -- Table structure for table `student`        |  -- Table structure for table `student`

  --                                            |  --

1.4.3 备份多个库

[root@db02 ~]# mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock -B  oldboy mysql >/opt/bak.sql

Warning: Using a password on the command line interface can be insecure. 提示:-B指定多个库

1.4.4 表备份

[root@db02 ~]# mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock  oldboy student >/opt/bak.sql

Warning: Using a password on the command line interface can be insecure. 提示:备份oldboy库的student表

[root@db02 ~]# mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock --compact  oldboy student >/opt/bak.sql   --compact参数只显示很少的有用输出,适合学习和测试环境调试用

Warning: Using a password on the command line interface can be insecure.

[root@db02 ~]# cat /opt/bak.sql

/*!40101 SET @saved_cs_client     = @@character_set_client */;

/*!40101 SET character_set_client = utf8 */;

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`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*!40101 SET character_set_client = @saved_cs_client */;

1.4.5 多库备份

[root@db02 ~]# vim bak.sql.sh

#!/bin/bash

Name=$(mysql -uroot -poldboy123 -S /data/3306/mysql.sock -e \'show databases;\'|sed 1d)

  for name in $Name

   do

    mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock -B $name|gzip >/opt/bak${name}_$(date +%F).sql.gz

   done

 

 

 

1.5 mysqldump里重要参数说明

mysqldump重要参数

参数说明

-B,--databases

会在备份的数据中增加建库(create)及use库的语句,同时可以直接接多个库名,备份多个库

-A,--all-databases

备份所有的数据库,同--databases

-d,--no-data

只备份库表结构(sql语句形式)。没有行数据

-t,--no-create-info

只备份表内行数据(sql语句形式)。没有表结构

-T,--tab=name

将库表和数据分离成不同的文件,行数据是纯文本,表结构是SQL语句。

-F,--flush-logs

刷新binlog日志,生成新的binlog文件,将来增量恢复从这个新binlog文件开始,当备份多个库时,每个库都会刷新一次binlog,如果想只刷一次binlog,可加--lock-all-tables或--master-data参数

--master-data={1|2}

在备份结构中增加binlog日志文件名及对应的binlog位置点(即CHANGE MASTER...语句)。值为1时不注释状态,值为2时是注释状态,该参数执行时会打开--lock-all-tables功能,除非有--single-transaction在,使用该参数时会关闭--lock-tables功能。

-x,--lock-all-tables

备份时对所有数据库的表执行全局读锁,期间同时禁止--single-transaction和--lock-tables参数功能

-l,--lock-tables

锁定所有的表为只读

--single-transaction

拍快照

在备份innodb引擎数据表时,通常用该选项来获取一个一致性的数据快照备份,它的工作原理是设定本次备份会话的隔离级别为REPEATABLE READ,并将整个备份放在 一个事务里,以确保执行本次dump会话时,不会看到其他连接会话已经提交了的数据,即备份开始时刻的数据是什么样,备份出来就是什么样子,也就相当于锁表备份数据,但是这个参数允许备份期间写入数据的,而不是-x锁表后的备份期间无法任何数据写入,启用该参数会关闭--lock-tables

--compact

只显示很少的有用输出,适合学习和测试环境调试用

 

1.6 binlog 内容

1.6.1 mysql的binlog日志作用是什么

MySQL的binlog日志用来记录mysql内部增删改等对mysql数据库有更新的内容的记录,(对数据库的改动),对数据库查询的语句如show,select开头的语句,不会被binlog日志记录,主要作用是,用于数据库的主从复制以及数据的增量恢复。

1.6.2 binlog是什么?

binlog一个二进制格式的文件,用于记录对数据库的更新日志,例如对数据库库表的更改及表的内容更改的SQL语句会记录到binlog里,但是对库表的查询等不会记录。

1.6.3 binlog对于备份的作用

当有数据写入到数据库时,还会同时把更新的SQL语句写入到对应的binlog文件里,这个文件就是上文说的binlog文件。

使用mysqldump备份,一般是对某一时刻的数据的全备,例如:00点进行数据库备份。

假设每天0点对数据库进行备份,那么在两次备份之间就有24小时的数据没有备份,在这期间一定丢失数据,使用mysqldump全量备份恢复也只能恢复到当日00点备份的时刻,但是有了binlog文件,就可以用了两次完整备份之间的数据丢失恢复还原,因为binlog文件里的数据就是写入数据库的数据,使用binlog恢复数据,我们称之为增量数据恢复。

1.6.4 为什么要刷新binlog?

binlog日志刷新(切割)的目的就是确定全备和增量备份的临界点,当全备完成后,全备时刻以前的binlog就无用了(全备这里有这部分数据),但是全备以后到下一次全备前的数据就是十分重要的,因此进行全备时需要找到全备和增量之间的临界点,以方便恢复。

1.6.5 如何开启binlog功能

binlog文件生效需要一个参数:log-bin,加入到my.cnf配置文件中即可。

 

重启生效

[root@db01 ~]# ll /data/3306/

总用量 808

-rw-rw---- 1 root  root    1467 3月  21 19:58 bin.sql

drwxr-xr-x 9 mysql mysql   4096 3月  21 22:52 data

-rw-r--r-- 1 mysql mysql   1884 3月  21 18:46 my.cnf

-rwx------ 1 mysql mysql   1195 2月  27 12:37 mysql

-rw-rw---- 1 mysql mysql   1352 3月  21 18:26 mysql-bin.000001

-rw-rw---- 1 mysql mysql    317 3月  21 18:48 mysql-bin.000002

-rw-rw---- 1 mysql mysql 654800 3月  21 22:57 mysql-bin.000003

-rw-rw---- 1 mysql mysql     84 3月  21 18:48 mysql-bin.index

-rw-rw---- 1 mysql mysql      6 3月  21 18:48 mysqld.pid

-rwx------ 1 mysql mysql   1363 3月  16 09:28 mysql_oldboy

srwxrwxrwx 1 mysql mysql      0 3月  21 18:48 mysql.sock

-rw-r----- 1 mysql mysql 129359 3月  21 22:10 oldboy_3306.err

 

.index是索引文件

.000001记录更改的SQL文件

1.6.6 如何配置binlog

[root@db02 ~]# mkdir /application/mysql/logs

[root@db02 ~]# chown -R mysql.mysql /application/mysql/logs

开启binlog

编辑/etc/my.cnf

[mysqld]

log_bin = /application/mysql/logs/oldboy-bin

重启:/etc/init.d/mysqld restart

[root@db02 ~]# ll /application/mysql/logs/

total 8

-rw-rw---- 1 mysql mysql 120 Jun 21 12:04 oldboy-bin.000001

-rw-rw---- 1 mysql mysql  42 Jun 21 12:04 oldboy-bin.index

5)使用-F刷新binlog日志

    使用-F将从备份后的时刻起重新binlog日志文件,将来增量恢复从这个新日志文件开始即可。

 

binlog文件切割的条件:

1、数据库重启,自动切割新文件。

2、mysqldump -F

3、binlog文件达到1.1G,自动切割

4、人为配置切割及调整

删除binlog日志方法

1、设置参数自动删除

expire_logs_days = 7  #删除7天前的日志

2、从头删到指定的文件位置

数据库执行

purge binary logs to \'mysql-bin.00004\';

 

 

 

1.7 特殊记录binlog位置的参数

mysqldump里提供了一个参数,允许我们不用刷新binlog,也可以找到全量和增量的临界点,就是--master-data参数,使用这个参数备份后,在备份的文件对应的SQL语句里会添加CHANGE MASTER语句及binlog文件及位置点信息。

当--master-data=1时,备份结果为可执行的“CHANGE MASTER...”语句,当--master-data=2时,备份结果为可执行的“--CHANGE MASTER...”语句,“--”在SQL语句里为注释的意思。--master-data参数除了确定增量恢复和全备之间的临界点外,做主从复制时作用更大。

1.8 生产场景不同引擎mysqldump备份命令

1)         innodb引擎企业生产备份可使用命令

2)         mysqldump -B -R --triggers --master-data=2 oldboy|gzip >/opt/alL_$(date +%F).sql.gz

mysqldump -A -B --master-data=2 --single-transaction |gzip >/opt/all.sql.gz

提示: --single-transaction是innodb引擎专有备份参数,优势就是备份期间数据依然可以写入数据库。--master-data作用:

基于事务引擎:不用锁表就可以获得一致性的备份.

99% 使用innodb事务引擎.ACID四大特性中的隔离性

--single-transaction

2)适合多引擎混合(例如:myisam与innodb混合)企业生产备份命令

mysqldump -A -B --master-data=2 |gzip >/opt/alL_$(date +%F).sql.gz

提示:这个备份的优势会锁表,备份期间影响数据写入,使用--master-data会自动开启-x锁表参数。

说明:如果数据库有特殊功能,例如:存储过程和函数数据就加上-R,如果有触发器数据就加上--triggers,如果考虑切割binlog日志也可以加-F,如果不想备份所有库,也可以取消-A,指定多个库名备份。

 

 

[root@db01 ~]# mysqldump --master-data=2 -B -x oldboy>/opt/oldboy.sql

[root@db01 ~]# mysqldump --master-data=2 -B -x oldboy|gzip>/opt/oldboy.sql.gz

[root@db01 ~]# ls -l /opt/

total 656

-rw-r--r--  1 root root   2051 Mar 17 14:44 bak.sql

-rw-r--r--  1 root root   2204 Mar 17 16:36 oldboy.sql

-rw-r--r--  1 root root    869 Mar 17 16:36 oldboy.sql.gz

drwxr-xr-x. 2 root root   4096 Mar 26  2015 rh

1.8.1 --master-data={1|2} 告诉你备份后时刻的binlog位置

2 注释

1 非注释,要执行(主从复制)

[root@db02 logs]# sed -n \'22p\' /opt/t.sql

-- CHANGE MASTER TO MASTER_LOG_FILE=\'oldboy-bin.000005\', MASTER_LOG_POS=344;

 

[root@db02 logs]# mysqldump  -B --master-data=2 oldboy >/opt/t.sql

1.8.2 解压:

zcat t.sql.gz >t1.sql

gzip -d t.sql.gz  #删压缩包

[root@db02 ~]# zcat /opt/oldboy.sql.gz

-- MySQL dump 10.13  Distrib 5.6.34, for Linux (x86_64)

--

-- Host: localhost    Database: oldboy

-- ------------------------------------------------------

-- Server version  5.6.34-log

 

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;

/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;

/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;

/*!40101 SET NAMES utf8 */;

/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;

/*!40103 SET TIME_ZONE=\'+00:00\' */;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;

/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;

/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=\'NO_AUTO_VALUE_ON_ZERO\' */;

/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

 

--

-- Position to start replication or point-in-time recovery from

--

 

CHANGE MASTER TO MASTER_LOG_FILE=\'mysql-bin.000004\', MASTER_LOG_POS=120;

表示从mysql-bin.000004的 MASTER_LOG_POS=120;开始切割binlog

查看binlog文件

[root@db02 ~]# mysqlbinlog /data/3306/binlog/mysql-bin.000004   

第2章 MySQL数据库恢复

2.1 使用gzip压缩备份数据库实践

指定压缩命令gzip压缩备份MySQL数据

[root@db01 ~]# mysqldump -S /data/3306/mysql.sock -B mysql|gzip >/opt/mysql_gzip_B.sql.gz

[root@db01 ~]# mysqldump -S /data/3306/mysql.sock -B mysql >/opt/mysql_gzip_B.sql

[root@db01 ~]# ll /opt/

总用量 1628

-rw-r--r--  1 root root 650671 3月  16 16:16 3306.sql

-rw-r--r--  1 root root 178497 3月  22 10:37 3306.sql.gz

-rw-r--r--  1 root root 650391 3月  22 11:19 mysql_gzip_B.sql   #没有压缩的备份数据

-rw-r--r--  1 root root 178358 3月  22 11:19 mysql_gzip_B.sql.gz #压缩过的数据备份

drwxr-xr-x. 2 root root   4096 3月  26 2015 rh

提示:同样的数据从没有备份的650391字节,到压缩备份的178358字节,缩小了很多。

2.2 针对压缩的备份数据恢复说明

方法1:使用gzip解压(会删除压缩文件)

[root@db01 ~]# gzip -d /opt/mysql_gzip_B.sql.gz

[root@db01 ~]# mysql -S /data/3306/mysql.sock </opt/mysql_gzip_B.sql

方法2:使用gzip解压(但不会删除压缩文件)

[root@db01 ~]# !mysqldump ##使用此方法会调出最近一次备份的命令

mysqldump -S /data/3306/mysql.sock -B --master-data=2 --single-transaction mysql|gzip >/mnt/mysql.sql.gz

[root@db01 ~]# gzip -cd /mnt/mysql.sql.gz >/mnt/mysql1.sql ##特殊解压方法

[root@db01 ~]# ll /mnt/

总用量 812

-rw-r--r-- 1 root root 650721 3月  22 23:20 mysql1.sql

-rw-r--r-- 1 root root 178465 3月  22 23:18 mysql.sql.gz

[root@db01 ~]# mysql -S /data/3306/mysql.sock </mnt/mysql1.sql

方法3:使用gunzip解压(不会删除压缩包)

[root@db01 ~]# gunzip -cd /mnt/mysql.sql.gz >/mnt/mysql2.sql

[root@db01 ~]# ll /mnt/mysql2.sql

-rw-r--r-- 1 root root 650721 3月  22 23:23 /mnt/mysql2.sql

[root@db01 ~]# mysql -S /data/3306/mysql.sock </mnt/mysql1.sql

或者

gunzip </mnt/mysql.sql.gz |mysql -S /data/3306/mysql.sock

方法4:使用zcat读取压缩包数据

[root@db01 ~]# zcat /mnt/mysql.sql.gz >/mnt/mysql3.sql

[root@db01 ~]# mysql -S /data/3306/mysql.sock </mnt/mysql1.sql

2.3 恢复数据库实践

2.3.1 数据库恢复基本事项

1、数据恢复和字符集关联很大,如果字符集不正确会导致恢复的数据乱码。

2、mysql命令以及source命令恢复数据库原理就是把文件的SQL语句,在数据库里重新执行的过程。

2.3.2 利用source命令恢复数据库

mysql 登录用它

innodb引擎

准备环境

mysqldump -B -R --triggers --master-data=2 oldboy|gzip >/opt/alL_$(date +%F).sql.gz

[root@db02 opt]# mysql -e "drop database oldboy;"

[root@db02 opt]# mysql -e "show databases;;"

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| oldgirl            |

| performance_schema |

+--------------------+

[root@db02 opt]# mysql </opt/alL_2017-06-22.sql

[root@db02 opt]# mysql -e "show databases;;"

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| oldboy             |

| oldgirl            |

| performance_schema |

+--------------------+

1、登录数据库

mysql -S /data/3306/mysql.sock

2、选择想要恢复的数据库

mysql> use mysql

3、使用source命令恢复数据(source 备份文件所在路径)

mysql> source /mnt/mysql1.sql

 

2.3.3 利用mysql命令恢复数据

mysql -S /data/3306/mysql.sock </mnt/mysql1.sql

不加-B的恶果。

create database oldboy;

mysql oldboy </opt/alL_2017-06-22.sql

 

2.3.4 利用文本插入数据

假定开发人员让我们插入数据到数据库(可能是邮件发给我们的,内容可能是字符串)
或者下面的文件
sql文件里面没有use db这样的字样时,在导入时就要指定数据库名了

[root@db01 opt]# cat /opt/new.sql

set names utf8;

use management

insert into test(name) values(\'小陶\');

环境创建

mysql> create database oldboy;

Query OK, 1 row affected (0.01 sec)

 

mysql> use oldboy

Database changed

mysql> CREATE TABLE test (

    -> id int(4) NOT NULL AUTO_INCREMENT,

    -> name char(20) NOT NULL,

    -> PRIMARY KEY (id)

    -> ) ;

Query OK, 0 rows affected (0.10 sec)

[root@db01 ~]# cat /mnt/new.aql

set names utf8;

use oldboy

insert into test(name) values(\'小陶\');

[root@db01 ~]# mysql -S /data/3306/mysql.sock </mnt/new.aql

[root@db01 ~]# mysql -S /data/3306/mysql.sock -e "select * from oldboy.test;"

+----+--------+

| id | name   |

+----+--------+

|  1 | 小陶   |

+----+--------+

 

提示:如果UTF8数据库,人工编辑的SQL文件,格式建议为“UTF8没有签名”格式

2.4 利用mysql -e参数查看mysql数据

mysql命令提供了一个功能,可以让使用者无需登录数据库,在Linux命令行就可以执行SQL语句。

[root@db01 ~]# mysql -S /data/3306/mysql.sock -e "select * from oldboy.test;"

+----+--------+

| id | name   |

+----+--------+

|  1 | 小陶   |

+----+--------+

 

2.5 利用mysql -e查看系统运行状态

[root@db01 ~]# mysql -S /data/3306/mysql.sock -e "show global status"|head -5

Variable_name   Value

Aborted_clients 0

Aborted_connects   5

Binlog_cache_disk_use  0

Binlog_cache_use   1

[root@db02 ~]# mysql -e "show global status like \'%uptime%\';"

+---------------------------+-------+

| Variable_name             | Value |

+---------------------------+-------+

| Uptime                    | 567   |

| Uptime_since_flush_status | 567   |

+---------------------------+-------+

 

2.6 利用mysql -e参数不重启数据库修改数据库参数

不重启数据库修改数据库参数还能生效

[root@db01 opt]# mysql -e "show variables;"|grep key_buffer

key_buffer_size  8388608

 

[root@db01 opt]# mysql -e "set global key_buffer_size = 1024*1024*16;"

[root@db01 opt]# mysql -e "show variables;"|grep key_buffer

key_buffer_size  16777216

不重启数据库更改数据库参数小结:

1、set global key_buffer_size = 1024*1024*16;    #及时生效,重启mysql失效。

2、配置文件也要增加或修改,编辑/etc/my.cnf,修改key_buffer_size = 16M

 

2.7 mysql常用命令小结

show processlist;      #查看数据库里正在执行的SQL语句,可能无法看全完整SQL语句。

show full processlist;  #查看正在执行的完整SQL语句,完整显示。

set global key_buffer_size = 1024*1024*16;  #不重启数据库调整数据库参数,直接生效,重启失效。

show variables;       #查看数据库的配置参数信息,例如:my.cnf里参数的生效情况。

show variables like \'%log_bin%\';

kill ID              #杀掉SQL线程命令,ID为线程号。

show session status;    #查看当前会话的数据库状态信息。

show global status;     #查看整个数据库运行状态信息,很重要,要分析并做好监控。

show engine innodb status;   #显示innodb引擎的性能状态(早期版本 show innodb status)

计算一天之内;MySQL数据库有多个insert,delete语句有没有好方法?

1、定时任务每天0点,show global status;按天取出对比

[root@db02 ~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock -e \'show global status;\'|egrep \'Com_insert|Com_delete\'

Com_delete  0

Com_delete_multi   0

Com_insert  12

Com_insert_select  0

2、按天分析binlog日志,获取数据库不同语句的频率

 

2.8 mysqladmin命令相关

mysqladmin password oldboy123               #设密码

mysqladmin -uroot -poldboy123 password oldboy  #修改密码

mysqladmin -uroot -poldboy123 status           #查看状态,相当于show status

mysqladmin -uroot -poldboy123 -i 1 status        #每秒查看一次状态

mysqladmin -uroot -poldboy123 extended-status   #等同show global status

mysqladmin -uroot -poldboy123 flush-logs        #切割日志

mysqladmin -uroot -poldboy123 processlist       #查看执行的SQL语句信息

mysqladmin -uroot -poldboy123 processlist -i 1    #每秒查看一次执行的SQL语句

mysqladmin -uroot -p\'oldboy\' shutdown          #关闭mysql服务

mysqladmin -uroot -p\'oldboy\' variables           #相当于show variables

修改密码

[root@db02 ~]# mysqladmin -uroot -poldboy1234 password oldboy123 -S /data/3306/mysql.sock

[root@db02 ~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock

2.9 mysql命令常用参数总结

mysql命令常用参数

说明

-u

指定数据库用户

-p

指定数据库密码

-S

指定数据库socket文件

-h

指定数据库主机,默认localhost

-P

指定数据库端口,默认3306

-e

不登录数据库执行数据库命令

更多命令信息,可执行mysql --help查看

 

2.10 企业案例:mysql sleep线程过多的问题案例

mysql> show processlist;               

+----+------+-----------+------+---------+------+-------+------------------+

| Id | User | Host      | db   | Command | Time | State | Info             |

+----+------+-----------+------+---------+------+-------+------------------+

| 89 | root | localhost | NULL | Query   |    0 | NULL  | show processlist |

+----+------+-----------+------+---------+------+-------+------------------+

1 row in set (0.00 sec)

mysql> kill 89;

慢查询堵了数据库,mysql> kill 89; 89IDkillinsert,update)可能要丢数据。

 

解决办法:

mysql> show variables like \'%_timeout%\';

+----------------------------+----------+

| Variable_name              | Value    |

+----------------------------+----------+

| connect_timeout            | 10       |

| interactive_timeout        | 28800    |

| wait_timeout               | 28800    |

+----------------------------+----------+

10 rows in set (0.00 sec)

set global wait_timeout = 60;

set global interactive_timeout = 60;

mysql> show global variables like \'interactive_timeout\';

+---------------------+-------+

| Variable_name       | Value |

+---------------------+-------+

| interactive_timeout | 60    |

+---------------------+-------+

1 row in set (0.00 sec)

mysql> show global variables like \'wait_timeout\';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| wait_timeout  | 60    |

+---------------+-------+

1 row in set (0.00 sec)

企业案例:mysql sleep线程过多的问题案例。

1、配置文件里修改:

[mysqld]

interactive_timeout = 120 此参数设置后wait_timeout自动生效。

wait_timeout = 120

2、其他方法:

1.PHP程序中,不使用持久链接,即使用mysql_connect而不是pconnect(JAVA调整连接池)。

2.PHP程序执行完毕,应该显式调用mysql_close。

3.逐步分析MySQL的SQL查询及慢查询日志,找到查询过慢的SQL,优化之。

http://www.cnblogs.com/pedro/p/4627239.html  

2.11 mysqlbinlog增量恢复工具

mysqlbinlog工具的作用是解析mysql的二进制binlog日志内容,把二进制日志解析成可以在MySQL数据库里执行的SQL语句。

 

2.11.1 MySQL的binlog日志是什么?

mysql数据目录下的如下文件就是mysql的binlog日志

[root@db01 ~]# ll /data/3306|grep mysql-bin*

-rw-rw---- 1 mysql mysql 651797 3月  22 11:50 mysql-bin.000001

-rw-rw---- 1 mysql mysql   1306 3月  22 23:53 mysql-bin.000002

提示:必须要打开log_bin才能生成上述文件。

 

2.11.2 解析指定库的binlog日志

利用mysqlbinlog -d参数解析指定库的binlog日志

[root@db01 3306]# mysqlbinlog -S /data/3306/mysql.sock -d mysql mysql-bin.000002 -r bin.sql  #-d指定库,-r指定生成的文件

[root@db01 3306]# grep -i insert bin.sql  #过滤内容,看到了曾经恢复的SQL语句

结论:mysqlbinlog可以指定-d实现分库导出binlog,如果使用-d参数,那更新数据时,必须要有use库名,才能分出指定库的binlog,例如,写入数据库的语句必须是下述写法:

use oldboy;

insert into test values(1,\'oldboy\')

下面的这种写法就不行:

inster into oldboy.test values(2,\'oldgirl\')

 

分库备份:

mysqlbinlog -S /data/3306/mysql.sock -d kkk mysql-bin.000002 -r a.sql

 

分表备份:

mysqlbinlog -S /data/3306/mysql.sock -d kkk mysql-bin.000002|grep -w test >b.sql

 

2.11.3 mysqlbinlog常用参数说明

mysqlbinlog命令常用参数

参数说明

-d, --database=name

根据指定库拆分binlog(拆分单表binlog可通过SQL关键字过滤)

-r, --result-file=name

指定解析binlog输出SQL语句的文件

-R, --read-from-remote-server

从MySQL服务器读取binlog日志,是下面参数的别名。read-from-remote-master=BINLOG-DUMP-DTDS

-j, --start-position=#

读取binlog的起始位置点,#号是具体的位置点

--stop-postion=#

读取binlog的停止位置点,#号是具体的位置点

--base64-output=decode-rows

解析ROW级别binlog日志的方法,例如:mysqlbinlog --base64-output=decode-rows -v mysql-bin.000016

--start-datetime=name

读取binlog的起始位置点。name是具体的时间格式2017-06-22 11:25:56

--stop-datetime=name

读取binlog的停止位置点。name是具体的时间格式2017-06-22 11:25:56

 

2.11.4 按照位置截取binlog内容

1)按照位置截取binlog内容的优点是精确,但是要花费时间寻找位置,例如:

a.截取指定起始点

mysqlbinlog oldboy-bin.000009 --start-position=8826 --stop-position=8975 -r pos.sql

b.指定开始位置,不指定结束位置,不指定的话默认到结束

mysqlbinlog oldboy-bin.000009 --start-position=8826 -r pos.sql

c.指定结束位置,不指定开始,默认找最初

mysqlbinlog oldboy-bin.000009 --stop-position=8975 -r pos.sql

2)按照时间截取binlog内容

mysqlbinlog mysql-bin.000020 --start-datetime=\'2014-10-16 17:14:15\' --stop-datetime=\'2014-10-16 17:15:15\' -r time.sql

具体规则同上

提示:所谓的时间点就是mysqlbinlog解析文件里的不同行行首的“#170323 1:07”标识的数据

第3章 老男孩增量恢复项目实践:

 

备份最牛逼的层次,永远都用不上备份。

 

什么时候会使用备份的数据?

1、恢复数据到测试库的时候。

2、人为通过SQL语句将数据删除的时候。*****

3、做主从复制的时候。

其它场景都不要使用备份恢复,而是直接使用主从复制功能,将业务切换到从库。

 

企业案例:人为删除了数据库,怎么恢复?

 

1、具备什么条件才能恢复数据库?

   a.全量备份(mysqldump)

   b.全量备份以后的所有binlog增量日志。

 

  

   增量恢复企业案例:

条件:

1.具备全量备份(mysqldump)。

2.除全量备份以外,还有全量备份之后产生的的所有binlog增量日志。

drop database oldboy;

CREATE DATABASE oldboy;

USE `oldboy`;

CREATE TABLE `test` (

  `id` int(4) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

INSERT INTO `test` VALUES (1,\'oldboy\'),(2,\'oldgirl\'),(3,\'inca\'),(4,\'zuma\'),(5,\'kaka\');

==================================================================

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  1 | oldboy  |

|  2 | oldgirl |

|  3 | inca    |

|  4 | zuma    |

|  5 | kaka    |

+----+---------+

5 rows in set (0.01 sec)

==================================================================

1、准备环境:

mkdir /data/backup -p

date -s "2017/06/22"

 

mysqldump -B --master-data=2 --single-transaction oldboy|gzip>/data/backup/oldboy_$(date +%F).sql.gz

 

mysql -e "use oldboy;insert into test values(6,\'bingbing\');"

mysql -e "use oldboy;insert into test values(7,\'xiaoting\');"

mysql -e "select * from oldboy.test;"

 

 

2、模拟误删数据:

date -s "2017/06/22 11:40"

mysql  -e "drop database oldboy;show databases;"

 

出现问题10分钟后,发现问题,删除了数据库了.

 

 

3、开始恢复准备

采用iptables防火墙屏蔽所有应用程序的写入。

[root@oldboy ~]# iptables -I INPUT -p tcp --dport 3306 ! -s 172.16.1.51 -j DROP #<==非172.16.1.51禁止访问数据库3306端口。

 

cp -a /application/mysql/logs/oldboy-bin.* /data/backup/

 

zcat oldboy_2017-06-22.sql.gz >oldboy_2017-06-22.sql

sed -n \'22p\' oldboy_2017-06-22.sql

mysqlbinlog -d oldboy --start-position=339 oldboy-bin.000008 -r bin.sql

 

需要恢复:

1.oldboy_2017-06-22.sql

2.bin.sql

grep -i drop bin.sql

sed -i \'/^drop.*/d\' bin.sql

 

 

4、开始恢复全备。

[root@db02 backup]# mysql <oldboy_2017-06-22.sql

[root@db02 backup]# mysql -e "show databases;"

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| oldboy             |

| oldgirl            |

| performance_schema |

+--------------------+

 

[root@db02 backup]# mysql -e "use oldboy;select * from test;"

+----+---------+

| id | name    |

+----+---------+

|  1 | oldboy  |

|  2 | oldgirl |

|  3 | inca    |

|  4 | zuma    |

|  5 | kaka    |

+----+---------+

 

 

5、开始恢复增量

[root@db02 backup]# mysql oldboy <bin.sql

[root@db02 backup]# mysql -e "use oldboy;select * from test;"

+----+----------+

| id | name     |

+----+----------+

|  1 | oldboy   |

|  2 | oldgirl  |

|  3 | inca     |

|  4 | zuma     |

|  5 | kaka     |

|  6 | bingbing |

|  7 | xiaoting |

+----+----------+

恢复完毕。

调整iptables允许用户访问.