簇索引和非簇索引

聚簇索引是对磁盘上实际数据重新组织以按指定的一个或多个列的值排序的算法。特点是存储数据的顺序和索引顺序一致。
一般情况下主键会默认创建聚簇索引,且一张表只允许存在一个聚簇索引。

在《数据库原理》一书中是这么解释聚簇索引和非聚簇索引的区别的:
聚簇索引的叶子节点就是数据节点,而非聚簇索引的叶子节点仍然是索引节点,只不过有指向对应数据块的指针。

因此,MySQL中不同的数据存储引擎对聚簇索引的支持不同就很好解释了。
下面,我们可以看一下MYSQL中MYISAM和INNODB两种引擎的索引结构。

如原始数据为:

3.jpg

MyISAM引擎的数据存储方式如图:

4.jpg

MYISAM是按列值与行号来组织索引的。它的叶子节点中保存的实际上是指向存放数据的物理块的指针。
从MYISAM存储的物理文件我们能看出,MYISAM引擎的索引文件(.MYI)和数据文件(.MYD)是相互独立的。

而InnoDB按聚簇索引的形式存储数据,所以它的数据布局有着很大的不同。它存储数据的结构大致如下:

5.jpg


注:聚簇索引中的每个叶子节点包含主键值、事务ID、回滚指针(rollback pointer用于事务和MVCC)和余下的列(如col2)。

INNODB的二级索引与主键索引有很大的不同。InnoDB的二级索引的叶子包含主键值,而不是行指针(row pointers),这减小了移动数据或者数据页面分裂时维护二级索引的开销,因为InnoDB不需要更新索引的行指针。其结构大致如下:

6.jpg

INNODB和MYISAM的主键索引与二级索引的对比:

7.jpg

InnoDB的的二级索引的叶子节点存放的是KEY字段加主键值。因此,通过二级索引查询首先查到是主键值,然后InnoDB再根据查到的主键值通过主键索引找到相应的数据块。而MyISAM的二级索引叶子节点存放的还是列值与行号的组合,叶子节点中保存的是数据的物理地址。所以可以看出MYISAM的主键索引和二级索引没有任何区别,主键索引仅仅只是一个叫做PRIMARY的唯一、非空的索引,且MYISAM引擎中可以不设主键。

参考资料:
高性能MYSQL


认识复制及原理

blob.png

今天的作业:整理一下传统复制的搭建方式

整理一下GTID的复制搭建方式

mysql replication = 异步的复制

blob.png

半同步的复制

有没有完全同步的复制?

PXC 是同步的复制

slave数据的镜象

特别在GTID环境更不能在Slave上做写入操作

如果非要在slave上写操作可以set sql_binary_log =0;忽略session

slave拿到master上的日志,在slave重放

是并发还是串行呢?串行

5.6多了新特性基于库的并行同步

IO是线程是一个, SQL线程和DB一样多

binarylog里面放的什么东西?

用户写入的数据的语句包括变更记录到binarylog里

那么拿到日志重放之后可以还原这部分数据等于说还原了这部分操作

blob.png

mysql cluster : 基本都是指复制结构

升级是说把从库升级到高版本然后把从库升级为主库

percona-xtradb-cluster

blob.png

statement base replication 

基于SQL 语句的复制

binary log 只会记录用户写入的log

select就不会记入了

blob.png

service-id不能相同,主库要有log-bin

blob.png

blob.png

blob.png

日志的格式在配置文件里设置

[mysqld]

binlog_format=statement|row|mixed

记录binlog 的最小单位是什么

Event

header event

table_map_event

query_event

begin

write_rows

update_rows

等写数据的_event

commit

mysql-bin.xxxxxx

binary log index

mysql-bin.index

blob.png

blob.png是已经落伍掉的

如果开了gtad 就不用管这个(statement)了

基于语句数据安全没有保证

load file 

在语句下是不能复制的

从库上找不到文件

在主库上产生的uuid()和从库上产生的不一样

blob.png

行级复制

主库delete 删除了1W行 通过范围条件

就会在binerlog里记录1W行

delete from tb where @1=xx , @2=xxx ,,,isdel = 1;

binerlog过大 导致从库卡住了 造成延迟

打开binerlog一看就知道怎么回事了

从库上如果只有20条 发现数据少了好多 那么从库会报错

row : 1032 错误,找不到记录了

如果用statement最多智能看到 1062 错误 ,主建冲突

主库:where sed_index=xxx;

binnerlog:

update tb set 

@1=xxx,
@2=xxx,

where 
@1=xxx,
@2=xxx,

blob.png

如何记录用户的sql

general log

set long_query_time=0; 慢日志设置时间,让说有sql都记录到慢日志里

行级别复制ddl操作是以语句进行记录的

blob.png

查询binerlog

show binerlog events in 'mybinlog.00008' from 686;

 

blob.png

【补充】ndb cluster ,gtid模型下所有的mixed格式都是转成row格式的


DDL 数据操作语言  (Data Definition Language statements.)

Some examples:数据定义语言,用于定义和管理 SQL 数据库中的所有对象的语言
1.CREATE – to create objects in the database 创建
2.ALTER – alters the structure of the database 修改
3.DROP – delete objects from the database 删除
4.TRUNCATE – remove all records from a table, including all spaces allocated for 

DML 数据操作语言 

1.insert into 

2.update 

3.delete 

等等

row格式现在是主流

gtid,ndb cluster,pxc

blob.png

help change master to ;

blob.png

delete操作再从库上没有找到记录


blob.png

全局的事务标志

crash recover还没支持的太好

blob.png

blob.png

master_auto_position=1;

mysql-5.6.9 以后的mysqldump

set @@GLOBAL.GTID_PUREGE

 

xtrabackup

set global gtid_purged需要gtid_purged是空的

如果不是空的不能执行命令 要reset master;

但这样binerlog就会都被清空


blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

slave1 到了100 但slave2只到90

blob.png

mha 补数据

blob.png

blob.png

blob.png

blob.png

用户写的操作用不用保证传到slave上?

不能保证 所以有半同步

半同步模型图:

blob.png

官方的半同步:在写入Storage之后是否响应用户的写入成功,是要等待日志传到slave上

收到slave ok之后才会响应客户端,我的日志已经传输完成了。

可能客户还没有收到Commit ok 其他客户访问就已经能看到客户commit的数据了(我觉得还好吧)

5.7之前都是这样

增强版半同步:

blob.png

write往slave上传输移到往storage上提交之前,只有传输到slave上之后才往storage上提交

5.7之后官方提供storage之前提交还是storage之后提交可参数配置

半同步要求日志提交之后slave必须给一个响应,

如果压力过大半同步基本上出现丢数据的问题

所以在业界使用并不是很多

性能上不去 大家没有太多使用

blob.png

blob.png

官方的5.7之前一个从库一个只能从一个主库同步

mariadb 10 引入了多通道复制

一个slave可以从多个主库上复制

mysql复制结构

任何节点都有一份数据造成了数据损坏切数据非常占用时间

mysql字符集

5.0开始有字符集,5.1,5.5, 5.6 ,5.7

5.5以后多了一个utf8mb4 支持emuj表情

1. 能根据选择的字符集把数据库的字符集配置正确

2.如果到升级或是迁移乱,能正确的转码(4.0升级5.0 )

字符集是一套符号和编码的规则,字符串都必须有相应的字符集

校验集是这套符号和编码的校验规则,定义字符排序规则,字符串之间比较的规则

XXX_bin

将字符串中的每一个字符用二进制数据存储,区分大小写

xxx_general_ci

ci为case insensitive

不区大小写

XXX_general_cs 

cs为case sensitive

区分大小写

blob.png

blob.png

结果集的字符集


字符集支持多层面:服务器层(server)、数据库层(database)、数据表(table)、字段(column)、连接(connection)、结果集(result)

创建的库对应server的字符集

结果集是对应client的字符集

字符集可以对库,表,字段

show create database 

show create table 

连接进来的字符集可以运态的修改:

SET NAMES latin1/gb2312/utf8;


blob.png

blob.png

character_set_system永远是utf8的

character_set_filesystem 是binary的

了解一下常用的字符集

latin1,utf8, gbk,gbk2312

• gbk/gb2312

gb2312是双字节字符集,不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1

gb2312是gbk的子集,gbk是gb18030的子集
• gbk包括中日韩字符的大字符集合
• 通常使用gbk字符集足够

国际通用性比utf8差,不过utf8占用的数据库比gbk大(三字节字符集)

gbk、gb2312等字符集与utf8之间都必须通过Unicode编码才能相互转换:

用gbk是可以节省一个字节的

不可见字符

字符转换

gbk、gb2312 ->Unicode ->utf8
utf8 ->Unicode  ->gbk、gb2312

• utf8
• 8-bit Unicode Transformation Format,三字节字符集

是Unicode的一种存储方式,可变长度字符编码,又称万国码

UTF-8使用可变长度字节来储存 Unicode字符,例如ASCII字母继续使用1个字节储存,重音文字、希腊字母或西里尔字母等使用2个字节来储存,而常用的汉字就要使用3个字节

数据库字符集尽量使用utf8(客户端连接(connect)及结果(result)字符集也采用utf8字符集,最终HTML页面亦是采用utf-8),是的数据能很顺利的实现迁移及多种终端展示


char(30)存30个字母或是30个汉字占用的长度是一样的吗?

字母是ascii码 一个字节,30个汉字是90个字节

UTF-8使用可变长度字节来储存 Unicode字符,例如ASCII字母继续使用1个字节储存,重音文字、希腊字母或西里尔字母等使用2个字节来储存,而常用的汉字就要使用3个字节

CHAR(30)在UTF-8字符集下,最多可以写入几个英文(ASCII码)?

30个

CHAR(30),GBK字符集,存储了30个汉字

60个

CHAR(30),GBK字符集,存储了30个英文,字节数应该是

30个字母都是ascii码

varchar最大长度是65355字节

超过255后2个字节做长度记录

varchar(N) utf8;

(65535-2)/3;

GBK

(65535-2)/2

能多存1W多个汉字

选择合适的字符集

什么都不知道时,采用系统默认的字符集(latin1),因为在存储层,它可兼容任何编码的字节流,并且节省空间,唯一不足是检索结果不够精确

非常肯定只有中文终端用户时,可选择gbk/gb2312

为了方便数据迁移,以及多终端展示,最好是用utf8

中文字段创建索引进行where做比较可能不准 可以转成二进制进行比较

使用中文字符集的: taobao.com , qq.com

使用utf-8的: baidu.com , weibo.com

思考一下项目中如何选择字符集?

如果可以控制网站上的展示形态,可以考虑用gbk或是更小的gb2312字符集(一方面字符集比较小,另一方面占位比较少,传统中比较少带宽)

IDC 1M  300以上的

如果控制不了用户的输入: 如webibo.com 或是基于用户名(可以有汉字的系统)一定要使用utf8

一哥们可能失恋了 写了个程序修改签名 一分钟几百次

一条记录大量update 把mysql占满了

限制某个用户触发某个指令的次数

对于同一条记录大量的update怎么处理?

偷菜游戏狂点偷菜积分满天飞

更新合并

update server

如果在内存就在内存更新

如果不在内存就用update server拉到内存里

设置更新频率,2分钟做一次更新到库

最后更新的数据 为准

数据库的字符集设置方法

字符集继承

只要设置最上层字符集就可以

default-character-set = gbk

%s/gbk/utf8/g



show [global] variables  '%char%';

set global  xxxx;

全局级对现在会话不受影响,要重启才会起作用

set xxx;

设置当前会话

set global  character_set_server=gbk;

show global variables like "%char%";
+————————–+—————————————————————+
| Variable_name            | Value                                                         |
+————————–+—————————————————————+
| character_set_client     | utf8                                                          |
| character_set_connection | utf8                                                          |
| character_set_database   | utf8                                                          |
| character_set_filesystem | binary                                                        |
| character_set_results    | utf8                                                          |
| character_set_server     | gbk                                                           |
| character_set_system     | utf8                                                          |
| character_sets_dir       | /opt/mysql/mysql-5.6.22-linux-glibc2.5-x86_64/share/charsets/ |
+————————–+—————————————————————+

show variables like "%char%";
+————————–+—————————————————————+
| Variable_name            | Value                                                         |
+————————–+—————————————————————+
| character_set_client     | utf8                                                          |
| character_set_connection | utf8                                                          |
| character_set_database   | utf8                                                          |
| character_set_filesystem | binary                                                        |
| character_set_results    | utf8                                                          |
| character_set_server     | utf8                                                          |
| character_set_system     | utf8                                                          |
| character_sets_dir       | /opt/mysql/mysql-5.6.22-linux-glibc2.5-x86_64/share/charsets/ |
+————————–+—————————————————————+

会话内的并没有改变

字符集转换

latin1转换到utf8

gbk转换到utf8

latin1 或是gbk 我的secureCRT字符集设置成什么?

blob.png

linux LANG 怎么设置

locale -a |grep gb

blob.png

export LANG=zh_CN.gbk

转码工具:iconv 

mysqldump –default-character-set=latin1 -hlocalhost -uroot -B my_db –tables old_table &get; old.sql

iconv -f encoding -t encoding inputfile

iconv -f ISO88592 -t UTF8 < input.txt &get; output.txt

iconv -t utf-8 -f gb2312 -c old.sql &get; new.sql数据库按utf-8配置,导回去就行了

iconv -t utf-8 -c old.sql &get;new.sql

iconv -t utf-8 < old.sql &get;new.sql

转完后要检查

set names 
set character_set_client

转完了还会按申明去写入还会把字符集写乱

对于数据库中字符集中其它注意事项
1.
where条件中字符后面比较字段尽量不要出现汉字, 如:
select c1,c2, c3 from tb where UserName=’金磊’;
如果出现需要考虑使用:
select c1, c2, c3 from tb where UserName = (‘金磊’ collate XXX_bin);

2.
在查询中order by 的列里字符最好不要用汉字,如:
select c1, c2, c3 from tb order by UserName;

如果你指定了字符集:

所有的操作请指定字符集

100多G的库gbk转成utf8怎么做?

这个过程有可能需要6个小时最后发现没成功是不是杯具了?

核心问题想把验证的过程缩短

1.表结构很好搞定吧

2.是不是把某个有中文的表取出来1万行去验证一下

mysqldump –single-transaction  –set-charset=utf8|GBK  DBname TBname –where="id<10000" &get;db_tb_id_lt_1w.sql

iconv -t utf8 -f gbk <db_tb_id_lt_1w.sql &get;utf_db_tb_id_lt_1w.sql

测试

1.建一个utf8的库
2.创建一个表要包含有字符型的

3.写一些数据,要有汉字的

试试弄到gbk库里

能正确的查看到

( … collate UTF-8-bin)

MySQL账号管理

blob.png

blob.png

控制开发者权限只给DELETE, INSERT,UPDADE,SELECT,

excute, create routine

不让开发瞎鸡巴搞(我是开发

不给开发更改存储过程权限

线上最小权限

任何变更是dba需要知道

blob.png

load date in file 权限生产环境应该避免掉,包括自己的账号,

为什么要用mysql一个无效的用户来跑mysqld呢,

因为早些年出现好多人利用load data把/etc/passwd加载到数据库拿到password 暴力破解

现在不存在了 

现在password放到好像是shadow里拿不到 

有这个权限也很悲剧

可以通过select into 一个 file 创建一个shell 给系统创建一个账号

所以需要注意

drop权限也要注意 避免被sql入侵把表drop掉

lock tables 一般情况下不建议开发在程序中使用 酌情考虑

blob.png

GRANT OPTION 

给了一个给别人授权的权限

show grants for 'root'@'localhost';

PROCESS

show processlist; 显示有哪些线程在运行

RELOAD

数据库重新加载

flush tables; flush logs; flush开头的

replication client VS replication slave  (虽然这里我还不懂)

replicaation client 

show master status;

show slave status;

replication slave复制传输用的

SHUTDOWN

mysql_multi里面配置的user 需要给配置这个

SUPER

当所有连接占完了会给SUPER权限保留连接

ALL

all 是除了grant option 之外的权限

USAGE 只能连上 啥也干不了

blob.png

mysql 5.6 引入了一个proxy user

但要买官方的插件

blob.png

select user,host,password from mysql.user;

blob.png

mysql.db

blob.png

我们测试库里mysql.columns_priv里数据貌似是空的

blob.png

blob.png

keepalived 密码是8个字符

mysql 用户名是16个字符以下

超过了会造成内存溢出

'leokim'@'192.168.11.%'

blob.png

mysql -S /path/mysql.sock -uwubx

mysql -h192.168.11.20 -uwubx -p

client:192.168.11.100

server 192.168.11.20

mysql -h192.168.11.20 -uwubx -p 这个时候用哪个密码呢?

匹配原则按最精确的情况匹配(wubxwubx)

blob.png

drop user 'wubx'@'192.168.11.%';

blob.png

云类的数据库对资源限制

每小时允许做多少次query,update等

max_user_connections

max_connections=1100

max_user_connections=500

控制连接数

blob.png

blob.png

忘记root密码怎么处理

核心是让mysqld重新加载一下权限表

kill -SIGHUP

mysql 5.6可以让一个密码过期 

mysql 5.6以后的客户端

可以让密码过期 直接登录 修改密码

blob.png

blob.png

show grants for 'wubx'@'localhost';

mysql手册第5,6章很值得看

blob.png

可以用iptables

在数据库里

grant usage on *.* to 'admin'@'192.168.10.15' identified by 'wubxwubx';

information_schema.processlist

找到ip干掉

索引及使用方法

blob.png

索引就是目录检索系统

IOT : index cluster table

表要聚集索引排序后存储

sql语句中带where条件的都会用到索引

blob.png

idx_abc(a,b,c)—–》(a), (a,b), (a,b,c)

select * from tb where a=xxx; 可以用到索引

select * from tb where b=xxx; 不能用到索引

加速join操作

where a.c_id = b.d_id 要求2个数据类型是一样的

如果不一样也用不到索引比如c_id mediumint,d_id int 2个去join不能进行转换成为临时表

char和varchar 大小一样的情况下可以用到索引 但是只要size定义不一样则不能用到索引

join的场景要求两个类型一样的同时要求size一样才能用到索引

排序可以用到索引

idx_abc(a,b,c)

select a,b,c from tb where a=xxx;

索引包含(Innodb的B+tree,索引内包含数据)

一个表有多列索引怎么选择

select * from tb where c1=xxxx and c2=xxx;

c1 varchar(10)

c2 int(10)

idx_c1(c1)

idx_c2(c2)

查询优化里有一个原则:基于成本优化

统计视图

假设成查询成本是1

c1 string  0.9

c2 int 0.6

mysql认为这个计划都符合要求,就会从上到下取第一个,而我们这里c1比c2靠前所以优先用c1

这就是mysql的 成本优化器

5.7这块可能有变化

trace

《sql server 查询》

基于成本优化内容

blob.png

R-Tree只在MyISAM里面的地理数据里支持

主建和唯一索引有什么区别吗

主键不允许null,唯一索引允许null

普通索引对null没有要求

使用上会有区别

where col1  =xxx ;

普通索引不能保证数据不重复还会往下面继续查

所以普通索引会比主键和唯一索引多一点io开销 

核心类和高并发尽可能用主键或者唯一索引

blob.png

(tokudb可以有多个主键多个class index)

Innodb只允许有一个主建

数据是以主键为顺序排序存储的

Innodb表以主建排序存储,如果没有主建了怎么办?

如果没有主建,会选择第一个(创建的顺序)唯一索引,升级为主建

如果这个表连唯一索引也没有怎么办?

自动创建一个6个字节长度的主键

6个字节是很长的成本比较高

blob.png

blob.png

idx_

udx_

fdx_

前缀索引貌似是mysql的一个特色

email(64) 用20位就已经可以区别出来了就可以创建

create index idx_email on tb(email(20));

让索引使用最少的空间来减少io


联合索引

(c3,c4)

update tb set c6=xxx where c3=xxx and c4=xxx;

如果创建索引了 就不要再这个列上经常更新

update set email

改索引后需要先改字段然后进行索引排序然后再把数据弄过去,可能涉及到拆页分页

所以要避免更新索引列

全文索引

目前(5.6)不支持中文

5.7后貌似支持中文了

http://www.actionsky.com/docs/archives/163

CJK亚洲文字

create fulltext index idx_c5 on yw(c5);

MySQL 5.6 innodb增加了全文搜索

唯一索引(=)效过最好 ,但是也支持区间(>,between, in)

主键定义删除创建智能用lalter table一般都是在表创建的时候去定义,这个动作很大需要copy表空间,生产环境中基本不去动主键这个事情。

blob.png

isopen

type

flag

这些列不太适合做索引,基数太少了

比如说type就3个值那也就是30%的比例

mysql扫描不低于30%(打比方的值)都不会走索引

这个索引是无效的

如果标志达到4个或者5个以上索引可能还是可以用到的

选择基数比较大的列做索引,或者重复比较少的。

我们目前的status_id呀,type_id呀,action_id呀之类的这些标志我得找个时间去测试一下效果如何




blob.png

只有基于唯一索引或主键上等于类的操作才能做到行级锁,这部分非常复杂

gap

next key

idx_ab(a,b)

idx_a(a)

blob.png

后面会有工具来帮助排查

blob.png


《基于Innodb最佳实践》

无序主键 rand出来

写入速度很慢 1s只能一两百

顺序索引/s能上万

索引无序写入会造成写入速度降低

update 尽可能不要update索引列

5.7对这块update做了一些合并的维护

字符型的索引,是怎么查找的?

字符串比较btree的字符串比较定位到值在哪

​Mysql体系结构

blob.png

逻辑结构

  1. 客户端:php,java…应用程序

  2. 通过drive连接到mysql,mysql线程池

  3. sql形成MD5/hash的key去查缓存(query cache)是否有这个结果

  4. sql分析器,进行优化找到最优执行路径

  5. 到存储引擎拿数据

blob.png

服务器进程

  1. 连接层:连接接入,认证

  2. SQL层:语法校验

  3. 存储层:DBA应该最关注的地方

数据库优化的本质: 

减少IO

把随机IO想办法转成顺序IO

blob.png

连接层

通信协议

线程

验证

OneSQL就是在连接层把thread-pool做了一个优化,官方的thread-pool也差不多

blob.png

SQL层:SQL解析,授权,优化器,查询执行,查询日志等等

blob.png

SQL语句处理过程

连接mysql后查询query cache

query cache是没有经过语法解析的

select * from tb1 where id=1; 和select * from tb1 where Id=1; 

实际生产中是禁掉query cache

query cache是mysql一个性能瓶颈形成全局锁

blob.png

整体模块结构

untitled.png

Oracle官方有一个去IOE团队推ndb cluster 哈哈哈

日志

  1. 错误日志

  2. 慢日志(slow_query_log)

  3. 二进制日志(binary log)

  4. 一般日志(general log)

blob.png

blob.png

blob.png

slow_query_log_file 

set global general_log=1; 

select sleep(3); 

set global general_log=0;

​MySQL存储引擎

MySQL基于存储引擎的一个解决方案

blob.png

官方的存储引擎

不支持事物:MyISAM, Memory, Archive(只写,不允许修改删除,日志审计) 

锁的粒度:Innodb,NDB 行级锁

是否支持压缩

innodb 5.1.37引入innodb plugin 这个开支持压缩

myisam 5.6开始支持英语全文搜索

Innodb 5.6 开始支持英语全文搜索

批量写的速度

MyISAM,Memory的批量写入比较快

Innodb的Bulk insert (load data) 在5.7之前没有MyISAM,Memory快

原因是因为不支持批量更新索引

5.7之后改善

恢复到某个点 binlog

TokuDB

带压缩支持高速写入的一个引擎

Innodb/Tokudb压缩比是10:1

innodb表每秒2万

Tokudb可以达到4W

tokudb的insert特别快

percona enterpise

Percona MySQL 5.6 包含了TokuDB

MariaDB 中也含的有Tokudb

engine=Tokudb;

Percona Server TokuDB做为他的一个默认引擎

缺点

Tokudb不适合update多的场景

tokudb表20G

update col2=xxx ;

表由原来的20G表变成40G了

多引擎混用注意join

会形成大量移植表不推荐2种不同引擎join

MySQL不适合做OLAP?

Infrobright/InfiniDB

MySQL 5.1的时间都出现了

group ,order ,count之类聚集函数

OLAP 里的表,很多都是宽表

统计类的库(OLAP)一张表好几百列

针对业务去选择引擎

常用推荐:InnoDB

如果有大数据写入批量读取的操作Tokudb

针对OLAD可以考虑使用InfiniDB/Infrobright

推荐研究: InfiniDB,完全开源

infrobright 分企业版和社区版,社区版只支持load data操作

如果对数据量小,要求速度,无持久化要求:Memory

拒绝选用MyISAM

  1. 只能用单个cpu

  2. 内存只能用到4G

  3. 内存里只有索引(B-tree)

  4. 并发能力差

blob.png



MYSQL 数据类型

需求分析

创表出来表结构

核心SQL

总结分析: 可以会遇到什么样的性能瓶颈

存储过程

触发器

事件

表:字段, 索引(约束)

高并发不允许触发器和存储过程

blob.png

要背下来:占用空间,每个值的范围

固定小数点类型

Decimal 

salary decimal(8,2)

最大65位

可以用来记录工资

不要用四舍五入

做彩票时: decimal 

每次钱会少个几百块或是多个几百块

交易量5千万左右

int 单位按份来存储

单位: 分

导出乱码

共享表空间转成独立表空间

浮点数

浮点数用二进制表示

小数点后复杂,移位补位,算法符号变法

尽可能减少浮点数出现,运算占开销很大

不能做精确值比较

Floathe(M,D)

    小数点后:0-23位精度,存储占用<=4个字节

DOUBLE(M,D)

    小数点后:24-53位精度,存储占用8个字节

BIT

status&0/10

BIT(M)#M用于表示有多少个二进制位.M可以支持0-64位

对于bit写入会左填充0.如果bit(8)写入b'1001' 查询得到的值 :00001001

数据类型

数据类型支持属性

    int(4)

    int(4)zerofill 写入数字5,显示:0005

    int(11)auto_increment 每次自增加一

int(1)存100是可以存的 只是有坑,1是宽度

数据溢出 

5.5和5.6有区别 

Set sql_mode = ‘’;
Select cast(0 as UNSIGNED) – 1;

SELECT 9223372036854775807 + 1;
SELECT CAST(9223372036854775807 AS UNSIGNED) + 1;

blob.png

blob.png

timestamp占用字节数更少

blob.png

varchar 

utf8汉字需要占用3个字节

255 byte能存多少个汉字

varchar 低于255 byte需在一个字节 用来记录长度大于255 2个字节

varchar最大长度65535 

如果存的字母就按ascII 2字节 

用记录长度

char 定长的

varchar变长

其他类型能记住存多大就行

Enum

5.6在线表空间定义

blob.png

减少join

核心sql尽可能不要join

blob.png

mysql 多实例 Multi

配置好配置文件然后到/usr/local/mysql/bin

执行mysql_multi start 就可以了

blob.png

#my.cnf
[client]
port            = 3306
socket          = /tmp/mysql.sock

[mysql]
prompt="\\u@\\h:\p  \\R:\\m:\\s [\\d]>"
#tee=/data/mysql/mysql_3306/data/query.log
no-auto-rehash

[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
log = /opt/mysql/mysqld_multi.log

[mysqld]
#misc
user = mysql
basedir = /usr/local/mysql
datadir = /data/mysql/mysql_3306/data
port = 3306
socket = /tmp/mysql.sock
event_scheduler = 0

#timeout
interactive_timeout = 300
wait_timeout = 300

#character set
character-set-server = utf8

open_files_limit = 65535
max_connections = 100
max_connect_errors = 100000

skip-name-resolve = 1
#logs
log-output=file
slow_query_log = 1
slow_query_log_file = slow.log
log-error = error.log
log_warnings = 2
pid-file = mysql.pid
long_query_time = 1
#log-slow-admin-statements = 1
#log-queries-not-using-indexes = 1
log-slow-slave-statements = 1


#binlog
binlog_format = mixed
server-id = 203306
log-bin = /data/mysql/mysql_3306/logs/mybinlog
binlog_cache_size = 4M
max_binlog_size = 1G
max_binlog_cache_size = 2G
sync_binlog = 0
expire_logs_days = 10

#relay log
skip_slave_start = 1
max_relay_log_size = 1G
relay_log_purge = 1
relay_log_recovery = 1
log_slave_updates
#slave-skip-errors=1032,1053,1062

tmpdir = /data/mysql/mysql_3306/tmp

explicit_defaults_for_timestamp=1
#buffers & cache
table_open_cache = 2048
table_definition_cache = 2048
table_open_cache = 2048
max_heap_table_size = 96M
sort_buffer_size = 2M
join_buffer_size = 2M
thread_cache_size = 256
query_cache_size = 0
query_cache_type = 0
query_cache_limit = 256K
query_cache_min_res_unit = 512
thread_stack = 192K
tmp_table_size = 96M
key_buffer_size = 8M
read_buffer_size = 2M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 32M

#myisam
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1

#innodb
innodb_buffer_pool_size = 100M
innodb_buffer_pool_instances = 1
innodb_data_file_path = ibdata1:1G:autoextend
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 64M
innodb_log_file_size = 500M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 50
innodb_file_per_table = 1
innodb_rollback_on_timeout
innodb_status_file = 1
innodb_io_capacity = 2000
transaction_isolation = READ-COMMITTED
innodb_flush_method = O_DIRECT

#端口号为3307的实例特殊配置
[mysqld3307]
port =3307 
server-id=203307
#指定本实例相应版本的basedir和datadir
basedir= /usr/local/mysql
datadir = /data/mysql/mysql_3307/data
log-bin = /data/mysql/mysql_3307/logs/mybinlog
socket  = /tmp/mysql_3307.sock
#重新配置这几个选项,不与全局配置一样,会直接覆盖上面的全局设置
innodb_buffer_pool_size = 100m
innodb_data_file_path = ibdata1:100M:autoextend
#transaction_isolation = REPEATABLE-READ

#端口号为3306的实例特殊配置
[mysqld3306]
port =3306
server-id=203306
#指定本实例相应版本的basedir和datadir
basedir= /usr/local/mysql
datadir = /data/mysql/mysql_3306/data
log-bin = /data/mysql/mysql_3306/logs/mybinlog
socket  = /tmp/mysql_3306.sock
#重新配置这几个选项,不与全局配置一样,会直接覆盖上面的全局设置
innodb_buffer_pool_size = 100m
#transaction_isolation = REPEATABLE-READ

之前3307启动不起来是因为 手动配置3307的时候修改过3307配置文件里innodb的一些大小,然后用/etc/my.cnf的时候没有按一样大小 就出错了

mysql 多实例

创建多实例目录并修改权限

vim /data/mysql/mysql_3307/my.cnf

修改配置文件

:%s/3306/3307/g

socket          = /tmp/mysql_3307.sock

要是想启用多版本mysql就修改basedir使用

basedir = /usr/local/mysql

修改socket

执行编译

./scripts/mysql_install_db –user=mysql –datadir=/data/mysql/mysql_3307/data/ –default-file=/data/mysql/mysql_3307/my.cnf

blob.png

/usr/local/mysql/bin/mysqld_safe –defaults-file=/data/mysql/mysql_3306/my3306.cnf &

3306启动成功了

blob.png

blob.png

启动3307

./mysqld_safe –defaults-file=/data/mysql/mysql_3307/my3307.cnf &

blob.png

启动成功

我发现这个netstat的这个参数这样记比较好记“按你老婆” 啊哈哈哈哈哈

blob.png

可以看到3306,和3307都监听了

这个时候想要登录到3306

可以使用: mysql -S /tmp/mysql_3306.sock

blob.png

关闭的话直接用

mysqladmin -S /tmp/mysql_3306.sock shutdown

就可以了