深入浅出MySQL-学习笔记by CZF

深入浅出MySQL  -- 读书笔记

第一部分     基础篇. - 2 -

第1章    MySQL的安装与配置. - 2 -

第2章    SQL 基础. - 2 -

第3章    MySQL支持的数据类型. - 3 -

第4章    MySQL中的运算符. - 6 -

第5章    常用函数. - 7 -

第6章    图形化工具的使用. - 9 -

第二部分     开发篇. - 9 -

第7章    存储引擎(表类型)的选择. - 9 -

第8章    选择合适的数据类型. - 11 -

第9章    字符集. - 12 -

第10章      索引的设计和使用. - 13 -

第11章      视图. - 13 -

第12章      存储过程和函数. - 14 -

第13章      触发器. - 17 -

第14章      事务控制和锁定语句. - 17 -

第15章      SQL中的安全问题. - 18 -

第16章      SQLMode 及相关问题. - 18 -

第17章      SQL 分区. - 19 -

第三部分     优化篇. - 22 -

第18章      SQL优化. - 22 -

第四部分. - 24 -

第19章. - 24 -


 

第一部分  基础篇

1.  MySQL 由于性能好,在开源数据库中独占鳌头,ANSI/ISO标准符合性不是太好

第1章  MySQL的安装与配置

2.  Linux中启动、重启、关闭MySql

service mysql start  /servicemysql restart  /service mysql stop

第2章  SQL 基础

3.  SQL分为DDL数据定义语言(create、drop)、DML数据操作语言(select、insert等)、DCL数据控制语言(权限、安全,grant,revoke)

4.  进入mysql控制台:  mysql -uroot -p

5.  sql常用DDL语句

show databases;

查看所有数据库

create database db1;

 

use db1;

 

show tables;

 

drop database dbname;

drop table tablename;

 

CREATE TABLE `users` (

  `id` char(9) NOT NULL,

  `age` varchar(45),

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

desc tablename;

查看表定义

show create table tablename;

查看表定义语句

alter table tablename modify [column]column_definition [first|after col_name]

修改列类型,可排序列

alter table tablename add [column]column_definition [first|after col_name]

 

alter table tablename drop [column]columnname

删除字段

alter table tablename change[column]oldcolNamecolumn_definition [first|after col_name]

字段改名

alter table tablename rename [to] new_tablename

表改名

like通配符:%匹配多个字符,下划线_匹配单个字符

 

6.  DML语句

insert into tablename[(field1,…,fieldn)] values (value1,…,valuen),(value1,…,valuen),...

 

update tablename set field1=value1,... [Where Condition]

 

delete from tablename[where...]

 

select [distinct] col1,col2,... from tablename [where..][order by colname asc|desc][limit start,count ]

start 从0开始,可省略。limit 1,3表示从第2条记录开始取3条记录

select name,count(1) count1 from users group by name having count1 >1

having是设置聚合后的选择条件的。聚合函数(sum,count,max,min,avg)

内连接 inner join 或者 from table1,table2

 

外链接分为左(外)连接和右(外)连接

left (outer) join/right (outer)join

左连接,结果包含左表全部行

子查询 in / not in / exists /not exists

有时候可用表连接优化

union/union all

union all 直接合并

union 去重(distinct)

group by 的with rollup子句

select staff_id,sum(amount) from payment group by staff_id with rollup

Ø  可查询总的统计数据

Ø  或者 group by 有两列时,还可以只根据第一列分组的本组统计信息。p305

bit_and(col_name) / bit_or(colname) 与 group by 结合使用

对每一个小组的col_name列的各值做 按位与,按位或 操作,类似与 sum()分组统计

7.  DCL语句

grant select,insert on dbname.* to 'z1'@'localhost' identified by '123'

对z1用户授予 dbname数据库所有表的select和insert权限

revoke insert on dbname.* from 'z1'@'localhost'

收回insert权限

8.  MySQL 查看帮助

? contents; 或者 helpcontents;查看帮助列表

?/help   查看具体帮助

9.  查询元数据( information_schema数据库)

该数据库是虚拟数据库(视图),Schemata表存储所有数据库信息,tables表存储所有表信息,columns存储列信息,statistics表存储索引信息。

第3章  MySQL支持的数据类型

10. MySQL 支持数值类型、字符串类型(包含枚举、Set类型)、日期时间

11. 数值类型

类型

大小

用途

TINYINT

1 字节

小整数值

SMALLINT

2 字节

大整数值

MEDIUMINT

3 字节

大整数值

INT或INTEGER

4 字节

大整数值

BIGINT

8 字节

极大整数值

FLOAT(M,D)

4 字节

单精度浮点数值

DOUBLE(M,D)【等同于real】

8 字节

双精度浮点数值

DECIMAL(M,D)

M+2

小数值

M是表示有效数字数的精度。M范围为1〜65。

D是表示小数点后的位数。 D的范围是0~30。MySQL要求D小于或等于(<=)M。

BIT(M)

1-8

位类型。最小值BIT(1),最大值BIT(64)

不指定宽度时,默认为1位

select 时不显示,需要用bin(),hex()函数转换成二进制或十六进制

select bin(col2),hex(col2) from t2

12. 指定int(5)类型,表示当宽度小于5时,在前面补0,配合zerofill使用.不指定宽度时,默认补齐11位。

create table t1(id1 int zerofill,id2int(5) zerofill);

13. 整形都有 unsigned 可选属性,最小值从0开始

14. 小数表示有浮点数(float、double)和定点数decimal。decimal在数据库中以字符串形式存放,比浮点数更精确,用于货币等精度高的数据。

15. 日期时间类型

类型

大小(字节)

范围

格式

用途

DATE

3

1000-01-01/9999-12-31

YYYY-MM-DD

日期值

TIME

3

'-838:59:59'/'838:59:59'

HH:MM:SS

时间值或持续时间

DATETIME

8

1000-01-01 00:00:00/9999-12-31 23:59:59

YYYY-MM-DD HH:MM:SS

混合日期和时间值

YEAR

1

1901/2155

YYYY

年份值

TIMESTAMP

4

1970-01-01 00:00:00/2038

结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07

YYYYMMDD HHMMSS

混合日期和时间值,时间戳

16.  now()函数获取当前日期时间,或者 CURRENT_DATE

17. DATETIME与TIMESTAMP区别:

Ø  DATETIME范围更广

Ø  TIMESTAMP显示值与时区有关

Ø  表中的第一个TIMESTAMP列自动设置为系统时间(CURRENT_TIMESTAMP)

18. 字符串类型

类型

大小

用途

CHAR

0-255字节

定长字符串

VARCHAR

0-65535 字节

变长字符串

TINYBLOB

0-255字节

不超过 255 个字符的二进制字符串

TINYTEXT

0-255字节

短文本字符串

BLOB

0-65 535字节

二进制形式的长文本数据

TEXT

0-65 535字节

长文本数据

MEDIUMBLOB

0-16 777 215字节

二进制形式的中等长度文本数据

MEDIUMTEXT

0-16 777 215字节

中等长度文本数据

LONGBLOB

0-4 294 967 295字节

二进制形式的极大文本数据

LONGTEXT

0-4 294 967 295字节

极大文本数据

enum

enum('M','F')

枚举类型(数据取单个值)

set

 

集合类型,(有多个值)

19. CHAR 和 VARCHAR 区别

Ø  CHAR 长度固定,存储时尾部空格补齐。VarChar长度可变。

Ø  Char不存储数据的尾部空格,Varchar存储

Ø  char最大长度255,varchar 最大长度65535(5.0.3以后版本)

20. BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR

Ø  不同的是它们包含二进制字符串而不包含非二进制字符串。它们没有字符集,并且排序和比较基于列值字节的数值。

Ø  Binary末尾补0,而Char末尾补空格。

第4章  MySQL中的运算符

21. 算术运算符

+  -   *   /【DIV】  %【MOD】    取模可用函数 MOD(a,b)

22. 比较运算符

Ø  select 时,比较结果为true,返回1,为false返回0,不确定返回NULL

Ø  默认数字作为浮点数比较,字符串不区分大小写进行比较

运算符

作用

=

等于

<=>

安全的等于(可以用于比较NULL值,2个NULL相等

<>(!=)

不等于

<    <=

小于   小于等于

>   >=

大于  大于等于

IS NULL、ISNULL

判断一个值是否为NULL

IS NOT NULL

判断一个值是否不为NULL

LEAST

在有两个或多个参数时,返回最小值

GREATEST

当有2或多个参数时,返回最大值

BETWEEN AND

判断一个值是否落在两个值之间(含边界

IN 、NOT IN

判断一个值是否落在IN列表中的任意一个值

LIKE

通配符匹配

REGEXP、RLIKE

正则表达式匹配

23. 逻辑运算符

NOT或者!    AND或者&&    OR或者||   XOR异或

24. 位运算符

~位取反      &位与          |位或     ^位异或      <<位左移    >>位右移

第5章  常用函数

25. 常用函数包括字符串函数,日期函数,数值函数、流程函数

26. 字符串函数

27. 数值函数

经测试,ceil(1) , floor(1) 结果都为 1.

所以CEIL(x)返回大于等于x的最小整数值,FLOOR(x)返回小于等于x的最大整数值

28. 日期时间函数

29. 流程函数

30. 其他函数

第6章  图形化工具的使用

31. 客户端MySQL workbench  和 web客户端phpMyAdmin

workbench功能有SQL开发,数据建模,Server管理、MySQL Utilities功能

32. 编写存储过程时,经常用 delimiter // 将 默认分隔符分号(;)变成双斜杠(//),存储过程编写完成后,delimiter ;  变回默认值。【存储过程中有分号】

33. MySQL Utilities工具集

 

第二部分  开发篇

第7章  存储引擎(表类型)的选择

34. 常用MySQL引擎:InnoDB(默认)、MyISAM(5.5之前默认)、Memory、Merge、CSV、PERFORMANCE_SCHEMA。第三方引擎TokuDB高写性能高压缩支持事务。

BLACKHOLE存储引擎不在磁盘存数据,只将DML操作记录在Bin LOG中,适合多级复制里的二级主库,见31章

35. 查看当前数据库支持的引擎:show engines \G;

36. 创建表时,设置引擎:create table t23( id int,primarykey (id))engine=MyISAM defaultcharset=gbk;

alter table t23 engine=InnoDB;

37. MyISAM存储引擎

MyISAM不支持事务、不支持外键,支持表锁。其优势是访问速度快。对事务完整性没有要求或者以select、Insert为主的应用可以采用。MyISAM类型的表可能会损坏。

          MyISAM表在磁盘上对应三个文件.frm存储表定义; .MYD(MYData,存储数据);

.MYI(MYIndex,存储索引)。

MyISAM支持3中存储格式:

Ø  静态表(固定长度)【默认】: 表中的字段都是非变长字段,用空格补齐。优点:访问速度快,容易缓存,出现故障容易恢复。缺点:占用空间大

Ø  动态表:包含变长字段,记录长度不是固定的。频繁更新和删除记录会产生碎片。需要定期执行OPTIMIZE TABLE 语句或者 myisamchk-r 命令来改善性能。

Ø  压缩表:myisampack工具创建

38. InnoDB存储引擎

提供了外键、事务安全,但是比MyISAM写的效率差一些,且会占用更多存储空间和内存使用。支持行锁,分布式事务。

存储方式:

Ø  共享表空间存储:表结构存储在.frm文件中,数据和索引保存在innodb_data_home_dir和innodb_data_file_path定义的表空间中

Ø  多表空间存储:表结构存储在.frm文件中。每个表的数据和索引单独保存在.ibd文件中

39. MEMORY存储引擎

MEMORY存储引擎使用存在于内存中的内容来创建表。多用于内容变化不频繁的代码表和临时(中间)表。优点:访问速度非常地快,因它的数据存放在内存,并且默认使用Hash索引。缺点一旦服务关闭,数据丢失。

40. MERGE存储引擎

  Merge存储引擎是一组MyISAM表的组合,这些表必须结构完全相同。Merge表本身没有数据,对merge表的增删改查实际是对内部MyISAM表进行的。

  Merge表通常用来透明地对多个表进行查询和更新,而对按照时间记录的日志操作则可以进行透明的插入操作。

  对于Merge表的插入,通过INSERT_METHOD子句定义

Ø  FIRST:插入到第一个内部表

Ø  LAST: 插入到最后一个内部表

Ø  NO或者不定义INSERT_METHOD 子句:   不能对该MERGE表进行插入

新建MERGE表语句:

 create table ta(id int,name char(10))engine=merge union=(tb2,tb3) insert_method=LAST ;

其中tb2与tb3结构与ta一样,只是engine=myisam

41. 如何选择合适的存储引擎

42. 创建Hash/Btree索引

create index name_index using hash[或btree] on tablename(colname);

查看表中的索引

show index from tablename [\G];

43. 使用 select LAST_INSERT_ID();返回当前线程最后插入记录的自增长列的值

44. 外键级联操作

临时关闭外键检查:set FOREIGN_KEY_CHECKS=0; 开启时设为1

Ø  RESTRICT / NO ACTION 限制在子表有关联记录的情况下,父表不能更新或删除

Ø  CASCADE 父表做更新相关列或删除记录时,更新或删除子表

Ø  SET NULL ……子表对应字段被设置为NULL

第8章  选择合适的数据类型

45. char 与 varchar用来存储少量字符串

Ø  char 固定长度,使用空格补齐,检索时去除尾部空格(即使插入实际数据时尾部有空格)。处理速度快,但是浪费存储空间,程序需要对数据尾部空格进行处理。对于长度变化不大,而对查询速度有要求的可选用。

Ø  varchar可变长度。varchar 性能逐渐提高

Ø  MyISAM存储引擎 推荐使用固定长度的char

Ø  InnoDB建议使用varchar。所有数据行都使用指向数据列值的头指针,因此主要看存储性能。

Ø  MEMORY 无论使用char还是varchar都是作为固定长度处理(作为char)

46. Text与BLOB用来存储大文本

Ø  BLOB可存储二进制,Text只能保存字符串

Ø  进行大量删除操作后,使用OPTIMIZE TABLE tablename;来进行碎片整理

Ø  可使用前缀索引,为字段的前n字符创建索引。context为text类型。查询时%不能放在最前面,否则将无法使用索引。

  create index idx_text on tb2(context(100));

Ø  【优化】不必要的时候不检索Text列,select col1,col2 而不是select *

Ø  【优化】把BLOB或者Text放到单独的表。把原表中的数据列转为固定长度,可以减少主表碎片。

47. 浮点数与定点数

Ø  浮点数float double超出精度时,四舍五入。

Ø  定点数decimal实际以字符串存储,可以更精确的表示精度(可用于货币)。

Ø  编程中应避免浮点数==比较,应使用范围比较

48. 日期类型选择:

Ø  尽量选择最小日期类型,YEAR DATE TIME

Ø  如果记录日期时间比较久远,选择DATETIME因其范围广

Ø  如果记录日期需要让不同时区的用户使用,使用TIMESTAMP

49. Linux du命令用于显示目录或文件的大小。du会显示指定的目录或文件所占用的磁盘空间

du -sh t.*          -s只显示总大小不显示子目录;-h以K M G 友好显示

第9章  字符集

50. 查看所有字符集:

Ø  show character set;

Ø  select * from information_schema.character_sets;

51. MySQL 的字符集包括字符集和校对规则(用于比较)

Ø  _ci  不区分大小写

Ø  _cs  区分大小写

Ø  _bin 比较是基于字符编码的值(区分大小写)

52. MySQL字符集和校对规则的4个级别的默认设置:

Ø  服务器级

在my.cnf中设置

[mysqld]

character_set_server=gbk

Ø  数据库级

Ø  表级

Ø  字段级

53. mysqldump 备份数据库结构,和数据  -d只导出表结构

第10章    索引的设计和使用

54. myISAM和InnoDB默认创建的是BTREE索引

55. 目前只有MyISAM引擎支持全文索引(innoDB从MySQL5.6支持),仅支持char varchar text

56. Memory引擎使用Hash索引,也支持Btree索引

57. 索引分类(第18章中还有索引详细讲解)

Ø  按底层结构:Hash索引和Btree索引。BTree索引适用于范围匹配【> < between<>】Hash单值匹配【= in】

Ø  普通索引、主键索引、唯一索引、全文索引

Ø  多列索引(组合索引)、前缀索引(部分索引):只是列的前面N个字符建索引

58. B树索引,不是二叉树,而是平衡树,B代表平衡(balanced)

59. 索引设计原则

Ø  搜索列设索引,即Where后面的列

Ø  列值没有大量相同值时,索引效率高

Ø  使用段索引(前缀索引)

Ø  使用最左索引(多列索引时)

Ø  不要过度使用索引,索引占空间,写操作性能降低

第11章    视图

60. 视图是虚拟表,对用户透明,数据来自实际表,且仅在使用视图时动态生成

Ø  简单:不用关心后台关联和筛选条件

Ø  安全:使用视图的用户仅能看到允许查询的结果

Ø  数据独立:可屏蔽表结构的修改对用户的影响,原表修改可通过修改视图解决

61. 创建视图:

不指定时,默认CASCADED。CASCADED需要满足定义本视图时使用到的所有视图的条件(Where)

62. show tables;可显示表和视图

show create view viewname ;可查看视图定义

information_schema.views表中可以查看视图相关信息

第12章    存储过程和函数

63. 存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合。

Ø  减少应用开发人员的工作(处理数据的逻辑在数据库,如需修改,不用改程序

Ø  减少数据在数据库和应用服务器之间的传输

Ø  提高数据处理效率(预编译)

64. 存储过程Procedure与函数Function区别

Ø  函数必须有返回值,存储过程没有

Ø  函数的参数只能是IN类型的,存储过程的参数可以是IN,OUT,INOUT

65. 定义

66. 调用存储过程或者函数 call sp_name(parameter[,…])

67. 创建存储过程时,常用delimiter $$ 命令将语句结束符由;改为$$

68. 删除存储过程或者函数:

drop {procedure | function} [if exists]sp_name;

69. 授权执行存储过程的权限:

70. 使用局部变量(仅在Begin 和 end 中有效,且必须在begin语句后面第一句)

Ø  定义: declare var_name[,…] type [defaut value]

Ø  赋值:1.直接赋值(常量、或表达式) Set;2.查询赋值  selectcolname into varname

71. 定义 条件 和 处理。(在处理过程中遇到问题时相应的处理步骤)

实例:

72. 光标:对结果集进行循环处理。

73. 流程控制

Ø  if  then  elseif then  else   end if

Ø  case when 两种用法

Ø  loop  leave(退出) itreate(继续下一轮循环)

Ø  repeat … until … end repeat

Ø  while … do …  end while

74. 事件调度器(时间触发器),定期创建表,定期清理历史数据

set GLOBAL event_scheduler=1;  打开事件调度器

或者 on schedule every 5second ……

第13章    触发器

75. 创建触发器

trigger_time  可以是 before 或者 after

trigger_event 可以是 insert update delete

Ø  同一个相同时间的相同触发事件只能定义一个触发器。

Ø  使用别名  new和 old 来引用触发器中变化的记录

76. 删除触发器

drop trigger [schema_name.]trigger_name;

删除表中所有触发器:drop trigger tblname;

77. 查看触发器

show triggers;显示所有触发器

查询information_schema.triggers表

78. 添加过多或过复杂触发器影响插入、更新、删除效率

第14章    事务控制和锁定语句

79. MySQL支持的锁

Ø  InnoDB支持 行级锁定

Ø  MyISAM 和MEMORY 支持 表级锁定

Ø  BDB存储引擎的表支持 页级锁定

80. 表锁

Ø  LOCK TABLES tbl_name[[AS] alias] lock_type [, tbl_name [[AS] alias]lock_type] ...

Ø  lock_type:READ[LOCAL]|[LOW_PRIORITY] WRITE

Ø  UNLOCK TABLES

Ø  UNLOCK TABLES显示的释放当前session锁保持的锁。

Ø  另外通过LOCK TABLEs语句为当前session获取新锁前会隐式的释放当前session之前的所有锁

81. 事务定义语法

chain :启动一个新事物 release:断开和客户端的连接。

82. 默认情况下MySQL是自动提交事务的。手动提交或回滚set autocommit=0;,设置之后所有的事务都需要通过明确的命令进行提交或者回滚

83. 事务提交前,修改并没有实际提交到数据库。

84. 所有DDL语句不能回滚。可以通过SAVEPOINT指定回滚事务的一个部分。

savepoint spname;…… rollback to savepoint spname;

85. 分布式事务  XA事务

Ø  只支持InnoDB存储引擎

Ø  存在问题,当前不推荐使用分布式事务P213

第15章    SQL中的安全问题

86. SQL注入:利用数据库的外部接口将用户数据插入到实际的数据库操作语言SQL中,入侵数据库

87. 注入方式

Ø  or 1=1

Ø  username=czf'/*

88. 应对措施

Ø  PreparedStatement

Ø  使用应用程序提供的转换函数  

Ø  自定义函数进行校验

第16章    SQL Mode 及相关问题

89. MySQL 可以运行在不同的SQL Mode(SQL模式)下,(支持的SQL语法和数据校验不同)

Ø  ANSI模式,保证大多数SQL符合标准的SQL语法,迁移时方便

Ø  STRICT_TRANS_TABLES(严格模式)  ,插入记录列长度超出定义时,产生ERROR而不是WARNING

Ø  TARDITIONAL(也是严格模式)模式时,插入错误格式的日期插入会报错,MOD(X,0)报错,而ANSI模式下错误格式的日期插入会变成“0000-00-0000:00:00”,MOD(X,0)结果为NULL

Ø  设置NO_BACKSLASH_ESCAPES模式,使数据中的反斜线\称为普通字符。

Ø  PIPES_AS_CONCAT模式(ANSI模式包含此模式):使||视为字符串连接操作符(为了兼容ORACLE)。

90. SET [SESSION|GLOBAL] sql_mode= 'ANSI';修改SQL MODE

91. 常用SQL MODE

“严格模式”为MYSQL 提供了很好的数据校验功能。

92. SQL MODE 在数据库迁移时(迁入或迁出其他类型数据库)有一定作用。为兼容其他数据库设置不同组合的SQL MODE。P224

第17章    SQL 分区

93. 分区:把数据表分成多个更小更容易管理的部分。分区对应用透明,不影响业务逻辑。逻辑上只有一个表,实际上对应数个物理分区对象。分区优点如下:

Ø  跨多磁盘存储,可以存储更多数据,获得更大的查询吞吐量。

Ø  优化查询。当where子句包含分区条件时,可以只扫描必要的分区提高效率

Ø  对于过期数据,可以通过删除分区来快速删除数据

94. 分区类型:

95. HASH分区示例:(分散热点读,使数据在各分区尽可能平均分布)

Ø  常规HASH分区:对分区数使用取模算法确定数据存储的分区。当增加或减少分区时,所有数据需要重新计算。数据分布均衡

Ø  线性HASH分区(BY LINER HASH(……)):使用 线性的2的幂运算法则(找到一个大于等于当前分区数(num)的2的幂(N),对这个值取模,如果结果大于分区数,则对N/2取模)。P238.分区维护时,MySQL能够处理的更加迅速,缺点是各分区数据分布不太均衡。

96. KEY分区:

KEY分区类似于HASH分区,也可以指定LINER,不同在于:

Ø  HASH允许自定义表达式,KEY不允许

Ø  HASH只支持整数分区,KEY支持出BLOB和TEXT以外的其他类型

Ø  创建KEY分区表时,可以不指定分区键,默认选择主键作为分区键(没有主键时,选择非空唯一键做分区键,如果没主键也没非空唯一键,就必须指定分区列)

97. Range分区示例:适用于需要删除过期数据和包含分区键的查询

此时如果插入 store_id 大于30 会出错。增加分区如下:

98. 分区表上要么没有 主键/唯一键时 ,要么分区字段必须是在 主键/唯一键 中。

99. explain partitions select …… 可以看到 查询用到了哪些分区

100.   List分区示例

101.   Columns分区(分为RANGE COLUMNS和LIST COLUMNS)支持所有整形,日期类型和字符类型。支持多列分区(相当于按多列依次排序分区:a<10 或者 a=10,b<10两种情况会分到P02分区):

102.   子分区:又称复合分区,对RANGE/LIST分区了的表再进行HASH/KEY分区,适用于数据量非常大的数据记录:

103.   分区对NULL值的处理

Ø  RANGE分区当最小值处理

Ø  HASH/KEY当0处理

Ø  LIST分区中NULL必须出现在枚举值中,否则无法插入

104.   RANGE/LIST分区管理

Ø  alter table tbname drop partition p2; 删除分区并删除该分区数据

Ø  只能从RANGE分区列表的最大端增加分区,否则出错

alter tabletabname add partition(partition p4 values less than (20));

Ø  合并/拆分分区:alter table tbname reorganize partition p2[,p3,……] into (partition p4 values less than(2005)[,……]);重新定义分区时,只能够重新定义相邻的分区

105.   HASH/KEY

Ø  合并(减少)分区:alter table tbname coalesce partition 2;减少到2个分区。不能用来增加分区

Ø  增加分区:alter table tbname add partition 8;增加8个分区,而不是增加到8个

第三部分  优化篇

第18章    SQL优化

106.   用 mysql 命令获得一些服务优化信息(看是查询多还是增删改多):

(1)show [session|global] status like'com_%'; 默认是Session。 #主要看 com_select,com_insert,com_update,com_delete统计结果,查到都是本次会话结果|本次服务启动后的所有结果

(2)就想查看 innodb 存储引擎的这些信息:show status like 'innodb_rows_%'; 主 要 查 看innodb_rows_read,innodb_rows_inesrted,innodb_rows_updated,innodb_rows_deleted 这四个参数

(3)show status like 'connections'; #查看连接 mysql 服务器的次数

(4)show status like 'uptime'; #mysql 服务器的工作时间

(5)show status like 'slow_queries'; #慢查询的次数

107.   定位效率较低的SQL语句

Ø  使用--log-slow-queries[=file_name] 选项启动mysql时,会记录所有执行时间超过long_query_time秒的sql语句到日志文件。

Ø  使用show processlist;命令实时查看mysql当前线程状态,是否锁表等

108.   通过explain[extended]或者desc分析低效率SQL的执行计划(分析后可用 show warnings;得到优化后的sql语句):

explain partitions select …… 可查看分区使用情况

mysql>explain select * from t1 \G 或:

mysql>desc select * from t1 \G 主要查看以下属性:

(1)type (访问类型)是否用到索引

ALL index range ref eq_refconst,system  NULL 性能左至右,由最差到最好

(2)key 索引名称

(3)rows 查询影响的行数(越少说明优化的越好)

109.   通过show profile分析sql

Ø  开启profile: set profiling=1;

Ø  show profiles;得到query_id;

Ø  show profile for query query_id;展示语句执行过程中每个状态消耗的时间

110.   通过trace 分析优化器如何选择执行计划。p266

111.   索引优化问题:

Ø  一般的要加索引的字段为:where | order by后面字段

Ø  查看索引使用情况: mysql>show status like'handler_read%'; #如果其中handler_read_rnd_next 的值高则索引低效,需要去优化索引,而如果低则说明索引 高效.

112.   存在索引但是优化器没有使用(索引失效)的情况:

Ø  以%开头的Like查询无法使用B-Tree索引(应使用全文索引解决)

Ø  数据类型出现隐式转换时不会使用索引(列类型是字符串,where中要用'123',而不是123)

Ø  复合索引不满足最左索引时(最左匹配是B-Tree索引的首要原则)

Ø  MySQL估计使用索引比全表扫描更慢(表数据量很小时)或(筛选性越高越容易使用的到索引,比如like 'w%'使用全表扫描,而like'sw%' 使用索引)

Ø  or 前后列都有索引时才会用到索引

113.   实用的(表管理)优化方法

Ø  定期分析表和检查表:analyze|check table tbname;刷新系统的统计信息使其能够做出正确的执行计划|检查表(视图)是否有错

Ø  定期优化表:optimize table tablename;对含有变长类型varchar等的表进行大量删除后,留下的碎片进行整理。

114.   常用SQL的优化

Ø  Select col1,col2,…… 而不是 select * from 只选择必要字段

Ø  insert优化:

(1)大批量数据的导入优化: 前后执行以下操作

alter table t1 disable keys | alter table t1 enable keys;

mysql>set unique_checks=0; | msyql>set unique_checks=1;

mysql>autocommit=0; |  mysql>autocommit=1;

(2)当一个文件装载一个表时,用 load data infile 要比很多 insert 语句快 20 倍,而 mysqlimport 这种导入也很快,因为它用的本来就是 load data infile 这种函数接口.

(3)优化 insert 语句,最好用一行多值的这种形式:

insert into t1(name) values(1),(2),(3)

Ø  order by 优化p289:尽量减少额外的排序,通过索引直接返回有序数据。Where条件和order by 使用相同的索引,并且orderby 的顺序和索引的顺序相同(组合索引时),并且order by 的字段都是升序或者都是降序。否则需要额外的排序

Ø  查询包括 groupby 但如何避免排序结果的消耗:

mysql>desc select id from t1 group by idorder by null \G

Ø  优化嵌套查询:

(1)mysql>desc select * from t1 wheres_id not in (select id from comany2) \G

(2)mysql>desc select * form t1 left joincompany2 on t1.s_id=comany2.id where t1.s_id is null \G #以上 leftjoin 这种形式明显快于 not in ()这种子查询,因为 join 不需要在内存中建立临时表来 完成这个逻辑上需要两个步骤的查询工作.

Ø  分页查询优化思路:

(1):在索引上完成排序分页操作,最后根据主键关联回原表查询所需要的其他列。

(2):记录上一页最大/小值,将limit m,n 转为where id limit n; (该方法只适用于排序字段不会出现重复值时)

Ø  sql 索引提示:

(1)use index

mysql>desc select * from t1 use index (ind_id) where id=3 \G

(2)ignore index

mysql>desc select * from t1 ignore index (ind_id) where id=3\G

(3)force index

mysql>desc select * from t1 force index (ind_id) where id>0 \G #注意这种 where 后这种带范围判断的字段的索引是不起作用的,但可以人为的强制去用 index,虽然使用索引效率不是最高,这是 mysql 留给用户的一个自行选择计划的权力而已.

Ø  与删除表有关的优化: 用truncatedelete两种方法都可以把表中数据清空,但是用truncate明显比delete速度要快,而且节省内存

115.   什么叫做覆盖索引?

索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。

是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)。

  MySQL只能使用B-Tree索引做覆盖索引

当发起一个被索引覆盖的查询(也叫作索引覆盖查询)时,在EXPLAIN的Extra列可以看到“Using index”的信息

116.   SQL中使用正则表达式 REGEXP

select 'abcdefg' REGEXP '^a';结果为1

select * from where colname REGEXP '@163[,.]com$';

117.   使用RAND()提取随机行

select * from tbname order by rand()[ limit count_num ];

118.   MySQL数据库对应操作系统下的目录,表对应一个或多个文件。操作系统的大小写敏感决定了数据库名和表名的大小写敏感性。(window不敏感,Unix敏感)。列、索引、存储程序和触发器名在任何平台都对大小写不敏感。

第19章    优化数据库对象

119.   优化表的数据类型

select * from tablename procedure analyse();让mysql给出优化建议

120.   垂直拆分和水平拆分

Ø  垂直拆分:某些列常用,某些列不常用。查询时减少io次数。缺点是需要管理冗余列,查询所有数据时需要联合join操作

Ø  水平拆分:表数据量很大、表中分别记录不同时期或不同地区数据,有的数据常用,有的不常用。缺点给应用增加复杂度,需要union操作

121.   使用逆规范化加快查询(增加冗余列等)

122.   使用中间表提高统计速度(统计时不会影响线上应用,可以对中间表增加索引或者新列提高效率和辅助查询)

第20章    锁问题

123.   MyISAM和MEMORY采用表级锁,InnoDB采用行级锁(默认),也支持表级锁

Ø  表级锁(应用最广泛):开销小,加锁快,不会出现死锁总是一次获得sql语句所需要的全部锁),锁定粒度最大,发生冲突概率最高,并发度最低。适用于以查询为主,少量更新的应用。

Ø  行级锁:开销大,加锁慢,会出现死锁,锁定粒度最小,发送锁冲突概率最低,并发度最高。

Ø  页面锁(BDB存储引擎【已被innoDB取代】支持):会死锁,开销和粒度位于表级和行级之间

124.   查询表级锁争用情况:showstatus like 'table%';

如果Table_locks_waitd值比较高,说明存在较严重的表级锁争用情况

125.   表级锁模式locktable tbname read|write;…… unlock tables;

Ø  表共享读锁:读与读可以共享

Ø  表独占写锁:写与读,写与写之间必须串行(其他线程阻塞)

126.   MyISAM执行查询(select)前会自动给涉及的所有表加读锁,在执行更新操作(insert/update/delete)前会自动给涉及到的表加写锁。显式加锁可以实现某一时间点对多个表读取的一致性。

127.   同一个表一个语句中出现多次时,要通过与SQL语句中相同的别名锁定多次,否则会出错:

lock table tb2 as a read,tb2 as b read;

128.   并发插入(解决对同一个表查询和插入的锁争用):

Ø  Session1:lock tabletbname read local; 当前Session无法访问其他Session并发插入的数据行。

Ø  Session2:其他线程虽然不能对tbname表进行更新和删除操作,但是可以在尾部进行并发的插入操作。

129.   MyISAM锁调度:

Ø  写进程优先获得锁,即使其比读进程后来到锁等待队列。(因此,MyISAM不太适合有大量更新操作和查询操作的应用)

Ø  为防止大量更新操作导致查询操作很难得到读锁,有以下方式:

130.   事务的acid属性

Ø  原子性:一个事务包含多个操作,这些操作要么全部执行,要么全都不执行

Ø  一致性:一致性是指事务使得系统从一个一致的状态转换到另一个一致状态。(如果你做个银行数据库的话,无论怎么转账,钱的总数都不变)

Ø  隔离性:并发事务之间互相影响的程度,比如一个事务会不会读取到另一个未提交的事务修改的数据

Ø  持久性(Durability): 事务提交后,对系统的影响是永久的

131.   并发事务问题:

Ø  更新丢失:俩事务同时修改同一份数据,后保存的覆盖了先保存的

Ø  脏读:事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,如果事务A提交失败,事务B读到的就是脏数据。

Ø  不可重复读:在同一个事务中,对于同一份数据读取到的结果不一致。比如,事务B在事务A提交前读到的结果,和提交后读到的结果可能不同。不可重复读出现的原因就是事务并发修改记录,要避免这种情况,最简单的方法就是对要修改的记录加锁,这回导致锁竞争加剧,影响性能。另一种方法是通过MVCC可以在无锁的情况下,避免不可重复读。

Ø  幻读:在同一个事务中,同一个查询多次返回的结果不一致。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。需要将事务串行化,才能避免幻读。

132.   数据库实现事务隔离的方式

Ø  加锁

Ø  MVCC(MultiVersion Concurrency Control)多版本并发控制(乐观锁???)

133.   隔离级别(下面4种MySQL都支持)

Ø  未提交读Read Uncommitted:最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。

Ø  已提交读Read Committed:只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。

Ø  可重复读Repeated Read:在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读

Ø  可串行化Serializable:事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题

134.   隔离级别的选用:

Ø  尽量使用较低的隔离级别,以减少锁争用的机率

Ø  通过优化逻辑,大部分应用使用Read Committed隔离级别就够了

Ø  修改隔离级别:set session transaction isolation level repeatable read|serializable;

135.   获取InnoDB行锁争用情况

Ø  show status like 'innodb_row_lock%';结果中的InnoDB_row_lock_waits和InnoDB_row_lock_time_avg的值高的话,说明锁争用严重

Ø  查看 information_schema.innodb_locks表

Ø  设置InnoDB Monitors观察锁冲突p327

136.   InnoDB行锁模式

Ø  共享锁(S):允许事务去读某些行,阻止其他事务获得相同数据集的排他锁

Ø  排他锁(X):允许更新相关行,阻止其他事务获得S或者X锁

意向锁(表锁)是InnoDB自动加的,不需要用户干预

Ø  意向共享锁(IS):加共享锁时必须取得该表的IS锁

Ø  意向排他锁(IX):加排他锁时必须取得该表的IX锁

137.   加锁语句

对于update、delete、insert语句InnoDB会自动给涉及数据集加排他锁(X);

对于普通select语句InnoDB不会自动加锁,显示加锁如下:

Ø  共享锁(S): select * from tbname where …… lock in share mode;

Ø  排他锁(X):select * from tbname where …… for update;

Ø  commit;释放锁(获得锁之前设置setautocommit=0;)

138.   死锁示例:P329

两个Session都对同一记录获取S锁,再都对这条记录进行update,结果都等待获取X锁而产生死锁,发生死锁时,会导致某Session自动退出释放锁。

139.   InnoDB 行锁实现方式:

Ø  通过给索引上的索引项加锁来实现,如果没有索引,将通过隐藏的聚簇索引来对记录加锁。

Ø  如果不通过索引条件检索数据,InnoDB将对表中的所有记录加锁,等同于表锁

Ø  Next-Key锁(防止“幻读”):对于键值在条件范围内但实际并不存在的记录,叫做“间隙”。当加锁时用的是范围条件而不是相等条件检索数据时,InnoDB会给符合条件的数据记录的索引项加锁也会对间隙加锁,这就是Next-Key锁。

140.   MySQL通过BINLOG记录执行成功的insert update delete等更新数据的sql语句,并由此实现MySQL数据库的恢复和从主复制。

141.   InnoDB使用表锁的情况(默认应使用行级锁,事务和行级锁往往是选择InnoDB的理由)

Ø  事务需要更新大部分或者所有的数据

Ø  事务涉及多个表,比较复杂,很可能引起死锁。

142.   InnoDB死锁处理方法

Ø  InnoDB 一般能自动检测到,并使一个事务释放锁并回退,另一个事务获得锁,继续完成事务

Ø  设置锁等待超时参数innodb_lock_wait_timeout来解决

143.   InnoDB死锁避免方法:

Ø  不同程序并发访问多个表时,约定相同的顺序访问,降低死锁概率

Ø  批处理数据时,实现排好序,保证每个线程按固定的顺序处理记录,……

Ø  如果需要更新记录,应直接申请足够级别的锁(排他锁),而不是先申请共享锁,更新时再请排他锁。

Ø  尽量使用小事务,锁冲突概率小

Ø  尽量使用相等条件访问数据,避免Next-Key锁对并发插入的影响。

Ø  对于复杂事务采用表锁来提高处理速度和减少发生死锁概率。

144.   查看隔离级别:select @@tx_isolation;

145.   查看最后一个死锁产生的原因:showinnodb status \G;

第21章    优化MySQL Server

146.   MySQL 内存优化原则

Ø  将尽量多的内存分配给MySQL做缓存(前提给OS和其他程序留够足够内存)

Ø  MyISAM的数据文件读取依赖于操作系统自身的IO缓存,需要预留更多内存给系统IO缓存

Ø  排序区、连接区等缓存是给每个数据库会话专用的,其默认值要根据最大连接数合理分配,如果太大,不但浪费内存资源,并发高时会导致物理内存耗尽。

147.   MyISAM内存优化

Ø  建议至少将1/4的可用内存分配给key_buffer_size: key_buffer_size=4G

Ø  使用多个索引缓存,利用配置文件在MySQL启动时自动创建并预加载索引缓存

hot_cache.key_buffer_size=2G

cache index tablename in hot_cache;

load index into cache tablename;

Ø  调整“中点插入策略”:set globalkey_cache_division_limit=70;  p355

Ø  调整read_buffer_size(经常顺序扫描时)和read_rnd_buffer_zize(经常做排序时);

148.   InnoDB内存优化

Ø  专用数据库服务器可将80%的物理内存分配给InnoDB buffer pool:  设置 innodb_buffer_pool_size

Ø  ……p357

149.   redo log 是innodb保证事务ACID属性的重要机制

150.   调整MySQL并发参数

Ø  调整max_connections提高并发连接

Ø  调整thread_cache_size控制MySQL缓存客户线程的数量

Ø  调整innodb_lock_wait_timeout,而控制innodb事务等待行锁的时间,需要快速反馈交互时调小,后台批处理操作时跳大以避免回滚

第22章    磁盘IO问题

151.   io优化思路

Ø  使用磁盘阵列RAID

Ø  使用虚拟文件卷或者软RAID

Ø  采用符号链接(Symbolic Links)分布I/O

Ø  禁止Linux操作系统更新文件的atime属性

Ø  使用裸设备(raw device)存放InnoDB的共享表空间

Ø  调整I/O调度算法(建议MySQL环境设置为deadline调度算法)

Ø  RAID卡充放电时,会禁用write back功能,性能下降(业务量低时,手动触发充放电;或设置Forced writeBack 写策略)

152.   Linux系统,ln命令用来为文件创件连接,连接类型分为硬连接和符号连接(软连接)两种,默认的连接类型是硬连接。如果要创建符号连接必须使用"-s"选项。

Ø  硬链接:建立硬链接时,在另外的目录或本目录中增加目标文件的一个目录项,这样,一个文件就登记在多个目录中。ln命令会增加链接数,rm命令会减少链接数。一个文件除非链接数为0,否则不会从文件系统中被物理地删除。

Ø  符号链接:符号链接也称为软链接,是将一个路径名链接到一个文件。符号链接事实上只是一个文本文件,其中包含它提供链接的另一个文件的路径名。另一个文件是实际包含所有数据的文件。所有读、写文件内容的命令被用于符号链接时,将沿着链接方向前进来访问实际的文件。

153.   裸设备:也叫裸分区(原始分区),是一种没有经过格式化,不被Unix/Linux通过文件系统来读取的特殊字符设备。它由应用程序负责对它进行读写操作。不经过文件系统的缓冲。裸设备可以绑定一个分区,也可以绑定一个磁盘。

因为使用裸设备避免了在经过unix操作系统这一层,数据直接从disk到mysql之间进行无缝传输,所以使用裸设备对于读写频繁的数据库应用来说,可以极大的提高数据库系统的性能

第23章    应用优化

154.   优化思路

Ø  使用连接池(建立数据库连接代价较昂贵)

Ø  减少对MySQL访问(避免重复检索数据、使用MySQL查询缓存、Web加Cache层(redis、EhCache等))

Ø  数据库负载均衡(利用MySql主从复制分流查询;采用分布式数据库架构MySQL CLUSTER)

第四部分  管理维护篇

第24章    MySQL高级安装和升级

155.   安装方式(启动MySQL:bin/mysqld_safe –user=mysql &)p388:

Ø  安装RPM包:无法设置路径安装最简单

Ø  安装编译后的二进制包:折中方案

Ø  安装源码包:配置灵活,性能最优

156.   安装相关linux命令

Ø  安装rpm包:rpm -ivh ****.rpm

Ø  添加用户组  groupaddmysql

Ø  添加用户 useradd -g mysql mysql

Ø  常用解压命令  tar -xzvf ***.tar.gz

Ø  符号链接:  ln-s mysql-**-os  mysql

Ø  改变文件主 chown -r root var  #  -r递归

Ø  改变用户组 chgrp -r root .  

在linux中,&和&&,|和||介绍如下:

Ø  &  表示任务在后台执行,如要在后台运行redis,则有 redis-server &

Ø  && 表示前一条命令执行成功时才执行后一条命令 ,如 echo '1‘ && echo '2'   

Ø  | 表示管道,上一条命令的输出作为下一条命令参数,如 echo 'yes' | wc -l

Ø  || 表示上一条命令执行失败后才执行下一条,如cat nofile || echo "fail"

157.   MySql配置文件加载顺序,后面的会覆盖前面的

--defaults-extra-file是MySQL启动参数

修改参数的三种方式:

Ø  mysql> set para_name=value;   仅本Session有效

Ø  mysql> set global para_name=value;   本Session无效,新连接有效,MySQL重启后失效

Ø  修改my.cnf或者my.ini 永久有效

158.   MySQL备份数据

mysqldump –-tab=DUMPDIR db_name  #导出数据 -tab表示分别生成.sql 和.txt 分别表示创建语句和纯数据文本

mysqlimport db_name DUMPDIR/*.txt ;    #加载数据

159.   MySQL升级时,数据库迁移(MyISAM引擎可直接复制文件.frm/.MYD/.MYI)P392

第25章    MySQL中的常用工具

160.   mysql客户端连接工具

Ø  大写P端口,小写p密码

Ø  --default-character-set=utf8 设置默认字符集

Ø  -e "sqlquerytext"或者 --execute="sqlquerytext" 连接后直接执行

Ø 

Ø  -f多语句时,遇错误继续执行下句

Ø  mysql -uroot test  :连接MySQL,顺便在test数据库下执行a.sql

Ø  my.cnf里面[client]组内可以配置用户名密码

[client]

user=z1

password=z222

161.   mysqladmin(MySQL管理工具,功能与mysql类似,侧重于管理,例如关闭数据库),可执行命令有flush-privileges/processlist/killid/等p404

mysqladmin -uroot -p shutdown 关闭数据库

162.   myisampack(MyISAM表压缩工具,压缩率高,单压缩后,表只能读取)

163.   mysqlhotcopy(MysISAM表热备份工具,是Perl脚本,速度快但需要Unix或Linux环境且只用于MyISAM引擎)

它使用lock tables/flushtables/cp或scp 快速备份数据库,用法如下:

mysqlhotcopy db_name[dbname2……] [/path]

164.   mysqlcheck(MyISAM表检查修复维护工具)

165.   mysqlbinlog(日志管理工具)

166.   mysqldump(数据导出工具)

Ø  mysqldump [options] db_name [tables]

Ø  mysqldump [options] –-database DB1 [DB2,……]

Ø  mysqldump [options] –-all-database #备份所有数据库

Ø  -T 参数创建 tab分割的文本文件,--fields-terminated-by=name设置字段分隔符

167.   mysqlimport(数据导入工具)

LOAD DATA INFILE也可导入文本数据

mysqlimport [options] db_name textfile1[textfile2……]

168.   mysqlshow(数据库对象查看工具)

mysqlshow [options][db_name[tablename[colname]]]

Ø  不加选项显示所有数据库 mysqlshow -uroot -p

Ø  --count显示数据库和表的统计信息

Ø  -k或者--keys显示指定表所有索引

169.   perror(错误查看工具)

170.   replace(文本替换工具)

Ø  replace from to[from to]…… --filename[filename2]……

Ø  replace from to[from to]…… < filename

将文件filename中的from字符串全部替换为to字符串。区别是第二种 < 只是把文件作为输入,文件内容不会改变

171.   Linux 的more命令查看文本文件,sed利用script来处理文本文件,nl 命令可以输出文本文件并加上编号

第26章    MySQL日志

172.   4种主要日志(还有undo log/redo log保持事务持久性用的):

Ø  错误日志--error_log=filename;记录mysql启动和停止及运行时的严重错误

Ø  二进制日志 --log-bin[=filename]:记录所有的DDL和DML语句但不包括查询,对于灾难时的数据恢复起着及其重要的作用

三种格式,可通过--binlog_format参数设置

1)  STATEMENT(记录SQL语句,缺点当客户端采用了不确定函数如current_user()时会导致主从数据库不一致)、

2)  ROW(记录变化的数据行,缺点日志量大)

3)  MIXED(混合前两种模式,目前默认采用

日志删除:

1)  【优选】参数--expire_logs_days=3;设置日志文件保留日期,3天后自动删除

2)  RESET MASTER;命令删除所有binlog

3)  PURGE MASTER LOGS TO 'mysql-bin.000006';将000006编号之前的日志删除

4)  PURGE MASTER LOGS BEFORE'yyyy-mm-dd hh24:mi:ss';删除此日期前的日志

Ø  查询日志  --general_log=1;--general_log_file=filename;

Ø  慢查询日志 --slow_query_log=1;slow_query_log_file[=file_name];所有执行时间超过long_query_time(单位秒,默认10秒)并且扫描记录数大于min_examined_row_limit的所有SQL语句日志。使用mysqldumpslow工具可对慢查询日志进行分类汇总,便于查看(只是变量不一样的SQL视为同一个SQL)

173.   第三方MySQL日志分析工具mysqlsla(sla,Statement Log Analyzer)可查看各种日志,较方便P433

第27章    备份与恢复

174.   MySQL备份主要分为逻辑备份(对不同存储引擎用相同的方法备份)和物理备份(基于文件复制,不同存储引擎备份方法不同)

175.   备份策略:

Ø  区分表的存储引擎是事务型或非事务型

Ø  全备份(只需要保持最新备份,恢复时间短)还是增量备份(需要全备份加日志,恢复时间长)

Ø  定期备份在系统负载小时备份

Ø  确保打开MySQL的log-bin选项,产生BINLOG才能恢复

Ø  复制不能代替备份,无法处理误操作

176.   逻辑备份:mysqldump见25章,MyISAM引擎时需要-l来用读锁锁定所有表,保证数据一致性

Ø  完全恢复时,需要恢复某一个备份,还要将备份后执行的日志进行重做:

Ø  基于时间点的恢复:利用mysqlbinlog的--stop-date和--start-date参数

Ø  基于位置的恢复:利用mysqlbinlog的--stop-position和--start-position

177.   物理备份比逻辑备份快(基于文件复制)分为冷备份和热备份

Ø  冷备份适合(MyISAM和InnoDB):停服务,备份数据文件和日志。恢复时,先停服务恢复文件,再启用MySQL服务,使用mysqlbinlog恢复自备份以来的binlog

Ø  热备份(对要备份的表加读锁,再复制文件,无需停MySQL服务):

1)  MyISAM热备份:使用mysqlhotcopy工具或者给所有表加读锁(flush tables for read;)后复制数据文件到备份目录。

2)  InnoDB热备份:第三方工具(ibbackup[收费]或Xtrabackup【免费开源,支持MyISAM和InnoDB】)P443

178.   导出数据为文本文件(CSV都好分割)而不是sql,优点(excel显示,节省空间,导入数据库速度快【LOAD DATA比普通SQL快20倍】),方法如下:

Ø  方法一:SELECT……INTO OUTFILE 命令

Ø  方法二:mysqldump

mysqldump除了生成tbname.txt还会生额外成表的创建SQL文件tbname.sql

179.   纯文本数据导入:P457

Ø  LOAD DATA [LOCAL] INFILEfilename INTO TABLE tablename命令

Ø  mysqlimport工具

mysqlimport -uroot -p*** [--LOCAL] dbname filename.txt[options]

LOCAL参数表示,文件在客户端,上传到服务器端读取,如果不指定LOCAL参数,则表明文件在服务器端,直接由服务器读取。

第28章    MySQL权限与安全

180.   MySQL权限系统

Ø  登录认证【通过“mysql”数据库user表对ip地址和用户名联合认证】

Ø  用户权限管理【"mysql"数据库中有3个权限表(user/db/host[不常用])】,按照user->db->tables_priv->columns_priv表的顺序读取用户权限,权限范围逐渐缩小,全局权限覆盖局部权限

grant select on *.* to z1@localhost;

revoke select on *.* to z1@localhost;

181.   账号管理

创建账号:

Ø  【优选】grant语句直接创建[用户不存在时,创建用户;存在时增加权限]

grant allprivileges on *.* to 'z2'@'%' identified by '123'  ……授予所有权限,%代表所有ip,用户名z2,密码123

Ø  直接操作mysql.user表 插入用户名,密码(password(***)),然后使用flushprivileges;刷新权限

182.   MySql的权限如下表所示:

Ø  ALL   除GRANT OPTION外的所有权限

Ø  ALTER   使用ALTER TABLE

Ø  ALTER ROUTING   使用ALTER PROCEDURE和DROPPROCEDURE

Ø  CREATE 使用CREATE TABLE

Ø  CREATE ROUTING  使用CREATE PROCEDURE

Ø  CREATE TEMPORARY TABLES  使用CREATE TEMPORARY TABLE

Ø  CREATE USER  使用CREATE USER、DROP USER、RENAME USER和REVOKE ALL PRIVILLEAGES

Ø  CREATE VIEW  使用CREATE VIEW

Ø  DELETE 使用DELETE

Ø  DROP  使用DROP TABLE

Ø  EXECUTE  使用CALL和存储过程

Ø  FILE  使用SELECT INTO OUTFILE和LOAD DATA INFILE

Ø  GRANT OPTION 使用GRANT和REVOKE

Ø  INDEX 使用CREATE INDEX和DROP INDEX

Ø  INSERT 使用INSERT

Ø  LOCK TABLES  使用LOCK TABLES

Ø  PROCESS  使用SHOW FULL PROCESSLIST

Ø  RELOAD 使用FFLUSH

Ø  REPLICATION CLIENT 服务器位置的访问

Ø  REPLICATION SLAVE  由复制从属使用

Ø  SELECT 使用SELECT

Ø  SHOW DATABASES  使用SHOW DATABASES

Ø  SHOW VIEW 使用SHOW CREATE VIEW

Ø  SHUTDOWN  使用mysqladmin shutdown(用来关闭MySQL)

Ø  SUPER 使用CHANGE MASTER、KILL、LOGS、PURGE、MASTER和SET GLOBAL。还允许mysqladmin调试登录

Ø  UPDATE 使用UPDATE

Ø  USAGE 无访问权限,只可以登录

183.   查看权限:

Ø  show grants for user@host;

Ø  直接查看information_schema.SCHEMA_PRIVILEGES表

184.   收回权限:revoke语句 ,用法类似 grant

185.   修改密码:

Ø  mysqladmin -u user_name -h host_name password"new_pwd"

Ø  set password for 'jeff'@'%' = password('newpwd');

Ø  set password = password('newpwd');改自己密码

Ø  grant usage on *.* to 'jeff'@'%' identified by [password] 'pwd';加password关键字时,pwd要用md5计算过的字符串,这样不用明文更安全

Ø  直接修改mysql.user表,然后flushprivileges;刷新权限

186.   删除账号:

Ø  drop user;

Ø  直接操作mysql.user表,删除用户

187.   账号资源限制:

188.   MySQL安全问题

Ø  操作系统安全:

1)  mysql除了数据文件目录,其他文件和目录属主都改为root

2)  尽量避免以root权限运行MySQL

3)  创建用户时,如果用域名指定host列,可能受到DNS攻击

Ø  数据库安全

1)  删除匿名账户(安装时,默认有个空账户可以操作test数据库)

2)  给root账户设置口令

3)  设置安全密码(6位以上含字符数字下划线特殊字符)

4)  只授予必需的权限(而不是 all privileges)

5)  除root外,任何用户不应有mysql数据库user表的存取权限

6)  不要将FILE、PROCESS或SUPER权限授予管理员以外的账号

7)  Load Data Local安全问题P488

8)  MERGE存储引擎权限漏洞(B有表T的权限,创建一个包含T的MERGE表,当B对T的权限被收回时,B仍能通过MERGE表访问T的数据)

9)  Drop Table 命令并不回收权限,需手动回收(删表后,建同名表,以前有权限的还是有权限)

10) 使用SSL连接

11) 尽量给用户加上IP限制

12) Revoke命令漏洞(在同一个数据库上多次赋予权限,权限会自动合并,但是在不同数据库上多次赋予权限,不会自动合并。回收时必须分别回收)P494

第29章    MySQL监控

189.   监控目标:完成服务器中各种监控信息(CPU,内存,网络,数据库状态等)的采集、分析、存储,且支持快速的报警和信息发送

190.   常用网络监控工具:Cacti、Nagios、Zabbix+Fromdual插件P506【优选,开源、支持中文、配置简单、Email通知】等

191.   LAMP环境(Linux、Apache、MySQL、PHP)

第30章    MySQL常见问题和应用技巧

192.   忘记root 密码时,用--skip-grant-tables选项重启MySQL服务,跳过认证,用root登录无需密码,然后通过setpassword=password('123');flush privileges

193.   MyISAM表损坏时(1.使用myisamchk工具;2.SQL命令:CHECK/REPAIR TABLE)

194.   MyISAM表超过4G无法访问:alter table tbl_name MAX_ROWS=10000000 AVG_ROW_LENGTH=15000,修改表的最大记录数和平均记录长度,因此改变最大size

195.   数据目录磁盘空间不足:

Ø  MyISAM引擎:创建表时,使用DATA DIRECTORY和INDEX DIRECTORY分别指定数据目录和索引目录的存储目录。如果表已创建,可以将表的数据文件和索引文件mv到磁盘空间充足的分区上,然后在原文件处创建符号链接即可。

Ø  InnoDB引擎:在MySQL配置文件中用innodb_data_file_path中增加文件:innodb_data_file_path=/home/ibdata1:2000M;/home1/ibdata2:200M:autoextend重启数据库生效

196.   Linux export命令用于设置或显示环境变量。在shell中执行程序时,shell会提供一组环境变量。export可新增,修改或删除环境变量,供后续执行的程序使用。export的效力仅及于该次登陆操作。

197.   客户端通过中继服务器访问某内网的MySQL数据库(使用SecureCRT或MySQL Proxy工具)

第五部分  架构篇

第31章    MySQL复制

198.   主从复制原理:将主数据库的DDL和DML操作通过二进制日志传到复制服务器(从库),然后在从库上对这些日志进行重做,保存主从同步。MySQL使用3个线程完成主从复制,Binlog Dump线程跑在主库上,I/O线程和SQL线程跑在从库上。

199.   MySQL复制优点:

Ø  【冗余】如果主库出问题,可快速切换至从库提供服务

Ø  【负载均衡】在从库执行查询操作,降低主库的访问压力

Ø  【便于备份】在从库上备份,避免备份对主库影响

200.   复制中的两种文件(二进制日志binlog,中继日志relay log)。中继日志格式与二进制日志一样,从库上的SQL线程执行完当前中继日志文件中的事件后,会自动删除中继日志。从库创建两个日志文件master.info和relay_log.info来保存复制进度,分别记录从库IO线程当前读取二进制日志binlog的进度和SQL线程应用中继日志的进度。

201.   二进制日志的三种格式(格式对应MySQL参数binlog_format)对应三种复制方式(Statement、Row、Mixed)

mysqlbinlog检查Row格式的binlog,会显示乱码,需要通过Base64解码后查看(参数: --v --base64-output=DECODE-ROWS

202.   常见复制的3中架构:

Ø  一主多从:用在读请求压力非常大时。实现读写分离,把实时性要求不高的的读请求通过负载均衡分布到多个从库上,降低主库读取压力。当主库异常时,可把一个从库切换为主库。

Ø  多级复制:随着从库的增加,主库的IO压力和网络压力会增长(每个从库在主库上有一个独立的Binlog Dump线程来发送事件)。多级复制解决了这个问题。【缺点】:经历两次复才到从节点,延时大。可用BLACKHOLE存储引擎,降低延时。(BLACKHOLE存储引擎不在磁盘存数据,只将DML操作记录在Bin LOG中,适合多级复制里的二级主库)

Ø  双主复制:适用于DBA做维护等需要主从切换的场景,在维护时,不影响服务。维护过程见P546.

203.   复制方式:

Ø  异步复制:

1)  保证主从数据库版本一致,在主库建用户,授予REPLICATION SLAVE权限,grant replicationslave on *.* TO 'repl'@'192.168.7.200' identified by '1234test'

2)  修改主库配置文件my.cnf,开启binlog,设置server-id。

[mysqld]

binlog = /home/mysql/log/mysql-bin-log.log

server-id = 1

3)  锁定所有表只可以读,保证得到一致性快照,flush tables with readlock;然后用show master status;命令得到二进制文件名和偏移量;备份数据库;unlock tables;

4)  恢复数据到从库,在从库中设置server-id=2;使用--skip-slave-start选项启动数据库;配置主库信息:

启动slave线程:startslave;

Ø  半同步复制:半同步复制是通过插件(semisync_master.so和semisync_slave.so)实现的(更好的保证二进制日志的完整性和安全性P552。异步复制时,主库执行完Commit提交操作后,在主库写入binlog日志后可成功返回客户端,无需等待binlog日志传送给从库。而半同步复制时,必须等待其中一个从库也收到Binlog事务并成功写入中继日志后,主库才返回Commit操作成功给客户端

1)  一般插件在$MYSQL_HOME/lib/plugin目录下,在主库上安装:install pluginrepl_semi_sync_master SONAME 'semisync_master.so';在从库上安装:install plugin repl_semi_sync_slave SONAME 'semisync_slave.so';

2)  在主库上打开半同步参数:

set global rpl_semi_sync_master_enabled=1;

set global rpl_semi_sync_master_timeout=30000;等30秒超时后自动转异步复制,如果网络状况恢复,会自动切换为半同步模式

3)  从库:set global rpl_semi_sync_slave_enabled=1;

4)  如果是异步复制改为半同步复制则需要重启主库IO线程:(新配置不需要重启)

STOP SLAVE IO_THREAD;START SLAVE IO_THREAD;

204.   iptables命令是Linux上常用的防火墙软件

205.   复制时的启动选项:

Ø  log-slave-updates:从库上的更新操作是否写进二进制日志,默认不打开,如果从库也要作为其他库的主库,则需要打开

Ø  master-connect-retry:主库和从库连接丢失时重试的时间间隔,默认60秒。

Ø  read-only:设置从库只能接受超级用户的更新操作,限制应用程序错误的对从库进行了更新操作。

Ø  replicate-do-db/replicate-do-table /replicate-ignore-db/replicate-ignore-table等:指定哪些库或表需要复制到从库。

Ø  slave-skip-errors:从库执行SQL出错时,逃过继续执行(默认会停止复制)

206.   维护:

Ø  查看从库状态:show slave status;可查看Slave_IO_Running和Slave_SQL_Running值是不是都为YES,如果有一个为NO则复制停止了

Ø  切换主从库

1)  在每个从库上,执行STOP SLAVE IO_THREAD;然后检查SHOW PROCESSLIST输出,直到状态是Has read all relay log.表示执行了所有的Relay Log

2)  在从库S1上执行stop slave;停止从服务,执行reset master;设置成主数据库。删除master.info和relay_log.info文件,否则下次还会启动为从库

3)  在其他各从库上执行:

stop slave;

change master to master_host='此处是S1的ip';

start slave;

4)  通知客户端将数据库地址切换到s1,如果之前的主库可修复,则配置为S1的从库

第32章    MySQL Cluster

207.   集群架构:

三种节点都是逻辑节点,可以在不同服务器,也可以在同一台服务器。

Ø  管理节点:只能有一个,对其他节点进行管理。通过config.ini配置文件配置数据节点位置,每个数据节点上保存数据的磁盘位置等信息。

Ø  SQL节点,存放表结构。可以有多个。应用不能直接访问数据节点,只能通过SQL节点去访问。

Ø  数据节点必须使用NDB 存储引擎存放数据,否则不会同步到其他节点。可以有多个

208.   MySQL Cluster访问过程:

209.   MySQL Cluster目前只支持Linux(不支持Windows),配置过程示例(详见P580):

Ø  安装Cluster软件包:SQL节点和数据节点必须下载Server包和Cluster storage engine包。管理节点必须下载Client包和Cluster storage engine management/basic tools/extra tools三个包。

Ø  管理节点配置:创建目录mysql_cluster,并创建文件config.ini,[NDB_MGMD]表示管理节点配置,只能有一个。[NDBD]:表示数据节点。[MYSQLD]表示SQL节点

Ø  SQL节点和数据节点配置。在my.cnf[MYSQLD]中加入ndbcluster,和ndb-connectstring=192.168.7.187等配置

210.   Cluster使用

Ø  节点启动顺序为:管理节点-> 数据节点-> SQL节点

Ø  shell下启动管理节点:ndb_mgmd -f ./config.ini

Ø  启动数据节点:ndbd --initial--ndb-connectstring=192.168.7.187:1186

Ø  SQL节点的启动,启动MySQL服务即可:./bin/mysqld_safe &

Ø  ndb_mgm命令进入控制台,ndb_mgm>show命令可查看集群状态

211.   Cluster关闭:ndb_mgm -e shutdown

212.   Cluster备份:

Ø  可以使用mysqldump在SQL节点备份。

Ø  也可以在管理服务器使用ndb_mgm工具下start_backup命令备份 ndb_mgm>start backup;备份的数据在各个数据节点

Ø  恢复时需在各个数据节点使用工具ndb_restore工具。详见P590

213.   Cluster日志管理:集群日志在配置文件config.ini所在的目录。在ndb_mgm命令行中,cluster_info命令查看当前日志状态,clusterlogon/off命令打开或者关闭日志。

第33章    高可用架构

214.   数据库高可用框架MMM和MHA

215.   MMM(Master-Master replication manager for MySQL)

Ø  是一套支持双主故障切换双主日常管理的脚本程序。

Ø  使用Perl语言开发。

Ø  双主复制业务上同一时刻值允许对一个主库进行写入(也可读),另一台备选主上提供部分读服务。

Ø  MMM一方面实现了故障切换的功能,也可以实现多个从库SLAVES的READ的负载均衡

Ø  MMM无法完全地保证数据一致性,适用于对数据一致性要求不是很高的场景

216.   MHA【优选】(MasterHigh Availability)

Ø  是目前在MySQL高可用方面相对成熟的解决方案,是一套高可用环境下故障切换主从提升的高可用软件。

Ø  MHA能在30秒内自动完成故障切换,并可最大程度保证数据的一致性(与MySQL半同步复制配合)

Ø  MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。

Ø  MHA主要支持一主多从架构,一个复制集群中最少有三台服务器,一主二从。

Ø  Manager节点定期探测集群中的master节点,当master节点故障时,可以自动将最新数据的SLAVE提升为新的master,其他SLAVE指向新的master。(整个过程对应用透明)

217.   scp命令用于Linux之间复制文件和目录。scp是 secure copy的缩写, scp是linux系统下基于ssh登陆进行安全的远程文件拷贝命令。

你可能感兴趣的:(MySQL)