- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章MySQL服务维护笔记由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
使用MySQL服务的一些经验,主要从以下几个方面考虑的MySQL服务规划设计。对于高负载站点来说PHP和MySQL运行在一起(或者说任何应用和数据库运行在一起的规划)都是性能最大的瓶颈,这样的设计有如让人一手画圆一手画方,这样2个人的工作效率肯定不如让一个人专门画圆一个人专门画方效率高,让应用和数据库都跑在一台高性能服务器上说不定还不如跑在2台普通服务器上快.
以下就是针对MySQL作为专门的数据库服务器的优化建议:
MySQL服务的安装/配置的通用性,
系统的升级和数据迁移方便性,
备份和系统快速恢复,
数据库应用的设计要点,
一次应用优化实战,
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 。
makeinstall 。
服务的启动和停止 。
================ 。
1复制缺省的mysql/var/mysql到/data/app_1/目录下, 。
2MySQLD的启动脚本: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"$@" 。
-Omax_connections=500-Owait_timeout=600-Okey_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 。
注意:必须写全路径 。
3MySQLD的停止脚本:stop_mysql.sh 。
#!/bin/sh 。
rundir=`dirname"$0"` 。
echo"$rundir" 。
/home/mysql/bin/mysqladmin-umysql-S"$rundir"/mysql.sockshutdown 。
使用这个脚本的好处在于:
1多个服务启动:对于不同服务只需要修改脚本中的--port[=端口号]参数。单个目录下的数据和服务脚本都是可以独立打包的.
2所有服务相应文件都位于/data/app_1/目录下:比如:mysql.pidmysql.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上运行了.
服务的备份 。
========== 。
尽量使用MySQLDUMP而不是直接备份数据文件,以下是一个按weekday将数据轮循备份的脚本:备份的间隔和周期可以根据备份的需求确定 。
/home/mysql/bin/mysqldump-S/data/app_1/mysql.sock-umysqldb_name|gzip-f>/path/to/backup/db_name.`data+%w`.dump.gz 。
因此写在CRONTAB中一般是:
154***/home/mysql/bin/mysqldump-S/data/app_1/mysql.sock-umysqldb_name|gzip-f>/path/to/backup/db_name.`data+%w`.dump.gz 。
注意:
1在crontab中'%'需要转义成'%' 。
2根据日志统计,应用负载最低的时候一般是在早上4-6点 。
先备份在本地然后传到远程的备份服务器上,或者直接建立一个数据库备份帐号,直接在远程的服务器上备份,远程备份只需要将以上脚本中的-S/path/to/msyql.sock改成-hIP.ADDRESS即可.
数据的恢复和系统的升级 。
====================== 。
日常维护和数据迁移:在数据盘没有被破坏的情况下 。
硬盘一般是系统中寿命最低的硬件。而系统(包括操作系统和MySQL应用)的升级和硬件升级,都会遇到数据迁移的问题.
只要数据不变,先装好服务器,然后直接将数据盘(硬盘2)安装上,只需要将启动脚本重新加入到rc.local文件中,系统就算是很好的恢复了.
灾难恢复:数据库数据本身被破坏的情况下 。
确定破坏的时间点,然后从备份数据中恢复.
应用的设计要点 。
============== 。
如果MySQL应用占用的CPU超过10%就应该考虑优化了.
如果这个服务可以被其他非数据库应用代替(比如很多基于数据库的计数器完全可以用WEB日志统计代替)最好将其禁用:
非用数据库不可吗?虽然数据库的确可以简化很多应用的结构设计,但本身也是一个系统资源消耗比较大的应用。在某些情况下文本,DBM比数据库是更好的选择,比如:很多应用如果没有很高的实时统计需求的话,完全可以先记录到文件日志中,定期的导入到数据库中做后续统计分析。如果还是需要记录简单的2维键-值对应结构的话可以使用类似于DBM的HEAP类型表。因为HEAP表全部在内存中存取,效率非常高,但服务器突然断电时有可能出现数据丢失,所以非常适合存储在线用户信息,日志等临时数据。即使需要使用数据库的,应用如果没有太复杂的数据完整性需求的化,完全可以不使用那些支持外键的商业数据库,比如MySQL。只有非常需要完整的商业逻辑和事务完整性的时候才需要Oracle这样的大型数据库。对于高负载应用来说完全可以把日志文件,DBM,MySQL等轻量级方式做前端数据采集格式,然后用OracleMSSQLDB2Sybase等做数据库仓库以完成复杂的数据库挖掘分析工作.
有朋友和我说用标准的MyISAM表代替了InnoDB表以后,数据库性能提高了20倍.
数据库服务的主要瓶颈:单个服务的连接数 。
对于一个应用来说,如果数据库表结构的设计能够按照数据库原理的范式来设计的话,并且已经使用了最新版本的MySQL,并且按照比较优化的方式运行了,那么最后的主要瓶颈一般在于单个服务的连接数,即使一个数据库可以支持并发500个连接,最好也不要把应用用到这个地步,因为并发连接数过多数据库服务本身用于调度的线程的开销也会非常大了。所以如果应用允许的话:让一台机器多跑几个MySQL服务分担。将服务均衡的规划到多个MySQL服务端口上:比如app_1==>3301app_2==>3302...app_9==>3309。一个1G内存的机器跑上10个MySQL是很正常的。让10个MySQLD承担1000个并发连接效率要比让2个MySQLD承担1000个效率高的多。当然,这样也会带来一些应用编程上的复杂度,
使用单独的数据库服务器(不要让数据库和前台WEB服务抢内存),MySQL拥有更多的内存就可能能有效的进行结果集的缓存;在前面的启动脚本中有一个-Okey_buffer=32M参数就是用于将缺省的8M索引缓存增加到32M(当然对于) 。
应用尽量使用PCONNECT和polling机制,用于节省MySQL服务建立连接的开销,但也会造成MySQL并发链接数过多(每个HTTPD都会对应一个MySQL线程),
表的横向拆分:让最常被访问的10%的数据放在一个小表里,90%的历史数据放在一个归档表里(所谓:快慢表),数据中间通过定期“搬家”和定期删除无效数据来节省,毕竟大部分应用(比如论坛)访问2个月前数据的几率会非常少,而且价值也不是很高。这样对于应用来说总是在一个比较小的结果级中进行数据选择,比较有利于数据的缓存,不要指望MySQL中对单表记录条数在10万级以上还有比较高的效率。而且有时候数据没有必要做那么精确,比如一个快表中查到了某个人发表的文章有60条结果,快表和慢表的比例是1:20,那么就可以简单的估计这个人一共发表了1200篇。Google的搜索结果数也是一样:对于很多上十万的结果数,后面很多的数字都是通过一定的算法估计出来的.
数据库字段设计:表的纵向拆分(过渡范化):将所有的定长字段(char,int等)放在一个表里,所有的变长字段(varchar,text,blob等)放在另外一个表里,2个表之间通过主键关联,这样,定长字段表可以得到很大的优化(这样可以使用HEAP表类型,数据完全在内存中存取),这里也说明另外一个原则,对于我们来说,尽量使用定长字段可以通过空间的损失换取访问效率的提高。在MySQL4中也出现了支持外键和事务的InnoDB类型表,标准的MyISAM格式表和基于HASH结构的HEAP内存表,MySQL之所以支持多种表类型,实际上是针对不同应用提供了不同的优化方式,
仔细的检查应用的索引设计:可以在服务启动参数中加入--log-slow-queries[=file]用于跟踪分析应用瓶颈,对于跟踪服务瓶颈最简单的方法就是用MySQL的status查看MySQL服务的运行统计和showprocesslist来查看当前服务中正在运行的SQL,如果某个SQL经常出现在PROCESSLIST中,一。有可能被查询的此时非常多,二,里面有影响查询的字段没有索引,三,返回的结果数过多数据库正在排序(SORTING);所以做一个脚本:比如每2秒运行以下showprocesslist;把结果输出到文件中,看到底是什么查询在吃CPU.
全文检索:如果相应字段没有做全文索引的话,全文检索将是一个非常消耗CPU的功能,因为全文检索是用不上一般数据库的索引的,所以要进行相应字段记录遍历。关于全文索引可以参考一下基于Java的全文索引引擎lucene的介绍.
前台应用的记录缓存:比如一个经常使用数据库认证,如果需要有更新用户最后登陆时间的操作,最好记录更新后就把用户放到一个缓存中(设置2个小时后过期),这样如果用户在2个小时内再次使用到登陆,就直接从缓存里认证,避免了过于频繁的数据库操作.
查询优先的表应该尽可能为where和orderby字句中的字段加上索引,数据库更新插入优先的应用索引越少越好.
总之:对于任何数据库单表记录超过100万条优化都是比较困难的,关键是要把应用能够转化成数据库比较擅长的数据上限内。也就是把复杂需求简化成比较成熟的解决方案内.
一次优化实战 。
============ 。
以下例子是对一个论坛应用进行的优化:
用Webalizer代替了原来的通过数据库的统计.
首先通过TOP命令查看MySQL服务的CPU占用左右80%和内存占用:10M,说明数据库的索引缓存已经用完了,修改启动参数,增加了-Okey_buffer=32M,过一段时间等数据库稳定后看的内存占用是否达到上限。最后将缓存一直增加到64M,数据库缓存才基本能充分使用。对于一个数据库应用来说,把内存给数据库比给WEB服务实用的多,因为MySQL查询速度的提高能加快web应用从而节省并发的WEB服务所占用的内存资源.
用showprocesslist;统计经常出现的SQL:
每分钟运行一次showprocesslist并记录日志:
*****(/home/mysql/bin/mysql-uuser-ppassword>/home/chedong/mysql_processlist.log) 。
show_processlist.sql里就一句:
showprocesslist,
比如可以从日志中将包含where的字句过滤出来:
grepwheremysql_processlist.log 。
如果发现有死锁,一定要重新审视一下数据库设计了,对于一般情况:查询速度很慢,就将SQLwhere字句中没有索引的字段加上索引,如果是排序慢就将orderby字句中没有索引的字段加上。对于有%like%的查询,考虑以后禁用和使用全文索引加速.
还是根据showprocesslist;看经常有那些数据库被频繁使用,考虑将数据库拆分到其他服务端口上.
MSSQL到MySQL的数据迁移:ACCESS+MySQLODBCDriver 。
在以前的几次数据迁移实践过程中,我发现最简便的数据迁移过程并不是通过专业的数据库迁移工具,也不是MSSQL自身的DTS进行数据迁移(迁移过程中间会有很多表出错误警告),但通过将MSSQL数据库通过ACCESS获取外部数据导入到数据库中,然后用ACCESS的表==>右键==>导出,制定ODBC,通过MySQL的DSN将数据导出。这样迁移大部分数据都会非常顺利,如果导出的表有索引问题,还会出添加索引提示(DTS就不行),然后剩余的工作就是在MySQL中设计字段对应的SQL脚本了.
参考文档:
MySQL的参考:
http://www.mysql.com/documentation/mysql/bychapter/ 。
最后此篇关于MySQL服务维护笔记的文章就讲到这里了,如果你想了解更多关于MySQL服务维护笔记的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
目前我正在构建相当大的网络系统,我需要强大的 SQL 数据库解决方案。我选择 Mysql 而不是 Postgres,因为一些任务需要只读(MyISAM 引擎)而其他任务需要大量写入(InnoDB)。
我在 mysql 中使用如下命令。当它显示表格数据时,它被格式化为一个非常干净的表格,间距均匀且 |作为列分隔符。 SELECT * FROM TABLE_NAME; 当我从 CLI 运行命令时,如下
我知道这个问题之前已经被问过好几次了,我已经解决了很多问题,但到目前为止没有任何效果。 MySQL 试图将自身安装到的目录 (usr/local/mysql) 肯定有问题。关于我的错误的奇怪之处在于我
以下是我的 SQL 数据结构,我正在尝试如下两个查询: Select Wrk_ID, Wrk_LastName, Skill_Desc from Worker, Skill where
我们有一个本地 mysql 服务器(不在公共(public)域上),并希望将该服务器复制到我们拥有的 google 云 sql 实例。我的问题是:1.这可能吗?2.我们的本地服务器只能在本地网络上访问
我有一个表(test_table),其中一些字段值(例如字段 A、B 和 C)是从外部应用程序插入的,还有一个字段(字段 D),我想从现有表(store_table)插入其值,但在插入前者(A、B 和
我想创建一个 AWS RDS 实例,然后使用 terraform 管理数据库用户。因此,首先,我创建了一个 RDS 实例,然后使用创建的 RDS 实例初始化 mysql 提供程序,以进一步将其用于用户
当用户在我的网站上注册时,他们会在我的一个数据库中创建自己的表格。该表存储用户发布的所有帖子。我还想做的是也为他们生成自己的 MySql 用户——该用户仅有权从他们的表中读取、写入和删除。 创建它应该
我有一个关于 ColdFusion 和 Mysql 的问题。我有两个表:PRODUCT 和 PRODUCT_CAT。我想列出包含一些标记为:IS_EXTRANET=1 的特殊产品的类别。所以我写了这个
我想获取 recipes_id 列的值,以获取包含 ingredient_id 的 2,17 和 26 条目的值。 假设 ingredient_id 2 丢失则不获取记录。 我已经尝试过 IN 运算符
在 Ubuntu 中,我通常安装两者,但 MySQL 的客户端和服务器之间有什么区别。 作为奖励,当一个新语句提到它需要 MySQL 5.x 时,它是指客户端、服务器还是两者兼而有之。例如这个链接ht
我重新访问了我的数据库并注意到我有一些 INT 类型的主键。 这还不够独特,所以我想我会有一个指导。 我来自微软 sql 背景,在 ssms 中你可以 选择类型为“uniqeidentifier”并自
我的系统上有 MySQL,我正在尝试确定它是 Oracle MySQL 还是 MySQL。 Oracle MySQL 有区别吗: http://www.oracle.com/us/products/m
我是在生产 MySQL 中运行的应用程序的新维护者。之前的维护者已经离开,留下的文档很少,而且联系不上了。 我面临的问题是执行以下请求大约需要 10 秒: SELECT COUNT(*) FROM `
我有两个位于不同机器上的 MySQL 数据库。我想自动将数据从一台服务器传输到另一台服务器。比方说,我希望每天早上 4:00 进行数据传输。 可以吗?是否有任何 MySQL 内置功能可以让我们做到这一
有什么方法可以使用 jdbc 查询位于 mysql 根目录之外的目录中的 mysql 表,还是必须将它们移动到 mysql 根目录内的数据库文件夹中?我在 Google 上搜索时没有找到任何东西。 最
我在 mysql 数据库中有两个表。成员和 ClassNumbers。两个表都有一个付费年份字段,都有一个代码字段。我想用代码数字表中的值更新成员表中的付费年份,其中成员中的代码与 ClassNumb
情况:我有 2 台服务器,其中一台当前托管一个实时 WordPress 站点,我希望能够将该站点转移到另一台服务器,以防第一台服务器出现故障。传输源文件很容易;传输数据库是我需要弄清楚如何做的。两台服
Phpmyadmin 有一个功能是“复制数据库到”..有没有mysql查询来写这个函数?类似于将 db A 复制到新的 db B。 最佳答案 首先创建复制数据库: CREATE DATABASE du
我有一个使用 mySQL 作为后端的库存软件。我已经在我的计算机上对其进行了测试,并且运行良好。 当我在计算机上安装我的软件时,我必须执行以下步骤: 安装 mySQL 服务器 将用户名指定为“root
我是一名优秀的程序员,十分优秀!