`
wangdei
  • 浏览: 366121 次
社区版块
存档分类
最新评论

MySQL服务维护笔记

阅读更多

内容摘要:使用MySQL服务的一些经验,主要从以下几个方面考虑的MySQL服务规划设计。对于高负载站点来说PHP和MySQL运行在一起(或者说任何应用和数据库运行在一起的规划)都是性能最大的瓶颈,这样的设计有如让人一手画圆一手画方,这样2个人的工作效率肯定不如让一个人专门画圆一个人专门画方效率高,让应用和数据库都跑在一台高性能服务器上说不定还不如跑在2台普通服务器上快。

以下就是针对MySQL作为专门的数据库服务器的优化建议:

  1. MySQL服务的安装/配置的通用性;
  2. 系统的升级和数据迁移方便性;
  3. 备份和系统快速恢复;
  4. 数据库应用的设计要点;
  5. 一次应用优化实战;

MySQL服务器的规划
=================
为了以后维护,升级备份的方便和数据的安全性,最好将MySQL程序文件和数据分别安装在“不同的硬件”上。

         /   / 
        |    /usr                     <== 操作系统         
        |    /home/mysql              <== mysql主目录,为了方便升级,这只是一个最新版本目录的链接 
硬盘1==>|    /home/mysql-3.23.54/     <== 最新版本的mysql /home/mysql链接到这里
         \   /home/mysql-old/         <== 以前运行的旧版本的mysql

         /   /data/app_1/             <== 应用数据和启动脚本等
硬盘2==>|    /data/app_2/
         \   /data/app_3/

MySQL服务的安装和服务的启动:
MySQL一般使用当前STABLE的版本:
尽量不使用--with-charset=选项,我感觉with-charset只在按字母排序的时候才有用,这些选项会对数据的迁移带来很多麻烦。
尽量不使用innodb,innodb主要用于需要外键,事务等企业级支持,代价是速度比MYISAM有数量级的下降。
./configure --prefix=/home/mysql --without-innodb
make
make install

服务的启动和停止
================
1 复制缺省的mysql/var/mysql到 /data/app_1/目录下,
2 MySQLD的启动脚本:start_mysql.sh
#!/bin/sh
rundir=`dirname "$0"`
echo "$rundir"
/home/mysql/bin/safe_mysqld --user=mysql --pid-file="$rundir"/mysql.pid --datadir="$rundir"/var "$@"\
-O max_connections=500 -O wait_timeout=600 -O key_buffer=32M --port=3402 --socket="$rundir"/mysql.sock &

注释:
--pid-file="$rundir"/mysql.pid --socket="$rundir"/mysql.sock --datadir="$rundir"/var
目的都是将相应数据和应用临时文件放在一起;
-O 后面一般是服务器启动全局变量优化参数,有时候需要根据具体应用调整;
--port: 不同的应用使用PORT参数分布到不同的服务上去,一个服务可以提供的连接数一般是MySQL服务的主要瓶颈;

修改不同的服务到不同的端口后,在rc.local文件中加入:
/data/app_1/start_mysql.sh
/data/app_2/start_mysql.sh
/data/app_3/start_mysql.sh
注意:必须写全路径

3 MySQLD的停止脚本:stop_mysql.sh
#!/bin/sh
rundir=`dirname "$0"`
echo "$rundir"
/home/mysql/bin/mysqladmin -u mysql -S"$rundir"/mysql.sock shutdown

使用这个脚本的好处在于:
1 多个服务启动:对于不同服务只需要修改脚本中的--port[=端口号]参数。单个目录下的数据和服务脚本都是可以独立打包的。
2 所有服务相应文件都位于/data/app_1/目录下:比如:mysql.pid mysql.sock,当一台服务器上启动多个服务时,多个服务不会互相影响。但都放到缺省的/tmp/下则有可能被其他应用误删。
3 当硬盘1出问题以后,直接将硬盘2放到一台装好MySQL的服务器上就可以立刻恢复服务(如果放到my.cnf里则还需要备份相应的配置文件)。

服务启动后/data/app_1/下相应的文件和目录分布如下:
/data/app_1/
    start_mysql.sh 服务启动脚本
    stop_mysql.sh 服务停止脚本
    mysql.pid 服务的进程ID
    mysql.sock 服务的SOCK
    var/ 数据区
       mysql/ 用户库
       app_1_db_1/ 应用库
       app_1_db_2/
...
/data/app_2/
...

查看所有的应用进程ID:
cat /data/*/mysql.pid

查看所有数据库的错误日志:
cat /data/*/var/*.err

个人建议:MySQL的主要瓶颈在PORT的连接数上,因此,将表结构优化好以后,相应单个MySQL服务的CPU占用仍然在10%以上,就要考虑将服务拆分到多个PORT上运行了。

服务的备份
==========
尽量使用MySQL DUMP而不是直接备份数据文件,以下是一个按weekday将数据轮循备份的脚本:备份的间隔和周期可以根据备份的需求确定
/home/mysql/bin/mysqldump -S/data/app_1/mysql.sock -umysql db_name | gzip -f>/path/to/backup/db_name.`date +%w`.dump.gz
因此写在CRONTAB中一般是:
15 4 * * * /home/mysql/bin/mysqldump -S/data/app_1/mysql.sock -umysql db_name | gzip -f>/path/to/backup/db_name.`date +\%w`.dump.gz
注意:
1 在crontab中'%'需要转义成'\%'
2 根据日志统计,应用负载最低的时候一般是在早上4-6点

先备份在本地然后传到远程的备份服务器上,或者直接建立一个数据库备份帐号,直接在远程的服务器上备份,远程备份只需要将以上脚本中的-S /path/to/msyql.sock改成-h IP.ADDRESS即可。

数据的恢复和系统的升级
======================
日常维护和数据迁移:在数据盘没有被破坏的情况下
硬盘一般是系统中寿命最低的硬件。而系统(包括操作系统和MySQL应用)的升级和硬件升级,都会遇到数据迁移的问题。
只要数据不变,先装好服务器,然后直接将数据盘(硬盘2)安装上,只需要将启动脚本重新加入到rc.local文件中,系统就算是很好的恢复了。

灾难恢复:数据库数据本身被破坏的情况下
确定破坏的时间点,然后从备份数据中恢复。

应用的设计要点
==============
如果MySQL应用占用的CPU超过10%就应该考虑优化了。

  1. 如果这个服务可以被其他非数据库应用代替(比如很多基于数据库的计数器完全可以用WEB日志统计代替)最好将其禁用:
    非用数据库不可吗?虽然数据库的确可以简化很多应用的结构设计,但本身也是一个系统资源消耗比较大的应用。在某些情况下文本,DBM比数据库是更好的选择,比如:很多应用如果没有很高的实时统计需求的话,完全可以先记录到文件日志中,定期的导入到数据库中做后续统计分析。如果还是需要记录简单的2维键-值对应结构的话可以使用类似于DBM的HEAP类型表。因为HEAP表全部在内存中存取,效率非常高,但服务器突然断电时有可能出现数据丢失,所以非常适合存储在线用户信息,日志等临时数据。即使需要使用数据库的,应用如果没有太复杂的数据完整性需求的化,完全可以不使用那些支持外键的商业数据库,比如MySQL。只有非常需要完整的商业逻辑和事务完整性的时候才需要Oracle这样的大型数据库。对于高负载应用来说完全可以把日志文件,DBM,MySQL等轻量级方式做前端数据采集格式,然后用Oracle MSSQL DB2 Sybase等做数据库仓库以完成复杂的数据库挖掘分析工作。
    有朋友和我说用标准的MyISAM表代替了InnoDB表以后,数据库性能提高了20倍。

  2. 数据库服务的主要瓶颈:单个服务的连接数
    对于一个应用来说,如果数据库表结构的设计能够按照数据库原理的范式来设计的话,并且已经使用了最新版本的MySQL,并且按照比较优化的方式运行了,那么最后的主要瓶颈一般在于单个服务的连接数,即使一个数据库可以支持并发500个连接,最好也不要把应用用到这个地步,因为并发连接数过多数据库服务本身用于调度的线程的开销也会非常大了。所以如果应用允许的话:让一台机器多跑几个MySQL服务分担。将服务均衡的规划到多个MySQL服务端口上:比如app_1 ==> 3301 app_2 ==> 3302...app_9 ==> 3309。一个1G内存的机器跑上10个MySQL是很正常的。让10个MySQLD承担1000个并发连接效率要比让2个MySQLD承担1000个效率高的多。当然,这样也会带来一些应用编程上的复杂度;

  3. 使用单独的数据库服务器(不要让数据库和前台WEB服务抢内存),MySQL拥有更多的内存就可能能有效的进行结果集的缓存;在前面的启动脚本中有一个-O key_buffer=32M参数就是用于将缺省的8M索引缓存增加到32M(当然对于)

  4. 应用尽量使用PCONNECT和polling机制,用于节省MySQL服务建立连接的开销,但也会造成MySQL并发链接数过多(每个HTTPD都会对应一个MySQL线程);

  5. 表的横向拆分:让最常被访问的10%的数据放在一个小表里,90%的历史数据放在一个归档表里(所谓:快慢表),数据中间通过定期“搬家”和定期删除无效数据来节省,毕竟大部分应用(比如论坛)访问2个月前数据的几率会非常少,而且价值也不是很高。这样对于应用来说总是在一个比较小的结果级中进行数据选择,比较有利于数据的缓存,不要指望MySQL中对单表记录条数在10万级以上还有比较高的效率。而且有时候数据没有必要做那么精确,比如一个快表中查到了某个人发表的文章有60条结果,快表和慢表的比例是1:20,那么就可以简单的估计这个人一共发表了1200篇。Google的搜索结果数也是一样:对于很多上十万的结果数,后面很多的数字都是通过一定的算法估计出来的。

  6. 数据库字段设计:表的纵向拆分(过渡范化):将所有的定长字段(char, int等)放在一个表里,所有的变长字段(varchar,text,blob等)放在另外一个表里,2个表之间通过主键关联,这样,定长字段表可以得到很大的优化(这样可以使用HEAP表类型,数据完全在内存中存取),这里也说明另外一个原则,对于我们来说,尽量使用定长字段可以通过空间的损失换取访问效率的提高。在MySQL4中也出现了支持外键和事务的InnoDB类型表,标准的MyISAM格式表和基于HASH结构的HEAP内存表,MySQL之所以支持多种表类型,实际上是针对不同应用提供了不同的优化方式;

  7. 仔细的检查应用的索引设计:可以在服务启动参数中加入 --log-slow-queries[=file]用于跟踪分析应用瓶颈,对于跟踪服务瓶颈最简单的方法就是用MySQL的status查看MySQL服务的运行统计和show processlist来查看当前服务中正在运行的SQL,如果某个SQL经常出现在PROCESS LIST中,一。有可能被查询的此时非常多,二,里面有影响查询的字段没有索引,三,返回的结果数过多数据库正在排序(SORTING);所以做一个脚本:比如每2秒运行以下show processlist;把结果输出到文件中,看到底是什么查询在吃CPU。

  8. 全文检索:如果相应字段没有做全文索引的话,全文检索将是一个非常消耗CPU的功能,因为全文检索是用不上一般数据库的索引的,所以要进行相应字段记录遍历。关于全文索引可以参考一下基于Java的全文索引引擎lucene的介绍

  9. 前台应用的记录缓存:比如一个经常使用数据库认证,如果需要有更新用户最后登陆时间的操作,最好记录更新后就把用户放到一个缓存中(设置2个小时后过期),这样如果用户在2个小时内再次使用到登陆,就直接从缓存里认证,避免了过于频繁的数据库操作。

  10. 查询优先的表应该尽可能为where和order by字句中的字段加上索引,数据库更新插入优先的应用索引越少越好。

总之:对于任何数据库单表记录超过100万条优化都是比较困难的,关键是要把应用能够转化成数据库比较擅长的数据上限内。也就是把复杂需求简化成比较成熟的解决方案内。

一次优化实战
============
以下例子是对一个论坛应用进行的优化:

  1. 用Webalizer代替了原来的通过数据库的统计。
  2. 首先通过TOP命令查看MySQL服务的CPU占用左右80%和内存占用:10M,说明数据库的索引缓存已经用完了,修改启动参数,增加了-O key_buffer=32M,过一段时间等数据库稳定后看的内存占用是否达到上限。最后将缓存一直增加到64M,数据库缓存才基本能充分使用。对于一个数据库应用来说,把内存给数据库比给WEB服务实用的多,因为MySQL查询速度的提高能加快web应用从而节省并发的WEB服务所占用的内存资源。
  3. 用show processlist;统计经常出现的SQL:

    每分钟运行一次show processlist并记录日志:
    * * * * * (/home/mysql/bin/mysql -uuser -ppassword < /home/chedong/show_processlist.sql >>  /home/chedong/mysql_processlist.log)

    show_processlist.sql里就一句:
    show processlist;

    比如可以从日志中将包含where的字句过滤出来:
    grep where mysql_processlist.log
    如果发现有死锁,一定要重新审视一下数据库设计了,对于一般情况:查询速度很慢,就将SQL where字句中没有索引的字段加上索引,如果是排序慢就将order by字句中没有索引的字段加上。对于有%like%的查询,考虑以后禁用和使用全文索引加速。

  4. 还是根据show processlist;看经常有那些数据库被频繁使用,考虑将数据库拆分到其他服务端口上。

MSSQL到MySQL的数据迁移:ACCESS+MySQL ODBC Driver

在以前的几次数据迁移实践过程中,我发现最简便的数据迁移过程并不是通过专业的数据库迁移工具,也不是MSSQL自身的DTS进行数据迁移(迁移过程中间会有很多表出错误警告),但通过将MSSQL数据库通过ACCESS获取外部数据导入到数据库中,然后用ACCESS的表==>右键==>导出,制定ODBC,通过MySQL的DSN将数据导出。这样迁移大部分数据都会非常顺利,如果导出的表有索引问题,还会出添加索引提示(DTS就不行),然后剩余的工作就是在MySQL中设计字段对应的SQL脚本了。

参考文档:

MySQL的参考:
http://dev.mysql.com/doc/

分享到:
评论

相关推荐

    MySQL服务维护笔记.zip_mysql 维护

    MySQL服务维护笔记

    MySQL服务维护笔记第1/2页

    MySQL服务维护笔记

    MySQL Word 版本笔记超级详细版本.docx

    mysql的笔记详细总结,用于自己的学习笔记记录DB:数据库(Database)即存储数据的“仓库”。它保存了一系列有组织的数据。 DBMS:数据库管理系统(Database Management System):是一种操纵和管理数据库的大型软件...

    MySQL5.7学习笔记 完整版PDF

    《MySQL5.7学习笔记》将从MySQL5.7的安装、配置、使用等方面进行详细介绍,帮助读者快速掌握MySQL5.7的使用技巧。首先,我们将介绍MySQL5.7的安装方法,包括Windows和Linux平台的安装步骤。然后,我们将讲解MySQL5.7...

    MySQL数据库学习笔记

    数据库管理系统能够为数据库提供数据的定义、建立、维护、查询和统计等操作功能,并完成对数据完整性、安全性进行控制的功能。 一般的,我们说到的数据库,就是指DBMS. 数据库服务器. 数据库应用系统(DataBase ...

    MySQL学习笔记_个人学习用

    MySQL学习笔记_个人学习用,参考书籍是《深入浅出MySQL数据库开发、优化与管理维护》

    MySQL数据库笔记.doc

    数据库系统的一个主要目的是给用户提供数据的抽象视图,也就是说隐藏关于数据存储和维护的某些细节,笔记里面包括了数据库的CRUD的具体操作以及案例,旨在帮助小伙伴更好更快的掌握数据库的原理以及使用。

    高级MySQL笔记时,需要深入了解数据库的内部机制和优化技巧,以提高数据库性能和效率

    mysql高级笔记。MySQL是一种流行的关系型数据库管理系统,具有高度的灵活性和可扩展性。在进行高级MySQL笔记时,需要深入了解数据库的内部机制和优化技巧,以提高数据库性能和效率。索引优化:索引是提高数据库查询...

    MySQL NDB集群部署与维护

    通过学习mysql官方文档,在实验中形成的一份简明扼要的笔记性质文档,适合MySQL NDB集群感兴趣的同学参考。

    mysql高级笔记.rar

    采用了关系模型来组织数据的存储,以行和列(即表格)的形式存储数据并记录数据与数据之间的关系--将数据存储在表格中,可以通过建立表格与表格之间的关联来维护数据与数据之间的关系。 非关系型数据库(NoSQL (Not...

    mariadb学习笔记

    Mariadb学习笔记,MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。在存储引擎方面,使用XtraDB...

    MySQL学习笔记4-数据库管理和备份恢复.md

    最后提出数据库定期维护的必要性,建议了自动备份、性能监控、日志清理等具体维护措施并提供代码实例。内容结构清晰,点评精当。 适合人群: 需要学习数据库管理和维护知识的学习者。文中具体的技术点解析及代码示例...

    MySQL 数据库设计复习笔记及项目实战

    最近手头上有3个项目开动,其他2个都是从底层开始的,一个已经开始了一段时间的了,在小城市小团队开发的条件下,都没有专门的DBA来做数据库的设计和维护,往往都是开发人员顶上,可是看了很多的数据库的设计,感觉...

    JAVA 五年的工作经验和学习笔记

    本文档还在持续维护中,各位可以通过《笔记变更说明》查看升级日志。 在这里声明下,本文档一部分是个人从学习、工作中整理出来的(代码都是经过调试的),还有一部分是从网上整理的。 本站相关文档都是经过...

    【毕业设计】基于springboot的仿共享单车后台源码及笔记【源码+SQL脚本】.zip

    redis缓存token(token作为用户的标识,维护用户的状态,类似于session) redis结合ActiveMQ发送短信验证码和防止恶意短信无限发送 整合云存储,保存头像(七牛云对象存储为例) 整合mongodb获取附近单车以及距离,...

    java_study_note:个人学习笔记

    以后不再维护,转移到笔记总览(source目录)反弹:Java笔记基础java知识点,基本全是代码+注释反射,注解,jdbc,javaweb,redis基本使用java并发基础,完善中。替代设计原理。 杂项,日常学习中遇见的一些问题,...

    shardingsphere学习笔记.xmind

    目前支持数据分片、读写分离、数据加密、影子库压测等功能,以及支持 MySQL、PostgreSQL、SQLServer、Oracle 等数据库。官方最新版本为5.0.0-beta。说明:目前项目实际使用版本是4.1.1的(官方不再维护),但是...

    基于SSM+MySQL的在线读书与阅读分享论坛设计与实现(源码+数据库+文档)

    基于SSM+MySQL的在线读书与阅读分享论坛设计与实现(源码+数据库+文档).zip 高分通过项目,已获导师指导。 本项目是一套基于SSM的在线读书与阅读分享论坛,主要针对计算机相关专业的正在做毕设的学生和需要项目实战...

    Personal-Encyclopedia:帮助维护数据和笔记的 Java 软件

    个人百科Java 软件可帮助维护您的数据和笔记,并提供搜索选项以有效地管理您的数据。 使用的编程语言是Java 。 为了处理数据,它使用MySQL数据库。 ##MySQL 数据库所用数据库的名称是Personalenc 。本系统使用的表 ...

Global site tag (gtag.js) - Google Analytics