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验证数据包的接受情况