分类目录归档:Mysql性能优化

mysqlbinlog工具使用

1、使用mysqlbinlog工具来恢复

Mysqlbinlog日志如何开启?

在my.cnf这个文件中加一行。

#vi /etc/my.cnf
[mysqld]
log-bin=mysqlbin-log #添加这一行就可以了,=号后面自己定义日志文件名,默认该文件是存储在datadir中。

mysqlbinlog用法详细说明

服务器生成的二进制日志文件写成二进制格式。要想检查这些文本格式的文件,应使用mysqlbinlog实用工具。

#mysqlbinlog [options] log-files…

例如,要想显示二进制日志mysql-bin.407的内容,使用下面的命令:

#mysqlbinlog mysql-bin.407

输出包括在mysql-bin.407中包含的所有语句,以及其它信息例如每个语句花费的时间、客户发出的线程ID、发出线程时的时间戳等等。

参数说明(mysql5以上版本参数添加了很多):
mysqlbinlog支持下面的选项:

—help,-? 显示帮助消息并退出。
—database=db_name,-d db_name 只列出该数据库的条目(只用本地日志)。
–force-read,-f 使用该选项,如果mysqlbinlog读它不能识别的二进制日志事件,它会打印警告,忽略该事件并继续。没有该选项,如果mysqlbinlog读到此类事件则停止。
–hexdump,-H 在注释中显示日志的十六进制转储。该输出可以帮助复制过程中的调试。在MySQL 5.1.2中添加了该选项。
–host=host_name,-h host_name 获取给定主机上的MySQL服务器的二进制日志。
–local-load=path,-l pat 为指定目录中的LOAD DATA INFILE预处理本地临时文件。
–offset=N,-o N 跳过前N个条目。
–password[=password],-p[password] 当连接服务器时使用的密码。如果使用短选项形式(-p),选项和 密码之间不能有空格。如果在命令行中–password或-p选项后面没有 密码值,则提示输入一个密码。
–port=port_num,-P port_num 用于连接远程服务器的TCP/IP端口号。
–position=N,-j N 不赞成使用,应使用–start-position。
–protocol={TCP | SOCKET | PIPE | -position 使用的连接协议。
–read-from-remote-server,-R 从MySQL服务器读二进制日志。如果未给出该选项,任何连接参数选项将被忽略。这些选项是–host、–password、–port、–protocol、–socket和–user。
–result-file=name, -r name 将输出指向给定的文件。
–short-form,-s 只显示日志中包含的语句,不显示其它信息。
–socket=path,-S path 用于连接的套接字文件。
–start-datetime=datetime 从二进制日志中第1个日期时间等于或晚于datetime参量的事件开始读取。datetime值相对于运行mysqlbinlog的机器上的本地时区。该值格式应符合DATETIME或TIMESTAMP数据类型。
–stop-datetime=datetime 从二进制日志中第1个日期时间等于或晚于datetime参量的事件起停止读。关于datetime值的描述参见–start-datetime选项。该选项可以帮助及时恢复。
–start-position=N 从二进制日志中第1个位置等于N参量时的事件开始读。
–stop-position=N 从二进制日志中第1个位置等于和大于N参量时的事件起停止读。
–to-last-logs,-t 在MySQL服务器中请求的二进制日志的结尾处不停止,而是继续打印直到最后一个二进制日志的结尾。如果将输出发送给同一台MySQL服务器,会导致无限循环。该选项要求–read-from-remote-server。
–disable-logs-bin,-D 禁用二进制日志。如果使用–to-last-logs选项将输出发送给同一台MySQL服务器,可以避免无限循环。该选项在崩溃恢复时也很有用,可以避免复制已经记录的语句。注释:该选项要求有SUPER权限。
–user=user_name,-u user_name 连接远程服务器时使用的MySQL用户名。
–version,-V 显示版本信息并退出。

还可以使用–var_name=value选项设置下面的变量:
Variables (–variable-name=value)
and boolean options {FALSE|TRUE} Value (after reading options)
——————————— —————————–
base64-output (No default value)
character-sets-dir (No default value)
database (No default value)
debug-check FALSE
debug-info FALSE
disable-log-bin FALSE
force-if-open TRUE
force-read FALSE
hexdump FALSE
host (No default value)
local-load (No default value)
offset 0
port 3306
position 4
read-from-remote-server FALSE
server-id 0
set-charset (No default value)
short-form FALSE
socket /tmp/mysql.sock
start-datetime (No default value)
start-position 4
stop-datetime (No default value)
stop-position 18446744073709551615
to-last-log FALSE
user (No default value)
open_files_limit 64
例子:
查看日志

#mysqlbinlog mysql-bin.407

根据position从20-2000查找resource库相关记录,并输出到指定文件:

#mysqlbinlog –start-position=”20″ –stop-position=”2000″ –database=resource mysql-bin.407 –result-file=result.sql

查找并导入数据库:

#mysqlbinlog –start-position=”20″ –stop-position=”2000″ –database=resource mysql-bin.407 | mysql -u root

还可以根据时间来查找记录:

#mysqlbinlog –start-datetime=”2012-09-20 8:10:00″ –stop-datetim=”2012-09-25 07:30:00″ mysql-bin.407 –result-file=result.sql
2、Mysqlbinlog导出并转换编码导入

原中文编码为gb2312,转换utf8编码,并插入
(1)从position=387426452开始导出resource数据库信息
#/usr/local/mysql/bin/mysqlbinlog –position=387426452 –set-charset=utf8 –database=resource mysql-bin.407 –result-file=result_resource.sql

(2)转换编码为utf8
#iconv -t utf-8 -f gb2312 -c result_resource.sql > new_result_resource.sql_utf8.sql

(3)导入数据库
在mysql会话中需要set names utf8;

mysql> set names utf8;

mysql> source /tmp/new_result_resource.sql_utf8.sql

MySQL数据库性能优化之硬件瓶颈分析

我们在谈论基于硬件进行优化的时候,不能仅仅将数据库使用的硬件划分为主机和存储两部分,而是需要进一步对硬件进行更细的分解,至少也应该分解到如下范畴:

 主机

1. CPU:仅仅只能决定运算速度,即使是运算速度都还取决于与内存之间的总线带宽以及内存本身的速度。

2. 内存:大小决定了所能缓存的数据量,主要决定了热点数据的访问速度。

3. 磁盘:

3.1 大小:决定了你最终能存放多少数据量。

3.2 转速:决定了你每一次IO请求的延时时间,也就是决定了我们常说的IOPS和MBPS。

3.3 数目:磁盘数目决定了。

3.4 类型

3.4.1 机械:SAS or SATA or FC

3.4.2 SSD:磁盘 or PCI卡

4. Raid卡:

4.1 缓存:缓存大小对数据写入速度有较大影响,使用策略也会直接影响IO效率。

4.2 电池:电池充放电策略会影响到瞬时IO的波动。

5. 其他:如总线带宽等,决定了CPU与内存间数据传输效率,这一点很多时候关注较少,但也可能会出现瓶颈。

 存储

1. 内存:存储设备同样也有内存,用来存储前端主机访问的热点数据。存储的内存大小同样决定了热点数据的访问速度。

2. 磁盘:和主机磁盘类似。

3. 线路/环路带宽:环路带宽必须能够匹配磁盘带宽,至少不能少于磁盘所能输出的能力,否则就想被堵在高速收费站等待通行的车辆一样。

网络

1. 延时:不同的网络设备其延时会有差异,对于 OLTP 设备来说,延时自然是越小越好。

2. 吞吐量:对于数据库集群来说,各个节点之间的网络吞吐量可能直接决定集群的处理能力。

3. iops:对于 OLTP 系统,数据传输更多是以小IO多并发方式,有时候光有大带宽并不一定能满足需求。

硬件角度所能提供的处理能力,一定是上面所列的多个方面(这里仅仅只是主要部分,可能还有其他)共同决定的整体能力,任何一个方面出现瓶颈,都能导致整体性能上不去,也就是我们常说的木桶原理。

在以往的经验中,最容易出现性能瓶颈的地方主要会出现在以下几个方面:

IO资源方面瓶颈

出现 IO 资源方面瓶颈的时候,主要表现在服务器 iowait 很高,usr 占比较少,系统响应较慢,数据库中经常会存在大量执行状态的 session。

遇到 IO 资源方面的瓶颈,我们可以使用的硬件层面优化方案主要就是:

1. 增加内存加大可缓存的数据量:这个方案能否达到效果取决于系统热点数据的总量,毕竟内存的成本也是比较高的,而且单台设备所能管理的内存量也是有限的。

2. 改善底层存储设备的 IO 能力:如本文前面所述,底层存储能力的改善同时取决于多个方面,既有单个磁盘本身的能力问题,也包括磁盘数目方面的策略,同时还受到存储自身以及存储和主机之间的带宽限制。所以在优化底层存储能力的同时需要同时考虑到这3方面的因素,做好总体分析和局部的平衡。

 CPU资源方面瓶颈

当 CPU 方面资源遇到瓶颈的时候,主要表现在服务器CPU利用率中 usr 所占比例很高,iowait却很小。这类问题大多出现在数据量并不是太大,同时又有足够内存来对数据进行缓存的应用场景。同时也是目前大多数中小网站所面临的数据库性能瓶颈。

当遇到 CPU 方面的资源瓶颈的时候,可能由两个方面造成:

1. 过多依赖数据库进行逻辑运算:对于这种状况,最好的优化方式是将运算尽可能从数据库端迁移到应用端,降低数据库主机的计算量。毕竟对有状态的系统设备(数据库)进行扩容的成本远高于无状态类系统设备(应用)。当然如果非要从数据库端的硬件来解决问题,那就只有通过增加设备CPU数目(如果支持),或者是使用CPU能力更为高端的主机来替换老主机。

2. 数据库逻辑IO太大:对于这类状况,从硬件角度来说能做的就只有提升CPU处理能力。要么增加 CPU 数目(如果支持),要么换CPU更强劲的主机。但是在这之前,还是建议先尝试从应用角度优化看看是否能够尽量降低非必要请求或者是减少每次请求的数据量。同时从数据库角度针对 Schema结构以及索引进行相应的优化调整,尽可能让完成一次请求所需要检索的数据量更小,从而达到降低逻辑IO的目的。

网络资源方面的瓶颈

一般来说应用与数据库之间的网络交互所需的资源并不是非常大,所以这个环境遇到瓶颈的可能并不是非常大。但是在分布式的集群环境中,各个数据库节点之间的网络环境经常会称为系统的瓶颈。

比较常见的场景如 MySQL Cluster 或者是 Oracle RAC 环境中,节点之间的数据交换网络环境的优劣可能直接影响到系统的整体处理能力,因为在节点间会存在大量的数据交换,都是依赖网络传输来完成。

在这样的场景中,廉价一点的解决方案是通过 万兆交换机 来替换现在常用的 千兆交换机 来提升网络处理能力降低网络延时。不过这个方案主要提升的是吞吐量方面,对于延时方面的提升可能并不一定能满足某些要求非常高的场景。这时候就该考虑使用更为昂贵但也更高效的方案:用 Infiniband 替换普通交换机来极大的降低网络方面所带来的数据交换延时。

Percona Server5.5.x安装配置

Percona 为 MySQL 数据库服务器进行了改进,在功能和性能上较 MySQL 有着很显著的提升。该版本提升了在高负载情况下的 MyIsAM 的性能、为 DBA 提供一些非常有用的性能诊断工具;另外有更多的参数和命令来控制服务器行为。
1、
安装依赖包

yum install make gcc gcc-c++ ncurses ncurses-devel bison

2、下载源码,编译安装

wget http://www.percona.com/redir/downloads/Percona-Server-5.5/Percona-Server-5.5.27-28.1/source/Percona-Server-5.5.27-rel28.1.tar.gz

tar zxvf Percona-Server-5.5.27-rel28.1.tar.gz

cd Percona-Server-5.5.27-rel28.1

设置变量、创建安装路径:

INSTALL_PATH=/data/usr/percona #设置安装路径

创建mysql组和用户

useradd -r -M -s /sbin/nologin mysql

编译安装:

cmake . \

-DCMAKE_BUILD_TYPE=RelWithDebInfo \

-DBUILD_CONFIG=mysql_release \

-DFEATURE_SET=community \

-DWITH_EMBEDDED_SERVER=OFF \

-DCMAKE_INSTALL_PREFIX=$INSTALL_PATH \

make && make install

3、配置

chown -R msyql:mysql /data/usr/percona

安装系统表:

cd /data/usr/percona

sh scripts/mysql_install_db –user=mysql

chown -R root /data/usr/percona

chown -R mysql:mysql /data/usr/percona/data

配置my.cnf配置文件:

cp support-files/my-medium.cnf /etc/my.cnf

配置mysqlservice服务:

cp support-files/mysql.server /etc/init.d/mysql.server

chmod a+x /etc/init.d/mysql.server

chkconfig –add mysql.server

修改mysqlroot密码:

/data/usr/percona/bin/mysqladmin -uroot password ‘password’

4、启动mysql

/data/usr/percona/bin/mysqld_safe –user=mysql &

验证启动是否成功:

netstat -tunlp|grep 3306

数据库安全漏洞浅析

数据库漏洞的种类繁多和危害性严重是数据库系统受到攻击的主要原因,通过研究数据库漏洞分类,有助于人们对漏洞的深入理解并加以预防和避免。

美国Verizon就“核心数据是如何丢失的”做过一次全面的市场调查,结果发现,75%的数据丢失情况是由于数据库漏洞造成的,这说明数据库的安全非常重要。
据CVE的数据安全漏洞统计,Oracle、SQL Server、MySQL等主流数据库的漏洞逐年上升,以Oracle为例,当前漏洞总数已经超过了1200多个。

数据库安全漏洞从来源上,大致可以分为四类:缺省安装漏洞、人为使用上的漏洞、数据库设计缺陷、数据库产品的bug。

继续阅读

mysql长连接和短连接

什么是长连接?

其实长连接是相对于通常的短连接而说的,也就是长时间保持客户端与服务端的连接状态。

通常的短连接操作步骤是:

连接-》数据传输-》关闭连接

而长连接通常就是:

连接-》数据传输-》保持连接-》数据传输-》保持连接-》…………-》关闭连接

这就要求长连接在没有数据通信时,定时发送数据包,以维持连接状态,短连接在没有数据传输时直接关闭就行了

什么时候用长连接,短连接?

长连接主要用于在少数客户端与服务端的频繁通信,因为这时候如果用短连接频繁通信常会发生Socket出错,并且频繁创建Socket连接也是对资源的浪费。

但是对于服务端来说,长连接也会耗费一定的资源,需要专门的线程(unix下可以用进程管理)来负责维护连接状态。

总之,长连接和短连接的选择要视情况而定。

 

首先,如果使用了长连接而长期没有对数据库进行任何操作,那么在timeout值后,mysql server就会关闭此连接,而客户端在执行查询的时候就会得到一个类似于“MySQL server has gone away“这样的错误。

在使用mysql_real_connect连接数据库之后,再使用mysql_options( &mysql, MYSQL_OPT_RECONNECT, … ) 来设置为自动重连。这样当mysql连接丢失的时候,使用mysql_ping能够自动重连数据库。如果是在mysql 5.1.6之前,那么则应在每次执行完real_connect 之后执行mysql_options( &mysql, MYSQL_OPT_RECONNECT, … ) ,如果是mysql 5.1.6+,则在connect之前执行一次就够了。

 

查看mysql连接数

mysqladmin -uroot -p  processlist

实际的测试中我发现,当设置了MYSQL_OPT_RECONNECT为1时,超时后再查看processlist,则自动建立的连接不在列表中,但事实上连接确实建立并被使用了。

 

在MYSQL的默认设置中,如果一个数据库连接超过8小时没有使用(闲置8小时),服务器将断开这条连接,后续在该连接上进行的查询操作都将失败。网络上对该问题的描述非常多。也提供了相应的解决办法。我在这里提一些我自己的看法。

解决办法一:修改MYSQL服务器的配置参数

道理非常简单,MYSQL的默认设置是在数据库连接超过8小时没有使用后将其断开,如果我们将这个时间改成更大的数值,那么连接超时所需的时间就会更长,也就意味着更不容易超时。网络上提供的修改方法一般是修改/etc/my.cnf,在这个文件中添加一行wait_timeout=你需要设置的超时时间。实际上有一种比较简单的方法来修改这个参数:

首先作为超级用户登录到MYSQL,注意必须是超级用户,否则后面会提示没有修改权限。然后输入

show global variables like ‘wait_timeout’;

回车执行后显示目前的超时时间:

+—————+——-+

| Variable_name | Value |

+—————+——-+

| wait_timeout | 28800 |

+—————+——-+

1 row in set (0.00 sec)

上面显示的是默认的超时时间,即8个小时(单位是秒)。现在重新设置该参数,例如我们要将超时时间设置成10个小时,可以输入:

set global wait_timeout=36000;

回车执行,显示:

Query OK, 0 rows affected (0.00 sec)

表示设置成功,可以重新使用show global variables like ‘wait_timeout’来验证。

这种方法比较直观,而且设置的参数立即生效。但如果/etc/my.cnf中没有配置,则重启服务后,global变量会从/etc/my.cnf中读取新的变量值。

 

下边是一段示例代码:

if(!mysql_real_connect(&logdb, my_hostname, my_user, my_password, my_dbname, my_port, my_sock, 0)){
ast_log(LOG_ERROR, “Failed to connect to mysql database %s on %s.\n”, my_dbname, my_hostname);
use_mysql = 0;
} else {
char value = 1;
mysql_options(&logdb, MYSQL_OPT_RECONNECT, (char*)&value);
use_mysql = 1;
}

【转】在线热切换innodb表空间

MyIsAM 是一个非常不错的 MySQL 的存储引擎,目前使用非常广泛基本所有的网站和项目,我想都会优先选择这个,这个也有很好的诊断和微调的工具.我发现其中一个缺点,就是磁盘空间管理时设计非常低效.这个设计成给所有数据都存到 ibdata1 文件,所以这个文件的存储空间会不断的扩展.MyIsAM 并不会收缩这些空间,就算你删除表和数据库. 继续阅读

如何确定你最优的innodb日志文件大小

pager grep sequence ;过滤关键字
show engine innodb status\G select sleep(60); show engine innodb status\G;查看一分钟的log sequence的日志号范围
Log sequence number 95273222542
1 row in set (0.00 sec)

1 row in set (1 min 0.00 sec)

Log sequence number 95273302943

select (95273302943 – 95273222542) / 1024 / 1024 as MB_per_min;得到每分钟的日志大小

然后根据每分钟日志文件大小除以innodb的日志文件个数,得到单个日志文件大小。

mysql 5.1.61以下版本身份认证bug修复

mysql 5.1.61以下版本身份认证可能存在密码不正确而通过认证。问题出现在/opt/src/Percona-Server-5.1.58/sql/password.c里面的memcmp函数返回结果。红色部分我已经标注,修复方法加上test进行测试返回即可。
my_bool
check_scramble(const char *scramble_arg, const char *message,
const uint8 *hash_stage2)
{
SHA1_CONTEXT sha1_context;
uint8 buf[SHA1_HASH_SIZE];
uint8 hash_stage2_reassured[SHA1_HASH_SIZE];

mysql_sha1_reset(&sha1_context);
/* create key to encrypt scramble */
mysql_sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH);
mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
mysql_sha1_result(&sha1_context, buf);
/* encrypt scramble */
my_crypt((char *) buf, buf, (const uchar *) scramble_arg, SCRAMBLE_LENGTH);
/* now buf supposedly contains hash_stage1: so we can get hash_stage2 */
mysql_sha1_reset(&sha1_context);
mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
mysql_sha1_result(&sha1_context, hash_stage2_reassured);

  return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));
/*  return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);*/
}

修改了源码,然后直接cd /opt/src/Percona-Server-5.1.58 && make && make install即可

会直接替换mysqld文件。找个时间重启下mysql服务器即完成bug修复。
bug描述:http://bugs.mysql.com/bug.php?id=64884

注:

memcmp的返回值实际上是int,而my_bool实际上是char。那么在把int转换成char的时候,就有可能发生截断。比如,memcmp返回0×200,截断后变成了0,调用check_scramble函数的就误以为“password is correct“。

但是一般来说,memcmp的返回值都在[127,-128]之内。glibc的经SSE优化后的代码,不是如此。所以这个BUG只在特定的编译环境下才会触发:即编译MySQL的时候加了-fno-builtin,并且所使用的glibc是经SSE优化后的(一般系统自带的都是如此)。这里所说的glibc是指Linux的glibc,FreeBSD的libc不受影响

shell测试漏洞是否存在:

for i in `seq 1 1000`; do mysql -uroot -paaaa -h localhost 2>/dev/null; done


 用这个试试,能进去就说明中招了~~

C语言测试:
vim sk.c


#include <stdio.h>

 #include <stdlib.h>


 int main(void) {

         int one, two, ret;

         time_t start = time(0);

         time_t now;


         srand(getpid()*start);

         while (1) {

                 one = rand();

                 two = rand();

                 ret = memcmp(&one, &two, sizeof(int));

                 if (ret < -128 || ret > 127)

                         break;

                 time(&now);

                 if (now - start > 10) {

                         printf("Not triggered in 10 seconds, *probably* not vulnerable..\n");

                         return 1;

                 }

         }

         printf("Vulnerable! memcmp returned: %d\n", ret);

         return 0;

 }

gcc sk.c -o sk
运行看看!

PostgreSQL的基本使用

PostgreSQL是以加州大学伯克利分校计算机系开发的 POSTGRES,版本 4.2为基础的对象关系型数据库管理系统(ORDBMS)。 PostgreSQL支持大部分 SQL标准并且提供了许多其他现代特性:复杂查询、外键、触发器、视图、事务完整性、多版本并发控制。同样,PostgreSQL 可以用许多方法扩展,比如, 通过增加新的数据类型、函数、操作符、聚集函数、索引方法、过程语言。并且,因为许可证的灵活,任何人都可以以任何目的免费使用,修改,和分发 PostgreSQL。
继续阅读

MySQL server has gone away的解决办法

当一个PHP脚本在请求URL的时候,可能这个被请求的网页非常慢慢,超过了mysql的 wait-timeout时间,然后当网页内容被抓回来后,准备插入到MySQL的时候,发现MySQL的连接超时关闭了,于是就出现了“MySQL server has gone away”这样的错误提示,解决这个问题,我的经验有以下两点,或许对大家有用处: 继续阅读