mysql


一、数据库种类及关系型数据库原理2

1.1数据库种类:2

1.2非关系型数据库种类3

1.3非关系型数据库产品介绍4

二、mysql介绍及安装5

2.1 mysql数据库优势6

2.2 mysql三条产品线:6

2.3 mysql选择建议6

2.4 mysql5.1/5.5编译安装7

三、mysql应用管理9

3.1 mysql启动与关闭原理9

3.2登陆mysql9

3.3修改mysql密码10

3.4找回丢失的mysql密码11

3.5 SQL语言11

3.6数据库字符集12

3.7显示-连接-删除等数据库的管理13

3.8 mysql建表语句及表结构15

3.9 mysql索引16

3.10 DML语句之insert19

3.11 DQL之select20

3.12 DQL之select多表连表查询21

3.13 DML之update24

3.14 DML之alter24

四、mysql字符集25

4.1 数据库字符集介绍25

4.2 mysql数据库常见字符集介绍25

4.3 如何选择合适的字符集?25

4.4 mysql插入中文数据不乱码深度剖析26

4.5 数据字符集修改案例28

五、mysql备份/增量备份29

5.1 备份单个数据库29

5.2 mysqldump逻辑备份工作原理30

5.3 备份多个库30

5.4 多表备份30

5.5 只备份表结构及数据31

5.6 myisam与innodb引擎备份32

5.7 source恢复mysql数据32

5.8 分库备份后mysql分库恢复33

六、mysql进程状态binlog33

6.1 mysql进程状态33

6.2 mysqlbinlog33

6.3 mydqldump(--master-data)35

七、mysql主从复制35

7.1 mysql主从复制介绍35

7.2 mysql主从同步原理36

7.3 mysql主从同步部署36

7.4 mysql主从同步配置步骤39

7.5 mysql主从故障及主从延迟解决方案39

7.6 mysql主从常见故障41

7.7 mysql主从复制线程状态42

7.8 mysql主从读写分离授权方案43

7.9 mysql双主方案45

八、mysql服务多种日志47

8.1 mysql三种常见日志类型47

8.2 binlog日志的三种模式47

8.3 调整binlog日志模式方法48

九、mysql存储引擎48

9.1什么是存储引擎48

9.2 mysql事务以及ACID特性48

9.3 MyISAM引擎特点及调优49

9.4 InnoDB引擎特点及调优50

9.5修改mysql引擎51

十、mysql优化52

10.1 mysql负载高情况查看52

10.2 mysql优化思路52

10.3 mysql数据库优化52





一、数据库种类及关系型数据库原理

1.1数据库种类:

按照早期的数据库理论,比较流行的数据库模型有三种:

层次式数据库

网络式数据库

关系型数据库


在当今互联网中,最常用的数据库模型:

关系型数据库

非关系型数据库


关系型数据库使用类似于excel表格来表示

关系型数据库使用结构化查询语言SQL语句来对数据进行存取

代表作品,mysql oracle


随着互联网web2.0网站的兴起,传统的关系型数据库在应付web2.0网站,特别是对于规模日益扩大的海量数据,超大规模和高并发的微博、微信、SNS类型的web2.0纯动态网络瓶颈都难以有效突破,于是开始出现了大批针对特定场景,以高性能和使用便利为目的的功能特异化的数据库产品,NoSQL(非关系型)类的数据库就是在这样的情境中诞生并得到了非常迅速的发展。


【动态请求越来越多,对数据库的要求越来越高,传统的数据库遵循SAD理论(保持数据一致性,存放磁盘等)存取数据很慢,在这种情况下,非关系型数据库就诞生了】

NoSQL:

Google的BigTable

Amazon的Dynamo

成功的商业NoSQL


开源NoSQL:

Facebook的Cassandra

Apache的HBase

Redis,mongodb


1.2非关系型数据库种类

(1)键值(Key-Value)存储数据库

键值数据库就类似传统语言中使用的哈希表。可以通过key来添加、查询或者删除数据,因为使用key主键访问,所以会获得很高的性能及扩展性。

键值(Key-Value)数据库主要是使用一个哈希表,这个表中有一个特定的键和一个特向指定的数据。Key/Value模型对于IT系统来说的有时在于简单、易部署、高并发。

典型产品:Memcached、Redis、MemcacheDB、Berkeley DB


(2)列存储(Column-oriented)数据库

列存储数据库将数据存储在列族(column family)中,一个列族存储经常被一起查询的相关数据。举个例子,如果我们有一个Person类,我们通常会一起查询他们的姓名和年龄而不是薪资。这种情况下,姓名和年龄就会被放入一个列族中,而薪资则在另一个列族中。

这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是有列家族来安排的。

典型产品:Cassandra,HBase


(3)面向文档(Document-Oriented)数据库

文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。

面向文档数据库会将数据以文档的形式存储。每个文档都是自包含的数据单元,是一系列数据项的集合。每个数据项都有一个名称与对应的值,值既可以是简单的数据类型,如字符串、数字和日期等;也可以使复杂的类型,如有序列表和关联对象。数据存储的最小单位是文档,同一个表中存储的文档属性可以是不通的,数据可以使用XML、JSON或者JSONB等多种形式存储。

典型产品:MogoDB、CouchDB


(4)图形(Graph)数据库

图形数据库允许我们将数据库以图的方式存储。实体会被作为顶点,而实体之间的关系则会被作为边。比如我们有三个实体,Steve Jobs、Apple和Next,则会有两个"Founded by"的边将Apple和Next连接到Steve Jobs.

图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要指定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。

典型产品:Neo4J、InfoGrid


1.3非关系型数据库产品介绍


(1)Memcached(key-value)

  Memcached是一个开源的、高性能的、具有分布式内存对象的缓存系统。通过它可以减轻数据库负载,加速动态Web应用,最初版本由LiveJournal的Brad Fitzpatrick在2003年开发完成。目前全球有非常多的用户都在使用它来构建自己的大负载网站或提高自己的高访问网站的响应速度。

注意:Memcache是这个项目的名称,而Memcached是服务器端的主程序文件名。


(2)redis(key-value)

  和Memcached类似,redis也是一个key-value型存储系统。但redis支持的存储value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)等。这些数据类型都支持push/pop、add/remove及取交集、并集、差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不方式的排序。与memcached一样,为了保证效率,redis的数据都是缓存在内存中。区别是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且再此基础上实现了master-slave(主从)同步。

  Redis是一个高性能的key-value数据库。redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。

官网:http://www.redis.io/documemtation


redis特点:

1.支持内存缓存,这个功能相当于memcached

2.支持持久化,这个功能相当于memcachedb,ttserver

3.数据类型更丰富。比其他key-value库功能更强

4.支持集群,分布式

5.支持队列等特殊功能



(3)MongoDB(Document-oriented)

  MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,累似json的bjson格式,因此可以存储比较复杂的数据类型。Mogodb最大的特点是他支持的查询语言非常强大,它的语法有点类似于面向对象的查询语言,几乎可以实现关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。它的特点是高性能、易部署、易使用,存储数据非常方便。

  主要功能特性:

1.面向集合存储,易存储对象类型的数据

2.模式自由

3.支持动态查询

4.支持完全索引, 包含内部对象

5.支持查询

6.支持复制和故障恢复

7.使用高效的二进制数据存储,包括大型对象(如视频等)

8.自动处理碎片,以支持云计算层次的扩展性

9.支持ruby,python,java,c++,php等多种语言

10.文件存储格式为bson(一种json的扩展)

11.可通过网络访问

默认端口27017

http://www.mongodb.org/display/DOCS/Manual

http://www.mongodb.org/display/DOCS/Home


(4)Cassandra(Column-oriented)

  Apache Cassandra是一套开源分布式Key-Value存储系统。它最初由Facebook开发,用于存储特别大的数据。Facebook目前在使用此系统。

主要特性:

分布式

基于column的结构化

高伸展性

  Cassandra的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对Cassandra的一个写操作,会被复制到其他节点上去,对Cassandra的读操作,也会被路由到某个节点上面去读取。对于一个Cassandra群集来说,扩展性能是比较简单的事情,只管在集群里面添加节点就可以了。


其他不常用非关系型数据库

HBase,MemcacheDB,Berkeley DB,Tokyo Cabinet\Tokyo Tyrant(ttserver)


二、mysql介绍及安装

2.1 mysql数据库优势

(1)mysql性能卓越,服务稳定,很少出现宕机

(2)mysql开放源代码且无版权制约,自主性及使用成本低

(3)mysql历史悠久,社区及用户非常活跃,遇到问题,可以寻求帮助

(4)pmysql软件体积小,安装使用简单,并且易于维护,安装及维护成本低

(5)mysql口碑效应,使得企业无需考虑就直接用之,LAMP,LEMP流行架构

(6)mysql支持多重操作系统,提供多重API接口,支持多重开发语言,特别对流行的PHP语言有很好的支持


2.2 mysql三条产品线:

第一条产品线:5.0.xx及升级到5.1.xx的产品系列  

这条产品线继续完善与改进其用户体验和性能,同时增加新功能,这条路线可以说是mysql早起产品的延续系列,这一些列的产品发布情况及历史版本如下:

  mysql5.1是当前稳定(产品质量)发布系列。只针对漏洞修复重新发布;没有增加会影响稳定性的功能。

  mysql5.0是前一稳定(产品质量)发布系列。只针对严重漏洞修复和安全修复重新发布;没有增加会影响该系列的重要功能。

  mysql4.0和3.23是旧的稳定(产品质量)发布系列。该版本不再使用,新的发布只用来修复特别严重的漏洞(以前的安全问题)。


第二条产品线:5.4.xx-5.7.xx

  为了更好的整合mysql AB公司社区和第三方公司开发的新存储引擎,以及吸收新的实现算法等,从而更好的支持SMP架构,提高性能而做了大量的代码重构。版本号为从5.4.xx开始,目前发展到了5.6.x

主流:互联网公司用mysql5.5


第三条产品线:6.0.xx-7.1.xx

  为了更好的推广mysql Cluster版本,以及提高mysql Cluster的性能和稳定性,以及功能改进和增加,以及改动mysql基础功能,使其对Cluster存储引擎提供更有效地支持与优化。版本号为6.0.xx开发,目前发展到7.1.xx



2.3 mysql选择建议

(1)稳定版:选择开源的社区版的稳定版GA版本

(2)产品线:可以选择5.1或5.5。互联网公司主流5.5,其次是5.1和5.6。

(3)选择mysql数据库GA发布后6个月以上的GA版本。

(4)要选择前后几个月没有大的BUG修复的版本,而不是大量修复BUG的集中版本。

(5)最好向后较长时间没有更新发布的版本。

(6)要考虑开发人员开发程序使用的版本是否兼容你选的版本。

(7)作为内部开发测试数据库环境,跑大概3-6个月时间。

(8)优先企业非核心业务采用新版本的数据库GA版本软件

(9)向DBA高手请教,或者在及技术氛围好的群里和大家一起交流,使用真正的高手们用过的好用的GA版本产品。

(10)经过上述工序后,若是没有重要的功能BUG或性能瓶颈,则可以开始考虑作为任何业务数据服务的后端数据库软件。


2.4 mysql5.1/5.5编译安装

Yum install ncurses-devel –y

useradd mysql -s /sbin/nologin -M

################使用configure编译mysql5.1################

./configure 

--prefix=/application/mysql5.1.72 \ 

--with-unix-socket-path=/application/mysql5.1.72/tmp/mysql.sock \

--localstatedir=/application/mysql5.1.72/data \

--enable-assembler \

--enable-thread-safe-client \

--with-mysqld-user=mysql \

--with-big-tables \

--without-debug \

--with-pthread \

--enable-assembler \

--with-extra-charsets=complex \

--with-readline \

--with-ssl \

--with-embedded-server \

--enable-local-infile \

--with-plugins=partition,innobase \

--with-mysqld-ldflags=-all-static \

--with-client-ldflags=-all-static

make

make install


################使用cmake编译mysql5.5################

tar xf mysql-5.5.32.tar.gz

cd mysql-5.5.32

cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.5.32 \

-DMYSQL_DATADIR=/application/mysql-5.5.32/data \

-DMYSQL_UNIX_ADDR=/application/mysql-5.5.32/tmp/mysql.sock \

-DDEFAULT_CHARSET=utf8 \

-DDEFAULT_COLLATION=utf8_general_ci \

-DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii \

-DENABLED_LOCAL_INFILE=ON \

-DWITH_INNOBASE_STORAGE_ENGINE=1 \

-DWITH_FEDERATED_STORAGE_ENGINE=1 \

-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \

-DWITHOUT_PARTITION_STORAGE_ENGINE=1 \

-DWITH_FAST_MUTEXES=1 \

-DWITH_ZLIB=bundled \

-DENABLED_LOCAL_INFILE=1 \

-DWITH_READLINE=1 \

-DWITH_EMBEDDED_SERVER=1 \

-DWITH_DEBUG=0

make

make install

ln -s /application/mysql-5.5.32/ /application/mysql


5.0-5.1使用configure  5.5-5.6使用cmake



初始化数据库

ln -s /application/mysql5.1.72/ /application/mysql

cp /home/xiaoyi/tools/mysql-5.1.72/support-files/my-small.cnf /etc/my.cnf

echo 'export PATH=/application/mysql/bin:$PATH' >> /etc/profile

source /etc/profile

/application/mysql/bin/mysql_install_db --basedir=/application/mysql --datadir=/application/mysql/data --user=mysql

/bin/cp /home/xiaoyi/tools/mysql-5.1.72/support-files/mysql.server /etc/init.d/mysqld

chmod +x /etc/init.d/mysqld

chown -R mysql.mysql /application/mysql/data/

chmod -R 1777 /tmp/



[root@mysql-master mysql]# /etc/init.d/mysqld start

Starting MySQL. SUCCESS! 

[root@mysql-master mysql]# lsof -i:3306

COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

mysqld  10762 mysql   10u  IPv4  60630      0t0  TCP *:mysql (LISTEN)

[root@mysql-master mysql]#


[root@mysql-master mysql]# mysql

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.1.72 Source distribution


Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.


Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql>




三、mysql应用管理

3.1 mysql启动与关闭原理


单实例mysql启动

/etc/init.d/mysqld start

查看mysql端口

ss -ntulp|grep 3306

查看mysql 进程

ps -ef|grep mysql|grep -v grep


mysql启动原理

(1)/etc/init.d/mysqld是一个shell启动脚本,启动后最终会调用mysqld_safe脚本,最后调用mysqld服务启动mysql

 $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args > /dev/null 2>&1 &


(2)初始化数据库时mysql系统输出给出的启动方法

mysqld_safe --user=mysql


(3)常规方法关闭数据库

/etc/init.d/mysqld stop


(4)强制关闭数据库方法:

killall mysqld

pkill mysqld

killall -9 mysqld


(5)优雅关闭mysql

mysqladmin -uroot -prinimei shutdown

/etc/init.d/mysqld stop

kill -USR2 `cat path/pid`


3.2登陆mysql

(1)mysql

(2)mysql -uroot

(3)mysql -uroot -p

(4)mysql -uroot -p'rinimei'

(5)mysql -uroot -prinimei


history -c 删除所有历史记录

history -d 2 删除第二条历史记录


查看mysql的历史记录

cat /root/.mysql_history 


登陆mysql后

a.登陆后默认提示符为

mysql>

b.为了防止操作失误,可以标记是测试环境,写在配置里永久生效

mysql>prompt \u@test \r:\m:\s->

PROMPT set to '\u@test \r:\m:\s->'


命令行修改mysql提示符(临时生效)

prompt \u@xiaoyi \r:\m:\s->


配置文件修改登陆提示符

my.cnf配置文件中[mysql]模块下添加如下内容(注意不是mysqld),保存后,无需重启mysql,退出当前session,重新登陆即可。如果在my.cnf配置文件中加,可以用\\,避免转义带来的问题。

[mysql]

prompt=\\u@xiaoyi \\r:\\m:\\s->


system可执行系统命令

mysql> system ls /tmp

1  ssh-WeqjZ36124  yum.log


3.3修改mysql密码 

a.修改mysql root密码方法一:命令行外修改法

 

mysqladmin -uroot -p’rinimei’ password ‘ririri’

b.修改mysql root密码法二:sql语句修改法

mysql>update mysql.user set password=password("rinimei") where user='root';

提示:此方法适合密码丢失后通过--skip-grant-tables参数启动数据库后修改密码

警告:

1.必须指定where条件,否则全改

2.必须指定password()函数来更改密码


c.修改管理员root密码法三:

mysql>set password=password('rinmei');

提示:不适合--skip-grant-tables方式修改密码


3.4找回丢失的mysql密码

1)首先停止mysql

/etc/init.d/mysqld stop


2)使用--skip-grant-tables启动mysql,忽略授权登陆验证

mysqld_safe --skip-grant-tables --user=mysql &


3)直接输入mysql进入

mysql


mysql>update mysql.user set password=password("rinimei") where user='root' and host='localhost';

mysql>flush privileges;


4)重启服务再登陆

mysqladmin -uroot -prinimei shutdown

/etc/init.d/mysqld start

mysql -uroot -prinimei


使用二进制包报错需要修改以下:

cp /application/mysql/bin/mysqld_safe

sed -i 's#/usr/local/mysql#/application/mysql#g' /application/mysql/bin/mysqld_safe


3.5 SQL语言

SQL结构化查询语言

 

什么是SQL?

    SQL,英文全称Structured Query Language,结构化查询语言,它是一种对关系数据库中的数据进行定义和操作的语言方法,是大多数关系数据库管理系统所支持的工业标准。


SQL的分类

SQL结构化查询语言包含6个部分:

(1)数据查询语言(DQL):

  DQL(Data Query Language),也称数据检索语句,用以从表中获得数据,确定数据怎样在应用程序给出。关键字SELECT是DQL(也是所有SQL)用得最多的动词,其他DQL常用的保留字有WHERE,ORDER BY,GROUP BY和HAVING。这些DQL保留字常与其他类型的SQL语句一起使用。

mysql>select user,host from mysql.user order by user asc; 升序排列

mysql>select user,host from mysql.user order by user desc; 倒序排列


(2)数据操作语言(DML):

  DML(Data Manipulation Language),其语句包括动词INSERT,UPDATE和DELETE。它们分别用于添加,修改和删除表中的行(数据)。也称为动作查询语言。

mysql>delete from mysql.user where user='rinimei';


(3)事物处理语言(TPL)

  它的语句能确保被DML语句影响的表的所有行及时得以更新。TPL语句包括BEGIN,TRANSACTION,COMMIT和ROLLBACK


(4)数据控制语言(DCL):

DCL全称(Data Control Language),它的语句通过GRANT或REVOKE获得许可,确定单个用户和用户组对数据库对象的访问。某些RDBMS可用GRANT或REVOKE控制对表单个列的访问。


(5)数据定义语言(DDL):

DDL(Data Definition Language),其语句包括动词CREATE和DROP。在数据库中创建新表或删除表(CREATE TABLE或DROP TABLE);为表加入索引等。DDL包括许多人与数据库目录中获得数据有关的保留字。它也是动作查询的一部分。


(6)指针控制语言(CCL):

CCL(Cursor Control Language),它的语句,像DECLARE CURSOR,FETCH INTO和UPDATE WHERE CURRENT用于对一个或多个表单独进行的操作。


小结:SQL语句最常见的分类一般就是3类:

DDL-数据定义语言(CREATE,ALTER,DROP)

DML-数据操作语言(SELECT,INSERT,DELETE,UPDATE)

DCL-数据控制语言(GRANT,REVOKE,COMMIT,ROLLBACK)


3.6数据库字符集

数据库字符集

创建数据库

a.create database xiaoyi_default;(数据库名不能数字开头)


查看建表语句

show create database xiaoyi\G


mysql> show create database xiaoyi\G

*************************** 1. row ***************************

       Database: xiaoyi

Create Database: CREATE DATABASE `xiaoyi` /*!40100 DEFAULT CHARACTER SET latin1 */

1 row in set (0.00 sec)


mysql> show collation;

查看所有collate


b.建立一个名为xiaoyi_gbk的GBK字符集数据库

create database xiaoyi_gbk default character set gbk collate gbk_chinese_ci;

mysql> show create database xiaoyi_gbk\G

*************************** 1. row ***************************

       Database: xiaoyi_gbk

Create Database: CREATE DATABASE `xiaoyi_gbk` /*!40100 DEFAULT CHARACTER SET gbk */

1 row in set (0.00 sec)


c.创建一个名为xiaoyi_utf8的utf8字符集数据库

create database xiaoyi_utf8 character set utf8 collate utf8_general_ci;


小结:创建不同字符集格式的数据库命令(编译时未指定)

create database xiaoyi;  ##默认数据库配置,相当于创建拉丁字符集数据库。

create database olbdoy_gbk default character set gbk collate gbk_chinese_ci; 

##创建gbk字符集数据库

create database olbdoy_utf8 character set utf8 collate utf8_general_ci;

##创建utf8字符集数据库


提示:如果编译的时候指定了特定的字符集,则以后创建对应的数据库就不需要指定字符集了

--DDEFAULT_CHARSET=utf8 \

--DDEFAULT_COLLATION=utf8_general_ci \


数据库要支持创建库的字符集,例如

-DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii \



3.7显示-连接-删除等数据库的管理

显示数据库

show database like '%yi%';


显示当前数据库

select database();


删除数据库

drop database xiaoyi;


连接数据库

use xiaoyi;


查看版本

select version();


查看当前用户

select user();


查看当前时间

select now();


查表

切到数据库里面去查看

show tables;

show tables like 'user'

show tables from xiaoyi_gbk; #查看指定库中的表。

show tables in xiaoyi_gbk;


删除mysql系统多余帐号

语法:drop user "user"@"主机域" #注意引号,可以是单或双引号,但是不能不加

drop user 'root'@'xiaoyi';

drop user ''@'xiaoyi';

drop user ''@'localhost'; #没有的部分就用两个单引号代替即可。


注意:

如果drop删除不了(一般是特殊字符或大写),可以用下面方式删除(以root用户,xiaoyi主机为例)

delete from mysql.user where user='root' and host='xiaoyi';

flush privileges;


创建mysql用户及赋予用户权限

grant all on db1.* to 'user'@'localhost' identified by 'rinimei';


create user 'user'@'localhost' identified by 'rinimei';

grant all on db1.* to 'user'@'localhost';

#以上命令相当于一条


show grants for xiaoyi@'localhost';



授权局域网内主机远程连接数据库

a.百分号匹配法

grant all on *.* to test@'10.0.0.%' identified by 'test123';

b.子网掩码匹配法

grant all on *.* to test@'10.0.0.0/255.255.255.0' identified by 'test123';


1.本地mysql -uroot -prinimei 连接数据库相当于mysql -uroot -prinimei -hlocalhost

2.要连接10.0.0.7的数据库,命令为mysql -utest -prinimei -h10.0.0.7

grant all on *.* to test@'10.0.0.%' identified by 'test123';

提示:上述命令的意思是授权10.0.0.%,匹配这个字符串IP地址的所有主机可以连接数据库。百分号%匹配所有10.0.0.0/24内的主机。

3.通过php服务器连接mysql服务器的代码写法为:

<?php

//$link_id=mysql_connect('主机名',‘用户’,‘密码’);

$link_id=mysql_connect('10.0.0.7','test','test123')or mysql_error();

if($link_id){

echo "mysql successful by xiaoyi!";

}else{

echo mysql_error();

}

?>


mysql用户可以授权的权限有哪些

1.先看看前面授权过的xiaoyi的权限

help revoke

revoke insert on test.* from xiaoyi@'localhost';

show grants for xiaoyi@'localhost';

| GRANT SELECT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `test`.* TO 'xiaoyi'@'localhost' |


在shell界面下执行mysql命令

mysql -uroot -prinimei -e "show grants for xiaoyi@localhost;"



3.8 mysql建表语句及表结构

表操作


(1)以默认字符集创建库

create database xiaoyi;

show create database xiaoyi \G


(2)建立表

建表语句

use xiaoyi

create table student(

id int(4) not null,

name char(20) not null,

age tinyint(2) not null default '0',

dept varchar(16) default null

);


(3)mysql生成的建表语句

mysql> show create table student\G 

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(4) NOT NULL,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


int 数字类型

char 定长字符类型

tinyint 很小的数字类型

varchar 变长字符类型

ENGINE=InnoDB 引擎

CHARSET=latin1 字符集


mysql5.1及以前默认引擎为MyISAM

mysql5.5以后默认引擎为InnoDB


查看表结构以及建表语句

查看建立的表结构

desc student;

show columns from student;


查看已建表的语句

show create table student\G


3.9 mysql索引

索引就像书的目录一样,如果在字段上建立了索引,那么以索引列为查询条件时可以加快查询速度,这是mysql优化的重要内容之一


(1)创建主键索引

查询数据库,按主键查询是最快的,每个表只能有一个主键列,但是可以有多个普通索引列。主键列要求列的所有内容必须唯一,而普通索引列不要求内容必须唯一。


建立主键索引的方法:

①在建表时,可以增加建立主键索引的语句

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)

);

mysql> desc student;

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

| Field | Type        | Null | Key | Default | Extra          |

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

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

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

4 rows in set (0.00 sec)


提示:

1.primary key(id)主键

2.KEY index_name(name)name字段普通索引


②建表后通过alter命令增加主键索引(不这样干)

a.主键列不能重复创建,必须先删除上面配置

alter table student drop primary key;


利用alter命令修改id列为自增主键列

alter table student change id id int primary key auto_increment;


alter table student change id id int(4); 

alter table student drop primary key;


(2)创建普通索引

①在建表时,可以增加简历普通索引的语句

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)

);


②建表后利用alter增加普通索引

删除建表时的index_name索引,

alter table student drop index index_name,

在name列上添加索引,索引名为index_name,

alter table student add index index_name(name);


提示:PRI为主键的标识,MUL为普通索引的标识。


(3)对字段的前n个字符创建普通索引

当遇到表中比较大的列时,列内容的前n个字符在所有内容中已经接近唯一时,这时可以对列的前n个字符简历索引,而无需对整个列建立索引,这样可以节省创建索引占用的系统空间,以及降低读取和更新维护索引消耗的系统资源。


对字段的前n个字符创建普通索引的语法:

create index index_name on student(name(8)); #条件列前n个字符创建索引

操作实践:

在dept系别上,前8个字符创建索引,此列总共长度为16个。


show index from student\G



(4)为表的多个字段创建联合索引

如果查询数据的条件是多列时,我们可以为多个查询的列创建联合索引,甚至,可以为多列的前n个字符列创建联合索引:

create index ind_name_dept on student(name,dept);

show index from student\G



create index ind_name_dept on student(name(8),dept(10))


提示:按条件列查询数据时,联合索引是有前缀生效特性的。

index(a,b,c)仅a,ab,abc三个查询条件列可以走索引。


(5)创建唯一索引(非主键)

create unique index index_name on student(name);


(6)索引列的创建及生效条件

问号1.既然索引可以加快查询速度,那么就给所有的列建索引?

解答:索引不但占用系统空间,更新数据时还需要维护索引数据的,因此,索引是一把双刃剑,并不是越多越好

例如:数十到几百行的小表上无需建立索引,写繁琐,读少的业务要少建立索引。


问号2.到底在哪些列上创建索引呢?

 select user,host from mysql.user where host=  索引一定要创建在where后的条件列,而不是select后的选择数据的列。另外我们要尽量选择在唯一值多的大表上建立索引。


创建索引相关命令集合:

1.创建索引相关命令集合

创建主键索引:

alter table student change id id int primary key auto_increment;

删除主键索引:

alter table student drop primary key;


创建普通索引:

alter table student add index index_dept(dept(8));

(根据列的前n个字符创建索引)

create index index_dept on student(dept(8));

删除普通索引

alter table student drop index index_dept;

drop index index_dept on student;


根据多个列创建联合索引:

create index ind_name_dept on student(name,dept);

(根据多个列的前n个字符创建联合索引)

create index ind_name_dept on student(name(8),dept(10))


创建唯一索引:

create unique index uni_ind_name on student(name);


①要在表的列上创建索引

②索引会加快查询速度,但是会影响更新的速度

③索引不是越多越好,要在频繁查询的where后的条件列上创建索引

④小表或唯一值极少的列上不建立索引,要在大表以及不同内容多的列上创建索引



3.10 DML语句之insert

往表中插入数据

1.新建一个简单的测试表test

create table `test` (

`id` int(4) NOT NULL AUTO_INCREMENT,

`name` char(20) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;


2.往表中插入数据的不同的语法例子:

(1)按规矩指定所有列名,并且每列都插入值

insert into test(id,name) values(1,'xiaoyi');

(2)由于id列为自增的,所以,可以只在name列插入值

insert into test(name) values('girl');

(3)如果不指定列,就要按规矩为每列都插入恰当的值

insert into test values(3,'inca');

(4)批量插入数据方法,提升效率

insert into test values(4,'zuma'),(5,'kaka');

insert into `test` values(1,'xiaoyi'),(2,'girl'),(3,'inca'),(4,'zuma'),(5,'kaka');


删除表中所有数据

delete from test;


(5)测试完毕,退出数据库,然后备份上树数据,留着备用:

mysqldump -uroot -prinimei -B xiaoyi > /opt/xiaoyi_bak.sql

-A备份所有库


(6)备份后检查备份的sql数据内容:过滤无用信息

grep -E -v "#|\/|^$|--" /opt/xiaoyi_bak.sql 


提示:

-A表示所有库,后面不能在指定xiaoyi_gbk库了。

5.1.68版本:

mysqldump -uroot -prinimei -A -B --events > /tmp/xiaoyi_bak.sql


3.11 DQL之select

查询数据

1.查看test中所有数据

a.进入指定库中查询

use xiaoyi

select * from test;


(1)查看表test中的两行数据

select id,name from test limit 2;

select id,name from test limit 0,2;


(2)指定固定条件查询

select id,name from test where id=1;

select id,name from test where name='girl';

提示:字符类型的查询条件要带引号

select id,name from test where id=2 and name='girl';

select id,name from test where id=5 or name='girl';


(3)指定固定条件范围查数据

select id,name from test where id>2 and id<4;


(4)其他查询功能

排序功能

select id,name from test order by id;

select id,name from test order by id asc;

select id,name from test order by id desc;


3.12 DQL之select多表连表查询


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


--学生表:Student(Sno,Sname,Ssex,Sage,Sdept)  


-------- (学号-主键,姓名,性别,年龄,所在系)  


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

drop  tables  student;  

create  table  student(  

Sno  int(10)  NOT  NULL  COMMENT  '学号',  

Sname  varchar(16)  NOT  NULL  COMMENT  '姓名',  

Ssex  char(2)  NOT  NULL  COMMENT  '性别',  

Sage  tinyint(2)    NOT  NULL  default  '0'  COMMENT  '学生年龄',  

Sdept  varchar(16)    default  NULL    COMMENT  '学生所在系别',    

PRIMARY  KEY    (Sno)  ,  

key  index_Sname  (Sname)  

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

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



------课程表:Course(Cno,Cname,Ccredit)  

>------ (课程号-主键,课程名,学分)  

>

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

create  table  course(  

Cno  int(10)  NOT  NULL  COMMENT  '课程号',  

Cname  varchar(64)  NOT  NULL  COMMENT  '课程名',  

Ccredit  tinyint(2)  NOT  NULL  COMMENT  '学分',  

PRIMARY  KEY    (Cno)    

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


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



------选课表:  SC(Sno,Cno,Grade)  


------ (学号-主键,课程号-主键,成绩)  


------其中SC 表主键参照Student,Course 表  


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


CREATE  TABLE  `SC`  (  

      SCid  int(12)  NOT  NULL  auto_increment  COMMENT  '主键',  

    `Cno`  int(10)  NOT  NULL  COMMENT  '课程号',  

    `Sno`  int(10)  NOT  NULL  COMMENT  '学号',  

    `Grade`  tinyint(2)  NOT  NULL  COMMENT  '学生成绩',  

    PRIMARY  KEY    (`SCid`)  

)  ENGINE=InnoDB  DEFAULT  CHARSET=utf8;  



往关联表中填充数据

1.学生表插入数据:

INSERT  INTO  student  values(0001,'宏志','男',30,'计算机网络');  

INSERT  INTO  student  values(0002,'硕硕  ','男',30,'computer  application');  

INSERT  INTO  student  values(0003,'xiaoyi','男',28,'物流管理');  

INSERT  INTO  student  values(0004,'脉动','男',29,'computer  application');  

INSERT  INTO  student  values(0005,'girl','女',26,'计算机科学与技术');  

INSERT  INTO  student  values(0006,'莹莹','女',22,'护士');  


2.课程表插入数据:

INSERT  INTO  course  values(1001,'Linux 中高级运维',3);  

INSERT  INTO  course  values(1002,'Linux 高级架构师',5);  

INSERT  INTO  course  values(1003,'MySQL 高级Dba',4);  

INSERT  INTO  course  values(1004,'Python 运维开发',4);  

INSERT  INTO  course  values(1005,'Java  web 开发',3);  


3.选课表插入数据

INSERT  INTO  SC(Sno,Cno,Grade)    values(0001,1001,4);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0001,1002,3);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0001,1003,1);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0001,1004,6);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0002,1001,3);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0002,1002,2);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0002,1003,2);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0002,1004,8);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0003,1001,4);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0003,1002,4);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0003,1003,2);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0003,1004,8);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0004,1001,1);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0004,1002,1);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0004,1003,2);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0004,1004,3);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0005,1001,5);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0005,1002,3);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0005,1003,2);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0005,1004,9);


mysql> select student.Sno,student.Sname,course.Cname,SC.Grade from student,course,SC where student.Sno=SC.Sno and course.Cno=SC.Cno;

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

| Sno | Sname    | Cname                 | Grade |

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

|   1 | 宏志     | Linux 中高级运维      |     4 |

|   2 | 硕硕     | Linux 中高级运维      |     3 |

|   3 | xiaoyi   | Linux 中高级运维      |     4 |

|   4 | 脉动     | Linux 中高级运维      |     1 |

|   5 | girl     | Linux 中高级运维      |     5 |

|   1 | 宏志     | Linux 高级架构师      |     3 |

|   2 | 硕硕     | Linux 高级架构师      |     2 |

|   3 | xiaoyi   | Linux 高级架构师      |     4 |

|   4 | 脉动     | Linux 高级架构师      |     1 |

|   5 | girl     | Linux 高级架构师      |     3 |

|   1 | 宏志     | MySQL 高级Dba         |     1 |

|   2 | 硕硕     | MySQL 高级Dba         |     2 |

|   3 | xiaoyi   | MySQL 高级Dba         |     2 |

|   4 | 脉动     | MySQL 高级Dba         |     2 |

|   5 | girl     | MySQL 高级Dba         |     2 |

|   1 | 宏志     | Python 运维开发       |     6 |

|   2 | 硕硕     | Python 运维开发       |     8 |

|   3 | xiaoyi   | Python 运维开发       |     8 |

|   4 | 脉动     | Python 运维开发       |     3 |

|   5 | girl     | Python 运维开发       |     9 |

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

20 rows in set (0.00 sec)


mysql>


3.13 DML之update

更改表数据

update test set name=’yige’ where id=3;

mysql> update test set name='yige' where id=3;

Query OK, 1 row affected (0.02 sec)

Rows matched: 1  Changed: 1  Warnings: 0


mysql> select * from test;

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

| id | name   |

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

|  1 | xiaoyi |

|  2 | girl   |

|  3 | yige   |

|  4 | zuma   |

|  5 | kaka   |

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

5 rows in set (0.00 sec)


mysql>


3.14 DML之alter


alias mysql='mysql -U'

#不加where不允许修改表a


删除表中数据

delete from test where id=1;

delete from test where id>3;

提示:不加条件就是全部删除,也是非常危险的操作,delete from test,这里就不演示了


truncate table test;  #执行清空命令


truncate table test;和delete from test;区别

1.truncate table test;更快,清空物理文件

2.delete from test;逻辑清楚,按行删。


增删改表的字段

命令语法:

alter table 表名 add 字段 类型 其他;


alter table test add sex char(4);


alter table test add age char(4) after name;


alter table test add qq varchar(15) first;

 

alter table test add firstphoto_url varchar(255) default null comment ‘第一张土图片’;


修改字段

alter table test change qq msn tinyint;


更改表名


rename法:

rename table test to test1;


alter法:

alter table olbdoy rename to test;


四、mysql字符集

4.1 数据库字符集介绍

  简单的说,字符集就是一套文字符号及其编码、比较规则的集合,第一个计算机字符集ASC2

  mysql数据库字符集包括字符集(CHARACTER)和校对规则(COLLATION)两个概念。其中,字符集是用来定义mysql数据字符串的存储方式。而校对规则则是定义比较字符串的方式。


4.2 mysql数据库常见字符集介绍

  在互联网环境中,使用mysql时常用的字符集有:

GBK2不是国际标准

UTF-83中英文混合的环境,建议使用此字符集

latin11mysql的默认字符集

utf8mb44UTF-8 Unicode


4.3 如何选择合适的字符集?

(1)如果处理各种各样的文字,发布到不同语言国家地区,应选Unicode字符集,对mysql来说就是UTF-8(每个汉字三字节),如果应用需处理英文,仅有少量汉字UTF-8更好。

(2)如果只需支持中文,并且数据量很大,性能要有也很高,可选GBK(定长 每个汉字占双字节,英文也占双字节),如果需大量运算,比较排序等 定长字符集,更快,性能高。

(3)处理移动互联网业务,可能需要使用utf8mb4字符集


4.4 mysql插入中文数据不乱码深度剖析

1.先看下Mysql默认情况下设置的字符集

mysql>show variables like 'character_set%';

不同字符集参数的含义如下:

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

| Variable_name            | Value                                     |

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

| character_set_client     | utf8 #客户端字符集;                       |

| character_set_connection | utf8  #连接字符集;       |

| character_set_database   | latin1#数据库字符集,配置文件指定或建库建表指定|

| character_set_filesystem | binary                                    |

| character_set_results    | utf8  #返回结果字符集;       |

| character_set_server     | latin1#服务器字符集,配置文件指定或建库表指定|

| character_set_system     | utf8                                      |

| character_sets_dir       | /application/mysql-5.5.32/share/charsets/ |

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

更改系统字符集变量后,查看mysql中字符集的变化。

echo $LANG

zh_CN.UTF8

mysql -uroot -prinimei -e "show variables like 'character_set%';"


set names 原理:

character_set_client

character_set_connection

character_set_results


mysql命令参数--default-character-set=latin1在做什么?

mysql -uroot -prinimei --default-character-set=latin1 xiaoyi < test.sql

mysql -uroot -prinimei -e "show variables like'character_set%';"


通过mysql命令加上字符集参数指定latin1字符集导入test.sql语句

mysql -uroot -prinimei -e "set names latin1;select * from xiaoyi.student;"



mysql -uroot -prinimei --default-character-set=latin1


不乱码的思想:建议中英文环境选择utf8

(1)linux系统服务端

cat /etc/sysconfig/i18n

#LANG="zh_CN.GB2312"

LANG="zh_CN.utf8"

提示:linux客户端也要更改字符集


(2)mysql客户端

临时:

set names utf8

永久:

更改my.cnf客户端模块的参数,可以实现set names utf8的效果,并且永久生效。


[client]

default-character-set=latin1

提示:无需重启服务,退出重新登陆就生效。相当于set names latin1;


实际改动:

character_set_client

character_set_connection

character_set_results



(3)mysql服务端

[mysqld]

default-character-set=utf8适合5.1以前版本

character-set-server=utf8适合5.5


实际改动:

character_set_database

character_set_server


(4)mysql数据库中建库建表

create database xiaoyi_utf8 default character set utf8 collate utf8_general_ci;


create table `student` (

`id` int(4) not null auto_increment,

`name` char(20) not null,

primary key(`id`)

) engine=innodb auto_increment=10 default charset=utf8


(5)开发的程序的字符集:


4.5 数据字符集修改案例


对于已有的数据库想修改字符集不能直接通过"alter database character set *"或"alter table tablename character set *",这两个命令都没有更新已有记录的字符集,而只是对新创建的表或者记录生效。


已经有记录的字符的调整,必须先将数据导出,经过修改字符集后重新导入后才可完成。

修改数据库默认编码:

alter database[your db name]charaset[your character setting]


下面模拟将utf8字符集的数据库修改成GBK字符集的实际过程。

(1)导出表结构

mysqldump -uroot -p --default-character-set=latin1 -d dbname > alltable.sql

--default-character-set=gbk 表示以GBK字符集进行连接 -d 只导表结构


(2)编辑alltable.sql将latin1改成GBK


(3)确保数据库不再更新,导出所有数据

mysqldump -uroot -p --quick --no-create-info(-t) --extended-insert --default-character-set=latin1 dbname > alldata.sql


参数说明:

--quick:用于转储大的表,强制mysqldump从服务器一次一行的检索数据而不是检索所有行,并输出前cache到内存中。

--no-create-info:不创建create table语句

--extended-insert:使用包括几个values列表的多行insert语法,这样文件更小,IO也小,导入数据时会非常快。

--default-character-set=latin1#按照原有字符集导出数据,这样导出的文件中,所有中文都是可见的,不会保存成乱码。


(4)打开alldata.sql将set names latin1修改成set names gbk;


(5)建库

create database dbname default charset gbk;


(6)创建表,执行alltable.sql

mysql -uroot -p dbname < alltable.sql


(7)导入数据

mysql -uroot -p dbname < alldata.sql



五、mysql备份/增量备份

5.1 备份单个数据库

语法:mysqldump -u 用户名 -p 数据库名 > 备份的文件名


范例1:备份名字为xiaoyi的库

a.查看备份前的数据

mysql -uroot -prinimei -e "use xiaoyi;show tables;select * from student;"

b.执行备份的命令

mysqldump -uroot -prinimei xiaoyi > /opt/mysql_bak.sql

c.检查备份的结果

egrep -v "#|\*|--|^$" /opt/mysql_bak.sql


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=latin1;

LOCK TABLES `test` WRITE;

INSERT INTO `test` VALUES (1,'xiaoyi'),(2,'girl'),(3,'inca'),(4,'zuma'),(5,'kaka');

UNLOCK TABLES;



范例2:设置字符集参数备份解决乱码问题

a.查看备份前数据库客户端及服务端的字符集设置

mysql -uroot -prinimei -e "show variables like '%character%'"

b.指定对应的字符集备份,这里为--default-character-set=latin1

执行结果:

mysqldump -uroot -prinimei --default-character-set=latin1 xiaoyi > /opt/mysql_bak.sql



范例3:

备份时加-B参数(备份时,添加库的语句和切换库的语句也备份)

mysqldump -uroot -prinimei --default-character-set=latin -B xiaoyi > /opt/mysql_bak_b.sql

mysql -uroot -prinimei < /opt/mysql_bak_b.sql

mysql -uroot -prinimei -e "select * from xiaoyi.student;" 

和前面的备份文件相比,看看-B参数的作用

>CREATE DATABASE /*!32312 IF NOT EXISTS*/ `xiaoyi` /*!40100 DEFAULT CHARACTER SET latin1 */;

>

>USE `xiaoyi`;



范例4:优化备份文件大小减少输出注释

--compact参数说明:

###(测试时用的比较多)也可以优化输出的大小,让内容更少,适合调试。

--compact Give less verbose output (useful for debugging).Disables

 structure comments and header/footer constructs. Enables 

 options --skip-add-drop-table --no-set-names

 --skip-disable-keys --skip-add-locks

参数说明:该选项使得输出内容更简洁,不包括默认选项中各种注释。有如下几个参数的功能。

--skip-add-drop-table  --no-set-names  --skip-disable-keys  --skip-add-locks


范例5:

指定压缩命令压缩备份的mysql数据

mysqldump -uroot -prinimei --default-character-set=latin1 -B xiaoyi|gzip > /opt/mysql_bak_b.sql.gz

效率提高将近3倍


通过以上例子得出什么结论?

a.导出数据用-B参数

b.用gzip对备份的数据压缩


5.2 mysqldump逻辑备份工作原理


mysqldump的工作原理

利用mysqldump命令备份数据的过程,实际上就是把数据从mysql库里以逻辑的sql语句的形式直接输出或者生成备份的文件的过程


5.3 备份多个库

备份多个库及多个参数练习

a.操作结果

mysqldump -uroot -prinimei -B xiaoyi xiaoyi_gbk|gzip > /opt/all_bak.sql.gz

b.-B参数说明

提示:-B参数是关键,表示接多个库,并且增加use db,和create database db的信息

#####(生产环境常用)

mysql -uroot -prinimei -B xiaoyi xiaoyi_gbk|gzip > /opt/mul.sql.gz


5.4 多表备份

备份多个表

    语法:mysqldump -uroot -prinimei 数据库名 表名1 表名2 > 备份的文件名

mysqldump -uroot -prinimei --compact xiaoyi student test > /opt/table.sql


企业需求:一个库里有大表有小表,有时可能需要只恢复某一个小表,上述的多表备份文件很难拆开,就会像没有分库那样导致恢复某一个小表很麻烦。

  那么又如何进行分表备份呢?如下,和分库的思想一样,每执行一条语句备份一个表,生成不同的数据文件即可

mysqldump -uroot -prinimei test > xiaoyi_test.sql

mysqldump -uroot -prinimei test1 > xiaoyi_test1.sql



分表备份缺点:文件多,很碎

1.备一个完整全备,再做一个分库分表备份

2.脚本批量恢复多个SQL文件


5.5 只备份表结构及数据

备份数据库表结构(不包含数据)

利用mysqldump -d参数只备份表的结构,例:备份xiaoyi库的所有表的结构

mysqldump -uroot -prinimei -B -d xiaoyi > /opt/t.sql

egrep -v "#|\*|--|^$" /opt/t.sql


备份数据库数据

mysqldump -uroot -prinimei --compact -t xiaoyi student


备份整个数据库

mysqldump -uroot -prinimei -A -B --events|gzip > /opt/a.sql.gz



-F 切割binlog


mysqldump -uroot -prinimei --master-date=1 --compact xiaoyi

找到binlog位置

mysqldump的关键参数说明

关键参数:mysqldump --help

1.-B指定多个库,增加建库语句和use语句

2.--compact去掉注释,适合调试输出,生产不用

3.-A备份所有库

4.-F刷新binlog日志

5.--master-data增加binlog日志文件名及对应的位置点

6.-x,--lock-all-tables

  Locks all tables across all databases.This is achieved 

by taking a global read lock for the duration of the

whole dump.Automatically turns --single-transaction and 

--lock-tables off

7.-l,--lock-tables Lock all tables for read.

8.-d 只备份表结构

9.-t 只备份数据

10.--single-transaction 适合innodb事物数据库备份

  InnoDB表在备份时,通常启用选项--single-trasaction来保证备份的一致性,实际上它的工作原理是设定本次会话的隔离级别为:REPEATABLE READ,以确保本次会话(dump)时,不会看到其他会话已经提交了的数据。


myisam:

mysqldump -uroot -prinimei -A -B --master-data=2 -x --events|gzip > /opt/all.sql.gz


5.6 myisam与innodb引擎备份

myisam:

mysqldump -uroot -prinimei -A -B --master-data=2 -x --events|gzip > /opt/all.sql.gz


innodb:

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


#for MyISAM

mysqldump --user=root --all-databases --flush-privileges --lock-all-tables \

--master-data=1 --flush-logs --triggers --routines --events \

--hex-blob > $BACKUP_DIR/flush_dump_$BACKUP_TIMESTAMP.sql


#for InnoDB

mysqldump --user=root --all-databases --flush-privileges --single-transaction \

--master-data=1 --flush-logs --triggers --routines --events \

--hex-blob > $BACKUP_DIR/flush_dump_$BACKUP_TIMESTAMP.sql


5.7 source恢复mysql数据

a.利用source命令恢复数据库

mysql>use 数据库

mysql>source xiaoyi_db.sql

b.利用mysql命令恢复数据库

cat test.sql

use xiaoyi

insert into test(name) values("xiaoyi");

mysql -uroot -prinimei < test.sql

mysql -uroot -prinimei -e "select * from xiaoyi.test;"|tail -1


备份库时指定-B,恢复时无需指定库恢复,为什么?

因为-B参数带了use xiaoyi还会有create database xiaoyi;

而恢复时指定库就类似于use xiaoyi;

mysql -uroot -prinimei > insert.sql

否则只能用如下方法

mysql -uroot -prinimei xiaoyi < insert.sql

因此建议备份库时指定-B。


说明:mysql不光可以恢复mysqldump的备份,只要是sql语句,都可以通过Mysql命令执行到数据库中。


5.8 分库备份后mysql分库恢复


通过脚本读指定的库和表,调用mysql命令恢复

gzip -d *

for dbname in `ls *.sql|sed 's#_bak.sql##g'`;

do

mysql -uroot -prinimei < ${dbname}_bak.sql

done


六、mysql进程状态binlog

6.1 mysql进程状态

MyISAM引擎存放索引的缓冲区

/etc/my.cnf

[mysqld]

key_buffer


mysql -uroot -prinimei -e "show variables;" | grep key_buffer

mysql>show variables like 'key_buffer%';

set global key_buffer_size=1024*1024*32;


重启生效方法:

vim /etc/my.cnf

[mysqld]

key_buffer_size = 32K

mysql>set global key_buffer_size=1024*32

mysql>show variables like 'key_buffer%';


小结:

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

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

show processlist; 查看正在执行的sql语句,看不全

show full processlist;查看正在执行的完整sql语句,全

set global key_buffer_size = 32777218 不重启数据库调整数据库参数,直接生效,重启后失效

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


6.2 mysqlbinlog

mysqlbinlog:解析mysqlbinlog日志

mysql的binlog日志是什么?

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

mysql-bin.000001

mysql-bin.000002

mysql的binlog日志作用是什么?

用来记录mysql内部增删改等对mysql数据库有更新的内容的记录。


mysqlbinlog mysql-bin.000020 > all.sql

mysqlbinlog -d xiaoyi mysql-bin.000020 > xiaoyi.sql


基于位置点的增量恢复

1.指定开始位置和结束位置

mysqlbinlog mysql-bin.000021 --start-position=510 --stop-position=1312 -r pos.sql

输出 初始位置510,结束位置1312的所有binlog日志到pos.sql

注意:结尾的日志点比较特殊,不会被包含。即输出1312pos以前的binlog.位置点信息一般要实际存在,不能乱指定。

2.指定开始位置到文件结束

mysqlbinlog mysql-bin.000021 --start-position=510 pos510-end.sql

输出 初始位置510,结束位置到文件结尾的所有binlog到pos510-end.sql,当然,你也可以指定库名输出binlog,如:

mysqlbinlog mysql-bin.000021 --start-position=510 -r pos510-end-xiaoyi.sql -d xiaoyi

-r 重定向 -d 指定库

3.从文件开头到指定位置结束

mysqlbinlog mysql-bin.000021 --stop-position=510 -r start-pos510-xiaoyi.sql -d xiaoyi


基于时间点的增量恢复

1.指定开始时间和结束时间

mysqlbinlog mysql-bin.000021 --start-datetime='2015-03-19 02:58:53' --stop-datetime='2015-03-19 03:22:44' -r time.sql

  上面语句将显示2015-03-19 02:58:54---2015-03-19 03:22:44时间段的binlog,并输出到time.sql


2.指定开始时间到文件结束

mysqlbinlog mysql-bin.000021 --start-datetime='' -d xiaoyi -r time.sql

  这个语句只有开始时间,到日志结尾,xiaoyi数据库的binlog输出到time.sql


3.从文件开头到指定结束时间

mysqlbinlog mysql-bin.000021 --stop-datetime='' -d xiaoyi -r time.sql

  这个语句只有结束时间,从日志开头到''截止,xiaoyi数据库的binlog输出



mysqlbinlog

-d截取指定库的binlog

按照位置截取:

mysqlbinlog mysql-bin.000020 --start-position=365 --stop-position=456 -r pos.sql

按照时间接取:

mysqlbinlog mysql-bin.000020 --start-datetime='2015-03-19 03:22:44' --stop-datetime='2015-03-19 03:22:44' -r time.sql



binlog功能怎么打开?

grep log-bin /etc/my.cnf



6.3 mydqldump(--master-data)

mysqldump-master-data

myisam备份命令:

mysqldump -uroot -prinimei -A -B -F --master-data=2 -x --events|gzip > /opt/all.sql.gz

innodb备份命令:

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


--master-data=2

--CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000020',MASTER_LOG_POS=1191;


--master-data=1

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000020',MASTER_LOG_POS=1191;



七、mysql主从复制

mysql主从复制

7.1 mysql主从复制介绍

  mysql支持单向、双向、链式级联、实时、异步复制。在复制过程中,一台服务器充当主服务器(master),而另一个或多个其他的服务器充当从服务器(slave).

  复制可以是单向:M→S,也可以是双向M←→M,当然也可以多M环状同步等。

  如果设置了链式级联复制,那么,从(slave)服务器本身除了充当从服务器之外,也会同时充当其下面从服务器的主服务器。

  链式级联复制类似A→B→C→D的复制形式

(1)单向主从同步模式(√)

   一主两从及多从的mysql架构方案(√)

(2)双向主从同步(互为主从)(!)

(3)线性级联单向双主同步(√)

(4)环状级联单向多主同步(!)

(5)环状级联单向多主多从同步


7.2 mysql主从同步原理

 


7.3 mysql主从同步部署

(1)定义服务器角色

mysql master:192.168.11.2port:3306

mysql slave:192.168.11.3 port:3306


(2)定义server-id

vim /etc/my.cnf

[mysqld]

log-bin = mysql-bin

server-id = 1

提示:

(1)上面两个参数要放在my.cnf中的[mysqld]模块下,否则会报错

(2)server-id的值使用服务器ip地址的最后8位如19,目的是避免不同机器或实例ID重复(不适合多实例)0<server-id<2的32次方-1的自然数

(3)要先在my.cnf配置文件中查找相关参数,并按照要求修改。不存在时在添加参数,切记,参数不能重复

(4)修改my.cnf配置后需要重启数据库,命令为:/etc/init.d/mysql restart,注意要确认真

正重启了


检查配置后的结果

egrep "server-id|log-bin" /etc/my.cnf

[root@mysql-master data]# egrep "server-id|log-bin" /etc/my.cnf

server-id= 2

log-bin=mysql-bin


[root@mysql-master data]# pwd

/application/mysql/data

[root@mysql-master data]# ll

total 20536

drwx------. 2 mysql mysql     4096 Dec 14 16:44 gong

drwx------. 2 mysql mysql     4096 Dec 14 17:18 gongyi

-rw-rw----. 1 mysql mysql 10485760 Dec 15 14:19 ibdata1

-rw-rw----. 1 mysql mysql  5242880 Dec 15 14:19 ib_logfile0

-rw-rw----. 1 mysql mysql  5242880 Dec 13 15:10 ib_logfile1

drwx------. 2 mysql root      4096 Dec 13 15:07 mysql

-rw-rw----. 1 mysql mysql      106 Dec 15 14:19 mysql-bin.000001

-rw-rw----. 1 mysql mysql       19 Dec 15 14:19 mysql-bin.index

-rw-r-----. 1 mysql root     17728 Dec 15 14:19 mysql-master.err

-rw-rw----. 1 mysql mysql        5 Dec 15 14:19 mysql-master.pid

drwx------. 2 mysql root      4096 Dec 13 15:07 test

drwx------. 2 mysql mysql     4096 Dec 14 16:34 xiaoyi


mysql> show variables like 'log_bin';

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

| Variable_name | Value |

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

| log_bin       | ON    |

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

1 row in set (0.00 sec)


mysql> show variables like 'server_id';

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

| Variable_name | Value |

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

| server_id     | 2    |

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

1 row in set (0.00 sec)



(3)建立用于同步的帐号rep

mysql> grant replication slave on *.* to 'rep'@'192.168.11.%' identified by "rinimei";

Query OK, 0 rows affected (0.00 sec)


mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)


#replication slave为mysql同步的必须权限,此处不要授权all

#*.*表示所有库所有表,也可以指定具体的库和表进行复制。xiaoyi.test

#'rep'@'192.168.11.%',rep为同步帐号, 192.168.11.%为授权主机网段,使用了%表示允许整个192.168.11.0网段以rep用户访问

mysql>flush tables with read lock;

查看主库状态

mysql>show master status;

show master logs;

再开一个窗口

mysqldump -uroot -prinimei -A -B --events --master-data=2 > /opt/rep.sql

mysql>unlock tables;



从库操作:

mysql -uroot -prinimei < rep.sql


从库log-bin可开可不开,从库server-id与主库不一样

mysql> CHANGE MASTER TO MASTER_HOST='192.168.11. 2',MASTER_PORT=3306,MASTER_USER='rep',MASTER_PASSWORD='rinimei',MASTER_LOG_FILE='mysql-bin.000007',MASTER_LOG_POS=334;

Query OK, 0 rows affected (0.09 sec)


[root@mysql-slave data]# cat master.info 

15

mysql-bin.000007

334

192.168.11.2

rep

rinimei

3306

60

0


mysql> start slave;

Query OK, 0 rows affected, 1 warning (0.00 sec)


mysql> show slave status\G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.11.2

                  Master_User: rep

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000007

          Read_Master_Log_Pos: 334

               Relay_Log_File: mysql-slave-relay-bin.000002

                Relay_Log_Pos: 251

        Relay_Master_Log_File: mysql-bin.000007

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

mysql-master->create database zz;

Query OK, 1 row affected (0.01 sec)

mysql-slave->show databases;

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

| Database           |

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

| information_schema |

| gong               |

| gongyi             |

| mysql              |

| test               |

| xiaoyi             |

| yy                 |

| zz                 |

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

8 rows in set (0.00 sec)



7.4 mysql主从同步配置步骤

(1)准备两台数据库环境,或者单台多实例环境,能否正常启动和登陆

(2)配置my.cnf文件,主库配置log-bin和server-id参数,从库配置server-id,不能和主库及其他从库一样,一般不开启从库log-bin功能。注意:配置参数后要重启生效。

(3)登陆主库增加用于从库连接主库同步的账户,例如:rep,并授权replication slave同步的权限。

(4)登陆主库,整库锁表flush table with read lock(窗口关闭后失效,超时参数到了也失效),然后show master status查看binlog的位置状态

(5)新开窗口,linux命令行备份或导出原有的数据库数据,并拷贝到从库所在的服务器目录

如果数据量很大,并且允许停机,可以停机打包,而不用mysqldump

(6)解锁主库,unlock tables;

(7)把主库导出的原有数据恢复到从库

(8)根据主库的show master status查看binlog的位置状态,在从库执行change master to

(9)从库开启同步开关 start slave

(10)从库show slave status\G,检查同步状态,并在主库进行更新测试




7.5 mysql主从故障及主从延迟解决方案

(1)MySQL数据库主从同步延迟原理。

 

答:谈到MySQL数据库主从同步延迟原理,得从mysql的数据库主从复制原理说起,mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生binlog,binlog是顺序写,所以效率很高,slave的Slave_IO_Running线程到主库取日志,效率很比较高,下一步,问题来了,slave的Slave_SQL_Running线程将主库的DDL和DML操作在slave实施。DML和DDL的IO操作是随即的,不是顺序的,成本高很多,还可能可slave上的其他查询产生lock争用,由于Slave_SQL_Running也是单线程的,所以一个DDL卡主了,需要执行10分钟,那么所有之后的DDL会等待这个DDL执行完才会继续执行,这就导致了延时。有朋友会问:“主库上那个相同的DDL也需要执行10分,为什么slave会延时?”,答案是master可以并发,Slave_SQL_Running线程却不可以。

 

(2) MySQL数据库主从同步延迟是怎么产生的。

 

答:当主库的TPS并发较高时,产生的DDL数量超过slave一个sql线程所能承受的范围,那么延时就产生了,当然还有就是可能与slave的大型query语句产生了锁等待。

 

(3) MySQL数据库主从同步延迟解决方案

 

答:最简单的减少slave同步延时的方案就是在架构上做优化,尽量让主库的DDL快速执行。还有就是主库是写,对数据安全性较高,比如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置,而slave则不需要这么高的数据安全,完全可以讲sync_binlog设置为0或者关闭binlog,innodb_flushlog也可以设置为0来提高sql的执行效率。另外就是使用比主库更好的硬件设备作为slave。

 

mysql-5.6.3已经支持了多线程的主从复制。Oracle使用的是以数据库(schema)为单位做多线程,不同的库可以使用不同的复制线程。

 

sync_binlog=1

 

This makes MySQL synchronize the binary log’s contents to disk each time it commits a transaction

 

默认情况下,并不是每次写入时都将binlog与硬盘同步。因此如果操作系统或机器(不仅仅是MySQL服务器)崩溃,有可能binlog中最后的语句丢 失了。要想防止这种情况,你可以使用sync_binlog全局变量(1是最安全的值,但也是最慢的),使binlog在每N次binlog写入后与硬盘 同步。即使sync_binlog设置为1,出现崩溃时,也有可能表内容和binlog内容之间存在不一致性。如果使用InnoDB表,MySQL服务器 处理COMMIT语句,它将整个事务写入binlog并将事务提交到InnoDB中。如果在两次操作之间出现崩溃,重启时,事务被InnoDB回滚,但仍 然存在binlog中。可以用--innodb-safe-binlog选项来增加InnoDB表内容和binlog之间的一致性。(注释:在MySQL 5.1中不需要--innodb-safe-binlog;由于引入了XA事务支持,该选项作废了),该选项可以提供更大程度的安全,使每个事务的 binlog(sync_binlog =1)和(默认情况为真)InnoDB日志与硬盘同步,该选项的效果是崩溃后重启时,在滚回事务后,MySQL服务器从binlog剪切回滚的 InnoDB事务。这样可以确保binlog反馈InnoDB表的确切数据等,并使从服务器保持与主服务器保持同步(不接收 回滚的语句)。

 

 

抱怨Innodb比MyISAM慢 100倍?那么你大概是忘了调整这个值。默认值1的意思是每一次事务提交或事务外的指令都需要把日志写入(flush)硬盘,这是很费时的。特别是使用电 池供电缓存(Battery backed up cache)时。设成2对于很多运用,特别是从MyISAM表转过来的是可以的,它的意思是不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬 盘,所以你一般不会丢失超过1-2秒的更新。设成0会更快一点,但安全方面比较差,即使MySQL挂了也可能会丢失事务的数据。而值2只会在整个操作系统 挂了时才可能丢数据。




7.6 mysql主从常见故障

主从复制部署配置问题汇总:

(1)主库show master status没结果,主库binlog功能开关没开或没生效

egrep "server-id|log-bin" /etc/my.cnf

log-bin = mysql-bin

server-id = 1


mysql>show variables like 'server_id';

mysql>show variables like 'log_bin';

提示:配置文件里的参数和show variables里的参数不一样,例如my.cnf里log-bin,show的时候log_bin


mysql5.1 flush tables with read lock;

mysql5.5 flush table with read lock;

提示:这个锁表命令的时间,在不同的引擎的情况下,会受下面参数的控制,锁表时,如果超过设置时间不操作会自动解锁

interactive_timeout = 60

wait_timeout = 60

默认情况下时长为:

mysql>show variables like '%timeout%';

set global wait_timeout = 10;

set global interactive_timeout = 10;


(2)CHANGE MASTER时多了空格错误:

Last_IO_Error:Got fatal error 1236 from master when reading data from binary log:'Could not find first log file name in binary log index file'

MASTER_LOG_FILE=' mysql-bin.000001 ';

(3)服务无法启动故障

/etc/init.d/mysqld start

MYSQL is running

ps -ef|grep mysql

root163615950 11:47 pts/000:00:00 grep --color=auto mysql

rm -f /application/mysql/mysql.sock /application/mysql/*.pid

/etc/init.d/mysqld start


(4)由于切换binlog导致show master status位置变化无影响



7.7 mysql主从复制线程状态

登陆数据库查看mysql线程同步状态

主库/从库

mysql>show processlist\G

    下面列出了主服务器binlog dump线程的state列的最常见的状态。

sending binlog event to slave

二进制日志由各种事件组成,一个事件通常为一个更新加一些其他信息。线程已经从二进制日志读取了一个事件并且正将它发送到从服务器。

finished reading one binlog;switching to next binlog

线程已经读完二进制日志文件并且正打开下一个要发送到从服务器的日志文件

has sent all binlog to slave;waiting for binlog to be updated

线程已经从二进制日志读取所有主要的更新并已经发送到了从服务器。线程现在正空闲,等待由主服务器上新的更新导致的出现在二进制日志中的新事件

waiting to finalize termination

线程停止事发生的一个很简单的状态


复制从I/O线程状态

    下面列出了从服务器的I/O线程的state列的最常见的状态。该状态也出现在Slave_IO_State列,由SHOW SLAVE STATUS显示。


connecting to master

线程正试图连接主服务器

checking master version

建立同主服务器之间的连接后立即临时出现的状态

registering slave slave on master

建立同主服务器之间的连接后立即临时出现的状态

requesting binlog dump

建立同主服务器之间的连接后立即临时出现的状态。线程向主服务器发送一条请求,索取从请求的二进制日志文件名和位置开始的二进制日志的内容

waiting to reconnect after a failed binlog dump request

线程正尝试重新连接主服务器

waiting for master to send event

线程已经连接上主服务器,正等待二进制日志事件到达。如果主服务器正空闲,会持续较长的事件。如果等待持续slave_read_timeout秒,则发生超时。此时,线程认为连接被中断并企图重新连接。

queueing master event to the relay log

线程已经读取一个事件,正将它复制到中继日志供SQL线程来处理

waiting to reconnect after a failed mster event read

读取时(由于没有连接)出现错误。线程企图重新连接前将睡眠master-connect-retry秒

reconnecting after a failed master event read

线程正尝试重新连接主服务器。当连接重新建立后,状态变为waiting for master to send

waiting for the slave SQL thread to free enough relay log space

正使用一个非零relay_log_space_limit值,中继日志已经增长到其组合大小超过该值。I/O线程正等待直到SQL线程处理中继日志内容并删除部分中继日志文件来释放足够的空间。

waiting for slave mutex on exit

线程停止时发生的一个很简单的状态。



复制从SQL线程状态

    下面列出了从服务器的SQL线程的state列的最常见的状态。

reading event from the relay log

线程已经从中继日志读取一个事件,可以对事件进行处理了

has read all relay log;waiting for the slave I/O thread to update it

线程已经处理了中继日志文件中的所有事件,现在正等待I/O线程将新事件写入中继日志

waiting for slave mutex on exit

线程停止时发生的一个很简单的状态。

I/O线程的state列也可以显示语句的文本。这说明线程已经从中继日志读取了一个事件,从中提取了语句,并且正在执行语句。


查看mysql线程同步状态的用途

    通过mysql线程同步状态查看数据库同步是否完成,用于主库宕机或者人工数据库主从切换迁移等。

    主机宕机选择最快的从库提升为主,就需要查看,当然也可以利用mysql的半同步功能,选择固定的库提升为主。


7.8 mysql主从读写分离授权方案

(1)方案1

主库:web rinimei 192.168.11.2 3306(select,insert,delete,update)

从库:主库的web用户同步到从库,然后回收insert,delete,update权限


(2)方案2

主库:web _w rinimei 192.168.11.2 3306 (select,insert,delete,update)

从库:web_r rinimei 192.168.11.3 3306 (select)

风险:web_w连接从库

开发:2套用户密码不专业


3.方案3

mysql库不同步binlog-igore-db=mysql

主库:web rinimei 192.168.11.2 (select,insert,delete,update)

从库:web rinimei 192.168.11.3(select)

缺陷:从库切换主库的时候,连接用户权限问题

保留一个从库专门准备接替主


4.方案4

设置从库read-only


生产环境一般采取忽略授权表方式的同步,然后对从服务器slave上的用户仅授权select读权限。不同步mysql库,这样我们就保证主库和从库相同的用户可以授权不同的权限。


replicate-ignore-db = mysql

binlog-ignore-db = mysql

binlog-ignore-db = performance_schema

binlog-ignore-db = information_schema


DO:同步少量库

binlog-do-db=db_xiaoyi

replicate-do-db=db_xiaoyi   #如需跨数据库更新并且不想复制这些更新,应该使用该选项

replicate-do-table=db_xiaoyi #允许跨数据库更新

replicate-wild-do-table=db_xiaoyi #用于跨数据库更新


ignore:排除

binlog-ignore-db=mysql

replicate-ignore-db=mysql  #如需跨数据库更新并且不想复制这些更新,不应使用该选项

replicate-ignore-table=mysql #该选项可以跨数据库进行更新

replicate-wild-ignore-table=db_xiaoyi #该选项可以跨数据库进行更新。


特殊注意:

如果服务器用binlog-ignore-db=sales启动,并且执行USE prices;UPDATE sales.januar SET amount=amount+1000;该语句不写入二进制日志。



Replication中还以通过以下选项来减少binlog数据量,

来达到提高效率的目的,前两个用在Master端,后六个是用在Slave端


Master端:

--binlog-do-db二进制日志记录的数据库(多个数据库用,分隔)

--binlog-ignore-db二进制日忽略的数据库(多个数据库用,分隔)


在replication的slave端还有以下6个参数

--replication-do-db设定需要复制的数据库(多个数据库用,分隔)

--replication-ignore-db设定忽略复制的数据库(多个数据库用,分隔)

--replication-do-table设定需要复制的表(多个表用,分隔)

--replication-ignore-table设定忽略复制的表(多个表用,分隔)

--replication-wild-do-table同replication-do-table功能一样,但是可以加通配符

--replication-wild-ignore-table同replication-ignore-table功能一样,但是可以加通配符


mysql连接慢:

skip-name-resolve


让mysql slave库记录binlog方法


需要记录binlog的情况

1.当前从库还要作为其他从库的主库

2.把从库作为备份服务器时需要开启binlog


log-bin = mysql-bin

log-slave-updates

expire_logs_days = 7



7.9 mysql双主方案

解决主键自增长变量冲突:

master1:

auto_increment_increment = 2 #自增ID的间隔,如1 3 5间隔为2

auto_increment_offset = 1 #ID的初始位置

(将形成1,3,5,7...序列)

master2:

auto_increment_increment = 2 #自增ID的间隔,如2 4 6间隔为2

auto_increment_offset = 2 #ID的初始位置

(将形成2,4,6,8...序列)


1,3,5       11

     6,8,10


mysqldump -uroot -prinimei -A -B --master-date=1 -x --events > /opt/bak.sql

change master to


create table student(

id int(4) not null AUTO_INCREMENT,

name char(20) not null,

primary key(id)

);


insert into student(name) values('xiaoyi1');



互为主从参数:

log-slave-updates #开启从库binlog日志

binlog-ignore-db=mysql #不记录binlog日志

skip-slave-start #启动时忽略从库启动

replicate-same-server-id = 0


#########以下为在主库master1(10.0.0.240 3306)上的操作

1.开启binlog并设置server-id的值

vim /etc/my.cnf

server-id = 247 #IP最后一位数字的前两个数字 加 端口号数字的最后一位

log-bin=mysql-bin


2.建立用于同步的帐号ryanrep(master)

mysql -uroot -prinimei 

grant replication slave on *.* to 'ryanrep'@'10.0.0.%' identified by 'ryanrep';


3.锁表只读(master)(切记窗口不要关掉)

flush tables with read lock;


4.查看master状态当前日志文件名和二进制日志偏移量(要记录,后面要用到)

mysql> show master status;

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

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

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

| mysql-bin.000003 |     1323 |              |                  |

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

1 row in set (0.00 sec)


5.单开新窗口,备份数据库(数据量大,并且允许停机可以TAR,或直接CP)(master)

mysqldump -uroot -prinimei -A -B >/home/rhy/from240.sql



双主同步,互为主从

#m1(10.0.0.240 3306)

#____m-m m1 start____

auto_increment_increment = 2

auto_increment_offset = 1

log-slave-updates

log-bin

#m2(10.0.0.242 3306)

#____m-m m2 start____

auto_increment_increment = 2

auto_increment_offset = 2

log-slave-updates

log-bin


使用主主前提:

1.表的主键自增

2.程序写库指定ID



八、mysql服务多种日志

8.1 mysql三种常见日志类型

错误日志(error log):记录mysql服务进程mysqld在启动/关闭或运行过程中遇到的错误信息:

查询日志(uery log):又可分为两类

    普通查询日志(general query log):记录客户端连接信息和执行的SQL语句信息

    慢查询日志(slow query log):记录执行时间超出指定值(lang_query_time)的SQL语句

二进制日志(binary log):记录数据被修改的相关信息


错误日志:

[mysqld_safe]

log-error = mysql.err

普通查询日志:

show variables like 'general_log%';

慢查询日志:

lang_query_time = 1

log-slow-queries = slow.log

log_queries_not_using_indexes

二进制日志

mysql> show variables like '%log_bin%';

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

| Variable_name                    | Value |

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

| log_bin                         | ON    |    记录binlog

| log_bin_trust_function_creators     | OFF   |    临时不记录binlog

| sql_log_bin                      | ON    |

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

3 rows in set (0.00 sec)


8.2 binlog日志的三种模式

statement level模式

    每一条会修改数据的sql都会记录到master的bin-log中。slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行。

    优点:statement level下的优点首先就是解决了row level下的缺点,不需要记录每一行数据的变化,减少bin-log日志量,节约IO,提高性能。因为他只需要记录在Master 上所执行的语句的细节,减少bin-log日志量,节约IO,提高性能。因为它只需要记录在master上所执行的语句的细节,以及执行语句时候的上下文的信息

    缺点:由于是记录的执行语句,所以,为了让这些语句在slave端也能执行,还必须记录每条语句在执行的时候的一些相关信息,也就是上下文信息,以保证所有语句在slave端被执行的时候能够得到和在master端执行时候相同的结果。


Row Level模式

    日志中会记录成每一行数据被修改的形式,然后在slave再对相同的数据进行修改。

    优点:在row level模式下,bin-log中可以不记录执行的sql语句的上下文相关的信息,仅仅只需记录那一条记录被修改了。所以row level的日志内容会非常清楚的记录下每一行数据修改的细节,非常容易理解。

    缺点:row level模式下,所有的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容。


Mixed模式

    实际上就是前两种模式的结合。在Mixed模式下,mysql会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在statement和row之间选择一种。


8.3 调整binlog日志模式方法

(1)在配置文件中修改

log-bin = mysql-bin

binlog_format = "STATEMENT"

binlog_format = "ROW"

binlog_format = "MIXED"

(2)在线修改立即生效方法

运行时在线修改:

mysql>set session binlog_format = 'STATEMENT';

mysql>set session binlog_format = 'ROW';

mysql>set session binlog_format = 'MIXED';

(3)全局生效:

mysql>set global binlog_fomat = 'STATEMENT';

mysql>set global binlog_fomat = 'ROW';

mysql>set global binlog_fomat = 'MIXED';



九、mysql存储引擎

9.1什么是存储引擎

    数据库表里的数据存数在数据库里与mp4 .avi等文件存储在磁盘上类似。

    对于用户和应用程序来说同样一张表的数据,无论用什么引擎来存储,用户看到的数据都是一样的。不同的引擎存储,引擎的功能,占用的空间大小,读取性能可能有区别。

    mysql最常用的存储引擎为:Myisam和Innodb。



9.2 mysql事务以及ACID特性

    简单的说,事务就是指逻辑上一组SQL语句操作,组成这组操作的各个SQL语句,执行时要么全成功要么全失败。


事务的四大特性(ACID)

a.原子性(Atomicity)

事务是一个不可分割的单位,事务中的所有SQL等操作要么全都发生,要么都不发生。

b.一致性(Consistency)

事务发生前和发生后,数据的完整性必须保持一致

c.隔离性(Isolation)

当并发访问数据库时,一个正在执行的事务在执行完毕前,对于其他的会话是不可见的,多个并发事务之间的数据是相互隔离的。

d.持久性(Durability)

一个事务一旦被提交,它对数据库中的数据改变就是永久性的。如果出了错误,事务也不允许被撤销,只能通过“补偿性事务”。


事务的开启:

数据库默认事务是自动提交的,也就是发一条sql它就执行一条。如果想多条sql放一个事务中执行,则需要使用事务进行处理。当开启一个事务,并且没有提交,mysql会自动回滚事务。或者使用rollback手动回滚事务。


数据库开启事物命令:

start transcation 开启事务

rollback 回滚事务

commit提交事务


set global autocommit=OFF;

set autocommit=OFF禁止自动提交

set autocommit=ON开启自动提交

rollback 回滚事物

commit提交事物



9.3 MyISAM引擎特点及调优

MyISAM引擎特点

(1)不支持事务

(2)表级锁定(更新时锁整个表);其锁定机制是表级索引,这虽然可以让锁定的实现成本很小但是也同时大大降低了其并发性能。

(3)读写互相阻塞:不仅会在写入的时候阻塞读取,MyISAM在读的时候阻塞写入,但本身读不会阻塞另外的读。

(4)只会缓存索引:MyISAM可以通过key_buffer_size缓存索引,以大大提高访问性能减少磁盘IO,但是这个缓存区只会缓存所引,而不会缓存数据。

(5)读取速度较快,占用资源相对较少。

(6)不支持外键约束,但支持全文索引。

(7)MyISAM引擎是MySQL5.5.5前缺省的存储引擎


MyISAM引擎适用的场景

(1)不需要事务支持的业务(转账就不行)

(2)一般为读数据比较多的应用,读写都频繁场景不适合,读多或者写多的都适合。

(3)读写并发访问相对较低的业务(纯读纯写高并发也可以)

(4)数据修改相对较少的业务(阻塞问题)

(5)以读为主的业务

(6)对数据一致性要求不是非常高的业务。

(7)硬件资源比较差的机器可以用MyISAM

小结:单一对数据库的操作都可以使用MyISAM,所谓单一就是尽量纯读,或纯写


MyISAM引擎调优

(1)设置合适的索引(缓存机制)

(2)调整读写优先级,根据实际需求确保重要操作更优先执行。

(3)启用延迟插入改善大批量写入性能(降低写入频率,尽可能多条数据一次性写入)

(4)尽量顺序操作让insert数据都写入到尾部,减少阻塞。

(5)分解大的操作,降低单个操作的阻塞时间。

(6)降低并发数(减少对mysql访问),某些高并发场景通过应用进行排队队列机制

(7)对于相对静态(更改不频繁)的数据库数据充分利用Query Cache或memcached缓存服务可以极大的提高访问效率。

query_cache_size = 2M

query_cache_limit = 1M

query_cache_min_res_unit = 2k

(8)MyISAM的Count只有在全表扫描的时候特别高效,带有其他条件的count都需要进行实际的数据访问。

select count(*) from test.table;

(9)可以把主从同步的主库使用innodb,从库使用MyISAM引擎



9.4 InnoDB引擎特点及调优

(1)支持事务:支持4个事务隔离级别,支持多版本读

(2)行级锁定(更新时一般是锁定当前行)通过索引实现,全表扫描仍然会是表锁,注意间隙锁的影响。

(3)读写阻塞与事务隔离级别相关

(4)具有非常高效的缓存特性:能缓存索引,也能缓存数据

(5)整个表和主键以Cluster方式存储,组成一颗平衡树。

(6)所有Secondary Index都会保存主键信息

(7)支持分区,表空间,类似oracle数据库

(8)支持外键约束,5.5以前不支持全文索引,以后支持了

(9)和MyISAM引擎比,InnoDB对硬件资源要求比较高。



InnoDB引擎适合的场景

(1)需要事务支持的业务(具有较好的事务特性)

(2)行级锁定对高并发有很好的适应能力,但需要确保查询是通过所引完成。

(3)数据读写及更新都较为频繁的场景,如:BBS,SNS,微博,微信等。

(4)数据一致性要求高的业务,例如:充值转账,银行卡转账。

(5)硬件设备内存较大,可以利用InnoDB较好的缓存能力来提高内存利用率,尽可能减少磁盘IO。


InnoDB引擎调优

(1)主键尽可能小,避免给Secondary index带来过大的空间负担

(2)避免全表扫描,因为会使用表锁

(3)尽可能缓存所有的所引和数据,提高相应速度,减少磁盘IO消耗

(4)在大批量小插入的时候,尽量自己控制事务而不要使用autocommit自动提交。有开关可以控制提交方式

(5)合理设置innodb_flush_log_at_trx_commit参数值,不要过度追求安全性。

如果innodb_flush_log_at_trx_commit的值为0,log buffer每秒就会被刷写日志文件到磁盘,提交事务的时候不做任何操作。

(6)避免主键更新,因为这就会带来大量的数据移动。



InnoDB引擎重要参数:

innodb_additional_mem_pool_size = 16M

innodb_buffer_pool_size = 2048M  (50%-80%)

innodb_data_file_path = ibdata1:1024M:autoextend

innodb_file_io_threads = 4

innodb_thread_concurrency = 8

innodb_flush_log_at_trx_commit = 2

innodb_log_buffer_size = 16M

innodb_log_file_size = 128M

innodb_log_files_in_group = 3

innodb_max_dirty_pages_pct = 90

innodb_lock_wait_timeout = 120

innodb_file_per_table = 0


MyISAM引擎重要参数

key_buffer_size = 2048M



9.5修改mysql引擎

(1)mysql命令语句修改

ALTER TABLE test ENGINE = MyISAM


(2)使用sed对备份内容进行引擎转换

mysqldump >aa.sql

nohup sed -e 's/MyISAM/InnoDB/g' aa.sql  > bb.sql &

mysql <bb.sql


(3)mysql_convert_table_format命令修改

mysql_convert_table_format --user=root --password=rinimei --engine=MyISAM xiaoyi test;



十、mysql优化

10.1 mysql负载高情况查看

(1)系统负载比较高

uptime

(2)网站打开很慢,mysql大量线程等待

mysql -uroot -prinimei -e "show full processlist"|grep -vi sleep

(3)慢查询语句

long_query_time = 1

log-slow-queries = slow.log


查看利用索引情况

explain select id from test where ader='' and dateline='';

查看表结构

show create table test \G


10.2 mysql优化思路

(1)从业务上实现用户先登录后再搜索,这样减少搜索次数,从而减轻数据库的压力

(2)如果有大量频繁的搜索,一般是爬虫在爬网站,分析web日志(AWTATS),封IP

(3)配置多个主从同步,程序上实现读写分离

(4)在数据库前端加上memcacehd缓存

(5)like '%666%'的语句,一般在mysql里很难优化,可以通过搜索服务Sphinx实现搜索


10.3 mysql数据库优化

(1)硬件优化

a.64位CPU 一台机器8-16颗CPU 2-4颗

b.mem 96G-128G 3-4个实例 32G-64G 2个实例

c.disk 数量越多越好 性能:SSD(高并发)>SAS(普通业务线上)>SATA(线下)

 raid 4块盘:RAID0>RAID10>RAID5>RAID1

d. 多快网卡bond,以及buffer,tcp优化


(2)软件优化

操作系统:x86_64系统

软件:mysql编译优化


(3)my.cnf参数优化

优化的幅度很小,大部分是架构以及SQL语句优化


(4)SQL语句优化

a.抓出慢查询语句

(set global long _query_time=2;

set global slow_query_log='ON';)

my.cnf

long_query_time = 2

long-slow-queries = /usr/local/mysql/mysql-slow.log

log-queries-not-using-indexes = on 

按天轮训slow.log

b.慢查询日志分析工具 mysqlsla

c.大的复杂的SQL语句拆成多个小的SQL语句

d.数据库是存储数据的地方,不是计算数据的地方,对数据计算,应用类处理,都要拿出


(5)架构上优化

a.业务拆分:搜索功能,like '666'一般不要用mysql;交友等业务使用nosql持久化存储

b.数据库前端加缓存,memcacehd等

c.动态的数据静态化,文件,页面静态化(伪静态)

d.数据库集群与读写分离。通过程序或者dbproxy进行集群读写分离。


(6)流程制度安全优化

任何一次人为数据库记录的更新,都要走一个流程:

a.人的流程:开发→核心开发→运维或DBA

b.测试流程:开发环境测试→测试环境测试→IDC测试→线上执行

c.客户端管理,phpmyadmin