MySQL两种常用的存储引擎
MyISAM:
表数据文件和表索引文件都是独立存放
适合记录少于2000万以下
适合并发量不是很高的环境
适合简单的查询
不支持事务
容易出现数据丢失,表损坏,经常需要修复,修复往往也导致数据丢失
适合读多写少的环境
优化:主要是索引
Innodb:
表数据文件和表索引文件是共同一个文件
适合大规模数据,小规模的数据反而效率不高
适合并发量高的环境
适合复杂的查询
支持事务
支持数据自动修复,保证了数据丢失最少
什么是事务?
事务是由一个或多个SQL语句组成的一系列操作,这些操作要么一同成功,要么就完全不执行。例子:银行汇款(扣钱+汇钱)
特点ACID:
原子性(atomicty):
事务要么成功,要么失败
一致性(consistency):
隔离性(isolation):
事务与事务之间互不影响,独立进行。
持久性(durability):
事务最后提交之后,所造成数据变更是永久生效。
事务的四个特点设计之处是为了能够让数据库支持高并发运作,但是如果真的要实现以上四个特点,比较困难,因为事务的并发总会引起以下的一些问题:
1、脏读问题:
一个事务读取了另外一个事务更改了但是还没确定最终提交的数据。
2、幻读问题:
同一个事务中的同样一个查询重复出现,但先后得到的结果不一样,后面的查询比前面的查询多了一些记录
3、更新丢失:
刚更新的记录被另外一个事务覆盖了。
4、不可重复读:
同一个事务中重复读取相同记录,但记录是不一样了。
数据的隔离级别:
1、未提交读级别:
相当于不支持事务,不能解决事务并发时候带来以上四个问题。
2、已提交读级别:
只允许读取其他事务已经提交的数据,未提交的数据其他事务是看不到。
解决了脏读问题
3、可重复读级别:
同一个事务中,不管重复执行多少次相同的查询,看到的记录都是一样。
解决了脏读问题,解决了不可重复读问题,但标准该隔离级别不能解决幻读。
4、串行级别:
事务是一个紧接一个操作,完成了一个才能进行下一个事务。
Innodb实现了可重复读级别:解决了幻读问题
Oracle实现了已提交读级别
commit
DCL语句的执行: create,alter更改表结构等,创建表等语句都会导致事务自动提交
或者手工执行了commit/rollback语句事务就结束
缓存优化:
innodb_buffer_pool_size
innodb专用的,用户缓存数据文件和索引数据。
操作系统使用: 400M
binlog_cache_size: 2Mx300= 600M
thread_stack:200K x 300 = 60M
query_cache: 64M
join_buffer: 2Mx300= 600M
sort_buffer: 2Mx300= 600M
key_buffer_size: 128M
上面总的使用约等于2.4G空间
设定的时候,根据物理内存和其他内存组件联合考虑
通过计算使用百分比,推算结果:
mysql> show status like 'innodb%';
+-----------------------------------+---------+
| Variable_name | Value |
+-----------------------------------+---------+
| Innodb_buffer_pool_pages_data | 64 |
| Innodb_buffer_pool_pages_dirty | 0 |
| Innodb_buffer_pool_pages_flushed | 0 |
| Innodb_buffer_pool_pages_free | 8128 | 《--
| Innodb_buffer_pool_pages_misc | 0 |
| Innodb_buffer_pool_pages_total | 8192 | 《--- 使用百分比90%以上
| Innodb_buffer_pool_read_ahead_rnd | 1 |
| Innodb_buffer_pool_read_ahead_seq | 0 |
| Innodb_buffer_pool_read_requests | 184 |
| Innodb_buffer_pool_reads | 13 |
| Innodb_buffer_pool_wait_free | 0 |
| Innodb_buffer_pool_write_requests | 0 |
命中率
(Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests ==> 95%以上很优化配置
innodb_additional_mem_pool_size
额外需要用到缓存的组件就是使用该参数指定的内存,一般不需要调整,如果不足,innodb会自动调整。
数据文件优化
innodb_open_files <---考虑是否足够应对innodb表的数量
共用表空间:500个innodb表,一般500+100左右
独立表空间(每个表有独立的数据文件):500个innodb表,一般设置2x500+100
innodb_data_file_path
指定数据文件的存放地方,大小等属性
ibdata1:1024M:autoextend:max:8096M
ibdata1:1024M;ibdata2:1024M:autoextend:max:8096M
添加新数据文件报错:
# tail -f /data/mysqld.err
111106 14:10:14 mysqld_safe Starting mysqld daemon with databases from /data
111106 14:10:14 InnoDB: Initializing buffer pool, size = 128.0M
111106 14:10:14 InnoDB: Completed initialization of buffer pool
InnoDB: Error: data file ./ibdata1 is of a different size
InnoDB: 289280 pages (rounded down to MB)
InnoDB: than specified in the .cnf file 65536 pages!
原因:mysql识别的旧的ibdata1数据文件为289280 pages ( 1 page = 16KB),而配置文件中由于去掉了autoextend,所以就认为数据文件是65536,前后不一致,所以报错。
增加新的数据文件之前,计算旧的数据文件文件大小,然后替换配置中的旧的值
ibdata1:4520M;ibdata2:1024M:autoextend:max:8096M
289280 * 16 / 1024 = 4520M
innodb_data_home_dir 指定数据文件保存路径,默认和data_dir一样
优化:
可以把数据文件安独立存放在不同设备,使用软连连接的方法
建议使用raid设备
数据文件初始化尽可能大一点,这样可以避免不断获宠数据文件带来了性能损耗
如果并发量高,数据吞吐量很大,可以适当增大innodb_autoextend_increment设定值,每次扩容尽可能大一点,避免重复多次扩容。
innodb_doublewrite 默认是ON
------------
连续读写,重复使用
## at xxxx
789 at xxxx
...
...
@@ at xxx
111 at xxx
------------
真正最后保存数据的地方,分散,体积大,读写较慢
1234##@@ <---- 1234##78 , 1234##@@
111defg <--- 111cedfg
abc789cde <---- abc789cde
------------
日志文件优化
innodb_log_buffer_size , 建议值 2M
innodb_log_file_size , 建议值 128-256M
innodb_log_files_in_group
可以使用软链接分开存放于不同的存储设备,最好跟数据文件也是分开
innodb_log_group_home_dir
日志文件的路径,默认data_dir
事务优化
innodb_flush_log_at_trx_commit
0 每一秒同步log_buffer中的日志到磁盘的日志文件中,而且保证信息不会存在于文件系统缓存中。如果mysqld进程crash,最极端的情况会丢失1秒数据(1秒钟可以并发多个事务)。IO相对来说少一点,性能是一般
1 每完成一个事务,就会马上同步log_buffer中的信息到磁盘的日志文件中,而且保证信息不会存在于文件系统缓存中。如果mysqld进程crash或者操作系统crash,最极端的情况仅仅是丢失1个事务的数据。IO消耗大,但数据很安全,性能最差
2 每完成一个事务,就会马上把log_buffer中的信息写到日志文件中,但不保证文件是实时写到磁盘,也就是存在数据还在文件系统缓存的情况。 如果系统crash,会丢失数据,而且很难保证丢失多少数据。如果mysqld进程crash,丢失1个事务数据。数据最不安全,但性能是最好的
innodb内部并发线程数:
innodb_thread_concurrency 很难改。
硬件环境对数据库影响:
OLTP在线事务类型(web应用):
特点:
并发量高
短连接
单个连接请求的数据量很少,但是并发量高,所以总体数据量还是挺大的
请求比较零散,随机IO比较多
优化:
对cpu资源要求比较高
存储设备要求IOPS要大,IO吞出量次要
为了减少零散读取,减少随机IO发生机率,可以增加内存,加载缓存
对网络设备要求比较高,一般要求千兆网卡
OLAP数据仓库、数据分析业务
特点:
海量数据
长连接
并发量很低
单个连接涉及的数据量很大,但是真正返回给客户端的数据往往是很少。
优化:
对cpu要求没那么高
对网络设备要求不高:
如果多机并行运算分析数据,机器之前的网络设备要求就比较高,一般千兆就满足。
请求的数据比较集中,所以顺序IO比较多,要求IO吞吐量比较高
存储设备有足够大容量
总结:
内存是首要条件
硬盘存储性能要好,一般选择阵列(raid5,raid10)
千兆网卡
双网卡绑定:
网卡的型号和带宽,工作模式都应该一样。
连接同一个交换机
临时绑定:
# modprobe bonding mode=0 miimon=100
# ifconfig bond0 10.1.1.23 netmask 255.255.255.0 up
# ifenslave bond0 eth0
# ifenslave bond0 eth1
配置文件静态绑定:
# vim /etc/modprobe.conf
alias bond0 bonding
options bond0 mode=0 miimon=100
# vim ifcfg-bond0
DEVICE=bond0
BOOTPROTO=static
ONBOOT=yes
IPADDR=10.1.1.23
NETMASK=255.255.255.0
# vim ifcfg-eth0
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
HWADDR=00:D0:B7:D3:10:A2
SLAVE=yes
MASTER=bond0
# vim ifcfg-eth1
DEVICE=eth1
BOOTPROTO=none
ONBOOT=yes
HWADDR=00:D0:B7:D3:22:B2
SLAVE=yes
MASTER=bond0
# service network restart
# ifconfig验证数据包的接受情况