2018/07 作者:ihunter 0 次 0
一、概述
事件现象:近一段时间数据表经常被损坏,查询等待时间过长,数据统计不正确
事件分析:并发量过大,数据表过大,update、insert操作频繁。数据库引擎为MyIsam,由于MyISAM没有事务,在大并发下会出现坏表。并发越大,越容易坏。
技术方案:
待整改: 数据存储引擎变更, 从MyISAM转成InnoDB
近期: 数据表分区,将一张表分为多个区
中期: 数据分表,将一张表分成多张表
远期: 多服务器承担负载,实现数据分离
二、 数据库引擎转变--MyISAM 转成 InnoDB
从MyISAM 转到 InnoDB 需要注意的几点:
1、 MyISAM的主键索引中,可以在非第一列(非第一个字段)使用自增列,而InnoDB的主键索引中包含自增列时,必须在最前面
2、 不带条件频繁统计全表总记录数时(SELECT COUNT(*) FROM TAB),InnoDB相对较慢,而MyISAM则飞快;不过,如果是基于索引条件的统计,则二者相差不大;
3、 InnoDB在5.6版本以前不支持全文索引,当然很少会有人在MySQL里直接跑全文索引,确实有需要的话,可以采用Sphinx、Lucene等其他方案实现
4、 InnoDB不支持LOAD TABLE FROM MASTER语法
5、 由于innodb存储引擎,对用户来说是透明的,对程序逻辑不受任何影响,永久解决索引文件损坏的问题。
从MyISAM转成InnoDB的优点:
1、 完整事务特性支持,以及更高的数据并发存取效率,即更高的TPS;
2、 数据库实例异常重启后,InnoDB表能自动修复,而且速度相对更快,而MyISAM需要被触发才能修复,且相对耗时可能多4~5倍甚至更多
3、 更高的数据读取性能,因为InnoDB把数据及索引同时缓存在内存中,而MyISAM只缓存了索引;
4、 InnoDB支持外键(当然了在MySQL中,外键比较少用);
从MyISAM转成InnoDB的缺点:
1、 相比MyISAM,同样的数据量,InnoDB需要占用更多的空间
2、 非大并发情况下,InnoDB查询速度更慢
3、 相同数据量的查询,占用系统资源的更多,需要更多的内存和CPU来支撑
4、 备份相对MyISAM不太方便
其他前期准备:
1、 检查是否支持InnoDB, show engines;
2、 修改My.cnf配置文件相关参数
3、进行数据库的备份
从MyISAM转成InnoDB具体操作方法:
1、 修改整个数据库所有表的存储引擎
1、 mysqldump -d -u*** -p dbname > mysql_table.sql -d 表示不导出数据,只导出表结构
2、sed -i 's/MyISAM/INNODB/g' mysql_table.sql 将导出文件中的MyISAM字符串替换成InnoDB
3、mysql> create database mysql_new; 新建数据库
Mysql -u *** -p mysql_new < mysql_table.sql 将结构导入数据库
4、mysqldump –t –u*** -p dbname > mysql_data.sql 参数t表示只导数据,不导结构
5、mysql -u*** -p mysql_new < mysql _data.sql 最后导入数据
2、 修改单表存储引擎
ALTER TABLE mysql_table ENGINE=MyISAM; //直接用命令行即可修改
innodb引擎 配置文件my.cnf 参数修改:
innodb-buffer-pool-size= 16M //这是InnoDB最重要的设置,对InnoDB性能有决定性的影响。默认只有8M,因此默认的数据库设置下面InnoDB性能很差。在只有InnoDB存储引擎的数据库服务器上面,可以设置60-80%的内存。
相关链接:http://www.educity.cn/wenda/400332.html
innodb_file_format= Barracuda
//innodb表压缩可用该选项
相关链接:http://www.tuicool.com/articles/3qm2U3J
innodb_file_per_table= 1
//为每一个新数据表创建一个表空间文件而不是把数据表都集中保存在中央表空间里(后者是默认设置)
相关链接: http://blog.csdn.net/ywh147/article/details/8996022
innodb-log-file-size= 512M //该参数决定了recovery speed。太大的话recovery就会比较慢,太小了影响查询性能,一般取256M可以兼顾性能和recovery的速度
相关链接: http://www.tanbo.name/html/120.html
innodb_lock_wait_timeout= 15 //事务等待时间,如果某个事务在等待n秒(s)后还没有获得所需要的资源,就使用ROLLBACK命令放弃这个事务。
相关链接: http://blog.itpub.net/12679300/viewspace-1418320/
innodb_flush_log_at_trx_commit= 2 //提交事务时刷写日志的方式
相关链接:http://wzmtony.blog.163.com/blog/static/20318015620130171834386/
innodb_file_io_threads=4
//文件读写IO数,这个参数只在Windows上起作用。在linux上只会等于4
相关链接:
http://www.ttlsa.com/mysql/mysql-innodb-storage-engine-parameters-detailed-and-optimization/
innodb_thread_concurrency=16 并发线程限制进入内核的数量
相关链接:http://blog.csdn.net/z1988316/article/details/7166025
innodb_log_buffer_size=16M //InnoDB 存储引擎的事务日志所使用的缓冲区
相关链接:http://database.chinaunix.net/a2011/1123/1278/000001278369_1.shtml
default-storage-ENGINE=MyISAM //加上这段之后,以后新增的数据表型态都即是 InnoDB,不然每次新增一次数据表,SQL 后面得加上 ENGINE=MyISAM;
read_rnd_buffer_size=16M
//类似于read_buffer_size选项,但针对的是按某种特定顺序(比如使用了ORDER BY子句的查询)输出的查询结果(默认设置是256K)。
相关链接:http://www.cnblogs.com/captain_jack/archive/2010/10/12/1848496.html
read_buffer_size=1M
//为从数据表顺序读取数据的读操作保留的缓存区的长度(默认设置是128KB); 这个选项的设置值在必要时可以用SQL命令SET SESSION read_buffer_size = n命令加以改变。
相关链接:http://www.cnblogs.com/captain_jack/archive/2010/10/12/1848496.html
key_buffer_size=256M
//用来存放索引区块的RMA值(默认设置是8M)。
相关链接:http://www.cnblogs.com/captain_jack/archive/2010/10/12/1848496.html
innodb_additional_mem_pool_size=80M
#这个参数用来设置 InnoDB 存储的数据目录信息和其它内部数据结构的内存池大小,类似于Oracle的library cache。这不是一个强制参数,可以被突破。
相关链接:http://www.linuxyw.com/a/shujuku/20130506/216.html
http://blog.sina.com.cn/s/blog_593bf1da0100xznj.html
innodb_max_dirty_pages_pct=90
// Buffer_Pool中Dirty_Page所占的数量,直接影响InnoDB的关闭时间。参数innodb_max_dirty_pages_pct可以直接控制了Dirty_Page在Buffer_Pool中所占的比率,而且幸运的是innodb_max_dirty_pages_pct是可以动态改变的。
相关链接:http://blog.sina.com.cn/s/blog_593bf1da0100xznj.html
关于mysql innodb存储引擎my.cnf调优介绍
相关链接:
http://www.ttlsa.com/mysql/mysql-innodb-storage-engine-parameters-detailed-and-optimization/
http://www.jb51.net/article/27069.htm
http://www.jb51.net/article/47419.htm
http://blog.csdn.net/yunhua_lee/article/details/7082772
由于innodb存储引擎需要消耗更多的系统资源,建议将初期将内存加大G,硬盘空间增至G,未来根据需求和负载情况,在做继续调整。