Mysql介绍... 4mysql
登陆mysql mysql –u root –p【掌握】... 4linux
SQL语言... 4sql
DCL. 4shell
grant. 4数据库
revoke. 4express
DDL. 4windows
建库... 4缓存
删库... 4安全
Mysqldumpslow过滤日志(定位缩小范围)... 13
分析Explain(记重要的参数的含义,分析给出建议)... 15
Show processlist(第二阶段还会讲,看链接数等)... 17
运行状态分析(运行一段时间,看是否要打开或调整)... 20
关系型数据库
修改密码 mysqladmin –u root –p[oldpassword] password newpassword
使用客户端数据库管理软件 若是没法链接就执行
GRANT ALL PRIVILEGES ON *.* TO ‘用户名’@’%’ IDENTIFIED BY ‘密码’ WITH GRANT OPTION;
或者本身博客
(data control language):数据控制语言,用于控制不一样数据对象访问级别的语句。定义了数据库、表、列、用户的访问权限和安全级别(grant、revoke)【了解】
语法:grant 权限 on 数据库对象 to 用户;
Grant select on testdb.* to ‘user_1’@’%’;
revoke select on testdb.* from ‘user_1’@’%’;
(data definition languages):数据定义语言,数据库、表、索引等对象的定义(create、drop、alter、truncate、rename)【掌握】
create database dbname default charset=utf8;
drop database dbname
一、 create table table_name (col1 type1[not null] [primary key],col2 type2[not null],…);
二、 create table table_name1 like table_name2;建立一个与当前某各表结构类似的空表。
三、数值类型、日期时间、字符串
四、经常使用函数( 数值函数、字符串函数、日期时间函数、其余函数)
desc table_name;
drop table table_name;
alter table table_name
MODIFY col_name column_definition –修改字段类型
CHANGE old_col_name new_col_name definition –修改字段名称
ADD col_name column_definition –添加字段
DROP col_name;--删除字段
(data manipulation language):数据操做语言,用于增删改查记录,并检查数据完整性,(insert、delete、update、select)
insert into table1(field1,field2) values(value1,value2);
delete from table1 where 范围;
update table1 set field1=value1 where 范围;
select * from table1 where 范围;
select * from table1 order by field1,field2 [desc];
Select count(1) as totalcount from table1;
Select sum(field1) as sumvalue from table1;
Select avg(field1) as avgvalue from table1;
Select max(field1) as maxvalue from table1;
Select min(field1) as minvalue from table1;
内链接相对其余连接效率高。
Select col1,col2,….from table1,table2 where table1.col3=table2.col2;
外连接分为左外链接和右外链接。
左外链接:select col1,col2,….from table1 left join table2 on table1.col2=table2.col3;
右外链接:select col1,col2,….from table1 right join table2 on table1.col2=table2.col3;
Select * from table1 where col[in][=](select col2 from table2 where 范围);
mysqldump –u root –p 123123 ultrax > 20141210.sql;
# ultrax 备份的数据库名,20141210.sql备份的sql文件名
#视图 存储过程、函数都要备份
mysql –u root –p 123123 ultrax< 20141210.sql;
#命令不一样、符号不一样
MyISAM 【掌握】 |
5.5版本之前默认的存储引擎。 不支持事务、外键;适用于对事务完整性没有要求、以select、insert为主的应用。 |
Innodb 【掌握】 |
提供了具备提交、回滚、崩溃修复能力的事务安全。 对此MyISAM写的处理效率会差一些,而且会占用更多磁盘空间以保留数据和索引。 在并发条件下要求数据的一致性,数据准确性要求高的。 |
Memory 【了解】 |
使用存在内存中的内容来建立表。 每一个memory表只实际对应一个磁盘文件。此类型的表访问很是快,默认使用了HASH索引。可是一旦服务关闭,表中数据就会丢失。 对表的大小有限制,数据不能持久。一般用于更新不太频繁的小表。 |
视图是一种虚拟存在的表,对于使用视图的用户来讲基本上是透明的。在数据库中不占用存储空间。
一、 能够限制用户数据,聚焦特定数据
二、 能够简化查询操做。
三、 能够保护基本数据的安全性。
四、 能够合并分离数据,创建分区视图。
三种方法
1、Create view person_v as select * from table_name;
2、create view person_v as select id,name,age from table_name;
3、create view person_v[vid,vname,vage] as select * from table_name;
Show create view view_name;
原子性atomic,不能嵌套
一致性consistent
隔离性isolated
持续性druable
begin开始一个事务
Commit提交事务(只有提交以后才生效)
Rollback回滚事务
1. Mysql中只有innodb和dbd支持事务
2. ddl和dcl不能回滚。
3. 隐式提交ddl:create table、create database、lock tables、alter function、start transaction等
存储过程是事先通过编译并存储在数据库中一段sql语句的集合。
存储过程当中使用参数的类型:in out inout
delimiter $$
create procedure 存储过程名(参数列表)
begin
sql代码块
end
$$
drop procedure if exists 存储过程名;
注意事项:
一、 建立存储过程必需要有参数列表项,若没有参数使用空参“()”..
二、 删除存储过程时存储过程名后面没有“()”.
三、 定义变量语句: set @变量名=初始值。
call 存储过程名([参数]);
取bbs中指定日期的帖子,返回帖子数
存储过程调用者,在调用存储过程时传入的参数。
存储过程内部给调用者返回的参数。
调用者既能给存储过程传入参数,又能从存储过程获得返回参数。
IF(exPR1,expr2,expr3) #若是exPR1 为true,则返回exPR2,不然返回exPR3
WHILE expression DO
Statements
END WHILE;
索引是提升select操做性能的最佳方法。全部列类型均可以使用索引。每一个表至少支持16个索引。
注意:只对select有做用。
索引列:
一、最适合使用索引的列是出如今where子句中的列,或者链接子句中指定的列。
二、使用惟一索引。在惟一列上添加索引。
三、使用短索引。
四、不能滥用索引。索引不能添加太多。在修改表数据的索引须要更新,有的时候须要重构,比较耗时。
一、 创建在主键上。
二、 常常用在链接列上。
三、 常常须要排序的列上。
四、 使用在where子句的列上。
五、 在常常须要条件搜索的列上。
一、 不多使用的列。
二、 有不多不一样数值的列。
三、 当列的字段类型为text 、image、bit时,不添加索引。
四、 当修改远大于检索时。(涉及到索引更新或重构)。
一、 隐式转化致使索引失效。
二、 <>、not in、not exists、!=、like 致使索引失效。
三、 对索引列进行运算(+、-、*、\、!=),致使索引失效。
例如:select * from table1 where age+3=10;
四、 不要在sql中使用双引号。
五、 不要将空值与运算符进行比较。 应使用 is null 、is not null
当给一张表的某列建立主键时,就会给该列添加主键索引。
Alter table table_name ADD PRIMARY KEY (col_list);
不能使用create index 的方式为表添加主键索引。
索引的列是惟一的并且不能存在null值。
两种建立方式:
直接建立索引:
Create index index_name ON table_name(col_list);
经过修改表,为表添加索引:
Alter table table_name ADD index index_name (col_list);
ALTER TABLE article ADD INDEX X(category_id,comments,views);
建立方法:
1.create unique index index_name on table_name(col_list);
2.alter table_name add UNIQUE index_name(col_list);
惟一索引的列的值必须是惟一的,能够为空值。
Drop index 索引名 on 表名;
DROP INDEX X ON article;
Show index from 表名;
SHOW INDEX FROM article;
分类 |
特色 |
引擎 |
备注 |
表级锁 |
开销小、锁定力度大 发生冲突几率高,不会出现死锁。 |
Mysam memory |
|
行级锁 |
开销大、锁定力度小 发生冲突几率高,会出现死锁。 |
innodb |
常说的 死锁 |
页面锁 |
开销介于表级锁和行级锁之间,会出现死锁。 |
bdb |
没人用 |
Show status like ‘table%’;
#table_locks_waited和 table_locks_immediate状态变量来分析数据库的所竞争,table_locks_waited越高,所竞争越严重。
同一个查询器session锁表lock table 表名 write;
另外一个查询器session就不能使用;
第一个表释放unlock tables;后,另外一个查询器可查询。
Show status like ‘innodb_row_lock%’;
#获取innodb行锁争用状况;
#重点看innodb_row_lock_current_waits 、innodb_row_lock_time_avg
查询优化的实际 就是让优化器能按照预想的合理方式运行。
(根据现象肯定抓取范围---》定位排查缩小范围---》对定位出来的sql进行分析,肯定出问题----》给出建议)
每步的作法shell脚本(查看mysql服务器状态)、慢查询、
慢查询(重点)(抓取范围 和 定位)、explain分析
Mysql的配置文件my.cnf
1.Vi /etc/my.cnf #在最后添加
log-slow-queries=/var/log/mysql/slowquery.log #慢查询日志写哪里、需提早建好这路径、文件
long_query_time=2#超时阀值,默认是10 s。单位为 秒。
2.验证慢查询日志是否开启
show_variables like ‘%slow%’;
slow_query_log、 log_slow_queries为on,即为开启;
如未开启,在mysql 命令行中: set global log_slow_queries=ON;
日志内容
#Time时间戳
Query_time查询时间
Lock_time锁定时间
Rows_sent行数
Rows_examined
下面是捕捉出来的语句(正常是select语句,不要加没加索引的条件,由于log会太大)
mysqldumpslow –s c –t 3 –g “left join” /var/log/mysql/slowquery.log #记录中包含left join的
# -s 表示按照何种方式排序, c (访问次数)、t(时间)、 l(查询时间)、 r(返回记录数);ac 、at 、al 、ar,表示倒序;
# -t 表示取前面多少条记录
# -g 表示后面能够写一个正则匹配模式,不分大小写
1. Mysqldumpslow –s c –t 20 /var/log/mysql/slowquery.log #访问次数最多的20个sql
2. Mysqldumpslow –s r –t 20 /var/log/mysql/slowquery.log #返回记录集最多的20个sql
3. Mysqldumpslow –t 10 –s t –g “left join” /var/log/mysql/slowquery.log #按照时间返回前10条里包含left join的sql语句
4. Mysqldumpslow –s l –t 20 /var/log/mysql/slowquery.log #查询时间最长的20个sql
1.使用mysqldumpslow过滤查询日志,查看sql;
2.若是是模糊的查询条件,使用具体值替换;
3.用explain来分析sql;
(不必定是具体的sql :between N and N)定位出了问题,接下来用explain来分析
1.只能解释select操做
2不包括 触发器、存储过程的信息;不包括 用户自定义函数对查询的影响状况;
3.不考虑cache;
4.不能显示mysql在执行查询时所做的优化工做;
5.部分统计信息是估算的,不是精确值;
写sql时,where语句后面的mkey(varchar)=111,索引被转换了,没用上索引。致使type为all、row很大;改为=’111’,type变好了,key用的主键索引、row=1;
发现一个慢查询,查询时服务器io飙升,io占用率达到100%,执行时间长达7s。
思路典型:
1.抓到慢查询,同时监控了服务器 [ io占用率高 ];
2.explain分析(type all;key null没用索引、row也很大、extra usingfilesort、using temporary(临时表),猜想:内存放不下、放在磁盘,和磁盘交互增长,致使了io问题;
3.解决反馈开发、 dba :拆sql;
CREATE TABLE IF NOT EXISTS article (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
author_id int(10) unsigned NOT NULL,
category_id int(10) unsigned NOT NULL,
views int(10) unsigned NOT NULL,
comments int(10) unsigned NOT NULL,
title varbinary(255) NOT NULL,
content text NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO article
(author_id, category_id, views, comments, title, content) VALUES
(1, 1, 1, 1, '1', '1'),
(2, 2, 2, 2, '2', '2'),
(1, 1, 3, 3, '3', '3');
EXPLAIN
SELECT author_id FROM article WHERE category_id = 1 AND comments > 1 ORDER BY views DESC LIMIT 1;
优化:索引---放那些字段上加呢?索引的原则给字段加索引;再继续explain看状况。调整索引。再explain,直到调到满意。
Step 1.
where条件中使用了category_id 、comments 、views三个字段,给三个字段都加上索引;
Step 2.
由于comments检索用了> <符号,致使了索引无效,去掉此字段上的索引再试试。
Sleep |
一般表明资源未释放,可能会致使too many connections链接 |
|
Waiting for net,reading from net,writing to net |
偶尔出现也无妨,如大量出现,迅速检查数据库到前端的网络链接状态和流量 |
|
Locked |
有更新操做锁定。一般使用innodb能够更好的减小locked状态的产生 |
|
Copy to tmp table |
索引及现有结构没法涵盖查询条件,才会创建一个临时表来知足查询要求,产生巨大的io压力。很可怕的搜索语句会致使这样的状况,若是是数据分析,或周期性的数据清理任务,偶尔出现,可容许。频繁出现就要优化。一般与连表查询有关,建议逐渐习惯不使用连表查询。 |
|
Sending data |
并非发送数据,从物理磁盘获取数据的进程,若是影响的结果集较多,就要从不一样磁盘碎片去抽取数据,偶尔出现能够,若有链接较多,就要考虑优化查询的索引项。 |
|
Freeding items |
理论上不会出现不少,偶尔出现无妨。如大量出现,内存、磁盘可能已经出现问题,如磁盘满或损坏。 |
|
Sorting for |
同sending data |
slowmysql.sh
1.配置my.cnf 中,最后添加:
[client]
User=root
Password=123123
2.安装bc,yum install bc
3.chmod 777 –R slowmysql.sh
4.sh slowmysql.sh
执行完成后,会显示mysql
缺省最大链接数是100,调到更高只是为了出现问题时给咱们更多的缓冲时间而不是任其一直处于那么高的状态。
指标:max_connections设置的最大链接数;historic max_used_connections以往达到的最大链接数
(链接数设置多少---参数优化)
缓存sql文本和查询结果,若是运行相同的sql,服务器就直接从缓存中取到结果,而不须要再去解析和执行sql。将客户端提交给mysql的select类query请求返回结果集cache到内存中
若是表更改了【表中数据、结构的改变insert、update、delete、truncate、alter table、drop table、drop database】,那使用这个表的缓存的查询就失效,查询缓存值的相关条目被清空。
不常改变数据且有大量相同sql查询的表,设置query cache会节约很大性能。
查询必须是彻底相同的才能被认为是相同的。一样的查询字符串,因为其它缘由可能被认为是不一样的,使用不一样的数据库、不一样的协议版本、不一样默认字符集的的查询被认为是不一样的查询,而分别缓存。【需合理开启与设置query cache】
1 更改后失效2.要彻底相同
1. 编辑 my.cnf,添加:
query_cache_size=268435456 #设置query cache所使用的内存大小,默认值为0。大小必须是1024的整数倍。
query_cache_type=1 #给全部查询作cache
query_cache_limit=1048576 #容许cache单条query结果集的最大容量,默认是1MB,超过此参数设置的query结果集将不会被cache。
2. 重启mysql
SHOW VARIABLES LIKE '%query_cache%';
query_cache_limit : #容许cache单条query结果集的最大容量
query_cache_size :#query cache所使用的内存大小
query_cache_type :#控制query cache功能的开关,可设置为0 、1、2;
0(OFF) 关闭query cache,任何状况都不会使用query cache;
1 (ON) 开启 query cache,当select语句中使用SQL_NO_CACHE提示后,不使用query chache;
2(DEMAND) 开启query cache,仅当select语句中使用了SQL_CACHE提示后,才使用query chache。最灵活。
Show status like ‘%qcache%’;
Qcache_free_blocks :数目大说明可能有碎片
Qcache_free_memory:缓存中空闲内存
Qcache_hits:每次查询在缓存中命中时就增长
Qcache_inserts:每次插入一个查询就增长
Qcache_lowmem_prunes:缓存出现内存不足且必需要清理以便为更多查询提供空间的次数。这个数最好长时间来看;若是这个数字在不断增加,就表示可能碎片很是严重,或者内存不多。(上面的free_blocks和free_memory能够告诉你属于哪一种状况)
Qcache_total_blocks:缓存中块的总数量
命中率= Qcache_hits/(Qcache_hits+Qcache_inserts)
碎片率=Qcache_free_blocks/Qcache_total_blocks #如超过20%,可用flush query cache整理缓存碎片
利用率=(query_cache_size – Qcache_free_memory)/query_cache_size #低于25%说明query_cache_size设置的过大,可适当减少;高于80%,并且Qcache_lowmem_prunes>50,说明query_cache_size可能有点小,要不就是碎片太多。
Show global status;mysql服务器运行状态
日志满了-磁盘满-并发上来—磁盘不够
SHOW VARIABLES LIKE 'log_%'; #是否启用了日志
Show master status;日志状态
Show master logs;日志信息
问题:mysql:error 1040:too many connections
解决:访问量高—增长从服务器;配置中的 最大链接数。
查看链接数
#容许的最大链接数
SHOW VARIABLES LIKE 'max_connections';
#以往达到的最大链接数
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
比较理想的设置:Max_used_connections/max_connections*100% 大概85%
链接的状态:show full processlist;
sleep:线程正在等待客户端发送新的请求.
query:线程正在执行查询或正将结果发送给客户端。
locked:线程等待表锁
analyzing and statistics:线程正在收集存储引擎的统计信息,并生成查询的执行计划。
copying to tmp table [on disk]:线程正在执行查询,并将结果集都复制到临时表中,此状态通常要么是group by操做,要么是文件排序操做,或者是union操做。如这个状态后面还有 on disk标记,那表示mysql正将一个内存临时表放到磁盘上。
sorting result:线程正对结果集排序。
sending data:线程可能在多个状态之间传送数据,或生菜结果集,或在向客户端返回数据。
Key_buffer_size 是对MyISAM引擎的表影响大的参数。
#查看key_buffer_size参数设置的大小,单位b
SHOW VARIABLES LIKE 'key_buffer_size';
SHOW GLOBAL STATUS LIKE 'key_read%';
#计算索引未命中缓存的几率
Key_cache_miss_rate=key_reads/key_read_requests *100%
Key_cache_miss_rate在0.1%如下都很好,若是key_cache_miss_rate在0.01%如下的话,而key_buffer_size分配过多,能够适当减小。
#
SHOW VARIABLES LIKE 'table_open_cache';
#
SHOW GLOBAL STATUS LIKE 'open%tables%'
#Open_tables表示打开表的数量;opened_tables打开过的表数量(opened_tables大 说明配置的table_open_cache可能过小)
比较合适的值:Open_tables/Opened_tables*100%>=85%
Open_tables/table_open_cache*100%<=95%()
存储空间比例的计算,是否是过度使用,是否是不多使用但也占了很大存储空间
Show global status like ‘Handler_read_rnd_next’;
SHOW GLOBAL STATUS LIKE 'com_select';
表扫描率:Handler_reader_rnd_next/Com_select’
若是表扫描超过4000,说明进行了太多表扫描,有可能索引没建好[根本缘由];临时的解决增长read_buffer_size值(Show variables like ‘read_buffer_size’;)会有效,最好不超过8MB.(能够容纳内容进来,方便提取)
SHOW VARIABLES LIKE'read_rnd_buffer_size';
#进行随机扫描的时候使用buffer,可是太随机优化的东西都用不上,性能会不太好,遇到的比较少)read_rnd_buffer_size值适当的调大,对提升order by 操做的性能有必定效果
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
0 : log thread每隔1秒就会将log buffer中的数据写入到文件,同时还会通知文件系统进行文件同步flush操做,保证数据确实写入到磁盘上。比较看重性能,高并发写的日志服务器,设为0.
1: 通常为1。每次事务结束都会出发log thread将log buffer中的数据写入文件并通知文件系统同步文件。比较合理,性能稍差。
2 : log thread会在每次事务结束时,将数据写入事务日志,但写入仅仅调用了文件系统的文件写入操做。文件系统什么时间将缓存中的这些数据同步到物理磁盘,log thread就不知道了。对数据一致性、完整性要求不高时,设为2.
#每一个日志文件大小
SHOW VARIABLES LIKE 'innodb_log_file_size';
一个日志组中每一个日志文件的大小。在高写入负载尤为是大数据集的状况下很重要。这个值越大性能相对越高,但反作用是恢复时间加大,扫描恢复时间长。【可恢复的多,因此用时长】
通常64M—512M,具体取决于服务器的空间。
SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'interactive_timeout';
# wait_timeout 取值范围1-2147483(windows),1-31536000(linux);
#interactive_timeout取值随wait_timeout变更;
#默认都是28800s(8小时)、
#两个参数要一样的值、同时设置,timeout才会生效。
原理
主数据库负责写(一个主库集中写,保证了数据一致)、从库读(从库横向扩展,分流了压力)
实现
1.master打开二进制日志,将改变 记录到 二进制日志
2.slave将master的二进制日志拷贝到它的中继日志(relay log)。(slave开始一个工做线程—io线程,io线程在master上打开一个普通的链接,而后开始binlog dump process。从master的二进制日志中读取事件,如已经跟上master,会睡眠并等待maste产生新时间,io线程将这些事件写入中继日志)
3.slave重作中继日志中的事件。(sql线程从中继日志读取事件,并重放其中的事件而更新slave数据,和master中数据一致。只要该进程与io线程保持一致,中继日志一般位于os缓存中,因此中继日志开销小)
(创建在主从复制上。也是主从复制的目的)
(后面会讲、负载均衡 策略)
Session、mysql(query_cache 、命中率)表空间、日志
Top_session:当前正在运行的sql、
柱状图 summary—sql、逻辑io、物理io
数据库选型(mysql数据库、服务器os):sql(抓取定位分析)、架构(主从、分库分表)、参数(链接数、表扫描、超时、打开表数)
原则:never make a change in production first
Have a good benchmark or reable load
Start with a good baseline
Only change 1thing at a time
Identify a set of possible changes
Try each change separately
Try in combinations of 2 then 3 ,etc
Monitor the results
Query performance –query analyzer,slow query log,etc.
Throughput
Single query time
Average query time
Cpu
Io
Network
Document and save the results